Proper way to infer Quad Port Ram?
I generated the Quad Port Template in Quartus 2025.3. I then wrapped it into a wrapper and finally into my design.
This is then instantiated with the following generics:
Info(19337): VHDL info at quad_port_ram.vhd(10): executing entity "quad_port_ram(data_width=578,addr_width=7)" with architecture "rtl"
Info(19337): VHDL info at quad_port_ram.vhd(10): executing entity "quad_port_ram(data_width=578,addr_width=8)" with architecture "rtl"
Info(19337): VHDL info at quad_port_ram.vhd(10): executing entity "quad_port_ram(data_width=578,addr_width=9)" with architecture "rtl"
Info(19337): VHDL info at quad_port_ram.vhd(10): executing entity "quad_port_ram(data_width=578,addr_width=10)" with architecture "rtl"
However I get the following errors:
Warning(276002): Cannot convert all sets of registers into RAM megafunctions when creating nodes; therefore, the resulting number of registers remaining in design can cause longer compilation time or result in insufficient memory to complete Analysis and Synthesis
Is there something that can be done to properly infer quad-port ram in 25.3?
Here's the VHDL generated from the template:
-- Quartus Prime VHDL Template
-- Quad Port RAM with separate read/write addresses and
-- single read/write clock
-- This style of RAM cannot be used on Arria 10,
-- which does not support Quad Port RAM
library ieee;
use ieee.std_logic_1164.all;
entity quad_port_ram is
generic
(
DATA_WIDTH : natural := 2;
ADDR_WIDTH : natural := 6
);
port
(
clk : in std_logic;
read_addr_a : in natural range 0 to 2**ADDR_WIDTH - 1;
read_addr_b : in natural range 0 to 2**ADDR_WIDTH - 1;
write_addr_a : in natural range 0 to 2**ADDR_WIDTH - 1;
write_addr_b : in natural range 0 to 2**ADDR_WIDTH - 1;
data_a : in std_logic_vector((DATA_WIDTH-1) downto 0);
data_b : in std_logic_vector((DATA_WIDTH-1) downto 0);
we_a : in std_logic := '1';
we_b : in std_logic := '1';
q_a : out std_logic_vector((DATA_WIDTH -1) downto 0);
q_b : out std_logic_vector((DATA_WIDTH -1) downto 0)
);
end quad_port_ram;
architecture rtl of quad_port_ram is
-- Build a 2-D array type for the RAM
subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t;
-- Declare the RAM
shared variable ram : memory_t;
begin
-- Port A
process(clk)
begin
if(rising_edge(clk)) then
if(we_a = '1') then
ram(write_addr_a) := data_a;
end if;
end if;
end process;
process(clk)
begin
if(rising_edge(clk)) then
q_a <= ram(read_addr_a);
end if;
end process;
-- Port B
process(clk)
begin
if(rising_edge(clk)) then
if(we_b = '1') then
ram(write_addr_b) := data_b;
end if;
end if;
end process;
process(clk)
begin
if(rising_edge(clk)) then
q_b <= ram(read_addr_b);
end if;
end process;
end rtl;