From b97c6582b8791b3e6343789548b73c7a80e1c6bf Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sat, 3 Feb 2024 20:25:09 +0000 Subject: [PATCH] Allow port collapsing in component instantiations --- src/driver.c | 19 +++++++++++-- src/driver.h | 4 +-- src/elab.c | 3 ++ test/lower/directmap6.vhd | 28 +++++++++++++++++++ test/test_lower.c | 58 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 test/lower/directmap6.vhd diff --git a/src/driver.c b/src/driver.c index 632df696..edda9c86 100644 --- a/src/driver.c +++ b/src/driver.c @@ -1,5 +1,5 @@ // -// Copyright (C) 2023 Nick Gasson +// Copyright (C) 2023-2024 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 @@ -263,12 +263,25 @@ static void visit_block(driver_set_t *ds, tree_t b, bool tentative) } -driver_set_t *find_drivers(tree_t block) +driver_set_t *find_drivers(tree_t where) { driver_set_t *ds = xcalloc(sizeof(driver_set_t)); ds->map = hash_new(128); - visit_block(ds, block, false); + switch (tree_kind(where)) { + case T_ARCH: + case T_BLOCK: + case T_FOR_GENERATE: + case T_COND_STMT: + case T_ALTERNATIVE: + visit_block(ds, where, false); + break; + case T_BINDING: + visit_port_map(ds, primary_unit_of(tree_ref(where)), where, false); + break; + default: + fatal_trace("cannot find drivers in %s", tree_kind_str(tree_kind(where))); + } if (opt_get_int(OPT_DRIVER_VERBOSE)) dump_drivers(ds); diff --git a/src/driver.h b/src/driver.h index 23e9721f..3cae655c 100644 --- a/src/driver.h +++ b/src/driver.h @@ -1,5 +1,5 @@ // -// Copyright (C) 2023 Nick Gasson +// Copyright (C) 2023-2024 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 @@ -32,7 +32,7 @@ typedef struct _driver_info { bool tentative; } driver_info_t; -driver_set_t *find_drivers(tree_t block); +driver_set_t *find_drivers(tree_t where); driver_info_t *get_drivers(driver_set_t *ds, tree_t what); bool has_unique_driver(driver_set_t *ds, tree_t what); void free_drivers(driver_set_t *ds); diff --git a/src/elab.c b/src/elab.c index 08447544..51c23242 100644 --- a/src/elab.c +++ b/src/elab.c @@ -1333,6 +1333,9 @@ static void elab_component(tree_t inst, tree_t comp, const elab_ctx_t *ctx) elab_generics(comp, inst, &new_ctx); elab_ports(comp, inst, &new_ctx); + if (bind != NULL && tree_kind(bind) != T_VERILOG) // XXX: temporary + new_ctx.drivers = find_drivers(bind); + if (error_count() == 0) elab_lower(b, NULL, &new_ctx); diff --git a/test/lower/directmap6.vhd b/test/lower/directmap6.vhd new file mode 100644 index 00000000..e62b41bb --- /dev/null +++ b/test/lower/directmap6.vhd @@ -0,0 +1,28 @@ +entity sub is + port ( ii : in bit; oo : out bit ); +end entity; + +architecture test of sub is +begin + oo <= ii after 1 ps; +end architecture; + +------------------------------------------------------------------------------- + +entity directmap6 is +end entity; + +architecture test of directmap6 is + component sub is + port ( i : in bit; o : out bit ); + end component; + + for u : sub use entity work.sub + port map ( ii => i, oo => o ); + + signal x, y : bit; +begin + + u: sub port map ( x, y ); + +end architecture; diff --git a/test/test_lower.c b/test/test_lower.c index 76bc61fd..79c3d98a 100644 --- a/test/test_lower.c +++ b/test/test_lower.c @@ -5939,6 +5939,63 @@ START_TEST(test_issue837) } END_TEST +START_TEST(test_directmap6) +{ + input_from_file(TESTDIR "/lower/directmap6.vhd"); + + run_elab(); + + { + vcode_unit_t vu = find_unit("WORK.DIRECTMAP6.U"); + vcode_select_unit(vu); + + EXPECT_BB(0) = { + { VCODE_OP_VAR_UPREF, .hops = 1, .name = "X" }, + { VCODE_OP_LOAD_INDIRECT }, + { VCODE_OP_VAR_UPREF, .hops = 1, .name = "Y" }, + { VCODE_OP_LOAD_INDIRECT }, + { VCODE_OP_DEBUG_LOCUS }, + { VCODE_OP_ALIAS_SIGNAL }, + { VCODE_OP_STORE, .name = "I" }, + { VCODE_OP_DEBUG_LOCUS }, + { VCODE_OP_ALIAS_SIGNAL }, + { VCODE_OP_STORE, .name = "O" }, + { VCODE_OP_CONST, .value = 0 }, + { VCODE_OP_CONST, .value = 1 }, + { VCODE_OP_MAP_CONST }, + { VCODE_OP_RETURN }, + }; + + CHECK_BB(0); + } + + { + vcode_unit_t vu = find_unit("WORK.DIRECTMAP6.U.SUB"); + vcode_select_unit(vu); + + EXPECT_BB(0) = { + { VCODE_OP_PACKAGE_INIT, .name = "STD.STANDARD" }, + { VCODE_OP_VAR_UPREF, .hops = 1, .name = "I" }, + { VCODE_OP_LOAD_INDIRECT }, + { VCODE_OP_VAR_UPREF, .hops = 1, .name = "O" }, + { VCODE_OP_LOAD_INDIRECT }, + { VCODE_OP_DEBUG_LOCUS }, + { VCODE_OP_ALIAS_SIGNAL }, + { VCODE_OP_STORE, .name = "II" }, + { VCODE_OP_DEBUG_LOCUS }, + { VCODE_OP_ALIAS_SIGNAL }, + { VCODE_OP_STORE, .name = "OO" }, + { VCODE_OP_CONST, .value = 0 }, + { VCODE_OP_CONST, .value = 1 }, + { VCODE_OP_MAP_CONST }, + { VCODE_OP_RETURN }, + }; + + CHECK_BB(0); + } +} +END_TEST + Suite *get_lower_tests(void) { Suite *s = suite_create("lower"); @@ -6081,6 +6138,7 @@ Suite *get_lower_tests(void) tcase_add_test(tc, test_subtype2); tcase_add_test(tc, test_directmap5); tcase_add_test(tc, test_issue837); + tcase_add_test(tc, test_directmap6); suite_add_tcase(s, tc); return s; -- 2.39.2