Skip to content

Commit

Permalink
Fix spurious error with generic package types in port list
Browse files Browse the repository at this point in the history
Fixes #881
  • Loading branch information
nickg committed Apr 24, 2024
1 parent 51ba06d commit c48d194
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 11 deletions.
3 changes: 2 additions & 1 deletion src/names.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
4 changes: 2 additions & 2 deletions src/sem.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
14 changes: 6 additions & 8 deletions src/type.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
130 changes: 130 additions & 0 deletions test/regress/issue881.vhd
Original file line number Diff line number Diff line change
@@ -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 ;
1 change: 1 addition & 0 deletions test/regress/testlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -968,3 +968,4 @@ issue878 wave,2008,dump-arrays
ivtest2 verilog,gold
ivtest3 verilog
vlog9 verilog
issue881 normal,2008

0 comments on commit c48d194

Please sign in to comment.