Skip to content

Commit

Permalink
Elaboration needs to copy subprograms in architecture body. Fixes #428
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Oct 9, 2021
1 parent 9ac434d commit 490e8ac
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/sem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,8 @@ static bool sem_check_process(tree_t t)

if (tree_kind(d) == T_USE)
tree_add_context(top_scope->unit, d);
else if (is_subprogram(d))
tree_add_attr_int(d, elab_copy_i, 1);
}

ok = ok && sem_check_stmts(t, tree_stmt, tree_stmts(t));
Expand Down Expand Up @@ -1494,6 +1496,8 @@ static bool sem_check_arch(tree_t t)

if (tree_kind(d) == T_USE)
tree_add_context(t, d);
else if (is_subprogram(d))
tree_add_attr_int(d, elab_copy_i, 1);
}
}

Expand Down
139 changes: 139 additions & 0 deletions test/regress/issue428.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
library ieee;
use ieee.std_logic_1164.all;
package SYNC is
constant SYNC_MAX_PLUG_SIZE : integer := 32;
subtype SYNC_PLUG_NUM_TYPE is integer range 1 to SYNC_MAX_PLUG_SIZE;
subtype SYNC_SIG_TYPE is std_logic_vector(1 to SYNC_MAX_PLUG_SIZE);
subtype SYNC_REQ_TYPE is integer;
subtype SYNC_ACK_TYPE is std_logic;
type SYNC_REQ_VECTOR is array (INTEGER range <>) of SYNC_REQ_TYPE;
type SYNC_ACK_VECTOR is array (INTEGER range <>) of SYNC_ACK_TYPE;
component SYNC_SIG_DRIVER
generic (
PLUG_NUM : SYNC_PLUG_NUM_TYPE := 1
);
port (
SYNC : inout SYNC_SIG_TYPE;
REQ : in SYNC_REQ_TYPE;
ACK : out SYNC_ACK_TYPE
);
end component;
end package;

library ieee;
use ieee.std_logic_1164.all;
library WORK;
use WORK.SYNC.all;
entity SYNC_SIG_DRIVER_SUB_UNIT is
port (
SYNC_I : in SYNC_SIG_TYPE;
SYNC_O : out std_logic;
REQ : in SYNC_REQ_TYPE;
ACK : out SYNC_ACK_TYPE
);
end SYNC_SIG_DRIVER_SUB_UNIT;
architecture MODEL of SYNC_SIG_DRIVER_SUB_UNIT is
function ALL_ONE(SYNC : SYNC_SIG_TYPE) return boolean is
variable sync_vec : SYNC_SIG_TYPE;
constant all_1 : SYNC_SIG_TYPE := (others => '1');
begin
for i in SYNC'range loop
if (SYNC(i) = '0') then
sync_vec(i) := '0';
else
sync_vec(i) := '1';
end if;
end loop;
if (sync_vec = all_1) then
return true;
else
return false;
end if;
end function;
begin
process begin
SYNC_O <= 'Z';
ACK <= '0';
SYNC_LOOP: loop
if (REQ > 0) then
SYNC_O <= 'H';
wait until (ALL_ONE(SYNC_I)); -- This line causes an error
SYNC_O <= '0';
ACK <= '1';
wait until (REQ = 0);
ACK <= '0';
elsif (REQ = 0) then
SYNC_O <= '0';
else
SYNC_O <= 'Z';
end if;
wait on REQ;
end loop;
end process;
end MODEL;

library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
library WORK;
use WORK.SYNC.all;
entity SYNC_SIG_DRIVER is
generic (
PLUG_NUM : SYNC_PLUG_NUM_TYPE := 1
);
port (
SYNC : inout SYNC_SIG_TYPE;
REQ : in SYNC_REQ_TYPE;
ACK : out SYNC_ACK_TYPE
);
end SYNC_SIG_DRIVER;
architecture MODEL of SYNC_SIG_DRIVER is
component SYNC_SIG_DRIVER_SUB_UNIT is
port (
SYNC_I : in SYNC_SIG_TYPE;
SYNC_O : out std_logic;
REQ : in SYNC_REQ_TYPE;
ACK : out SYNC_ACK_TYPE
);
end component;
begin
U: SYNC_SIG_DRIVER_SUB_UNIT
port map(
SYNC_I => SYNC,
SYNC_O => SYNC(PLUG_NUM),
REQ => REQ,
ACK => ACK
);
end MODEL;

library ieee;
use ieee.std_logic_1164.all;
library WORK;
use WORK.SYNC.all;
entity issue428 is
end issue428;
architecture MODEL of issue428 is
constant PLUG_SIZE : integer := 2;
signal SYNC : SYNC_SIG_TYPE;
signal REQ : SYNC_REQ_VECTOR(1 to PLUG_SIZE);
signal ACK : SYNC_ACK_VECTOR(1 to PLUG_SIZE);
begin
PLUG : for i in 1 to PLUG_SIZE generate
DRIVER : SYNC_SIG_DRIVER
generic map (PLUG_NUM => i)
port map (SYNC => SYNC, REQ => REQ(i), ACK => ACK(i));
end generate;
process begin
REQ(1) <= 0;
wait;
end process;
process begin
wait for 5 ns;
REQ(2) <= 1;
wait for 10 ns;
assert ack(2) = '1';
wait;
end process;

sync <= (others => '1') after 10 ns;
end MODEL;
1 change: 1 addition & 0 deletions test/regress/testlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -382,3 +382,4 @@ issue405 normal
issue423 normal
driver6 normal
driver7 fail,gold
issue428 normal
2 changes: 1 addition & 1 deletion test/test_elab.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ START_TEST(test_copy1)
tree_t func2 = search_decls(sub2_i, ident_new("DOUBLE"), 0);
fail_if(func1 == NULL);
fail_if(func2 == NULL);
fail_unless(func1 == func2); // Should not copy functions
fail_if(func1 == func2); // Should copy functions

tree_t var1 = search_decls(sub1_i, ident_new("GLOBAL"), 0);
tree_t var2 = search_decls(sub2_i, ident_new("GLOBAL"), 0);
Expand Down

0 comments on commit 490e8ac

Please sign in to comment.