File: /__w/ctu-can-regression/ctu-can-regression/src/common_blocks/dp_inf_ram_be.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: -- Dual Port Inferred RAM with Byte enables
71: --
72: -- Purpose:
73: -- Dual port Memory wrapper for inferrence of RAM blocks in Intel and Xilinx
74: -- FPGAs. Port A is write only. Port B is read only. Port A interface is
75: -- synchronous. Read interface is either combinatorial (asynchronous) or
76: -- registered (synchronous). Clock is shared between the two ports. If used
77: -- on ASIC or FPGA without memories, synthesized as DFFs without Set or Reset.
78: --------------------------------------------------------------------------------
79:
80: Library ieee;
81: USE IEEE.std_logic_1164.all;
82: USE IEEE.numeric_std.ALL;
83:
84: entity dp_inf_ram_be is
85: generic (
86: -- Width of memory word (in bits)
87: G_WORD_WIDTH : natural := 32;
88:
89: -- Memory depth (in words)
90: G_DEPTH : natural := 32;
91:
92: -- Address width (in bits)
93: G_ADDRESS_WIDTH : natural := 8;
94:
95: -- Synchronous read
96: G_SYNC_READ : boolean := true;
97:
98: -- If true, res_n causes RAM to be reset
99: G_RESETABLE : boolean := false
100: );
101: port (
102: -------------------------------------------------------------------------------------------
103: -- Clock and Reset
104: -------------------------------------------------------------------------------------------
105: clk_sys : in std_logic;
106: res_n : in std_logic;
107:
108: -------------------------------------------------------------------------------------------
109: -- Port A - Data input
110: -------------------------------------------------------------------------------------------
111: addr_A : in std_logic_vector(G_ADDRESS_WIDTH - 1 downto 0);
112: write : in std_logic;
113: data_in : in std_logic_vector(G_WORD_WIDTH - 1 downto 0);
114: be : in std_logic_vector(G_WORD_WIDTH / 8 - 1 downto 0);
115:
116: -------------------------------------------------------------------------------------------
117: -- Port B - Data output
118: -------------------------------------------------------------------------------------------
119: addr_B : in std_logic_vector(G_ADDRESS_WIDTH - 1 downto 0);
120: data_out : out std_logic_vector(G_WORD_WIDTH - 1 downto 0)
121: );
122: end entity;
123:
124: architecture rtl of dp_inf_ram_be is
125:
126: -----------------------------------------------------------------------------------------------
127: -- Memory definition
128: -----------------------------------------------------------------------------------------------
129: type memory_type is array(0 to G_DEPTH - 1) of
130: std_logic_vector(G_WORD_WIDTH - 1 downto 0);
131: signal ram_memory : memory_type;
132:
133: signal int_read_data : std_logic_vector(G_WORD_WIDTH - 1 downto 0);
134: signal byte_we : std_logic_vector(G_WORD_WIDTH/8 - 1 downto 0);
135:
136: begin
137:
138: -----------------------------------------------------------------------------------------------
139: -- Memory Write access process - per byte
140: -----------------------------------------------------------------------------------------------
141: byte_gen : for i in 0 to G_WORD_WIDTH/8 - 1 generate
142: byte_we(i) <= '1' when (write = '1' and be(i) = '1')
143: else
144: '0';
145: end generate;
146:
147: -----------------------------------------------------------------------------------------------
148: -- RAM memory (non-resetable version)
149: -----------------------------------------------------------------------------------------------
150: ram_rst_false_gen : if (not G_RESETABLE) generate
151:
152: ram_write_process : process(clk_sys)
153: begin
154: if (rising_edge(clk_sys)) then
155: for i in 0 to G_WORD_WIDTH/8 - 1 loop
156: if (byte_we(i) = '1') then
157: ram_memory(to_integer(unsigned(addr_A)))(i * 8 + 7 downto i * 8)
158: <= data_in(i * 8 + 7 downto i * 8);
159: end if;
160: end loop;
161: end if;
162: end process;
163:
164: end generate;
165:
166: -----------------------------------------------------------------------------------------------
167: -- RAM memory (resetable version)
168: -----------------------------------------------------------------------------------------------
169: ram_rst_true_gen : if (G_RESETABLE) generate
170:
171: ram_write_process : process(clk_sys, res_n)
172: begin
173: if (res_n = '0') then
174: ram_memory <= (others => (others => '0'));
175: elsif (rising_edge(clk_sys)) then
176: for i in 0 to G_WORD_WIDTH/8 - 1 loop
177: if (byte_we(i) = '1') then
178: ram_memory(to_integer(unsigned(addr_A)))(i * 8 + 7 downto i * 8)
179: <= data_in(i * 8 + 7 downto i * 8);
180: end if;
181: end loop;
182: end if;
183: end process;
184:
185: end generate;
186:
187: -----------------------------------------------------------------------------------------------
188: -- Memory read access
189: -----------------------------------------------------------------------------------------------
190: int_read_data <= ram_memory(to_integer(unsigned(addr_B)));
191:
192: -- Synchronous read
193: sync_read_gen : if (G_SYNC_READ) generate
194: ram_read_process : process(clk_sys)
195: begin
196: if (rising_edge(clk_sys)) then
197: data_out <= int_read_data;
198: end if;
199: end process;
200: end generate;
201:
202: -- Asynchronous read
203: async_read_gen : if (not G_SYNC_READ) generate
204: data_out <= int_read_data;
205: end generate;
206:
207:
208: -----------------------------------------------------------------------------------------------
209: -- Assertions on size
210: -----------------------------------------------------------------------------------------------
211: -- coverage off
212: assert ((G_WORD_WIDTH = 8) or
213: (G_WORD_WIDTH = 16) or
214: (G_WORD_WIDTH = 32) or
215: (G_WORD_WIDTH = 64) or
216: (G_WORD_WIDTH = 128))
217: report "Unsupported inferred RAM word width! " &
218: "Only 8, 16, 32, 64 and 128 are allowed!"
219: severity failure;
220: -- coverage on
221:
222: end architecture;