]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - hw/xilinx_dualport_bram.vhd
pxmc: I component accumulator with long type and PXMC_SUBDIV argument protection.
[fpga/lx-cpu1/lx-rocon.git] / hw / xilinx_dualport_bram.vhd
1 -- Xilinx dualport BRAM template, write-first mode, no delay
2 library ieee;
3 use ieee.std_logic_1164.all;
4 use ieee.numeric_std.all;
5 use work.lx_rocon_pkg.all;
6
7 entity xilinx_dualport_bram is
8         generic
9         (
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
18         );
19         port
20         (
21                 clka : in std_logic;
22                 rsta : in std_logic;
23                 ena : in std_logic;
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);
28                 clkb : in std_logic;
29                 rstb : in std_logic;
30                 enb : in std_logic;
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)
35         );
36 end xilinx_dualport_bram;
37
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'));
41
42 begin
43
44 -- CLKA process
45 ram_process_a:
46         process
47         begin
48
49                 wait until clka'event and clka = '1';
50
51                 if ena = '1' then
52
53                         -- Depends on the port type
54                         case port_a_type is
55                                 when READ_FIRST =>
56                                         -- Read
57                                         if rsta = '1' then
58                                                 douta <= (others => '0');
59                                         else
60                                                 douta <= ram_block(to_integer(unsigned(addra)));
61                                         end if;
62                                         -- Write
63                                         for i in 0 to (we_width-1) loop
64                                                 if wea(i) = '1' then
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));
67                                                 end if;
68                                         end loop;
69
70                                 when WRITE_FIRST =>
71                                         -- Write
72                                         for i in 0 to (we_width-1) loop
73                                                 if wea(i) = '1' then
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));
76                                                 end if;
77                                         end loop;
78                                         -- Read
79                                         if rsta = '1' then
80                                                 douta <= (others => '0');
81                                         else
82                                                 douta <= ram_block(to_integer(unsigned(addra)));
83                                         end if;
84
85                                 when NO_CHANGE =>
86                                         -- Write
87                                         for i in 0 to (we_width-1) loop
88                                                 if wea(i) = '1' then
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));
91                                                 end if;
92                                         end loop;
93                                         -- Read (if not writing)
94                                         if to_integer(unsigned(wea)) = 0 then
95                                                 if rsta = '1' then
96                                                         douta <= (others => '0');
97                                                 else
98                                                         douta <= ram_block(to_integer(unsigned(addra)));
99                                                 end if;
100                                         end if;
101                                 end case;
102
103                 end if;
104
105         end process;
106
107 -- CLKB process
108 ram_process_b:
109         process
110         begin
111
112                 wait until clkb'event and clkb = '1';
113
114                 if enb = '1' then
115
116                         -- Depends on the port type
117                         case port_b_type is
118                                 when READ_FIRST =>
119                                         -- Read
120                                         if rstb = '1' then
121                                                 doutb <= (others => '0');
122                                         else
123                                                 doutb <= ram_block(to_integer(unsigned(addrb)));
124                                         end if;
125                                         -- Write
126                                         for i in 0 to (we_width-1) loop
127                                                 if web(i) = '1' then
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));
130                                                 end if;
131                                         end loop;
132
133                                 when WRITE_FIRST =>
134                                         -- Write
135                                         for i in 0 to (we_width-1) loop
136                                                 if web(i) = '1' then
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));
139                                                 end if;
140                                         end loop;
141                                         -- Read
142                                         if rstb = '1' then
143                                                 doutb <= (others => '0');
144                                         else
145                                                 doutb <= ram_block(to_integer(unsigned(addrb)));
146                                         end if;
147
148                                 when NO_CHANGE =>
149                                         -- Write
150                                         for i in 0 to (we_width-1) loop
151                                                 if web(i) = '1' then
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));
154                                                 end if;
155                                         end loop;
156                                         -- Read (if not writing)
157                                         if to_integer(unsigned(web)) = 0 then
158                                                 if rstb = '1' then
159                                                         doutb <= (others => '0');
160                                                 else
161                                                         doutb <= ram_block(to_integer(unsigned(addrb)));
162                                                 end if;
163                                         end if;
164                                 end case;
165
166                 end if;
167
168         end process;
169
170 end Behavioral;