From bffe7a6e57e59a5e60976986c6734db332866f11 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Thu, 18 Jun 2026 21:54:57 +0200 Subject: [PATCH] WIP migration to twine --- frontends/ast/ast.cc | 11 +++++------ frontends/ast/genrtlil.cc | 21 +++++++++++---------- kernel/rtlil.cc | 12 ++++++++---- kernel/rtlil.h | 2 +- kernel/twine.h | 28 +++++++++++++++++++++++++--- passes/hierarchy/hierarchy.cc | 11 ++++++----- passes/opt/opt_expr.cc | 9 ++++++--- 7 files changed, 62 insertions(+), 32 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 76bf5fb23..851bdb557 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1484,7 +1484,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool nodisplay, bool dump if (defer_local) child->str = "$abstract" + child->str; - TwineRef mod_name = TwineSearch(&design->twines).find(child->str); + TwineRef mod_name = design->twines.find(child->str); if (design->has(mod_name)) { RTLIL::Module *existing_mod = design->module(mod_name); if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) { @@ -1720,11 +1720,10 @@ TwineRef AstModule::derive(RTLIL::Design *design, const dicttwines); - TwineRef new_modname_ref = search.find(new_modname); + TwineRef new_modname_ref = design->twines.find(new_modname); if (!design->has(new_modname_ref)) { if (!new_ast) { - TwineRef modname_ref = search.find(modname); + TwineRef modname_ref = design->twines.find(modname); auto mod = dynamic_cast(design->module(modname_ref)); new_ast = mod->ast->clone(); } @@ -1748,7 +1747,7 @@ TwineRef AstModule::derive(RTLIL::Design *design, const dicttwines).find(modname); + TwineRef new_ref = design->twines.find(modname); design->module(new_ref)->check(); RTLIL::Module* mod = design->module(new_ref); @@ -1872,7 +1871,7 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dicthas(TwineSearch(&design->twines).find(modname))) + if (design->has(design->twines.find(modname))) return modname; if (!quiet) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 0adfcfc47..95d63472d 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -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()); }; - TwineRef id_tw = TwineSearch(&module->design->twines).find(id.str()); + TwineRef id_tw = module->design->twines.find(id.str()); if (const RTLIL::Wire *wire = module->wire(id_tw)) already_exists(wire, "signal"); if (const RTLIL::Cell *cell = module->cell(id_tw)) @@ -500,13 +500,12 @@ struct AST_INTERNAL::ProcessGenerator continue; std::string wire_name; - TwineSearch search(¤t_module->design->twines); do { wire_name = stringf("$%d%s[%d:%d]", new_temp_count[chunk.wire]++, chunk.wire->name, chunk.width+chunk.offset-1, chunk.offset);; if (chunk.wire->name.str().find('$') != std::string::npos) wire_name += stringf("$%d", autoidx++); - } while (current_module->wire(search.find(wire_name)) != nullptr); + } while (current_module->wire(current_module->design->twines.find(wire_name)) != nullptr); RTLIL::Wire *wire = current_module->addWire(current_module->design->twines.add(std::string{wire_name}), chunk.width); set_src_attr(wire, always.get()); @@ -985,7 +984,8 @@ struct AST_INTERNAL::ProcessGenerator set_src_attr(&action, child.get()); action.memid = memid; action.address = child->children[0]->genWidthRTLIL(-1, true, &subst_rvalue_map.stdmap()); - action.data = child->children[1]->genWidthRTLIL(current_module->memories[TwineSearch(¤t_module->design->twines).find(memid)]->width, true, &subst_rvalue_map.stdmap()); + TwineRef memid_tw = current_module->design->twines.find(memid); + action.data = child->children[1]->genWidthRTLIL(current_module->memories[memid_tw]->width, 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 priority_mask = RTLIL::Const(0, cur_idx); @@ -1629,8 +1629,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_assert(id2ast != nullptr); - TwineSearch search(¤t_module->design->twines); - TwineRef str_ref = search.find(str); + TwineRef str_ref = current_module->design->twines.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})); @@ -1677,7 +1676,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // with the individual signals: if (is_interface) { IdString dummy_wire_name = stringf("$dummywireforinterface%s", str); - RTLIL::Wire *dummy_wire = current_module->wire(search.find(dummy_wire_name.str())); + RTLIL::Wire *dummy_wire = current_module->wire(current_module->design->twines.find(dummy_wire_name.str())); if (!dummy_wire) { dummy_wire = current_module->addWire(current_module->design->twines.add(std::string{dummy_wire_name.str()})); dummy_wire->set_bool_attribute(ID::is_interface); @@ -2052,7 +2051,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::Cell *cell = current_module->addCell(current_module->design->twines.add(std::string{sstr.str()}), TW::$memrd); set_src_attr(cell, this); - RTLIL::Wire *wire = current_module->addWire(current_module->design->twines.add(std::string{cell->name.str() + "_DATA"}), current_module->memories[TwineSearch(¤t_module->design->twines).find(str)]->width); + TwineRef mem_tw = current_module->design->twines.find(str); + RTLIL::Wire *wire = current_module->addWire(current_module->design->twines.add(std::string{cell->name.str() + "_DATA"}), current_module->memories[mem_tw]->width); set_src_attr(wire, this); int mem_width, mem_size, addr_bits; @@ -2102,13 +2102,14 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) SigSpec addr_sig = children[0]->genRTLIL(); + TwineRef mem_tw = current_module->design->twines.find(str); cell->setPort(TW::ADDR, addr_sig); - cell->setPort(TW::DATA, children[1]->genWidthRTLIL(current_module->memories[TwineSearch(¤t_module->design->twines).find(str)]->width * num_words, true)); + cell->setPort(TW::DATA, children[1]->genWidthRTLIL(current_module->memories[mem_tw]->width * num_words, true)); cell->setPort(TW::EN, en_sig); cell->parameters[ID::MEMID] = RTLIL::Const(str); cell->parameters[ID::ABITS] = RTLIL::Const(GetSize(addr_sig)); - cell->parameters[ID::WIDTH] = RTLIL::Const(current_module->memories[TwineSearch(¤t_module->design->twines).find(str)]->width); + cell->parameters[ID::WIDTH] = RTLIL::Const(current_module->memories[mem_tw]->width); cell->parameters[ID::PRIORITY] = RTLIL::Const(autoidx-1); } diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 12bfd4a93..4fc5b8442 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2097,8 +2097,10 @@ namespace { void check() { - if (!cell->type.begins_with("$") || cell->type.begins_with("$__") || cell->type.begins_with("$paramod") || cell->type.begins_with("$fmcombine") || - cell->type.begins_with("$verific$") || cell->type.begins_with("$array:") || cell->type.begins_with("$extern:")) + std::string type_str = cell->type.str(); + std::string_view type_sv = type_str; + if (!type_sv.starts_with("$") || type_sv.starts_with("$__") || type_sv.starts_with("$paramod") || type_sv.starts_with("$fmcombine") || + type_sv.starts_with("$verific$") || type_sv.starts_with("$array:") || type_sv.starts_with("$extern:")) return; if (cell->type_impl == TW($buf)) { @@ -5258,8 +5260,10 @@ void RTLIL::Cell::check() void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) { - if (!type.begins_with("$") || type.begins_with("$_") || type.begins_with("$paramod") || type.begins_with("$fmcombine") || - type.begins_with("$verific$") || type.begins_with("$array:") || type.begins_with("$extern:")) + std::string type_str = type.str(); + std::string_view type_sv = type_str; + if (!type_sv.starts_with("$") || type_sv.starts_with("$_") || type_sv.starts_with("$paramod") || type_sv.starts_with("$fmcombine") || + type_sv.starts_with("$verific$") || type_sv.starts_with("$array:") || type_sv.starts_with("$extern:")) return; if (type == TW($buf) || type == TW($mux) || type == TW($pmux) || type == TW($bmux) || type == TW($bwmux) || type == TW($bweqx)) { diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 214bed6dd..7862da501 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -549,7 +549,7 @@ struct RTLIL::IdString template struct compare_ptr_by_name { bool operator()(const T *a, const T *b) const { - return (a == nullptr || b == nullptr) ? (a < b) : (a->name < b->name); + return (a == nullptr || b == nullptr) ? (a < b) : (a->name.ref() < b->name.ref()); } }; diff --git a/kernel/twine.h b/kernel/twine.h index 1e998e11b..2ea55c238 100644 --- a/kernel/twine.h +++ b/kernel/twine.h @@ -229,11 +229,33 @@ struct TwinePool { } }, (*this)[ref].data); } + void append_str(TwineRef ref, std::string& out) const { + if (ref == Twine::Null) + return; + if (twine_is_public(ref)) + out += '\\'; + std::visit([&](const auto& val) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + } else if constexpr (std::is_same_v) { + out += val; + } else if constexpr (std::is_same_v>) { + for (size_t i = 0; i < val.size(); ++i) { + if (i > 0) + out += '|'; + append_str(val[i], out); + } + } else if constexpr (std::is_same_v) { + append_str(val.prefix, out); + out += val.tail; + } + }, (*this)[ref].data); + } // Escaped form: leading '\' for public name handles, content otherwise. std::string str(TwineRef ref) const { - std::ostringstream os; - print(ref, os); - return os.str(); + std::string out; + append_str(ref, out); + return out; } // Name content without the publicity escape. diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index f5174c9ba..a2ddda1c4 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -663,12 +663,13 @@ void hierarchy_worker(RTLIL::Design *design, std::set &used, RTL log("Used module: %*s%s\n", indent, "", mod->design->twines.str(mod->meta_->name).data()); used.insert(mod); - TwineSearch search(&design->twines); for (auto cell : mod->cells()) { - std::string celltype = cell->type.str(); - if (celltype.compare(0, strlen("$array:"), "$array:") == 0) - celltype = basic_cell_type(celltype); - if (RTLIL::Module *cm = design->module(search.find(celltype))) + RTLIL::Module *cm; + if (cell->type.begins_with("$array:")) + cm = design->module(design->twines.find(basic_cell_type(cell->type.str()))); + else + cm = design->module(cell->type.ref()); + if (cm) hierarchy_worker(design, used, cm, indent+4); } } diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 221bb5ec0..b1a087541 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -22,6 +22,7 @@ #include "kernel/sigtools.h" #include "kernel/celltypes.h" #include "kernel/newcelltypes.h" +#include "kernel/twine.h" #include "kernel/utils.h" #include "kernel/log.h" #include "kernel/unstable/patch.h" @@ -385,7 +386,7 @@ void handle_polarity_inv(Cell *cell, TwineRef port, IdString param, const SigMap SigBit sig = assign_map(raw); if (auto inv_a = get_inverted_raw(sig)) { SigBit new_sig = assign_map(*inv_a); - auto twines = cell->module->design->twines; + auto& twines = cell->module->design->twines; log_debug("Inverting %s of %s cell `%s' in module `%s': %s -> %s\n", twines.unescaped_str(port), cell->type.unescaped(), cell, cell->module, log_signal(sig), log_signal(new_sig)); @@ -397,7 +398,9 @@ void handle_polarity_inv(Cell *cell, TwineRef port, IdString param, const SigMap void handle_clkpol_celltype_swap(Cell *cell, string type1, string type2, TwineRef port, const SigMap &assign_map) { log_assert(GetSize(type1) == GetSize(type2)); - string cell_type = cell->type.str(); + if ((size_t)cell->type_impl > STATIC_TWINE_END) + return; + const std::string &cell_type = TwinePool::globals_[(size_t)cell->type_impl].leaf(); if (GetSize(type1) != GetSize(cell_type)) return; @@ -414,7 +417,7 @@ void handle_clkpol_celltype_swap(Cell *cell, string type1, string type2, TwineRe if (cell->type.in(type1, type2)) { SigSpec sig = assign_map(cell->getPort(port)); - auto twines = cell->module->design->twines; + auto& twines = cell->module->design->twines; if (auto inv_a = get_inverted_raw(sig)) { SigSpec new_sig = assign_map(*inv_a); log_debug("Inverting %s of %s cell `%s' in module `%s': %s -> %s\n",