From c48d194a4b1f7454524a3f0bd16fa8faf9f7ec85 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Wed, 24 Apr 2024 20:41:27 +0100 Subject: [PATCH] Fix spurious error with generic package types in port list Fixes #881 --- src/names.c | 3 +- src/sem.c | 4 +- src/type.c | 14 ++-- test/regress/issue881.vhd | 130 ++++++++++++++++++++++++++++++++++++++ test/regress/testlist.txt | 1 + 5 files changed, 141 insertions(+), 11 deletions(-) create mode 100644 test/regress/issue881.vhd diff --git a/src/names.c b/src/names.c index dc499675..af3ebebc 100644 --- a/src/names.c +++ b/src/names.c @@ -1114,7 +1114,8 @@ static scope_t *private_scope_for(nametab_t *tab, tree_t unit) // and as a actual generic subprogram tree_t value = find_generic_map(unit, i, g); if (value == NULL) - assert(error_count() > 0); + assert(error_count() > 0 + || is_uninstantiated_package(unit)); else if (tree_kind(value) == T_REF && tree_has_ref(value)) { decl = tree_ref(value); assert(is_subprogram(decl)); diff --git a/src/sem.c b/src/sem.c index 4937df1d..51161a18 100644 --- a/src/sem.c +++ b/src/sem.c @@ -4480,8 +4480,8 @@ static bool sem_check_port_actual(formal_map_t *formals, int nformals, if (!sem_check_type(expr, type, tab)) sem_error(value, "type of actual %s does not match type %s of formal " - "port %s", type_pp(value_type), type_pp(type), - istr(tree_ident(decl))); + "port %s", type_pp2(value_type, type), + type_pp2(type, value_type), istr(tree_ident(decl))); const port_mode_t mode = tree_subkind(decl); diff --git a/src/type.c b/src/type.c index 879df6a8..cbbae2e5 100644 --- a/src/type.c +++ b/src/type.c @@ -165,15 +165,13 @@ static bool _type_eq(type_t a, type_t b, bool strict, hash_t *map) type_kind_t kind_b = b->object.kind; if (map != NULL) { - if (kind_a == T_GENERIC) { - a = hash_get(map, a) ?: a; - kind_a = a->object.kind; - } + assert(standard() >= STD_08); // Type generics - if (kind_b == T_GENERIC) { - b = hash_get(map, b) ?: b; - kind_b = b->object.kind; - } + a = hash_get(map, a) ?: a; + kind_a = a->object.kind; + + b = hash_get(map, b) ?: b; + kind_b = b->object.kind; if (a == b) return true; diff --git a/test/regress/issue881.vhd b/test/regress/issue881.vhd new file mode 100644 index 00000000..6c05439d --- /dev/null +++ b/test/regress/issue881.vhd @@ -0,0 +1,130 @@ +package generic_complex is generic ( + type t ; + + -- default subprograms + function "+"(l, r : t) return t is <> ; + function to_string(x : t) return string is <> +) ; + + -- cute way of making an array of type t with indices for re and im parts + type complex_parts is (re, im) ; + type complex is array(complex_parts) of t ; + + -- complex summing operation + function "+"(l, r : complex) return complex ; + + -- string representation + function to_string(x : complex) return string ; + +end package ; + +package body generic_complex is + + function "+"(l, r : complex) return complex is + begin + return (re => l(re)+r(re), im => l(im)+r(im)) ; + end function ; + + function to_string(x : complex) return string is + begin + return "(" & to_string(x(re)) & "," & to_string(x(im)) & ")" ; + end function ; + +end package body ; + +entity pipelined_complex_sum is + generic ( + package complex_pkg is new work.generic_complex generic map(<>) + ) ; + port ( + clock : in bit ; + a : in complex_pkg.complex ; + b : in complex_pkg.complex ; + c : out complex_pkg.complex + ) ; +end entity ; + +architecture arch of pipelined_complex_sum is + + use complex_pkg.all ; + +begin + + process(clock) + begin + if( rising_edge(clock) ) then + c <= a + b ; + end if ; + end process ; + +end architecture ; + +-- create the two different complex packages +package complex_int is new work.generic_complex generic map (t => integer) ; +package complex_real is new work.generic_complex generic map (t => real) ; + +use work.complex_real.all ; +use work.complex_int.all ; + +entity issue881 is +end entity ; + +architecture arch of issue881 is + + -- signals for real summer + signal ar : work.complex_real.complex ; + signal br : work.complex_real.complex ; + signal cr : work.complex_real.complex ; + + -- signals for int summer + signal ai : work.complex_int.complex ; + signal bi : work.complex_int.complex ; + signal ci : work.complex_int.complex ; + + -- clock + signal clock : bit ; + +begin + + clock <= not clock after 1 ns ; + + U_real_summer : entity work.pipelined_complex_sum + generic map ( + complex_pkg => work.complex_real + ) port map ( + clock => clock, + a => ar, + b => br, + c => cr + ) ; + + U_int_summer : entity work.pipelined_complex_sum + generic map ( + complex_pkg => work.complex_int + ) port map ( + clock => clock, + a => ai, + b => bi, + c => ci + ) ; + + tb : process + variable val : work.complex_int.complex ; + begin + for i in 1 to 10 loop + val := (i, 42*i) ; + ai <= val ; + ar <= (real(val(re)), real(val(im))) ; + + val := (-7*i, 100*i) ; + bi <= val ; + br <= (real(val(re)), real(val(im))) ; + + wait until rising_edge(clock) ; + end loop ; + + assert ci = (-54, 1278); + std.env.stop ; + end process ; + +end architecture ; diff --git a/test/regress/testlist.txt b/test/regress/testlist.txt index 1d187230..8a1cf4df 100644 --- a/test/regress/testlist.txt +++ b/test/regress/testlist.txt @@ -968,3 +968,4 @@ issue878 wave,2008,dump-arrays ivtest2 verilog,gold ivtest3 verilog vlog9 verilog +issue881 normal,2008 -- 2.39.2