rx_buffer.vhd 42.3 KB
Newer Older
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
1
--------------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
2
-- 
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
3
-- CTU CAN FD IP Core
4
-- Copyright (C) 2015-2018
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
5
-- 
6 7
-- Authors:
--     Ondrej Ille <ondrej.ille@gmail.com>
8
--     Martin Jerabek <martin.jerabek01@gmail.com>
9 10
-- 
-- Project advisors: 
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
11 12
-- 	Jiri Novak <jnovak@fel.cvut.cz>
-- 	Pavel Pisa <pisa@cmp.felk.cvut.cz>
13
-- 
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
14 15 16 17
-- Department of Measurement         (http://meas.fel.cvut.cz/)
-- Faculty of Electrical Engineering (http://www.fel.cvut.cz)
-- Czech Technical University        (http://www.cvut.cz/)
-- 
18 19 20 21 22
-- 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
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
23 24
-- Component is furnished to do so, subject to the following conditions:
-- 
25
-- The above copyright notice and this permission notice shall be included in
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
26 27
-- all copies or substantial portions of the Component.
-- 
28 29 30 31
-- 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
32
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
33
-- FROM, OUT OF OR IN CONNECTION WITH THE COMPONENT OR THE USE OR OTHER DEALINGS
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
34 35
-- IN THE COMPONENT.
-- 
36 37
-- 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
38
-- protocol license from Bosch.
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
39
-- 
40 41 42
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
43 44
-- Module:
--  RX Buffer
45
--
46 47 48 49 50 51
-- Purpose:
--  Stores RX CAN frame during its reception into RX Buffer RAM. Controlled by
--  Protocol control FSM. RX Frame is read word by word from Memory registers. 
--  RX Buffer is continously stored as it is being received. At the end of frame
--  it is committed to memory, and becomes available to the user. If Overrun
--  or Release receive Buffer occured meanwhile, frame is reverted.
52
--------------------------------------------------------------------------------
53

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
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.reduce_lib.all;

use work.CAN_FD_register_map.all;
use work.CAN_FD_frame_format.all;
70

71
entity rx_buffer is
72
    generic(
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
73 74 75 76 77
        -- Reset polarity
        G_RESET_POLARITY            :       std_logic := '0';
        
        -- RX Buffer size
        G_RX_BUFF_SIZE              :       natural range 32 to 4096 := 32
78 79 80
    );
    port(
        ------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
81
        -- Clocks and Asynchronous reset 
82
        ------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
83 84
        -- System clock
        clk_sys              :in     std_logic;
85
        
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
86 87
        -- Async. reset
        res_n                :in     std_logic;
88

89
        ------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
90
        -- Metadata from CAN Core
91
        ------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
92
        -- Frame Identifier
93
        rec_ident            :in     std_logic_vector(28 downto 0);
94
        
95
        -- Data length code
96
        rec_dlc              :in     std_logic_vector(3 downto 0);
97
        
98
        -- Recieved identifier type (0-BASE Format, 1-Extended Format);
99
        rec_ident_type       :in     std_logic;
100
        
101
        -- Recieved frame type (0-Normal CAN, 1- CAN FD)
102
        rec_frame_type       :in     std_logic;
103
        
104
        -- Recieved frame is RTR Frame(0-No, 1-Yes)
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
105
        rec_is_rtr           :in     std_logic;
106
        
107
        -- Whenever frame was recieved with BIT Rate shift 
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
108
        rec_brs              :in     std_logic;
109 110

        -- Recieved error state indicator
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
111
        rec_esi              :in     std_logic;
112

Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
113
        ------------------------------------------------------------------------
114
        -- Control signals from CAN Core which control storing of CAN Frame.
115
        -- (Filtered by Frame Filters)
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
116
        ------------------------------------------------------------------------
117 118
        -- After control field of CAN frame, metadata are valid and can be stored.
        -- This command starts the RX FSM for storing.
119
        store_metadata_f     :in     std_logic;
120 121 122 123 124
       
        -- Signal that one word of data can be stored (TX_DATA_X_W). This signal
        -- is active when 4 bytes were received or data reception has finished 
        -- on 4 byte unaligned number of frames! (Thus allowing to store also
        -- data which are not 4 byte aligned!
125
        store_data_f         :in     std_logic;
126 127

        -- Data word which should be stored when "store_data" is active!
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
128
        store_data_word      :in     std_logic_vector(31 downto 0);
129

Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
130
        -- Received frame valid (commit RX Frame)
131
        rec_valid_f          :in     std_logic;
132
        
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
133
        -- Abort storing of RX Frame to RX Buffer.
134
        rec_abort_f          :in     std_logic;
135 136 137

        -- Signals start of frame. If timestamp on RX frame should be captured
        -- in the beginning of the frame, this pulse captures the timestamp!
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
138
        sof_pulse            :in     std_logic;
139

Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
140
        -----------------------------------------------------------------------
141
        -- Status signals of RX buffer
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
142
        -----------------------------------------------------------------------
143
        -- Actual size of synthetised message buffer (in 32 bit words)
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
144
        rx_buf_size          :out    std_logic_vector(12 downto 0);
145
        
146
        -- Signal whenever buffer is full (no free memory words)
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
147
        rx_full              :out    std_logic;
148
        
149
        -- Signal whenever buffer is empty (no frame (message) is stored)
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
150
        rx_empty             :out    std_logic;
151 152
        
        -- Number of frames (messages) stored in recieve buffer
153
        rx_frame_count       :out    std_logic_vector(10 downto 0);
154 155
        
        -- Number of free 32 bit wide words
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
156
        rx_mem_free          :out    std_logic_vector(12 downto 0);
157 158
        
        -- Position of read pointer
159
        rx_read_pointer      :out    std_logic_vector(11 downto 0);
160 161
        
        -- Position of write pointer
162
        rx_write_pointer     :out    std_logic_vector(11 downto 0);
163 164 165
        
        -- Overrun occurred, data were discarded!
        -- (This is a flag and persists until it is cleared by SW)! 
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
166
        rx_data_overrun      :out    std_logic;
167 168
        
        -- External timestamp input
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
169
        timestamp            :in     std_logic_vector(63 downto 0);
170

Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
171 172 173
        -----------------------------------------------------------------------
        -- Memory registers interface
        -----------------------------------------------------------------------
174
        -- Actually loaded data for reading
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
175
        rx_read_buff         :out    std_logic_vector(31 downto 0);
176 177
        
        -- Driving bus from registers
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
178
        drv_bus              :in     std_logic_vector(1023 downto 0)
179
    );
180 181 182
end entity;

architecture rtl of rx_buffer is
183 184

    ----------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
185
    -- Driving bus aliases
186
    ----------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
187
    
188 189 190 191 192 193 194 195 196 197 198 199 200 201
    -- Erase command from driving registers. Resets FIFO pointers!
    signal drv_erase_rx             :       std_logic;

    -- Command to load increase the reading pointer
    signal drv_read_start           :       std_logic;

    -- Clear data OverRun Flag
    signal drv_clr_ovr              :       std_logic;

    -- Receive Timestamp options
    signal drv_rtsopt               :       std_logic;


    ----------------------------------------------------------------------------
202
    -- FIFO  Memory - Pointers
203
    ----------------------------------------------------------------------------
204
        
205
    -- Read Pointer (access from SW)
206
    signal read_pointer             : std_logic_vector(11 downto 0);
207

208
    -- Read pointer incremented by 1 (combinationally)
209
    signal read_pointer_inc_1       : std_logic_vector(11 downto 0);
210

211
    -- Write pointer (committed, available to SW, after frame was stored)
212
    signal write_pointer            : std_logic_vector(11 downto 0);
213 214 215 216

    -- Write pointer RAW. Changing during frame, as frame is continously stored
    -- to the buffer. When frame is sucesfully received, it is updated to
    -- write pointer!
217
    signal write_pointer_raw        : std_logic_vector(11 downto 0);
218

219
    -- Timestamp write pointer which is used for storing timestamp at the end of
220
    -- data frame!
221
    signal write_pointer_ts         : std_logic_vector(11 downto 0);
222

223 224
    -- Number of free memory words available to SW after frame was committed.
    signal rx_mem_free_i            : std_logic_vector(12 downto 0);
225 226

    -- Data that will be written to the RX Buffer memory!
227
    signal memory_write_data        : std_logic_vector(31 downto 0);
228

229 230 231
    -- RX Buffer mem free
    constant C_RX_BUF_MEM_FREE_ZEROES : std_logic_vector(12 downto 0) :=
        (OTHERS => '0');
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
232

233 234
    constant C_RX_BUF_PTR_ZEROES : std_logic_vector(11 downto 0) :=
        (OTHERS => '0');
235 236 237 238 239 240 241

    ----------------------------------------------------------------------------
    -- FIFO  Memory - Free words, Overrun status
    ----------------------------------------------------------------------------

    -- Data overrun flag. Recieved message was lost, because there was not
    -- enough space in FIFO during storing! Available for SW!
242
    signal data_overrun_flg           :       std_logic;
243 244 245 246

    -- Internal data overrun flag. This flag is not available to SW, but it
    -- is restarted automatically at the beginning of each new frame reception!
    -- This allows to accept next frames when overrun occurred on previous ones!
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
247
    signal data_overrun_i           :       std_logic;
248 249 250

    -- Combinationally decoded overrun condition. Active when there is intention
    -- to store word to the memory, but there is not enough free space! 
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
251
    signal overrun_condition        :       std_logic;
252 253

     -- RX Buffer is empty (no frame is stored in it)
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
254
    signal rx_empty_i               :       std_logic;
255 256

    -- Indicator of at least one free word in RX FIFO!
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
257
    signal is_free_word             :       std_logic;
258 259 260

    -- Number of frames currently stored in RX Buffer. Smallest frame length
    -- stored is 4 (FRAME_FORMAT +  IDENTIFIER + 2 * TIMESTAMP). Since we need
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
261 262
    -- to store 0 and also G_RX_BUFF_SIZE / 4 values we need one value more than can
    -- fit into G_RX_BUFF_SIZE / 4 width counter. Use one bit wider counter.
263
    signal frame_count              :       natural range 0 to (G_RX_BUFF_SIZE / 2) - 1; 
264 265 266

    -- Counter for reading the frame. When whole frame is read,
    -- number of frames must be decremented.
267 268
    signal read_counter_d           :       unsigned(4 downto 0);
    signal read_counter_q           :       unsigned(4 downto 0);
269 270 271 272 273 274


    ----------------------------------------------------------------------------
    -- FIFO  Memory - Commands which manipulate pointers, or indicate intent
    --  to write or read from the memory.
    ----------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
275 276
    
    -- When commit of RX Frame is signalled by CAN Core (rec_valid)
277
    -- "commit_rx_frame" is set to indicate that frame was sucesfully
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
278
    -- stored. Note that "rec_valid" is not enough to indicate that
279 280
    -- frame was stored sucesfully! If frame storing fails at some point due
    -- to lack of memory in FIFO, Protocol control will still finish the frame
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
281
    -- and provide "rec_valid"! Thus RX FSM sets "commit_rx_frame" only
282 283 284
    -- if "data_overrun" did not occur during the frame!
    signal commit_rx_frame          :       std_logic;

285 286 287 288 289
    -- When overrun occurred at any point in the frame and some word was not
    -- stored, frame can not be committed, and write_pointer must be moved
    -- back to last committed value!
    signal commit_overrun_abort     :       std_logic;

290 291
    -- Indicates that read occurred, and that it is valid (there is something
    -- to read), thus read pointer can be incremented.
292
    signal read_increment           :       std_logic;
293 294 295

    -- Indicates that "write_raw_intent" is OK (no overrun) and data can be
    -- truly written to the memory and raw pointer can be updated!
296 297 298 299 300 301
    signal write_raw_OK             :       std_logic;


    ----------------------------------------------------------------------------
    -- RX Buffer FSM outputs
    ----------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
302
    
303 304 305
    -- Indicates that FSM is in a state which would like to perform write of a
    -- word to RX Buffer memory!
    signal write_raw_intent         :       std_logic;
306

307 308
    -- Indicates that FSM is in one of states for writing timestamp
    signal write_ts                 :       std_logic;
309

310 311
    -- Storing of timestamp is at the end.
    signal stored_ts                :       std_logic;
312 313

    -- Data write selector
314
    signal data_selector            :       std_logic_vector(4 downto 0);
315

316 317
    -- Signals that write pointer should be stored to timestamp write pointer
    signal store_ts_wr_ptr          :       std_logic;
318

319 320
    -- Increment timestamp write pointer
    signal inc_ts_wr_ptr            :       std_logic;
321 322 323

    -- Restart overrun flag upon start of new frame
    signal reset_overrun_flag       :       std_logic;
324 325 326 327 328


    ----------------------------------------------------------------------------
    -- RX FSM, Timestamp capturing, combinationally decoded words
    ----------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
329
    
330 331 332 333 334 335 336 337 338 339
    -- Combinationally decoded size of the frame (without Frame format word)
    -- from received DLC (the size is in 32-bit words).
    signal rwcnt_com                :       natural range 0 to 31;

    -- Combinational decoded frame format word from metadata.
    signal frame_form_w             :       std_logic_vector(31 downto 0);

    -- Internal timestamp captured for storing. Captured either in the
    -- beginning or end of frame. 
    signal timestamp_capture        :       std_logic_vector(63 downto 0);
340 341 342
    
    -- Clock enable signal for timestamp capture register 
    signal timestamp_capture_ce     :       std_logic;
343

344

345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
    ----------------------------------------------------------------------------
    -- RAM wrapper signals
    ----------------------------------------------------------------------------
    
    -- Write control signal    
    signal RAM_write                :       std_logic;

    -- Data output from port B     
    signal RAM_data_out             :       std_logic_vector(31 downto 0);

    -- Write address (connected to write pointer)
    signal RAM_write_address        :       std_logic_vector(11 downto 0);

    -- Read address (connected to read pointer)
    signal RAM_read_address         :       std_logic_vector(11 downto 0);

361 362 363 364 365
    ----------------------------------------------------------------------------
    -- Common reset signal
    ----------------------------------------------------------------------------
    signal rx_buf_res_d             :       std_logic;
    signal rx_buf_res_q             :       std_logic;
366
    
367

368 369 370 371 372 373 374 375 376
begin

    ----------------------------------------------------------------------------
    -- Driving bus aliases
    ----------------------------------------------------------------------------
    drv_erase_rx          <= drv_bus(DRV_ERASE_RX_INDEX);
    drv_read_start        <= drv_bus(DRV_READ_START_INDEX);
    drv_clr_ovr           <= drv_bus(DRV_CLR_OVR_INDEX);
    drv_rtsopt            <= drv_bus(DRV_RTSOPT_INDEX);
377

378 379 380 381

    ----------------------------------------------------------------------------
    -- Propagating status registers on output
    ----------------------------------------------------------------------------
382 383 384
    rx_read_pointer      <= read_pointer;
    rx_write_pointer     <= write_pointer;
    rx_data_overrun      <= data_overrun_flg;
385
    rx_buf_size          <= std_logic_vector(to_unsigned(G_RX_BUFF_SIZE, 13));
386

387
    rx_empty_i           <= '1' when (frame_count = 0)
388 389
                                else
                            '0'; 
390

391 392
    rx_full              <= '1' when (rx_mem_free_i = C_RX_BUF_MEM_FREE_ZEROES)
                                else
393
                            '0';
394

395
    rx_frame_count       <= std_logic_vector(to_unsigned(frame_count, 11)); 
396 397
    rx_mem_free          <= rx_mem_free_i;
    rx_empty             <= rx_empty_i;
398

399 400 401 402 403 404
    ----------------------------------------------------------------------------
    -- Common reset signal. Whole buffer can be reset by two ways:
    --  1. Asynchronous reset - res_n
    --  2. Release Receive Buffer command - drv_erase_rx.
    -- To avoid glitches a DFF is inserted after the reset!
    ----------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
405
    rx_buf_res_d <= G_RESET_POLARITY when (drv_erase_rx = '1') else
406 407
                    (not G_RESET_POLARITY);

Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
408 409 410 411 412 413 414 415
    res_reg_inst : dff_arst
    generic map(
        G_RESET_POLARITY   => G_RESET_POLARITY,
        
        -- Reset to the same value as is polarity of reset so that other DFFs
        -- which are reset by output of this one will be reset too!
        G_RST_VAL          => G_RESET_POLARITY
    )
416
    port map(
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
417
        arst               => res_n,                -- IN
418 419
        clk                => clk_sys,              -- IN
        input              => rx_buf_res_d,         -- IN
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
420

421 422
        output             => rx_buf_res_q          -- OUT
    );
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
423
    
424

425 426 427
    ----------------------------------------------------------------------------
    -- RX Buffer FSM component
    ----------------------------------------------------------------------------
428
    rx_buffer_fsm_inst : rx_buffer_fsm
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
429 430 431
    generic map(
        G_RESET_POLARITY    => G_RESET_POLARITY
    )
432
    port map(
433
        clk_sys             => clk_sys,             -- IN
434
        res_n               => res_n,               -- IN
435 436 437
        store_metadata_f    => store_metadata_f,    -- IN
        store_data_f        => store_data_f,        -- IN
        rec_valid_f         => rec_valid_f,         -- IN
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
438
        rec_abort_f         => rec_abort_f,         -- IN
439 440 441
        sof_pulse           => sof_pulse,           -- IN
        
        write_raw_intent    => write_raw_intent,    -- OUT
442 443
        write_ts            => write_ts,            -- OUT
        stored_ts           => stored_ts,           -- OUT
444
        data_selector       => data_selector,       -- OUT
445 446
        store_ts_wr_ptr     => store_ts_wr_ptr,     -- OUT
        inc_ts_wr_ptr       => inc_ts_wr_ptr,       -- OUT
447
        reset_overrun_flag  => reset_overrun_flag   -- OUT
448 449 450 451 452 453
    );


    ----------------------------------------------------------------------------
    -- RX Buffer Memory pointers
    ----------------------------------------------------------------------------
454
    rx_buffer_pointers_inst : rx_buffer_pointers
455
    generic map(
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
456
        G_RESET_POLARITY        => G_RESET_POLARITY,
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
457
        G_RX_BUFF_SIZE          => G_RX_BUFF_SIZE
458 459
    )
    port map(
460
        clk_sys                 => clk_sys,                 -- IN
461
        rx_buf_res_q            => rx_buf_res_q,            -- IN
462
        rec_abort_f             => rec_abort_f,             -- IN
463 464 465
        commit_rx_frame         => commit_rx_frame,         -- IN
        write_raw_OK            => write_raw_OK,            -- IN
        commit_overrun_abort    => commit_overrun_abort,    -- IN
466 467
        store_ts_wr_ptr         => store_ts_wr_ptr,         -- IN
        inc_ts_wr_ptr           => inc_ts_wr_ptr,           -- IN
468 469 470 471 472 473 474
        read_increment          => read_increment,          -- IN
        drv_bus                 => drv_bus,                 -- IN
        
        read_pointer            => read_pointer,            -- OUT
        read_pointer_inc_1      => read_pointer_inc_1,      -- OUT
        write_pointer           => write_pointer,           -- OUT
        write_pointer_raw       => write_pointer_raw,       -- OUT
475
        write_pointer_ts        => write_pointer_ts,        -- OUT
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
476
        rx_mem_free_i           => rx_mem_free_i            -- OUT
477 478
    );

479 480

    ----------------------------------------------------------------------------
481
    -- Memory data which are written depend on state of the FSM
482
    ----------------------------------------------------------------------------
483
    with data_selector select memory_write_data <=
484 485 486 487 488
        frame_form_w                     when "00001",
        "000" & rec_ident                when "00010",
        store_data_word                  when "00100",
        timestamp_capture(31 downto 0)   when "01000",
        timestamp_capture(63 downto 32)  when "10000",
489
        (OTHERS => '0')                  when others;
490

491 492 493 494

    ----------------------------------------------------------------------------
    -- Signalling that read which came is valid (there is sth to read)
    ----------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
495 496
    read_increment <= '1' when (drv_read_start = '1' and rx_empty_i = '0') else
                      '0';
497 498 499 500 501

    ----------------------------------------------------------------------------
    -- Signalling that FSM may progress with the write (there is enough space
    -- in the buffer, nor any previous data were lost due to overrun)
    ----------------------------------------------------------------------------
502
    write_raw_OK         <= '1' when (write_raw_intent = '1' and
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
503 504
                                       overrun_condition = '0' and
                                       data_overrun_i = '0')
505 506
                                else
                            '0';
507 508

    ----------------------------------------------------------------------------
509 510 511 512 513 514
    -- Store of new word can be executed only if there is space in the buffer.
    -- We don't need exact amount of words. We only need to know if there is
    -- space! When "read_pointer" and "write_pointer_raw" are equal, then 
    -- memory is either empty, or full! If there is no frame stored and pointers
    -- are equal, then memory is empty! If there is at least one frame and
    -- pointers are equal, then memory must be full!
515
    ----------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
516
    is_free_word          <= '0' when (read_pointer = write_pointer_raw and
517
                                       frame_count > 0)
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
518 519
                                 else
                             '1';
520 521 522 523

    ----------------------------------------------------------------------------
    -- Overrun condition. Following conditions must be met:
    --  1. FSM wants to write to memory either to the position of
524
    --      "write_pointer_raw". Note that "write_pointer_ts" writes to
525 526 527 528
    --      words which were already written, thus there is no need to watch
    --      for overrun!
    --  2. There is no free word in the memory remaining!
    ----------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
529 530 531 532
    overrun_condition <= '1' when (write_raw_intent = '1' and 
                                  (is_free_word = '0'))
                             else
                         '0';
533 534 535 536 537 538


    ----------------------------------------------------------------------------
    -- When buffer is empty the word on address of read pointer is not valid,
    -- provide zeroes instead
    ----------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
539 540
    rx_read_buff <= RAM_data_out when (rx_empty_i = '0') else
                    (OTHERS => '0');
541 542 543 544 545


    ----------------------------------------------------------------------------
    -- Receive data size (in words) decoder
    ----------------------------------------------------------------------------
546
    with rec_dlc select rwcnt_com <=
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568
        3 when "0000", --Zero bits
        4 when "0001", --1 byte
        4 when "0010", --2 bytes
        4 when "0011", --3 bytes
        4 when "0100", --4 bytes
        5 when "0101", --5 bytes
        5 when "0110", --6 bytes
        5 when "0111", --7 bytes
        5 when "1000", --8 bytes
        6 when "1001", --12 bytes
        7 when "1010", --16 bytes
        8 when "1011", --20 bytes
        9 when "1100", --24 bytes
        11 when "1101", --32 bytes
        15 when "1110", --48 bytes
        19 when "1111", --64 bytes
        0  when others;


    ----------------------------------------------------------------------------
    -- Frame format word assignment
    ----------------------------------------------------------------------------
569
    frame_form_w(DLC_H downto DLC_L)      <= rec_dlc;
570 571
    frame_form_w(4)                       <= '0';
    frame_form_w(RTR_IND)                 <= rec_is_rtr;
572 573
    frame_form_w(IDE_IND)                 <= rec_ident_type;
    frame_form_w(FDF_IND)                 <= rec_frame_type;
574
    frame_form_w(8)                       <= '1'; -- Reserved
575
    frame_form_w(BRS_IND)                 <= rec_brs;
576 577
    frame_form_w(ESI_RSV_IND)             <= rec_esi;

578 579 580 581 582 583 584 585 586

    ----------------------------------------------------------------------------
    -- RWCNT (Read word count is calculated like so:
    --  1. For RTR Frames -> 3 (Only ID + 2 Timestamp words)
    --  2. For Normal CAN Frames with DLC > 8 max. 8 bytes -> RWCNT = 5
    --  3. Otherwise Number of data bytes is matching Received DLC!
    ----------------------------------------------------------------------------
    frame_form_w(RWCNT_H downto RWCNT_L)  <=
        "00011" when (rec_is_rtr = RTR_FRAME) else
587
        "00101" when ((rec_frame_type = NORMAL_CAN) and (rec_dlc(3) = '1')) else
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
588
         std_logic_vector(to_unsigned(rwcnt_com, (RWCNT_H - RWCNT_L + 1)));
589 590 591 592 593 594 595 596

    frame_form_w(31 downto 16)            <= (OTHERS => '0');


    ----------------------------------------------------------------------------
    -- Capturing timestamp. Done at the beginning or end of frame based on
    -- SW configuration.
    ----------------------------------------------------------------------------
597 598 599 600 601 602
    timestamp_capture_ce <= '1' when (drv_rtsopt = RTS_END and rec_valid_f = '1')
                                else
                            '1' when (drv_rtsopt = RTS_BEG and sof_pulse = '1')
                                else
                            '0';
                            
603 604
    capt_ts_proc : process(clk_sys, res_n)
    begin
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
605
        if (res_n = G_RESET_POLARITY) then
606 607
            timestamp_capture       <= (OTHERS => '0');
        elsif (rising_edge(clk_sys)) then
608
            if (timestamp_capture_ce = '1') then
609 610 611 612 613 614 615
                timestamp_capture   <= timestamp;
            end if;
        end if;
    end process;


    ----------------------------------------------------------------------------
616
    -- Reading counter (read_counter_q) which is loaded by RWCNT during read
617 618
    -- of frame format word. Then each next read decreases the counter. When 
    -- read counter reaches zero, message count is decreased. If "commit_rx_frame" 
619 620
    -- comes, "frame_count" is incremented. If both occur at the same time
    -- , "frame_count" does not change.
621
    ----------------------------------------------------------------------------
622 623 624
    
    ---------------------------------------------------------------------------
    -- During the read of FRAME_FORMAT word store the length of the frame to
625 626
    -- "read_counter", thus we know how much we have to read before 
    -- decrementing the "frame_count".
627
    ---------------------------------------------------------------------------
628 629
    read_counter_d <= read_counter_q - 1 when (read_counter_q > "00000") else
                      unsigned(RAM_data_out(RWCNT_H downto RWCNT_L));
630
    
631
    read_frame_proc : process(clk_sys, rx_buf_res_q)
632
    begin
633
        if (rx_buf_res_q = G_RESET_POLARITY) then
634
            read_counter_q <= (OTHERS => '0');
635 636 637

        elsif (rising_edge(clk_sys)) then

638 639 640 641
            --------------------------------------------------------------------
            -- Reading frame by user when there is active read and there is
            -- something to read
            --------------------------------------------------------------------
642
            if (read_increment = '1') then
643
                read_counter_q <= read_counter_d;
644
            end if;
645 646 647 648
        end if;    
    end process;


649
    ---------------------------------------------------------------------------
650 651
    -- Manipulation of "frame_count". When last word is read from frame
    -- (read_counter_q = 1 and read_increment), "frame_count" is
652 653 654 655
    -- decreased, when new frame is committed, message count is increased.
    -- If both at the same time, no change since one frame is added, next is 
    -- removed!
    ---------------------------------------------------------------------------
656
    frame_count_ctr_proc : process(clk_sys, rx_buf_res_q)
657
    begin
658
        if (rx_buf_res_q = G_RESET_POLARITY) then
659
            frame_count <= 0;
660

661
        elsif (rising_edge(clk_sys)) then
662

663
            -- Read of last word, but no new commit
664
            if ((read_increment = '1') and (read_counter_q = "00001")) then
665
                if (commit_rx_frame = '0') then
666
                    frame_count           <= frame_count - 1;
667 668
                end if;

669 670
            -- Commit of new frame
            elsif (commit_rx_frame = '1') then
671
                frame_count               <= frame_count + 1;
672
            end if;
673 674 675

        end if;
    end process;
676
    
677 678 679 680 681

    ----------------------------------------------------------------------------
    -- Commit RX Frame when last word was written and overrun did not occur!
    -- This can be either from "rxb_store_data" state or "rxb_store_end_ts_high"
    ----------------------------------------------------------------------------
682
    commit_proc : process(clk_sys, rx_buf_res_q)
683
    begin
684
        if (rx_buf_res_q = G_RESET_POLARITY) then
685 686
            commit_rx_frame       <= '0';
            commit_overrun_abort  <= '0';
687 688 689

        elsif (rising_edge(clk_sys)) then

690
            if (stored_ts = '1') then
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
691
                if (data_overrun_i = '0') then
692 693 694 695
                    commit_rx_frame         <= '1';
                else
                    commit_overrun_abort    <= '1';
                end if;
696
            else
697 698
                commit_rx_frame             <= '0';
                commit_overrun_abort        <= '0';
699 700 701 702 703 704 705
            end if;

        end if;
    end process;


    ----------------------------------------------------------------------------
706 707 708 709
    -- Calculation of data overrun flag for user. If FSM would like to write to
    -- the memory, and there is not enough free space, data overrun flag will be
    -- set, and no further writes will be executed. Data Overrun flag can be
    -- cleared from Memory registers via Driving bus.
710
    ----------------------------------------------------------------------------
711
    sw_dor_proc : process(clk_sys, rx_buf_res_q)
712
    begin
713
        if (rx_buf_res_q = G_RESET_POLARITY) then
714
            data_overrun_flg      <= '0';
715
            
716 717 718 719 720 721
        elsif (rising_edge(clk_sys)) then

            --------------------------------------------------------------------
            -- SW overrun flag -> Cleared from SW!
            --------------------------------------------------------------------
            if (drv_clr_ovr = '1') then
722
                data_overrun_flg  <= '0';
723
 
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
724
            elsif (overrun_condition = '1') then
725
                data_overrun_flg  <= '1';
726
            else
727
                data_overrun_flg  <= data_overrun_flg;
728 729 730 731
            end if;

        end if;
    end process;
732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752
    
    ----------------------------------------------------------------------------
    -- Internal data overrun flag. This will be set by two conditions:
    --  1. When FSM attempts to write to full RAM.
    --  2. When RRB command is issued and frame storing is in progress! If such
    --     situation occurs, pointers are erased RX Buffer FSM is erased, while
    --     Protocol control continues storing the frame (increments Raw write
    --     pointer). Commiting such a frame would result in inconsistend state
    --     of RX Buffer. So if RRB during storing occurs, all pointers are 
    --     erased, RX Buffer FSM keeps storing, and overrun flag is set. At the
    --     end of storing, flag is erased and raw write pointer is reverted to
    --     commited pointer (which is zero because it was erased).
    -- 
    -- Cleared at the end of frame storing! Note that this register can't be
    -- reset by RRB, only by res_n! 
    ----------------------------------------------------------------------------
    internal_dor_proc : process(clk_sys, res_n)
    begin
        if (res_n = G_RESET_POLARITY) then
            data_overrun_i        <= '0';
        elsif (rising_edge(clk_sys)) then
753
            if (overrun_condition = '1' or drv_erase_rx = '1') then
754
                data_overrun_i    <= '1';
755 756
            elsif (reset_overrun_flag = '1') then
                data_overrun_i    <= '0';
757 758 759 760 761
            else
                data_overrun_i    <= data_overrun_i;
            end if;
        end if;
    end process;
762 763 764


    ----------------------------------------------------------------------------
765 766
    -- RAM Memory of RX Buffer
    ----------------------------------------------------------------------------
767 768 769 770
    rx_buffer_ram_inst : rx_buffer_ram
    generic map(
        G_RESET_POLARITY     => G_RESET_POLARITY,
        G_RX_BUFF_SIZE       => G_RX_BUFF_SIZE
771 772
    )
    port map(
773
        -- Clocks and Asynchronous reset 
774 775
        clk_sys              => clk_sys,                -- IN
        res_n                => res_n,                  -- IN
776 777

        -- Port A - Write (from CAN Core)
778 779 780
        port_a_address       => RAM_write_address,      -- IN
        port_a_data_in       => memory_write_data,      -- IN
        port_a_write         => RAM_write,              -- IN
781 782

        -- Port B - Read (from Memory registers)
783 784
        port_b_address       => RAM_read_address,       -- IN
        port_b_data_out      => RAM_data_out            -- OUT
785
    );
786

787
    -- Memory written either on regular write or timestamp write
788
    RAM_write  <= '1' when (write_raw_OK = '1' or
789
                           (write_ts = '1' and data_overrun_i = '0' and
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
790
                            overrun_condition = '0'))
791 792
                      else
                  '0';
793

794 795
    ----------------------------------------------------------------------------
    -- Memory write address is multiplexed between "write_pointer_raw" for
796
    -- regular writes and "write_pointer_ts" for writes of timestamp!
797
    ----------------------------------------------------------------------------
798
    RAM_write_address   <= write_pointer_ts when (write_ts = '1') else
799
                           write_pointer_raw;
800

801 802 803 804 805 806
    ----------------------------------------------------------------------------
    -- RAM read address is given by read pointers. If no transaction for read
    -- of RX DATA is in progress, read pointer is given by its real value.
    -- During transaction, Incremented Read pointer is chosen to avoid one clock
    -- cycle delay caused by increment on read pointer!
    ----------------------------------------------------------------------------
807 808 809
    RAM_read_address <= read_pointer_inc_1 when (read_increment = '1') else
                              read_pointer;
                              
810 811 812 813 814 815

    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- Assertions
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
816

817

818 819 820 821 822
    ----------------------------------------------------------------------------
    -- RX Buffer size can be only powers of 2. Since modulo arithmetics is used
    -- on memory pointers, using non power of 2 value would result in increased
    -- logic usage!
    ----------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
823 824 825 826 827 828 829 830
    assert ((G_RX_BUFF_SIZE = 32) or
            (G_RX_BUFF_SIZE = 64) or
            (G_RX_BUFF_SIZE = 128) or
            (G_RX_BUFF_SIZE = 256) or
            (G_RX_BUFF_SIZE = 512) or
            (G_RX_BUFF_SIZE = 1024) or
            (G_RX_BUFF_SIZE = 2048) or
            (G_RX_BUFF_SIZE = 4096))
831
    report "Unsupported RX Buffer size! RX Buffer must be power of 2!"
832
        severity failure;
833

834
    -- <RELEASE_OFF>
835 836 837 838 839 840 841

    ----------------------------------------------------------------------------
    -- Storing sequence is like so:
    --  1. Store metadata.
    --  2. Store data "n" times, n = ceil(data_length / 4). De-facto RWCNT field
    --     contains number of remaining words (apart from FRAME_FORMAT_W). Thus,
    --     RWCNT - 3 = number of expected data words.
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
842
    --  3. Get "rec_abort" or "rec_valid" command.
843 844 845 846 847
    --
    --  This process verifies that "rec_data" command comes expected number of
    --  times (RWCNT - 3). This verifies consistency of storing protocol by
    --  CAN Core, as well as RWCNT field! 
    ----------------------------------------------------------------------------
848
    -- pragma translate_off
849 850 851 852
    rwcnt_assert_proc : process(clk_sys)
        variable exp_data_stores    : natural := 0;
        variable act_data_stores   : natural := 0;
    begin
853
        if (rising_edge(clk_sys) and now /= 0 fs) then
854 855

            -- Calculate number of expected "store_data" commands from CAN Core.
856
            if (rec_abort_f = '1') then
857 858 859
                exp_data_stores := 0;
                act_data_stores := 0;

860
            elsif (store_metadata_f = '1') then
861 862 863 864 865 866 867

                exp_data_stores := to_integer(unsigned(
                                    frame_form_w(RWCNT_H downto RWCNT_L))) - 3;
                act_data_stores := 0;
            end if;

            -- Count actual number of "store_data" commands.
868
            if (store_data_f = '1') then
869 870 871 872 873
                act_data_stores := act_data_stores + 1;
            end if;

            -- Check when frame was received that proper number of "store_data"
            -- commands did arrive.
874
            if (rec_valid_f = '1' and 
875 876 877 878 879 880 881 882 883
                act_data_stores /= exp_data_stores)
            then
                report "'store_data' count corrupted by CAN Core! " &
                       "Expected: " & integer'image(exp_data_stores) &
                       "  Actual: " & integer'image(act_data_stores)
                severity error;
            end if;
        end if;
    end process;
884
    -- pragma translate_on
885 886


887 888 889 890 891 892 893 894 895
    ----------------------------------------------------------------------------
    -- Assertions
    ----------------------------------------------------------------------------
    -- psl default clock is rising_edge(clk_sys);
    
    -- psl read_counter_lt_rwcnt_asrt : assert never
    --  (read_counter_q > 19)
    -- report "Read counter higher than longest RWCNT!"
    -- severity error;
896 897 898 899 900 901 902
    
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- Functional coverage
    ----------------------------------------------------------------------------
    ----------------------------------------------------------------------------
    -- psl rx_buf_empty_cov : 
903
    --      cover {rx_empty = '1'};
904 905 906 907 908
    --
    -- psl rx_buf_not_empty_to_empty_cov :
    --      cover {rx_empty = '0'; rx_empty = '1'};
    --
    -- psl rx_buf_rx_full_cov :
909
    --      cover {rx_full = '1'};
910 911 912 913 914
    -- 
    -- psl rx_buf_rx_full_to_not_full_cov :
    --      cover {(rx_full = '1'); (rx_full = '0')};
    --
    -- psl rx_buf_overrun_cov :
915
    --      cover {overrun_condition = '1'};
916 917
    --
    -- psl rx_buf_commit_overrun_abort_cov :
918
    --      cover {commit_overrun_abort = '1'};
919 920
    --
    -- psl rx_buf_overrun_flags_cov :
921
    --      cover {data_overrun_i = '1' and data_overrun_flg = '1'};
922 923
    --
    -- psl rx_buf_overrun_clear_cov :
924
    --      cover {drv_clr_ovr = '1'};
925
    --
926
    -- psl rx_buf_write_ts_cov :
927
    --      cover {write_ts = '1'};
928 929
    -- 
    -- psl rx_buf_release_receive_buffer_cov :
930
    --      cover {drv_erase_rx = '1'}; 
Ille, Ondrej, Ing.'s avatar