3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-11-14 10:01:17 +00:00

simplify: refactor specific package import

This commit is contained in:
Emil J. Tywoniak 2025-11-10 14:26:10 +01:00
parent 54e5eb1c3c
commit 8f53d21ea7

View file

@ -889,6 +889,52 @@ static void check_auto_nosync(AstNode *node)
check_auto_nosync(child.get()); check_auto_nosync(child.get());
} }
class PackageImporter {
std::set<std::string> import_items;
bool is_wildcard;
const AstNode* node;
public:
PackageImporter(const AstNode* n, const AstNode* child) : node(n) {
is_wildcard = child->children.empty();
// For specific imports, collect the list of items to import
if (!is_wildcard) {
for (auto& item : child->children) {
import_items.insert(item->str);
}
}
}
void import(std::map<std::string, AstNode*>& scope, AstNode* to_import) const {
// Check if this is a specific import and if this item should be imported
if (!is_wildcard && import_items.count(to_import->str) == 0)
return;
if (to_import->type == AST_PARAMETER || to_import->type == AST_LOCALPARAM ||
to_import->type == AST_TYPEDEF || to_import->type == AST_FUNCTION ||
to_import->type == AST_TASK || to_import->type == AST_ENUM) {
// For wildcard imports, check if item already exists (from specific import)
if (is_wildcard && scope.count(to_import->str) > 0)
return;
scope[to_import->str] = to_import;
}
if (to_import->type == AST_ENUM) {
for (auto& enode : to_import->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 && scope.count(enode->str) > 0)
continue;
if (scope.count(enode->str) == 0)
scope[enode->str] = enode.get();
else
node->input_error("enum item %s already exists in current scope\n", enode->str);
}
}
}
};
// convert the AST into a simpler AST that has all parameters substituted by their // convert the AST into a simpler AST that has all parameters substituted by their
// values, unrolled for-loops, expanded generate blocks, etc. when this function // values, unrolled for-loops, expanded generate blocks, etc. when this function
// is done with an AST it can be converted into RTLIL using genRTLIL(). // is done with an AST it can be converted into RTLIL using genRTLIL().
@ -1123,45 +1169,10 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
} }
if (package_node) { if (package_node) {
bool is_wildcard = child->children.empty(); PackageImporter importer(this, child);
std::set<std::string> 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 // Import names from the package into current scope
for (auto& pkg_child : package_node->children) { for (auto& pkg_child : package_node->children) {
// Check if this is a specific import and if this item should be imported importer.import(current_scope, pkg_child.get());
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
input_error("enum item %s already exists in current scope\n", enode->str);
}
}
} }
// Remove the import node since it's been processed // Remove the import node since it's been processed
children.erase(children.begin() + i); children.erase(children.begin() + i);