File: /__w/CTU-CAN-FD/CTU-CAN-FD/src/memory_registers/mr_top.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: -- Memory registers
71: --
72: -- Purpose:
73: -- Configuration and Status registers are implemented here. Access over 32 bit,
74: -- Avalon compatible interface. Write in the same clock cycle, read data are
75: -- returned in next clock cycle. Driving bus is created here. Memory registers
76: -- are generated by Register Map Generation Tool.
77: --------------------------------------------------------------------------------
78:
79: Library ieee;
80: use ieee.std_logic_1164.all;
81: use ieee.numeric_std.ALL;
82:
83: Library ctu_can_fd_rtl;
84: use ctu_can_fd_rtl.can_constants_pkg.all;
85: use ctu_can_fd_rtl.can_types_pkg.all;
86:
87: use ctu_can_fd_rtl.CAN_FD_register_map.all;
88: use ctu_can_fd_rtl.CAN_FD_frame_format.all;
89:
90: use ctu_can_fd_rtl.can_registers_pkg.all;
91:
92: entity mr_top is
93: generic (
94: -- Support Filter A
95: G_FILT_A_EN : boolean;
96:
97: -- Support Filter B
98: G_FILT_B_EN : boolean;
99:
100: -- Support Filter C
101: G_FILT_C_EN : boolean;
102:
103: -- Support Range Fi
104: G_FILT_RANGE_EN : boolean;
105:
106: -- Support Test registers
107: G_TEST_REGS_EN : boolean;
108:
109: -- Support Traffic counters
110: G_TRAFFIC_CTRS_EN : boolean;
111:
112: -- Support Parity
113: G_PARITY_EN : boolean;
114:
115: -- Number of TXT Buffers
116: G_TXT_BUF_COUNT : natural range 2 to 8;
117:
118: -- Size of RX Buffer
119: G_RX_BUF_SIZE : natural;
120:
121: -- Width of RX Buffer frame counter
122: G_RX_BUF_FRAME_CNT_WIDTH : natural range 3 to 11;
123:
124: -- Width of RX Buffer pointers
125: G_RX_BUF_PTR_WIDTH : natural range 5 to 12;
126:
127: -- Number of Interrupts
128: G_INT_COUNT : natural;
129:
130: -- Width (number of bits) in transceiver delay measurement counter
131: G_TRV_CTR_WIDTH : natural;
132:
133: -- Number of active timestamp bits
134: G_TS_BITS : natural range 0 to 63;
135:
136: -- DEVICE_ID (read from register)
137: G_DEVICE_ID : std_logic_vector(15 downto 0);
138:
139: -- MINOR Design version
140: G_VERSION_MINOR : std_logic_vector(7 downto 0);
141:
142: -- MAJOR Design version
143: G_VERSION_MAJOR : std_logic_vector(7 downto 0);
144:
145: -- Technology type
146: G_TECHNOLOGY : natural
147: );
148: port (
149: -------------------------------------------------------------------------------------------
150: -- Clock and Reset
151: -------------------------------------------------------------------------------------------
152: clk_sys : in std_logic;
153: rst_n : in std_logic;
154:
155: -- Soft reset (Input reset + Software Reset)
156: res_soft_n : out std_logic;
157:
158: -- Core Reset (Input reset + Software Reset + Active when disabled)
159: res_core_n : out std_logic;
160:
161: -------------------------------------------------------------------------------------------
162: -- DFT support
163: -------------------------------------------------------------------------------------------
164: scan_mode : in std_logic;
165:
166: -------------------------------------------------------------------------------------------
167: -- Main memory bus interface
168: -------------------------------------------------------------------------------------------
169: -- Data input
170: data_in : in std_logic_vector(31 downto 0);
171:
172: -- Data output
173: data_out : out std_logic_vector(31 downto 0);
174:
175: -- Address
176: adress : in std_logic_vector(11 downto 0);
177:
178: -- Chip Select
179: scs : in std_logic;
180:
181: -- Read
182: srd : in std_logic;
183:
184: -- Write
185: swr : in std_logic;
186:
187: -- Byte enable
188: sbe : in std_logic_vector(3 downto 0);
189:
190: -- Timestamp input
191: timestamp : in std_logic_vector(63 downto 0);
192:
193: -------------------------------------------------------------------------------------------
194: -- Configuration and Status to/from rest of the core
195: -------------------------------------------------------------------------------------------
196: -- Configuration from control registers to rest of the core
197: mr_ctrl_out : out control_registers_out_t;
198:
199: -- Configuration from test registers to rest of the core
200: mr_tst_out : out test_registers_out_t;
201:
202: -- Status to registers from CAN core
203: cc_stat : in t_can_core_stat;
204:
205: -- Debug record from Protocol control
206: pc_dbg : in t_protocol_control_dbg;
207:
208: -- RX buffer test data in
209: mr_tst_rdata_tst_rdata_rxb : in std_logic_vector(31 downto 0);
210:
211: -- TXT buffers test data input
212: mr_tst_rdata_tst_rdata_txb : in t_txt_bufs_output(G_TXT_BUF_COUNT - 1 downto 0);
213:
214: -------------------------------------------------------------------------------------------
215: -- RX Buffer Interface
216: -------------------------------------------------------------------------------------------
217: -- RX Buffer is full
218: rx_full : in std_logic;
219:
220: -- RX Buffer is empty
221: rx_empty : in std_logic;
222:
223: -- Number of frames in RX buffer
224: rx_frame_count : in std_logic_vector(G_RX_BUF_FRAME_CNT_WIDTH - 1 downto 0);
225:
226: -- Number of free 32 bit words
227: rx_mem_free : in std_logic_vector(G_RX_BUF_PTR_WIDTH downto 0);
228:
229: -- Position of read pointer
230: rx_read_pointer : in std_logic_vector(G_RX_BUF_PTR_WIDTH - 1 downto 0);
231:
232: -- Position of write pointer
233: rx_write_pointer : in std_logic_vector(G_RX_BUF_PTR_WIDTH - 1 downto 0);
234:
235: -- Data overrun Flag
236: rx_data_overrun : in std_logic;
237:
238: -- Middle of frame indication
239: rx_mof : in std_logic;
240:
241: -- RX Buffer parity error flag
242: rx_parity_error : in std_logic;
243:
244: -- RX Buffer data output
245: rxb_port_b_data_out : in std_logic_vector(31 downto 0);
246:
247: -------------------------------------------------------------------------------------------
248: -- Interface to TXT Buffers
249: -------------------------------------------------------------------------------------------
250: -- TXT Buffer RAM Port A - Write port
251: txtb_port_a_data_in : out std_logic_vector(31 downto 0);
252: txtb_port_a_address : out std_logic_vector(4 downto 0);
253: txtb_port_a_cs : out std_logic_vector(G_TXT_BUF_COUNT - 1 downto 0);
254: txtb_port_a_be : out std_logic_vector(3 downto 0);
255:
256: -- Prioriy of buffers
257: mr_tx_priority : out t_txt_bufs_priorities(G_TXT_BUF_COUNT - 1 downto 0);
258:
259: -- Command indices (chip selects)
260: mr_tx_command_txbi : out std_logic_vector(G_TXT_BUF_COUNT - 1 downto 0);
261:
262: -- TXT Buffer status
263: txtb_state : in t_txt_bufs_state(G_TXT_BUF_COUNT - 1 downto 0);
264:
265: -- TXT Buffer Parity Error
266: txtb_parity_error_valid : in std_logic_vector(G_TXT_BUF_COUNT - 1 downto 0);
267:
268: -- Parity Error in Backup buffer during TXT Buffer backup mode
269: txtb_bb_parity_error : in std_logic_vector(G_TXT_BUF_COUNT / 2 - 1 downto 0);
270:
271: -------------------------------------------------------------------------------------------
272: -- Bus synchroniser interface
273: -------------------------------------------------------------------------------------------
274: -- Measured Transceiver Delay
275: trv_delay : in std_logic_vector(G_TRV_CTR_WIDTH - 1 downto 0);
276:
277: -------------------------------------------------------------------------------------------
278: -- Interrrupt Manager Interface
279: -------------------------------------------------------------------------------------------
280: -- Interrupt Vector
281: mr_int_stat_rxi_o : in std_logic;
282: mr_int_stat_txi_o : in std_logic;
283: mr_int_stat_ewli_o : in std_logic;
284: mr_int_stat_doi_o : in std_logic;
285: mr_int_stat_fcsi_o : in std_logic;
286: mr_int_stat_ali_o : in std_logic;
287: mr_int_stat_bei_o : in std_logic;
288: mr_int_stat_ofi_o : in std_logic;
289: mr_int_stat_rxfi_o : in std_logic;
290: mr_int_stat_bsi_o : in std_logic;
291: mr_int_stat_rbnei_o : in std_logic;
292: mr_int_stat_txbhci_o : in std_logic;
293:
294: -- Interrupt Enable
295: mr_int_ena_set_int_ena_set_o : in std_logic_vector(G_INT_COUNT - 1 downto 0);
296:
297: -- Interrupt Mask
298: mr_int_mask_set_int_mask_set_o : in std_logic_vector(G_INT_COUNT - 1 downto 0)
299: );
300: end entity;
301:
302: architecture rtl of mr_top is
303:
304: -- Generated register maps inputs/outputs
305: signal mr_ctrl_out_i : control_registers_out_t;
306: signal mr_ctrl_in : control_registers_in_t;
307:
308: signal mr_tst_out_i : test_registers_out_t;
309: signal mr_tst_in : test_registers_in_t;
310:
311: -- TXT buffer outputs - padded
312: signal mr_tst_rdata_tst_rdata_txb_i : t_txt_bufs_output(7 downto 0);
313:
314: -- Chip select signals for each memory sub-block
315: signal control_registers_cs : std_logic;
316: signal control_registers_cs_reg : std_logic;
317:
318: signal test_registers_cs : std_logic;
319: signal test_registers_cs_reg : std_logic;
320:
321: -- Read data from generated register modules
322: signal control_registers_rdata : std_logic_vector(31 downto 0);
323: signal test_registers_rdata : std_logic_vector(31 downto 0);
324:
325: -- Locks active
326: signal reg_lock_1_active : std_logic;
327: signal reg_lock_2_active : std_logic;
328:
329: -- Additional generated resets
330: signal soft_res_d_n : std_logic;
331: signal soft_res_q_n : std_logic;
332:
333: signal res_core_d_n : std_logic;
334:
335: -- Clock gating for register map
336: signal control_regs_clk_en : std_logic;
337: signal test_regs_clk_en : std_logic;
338:
339: signal clk_control_regs : std_logic;
340: signal clk_test_regs : std_logic;
341:
342: -- SCS and SWR
343: signal scs_and_swr : std_logic;
344:
345: begin
346:
347: -----------------------------------------------------------------------------------------------
348: -- Propagation of Avalon Data Bus to TXT Buffer RAM
349: -----------------------------------------------------------------------------------------------
350: txtb_port_a_data_in <= data_in;
351:
352: -----------------------------------------------------------------------------------------------
353: -- Since TX_DATA registers are in separate region, which is word aligned, it is enough to take
354: -- the lowest bits to create the address offset.
355: -----------------------------------------------------------------------------------------------
356: txtb_port_a_address <= adress(6 downto 2);
357:
358: -----------------------------------------------------------------------------------------------
359: -- TXT Buffer RAMs chip select signals.
360: -----------------------------------------------------------------------------------------------
361: scs_and_swr <= '1' when (scs = '1' and swr = '1') else
362: '0';
363:
364: g_txtb_port_a_cs : for i in 0 to G_TXT_BUF_COUNT - 1 generate
365: type tx_buff_addr_type is array (0 to 7) of
366: std_logic_vector(3 downto 0);
367: constant buf_addr : tx_buff_addr_type := (
368: TX_BUFFER_1_BLOCK, TX_BUFFER_2_BLOCK,
369: TX_BUFFER_3_BLOCK, TX_BUFFER_4_BLOCK,
370: TX_BUFFER_5_BLOCK, TX_BUFFER_6_BLOCK,
371: TX_BUFFER_7_BLOCK, TX_BUFFER_8_BLOCK
372: );
373:
374: begin
375: txtb_port_a_cs(i) <= '1' when (adress(11 downto 8) = buf_addr(i) and scs_and_swr = '1')
376: else
377: '0';
378: end generate g_txtb_port_a_cs;
379:
380: txtb_port_a_be <= sbe;
381:
382: -----------------------------------------------------------------------------------------------
383: -- Chip selects for register map blocks
384: -----------------------------------------------------------------------------------------------
385: control_registers_cs <= '1' when (adress(11 downto 8) = CONTROL_REGISTERS_BLOCK) and
386: (scs = '1')
387: else
388: '0';
389:
390: test_registers_cs <= '1' when (adress(11 downto 8) = TEST_REGISTERS_BLOCK) and
391: (scs = '1')
392: else
393: '0';
394:
395: -----------------------------------------------------------------------------------------------
396: -- Registering control registers chip select
397: -----------------------------------------------------------------------------------------------
398: p_chip_sel_reg : process(rst_n, clk_sys)
399: begin
400: if (rst_n = '0') then
401: control_registers_cs_reg <= '0';
402: test_registers_cs_reg <= '0';
403: elsif (rising_edge(clk_sys)) then
404: control_registers_cs_reg <= control_registers_cs;
405: test_registers_cs_reg <= test_registers_cs;
406: end if;
407: end process;
408:
409: -----------------------------------------------------------------------------------------------
410: -- Read data multiplexor. Use registered version of chip select signals since read data are
411: -- returned one clock cycle later!
412: -----------------------------------------------------------------------------------------------
413: data_out <= control_registers_rdata when (control_registers_cs_reg = '1') else
414: test_registers_rdata when (test_registers_cs_reg = '1') else
415: (others => '0');
416:
417: -----------------------------------------------------------------------------------------------
418: -- Clock gating - Ungate clocks for read or write. Note that write enable / read enable is
419: -- still brought also to register map! This is for FPGA implementation where clock gate is
420: -- transparent!
421: -----------------------------------------------------------------------------------------------
422: control_regs_clk_en <= '1' when (srd = '1' or swr = '1') and (control_registers_cs = '1')
423: else
424: '0';
425:
426: test_regs_clk_en <= '1' when (srd = '1' or swr = '1') and (test_registers_cs = '1')
427: else
428: '0';
429:
430: i_clk_gate_control_regs : entity ctu_can_fd_rtl.clk_gate
431: generic map(
432: G_TECHNOLOGY => G_TECHNOLOGY
433: )
434: port map(
435: clk_in => clk_sys, -- IN
436: clk_en => control_regs_clk_en, -- IN
437: scan_mode => scan_mode, -- IN
438:
439: clk_out => clk_control_regs -- OUT
440: );
441:
442: i_clk_gate_test_regs : entity ctu_can_fd_rtl.clk_gate
443: generic map(
444: G_TECHNOLOGY => G_TECHNOLOGY
445: )
446: port map(
447: clk_in => clk_sys, -- IN
448: clk_en => test_regs_clk_en, -- IN
449: scan_mode => scan_mode, -- IN
450:
451: clk_out => clk_test_regs -- OUT
452: );
453:
454: -----------------------------------------------------------------------------------------------
455: -- Control registers instance
456: -----------------------------------------------------------------------------------------------
457: i_control_registers_reg_map : entity ctu_can_fd_rtl.control_registers_reg_map
458: generic map(
459: DATA_WIDTH => 32,
460: ADDRESS_WIDTH => 8,
461: REGISTERED_READ => true,
462: CLEAR_READ_DATA => false,
463:
464: G_FILT_A_EN => G_FILT_A_EN,
465: G_FILT_B_EN => G_FILT_B_EN,
466: G_FILT_C_EN => G_FILT_C_EN,
467: G_FILT_RANGE_EN => G_FILT_RANGE_EN,
468: G_TRAFFIC_CTRS_EN => G_TRAFFIC_CTRS_EN,
469: G_TXT_BUF_COUNT => G_TXT_BUF_COUNT
470: )
471: port map(
472: clk_sys => clk_control_regs, -- IN
473: rst_n => soft_res_q_n, -- IN
474: address => adress(7 downto 0), -- IN
475: w_data => data_in, -- IN
476: r_data => control_registers_rdata, -- OUT
477: cs => control_registers_cs, -- IN
478: read => srd, -- IN
479: write => swr, -- IN
480: be => sbe, -- IN
481: lock_1 => reg_lock_1_active, -- IN
482: lock_2 => reg_lock_2_active, -- IN
483: control_registers_out => mr_ctrl_out_i, -- OUT
484: control_registers_in => mr_ctrl_in -- IN
485: );
486: mr_ctrl_out <= mr_ctrl_out_i;
487:
488: -----------------------------------------------------------------------------------------------
489: -- Test registers instance
490: -----------------------------------------------------------------------------------------------
491: g_test_registers_true : if (G_TEST_REGS_EN) generate
492: i_test_registers_reg_map : entity ctu_can_fd_rtl.test_registers_reg_map
493: generic map (
494: DATA_WIDTH => 32,
495: ADDRESS_WIDTH => 8,
496: REGISTERED_READ => true,
497: CLEAR_READ_DATA => false
498: )
499: port map(
500: clk_sys => clk_test_regs, -- IN
501: rst_n => soft_res_q_n, -- IN
502: address => adress(7 downto 0), -- IN
503: w_data => data_in, -- IN
504: r_data => test_registers_rdata, -- OUT
505: cs => test_registers_cs, -- IN
506: read => srd, -- IN
507: write => swr, -- IN
508: be => sbe, -- IN
509: lock_1 => reg_lock_1_active, -- IN
510: lock_2 => reg_lock_2_active, -- IN
511: test_registers_out => mr_tst_out_i, -- OUT
512: test_registers_in => mr_tst_in -- IN
513: );
514:
515: -- Padding to full width of possible TXT Buffers
516: g_txt_buf_test_data_padding : for i in 0 to 7 generate
517:
518: g_txt_buf_padding_index_true : if (i < G_TXT_BUF_COUNT) generate
519: mr_tst_rdata_tst_rdata_txb_i(i) <= mr_tst_rdata_tst_rdata_txb(i);
520: end generate g_txt_buf_padding_index_true;
521:
522: g_txt_buf_padding_index_false : if (i >= G_TXT_BUF_COUNT) generate
523: mr_tst_rdata_tst_rdata_txb_i(i) <= (others => '0');
524: end generate g_txt_buf_padding_index_false;
525:
526: end generate;
527:
528: -- Select test read data from RX buffer and TXT buffers
529: with mr_tst_out_i.tst_dest_tst_mtgt select mr_tst_in.tst_rdata_tst_rdata <=
530: mr_tst_rdata_tst_rdata_rxb when TMTGT_RXBUF,
531: mr_tst_rdata_tst_rdata_txb_i(0) when TMTGT_TXTBUF1,
532: mr_tst_rdata_tst_rdata_txb_i(1) when TMTGT_TXTBUF2,
533: mr_tst_rdata_tst_rdata_txb_i(2) when TMTGT_TXTBUF3,
534: mr_tst_rdata_tst_rdata_txb_i(3) when TMTGT_TXTBUF4,
535: mr_tst_rdata_tst_rdata_txb_i(4) when TMTGT_TXTBUF5,
536: mr_tst_rdata_tst_rdata_txb_i(5) when TMTGT_TXTBUF6,
537: mr_tst_rdata_tst_rdata_txb_i(6) when TMTGT_TXTBUF7,
538: mr_tst_rdata_tst_rdata_txb_i(7) when TMTGT_TXTBUF8,
539: (others => '0') when others;
540:
541: end generate g_test_registers_true;
542:
543: g_test_registers_false : if (not G_TEST_REGS_EN) generate
544: test_registers_rdata <= (others => '0');
545: mr_tst_in.tst_rdata_tst_rdata <= (others => '0');
546: mr_tst_out_i <= ('0', '0', (others => '0'), (others => '0'), (others => '0'));
547: mr_tst_rdata_tst_rdata_txb_i <= (others => (others => '0'));
548: end generate;
549:
550: mr_tst_out <= mr_tst_out_i;
551:
552: -----------------------------------------------------------------------------------------------
553: -- Lock signals
554: -----------------------------------------------------------------------------------------------
555: -- Lock 1 - Locked when MODE[TSTM] = 0
556: reg_lock_1_active <= not mr_ctrl_out_i.mode_tstm;
557:
558: -- Lock 2 - Locked when SETTINGS[ENA] = 1
559: reg_lock_2_active <= mr_ctrl_out_i.settings_ena;
560:
561: -----------------------------------------------------------------------------------------------
562: -- Two reset registers:
563: -- 1. Soft reset - Resets memory registers
564: -- 2. Core reset - Resets rest of the core when disabled.
565: --
566: -- Both need to be gated to inactive value in Scan mode since they reset other flops.
567: -----------------------------------------------------------------------------------------------
568:
569: -- Writing MODE[RST] = 1 causes Soft Reset
570: soft_res_d_n <= not mr_ctrl_out_i.mode_rst;
571:
572: i_soft_rst_rst_reg : entity ctu_can_fd_rtl.rst_reg
573: generic map (
574: G_RESET_POLARITY => '0'
575: )
576: port map(
577: -- Clock and Reset
578: clk => clk_sys, -- IN
579: arst => rst_n, -- IN
580:
581: -- Flip flop input / output
582: d => soft_res_d_n, -- IN
583: q => soft_res_q_n, -- OUT
584:
585: -- Scan mode control
586: scan_mode => scan_mode -- IN
587: );
588:
589: -- Reset of the rest of core is the same as soft reset, but it is also active when
590: -- SETTINGS[ENA] = '0'. Thus disabled node has all of its logic in reset!
591: res_core_d_n <= '0' when (mr_ctrl_out_i.mode_rst = '1' or mr_ctrl_out_i.settings_ena = '0')
592: else
593: '1';
594:
595: i_global_rst_rst_reg : entity ctu_can_fd_rtl.rst_reg
596: generic map (
597: G_RESET_POLARITY => '0'
598: )
599: port map(
600: -- Clock and Reset
601: clk => clk_sys, -- IN
602: arst => rst_n, -- IN
603:
604: -- Flip flop input / output
605: d => res_core_d_n, -- IN
606: q => res_core_n, -- OUT
607:
608: -- Scan mode control
609: scan_mode => scan_mode -- IN
610: );
611:
612: -----------------------------------------------------------------------------------------------
613: -- Reset propagation to output
614: -----------------------------------------------------------------------------------------------
615: res_soft_n <= soft_res_q_n;
616:
617: -----------------------------------------------------------------------------------------------
618: -----------------------------------------------------------------------------------------------
619: -- Control registers - Write Data to Driving Bus connection
620: -----------------------------------------------------------------------------------------------
621: -----------------------------------------------------------------------------------------------
622:
623: mr_tx_priority(0) <= mr_ctrl_out_i.tx_priority_txt1p;
624: mr_tx_command_txbi(0) <= mr_ctrl_out_i.tx_command_txb1;
625:
626: mr_tx_priority(1) <= mr_ctrl_out_i.tx_priority_txt2p;
627: mr_tx_command_txbi(1) <= mr_ctrl_out_i.tx_command_txb2 when (mr_ctrl_out_i.mode_txbbm = '0')
628: else
629: mr_ctrl_out_i.tx_command_txb1 or mr_ctrl_out_i.tx_command_txb2;
630:
631: g_mt_2_txt_buffs : if (G_TXT_BUF_COUNT > 2) generate
632: mr_tx_priority(2) <= mr_ctrl_out_i.tx_priority_txt3p;
633: mr_tx_command_txbi(2) <= mr_ctrl_out_i.tx_command_txb3;
634: end generate;
635:
636: g_mt_3_txt_buffs : if (G_TXT_BUF_COUNT > 3) generate
637: mr_tx_priority(3) <= mr_ctrl_out_i.tx_priority_txt4p;
638: mr_tx_command_txbi(3) <= mr_ctrl_out_i.tx_command_txb4 when (mr_ctrl_out_i.mode_txbbm = '0')
639: else
640: mr_ctrl_out_i.tx_command_txb3 or mr_ctrl_out_i.tx_command_txb4;
641: end generate;
642:
643: g_mt_4_txt_buffs : if (G_TXT_BUF_COUNT > 4) generate
644: mr_tx_priority(4) <= mr_ctrl_out_i.tx_priority_txt5p;
645: mr_tx_command_txbi(4) <= mr_ctrl_out_i.tx_command_txb5;
646: end generate;
647:
648: g_mt_5_txt_buffs : if (G_TXT_BUF_COUNT > 5) generate
649: mr_tx_priority(5) <= mr_ctrl_out_i.tx_priority_txt6p;
650: mr_tx_command_txbi(5) <= mr_ctrl_out_i.tx_command_txb6 when (mr_ctrl_out_i.mode_txbbm = '0')
651: else
652: mr_ctrl_out_i.tx_command_txb5 or mr_ctrl_out_i.tx_command_txb6;
653: end generate;
654:
655: g_mt_6_txt_buffs : if (G_TXT_BUF_COUNT > 6) generate
656: mr_tx_priority(6) <= mr_ctrl_out_i.tx_priority_txt7p;
657: mr_tx_command_txbi(6) <= mr_ctrl_out_i.tx_command_txb7;
658: end generate;
659:
660: g_mt_7_txt_buffs : if (G_TXT_BUF_COUNT > 7) generate
661: mr_tx_priority(7) <= mr_ctrl_out_i.tx_priority_txt8p;
662: mr_tx_command_txbi(7) <= mr_ctrl_out_i.tx_command_txb8 when (mr_ctrl_out_i.mode_txbbm = '0')
663: else
664: mr_ctrl_out_i.tx_command_txb7 or mr_ctrl_out_i.tx_command_txb8;
665: end generate;
666:
667: -----------------------------------------------------------------------------------------------
668: -----------------------------------------------------------------------------------------------
669: -- Control registers - Read Data to status signals connection
670: -----------------------------------------------------------------------------------------------
671: -----------------------------------------------------------------------------------------------
672:
673: -- DEVICE ID
674: mr_ctrl_in.device_id_device_id <= G_DEVICE_ID;
675:
676: -- VERSION
677: mr_ctrl_in.version_ver_minor <= G_VERSION_MINOR;
678: mr_ctrl_in.version_ver_major <= G_VERSION_MAJOR;
679:
680: -- STATUS
681: mr_ctrl_in.status_idle <= '1' when (cc_stat.is_bus_off = '1') else
682: '1' when (cc_stat.is_idle = '1') else
683: '0';
684: mr_ctrl_in.status_ewl <= cc_stat.status_ewl;
685: mr_ctrl_in.status_txs <= cc_stat.is_transmitter;
686: mr_ctrl_in.status_rxs <= cc_stat.is_receiver;
687:
688: -- Go through TXT Buffers and check at least one is empty
689: p_txnf_calc : process(txtb_state)
690: begin
691: mr_ctrl_in.status_txnf <= '0';
692: for i in 0 to G_TXT_BUF_COUNT - 1 loop
693: if (txtb_state(i) = TXT_ETY) then
694: mr_ctrl_in.status_txnf <= '1';
695: end if;
696: end loop;
697: end process;
698:
699: mr_ctrl_in.status_rxne <= not rx_empty;
700: mr_ctrl_in.status_dor <= rx_data_overrun;
701: mr_ctrl_in.status_eft <= pc_dbg.is_err;
702: mr_ctrl_in.status_pexs <= cc_stat.status_pexs;
703: mr_ctrl_in.status_rxpe <= rx_parity_error;
704:
705: -- TXT Buffer parity error and double parity error
706: p_txpe_flag : process(soft_res_q_n, clk_sys)
707: begin
708: if (soft_res_q_n = '0') then
709: mr_ctrl_in.status_txpe <= '0';
710: mr_ctrl_in.status_txdpe <= '0';
711: elsif rising_edge(clk_sys) then
712: for i in 0 to G_TXT_BUF_COUNT - 1 loop
713: if (txtb_parity_error_valid(i) = '1') then
714: mr_ctrl_in.status_txpe <= '1';
715: end if;
716:
717: if (txtb_bb_parity_error(i / 2) = '1') then
718: mr_ctrl_in.status_txdpe <= '1';
719: end if;
720: end loop;
721:
722: if (mr_ctrl_out_i.command_ctxpe = '1') then
723: mr_ctrl_in.status_txpe <= '0';
724: end if;
725:
726: if (mr_ctrl_out_i.command_ctxdpe = '1') then
727: mr_ctrl_in.status_txdpe <= '0';
728: end if;
729: end if;
730: end process;
731:
732: mr_ctrl_in.status_stcnt <= '1' when G_TRAFFIC_CTRS_EN
733: else
734: '0';
735: mr_ctrl_in.status_sprt <= '1' when G_PARITY_EN
736: else
737: '0';
738: mr_ctrl_in.status_strgs <= '1' when G_TEST_REGS_EN
739: else
740: '0';
741:
742: -- INT_STAT
743: mr_ctrl_in.int_stat_rxi <= mr_int_stat_rxi_o;
744: mr_ctrl_in.int_stat_txi <= mr_int_stat_txi_o;
745: mr_ctrl_in.int_stat_ewli <= mr_int_stat_ewli_o;
746: mr_ctrl_in.int_stat_doi <= mr_int_stat_doi_o;
747: mr_ctrl_in.int_stat_fcsi <= mr_int_stat_fcsi_o;
748: mr_ctrl_in.int_stat_ali <= mr_int_stat_ali_o;
749: mr_ctrl_in.int_stat_bei <= mr_int_stat_bei_o;
750: mr_ctrl_in.int_stat_ofi <= mr_int_stat_ofi_o;
751: mr_ctrl_in.int_stat_rxfi <= mr_int_stat_rxfi_o;
752: mr_ctrl_in.int_stat_bsi <= mr_int_stat_bsi_o;
753: mr_ctrl_in.int_stat_rbnei <= mr_int_stat_rbnei_o;
754: mr_ctrl_in.int_stat_txbhci <= mr_int_stat_txbhci_o;
755:
756: -- INT_ENA_SET
757: mr_ctrl_in.int_ena_set_int_ena_set <= mr_int_ena_set_int_ena_set_o;
758:
759: -- INT_MASK_SET
760: mr_ctrl_in.int_mask_set_int_mask_set <= mr_int_mask_set_int_mask_set_o;
761:
762: -- FAULT_STATE
763: mr_ctrl_in.fault_state_era <= cc_stat.is_err_active;
764: mr_ctrl_in.fault_state_erp <= cc_stat.is_err_passive;
765: mr_ctrl_in.fault_state_bof <= cc_stat.is_bus_off;
766:
767: -- REC
768: mr_ctrl_in.rec_rec_val <= cc_stat.rx_err_ctr;
769:
770: -- TEC
771: mr_ctrl_in.tec_tec_val <= cc_stat.tx_err_ctr;
772:
773: -- ERR_NORM
774: mr_ctrl_in.err_norm_err_norm_val <= cc_stat.norm_err_ctr;
775: mr_ctrl_in.err_fd_err_fd_val <= cc_stat.data_err_ctr;
776:
777: -- FILTER_STATUS
778: mr_ctrl_in.filter_status_sfa <= '1' when G_FILT_A_EN else
779: '0';
780:
781: mr_ctrl_in.filter_status_sfb <= '1' when G_FILT_B_EN else
782: '0';
783:
784: mr_ctrl_in.filter_status_sfc <= '1' when G_FILT_C_EN else
785: '0';
786:
787: mr_ctrl_in.filter_status_sfr <= '1' when G_FILT_RANGE_EN else
788: '0';
789:
790: -- RX_MEM_INFO
791: mr_ctrl_in.rx_mem_info_rx_buff_size <= std_logic_vector(to_unsigned(G_RX_BUF_SIZE, 13));
792:
793: p_rx_mem_free_assign : process (rx_mem_free)
794: begin
795: mr_ctrl_in.rx_mem_info_rx_mem_free <= (others => '0');
796: mr_ctrl_in.rx_mem_info_rx_mem_free(G_RX_BUF_PTR_WIDTH downto 0) <= rx_mem_free;
797: end process;
798:
799: -- RX_POINTERS
800: p_rx_write_pointer_assign : process (rx_write_pointer)
801: begin
802: mr_ctrl_in.rx_pointers_rx_wpp <= (others => '0');
803: mr_ctrl_in.rx_pointers_rx_wpp(G_RX_BUF_PTR_WIDTH - 1 downto 0) <= rx_write_pointer;
804: end process;
805:
806: p_rx_read_pointer_assign : process (rx_read_pointer)
807: begin
808: mr_ctrl_in.rx_pointers_rx_rpp <= (others => '0');
809: mr_ctrl_in.rx_pointers_rx_rpp(G_RX_BUF_PTR_WIDTH - 1 downto 0) <= rx_read_pointer;
810: end process;
811:
812: -- RX_STATUS register
813: mr_ctrl_in.rx_status_rxe <= rx_empty;
814: mr_ctrl_in.rx_status_rxf <= rx_full;
815: mr_ctrl_in.rx_status_rxmof <= rx_mof;
816:
817: p_rxfrc_assign : process (rx_frame_count)
818: begin
819: mr_ctrl_in.rx_status_rxfrc <= (others => '0');
820: mr_ctrl_in.rx_status_rxfrc(G_RX_BUF_FRAME_CNT_WIDTH - 1 downto 0) <= rx_frame_count;
821: end process;
822:
823: -- RX_DATA register - Read data word from RX Buffer FIFO.
824: mr_ctrl_in.rx_data_rx_data <= rxb_port_b_data_out;
825:
826: -- TX_STATUS register
827: p_tx_status : process(txtb_state)
828: variable txtb_state_padded : t_txt_bufs_state(7 downto 0);
829: begin
830: txtb_state_padded := (others => (others => '0'));
831: txtb_state_padded(G_TXT_BUF_COUNT - 1 downto 0) := txtb_state;
832:
833: mr_ctrl_in.tx_status_tx1s <= txtb_state_padded(0);
834: mr_ctrl_in.tx_status_tx2s <= txtb_state_padded(1);
835: mr_ctrl_in.tx_status_tx3s <= txtb_state_padded(2);
836: mr_ctrl_in.tx_status_tx4s <= txtb_state_padded(3);
837: mr_ctrl_in.tx_status_tx5s <= txtb_state_padded(4);
838: mr_ctrl_in.tx_status_tx6s <= txtb_state_padded(5);
839: mr_ctrl_in.tx_status_tx7s <= txtb_state_padded(6);
840: mr_ctrl_in.tx_status_tx8s <= txtb_state_padded(7);
841: end process;
842:
843: -- TXTB_INFO
844: mr_ctrl_in.txtb_info_txt_buffer_count <= std_logic_vector(to_unsigned(G_TXT_BUF_COUNT, 4));
845:
846: -- ERR_CAPT
847: mr_ctrl_in.err_capt_err_pos <= cc_stat.err_pos;
848: mr_ctrl_in.err_capt_err_type <= cc_stat.err_type;
849: mr_ctrl_in.err_capt_err_erp <= cc_stat.err_erp;
850:
851: -- RETR_CTR
852: mr_ctrl_in.retr_ctr_retr_ctr_val <= cc_stat.retr_ctr;
853:
854: -- ALC
855: mr_ctrl_in.alc_alc_bit <= cc_stat.alc_bit;
856: mr_ctrl_in.alc_alc_id_field <= cc_stat.alc_id_field;
857:
858: -- TS_INFO
859: mr_ctrl_in.ts_info_ts_bits <= std_logic_vector(to_unsigned(G_TS_BITS, 6));
860:
861: -- TRV_DELAY
862: mr_ctrl_in.trv_delay_trv_delay_value <= trv_delay;
863:
864: -- RX_FR_CTR
865: mr_ctrl_in.rx_fr_ctr_rx_fr_ctr_val <= cc_stat.rx_frame_ctr;
866:
867: -- TX_FR_CTR
868: mr_ctrl_in.tx_fr_ctr_tx_fr_ctr_val <= cc_stat.tx_frame_ctr;
869:
870: -- DEBUG
871: mr_ctrl_in.debug_register_stuff_count <= cc_stat.bst_ctr;
872: mr_ctrl_in.debug_register_destuff_count <= cc_stat.dst_ctr;
873: mr_ctrl_in.debug_register_pc_arb <= pc_dbg.is_arbitration;
874: mr_ctrl_in.debug_register_pc_con <= pc_dbg.is_control;
875: mr_ctrl_in.debug_register_pc_dat <= pc_dbg.is_data;
876: mr_ctrl_in.debug_register_pc_stc <= pc_dbg.is_stuff_count;
877: mr_ctrl_in.debug_register_pc_crc <= pc_dbg.is_crc;
878: mr_ctrl_in.debug_register_pc_crcd <= pc_dbg.is_crc_delim;
879: mr_ctrl_in.debug_register_pc_ack <= pc_dbg.is_ack;
880: mr_ctrl_in.debug_register_pc_ackd <= pc_dbg.is_ack_delim;
881: mr_ctrl_in.debug_register_pc_eof <= pc_dbg.is_eof;
882: mr_ctrl_in.debug_register_pc_int <= pc_dbg.is_intermission;
883: mr_ctrl_in.debug_register_pc_susp <= pc_dbg.is_suspend;
884: mr_ctrl_in.debug_register_pc_ovr <= pc_dbg.is_overload;
885: mr_ctrl_in.debug_register_pc_sof <= pc_dbg.is_sof;
886:
887: -- YOLO
888: mr_ctrl_in.yolo_reg_yolo_val <= YOLO_VAL_RSTVAL;
889:
890: -- TIMESTAMP_LOW, TIMESTAMP_HIGH
891: mr_ctrl_in.timestamp_low_timestamp_low <= timestamp(31 downto 0);
892: mr_ctrl_in.timestamp_high_timestamp_high <= timestamp(63 downto 32);
893:
894: -----------------------------------------------------------------------------------------------
895: -- Assertions / Functional coverage
896: -----------------------------------------------------------------------------------------------
897:
898: -- psl default clock is rising_edge(clk_sys);
899:
900: -- psl no_simul_two_reg_block_access_asrt : assert never
901: -- (control_registers_cs_reg = '1' and test_registers_cs_reg = '1')
902: -- report "Control registers and test registers can't be accessed at once!";
903:
904: -- psl no_rxpe_when_parity_disabled_cov : assert never
905: -- (mr_ctrl_out_i.settings_pchke = '0' and rx_parity_error = '1')
906: -- report "RX Parity error generated when SETTINGS[PCHKE] is disabled.";
907:
908: -- psl no_txpe_when_parity_disabled_cov : assert never
909: -- (mr_ctrl_out_i.settings_pchke = '0' and mr_ctrl_in.status_txpe = '1')
910: -- report "TX Parity error generated when SETTINGS[PCHKE] is disabled.";
911:
912: -- psl no_txdpe_when_parity_disabled_cov : assert never
913: -- (mr_ctrl_out_i.settings_pchke = '0' and mr_ctrl_in.status_txdpe = '1')
914: -- report "TX Double parity error generated when SETTINGS[PCHKE] is disabled.";
915:
916: -- coverage off
917: -- pragma translate_off
918: g_txtb_func_cov : for i in 0 to G_TXT_BUF_COUNT - 1 generate
919: begin
920:
921: p_txtb_per_state_chk : process (txtb_state, mr_ctrl_out_i.settings_pchke)
922: begin
923: if (mr_ctrl_out_i.settings_pchke = '0' and txtb_state(i) = TXT_PER) then
924: report "TXT Buffer in 'Parity error' state when SETTINGS[PCHKE] is disabled."
925: severity error;
926: end if;
927: end process;
928:
929: end generate;
930: -- coverage on
931: -- pragma translate_on
932:
933: end architecture;