09-21-2020 04:14 AM
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?
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));
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;
process(wclk, we, addr)
if (rising_edge(wclk)) then
if (we = '1') then
mem(conv_integer(addr)) <= d;
o <= mem(conv_integer(addr));
09-21-2020 05:48 AM
If you are ok using one of the Xilinx parameterizable models, go to the tools pull down, then choose language templates:
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.
09-21-2020 06:51 AM
09-21-2020 07:01 AM
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.
09-21-2020 08:35 AM
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.