diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 97abf7452..010f4e14f 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1123,16 +1123,39 @@ 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 + bool is_wildcard = child->children.empty(); + std::set import_items; + + // For specific imports, collect the list of items to import + if (!is_wildcard) { + for (auto& import_item : child->children) { + import_items.insert(import_item->str); + } + } + + // Import names from the package into current scope for (auto& pkg_child : package_node->children) { + // Check if this is a specific import and if this item should be imported + if (!is_wildcard && import_items.count(pkg_child->str) == 0) + continue; + 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) { + // For wildcard imports, check if item already exists (from specific import) + if (is_wildcard && current_scope.count(pkg_child->str) > 0) + continue; current_scope[pkg_child->str] = pkg_child.get(); } if (pkg_child->type == AST_ENUM) { for (auto& enode : pkg_child->children) { log_assert(enode->type==AST_ENUM_ITEM); + // Check if this enum item should be imported + if (!is_wildcard && import_items.count(enode->str) == 0) + continue; + // For wildcard imports, check if item already exists (from specific import) + if (is_wildcard && current_scope.count(enode->str) > 0) + continue; if (current_scope.count(enode->str) == 0) current_scope[enode->str] = enode.get(); else diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index ef8427679..e6c7f3672 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -428,6 +428,7 @@ #include #include #include + #include #include "frontends/verilog/verilog_frontend.h" struct specify_target { @@ -462,6 +463,7 @@ using string_t = std::unique_ptr; using ast_t = std::unique_ptr; + using ast_list_t = std::vector; using al_t = std::unique_ptr>>; using specify_target_ptr_t = std::unique_ptr; using specify_triple_ptr_t = std::unique_ptr; @@ -557,6 +559,8 @@ %type struct_union %type asgn_binop inc_or_dec_op %type genvar_identifier +%type import_item_list +%type import_item %type specify_target %type specify_triple specify_opt_triple @@ -830,10 +834,37 @@ package_body_stmt: import_stmt: TOK_IMPORT hierarchical_id TOK_PACKAGESEP TOK_ASTER TOK_SEMICOL { - // Create an import node to track package imports + // Create an import node to track specific and wildcard package imports auto import_node = std::make_unique(@$, AST_IMPORT); import_node->str = *$2; extra->ast_stack.back()->children.push_back(std::move(import_node)); + } | + TOK_IMPORT hierarchical_id TOK_PACKAGESEP import_item_list TOK_SEMICOL { + // Create an import node to track specific package imports + auto import_node = std::make_unique(@$, AST_IMPORT); + import_node->str = *$2; + // Move children from import_item_list to import_node + import_node->children = std::move($4); + extra->ast_stack.back()->children.push_back(std::move(import_node)); + }; + +import_item_list: + import_item { + ast_list_t list; + list.push_back(std::move($1)); + $$ = std::move(list); + } | + import_item_list TOK_COMMA import_item { + $1.push_back(std::move($3)); + $$ = std::move($1); + }; + +import_item: + TOK_ID { + // Create a simple node to store the imported item name + auto item_node = std::make_unique(@$, AST_NONE); + item_node->str = *$1; + $$ = std::move(item_node); }; interface: diff --git a/tests/verilog/package_import_specific.sv b/tests/verilog/package_import_specific.sv new file mode 100644 index 000000000..97004ed56 --- /dev/null +++ b/tests/verilog/package_import_specific.sv @@ -0,0 +1,14 @@ +package package_import_specific; + + localparam integer + DATA_WIDTH = 8, + ADDR_WIDTH = 4; + + localparam logic [2:0] + IDLE = 3'b000, + START = 3'b001, + DATA = 3'b010, + STOP = 3'b100, + DONE = 3'b101; + +endpackage diff --git a/tests/verilog/package_import_specific.ys b/tests/verilog/package_import_specific.ys new file mode 100644 index 000000000..8b183aac4 --- /dev/null +++ b/tests/verilog/package_import_specific.ys @@ -0,0 +1,5 @@ +read_verilog -sv package_import_specific.sv +read_verilog -sv package_import_specific_module.sv +hierarchy -check +proc +opt -full diff --git a/tests/verilog/package_import_specific_module.sv b/tests/verilog/package_import_specific_module.sv new file mode 100644 index 000000000..a568af4d2 --- /dev/null +++ b/tests/verilog/package_import_specific_module.sv @@ -0,0 +1,16 @@ +import package_import_specific::DATA_WIDTH; +import package_import_specific::IDLE; + +module package_import_specific_module; + logic [DATA_WIDTH-1:0] data; + logic [3:0] addr; + logic [2:0] state; + + always_comb begin + case (state) + IDLE: data = 8'h00; + default: data = 8'hFF; + endcase + end + +endmodule