Electronic – Dual port RAM on Altera and Xilinx FPGA

fpgaintel-fpgaramvhdlxilinx

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;
    ADDR    : integer := 10
);
port (
    -- Port A
    a_clk   : in  std_logic;
    a_wr    : in  std_logic;
    a_addr  : in  std_logic_vector(ADDR-1 downto 0);
    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_addr  : in  std_logic_vector(ADDR-1 downto 0);
    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
            mem(conv_integer(a_addr)) := a_din;
        end if;
        a_dout <= mem(conv_integer(a_addr));
    end if;
end process;

-- Port B
process(b_clk)
begin
    if(b_clk'event and b_clk='1') then
        if(b_wr='1') then
            mem(conv_integer(b_addr)) := b_din;
        end if;
        b_dout <= mem(conv_integer(b_addr));
    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?

Best Answer

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.

Single Port Configuration

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.

True Dual Port Width

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.

Related Topic