From 08b55a20e36a24d09be9016ceda658bc8ba04ad3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Sep 2019 14:11:01 -0700 Subject: module->derive() to be lazy and not touch ast if already derived --- frontends/ast/ast.cc | 82 ++++++++++++++++++++++++++++++++-------------------- frontends/ast/ast.h | 2 +- 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 21279cbfa..e4539f303 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1382,10 +1382,10 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict parameters, dict interfaces, dict modports, bool mayfail) +RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict parameters, dict interfaces, dict modports, bool /*mayfail*/) { AstNode *new_ast = NULL; - std::string modname = derive_common(design, parameters, &new_ast, mayfail); + std::string modname = derive_common(design, parameters, &new_ast); // Since interfaces themselves may be instantiated with different parameters, // "modname" must also take those into account, so that unique modules @@ -1455,10 +1455,10 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict parameters, bool mayfail) +RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict parameters, bool /*mayfail*/) { AstNode *new_ast = NULL; - std::string modname = derive_common(design, parameters, &new_ast, mayfail); + std::string modname = derive_common(design, parameters, &new_ast); if (!design->has(modname)) { new_ast->str = modname; @@ -1473,47 +1473,75 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict parameters, AstNode **new_ast_out, bool) +std::string AstModule::derive_common(RTLIL::Design *design, dict parameters, AstNode **new_ast_out) { std::string stripped_name = name.str(); if (stripped_name.compare(0, 9, "$abstract") == 0) stripped_name = stripped_name.substr(9); - log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); - loadconfig(); - std::string para_info; - AstNode *new_ast = ast->clone(); int para_counter = 0; - int orig_parameters_n = parameters.size(); - for (auto it = new_ast->children.begin(); it != new_ast->children.end(); it++) { - AstNode *child = *it; + for (const auto child : ast->children) { if (child->type != AST_PARAMETER) continue; para_counter++; std::string para_id = child->str; if (parameters.count(para_id) > 0) { log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str]))); - rewrite_parameter: para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); - delete child->children.at(0); - if ((parameters[para_id].flags & RTLIL::CONST_FLAG_REAL) != 0) { - child->children[0] = new AstNode(AST_REALVALUE); - child->children[0]->realvalue = std::stod(parameters[para_id].decode_string()); - } else if ((parameters[para_id].flags & RTLIL::CONST_FLAG_STRING) != 0) - child->children[0] = AstNode::mkconst_str(parameters[para_id].decode_string()); - else - child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0); - parameters.erase(para_id); continue; } para_id = stringf("$%d", para_counter); + if (parameters.count(para_id) > 0) { + log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); + para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); + continue; + } + } + + std::string modname; + if (parameters.size() == 0) + modname = stripped_name; + else if (para_info.size() > 60) + modname = "$paramod$" + sha1(para_info) + stripped_name; + else + modname = "$paramod" + stripped_name + para_info; + + if (design->has(modname)) + return modname; + + log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); + loadconfig(); + + AstNode *new_ast = ast->clone(); + para_counter = 0; + for (auto child : new_ast->children) { + if (child->type != AST_PARAMETER) + continue; + para_counter++; + std::string para_id = child->str; + if (parameters.count(para_id) > 0) { + log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str]))); + goto rewrite_parameter; + } + para_id = stringf("$%d", para_counter); if (parameters.count(para_id) > 0) { log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); goto rewrite_parameter; } + continue; + rewrite_parameter: + delete child->children.at(0); + if ((parameters[para_id].flags & RTLIL::CONST_FLAG_REAL) != 0) { + child->children[0] = new AstNode(AST_REALVALUE); + child->children[0]->realvalue = std::stod(parameters[para_id].decode_string()); + } else if ((parameters[para_id].flags & RTLIL::CONST_FLAG_STRING) != 0) + child->children[0] = AstNode::mkconst_str(parameters[para_id].decode_string()); + else + child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0); + parameters.erase(para_id); } for (auto param : parameters) { @@ -1526,16 +1554,6 @@ std::string AstModule::derive_common(RTLIL::Design *design, dictchildren.push_back(defparam); } - std::string modname; - - if (orig_parameters_n == 0) - modname = stripped_name; - else if (para_info.size() > 60) - modname = "$paramod$" + sha1(para_info) + stripped_name; - else - modname = "$paramod" + stripped_name + para_info; - - (*new_ast_out) = new_ast; return modname; } diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 93fee913e..0ec249ab9 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -296,7 +296,7 @@ namespace AST ~AstModule() YS_OVERRIDE; RTLIL::IdString derive(RTLIL::Design *design, dict parameters, bool mayfail) YS_OVERRIDE; RTLIL::IdString derive(RTLIL::Design *design, dict parameters, dict interfaces, dict modports, bool mayfail) YS_OVERRIDE; - std::string derive_common(RTLIL::Design *design, dict parameters, AstNode **new_ast_out, bool mayfail); + std::string derive_common(RTLIL::Design *design, dict parameters, AstNode **new_ast_out); void reprocess_module(RTLIL::Design *design, dict local_interfaces) YS_OVERRIDE; RTLIL::Module *clone() const YS_OVERRIDE; void loadconfig() const; -- cgit v1.2.3 From 0a1af434e8acfaa692d7990bce68fd23daed9519 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 30 Sep 2019 14:52:04 -0700 Subject: Fix for svinterfaces --- frontends/ast/ast.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index e4539f303..37a69d8bf 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1398,11 +1398,17 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dicthas(modname)) { + if (!design->has(new_modname)) { + if (!new_ast) { + auto mod = dynamic_cast(design->module(modname)); + new_ast = mod->ast->clone(); + } + modname = new_modname; new_ast->str = modname; // Iterate over all interfaces which are ports in this module: -- cgit v1.2.3