File: /__w/ctu-can-regression/ctu-can-regression/src/rx_buffer/rx_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: -- RX Buffer RAM
71: --
72: -- Purpose:
73: -- Wrapper for dual port RAM on RX Buffer! Port A - write only, Port B - read
74: -- only.
75: --
76: -- Memory parameters:
77: -- Depth: G_RX_BUFF_SIZE
78: -- Word size: 32 bits
79: -- Read: Synchronous
80: -- Write: Synchronous
81: -- Port A: Write Only
82: -- Port B: Read only
83: --
84: --------------------------------------------------------------------------------
85:
86: Library ieee;
87: use ieee.std_logic_1164.all;
88: use ieee.numeric_std.ALL;
89: use ieee.math_real.ALL;
90:
91: Library ctu_can_fd_rtl;
92: use ctu_can_fd_rtl.can_constants_pkg.all;
93: use ctu_can_fd_rtl.can_types_pkg.all;
94:
95: use ctu_can_fd_rtl.CAN_FD_register_map.all;
96: use ctu_can_fd_rtl.CAN_FD_frame_format.all;
97:
98: use ctu_can_fd_rtl.can_registers_pkg.all;
99:
100: entity rx_buffer_ram is
101: generic (
102: -- RX Buffer size
103: G_RX_BUFF_SIZE : natural range 32 to 4096;
104:
105: -- Width of RX Buffer pointers
106: G_RX_BUFF_PTR_WIDTH : natural range 5 to 12;
107:
108: -- Add parity to RX Buffer RAM
109: G_SUP_PARITY : boolean;
110:
111: -- Reset RX Buffer RAM
112: G_RESET_RX_BUF_RAM : boolean
113: );
114: port(
115: -------------------------------------------------------------------------------------------
116: -- Clocks and Asynchronous reset
117: -------------------------------------------------------------------------------------------
118: res_n : in std_logic;
119: clk_sys : in std_logic;
120:
121: -------------------------------------------------------------------------------------------
122: -- Memory testability
123: -------------------------------------------------------------------------------------------
124: mr_tst_control_tmaena : in std_logic;
125: mr_tst_control_twrstb : in std_logic;
126: mr_tst_dest_tst_addr : in std_logic_vector(15 downto 0);
127: mr_tst_dest_tst_mtgt : in std_logic_vector(3 downto 0);
128: mr_tst_wdata_tst_wdata : in std_logic_vector(31 downto 0);
129:
130: mr_tst_rdata_tst_rdata : out std_logic_vector(31 downto 0);
131:
132: -------------------------------------------------------------------------------------------
133: -- Port A - Write (from CAN Core)
134: -------------------------------------------------------------------------------------------
135: rxb_port_a_address : in std_logic_vector(G_RX_BUFF_PTR_WIDTH - 1 downto 0);
136: rxb_port_a_data_in : in std_logic_vector(31 downto 0);
137: rxb_port_a_write : in std_logic;
138:
139: -------------------------------------------------------------------------------------------
140: -- Port B - Read (from Memory registers)
141: -------------------------------------------------------------------------------------------
142: rxb_port_b_address : in std_logic_vector(G_RX_BUFF_PTR_WIDTH - 1 downto 0);
143: rxb_port_b_data_out : out std_logic_vector(31 downto 0);
144:
145: -------------------------------------------------------------------------------------------
146: -- Parity mismatch
147: -------------------------------------------------------------------------------------------
148: parity_mismatch : out std_logic
149: );
150: end entity;
151:
152: architecture rtl of rx_buffer_ram is
153:
154: signal rxb_port_a_address_i : std_logic_vector(G_RX_BUFF_PTR_WIDTH - 1 downto 0);
155: signal rxb_port_a_write_i : std_logic;
156: signal rxb_port_a_data_in_i : std_logic_vector(31 downto 0);
157: signal rxb_port_b_address_i : std_logic_vector(G_RX_BUFF_PTR_WIDTH - 1 downto 0);
158: signal rxb_port_b_data_out_i : std_logic_vector(31 downto 0);
159:
160: signal mr_tst_dest_tst_addr_pad : std_logic_vector(15 downto 0);
161:
162: signal tst_ena : std_logic;
163:
164: signal parity_word : std_logic_vector(G_RX_BUFF_SIZE - 1 downto 0);
165: signal parity_write : std_logic;
166: signal parity_read_real : std_logic;
167: signal parity_read_exp : std_logic;
168:
169: begin
170:
171: -------------------------------------------------------------------------------------------
172: -- RAM is implemented as synchronous inferred RAM for FPGAs. Synchronous RAM is chosen
173: -- since some FPGA families does not provide inferred RAM for asynchronously read data (in
174: -- the same clock cycle).
175: -------------------------------------------------------------------------------------------
176: dp_inf_ram_inst : entity ctu_can_fd_rtl.dp_inf_ram
177: generic map (
178: G_WORD_WIDTH => 32,
179: G_DEPTH => G_RX_BUFF_SIZE,
180: G_ADDRESS_WIDTH => G_RX_BUFF_PTR_WIDTH,
181: G_SYNC_READ => true,
182: G_RESETABLE => G_RESET_RX_BUF_RAM
183: )
184: port map(
185: clk_sys => clk_sys, -- IN
186: res_n => res_n, -- IN
187:
188: addr_A => rxb_port_a_address_i, -- IN
189: write => rxb_port_a_write_i, -- IN
190: data_in => rxb_port_a_data_in_i, -- IN
191:
192: addr_B => rxb_port_b_address_i, -- IN
193: data_out => rxb_port_b_data_out_i -- OUT
194: );
195: rxb_port_b_data_out <= rxb_port_b_data_out_i;
196:
197: -- Note: If you want to replace RAM by dedicated memory macro,
198: -- place it instead of "dp_inf_ram_inst"!
199:
200: -----------------------------------------------------------------------------------------------
201: -----------------------------------------------------------------------------------------------
202: -- Parity protection
203: -----------------------------------------------------------------------------------------------
204: -----------------------------------------------------------------------------------------------
205: parity_true_gen : if (G_SUP_PARITY) generate
206: begin
207:
208: -------------------------------------------------------------------------------------------
209: -- Parity encoding
210: -------------------------------------------------------------------------------------------
211: parity_calculator_write_inst : entity ctu_can_fd_rtl.parity_calculator
212: generic map (
213: G_WIDTH => 32,
214: G_PARITY_TYPE => C_PARITY_TYPE
215: )
216: port map(
217: data_in => rxb_port_a_data_in,
218: parity => parity_write
219: );
220:
221: -------------------------------------------------------------------------------------------
222: -- Parity memory (vector with per word bit of RAM)
223: -------------------------------------------------------------------------------------------
224: parity_mem_proc : process(clk_sys, res_n)
225: begin
226: if (res_n = '0') then
227: parity_word <= (others => '0');
228: elsif (rising_edge(clk_sys)) then
229: if (rxb_port_a_write = '1') then
230: parity_word(to_integer(unsigned(rxb_port_a_address))) <= parity_write;
231: end if;
232: end if;
233: end process;
234:
235: -------------------------------------------------------------------------------------------
236: -- Parity decoding
237: -------------------------------------------------------------------------------------------
238: parity_calculator_read_inst : entity ctu_can_fd_rtl.parity_calculator
239: generic map (
240: G_WIDTH => 32,
241: G_PARITY_TYPE => C_PARITY_TYPE
242: )
243: port map(
244: data_in => rxb_port_b_data_out_i,
245: parity => parity_read_real
246: );
247:
248: -------------------------------------------------------------------------------------------
249: -- Parity check
250: --
251: -- When reading from RX Buffer RAM, read data are obtained one clock cycle later!
252: -------------------------------------------------------------------------------------------
253: parity_check_proc : process(clk_sys, res_n)
254: begin
255: if (res_n = '0') then
256: parity_read_exp <= '0';
257: elsif (rising_edge(clk_sys)) then
258: parity_read_exp <= parity_word(to_integer(unsigned(rxb_port_b_address)));
259: end if;
260: end process;
261:
262: parity_mismatch <= '1' when (parity_read_real /= parity_read_exp)
263: else
264: '0';
265:
266: end generate parity_true_gen;
267:
268: parity_false_gen : if (not G_SUP_PARITY) generate
269: parity_mismatch <= '0';
270: parity_read_real <= '0';
271: parity_read_exp <= '0';
272: parity_word <= (others => '0');
273: parity_write <= '0';
274: end generate;
275:
276:
277: -----------------------------------------------------------------------------------------------
278: -----------------------------------------------------------------------------------------------
279: -- Memory testability
280: --
281: -- When memory test is enabled, control by Test registers.
282: -----------------------------------------------------------------------------------------------
283: -----------------------------------------------------------------------------------------------
284: process (mr_tst_dest_tst_addr)
285: begin
286: mr_tst_dest_tst_addr_pad <=
287: std_logic_vector(unsigned(mr_tst_dest_tst_addr) mod G_RX_BUFF_SIZE);
288: end process;
289:
290: tst_ena <= '1' when (mr_tst_control_tmaena = '1') and (mr_tst_dest_tst_mtgt = TMTGT_RXBUF)
291: else
292: '0';
293:
294: -- Write port
295: rxb_port_a_address_i <= rxb_port_a_address when (tst_ena = '0')
296: else
297: mr_tst_dest_tst_addr_pad(G_RX_BUFF_PTR_WIDTH - 1 downto 0);
298:
299: rxb_port_a_write_i <= rxb_port_a_write when (tst_ena = '0')
300: else
301: mr_tst_control_twrstb;
302:
303: rxb_port_a_data_in_i <= rxb_port_a_data_in when (tst_ena = '0')
304: else
305: mr_tst_wdata_tst_wdata;
306:
307: -- Read port
308: rxb_port_b_address_i <= rxb_port_b_address when (tst_ena = '0')
309: else
310: mr_tst_dest_tst_addr_pad(G_RX_BUFF_PTR_WIDTH - 1 downto 0);
311:
312: mr_tst_rdata_tst_rdata <= rxb_port_b_data_out_i when (tst_ena = '1')
313: else
314: (others => '0');
315:
316:
317: -----------------------------------------------------------------------------------------------
318: -----------------------------------------------------------------------------------------------
319: -- Assertions
320: -----------------------------------------------------------------------------------------------
321: -----------------------------------------------------------------------------------------------
322:
323: -- psl default clock is rising_edge(clk_sys);
324: --
325: -- psl rx_ram_port_a_no_addr_overflow : assert never
326: -- to_integer(unsigned(rxb_port_a_address)) >= G_RX_BUFF_SIZE
327: -- report "RX Buffer RAM - Port A address overflow";
328: --
329: -- psl rx_ram_port_b_no_addr_overflow : assert never
330: -- to_integer(unsigned(rxb_port_b_address)) >= G_RX_BUFF_SIZE
331: -- report "RX Buffer RAM - Port B address overflow";
332:
333: end architecture;