File: /__w/ctu-can-regression/ctu-can-regression/src/tx_arbitrator/tx_arbitrator.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: -- TX Arbitrator
71: --
72: -- Purpose:
73: -- Circuit for selecting the valid frame for CAN Core from generic number of
74: -- TXT buffer inputs. Compares priorities of each buffer (SW selected) and
75: -- picks the highest priority buffer whose input is valid. Timestamp of high-
76: -- est priority frame is selected and compared with external timestamp. The
77: -- frame is marked as valid for CAN Core only if this timestamp is lower than
78: -- value of external Timestamp. This realizes the functionality of transmission
79: -- at exact time! Metadata of transmitted frame are loaded to output of TX
80: -- Arbitrator as part of selection process.
81: --------------------------------------------------------------------------------
82:
83: Library ieee;
84: use ieee.std_logic_1164.all;
85: use ieee.numeric_std.ALL;
86: use ieee.math_real.ALL;
87:
88: Library ctu_can_fd_rtl;
89: use ctu_can_fd_rtl.can_constants_pkg.all;
90: use ctu_can_fd_rtl.can_types_pkg.all;
91:
92: use ctu_can_fd_rtl.CAN_FD_register_map.all;
93: use ctu_can_fd_rtl.CAN_FD_frame_format.all;
94:
95: entity tx_arbitrator is
96: generic (
97: -- Number of TXT Buffers
98: G_TXT_BUFFER_COUNT : natural range 1 to 8
99: );
100: port (
101: -------------------------------------------------------------------------------------------
102: -- Clock and Asynchronous reset
103: -------------------------------------------------------------------------------------------
104: clk_sys : in std_logic;
105: res_n : in std_logic;
106:
107: -------------------------------------------------------------------------------------------
108: -- TXT Buffers interface
109: -------------------------------------------------------------------------------------------
110: -- Data words from TXT Buffers RAM memories
111: txtb_port_b_data_out : in t_txt_bufs_output(G_TXT_BUFFER_COUNT - 1 downto 0);
112:
113: -- TXT Buffers are available, can be selected by TX Arbitrator
114: txtb_available : in std_logic_vector(G_TXT_BUFFER_COUNT - 1 downto 0);
115:
116: -- TXT Buffer is in state in which it can have backup buffer
117: txtb_allow_bb : in std_logic_vector(G_TXT_BUFFER_COUNT - 1 downto 0);
118:
119: -- Pointer to TXT Buffer
120: txtb_port_b_address : out std_logic_vector(4 downto 0);
121:
122: -- Clock enable to TXT Buffer port B
123: txtb_port_b_clk_en : out std_logic;
124:
125: -- Parity check valid
126: txtb_parity_check_valid : out std_logic;
127:
128: -- Parity Mismatch in TXT Buffer
129: txtb_parity_mismatch : in std_logic_vector(G_TXT_BUFFER_COUNT - 1 downto 0);
130:
131: -- TXT Buffer index
132: txtb_index_muxed : out natural range 0 to G_TXT_BUFFER_COUNT - 1;
133:
134: -- TXT Buffer is operating as backup buffer
135: txtb_is_bb : out std_logic_vector(G_TXT_BUFFER_COUNT / 2 - 1 downto 0);
136:
137: -------------------------------------------------------------------------------------------
138: -- CAN Core Interface
139: -------------------------------------------------------------------------------------------
140: -- TXT Buffer memory word
141: tran_word : out std_logic_vector(31 downto 0);
142:
143: -- TX Data length code
144: tran_dlc : out std_logic_vector(3 downto 0);
145:
146: -- TX Remote transmission request flag
147: tran_is_rtr : out std_logic;
148:
149: -- TX Identifier type (0-Basic,1-Extended);
150: tran_ident_type : out std_logic;
151:
152: -- TX Frame type (0-CAN 2.0, 1-CAN FD)
153: tran_frame_type : out std_logic;
154:
155: -- TX Frame Bit rate shift Flag
156: tran_brs : out std_logic;
157:
158: -- TX Identifier
159: tran_identifier : out std_logic_vector(28 downto 0);
160:
161: -- TX Frame test
162: tran_frame_test : out t_frame_test_w;
163:
164: -- There is valid frame selected, can be locked for transmission
165: tran_frame_valid : out std_logic;
166:
167: -- Parity error occured during read of data words from TXT Buffer
168: tran_frame_parity_error : out std_logic;
169:
170: -- HW Commands from CAN Core for manipulation with TXT Buffers
171: txtb_hw_cmd : in t_txtb_hw_cmd;
172:
173: -- Selected TXT Buffer changed in comparison to previous transmission
174: txtb_changed : out std_logic;
175:
176: -- Index of the TXT Buffer for which the actual HW command is valid
177: txtb_hw_cmd_cs : out std_logic_vector(G_TXT_BUFFER_COUNT - 1 downto 0);
178:
179: -- Pointer to TXT Buffer given by CAN Core. Used for reading data words.
180: txtb_ptr : in natural range 0 to 20;
181:
182: -- TXT Buffer clock enable (from Protocol control)
183: txtb_clk_en : in std_logic;
184:
185: -------------------------------------------------------------------------------------------
186: -- RX Buffer interface
187: -------------------------------------------------------------------------------------------
188:
189: -- TXT Buffer index that is:
190: -- - Currently validated (when no transmission is in progress)
191: -- - Used for transmission (when transmission is in progress)
192: curr_txtb_index : out std_logic_vector(2 downto 0);
193:
194: -------------------------------------------------------------------------------------------
195: -- Memory registers interface
196: -------------------------------------------------------------------------------------------
197: mr_mode_tttm : in std_logic;
198: mr_mode_txbbm : in std_logic;
199: mr_settings_pchke : in std_logic;
200: mr_tx_priority : in t_txt_bufs_priorities(G_TXT_BUFFER_COUNT - 1 downto 0);
201:
202: -------------------------------------------------------------------------------------------
203: -- Timestamp
204: -------------------------------------------------------------------------------------------
205: timestamp : in std_logic_vector(63 downto 0)
206: );
207: end entity;
208:
209: architecture rtl of tx_arbitrator is
210:
211: -----------------------------------------------------------------------------------------------
212: -- Internal signals
213: -----------------------------------------------------------------------------------------------
214:
215: -- Indicates the highest selected buffer and its validity from combinational priority decoder
216: signal select_buf_avail : std_logic;
217: signal select_buf_index : natural range 0 to G_TXT_BUFFER_COUNT - 1;
218:
219: -- Input word from TXT Buffer !!!
220: signal txtb_selected_input : std_logic_vector(31 downto 0);
221:
222: -- TXT Buffer timestamp joined combinationally. Given by ts_low_internal and upper timestamp
223: -- word, out the output of RAM
224: signal txtb_timestamp : std_logic_vector(63 downto 0);
225:
226: -- Comparison of loaded timestamp from TXT Buffer.
227: signal timestamp_valid : std_logic;
228:
229: -- The output of priority decoder (selected TXT Buffer) has changed, pulse for one clock cycle
230: signal select_index_changed : std_logic;
231:
232: -- Signal that there is "Validated" TXT Buffer
233: signal validated_buffer : std_logic;
234:
235: -- TXT Buffer clock enable (one cycle later)
236: signal txtb_clk_en_q : std_logic;
237:
238: -- Metadata words read by TX Arbitrator are valid
239: signal tx_arb_parity_check_valid : std_logic;
240:
241: -----------------------------------------------------------------------------------------------
242: -- Internal registers
243: -----------------------------------------------------------------------------------------------
244:
245: -- Registered values for detection of change
246: signal select_buf_index_reg : natural range 0 to G_TXT_BUFFER_COUNT - 1;
247:
248: -- Lower timestamp loaded from TXT Buffer
249: signal ts_low_internal : std_logic_vector(31 downto 0);
250:
251: -- TXT Buffer index that is:
252: -- - Currently validated (when no transmission is in progress)
253: -- - Used for transmission (when transmission is in progress)
254: signal curr_txtb_index_i : natural range 0 to G_TXT_BUFFER_COUNT - 1;
255:
256: -- TXT Buffer internal index of last buffer that was locked from buffer change, Protocol control
257: -- can erase retransmitt counter
258: signal last_txtb_index : natural range 0 to G_TXT_BUFFER_COUNT - 1;
259:
260: -- TXT Buffer index validated or used for transmission
261: signal txtb_index_muxed_i : natural range 0 to G_TXT_BUFFER_COUNT - 1;
262:
263: -- Pointer to TXT Buffer for loading CAN frame metadata and timstamp during the selection of
264: -- TXT Buffer.
265: signal txtb_pointer_meta_q : natural range 0 to 20;
266: signal txtb_pointer_meta_d : natural range 0 to 20;
267:
268: -- Double buffer registers for metadata
269: signal tran_dlc_dbl_buf : std_logic_vector(3 downto 0);
270: signal tran_is_rtr_dbl_buf : std_logic;
271: signal tran_ident_type_dbl_buf : std_logic;
272: signal tran_frame_type_dbl_buf : std_logic;
273: signal tran_brs_dbl_buf : std_logic;
274:
275: -- Double buffer register for frame testability
276: signal tran_frame_test_dbl_buf : t_frame_test_w;
277:
278: -- Comitted values of internal signals
279: signal tran_dlc_com : std_logic_vector(3 downto 0);
280: signal tran_is_rtr_com : std_logic;
281: signal tran_ident_type_com : std_logic;
282: signal tran_frame_type_com : std_logic;
283: signal tran_brs_com : std_logic;
284: signal tran_frame_valid_com : std_logic;
285: signal tran_identifier_com : std_logic_vector(28 downto 0);
286:
287: -----------------------------------------------------------------------------------------------
288: -- TX Arbitrator FSM outputs
289: -----------------------------------------------------------------------------------------------
290:
291: -- Load Timestamp lower word to metadata pointer
292: signal load_ts_lw_addr : std_logic;
293:
294: -- Load Timestamp upper word to metadata pointer
295: signal load_ts_uw_addr : std_logic;
296:
297: -- Load Frame format word to metadata pointer
298: signal load_ffmt_w_addr : std_logic;
299:
300: -- Load identifier word to metadata pointer
301: signal load_ident_w_addr : std_logic;
302:
303: -- Load frame test word to metadata pointer
304: signal load_frame_test_w_addr : std_logic;
305:
306: -- Store timestamp lower word
307: signal store_ts_l_w : std_logic;
308:
309: -- Commit content of double buffer registers to registers visible by CAN Core
310: signal commit_dbl_bufs : std_logic;
311:
312: -- Store metadata (Frame format word) to double buffer registers.
313: signal buffer_md_w : std_logic;
314:
315: -- Store frame test word to double buffer registers
316: signal buffer_frame_test_w : std_logic;
317:
318: -- Store last locked TXT Buffer index
319: signal store_last_txtb_index : std_logic;
320:
321: -- Set valid selected buffer on TX Arbitrator output.
322: signal frame_valid_com_set : std_logic;
323:
324: -- Clear valid selected buffer on TX Arbitrator output.
325: signal frame_valid_com_clear : std_logic;
326:
327: -- TX Arbitrator is locked
328: signal tx_arb_locked : std_logic;
329:
330: -- TXT Buffer clock enable for reading metadata
331: signal txtb_meta_clk_en : std_logic;
332:
333: -- TXT Buffer Backup mode enable
334: signal mr_tx_priority_txbbm : t_txt_bufs_priorities(G_TXT_BUFFER_COUNT - 1 downto 0);
335:
336: -- Parity mismatches in TXT Buffers:
337: -- 1. Mismatch during TXT Buffer validation
338: -- 2. Mismatch during transmission
339: signal txtb_parity_mismatch_vld : std_logic;
340: signal txtb_parity_mismatch_tx : std_logic;
341:
342: -- Unlocking TXT Buffers at the end of transmission
343: signal txtb_hw_cmd_unlock : std_logic;
344:
345: -----------------------------------------------------------------------------------------------
346: -- Comparing procedure for two 64 bit std logic vectors
347: -----------------------------------------------------------------------------------------------
348: function less_than(
349: signal a : in std_logic_vector(63 downto 0);
350: signal b : in std_logic_vector(63 downto 0)
351: )return std_logic is
352: begin
353: if (unsigned(a(63 downto 32)) < unsigned(b(63 downto 32))) or
354: ((a(63 downto 32) = b(63 downto 32)) and
355: (unsigned(a(31 downto 0)) < unsigned(b(31 downto 0))))then
356: return '1';
357: else
358: return '0';
359: end if;
360: end function;
361:
362: begin
363:
364: -----------------------------------------------------------------------------------------------
365: -- Priority decoder on TXT Buffers
366: -----------------------------------------------------------------------------------------------
367: priority_decoder_inst : entity ctu_can_fd_rtl.priority_decoder
368: generic map (
369: G_TXT_BUFFER_COUNT => G_TXT_BUFFER_COUNT
370: )
371: port map (
372: prio => mr_tx_priority_txbbm, -- IN
373: prio_valid => txtb_available, -- IN
374:
375: output_valid => select_buf_avail, -- OUT
376: output_index => select_buf_index -- OUT
377: );
378:
379:
380: -----------------------------------------------------------------------------------------------
381: -- TX Arbitrator FSM
382: -----------------------------------------------------------------------------------------------
383: tx_arbitrator_fsm_inst : entity ctu_can_fd_rtl.tx_arbitrator_fsm
384: port map (
385: clk_sys => clk_sys, -- IN
386: res_n => res_n, -- IN
387:
388: select_buf_avail => select_buf_avail, -- IN
389: select_index_changed => select_index_changed, -- IN
390: timestamp_valid => timestamp_valid, -- IN
391: txtb_hw_cmd_lock => txtb_hw_cmd.lock, -- IN
392: txtb_hw_cmd_unlock => txtb_hw_cmd_unlock, -- IN
393: txtb_parity_mismatch_vld => txtb_parity_mismatch_vld, -- IN
394:
395: load_ts_lw_addr => load_ts_lw_addr, -- OUT
396: load_ts_uw_addr => load_ts_uw_addr, -- OUT
397: load_ffmt_w_addr => load_ffmt_w_addr, -- OUT
398: load_ident_w_addr => load_ident_w_addr, -- OUT
399: load_frame_test_w_addr => load_frame_test_w_addr, -- OUT
400: txtb_meta_clk_en => txtb_meta_clk_en, -- OUT
401:
402: store_ts_l_w => store_ts_l_w, -- OUT
403: commit_dbl_bufs => commit_dbl_bufs, -- OUT
404: buffer_frame_test_w => buffer_frame_test_w, -- OUT
405: buffer_md_w => buffer_md_w, -- OUT
406: tx_arb_locked => tx_arb_locked, -- OUT
407: store_last_txtb_index => store_last_txtb_index, -- OUT
408: frame_valid_com_set => frame_valid_com_set, -- OUT
409: frame_valid_com_clear => frame_valid_com_clear, -- OUT
410: tx_arb_parity_check_valid => tx_arb_parity_check_valid -- OUT
411: );
412:
413: -----------------------------------------------------------------------------------------------
414: -- TXT Buffer differences fo Shuffle priorites of TXT Buffers, in TXT Buffer Backup mode,
415: -- replace priority of "Backup" buffer with priority of "original" buffer
416: -----------------------------------------------------------------------------------------------
417: txtb_priority_gen : for i in 0 to G_TXT_BUFFER_COUNT - 1 generate
418:
419: -- Original Buffers
420: txtb_priority_even_gen : if ((i mod 2) = 0) generate
421: mr_tx_priority_txbbm(i) <= mr_tx_priority(i);
422: end generate;
423:
424: -- Backup buffers
425: txtb_priority_odd_gen : if ((i mod 2) = 1) generate
426:
427: mr_tx_priority_txbbm(i) <= mr_tx_priority(i) when (mr_mode_txbbm = '0')
428: else
429: mr_tx_priority(i - 1);
430:
431: txtb_is_bb(i / 2) <= '1' when (mr_mode_txbbm = '1' and curr_txtb_index_i = i-1 and
432: txtb_allow_bb(i - 1) = '1')
433: else
434: '0';
435: end generate;
436: end generate;
437:
438:
439: -----------------------------------------------------------------------------------------------
440: -- Comparing timestamp with external timestamp. This assumes that Upper timestamp is on the
441: -- output of buffer and lower timestamp is stored in "ts_low_internal".
442: -----------------------------------------------------------------------------------------------
443: timestamp_valid <= less_than(txtb_timestamp, timestamp) when (mr_mode_tttm = TTTM_ENABLED)
444: else
445: '1';
446:
447: -----------------------------------------------------------------------------------------------
448: -- When TXT Buffer which is currently "Validated" suddenly becomes "Unavailable" (e.g. due to
449: -- Set Abort command), this must be signalled to Protocol control in the same clock cycle!
450: -- During transmission, CAN Core is reading metadata from outputs. Since the frame is valid,
451: -- it is logical to also have "tran_frame_valid" active!
452: -----------------------------------------------------------------------------------------------
453: validated_buffer <= '1' when (txtb_available(curr_txtb_index_i) = '1') and
454: (tran_frame_valid_com = '1')
455: else
456: '0';
457:
458: tran_frame_valid <= '1' when (validated_buffer = '1') or (tx_arb_locked = '1')
459: else
460: '0';
461:
462: -----------------------------------------------------------------------------------------------
463: -- Parity mismatch during validation of TXT Buffer, must be indexed using "raw" /
464: -- "combinatorial" index of buffer which is currently being validated.
465: -----------------------------------------------------------------------------------------------
466: txtb_parity_mismatch_vld <= '1' when (txtb_parity_mismatch(select_buf_index) = '1')
467: else
468: '0';
469:
470: -----------------------------------------------------------------------------------------------
471: -- Protocol controller reads from TXT Buffer, so if there is parity mismatch one clock cycle
472: -- later, this means there was error in data word. In such case, signal to Protocol controller
473: -- to start error frame! Buffer one which parity mismatch is checked, must be selected by
474: -- registered index of TXT Buffer which is used for transmission.
475: -----------------------------------------------------------------------------------------------
476: txtb_parity_mismatch_tx <= '1' when (txtb_parity_mismatch(curr_txtb_index_i) = '1')
477: else
478: '0';
479:
480: tran_frame_parity_error <= '1' when (txtb_parity_mismatch_tx = '1' and txtb_clk_en_q = '1')
481: else
482: '0';
483:
484: -----------------------------------------------------------------------------------------------
485: -- Selecting TXT Buffer output word based on TXT Buffer index. During transmission, use last
486: -- stored TXT buffer. Otherwise use combinatorially selected TXT buffer (during validation).
487: -----------------------------------------------------------------------------------------------
488: txtb_index_muxed_i <= curr_txtb_index_i when (tx_arb_locked = '1')
489: else
490: select_buf_index;
491:
492: -- Parity check. When Protocol controller wants to enable clock for TXT Buffer, it reads data
493: -- words from it for transmission. When this occurs, data will we available on the output of
494: -- TXT Buffer RAM one clock cycle later. At this cycle, TXT Buffer needs to check for parity
495: -- error.
496: txtb_parity_check_valid <= txtb_clk_en_q when (tx_arb_locked = '1')
497: else
498: tx_arb_parity_check_valid;
499:
500: -- Select read data based on index of TXT buffer which should be accessed
501: txtb_selected_input <= txtb_port_b_data_out(txtb_index_muxed_i);
502:
503: -- Transmitted data word taken from TXT Buffer output
504: tran_word <= txtb_selected_input;
505: txtb_index_muxed <= txtb_index_muxed_i;
506:
507: -----------------------------------------------------------------------------------------------
508: -- Joined timestamp from TXT Buffer. Note that it is not always valid! Only when the TXT Buffer
509: -- is addressed with upper timestamp word address!
510: -----------------------------------------------------------------------------------------------
511: txtb_timestamp <= txtb_selected_input & ts_low_internal;
512:
513: -----------------------------------------------------------------------------------------------
514: -- Output frame metadata and Identifier for CAN Core
515: -----------------------------------------------------------------------------------------------
516: tran_dlc <= tran_dlc_com;
517: tran_is_rtr <= tran_is_rtr_com;
518: tran_ident_type <= tran_ident_type_com;
519: tran_frame_type <= tran_frame_type_com;
520: tran_brs <= tran_brs_com;
521: tran_identifier <= tran_identifier_com;
522:
523: -----------------------------------------------------------------------------------------------
524: -- During Buffer selection, TX Arbitrator is addressing TXT Buffers.
525: -- During Transmission, the Core is addressing TXT Buffers. The same goes for clock enable.
526: -----------------------------------------------------------------------------------------------
527: -- TODO: Convert pointers to std_logic!
528: txtb_port_b_address <= std_logic_vector(to_unsigned(txtb_ptr, 5)) when (tx_arb_locked = '1')
529: else
530: std_logic_vector(to_unsigned(txtb_pointer_meta_q, 5));
531:
532: txtb_port_b_clk_en <= txtb_clk_en when (tx_arb_locked = '1')
533: else
534: txtb_meta_clk_en;
535:
536: txtb_hw_cmd_cs_demux_proc : process(curr_txtb_index_i)
537: begin
538: txtb_hw_cmd_cs <= (others => '0');
539: txtb_hw_cmd_cs(curr_txtb_index_i) <= '1';
540: end process;
541:
542: -----------------------------------------------------------------------------------------------
543: -- Register for TXT Buffer clock enable
544: -----------------------------------------------------------------------------------------------
545: txtb_clk_en_reg_proc : process(clk_sys, res_n)
546: begin
547: if (res_n = '0') then
548: txtb_clk_en_q <= '0';
549: elsif (rising_edge(clk_sys)) then
550: txtb_clk_en_q <= txtb_clk_en;
551: end if;
552: end process;
553:
554:
555: -----------------------------------------------------------------------------------------------
556: -- Register for loading lower 32 bits of CAN Frame timestamp
557: -----------------------------------------------------------------------------------------------
558: low_ts_reg_proc : process(res_n, clk_sys)
559: begin
560: if (res_n = '0') then
561: ts_low_internal <= (others => '0');
562: elsif (rising_edge(clk_sys)) then
563: if (store_ts_l_w = '1') then
564: ts_low_internal <= txtb_selected_input;
565: end if;
566: end if;
567: end process;
568:
569: -----------------------------------------------------------------------------------------------
570: -- Double buffer registers for Metadata.
571: -----------------------------------------------------------------------------------------------
572: dbl_buf_reg_ffmt_proc : process(clk_sys, res_n)
573: begin
574: if (res_n = '0') then
575: tran_dlc_dbl_buf <= (others => '0');
576: tran_is_rtr_dbl_buf <= '0';
577: tran_ident_type_dbl_buf <= '0';
578: tran_frame_type_dbl_buf <= '0';
579: tran_brs_dbl_buf <= '0';
580: elsif (rising_edge(clk_sys)) then
581: if (buffer_md_w = '1') then
582: tran_dlc_dbl_buf <= txtb_selected_input(DLC_H downto DLC_L);
583: tran_is_rtr_dbl_buf <= txtb_selected_input(RTR_IND);
584: tran_ident_type_dbl_buf <= txtb_selected_input(IDE_IND);
585: tran_frame_type_dbl_buf <= txtb_selected_input(FDF_IND);
586: tran_brs_dbl_buf <= txtb_selected_input(BRS_IND);
587: end if;
588: end if;
589: end process;
590:
591: -----------------------------------------------------------------------------------------------
592: -- Double buffer registers for Frame test word
593: -----------------------------------------------------------------------------------------------
594: dbl_buf_reg_ftw_proc : process(clk_sys, res_n)
595: begin
596: if (res_n = '0') then
597: tran_frame_test_dbl_buf.fstc <= '0';
598: tran_frame_test_dbl_buf.fcrc <= '0';
599: tran_frame_test_dbl_buf.sdlc <= '0';
600: tran_frame_test_dbl_buf.tprm <= (others => '0');
601: elsif (rising_edge(clk_sys)) then
602: if (buffer_frame_test_w = '1') then
603: tran_frame_test_dbl_buf.fstc <= txtb_selected_input(FSTC_IND);
604: tran_frame_test_dbl_buf.fcrc <= txtb_selected_input(FCRC_IND);
605: tran_frame_test_dbl_buf.sdlc <= txtb_selected_input(SDLC_IND);
606: tran_frame_test_dbl_buf.tprm <= txtb_selected_input(TPRM_H downto TPRM_L);
607: end if;
608: end if;
609: end process;
610:
611:
612: -----------------------------------------------------------------------------------------------
613: -- Capture registers for metadata commited to output of TX Arbitrator. Takenfrom double buffer
614: -- register.
615: -----------------------------------------------------------------------------------------------
616: meta_data_reg_proc : process(clk_sys, res_n)
617: begin
618: if (res_n = '0') then
619: tran_dlc_com <= (others => '0');
620: tran_is_rtr_com <= '0';
621: tran_ident_type_com <= '0';
622: tran_frame_type_com <= '0';
623: tran_brs_com <= '0';
624: elsif (rising_edge(clk_sys)) then
625: if (commit_dbl_bufs = '1') then
626: tran_frame_type_com <= tran_frame_type_dbl_buf;
627: tran_ident_type_com <= tran_ident_type_dbl_buf;
628: tran_dlc_com <= tran_dlc_dbl_buf;
629: tran_is_rtr_com <= tran_is_rtr_dbl_buf;
630: tran_brs_com <= tran_brs_dbl_buf;
631: end if;
632: end if;
633: end process;
634:
635: -----------------------------------------------------------------------------------------------
636: -- Capture registers for Identifier commited to output of TX Arbitrator.
637: -----------------------------------------------------------------------------------------------
638: identifier_reg_proc : process(clk_sys, res_n)
639: begin
640: if (res_n = '0') then
641: tran_identifier_com <= (others => '0');
642: elsif (rising_edge(clk_sys)) then
643: if (commit_dbl_bufs = '1') then
644: tran_identifier_com <= txtb_selected_input(28 downto 0);
645: end if;
646: end if;
647: end process;
648:
649: -----------------------------------------------------------------------------------------------
650: -- Capture registers for Frame test word commited to output of TX Arbitrator.
651: -----------------------------------------------------------------------------------------------
652: frame_test_w_reg_proc : process(clk_sys, res_n)
653: begin
654: if (res_n = '0') then
655: tran_frame_test.fstc <= '0';
656: tran_frame_test.fcrc <= '0';
657: tran_frame_test.sdlc <= '0';
658: tran_frame_test.tprm <= (others => '0');
659: elsif (rising_edge(clk_sys)) then
660: if (commit_dbl_bufs = '1') then
661: tran_frame_test <= tran_frame_test_dbl_buf;
662: end if;
663: end if;
664: end process;
665:
666: -----------------------------------------------------------------------------------------------
667: -- Register for "committed" valid frame output for CAN Core
668: -----------------------------------------------------------------------------------------------
669: tran_frame_valid_com_proc : process(clk_sys, res_n)
670: begin
671: if (res_n = '0') then
672: tran_frame_valid_com <= '0';
673: elsif (rising_edge(clk_sys)) then
674: if (frame_valid_com_set = '1') then
675: tran_frame_valid_com <= '1';
676: elsif (frame_valid_com_clear = '1') then
677: tran_frame_valid_com <= '0';
678: end if;
679: end if;
680: end process;
681:
682:
683: -----------------------------------------------------------------------------------------------
684: -- Storing values of selected TXT Buffer index when selection process ends. Storing TXT Buffer
685: -- at the time of LOCK from CAN Core. Two values are needed to determine change of selected TXT
686: -- Buffer for CAN Core. CAN Core needs this information for erasing retransmitt limit counter.
687: -----------------------------------------------------------------------------------------------
688: store_indices_proc : process(clk_sys, res_n)
689: begin
690: if (res_n = '0') then
691: last_txtb_index <= 0;
692: curr_txtb_index_i <= 0;
693:
694: elsif (rising_edge(clk_sys)) then
695: -- At the time of lock, the last index is stored from the last stored index.
696: if (store_last_txtb_index = '1') then
697: last_txtb_index <= curr_txtb_index_i;
698: end if;
699:
700: -- Combinationally selected index (select_buf_index) is stored when metadata are stored.
701: if (commit_dbl_bufs = '1') then
702: curr_txtb_index_i <= select_buf_index;
703: end if;
704:
705: end if;
706: end process;
707:
708: txtb_changed <= '1' when (last_txtb_index /= curr_txtb_index_i and store_last_txtb_index = '1')
709: else
710: '0';
711:
712: curr_txtb_index <= std_logic_vector(to_unsigned(curr_txtb_index_i, 3));
713:
714: -----------------------------------------------------------------------------------------------
715: -- Registering value of combinationally selected index by priority decoder to determine change
716: -- and signal restarting selection process to TX Arbitrator FSM.
717: -----------------------------------------------------------------------------------------------
718: sel_index_change_proc : process(clk_sys, res_n)
719: begin
720: if (res_n = '0') then
721: select_buf_index_reg <= 0;
722: elsif (rising_edge(clk_sys)) then
723: select_buf_index_reg <= select_buf_index;
724: end if;
725: end process;
726:
727: select_index_changed <= '0' when (select_buf_index = select_buf_index_reg)
728: else
729: '1';
730:
731:
732: -----------------------------------------------------------------------------------------------
733: -- Metadata pointer to address TXT Buffer Timestamp and Metadata Words.
734: -----------------------------------------------------------------------------------------------
735: txtb_pointer_meta_d <=
736: to_integer(unsigned(TIMESTAMP_L_W_ADR(11 downto 2))) when (load_ts_lw_addr = '1') else
737: to_integer(unsigned(TIMESTAMP_U_W_ADR(11 downto 2))) when (load_ts_uw_addr = '1') else
738: to_integer(unsigned(FRAME_FORMAT_W_ADR(11 downto 2))) when (load_ffmt_w_addr = '1') else
739: to_integer(unsigned(IDENTIFIER_W_ADR(11 downto 2))) when (load_ident_w_addr = '1') else
740: to_integer(unsigned(FRAME_TEST_W_ADR(11 downto 2))) when (load_frame_test_w_addr = '1') else
741: txtb_pointer_meta_q;
742:
743: store_meta_data_ptr_proc : process(clk_sys, res_n)
744: begin
745: if (res_n = '0') then
746: txtb_pointer_meta_q <= to_integer(unsigned(TIMESTAMP_L_W_ADR(11 downto 2)));
747: elsif (rising_edge(clk_sys)) then
748: txtb_pointer_meta_q <= txtb_pointer_meta_d;
749: end if;
750: end process;
751:
752: -----------------------------------------------------------------------------------------------
753: -- TXT Buffer unlock - When PC FSM ends transmission from a TXT Buffer
754: -----------------------------------------------------------------------------------------------
755: txtb_hw_cmd_unlock <= '1' when (txtb_hw_cmd.valid = '1' or txtb_hw_cmd.err = '1' or
756: txtb_hw_cmd.arbl = '1' or txtb_hw_cmd.failed = '1')
757: else
758: '0';
759:
760: -----------------------------------------------------------------------------------------------
761: -- Assertions
762: -----------------------------------------------------------------------------------------------
763:
764: -- psl default clock is rising_edge(clk_sys);
765:
766: -- When TXT Buffer is not ready for more than one cycle, LOCK command might not occur. If it is
767: -- not ready for one clock cycle, it might still be due to set abort and LOCK command applied
768: -- simultaneously. This is OK. But as soon as buffer is not ready for second cycle, LOCK command
769: -- can't be active!
770: --
771: -- psl txtb_no_lock_when_not_ready_asrt : assert never
772: -- {tran_frame_valid = '0';
773: -- tran_frame_valid = '0' and txtb_hw_cmd.lock = '1'}
774: -- report "NO TXT Buffer ready and lock occurs!";
775: -----------------------------------------------------------------------------------------------
776:
777: end architecture;