1 -- Xilinx dualport BRAM template, write-first mode, no delay
3 use ieee.std_logic_1164.all;
4 use ieee.numeric_std.all;
5 use work.lx_rocon_pkg.all;
7 entity xilinx_dualport_bram is
10 -- Not all combinations are plausible for BRAMs
11 -- byte width: 8, 9, 32, 36
12 -- we_width: 1, 2, 3, 4
13 byte_width : positive := 8;
14 address_width : positive := 8;
15 we_width : positive := 4;
16 port_a_type : BRAM_type := READ_FIRST;
17 port_b_type : BRAM_type := READ_FIRST
24 wea : in std_logic_vector((we_width-1) downto 0);
25 addra : in std_logic_vector((address_width-1) downto 0);
26 dina : in std_logic_vector(((byte_width*we_width)-1) downto 0);
27 douta : out std_logic_vector(((byte_width*we_width)-1) downto 0);
31 web : in std_logic_vector((we_width-1) downto 0);
32 addrb : in std_logic_vector((address_width-1) downto 0);
33 dinb : in std_logic_vector(((byte_width*we_width)-1) downto 0);
34 doutb : out std_logic_vector(((byte_width*we_width)-1) downto 0)
36 end xilinx_dualport_bram;
38 architecture Behavioral of xilinx_dualport_bram is
39 type ram is array (0 to ((2**address_width) - 1)) of std_logic_vector(((byte_width*we_width)-1) downto 0);
40 shared variable ram_block : ram := (others => (others => '0'));
49 wait until clka'event and clka = '1';
53 -- Depends on the port type
58 douta <= (others => '0');
60 douta <= ram_block(to_integer(unsigned(addra)));
63 for i in 0 to (we_width-1) loop
65 ram_block(to_integer(unsigned(addra)))(((i+1)*byte_width-1) downto (i*byte_width))
66 := dina(((i+1)*byte_width-1) downto (i*byte_width));
72 for i in 0 to (we_width-1) loop
74 ram_block(to_integer(unsigned(addra)))(((i+1)*byte_width-1) downto (i*byte_width))
75 := dina(((i+1)*byte_width-1) downto (i*byte_width));
80 douta <= (others => '0');
82 douta <= ram_block(to_integer(unsigned(addra)));
87 for i in 0 to (we_width-1) loop
89 ram_block(to_integer(unsigned(addra)))(((i+1)*byte_width-1) downto (i*byte_width))
90 := dina(((i+1)*byte_width-1) downto (i*byte_width));
93 -- Read (if not writing)
94 if to_integer(unsigned(wea)) = 0 then
96 douta <= (others => '0');
98 douta <= ram_block(to_integer(unsigned(addra)));
112 wait until clkb'event and clkb = '1';
116 -- Depends on the port type
121 doutb <= (others => '0');
123 doutb <= ram_block(to_integer(unsigned(addrb)));
126 for i in 0 to (we_width-1) loop
128 ram_block(to_integer(unsigned(addrb)))(((i+1)*byte_width-1) downto (i*byte_width))
129 := dinb(((i+1)*byte_width-1) downto (i*byte_width));
135 for i in 0 to (we_width-1) loop
137 ram_block(to_integer(unsigned(addrb)))(((i+1)*byte_width-1) downto (i*byte_width))
138 := dinb(((i+1)*byte_width-1) downto (i*byte_width));
143 doutb <= (others => '0');
145 doutb <= ram_block(to_integer(unsigned(addrb)));
150 for i in 0 to (we_width-1) loop
152 ram_block(to_integer(unsigned(addrb)))(((i+1)*byte_width-1) downto (i*byte_width))
153 := dinb(((i+1)*byte_width-1) downto (i*byte_width));
156 -- Read (if not writing)
157 if to_integer(unsigned(web)) = 0 then
159 doutb <= (others => '0');
161 doutb <= ram_block(to_integer(unsigned(addrb)));