diff --git a/src/Buffers_Message_Handling/txtBuffer.vhd b/src/Buffers_Message_Handling/txtBuffer.vhd index e319ad8e3e6be43ba41d109be1d8c5b1b6cc17a7..dc6bf8b9d9cc3f09d5c116f1a8395e721617b558 100644 --- a/src/Buffers_Message_Handling/txtBuffer.vhd +++ b/src/Buffers_Message_Handling/txtBuffer.vhd @@ -75,6 +75,7 @@ -- 30.8.2018 Added "txt_hw_cmd_int" output for Interrupt Manager. TXTB HW -- command Interrupt generated upon move to Done, Failed or -- Aborted states. +-- 10.11.2018 Separated TXT Buffer FSM to a standalone sub-module. -------------------------------------------------------------------------------- Library ieee; @@ -112,7 +113,7 @@ entity txtBuffer is ------------------------------------------------------------------------ -- Status signals ------------------------------------------------------------------------ - signal txtb_state :out txt_fsm_type; + signal txtb_state :out std_logic_vector(3 downto 0); ------------------------------------------------------------------------ -- Interrupt Manager @@ -152,14 +153,8 @@ architecture rtl of txtBuffer is --Signal aliases ---------------------------------------------------------------------------- - -- Time transcieve buffer - Data memory - signal txt_buffer_mem : frame_memory; - - -- FSM state of the buffer - signal buf_fsm : txt_fsm_type; - -- TXT Buffer memory protection - signal txtb_user_accessible : boolean; + signal txtb_user_accessible : std_logic; -- Internal buffer selects for commands. Commands are shared across the -- buffers so we need unique identifier @@ -174,22 +169,14 @@ architecture rtl of txtBuffer is --------------------------------------------------------------------------- -- Write control signal - signal RAM_write : std_logic; + signal RAM_write : std_logic; -- Read address (connected to read pointer) - signal RAM_read_address : std_logic_vector(4 downto 0); + signal RAM_read_address : std_logic_vector(4 downto 0); begin - - -- Buffer is ready for selection by TX Arbitrator only in state "Ready" - -- Abort signal must not be active. If not considered, - -- race conditions between HW and SW commands could occur. - txt_buf_ready <= '1' when ((buf_fsm = txt_ready) and - (txt_sw_cmd.set_abt = '0')) - else - '0'; - + -- Command buffer select signals hw_cbs <= '1' when txt_hw_cmd_buf_index = ID else @@ -198,31 +185,9 @@ begin sw_cbs <= '1' when txt_sw_buf_cmd_index(ID) = '1' else '0'; - - -- TXT Buffer HW Command generates interrupt upon transition to - -- Failed, Done and Aborted states! - txt_hw_cmd_int <= '1' when (hw_cbs = '1') and ((txt_hw_cmd.failed = '1') or - (txt_hw_cmd.valid = '1') or - ((txt_hw_cmd.unlock = '1') and - (buf_fsm = txt_ab_prog)) or - ((txt_sw_cmd.set_abt = '1') and - (sw_cbs = '1') and - (buf_fsm = txt_ready))) - else - '0'; - -- Connect internal buffer state to output - txtb_state <= buf_fsm; - - -- Memory protection of TXT Buffer - txtb_user_accessible <= false when ((buf_fsm = txt_ready) or - (buf_fsm = txt_tx_prog) or - (buf_fsm = txt_ab_prog)) - else - true; - -- TXT Buffer RAM write signal - RAM_write <= '1' when (tran_cs = '1' and txtb_user_accessible = true) + RAM_write <= '1' when (tran_cs = '1' and txtb_user_accessible = '1') else '0'; @@ -254,199 +219,28 @@ begin ); - ---------------------------------------------------------------------------- - -- Buffer FSM process + -- TXT Buffer FSM ---------------------------------------------------------------------------- - tx_buf_fsm_proc : process(res_n, clk_sys) - begin - if (res_n = ACT_RESET) then - buf_fsm <= txt_empty; + txtBuffer_fsm_comp : txtBuffer_fsm + generic map( + ID => ID + ) + port map( + clk_sys => clk_sys, + res_n => res_n, - elsif (rising_edge(clk_sys)) then - - buf_fsm <= buf_fsm; - - case buf_fsm is - - -------------------------------------------------------------------- - -- Buffer is empty - -------------------------------------------------------------------- - when txt_empty => - - -- "Set_ready" - if (txt_sw_cmd.set_rdy = '1' and sw_cbs = '1') then - buf_fsm <= txt_ready; - end if; - - - -------------------------------------------------------------------- - -- Buffer is ready for transmission - -------------------------------------------------------------------- - when txt_ready => - - -- Locking for transmission - if (txt_hw_cmd.lock = '1' and hw_cbs = '1') then - - -- Simultaneous "lock" and abort -> transmit, but - -- with abort pending - if (txt_sw_cmd.set_abt = '1' and sw_cbs = '1') then - buf_fsm <= txt_ab_prog; - else - buf_fsm <= txt_tx_prog; - end if; - - -- Abort the ready buffer - elsif (txt_sw_cmd.set_abt = '1' and sw_cbs = '1') then - buf_fsm <= txt_aborted; - else - buf_fsm <= buf_fsm; - end if; - - - -------------------------------------------------------------------- - -- Transmission from buffer is in progress - -------------------------------------------------------------------- - when txt_tx_prog => - - -- Unlock the buffer - if (txt_hw_cmd.unlock = '1' and hw_cbs = '1') then - - -- Retransmitt reached, transmitt OK, or try again... - if (txt_hw_cmd.failed = '1') then - buf_fsm <= txt_error; - elsif (txt_hw_cmd.valid = '1') then - buf_fsm <= txt_ok; - elsif (txt_hw_cmd.err = '1' or - txt_hw_cmd.arbl = '1') then - buf_fsm <= txt_ready; - else - buf_fsm <= buf_fsm; - end if; - - -- Request abort during transmission - elsif (txt_sw_cmd.set_abt = '1' and sw_cbs = '1') then - buf_fsm <= txt_ab_prog; - else - buf_fsm <= buf_fsm; - end if; - - - -------------------------------------------------------------------- - -- Transmission is in progress -> abort at nearest error! - -------------------------------------------------------------------- - when txt_ab_prog => - - -- Unlock the buffer - if (txt_hw_cmd.unlock = '1' and hw_cbs = '1') then - - -- Retransmitt reached, transmitt OK, or try again... - if (txt_hw_cmd.failed = '1') then - buf_fsm <= txt_error; - elsif (txt_hw_cmd.valid = '1') then - buf_fsm <= txt_ok; - elsif (txt_hw_cmd.err = '1' or - txt_hw_cmd.arbl = '1') then - buf_fsm <= txt_aborted; - else - buf_fsm <= buf_fsm; - end if; - - else - buf_fsm <= buf_fsm; - end if; - - - -------------------------------------------------------------------- - -- Transmission from buffer failed. Retransmitt limit was reached. - -------------------------------------------------------------------- - when txt_error => - - -- "Set_ready" - if (txt_sw_cmd.set_rdy = '1' and sw_cbs = '1') then - buf_fsm <= txt_ready; - end if; - - -- "Set_empty" - if (txt_sw_cmd.set_ety = '1' and sw_cbs = '1') then - buf_fsm <= txt_empty; - end if; - - - -------------------------------------------------------------------- - -- Transmission was aborted by user command - -------------------------------------------------------------------- - when txt_aborted => - - -- "Set_ready" - if (txt_sw_cmd.set_rdy = '1' and sw_cbs = '1') then - buf_fsm <= txt_ready; - end if; - - -- "Set_empty" - if (txt_sw_cmd.set_ety = '1' and sw_cbs = '1') then - buf_fsm <= txt_empty; - end if; - - - -------------------------------------------------------------------- - -- Transmission was succesfull - -------------------------------------------------------------------- - when txt_ok => - - -- "Set_ready" - if (txt_sw_cmd.set_rdy = '1' and sw_cbs = '1') then - buf_fsm <= txt_ready; - end if; - - -- "Set_empty" - if (txt_sw_cmd.set_ety = '1' and sw_cbs = '1') then - buf_fsm <= txt_empty; - end if; - - end case; - - -------------------------------------------------------------------- - -- If Core goes to bus-off, TXT Buffer goes to failed, regardless of - -- any other SW or HW commands - -------------------------------------------------------------------- - if (bus_off_start = '1') then - buf_fsm <= txt_error; - end if; - - end if; - end process; + txt_sw_cmd => txt_sw_cmd, + sw_cbs => sw_cbs, + txt_hw_cmd => txt_hw_cmd, + hw_cbs => hw_cbs, + bus_off_start => bus_off_start, - ---------------------------------------------------------------------------- - -- Monitoring invalid command combinations! - ---------------------------------------------------------------------------- - lock_check_proc : process(clk_sys) - begin - if (rising_edge(clk_sys)) then - if (txt_hw_cmd.lock = '1' and - buf_fsm /= txt_ready and - txt_hw_cmd_buf_index = ID) - then - report "Buffer not READY and LOCK occurred on TXT Buffer: " & - integer'image(ID) severity error; - end if; - end if; - end process; - - - unlock_check_proc : process(clk_sys) - begin - if (rising_edge(clk_sys)) then - if (txt_hw_cmd.unlock = '1' and - buf_fsm /= txt_tx_prog and - buf_fsm /= txt_ab_prog and - txt_hw_cmd_buf_index = ID) - then - report "Buffer not 'TX_prog' or 'AB_prog' and UNLOCK" & - " occurred on Buffer: " & integer'image(ID) severity error; - end if; - end if; - end process; + txtb_user_accessible => txtb_user_accessible, + txtb_hw_cmd_int => txt_hw_cmd_int, + txtb_state => txtb_state, + txt_buf_ready => txt_buf_ready + ); end architecture; diff --git a/src/Buffers_Message_Handling/txtBuffer_fsm.vhd b/src/Buffers_Message_Handling/txtBuffer_fsm.vhd new file mode 100644 index 0000000000000000000000000000000000000000..fe748c244b6135513610e57c7836891f04c88d35 --- /dev/null +++ b/src/Buffers_Message_Handling/txtBuffer_fsm.vhd @@ -0,0 +1,349 @@ +-------------------------------------------------------------------------------- +-- +-- CTU CAN FD IP Core +-- Copyright (C) 2015-2018 +-- +-- Authors: +-- Ondrej Ille +-- Martin Jerabek +-- +-- Project advisors: +-- Jiri Novak +-- Pavel Pisa +-- +-- Department of Measurement (http://meas.fel.cvut.cz/) +-- Faculty of Electrical Engineering (http://www.fel.cvut.cz) +-- Czech Technical University (http://www.cvut.cz/) +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy +-- of this VHDL component and associated documentation files (the "Component"), +-- to deal in the Component without restriction, including without limitation +-- the rights to use, copy, modify, merge, publish, distribute, sublicense, +-- and/or sell copies of the Component, and to permit persons to whom the +-- Component is furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in +-- all copies or substantial portions of the Component. +-- +-- THE COMPONENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-- AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +-- FROM, OUT OF OR IN CONNECTION WITH THE COMPONENT OR THE USE OR OTHER DEALINGS +-- IN THE COMPONENT. +-- +-- The CAN protocol is developed by Robert Bosch GmbH and protected by patents. +-- Anybody who wants to implement this IP core on silicon has to obtain a CAN +-- protocol license from Bosch. +-- +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- +-- Purpose: +-- Transmitt Message Buffer FSM. +-------------------------------------------------------------------------------- +-- Revision History: +-- +-- 07.11.2018 Created file +-------------------------------------------------------------------------------- + +Library ieee; +USE IEEE.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +use work.CANconstants.all; +use work.CANcomponents.all; +use work.CAN_FD_register_map.all; + +entity txtBuffer_fsm is + generic( + constant ID : natural + ); + port( + ------------------------------------------------------------------------ + -- Clock and reset + ------------------------------------------------------------------------ + signal clk_sys :in std_logic; + signal res_n :in std_logic; + + ------------------------------------------------------------------------ + -- SW Interface (Memory registers) + ------------------------------------------------------------------------ + signal txt_sw_cmd :in txt_sw_cmd_type; + signal sw_cbs :in std_logic; + + ------------------------------------------------------------------------ + -- HW Interface (CAN Core + ------------------------------------------------------------------------ + signal txt_hw_cmd :in txt_hw_cmd_type; + signal hw_cbs :in std_logic; + + ------------------------------------------------------------------------ + -- Other control signals + ------------------------------------------------------------------------ + signal bus_off_start :in std_logic; + + ------------------------------------------------------------------------ + -- Status signals + ------------------------------------------------------------------------ + + -- Buffer accessible from SW + signal txtb_user_accessible :out std_logic; + + -- HW Command applied on TXT Buffer -> Interrupt! + signal txtb_hw_cmd_int :out std_logic; + + -- Buffer status (FSM state) encoded for reading by SW from registers! + signal txtb_state :out std_logic_vector(3 downto 0); + + -- TXT Buffer is ready to be locked by CAN Core for transmission + signal txt_buf_ready :out std_logic + ); + +end entity; + + +architecture rtl of txtBuffer_fsm is + + -- FSM state of the buffer + signal buf_fsm : txt_fsm_type; + +begin + + ---------------------------------------------------------------------------- + -- Buffer FSM process + ---------------------------------------------------------------------------- + tx_buf_fsm_proc : process(res_n, clk_sys) + begin + if (res_n = ACT_RESET) then + buf_fsm <= txt_empty; + + elsif (rising_edge(clk_sys)) then + + buf_fsm <= buf_fsm; + + case buf_fsm is + + -------------------------------------------------------------------- + -- Buffer is empty + -------------------------------------------------------------------- + when txt_empty => + + -- "Set_ready" + if (txt_sw_cmd.set_rdy = '1' and sw_cbs = '1') then + buf_fsm <= txt_ready; + end if; + + + -------------------------------------------------------------------- + -- Buffer is ready for transmission + -------------------------------------------------------------------- + when txt_ready => + + -- Locking for transmission + if (txt_hw_cmd.lock = '1' and hw_cbs = '1') then + + -- Simultaneous "lock" and abort -> transmit, but + -- with abort pending + if (txt_sw_cmd.set_abt = '1' and sw_cbs = '1') then + buf_fsm <= txt_ab_prog; + else + buf_fsm <= txt_tx_prog; + end if; + + -- Abort the ready buffer + elsif (txt_sw_cmd.set_abt = '1' and sw_cbs = '1') then + buf_fsm <= txt_aborted; + else + buf_fsm <= buf_fsm; + end if; + + + -------------------------------------------------------------------- + -- Transmission from buffer is in progress + -------------------------------------------------------------------- + when txt_tx_prog => + + -- Unlock the buffer + if (txt_hw_cmd.unlock = '1' and hw_cbs = '1') then + + -- Retransmitt reached, transmitt OK, or try again... + if (txt_hw_cmd.failed = '1') then + buf_fsm <= txt_error; + elsif (txt_hw_cmd.valid = '1') then + buf_fsm <= txt_ok; + elsif (txt_hw_cmd.err = '1' or + txt_hw_cmd.arbl = '1') then + buf_fsm <= txt_ready; + else + buf_fsm <= buf_fsm; + end if; + + -- Request abort during transmission + elsif (txt_sw_cmd.set_abt = '1' and sw_cbs = '1') then + buf_fsm <= txt_ab_prog; + else + buf_fsm <= buf_fsm; + end if; + + + -------------------------------------------------------------------- + -- Transmission is in progress -> abort at nearest error! + -------------------------------------------------------------------- + when txt_ab_prog => + + -- Unlock the buffer + if (txt_hw_cmd.unlock = '1' and hw_cbs = '1') then + + -- Retransmitt reached, transmitt OK, or try again... + if (txt_hw_cmd.failed = '1') then + buf_fsm <= txt_error; + elsif (txt_hw_cmd.valid = '1') then + buf_fsm <= txt_ok; + elsif (txt_hw_cmd.err = '1' or + txt_hw_cmd.arbl = '1') then + buf_fsm <= txt_aborted; + else + buf_fsm <= buf_fsm; + end if; + + else + buf_fsm <= buf_fsm; + end if; + + + -------------------------------------------------------------------- + -- Transmission from buffer failed. Retransmitt limit was reached. + -------------------------------------------------------------------- + when txt_error => + + -- "Set_ready" + if (txt_sw_cmd.set_rdy = '1' and sw_cbs = '1') then + buf_fsm <= txt_ready; + end if; + + -- "Set_empty" + if (txt_sw_cmd.set_ety = '1' and sw_cbs = '1') then + buf_fsm <= txt_empty; + end if; + + + -------------------------------------------------------------------- + -- Transmission was aborted by user command + -------------------------------------------------------------------- + when txt_aborted => + + -- "Set_ready" + if (txt_sw_cmd.set_rdy = '1' and sw_cbs = '1') then + buf_fsm <= txt_ready; + end if; + + -- "Set_empty" + if (txt_sw_cmd.set_ety = '1' and sw_cbs = '1') then + buf_fsm <= txt_empty; + end if; + + + -------------------------------------------------------------------- + -- Transmission was succesfull + -------------------------------------------------------------------- + when txt_ok => + + -- "Set_ready" + if (txt_sw_cmd.set_rdy = '1' and sw_cbs = '1') then + buf_fsm <= txt_ready; + end if; + + -- "Set_empty" + if (txt_sw_cmd.set_ety = '1' and sw_cbs = '1') then + buf_fsm <= txt_empty; + end if; + + end case; + + -------------------------------------------------------------------- + -- If Core goes to bus-off, TXT Buffer goes to failed, regardless of + -- any other SW or HW commands + -------------------------------------------------------------------- + if (bus_off_start = '1') then + buf_fsm <= txt_error; + end if; + + end if; + end process; + + + ---------------------------------------------------------------------------- + -- Buffer FSM outputs + ---------------------------------------------------------------------------- + -- Memory protection of TXT Buffer + txtb_user_accessible <= '0' when ((buf_fsm = txt_ready) or + (buf_fsm = txt_tx_prog) or + (buf_fsm = txt_ab_prog)) + else + '1'; + + -- TXT Buffer HW Command generates interrupt upon transition to + -- Failed, Done and Aborted states! + txtb_hw_cmd_int <= '1' when (hw_cbs = '1') and ((txt_hw_cmd.failed = '1') or + (txt_hw_cmd.valid = '1') or + ((txt_hw_cmd.unlock = '1') and + (buf_fsm = txt_ab_prog)) or + ((txt_sw_cmd.set_abt = '1') and + (sw_cbs = '1') and + (buf_fsm = txt_ready))) + else + '0'; + + -- Buffer is ready for selection by TX Arbitrator only in state "Ready" + -- Abort signal must not be active. If not considered, + -- race conditions between HW and SW commands could occur. + txt_buf_ready <= '1' when ((buf_fsm = txt_ready) and + (txt_sw_cmd.set_abt = '0')) + else + '0'; + + -- Encoding Buffer FSM to output values read from TXT Buffer status register. + with buf_fsm select txtb_state <= + TXT_RDY when txt_ready, + TXT_TRAN when txt_tx_prog, + TXT_ABTP when txt_ab_prog, + TXT_TOK when txt_ok, + TXT_ERR when txt_error, + TXT_ABT when txt_aborted, + TXT_ETY when txt_empty; + + + ---------------------------------------------------------------------------- + -- Monitoring invalid command combinations! + ---------------------------------------------------------------------------- + lock_check_proc : process(clk_sys) + begin + if (rising_edge(clk_sys)) then + if (txt_hw_cmd.lock = '1' and + buf_fsm /= txt_ready and + hw_cbs = '1') + then + report "Buffer not READY and LOCK occurred on TXT Buffer: " & + integer'image(ID) & " Buffer state: " & + txt_fsm_type'image(buf_fsm) severity error; + end if; + end if; + end process; + + + unlock_check_proc : process(clk_sys) + begin + if (rising_edge(clk_sys)) then + if (txt_hw_cmd.unlock = '1' and + buf_fsm /= txt_tx_prog and + buf_fsm /= txt_ab_prog and + hw_cbs = '1') + then + report "Buffer not 'TX_prog' or 'AB_prog' and UNLOCK" & + " occurred on Buffer: " & integer'image(ID) severity error; + end if; + end if; + end process; + +end architecture; diff --git a/src/CAN_top_level.vhd b/src/CAN_top_level.vhd index 64778853e49014eb0f980a3066ed50c36dc449c7..115224b99ea5c787495f0bc07c18e77ac8d80e55 100644 --- a/src/CAN_top_level.vhd +++ b/src/CAN_top_level.vhd @@ -229,7 +229,7 @@ entity CAN_top_level is signal tran_cs : std_logic_vector(TXT_BUFFER_COUNT - 1 downto 0); -- Finite state machine types for TXT Buffer - signal txtb_fsms : txt_fsms_type; + signal txtb_state : txtb_state_type; -- Software commands + buffer indices that should be activated signal txt_sw_cmd : txt_sw_cmd_type; @@ -535,7 +535,7 @@ begin tran_data => tran_data, tran_addr => tran_addr, txtb_cs => tran_cs, - txtb_fsms => txtb_fsms, + txtb_state => txtb_state, txt_sw_cmd => txt_sw_cmd, txt_buf_cmd_index => txt_buf_cmd_index, txt_buf_prior_out => txt_buf_prior, @@ -603,7 +603,7 @@ begin tran_cs => tran_cs(i), txt_sw_cmd => txt_sw_cmd, txt_sw_buf_cmd_index => txt_buf_cmd_index, - txtb_state => txtb_fsms(i), + txtb_state => txtb_state(i), txt_hw_cmd => txt_hw_cmd, txt_hw_cmd_int => txt_hw_cmd_int(i), txt_hw_cmd_buf_index => txt_hw_cmd_buf_index, diff --git a/src/Libraries/CANcomponents.vhd b/src/Libraries/CANcomponents.vhd index e52f608a8cb830472fc8118dc79bf1ba6757fefd..e51ee4c63f3e05e2900c6fdd7c99e201e079665e 100644 --- a/src/Libraries/CANcomponents.vhd +++ b/src/Libraries/CANcomponents.vhd @@ -153,7 +153,7 @@ package CANcomponents is signal txtb_cs : out std_logic_vector( buf_count - 1 downto 0); - signal txtb_fsms : in txt_fsms_type; + signal txtb_state : in txtb_state_type; signal txt_sw_cmd : out txt_sw_cmd_type; signal txt_buf_cmd_index : out std_logic_vector( @@ -265,7 +265,7 @@ package CANcomponents is signal txt_sw_buf_cmd_index :in std_logic_vector( buf_count - 1 downto 0); - signal txtb_state :out txt_fsm_type; + signal txtb_state :out std_logic_vector(3 downto 0); signal txt_hw_cmd :in txt_hw_cmd_type; signal bus_off_start :in std_logic; signal txt_hw_cmd_buf_index :in natural range 0 to buf_count - 1; @@ -276,6 +276,28 @@ package CANcomponents is end component; + ---------------------------------------------------------------------------- + -- TXT Buffer FSM + ---------------------------------------------------------------------------- + component txtBuffer_fsm is + generic( + constant ID : natural + ); + port( + signal clk_sys :in std_logic; + signal res_n :in std_logic; + signal txt_sw_cmd :in txt_sw_cmd_type; + signal sw_cbs :in std_logic; + signal txt_hw_cmd :in txt_hw_cmd_type; + signal hw_cbs :in std_logic; + signal bus_off_start :in std_logic; + signal txtb_user_accessible :out std_logic; + signal txtb_hw_cmd_int :out std_logic; + signal txtb_state :out std_logic_vector(3 downto 0); + signal txt_buf_ready :out std_logic + ); + end component; + ---------------------------------------------------------------------------- -- TXT Arbitrator module ---------------------------------------------------------------------------- diff --git a/src/Libraries/CANconstants.vhd b/src/Libraries/CANconstants.vhd index 60b00e0f0af965d2b740fab6c2ed7f6663756ee6..1d93c85842d6874db927fdce29073f44d71eca07 100644 --- a/src/Libraries/CANconstants.vhd +++ b/src/Libraries/CANconstants.vhd @@ -287,8 +287,8 @@ package CANconstants is type txtb_output_type is array (0 to TXT_BUFFER_COUNT - 1) of std_logic_vector(31 downto 0); - type txt_fsms_type is array (0 to TXT_BUFFER_COUNT - 1) of - txt_fsm_type; + type txtb_state_type is array (0 to TXT_BUFFER_COUNT - 1) of + std_logic_vector(3 downto 0); type txt_sw_cmd_type is record set_rdy : std_logic; diff --git a/src/Registers_Memory_Interface/canfd_registers.vhd b/src/Registers_Memory_Interface/canfd_registers.vhd index 8d6c55f88961a68cfaa9a1f8ecab2c20d3386d6f..30b16f6a7a694c6ba6e7718ada854dbb66cfb866 100644 --- a/src/Registers_Memory_Interface/canfd_registers.vhd +++ b/src/Registers_Memory_Interface/canfd_registers.vhd @@ -214,7 +214,7 @@ entity canfd_registers is signal txtb_cs :out std_logic_vector(buf_count - 1 downto 0); -- Buffer status signals - signal txtb_fsms :in txt_fsms_type; + signal txtb_state :in txtb_state_type; -- Buffer commands + command index signal txt_sw_cmd :out txt_sw_cmd_type; @@ -1495,95 +1495,11 @@ begin when TX_STATUS_ADR => data_out_int(31 downto 3) <= (OTHERS => '0'); - ---------------------------------------------------- - -- We encode state here, later this will be moved to - -- higher level module. So far we unrool it and do - -- it for every Buffer state separately so that we - -- dont have problems with dependencies between - -- indices! (e.g if we used loop and used offset - -- from first buffer state) - ---------------------------------------------------- - case txtb_fsms(0) is - when txt_empty => - data_out_int(TX1S_H downto TX1S_L) <= TXT_ETY; - when txt_ready => - data_out_int(TX1S_H downto TX1S_L) <= TXT_RDY; - when txt_tx_prog => - data_out_int(TX1S_H downto TX1S_L) <= TXT_TRAN; - when txt_ab_prog => - data_out_int(TX1S_H downto TX1S_L) <= TXT_ABTP; - when txt_ok => - data_out_int(TX1S_H downto TX1S_L) <= TXT_TOK; - when txt_error => - data_out_int(TX1S_H downto TX1S_L) <= TXT_ERR; - when txt_aborted => - data_out_int(TX1S_H downto TX1S_L) <= TXT_ABT; - when others => - data_out_int(TX1S_H downto TX1S_L) <= - (OTHERS => '0'); - end case; - - case txtb_fsms(1) is - when txt_empty => - data_out_int(TX2S_H downto TX2S_L) <= TXT_ETY; - when txt_ready => - data_out_int(TX2S_H downto TX2S_L) <= TXT_RDY; - when txt_tx_prog => - data_out_int(TX2S_H downto TX2S_L) <= TXT_TRAN; - when txt_ab_prog => - data_out_int(TX2S_H downto TX2S_L) <= TXT_ABTP; - when txt_ok => - data_out_int(TX2S_H downto TX2S_L) <= TXT_TOK; - when txt_error => - data_out_int(TX2S_H downto TX2S_L) <= TXT_ERR; - when txt_aborted => - data_out_int(TX2S_H downto TX2S_L) <= TXT_ABT; - when others => - data_out_int(TX2S_H downto TX2S_L) <= - (OTHERS => '0'); - end case; - - case txtb_fsms(2) is - when txt_empty => - data_out_int(TX3S_H downto TX3S_L) <= TXT_ETY; - when txt_ready => - data_out_int(TX3S_H downto TX3S_L) <= TXT_RDY; - when txt_tx_prog => - data_out_int(TX3S_H downto TX3S_L) <= TXT_TRAN; - when txt_ab_prog => - data_out_int(TX3S_H downto TX3S_L) <= TXT_ABTP; - when txt_ok => - data_out_int(TX3S_H downto TX3S_L) <= TXT_TOK; - when txt_error => - data_out_int(TX3S_H downto TX3S_L) <= TXT_ERR; - when txt_aborted => - data_out_int(TX3S_H downto TX3S_L) <= TXT_ABT; - when others => - data_out_int(TX3S_H downto TX3S_L) <= - (OTHERS => '0'); - end case; - - case txtb_fsms(3) is - when txt_empty => - data_out_int(TX4S_H downto TX4S_L) <= TXT_ETY; - when txt_ready => - data_out_int(TX4S_H downto TX4S_L) <= TXT_RDY; - when txt_tx_prog => - data_out_int(TX4S_H downto TX4S_L) <= TXT_TRAN; - when txt_ab_prog => - data_out_int(TX4S_H downto TX4S_L) <= TXT_ABTP; - when txt_ok => - data_out_int(TX4S_H downto TX4S_L) <= TXT_TOK; - when txt_error => - data_out_int(TX4S_H downto TX4S_L) <= TXT_ERR; - when txt_aborted => - data_out_int(TX4S_H downto TX4S_L) <= TXT_ABT; - when others => - data_out_int(TX4S_H downto TX4S_L) <= - (OTHERS => '0'); - end case; - - + data_out_int(TX1S_H downto TX1S_L) <= txtb_state(0); + data_out_int(TX2S_H downto TX2S_L) <= txtb_state(1); + data_out_int(TX3S_H downto TX3S_L) <= txtb_state(2); + data_out_int(TX4S_H downto TX4S_L) <= txtb_state(3); + -------------------------------------------------------- -- TX_COMMAND (TX_SETTINGS and TX_COMMAND) -------------------------------------------------------- @@ -1806,10 +1722,10 @@ begin else '0'; - status_reg(TXNF_IND mod 8) <= '1' when (txtb_fsms(0) = txt_empty or - txtb_fsms(1) = txt_empty or - txtb_fsms(2) = txt_empty or - txtb_fsms(3) = txt_empty) + status_reg(TXNF_IND mod 8) <= '1' when (txtb_state(0) = TXT_ETY or + txtb_state(1) = TXT_ETY or + txtb_state(2) = TXT_ETY or + txtb_state(3) = TXT_ETY) else '0'; diff --git a/test/unit/TX_Buffer/Tx_Buffer_tb.vhd b/test/unit/TX_Buffer/Tx_Buffer_tb.vhd index 8a26e8b6b6aa025da2f753e2c757d56e15c71daa..d13ff1d364c6e056bc4690c10dc972f7eff173ff 100644 --- a/test/unit/TX_Buffer/Tx_Buffer_tb.vhd +++ b/test/unit/TX_Buffer/Tx_Buffer_tb.vhd @@ -62,6 +62,7 @@ use work.CANcomponents.ALL; USE work.CANtestLib.All; USE work.randomLib.All; use work.ID_transfer.all; +use work.CAN_FD_register_map.all; architecture tx_buf_unit_test of CAN_test is @@ -87,7 +88,7 @@ architecture tx_buf_unit_test of CAN_test is ------------------ --Status signals-- ------------------ - signal txtb_state : txt_fsm_type; + signal txtb_state : std_logic_vector(3 downto 0); ------------------------------------ --CAN Core and TX Arbiter Interface- @@ -98,7 +99,7 @@ architecture tx_buf_unit_test of CAN_test is ('0', '0', '0', '0', '0', '0'); signal txt_hw_cmd_int : std_logic; - signal txt_hw_cmd_buf_index : natural range 0 to 3; + signal txt_hw_cmd_buf_index : natural range 0 to 3 := 0; -- Buffer output and pointer to the RAM memory signal txt_word : std_logic_vector(31 downto 0); @@ -131,13 +132,13 @@ architecture tx_buf_unit_test of CAN_test is signal exit_imm_1 : boolean; signal exit_imm_2 : boolean; - signal txtb_exp_state : txt_fsm_type; + signal txtb_exp_state : std_logic_vector(3 downto 0); procedure calc_exp_state( signal sw_cmd : in txt_sw_cmd_type; signal hw_cmd : in txt_hw_cmd_type; - signal act_state : in txt_fsm_type; - signal exp_state : out txt_fsm_type + signal act_state : in std_logic_vector(3 downto 0); + signal exp_state : out std_logic_vector(3 downto 0) ) is begin @@ -145,67 +146,67 @@ architecture tx_buf_unit_test of CAN_test is exp_state <= act_state; case act_state is - when txt_empty => + when TXT_ETY => if (sw_cmd.set_rdy = '1') then - exp_state <= txt_ready; + exp_state <= TXT_RDY; end if; - when txt_ready => + when TXT_RDY => if (hw_cmd.lock = '1') then if (sw_cmd.set_abt = '1') then - exp_state <= txt_ab_prog; + exp_state <= TXT_ABTP; else - exp_state <= txt_tx_prog; + exp_state <= TXT_TRAN; end if; elsif (sw_cmd.set_abt = '1') then - exp_state <= txt_aborted; + exp_state <= TXT_ABT; end if; - when txt_tx_prog => + when TXT_TRAN => if (sw_cmd.set_abt = '1') then - exp_state <= txt_ab_prog; + exp_state <= TXT_ABTP; end if; if (hw_cmd.unlock = '1') then if (hw_cmd.valid = '1') then - exp_state <= txt_ok; + exp_state <= TXT_TOK; elsif (hw_cmd.err = '1' or hw_cmd.arbl = '1') then - exp_state <= txt_ready; + exp_state <= TXT_RDY; elsif (hw_cmd.failed = '1') then - exp_state <= txt_error; + exp_state <= TXT_ERR; end if; end if; - when txt_ab_prog => + when TXT_ABTP => if (hw_cmd.unlock = '1') then if (hw_cmd.valid = '1') then - exp_state <= txt_ok; + exp_state <= TXT_TOK; elsif (hw_cmd.err = '1' or hw_cmd.arbl = '1') then - exp_state <= txt_aborted; + exp_state <= TXT_ABT; elsif (hw_cmd.failed = '1') then - exp_state <= txt_error; + exp_state <= TXT_ERR; end if; end if; - when txt_ok => + when TXT_TOK => if (sw_cmd.set_ety = '1') then - exp_state <= txt_empty; + exp_state <= TXT_ETY; elsif (sw_cmd.set_rdy = '1') then - exp_state <= txt_ready; + exp_state <= TXT_RDY; end if; - when txt_aborted => + when TXT_ABT => if (sw_cmd.set_ety = '1') then - exp_state <= txt_empty; + exp_state <= TXT_ETY; elsif (sw_cmd.set_rdy = '1') then - exp_state <= txt_ready; + exp_state <= TXT_RDY; end if; - when txt_error => + when TXT_ERR => if (sw_cmd.set_ety = '1') then - exp_state <= txt_empty; + exp_state <= TXT_ETY; elsif (sw_cmd.set_rdy = '1') then - exp_state <= txt_ready; + exp_state <= TXT_RDY; end if; when others => end case; @@ -251,7 +252,7 @@ begin -- Data generation - stored by user writes ---------------------------------------------------------------------------- data_gen_proc : process - variable buf_fsm : txt_fsm_type; + variable buf_fsm : std_logic_vector(3 downto 0); begin tran_cs <= '0'; while res_n = ACT_RESET loop @@ -277,9 +278,9 @@ begin -- Data should be stored only if the buffer is accessible by user, -- when it is not ready, neither transmission is in progress. -- Store it in the shadow buffer! - if (buf_fsm /= txt_ready and - buf_fsm /= txt_tx_prog and - buf_fsm /= txt_ab_prog) + if (buf_fsm /= TXT_RDY and + buf_fsm /= TXT_TRAN and + buf_fsm /= TXT_ABTP) then shadow_mem(to_integer(unsigned(tran_addr))) <= tran_data; end if; @@ -341,11 +342,11 @@ begin rand_logic_s(rand_com_gen_ctr, txt_hw_cmd.lock, 0.2); rand_logic_s(rand_com_gen_ctr, txt_hw_cmd.unlock, 0.2); - if (txtb_state /= txt_ready) then + if (txtb_state /= TXT_RDY) then txt_hw_cmd.lock <= '0'; end if; - if (txtb_state /= txt_tx_prog and txtb_state /= txt_ab_prog) then + if (txtb_state /= TXT_TRAN and txtb_state /= TXT_ABTP) then txt_hw_cmd.unlock <= '0'; end if; wait for 0 ns; @@ -381,8 +382,8 @@ begin -- LCOV_EXCL_START process_error(state_coh_error_ctr, error_beh, exit_imm_2); log("State not updated as expected! Actual: " & - txt_fsm_type'image(txtb_state) & " Expected: " & - txt_fsm_type'image(txtb_exp_state), + to_hstring(txtb_state) & " Expected: " & + to_hstring(txtb_exp_state), error_l, log_level); -- LCOV_EXCL_STOP end if;