# Dual port RAM on Altera and Xilinx FPGA

I have always managed to synthesis a 256 x 32 bits dual-port RAM (not true dual port RAM) in Xilinx ISE with just 1 x 18K BRAM.

The example code from here was used:

-- A parameterized, inferable, true dual-port, dual-clock block RAM in VHDL.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity bram_tdp is
generic (
DATA    : integer := 72;
);
port (
-- Port A
a_clk   : in  std_logic;
a_wr    : in  std_logic;
a_din   : in  std_logic_vector(DATA-1 downto 0);
a_dout  : out std_logic_vector(DATA-1 downto 0);

-- Port B
b_clk   : in  std_logic;
b_wr    : in  std_logic;
b_din   : in  std_logic_vector(DATA-1 downto 0);
b_dout  : out std_logic_vector(DATA-1 downto 0)
);
end bram_tdp;

architecture rtl of bram_tdp is
-- Shared memory
type mem_type is array ( (2**ADDR)-1 downto 0 ) of std_logic_vector(DATA-1 downto 0);
shared variable mem : mem_type;
begin

-- Port A
process(a_clk)
begin
if(a_clk'event and a_clk='1') then
if(a_wr='1') then
end if;
end if;
end process;

-- Port B
process(b_clk)
begin
if(b_clk'event and b_clk='1') then
if(b_wr='1') then
end if;
end if;
end process;

end rtl;


I have tried to do the same for Altera, however compiling gives me figures requiring 2 x M20K RAM.

Shouldn't it require only 1 x M20K ? How can I do that without resorting to other resources such as other MLAB?

• Did it infer a true dual port out a pair of single ports? I recently had some trouble inferring a true dual port RAM in quartus and I had to put the RAM in a separate module to get it to synthesize correctly. The ide may be better than ise, but the synthesizer is crap. – alex.forencich Mar 28 '16 at 7:22
• I recommend to use the altsyncram macro from altera_mf. It's a macro to generate the correct RAM. – Paebbels Mar 28 '16 at 7:40
• Please show the code you used to infer the RAM. – Tom Carpenter Mar 28 '16 at 7:52
• I've checked and 256x32b is a supported configuration. 40b is the maximum width for an M20K. – Tom Carpenter Mar 28 '16 at 7:59
• I used the vhdl code below taken from danstrother.com/2010/09/11/inferring-rams-in-fpgas Sorry I have no idea how to paste the code here using markdown language and not exceeding word limit. – John Mar 29 '16 at 8:34

I've also now just tried compiling for a Stratix V with Quartus 15.0 which does have M20K blocks, and you are correct - it infers two M20Ks which should not be the case. In fact using the Verilog test code I have just removed from my answer also infers two M20Ks.

Why? The True Dual-Port Requirements

A single-port RAM of the size you are interested in should be possible to fit into a single M20K as it can support widths up to 40bits. For simple dual-port mode it should also fit - in this mode you have one read port and one write port.

Image Source: Stratix V Device Handbook, Section 2-9

However, in True Dual-Port mode it will not fit. The reason is because the M20Ks have only one 40bit wide read pathway and one 40bit wide write pathway. When operating in True Dual-Port mode, these pathways must be shared between the ports - in other words each port can only be 20bits wide.

Image Source: Stratix V Device Handbook, Section 2-9

Because of these shared pathways two M20Ks are required in order to fit the RAM. If you were operating in single port mode, or simple dual port mode, then it would require only 1.

• I used the vhdl code below taken from danstrother.com/2010/09/11/inferring-rams-in-fpgas – John Mar 29 '16 at 8:20
• Sorry I have no idea how to paste the code here using markdown language and not exceeding word limit. – John Mar 29 '16 at 8:32

It seems that you are using a Stratix V which is the only FPGA family having M20K memory blocks according to the Embedded Memory User Guide from Altera.

According to Table 2-8 of the Stratix V Device Handbook Volume 1, the maximum data width of one M20K in true dual-port mode is 20 bits. Thus, two M20K are required for a 32-bit data bus.

Only in simple dual-port mode, the M20K supports a data-width of up to 40 bits as listed in Table 2-7.