File: /__w/ctu-can-regression/ctu-can-regression/src/txt_buffer/txt_buffer_ram.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: -- TXT Buffer RAM
71: --
72: -- Purpose:
73: -- Wrapper for dual port RAM in TXT Buffer.
74: --
75: -- Memory parameters:
76: -- Depth: 20
77: -- Word size: 32 bits
78: -- Read: Synchronous
79: -- Write: Synchronous
80: -- Port A: Write Only
81: -- Port B: Read only
82: --
83: --------------------------------------------------------------------------------
84:
85: Library ieee;
86: use ieee.std_logic_1164.all;
87: use ieee.numeric_std.ALL;
88: use ieee.math_real.ALL;
89:
90: Library ctu_can_fd_rtl;
91: use ctu_can_fd_rtl.can_constants_pkg.all;
92: use ctu_can_fd_rtl.can_types_pkg.all;
93:
94: use ctu_can_fd_rtl.CAN_FD_register_map.all;
95: use ctu_can_fd_rtl.CAN_FD_frame_format.all;
96:
97: use ctu_can_fd_rtl.can_registers_pkg.all;
98:
99: entity txt_buffer_ram is
100: generic (
101: -- TXT buffer ID
102: G_ID : natural;
103:
104: -- TXT Buffer parity
105: G_SUP_PARITY : boolean;
106:
107: -- TXT Buffer RAM is resettable
108: G_RESET_TXT_BUF_RAM : boolean
109: );
110: port (
111: -------------------------------------------------------------------------------------------
112: -- Clock and Asynchronous reset
113: -------------------------------------------------------------------------------------------
114: clk_sys : in std_logic;
115: res_n : in std_logic;
116:
117: -------------------------------------------------------------------------------------------
118: -- Parity configuration
119: -------------------------------------------------------------------------------------------
120: mr_settings_pchke : in std_logic;
121:
122: -------------------------------------------------------------------------------------------
123: -- Memory Testability
124: -------------------------------------------------------------------------------------------
125: mr_tst_control_tmaena : in std_logic;
126: mr_tst_control_twrstb : in std_logic;
127: mr_tst_dest_tst_addr : in std_logic_vector(4 downto 0);
128: mr_tst_dest_tst_mtgt : in std_logic_vector(3 downto 0);
129: mr_tst_wdata_tst_wdata : in std_logic_vector(31 downto 0);
130:
131: mr_tst_rdata_tst_rdata : out std_logic_vector(31 downto 0);
132:
133: -------------------------------------------------------------------------------------------
134: -- Port A - Write (from Memory registers)
135: -------------------------------------------------------------------------------------------
136: txtb_port_a_address : in std_logic_vector(4 downto 0);
137: txtb_port_a_data_in : in std_logic_vector(31 downto 0);
138: txtb_port_a_parity : in std_logic;
139: txtb_port_a_write : in std_logic;
140: txtb_port_a_be : in std_logic_vector(3 downto 0);
141:
142: -------------------------------------------------------------------------------------------
143: -- Port B - Read (from CAN Core)
144: -------------------------------------------------------------------------------------------
145: txtb_port_b_address : in std_logic_vector(4 downto 0);
146: txtb_port_b_data_out : out std_logic_vector(31 downto 0);
147:
148: -------------------------------------------------------------------------------------------
149: -- Parity mismatch
150: -------------------------------------------------------------------------------------------
151: parity_mismatch : out std_logic
152: );
153: end entity;
154:
155: architecture rtl of txt_buffer_ram is
156:
157: -----------------------------------------------------------------------------------------------
158: -- FRAME_FORMAT_W
159: -- IDENTIFIER_W
160: -- TIMESTAMP_U_W
161: -- TIMESTAMP_L_W
162: -- DATA_*_* (16 words)
163: -- FRAME_TEST_W
164: -----------------------------------------------------------------------------------------------
165: constant C_TXT_BUF_DEPTH : natural := 21;
166:
167: signal txtb_port_a_address_i : std_logic_vector(4 downto 0);
168: signal txtb_port_a_write_i : std_logic;
169: signal txtb_port_a_data_i : std_logic_vector(31 downto 0);
170:
171: signal txtb_port_b_address_i : std_logic_vector(4 downto 0);
172: signal txtb_port_b_data_out_i : std_logic_vector(31 downto 0);
173:
174: signal tst_ena : std_logic;
175:
176: signal parity_word : std_logic_vector(C_TXT_BUF_DEPTH - 1 downto 0);
177: signal parity_read_real : std_logic;
178: signal parity_read_exp : std_logic;
179:
180: begin
181:
182: -----------------------------------------------------------------------------------------------
183: -- RAM is implemented as synchronous inferred RAM for FPGAs. Synchronous RAM is chosen since
184: -- some FPGA families does not provide inferred RAM for asynchronously read data (in the same
185: -- clock cycle).
186: -----------------------------------------------------------------------------------------------
187: dp_inf_ram_be_inst : entity ctu_can_fd_rtl.dp_inf_ram_be
188: generic map (
189: G_WORD_WIDTH => 32,
190: G_DEPTH => C_TXT_BUF_DEPTH,
191: G_ADDRESS_WIDTH => txtb_port_a_address'length,
192: G_SYNC_READ => true,
193: G_RESETABLE => G_RESET_TXT_BUF_RAM
194: )
195: port map(
196: clk_sys => clk_sys, -- IN
197: res_n => res_n, -- IN
198:
199: addr_a => txtb_port_a_address_i, -- IN
200: write => txtb_port_a_write_i, -- IN
201: data_in => txtb_port_a_data_i, -- IN
202: be => txtb_port_a_be, -- IN
203:
204: addr_b => txtb_port_b_address_i, -- IN
205: data_out => txtb_port_b_data_out_i -- OUT
206: );
207: txtb_port_b_data_out <= txtb_port_b_data_out_i;
208:
209: -- Note: If you want to replace RAM by dedicated memory macro,
210: -- place it instead of "dp_inf_ram_be_inst"!
211:
212: -----------------------------------------------------------------------------------------------
213: -----------------------------------------------------------------------------------------------
214: -- Parity protection
215: -----------------------------------------------------------------------------------------------
216: -----------------------------------------------------------------------------------------------
217: parity_true_gen : if (G_SUP_PARITY) generate
218:
219: -------------------------------------------------------------------------------------------
220: -- Storing Parity word
221: -------------------------------------------------------------------------------------------
222: parity_word_proc : process(res_n, clk_sys)
223: begin
224: if (res_n = '0') then
225: parity_word <= (others => '0');
226: elsif rising_edge(clk_sys) then
227: if (txtb_port_a_write = '1') then
228: parity_word(to_integer(unsigned(txtb_port_a_address))) <= txtb_port_a_parity;
229: end if;
230: end if;
231: end process;
232:
233: -------------------------------------------------------------------------------------------
234: -- Parity decoding
235: -------------------------------------------------------------------------------------------
236: parity_calculator_read_inst : entity ctu_can_fd_rtl.parity_calculator
237: generic map (
238: G_WIDTH => 32,
239: G_PARITY_TYPE => C_PARITY_TYPE
240: )
241: port map(
242: data_in => txtb_port_b_data_out_i,
243: parity => parity_read_real
244: );
245:
246: -------------------------------------------------------------------------------------------
247: -- Parity check
248: --
249: -- When reading from TXT Buffer RAM, read data are obtained one clock cycle later!
250: -------------------------------------------------------------------------------------------
251: parity_check_proc : process(clk_sys, res_n)
252: begin
253: if (res_n = '0') then
254: parity_read_exp <= '0';
255: elsif (rising_edge(clk_sys)) then
256: parity_read_exp <= parity_word(to_integer(unsigned(txtb_port_b_address)));
257: end if;
258: end process;
259:
260: parity_mismatch <= '1' when (parity_read_real /= parity_read_exp) and (mr_settings_pchke = '1')
261: else
262: '0';
263:
264: end generate;
265:
266: parity_false_gen : if (not G_SUP_PARITY) generate
267: parity_mismatch <= '0';
268: parity_read_exp <= '0';
269: parity_read_real <= '0';
270: parity_word <= (others => '0');
271: end generate;
272:
273: -----------------------------------------------------------------------------------------------
274: -- Memory testability
275: -----------------------------------------------------------------------------------------------
276: tst_ena <= '1' when (mr_tst_control_tmaena = '1') and
277: (mr_tst_dest_tst_mtgt = std_logic_vector(to_unsigned(G_ID + 2, 4)))
278: else
279: '0';
280:
281: -- Write port
282: txtb_port_a_address_i <= txtb_port_a_address when (tst_ena = '0')
283: else
284: mr_tst_dest_tst_addr(4 downto 0);
285:
286: txtb_port_a_write_i <= txtb_port_a_write when (tst_ena = '0')
287: else
288: mr_tst_control_twrstb;
289:
290: txtb_port_a_data_i <= txtb_port_a_data_in when (tst_ena = '0')
291: else
292: mr_tst_wdata_tst_wdata;
293:
294: -- Read port
295: txtb_port_b_address_i <= txtb_port_b_address when (tst_ena = '0')
296: else
297: mr_tst_dest_tst_addr(4 downto 0);
298:
299: mr_tst_rdata_tst_rdata <= txtb_port_b_data_out_i when (tst_ena = '1')
300: else
301: (others => '0');
302:
303: end architecture;