From 18e9002034f9e991e584706fea75db16fb1536ed Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Wed, 18 Jan 2023 20:10:59 +0000 Subject: [PATCH] Values not propagated through port map aggregate actual. Fixes #595 --- src/sem.c | 31 ++++++++++++++++---------- src/simp.c | 11 +++------- src/tree.c | 2 -- test/regress/issue595.vhd | 46 +++++++++++++++++++++++++++++++++++++++ test/regress/testlist.txt | 1 + 5 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 test/regress/issue595.vhd diff --git a/src/sem.c b/src/sem.c index b49c5fb0..47bb7a49 100644 --- a/src/sem.c +++ b/src/sem.c @@ -3872,19 +3872,28 @@ static bool sem_check_port_actual(formal_map_t *formals, int nformals, "mode OUT", istr(tree_ident(decl))); } - if (standard() < STD_08) { - if (mode == PORT_IN && !sem_globally_static(actual) - && !sem_static_name(actual, sem_globally_static)) { + if (mode == PORT_IN && !sem_globally_static(actual) + && !sem_static_name(actual, sem_globally_static)) { + // LRM 08 section 6.5.6.3 the actual is converted to a concurrent + // signal assignment to an anonymous signal that is then + // associated with the formal + if (standard() >= STD_08) { + tree_t w = tree_new(T_WAVEFORM); + tree_set_loc(w, tree_loc(value)); + tree_set_value(w, value); + + tree_set_value(param, w); + } + else sem_error(value, "actual associated with port %s of mode IN must be " - "a globally static expression or static name", + "a globally static expression or static name", istr(tree_ident(decl))); - } - else if (mode != PORT_IN && tree_kind(actual) != T_OPEN - && !sem_static_signal_name(actual)) { - sem_error(value, "actual associated with port %s of mode %s must be " - "a static signal name or OPEN", - istr(tree_ident(decl)), port_mode_str(tree_subkind(decl))); - } + } + else if (mode != PORT_IN && tree_kind(actual) != T_OPEN + && !sem_static_signal_name(actual)) { + sem_error(value, "actual associated with port %s of mode %s must be " + "a static signal name or OPEN", + istr(tree_ident(decl)), port_mode_str(tree_subkind(decl))); } return true; diff --git a/src/simp.c b/src/simp.c index 381d8135..ae1daa3b 100644 --- a/src/simp.c +++ b/src/simp.c @@ -1,5 +1,5 @@ // -// Copyright (C) 2011-2022 Nick Gasson +// Copyright (C) 2011-2023 Nick Gasson // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -1456,9 +1456,7 @@ static void simp_port_map(tree_t t, simp_ctx_t *ctx) tree_t m = tree_param(t, i); tree_t value = tree_value(m); - if (tree_kind(value) != T_FCALL) - continue; - else if (tree_flags(value) & TREE_F_GLOBALLY_STATIC) + if (tree_kind(value) != T_WAVEFORM) continue; char *signame LOCAL = xasprintf("%s_actual_%d", istr(tree_ident(t)), i); @@ -1484,12 +1482,9 @@ static void simp_port_map(tree_t t, simp_ctx_t *ctx) tree_t a = tree_new(T_SIGNAL_ASSIGN); tree_set_ident(a, ident_new("assign")); tree_set_target(a, r); + tree_add_waveform(a, value); tree_add_stmt(p, a); - tree_t wave = tree_new(T_WAVEFORM); - tree_set_value(wave, value); - tree_add_waveform(a, wave); - tree_t wait = tree_new(T_WAIT); tree_set_ident(wait, ident_new("wait")); tree_set_flag(wait, TREE_F_STATIC_WAIT); diff --git a/src/tree.c b/src/tree.c index cc36d8b9..531c5b0a 100644 --- a/src/tree.c +++ b/src/tree.c @@ -760,8 +760,6 @@ tree_t tree_value(tree_t t) void tree_set_value(tree_t t, tree_t v) { - if ((v != NULL) && (t->object.kind != T_ASSOC) && (t->object.kind != T_SPEC)) - tree_assert_expr(v); lookup_item(&tree_object, t, I_VALUE)->object = &(v->object); object_write_barrier(&(t->object), &(v->object)); } diff --git a/test/regress/issue595.vhd b/test/regress/issue595.vhd new file mode 100644 index 00000000..7aa8a98f --- /dev/null +++ b/test/regress/issue595.vhd @@ -0,0 +1,46 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity test1 is + port ( + inp : in std_logic_vector(0 to 1) + ); +end entity test1; +architecture beh of test1 is +begin + + process + begin + wait for 1 ps; + assert not is_X(inp(0)) report "inp0 is X" severity error; + assert not is_X(inp(1)) report "inp1 is X" severity error; + assert inp(0) = '1' report "inp0 is not 1" severity error; + assert inp(1) = '0' report "inp1 is not 0" severity error; + wait; + end process; + +end architecture beh; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity issue595 is +end entity issue595; +architecture beh of issue595 is + signal inp0 : std_logic; + signal inp1 : std_logic; +begin + i_test : entity work.test1 + port map( + inp => (inp1, inp0) + ); + process + begin + inp0 <= '0'; + inp1 <= '1'; + wait; + end process; + +end architecture beh; diff --git a/test/regress/testlist.txt b/test/regress/testlist.txt index 3ae53a7c..bdb3c674 100644 --- a/test/regress/testlist.txt +++ b/test/regress/testlist.txt @@ -705,3 +705,4 @@ case15 normal,2008 driver16 normal issue589 normal,2000 issue590 normal +issue595 normal,2008 -- 2.39.2