File: /__w/ctu-can-regression/ctu-can-regression/src/rx_buffer/rx_buffer_fsm.vhd
0: --------------------------------------------------------------------------------
1: --
2: -- CTU CAN FD IP Core
3: -- Copyright (C) 2021-2023 Ondrej Ille
4: -- Copyright (C) 2023- Logic Design Services Ltd.s
5: --
6: -- Permission is hereby granted, free of charge, to any person obtaining a copy
7: -- of this VHDL component and associated documentation files (the "Component"),
8: -- to use, copy, modify, merge, publish, distribute the Component for
9: -- non-commercial purposes. Using the Component for commercial purposes is
10: -- forbidden unless previously agreed with Copyright holder.
11: --
12: -- The above copyright notice and this permission notice shall be included in
13: -- all copies or substantial portions of the Component.
14: --
15: -- THE COMPONENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16: -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17: -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18: -- AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19: -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20: -- FROM, OUT OF OR IN CONNECTION WITH THE COMPONENT OR THE USE OR OTHER DEALINGS
21: -- IN THE COMPONENT.
22: --
23: -- The CAN protocol is developed by Robert Bosch GmbH and protected by patents.
24: -- Anybody who wants to implement this IP core on silicon has to obtain a CAN
25: -- protocol license from Bosch.
26: --
27: -- -------------------------------------------------------------------------------
28: --
29: -- CTU CAN FD IP Core
30: -- Copyright (C) 2015-2020 MIT License
31: --
32: -- Authors:
33: -- Ondrej Ille <ondrej.ille@gmail.com>
34: -- Martin Jerabek <martin.jerabek01@gmail.com>
35: --
36: -- Project advisors:
37: -- Jiri Novak <jnovak@fel.cvut.cz>
38: -- Pavel Pisa <pisa@cmp.felk.cvut.cz>
39: --
40: -- Department of Measurement (http://meas.fel.cvut.cz/)
41: -- Faculty of Electrical Engineering (http://www.fel.cvut.cz)
42: -- Czech Technical University (http://www.cvut.cz/)
43: --
44: -- Permission is hereby granted, free of charge, to any person obtaining a copy
45: -- of this VHDL component and associated documentation files (the "Component"),
46: -- to deal in the Component without restriction, including without limitation
47: -- the rights to use, copy, modify, merge, publish, distribute, sublicense,
48: -- and/or sell copies of the Component, and to permit persons to whom the
49: -- Component is furnished to do so, subject to the following conditions:
50: --
51: -- The above copyright notice and this permission notice shall be included in
52: -- all copies or substantial portions of the Component.
53: --
54: -- THE COMPONENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55: -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
56: -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57: -- AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58: -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
59: -- FROM, OUT OF OR IN CONNECTION WITH THE COMPONENT OR THE USE OR OTHER DEALINGS
60: -- IN THE COMPONENT.
61: --
62: -- The CAN protocol is developed by Robert Bosch GmbH and protected by patents.
63: -- Anybody who wants to implement this IP core on silicon has to obtain a CAN
64: -- protocol license from Bosch.
65: --
66: --------------------------------------------------------------------------------
67:
68: --------------------------------------------------------------------------------
69: -- Module:
70: -- RX Buffer FSM.
71: --
72: -- Purpose:
73: -- Reacts on commands from CAN Core and controls storing of CAN frame
74: -- continusly to RX Buffer RAM.
75: --------------------------------------------------------------------------------
76:
77: Library ieee;
78: use ieee.std_logic_1164.all;
79: use ieee.numeric_std.ALL;
80: use ieee.math_real.ALL;
81:
82: Library ctu_can_fd_rtl;
83: use ctu_can_fd_rtl.can_constants_pkg.all;
84: use ctu_can_fd_rtl.can_types_pkg.all;
85:
86: use ctu_can_fd_rtl.CAN_FD_register_map.all;
87: use ctu_can_fd_rtl.CAN_FD_frame_format.all;
88:
89: entity rx_buffer_fsm is
90: port (
91: -------------------------------------------------------------------------------------------
92: -- Clocks and reset
93: -------------------------------------------------------------------------------------------
94: clk_sys : in std_logic;
95: res_n : in std_logic;
96:
97: -------------------------------------------------------------------------------------------
98: -- Memory registers interface
99: -------------------------------------------------------------------------------------------
100: mr_mode_erfm : in std_logic;
101:
102: -------------------------------------------------------------------------------------------
103: -- Control signals from CAN Core (Filtered by Frame filters)
104: -------------------------------------------------------------------------------------------
105: -- Start Storing of Metadata to RX Buffer (first 4 words of frame)
106: store_metadata_f : in std_logic;
107:
108: -- Store Data word to RX Buffer
109: store_data_f : in std_logic;
110:
111: -- Received frame valid
112: rec_valid_f : in std_logic;
113:
114: -- Abort storing of RX Frame to RX Buffer.
115: rec_abort_f : in std_logic;
116:
117: -------------------------------------------------------------------------------------------
118: -- FSM outputs
119: -------------------------------------------------------------------------------------------
120: -- Intent to write to RX Buffer RAM
121: write_raw_intent : out std_logic;
122:
123: -- Select Timestamp write pointer
124: select_ts_wptr : out std_logic;
125:
126: -- Intend to comit frame to RX Buffer
127: commit_intent : out std_logic;
128:
129: -- Data selector for selection of memory word to be stored in RX Buffer
130: -- RAM (one hot coded)
131: data_selector : out std_logic_vector(4 downto 0);
132:
133: -- Load timestamp write pointer from regular write pointer
134: store_ts_wr_ptr : out std_logic;
135:
136: -- Increment timestamp write pointer by 1
137: inc_ts_wr_ptr : out std_logic;
138:
139: -- Error frame type
140: rec_erf : out std_logic;
141:
142: -- Reset internal overrun flag
143: reset_overrun_flag : out std_logic
144: );
145: end entity;
146:
147: architecture rtl of rx_buffer_fsm is
148:
149: -- RX Buffer FSM
150: signal curr_state : t_rx_buf_state;
151: signal next_state : t_rx_buf_state;
152:
153: -- Clock enable for state register
154: signal rx_fsm_ce : std_logic;
155:
156: begin
157:
158: -----------------------------------------------------------------------------------------------
159: -- Next State process
160: -----------------------------------------------------------------------------------------------
161: next_state_proc : process(curr_state, store_metadata_f, rec_abort_f, rec_valid_f, mr_mode_erfm)
162: begin
163: next_state <= curr_state;
164:
165: case curr_state is
166:
167: -------------------------------------------------------------------------------------------
168: -- Idle, waiting for "store_metada" to start storing first 4 words.
169: -------------------------------------------------------------------------------------------
170: when s_rxb_idle =>
171: if (store_metadata_f = '1') then
172: next_state <= s_rxb_store_frame_format;
173: elsif (mr_mode_erfm = ERFM_ENABLED and rec_abort_f = '1') then
174: next_state <= s_rxb_store_err_frame_format;
175: end if;
176:
177: -------------------------------------------------------------------------------------------
178: -- Storing FRAME_FORM_W. Proceed execpt if error ocurrs.
179: -------------------------------------------------------------------------------------------
180: when s_rxb_store_frame_format =>
181: if (rec_abort_f = '1') then
182: if (mr_mode_erfm = ERFM_ENABLED) then
183: next_state <= s_rxb_store_err_frame_format;
184: else
185: next_state <= s_rxb_idle;
186: end if;
187: else
188: next_state <= s_rxb_store_identifier;
189: end if;
190:
191: -------------------------------------------------------------------------------------------
192: -- Storing IDENTIFIER_W.
193: -- Move to storing timestamp words. Note that if SW configured timestamp from end of the
194: -- frame, we dont have it yet! We store invalid timestamp and later (if the frame is
195: -- received OK), we repeat the writes with timestamp captured at the end of frame!
196: -------------------------------------------------------------------------------------------
197: when s_rxb_store_identifier =>
198: next_state <= s_rxb_skip_ts_low;
199:
200: -------------------------------------------------------------------------------------------
201: -- Skip through TIMESTAMP_L_W, store only zeroes.
202: -------------------------------------------------------------------------------------------
203: when s_rxb_skip_ts_low =>
204: next_state <= s_rxb_skip_ts_high;
205:
206: -------------------------------------------------------------------------------------------
207: -- Skip through TIMESTAMP_U_W, store only zeroes.
208: -------------------------------------------------------------------------------------------
209: when s_rxb_skip_ts_high =>
210: next_state <= s_rxb_store_data;
211:
212: -------------------------------------------------------------------------------------------
213: -- Store DATA_W. If error ocurrs, abort the storing. If storing is finished, go to idle or
214: -- again timestamp storing depending on the timestamp option configuration. Note that now
215: -- timestamp storing is realized via different states!
216: -------------------------------------------------------------------------------------------
217: when s_rxb_store_data =>
218: if (rec_abort_f = '1') then
219: if (mr_mode_erfm = ERFM_ENABLED) then
220: next_state <= s_rxb_store_err_frame_format;
221: else
222: next_state <= s_rxb_idle;
223: end if;
224:
225: elsif (rec_valid_f = '1') then
226: next_state <= s_rxb_store_end_ts_low;
227: end if;
228:
229: -------------------------------------------------------------------------------------------
230: -- Store TIMESTAMP_L_W.
231: -------------------------------------------------------------------------------------------
232: when s_rxb_store_end_ts_low =>
233: next_state <= s_rxb_store_end_ts_high;
234:
235: -------------------------------------------------------------------------------------------
236: -- Store first TIMESTAMP_U_W.
237: -------------------------------------------------------------------------------------------
238: when s_rxb_store_end_ts_high =>
239: next_state <= s_rxb_idle;
240:
241: -------------------------------------------------------------------------------------------
242: -- Store FRAME_FORMAT_W of an Error frame
243: -------------------------------------------------------------------------------------------
244: when s_rxb_store_err_frame_format =>
245: next_state <= s_rxb_store_err_identifier;
246:
247: -------------------------------------------------------------------------------------------
248: -- Store IDENTIFIER_W of an Error frame
249: -------------------------------------------------------------------------------------------
250: when s_rxb_store_err_identifier =>
251: next_state <= s_rxb_store_err_ts_low;
252:
253: -------------------------------------------------------------------------------------------
254: -- Store TIMESTAMP_L_W of an Error frame
255: -------------------------------------------------------------------------------------------
256: when s_rxb_store_err_ts_low =>
257: next_state <= s_rxb_store_err_ts_high;
258:
259: -------------------------------------------------------------------------------------------
260: -- Store TIMESTAMP_U_W of an Error frame
261: -------------------------------------------------------------------------------------------
262: when s_rxb_store_err_ts_high =>
263: next_state <= s_rxb_idle;
264:
265: end case;
266: end process;
267:
268:
269: -----------------------------------------------------------------------------------------------
270: -- Current State process (outputs)
271: -----------------------------------------------------------------------------------------------
272: curr_state_proc : process(curr_state, store_data_f, rec_abort_f)
273: begin
274: write_raw_intent <= '0';
275: select_ts_wptr <= '0';
276: data_selector <= (others => '0');
277: commit_intent <= '0';
278: store_ts_wr_ptr <= '0';
279: inc_ts_wr_ptr <= '0';
280: reset_overrun_flag <= '0';
281: rec_erf <= '0';
282:
283: case curr_state is
284: when s_rxb_idle =>
285: reset_overrun_flag <= '1';
286:
287: when s_rxb_store_frame_format =>
288: if (rec_abort_f = '0') then
289: write_raw_intent <= '1';
290: end if;
291: data_selector <= "00001";
292:
293: when s_rxb_store_identifier =>
294: write_raw_intent <= '1';
295: data_selector <= "00010";
296:
297: when s_rxb_skip_ts_low =>
298: write_raw_intent <= '1';
299:
300: -- Here we capture value of Raw write pointer to Timestamp write pointer
301: -- so that it can be later used for Timestamp storing.
302: store_ts_wr_ptr <= '1';
303:
304: when s_rxb_skip_ts_high =>
305: write_raw_intent <= '1';
306:
307: when s_rxb_store_data =>
308: data_selector <= "00100";
309:
310: if (store_data_f = '1') then
311: write_raw_intent <= '1';
312: end if;
313:
314: when s_rxb_store_end_ts_low =>
315: data_selector <= "01000";
316:
317: -- Raw write pointer points to the last data frame word
318: -- when timestamp is stored at the end of frame. Need to
319: -- use backed-up timestamp write pointer.
320: select_ts_wptr <= '1';
321:
322: -- Timestamp write pointer is incremented once more when lower
323: -- timestamp word was stored, to point to higher timestamp word.
324: inc_ts_wr_ptr <= '1';
325:
326: when s_rxb_store_end_ts_high =>
327: data_selector <= "10000";
328:
329: -- Raw write pointer points to the last data frame word
330: -- when timestamp is stored at the end of frame. Need to
331: -- use backed-up timestamp write pointer.
332: select_ts_wptr <= '1';
333:
334: commit_intent <= '1';
335:
336: when s_rxb_store_err_frame_format =>
337: write_raw_intent <= '1';
338: data_selector <= "00001";
339: rec_erf <= '1';
340:
341: when s_rxb_store_err_identifier =>
342: write_raw_intent <= '1';
343: data_selector <= "00010";
344:
345: when s_rxb_store_err_ts_low =>
346: write_raw_intent <= '1';
347: data_selector <= "01000";
348:
349: when s_rxb_store_err_ts_high =>
350: write_raw_intent <= '1';
351: data_selector <= "10000";
352:
353: commit_intent <= '1';
354: end case;
355:
356: end process;
357:
358:
359: -----------------------------------------------------------------------------------------------
360: -- State register process
361: -----------------------------------------------------------------------------------------------
362: state_reg_proc : process(clk_sys, res_n)
363: begin
364: if (res_n = '0') then
365: curr_state <= s_rxb_idle;
366: elsif (rising_edge(clk_sys)) then
367: if (rx_fsm_ce = '1') then
368: curr_state <= next_state;
369: end if;
370: end if;
371: end process;
372:
373: -- Clock enable for State reg
374: rx_fsm_ce <= '1' when (next_state /= curr_state) else
375: '0';
376:
377: -----------------------------------------------------------------------------------------------
378: -- Assertions
379: -----------------------------------------------------------------------------------------------
380:
381: -- pragma translate_off
382:
383: assertions_block : block
384: -- Joined commands
385: signal cmd_join : std_logic_vector(3 downto 0);
386: begin
387: -- psl default clock is rising_edge(clk_sys);
388:
389: -- Joined commands, for assertions only
390: cmd_join <= store_metadata_f & store_data_f & rec_valid_f & rec_abort_f;
391:
392: -- psl store_metadata_in_idle_asrt : assert never
393: -- (store_metadata_f = '1' and (curr_state /= s_rxb_idle))
394: -- report "RX Buffer: Store metadata command did NOT come when RX buffer is idle!";
395:
396: -- psl commit_or_store_data_asrt : assert never
397: -- ((rec_valid_f = '1' or store_data_f = '1') and curr_state /= s_rxb_store_data)
398: -- report "RX Buffer: Store data or frame commit commands did not come when RX Buffer is receiving data!";
399:
400: -- psl rxb_not_storing_err_frm_when_next_occurs_asrt : assert never
401: -- (curr_state = s_rxb_store_err_frame_format or
402: -- curr_state = s_rxb_store_err_identifier or
403: -- curr_state = s_rxb_store_err_ts_low or
404: -- curr_state = s_rxb_store_err_ts_high) and (rec_abort_f = '1')
405: -- report "Error frame was not yet fully stored when another one occured.";
406:
407: -- coverage off
408: process (cmd_join)
409: begin
410: if (now > 0 ps) then
411: if (cmd_join /= "0000" and cmd_join /= "0001" and
412: cmd_join /= "0010" and cmd_join /= "0100" and
413: cmd_join /= "1000")
414: then
415: report "RX Buffer: RX Buffer commands should be one-hot encoded!"
416: severity error;
417: end if;
418: end if;
419: end process;
420: -- coverage on
421:
422: -- psl rx_no_abort_after_metadata_cov : assert never
423: -- (rec_abort_f = '1') and
424: -- (curr_state = s_rxb_store_identifier or curr_state = s_rxb_skip_ts_low or
425: -- curr_state = s_rxb_skip_ts_high or curr_state = s_rxb_store_end_ts_low or
426: -- curr_state = s_rxb_store_end_ts_high)
427: -- report "RX Buffer abort not supported storing of Identifier and Timestamp";
428:
429: -- psl rx_never_abort_and_store_in_idle : assert never
430: -- (curr_state = s_rxb_idle and store_metadata_f = '1' and rec_abort_f = '1')
431: -- report "When RX Buffer FSM is s_rxb_idle, store_metadata_f and rec_abort_f can't be simultaneous!";
432:
433: -- psl store_metadata_and_rec_abort_back_to_back_cov : cover
434: -- {mr_mode_erfm = ERFM_ENABLED and rec_abort_f = '1' and curr_state = s_rxb_store_frame_format}
435: -- report "rec_abort_f = 1 and curr_state = s_rxb_store_frame_format";
436:
437: -- psl rec_abort_in_idle_cov : cover
438: -- {mr_mode_erfm = ERFM_ENABLED and rec_abort_f = '1' and curr_state = s_rxb_idle}
439: -- report "rec_abort_f = 1 and curr_state = s_rxb_idle";
440:
441: -- psl rec_abort_in_store_data_cov : cover
442: -- {mr_mode_erfm = ERFM_ENABLED and rec_abort_f = '1' and curr_state = s_rxb_store_data}
443: -- report "rec_abort_f = 1 and curr_state = s_rxb_store_data";
444:
445: end block assertions_block;
446:
447: -- pragma translate_on
448:
449: end architecture;