rx_buffer_fsm.vhd 13.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
--------------------------------------------------------------------------------
-- 
-- CTU CAN FD IP Core
-- Copyright (C) 2015-2018
-- 
-- Authors:
--     Ondrej Ille <ondrej.ille@gmail.com>
--     Martin Jerabek <martin.jerabek01@gmail.com>
-- 
-- Project advisors: 
-- 	Jiri Novak <jnovak@fel.cvut.cz>
-- 	Pavel Pisa <pisa@cmp.felk.cvut.cz>
-- 
-- 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.
-- 
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
43 44 45
-- Module:
--  RX Buffer FSM.
-- 
46
-- Purpose:
47 48
--  Reacts on commands from CAN Core and controls storing of CAN frame 
--  continusly to RX Buffer RAM.
49 50
--------------------------------------------------------------------------------

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
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;
67 68

entity rx_buffer_fsm is
69 70 71
    generic(
        G_RESET_POLARITY     :       std_logic := '0'
    );
72 73
    port(
        ------------------------------------------------------------------------
74
        -- Clocks and reset 
75
        ------------------------------------------------------------------------
76 77 78
        -- System clock
        clk_sys              :in     std_logic;
        
79 80
        -- Asynchronous reset
        res_n                :in     std_logic;
81 82

        ------------------------------------------------------------------------
83
        -- Control signals from CAN Core (Filtered by Frame filters)
84
        ------------------------------------------------------------------------
85
        -- Start Storing of Metadata to RX Buffer (first 4 words of frame)
86
        store_metadata_f     :in     std_logic;
87
       
88
        -- Store Data word to RX Buffer
89
        store_data_f         :in     std_logic;
90 91

        -- Received frame valid
92
        rec_valid_f          :in     std_logic;
93
        
94
        -- Abort storing of RX Frame to RX Buffer.
95
        rec_abort_f          :in     std_logic;
96 97 98

        -- Start of Frame pulse
        sof_pulse            :in     std_logic;
99

100
        -----------------------------------------------------------------------
101
        -- FSM outputs
102
        -----------------------------------------------------------------------
103
        -- Intent to write to RX Buffer RAM
104
        write_raw_intent     :out    std_logic;
105

106 107
        -- Write Timestamp to RX Buffer RAM memory
        write_ts             :out    std_logic;
108

109 110
        -- Storing of Timestamp has ended.
        stored_ts            :out    std_logic;
111

112 113
        -- Data selector for selection of memory word to be stored in RX Buffer 
        -- RAM (one hot coded)
114
        data_selector        :out    std_logic_vector(4 downto 0);
115

116 117
        -- Load timestamp write pointer from regular write pointer
        store_ts_wr_ptr      :out    std_logic;
118

119 120
        -- Increment timestamp write pointer by 1
        inc_ts_wr_ptr        :out    std_logic;
121 122

        -- Reset internal overrun flag
123
        reset_overrun_flag   :out    std_logic
124 125 126 127 128
    );
end entity;

architecture rtl of rx_buffer_fsm is

129 130 131 132 133 134
    -- RX Buffer FSM
    signal curr_state               :       t_rx_buf_state;
    signal next_state               :       t_rx_buf_state;
    
    -- Clock enable for state register
    signal rx_fsm_ce                :       std_logic;
135

136
    -- <RELEASE_OFF>
137 138
    -- Joined commands (for assertions only)
    signal cmd_join                 :       std_logic_vector(3 downto 0);
139
    -- <RELEASE_ON>
140

141
begin
142 143

    ----------------------------------------------------------------------------
144
    -- Next State process
145
    ----------------------------------------------------------------------------
146
    next_state_proc : process(curr_state, store_metadata_f, rec_abort_f, 
147
        rec_valid_f)
148 149 150 151 152 153 154 155 156
    begin
        next_state <= curr_state;
        
        case curr_state is

        --------------------------------------------------------------------
        -- Idle, waiting for "store_metada" to start storing first 4 words.
        --------------------------------------------------------------------
        when s_rxb_idle =>
157
            if (store_metadata_f = '1' and rec_abort_f = '0') then
158 159
                next_state      <= s_rxb_store_frame_format;
            end if;
160

161 162 163 164
        --------------------------------------------------------------------
        -- Storing FRAME_FORM_W. Proceed execpt if error ocurrs.
        --------------------------------------------------------------------
        when s_rxb_store_frame_format =>
165
            if (rec_abort_f = '1') then
166 167 168 169
                next_state      <= s_rxb_idle;
            else
                next_state      <= s_rxb_store_identifier;
            end if;
170

171 172 173 174 175 176 177 178
        --------------------------------------------------------------------
        -- Storing IDENTIFIER_W.
        -- Move to storing timestamp words. Note that if SW configured
        -- timestamp from end of the frame, we dont have it yet! We store
        -- invalid timestamp and later (if the frame is received OK), we
        -- repeat the writes with timestamp captured at the end of frame!
        --------------------------------------------------------------------
        when s_rxb_store_identifier =>
179 180
            next_state      <= s_rxb_skip_ts_low;
            
181
        --------------------------------------------------------------------
182
        -- Skip through TIMESTAMP_L_W, store only zeroes.
183
        --------------------------------------------------------------------
184
        when s_rxb_skip_ts_low =>
185 186
            next_state      <= s_rxb_skip_ts_high;
            
187
        --------------------------------------------------------------------
188
        -- Skip through TIMESTAMP_U_W, store only zeroes.
189
        --------------------------------------------------------------------
190
        when s_rxb_skip_ts_high =>
191 192
            next_state      <= s_rxb_store_data;
            
193 194 195 196 197 198 199
        --------------------------------------------------------------------
        -- Store DATA_W. If error ocurrs, abort the storing. If storing is
        -- finished, go to idle or again timestamp storing depending on the
        -- timestamp option configuration. Note that now timestamp storing
        -- is realized via different states!
         --------------------------------------------------------------------
        when s_rxb_store_data =>
200
            if (rec_abort_f = '1') then 
201
                next_state      <= s_rxb_idle;
202
            elsif (rec_valid_f = '1') then
203
                next_state      <= s_rxb_store_end_ts_low;
204
            end if;
205

206
        --------------------------------------------------------------------
207
        -- Store TIMESTAMP_L_W.
208 209 210 211 212
        --------------------------------------------------------------------
        when s_rxb_store_end_ts_low =>
            next_state      <= s_rxb_store_end_ts_high;

        --------------------------------------------------------------------
213
        -- Store first TIMESTAMP_U_W.
214 215 216 217 218
        --------------------------------------------------------------------
        when s_rxb_store_end_ts_high =>
            next_state      <= s_rxb_idle;
            
        end case;
219 220 221 222
    end process;


    ----------------------------------------------------------------------------
223
    -- Current State process (outputs)
224
    ----------------------------------------------------------------------------
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
225
    curr_state_proc : process(curr_state, store_data_f)
226 227
    begin
        write_raw_intent <= '0';
228
        write_ts <= '0'; 
229
        data_selector <= (OTHERS => '0');
230 231 232
        stored_ts <= '0';
        store_ts_wr_ptr <= '0';
        inc_ts_wr_ptr <= '0';
233 234 235 236 237 238 239 240
        reset_overrun_flag <= '0';
        
        case curr_state is
        when s_rxb_idle =>
            reset_overrun_flag <= '1';
            
        when s_rxb_store_frame_format =>
            write_raw_intent <= '1';
241
            data_selector    <= "00001";
242 243 244
            
        when s_rxb_store_identifier =>
            write_raw_intent <= '1';
245
            data_selector    <= "00010";
246

247
        when s_rxb_skip_ts_low =>
248
            write_raw_intent <= '1';
249

250 251 252
            -- Here we capture value of Raw write pointer to Timestamp write pointer
            -- so that it can be later used for Timestamp storing.
            store_ts_wr_ptr <= '1';
253
            
254
        when s_rxb_skip_ts_high =>
255 256 257
            write_raw_intent <= '1';
            
        when s_rxb_store_data =>
258
            data_selector    <= "00100";
259
            
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
260
            if (store_data_f = '1') then
261 262 263 264
                write_raw_intent      <= '1';
            end if;
            
        when s_rxb_store_end_ts_low =>
265
            data_selector    <= "01000";
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
266

267
            -- Timestamp write pointer is incremented once more when lower
268
            -- timestamp word was stored, to point to higher timestamp word.
269
            inc_ts_wr_ptr <= '1';
270
            
271 272
            -- Signalling that timestamp is stored to memory.
            write_ts   <= '1';
273 274
            
        when s_rxb_store_end_ts_high =>
275 276
            data_selector    <= "10000";
            
277 278
            -- Storing of timestamp is ending and frame can be committed.
            stored_ts <= '1';
279
            
280 281
            -- Signalling that timestamp is stored to memory.
            write_ts   <= '1';
282 283 284
        end case;
    end process;
    
285 286

    ----------------------------------------------------------------------------
287
    -- State register process
288
    ----------------------------------------------------------------------------
289
    state_reg_proc : process(clk_sys, res_n)
290
    begin
291
        if (res_n = G_RESET_POLARITY) then
292 293 294 295
            curr_state <= s_rxb_idle;
        elsif (rising_edge(clk_sys)) then
            if (rx_fsm_ce = '1') then
                curr_state <= next_state;
296 297 298
            end if;
        end if;
    end process;
299 300 301 302
    
    -- Clock enable for State reg
    rx_fsm_ce <= '1' when (next_state /= curr_state) else
                 '0';
303
    
304
    -- <RELEASE_OFF>
305 306 307 308
    ---------------------------------------------------------------------------
    -- Assertions
    ---------------------------------------------------------------------------
    -- psl default clock is rising_edge(clk_sys);
309 310 311

    -- Joined commands, for assertions only
    cmd_join <= store_metadata_f & store_data_f & rec_valid_f & rec_abort_f; 
312 313
    
    -- psl store_metadata_in_idle_asrt : assert never
314
    --  (store_metadata_f = '1' and (curr_state /= s_rxb_idle))
315 316 317 318 319
    -- report "RX Buffer: Store metadata command did NOT come when RX buffer " &
    --        "is idle!"
    -- severity error;
    
    -- psl commit_or_store_data_asrt : assert never
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
320
    --  ((rec_valid_f = '1' or store_data_f = '1') and curr_state /= s_rxb_store_data)
321 322 323 324 325
    -- report "RX Buffer: Store data or frame commit commands did not come " &
    --        "when RX Buffer is receiving data!"
    -- severity error;

    -- psl sof_pulse_asrt_asrt : assert never
326
    --   (sof_pulse = '1' and (curr_state /= s_rxb_idle))
Ille, Ondrej, Ing.'s avatar
Ille, Ondrej, Ing. committed
327
    -- report "RX Buffer: SOF pulse should come when RX Buffer is idle!"
328 329
    -- severity error;
    
330
    -- psl rx_buf_cmds_one_hot_asrt : assert always
331 332
    --   (now > 0 ps) -> (cmd_join = "0000" or cmd_join = "0001" or 
    --    cmd_join = "0010" or cmd_join = "0100" or cmd_join = "1000")
333
    -- report "RX Buffer: RX Buffer commands should be one-hot encoded!"
334
    -- severity error;
335 336 337 338 339 340 341 342
    
    -- psl rx_no_abort_after_metadata : assert never
    --  (rec_abort_f = '1') and
    --  (curr_state = s_rxb_store_identifier or curr_state = s_rxb_skip_ts_low or
    --   curr_state = s_rxb_skip_ts_high or curr_state = s_rxb_store_end_ts_low or
    --   curr_state = s_rxb_store_end_ts_high)
    --  report "RX Buffer abort not supported storing of Identifier and Timestamp"
    --  severity error;
343

344
    -- <RELEASE_ON>
345
end architecture;