From d60e165b38f2dee29ff902f7c3543cfe14c5d640 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Fri, 11 Feb 2022 12:15:33 +0800 Subject: [PATCH] Fix incorrect generic map value with component generics. Issue #448 --- NEWS.md | 2 ++ src/elab.c | 6 +++++- test/elab/issue448.vhd | 49 ++++++++++++++++++++++++++++++++++++++++++ test/test_elab.c | 26 ++++++++++++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 test/elab/issue448.vhd diff --git a/NEWS.md b/NEWS.md index 95d7dfe4..32d96792 100644 --- a/NEWS.md +++ b/NEWS.md @@ -7,6 +7,8 @@ - Generic declarations are now allowed to hide the entity name. - Fix spurious error about duplicate declarations when using VHDL-2008 context declarations. +- Fix incorrect default generic value when component and entity specify + generics in different order (#448). ## Version 1.6.1 - 2022-02-05 - Fix compatibility with BSD make (#440). diff --git a/src/elab.c b/src/elab.c index 271d5c18..795c3fc0 100644 --- a/src/elab.c +++ b/src/elab.c @@ -756,6 +756,9 @@ static void elab_generics(tree_t entity, tree_t comp, tree_t inst, tree_t map = NULL, bind_expr = NULL; if (entity != comp) { + // Component generics may be in different order to entity + pos = UINT_MAX; + const int ngenerics_comp = tree_generics(comp); for (int j = 0; j < ngenerics_comp; j++) { tree_t g = tree_generic(comp, j); @@ -770,7 +773,7 @@ static void elab_generics(tree_t entity, tree_t comp, tree_t inst, for (int j = 0; j < binding_ngenmaps; j++) { tree_t m = tree_genmap(binding, j); assert(tree_subkind(m) == P_POS); - if (tree_pos(m) != pos) + if (tree_pos(m) != i) continue; tree_t value = tree_value(m); @@ -780,6 +783,7 @@ static void elab_generics(tree_t entity, tree_t comp, tree_t inst, tree_t decl = tree_ref(value); if (tree_kind(decl) == T_PORT_DECL) { cg = tree_ref(value); + pos = i; break; } } diff --git a/test/elab/issue448.vhd b/test/elab/issue448.vhd new file mode 100644 index 00000000..2d30f3e2 --- /dev/null +++ b/test/elab/issue448.vhd @@ -0,0 +1,49 @@ +entity IMAGE_STREAM_BUFFER_TEST_BENCH is + generic ( + NAME : STRING := "test"; + SCENARIO_FILE : STRING := "test.snr"; + ELEMENT_SIZE : integer := 8*1024; + LINE_SIZE : integer := 0; + BANK_SIZE : integer := 0; + FINISH_ABORT : boolean := FALSE + ); +end IMAGE_STREAM_BUFFER_TEST_BENCH; +----------------------------------------------------------------------------------- +-- +----------------------------------------------------------------------------------- +architecture MODEL of IMAGE_STREAM_BUFFER_TEST_BENCH is +begin + assert ELEMENT_SIZE > 0; +end MODEL; +----------------------------------------------------------------------------------- +-- ELEM_BITS=2bit, CHANNEL_SIZE=0, I.C=32, I.X=1, I.Y=1, O.C=32, O.X=3, O.Y=3 D_SIZE=8 +----------------------------------------------------------------------------------- +entity issue448 is + generic ( + NAME : STRING := "test_0_2_32x1x1_32x4x3x3_bug1"; + SCENARIO_FILE : STRING := "test_0_2_32x1x1_32x4x3x3_bug1.snr"; + + BANK_SIZE : integer := 0; + LINE_SIZE : integer := 0; + FINISH_ABORT : boolean := FALSE + ); +end issue448; +architecture MODEL of issue448 is + component IMAGE_STREAM_BUFFER_TEST_BENCH is + generic ( + NAME : STRING := "test"; + SCENARIO_FILE : STRING := "test.snr"; + BANK_SIZE : integer := 0; + LINE_SIZE : integer := 0; + FINISH_ABORT : boolean := FALSE + ); + end component; +begin + TB: IMAGE_STREAM_BUFFER_TEST_BENCH generic map ( + NAME => NAME , + SCENARIO_FILE => SCENARIO_FILE, + BANK_SIZE => BANK_SIZE , + LINE_SIZE => LINE_SIZE , + FINISH_ABORT => FINISH_ABORT + ); +end MODEL; diff --git a/test/test_elab.c b/test/test_elab.c index a5705b91..de394ce4 100644 --- a/test/test_elab.c +++ b/test/test_elab.c @@ -911,6 +911,31 @@ START_TEST(test_issue442) } END_TEST +START_TEST(test_issue448) +{ + input_from_file(TESTDIR "/elab/issue448.vhd"); + + tree_t e = run_elab(); + fail_if(e == NULL); + + tree_t b0 = tree_stmt(e, 0); + fail_unless(tree_ident(b0) == ident_new("ISSUE448")); + fail_unless(tree_stmts(b0) == 1); + + tree_t tb = tree_stmt(b0, 0); + fail_unless(tree_ident(tb) == ident_new("TB")); + fail_unless(tree_kind(tb) == T_BLOCK); + fail_unless(tree_stmts(tb) == 0); + fail_unless(tree_genmaps(tb) == 6); + + tree_t m1 = tree_value(tree_genmap(tb, 2)); + fail_unless(tree_kind(m1) == T_LITERAL); + fail_unless(tree_ival(m1) == 8192); + + fail_if_errors(); +} +END_TEST + Suite *get_elab_tests(void) { Suite *s = suite_create("elab"); @@ -967,6 +992,7 @@ Suite *get_elab_tests(void) tcase_add_test(tc, test_tc846); tcase_add_test(tc, test_issue435); tcase_add_test(tc, test_issue442); + tcase_add_test(tc, test_issue448); suite_add_tcase(s, tc); return s; -- 2.39.2