From b776283d79555ca7fdc3fa33b507a051ff2a085e Mon Sep 17 00:00:00 2001 From: Rahul Bhagwat Date: Sun, 3 Aug 2025 23:31:54 -0400 Subject: [PATCH 1/7] implement package import --- frontends/ast/ast.cc | 1 + frontends/ast/ast.h | 1 + frontends/ast/genrtlil.cc | 1 + frontends/ast/simplify.cc | 36 ++++++++++++++++++++++++++++++ frontends/verilog/verilog_lexer.l | 1 + frontends/verilog/verilog_parser.y | 11 +++++++++ 6 files changed, 51 insertions(+) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 431f7b4f8..04f749845 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -174,6 +174,7 @@ std::string AST::type2str(AstNodeType type) X(AST_MODPORT) X(AST_MODPORTMEMBER) X(AST_PACKAGE) + X(AST_IMPORT) X(AST_WIRETYPE) X(AST_TYPEDEF) X(AST_STRUCT) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 2c2d408ce..776b5c833 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -153,6 +153,7 @@ namespace AST AST_MODPORT, AST_MODPORTMEMBER, AST_PACKAGE, + AST_IMPORT, AST_WIRETYPE, AST_TYPEDEF, diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 26ed0e3e4..79e543376 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1361,6 +1361,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_GENIF: case AST_GENCASE: case AST_PACKAGE: + case AST_IMPORT: case AST_ENUM: case AST_MODPORT: case AST_MODPORTMEMBER: diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 4d8c57ced..b524fadfd 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1103,6 +1103,42 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin int counter = 0; label_genblks(existing, counter); std::map this_wire_scope; + + // Process package imports after clearing the scope but before processing module declarations + for (auto &child : children) { + if (child->type == AST_IMPORT) { + // Find the package in the design + AstNode *package_node = nullptr; + for (auto &design_child : current_ast->children) { + if (design_child->type == AST_PACKAGE && design_child->str == child->str) { + package_node = design_child; + break; + } + } + + if (package_node) { + // Import all names from the package into current scope + for (auto &pkg_child : package_node->children) { + if (pkg_child->type == AST_PARAMETER || pkg_child->type == AST_LOCALPARAM || + pkg_child->type == AST_TYPEDEF || pkg_child->type == AST_FUNCTION || + pkg_child->type == AST_TASK || pkg_child->type == AST_ENUM) { + current_scope[pkg_child->str] = pkg_child; + } + if (pkg_child->type == AST_ENUM) { + for (auto enode : pkg_child->children) { + log_assert(enode->type==AST_ENUM_ITEM); + if (current_scope.count(enode->str) == 0) + current_scope[enode->str] = enode; + else + input_error("enum item %s already exists in current scope\n", enode->str.c_str()); + } + } + } + } else { + input_error("Package `%s' not found for import\n", child->str.c_str()); + } + } + } for (size_t i = 0; i < children.size(); i++) { AstNode *node = children[i]; diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index e2d7a2cd9..19c0774af 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -334,6 +334,7 @@ TIME_SCALE_SUFFIX [munpf]?s "specparam" { return TOK_SPECPARAM; } "package" { SV_KEYWORD(TOK_PACKAGE); } "endpackage" { SV_KEYWORD(TOK_ENDPACKAGE); } +"import" { SV_KEYWORD(TOK_IMPORT); } "interface" { SV_KEYWORD(TOK_INTERFACE); } "endinterface" { SV_KEYWORD(TOK_ENDINTERFACE); } "modport" { SV_KEYWORD(TOK_MODPORT); } diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 17edc357d..bd9f47034 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -418,6 +418,7 @@ static const AstNode *addAsgnBinopStmt(dict *attr, AstNode * %token TOK_SUB_ASSIGN TOK_DIV_ASSIGN TOK_MOD_ASSIGN TOK_MUL_ASSIGN %token TOK_SHL_ASSIGN TOK_SHR_ASSIGN TOK_SSHL_ASSIGN TOK_SSHR_ASSIGN %token TOK_BIND TOK_TIME_SCALE +%token TOK_IMPORT %type range range_or_multirange non_opt_range non_opt_multirange %type wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type @@ -484,6 +485,7 @@ design: localparam_decl design | typedef_decl design | package design | + import_stmt design | interface design | bind_directive design | %empty; @@ -730,6 +732,15 @@ package_body: package_body_stmt: typedef_decl | localparam_decl | param_decl | task_func_decl; +import_stmt: + TOK_IMPORT hierarchical_id TOK_PACKAGESEP '*' ';' { + // Create an import node to track package imports + AstNode *import_node = new AstNode(AST_IMPORT); + import_node->str = *$2; + ast_stack.back()->children.push_back(import_node); + delete $2; + }; + interface: TOK_INTERFACE { enterTypeScope(); From 761015b23e1ce68b08b703f6a19f12362860d451 Mon Sep 17 00:00:00 2001 From: Rahul Bhagwat Date: Sun, 3 Aug 2025 23:48:33 -0400 Subject: [PATCH 2/7] add separate module test --- frontends/ast/simplify.cc | 20 ++++++++++++++++--- tests/verilog/package_import_separate.sv | 13 ++++++++++++ tests/verilog/package_import_separate.ys | 5 +++++ .../verilog/package_import_separate_module.sv | 19 ++++++++++++++++++ 4 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 tests/verilog/package_import_separate.sv create mode 100644 tests/verilog/package_import_separate.ys create mode 100644 tests/verilog/package_import_separate_module.sv diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index b524fadfd..8bb40cb6b 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1109,10 +1109,24 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (child->type == AST_IMPORT) { // Find the package in the design AstNode *package_node = nullptr; + + // First look in current_ast->children (for packages in same file) for (auto &design_child : current_ast->children) { - if (design_child->type == AST_PACKAGE && design_child->str == child->str) { - package_node = design_child; - break; + if (design_child->type == AST_PACKAGE) { + if (design_child->str == child->str) { + package_node = design_child; + break; + } + } + } + + // If not found, look in design->verilog_packages (for packages from other files) + if (!package_node && simplify_design_context != nullptr) { + for (auto &design_package : simplify_design_context->verilog_packages) { + if (design_package->str == child->str) { + package_node = design_package; + break; + } } } diff --git a/tests/verilog/package_import_separate.sv b/tests/verilog/package_import_separate.sv new file mode 100644 index 000000000..b2e5bb803 --- /dev/null +++ b/tests/verilog/package_import_separate.sv @@ -0,0 +1,13 @@ +package config_pkg; + localparam integer + DATA_WIDTH = 8, + ADDR_WIDTH = 4; + + localparam logic [2:0] + IDLE = 3'b000, + START = 3'b001, + DATA = 3'b010, + ODD_PARITY = 3'b011, + STOP = 3'b100, + DONE = 3'b101; +endpackage \ No newline at end of file diff --git a/tests/verilog/package_import_separate.ys b/tests/verilog/package_import_separate.ys new file mode 100644 index 000000000..0dff75897 --- /dev/null +++ b/tests/verilog/package_import_separate.ys @@ -0,0 +1,5 @@ +read_verilog -sv package_import_separate.sv +read_verilog -sv package_import_separate_module.sv +hierarchy -check +proc +opt -full \ No newline at end of file diff --git a/tests/verilog/package_import_separate_module.sv b/tests/verilog/package_import_separate_module.sv new file mode 100644 index 000000000..f940553b3 --- /dev/null +++ b/tests/verilog/package_import_separate_module.sv @@ -0,0 +1,19 @@ +import config_pkg::*; + +module top; + logic [DATA_WIDTH-1:0] data; + logic [ADDR_WIDTH-1:0] addr; + logic [2:0] state; + + always_comb begin + case (state) + IDLE: data = 8'h00; + START: data = 8'h01; + DATA: data = 8'h02; + ODD_PARITY: data = 8'h03; + STOP: data = 8'h04; + DONE: data = 8'h05; + default: data = 8'hFF; + endcase + end +endmodule \ No newline at end of file From fe59b6d3db1f13252b5a7cc308039558a8e41fdc Mon Sep 17 00:00:00 2001 From: Rahul Bhagwat Date: Mon, 4 Aug 2025 20:57:43 -0400 Subject: [PATCH 3/7] add safety checks and better name matching --- frontends/ast/simplify.cc | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 8bb40cb6b..693e8098a 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1105,25 +1105,35 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin std::map this_wire_scope; // Process package imports after clearing the scope but before processing module declarations - for (auto &child : children) { + for (size_t i = 0; i < children.size(); i++) { + AstNode *child = children[i]; if (child->type == AST_IMPORT) { + log_debug("Processing import for package: %s\n", child->str.c_str()); // Find the package in the design AstNode *package_node = nullptr; // First look in current_ast->children (for packages in same file) - for (auto &design_child : current_ast->children) { - if (design_child->type == AST_PACKAGE) { - if (design_child->str == child->str) { - package_node = design_child; - break; + if (current_ast != nullptr) { + for (auto &design_child : current_ast->children) { + if (design_child->type == AST_PACKAGE) { + if (design_child->str == child->str) { + package_node = design_child; + break; + } } } } // If not found, look in design->verilog_packages (for packages from other files) if (!package_node && simplify_design_context != nullptr) { + log_debug("Looking for package in design context, found %zu packages\n", simplify_design_context->verilog_packages.size()); for (auto &design_package : simplify_design_context->verilog_packages) { - if (design_package->str == child->str) { + // Handle both with and without leading backslash + std::string package_name = design_package->str; + if (package_name[0] == '\\') { + package_name = package_name.substr(1); + } + if (package_name == child->str || design_package->str == child->str) { package_node = design_package; break; } @@ -1148,8 +1158,16 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin } } } + // Remove the import node since it's been processed + delete child; + children.erase(children.begin() + i); + i--; // Adjust index since we removed an element } else { - input_error("Package `%s' not found for import\n", child->str.c_str()); + // If we can't find the package, just remove the import node to avoid errors later + log_warning("Package `%s' not found for import, removing import statement\n", child->str.c_str()); + delete child; + children.erase(children.begin() + i); + i--; // Adjust index since we removed an element } } } From 7e0157ba2bee52f194af93f669aadff5fb67b59b Mon Sep 17 00:00:00 2001 From: Rahul Bhagwat Date: Wed, 6 Aug 2025 15:32:36 -0400 Subject: [PATCH 4/7] fix whitespace issues --- frontends/ast/simplify.cc | 12 ++++++------ tests/verilog/package_import_separate.sv | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 693e8098a..9c0abc327 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1103,7 +1103,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin int counter = 0; label_genblks(existing, counter); std::map this_wire_scope; - + // Process package imports after clearing the scope but before processing module declarations for (size_t i = 0; i < children.size(); i++) { AstNode *child = children[i]; @@ -1111,7 +1111,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin log_debug("Processing import for package: %s\n", child->str.c_str()); // Find the package in the design AstNode *package_node = nullptr; - + // First look in current_ast->children (for packages in same file) if (current_ast != nullptr) { for (auto &design_child : current_ast->children) { @@ -1123,7 +1123,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin } } } - + // If not found, look in design->verilog_packages (for packages from other files) if (!package_node && simplify_design_context != nullptr) { log_debug("Looking for package in design context, found %zu packages\n", simplify_design_context->verilog_packages.size()); @@ -1139,12 +1139,12 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin } } } - + if (package_node) { // Import all names from the package into current scope for (auto &pkg_child : package_node->children) { - if (pkg_child->type == AST_PARAMETER || pkg_child->type == AST_LOCALPARAM || - pkg_child->type == AST_TYPEDEF || pkg_child->type == AST_FUNCTION || + if (pkg_child->type == AST_PARAMETER || pkg_child->type == AST_LOCALPARAM || + pkg_child->type == AST_TYPEDEF || pkg_child->type == AST_FUNCTION || pkg_child->type == AST_TASK || pkg_child->type == AST_ENUM) { current_scope[pkg_child->str] = pkg_child; } diff --git a/tests/verilog/package_import_separate.sv b/tests/verilog/package_import_separate.sv index b2e5bb803..eddde709b 100644 --- a/tests/verilog/package_import_separate.sv +++ b/tests/verilog/package_import_separate.sv @@ -2,7 +2,7 @@ package config_pkg; localparam integer DATA_WIDTH = 8, ADDR_WIDTH = 4; - + localparam logic [2:0] IDLE = 3'b000, START = 3'b001, @@ -10,4 +10,4 @@ package config_pkg; ODD_PARITY = 3'b011, STOP = 3'b100, DONE = 3'b101; -endpackage \ No newline at end of file +endpackage From d3c8e6c14c5249fe0de59be176a7bc8b76caaf7f Mon Sep 17 00:00:00 2001 From: Rahul Bhagwat Date: Wed, 6 Aug 2025 15:39:30 -0400 Subject: [PATCH 5/7] use more standard naming conventions --- tests/verilog/package_import_separate.sv | 17 +++++++++-------- tests/verilog/package_import_separate_module.sv | 14 +++++++------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/tests/verilog/package_import_separate.sv b/tests/verilog/package_import_separate.sv index eddde709b..2337e4bce 100644 --- a/tests/verilog/package_import_separate.sv +++ b/tests/verilog/package_import_separate.sv @@ -1,13 +1,14 @@ -package config_pkg; +package package_import_separate; + localparam integer - DATA_WIDTH = 8, - ADDR_WIDTH = 4; + DATAWIDTH = 8, + ADDRWIDTH = 4; localparam logic [2:0] - IDLE = 3'b000, + IDLE = 3'b000, START = 3'b001, - DATA = 3'b010, - ODD_PARITY = 3'b011, - STOP = 3'b100, - DONE = 3'b101; + DATA = 3'b010, + STOP = 3'b100, + DONE = 3'b101; + endpackage diff --git a/tests/verilog/package_import_separate_module.sv b/tests/verilog/package_import_separate_module.sv index f940553b3..b58d3b814 100644 --- a/tests/verilog/package_import_separate_module.sv +++ b/tests/verilog/package_import_separate_module.sv @@ -1,19 +1,19 @@ -import config_pkg::*; +import package_import_separate::*; -module top; - logic [DATA_WIDTH-1:0] data; - logic [ADDR_WIDTH-1:0] addr; +module package_import_separate_module; + logic [DATAWIDTH-1:0] data; + logic [ADDRWIDTH-1:0] addr; logic [2:0] state; - + always_comb begin case (state) IDLE: data = 8'h00; START: data = 8'h01; DATA: data = 8'h02; - ODD_PARITY: data = 8'h03; STOP: data = 8'h04; DONE: data = 8'h05; default: data = 8'hFF; endcase end -endmodule \ No newline at end of file + +endmodule From f12055d3e0bdac503ce01db8a35ea07d2c52ace9 Mon Sep 17 00:00:00 2001 From: Rahul Bhagwat Date: Wed, 6 Aug 2025 15:39:36 -0400 Subject: [PATCH 6/7] rm debug logs --- frontends/ast/simplify.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 9c0abc327..05cc57ba1 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1108,7 +1108,6 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin for (size_t i = 0; i < children.size(); i++) { AstNode *child = children[i]; if (child->type == AST_IMPORT) { - log_debug("Processing import for package: %s\n", child->str.c_str()); // Find the package in the design AstNode *package_node = nullptr; @@ -1126,7 +1125,6 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin // If not found, look in design->verilog_packages (for packages from other files) if (!package_node && simplify_design_context != nullptr) { - log_debug("Looking for package in design context, found %zu packages\n", simplify_design_context->verilog_packages.size()); for (auto &design_package : simplify_design_context->verilog_packages) { // Handle both with and without leading backslash std::string package_name = design_package->str; From 5cc1365b32df363c410ecd3890cd4d9445620d75 Mon Sep 17 00:00:00 2001 From: Rahul Bhagwat Date: Wed, 6 Aug 2025 19:00:11 -0400 Subject: [PATCH 7/7] add newline - whitespace --- tests/verilog/package_import_separate.ys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/verilog/package_import_separate.ys b/tests/verilog/package_import_separate.ys index 0dff75897..cbfcaa898 100644 --- a/tests/verilog/package_import_separate.ys +++ b/tests/verilog/package_import_separate.ys @@ -2,4 +2,4 @@ read_verilog -sv package_import_separate.sv read_verilog -sv package_import_separate_module.sv hierarchy -check proc -opt -full \ No newline at end of file +opt -full