Bug: Constant value for record types (NVC Simulator v1.15.2)
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
PACKAGE test_pkg IS
CONSTANT C_NUM_1 : integer := 4;
CONSTANT C_NUM_2 : integer := 2;
TYPE t_slv_vector IS ARRAY (natural RANGE <>) OF std_logic_vector;
TYPE rec_1 IS RECORD
a : std_logic_vector(C_NUM_2 - 1 DOWNTO 0);
b : std_logic_vector(1 DOWNTO 0);
END RECORD;
CONSTANT RST_REC_1 : rec_1 := (OTHERS => (OTHERS => '0'));
TYPE rec_2 IS RECORD
a : std_logic_vector(12 DOWNTO 0);
b : std_logic_vector(31 DOWNTO 0);
c : std_logic_vector(31 DOWNTO 0);
d : t_slv_vector(C_NUM_1 - 1 DOWNTO 0)(31 DOWNTO 0);
e : std_logic_vector(C_NUM_1 - 1 DOWNTO 0);
f : t_slv_vector(C_NUM_1 - 1 DOWNTO 0)(9 DOWNTO 0);
g : t_slv_vector(C_NUM_1 - 1 DOWNTO 0)(31 DOWNTO 0);
h : std_logic_vector(10 DOWNTO 0);
i : std_logic_vector(C_NUM_1 - 1 DOWNTO 0);
j : t_slv_vector(C_NUM_1 - 1 DOWNTO 0)(31 DOWNTO 0);
k : t_slv_vector(C_NUM_1 - 1 DOWNTO 0)(9 DOWNTO 0);
l : t_slv_vector(C_NUM_1 - 1 DOWNTO 0)(15 DOWNTO 0);
m : rec_1;
END RECORD;
CONSTANT RST_REC_2 : rec_2 := (
d => (OTHERS => (OTHERS => '0')),
f => (OTHERS => (OTHERS => '0')),
g => (OTHERS => (OTHERS => '0')),
j => (OTHERS => (OTHERS => '0')),
k => (OTHERS => (OTHERS => '0')),
l => (OTHERS => (OTHERS => '0')),
m => RST_REC_1,
OTHERS => (OTHERS => '0')
);
END test_pkg;
PACKAGE BODY test_pkg IS
END test_pkg;
Output file: /var/local/test/vunit_out/test_output/sys.test_tb.test-alive_23a14e315c62cefe3fd086f18fa92d5ddb35b2c4/output.txt
Seed for sys.test_tb.test-alive: 79a44ec5c06174dc
/opt/nvc/bin/nvc --work=sys:/var/local/test/vunit_out/nvc/libraries/sys --std=2008 --map=vunit_lib:/var/local/test/vunit_out/nvc/libraries/vunit_lib --map=sys:/var/local/test/vunit_out/nvc/libraries/sys -H 64m -e test_tb-bench '-grunner_cfg=active python runner : true,enabled_test_cases : test-alive,output path : /var/local/test/vunit_out/test_output/sys.test_tb.test-alive_23a14e315c62cefe3fd086f18fa92d5ddb35b2c4/,seed : 79a44ec5c06174dc,tb path : /var/local/test/,use_color : true' --no-save --jit -r --exit-severity=error
** Fatal: value length 13 does not match field B length 32
> /var/local/test/test_pkg.vhd:21
|
21 | b : std_logic_vector(31 DOWNTO 0);
| ^
Package SYS.TEST_PKG at /var/local/test/test_pkg.vhd:5
Process (init) at /var/local/test/test_tb.vhd:17
fail (P=0 S=0 F=1 T=1) sys.test_tb.test-alive (0.3 s)
==== Summary ==================================
fail sys.test_tb.test-alive (0.3 s)
===============================================
pass 0 of 1
fail 1 of 1
===============================================
Total time was 0.3 s
Elapsed time was 0.3 s
===============================================
Some failed!
NVC version: NVC Simulator v1.15.2
GHDL has no issue with this but NVC triggers this error.
Hi,
this occurs under the following conditions:
- NVC thinks the value assigned is not constant. For some reason, assigning
RST_REF_1is analysed as non-constant. - The
recordothers choice covers multiple record fields of the same array type, but of different width.
A simpler reproducer for this is:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
entity issue1248 is
end entity;
architecture test of issue1248 is
TYPE rec_1 IS RECORD
x : std_logic_vector(1 DOWNTO 0);
END RECORD;
TYPE rec_2 IS RECORD
a : std_logic_vector(12 DOWNTO 0);
b : std_logic_vector(31 DOWNTO 0);
m : rec_1;
END RECORD;
signal RST_REC_2 : rec_2;
signal B : std_logic := '1';
begin
process
begin
RST_REC_2 <= (
m => (OTHERS => (OTHERS => '0')),
OTHERS => (OTHERS => B)
-- If we replace the above assign with the following, it works
--OTHERS => (OTHERS => '0')
);
wait for 0 ns;
report "A: " & to_string(RST_REC_2.a);
report "B: " & to_string(RST_REC_2.b);
wait;
end process;
end architecture;
The call in lower_record_sub_aggregate taking the else if (type_is_array(ftype)) { branch
ends in lower_array_aggregate, but for each field covered by others, it boils down to the same
type. This is since there is only single tree_t for all record fields covered by others. It gets the
type (range) solved for the first field, and therefore all the follow-up fields "inherit it".
I am not sure on what it would take to fix it. Maybe unroll all the others record aggregates during
simp phase, and convert them to A_NAMED ? It seems to be too messy solution...