cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
AliAlra
Visitor
Visitor
379 Views
Registered: ‎05-23-2020

Single port RAM

When I synthesis my RTL for a single port RAM it won't be inferred as BRAM and use LUTs instead. How can I make it use BRAMs instead?

 

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity ram_32x8s_infer is
generic( d_width : integer := 400;
addr_width : integer := 4;
mem_depth : integer := 20);
port (o : out STD_LOGIC_VECTOR(d_width - 1 downto 0);
we, wclk : in STD_LOGIC;
d : in STD_LOGIC_VECTOR(d_width - 1 downto 0);
addr : in STD_LOGIC_VECTOR(addr_width - 1 downto 0));
end ram_32x8s_infer;

architecture xilinx of ram_32x8s_infer is
type mem_type is array (mem_depth - 1 downto 0) of
STD_LOGIC_VECTOR (d_width - 1 downto 0);

signal mem : mem_type;

begin

process(wclk, we, addr)
begin
if (rising_edge(wclk)) then
if (we = '1') then
mem(conv_integer(addr)) <= d;
end if;
end if;
end process;

o <= mem(conv_integer(addr));

end xilinx;

0 Kudos
Reply
5 Replies
surajc
Xilinx Employee
Xilinx Employee
357 Views
Registered: ‎01-30-2019

Hi @AliAlra 

Have a look at this example and the RTL attribute ram_style from UG901 

0 Kudos
Reply
DesLinx_RS
Visitor
Visitor
355 Views
Registered: ‎09-18-2020

If you are ok using one of the Xilinx parameterizable models, go to the tools pull down, then choose language templates:

DesLinx_RS_0-1600692203714.png

next, choose: xilinx parameterized macros/xpm/xpm_memorysingle port ram. As you can see in the screen shot below, you can customize the RAM, including which type of RAM you want the structure implemented in.

DesLinx_RS_2-1600692452885.png

 

 

Rob Swan | FPGA Design & Support Engineer – E3 | DesignLinx Solutions
https://www.designlinxhs.com
DesLinx_RS
Visitor
Visitor
334 Views
Registered: ‎09-18-2020

A really cool aspect of using the XPM is that you can play around with the RAM implementation simply by changing the parameter/generic in the model. None of the I/O change, just change the RAM( distributed, Block RAM, or Ultra RAM) implementation primitive, recompile, and you're off to the races. You can see how resource utilization, and access time are affected using the different implementations. Both Verilog and VHDL are supported!
Rob Swan | FPGA Design & Support Engineer – E3 | DesignLinx Solutions
https://www.designlinxhs.com
0 Kudos
Reply
avrumw
Guide
Guide
330 Views
Registered: ‎01-23-2009

The reason this code doesn't infer a BRAM is that what it is asking for is not implementable in a BRAM.

Your RTL code is asking for a combinatorial read - the read data is not clocked - it is combinatorially derived from the address. The block RAM is a synchronous read - the data is available one clock after the address. As a result, this code is simply not implementable in block RAMs, and will infer the only RAMs that can do combinatorial read; the distributed RAMs (or select RAMs) - these are far smaller (64bits instead of 36kbits).

If you want to use block RAMs, you must use sequential reads - you need to modify your architecture to allow for the one clock latency between the address and the read data.

Avrum

richardhead
Scholar
Scholar
311 Views
Registered: ‎08-01-2012

@DesLinx_RS 

While the XPM is a good start (and finally an answer to Altera's very good AltSyncram, AFIFO, SFIFO etc thats been around for years ), it does have some issues. The simulation model is only available as System Verilog. And even more annoying, the CDC parts of the AsyncFIFO contain SVA which is a extra feature for some external simulators. So if you only have a single language licence, you're stuck with the Vivado simulator (which is pretty basic for VHDL verification).

Inferring ram in VHDL is fairly straight forward, and so I find it easier just to infer them, and we even have an in house sync FIFO (which compiles slightly smaller than the XPM one). For Async we're using the XPM one as CDC can get a bit political. But this is still far better than a coregen FIFO.

0 Kudos
Reply