From 010cd4976a44bf214bb517fc848ac4cbbc1d8631 Mon Sep 17 00:00:00 2001 From: "Ille, Ondrej, Ing" Date: Wed, 16 Jan 2019 22:44:49 +0100 Subject: [PATCH] design: replace tx_data shift reg with fifo cache. Implement TX Data Cache (FIFO like). TX Data are stored at the time of regular sample point and read at the time of secondary sample point. Signed-off-by: Ille, Ondrej, Ing --- src/bus_sampling/bus_sampling.vhd | 61 +++----- src/bus_sampling/tx_data_cache.vhd | 238 +++++++++++++++++++++++++++++ src/lib/can_components.vhd | 20 +++ 3 files changed, 283 insertions(+), 36 deletions(-) create mode 100644 src/bus_sampling/tx_data_cache.vhd diff --git a/src/bus_sampling/bus_sampling.vhd b/src/bus_sampling/bus_sampling.vhd index a9cc7c6d..71b211af 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 00000000..1f7268d0 --- /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 6bcf7930..f9f95583 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 ---------------------------------------------------------------------------- -- GitLab