File: /__w/ctu-can-regression/ctu-can-regression/src/memory_registers/memory_registers.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 memory_registers is
93: generic (
94: -- Support Filter A
95: G_SUP_FILTA : boolean;
96:
97: -- Support Filter B
98: G_SUP_FILTB : boolean;
99:
100: -- Support Filter C
101: G_SUP_FILTC : boolean;
102:
103: -- Support Range Fi
104: G_SUP_RANGE : boolean;
105:
106: -- Support Test registers
107: G_SUP_TEST_REGISTERS : boolean;
108:
109: -- Support Traffic counters
110: G_SUP_TRAFFIC_CTRS : boolean;
111:
112: -- Support Parity
113: G_SUP_PARITY : boolean;
114:
115: -- Number of TXT Buffers
116: G_TXT_BUFFER_COUNT : natural range 2 to 8;
117:
118: -- Size of RX Buffer
119: G_RX_BUFF_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_BUFF_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: res_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_enable : 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_BUFFER_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_BUFF_PTR_WIDTH downto 0);
228:
229: -- Position of read pointer
230: rx_read_pointer : in std_logic_vector(G_RX_BUFF_PTR_WIDTH - 1 downto 0);
231:
232: -- Position of write pointer
233: rx_write_pointer : in std_logic_vector(G_RX_BUFF_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_BUFFER_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_BUFFER_COUNT - 1 downto 0);
258:
259: -- Command indices (chip selects)
260: mr_tx_command_txbi : out std_logic_vector(G_TXT_BUFFER_COUNT - 1 downto 0);
261:
262: -- TXT Buffer status
263: txtb_state : in t_txt_bufs_state(G_TXT_BUFFER_COUNT - 1 downto 0);
264:
265: -- TXT Buffer Parity Error
266: txtb_parity_error_valid : in std_logic_vector(G_TXT_BUFFER_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_BUFFER_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 memory_registers 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: txtb_port_a_cs_gen : for i in 0 to G_TXT_BUFFER_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 txtb_port_a_cs_gen;
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: chip_sel_reg_proc : process(res_n, clk_sys)
399: begin
400: if (res_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: clk_gate_control_regs_comp : 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_enable => scan_enable, -- IN
438:
439: clk_out => clk_control_regs -- OUT
440: );
441:
442: clk_gate_test_regs_comp : 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_enable => scan_enable, -- IN
450:
451: clk_out => clk_test_regs -- OUT
452: );
453:
454: -----------------------------------------------------------------------------------------------
455: -- Control registers instance
456: -----------------------------------------------------------------------------------------------
457: control_registers_reg_map_comp : 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: SUP_FILT_A => G_SUP_FILTA,
464: SUP_RANGE => G_SUP_RANGE,
465: SUP_FILT_C => G_SUP_FILTC,
466: SUP_FILT_B => G_SUP_FILTB,
467: SUP_TRAFFIC_CTRS => G_SUP_TRAFFIC_CTRS
468: )
469: port map(
470: clk_sys => clk_control_regs, -- IN
471: res_n => soft_res_q_n, -- IN
472: address => adress(7 downto 0), -- IN
473: w_data => data_in, -- IN
474: r_data => control_registers_rdata, -- OUT
475: cs => control_registers_cs, -- IN
476: read => srd, -- IN
477: write => swr, -- IN
478: be => sbe, -- IN
479: lock_1 => reg_lock_1_active, -- IN
480: lock_2 => reg_lock_2_active, -- IN
481: control_registers_out => mr_ctrl_out_i, -- OUT
482: control_registers_in => mr_ctrl_in -- IN
483: );
484: mr_ctrl_out <= mr_ctrl_out_i;
485:
486: -----------------------------------------------------------------------------------------------
487: -- Test registers instance
488: -----------------------------------------------------------------------------------------------
489: test_registers_gen_true : if (G_SUP_TEST_REGISTERS) generate
490: test_registers_reg_map_comp : entity ctu_can_fd_rtl.test_registers_reg_map
491: generic map (
492: DATA_WIDTH => 32,
493: ADDRESS_WIDTH => 8,
494: REGISTERED_READ => true,
495: CLEAR_READ_DATA => false
496: )
497: port map(
498: clk_sys => clk_test_regs, -- IN
499: res_n => soft_res_q_n, -- IN
500: address => adress(7 downto 0), -- IN
501: w_data => data_in, -- IN
502: r_data => test_registers_rdata, -- OUT
503: cs => test_registers_cs, -- IN
504: read => srd, -- IN
505: write => swr, -- IN
506: be => sbe, -- IN
507: lock_1 => reg_lock_1_active, -- IN
508: lock_2 => reg_lock_2_active, -- IN
509: test_registers_out => mr_tst_out_i, -- OUT
510: test_registers_in => mr_tst_in -- IN
511: );
512:
513: -- Padding to full width of possible TXT Buffers
514: txt_buf_test_data_padding_gen : for i in 0 to 7 generate
515:
516: txt_buf_padding_index_gen_true : if (i < G_TXT_BUFFER_COUNT) generate
517: mr_tst_rdata_tst_rdata_txb_i(i) <= mr_tst_rdata_tst_rdata_txb(i);
518: end generate txt_buf_padding_index_gen_true;
519:
520: txt_buf_padding_index_gen_false : if (i >= G_TXT_BUFFER_COUNT) generate
521: mr_tst_rdata_tst_rdata_txb_i(i) <= (others => '0');
522: end generate txt_buf_padding_index_gen_false;
523:
524: end generate;
525:
526: -- Select test read data from RX buffer and TXT buffers
527: with mr_tst_out_i.tst_dest_tst_mtgt select mr_tst_in.tst_rdata_tst_rdata <=
528: mr_tst_rdata_tst_rdata_rxb when TMTGT_RXBUF,
529: mr_tst_rdata_tst_rdata_txb_i(0) when TMTGT_TXTBUF1,
530: mr_tst_rdata_tst_rdata_txb_i(1) when TMTGT_TXTBUF2,
531: mr_tst_rdata_tst_rdata_txb_i(2) when TMTGT_TXTBUF3,
532: mr_tst_rdata_tst_rdata_txb_i(3) when TMTGT_TXTBUF4,
533: mr_tst_rdata_tst_rdata_txb_i(4) when TMTGT_TXTBUF5,
534: mr_tst_rdata_tst_rdata_txb_i(5) when TMTGT_TXTBUF6,
535: mr_tst_rdata_tst_rdata_txb_i(6) when TMTGT_TXTBUF7,
536: mr_tst_rdata_tst_rdata_txb_i(7) when TMTGT_TXTBUF8,
537: (others => '0') when others;
538:
539: end generate test_registers_gen_true;
540:
541: test_registers_gen_false : if (not G_SUP_TEST_REGISTERS) generate
542: test_registers_rdata <= (others => '0');
543: mr_tst_in.tst_rdata_tst_rdata <= (others => '0');
544: mr_tst_out_i <= ('0', '0', (others => '0'), (others => '0'), (others => '0'));
545: mr_tst_rdata_tst_rdata_txb_i <= (others => (others => '0'));
546: end generate;
547:
548: mr_tst_out <= mr_tst_out_i;
549:
550: -----------------------------------------------------------------------------------------------
551: -- Lock signals
552: -----------------------------------------------------------------------------------------------
553: -- Lock 1 - Locked when MODE[TSTM] = 0
554: reg_lock_1_active <= not mr_ctrl_out_i.mode_tstm;
555:
556: -- Lock 2 - Locked when SETTINGS[ENA] = 1
557: reg_lock_2_active <= mr_ctrl_out_i.settings_ena;
558:
559: -----------------------------------------------------------------------------------------------
560: -- Two reset registers:
561: -- 1. Soft reset - Resets memory registers
562: -- 2. Core reset - Resets rest of the core when disabled.
563: --
564: -- Both need to be gated to inactive value in Scan mode since they reset other flops.
565: -----------------------------------------------------------------------------------------------
566:
567: -- Writing MODE[RST] = 1 causes Soft Reset
568: soft_res_d_n <= not mr_ctrl_out_i.mode_rst;
569:
570: soft_rst_rst_reg_inst : entity ctu_can_fd_rtl.rst_reg
571: generic map (
572: G_RESET_POLARITY => '0'
573: )
574: port map(
575: -- Clock and Reset
576: clk => clk_sys, -- IN
577: arst => res_n, -- IN
578:
579: -- Flip flop input / output
580: d => soft_res_d_n, -- IN
581: q => soft_res_q_n, -- OUT
582:
583: -- Scan mode control
584: scan_enable => scan_enable -- IN
585: );
586:
587: -- Reset of the rest of core is the same as soft reset, but it is also active when
588: -- SETTINGS[ENA] = '0'. Thus disabled node has all of its logic in reset!
589: res_core_d_n <= '0' when (mr_ctrl_out_i.mode_rst = '1' or mr_ctrl_out_i.settings_ena = '0')
590: else
591: '1';
592:
593: global_rst_rst_reg_inst : entity ctu_can_fd_rtl.rst_reg
594: generic map (
595: G_RESET_POLARITY => '0'
596: )
597: port map(
598: -- Clock and Reset
599: clk => clk_sys, -- IN
600: arst => res_n, -- IN
601:
602: -- Flip flop input / output
603: d => res_core_d_n, -- IN
604: q => res_core_n, -- OUT
605:
606: -- Scan mode control
607: scan_enable => scan_enable -- IN
608: );
609:
610: -----------------------------------------------------------------------------------------------
611: -- Reset propagation to output
612: -----------------------------------------------------------------------------------------------
613: res_soft_n <= soft_res_q_n;
614:
615: -----------------------------------------------------------------------------------------------
616: -----------------------------------------------------------------------------------------------
617: -- Control registers - Write Data to Driving Bus connection
618: -----------------------------------------------------------------------------------------------
619: -----------------------------------------------------------------------------------------------
620:
621: mr_tx_priority(0) <= mr_ctrl_out_i.tx_priority_txt1p;
622: mr_tx_command_txbi(0) <= mr_ctrl_out_i.tx_command_txb1;
623:
624: mr_tx_priority(1) <= mr_ctrl_out_i.tx_priority_txt2p;
625: mr_tx_command_txbi(1) <= mr_ctrl_out_i.tx_command_txb2 when (mr_ctrl_out_i.mode_txbbm = '0')
626: else
627: mr_ctrl_out_i.tx_command_txb1 or mr_ctrl_out_i.tx_command_txb2;
628:
629: mt_2_txt_buffs : if (G_TXT_BUFFER_COUNT > 2) generate
630: mr_tx_priority(2) <= mr_ctrl_out_i.tx_priority_txt3p;
631: mr_tx_command_txbi(2) <= mr_ctrl_out_i.tx_command_txb3;
632: end generate;
633:
634: mt_3_txt_buffs : if (G_TXT_BUFFER_COUNT > 3) generate
635: mr_tx_priority(3) <= mr_ctrl_out_i.tx_priority_txt4p;
636: mr_tx_command_txbi(3) <= mr_ctrl_out_i.tx_command_txb4 when (mr_ctrl_out_i.mode_txbbm = '0')
637: else
638: mr_ctrl_out_i.tx_command_txb3 or mr_ctrl_out_i.tx_command_txb4;
639: end generate;
640:
641: mt_4_txt_buffs : if (G_TXT_BUFFER_COUNT > 4) generate
642: mr_tx_priority(4) <= mr_ctrl_out_i.tx_priority_txt5p;
643: mr_tx_command_txbi(4) <= mr_ctrl_out_i.tx_command_txb5;
644: end generate;
645:
646: mt_5_txt_buffs : if (G_TXT_BUFFER_COUNT > 5) generate
647: mr_tx_priority(5) <= mr_ctrl_out_i.tx_priority_txt6p;
648: mr_tx_command_txbi(5) <= mr_ctrl_out_i.tx_command_txb6 when (mr_ctrl_out_i.mode_txbbm = '0')
649: else
650: mr_ctrl_out_i.tx_command_txb5 or mr_ctrl_out_i.tx_command_txb6;
651: end generate;
652:
653: mt_6_txt_buffs : if (G_TXT_BUFFER_COUNT > 6) generate
654: mr_tx_priority(6) <= mr_ctrl_out_i.tx_priority_txt7p;
655: mr_tx_command_txbi(6) <= mr_ctrl_out_i.tx_command_txb7;
656: end generate;
657:
658: mt_7_txt_buffs : if (G_TXT_BUFFER_COUNT > 7) generate
659: mr_tx_priority(7) <= mr_ctrl_out_i.tx_priority_txt8p;
660: mr_tx_command_txbi(7) <= mr_ctrl_out_i.tx_command_txb8 when (mr_ctrl_out_i.mode_txbbm = '0')
661: else
662: mr_ctrl_out_i.tx_command_txb7 or mr_ctrl_out_i.tx_command_txb8;
663: end generate;
664:
665: -----------------------------------------------------------------------------------------------
666: -----------------------------------------------------------------------------------------------
667: -- Control registers - Read Data to status signals connection
668: -----------------------------------------------------------------------------------------------
669: -----------------------------------------------------------------------------------------------
670:
671: -- DEVICE ID
672: mr_ctrl_in.device_id_device_id <= G_DEVICE_ID;
673:
674: -- VERSION
675: mr_ctrl_in.version_ver_minor <= G_VERSION_MINOR;
676: mr_ctrl_in.version_ver_major <= G_VERSION_MAJOR;
677:
678: -- STATUS
679: mr_ctrl_in.status_idle <= '1' when (cc_stat.is_bus_off = '1') else
680: '1' when (cc_stat.is_idle = '1') else
681: '0';
682: mr_ctrl_in.status_ewl <= cc_stat.status_ewl;
683: mr_ctrl_in.status_txs <= cc_stat.is_transmitter;
684: mr_ctrl_in.status_rxs <= cc_stat.is_receiver;
685:
686: -- Go through TXT Buffers and check at least one is empty
687: txnf_calc_proc : process(txtb_state)
688: begin
689: mr_ctrl_in.status_txnf <= '0';
690: for i in 0 to G_TXT_BUFFER_COUNT - 1 loop
691: if (txtb_state(i) = TXT_ETY) then
692: mr_ctrl_in.status_txnf <= '1';
693: end if;
694: end loop;
695: end process;
696:
697: mr_ctrl_in.status_rxne <= not rx_empty;
698: mr_ctrl_in.status_dor <= rx_data_overrun;
699: mr_ctrl_in.status_eft <= pc_dbg.is_err;
700: mr_ctrl_in.status_pexs <= cc_stat.status_pexs;
701: mr_ctrl_in.status_rxpe <= rx_parity_error;
702:
703: -- TXT Buffer parity error and double parity error
704: txpe_flag_proc : process(soft_res_q_n, clk_sys)
705: begin
706: if (soft_res_q_n = '0') then
707: mr_ctrl_in.status_txpe <= '0';
708: mr_ctrl_in.status_txdpe <= '0';
709: elsif rising_edge(clk_sys) then
710: for i in 0 to G_TXT_BUFFER_COUNT - 1 loop
711: if (txtb_parity_error_valid(i) = '1') then
712: mr_ctrl_in.status_txpe <= '1';
713: end if;
714:
715: if (txtb_bb_parity_error(i / 2) = '1') then
716: mr_ctrl_in.status_txdpe <= '1';
717: end if;
718: end loop;
719:
720: if (mr_ctrl_out_i.command_ctxpe = '1') then
721: mr_ctrl_in.status_txpe <= '0';
722: end if;
723:
724: if (mr_ctrl_out_i.command_ctxdpe = '1') then
725: mr_ctrl_in.status_txdpe <= '0';
726: end if;
727: end if;
728: end process;
729:
730: mr_ctrl_in.status_stcnt <= '1' when G_SUP_TRAFFIC_CTRS
731: else
732: '0';
733: mr_ctrl_in.status_sprt <= '1' when G_SUP_PARITY
734: else
735: '0';
736: mr_ctrl_in.status_strgs <= '1' when G_SUP_TEST_REGISTERS
737: else
738: '0';
739:
740: -- INT_STAT
741: mr_ctrl_in.int_stat_rxi <= mr_int_stat_rxi_o;
742: mr_ctrl_in.int_stat_txi <= mr_int_stat_txi_o;
743: mr_ctrl_in.int_stat_ewli <= mr_int_stat_ewli_o;
744: mr_ctrl_in.int_stat_doi <= mr_int_stat_doi_o;
745: mr_ctrl_in.int_stat_fcsi <= mr_int_stat_fcsi_o;
746: mr_ctrl_in.int_stat_ali <= mr_int_stat_ali_o;
747: mr_ctrl_in.int_stat_bei <= mr_int_stat_bei_o;
748: mr_ctrl_in.int_stat_ofi <= mr_int_stat_ofi_o;
749: mr_ctrl_in.int_stat_rxfi <= mr_int_stat_rxfi_o;
750: mr_ctrl_in.int_stat_bsi <= mr_int_stat_bsi_o;
751: mr_ctrl_in.int_stat_rbnei <= mr_int_stat_rbnei_o;
752: mr_ctrl_in.int_stat_txbhci <= mr_int_stat_txbhci_o;
753:
754: -- INT_ENA_SET
755: mr_ctrl_in.int_ena_set_int_ena_set <= mr_int_ena_set_int_ena_set_o;
756:
757: -- INT_MASK_SET
758: mr_ctrl_in.int_mask_set_int_mask_set <= mr_int_mask_set_int_mask_set_o;
759:
760: -- FAULT_STATE
761: mr_ctrl_in.fault_state_era <= cc_stat.is_err_active;
762: mr_ctrl_in.fault_state_erp <= cc_stat.is_err_passive;
763: mr_ctrl_in.fault_state_bof <= cc_stat.is_bus_off;
764:
765: -- REC
766: mr_ctrl_in.rec_rec_val <= cc_stat.rx_err_ctr;
767:
768: -- TEC
769: mr_ctrl_in.tec_tec_val <= cc_stat.tx_err_ctr;
770:
771: -- ERR_NORM
772: mr_ctrl_in.err_norm_err_norm_val <= cc_stat.norm_err_ctr;
773: mr_ctrl_in.err_fd_err_fd_val <= cc_stat.data_err_ctr;
774:
775: -- FILTER_STATUS
776: mr_ctrl_in.filter_status_sfa <= '1' when G_SUP_FILTA else
777: '0';
778:
779: mr_ctrl_in.filter_status_sfb <= '1' when G_SUP_FILTB else
780: '0';
781:
782: mr_ctrl_in.filter_status_sfc <= '1' when G_SUP_FILTC else
783: '0';
784:
785: mr_ctrl_in.filter_status_sfr <= '1' when G_SUP_RANGE else
786: '0';
787:
788: -- RX_MEM_INFO
789: mr_ctrl_in.rx_mem_info_rx_buff_size <= std_logic_vector(to_unsigned(G_RX_BUFF_SIZE, 13));
790:
791: rx_mem_free_assign_proc : process (rx_mem_free)
792: begin
793: mr_ctrl_in.rx_mem_info_rx_mem_free <= (others => '0');
794: mr_ctrl_in.rx_mem_info_rx_mem_free(G_RX_BUFF_PTR_WIDTH downto 0) <= rx_mem_free;
795: end process;
796:
797: -- RX_POINTERS
798: rx_write_pointer_assign_proc : process (rx_write_pointer)
799: begin
800: mr_ctrl_in.rx_pointers_rx_wpp <= (others => '0');
801: mr_ctrl_in.rx_pointers_rx_wpp(G_RX_BUFF_PTR_WIDTH - 1 downto 0) <= rx_write_pointer;
802: end process;
803:
804: rx_read_pointer_assign_proc : process (rx_read_pointer)
805: begin
806: mr_ctrl_in.rx_pointers_rx_rpp <= (others => '0');
807: mr_ctrl_in.rx_pointers_rx_rpp(G_RX_BUFF_PTR_WIDTH - 1 downto 0) <= rx_read_pointer;
808: end process;
809:
810: -- RX_STATUS register
811: mr_ctrl_in.rx_status_rxe <= rx_empty;
812: mr_ctrl_in.rx_status_rxf <= rx_full;
813: mr_ctrl_in.rx_status_rxmof <= rx_mof;
814:
815: rxfrc_assign_proc : process (rx_frame_count)
816: begin
817: mr_ctrl_in.rx_status_rxfrc <= (others => '0');
818: mr_ctrl_in.rx_status_rxfrc(G_RX_BUF_FRAME_CNT_WIDTH - 1 downto 0) <= rx_frame_count;
819: end process;
820:
821: -- RX_DATA register - Read data word from RX Buffer FIFO.
822: mr_ctrl_in.rx_data_rx_data <= rxb_port_b_data_out;
823:
824: -- TX_STATUS register
825: tx_status_proc : process(txtb_state)
826: variable txtb_state_padded : t_txt_bufs_state(7 downto 0);
827: begin
828: txtb_state_padded := (others => (others => '0'));
829: txtb_state_padded(G_TXT_BUFFER_COUNT - 1 downto 0) := txtb_state;
830:
831: mr_ctrl_in.tx_status_tx1s <= txtb_state_padded(0);
832: mr_ctrl_in.tx_status_tx2s <= txtb_state_padded(1);
833: mr_ctrl_in.tx_status_tx3s <= txtb_state_padded(2);
834: mr_ctrl_in.tx_status_tx4s <= txtb_state_padded(3);
835: mr_ctrl_in.tx_status_tx5s <= txtb_state_padded(4);
836: mr_ctrl_in.tx_status_tx6s <= txtb_state_padded(5);
837: mr_ctrl_in.tx_status_tx7s <= txtb_state_padded(6);
838: mr_ctrl_in.tx_status_tx8s <= txtb_state_padded(7);
839: end process;
840:
841: -- TXTB_INFO
842: mr_ctrl_in.txtb_info_txt_buffer_count <= std_logic_vector(to_unsigned(G_TXT_BUFFER_COUNT, 4));
843:
844: -- ERR_CAPT
845: mr_ctrl_in.err_capt_err_pos <= cc_stat.err_pos;
846: mr_ctrl_in.err_capt_err_type <= cc_stat.err_type;
847: mr_ctrl_in.err_capt_err_erp <= cc_stat.err_erp;
848:
849: -- RETR_CTR
850: mr_ctrl_in.retr_ctr_retr_ctr_val <= cc_stat.retr_ctr;
851:
852: -- ALC
853: mr_ctrl_in.alc_alc_bit <= cc_stat.alc_bit;
854: mr_ctrl_in.alc_alc_id_field <= cc_stat.alc_id_field;
855:
856: -- TS_INFO
857: mr_ctrl_in.ts_info_ts_bits <= std_logic_vector(to_unsigned(G_TS_BITS, 6));
858:
859: -- TRV_DELAY
860: mr_ctrl_in.trv_delay_trv_delay_value <= trv_delay;
861:
862: -- RX_FR_CTR
863: mr_ctrl_in.rx_fr_ctr_rx_fr_ctr_val <= cc_stat.rx_frame_ctr;
864:
865: -- TX_FR_CTR
866: mr_ctrl_in.tx_fr_ctr_tx_fr_ctr_val <= cc_stat.tx_frame_ctr;
867:
868: -- DEBUG
869: mr_ctrl_in.debug_register_stuff_count <= cc_stat.bst_ctr;
870: mr_ctrl_in.debug_register_destuff_count <= cc_stat.dst_ctr;
871: mr_ctrl_in.debug_register_pc_arb <= pc_dbg.is_arbitration;
872: mr_ctrl_in.debug_register_pc_con <= pc_dbg.is_control;
873: mr_ctrl_in.debug_register_pc_dat <= pc_dbg.is_data;
874: mr_ctrl_in.debug_register_pc_stc <= pc_dbg.is_stuff_count;
875: mr_ctrl_in.debug_register_pc_crc <= pc_dbg.is_crc;
876: mr_ctrl_in.debug_register_pc_crcd <= pc_dbg.is_crc_delim;
877: mr_ctrl_in.debug_register_pc_ack <= pc_dbg.is_ack;
878: mr_ctrl_in.debug_register_pc_ackd <= pc_dbg.is_ack_delim;
879: mr_ctrl_in.debug_register_pc_eof <= pc_dbg.is_eof;
880: mr_ctrl_in.debug_register_pc_int <= pc_dbg.is_intermission;
881: mr_ctrl_in.debug_register_pc_susp <= pc_dbg.is_suspend;
882: mr_ctrl_in.debug_register_pc_ovr <= pc_dbg.is_overload;
883: mr_ctrl_in.debug_register_pc_sof <= pc_dbg.is_sof;
884:
885: -- YOLO
886: mr_ctrl_in.yolo_reg_yolo_val <= YOLO_VAL_RSTVAL;
887:
888: -- TIMESTAMP_LOW, TIMESTAMP_HIGH
889: mr_ctrl_in.timestamp_low_timestamp_low <= timestamp(31 downto 0);
890: mr_ctrl_in.timestamp_high_timestamp_high <= timestamp(63 downto 32);
891:
892: -----------------------------------------------------------------------------------------------
893: -- Assertions / Functional coverage
894: -----------------------------------------------------------------------------------------------
895:
896: -- psl default clock is rising_edge(clk_sys);
897:
898: -- psl no_simul_two_reg_block_access_asrt : assert never
899: -- (control_registers_cs_reg = '1' and test_registers_cs_reg = '1')
900: -- report "Control registers and test registers can't be accessed at once!";
901:
902: -- psl no_rxpe_when_parity_disabled_cov : assert never
903: -- (mr_ctrl_out_i.settings_pchke = '0' and rx_parity_error = '1')
904: -- report "RX Parity error generated when SETTINGS[PCHKE] is disabled.";
905:
906: -- psl no_txpe_when_parity_disabled_cov : assert never
907: -- (mr_ctrl_out_i.settings_pchke = '0' and mr_ctrl_in.status_txpe = '1')
908: -- report "TX Parity error generated when SETTINGS[PCHKE] is disabled.";
909:
910: -- psl no_txdpe_when_parity_disabled_cov : assert never
911: -- (mr_ctrl_out_i.settings_pchke = '0' and mr_ctrl_in.status_txdpe = '1')
912: -- report "TX Double parity error generated when SETTINGS[PCHKE] is disabled.";
913:
914: -- coverage off
915: -- pragma translate_off
916: txtb_func_cov_gen : for i in 0 to G_TXT_BUFFER_COUNT - 1 generate
917: begin
918:
919: process (txtb_state, mr_ctrl_out_i.settings_pchke)
920: begin
921: if (mr_ctrl_out_i.settings_pchke = '0' and txtb_state(i) = TXT_PER) then
922: report "TXT Buffer in 'Parity error' state when SETTINGS[PCHKE] is disabled."
923: severity error;
924: end if;
925: end process;
926:
927: end generate;
928: -- coverage on
929: -- pragma translate_on
930:
931: end architecture;