File: /__w/ctu-can-regression/ctu-can-regression/src/txt_buffer/txt_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: -- Transmitt Frame Buffer FSM.
71: --
72: -- Purpose:
73: -- Handles HW commands from Protocol control and SW commands from Memory
74: -- registers.
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 txt_buffer_fsm is
90: port (
91: -------------------------------------------------------------------------------------------
92: -- Clock and Asynchronous reset
93: -------------------------------------------------------------------------------------------
94: clk_sys : in std_logic;
95: res_n : in std_logic;
96:
97: -------------------------------------------------------------------------------------------
98: -- Memory registers interface
99: -------------------------------------------------------------------------------------------
100: mr_mode_bmm : in std_logic;
101: mr_mode_rom : in std_logic;
102: mr_settings_tbfbo : in std_logic;
103:
104: -------------------------------------------------------------------------------------------
105: -- Control signals
106: -------------------------------------------------------------------------------------------
107: tx_command_txce_valid : in std_logic;
108: tx_command_txcr_valid : in std_logic;
109: abort_applied : in std_logic;
110: abort_or_skipped : in std_logic;
111:
112: -------------------------------------------------------------------------------------------
113: -- CAN Core interface
114: -------------------------------------------------------------------------------------------
115: -- HW Commands
116: txtb_hw_cmd : in t_txtb_hw_cmd;
117:
118: -- HW Buffer select
119: txtb_hw_cmd_cs : in std_logic;
120:
121: -- Unit is Bus off
122: is_bus_off : in std_logic;
123:
124: -------------------------------------------------------------------------------------------
125: -- Parity checking logic
126: -------------------------------------------------------------------------------------------
127: -- Parity Error
128: txtb_parity_error_valid : in std_logic;
129:
130: -------------------------------------------------------------------------------------------
131: -- Status signals
132: -------------------------------------------------------------------------------------------
133: -- Buffer accessible from SW
134: txtb_user_accessible : out std_logic;
135:
136: -- TXT Buffer is in state for which its backup buffer can be used
137: txtb_allow_bb : out std_logic;
138:
139: -- HW Command applied on TXT Buffer.
140: txtb_hw_cmd_int : out std_logic;
141:
142: -- Buffer status (FSM state) encoded for reading by SW.
143: txtb_state : out std_logic_vector(3 downto 0);
144:
145: -- TXT Buffer is available to be locked by CAN Core for transmission
146: txtb_available : out std_logic;
147:
148: -- UnMask content of TXT Buffer RAM
149: txtb_unmask_data_ram : out std_logic
150: );
151: end entity;
152:
153: architecture rtl of txt_buffer_fsm is
154:
155: -- FSM signals
156: signal next_state : t_txt_buf_state;
157: signal curr_state : t_txt_buf_state;
158:
159: -- TXT Buffer clock enable
160: signal txt_fsm_ce : std_logic;
161:
162: -- Forced transition to failed state
163: signal go_to_failed : std_logic;
164: signal transient_state : std_logic;
165:
166: -- Internal HW Command, filtered by HW chip select for this Buffer
167: signal txtb_hw_cmd_i : t_txtb_hw_cmd;
168:
169: -- Arbitration lost or error valid fro current TXT Buffer
170: signal arbl_or_err : std_logic;
171:
172: begin
173:
174: transient_state <= '1' when ((curr_state = s_txt_ab_prog) or
175: (curr_state = s_txt_tx_prog) or
176: (curr_state = s_txt_ready))
177: else
178: '0';
179:
180: go_to_failed <= '1' when ((is_bus_off = '1' and mr_settings_tbfbo = TXTBUF_FAILED_BUS_OFF_ENABLED) or
181: mr_mode_bmm = BMM_ENABLED or
182: mr_mode_rom = ROM_ENABLED)
183: else
184: '0';
185:
186: txtb_hw_cmd_i <= txtb_hw_cmd when (txtb_hw_cmd_cs = '1')
187: else
188: (others => '0');
189:
190: arbl_or_err <= '1' when (txtb_hw_cmd_i.err = '1' or txtb_hw_cmd_i.arbl = '1') else
191: '0';
192:
193: txtb_allow_bb <= transient_state;
194:
195: -----------------------------------------------------------------------------------------------
196: -- Next state process
197: -----------------------------------------------------------------------------------------------
198: tx_buf_fsm_next_state_proc : process(curr_state, tx_command_txce_valid, tx_command_txcr_valid,
199: txtb_hw_cmd_i, abort_applied, go_to_failed, txtb_parity_error_valid, abort_or_skipped,
200: arbl_or_err)
201: begin
202: next_state <= curr_state;
203:
204: case curr_state is
205:
206: -------------------------------------------------------------------------------------------
207: -- Buffer is empty
208: -------------------------------------------------------------------------------------------
209: when s_txt_empty =>
210:
211: -- "Set_ready"
212: if (tx_command_txcr_valid = '1') then
213: next_state <= s_txt_ready;
214: end if;
215:
216: -------------------------------------------------------------------------------------------
217: -- Buffer is ready for transmission
218: -------------------------------------------------------------------------------------------
219: when s_txt_ready =>
220:
221: -- Node became bus-off
222: if (go_to_failed = '1') then
223: next_state <= s_txt_failed;
224:
225: -- Parity Error occured
226: elsif (txtb_parity_error_valid = '1') then
227: next_state <= s_txt_parity_err;
228:
229: -- Locking for transmission
230: elsif (txtb_hw_cmd_i.lock = '1') then
231:
232: -- Simultaneous "lock" and abort -> transmit, but with abort pending
233: if (abort_applied = '1') then
234: next_state <= s_txt_ab_prog;
235: else
236: next_state <= s_txt_tx_prog;
237: end if;
238:
239: -- Abort the ready buffer or Skip the original TXT Buffer getting "failed" or "OK".
240: elsif (abort_or_skipped = '1') then
241: next_state <= s_txt_aborted;
242: end if;
243:
244: -------------------------------------------------------------------------------------------
245: -- Transmission from buffer is in progress
246: -------------------------------------------------------------------------------------------
247: when s_txt_tx_prog =>
248:
249: -- Node became bus-off
250: if (go_to_failed = '1') then
251: next_state <= s_txt_failed;
252:
253: -- Parity Error occured
254: elsif (txtb_parity_error_valid = '1') then
255: next_state <= s_txt_parity_err;
256:
257: -- Retransmitt reached, do not try again
258: elsif (txtb_hw_cmd_i.failed = '1') then
259: next_state <= s_txt_failed;
260:
261: -- Transmission OK
262: elsif (txtb_hw_cmd_i.valid = '1') then
263: next_state <= s_txt_ok;
264:
265: -- Error or arbitration lost
266: elsif (arbl_or_err = '1') then
267: if (abort_applied = '1') then
268: next_state <= s_txt_aborted;
269: else
270: next_state <= s_txt_ready;
271: end if;
272:
273: -- Request abort during transmission
274: elsif (abort_applied = '1') then
275: next_state <= s_txt_ab_prog;
276: end if;
277:
278: -------------------------------------------------------------------------------------------
279: -- Transmission is in progress -> abort at nearest error!
280: -------------------------------------------------------------------------------------------
281: when s_txt_ab_prog =>
282:
283: -- Node became bus-off
284: if (go_to_failed = '1') then
285: next_state <= s_txt_failed;
286:
287: -- Parity Error occured
288: elsif (txtb_parity_error_valid = '1') then
289: next_state <= s_txt_parity_err;
290:
291: -- Retransmitt reached, do not try again
292: elsif (txtb_hw_cmd_i.failed = '1') then
293: next_state <= s_txt_failed;
294:
295: -- Transmission OK
296: elsif (txtb_hw_cmd_i.valid = '1') then
297: next_state <= s_txt_ok;
298:
299: -- Error or arbitration lost
300: elsif (arbl_or_err = '1') then
301: next_state <= s_txt_aborted;
302: end if;
303:
304: -------------------------------------------------------------------------------------------
305: -- Transmission from buffer failed. Retransmitt limit was reached.
306: -------------------------------------------------------------------------------------------
307: when s_txt_failed =>
308:
309: -- "Set_ready"
310: if (tx_command_txcr_valid = '1') then
311: next_state <= s_txt_ready;
312:
313: -- "Set_empty"
314: elsif (tx_command_txce_valid = '1') then
315: next_state <= s_txt_empty;
316: end if;
317:
318: -------------------------------------------------------------------------------------------
319: -- Transmission was aborted by user command
320: -------------------------------------------------------------------------------------------
321: when s_txt_aborted =>
322:
323: -- "Set_ready"
324: if (tx_command_txcr_valid = '1') then
325: next_state <= s_txt_ready;
326:
327: -- "Set_empty"
328: elsif (tx_command_txce_valid = '1') then
329: next_state <= s_txt_empty;
330: end if;
331:
332: -------------------------------------------------------------------------------------------
333: -- Transmission was succesfull
334: -------------------------------------------------------------------------------------------
335: when s_txt_ok =>
336:
337: -- "Set_ready"
338: if (tx_command_txcr_valid = '1') then
339: next_state <= s_txt_ready;
340:
341: -- "Set_empty"
342: elsif (tx_command_txce_valid = '1') then
343: next_state <= s_txt_empty;
344: end if;
345:
346: -------------------------------------------------------------------------------------------
347: -- Parity Error
348: -------------------------------------------------------------------------------------------
349: when s_txt_parity_err =>
350:
351: -- "Set_ready"
352: if (tx_command_txcr_valid = '1') then
353: next_state <= s_txt_ready;
354:
355: -- "Set_empty"
356: elsif (tx_command_txce_valid = '1') then
357: next_state <= s_txt_empty;
358: end if;
359:
360: end case;
361:
362: end process;
363:
364: -----------------------------------------------------------------------------------------------
365: -- State register clock enable
366: -----------------------------------------------------------------------------------------------
367: txt_fsm_ce <= '1' when (next_state /= curr_state) else
368: '0';
369:
370: -----------------------------------------------------------------------------------------------
371: -- State register
372: -----------------------------------------------------------------------------------------------
373: tx_buf_fsm_state_reg_proc : process(res_n, clk_sys)
374: begin
375: if (res_n = '0') then
376: curr_state <= s_txt_empty;
377: elsif (rising_edge(clk_sys)) then
378: if (txt_fsm_ce = '1') then
379: curr_state <= next_state;
380: end if;
381: end if;
382: end process;
383:
384: -----------------------------------------------------------------------------------------------
385: -- Buffer FSM outputs
386: -----------------------------------------------------------------------------------------------
387: -- Memory protection of TXT Buffer
388: txtb_user_accessible <= '0' when ((curr_state = s_txt_ready) or
389: (curr_state = s_txt_tx_prog) or
390: (curr_state = s_txt_ab_prog))
391: else
392: '1';
393:
394: -- TXT Buffer HW Command generates interrupt upon transition to Failed, Done and Aborted states!
395: txtb_hw_cmd_int <= '1' when (txtb_hw_cmd_i.failed = '1') or -- Fail transition completely
396: (txtb_hw_cmd_i.valid = '1') or -- Finish transition OK
397: ((txtb_hw_cmd_i.arbl = '1' or
398: txtb_hw_cmd_i.err = '1') and
399: (curr_state = s_txt_ab_prog)) -- Not failed completely, but already in
400: -- abort in progress -> No further transmissions
401: -- will continue -> Indicate to user
402: else
403: '1' when (is_bus_off = '1' and next_state = s_txt_failed and
404: transient_state = '1')
405: else
406: '0';
407:
408: -- Buffer is available for selection by TX Arbitrator only in state "Ready" Abort signal must
409: -- not be active. If not considered, race condition between HW and SW commands could occur!
410: txtb_available <= '1' when ((curr_state = s_txt_ready) and (abort_applied = '0'))
411: else
412: '0';
413:
414: -- Encoding Buffer FSM to output values read from TXT Buffer status register.
415: with curr_state select txtb_state <=
416: TXT_RDY when s_txt_ready,
417: TXT_TRAN when s_txt_tx_prog,
418: TXT_ABTP when s_txt_ab_prog,
419: TXT_TOK when s_txt_ok,
420: TXT_ERR when s_txt_failed,
421: TXT_ABT when s_txt_aborted,
422: TXT_ETY when s_txt_empty,
423: TXT_PER when s_txt_parity_err;
424:
425: -----------------------------------------------------------------------------------------------
426: -- Unmask content of TXT Buffer RAM (make it available for CAN Core and TX Arbitrator) when it
427: -- is valid for them to read from there. That is during TXT Buffer selection or during
428: -- transmission. During other moments content of TXT Buffer RAM is not needed by CAN Core nor
429: -- TX Arbitrator!
430: -----------------------------------------------------------------------------------------------
431: txtb_unmask_data_ram <= '1' when (transient_state = '1')
432: else
433: '0';
434:
435: -----------------------------------------------------------------------------------------------
436: -- Assertions
437: -----------------------------------------------------------------------------------------------
438:
439: -- psl default clock is rising_edge(clk_sys);
440:
441: -- HW Lock command should never arrive when the buffer is in other state
442: -- than ready
443: --
444: -- psl txtb_lock_only_in_rdy_asrt : assert always
445: -- ((txtb_hw_cmd.lock = '1' and txtb_hw_cmd_cs = '1') -> curr_state = s_txt_ready)
446: -- report "TXT Buffer not READY when LOCK command occurred!";
447: -----------------------------------------------------------------------------------------------
448: -- HW Unlock command is valid only when Buffer is TX in Progress or Abort in
449: -- progress.
450: --
451: -- psl txtb_unlock_only_in_tx_prog_asrt : assert always
452: -- ((txtb_hw_cmd_i.valid = '1' or txtb_hw_cmd_i.err = '1' or txtb_hw_cmd_i.arbl = '1' or txtb_hw_cmd_i.failed = '1') ->
453: -- (curr_state = s_txt_tx_prog or curr_state = s_txt_ab_prog or curr_state = s_txt_parity_err))
454: -- report "TXT Buffer not TX in progress, Abort in progress or Parity Error when unlock received!";
455: -----------------------------------------------------------------------------------------------
456: -- HW Lock command should never occur when there was abort in previous cycle!
457: --
458: -- psl txtb_no_lock_after_abort : assert never
459: -- {abort_applied = '1';txtb_hw_cmd.lock = '1' and txtb_hw_cmd_cs = '1'}
460: -- report "LOCK command after ABORT was applied!";
461: -----------------------------------------------------------------------------------------------
462:
463: end architecture;