Quartus 20.1.1 SE Crashes on Elaboration of Dual Port RAM VHDL Template
- 5 years ago
Provided is a work around solution to prevent Quartus from crashing during elaboration of Mixed Width Dual Port RAM with STD_LOGIC_VECTOR instead of NATURAL that includes dual clocks. RAM capacity and port widths are specified in bits. An assertion is provided for simulation. The required log base 2 utility function and package is also posted. Thanks KennyT_Intel for the tip on why Quartus crashes so that a work around solution could be found and posted.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;library work;
use work.utils.log2c;entity ram_dptrue is
generic (
ram_bits: natural;
dq1_bits: natural range 1 to 128;
dq2_bits: natural range 1 to 128);
port (
clk1 : in std_logic;
clk2 : in std_logic;addr1 : in std_logic_vector(log2c(ram_bits/dq1_bits)-1 downto 0);
wren1 : in std_logic;
d1 : in std_logic_vector(dq1_bits-1 downto 0);
q1 : out std_logic_vector(dq1_bits-1 downto 0);addr2 : in std_logic_vector(log2c(ram_bits/dq2_bits)-1 downto 0);
wren2 : in std_logic;
d2 : in std_logic_vector(dq2_bits-1 downto 0);
q2 : out std_logic_vector(dq2_bits-1 downto 0));
end entity ram_dptrue;architecture behavioural of ram_dptrue is
-- Build up 2D array to hold the memory
constant ram_depth : natural := ram_bits/dq1_bits;
constant ram_ratio : natural := dq1_bits/dq2_bits;type word_t is array(ram_ratio-1 downto 0) of std_logic_vector(dq2_bits-1 downto 0);
type ram_t is array(0 to ram_depth-1) of word_t;shared variable ram : ram_t;
signal d_local : word_t;
signal q_local : word_t;begin
assert (ram_ratio > 0) and (2**log2c(ram_ratio) = ram_ratio)
report "port size requires power of two ratio and dq1 >= dq2"
severity failure;-- Reorganize the read data from the RAM to match the output
unpack: for i in 0 to ram_ratio-1 generate
d_local(i) <= d1(dq2_bits*(i+1)-1 downto dq2_bits*i);
q1(dq2_bits*(i+1)-1 downto dq2_bits*i) <= q_local(i);
end generate unpack;port1: process(clk1)
begin
if (rising_edge(clk1)) then
if (wren1 = '1') then
ram(to_integer(unsigned(addr1))) := d_local;
-- Read during write returns NEW data
q_local <= d_local;
else
-- Read only
q_local <= ram(to_integer(unsigned(addr1)));
end if;
end if;
end process;port2: process(clk2)
begin
if (rising_edge(clk2)) then
if (wren2 = '1') then
ram(to_integer(unsigned(addr2)) / ram_ratio)(to_integer(unsigned(addr2)) mod ram_ratio) := d2;
-- Read during write returns NEW data
q2 <= d2;
else
-- Read only
q2 <= ram(to_integer(unsigned(addr2)) / ram_ratio)(to_integer(unsigned(addr2)) mod ram_ratio);
end if;
end if;
end process;end architecture behavioural;
-- Package Declaration
package utils is-- Functions
function log2c(n: integer) return integer;end package utils;
-- Package Body
package body utils isfunction log2c(n: integer) return integer is
variable m, p: integer;
begin
m := 0;
p := 1;
while p < n loop
m := m + 1;
p := p * 2;
end loop;
return m;
end log2c;end package body utils;