Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Dagobah
Beginner
57 Views

Quartus 20.1.1 SE Crashes on Elaboration of Dual Port RAM VHDL Template

Jump to solution

Problem Details
Error:
Internal Error: Sub-system: VRFX, File: /quartus/synth/vrfx/verific/vhdl/vhdlvalue_elab.cpp, Line: 6821
w_ref_type_a != VHDL_RAM_REF_VARIABLE_WORD_VARIABLE_BYTE
Stack Trace:
0x12411d: vrfx_altera_assert(bool, char const*, int, char const*) + 0x1d (synth_vrfx)
0x2d40b4: VhdlArrayConstraint::CreateDualPortValue(std::string&, std::string&, VhdlIdDef*) const + 0x818 (synth_vrfx)
0x29c54e: VhdlDeclaration::CreateStaticValues(VhdlConstraint*, VhdlDataFlow*) + 0x314 (synth_vrfx)
0x299212: VhdlVariableDecl::RecursiveElaborate(VhdlDataFlow*) + 0xe6 (synth_vrfx)
0x298e21: VhdlDeclaration::Elaborate(VhdlDataFlow*) + 0x47 (synth_vrfx)
0x2bc1a5: VhdlArchitectureBody::Elaborate(VhdlBlockConfiguration*) + 0xbf (synth_vrfx)
0x2bcc67: VhdlEntityDecl::CoreElaborate(VhdlSecondaryUnit*, char const*, VhdlBlockConfiguration*) + 0x463 (synth_vrfx)
0x2c23c9: VhdlEntityDecl::Elaborate(char const*, Array*, Map*, VhdlBlockConfiguration*) + 0x403 (synth_vrfx)
0x146283: VRFX_VERIFIC_VHDL_ELABORATOR::elaborate(BASEX_ELABORATE_INFO*) + 0x1df (synth_vrfx)
0x13b4e9: VRFX_ELABORATOR::elaborate(BASEX_ELABORATE_INFO*) + 0xb9 (synth_vrfx)
0x17947e: SGN_FN_LIB::elaborate(BASEX_ELAB_INFO_CORE*) const + 0x18e (synth_sgn)
0x1818ee: SGN_FN_LIB::start_vrf_flow() const + 0xe (synth_sgn)
0x18251d: SGN_FN_LIB::start(SGN_WRAPPER_INFO*) + 0xb6d (synth_sgn)
0x186f49: SGN_EXTRACTOR::single_module_extraction(HDB_INSTANCE_NAME*, HDB_ENTITY*, SGN_WRAPPER_INFO*) const + 0x119 (synth_sgn)
0x18f6a1: SGN_EXTRACTOR::recursive_extraction(HDB_INSTANCE_NAME*, SGN_WRAPPER_INFO*, char const*) + 0xf1 (synth_sgn)
0x19b990: SGN_EXTRACTOR::extract() + 0x2b0 (synth_sgn)
0x1a6200: sgn_qic_full(CMP_FACADE*, std::vector<std::string, std::allocator<std::string> >&, std::vector<double, std::allocator<double> >&) + 0x250 (synth_sgn)
0x19773: qsyn_execute_sgn(CMP_FACADE*, std::vector<std::string, std::allocator<std::string> >&, std::string const&, THR_NAMED_PIPE*, THR_NAMED_PIPE*) + 0x173 (quartus_map)
0x34a09: QSYN_FRAMEWORK::execute_core(THR_NAMED_PIPE*, THR_NAMED_PIPE*) + 0x219 (quartus_map)
0x3771f: QSYN_FRAMEWORK::execute() + 0x8af (quartus_map)
0x1b026: qexe_standard_main(QEXE_FRAMEWORK*, QEXE_OPTION_DEFINITION const**, int, char const**) + 0x6a7 (comp_qexe)
0x2b821: qsyn_main(int, char const**) + 0x151 (quartus_map)
0x3ee30: msg_main_thread(void*) + 0x10 (ccl_msg)
0x5acc: thr_final_wrapper + 0xc (ccl_thr)
0x3eeef: msg_thread_wrapper(void* (*)(void*), void*) + 0x62 (ccl_msg)
0x9f9c: mem_thread_wrapper(void* (*)(void*), void*) + 0x5c (ccl_mem)
0x8b39: err_thread_wrapper(void* (*)(void*), void*) + 0x27 (ccl_err)
0x5b0f: thr_thread_wrapper + 0x15 (ccl_thr)
0x40ea1: msg_exe_main(int, char const**, int (*)(int, char const**)) + 0xb2 (ccl_msg)
0x237b3: __libc_start_main + 0xf3 (c.so.6)


End-trace


Executable: quartus_map
Comment:
Quartus Synthesis and Mapping crashes while elaborating Intel Design Template File for Dual Port Ram.
One VHDL input file is required to reproduce problem with the following contents:
-- Quartus Prime VHDL Template
--
-- True Dual-Port RAM with single clock and different data width on the two ports
--
-- The first datawidth and the widths of the addresses are specified
-- The second data width is equal to DATA_WIDTH1 * RATIO, where RATIO = (1 << (ADDRESS_WIDTH1 - ADDRESS_WIDTH2)
-- RATIO must have value that is supported by the memory blocks in your target
-- device. Otherwise, no RAM will be inferred.
--
-- Read-during-write behavior returns old data for all combinations of read and
-- write on both ports
--
-- This style of RAM cannot be used on certain devices, e.g. Stratix V; in that case use the template for Dual-Port RAM with new data on read-during write on the same port

library ieee;
use ieee.std_logic_1164.all;

entity mixed_width_true_dual_port_ram is
generic (
DATA_WIDTH1 : natural := 8;
ADDRESS_WIDTH1 : natural := 10;
ADDRESS_WIDTH2 : natural := 8);
port (
we1 : in std_logic;
we2 : in std_logic;
clk1 : in std_logic;
clk2 : in std_logic;
addr1 : in natural range 0 to (2 ** ADDRESS_WIDTH1 - 1);
addr2 : in natural range 0 to (2 ** ADDRESS_WIDTH2 - 1);
data_in1 : in std_logic_vector(DATA_WIDTH1 - 1 downto 0);
data_in2 : in std_logic_vector(DATA_WIDTH1 * (2 ** (ADDRESS_WIDTH1 - ADDRESS_WIDTH2)) - 1 downto 0);
data_out1 : out std_logic_vector(DATA_WIDTH1 - 1 downto 0);
data_out2 : out std_logic_vector(DATA_WIDTH1 * 2 ** (ADDRESS_WIDTH1 - ADDRESS_WIDTH2) - 1 downto 0));
end entity mixed_width_true_dual_port_ram;

architecture rtl of mixed_width_true_dual_port_ram is
constant RATIO : natural := 2 ** (ADDRESS_WIDTH1 - ADDRESS_WIDTH2);
constant DATA_WIDTH2 : natural := DATA_WIDTH1 * RATIO;
constant RAM_DEPTH : natural := 2 ** ADDRESS_WIDTH2;

-- Use a multidimensional array to model mixed-width
type word_t is array(RATIO - 1 downto 0) of std_logic_vector(DATA_WIDTH1 - 1 downto 0);
type ram_t is array (0 to RAM_DEPTH - 1) of word_t;

-- declare the RAM
shared variable ram : ram_t;
signal w1_local : word_t;
signal q1_local : word_t;

begin -- rtl
-- Re-organize the write data to match the RAM word type
unpack: for i in 0 to RATIO - 1 generate
w1_local(i) <= data_in2(DATA_WIDTH1*(i+1) - 1 downto DATA_WIDTH1*i);
data_out2(DATA_WIDTH1*(i+1) - 1 downto DATA_WIDTH1*i) <= q1_local(i);
end generate unpack;

-- port B
process(clk1)
begin
if (rising_edge(clk1)) then
data_out1 <= ram(addr1 / RATIO)(addr1 mod RATIO);
if (we1 ='1') then
ram(addr1 / RATIO)(addr1 mod RATIO) := data_in1;
end if;
end if;
end process;

--port A
process(clk2)
begin
if (rising_edge(clk2)) then
if (we2 = '1') then
ram(addr2) := w1_local;
end if;
q1_local <= ram(addr2);
end if;
end process;
end rtl;


System Information
Platform: linux64
OS name: CentOS Linux
OS version:

Quartus Prime Information
Address bits: 64
Version: 20.1.1
Build: 720
Edition: Standard Edition

0 Kudos

Accepted Solutions
Dagobah
Beginner
17 Views

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 is

    function 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;

View solution in original post

3 Replies
KennyT_Intel
Moderator
38 Views
Dagobah
Beginner
27 Views

Yes, the posted link seems to be related to the problem and I am working on a VHDL work around to adhere to the RAM port width limitations of the tools.  However, I am now getting a different Fatal error with Segment Violation and would like to know if this is also a known issue with suggested method to fix or explanation for the crash:

Problem Details
Error:

*** Fatal Error: Segment Violation at 0x4b
Module: quartus_map
Stack Trace:
0x13ca17: CDB_SGATE_OTERM::adopt_fanouts(CDB_SGATE_OTERM*, bool) + 0x7 (db_cdb_sgate)
0x51032: OPT_RAM_CANDIDATE::create_bypass_logic(bool, bool) + 0x2e2 (synth_infer)
0x51e7e: OPT_RAM_CANDIDATE::do_non_tdp_conversion() + 0xce (synth_infer)
0x52aed: OPT_RAM_CANDIDATE::convert_to_megafunction() + 0x9d (synth_infer)
0x32106: opt_convert_candidates(std::vector<OPT_RAM_BLOCK_CANDIDATE*, std::allocator<OPT_RAM_BLOCK_CANDIDATE*> >&) + 0x76 (synth_infer)
0x19f6b9: RTL_SCRIPT::call_ram_rom_fns(char const*, char const*, char const*) + 0x459 (synth_opt)
0x19c67c: RTL_SCRIPT::call_named_function(char const*, char const*, char const*, int, int, int) + 0xaec (synth_opt)
0x19b2c7: RTL_SCRIPT::process_script(CDB_SGATE_NETLIST*, CDB_SGATE_HIERARCHY*, BASEX_ELABORATE_INFO*, CMP_FACADE*, RTL_SCRIPT_ENUM, char const* (*) [3], int, RTL_SCRIPT_STEP*, RTL_SCRIPT_STEP*) + 0x7c7 (synth_opt)
0x1ae3b1: opt_process_netlist_scripted(CMP_FACADE*, CDB_SGATE_HIERARCHY*, BASEX_ELABORATE_INFO*, RTL_SCRIPT_ENUM, bool) + 0x3c1 (synth_opt)
0x1af33c: RTL_ROOT::process_sgate_netlist(CMP_FACADE*, CDB_SGATE_HIERARCHY*, BASEX_ELABORATE_INFO*, RTL_PASS_ENUM) + 0x34c (synth_opt)
0x17ede7: SGN_SYNTHESIS::high_level_synthesis() + 0x1b7 (synth_sgn)
0x17fcc0: SGN_SYNTHESIS::process_current_stage() + 0x140 (synth_sgn)
0x191408: SGN_EXTRACTOR::synthesize_partition(unsigned long) + 0x378 (synth_sgn)
0x191ddc: SGN_EXTRACTOR::synthesis() + 0x1ec (synth_sgn)
0x1a58d4: SGN_EXTRACTOR::synthesis_and_post_processing() + 0x64 (synth_sgn)
0x1a65a0: sgn_qic_full(CMP_FACADE*, std::vector<std::string, std::allocator<std::string> >&, std::vector<double, std::allocator<double> >&) + 0x5f0 (synth_sgn)
0x19773: qsyn_execute_sgn(CMP_FACADE*, std::vector<std::string, std::allocator<std::string> >&, std::string const&, THR_NAMED_PIPE*, THR_NAMED_PIPE*) + 0x173 (quartus_map)
0x34a09: QSYN_FRAMEWORK::execute_core(THR_NAMED_PIPE*, THR_NAMED_PIPE*) + 0x219 (quartus_map)
0x3771f: QSYN_FRAMEWORK::execute() + 0x8af (quartus_map)
0x1b026: qexe_standard_main(QEXE_FRAMEWORK*, QEXE_OPTION_DEFINITION const**, int, char const**) + 0x6a7 (comp_qexe)
0x2b821: qsyn_main(int, char const**) + 0x151 (quartus_map)
0x3ee30: msg_main_thread(void*) + 0x10 (ccl_msg)
0x5acc: thr_final_wrapper + 0xc (ccl_thr)
0x3eeef: msg_thread_wrapper(void* (*)(void*), void*) + 0x62 (ccl_msg)
0x9f9c: mem_thread_wrapper(void* (*)(void*), void*) + 0x5c (ccl_mem)
0x8b39: err_thread_wrapper(void* (*)(void*), void*) + 0x27 (ccl_err)
0x5b0f: thr_thread_wrapper + 0x15 (ccl_thr)
0x40ea1: msg_exe_main(int, char const**, int (*)(int, char const**)) + 0xb2 (ccl_msg)
0x23493: __libc_start_main + 0xf3 (c.so.6)


End-trace


Executable: quartus_map
Comment:
None

System Information
Platform: linux64
OS name: CentOS Stream
OS version:

Quartus Prime Information
Address bits: 64
Version: 20.1.1
Build: 720
Edition: Standard Edition

Dagobah
Beginner
18 Views

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 is

    function 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;

View solution in original post