From c1c4c2831300d7d269bd4133679317190b67dc8b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 2 Jun 2023 18:58:42 -0700 Subject: [PATCH 1/2] Handle implicit task/function imports in the unit scope SystemVerilog requires that functions and tasks are not implicitly imported if a symbol with the same name appears in the scope, even if it the symbol is declared after its usage. To support this a list of potential imports is collected while parsing a scope and only when the end of the scope is reached it is evaluated whether the symbol should be imported or not based on whether it already exists in the scope. This currently works fine for all scopes except for the unit scope. Since the unit scope might span multiple files it is never explicitly closed and the potential imports are never checked. Make sure that after parsing all files is done the potential imports for the unit scope are checked. Signed-off-by: Lars-Peter Clausen --- main.cc | 2 ++ parse_api.h | 2 ++ pform.cc | 21 +++++++++++++++++---- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/main.cc b/main.cc index 8b93f1c62..057b70ac2 100644 --- a/main.cc +++ b/main.cc @@ -1126,6 +1126,8 @@ int main(int argc, char*argv[]) rc += pform_parse(source_files[idx]); } + pform_finish(); + if (pf_path) { ofstream out (pf_path); out << "PFORM DUMP NATURES:" << endl; diff --git a/parse_api.h b/parse_api.h index d95420916..da43030e1 100644 --- a/parse_api.h +++ b/parse_api.h @@ -58,6 +58,8 @@ extern void pform_dump(std::ostream&out, const PTaskFunc*tf); */ extern int pform_parse(const char*path); +extern void pform_finish(); + extern std::string vl_file; extern void pform_set_timescale(int units, int prec, const char*file, diff --git a/pform.cc b/pform.cc index e8aac1089..9b19f9dba 100644 --- a/pform.cc +++ b/pform.cc @@ -405,17 +405,22 @@ LexicalScope* pform_peek_scope(void) return lexical_scope; } -void pform_pop_scope() +static void pform_check_possible_imports(LexicalScope *scope) { - LexicalScope*scope = lexical_scope; - assert(scope); - map::const_iterator cur; for (cur = scope->possible_imports.begin(); cur != scope->possible_imports.end(); ++cur) { if (scope->local_symbols.find(cur->first) == scope->local_symbols.end()) scope->explicit_imports[cur->first] = cur->second; } scope->possible_imports.clear(); +} + +void pform_pop_scope() +{ + LexicalScope*scope = lexical_scope; + assert(scope); + + pform_check_possible_imports(scope); lexical_scope = scope->parent_scope(); assert(lexical_scope); @@ -3406,3 +3411,11 @@ int pform_parse(const char*path) destroy_lexor(); return error_count; } + +void pform_finish() +{ + // Wait until all parsing is done and all symbols in the unit scope are + // known before importing possible imports. + for (auto unit : pform_units) + pform_check_possible_imports(unit); +} From 542d80b1b1f87f7ab183d3b8818778c8bfb7dab8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 11 Jun 2023 09:15:09 -0700 Subject: [PATCH 2/2] Add regression tests for implicit function/task import the unit scope Check that implicit import of functions and tasks is supported if the wildcard import statement is in the unit scope. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/sv_wildcard_import8.v | 28 +++++++++++++++++++++++ ivtest/regress-vvp.list | 1 + ivtest/vvp_tests/sv_wildcard_import8.json | 5 ++++ 3 files changed, 34 insertions(+) create mode 100644 ivtest/ivltests/sv_wildcard_import8.v create mode 100644 ivtest/vvp_tests/sv_wildcard_import8.json diff --git a/ivtest/ivltests/sv_wildcard_import8.v b/ivtest/ivltests/sv_wildcard_import8.v new file mode 100644 index 000000000..fd0d1d77b --- /dev/null +++ b/ivtest/ivltests/sv_wildcard_import8.v @@ -0,0 +1,28 @@ +// Check that implicit imports of functions and tasks works if the wildcard +// import statement is in the unit scope. + +package P; + + function integer f(integer x); + return x * 2; + endfunction + + task t(bit failed); + if (failed) begin + $display("FAILED"); + end else begin + $display("PASSED"); + end + endtask + +endpackage + +import P::*; + +module test; + + initial begin + t(f(10) !== 20); + end + +endmodule diff --git a/ivtest/regress-vvp.list b/ivtest/regress-vvp.list index 681dd1a81..010bbd743 100644 --- a/ivtest/regress-vvp.list +++ b/ivtest/regress-vvp.list @@ -41,6 +41,7 @@ sv_array_cassign6 vvp_tests/sv_array_cassign6.json sv_array_cassign7 vvp_tests/sv_array_cassign7.json sv_foreach9 vvp_tests/sv_foreach9.json sv_foreach10 vvp_tests/sv_foreach10.json +sv_wildcard_import8 vvp_tests/sv_wildcard_import8.json sdf_header vvp_tests/sdf_header.json task_return1 vvp_tests/task_return1.json task_return2 vvp_tests/task_return2.json diff --git a/ivtest/vvp_tests/sv_wildcard_import8.json b/ivtest/vvp_tests/sv_wildcard_import8.json new file mode 100644 index 000000000..aefcb09a9 --- /dev/null +++ b/ivtest/vvp_tests/sv_wildcard_import8.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_wildcard_import8.v", + "iverilog-args" : [ "-g2005-sv" ] +}