twine: avoid TwinePool::lookup

This commit is contained in:
Emil J. Tywoniak 2026-06-16 22:57:13 +02:00
parent 4061593ce5
commit 3a5f5c77bf
23 changed files with 277 additions and 259 deletions

View File

@ -103,6 +103,7 @@ std::set<RTLIL::IdString> reg_wires;
std::string auto_prefix, extmem_prefix; std::string auto_prefix, extmem_prefix;
RTLIL::Module *active_module; RTLIL::Module *active_module;
std::optional<TwineSearch> active_search;
dict<RTLIL::SigBit, RTLIL::State> active_initdata; dict<RTLIL::SigBit, RTLIL::State> active_initdata;
SigMap active_sigmap; SigMap active_sigmap;
IdString initial_id; IdString initial_id;
@ -981,12 +982,10 @@ void dump_cell_expr_port(std::ostream &f, RTLIL::Cell *cell, std::string port, b
{ {
if (gen_signed && cell->parameters.count("\\" + port + "_SIGNED") > 0 && cell->parameters["\\" + port + "_SIGNED"].as_bool()) { if (gen_signed && cell->parameters.count("\\" + port + "_SIGNED") > 0 && cell->parameters["\\" + port + "_SIGNED"].as_bool()) {
f << stringf("$signed("); f << stringf("$signed(");
TwineRef port_ref = cell->module->design->twines.lookup("\\" + port); dump_sigspec(f, cell->getPort(TW::lookup(port)));
dump_sigspec(f, cell->getPort(port_ref != Twine::Null ? port_ref : cell->module->design->twines.add(Twine{"\\" + port})));
f << stringf(")"); f << stringf(")");
} else { } else {
TwineRef port_ref = cell->module->design->twines.lookup("\\" + port); dump_sigspec(f, cell->getPort(TW::lookup(port)));
dump_sigspec(f, cell->getPort(port_ref != Twine::Null ? port_ref : cell->module->design->twines.add(Twine{"\\" + port})));
} }
} }
@ -1014,7 +1013,7 @@ std::string cellname(RTLIL::Cell *cell)
if (wire->width != 1) if (wire->width != 1)
cell_name += stringf("[%d]", wire->start_offset + sig[0].offset); cell_name += stringf("[%d]", wire->start_offset + sig[0].offset);
if (active_module && active_module->count_id(active_module->design->twines.lookup(cell_name)) > 0) if (active_module && active_module->count_id(active_search->find(cell_name)) > 0)
goto no_special_reg_name; goto no_special_reg_name;
return id(cell_name); return id(cell_name);
@ -2014,7 +2013,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
char str[16]; char str[16];
snprintf(str, 16, "$%d", i); snprintf(str, 16, "$%d", i);
std::string port_str(str); std::string port_str(str);
TwineRef port_ref = cell->module->design->twines.lookup(port_str); TwineRef port_ref = active_search->find(port_str);
bool found_port = false; bool found_port = false;
for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) { for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) {
if (port_ref == Twine::Null || it->first != port_ref) if (port_ref == Twine::Null || it->first != port_ref)
@ -2377,6 +2376,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
reg_wires.clear(); reg_wires.clear();
reset_auto_counter(module); reset_auto_counter(module);
active_module = module; active_module = module;
active_search.emplace(&module->design->twines);
active_sigmap.set(module); active_sigmap.set(module);
active_initdata.clear(); active_initdata.clear();
@ -2487,6 +2487,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
f << stringf("%s" "endmodule\n", indent); f << stringf("%s" "endmodule\n", indent);
active_module = NULL; active_module = NULL;
active_search.reset();
active_sigmap.clear(); active_sigmap.clear();
active_initdata.clear(); active_initdata.clear();
} }

View File

@ -1160,7 +1160,7 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d
module->design = design; module->design = design;
module->ast = nullptr; module->ast = nullptr;
module->meta_->name = design->twines.add(Twine{ast->str}); module->meta_->name = design->twines.add(std::string{ast->str});
set_src_attr(module, ast); set_src_attr(module, ast);
module->set_bool_attribute(ID::cells_not_processed); module->set_bool_attribute(ID::cells_not_processed);
@ -1376,7 +1376,7 @@ AST_INTERNAL::process_and_replace_module(RTLIL::Design *design,
<< counter; << counter;
++counter; ++counter;
design->rename(old_module, design->twines.add(Twine{new_name.str()})); design->rename(old_module, design->twines.add(std::string{new_name.str()}));
old_module->set_bool_attribute(ID::to_delete); old_module->set_bool_attribute(ID::to_delete);
// Check if the module was the top module. If it was, we need to remove // Check if the module was the top module. If it was, we need to remove
@ -1484,7 +1484,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool nodisplay, bool dump
if (defer_local) if (defer_local)
child->str = "$abstract" + child->str; child->str = "$abstract" + child->str;
TwineRef mod_name = design->twines.lookup(child->str); TwineRef mod_name = TwineSearch(&design->twines).find(child->str);
if (design->has(mod_name)) { if (design->has(mod_name)) {
RTLIL::Module *existing_mod = design->module(mod_name); RTLIL::Module *existing_mod = design->module(mod_name);
if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) { if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) {
@ -1611,8 +1611,9 @@ bool AstModule::reprocess_if_necessary(RTLIL::Design *design)
std::string modname = cell->get_string_attribute(ID::reprocess_after); std::string modname = cell->get_string_attribute(ID::reprocess_after);
if (modname.empty()) if (modname.empty())
continue; continue;
TwineRef mod_ref = design->twines.lookup(modname); TwineSearch search(&design->twines);
TwineRef abstract_ref = design->twines.lookup("$abstract" + modname); TwineRef mod_ref = search.find(modname);
TwineRef abstract_ref = search.find("$abstract" + modname);
if (design->module(mod_ref) || design->module(abstract_ref)) { if (design->module(mod_ref) || design->module(abstract_ref)) {
log("Reprocessing module %s because instantiated module %s has become available.\n", log("Reprocessing module %s because instantiated module %s has become available.\n",
design->twines.str(meta_->name).c_str(), RTLIL::unescape_id(modname)); design->twines.str(meta_->name).c_str(), RTLIL::unescape_id(modname));
@ -1661,7 +1662,8 @@ void AstModule::expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdStr
std::pair<std::string,std::string> res = split_modport_from_type(ch->str); std::pair<std::string,std::string> res = split_modport_from_type(ch->str);
std::string interface_type = res.first; std::string interface_type = res.first;
std::string interface_modport = res.second; // Is "", if no modport std::string interface_modport = res.second; // Is "", if no modport
if (design->module(interface_type) != nullptr) { TwineRef interface_type_ref = TwineSearch(&design->twines).find(interface_type);
if (design->module(interface_type_ref) != nullptr) {
// Add a cell to the module corresponding to the interface port such that // Add a cell to the module corresponding to the interface port such that
// it can further propagated down if needed: // it can further propagated down if needed:
auto celltype_for_intf = std::make_unique<AstNode>(loc, AST_CELLTYPE); auto celltype_for_intf = std::make_unique<AstNode>(loc, AST_CELLTYPE);
@ -1671,7 +1673,7 @@ void AstModule::expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdStr
new_ast->children.push_back(std::move(cell_for_intf)); new_ast->children.push_back(std::move(cell_for_intf));
// Get all members of this non-overridden dummy interface instance: // Get all members of this non-overridden dummy interface instance:
RTLIL::Module *intfmodule = design->module(interface_type); // All interfaces should at this point in time (assuming RTLIL::Module *intfmodule = design->module(interface_type_ref); // All interfaces should at this point in time (assuming
// reprocess_module is called from the hierarchy pass) be // reprocess_module is called from the hierarchy pass) be
// present in design->modules_ // present in design->modules_
AstModule *ast_module_of_interface = (AstModule*)intfmodule; AstModule *ast_module_of_interface = (AstModule*)intfmodule;
@ -1718,10 +1720,11 @@ TwineRef AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RT
if (has_interfaces) if (has_interfaces)
new_modname += "$interfaces$" + interf_info; new_modname += "$interfaces$" + interf_info;
TwineRef new_modname_ref = design->twines.lookup(new_modname); TwineSearch search(&design->twines);
TwineRef new_modname_ref = search.find(new_modname);
if (!design->has(new_modname_ref)) { if (!design->has(new_modname_ref)) {
if (!new_ast) { if (!new_ast) {
TwineRef modname_ref = design->twines.lookup(modname); TwineRef modname_ref = search.find(modname);
auto mod = dynamic_cast<AstModule*>(design->module(modname_ref)); auto mod = dynamic_cast<AstModule*>(design->module(modname_ref));
new_ast = mod->ast->clone(); new_ast = mod->ast->clone();
} }
@ -1745,13 +1748,14 @@ TwineRef AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RT
} }
process_module(design, new_ast.get(), false); process_module(design, new_ast.get(), false);
design->module(modname)->check(); TwineRef new_ref = TwineSearch(&design->twines).find(modname);
design->module(new_ref)->check();
RTLIL::Module* mod = design->module(modname); RTLIL::Module* mod = design->module(new_ref);
// Now that the interfaces have been exploded, we can delete the dummy port related to every interface. // Now that the interfaces have been exploded, we can delete the dummy port related to every interface.
for(auto &intf : interfaces) { for(auto &intf : interfaces) {
TwineRef intf_name = design->twines.lookup(design->twines.str(intf.first)); TwineRef intf_name = intf.first;
if(mod->wire(intf_name) != nullptr) { if(mod->wire(intf_name) != nullptr) {
// Normally, removing wires would be batched together as it's an // Normally, removing wires would be batched together as it's an
// expensive operation, however, in this case doing so would mean // expensive operation, however, in this case doing so would mean
@ -1782,7 +1786,7 @@ TwineRef AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RT
log("Found cached RTLIL representation for module `%s'.\n", modname); log("Found cached RTLIL representation for module `%s'.\n", modname);
} }
return design->twines.add(Twine{modname}); return design->twines.add(std::string{modname});
} }
// create a new parametric module (when needed) and return the name of the generated module - without support for interfaces // create a new parametric module (when needed) and return the name of the generated module - without support for interfaces
@ -1793,7 +1797,7 @@ TwineRef AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RT
std::unique_ptr<AstNode> new_ast = NULL; std::unique_ptr<AstNode> new_ast = NULL;
std::string modname = derive_common(design, parameters, &new_ast, quiet); std::string modname = derive_common(design, parameters, &new_ast, quiet);
TwineRef modname_ref = design->twines.lookup(modname); TwineRef modname_ref = design->twines.add(std::string{modname});
if (!design->has(modname_ref) && new_ast) { if (!design->has(modname_ref) && new_ast) {
new_ast->str = modname; new_ast->str = modname;
process_module(design, new_ast.get(), false, NULL, quiet); process_module(design, new_ast.get(), false, NULL, quiet);
@ -1802,7 +1806,7 @@ TwineRef AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RT
log("Found cached RTLIL representation for module `%s'.\n", modname); log("Found cached RTLIL representation for module `%s'.\n", modname);
} }
return design->twines.add(Twine{modname}); return modname_ref;
} }
static std::string serialize_param_value(const RTLIL::Const &val) { static std::string serialize_param_value(const RTLIL::Const &val) {
@ -1868,7 +1872,7 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::Id
if (parameters.size()) // not named_parameters to cover hierarchical defparams if (parameters.size()) // not named_parameters to cover hierarchical defparams
modname = derived_module_name(stripped_name, named_parameters); modname = derived_module_name(stripped_name, named_parameters);
if (design->has(design->twines.lookup(modname))) if (design->has(TwineSearch(&design->twines).find(modname)))
return modname; return modname;
if (!quiet) if (!quiet)

View File

@ -46,8 +46,8 @@ using namespace AST_INTERNAL;
// helper function for creating RTLIL code for unary operations // helper function for creating RTLIL code for unary operations
static RTLIL::SigSpec uniop2rtlil(AstNode *that, TwineRef type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true) static RTLIL::SigSpec uniop2rtlil(AstNode *that, TwineRef type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true)
{ {
IdString name = stringf("%s$%s:%d$%d", type, RTLIL::encode_filename(*that->location.begin.filename), that->location.begin.line, autoidx++); IdString name = stringf("%s$%s:%d$%d", current_module->design->twines.str(type).c_str(), RTLIL::encode_filename(*that->location.begin.filename), that->location.begin.line, autoidx++);
RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, type); RTLIL::Cell *cell = current_module->addCell(current_module->design->twines.add(std::string{name.str()}), type);
set_src_attr(cell, that); set_src_attr(cell, that);
RTLIL::Wire *wire = current_module->addWire(Twine{Twine::Suffix{cell->meta_->name, "_Y"}}, result_width); RTLIL::Wire *wire = current_module->addWire(Twine{Twine::Suffix{cell->meta_->name, "_Y"}}, result_width);
@ -79,10 +79,10 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
} }
IdString name = stringf("$extend$%s:%d$%d", RTLIL::encode_filename(*that->location.begin.filename), that->location.begin.line, autoidx++); IdString name = stringf("$extend$%s:%d$%d", RTLIL::encode_filename(*that->location.begin.filename), that->location.begin.line, autoidx++);
RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, TW::$pos); RTLIL::Cell *cell = current_module->addCell(current_module->design->twines.add(std::string{name.str()}), TW::$pos);
set_src_attr(cell, that); set_src_attr(cell, that);
RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_Y"}, width); RTLIL::Wire *wire = current_module->addWire(current_module->design->twines.add(std::string{cell->name.str() + "_Y"}), width);
set_src_attr(wire, that); set_src_attr(wire, that);
wire->is_signed = that->is_signed; wire->is_signed = that->is_signed;
@ -105,8 +105,8 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
// helper function for creating RTLIL code for binary operations // helper function for creating RTLIL code for binary operations
static RTLIL::SigSpec binop2rtlil(AstNode *that, TwineRef type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) static RTLIL::SigSpec binop2rtlil(AstNode *that, TwineRef type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
{ {
IdString name = stringf("%s$%s:%d$%d", type, RTLIL::encode_filename(*that->location.begin.filename), that->location.begin.line, autoidx++); IdString name = stringf("%s$%s:%d$%d", current_module->design->twines.str(type).c_str(), RTLIL::encode_filename(*that->location.begin.filename), that->location.begin.line, autoidx++);
RTLIL::Cell *cell = current_module->addCell(Twine{name.str()}, type); RTLIL::Cell *cell = current_module->addCell(current_module->design->twines.add(std::string{name.str()}), type);
set_src_attr(cell, that); set_src_attr(cell, that);
RTLIL::Wire *wire = current_module->addWire(Twine{Twine::Suffix{cell->meta_->name, "_Y"}}, result_width); RTLIL::Wire *wire = current_module->addWire(Twine{Twine::Suffix{cell->meta_->name, "_Y"}}, result_width);
@ -141,10 +141,10 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const
std::stringstream sstr; std::stringstream sstr;
sstr << "$ternary$" << RTLIL::encode_filename(*that->location.begin.filename) << ":" << that->location.begin.line << "$" << (autoidx++); sstr << "$ternary$" << RTLIL::encode_filename(*that->location.begin.filename) << ":" << that->location.begin.line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, TW::$mux); RTLIL::Cell *cell = current_module->addCell(current_module->design->twines.add(std::string{sstr.str()}), TW::$mux);
set_src_attr(cell, that); set_src_attr(cell, that);
RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_Y"}, left.size()); RTLIL::Wire *wire = current_module->addWire(current_module->design->twines.add(std::string{cell->name.str() + "_Y"}), left.size());
set_src_attr(wire, that); set_src_attr(wire, that);
wire->is_signed = that->is_signed; wire->is_signed = that->is_signed;
@ -178,7 +178,7 @@ static void check_unique_id(RTLIL::Module *module, RTLIL::IdString id,
to_add_kind, id.c_str(), existing_kind, location_str.c_str()); to_add_kind, id.c_str(), existing_kind, location_str.c_str());
}; };
TwineRef id_tw = module->design->twines.lookup(id.str()); TwineRef id_tw = TwineSearch(&module->design->twines).find(id.str());
if (const RTLIL::Wire *wire = module->wire(id_tw)) if (const RTLIL::Wire *wire = module->wire(id_tw))
already_exists(wire, "signal"); already_exists(wire, "signal");
if (const RTLIL::Cell *cell = module->cell(id_tw)) if (const RTLIL::Cell *cell = module->cell(id_tw))
@ -355,7 +355,7 @@ struct AST_INTERNAL::ProcessGenerator
LookaheadRewriter la_rewriter(always.get()); LookaheadRewriter la_rewriter(always.get());
// generate process and simple root case // generate process and simple root case
proc = current_module->addProcess(Twine{stringf("$proc$%s:%d$%d", RTLIL::encode_filename(*always->location.begin.filename), always->location.begin.line, autoidx++)}); proc = current_module->addProcess(current_module->design->twines.add(std::string{stringf("$proc$%s:%d$%d", RTLIL::encode_filename(*always->location.begin.filename), always->location.begin.line, autoidx++)}));
set_src_attr(proc, always.get()); set_src_attr(proc, always.get());
for (auto &attr : always->attributes) { for (auto &attr : always->attributes) {
if (attr.second->type != AST_CONSTANT) if (attr.second->type != AST_CONSTANT)
@ -500,14 +500,15 @@ struct AST_INTERNAL::ProcessGenerator
continue; continue;
std::string wire_name; std::string wire_name;
TwineSearch search(&current_module->design->twines);
do { do {
wire_name = stringf("$%d%s[%d:%d]", new_temp_count[chunk.wire]++, wire_name = stringf("$%d%s[%d:%d]", new_temp_count[chunk.wire]++,
chunk.wire->name, chunk.width+chunk.offset-1, chunk.offset);; chunk.wire->name, chunk.width+chunk.offset-1, chunk.offset);;
if (chunk.wire->name.str().find('$') != std::string::npos) if (chunk.wire->name.str().find('$') != std::string::npos)
wire_name += stringf("$%d", autoidx++); wire_name += stringf("$%d", autoidx++);
} while (current_module->wire(current_module->design->twines.lookup(wire_name)) != nullptr); } while (current_module->wire(search.find(wire_name)) != nullptr);
RTLIL::Wire *wire = current_module->addWire(Twine{wire_name}, chunk.width); RTLIL::Wire *wire = current_module->addWire(current_module->design->twines.add(std::string{wire_name}), chunk.width);
set_src_attr(wire, always.get()); set_src_attr(wire, always.get());
chunk.wire = wire; chunk.wire = wire;
@ -820,7 +821,7 @@ struct AST_INTERNAL::ProcessGenerator
std::stringstream sstr; std::stringstream sstr;
sstr << ast->str << "$" << ast->location.begin.filename << ":" << ast->location.begin.line << "$" << (autoidx++); sstr << ast->str << "$" << ast->location.begin.filename << ":" << ast->location.begin.line << "$" << (autoidx++);
Wire *en = current_module->addWire(Twine{sstr.str() + "_EN"}, 1); Wire *en = current_module->addWire(current_module->design->twines.add(std::string{sstr.str() + "_EN"}), 1);
set_src_attr(en, ast); set_src_attr(en, ast);
proc->root_case.actions.push_back(SigSig(en, false)); proc->root_case.actions.push_back(SigSig(en, false));
current_case->actions.push_back(SigSig(en, true)); current_case->actions.push_back(SigSig(en, true));
@ -838,7 +839,7 @@ struct AST_INTERNAL::ProcessGenerator
} }
RTLIL::Const polarity = polarity_builder.build(); RTLIL::Const polarity = polarity_builder.build();
RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, TW::$print); RTLIL::Cell *cell = current_module->addCell(current_module->design->twines.add(std::string{sstr.str()}), TW::$print);
set_src_attr(cell, ast); set_src_attr(cell, ast);
cell->setParam(ID::TRG_WIDTH, triggers.size()); cell->setParam(ID::TRG_WIDTH, triggers.size());
cell->setParam(ID::TRG_ENABLE, (always->type == AST_INITIAL) || !triggers.empty()); cell->setParam(ID::TRG_ENABLE, (always->type == AST_INITIAL) || !triggers.empty());
@ -918,7 +919,7 @@ struct AST_INTERNAL::ProcessGenerator
if (GetSize(check) != 1) if (GetSize(check) != 1)
check = current_module->ReduceBool(NEW_TWINE, check); check = current_module->ReduceBool(NEW_TWINE, check);
Wire *en = current_module->addWire(Twine{cellname.str() + "_EN"}, 1); Wire *en = current_module->addWire(current_module->design->twines.add(std::string{cellname.str() + "_EN"}), 1);
set_src_attr(en, ast); set_src_attr(en, ast);
proc->root_case.actions.push_back(SigSig(en, false)); proc->root_case.actions.push_back(SigSig(en, false));
current_case->actions.push_back(SigSig(en, true)); current_case->actions.push_back(SigSig(en, true));
@ -936,7 +937,7 @@ struct AST_INTERNAL::ProcessGenerator
} }
RTLIL::Const polarity = polarity_builder.build(); RTLIL::Const polarity = polarity_builder.build();
RTLIL::Cell *cell = current_module->addCell(Twine{cellname.str()}, TW::$check); RTLIL::Cell *cell = current_module->addCell(current_module->design->twines.add(std::string{cellname.str()}), TW::$check);
set_src_attr(cell, ast); set_src_attr(cell, ast);
cell->set_bool_attribute(ID(keep)); cell->set_bool_attribute(ID(keep));
for (auto &attr : ast->attributes) { for (auto &attr : ast->attributes) {
@ -984,7 +985,7 @@ struct AST_INTERNAL::ProcessGenerator
set_src_attr(&action, child.get()); set_src_attr(&action, child.get());
action.memid = memid; action.memid = memid;
action.address = child->children[0]->genWidthRTLIL(-1, true, &subst_rvalue_map.stdmap()); action.address = child->children[0]->genWidthRTLIL(-1, true, &subst_rvalue_map.stdmap());
action.data = child->children[1]->genWidthRTLIL(current_module->memories[current_module->design->twines.lookup(memid)]->width, true, &subst_rvalue_map.stdmap()); action.data = child->children[1]->genWidthRTLIL(current_module->memories[TwineSearch(&current_module->design->twines).find(memid)]->width, true, &subst_rvalue_map.stdmap());
action.enable = child->children[2]->genWidthRTLIL(-1, true, &subst_rvalue_map.stdmap()); action.enable = child->children[2]->genWidthRTLIL(-1, true, &subst_rvalue_map.stdmap());
RTLIL::Const orig_priority_mask = child->children[4]->bitsAsConst(); RTLIL::Const orig_priority_mask = child->children[4]->bitsAsConst();
RTLIL::Const priority_mask = RTLIL::Const(0, cur_idx); RTLIL::Const priority_mask = RTLIL::Const(0, cur_idx);
@ -1477,7 +1478,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// signals. // signals.
RTLIL::IdString id = str; RTLIL::IdString id = str;
check_unique_id(current_module, id, this, "interface port"); check_unique_id(current_module, id, this, "interface port");
RTLIL::Wire *wire = current_module->addWire(Twine{id.str()}, 1); RTLIL::Wire *wire = current_module->addWire(current_module->design->twines.add(std::string{id.str()}), 1);
set_src_attr(wire, this); set_src_attr(wire, this);
wire->start_offset = 0; wire->start_offset = 0;
wire->port_id = port_id; wire->port_id = port_id;
@ -1517,7 +1518,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::Const val = children[0]->bitsAsConst(); RTLIL::Const val = children[0]->bitsAsConst();
RTLIL::IdString id = str; RTLIL::IdString id = str;
check_unique_id(current_module, id, this, "pwire"); check_unique_id(current_module, id, this, "pwire");
RTLIL::Wire *wire = current_module->addWire(Twine{id.str()}, GetSize(val)); RTLIL::Wire *wire = current_module->addWire(current_module->design->twines.add(std::string{id.str()}), GetSize(val));
current_module->connect(wire, val); current_module->connect(wire, val);
wire->is_signed = children[0]->is_signed; wire->is_signed = children[0]->is_signed;
@ -1542,7 +1543,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::IdString id = str; RTLIL::IdString id = str;
check_unique_id(current_module, id, this, "signal"); check_unique_id(current_module, id, this, "signal");
RTLIL::Wire *wire = current_module->addWire(Twine{id.str()}, range_left - range_right + 1); RTLIL::Wire *wire = current_module->addWire(current_module->design->twines.add(std::string{id.str()}), range_left - range_right + 1);
set_src_attr(wire, this); set_src_attr(wire, this);
wire->start_offset = range_right; wire->start_offset = range_right;
wire->port_id = port_id; wire->port_id = port_id;
@ -1573,7 +1574,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
input_error("Memory `%s' with non-constant width or size!\n", str); input_error("Memory `%s' with non-constant width or size!\n", str);
check_unique_id(current_module, RTLIL::IdString(str), this, "memory"); check_unique_id(current_module, RTLIL::IdString(str), this, "memory");
RTLIL::Memory *memory = current_module->addMemory(Twine{str}); RTLIL::Memory *memory = current_module->addMemory(current_module->design->twines.add(std::string{str}));
set_src_attr(memory, this); set_src_attr(memory, this);
memory->width = children[0]->range_left - children[0]->range_right + 1; memory->width = children[0]->range_left - children[0]->range_right + 1;
if (children[1]->range_right < children[1]->range_left) { if (children[1]->range_right < children[1]->range_left) {
@ -1628,8 +1629,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
log_assert(id2ast != nullptr); log_assert(id2ast != nullptr);
if (id2ast->type == AST_AUTOWIRE && current_module->wire(current_module->design->twines.lookup(str)) == nullptr) { TwineSearch search(&current_module->design->twines);
RTLIL::Wire *wire = current_module->addWire(Twine{str}); TwineRef str_ref = search.find(str);
if (id2ast->type == AST_AUTOWIRE && current_module->wire(str_ref) == nullptr) {
RTLIL::Wire *wire = current_module->addWire(current_module->design->twines.add(std::string{str}));
str_ref = wire->name.ref();
set_src_attr(wire, this); set_src_attr(wire, this);
// If we are currently processing a bind directive which wires up // If we are currently processing a bind directive which wires up
@ -1650,8 +1655,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
chunk = RTLIL::Const(id2ast->children[0]->bits); chunk = RTLIL::Const(id2ast->children[0]->bits);
goto use_const_chunk; goto use_const_chunk;
} }
else if ((id2ast->type == AST_WIRE || id2ast->type == AST_AUTOWIRE || id2ast->type == AST_MEMORY) && current_module->wire(current_module->design->twines.lookup(str)) != nullptr) { else if ((id2ast->type == AST_WIRE || id2ast->type == AST_AUTOWIRE || id2ast->type == AST_MEMORY) && current_module->wire(str_ref) != nullptr) {
RTLIL::Wire *current_wire = current_module->wire(current_module->design->twines.lookup(str)); RTLIL::Wire *current_wire = current_module->wire(str_ref);
if (current_wire->get_bool_attribute(ID::is_interface)) if (current_wire->get_bool_attribute(ID::is_interface))
is_interface = true; is_interface = true;
// Ignore // Ignore
@ -1672,15 +1677,15 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// with the individual signals: // with the individual signals:
if (is_interface) { if (is_interface) {
IdString dummy_wire_name = stringf("$dummywireforinterface%s", str); IdString dummy_wire_name = stringf("$dummywireforinterface%s", str);
RTLIL::Wire *dummy_wire = current_module->wire(current_module->design->twines.lookup(dummy_wire_name.str())); RTLIL::Wire *dummy_wire = current_module->wire(search.find(dummy_wire_name.str()));
if (!dummy_wire) { if (!dummy_wire) {
dummy_wire = current_module->addWire(Twine{dummy_wire_name.str()}); dummy_wire = current_module->addWire(current_module->design->twines.add(std::string{dummy_wire_name.str()}));
dummy_wire->set_bool_attribute(ID::is_interface); dummy_wire->set_bool_attribute(ID::is_interface);
} }
return dummy_wire; return dummy_wire;
} }
wire = current_module->wire(current_module->design->twines.lookup(str)); wire = current_module->wire(str_ref);
chunk.wire = wire; chunk.wire = wire;
chunk.width = wire->width; chunk.width = wire->width;
chunk.offset = 0; chunk.offset = 0;
@ -2044,10 +2049,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
std::stringstream sstr; std::stringstream sstr;
sstr << "$memrd$" << str << "$" << RTLIL::encode_filename(*location.begin.filename) << ":" << location.begin.line << "$" << (autoidx++); sstr << "$memrd$" << str << "$" << RTLIL::encode_filename(*location.begin.filename) << ":" << location.begin.line << "$" << (autoidx++);
RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, TW::$memrd); RTLIL::Cell *cell = current_module->addCell(current_module->design->twines.add(std::string{sstr.str()}), TW::$memrd);
set_src_attr(cell, this); set_src_attr(cell, this);
RTLIL::Wire *wire = current_module->addWire(Twine{cell->name.str() + "_DATA"}, current_module->memories[current_module->design->twines.lookup(str)]->width); RTLIL::Wire *wire = current_module->addWire(current_module->design->twines.add(std::string{cell->name.str() + "_DATA"}), current_module->memories[TwineSearch(&current_module->design->twines).find(str)]->width);
set_src_attr(wire, this); set_src_attr(wire, this);
int mem_width, mem_size, addr_bits; int mem_width, mem_size, addr_bits;
@ -2084,7 +2089,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
SigSpec en_sig = children[2]->genRTLIL(); SigSpec en_sig = children[2]->genRTLIL();
RTLIL::Cell *cell = current_module->addCell(Twine{sstr.str()}, TW::$meminit_v2); RTLIL::Cell *cell = current_module->addCell(current_module->design->twines.add(std::string{sstr.str()}), TW::$meminit_v2);
set_src_attr(cell, this); set_src_attr(cell, this);
int mem_width, mem_size, addr_bits; int mem_width, mem_size, addr_bits;
@ -2098,12 +2103,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
SigSpec addr_sig = children[0]->genRTLIL(); SigSpec addr_sig = children[0]->genRTLIL();
cell->setPort(TW::ADDR, addr_sig); cell->setPort(TW::ADDR, addr_sig);
cell->setPort(TW::DATA, children[1]->genWidthRTLIL(current_module->memories[current_module->design->twines.lookup(str)]->width * num_words, true)); cell->setPort(TW::DATA, children[1]->genWidthRTLIL(current_module->memories[TwineSearch(&current_module->design->twines).find(str)]->width * num_words, true));
cell->setPort(TW::EN, en_sig); cell->setPort(TW::EN, en_sig);
cell->parameters[ID::MEMID] = RTLIL::Const(str); cell->parameters[ID::MEMID] = RTLIL::Const(str);
cell->parameters[ID::ABITS] = RTLIL::Const(GetSize(addr_sig)); cell->parameters[ID::ABITS] = RTLIL::Const(GetSize(addr_sig));
cell->parameters[ID::WIDTH] = RTLIL::Const(current_module->memories[current_module->design->twines.lookup(str)]->width); cell->parameters[ID::WIDTH] = RTLIL::Const(current_module->memories[TwineSearch(&current_module->design->twines).find(str)]->width);
cell->parameters[ID::PRIORITY] = RTLIL::Const(autoidx-1); cell->parameters[ID::PRIORITY] = RTLIL::Const(autoidx-1);
} }
@ -2134,7 +2139,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (GetSize(check) != 1) if (GetSize(check) != 1)
check = current_module->ReduceBool(NEW_TWINE, check); check = current_module->ReduceBool(NEW_TWINE, check);
RTLIL::Cell *cell = current_module->addCell(Twine{cellname.str()}, TW::$check); RTLIL::Cell *cell = current_module->addCell(current_module->design->twines.add(std::string{cellname.str()}), TW::$check);
set_src_attr(cell, this); set_src_attr(cell, this);
for (auto &attr : attributes) { for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT) if (attr.second->type != AST_CONSTANT)
@ -2186,7 +2191,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::IdString id = str; RTLIL::IdString id = str;
check_unique_id(current_module, id, this, "cell"); check_unique_id(current_module, id, this, "cell");
RTLIL::Cell *cell = current_module->addCell(Twine{id.str()}, Twine::Null); RTLIL::Cell *cell = current_module->addCell(current_module->design->twines.add(std::string{id.str()}), Twine::Null);
set_src_attr(cell, this); set_src_attr(cell, this);
for (auto it = children.begin(); it != children.end(); it++) { for (auto it = children.begin(); it != children.end(); it++) {
@ -2195,7 +2200,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
std::string type_str = child->str; std::string type_str = child->str;
if (flag_icells && type_str.size() >= 2 && type_str[0] == '\\' && type_str[1] == '$') if (flag_icells && type_str.size() >= 2 && type_str[0] == '\\' && type_str[1] == '$')
type_str = type_str.substr(1); type_str = type_str.substr(1);
cell->type_impl = current_module->design->twines.add(Twine{type_str}); cell->type_impl = current_module->design->twines.add(std::string{type_str});
continue; continue;
} }
if (child->type == AST_PARASET) { if (child->type == AST_PARASET) {
@ -2234,7 +2239,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// non-trivial signed nodes are indirected through // non-trivial signed nodes are indirected through
// signed wires to enable sign extension // signed wires to enable sign extension
RTLIL::IdString wire_name = NEW_ID; RTLIL::IdString wire_name = NEW_ID;
RTLIL::Wire *wire = current_module->addWire(Twine{wire_name.str()}, GetSize(sig)); RTLIL::Wire *wire = current_module->addWire(current_module->design->twines.add(std::string{wire_name.str()}), GetSize(sig));
wire->is_signed = true; wire->is_signed = true;
current_module->connect(wire, sig); current_module->connect(wire, sig);
sig = wire; sig = wire;
@ -2243,9 +2248,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (child->str.size() == 0) { if (child->str.size() == 0) {
char buf[100]; char buf[100];
snprintf(buf, 100, "$%d", ++port_counter); snprintf(buf, 100, "$%d", ++port_counter);
cell->setPort(current_module->design->twines.add(Twine{std::string(buf)}), sig); cell->setPort(current_module->design->twines.add(std::string{std::string(buf)}), sig);
} else { } else {
cell->setPort(current_module->design->twines.add(Twine{child->str}), sig); cell->setPort(current_module->design->twines.add(std::string{child->str}), sig);
} }
continue; continue;
} }
@ -2357,8 +2362,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (width <= 0) if (width <= 0)
input_error("Failed to detect width of %s!\n", RTLIL::unescape_id(str)); input_error("Failed to detect width of %s!\n", RTLIL::unescape_id(str));
TwineRef _type = current_module->design->twines.add(Twine{str.substr(1)}); TwineRef _type = current_module->design->twines.add(std::string{str});
Cell *cell = current_module->addCell(Twine{myid}, _type); Cell *cell = current_module->addCell(current_module->design->twines.add(std::string{myid}), _type);
set_src_attr(cell, this); set_src_attr(cell, this);
cell->parameters[ID::WIDTH] = width; cell->parameters[ID::WIDTH] = width;
@ -2369,7 +2374,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
cell->attributes[ID::reg] = attr->asAttrConst(); cell->attributes[ID::reg] = attr->asAttrConst();
} }
Wire *wire = current_module->addWire(Twine{myid + "_wire"}, width); Wire *wire = current_module->addWire(current_module->design->twines.add(std::string{myid + "_wire"}), width);
set_src_attr(wire, this); set_src_attr(wire, this);
cell->setPort(TW::Y, wire); cell->setPort(TW::Y, wire);

View File

@ -704,7 +704,7 @@ void AST::set_simplify_design_context(const RTLIL::Design *design)
// lookup the module with the given name in the current design context // lookup the module with the given name in the current design context
static const RTLIL::Module* lookup_module(const std::string &name) static const RTLIL::Module* lookup_module(const std::string &name)
{ {
return simplify_design_context->module(name); return simplify_design_context->module(TwineSearch(&simplify_design_context->twines).find(name));
} }
const RTLIL::Module* AstNode::lookup_cell_module() const RTLIL::Module* AstNode::lookup_cell_module()
@ -1474,6 +1474,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
module = lookup_cell_module(); module = lookup_cell_module();
if (module) { if (module) {
size_t port_counter = 0; size_t port_counter = 0;
TwineSearch search(&module->design->twines);
for (auto& child : children) { for (auto& child : children) {
if (child->type != AST_ARGUMENT) if (child->type != AST_ARGUMENT)
continue; continue;
@ -1481,7 +1482,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
// determine the full name of port this argument is connected to // determine the full name of port this argument is connected to
TwineRef port_name; TwineRef port_name;
if (child->str.size()) if (child->str.size())
port_name = module->design->twines.lookup(child->str); port_name = search.find(child->str);
else { else {
if (port_counter >= module->ports.size()) if (port_counter >= module->ports.size())
input_error("Cell instance has more ports than the module!\n"); input_error("Cell instance has more ports than the module!\n");

View File

@ -116,11 +116,11 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
} }
std::string escaped_name = RTLIL::escape_id(wire_name); std::string escaped_name = RTLIL::escape_id(wire_name);
TwineRef wire_ref = design->twines.lookup(escaped_name); TwineRef wire_ref = TwineSearch(&design->twines).find(escaped_name);
Wire *wire = module->wire(wire_ref); Wire *wire = module->wire(wire_ref);
if (wire == nullptr) if (wire == nullptr)
wire = module->addWire(Twine{escaped_name}); wire = module->addWire(design->twines.add(std::string{escaped_name}));
return wire; return wire;
}; };
@ -174,10 +174,10 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
if (name == nullptr) if (name == nullptr)
goto error; goto error;
std::string escaped_name = RTLIL::escape_id(name); std::string escaped_name = RTLIL::escape_id(name);
module->meta_->name = design->twines.add(Twine{escaped_name}); module->meta_->name = design->twines.add(std::string{escaped_name});
obj_attributes = &module->attributes; obj_attributes = &module->attributes;
obj_parameters = nullptr; obj_parameters = nullptr;
if (design->module(design->twines.lookup(escaped_name))) if (design->module(module->meta_->name))
log_error("Duplicate definition of module %s in line %d!\n", escaped_name.c_str(), line_count); log_error("Duplicate definition of module %s in line %d!\n", escaped_name.c_str(), line_count);
design->add(module); design->add(module);
continue; continue;
@ -200,13 +200,13 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
int width = wp.second.first; int width = wp.second.first;
bool isinput = wp.second.second; bool isinput = wp.second.second;
RTLIL::Wire *wire = module->addWire(Twine{design->twines.str(name)}, width); RTLIL::Wire *wire = module->addWire(design->twines.add(std::string{design->twines.str(name)}), width);
wire->port_input = isinput; wire->port_input = isinput;
wire->port_output = !isinput; wire->port_output = !isinput;
for (int i = 0; i < width; i++) { for (int i = 0; i < width; i++) {
std::string other_name = design->twines.str(name) + stringf("[%d]", i); std::string other_name = design->twines.str(name) + stringf("[%d]", i);
TwineRef other_ref = design->twines.lookup(other_name); TwineRef other_ref = TwineSearch(&design->twines).find(other_name);
RTLIL::Wire *other_wire = module->wire(other_ref); RTLIL::Wire *other_wire = module->wire(other_ref);
if (other_wire) { if (other_wire) {
other_wire->port_input = false; other_wire->port_input = false;
@ -236,18 +236,18 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
for (auto cell : remove_cells) for (auto cell : remove_cells)
module->remove(cell); module->remove(cell);
Wire *true_wire = module->wire(design->twines.lookup("$true")); Wire *true_wire = module->wire(TW::lookup("$true"));
Wire *false_wire = module->wire(design->twines.lookup("$false")); Wire *false_wire = module->wire(TW::lookup("$false"));
Wire *undef_wire = module->wire(design->twines.lookup("$undef")); Wire *undef_wire = module->wire(TW::lookup("$undef"));
if (true_wire != nullptr) if (true_wire != nullptr)
module->rename(true_wire, design->twines.add(Twine{stringf("$true$%d", ++blif_maxnum)})); module->rename(true_wire, design->twines.add(std::string{stringf("$true$%d", ++blif_maxnum)}));
if (false_wire != nullptr) if (false_wire != nullptr)
module->rename(false_wire, design->twines.add(Twine{stringf("$false$%d", ++blif_maxnum)})); module->rename(false_wire, design->twines.add(std::string{stringf("$false$%d", ++blif_maxnum)}));
if (undef_wire != nullptr) if (undef_wire != nullptr)
module->rename(undef_wire, design->twines.add(Twine{stringf("$undef$%d", ++blif_maxnum)})); module->rename(undef_wire, design->twines.add(std::string{stringf("$undef$%d", ++blif_maxnum)}));
autoidx.ensure_at_least(blif_maxnum+1); autoidx.ensure_at_least(blif_maxnum+1);
blif_maxnum = 0; blif_maxnum = 0;
@ -276,10 +276,10 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
while ((p = strtok(NULL, " \t\r\n")) != NULL) while ((p = strtok(NULL, " \t\r\n")) != NULL)
{ {
std::string wire_name_str = stringf("\\%s", p); std::string wire_name_str = stringf("\\%s", p);
TwineRef wire_ref = design->twines.lookup(wire_name_str); TwineRef wire_ref = TwineSearch(&design->twines).find(wire_name_str);
RTLIL::Wire *wire = module->wire(wire_ref); RTLIL::Wire *wire = module->wire(wire_ref);
if (wire == nullptr) if (wire == nullptr)
wire = module->addWire(Twine{wire_name_str}); wire = module->addWire(design->twines.add(std::string{wire_name_str}));
if (!strcmp(cmd, ".inputs")) if (!strcmp(cmd, ".inputs"))
wire->port_input = true; wire->port_input = true;
else else
@ -288,7 +288,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
if (wideports) { if (wideports) {
std::pair<RTLIL::IdString, int> wp = wideports_split(p); std::pair<RTLIL::IdString, int> wp = wideports_split(p);
if (!wp.first.empty() && wp.second >= 0) { if (!wp.first.empty() && wp.second >= 0) {
TwineRef wp_ref = design->twines.lookup(wp.first.str()); TwineRef wp_ref = design->twines.add(std::string{wp.first.str()});
wideports_cache[wp_ref].first = std::max(wideports_cache[wp_ref].first, wp.second + 1); wideports_cache[wp_ref].first = std::max(wideports_cache[wp_ref].first, wp.second + 1);
wideports_cache[wp_ref].second = !strcmp(cmd, ".inputs"); wideports_cache[wp_ref].second = !strcmp(cmd, ".inputs");
} }
@ -311,7 +311,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
goto error_with_reason; goto error_with_reason;
} }
module->rename(lastcell, design->twines.add(Twine{RTLIL::escape_id(p)})); module->rename(lastcell, design->twines.add(std::string{RTLIL::escape_id(p)}));
continue; continue;
} }
@ -381,7 +381,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
if (dff_name.empty()) { if (dff_name.empty()) {
cell = module->addFfGate(NEW_TWINE, blif_wire(d), blif_wire(q)); cell = module->addFfGate(NEW_TWINE, blif_wire(d), blif_wire(q));
} else { } else {
cell = module->addCell(NEW_TWINE, design->twines.add(Twine{dff_name.str()})); cell = module->addCell(NEW_TWINE, design->twines.add(std::string{dff_name.str()}));
cell->setPort(TW::D, blif_wire(d)); cell->setPort(TW::D, blif_wire(d));
cell->setPort(TW::Q, blif_wire(q)); cell->setPort(TW::Q, blif_wire(q));
} }
@ -400,8 +400,8 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
goto error; goto error;
IdString celltype = RTLIL::escape_id(p); IdString celltype = RTLIL::escape_id(p);
RTLIL::Cell *cell = module->addCell(NEW_TWINE, design->twines.add(Twine{celltype.str()})); RTLIL::Cell *cell = module->addCell(NEW_TWINE, design->twines.add(std::string{celltype.str()}));
RTLIL::Module *cell_mod = design->module(celltype); RTLIL::Module *cell_mod = design->module(cell->type.ref());
dict<TwineRef, dict<int, SigBit>> cell_wideports_cache; dict<TwineRef, dict<int, SigBit>> cell_wideports_cache;
@ -416,15 +416,15 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
std::pair<RTLIL::IdString, int> wp = wideports_split(p); std::pair<RTLIL::IdString, int> wp = wideports_split(p);
if (wp.first.empty()) { if (wp.first.empty()) {
std::string port_name_str = RTLIL::escape_id(p); std::string port_name_str = RTLIL::escape_id(p);
TwineRef port_ref = design->twines.lookup(port_name_str); TwineRef port_ref = design->twines.add(std::string{port_name_str});
cell->setPort(port_ref, *q ? blif_wire(q) : SigSpec()); cell->setPort(port_ref, *q ? blif_wire(q) : SigSpec());
} else { } else {
TwineRef wp_ref = design->twines.lookup(wp.first.str()); TwineRef wp_ref = design->twines.add(std::string{wp.first.str()});
cell_wideports_cache[wp_ref][wp.second] = blif_wire(q); cell_wideports_cache[wp_ref][wp.second] = blif_wire(q);
} }
} else { } else {
std::string port_name_str = RTLIL::escape_id(p); std::string port_name_str = RTLIL::escape_id(p);
TwineRef port_ref = design->twines.lookup(port_name_str); TwineRef port_ref = design->twines.add(std::string{port_name_str});
cell->setPort(port_ref, *q ? blif_wire(q) : SigSpec()); cell->setPort(port_ref, *q ? blif_wire(q) : SigSpec());
} }
} }

View File

@ -375,7 +375,10 @@ struct RTLILFrontendWorker {
// We don't need to addref/release in this case. // We don't need to addref/release in this case.
std::optional<RTLIL::IdString> id = try_parse_id(); std::optional<RTLIL::IdString> id = try_parse_id();
if (id.has_value()) { if (id.has_value()) {
RTLIL::Wire *wire = current_module->wire(design->twines.lookup(id->str())); std::string s = id->str();
bool pub = !s.empty() && s[0] == '\\';
TwineRef ref = twine_tag(design->twines.find(Twine{pub ? s.substr(1) : s}), pub);
RTLIL::Wire *wire = current_module->wire(ref);
if (wire == nullptr) { if (wire == nullptr) {
if (flag_legalize) if (flag_legalize)
wire = legalize_wire(*id); wire = legalize_wire(*id);

View File

@ -209,7 +209,7 @@ struct IdStringCollector {
} }
void trace(const RTLIL::Cell &cell) { void trace(const RTLIL::Cell &cell) {
trace_named(cell); trace_named(cell);
trace(cell.type); trace(cell.type_impl);
trace_keys(cell.connections_); trace_keys(cell.connections_);
trace_keys(cell.parameters); trace_keys(cell.parameters);
} }
@ -1536,14 +1536,14 @@ const RTLIL::Module *RTLIL::Design::module(TwineRef id) const {
RTLIL::Module *RTLIL::Design::module(TwineRef id) { RTLIL::Module *RTLIL::Design::module(TwineRef id) {
return modules_.count(id) ? modules_.at(id) : NULL; return modules_.count(id) ? modules_.at(id) : NULL;
} }
const RTLIL::Module *RTLIL::Design::module(IdString id) const { // const RTLIL::Module *RTLIL::Design::module(IdString id) const {
TwineRef r = twines.lookup(id.str()); // TwineRef r = twines.lookup(id.str());
return r == Twine::Null ? NULL : module(r); // return r == Twine::Null ? NULL : module(r);
} // }
RTLIL::Module *RTLIL::Design::module(IdString id) { // RTLIL::Module *RTLIL::Design::module(IdString id) {
TwineRef r = twines.lookup(id.str()); // TwineRef r = twines.lookup(id.str());
return r == Twine::Null ? NULL : module(r); // return r == Twine::Null ? NULL : module(r);
} // }
RTLIL::Module *RTLIL::Design::top_module() const RTLIL::Module *RTLIL::Design::top_module() const
{ {
@ -5168,7 +5168,7 @@ bool RTLIL::Cell::input(TwineRef portname) const
if (yosys_celltypes.cell_known(type_impl)) if (yosys_celltypes.cell_known(type_impl))
return yosys_celltypes.cell_input(type_impl, portname); return yosys_celltypes.cell_input(type_impl, portname);
if (module && module->design) { if (module && module->design) {
RTLIL::Module *m = module->design->module(type); RTLIL::Module *m = module->design->module(type_impl);
RTLIL::Wire *w = m ? m->wire(portname) : nullptr; RTLIL::Wire *w = m ? m->wire(portname) : nullptr;
return w && w->port_input; return w && w->port_input;
} }
@ -5224,7 +5224,7 @@ const RTLIL::Const &RTLIL::Cell::getParam(IdString paramname) const
if (it != parameters.end()) if (it != parameters.end())
return it->second; return it->second;
if (module && module->design) { if (module && module->design) {
RTLIL::Module *m = module->design->module(type); RTLIL::Module *m = module->design->module(type_impl);
if (m) if (m)
return m->parameter_default_values.at(paramname); return m->parameter_default_values.at(paramname);
} }
@ -6586,6 +6586,9 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri
sigspec_parse_split(tokens, str, ','); sigspec_parse_split(tokens, str, ',');
sig = RTLIL::SigSpec(); sig = RTLIL::SigSpec();
std::optional<TwineSearch> search;
if (module)
search.emplace(&module->design->twines);
for (int tokidx = int(tokens.size())-1; tokidx >= 0; tokidx--) for (int tokidx = int(tokens.size())-1; tokidx >= 0; tokidx--)
{ {
std::string netname = tokens[tokidx]; std::string netname = tokens[tokidx];
@ -6609,7 +6612,7 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri
if (netname[0] != '$' && netname[0] != '\\') if (netname[0] != '$' && netname[0] != '\\')
netname = "\\" + netname; netname = "\\" + netname;
if (module->design->twines.lookup(netname) == Twine::Null) { if (search->find(netname) == Twine::Null) {
size_t indices_pos = netname.size()-1; size_t indices_pos = netname.size()-1;
if (indices_pos > 2 && netname[indices_pos] == ']') if (indices_pos > 2 && netname[indices_pos] == ']')
{ {
@ -6627,12 +6630,12 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri
} }
{ {
TwineRef wid = module->design->twines.lookup(netname); TwineRef wid = search->find(netname);
if (wid == Twine::Null || module->wires_.count(wid) == 0) if (wid == Twine::Null || module->wires_.count(wid) == 0)
return false; return false;
} }
RTLIL::Wire *wire = module->wire(module->design->twines.lookup(netname)); RTLIL::Wire *wire = module->wire(search->find(netname));
if (!indices.empty()) { if (!indices.empty()) {
std::vector<std::string> index_tokens; std::vector<std::string> index_tokens;
sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':'); sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':');

View File

@ -1357,31 +1357,30 @@ struct NameMasqBase {
return self().escaped(); return self().escaped();
} }
bool isPublic() const { return twine_is_public(self().ref()); } bool isPublic() const { return twine_is_public(self().ref()); }
bool empty() const { return RTLIL::IdString(self()).empty(); } bool empty() const { return self().ref() == Twine::Null; }
std::string str() const { return self().escaped(); } std::string str() const { return self().escaped(); }
std::string unescape() const { return self().unescaped(); } std::string unescape() const { return self().unescaped(); }
bool begins_with(const char *s) const { return str().starts_with(s); } bool begins_with(const char *s) const { return str().starts_with(s); }
bool ends_with(const char *s) const { return str().ends_with(s); } bool ends_with(const char *s) const { return str().ends_with(s); }
template <typename... Ts> bool in(Ts &&...args) const { template <typename... Ts> bool in(Ts &&...args) const {
return RTLIL::IdString(self()).in(std::forward<Ts>(args)...); return self().ref().in(std::forward<Ts>(args)...);
} }
std::string substr(size_t pos = 0, size_t len = std::string::npos) const { std::string substr(size_t pos = 0, size_t len = std::string::npos) const {
return RTLIL::IdString(self()).substr(pos, len); return self().escaped().substr(pos, len);
} }
// TODO less IdString construction in masquerades size_t size() const { return self().escaped().size(); }
size_t size() const { return RTLIL::IdString(self()).size(); } bool contains(const char *p) const { return self().escaped().find(p) != std::string::npos; }
bool contains(const char *p) const { return RTLIL::IdString(self()).contains(p); } char operator[](int n) const { return self().escaped()[n]; }
char operator[](int n) const { return RTLIL::IdString(self()).str()[n]; } bool lt_by_name(RTLIL::IdString rhs) const { return self().escaped() < rhs.str(); }
bool lt_by_name(RTLIL::IdString rhs) const { return RTLIL::IdString(self()).lt_by_name(rhs); } bool lt_by_name(const Derived &rhs) const { return self().escaped() < rhs.escaped(); }
bool lt_by_name(const Derived &rhs) const { return RTLIL::IdString(self()).lt_by_name(RTLIL::IdString(rhs)); } bool operator==(RTLIL::IdString rhs) const { return self().escaped() == rhs.str(); }
bool operator==(RTLIL::IdString rhs) const { return RTLIL::IdString(self()) == rhs; } bool operator!=(RTLIL::IdString rhs) const { return self().escaped() != rhs.str(); }
bool operator!=(RTLIL::IdString rhs) const { return RTLIL::IdString(self()) != rhs; } bool operator<(RTLIL::IdString rhs) const { return self().escaped() < rhs.str(); }
bool operator<(RTLIL::IdString rhs) const { return RTLIL::IdString(self()) < rhs; } bool operator==(const std::string &rhs) const { return self().escaped() == rhs; }
bool operator==(const std::string &rhs) const { return RTLIL::IdString(self()) == rhs; } bool operator!=(const std::string &rhs) const { return self().escaped() != rhs; }
bool operator!=(const std::string &rhs) const { return RTLIL::IdString(self()) != rhs; } bool operator==(const Derived &rhs) const { return self().ref() == rhs.ref(); }
bool operator==(const Derived &rhs) const { return RTLIL::IdString(self()) == RTLIL::IdString(rhs); } bool operator!=(const Derived &rhs) const { return self().ref() != rhs.ref(); }
bool operator!=(const Derived &rhs) const { return RTLIL::IdString(self()) != RTLIL::IdString(rhs); } bool operator<(const Derived &rhs) const { return self().escaped() < rhs.escaped(); }
bool operator<(const Derived &rhs) const { return RTLIL::IdString(self()) < RTLIL::IdString(rhs); }
[[nodiscard]] Hasher hash_into(Hasher h) const { return RTLIL::IdString(self()).hash_into(h); } [[nodiscard]] Hasher hash_into(Hasher h) const { return RTLIL::IdString(self()).hash_into(h); }
private: private:
const Derived &self() const { return *static_cast<const Derived *>(this); } const Derived &self() const { return *static_cast<const Derived *>(this); }
@ -1389,11 +1388,11 @@ private:
} // namespace RTLIL } // namespace RTLIL
template<typename Derived> template<typename Derived>
inline bool operator==(RTLIL::IdString lhs, const RTLIL::NameMasqBase<Derived> &rhs) { inline bool operator==(RTLIL::IdString lhs, const RTLIL::NameMasqBase<Derived> &rhs) {
return lhs == RTLIL::IdString(rhs); return lhs.str() == static_cast<const Derived &>(rhs).escaped();
} }
template<typename Derived> template<typename Derived>
inline bool operator!=(RTLIL::IdString lhs, const RTLIL::NameMasqBase<Derived> &rhs) { inline bool operator!=(RTLIL::IdString lhs, const RTLIL::NameMasqBase<Derived> &rhs) {
return lhs != RTLIL::IdString(rhs); return lhs.str() != static_cast<const Derived &>(rhs).escaped();
} }
// Read-only masquerade for Wire::name. Reads materialise the TwineRef in // Read-only masquerade for Wire::name. Reads materialise the TwineRef in
@ -1448,24 +1447,24 @@ struct RTLIL::CellTypeMasq {
return ref().in(std::forward<Ts>(args)...); return ref().in(std::forward<Ts>(args)...);
} }
std::string substr(size_t pos = 0, size_t len = std::string::npos) const { std::string substr(size_t pos = 0, size_t len = std::string::npos) const {
return RTLIL::IdString(*this).substr(pos, len); return escaped().substr(pos, len);
} }
size_t size() const { return str().size(); } size_t size() const { return str().size(); }
// bool contains(const char *p) const { return str().contains(p); } bool contains(const char *p) const { return escaped().find(p) != std::string::npos; }
char operator[](int n) const { return str()[n]; } char operator[](int n) const { return str()[n]; }
bool operator==(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) == rhs; } bool operator==(RTLIL::IdString rhs) const { return escaped() == rhs.str(); }
bool operator!=(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) != rhs; } bool operator!=(RTLIL::IdString rhs) const { return escaped() != rhs.str(); }
bool operator<(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) < rhs; } bool operator<(RTLIL::IdString rhs) const { return escaped() < rhs.str(); }
bool operator==(TwineRef rhs) const { return ref() == rhs; } bool operator==(TwineRef rhs) const { return ref() == rhs; }
bool operator!=(TwineRef rhs) const { return ref() != rhs; } bool operator!=(TwineRef rhs) const { return ref() != rhs; }
bool operator==(const std::string &rhs) const { return RTLIL::IdString(*this) == rhs; } bool operator==(const std::string &rhs) const { return escaped() == rhs; }
bool operator!=(const std::string &rhs) const { return RTLIL::IdString(*this) != rhs; } bool operator!=(const std::string &rhs) const { return escaped() != rhs; }
bool operator==(const CellTypeMasq &rhs) const { return ref() == rhs.ref(); } bool operator==(const CellTypeMasq &rhs) const { return ref() == rhs.ref(); }
bool operator!=(const CellTypeMasq &rhs) const { return ref() != rhs.ref(); } bool operator!=(const CellTypeMasq &rhs) const { return ref() != rhs.ref(); }
[[nodiscard]] Hasher hash_into(Hasher h) const { return RTLIL::IdString(*this).hash_into(h); } [[nodiscard]] Hasher hash_into(Hasher h) const { return RTLIL::IdString(*this).hash_into(h); }
}; };
inline bool operator==(RTLIL::IdString lhs, const RTLIL::CellTypeMasq &rhs) { return lhs == RTLIL::IdString(rhs); } inline bool operator==(RTLIL::IdString lhs, const RTLIL::CellTypeMasq &rhs) { return lhs.str() == rhs.escaped(); }
inline bool operator!=(RTLIL::IdString lhs, const RTLIL::CellTypeMasq &rhs) { return lhs != RTLIL::IdString(rhs); } inline bool operator!=(RTLIL::IdString lhs, const RTLIL::CellTypeMasq &rhs) { return lhs.str() != rhs.escaped(); }
inline bool operator==(TwineRef lhs, const RTLIL::CellTypeMasq &rhs) { return lhs == rhs.ref(); } inline bool operator==(TwineRef lhs, const RTLIL::CellTypeMasq &rhs) { return lhs == rhs.ref(); }
inline bool operator!=(TwineRef lhs, const RTLIL::CellTypeMasq &rhs) { return lhs != rhs.ref(); } inline bool operator!=(TwineRef lhs, const RTLIL::CellTypeMasq &rhs) { return lhs != rhs.ref(); }
@ -2156,8 +2155,8 @@ struct RTLIL::Design
~Design(); ~Design();
RTLIL::ObjRange<RTLIL::Module*, TwineRef> modules(); RTLIL::ObjRange<RTLIL::Module*, TwineRef> modules();
RTLIL::Module *module(IdString name); // RTLIL::Module *module(IdString name);
const RTLIL::Module *module(IdString name) const; // const RTLIL::Module *module(IdString name) const;
RTLIL::Module *module(TwineRef name); RTLIL::Module *module(TwineRef name);
const RTLIL::Module *module(TwineRef name) const; const RTLIL::Module *module(TwineRef name) const;
RTLIL::Module *top_module() const; RTLIL::Module *top_module() const;

View File

@ -258,7 +258,9 @@ static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
obj_id = RTLIL::escape_id(argv[i++]); obj_id = RTLIL::escape_id(argv[i++]);
attr_id = RTLIL::escape_id(argv[i++]); attr_id = RTLIL::escape_id(argv[i++]);
RTLIL::Module *mod = yosys_design->module(mod_id); TwineSearch search(&yosys_design->twines);
auto mod_twine = search.find(mod_id);
RTLIL::Module *mod = yosys_design->module(mod_twine);
if (!mod) if (!mod)
ERROR("module not found") ERROR("module not found")
@ -266,7 +268,6 @@ static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
if (mod_flag) { if (mod_flag) {
obj = mod; obj = mod;
} else { } else {
TwineSearch search(&yosys_design->twines);
auto obj_twine = search.find(obj_id); auto obj_twine = search.find(obj_id);
obj = mod->wire(obj_twine); obj = mod->wire(obj_twine);
if (!obj) if (!obj)
@ -323,7 +324,9 @@ static int tcl_has_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
obj_id = RTLIL::escape_id(argv[i++]); obj_id = RTLIL::escape_id(argv[i++]);
attr_id = RTLIL::escape_id(argv[i++]); attr_id = RTLIL::escape_id(argv[i++]);
RTLIL::Module *mod = yosys_design->module(mod_id); TwineSearch search(&yosys_design->twines);
auto mod_twine = search.find(mod_id);
RTLIL::Module *mod = yosys_design->module(mod_twine);
if (!mod) if (!mod)
ERROR("module not found") ERROR("module not found")
@ -331,7 +334,6 @@ static int tcl_has_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
if (mod_flag) { if (mod_flag) {
obj = mod; obj = mod;
} else { } else {
TwineSearch search(&yosys_design->twines);
auto obj_twine = search.find(obj_id); auto obj_twine = search.find(obj_id);
obj = mod->wire(obj_twine); obj = mod->wire(obj_twine);
if (!obj) if (!obj)
@ -378,7 +380,9 @@ static int tcl_set_attr(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *const
obj_id = RTLIL::escape_id(Tcl_GetString(objv[i++])); obj_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
attr_id = RTLIL::escape_id(Tcl_GetString(objv[i++])); attr_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
RTLIL::Module *mod = yosys_design->module(mod_id); TwineSearch search(&yosys_design->twines);
auto mod_twine = search.find(mod_id);
RTLIL::Module *mod = yosys_design->module(mod_twine);
if (!mod) if (!mod)
ERROR("module not found") ERROR("module not found")
@ -386,7 +390,6 @@ static int tcl_set_attr(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *const
if (mod_flag) { if (mod_flag) {
obj = mod; obj = mod;
} else { } else {
TwineSearch search(&yosys_design->twines);
auto obj_twine = search.find(obj_id); auto obj_twine = search.find(obj_id);
obj = mod->wire(obj_twine); obj = mod->wire(obj_twine);
if (!obj) if (!obj)
@ -457,11 +460,12 @@ static int tcl_get_param(ClientData, Tcl_Interp *interp, int argc, const char *a
cell_id = RTLIL::escape_id(argv[i++]); cell_id = RTLIL::escape_id(argv[i++]);
param_id = RTLIL::escape_id(argv[i++]); param_id = RTLIL::escape_id(argv[i++]);
RTLIL::Module *mod = yosys_design->module(mod_id); TwineSearch search(&yosys_design->twines);
auto mod_twine = search.find(mod_id);
RTLIL::Module *mod = yosys_design->module(mod_twine);
if (!mod) if (!mod)
ERROR("module not found") ERROR("module not found")
TwineSearch search(&yosys_design->twines);
auto cell_twine = search.find(cell_id); auto cell_twine = search.find(cell_id);
Cell* cell = mod->cell(cell_twine); Cell* cell = mod->cell(cell_twine);
if (!cell) if (!cell)
@ -505,11 +509,12 @@ static int tcl_set_param(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *cons
cell_id = RTLIL::escape_id(Tcl_GetString(objv[i++])); cell_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
param_id = RTLIL::escape_id(Tcl_GetString(objv[i++])); param_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
RTLIL::Module *mod = yosys_design->module(mod_id); TwineSearch search(&yosys_design->twines);
auto mod_twine = search.find(mod_id);
RTLIL::Module *mod = yosys_design->module(mod_twine);
if (!mod) if (!mod)
ERROR("module not found") ERROR("module not found")
TwineSearch search(&yosys_design->twines);
auto cell_twine = search.find(cell_id); auto cell_twine = search.find(cell_id);
RTLIL::Cell *cell = mod->cell(cell_twine); RTLIL::Cell *cell = mod->cell(cell_twine);
if (!cell) if (!cell)

View File

@ -333,10 +333,10 @@ struct TwinePool {
return ref; return ref;
} }
// Interns an object name and returns a publicity-tagged handle. Leaf // Interns a structural Twine verbatim and returns the handle. Leaf content
// strings follow the escaped convention: a leading '\' marks a public // is stored as-is — callers holding an escaped string must strip the '\'
// name (stripped from the stored content), '$' a private one. Suffix // and tag publicity themselves (or use the add(std::string) overload).
// and concat names inherit the prefix/first-child handle's publicity. // Suffix names inherit the prefix handle's publicity.
TwineRef add(Twine t) { TwineRef add(Twine t) {
bool is_public = false; bool is_public = false;
if (auto *sfx = std::get_if<Twine::Suffix>(&t.data)) { if (auto *sfx = std::get_if<Twine::Suffix>(&t.data)) {
@ -392,11 +392,6 @@ struct TwinePool {
return Twine::Null; return Twine::Null;
} }
// linear deep scan; only for rare by-string lookups. Accepts the
// escaped name convention: a leading '\' is stripped and the returned
// handle carries TWINE_PUBLIC_BIT.
TwineRef lookup(std::string_view sv) const;
// Erases every backing node not reachable from `roots`; refs to // Erases every backing node not reachable from `roots`; refs to
// surviving nodes stay valid. Returns the number of erased nodes. // surviving nodes stay valid. Returns the number of erased nodes.
template<typename Pool> template<typename Pool>
@ -685,31 +680,19 @@ struct TwineChildPool {
} }
}; };
inline TwineRef TwinePool::lookup(std::string_view sv) const {
bool is_public = !sv.empty() && sv[0] == '\\';
if (is_public)
sv.remove_prefix(1);
DeepTwineEq eq{this};
for (TwineRef ref = 0; ref < globals_.size(); ref++)
if (eq(ref, sv))
return twine_tag(ref, is_public);
for (auto it = backing.begin(); it != backing.end(); ++it) {
TwineRef ref = STATIC_TWINE_END + backing.get_index(it);
if (eq(ref, sv))
return twine_tag(ref, is_public);
}
return Twine::Null;
}
struct TwineSearch { struct TwineSearch {
TwinePool* pool; const TwinePool* pool;
std::unordered_set<TwineRef, DeepTwineHash, DeepTwineEq> index; std::unordered_set<TwineRef, DeepTwineHash, DeepTwineEq> index;
TwineSearch(TwinePool* pool) : pool(pool), index(0, DeepTwineHash{pool}, DeepTwineEq{pool}) { TwineSearch(const TwinePool* pool) : pool(pool), index(0, DeepTwineHash{pool}, DeepTwineEq{pool}) {
for (TwineRef ref = 0; ref < STATIC_TWINE_END; ref++)
index.insert(ref);
for (auto it = pool->backing.begin(); it != pool->backing.end(); ++it) { for (auto it = pool->backing.begin(); it != pool->backing.end(); ++it) {
if (it->is_dead())
continue;
index.insert(STATIC_TWINE_END + pool->backing.get_index(it)); index.insert(STATIC_TWINE_END + pool->backing.get_index(it));
} }
} }
// Escaped-name aware, same contract as TwinePool::lookup. // Escaped-name aware. Resolves both statics and locals by content.
TwineRef find(std::string_view sv) const { TwineRef find(std::string_view sv) const {
bool is_public = !sv.empty() && sv[0] == '\\'; bool is_public = !sv.empty() && sv[0] == '\\';
if (is_public) if (is_public)

View File

@ -254,21 +254,22 @@ struct DesignPass : public Pass {
if (import_mode) if (import_mode)
{ {
std::string prefix = RTLIL::escape_id(as_name); std::string prefix = RTLIL::escape_id(as_name);
TwineRef as_name_ref = copy_to_design->twines.add(std::string{prefix});
pool<Module*> queue; pool<Module*> queue;
dict<IdString, IdString> done; dict<IdString, IdString> done;
if (copy_to_design->module(prefix) != nullptr) if (copy_to_design->module(as_name_ref) != nullptr)
copy_to_design->remove(copy_to_design->module(prefix)); copy_to_design->remove(copy_to_design->module(as_name_ref));
if (GetSize(copy_src_modules) != 1) if (GetSize(copy_src_modules) != 1)
log_cmd_error("No top module found in source design.\n"); log_cmd_error("No top module found in source design.\n");
for (auto mod : copy_src_modules) for (auto mod : copy_src_modules)
{ {
log("Importing %s as %s.\n", mod, RTLIL::unescape_id(prefix)); log("Importing %s as %s.\n", mod, design->twines.unescaped_str(as_name_ref));
RTLIL::Module *t = mod->clone(copy_to_design, copy_to_design->twines.add(Twine{prefix})); RTLIL::Module *t = mod->clone(copy_to_design, as_name_ref);
t->attributes.erase(ID::top); t->attributes.erase(ID::top);
queue.insert(t); queue.insert(t);
@ -290,21 +291,22 @@ struct DesignPass : public Pass {
if (done.count(cell->type) == 0) if (done.count(cell->type) == 0)
{ {
std::string trg_name = prefix + "." + (cell->type.unescape()); std::string trg_name = prefix + "." + cell->type.unescape();
TwineRef trg_ref = copy_to_design->twines.add(std::string{trg_name});
log("Importing %s as %s.\n", fmod, RTLIL::unescape_id(trg_name)); log("Importing %s as %s.\n", log_id(fmod), RTLIL::unescape_id(trg_name).c_str());
if (copy_to_design->module(trg_name) != nullptr) if (copy_to_design->module(trg_ref) != nullptr)
copy_to_design->remove(copy_to_design->module(trg_name)); copy_to_design->remove(copy_to_design->module(trg_ref));
RTLIL::Module *t = fmod->clone(copy_to_design, copy_to_design->twines.add(Twine{trg_name})); RTLIL::Module *t = fmod->clone(copy_to_design, trg_ref);
t->attributes.erase(ID::top); t->attributes.erase(ID::top);
queue.insert(t); queue.insert(t);
done[cell->type] = trg_name; done[cell->type] = trg_name;
} }
cell->type_impl = cell->module->design->twines.add(Twine{done.at(cell->type).str()}); cell->type_impl = cell->module->design->twines.add(std::string{done.at(cell->type).str()});
} }
} }
} }
@ -317,11 +319,12 @@ struct DesignPass : public Pass {
for (auto mod : copy_src_modules) for (auto mod : copy_src_modules)
{ {
std::string trg_name = as_name.empty() ? copy_from_design->twines.str(mod->meta_->name) : RTLIL::escape_id(as_name); std::string trg_name = as_name.empty() ? copy_from_design->twines.str(mod->meta_->name) : RTLIL::escape_id(as_name);
TwineRef trg_ref = copy_to_design->twines.add(std::string{trg_name});
if (copy_to_design->module(trg_name) != nullptr) if (copy_to_design->module(trg_ref) != nullptr)
copy_to_design->remove(copy_to_design->module(trg_name)); copy_to_design->remove(copy_to_design->module(trg_ref));
mod->clone(copy_to_design, copy_to_design->twines.add(Twine{trg_name})); mod->clone(copy_to_design, trg_ref);
} }
} }

View File

@ -273,7 +273,7 @@ static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs)
{ {
if (design->module(cell->type_impl) == nullptr) if (design->module(cell->type_impl) == nullptr)
continue; continue;
lhs.selected_modules.insert(design->twines.add(Twine{cell->type.str()})); lhs.selected_modules.insert(design->twines.add(std::string{cell->type.str()}));
} }
} }
} }
@ -286,7 +286,7 @@ static void select_op_cells_to_modules(RTLIL::Design *design, RTLIL::Selection &
if (lhs.selected_module(mod->meta_->name)) if (lhs.selected_module(mod->meta_->name))
for (auto cell : mod->cells()) for (auto cell : mod->cells())
if (lhs.selected_member(mod->meta_->name, cell->meta_->name) && (design->module(cell->type_impl) != nullptr)) if (lhs.selected_member(mod->meta_->name, cell->meta_->name) && (design->module(cell->type_impl) != nullptr))
new_sel.selected_modules.insert(design->twines.add(Twine{cell->type.str()})); new_sel.selected_modules.insert(design->twines.add(std::string{cell->type.str()}));
lhs = new_sel; lhs = new_sel;
} }
@ -295,7 +295,7 @@ static void select_op_module_to_cells(RTLIL::Design *design, RTLIL::Selection &l
RTLIL::Selection new_sel(false, lhs.selects_boxes, design); RTLIL::Selection new_sel(false, lhs.selects_boxes, design);
for (auto mod : design->modules()) for (auto mod : design->modules())
for (auto cell : mod->cells()) for (auto cell : mod->cells())
if ((design->module(cell->type_impl) != nullptr) && lhs.selected_whole_module(design->twines.add(Twine{cell->type.str()}))) if ((design->module(cell->type_impl) != nullptr) && lhs.selected_whole_module(design->twines.add(std::string{cell->type.str()})))
new_sel.selected_members[mod->meta_->name].insert(cell->meta_->name); new_sel.selected_members[mod->meta_->name].insert(cell->meta_->name);
lhs = new_sel; lhs = new_sel;
} }
@ -1480,7 +1480,7 @@ struct SelectPass : public Pass {
} }
IdString mod_name = RTLIL::escape_id(line.substr(0, slash_pos)); IdString mod_name = RTLIL::escape_id(line.substr(0, slash_pos));
IdString obj_name = RTLIL::escape_id(line.substr(slash_pos+1)); IdString obj_name = RTLIL::escape_id(line.substr(slash_pos+1));
sel.selected_members[design->twines.add(Twine{mod_name.str()})].insert(design->twines.add(Twine{obj_name.str()})); sel.selected_members[design->twines.add(std::string{mod_name.str()})].insert(design->twines.add(std::string{obj_name.str()}));
} }
select_filter_active_mod(design, sel); select_filter_active_mod(design, sel);
@ -1745,6 +1745,7 @@ struct CdPass : public Pass {
design->push_full_selection(); design->push_full_selection();
design->selected_active_module = TwineRef{}; design->selected_active_module = TwineRef{};
TwineSearch search(&design->twines);
while (1) while (1)
{ {
size_t pos = modname.rfind('.'); size_t pos = modname.rfind('.');
@ -1753,12 +1754,13 @@ struct CdPass : public Pass {
break; break;
modname = modname.substr(0, pos); modname = modname.substr(0, pos);
Module *mod = design->module(RTLIL::IdString(modname)); TwineRef mod_ref = search.find(modname);
Module *mod = design->module(mod_ref);
if (mod == nullptr) if (mod == nullptr)
continue; continue;
design->selected_active_module = design->twines.add(Twine{modname}); design->selected_active_module = mod_ref;
design->pop_selection(); design->pop_selection();
design->push_full_selection(); design->push_full_selection();
select_filter_active_mod(design, design->selection()); select_filter_active_mod(design, design->selection());
@ -1769,17 +1771,18 @@ struct CdPass : public Pass {
return; return;
} }
std::string modname = RTLIL::escape_id(args[1]); TwineSearch search(&design->twines);
TwineRef modname = search.find(RTLIL::escape_id(args[1]));
if (design->module(RTLIL::IdString(modname)) == nullptr && design->selected_active_module) { if (design->module(modname) == nullptr && design->selected_active_module) {
RTLIL::Module *module = design->module(design->selected_active_module); RTLIL::Module *module = design->module(design->selected_active_module);
TwineRef cell_ref = design->twines.lookup(modname); TwineRef cell_ref = modname;
if (module != nullptr && cell_ref && module->cell(cell_ref) != nullptr) if (module != nullptr && cell_ref && module->cell(cell_ref) != nullptr)
modname = design->twines.str(module->cell(cell_ref)->type.ref()); modname = module->cell(cell_ref)->type_impl;
} }
if (design->module(RTLIL::IdString(modname)) != nullptr) { if (design->module(modname) != nullptr) {
design->selected_active_module = design->twines.add(Twine{modname}); design->selected_active_module = modname;
design->pop_selection(); design->pop_selection();
design->push_full_selection(); design->push_full_selection();
select_filter_active_mod(design, design->selection()); select_filter_active_mod(design, design->selection());
@ -1787,7 +1790,7 @@ struct CdPass : public Pass {
return; return;
} }
log_cmd_error("No such module `%s' found!\n", RTLIL::unescape_id(modname)); log_cmd_error("No such module `%s' found!\n", design->twines.str(modname));
} }
} CdPass; } CdPass;
@ -1844,8 +1847,9 @@ struct LsPass : public Pass {
if (!matches.empty()) { if (!matches.empty()) {
log("\n%d %s:\n", int(matches.size()), "modules"); log("\n%d %s:\n", int(matches.size()), "modules");
std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str()); std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str());
TwineSearch search(&design->twines);
for (auto id : matches) for (auto id : matches)
log(" %s%s\n", log_id(id), design->selected_whole_module(design->module(id)) ? "" : "*"); log(" %s%s\n", log_id(id), design->selected_whole_module(design->module(search.find(id.str()))) ? "" : "*");
} }
} }
else else

View File

@ -56,6 +56,7 @@ struct ShowWorker
FILE *f; FILE *f;
RTLIL::Design *design; RTLIL::Design *design;
TwineSearch search;
RTLIL::Module *module; RTLIL::Module *module;
uint32_t currentColor; uint32_t currentColor;
bool genWidthLabels; bool genWidthLabels;
@ -148,7 +149,7 @@ struct ShowWorker
std::string findColor(IdString member_name) std::string findColor(IdString member_name)
{ {
TwineRef member_ref = design->twines.lookup(member_name.str()); TwineRef member_ref = search.find(member_name.str());
for (auto &s : color_selections) for (auto &s : color_selections)
if (member_ref && s.second.selected_member(module->meta_->name, member_ref)) { if (member_ref && s.second.selected_member(module->meta_->name, member_ref)) {
return stringf("color=\"%s\", fontcolor=\"%s\"", s.first, s.first); return stringf("color=\"%s\", fontcolor=\"%s\"", s.first, s.first);
@ -175,7 +176,7 @@ struct ShowWorker
const char *findLabel(std::string member_name) const char *findLabel(std::string member_name)
{ {
TwineRef member_ref = design->twines.lookup(member_name); TwineRef member_ref = search.find(member_name);
for (auto &s : label_selections) for (auto &s : label_selections)
if (member_ref && s.second.selected_member(module->meta_->name, member_ref)) if (member_ref && s.second.selected_member(module->meta_->name, member_ref))
return escape(s.first); return escape(s.first);
@ -627,7 +628,7 @@ struct ShowWorker
const std::string wireshape, bool genSignedLabels, bool stretchIO, bool enumerateIds, bool abbreviateIds, bool notitle, bool href, const std::string wireshape, bool genSignedLabels, bool stretchIO, bool enumerateIds, bool abbreviateIds, bool notitle, bool href,
const std::vector<std::pair<std::string, RTLIL::Selection>> &color_selections, const std::vector<std::pair<std::string, RTLIL::Selection>> &color_selections,
const std::vector<std::pair<std::string, RTLIL::Selection>> &label_selections, RTLIL::IdString colorattr) : const std::vector<std::pair<std::string, RTLIL::Selection>> &label_selections, RTLIL::IdString colorattr) :
f(f), design(design), currentColor(colorSeed), genWidthLabels(genWidthLabels), wireshape(wireshape), f(f), design(design), search(&design->twines), currentColor(colorSeed), genWidthLabels(genWidthLabels), wireshape(wireshape),
genSignedLabels(genSignedLabels), stretchIO(stretchIO), enumerateIds(enumerateIds), abbreviateIds(abbreviateIds), genSignedLabels(genSignedLabels), stretchIO(stretchIO), enumerateIds(enumerateIds), abbreviateIds(abbreviateIds),
notitle(notitle), href(href), color_selections(color_selections), label_selections(label_selections), colorattr(colorattr) notitle(notitle), href(href), color_selections(color_selections), label_selections(label_selections), colorattr(colorattr)
{ {

View File

@ -261,7 +261,7 @@ struct statdata_t {
} else if (it == "S") { } else if (it == "S") {
port_name = TW::S; port_name = TW::S;
} else { } else {
port_name = design->twines.add(Twine{it}); port_name = design->twines.add(std::string{it});
} }
if (cell->hasPort(port_name)) { if (cell->hasPort(port_name)) {
int width = GetSize(cell->getPort(port_name)); int width = GetSize(cell->getPort(port_name));
@ -886,7 +886,7 @@ void read_liberty_cellarea(dict<IdString, cell_area_t> &cell_area, string libert
if (ar != nullptr && !ar->value.empty()) { if (ar != nullptr && !ar->value.empty()) {
string prefix = cell->args[0].substr(0, 1) == "$" ? "" : "\\"; string prefix = cell->args[0].substr(0, 1) == "$" ? "" : "\\";
// TwineRef t = twines.add(Twine{prefix + cell->args[0]}); // TwineRef t = twines.add(std::string{prefix + cell->args[0]});
IdString t = prefix + cell->args[0]; IdString t = prefix + cell->args[0];
cell_area[t] = {atof(ar->value.c_str()), is_flip_flop, single_parameter_area, double_parameter_area, cell_area[t] = {atof(ar->value.c_str()), is_flip_flop, single_parameter_area, double_parameter_area,
port_names}; port_names};
@ -962,9 +962,11 @@ struct StatPass : public Pass {
continue; continue;
} }
if (args[argidx] == "-top" && argidx + 1 < args.size()) { if (args[argidx] == "-top" && argidx + 1 < args.size()) {
if (design->module(RTLIL::escape_id(args[argidx + 1])) == nullptr) TwineRef top_ref = TwineSearch(&design->twines).find(RTLIL::escape_id(args[argidx + 1]));
if (design->module(top_ref) == nullptr)
log_cmd_error("Can't find module %s.\n", args[argidx + 1]); log_cmd_error("Can't find module %s.\n", args[argidx + 1]);
top_mod = design->module(RTLIL::escape_id(args[++argidx])); top_mod = design->module(top_ref);
argidx++;
continue; continue;
} }
if (args[argidx] == "-json") { if (args[argidx] == "-json") {

View File

@ -119,11 +119,11 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
log_assert(indices.empty()); log_assert(indices.empty());
RTLIL::Module *mod = design->addModule(design->twines.add(Twine{celltype.str()})); RTLIL::Module *mod = design->addModule(design->twines.add(std::string{celltype.str()}));
mod->attributes[ID::blackbox] = RTLIL::Const(1); mod->attributes[ID::blackbox] = RTLIL::Const(1);
for (auto &decl : ports) { for (auto &decl : ports) {
RTLIL::Wire *wire = mod->addWire(design->twines.add(Twine{decl.portname}), portwidths.at(decl.portname)); RTLIL::Wire *wire = mod->addWire(design->twines.add(std::string{decl.portname}), portwidths.at(decl.portname));
wire->port_id = decl.index; wire->port_id = decl.index;
wire->port_input = decl.input; wire->port_input = decl.input;
wire->port_output = decl.output; wire->port_output = decl.output;
@ -284,8 +284,8 @@ struct IFExpander
for (auto mod_wire : mod_replace_ports->wires()) { for (auto mod_wire : mod_replace_ports->wires()) {
std::string signal_name1 = conn_name_str + "." + design.twines.unescaped_str(mod_wire->name.ref()); std::string signal_name1 = conn_name_str + "." + design.twines.unescaped_str(mod_wire->name.ref());
std::string signal_name2 = interface_name.str() + "." + design.twines.unescaped_str(mod_wire->name.ref()); std::string signal_name2 = interface_name.str() + "." + design.twines.unescaped_str(mod_wire->name.ref());
connections_to_add.push_back(design.twines.add(Twine{signal_name1})); connections_to_add.push_back(design.twines.add(std::string{signal_name1}));
TwineRef signal_name2_ref = design.twines.lookup(signal_name2); TwineRef signal_name2_ref = TwineSearch(&design.twines).find(signal_name2);
if(module.wire(signal_name2_ref) == nullptr) { if(module.wire(signal_name2_ref) == nullptr) {
log_error("Could not find signal '%s' in '%s'\n", log_error("Could not find signal '%s' in '%s'\n",
signal_name2.c_str(), design.twines.str(module.meta_->name).data()); signal_name2.c_str(), design.twines.str(module.meta_->name).data());
@ -389,11 +389,11 @@ RTLIL::Module *get_module(RTLIL::Design &design,
const std::vector<std::string> &libdirs) const std::vector<std::string> &libdirs)
{ {
std::string cell_type = design.twines.str(cell.type.ref()); std::string cell_type = design.twines.str(cell.type.ref());
RTLIL::Module *abs_mod = design.module("$abstract" + cell_type); RTLIL::Module *abs_mod = design.module(TwineSearch(&design.twines).find("$abstract" + cell_type));
if (abs_mod) { if (abs_mod) {
cell.type_impl = design.twines.add(Twine{design.twines.str(abs_mod->derive(&design, cell.parameters))}); cell.type_impl = design.twines.add(std::string{design.twines.str(abs_mod->derive(&design, cell.parameters))});
cell.parameters.clear(); cell.parameters.clear();
RTLIL::Module *mod = design.module(cell.type); RTLIL::Module *mod = design.module(cell.type.ref());
log_assert(mod); log_assert(mod);
return mod; return mod;
} }
@ -417,7 +417,7 @@ RTLIL::Module *get_module(RTLIL::Design &design,
continue; continue;
Frontend::frontend_call(&design, NULL, filename, ext.second); Frontend::frontend_call(&design, NULL, filename, ext.second);
RTLIL::Module *mod = design.module(cell.type); RTLIL::Module *mod = design.module(cell.type.ref());
if (!mod) if (!mod)
log_error("File `%s' from libdir does not declare module `%s'.\n", log_error("File `%s' from libdir does not declare module `%s'.\n",
filename.c_str(), cell_type.c_str()); filename.c_str(), cell_type.c_str());
@ -514,7 +514,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
int idx = atoi(cell->type.substr(pos_idx + 1, pos_num).c_str()); int idx = atoi(cell->type.substr(pos_idx + 1, pos_num).c_str());
int num = atoi(cell->type.substr(pos_num + 1, pos_type).c_str()); int num = atoi(cell->type.substr(pos_num + 1, pos_type).c_str());
array_cells[cell] = std::pair<int, int>(idx, num); array_cells[cell] = std::pair<int, int>(idx, num);
cell->type_impl = cell->module->design->twines.add(Twine{cell->type.str().substr(pos_type + 1)}); cell->type_impl = cell->module->design->twines.add(std::string{cell->type.str().substr(pos_type + 1)});
} }
dict<TwineRef, RTLIL::Module*> interfaces_by_name; dict<TwineRef, RTLIL::Module*> interfaces_by_name;
@ -575,7 +575,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
for (auto &p : if_expander.interfaces_to_add_to_submodule) for (auto &p : if_expander.interfaces_to_add_to_submodule)
interfaces_by_name[p.first] = p.second; interfaces_by_name[p.first] = p.second;
for (auto &p : if_expander.modports_used_in_submodule) for (auto &p : if_expander.modports_used_in_submodule)
modports_by_name[p.first] = design->twines.add(Twine{p.second.str()}); modports_by_name[p.first] = design->twines.add(std::string{p.second.str()});
cell->type_impl = mod->derive(design, cell->type_impl = mod->derive(design,
cell->parameters, cell->parameters,
interfaces_by_name, interfaces_by_name,
@ -663,12 +663,13 @@ void hierarchy_worker(RTLIL::Design *design, std::set<RTLIL::Module*> &used, RTL
log("Used module: %*s%s\n", indent, "", mod->design->twines.str(mod->meta_->name).data()); log("Used module: %*s%s\n", indent, "", mod->design->twines.str(mod->meta_->name).data());
used.insert(mod); used.insert(mod);
TwineSearch search(&design->twines);
for (auto cell : mod->cells()) { for (auto cell : mod->cells()) {
std::string celltype = cell->type.str(); std::string celltype = cell->type.str();
if (celltype.compare(0, strlen("$array:"), "$array:") == 0) if (celltype.compare(0, strlen("$array:"), "$array:") == 0)
celltype = basic_cell_type(celltype); celltype = basic_cell_type(celltype);
if (design->module(celltype)) if (RTLIL::Module *cm = design->module(search.find(celltype)))
hierarchy_worker(design, used, design->module(celltype), indent+4); hierarchy_worker(design, used, cm, indent+4);
} }
} }
@ -712,9 +713,9 @@ bool set_keep_print(std::map<RTLIL::Module*, bool> &cache, RTLIL::Module *mod)
{ {
if (cache.count(mod) == 0) if (cache.count(mod) == 0)
for (auto c : mod->cells()) { for (auto c : mod->cells()) {
if (mod->meta_->name == mod->design->twines.add(Twine{c->type.str()})) if (mod->meta_->name == mod->design->twines.add(std::string{c->type.str()}))
continue; continue;
RTLIL::Module *m = mod->design->module(c->type); RTLIL::Module *m = mod->design->module(c->type.ref());
if ((m != nullptr && set_keep_print(cache, m)) || c->type == TW($print)) if ((m != nullptr && set_keep_print(cache, m)) || c->type == TW($print))
return cache[mod] = true; return cache[mod] = true;
} }
@ -725,9 +726,9 @@ bool set_keep_assert(std::map<RTLIL::Module*, bool> &cache, RTLIL::Module *mod)
{ {
if (cache.count(mod) == 0) if (cache.count(mod) == 0)
for (auto c : mod->cells()) { for (auto c : mod->cells()) {
if (mod->meta_->name == mod->design->twines.add(Twine{c->type.str()})) if (mod->meta_->name == mod->design->twines.add(std::string{c->type.str()}))
continue; continue;
RTLIL::Module *m = mod->design->module(c->type); RTLIL::Module *m = mod->design->module(c->type.ref());
if ((m != nullptr && set_keep_assert(cache, m)) || c->type.in(TW($check), TW($assert), TW($assume), TW($live), TW($fair), TW($cover))) if ((m != nullptr && set_keep_assert(cache, m)) || c->type.in(TW($check), TW($assert), TW($assume), TW($live), TW($fair), TW($cover)))
return cache[mod] = true; return cache[mod] = true;
} }
@ -745,7 +746,7 @@ int find_top_mod_score(Design *design, Module *module, dict<Module*, int> &db)
if (celltype.compare(0, strlen("$array:"), "$array:") == 0) if (celltype.compare(0, strlen("$array:"), "$array:") == 0)
celltype = basic_cell_type(celltype); celltype = basic_cell_type(celltype);
// Is this cell a module instance? // Is this cell a module instance?
auto instModule = design->module(celltype); auto instModule = design->module(TwineSearch(&design->twines).find(celltype));
// If there is no instance for this, issue a warning. // If there is no instance for this, issue a warning.
if (instModule != nullptr) { if (instModule != nullptr) {
score = max(score, find_top_mod_score(design, instModule, db) + 1); score = max(score, find_top_mod_score(design, instModule, db) + 1);
@ -775,16 +776,17 @@ RTLIL::Wire *find_implicit_port_wire(Module *module, Cell *cell, const std::stri
{ {
const std::string &cellname = cell->name.str(); const std::string &cellname = cell->name.str();
size_t idx = cellname.size(); size_t idx = cellname.size();
TwineSearch search(&module->design->twines);
while ((idx = cellname.find_last_of('.', idx-1)) != std::string::npos) { while ((idx = cellname.find_last_of('.', idx-1)) != std::string::npos) {
std::string wire_name = cellname.substr(0, idx+1) + port.substr(1); std::string wire_name = cellname.substr(0, idx+1) + port.substr(1);
TwineRef ref = module->design->twines.lookup(wire_name); TwineRef ref = search.find(wire_name);
if (ref != Twine::Null) { if (ref != Twine::Null) {
Wire *found = module->wire(ref); Wire *found = module->wire(ref);
if (found != nullptr) if (found != nullptr)
return found; return found;
} }
} }
TwineRef ref = module->design->twines.lookup(port); TwineRef ref = search.find(port);
if (ref != Twine::Null) if (ref != Twine::Null)
return module->wire(ref); return module->wire(ref);
return nullptr; return nullptr;
@ -1014,10 +1016,12 @@ struct HierarchyPass : public Pass {
{ {
IdString top_name = RTLIL::escape_id(load_top_mod); IdString top_name = RTLIL::escape_id(load_top_mod);
IdString abstract_id = "$abstract" + RTLIL::escape_id(load_top_mod); IdString abstract_id = "$abstract" + RTLIL::escape_id(load_top_mod);
top_mod = design->module(top_name); TwineSearch search(&design->twines);
top_mod = design->module(search.find(top_name.str()));
RTLIL::Module *abstract_mod = design->module(search.find(abstract_id.str()));
dict<RTLIL::IdString, RTLIL::Const> top_parameters; dict<RTLIL::IdString, RTLIL::Const> top_parameters;
if ((top_mod == nullptr && design->module(abstract_id)) || top_mod != nullptr) { if ((top_mod == nullptr && abstract_mod) || top_mod != nullptr) {
for (auto &para : parameters) { for (auto &para : parameters) {
SigSpec sig_value; SigSpec sig_value;
if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second)) if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second))
@ -1026,12 +1030,12 @@ struct HierarchyPass : public Pass {
} }
} }
if (top_mod == nullptr && design->module(abstract_id)) if (top_mod == nullptr && abstract_mod)
top_mod = design->module(design->module(abstract_id)->derive(design, top_parameters)); top_mod = design->module(abstract_mod->derive(design, top_parameters));
else if (top_mod != nullptr && !top_parameters.empty()) else if (top_mod != nullptr && !top_parameters.empty())
top_mod = design->module(top_mod->derive(design, top_parameters)); top_mod = design->module(top_mod->derive(design, top_parameters));
TwineRef top_name_ref = design->twines.add(Twine{top_name.str()}); TwineRef top_name_ref = design->twines.add(std::string{top_name.str()});
if (top_mod != nullptr && top_mod->meta_->name != top_name_ref) { if (top_mod != nullptr && top_mod->meta_->name != top_name_ref) {
Module *m = top_mod->clone(); Module *m = top_mod->clone();
m->meta_->name = top_name_ref; m->meta_->name = top_name_ref;
@ -1119,7 +1123,7 @@ struct HierarchyPass : public Pass {
top_mod = design->module(top_mod->derive(design, top_parameters)); top_mod = design->module(top_mod->derive(design, top_parameters));
TwineRef top_name_ref = design->twines.add(Twine{top_name.str()}); TwineRef top_name_ref = design->twines.add(std::string{top_name.str()});
if (top_mod != nullptr && top_mod->meta_->name != top_name_ref) { if (top_mod != nullptr && top_mod->meta_->name != top_name_ref) {
Module *m = top_mod->clone(); Module *m = top_mod->clone();
m->meta_->name = top_name_ref; m->meta_->name = top_name_ref;
@ -1296,7 +1300,7 @@ struct HierarchyPass : public Pass {
id, module, cell, cell->type.unescaped()); id, module, cell, cell->type.unescaped());
new_connections_twine[conn.first] = conn.second; new_connections_twine[conn.first] = conn.second;
} else } else
new_connections_twine[design->twines.add(Twine{pos_map.at(key).str()})] = conn.second; new_connections_twine[design->twines.add(std::string{pos_map.at(key).str()})] = conn.second;
} else } else
new_connections_twine[conn.first] = conn.second; new_connections_twine[conn.first] = conn.second;
} }
@ -1335,8 +1339,7 @@ struct HierarchyPass : public Pass {
if (new_m_ref == TwineRef{}) if (new_m_ref == TwineRef{})
continue; continue;
if (new_m_ref != m->meta_->name) { if (new_m_ref != m->meta_->name) {
IdString new_m_name(std::string(design->twines.str(new_m_ref))); m = design->module(new_m_ref);
m = design->module(new_m_name);
blackbox_derivatives.insert(m); blackbox_derivatives.insert(m);
} }
} }
@ -1388,7 +1391,7 @@ struct HierarchyPass : public Pass {
} }
for (auto &it : defaults_db.at(cell->type)) { for (auto &it : defaults_db.at(cell->type)) {
TwineRef port_ref = design->twines.add(Twine{it.first.str()}); TwineRef port_ref = design->twines.add(std::string{it.first.str()});
if (!cell->hasPort(port_ref)) if (!cell->hasPort(port_ref))
cell->setPort(port_ref, it.second); cell->setPort(port_ref, it.second);
} }
@ -1525,8 +1528,7 @@ struct HierarchyPass : public Pass {
if (new_m_ref == TwineRef{}) if (new_m_ref == TwineRef{})
continue; continue;
if (new_m_ref != m->meta_->name) { if (new_m_ref != m->meta_->name) {
IdString new_m_name(std::string(design->twines.str(new_m_ref))); m = design->module(new_m_ref);
m = design->module(new_m_name);
blackbox_derivatives.insert(m); blackbox_derivatives.insert(m);
} }
} else { } else {

View File

@ -326,7 +326,7 @@ void remove_mems(RTLIL::Module* mod, const MemAnalysis& mem_analysis, bool verbo
if (!mem_analysis.unused[it.second].load(std::memory_order_relaxed)) if (!mem_analysis.unused[it.second].load(std::memory_order_relaxed))
continue; continue;
std::string id_s = it.first; std::string id_s = it.first;
TwineRef id = mod->design->twines.add(Twine{it.first}); TwineRef id = mod->design->twines.add(std::string{it.first});
if (verbose) if (verbose)
log_debug(" removing unused memory `%s'.\n", id_s); log_debug(" removing unused memory `%s'.\n", id_s);
delete mod->memories.at(id); delete mod->memories.at(id);

View File

@ -144,12 +144,11 @@ bool compare_signals(const RTLIL::SigBit &s1, const RTLIL::SigBit &s2, const Sha
return w2->name.lt_by_name(w1->name); return w2->name.lt_by_name(w1->name);
} }
bool check_public_name(RTLIL::IdString id) bool check_public_name(const std::string &id_str)
{ {
if (id.begins_with("$")) if (!id_str.empty() && id_str[0] == '$')
return false; return false;
const std::string &id_str = id.str(); if (id_str.rfind("\\_", 0) == 0 && (id_str.back() == '_' || id_str.find("_[") != std::string::npos))
if (id.begins_with("\\_") && (id.ends_with("_") || id_str.find("_[") != std::string::npos))
return false; return false;
if (id_str.find(".$") != std::string::npos) if (id_str.find(".$") != std::string::npos)
return false; return false;
@ -438,7 +437,7 @@ struct WireDeleter {
if (wire->port_id != 0 || wire->get_bool_attribute(ID::keep) || !initval.is_fully_undef()) { if (wire->port_id != 0 || wire->get_bool_attribute(ID::keep) || !initval.is_fully_undef()) {
// do not delete anything with "keep" or module ports or initialized wires // do not delete anything with "keep" or module ports or initialized wires
} else } else
if (!purge_mode && check_public_name(wire->name) && (check_any(used_sig_analysis.raw_connected, s1) || check_any(used_sig_analysis.connected, s2) || s1 != s2)) { if (!purge_mode && check_public_name(wire->name.escaped()) && (check_any(used_sig_analysis.raw_connected, s1) || check_any(used_sig_analysis.connected, s2) || s1 != s2)) {
// do not get rid of public names unless in purge mode or if the wire is entirely unused, not even aliased // do not get rid of public names unless in purge mode or if the wire is entirely unused, not even aliased
} else } else
if (!check_any(used_sig_analysis.raw_connected, s1)) { if (!check_any(used_sig_analysis.raw_connected, s1)) {
@ -520,7 +519,7 @@ struct WireDeleter {
int delete_wires(RTLIL::Module* mod, bool verbose) { int delete_wires(RTLIL::Module* mod, bool verbose) {
int deleted_and_unreported = 0; int deleted_and_unreported = 0;
for (auto wire : del_wires_queue) { for (auto wire : del_wires_queue) {
if (ys_debug() || (check_public_name(wire->name) && verbose)) if (ys_debug() || (check_public_name(wire->name.escaped()) && verbose))
log_debug(" removing unused non-port wire %s.\n", wire->name); log_debug(" removing unused non-port wire %s.\n", wire->name);
else else
deleted_and_unreported++; deleted_and_unreported++;

View File

@ -421,7 +421,7 @@ void handle_clkpol_celltype_swap(Cell *cell, string type1, string type2, TwineRe
twines.unescaped_str(port), cell->type.unescaped(), cell, cell->module, twines.unescaped_str(port), cell->type.unescaped(), cell, cell->module,
log_signal(sig), log_signal(new_sig)); log_signal(sig), log_signal(new_sig));
cell->setPort(port, new_sig); cell->setPort(port, new_sig);
cell->type_impl = cell->module->design->twines.add(Twine{cell->type == type1 ? type2 : type1}); cell->type_impl = cell->module->design->twines.add(std::string{cell->type == type1 ? type2 : type1});
} }
} }
} }

View File

@ -77,7 +77,7 @@ struct RmportsPassPass : public Pass {
{ {
log(" Removing port \"%s\" from instance \"%s\"\n", log(" Removing port \"%s\" from instance \"%s\"\n",
p.c_str(), cell->type); p.c_str(), cell->type);
cell->unsetPort(cell->module->design->twines.add(Twine{p.str()})); cell->unsetPort(cell->module->design->twines.add(std::string{p.str()}));
} }
} }
} }

View File

@ -244,7 +244,7 @@ struct WreduceWorker
{ {
port_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool(); port_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool();
auto &twines = cell->module->design->twines; auto &twines = cell->module->design->twines;
SigSpec sig = mi.sigmap(cell->getPort(twines.add(Twine{stringf("\\%c", port)}))); SigSpec sig = mi.sigmap(cell->getPort(twines.add(std::string{stringf("\\%c", port)})));
if (port == 'B' && cell->type.in(TW($shl), TW($shr), TW($sshl), TW($sshr))) if (port == 'B' && cell->type.in(TW($shl), TW($shr), TW($sshl), TW($sshr)))
port_signed = false; port_signed = false;
@ -268,8 +268,8 @@ struct WreduceWorker
if (bits_removed) { if (bits_removed) {
log("Removed top %d bits (of %d) from port %c of cell %s.%s (%s).\n", log("Removed top %d bits (of %d) from port %c of cell %s.%s (%s).\n",
bits_removed, GetSize(sig) + bits_removed, port, module, cell, cell->type.unescaped()); bits_removed, GetSize(sig) + bits_removed, port, module, cell, cell->type.unescaped());
// SigSpec sig = mi.sigmap(cell->getPort(twines.add(Twine{stringf("\\%c", port)}))); // SigSpec sig = mi.sigmap(cell->getPort(twines.add(std::string{stringf("\\%c", port)})));
cell->setPort(twines.add(Twine{stringf("\\%c", port)}), sig); cell->setPort(twines.add(std::string{stringf("\\%c", port)}), sig);
did_something = true; did_something = true;
} }
} }
@ -640,7 +640,7 @@ struct WreducePass : public Pass {
if (!opt_memx && c->type.in(TW($memrd), TW($memrd_v2), TW($memwr), TW($memwr_v2), TW($meminit), TW($meminit_v2))) { if (!opt_memx && c->type.in(TW($memrd), TW($memrd_v2), TW($memwr), TW($memwr_v2), TW($meminit), TW($meminit_v2))) {
std::string memid_s = c->getParam(ID::MEMID).decode_string(); std::string memid_s = c->getParam(ID::MEMID).decode_string();
TwineRef memid = design->twines.add(Twine{memid_s}); TwineRef memid = design->twines.add(std::string{memid_s});
RTLIL::Memory *mem = module->memories.at(memid); RTLIL::Memory *mem = module->memories.at(memid);
if (mem->start_offset >= 0) { if (mem->start_offset >= 0) {
int cur_addrbits = c->getParam(ID::ABITS).as_int(); int cur_addrbits = c->getParam(ID::ABITS).as_int();

View File

@ -288,11 +288,14 @@ struct ProcArstPass : public Pass {
extra_args(args, argidx, design); extra_args(args, argidx, design);
pool<Wire*> delete_initattr_wires; pool<Wire*> delete_initattr_wires;
TwineRef global_arst_ref = global_arst.empty() ? Twine::Null
: TwineSearch(&design->twines).find(global_arst);
for (auto mod : design->all_selected_modules()) { for (auto mod : design->all_selected_modules()) {
SigMap assign_map(mod); SigMap assign_map(mod);
for (auto proc : mod->selected_processes()) { for (auto proc : mod->selected_processes()) {
proc_arst(mod, proc, assign_map); proc_arst(mod, proc, assign_map);
if (global_arst.empty() || mod->wire(design->twines.lookup(global_arst)) == nullptr) if (global_arst_ref == Twine::Null || mod->wire(global_arst_ref) == nullptr)
continue; continue;
std::vector<RTLIL::SigSig> arst_actions; std::vector<RTLIL::SigSig> arst_actions;
for (auto sync : proc->syncs) for (auto sync : proc->syncs)
@ -316,7 +319,7 @@ struct ProcArstPass : public Pass {
if (!arst_actions.empty()) { if (!arst_actions.empty()) {
RTLIL::SyncRule *sync = new RTLIL::SyncRule; RTLIL::SyncRule *sync = new RTLIL::SyncRule;
sync->type = global_arst_neg ? RTLIL::SyncType::ST0 : RTLIL::SyncType::ST1; sync->type = global_arst_neg ? RTLIL::SyncType::ST0 : RTLIL::SyncType::ST1;
sync->signal = mod->wire(design->twines.lookup(global_arst)); sync->signal = mod->wire(global_arst_ref);
sync->actions = arst_actions; sync->actions = arst_actions;
proc->syncs.push_back(sync); proc->syncs.push_back(sync);
} }

View File

@ -94,7 +94,7 @@ void gen_aldff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec sig_set
std::stringstream sstr; std::stringstream sstr;
sstr << "$procdff$" << (autoidx++); sstr << "$procdff$" << (autoidx++);
RTLIL::Cell *cell = mod->addCell(Twine{sstr.str()}, TW($aldff)); RTLIL::Cell *cell = mod->addCell(mod->design->twines.add(std::string{sstr.str()}), TW($aldff));
cell->attributes = proc->attributes; cell->attributes = proc->attributes;
cell->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size()); cell->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size());
@ -116,7 +116,7 @@ void gen_dff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::Const val_rst, RT
std::stringstream sstr; std::stringstream sstr;
sstr << "$procdff$" << (autoidx++); sstr << "$procdff$" << (autoidx++);
RTLIL::Cell *cell = mod->addCell(Twine{sstr.str()}, clk.empty() ? TW($ff) : arst ? TW($adff) : TW($dff)); RTLIL::Cell *cell = mod->addCell(mod->design->twines.add(std::string{sstr.str()}), clk.empty() ? TW($ff) : arst ? TW($adff) : TW($dff));
cell->attributes = proc->attributes; cell->attributes = proc->attributes;
cell->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size()); cell->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size());

View File

@ -155,7 +155,7 @@ RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
std::stringstream sstr; std::stringstream sstr;
sstr << "$procmux$" << (autoidx++); sstr << "$procmux$" << (autoidx++);
RTLIL::Wire *cmp_wire = mod->addWire(Twine{sstr.str() + "_CMP"}, 0); RTLIL::Wire *cmp_wire = mod->addWire(mod->design->twines.add(std::string{sstr.str() + "_CMP"}), 0);
for (auto comp : compare) for (auto comp : compare)
{ {
@ -178,7 +178,7 @@ RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
else else
{ {
// create compare cell // create compare cell
RTLIL::Cell *eq_cell = mod->addCell(Twine{stringf("%s_CMP%d", sstr.str(), cmp_wire->width)}, ifxmode ? TW($eqx) : TW($eq)); RTLIL::Cell *eq_cell = mod->addCell(mod->design->twines.add(std::string{stringf("%s_CMP%d", sstr.str(), cmp_wire->width)}), ifxmode ? TW($eqx) : TW($eq));
apply_attrs(eq_cell, sw, cs); apply_attrs(eq_cell, sw, cs);
eq_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0); eq_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
@ -201,10 +201,10 @@ RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
} }
else else
{ {
ctrl_wire = mod->addWire(Twine{sstr.str() + "_CTRL"}); ctrl_wire = mod->addWire(mod->design->twines.add(std::string{sstr.str() + "_CTRL"}));
// reduce cmp vector to one logic signal // reduce cmp vector to one logic signal
RTLIL::Cell *any_cell = mod->addCell(Twine{sstr.str() + "_ANY"}, TW($reduce_or)); RTLIL::Cell *any_cell = mod->addCell(mod->design->twines.add(std::string{sstr.str() + "_ANY"}), TW($reduce_or));
apply_attrs(any_cell, sw, cs); apply_attrs(any_cell, sw, cs);
any_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0); any_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
@ -236,10 +236,10 @@ RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
log_assert(ctrl_sig.size() == 1); log_assert(ctrl_sig.size() == 1);
// prepare multiplexer output signal // prepare multiplexer output signal
RTLIL::Wire *result_wire = mod->addWire(Twine{sstr.str() + "_Y"}, when_signal.size()); RTLIL::Wire *result_wire = mod->addWire(mod->design->twines.add(std::string{sstr.str() + "_Y"}), when_signal.size());
// create the multiplexer itself // create the multiplexer itself
RTLIL::Cell *mux_cell = mod->addCell(Twine{sstr.str()}, TW($mux)); RTLIL::Cell *mux_cell = mod->addCell(mod->design->twines.add(std::string{sstr.str()}), TW($mux));
apply_attrs(mux_cell, sw, cs); apply_attrs(mux_cell, sw, cs);
mux_cell->parameters[ID::WIDTH] = RTLIL::Const(when_signal.size()); mux_cell->parameters[ID::WIDTH] = RTLIL::Const(when_signal.size());