From d4331118e5ff97328b4511d6a62c5e5b65aaf3e2 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Fri, 29 Dec 2023 21:21:14 +0000 Subject: [PATCH] Fix calculation of aggregate bounds with concatenation --- src/lower.c | 22 +++++++++++++++++- test/regress/issue819.vhd | 48 +++++++++++++++++++++++++++++++++++++++ test/regress/testlist.txt | 1 + 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 test/regress/issue819.vhd diff --git a/src/lower.c b/src/lower.c index 0c87c47c..37399953 100644 --- a/src/lower.c +++ b/src/lower.c @@ -3810,6 +3810,8 @@ static vcode_reg_t lower_aggregate_bounds(lower_unit_t *lu, tree_t expr, const int nassocs = tree_assocs(expr); + const bool pos_concat = (standard() >= STD_08 && dimension_of(type) == 1); + int64_t pos = 0; bool known_elem_count = true; for (int i = 0; i < nassocs; i++) { tree_t a = tree_assoc(expr, i); @@ -3856,7 +3858,25 @@ static vcode_reg_t lower_aggregate_bounds(lower_unit_t *lu, tree_t expr, break; case A_POS: - ihigh = ilow = (dir == RANGE_TO ? low + i : high - i); + { + int64_t length = 1; + if (pos_concat) { + type_t value_type = tree_type(tree_value(a)); + if (type_eq(type, value_type)) + length = lower_array_const_size(value_type); + } + + if (dir == RANGE_TO) { + ilow = low + pos; + ihigh = ilow + length - 1; + } + else { + ihigh = high - pos; + ilow = ihigh - length + 1; + } + + pos += length; + } break; } diff --git a/test/regress/issue819.vhd b/test/regress/issue819.vhd new file mode 100644 index 00000000..e8e5f2d3 --- /dev/null +++ b/test/regress/issue819.vhd @@ -0,0 +1,48 @@ +package my_logic is + type std_ulogic is ('U', '0', '1', 'X'); + type std_ulogic_vector is array (natural range <>) of std_ulogic; + type unsigned is array (natural range <>) of std_ulogic; + type signed is array (natural range <>) of std_ulogic; +end package; + +library ieee; +use work.my_logic.all; + +package uCPUtypes is + alias logic is std_ulogic; + alias logic_vec is std_ulogic_vector; + subtype unsigned_byte is unsigned(7 downto 0); + subtype code_word is unsigned(11 downto 0); +end package uCPUtypes; + +------------------------------------------------------------------------------- + +library ieee; +use work.uCPUtypes.all; +use work.my_logic.all; + +entity issue819 is +end entity; + +architecture test of issue819 is + signal rom_data : code_word; + alias op : unsigned(2 downto 0) is rom_data(11 downto 9); -- opcode + + signal alu_arg, alu_res : unsigned_byte; + signal alu_c : logic; + +begin + + with op(1 downto 0) select + (alu_c, alu_res) <= '0' & alu_arg when "00", + ('X', x"XX") when others; + + check: process is + begin + wait for 1 ns; + assert alu_c = 'X'; + assert alu_res = X"XX"; + wait; + end process; + +end architecture; diff --git a/test/regress/testlist.txt b/test/regress/testlist.txt index 6deacfe8..da4ea792 100644 --- a/test/regress/testlist.txt +++ b/test/regress/testlist.txt @@ -915,3 +915,4 @@ issue815 normal,2019 issue817 fail,gold,2008 issue816 fail,gold gentype7 normal,2019 +issue819 normal,2008 -- 2.39.2