SURF  1.0
OctalPortRam.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : OctalPortRam.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2016-04-12
5 -- Last update: 2016-04-19
6 -------------------------------------------------------------------------------
7 -- Description: This module infers a Quad Port RAM as distributed RAM
8 -------------------------------------------------------------------------------
9 -- This file is part of 'SLAC Firmware Standard Library'.
10 -- It is subject to the license terms in the LICENSE.txt file found in the
11 -- top-level directory of this distribution and at:
12 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
13 -- No part of 'SLAC Firmware Standard Library', including this file,
14 -- may be copied, modified, propagated, or distributed except according to
15 -- the terms contained in the LICENSE.txt file.
16 -------------------------------------------------------------------------------
17 
18 library ieee;
19 use ieee.std_logic_1164.all;
20 use ieee.std_logic_arith.all;
21 use ieee.std_logic_unsigned.all;
22 
23 use work.StdRtlPkg.all;
24 
25 --! @see entity
26  --! @ingroup base_ram
27 entity OctalPortRam is
28  generic (
29  TPD_G : time := 1 ns;
30  RST_POLARITY_G : sl := '1'; -- '1' for active high rst, '0' for active low
31  REG_EN_G : boolean := true;
32  MODE_G : string := "no-change";
33  BYTE_WR_EN_G : boolean := false;
34  DATA_WIDTH_G : integer range 1 to (2**24) := 16;
35  BYTE_WIDTH_G : integer := 8;
36  ADDR_WIDTH_G : integer range 1 to (2**24) := 4;
37  INIT_G : slv := "0");
38  port (
39  -- Port A (Read/Write)
40  clka : in sl := '0';
41  en_a : in sl := '1';
42  wea : in sl := '0';
43  weaByte : in slv(wordCount(DATA_WIDTH_G, BYTE_WIDTH_G)-1 downto 0) := (others => '0');
44  rsta : in sl := not(RST_POLARITY_G);
45  addra : in slv(ADDR_WIDTH_G-1 downto 0) := (others => '0');
46  dina : in slv(DATA_WIDTH_G-1 downto 0) := (others => '0');
47  douta : out slv(DATA_WIDTH_G-1 downto 0);
48  -- Port B (Read Only)
49  clkb : in sl := '0';
50  en_b : in sl := '1';
51  rstb : in sl := not(RST_POLARITY_G);
52  addrb : in slv(ADDR_WIDTH_G-1 downto 0) := (others => '0');
53  doutb : out slv(DATA_WIDTH_G-1 downto 0);
54  -- Port C (Read Only)
55  en_c : in sl := '1';
56  clkc : in sl := '0';
57  rstc : in sl := not(RST_POLARITY_G);
58  addrc : in slv(ADDR_WIDTH_G-1 downto 0) := (others => '0');
59  doutc : out slv(DATA_WIDTH_G-1 downto 0);
60  -- Port D (Read Only)
61  en_d : in sl := '1';
62  clkd : in sl := '0';
63  rstd : in sl := not(RST_POLARITY_G);
64  addrd : in slv(ADDR_WIDTH_G-1 downto 0) := (others => '0');
65  doutd : out slv(DATA_WIDTH_G-1 downto 0);
66  -- Port E (Read Only)
67  en_e : in sl := '1';
68  clke : in sl := '0';
69  rste : in sl := not(RST_POLARITY_G);
70  addre : in slv(ADDR_WIDTH_G-1 downto 0) := (others => '0');
71  doute : out slv(DATA_WIDTH_G-1 downto 0);
72  -- Port F (Read Only)
73  en_f : in sl := '1';
74  clkf : in sl := '0';
75  rstf : in sl := not(RST_POLARITY_G);
76  addrf : in slv(ADDR_WIDTH_G-1 downto 0) := (others => '0');
77  doutf : out slv(DATA_WIDTH_G-1 downto 0);
78  -- Port G (Read Only)
79  en_g : in sl := '1';
80  clkg : in sl := '0';
81  rstg : in sl := not(RST_POLARITY_G);
82  addrg : in slv(ADDR_WIDTH_G-1 downto 0) := (others => '0');
83  doutg : out slv(DATA_WIDTH_G-1 downto 0);
84  -- Port H (Read Only)
85  en_h : in sl := '1';
86  clkh : in sl := '0';
87  rsth : in sl := not(RST_POLARITY_G);
88  addrh : in slv(ADDR_WIDTH_G-1 downto 0) := (others => '0');
89  douth : out slv(DATA_WIDTH_G-1 downto 0));
90 end OctalPortRam;
91 
92 architecture rtl of OctalPortRam is
93 
94  -- Initial RAM Values
95  constant NUM_BYTES_C : natural := wordCount(DATA_WIDTH_G, BYTE_WIDTH_G);
96  constant FULL_DATA_WIDTH_C : natural := NUM_BYTES_C*BYTE_WIDTH_G;
97 
98  constant INIT_C : slv(DATA_WIDTH_G-1 downto 0) := ite(INIT_G = "0", slvZero(DATA_WIDTH_G), INIT_G);
99 
100  -- Shared memory
101  type mem_type is array ((2**ADDR_WIDTH_G)-1 downto 0) of slv(DATA_WIDTH_G-1 downto 0);
102  signal mem : mem_type := (others => INIT_C);
103 
104  signal weaByteInt : slv(weaByte'range);
105 
106  -- Attribute for XST (Xilinx Synthesis)
107  attribute ram_style : string;
108  attribute ram_style of mem : signal is "distributed";
109 
110  attribute ram_extract : string;
111  attribute ram_extract of mem : signal is "TRUE";
112 
113  -- Attribute for Synplicity Synthesizer
114  attribute syn_ramstyle : string;
115  attribute syn_ramstyle of mem : signal is "distributed";
116 
117  attribute syn_keep : string;
118  attribute syn_keep of mem : signal is "TRUE";
119 
120 begin
121 
122  -- MODE_G check
123  assert (MODE_G = "no-change") or (MODE_G = "read-first") or (MODE_G = "write-first")
124  report "MODE_G must be either no-change, read-first, or write-first"
125  severity failure;
126 
127  weaByteInt <= weaByte when BYTE_WR_EN_G else (others => wea);
128 
129 
130  -- Port A
131  PORT_A_NOT_REG : if (REG_EN_G = false) generate
132 
133  process(clka)
134  begin
135  if rising_edge(clka) then
136  if (en_a = '1') then
137  for i in NUM_BYTES_C-1 downto 0 loop
138  if (weaByteInt(i) = '1') then
139  mem(conv_integer(addra))(minimum(DATA_WIDTH_G-1, (i+1)*BYTE_WIDTH_G-1) downto i*BYTE_WIDTH_G) <=
140  dina(minimum(DATA_WIDTH_G-1, (i+1)*BYTE_WIDTH_G-1) downto i*BYTE_WIDTH_G);
141  end if;
142  end loop;
143  end if;
144  end if;
145  end process;
146 
147  douta <= mem(conv_integer(addra));
148 
149 
150  end generate;
151 
152  PORT_A_REG : if (REG_EN_G = true) generate
153 
154  NO_CHANGE_MODE : if MODE_G = "no-change" generate
155  process(clka)
156  begin
157  if rising_edge(clka) then
158  if en_a = '1' then
159  for i in NUM_BYTES_C-1 downto 0 loop
160  if (weaByteInt(i) = '1') then
161  mem(conv_integer(addra))(minimum(DATA_WIDTH_G-1, (i+1)*BYTE_WIDTH_G-1) downto i*BYTE_WIDTH_G) <=
162  dina(minimum(DATA_WIDTH_G-1, (i+1)*BYTE_WIDTH_G-1) downto i*BYTE_WIDTH_G);
163  end if;
164  end loop;
165  end if;
166  end if;
167  end process;
168 
169  process(clka)
170  begin
171  if rising_edge(clka) then
172  if (en_a = '1' and weaByteInt = 0) then
173  douta <= mem(conv_integer(addra)) after TPD_G;
174  end if;
175  if rsta = RST_POLARITY_G then
176  douta <= INIT_C after TPD_G;
177  end if;
178  end if;
179  end process;
180 
181  end generate;
182 
183  READ_FIRST_MODE : if MODE_G = "read-first" generate
184  process(clka)
185  begin
186  if rising_edge(clka) then
187  if en_a = '1' then
188  douta <= mem(conv_integer(addra)) after TPD_G;
189  for i in 0 to NUM_BYTES_C-1 loop
190  if (weaByteInt(i) = '1') then
191  mem(conv_integer(addra))(minimum(DATA_WIDTH_G-1, (i+1)*BYTE_WIDTH_G-1) downto i*BYTE_WIDTH_G) <=
192  dina(minimum(DATA_WIDTH_G-1, (i+1)*BYTE_WIDTH_G-1) downto i*BYTE_WIDTH_G);
193  end if;
194  end loop;
195  end if;
196  if rsta = RST_POLARITY_G then
197  douta <= INIT_C after TPD_G;
198  end if;
199  end if;
200  end process;
201  end generate;
202 
203  WRITE_FIRST_MODE : if MODE_G = "write-first" generate
204  process(clka)
205  begin
206  if rising_edge(clka) then
207  if en_a = '1' then
208  for i in NUM_BYTES_C-1 downto 0 loop
209  if (weaByteInt(i) = '1') then
210  mem(conv_integer(addra))(minimum(DATA_WIDTH_G-1, (i+1)*BYTE_WIDTH_G-1) downto i*BYTE_WIDTH_G) <=
211  dina(minimum(DATA_WIDTH_G-1, (i+1)*BYTE_WIDTH_G-1) downto i*BYTE_WIDTH_G);
212  end if;
213  end loop;
214  douta <= mem(conv_integer(addra)) after TPD_G;
215  end if;
216 
217  if rsta = RST_POLARITY_G then
218  douta <= INIT_C after TPD_G;
219  end if;
220  end if;
221  end process;
222  end generate;
223 
224  end generate;
225 
226  -- Port B
227  PORT_B_REG : if (REG_EN_G = true) generate
228  process(clkb)
229  begin
230  if rising_edge(clkb) then
231  if rstb = RST_POLARITY_G then
232  doutb <= INIT_C after TPD_G;
233  elsif en_b = '1' then
234  doutb <= mem(conv_integer(addrb)) after TPD_G;
235  end if;
236  end if;
237  end process;
238  end generate;
239 
240  PORT_B_NOT_REG : if (REG_EN_G = false) generate
241  doutb <= mem(conv_integer(addrb));
242  end generate;
243 
244  -- Port C
245  PORT_C_REG : if (REG_EN_G = true) generate
246  process(clkc)
247  begin
248  if rising_edge(clkc) then
249  if rstc = RST_POLARITY_G then
250  doutc <= INIT_C after TPD_G;
251  elsif en_c = '1' then
252  doutc <= mem(conv_integer(addrc)) after TPD_G;
253  end if;
254  end if;
255  end process;
256  end generate;
257 
258  PORT_C_NOT_REG : if (REG_EN_G = false) generate
259  doutc <= mem(conv_integer(addrc));
260  end generate;
261 
262  -- Port D
263  PORT_D_REG : if (REG_EN_G = true) generate
264  process(clkd)
265  begin
266  if rising_edge(clkd) then
267  if rstd = RST_POLARITY_G then
268  doutd <= INIT_C after TPD_G;
269  elsif en_d = '1' then
270  doutd <= mem(conv_integer(addrd)) after TPD_G;
271  end if;
272  end if;
273  end process;
274  end generate;
275 
276  PORT_D_NOT_REG : if (REG_EN_G = false) generate
277  doutd <= mem(conv_integer(addrd));
278  end generate;
279 
280  -- Port E
281  PORT_E_REG : if (REG_EN_G = true) generate
282  process(clke)
283  begin
284  if rising_edge(clke) then
285  if rste = RST_POLARITY_G then
286  doute <= INIT_C after TPD_G;
287  elsif en_e = '1' then
288  doute <= mem(conv_integer(addre)) after TPD_G;
289  end if;
290  end if;
291  end process;
292  end generate;
293 
294  PORT_E_NOT_REG : if (REG_EN_G = false) generate
295  doute <= mem(conv_integer(addre));
296  end generate;
297 
298  -- Port F
299  PORT_F_REG : if (REG_EN_G = true) generate
300  process(clkf)
301  begin
302  if rising_edge(clkf) then
303  if rstf = RST_POLARITY_G then
304  doutf <= INIT_C after TPD_G;
305  elsif en_f = '1' then
306  doutf <= mem(conv_integer(addrf)) after TPD_G;
307  end if;
308  end if;
309  end process;
310  end generate;
311 
312  PORT_F_NOT_REG : if (REG_EN_G = false) generate
313  doutf <= mem(conv_integer(addrf));
314  end generate;
315 
316  -- Port G
317  PORT_G_REG : if (REG_EN_G = true) generate
318  process(clkg)
319  begin
320  if rising_edge(clkg) then
321  if rstg = RST_POLARITY_G then
322  doutg <= INIT_C after TPD_G;
323  elsif en_g = '1' then
324  doutg <= mem(conv_integer(addrg)) after TPD_G;
325  end if;
326  end if;
327  end process;
328  end generate;
329 
330  PORT_G_NOT_REG : if (REG_EN_G = false) generate
331  doutg <= mem(conv_integer(addrg));
332  end generate;
333 
334  -- Port H
335  PORT_H_REG : if (REG_EN_G = true) generate
336  process(clkh)
337  begin
338  if rising_edge(clkh) then
339  if rsth = RST_POLARITY_G then
340  douth <= INIT_C after TPD_G;
341  elsif en_h = '1' then
342  douth <= mem(conv_integer(addrh)) after TPD_G;
343  end if;
344  end if;
345  end process;
346  end generate;
347 
348  PORT_H_NOT_REG : if (REG_EN_G = false) generate
349  douth <= mem(conv_integer(addrh));
350  end generate;
351 
352 end rtl;
in rstesl :=not ( RST_POLARITY_G)
in weasl := '0'
INIT_Gslv := "0"
in en_fsl := '1'
out doutbslv( DATA_WIDTH_G- 1 downto 0)
MODE_Gstring := "no-change"
out douteslv( DATA_WIDTH_G- 1 downto 0)
in en_hsl := '1'
in rstasl :=not ( RST_POLARITY_G)
BYTE_WIDTH_Ginteger := 8
ADDR_WIDTH_Ginteger range 1 to ( 2** 24):= 4
in en_dsl := '1'
std_logic sl
Definition: StdRtlPkg.vhd:28
in clkcsl := '0'
out doutgslv( DATA_WIDTH_G- 1 downto 0)
in rstbsl :=not ( RST_POLARITY_G)
out doutcslv( DATA_WIDTH_G- 1 downto 0)
_library_ ieeeieee
Definition: DualPortRam.vhd:18
in addreslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
in en_esl := '1'
in en_bsl := '1'
in addrcslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
in clkfsl := '0'
in rsthsl :=not ( RST_POLARITY_G)
in clkgsl := '0'
in addraslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
in dinaslv( DATA_WIDTH_G- 1 downto 0) :=( others => '0')
in rstdsl :=not ( RST_POLARITY_G)
out doutfslv( DATA_WIDTH_G- 1 downto 0)
in weaByteslv( wordCount( DATA_WIDTH_G, BYTE_WIDTH_G)- 1 downto 0) :=( others => '0')
in en_csl := '1'
TPD_Gtime := 1 ns
in addrgslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
REG_EN_Gboolean := true
in rstgsl :=not ( RST_POLARITY_G)
in en_gsl := '1'
out douthslv( DATA_WIDTH_G- 1 downto 0)
in clkesl := '0'
in clkbsl := '0'
in clkhsl := '0'
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
in addrdslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
out doutaslv( DATA_WIDTH_G- 1 downto 0)
RST_POLARITY_Gsl := '1'
in clkasl := '0'
BYTE_WR_EN_Gboolean := false
in clkdsl := '0'
in addrhslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
out doutdslv( DATA_WIDTH_G- 1 downto 0)
in addrfslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
in rstfsl :=not ( RST_POLARITY_G)
in rstcsl :=not ( RST_POLARITY_G)
in addrbslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
in en_asl := '1'
std_logic_vector slv
Definition: StdRtlPkg.vhd:29