diff --git a/src/bus_sampling/bus_sampling.vhd b/src/bus_sampling/bus_sampling.vhd index a9cc7c6d5f72fa1d5f13cc0c827104e1959385cf..71b211afc29bf51400dd2da14e083e4f35c0424e 100644 --- a/src/bus_sampling/bus_sampling.vhd +++ b/src/bus_sampling/bus_sampling.vhd @@ -86,6 +86,9 @@ -- reading wrong value from TRV_DELAY register during measurment. -- 10.12.2018 Re-factored, added generic Shift register instances. Added -- generic synchronisation chain module. +-- 16.1.2019 Replaced TX Data Shift register with FIFO like TX Data Cache. +-- TX Data are stored only once per bit. TX Data Cache consumes +-- drastically less DFFs. -------------------------------------------------------------------------------- Library ieee; @@ -203,17 +206,15 @@ architecture rtl of bus_sampling is -- Shift registers length constant SSP_SHIFT_LENGTH : natural := 130; - constant TX_DATA_SHIFT_LENGTH : natural := 130; + + -- Depth of FIFO Cache for TX Data + constant TX_CACHE_DEPTH : natural := 8; -- Reset value for secondar sampling point shift registers constant SSP_SHIFT_RST_VAL : std_logic_vector(SSP_SHIFT_LENGTH - 1 downto 0) := (OTHERS => '0'); - constant TX_DATA_SHIFT_RST_VAL : std_logic_vector(TX_DATA_SHIFT_LENGTH - 1 - downto 0) := - (OTHERS => RECESSIVE); - constant SSP_DELAY_SAT_VAL : natural := SSP_SHIFT_LENGTH - 1; ----------------------------------------------------------------------------- @@ -263,10 +264,6 @@ architecture rtl of bus_sampling is signal sample_sec_del_1 : std_logic; signal sample_sec_del_2 : std_logic; - -- Shift Register for storing the TX data for secondary sample point - signal tx_data_shift : std_logic_vector - (TX_DATA_SHIFT_LENGTH - 1 downto 0); - -- Delayed TX Data from TX Data shift register at position of secondary -- sampling point. signal tx_data_delayed : std_logic; @@ -444,41 +441,33 @@ begin output => open ); - ---------------------------------------------------------------------------- - -- Shift register for TX data. Stored by shift register to be compared - -- with sampled RX Data in Secondary sampling point to detect bit error. - ---------------------------------------------------------------------------- - tx_data_shift_reg_comp : shift_reg - generic map( - reset_polarity => ACT_RESET, - reset_value => TX_DATA_SHIFT_RST_VAL, - width => TX_DATA_SHIFT_LENGTH, - shift_down => false - ) - port map( - clk => clk_sys, - res_n => shift_regs_res_n, - - input => data_tx, - enable => '1', - - reg_stat => tx_data_shift, - output => open - ); - - ---------------------------------------------------------------------------- -- Secondary sampling point address decoder. Secondary sampling point -- is taken from SSP Shift register at position of transceiver delay. ---------------------------------------------------------------------------- sample_sec_comb <= sample_sec_shift(to_integer(unsigned(ssp_delay))); + ---------------------------------------------------------------------------- - -- Delayed TX data address decoder. At the time of secondary sampling point, - -- TX data from TX Data shift register at position of transceiver delay are - -- taken for bit error detection! + -- TX DATA Cache. Stores TX Data when Sample point enters the SSP shift + -- register and reads data when Sample point steps out of shift register. + -- This gets the TX data which correspond to the RX Bit in Secondary + -- sampling point. ---------------------------------------------------------------------------- - tx_data_delayed <= tx_data_shift(to_integer(unsigned(ssp_delay))); + tx_data_cache_comp : tx_data_cache + generic map( + reset_polarity => ACT_RESET, + tx_cache_depth => TX_CACHE_DEPTH, + tx_cache_res_val => RECESSIVE + ) + port map( + clk_sys => clk_sys, + res_n => shift_regs_res_n, + write => sample_dbt, + read => sample_sec, + data_in => data_tx, + data_out => tx_data_delayed + ); ---------------------------------------------------------------------------- diff --git a/src/bus_sampling/tx_data_cache.vhd b/src/bus_sampling/tx_data_cache.vhd new file mode 100644 index 0000000000000000000000000000000000000000..1f7268d043a7b24ae2817b861c7bfdcf3f0db97f --- /dev/null +++ b/src/bus_sampling/tx_data_cache.vhd @@ -0,0 +1,238 @@ +-------------------------------------------------------------------------------- +-- +-- 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: +-- TX Data Cache (FIFO-like). Stores TX Data into FIFO buffer. TX Data are +-- stored in time of regular sample point and read at the time of delayed +-- sample point. Read data are used for bit error detection. +-------------------------------------------------------------------------------- +-- 16.01.2019 Created file +-------------------------------------------------------------------------------- + +Library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.ALL; +use ieee.math_real.ALL; + +Library work; +use work.id_transfer.all; +use work.can_constants.all; +use work.can_components.all; +use work.can_types.all; +use work.cmn_lib.all; +use work.drv_stat_pkg.all; +use work.endian_swap.all; +use work.reduce_lib.all; + +use work.CAN_FD_register_map.all; +use work.CAN_FD_frame_format.all; + +entity tx_data_cache is + generic( + -- Reset polarity + constant reset_polarity : std_logic; + + -- Depth of FIFO (Number of bits that can be stored) + constant tx_cache_depth : natural range 4 to 32 := 8; + + -- FIFO reset value + constant tx_cache_res_val : std_logic + ); + port( + ------------------------------------------------------------------------ + -- Clock and Async reset + ------------------------------------------------------------------------ + signal clk_sys :in std_logic; + signal res_n :in std_logic; + + ------------------------------------------------------------------------ + -- Control signals + ------------------------------------------------------------------------ + -- Store input data + signal write :in std_logic; + + -- Read output data + signal read :in std_logic; + + ------------------------------------------------------------------------ + -- Data signals + ------------------------------------------------------------------------ + signal data_in :in std_logic; + signal data_out :out std_logic + ); +end entity; + + +architecture rtl of tx_data_cache is + + + -- Cache Memory (FIFO in DFFs) + signal tx_cache_mem : std_logic_vector(tx_cache_depth - 1 downto 0); + + --------------------------------------------------------------------------- + -- Access pointers + --------------------------------------------------------------------------- + -- Write Pointer + signal write_pointer : natural range 0 to tx_cache_depth - 1; + signal write_pointer_nxt : natural range 0 to tx_cache_depth - 1; + + -- Read pointer + signal read_pointer : natural range 0 to tx_cache_depth - 1; + signal read_pointer_nxt : natural range 0 to tx_cache_depth - 1; + +begin + + ---------------------------------------------------------------------------- + -- Combinationally incrementing write and read pointers + ---------------------------------------------------------------------------- + write_pointer_nxt <= (write_pointer + 1) mod tx_cache_depth; + read_pointer_nxt <= (read_pointer + 1) mod tx_cache_depth; + + + ---------------------------------------------------------------------------- + -- Incrementing the pointers upon read or write. + ---------------------------------------------------------------------------- + write_ptr_proc : process(clk_sys, res_n) + begin + if (res_n = reset_polarity) then + write_pointer <= 0; + elsif (rising_edge(clk_sys)) then + if (write = '1') then + write_pointer <= write_pointer_nxt; + end if; + end if; + end process; + + + read_ptr_proc : process(clk_sys, res_n) + begin + if (res_n = reset_polarity) then + read_pointer <= 0; + elsif (rising_edge(clk_sys)) then + if (read = '1') then + read_pointer <= read_pointer_nxt; + end if; + end if; + end process; + + + ---------------------------------------------------------------------------- + -- Storing data to FIFO. + ---------------------------------------------------------------------------- + tx_cache_mem_proc : process(clk_sys, res_n) + begin + if (res_n = reset_polarity) then + tx_cache_mem <= (OTHERS => tx_cache_res_val); + elsif (rising_edge(clk_sys)) then + if (write = '1') then + tx_cache_mem(write_pointer) <= data_in; + end if; + end if; + end process; + + + ---------------------------------------------------------------------------- + -- Reading data from FIFO combinationally. + -- We need to have the data available right away, not pipelined! + ---------------------------------------------------------------------------- + data_out <= tx_cache_mem(read_pointer); + + + ---------------------------------------------------------------------------- + ---------------------------------------------------------------------------- + -- Assertions on input signals + ---------------------------------------------------------------------------- + ---------------------------------------------------------------------------- + + ---------------------------------------------------------------------------- + -- Monitor overflow of both pointers (as if highest bit), and check that: + -- 1. There is no read when FIFO is empty + -- 2. It never happends that FIFO is full and write occurs, this is + -- failure, since design does not have this control and would corrupt + -- previous data. This is not expected to happend since 8 bits in FIFO + -- means de-facto 8 bits on the fly on CAN Bus. This is crazy and no + -- one will ever use it! Just in case something like this happends be + -- sure that it is caught in simulation... + ---------------------------------------------------------------------------- + -- pragma translate_off + assert_proc : process + variable write_ptr_higher : boolean := true; + variable cache_full : boolean := false; + variable cache_empty : boolean := false; + begin + wait until rising_edge(clk_sys); + + -- Write overflows -> Write is now under read + if (write = '1' and write_pointer = tx_cache_depth - 1) then + write_ptr_higher := false; + end if; + + -- Read overflows -> Read is now under write + if (read = '1' and read_pointer = tx_cache_depth - 1) then + write_ptr_higher := true; + end if; + + -- Find out if cache is full or empty! + if (read_pointer = write_pointer) then + if (write_ptr_higher) then + cache_full := true; + else + cache_empty := true; + end if; + end if; + + -- Check that if FIFO is empty no read occurs + -- if (cache_empty and read = '1') then + -- report "Should not read from empty TX Data cache -> BUG!" + -- severity failure; + -- end if; + + -- Check that if FIFO is full no write occurs + -- if (cache_full and read = '1') then + -- report "Should not write to full TX Data cache -> BUG!" + -- severity failure; + -- end if; + end process; + -- pragma translate_on + + +end architecture; diff --git a/src/lib/can_components.vhd b/src/lib/can_components.vhd index 6bcf793041aa6a0d0c4f0ee9b32494132cd9b035..f9f95583c0cd20b4596c55589a765b6df4c6acae 100644 --- a/src/lib/can_components.vhd +++ b/src/lib/can_components.vhd @@ -755,6 +755,26 @@ package can_components is end component; + ---------------------------------------------------------------------------- + -- TX Data cache + ---------------------------------------------------------------------------- + component tx_data_cache is + generic( + constant reset_polarity : std_logic; + constant tx_cache_depth : natural range 4 to 32 := 8; + constant tx_cache_res_val : std_logic + ); + port( + signal clk_sys :in std_logic; + signal res_n :in std_logic; + signal write :in std_logic; + signal read :in std_logic; + signal data_in :in std_logic; + signal data_out :out std_logic + ); + end component; + + ---------------------------------------------------------------------------- -- Data edge detector ----------------------------------------------------------------------------