diff options
Diffstat (limited to 'frontends/ast/ast.cc')
-rw-r--r-- | frontends/ast/ast.cc | 278 |
1 files changed, 151 insertions, 127 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 5bbea0faf..2b6002548 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -88,6 +88,8 @@ std::string AST::type2str(AstNodeType type) X(AST_LIVE) X(AST_FAIR) X(AST_COVER) + X(AST_ENUM) + X(AST_ENUM_ITEM) X(AST_FCALL) X(AST_TO_BITS) X(AST_TO_SIGNED) @@ -180,7 +182,7 @@ bool AstNode::get_bool_attribute(RTLIL::IdString id) AstNode *attr = attributes.at(id); if (attr->type != AST_CONSTANT) - log_file_error(attr->filename, attr->linenum, "Attribute `%s' with non-constant value!\n", id.c_str()); + log_file_error(attr->filename, attr->location.first_line, "Attribute `%s' with non-constant value!\n", id.c_str()); return attr->integer != 0; } @@ -195,13 +197,13 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch this->type = type; filename = current_filename; - linenum = get_line_num(); is_input = false; is_output = false; is_reg = false; is_logic = false; is_signed = false; is_string = false; + is_enum = false; is_wand = false; is_wor = false; is_unsized = false; @@ -277,7 +279,8 @@ void AstNode::dumpAst(FILE *f, std::string indent) const } std::string type_name = type2str(type); - fprintf(f, "%s%s <%s:%d>", indent.c_str(), type_name.c_str(), filename.c_str(), linenum); + fprintf(f, "%s%s <%s:%d.%d-%d.%d>", indent.c_str(), type_name.c_str(), filename.c_str(), location.first_line, + location.first_column, location.last_line, location.last_column); if (!flag_no_dump_ptr) { if (id2ast) @@ -321,6 +324,9 @@ void AstNode::dumpAst(FILE *f, std::string indent) const fprintf(f, " %d", v); fprintf(f, " ]"); } + if (is_enum) { + fprintf(f, " type=enum"); + } fprintf(f, "\n"); for (auto &it : attributes) { @@ -933,20 +939,22 @@ RTLIL::Const AstNode::realAsConst(int width) } // create a new AstModule from an AST_MODULE AST node -static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL) +static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL, bool quiet = false) { log_assert(ast->type == AST_MODULE || ast->type == AST_INTERFACE); if (defer) log("Storing AST representation for module `%s'.\n", ast->str.c_str()); - else + else if (!quiet) { log("Generating RTLIL representation for module `%s'.\n", ast->str.c_str()); + } current_module = new AstModule; current_module->ast = NULL; current_module->name = ast->str; - current_module->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum); - current_module->set_bool_attribute("\\cells_not_processed"); + current_module->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, + ast->location.first_column, ast->location.last_line, ast->location.last_column); + current_module->set_bool_attribute(ID::cells_not_processed); current_ast_mod = ast; AstNode *ast_before_simplify; @@ -999,61 +1007,61 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast log("--- END OF AST DUMP ---\n"); } - if (flag_nowb && ast->attributes.count("\\whitebox")) { - delete ast->attributes.at("\\whitebox"); - ast->attributes.erase("\\whitebox"); + if (flag_nowb && ast->attributes.count(ID::whitebox)) { + delete ast->attributes.at(ID::whitebox); + ast->attributes.erase(ID::whitebox); } - if (ast->attributes.count("\\lib_whitebox")) { + if (ast->attributes.count(ID::lib_whitebox)) { if (!flag_lib || flag_nowb) { - delete ast->attributes.at("\\lib_whitebox"); - ast->attributes.erase("\\lib_whitebox"); + delete ast->attributes.at(ID::lib_whitebox); + ast->attributes.erase(ID::lib_whitebox); } else { - if (ast->attributes.count("\\whitebox")) { - delete ast->attributes.at("\\whitebox"); - ast->attributes.erase("\\whitebox"); + if (ast->attributes.count(ID::whitebox)) { + delete ast->attributes.at(ID::whitebox); + ast->attributes.erase(ID::whitebox); } - AstNode *n = ast->attributes.at("\\lib_whitebox"); - ast->attributes["\\whitebox"] = n; - ast->attributes.erase("\\lib_whitebox"); + AstNode *n = ast->attributes.at(ID::lib_whitebox); + ast->attributes[ID::whitebox] = n; + ast->attributes.erase(ID::lib_whitebox); } } - if (!blackbox_module && ast->attributes.count("\\blackbox")) { - AstNode *n = ast->attributes.at("\\blackbox"); + if (!blackbox_module && ast->attributes.count(ID::blackbox)) { + AstNode *n = ast->attributes.at(ID::blackbox); if (n->type != AST_CONSTANT) - log_file_error(ast->filename, ast->linenum, "Got blackbox attribute with non-constant value!\n"); + log_file_error(ast->filename, ast->location.first_line, "Got blackbox attribute with non-constant value!\n"); blackbox_module = n->asBool(); } - if (blackbox_module && ast->attributes.count("\\whitebox")) { - AstNode *n = ast->attributes.at("\\whitebox"); + if (blackbox_module && ast->attributes.count(ID::whitebox)) { + AstNode *n = ast->attributes.at(ID::whitebox); if (n->type != AST_CONSTANT) - log_file_error(ast->filename, ast->linenum, "Got whitebox attribute with non-constant value!\n"); + log_file_error(ast->filename, ast->location.first_line, "Got whitebox attribute with non-constant value!\n"); blackbox_module = !n->asBool(); } - if (ast->attributes.count("\\noblackbox")) { + if (ast->attributes.count(ID::noblackbox)) { if (blackbox_module) { - AstNode *n = ast->attributes.at("\\noblackbox"); + AstNode *n = ast->attributes.at(ID::noblackbox); if (n->type != AST_CONSTANT) - log_file_error(ast->filename, ast->linenum, "Got noblackbox attribute with non-constant value!\n"); + log_file_error(ast->filename, ast->location.first_line, "Got noblackbox attribute with non-constant value!\n"); blackbox_module = !n->asBool(); } - delete ast->attributes.at("\\noblackbox"); - ast->attributes.erase("\\noblackbox"); + delete ast->attributes.at(ID::noblackbox); + ast->attributes.erase(ID::noblackbox); } if (blackbox_module) { - if (ast->attributes.count("\\whitebox")) { - delete ast->attributes.at("\\whitebox"); - ast->attributes.erase("\\whitebox"); + if (ast->attributes.count(ID::whitebox)) { + delete ast->attributes.at(ID::whitebox); + ast->attributes.erase(ID::whitebox); } - if (ast->attributes.count("\\lib_whitebox")) { - delete ast->attributes.at("\\lib_whitebox"); - ast->attributes.erase("\\lib_whitebox"); + if (ast->attributes.count(ID::lib_whitebox)) { + delete ast->attributes.at(ID::lib_whitebox); + ast->attributes.erase(ID::lib_whitebox); } std::vector<AstNode*> new_children; @@ -1074,8 +1082,8 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast ast->children.swap(new_children); - if (ast->attributes.count("\\blackbox") == 0) { - ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false); + if (ast->attributes.count(ID::blackbox) == 0) { + ast->attributes[ID::blackbox] = AstNode::mkconst_int(1, false); } } @@ -1083,7 +1091,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast for (auto &attr : ast->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + log_file_error(ast->filename, ast->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); current_module->attributes[attr.first] = attr.second->asAttrConst(); } for (size_t i = 0; i < ast->children.size(); i++) { @@ -1116,7 +1124,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast } if (ast->type == AST_INTERFACE) - current_module->set_bool_attribute("\\is_interface"); + current_module->set_bool_attribute(ID::is_interface); current_module->ast = ast_before_simplify; current_module->nolatches = flag_nolatches; current_module->nomeminit = flag_nomeminit; @@ -1171,10 +1179,19 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump for (auto n : design->verilog_globals) (*it)->children.push_back(n->clone()); - for (auto n : design->verilog_packages){ - for (auto o : n->children) { + // append nodes from previous packages using package-qualified names + for (auto &n : design->verilog_packages) { + for (auto &o : n->children) { AstNode *cloned_node = o->clone(); - cloned_node->str = n->str + std::string("::") + cloned_node->str.substr(1); + // log("cloned node %s\n", type2str(cloned_node->type).c_str()); + if (cloned_node->type == AST_ENUM) { + for (auto &e : cloned_node->children) { + log_assert(e->type == AST_ENUM_ITEM); + e->str = n->str + std::string("::") + e->str.substr(1); + } + } else { + cloned_node->str = n->str + std::string("::") + cloned_node->str.substr(1); + } (*it)->children.push_back(cloned_node); } } @@ -1188,25 +1205,31 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump if (design->has((*it)->str)) { RTLIL::Module *existing_mod = design->module((*it)->str); if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) { - log_file_error((*it)->filename, (*it)->linenum, "Re-definition of module `%s'!\n", (*it)->str.c_str()); + log_file_error((*it)->filename, (*it)->location.first_line, "Re-definition of module `%s'!\n", (*it)->str.c_str()); } else if (nooverwrite) { - log("Ignoring re-definition of module `%s' at %s:%d.\n", - (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); + log("Ignoring re-definition of module `%s' at %s:%d.%d-%d.%d.\n", + (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->location.first_line, (*it)->location.first_column, (*it)->location.last_line, (*it)->location.last_column); continue; } else { - log("Replacing existing%s module `%s' at %s:%d.\n", - existing_mod->get_bool_attribute("\\blackbox") ? " blackbox" : "", - (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum); + log("Replacing existing%s module `%s' at %s:%d.%d-%d.%d.\n", + existing_mod->get_bool_attribute(ID::blackbox) ? " blackbox" : "", + (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->location.first_line, (*it)->location.first_column, (*it)->location.last_line, (*it)->location.last_column); design->remove(existing_mod); } } design->add(process_module(*it, defer)); } - else if ((*it)->type == AST_PACKAGE) + else if ((*it)->type == AST_PACKAGE) { + // process enum/other declarations + (*it)->simplify(true, false, false, 1, -1, false, false); design->verilog_packages.push_back((*it)->clone()); - else + } + else { + // must be global definition + (*it)->simplify(false, false, false, 1, -1, false, false); //process enum/other declarations design->verilog_globals.push_back((*it)->clone()); + } } } @@ -1261,9 +1284,9 @@ AstNode * AST::find_modport(AstNode *intf, std::string name) // Iterate over all wires in an interface and add them as wires in the AST module: void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule, std::string intfname, AstNode *modport) { - for (auto &wire_it : intfmodule->wires_){ - AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, AstNode::mkconst_int(wire_it.second->width -1, true), AstNode::mkconst_int(0, true))); - std::string origname = log_id(wire_it.first); + for (auto w : intfmodule->wires()){ + AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, AstNode::mkconst_int(w->width -1, true), AstNode::mkconst_int(0, true))); + std::string origname = log_id(w->name); std::string newname = intfname + "." + origname; wire->str = newname; if (modport != NULL) { @@ -1297,7 +1320,7 @@ void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule // When an interface instance is found in a module, the whole RTLIL for the module will be rederived again // from AST. The interface members are copied into the AST module with the prefix of the interface. -void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module*> local_interfaces) +void AstModule::reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module*> &local_interfaces) { loadconfig(); @@ -1306,9 +1329,9 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT for (auto &intf : local_interfaces) { std::string intfname = intf.first.str(); RTLIL::Module *intfmodule = intf.second; - for (auto &wire_it : intfmodule->wires_){ - AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, AstNode::mkconst_int(wire_it.second->width -1, true), AstNode::mkconst_int(0, true))); - std::string newname = log_id(wire_it.first); + for (auto w : intfmodule->wires()){ + AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, AstNode::mkconst_int(w->width -1, true), AstNode::mkconst_int(0, true))); + std::string newname = log_id(w->name); newname = intfname + "." + newname; wire->str = newname; new_ast->children.push_back(wire); @@ -1332,7 +1355,7 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT std::pair<std::string,std::string> res = split_modport_from_type(ch->str); std::string interface_type = res.first; std::string interface_modport = res.second; // Is "", if no modport - if (design->modules_.count(interface_type) > 0) { + if (design->module(interface_type) != nullptr) { // Add a cell to the module corresponding to the interface port such that // it can further propagated down if needed: AstNode *celltype_for_intf = new AstNode(AST_CELLTYPE); @@ -1342,7 +1365,7 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT new_ast->children.push_back(cell_for_intf); // Get all members of this non-overridden dummy interface instance: - RTLIL::Module *intfmodule = design->modules_[interface_type]; // All interfaces should at this point in time (assuming + RTLIL::Module *intfmodule = design->module(interface_type); // All interfaces should at this point in time (assuming // reprocess_module is called from the hierarchy pass) be // present in design->modules_ AstModule *ast_module_of_interface = (AstModule*)intfmodule; @@ -1362,12 +1385,12 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT std::string original_name = this->name.str(); std::string changed_name = original_name + "_before_replacing_local_interfaces"; design->rename(this, changed_name); - this->set_bool_attribute("\\to_delete"); + this->set_bool_attribute(ID::to_delete); // Check if the module was the top module. If it was, we need to remove the top attribute and put it on the // new module. - if (this->get_bool_attribute("\\initial_top")) { - this->attributes.erase("\\initial_top"); + if (this->get_bool_attribute(ID::initial_top)) { + this->attributes.erase(ID::initial_top); is_top = true; } @@ -1377,15 +1400,15 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT design->add(newmod); RTLIL::Module* mod = design->module(original_name); if (is_top) - mod->set_bool_attribute("\\top"); + mod->set_bool_attribute(ID::top); // Set the attribute "interfaces_replaced_in_module" so that it does not happen again. - mod->set_bool_attribute("\\interfaces_replaced_in_module"); + mod->set_bool_attribute(ID::interfaces_replaced_in_module); } // create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces // This method is used to explode the interface when the interface is a port of the module (not instantiated inside) -RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool /*mayfail*/) +RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool /*mayfail*/) { AstNode *new_ast = NULL; std::string modname = derive_common(design, parameters, &new_ast); @@ -1437,13 +1460,20 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R // Now that the interfaces have been exploded, we can delete the dummy port related to every interface. for(auto &intf : interfaces) { - if(mod->wires_.count(intf.first)) { - mod->wires_.erase(intf.first); + if(mod->wire(intf.first) != nullptr) { + // Normally, removing wires would be batched together as it's an + // expensive operation, however, in this case doing so would mean + // that a cell with the same name cannot be created (below)... + // Since we won't expect many interfaces to exist in a module, + // we can let this slide... + pool<RTLIL::Wire*> to_remove; + to_remove.insert(mod->wire(intf.first)); + mod->remove(to_remove); mod->fixup_ports(); - // We copy the cell of the interface to the sub-module such that it can further be found if it is propagated - // down to sub-sub-modules etc. - RTLIL::Cell * new_subcell = mod->addCell(intf.first, intf.second->name); - new_subcell->set_bool_attribute("\\is_interface"); + // We copy the cell of the interface to the sub-module such that it + // can further be found if it is propagated down to sub-sub-modules etc. + RTLIL::Cell *new_subcell = mod->addCell(intf.first, intf.second->name); + new_subcell->set_bool_attribute(ID::is_interface); } else { log_error("No port with matching name found (%s) in %s. Stopping\n", log_id(intf.first), modname.c_str()); @@ -1452,7 +1482,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R // If any interfaces were replaced, set the attribute 'interfaces_replaced_in_module': if (interfaces.size() > 0) { - mod->set_bool_attribute("\\interfaces_replaced_in_module"); + mod->set_bool_attribute(ID::interfaces_replaced_in_module); } } else { @@ -1464,16 +1494,18 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R } // create a new parametric module (when needed) and return the name of the generated module - without support for interfaces -RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool /*mayfail*/) +RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool /*mayfail*/) { + bool quiet = lib || attributes.count(ID::blackbox) || attributes.count(ID::whitebox); + AstNode *new_ast = NULL; - std::string modname = derive_common(design, parameters, &new_ast); + std::string modname = derive_common(design, parameters, &new_ast, quiet); if (!design->has(modname)) { new_ast->str = modname; - design->add(process_module(new_ast, false)); + design->add(process_module(new_ast, false, NULL, quiet)); design->module(modname)->check(); - } else { + } else if (!quiet) { log("Found cached RTLIL representation for module `%s'.\n", modname.c_str()); } @@ -1482,7 +1514,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R } // create a new parametric module (when needed) and return the name of the generated module -std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out) +std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, AstNode **new_ast_out, bool quiet) { std::string stripped_name = name.str(); @@ -1496,16 +1528,18 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString 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]))); - para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); + auto it = parameters.find(child->str); + if (it != parameters.end()) { + if (!quiet) + log("Parameter %s = %s\n", child->str.c_str(), log_signal(it->second)); + para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second)); 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]))); + it = parameters.find(stringf("$%d", para_counter)); + if (it != parameters.end()) { + if (!quiet) + log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(it->second)); + para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second)); continue; } } @@ -1521,47 +1555,56 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString 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()); + if (!quiet) + log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str()); loadconfig(); + pool<IdString> rewritten; + rewritten.reserve(GetSize(parameters)); + 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]))); + auto it = parameters.find(child->str); + if (it != parameters.end()) { + if (!quiet) + log("Parameter %s = %s\n", child->str.c_str(), log_signal(it->second)); 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]))); + it = parameters.find(stringf("$%d", para_counter)); + if (it != parameters.end()) { + if (!quiet) + log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(it->second)); goto rewrite_parameter; } continue; rewrite_parameter: delete child->children.at(0); - if ((parameters[para_id].flags & RTLIL::CONST_FLAG_REAL) != 0) { + if ((it->second.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()); + child->children[0]->realvalue = std::stod(it->second.decode_string()); + } else if ((it->second.flags & RTLIL::CONST_FLAG_STRING) != 0) + child->children[0] = AstNode::mkconst_str(it->second.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); + child->children[0] = AstNode::mkconst_bits(it->second.bits, (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0); + rewritten.insert(it->first); } - for (auto param : parameters) { - AstNode *defparam = new AstNode(AST_DEFPARAM, new AstNode(AST_IDENTIFIER)); - defparam->children[0]->str = param.first.str(); - if ((param.second.flags & RTLIL::CONST_FLAG_STRING) != 0) - defparam->children.push_back(AstNode::mkconst_str(param.second.decode_string())); - else - defparam->children.push_back(AstNode::mkconst_bits(param.second.bits, (param.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0)); - new_ast->children.push_back(defparam); - } + if (GetSize(rewritten) < GetSize(parameters)) + for (const auto ¶m : parameters) { + if (rewritten.count(param.first)) + continue; + AstNode *defparam = new AstNode(AST_DEFPARAM, new AstNode(AST_IDENTIFIER)); + defparam->children[0]->str = param.first.str(); + if ((param.second.flags & RTLIL::CONST_FLAG_STRING) != 0) + defparam->children.push_back(AstNode::mkconst_str(param.second.decode_string())); + else + defparam->children.push_back(AstNode::mkconst_bits(param.second.bits, (param.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0)); + new_ast->children.push_back(defparam); + } (*new_ast_out) = new_ast; return modname; @@ -1607,25 +1650,6 @@ void AstModule::loadconfig() const flag_icells = icells; flag_pwires = pwires; flag_autowire = autowire; - use_internal_line_num(); -} - -// internal dummy line number callbacks -namespace { - int internal_line_num; - void internal_set_line_num(int n) { - internal_line_num = n; - } - int internal_get_line_num() { - return internal_line_num; - } -} - -// use internal dummy line number callbacks -void AST::use_internal_line_num() -{ - set_line_num = &internal_set_line_num; - get_line_num = &internal_get_line_num; } YOSYS_NAMESPACE_END |