diff --git a/Makefile b/Makefile index df1670b08..f272a52e9 100644 --- a/Makefile +++ b/Makefile @@ -744,9 +744,13 @@ OBJS += passes/cmds/stat.o OBJS += passes/cmds/design.o OBJS += passes/cmds/plugin.o +include $(YOSYS_SRC)/kernel/unstable/Makefile.inc include $(YOSYS_SRC)/passes/proc/Makefile.inc include $(YOSYS_SRC)/passes/opt/Makefile.inc -include $(YOSYS_SRC)/passes/techmap/Makefile.inc +OBJS += passes/techmap/simplemap.o +OBJS += passes/techmap/libcache.o +OBJS += passes/techmap/libparse.o +# include $(YOSYS_SRC)/passes/techmap/Makefile.inc include $(YOSYS_SRC)/backends/verilog/Makefile.inc include $(YOSYS_SRC)/backends/rtlil/Makefile.inc diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index c9dddd649..0d2b99bb7 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -837,7 +837,7 @@ void AigerReader::post_process() wire->port_input = false; module->connect(wire, existing); } - log_debug(" -> %s\n", design->twines.unescaped_str(escaped_s)); + log_debug(" -> %s\n", log_id(escaped_s)); } else { RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index); @@ -848,7 +848,7 @@ void AigerReader::post_process() module->connect(wire, existing); wire->port_input = false; } - log_debug(" -> %s\n", design->twines.unescaped_str(indexed_name)); + log_debug(" -> %s\n", log_id(indexed_name)); } if (wideports && !existing) { @@ -884,7 +884,7 @@ void AigerReader::post_process() module->connect(wire, existing); wire = existing; } - log_debug(" -> %s\n", design->twines.unescaped_str(escaped_s)); + log_debug(" -> %s\n", log_id(escaped_s)); } else { RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index); @@ -896,7 +896,7 @@ void AigerReader::post_process() existing->port_output = true; module->connect(wire, existing); } - log_debug(" -> %s\n", design->twines.unescaped_str(indexed_name)); + log_debug(" -> %s\n", log_id(indexed_name)); } if (wideports && !existing) { @@ -914,7 +914,7 @@ void AigerReader::post_process() else if (type == "box") { RTLIL::Cell* cell = module->cell(design->twines.lookup(stringf("$box%d", variable))); if (!cell) - log_debug("Box %d (%s) no longer exists.\n", variable, design->twines.unescaped_str(escaped_s)); + log_debug("Box %d (%s) no longer exists.\n", variable, log_id(escaped_s)); else module->rename(cell, design->twines.add(Twine{escaped_s.str()})); } diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 5018abfe8..fe701ac6c 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -2203,10 +2203,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) const auto* value = child->children[0].get(); if (value->type == AST_REALVALUE) log_file_warning(*location.begin.filename, location.begin.line, "Replacing floating point parameter %s.%s = %f with string.\n", - cell, design->twines.unescaped_str(paraname), value->realvalue); + cell, log_id(paraname), value->realvalue); else if (value->type != AST_CONSTANT) input_error("Parameter %s.%s with non-constant value!\n", - cell, design->twines.unescaped_str(paraname)); + cell, log_id(paraname)); cell->parameters[paraname] = value->asParaConst(); continue; } diff --git a/frontends/rtlil/rtlil_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index 64fcef407..8c8d099e5 100644 --- a/frontends/rtlil/rtlil_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -341,7 +341,7 @@ struct RTLILFrontendWorker { error("No wires found for legalization"); int hash = hash_ops::hash(id).yield(); RTLIL::Wire *wire = current_module->wire_at(abs(hash % wires_size)); - log("Legalizing wire `%s' to `%s'.\n", design->twines.unescaped_str(id), design->twines.unescaped_str(wire->name)); + log("Legalizing wire `%s' to `%s'.\n", log_id(id), design->twines.unescaped_str(wire->name.ref())); return wire; } @@ -365,8 +365,11 @@ struct RTLILFrontendWorker { if (wire == nullptr) { if (flag_legalize) wire = legalize_wire(*id); - else + else { + // for (auto wire : current_module->wires()) + // design->twines.dump(wire->meta_->name); error("Wire `%s' not found.", *id); + } } sig = RTLIL::SigSpec(wire); } else { @@ -423,7 +426,7 @@ struct RTLILFrontendWorker { void parse_module() { - TwineRef module_name = design->twines.lookup(parse_id()); + TwineRef module_name = design->twines.add(parse_id()); expect_eol(); bool delete_current_module = false; diff --git a/kernel/drivertools.cc b/kernel/drivertools.cc index aa34bf731..518f726dc 100644 --- a/kernel/drivertools.cc +++ b/kernel/drivertools.cc @@ -866,7 +866,7 @@ DriveSpec DriverMap::operator()(DriveSpec spec) std::string log_signal(DriveChunkWire const &chunk) { - std::string id = design->twines.unescaped_str(chunk.wire->name); + std::string id = chunk.wire->module->design->twines.unescaped_str(chunk.wire->name.ref()); if (chunk.is_whole()) return id; if (chunk.width == 1) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 135ba7265..ea2639634 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -17,6 +17,7 @@ * */ +#include "kernel/rtlil.h" #include "kernel/yosys.h" #include "kernel/macc.h" #include "kernel/newcelltypes.h" @@ -1833,7 +1834,7 @@ RTLIL::Module::Module() design = nullptr; refcount_wires_ = 0; refcount_cells_ = 0; - meta_ = nullptr; + meta_ = new ObjMeta; #ifdef YOSYS_ENABLE_PYTHON RTLIL::Module::get_all_modules()->insert(std::pair(hashidx_, this)); @@ -2948,14 +2949,11 @@ namespace { void RTLIL::Module::sort() { - auto sort_twine_by_str = [this](TwineRef a, TwineRef b) { - return design->twines.flat_string(a) < design->twines.flat_string(b); - }; - wires_.sort(sort_twine_by_str); - cells_.sort(sort_twine_by_str); + wires_.sort(sort_by_twine_str_expensive(design->twines)); + cells_.sort(sort_by_twine_str_expensive(design->twines)); parameter_default_values.sort(sort_by_id_str()); - memories.sort(sort_twine_by_str); - processes.sort(sort_twine_by_str); + memories.sort(sort_by_twine_str_expensive(design->twines)); + processes.sort(sort_by_twine_str_expensive(design->twines)); for (auto &it : cells_) it.second->sort(); for (auto &it : wires_) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 318086b10..4d369aa67 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -130,6 +130,7 @@ namespace RTLIL struct StaticIdString; struct SigNormIndex; struct ObjMeta; + template struct NameMasqBase; struct ModuleNameMasq; struct WireNameMasq; struct CellNameMasq; @@ -825,6 +826,18 @@ namespace RTLIL { return a.lt_by_name(b); } }; + struct sort_by_twine_str_expensive { + const TwinePool& pool; + explicit sort_by_twine_str_expensive(const TwinePool& pool) + : pool(pool) {} + bool operator()(TwineRef a, TwineRef b) const { + bool a_public = a.is_public(); + bool b_public = b.is_public(); + std::string a_str = pool.str(a); + std::string b_str = pool.str(b); + return std::tie(a_str, a_public) < std::tie(b_str, b_public); + } + }; static inline std::string encode_filename(const std::string &filename) { @@ -1329,97 +1342,85 @@ struct RTLIL::NamedObject : public RTLIL::AttrObject RTLIL::IdString name; }; +// CRTP base shared by WireNameMasq, CellNameMasq, and ModuleNameMasq. +// Derived must define ref(), escaped(), and unescaped(); everything else +// is derived from those three via operator IdString(). +namespace RTLIL { +template +struct NameMasqBase { + operator RTLIL::IdString() const { + std::string s = self().escaped(); + if (s.empty()) return RTLIL::IdString{}; + return RTLIL::IdString(s); + } + bool isPublic() const { return twine_is_public(self().ref()); } + bool empty() const { return RTLIL::IdString(self()).empty(); } + std::string str() const { return self().escaped(); } + const char *c_str() const { return RTLIL::IdString(self()).c_str(); } + std::string unescape() const { return self().unescaped(); } + bool begins_with(const char *s) const { return RTLIL::IdString(self()).begins_with(s); } + bool ends_with(const char *s) const { return RTLIL::IdString(self()).ends_with(s); } + template bool in(Ts &&...args) const { + return RTLIL::IdString(self()).in(std::forward(args)...); + } + std::string substr(size_t pos = 0, size_t len = std::string::npos) const { + return RTLIL::IdString(self()).substr(pos, len); + } + size_t size() const { return RTLIL::IdString(self()).size(); } + bool contains(const char *p) const { return RTLIL::IdString(self()).contains(p); } + char operator[](int n) const { return RTLIL::IdString(self()).str()[n]; } + 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 RTLIL::IdString(self()).lt_by_name(RTLIL::IdString(rhs)); } + bool operator==(RTLIL::IdString rhs) const { return RTLIL::IdString(self()) == rhs; } + bool operator!=(RTLIL::IdString rhs) const { return RTLIL::IdString(self()) != rhs; } + bool operator<(RTLIL::IdString rhs) const { return RTLIL::IdString(self()) < rhs; } + bool operator==(const std::string &rhs) const { return RTLIL::IdString(self()) == rhs; } + bool operator!=(const std::string &rhs) const { return RTLIL::IdString(self()) != rhs; } + bool operator==(const Derived &rhs) const { return RTLIL::IdString(self()) == RTLIL::IdString(rhs); } + bool operator!=(const Derived &rhs) const { return RTLIL::IdString(self()) != RTLIL::IdString(rhs); } + 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); } +private: + const Derived &self() const { return *static_cast(this); } +}; +} // namespace RTLIL +template +inline bool operator==(RTLIL::IdString lhs, const RTLIL::NameMasqBase &rhs) { + return lhs == RTLIL::IdString(rhs); +} +template +inline bool operator!=(RTLIL::IdString lhs, const RTLIL::NameMasqBase &rhs) { + return lhs != RTLIL::IdString(rhs); +} + // Read-only masquerade for Wire::name. Reads materialise the TwineRef in // the owning Design's twines pool into a temporary IdString. Writes are // intentionally unsupported — use Module::rename(wire, new_name) instead. // Defined before Wire so it can be used as a [[no_unique_address]] member. -struct RTLIL::WireNameMasq { +struct RTLIL::WireNameMasq : RTLIL::NameMasqBase { WireNameMasq() = default; WireNameMasq(const WireNameMasq &) = delete; WireNameMasq(WireNameMasq &&) = delete; WireNameMasq &operator=(const WireNameMasq &) = delete; WireNameMasq &operator=(WireNameMasq &&) = delete; - // Materialise → IdString. Slow path; intended for plugin code. - operator RTLIL::IdString() const; // Tagged name handle (Twine::Null when unnamed). TwineRef ref() const; // Escaped form ('\'-prefixed when public) / bare content. std::string escaped() const; std::string unescaped() const; - bool isPublic() const { return twine_is_public(ref()); } - bool empty() const { return RTLIL::IdString(*this).empty(); } - std::string str() const { return escaped(); } - const char *c_str() const { return RTLIL::IdString(*this).c_str(); } - std::string unescape() const { return unescaped(); } - bool begins_with(const char *s) const { return RTLIL::IdString(*this).begins_with(s); } - bool ends_with(const char *s) const { return RTLIL::IdString(*this).ends_with(s); } - template bool in(Ts &&...args) const { - return RTLIL::IdString(*this).in(std::forward(args)...); - } - std::string substr(size_t pos = 0, size_t len = std::string::npos) const { - return RTLIL::IdString(*this).substr(pos, len); - } - size_t size() const { return RTLIL::IdString(*this).size(); } - bool contains(const char *p) const { return RTLIL::IdString(*this).contains(p); } - char operator[](int n) const { return RTLIL::IdString(*this).str()[n]; } - bool lt_by_name(RTLIL::IdString rhs) const { return RTLIL::IdString(*this).lt_by_name(rhs); } - bool lt_by_name(const WireNameMasq &rhs) const { return RTLIL::IdString(*this).lt_by_name(RTLIL::IdString(rhs)); } - bool operator==(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) == rhs; } - bool operator!=(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) != rhs; } - bool operator<(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) < rhs; } - bool operator==(const std::string &rhs) const { return RTLIL::IdString(*this) == rhs; } - bool operator!=(const std::string &rhs) const { return RTLIL::IdString(*this) != rhs; } - bool operator==(const WireNameMasq &rhs) const { return RTLIL::IdString(*this) == RTLIL::IdString(rhs); } - bool operator!=(const WireNameMasq &rhs) const { return RTLIL::IdString(*this) != RTLIL::IdString(rhs); } - bool operator<(const WireNameMasq &rhs) const { return RTLIL::IdString(*this) < RTLIL::IdString(rhs); } - [[nodiscard]] Hasher hash_into(Hasher h) const { return RTLIL::IdString(*this).hash_into(h); } }; -inline bool operator==(RTLIL::IdString lhs, const RTLIL::WireNameMasq &rhs) { return lhs == RTLIL::IdString(rhs); } -inline bool operator!=(RTLIL::IdString lhs, const RTLIL::WireNameMasq &rhs) { return lhs != RTLIL::IdString(rhs); } // Read-only masquerade for Cell::name. Same contract as WireNameMasq. -struct RTLIL::CellNameMasq { +struct RTLIL::CellNameMasq : RTLIL::NameMasqBase { CellNameMasq() = default; CellNameMasq(const CellNameMasq &) = delete; CellNameMasq(CellNameMasq &&) = delete; CellNameMasq &operator=(const CellNameMasq &) = delete; CellNameMasq &operator=(CellNameMasq &&) = delete; - operator RTLIL::IdString() const; - // Tagged name handle (Twine::Null when unnamed). TwineRef ref() const; - // Escaped form ('\'-prefixed when public) / bare content. std::string escaped() const; std::string unescaped() const; - bool isPublic() const { return twine_is_public(ref()); } - bool empty() const { return RTLIL::IdString(*this).empty(); } - std::string str() const { return escaped(); } - const char *c_str() const { return RTLIL::IdString(*this).c_str(); } - std::string unescape() const { return unescaped(); } - bool begins_with(const char *s) const { return RTLIL::IdString(*this).begins_with(s); } - bool ends_with(const char *s) const { return RTLIL::IdString(*this).ends_with(s); } - template bool in(Ts &&...args) const { - return RTLIL::IdString(*this).in(std::forward(args)...); - } - std::string substr(size_t pos = 0, size_t len = std::string::npos) const { - return RTLIL::IdString(*this).substr(pos, len); - } - size_t size() const { return RTLIL::IdString(*this).size(); } - bool contains(const char *p) const { return RTLIL::IdString(*this).contains(p); } - char operator[](int n) const { return RTLIL::IdString(*this).str()[n]; } - bool lt_by_name(RTLIL::IdString rhs) const { return RTLIL::IdString(*this).lt_by_name(rhs); } - bool lt_by_name(const CellNameMasq &rhs) const { return RTLIL::IdString(*this).lt_by_name(RTLIL::IdString(rhs)); } - bool operator==(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) == rhs; } - bool operator!=(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) != rhs; } - bool operator<(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) < rhs; } - bool operator==(const std::string &rhs) const { return RTLIL::IdString(*this) == rhs; } - bool operator!=(const std::string &rhs) const { return RTLIL::IdString(*this) != rhs; } - bool operator==(const CellNameMasq &rhs) const { return RTLIL::IdString(*this) == RTLIL::IdString(rhs); } - bool operator!=(const CellNameMasq &rhs) const { return RTLIL::IdString(*this) != RTLIL::IdString(rhs); } - bool operator<(const CellNameMasq &rhs) const { return RTLIL::IdString(*this) < RTLIL::IdString(rhs); } - [[nodiscard]] Hasher hash_into(Hasher h) const { return RTLIL::IdString(*this).hash_into(h); } }; -inline bool operator==(RTLIL::IdString lhs, const RTLIL::CellNameMasq &rhs) { return lhs == RTLIL::IdString(rhs); } -inline bool operator!=(RTLIL::IdString lhs, const RTLIL::CellNameMasq &rhs) { return lhs != RTLIL::IdString(rhs); } // Read-only masquerade for Cell::type. Backed by Cell::type_impl. // Write the type via cell->type_impl directly. @@ -2935,12 +2936,12 @@ public: RTLIL::SigBit Oai4Gate (Twine &&name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, TwineRef src = Twine::Null); }; -// Zero-size masquerade for Module::name. Reads/writes route through -// module->design->obj_name(this) / obj_set_name. Shadows NamedObject::name +// Zero-size masquerade for Module::name. Same contract as WireNameMasq, +// plus a write path via operator=(IdString). Shadows NamedObject::name // at the Module-instance scope; static_cast(module)->name // still hits the (now-unused) inline base field. Writing requires // module->design to be set first. -struct RTLIL::ModuleNameMasq { +struct RTLIL::ModuleNameMasq : RTLIL::NameMasqBase { // Copying/moving is forbidden: a ModuleNameMasq derives its identity from // `this` via offsetof(Module, name), so any instance not embedded in a // Module would resolve to garbage. All conversions go through @@ -2948,35 +2949,15 @@ struct RTLIL::ModuleNameMasq { ModuleNameMasq() = default; ModuleNameMasq(const ModuleNameMasq&) = delete; ModuleNameMasq(ModuleNameMasq&&) = delete; - operator RTLIL::IdString() const; operator TwineRef() const; ModuleNameMasq& operator=(RTLIL::IdString id); // Without this, `new_mod->name = src_mod->name` invokes the implicit // copy-assign (no-op) instead of operator=(IdString), so the meta // never gets written. ModuleNameMasq& operator=(const ModuleNameMasq& other) { return *this = RTLIL::IdString(other); } - bool empty() const { return RTLIL::IdString(*this).empty(); } - std::string str() const { return RTLIL::IdString(*this).str(); } - const char* c_str() const { return RTLIL::IdString(*this).c_str(); } - bool isPublic() const { return RTLIL::IdString(*this).isPublic(); } - std::string unescape() const { return RTLIL::IdString(*this).unescape(); } - bool begins_with(const char* s) const { return RTLIL::IdString(*this).begins_with(s); } - bool ends_with(const char* s) const { return RTLIL::IdString(*this).ends_with(s); } - template bool in(Ts&&... args) const { - return RTLIL::IdString(*this).in(std::forward(args)...); - } - std::string substr(size_t pos = 0, size_t len = std::string::npos) const { - return RTLIL::IdString(*this).substr(pos, len); - } - size_t size() const { return RTLIL::IdString(*this).size(); } - bool contains(const char *p) const { return RTLIL::IdString(*this).contains(p); } - bool operator==(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) == rhs; } - bool operator!=(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) != rhs; } - bool operator< (RTLIL::IdString rhs) const { return RTLIL::IdString(*this) < rhs; } - bool operator==(const std::string &rhs) const { return RTLIL::IdString(*this) == rhs; } - bool operator!=(const std::string &rhs) const { return RTLIL::IdString(*this) != rhs; } - bool operator==(const ModuleNameMasq &rhs) const { return RTLIL::IdString(*this) == RTLIL::IdString(rhs); } - bool operator!=(const ModuleNameMasq &rhs) const { return RTLIL::IdString(*this) != RTLIL::IdString(rhs); } + TwineRef ref() const; + std::string escaped() const; + std::string unescaped() const; }; struct RTLIL::Module : public RTLIL::AttrObject, public CellAdderMixin @@ -3378,13 +3359,6 @@ inline std::string RTLIL::WireNameMasq::unescaped() const { return w->module->design->twines.unescaped_str(id); } -inline RTLIL::WireNameMasq::operator RTLIL::IdString() const { - std::string s = escaped(); - if (s.empty()) - return RTLIL::IdString{}; - return RTLIL::IdString(s); -} - inline TwineRef RTLIL::CellNameMasq::ref() const { const RTLIL::Cell *c = reinterpret_cast( reinterpret_cast(this) - offsetof(RTLIL::Cell, name)); @@ -3411,13 +3385,6 @@ inline std::string RTLIL::CellNameMasq::unescaped() const { return c->module->design->twines.unescaped_str(id); } -inline RTLIL::CellNameMasq::operator RTLIL::IdString() const { - std::string s = escaped(); - if (s.empty()) - return RTLIL::IdString{}; - return RTLIL::IdString(s); -} - inline TwineRef RTLIL::CellTypeMasq::ref() const { const RTLIL::Cell *c = reinterpret_cast( reinterpret_cast(this) - offsetof(RTLIL::Cell, type)); @@ -3456,13 +3423,33 @@ inline RTLIL::CellTypeMasq::operator RTLIL::IdString() const { return RTLIL::IdString(s); } -// inline RTLIL::ModuleNameMasq& RTLIL::ModuleNameMasq::operator=(RTLIL::IdString id) { -// RTLIL::Module *m = reinterpret_cast( -// reinterpret_cast(this) - offsetof(RTLIL::Module, name)); -// log_assert(m->design && "assignment to Module::name requires the module to be attached to a design"); -// m->design->obj_set_name(m, id); -// return *this; -// } +inline TwineRef RTLIL::ModuleNameMasq::ref() const { + const RTLIL::Module *m = reinterpret_cast( + reinterpret_cast(this) - offsetof(RTLIL::Module, name)); + if (!m->design || !m->meta_) + return Twine::Null; + return m->meta_->name; +} + +inline std::string RTLIL::ModuleNameMasq::escaped() const { + const RTLIL::Module *m = reinterpret_cast( + reinterpret_cast(this) - offsetof(RTLIL::Module, name)); + TwineRef id = ref(); + if (id == Twine::Null) + return std::string(); + return m->design->twines.str(id); +} + +inline std::string RTLIL::ModuleNameMasq::unescaped() const { + const RTLIL::Module *m = reinterpret_cast( + reinterpret_cast(this) - offsetof(RTLIL::Module, name)); + TwineRef id = ref(); + if (id == Twine::Null) + return std::string(); + return m->design->twines.unescaped_str(id); +} + +inline RTLIL::ModuleNameMasq::operator TwineRef() const { return ref(); } YOSYS_NAMESPACE_END diff --git a/kernel/scopeinfo.cc b/kernel/scopeinfo.cc index 4557c8441..20cc9ea3a 100644 --- a/kernel/scopeinfo.cc +++ b/kernel/scopeinfo.cc @@ -100,13 +100,13 @@ static const char *attr_prefix(ScopeinfoAttrs attrs) bool scopeinfo_has_attribute(const RTLIL::Cell *scopeinfo, ScopeinfoAttrs attrs, RTLIL::IdString id) { log_assert(scopeinfo->type == TW($scopeinfo)); - return scopeinfo->has_attribute(attr_prefix(attrs) + design->twines.unescaped_str(id)); + return scopeinfo->has_attribute(attr_prefix(attrs) + RTLIL::unescape_id(id)); } RTLIL::Const scopeinfo_get_attribute(const RTLIL::Cell *scopeinfo, ScopeinfoAttrs attrs, RTLIL::IdString id) { log_assert(scopeinfo->type == TW($scopeinfo)); - auto found = scopeinfo->attributes.find(attr_prefix(attrs) + design->twines.unescaped_str(id)); + auto found = scopeinfo->attributes.find(attr_prefix(attrs) + RTLIL::unescape_id(id)); if (found == scopeinfo->attributes.end()) return RTLIL::Const(); return found->second; diff --git a/kernel/twine.h b/kernel/twine.h index 48f2b17ff..362c93ad6 100644 --- a/kernel/twine.h +++ b/kernel/twine.h @@ -196,6 +196,8 @@ struct TwinePool { os << ", tail: \"" << val.tail << "\")"; } }, twine.data); + if (ref.is_public()) + os << " pub"; } void print(TwineRef ref, std::ostream& os = std::cout) const { if (ref == Twine::Null) @@ -302,29 +304,22 @@ struct TwinePool { // and concat names inherit the prefix/first-child handle's publicity. TwineRef add(Twine t) { bool is_public = false; - if (auto *leaf = std::get_if(&t.data)) { - assert(!leaf->empty()); - if ((*leaf)[0] == '\\') { - is_public = true; - leaf->erase(0, 1); - assert(!leaf->empty()); - } else { - assert((*leaf)[0] == '$'); - } - } else if (auto *sfx = std::get_if(&t.data)) { + if (auto *sfx = std::get_if(&t.data)) { is_public = twine_is_public(sfx->prefix); - } else if (auto *children = std::get_if>(&t.data)) { - is_public = false; } return twine_tag(add_inner(std::move(t)), is_public); } TwineRef add(std::string&& s) { - if (s.size()) { + if (s.size() > 1) { if (s[0] == '\\') return twine_tag(add(Twine{s.substr(1)}), true); + else if (s[0] == '$') + return twine_tag(add(Twine{std::move(s)}), false); else return twine_tag(add(Twine{std::move(s)}), true); + } else if (s.size() > 0) { + return twine_tag(add(Twine{std::move(s)}), true); } else { return Twine::Null; } diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index ea6772e07..f802c31ea 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -529,7 +529,7 @@ struct CheckPass : public Pass { driver_src = stringf(" source: %s", src_attr); } - message += stringf(" cell %s (%s)%s\n", driver, design->twines.unescaped_str(driver->type), driver_src); + message += stringf(" cell %s (%s)%s\n", driver, design->twines.unescaped_str(driver->type.ref()), driver_src); if (!coarsened_cells.count(driver)) { MatchingEdgePrinter printer(message, sigmap, prev, bit); diff --git a/passes/cmds/edgetypes.cc b/passes/cmds/edgetypes.cc index 1fbd07b45..c29942d50 100644 --- a/passes/cmds/edgetypes.cc +++ b/passes/cmds/edgetypes.cc @@ -92,12 +92,12 @@ struct EdgetypePass : public Pass { auto sink_bit_index = std::get<2>(sink); string source_str = multibit_ports.count(std::pair(source_cell_type, source_port_name)) ? - stringf("%s.%s[%d]", design->twines.unescaped_str(source_cell_type), module->design->twines.str(source_port_name).c_str(), source_bit_index) : - stringf("%s.%s", design->twines.unescaped_str(source_cell_type), module->design->twines.str(source_port_name).c_str()); + stringf("%s.%s[%d]", log_id(source_cell_type), module->design->twines.str(source_port_name).c_str(), source_bit_index) : + stringf("%s.%s", log_id(source_cell_type), module->design->twines.str(source_port_name).c_str()); string sink_str = multibit_ports.count(std::pair(sink_cell_type, sink_port_name)) ? - stringf("%s.%s[%d]", design->twines.unescaped_str(sink_cell_type), module->design->twines.str(sink_port_name).c_str(), sink_bit_index) : - stringf("%s.%s", design->twines.unescaped_str(sink_cell_type), module->design->twines.str(sink_port_name).c_str()); + stringf("%s.%s[%d]", log_id(sink_cell_type), module->design->twines.str(sink_port_name).c_str(), sink_bit_index) : + stringf("%s.%s", log_id(sink_cell_type), module->design->twines.str(sink_port_name).c_str()); edge_cache.insert(source_str + " " + sink_str); } diff --git a/passes/cmds/linecoverage.cc b/passes/cmds/linecoverage.cc index 6ff51b67e..b50c77666 100644 --- a/passes/cmds/linecoverage.cc +++ b/passes/cmds/linecoverage.cc @@ -95,7 +95,7 @@ struct CoveragePass : public Pass { { log_debug("Module %s:\n", module); for (auto wire: module->wires()) { - log_debug("%s\t%s\t%s\n", module->selected(wire) ? "*" : " ", wire->get_src_attribute(), design->twines.unescaped_str(wire->name)); + log_debug("%s\t%s\t%s\n", module->selected(wire) ? "*" : " ", wire->get_src_attribute(), design->twines.unescaped_str(wire->name.ref())); for (auto src: design->src_leaves(wire)) { auto filename = extract_src_filename(src); if (filename.empty()) continue; diff --git a/passes/cmds/portarcs.cc b/passes/cmds/portarcs.cc index cc56cf7d9..1ee6d8ba2 100644 --- a/passes/cmds/portarcs.cc +++ b/passes/cmds/portarcs.cc @@ -126,7 +126,7 @@ struct PortarcsPass : Pass { for (auto cell : m->cells()) // Ignore all bufnorm helper cells if (!cell->type.in(TW($buf), TW($input_port), TW($output_port), TW($public), TW($connect), TW($tribuf))) { - auto tdata = tinfo.find(cell->type); + auto tdata = tinfo.find(cell->type.ref()); if (tdata == tinfo.end()) log_cmd_error("Missing timing data for module '%s'.\n", cell->type.unescaped()); for (auto [edge, delay] : tdata->second.comb) { @@ -174,7 +174,7 @@ struct PortarcsPass : Pass { if (!bit.wire->port_input) { auto cell = bit.wire->driverCell(); - auto tdata = tinfo.find(cell->type); + auto tdata = tinfo.find(cell->type.ref()); log_assert(tdata != tinfo.end()); for (auto [edge, delay] : tdata->second.comb) { auto from = edge.first.get_connection(cell); @@ -224,7 +224,7 @@ struct PortarcsPass : Pass { p[j] = -1; auto cell = ordering[i].wire->driverCell(); - auto tdata = tinfo.find(cell->type); + auto tdata = tinfo.find(cell->type.ref()); log_assert(tdata != tinfo.end()); for (auto [edge, delay] : tdata->second.comb) { auto from = edge.first.get_connection(cell); diff --git a/passes/cmds/printattrs.cc b/passes/cmds/printattrs.cc index b0f3c4841..f0f0c8b19 100644 --- a/passes/cmds/printattrs.cc +++ b/passes/cmds/printattrs.cc @@ -47,9 +47,9 @@ struct PrintAttrsPass : public Pass { static void log_const(RTLIL::IdString s, const RTLIL::Const &x, const unsigned int indent) { if (x.flags & RTLIL::CONST_FLAG_STRING) - log("%s(* %s=\"%s\" *)\n", get_indent_str(indent), design->twines.unescaped_str(s), x.decode_string()); + log("%s(* %s=\"%s\" *)\n", get_indent_str(indent), log_id(s), x.decode_string()); else if (x.flags == RTLIL::CONST_FLAG_NONE || x.flags == RTLIL::CONST_FLAG_SIGNED) - log("%s(* %s=%s *)\n", get_indent_str(indent), design->twines.unescaped_str(s), x.as_string()); + log("%s(* %s=%s *)\n", get_indent_str(indent), log_id(s), x.as_string()); else log_assert(x.flags & RTLIL::CONST_FLAG_STRING || x.flags == RTLIL::CONST_FLAG_NONE); //intended to fail } @@ -88,7 +88,7 @@ struct PrintAttrsPass : public Pass { } for (auto wire : mod->selected_wires()) { - log("%s%s\n", get_indent_str(indent), design->twines.unescaped_str(wire->name)); + log("%s%s\n", get_indent_str(indent), design->twines.unescaped_str(wire->name.ref())); indent += 2; log_src(design, wire, indent); for (auto &it : wire->attributes) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 424999423..c89b204cc 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -1845,7 +1845,7 @@ struct LsPass : public Pass { log("\n%d %s:\n", int(matches.size()), "modules"); std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str()); for (auto id : matches) - log(" %s%s\n", design->twines.unescaped_str(id), design->selected_whole_module(design->module(id)) ? "" : "*"); + log(" %s%s\n", log_id(id), design->selected_whole_module(design->module(id)) ? "" : "*"); } } else diff --git a/passes/cmds/sta.cc b/passes/cmds/sta.cc index 663f69dd1..d664e518f 100644 --- a/passes/cmds/sta.cc +++ b/passes/cmds/sta.cc @@ -206,7 +206,7 @@ struct StaWorker log("Latest arrival time in '%s' is %d:\n", module, maxarrival); auto it = endpoints.find(maxbit); if (it != endpoints.end() && it->second.sink) - log(" %6d %s (%s.%s)\n", maxarrival, it->second.sink, design->twines.unescaped_str(it->second.sink->type), design->twines.unescaped_str(it->second.port)); + log(" %6d %s (%s.%s)\n", maxarrival, it->second.sink, design->twines.unescaped_str(it->second.sink->type.ref()), design->twines.unescaped_str(it->second.port)); else { log(" %6d (%s)\n", maxarrival, b.wire->port_output ? "" : ""); if (!b.wire->port_output) @@ -217,7 +217,7 @@ struct StaWorker int arrival = b.wire->get_intvec_attribute(ID::sta_arrival)[b.offset]; if (jt->second.driver) { log(" %s\n", log_signal(b)); - log(" %6d %s (%s.%s->%s)\n", arrival, jt->second.driver, design->twines.unescaped_str(jt->second.driver->type), design->twines.unescaped_str(jt->second.src_port), design->twines.unescaped_str(jt->second.dst_port)); + log(" %6d %s (%s.%s->%s)\n", arrival, jt->second.driver, design->twines.unescaped_str(jt->second.driver->type.ref()), design->twines.unescaped_str(jt->second.src_port), design->twines.unescaped_str(jt->second.dst_port)); } else if (b.wire->port_input) log(" %6d %s (%s)\n", arrival, log_signal(b), ""); diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index ab2f97be7..09b8fd25f 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -23,6 +23,7 @@ #include "kernel/cost.h" #include "kernel/gzip.h" #include "kernel/log_help.h" +#include "kernel/rtlil.h" #include "kernel/yosys.h" #include "libs/json11/json11.hpp" #include "passes/techmap/libparse.h" @@ -59,18 +60,19 @@ struct statdata_t { double local_sequential_area = 0; double submodule_area = 0; int num_submodules = 0; - std::map num_submodules_by_type; - std::map submodules_area_by_type; + std::map num_submodules_by_type; + std::map submodules_area_by_type; - std::map local_num_cells_by_type; - std::map local_area_cells_by_type; - std::map local_seq_area_cells_by_type; + std::map local_num_cells_by_type; + std::map local_area_cells_by_type; + std::map local_seq_area_cells_by_type; string tech; - std::map num_cells_by_type; - std::map area_cells_by_type; - std::map seq_area_cells_by_type; - std::set unknown_cell_area; + std::map num_cells_by_type_raw; + std::map num_cells_by_type; + std::map area_cells_by_type; + std::map seq_area_cells_by_type; + std::set unknown_cell_area; statdata_t operator+(const statdata_t &other) const { @@ -80,6 +82,8 @@ struct statdata_t { #undef X for (auto &it : num_cells_by_type) sum.num_cells_by_type[it.first] += it.second; + for (auto &it : num_cells_by_type_raw) + sum.num_cells_by_type_raw[it.first] += it.second; return sum; } statdata_t operator*(unsigned int other) const @@ -88,6 +92,8 @@ struct statdata_t { #define X(_name) sum._name *= other; STAT_NUMERIC_MEMBERS #undef X + for (auto &it : sum.num_cells_by_type_raw) + it.second *= other; for (auto &it : sum.num_cells_by_type) it.second *= other; return sum; @@ -103,6 +109,12 @@ struct statdata_t { else num_cells_by_type[it.first] = it.second; } + for (auto &it : other.num_cells_by_type_raw) { + if (num_cells_by_type_raw.count(it.first)) + num_cells_by_type_raw[it.first] += it.second; + else + num_cells_by_type_raw[it.first] = it.second; + } for (auto &it : other.submodules_area_by_type) { if (submodules_area_by_type.count(it.first)) submodules_area_by_type[it.first] += it.second; @@ -141,7 +153,7 @@ struct statdata_t { } } - statdata_t(RTLIL::Design *design, const RTLIL::Module *mod, bool width_mode, dict &cell_area, string techname) + statdata_t(RTLIL::Design *design, const RTLIL::Module *mod, bool width_mode, dict &cell_area, string techname) { tech = techname; @@ -183,7 +195,7 @@ struct statdata_t { local_num_memory_bits += it.second->width * it.second->size; } for (auto cell : mod->selected_cells()) { - TwineRef cell_type = cell->type_impl; + IdString cell_type = cell->type; if (width_mode) { if (cell_type.in(TW($not), TW($pos), TW($neg), TW($logic_not), TW($logic_and), TW($logic_or), TW($reduce_and), TW($reduce_or), TW($reduce_xor), TW($reduce_xnor), TW($reduce_bool), TW($lut), TW($and), TW($or), @@ -193,25 +205,25 @@ struct statdata_t { int width_a = cell->hasPort(TW::A) ? GetSize(cell->getPort(TW::A)) : 0; int width_b = cell->hasPort(TW::B) ? GetSize(cell->getPort(TW::B)) : 0; int width_y = cell->hasPort(TW::Y) ? GetSize(cell->getPort(TW::Y)) : 0; - cell_type = design->twines.add(Twine{stringf("%s_%d", cell_type, max({width_a, width_b, width_y}))}); + cell_type = stringf("%s_%d", cell_type, max({width_a, width_b, width_y})); } else if (cell_type.in(TW($mux))) - cell_type = design->twines.add(Twine{stringf("%s_%d", cell_type, GetSize(cell->getPort(TW::Y)))}); + cell_type = stringf("%s_%d", cell_type, GetSize(cell->getPort(TW::Y))); else if (cell_type.in(TW($bmux), TW($pmux))) cell_type = - design->twines.add(Twine{stringf("%s_%d_%d", cell_type, GetSize(cell->getPort(TW::Y)), GetSize(cell->getPort(TW::S)))}); + stringf("%s_%d_%d", cell_type, GetSize(cell->getPort(TW::Y)), GetSize(cell->getPort(TW::S))); else if (cell_type == TW($demux)) cell_type = - design->twines.add(Twine{stringf("%s_%d_%d", cell_type, GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::S)))}); + stringf("%s_%d_%d", cell_type, GetSize(cell->getPort(TW::A)), GetSize(cell->getPort(TW::S))); else if (cell_type.in(TW($sr), TW($ff), TW($dff), TW($dffe), TW($dffsr), TW($dffsre), TW($adff), TW($adffe), TW($sdff), TW($sdffe), TW($sdffce), TW($aldff), TW($aldffe), TW($dlatch), TW($adlatch), TW($dlatchsr))) - cell_type = design->twines.add(Twine{stringf("%s_%d", cell_type, GetSize(cell->getPort(TW::Q)))}); + cell_type = stringf("%s_%d", cell_type, GetSize(cell->getPort(TW::Q))); } if (!cell_area.empty()) { // check if cell_area provides a area calculator - if (cell_area.count(cell->type_impl)) { - cell_area_t cell_data = cell_area.at(cell->type_impl); + if (cell_area.count(cell->type)) { + cell_area_t cell_data = cell_area.at(cell->type); if (cell_data.single_parameter_area.size() > 0) { // assume that we just take the max of the A,B,Y ports @@ -311,6 +323,7 @@ struct statdata_t { } else { unknown_cell_area.insert(cell_type); num_cells++; + num_cells_by_type_raw[cell->type_impl]++; num_cells_by_type[cell_type]++; local_num_cells++; local_num_cells_by_type[cell_type]++; @@ -321,6 +334,7 @@ struct statdata_t { } } else { num_cells++; + num_cells_by_type_raw[cell->type_impl]++; num_cells_by_type[cell_type]++; area_cells_by_type[cell_type] = 0; seq_area_cells_by_type[cell_type] = 0; @@ -341,12 +355,12 @@ struct statdata_t { unsigned int estimate_xilinx_lc() { - unsigned int lut6_cnt = num_cells_by_type[TW::LUT6]; - unsigned int lut5_cnt = num_cells_by_type[TW::LUT5]; - unsigned int lut4_cnt = num_cells_by_type[TW::LUT4]; - unsigned int lut3_cnt = num_cells_by_type[TW::LUT3]; - unsigned int lut2_cnt = num_cells_by_type[TW::LUT2]; - unsigned int lut1_cnt = num_cells_by_type[TW::LUT1]; + unsigned int lut6_cnt = num_cells_by_type[ID::LUT6]; + unsigned int lut5_cnt = num_cells_by_type[ID::LUT5]; + unsigned int lut4_cnt = num_cells_by_type[ID::LUT4]; + unsigned int lut3_cnt = num_cells_by_type[ID::LUT3]; + unsigned int lut2_cnt = num_cells_by_type[ID::LUT2]; + unsigned int lut1_cnt = num_cells_by_type[ID::LUT1]; unsigned int lc_cnt = 0; lc_cnt += lut6_cnt; @@ -396,7 +410,7 @@ struct statdata_t { unsigned int tran_cnt = 0; auto &gate_costs = CellCosts::cmos_gate_cost(); - for (auto it : num_cells_by_type) { + for (auto it : num_cells_by_type_raw) { auto ctype = it.first; auto cnum = it.second; @@ -503,7 +517,7 @@ struct statdata_t { } } - void log_data(const TwinePool& twines, TwineRef mod_name, bool top_mod, bool print_area = true, bool print_hierarchical = true, bool print_global_only = false) + void log_data(TwineRef mod_name, bool top_mod, bool print_area = true, bool print_hierarchical = true, bool print_global_only = false) { print_log_header(print_area, print_hierarchical, print_global_only); @@ -521,7 +535,7 @@ struct statdata_t { print_log_line("cells", local_num_cells, local_area, num_cells, area, 0, print_area, print_hierarchical, print_global_only); for (auto &it : num_cells_by_type) if (it.second) { - auto name = twines.unescaped_str(it.first); + auto name = RTLIL::unescape_id(it.first); print_log_line(name, local_num_cells_by_type.count(it.first) ? local_num_cells_by_type.at(it.first) : 0, local_area_cells_by_type.count(it.first) ? local_area_cells_by_type.at(it.first) : 0, it.second, area_cells_by_type.at(it.first), 1, print_area, print_hierarchical, print_global_only); @@ -531,7 +545,7 @@ struct statdata_t { print_global_only); for (auto &it : num_submodules_by_type) if (it.second) - print_log_line(twines.unescaped_str(it.first), it.second, 0, it.second, + print_log_line(RTLIL::unescape_id(it.first), it.second, 0, it.second, submodules_area_by_type.count(it.first) ? submodules_area_by_type.at(it.first) : 0, 1, print_area, print_hierarchical, print_global_only); } @@ -580,7 +594,7 @@ struct statdata_t { count_local, area_local); } - void log_data_json(const TwinePool& twines, const char *mod_name, bool first_module, bool hierarchical = false, bool global_only = false) + void log_data_json(const char *mod_name, bool first_module, bool hierarchical = false, bool global_only = false) { if (!first_module) log(",\n"); @@ -605,7 +619,7 @@ struct statdata_t { if (it.second) { if (!first_line) log(",\n"); - log(" %s: %s", json11::Json(twines.unescaped_str(it.first)).dump(), + log(" %s: %s", json11::Json(RTLIL::unescape_id(it.first)).dump(), json_line(local_num_cells_by_type.count(it.first) ? local_num_cells_by_type.at(it.first) : 0, local_area_cells_by_type.count(it.first) ? local_area_cells_by_type.at(it.first) : 0, it.second, area_cells_by_type.at(it.first)) @@ -619,7 +633,7 @@ struct statdata_t { if (it.second) { if (!first_line) log(",\n"); - log(" %s: %s", json11::Json(twines.unescaped_str(it.first)).dump(), + log(" %s: %s", json11::Json(RTLIL::unescape_id(it.first)).dump(), json_line(0, 0, it.second, submodules_area_by_type.count(it.first) ? submodules_area_by_type.at(it.first) : 0) .c_str()); @@ -660,14 +674,14 @@ struct statdata_t { if (it.second) { if (!first_line) log(",\n"); - log(" %s: %u", json11::Json(twines.unescaped_str(it.first)).dump(), it.second); + log(" %s: %u", json11::Json(RTLIL::unescape_id(it.first)).dump(), it.second); first_line = false; } for (auto &it : num_submodules_by_type) if (it.second) { if (!first_line) log(",\n"); - log(" %s: %u", json11::Json(twines.unescaped_str(it.first)).dump(), it.second); + log(" %s: %u", json11::Json(RTLIL::unescape_id(it.first)).dump(), it.second); first_line = false; } log("\n"); @@ -695,14 +709,14 @@ struct statdata_t { if (it.second) { if (!first_line) log(",\n"); - log(" %s: %u", json11::Json(twines.unescaped_str(it.first)).dump(), it.second); + log(" %s: %u", json11::Json(RTLIL::unescape_id(it.first)).dump(), it.second); first_line = false; } for (auto &it : num_submodules_by_type) if (it.second) { if (!first_line) log(",\n"); - log(" %s: %u", json11::Json(twines.unescaped_str(it.first)).dump(), it.second); + log(" %s: %u", json11::Json(RTLIL::unescape_id(it.first)).dump(), it.second); first_line = false; } log("\n"); @@ -724,7 +738,7 @@ struct statdata_t { } }; -statdata_t hierarchy_worker(const TwinePool& twines, std::map &mod_stat, TwineRef mod, int level, bool quiet = false, bool has_area = true, +statdata_t hierarchy_worker(const TwinePool& twines, std::map &mod_stat, IdString mod, int level, bool quiet = false, bool has_area = true, bool hierarchy_mode = true) { statdata_t mod_data = mod_stat.at(mod); @@ -732,7 +746,7 @@ statdata_t hierarchy_worker(const TwinePool& twines, std::map 0) { if (!quiet) - mod_data.print_log_line(twines.unescaped_str(it.first), mod_stat.at(it.first).local_num_cells, + mod_data.print_log_line(RTLIL::unescape_id(it.first), mod_stat.at(it.first).local_num_cells, mod_stat.at(it.first).local_area, mod_stat.at(it.first).num_cells, mod_stat.at(it.first).area, level, has_area, hierarchy_mode); hierarchy_worker(twines, mod_stat, it.first, level + 1, quiet, has_area, hierarchy_mode) * it.second; @@ -742,50 +756,50 @@ statdata_t hierarchy_worker(const TwinePool& twines, std::map &mod_stat, - bool width_mode, dict &cell_area, string techname) +statdata_t hierarchy_builder(RTLIL::Design *design, const RTLIL::Module *top_mod, std::map &mod_stat, + bool width_mode, dict &cell_area, string techname) { if (top_mod == nullptr) top_mod = design->top_module(); statdata_t mod_data(design, top_mod, width_mode, cell_area, techname); for (auto cell : top_mod->selected_cells()) { - if (cell_area.count(cell->type_impl) == 0) { + if (cell_area.count(cell->type) == 0) { if (design->has(cell->type_impl)) { if (!(design->module(cell->type)->attributes.count(ID::blackbox))) { // deal with modules mod_data.add( hierarchy_builder(design, design->module(cell->type), mod_stat, width_mode, cell_area, techname)); - mod_data.num_submodules_by_type[cell->type_impl]++; - mod_data.submodules_area_by_type[cell->type_impl] += mod_stat.at(cell->type_impl).area; - mod_data.submodule_area += mod_stat.at(cell->type_impl).area; + mod_data.num_submodules_by_type[cell->type]++; + mod_data.submodules_area_by_type[cell->type] += mod_stat.at(cell->type).area; + mod_data.submodule_area += mod_stat.at(cell->type).area; mod_data.num_submodules++; - mod_data.unknown_cell_area.erase(cell->type_impl); + mod_data.unknown_cell_area.erase(cell->type); mod_data.num_cells -= - (mod_data.num_cells_by_type.count(cell->type_impl) != 0) ? mod_data.num_cells_by_type.at(cell->type_impl) : 0; - mod_data.num_cells_by_type.erase(cell->type_impl); - mod_data.local_num_cells -= (mod_data.local_num_cells_by_type.count(cell->type_impl) != 0) - ? mod_data.local_num_cells_by_type.at(cell->type_impl) + (mod_data.num_cells_by_type.count(cell->type) != 0) ? mod_data.num_cells_by_type.at(cell->type) : 0; + mod_data.num_cells_by_type.erase(cell->type); + mod_data.local_num_cells -= (mod_data.local_num_cells_by_type.count(cell->type) != 0) + ? mod_data.local_num_cells_by_type.at(cell->type) : 0; - mod_data.local_num_cells_by_type.erase(cell->type_impl); - mod_data.local_area_cells_by_type.erase(cell->type_impl); + mod_data.local_num_cells_by_type.erase(cell->type); + mod_data.local_area_cells_by_type.erase(cell->type); } else { // deal with blackbox cells if (design->module(cell->type)->attributes.count(ID::area) && design->module(cell->type)->attributes.at(ID::area).size() == 0) { - mod_data.num_submodules_by_type[cell->type_impl]++; + mod_data.num_submodules_by_type[cell->type]++; mod_data.num_submodules++; - mod_data.submodules_area_by_type[cell->type_impl] += - double(design->module(cell->type_impl)->attributes.at(ID::area).as_int()); - mod_data.area += double(design->module(cell->type_impl)->attributes.at(ID::area).as_int()); - mod_data.unknown_cell_area.erase(cell->type_impl); + mod_data.submodules_area_by_type[cell->type] += + double(design->module(cell->type)->attributes.at(ID::area).as_int()); + mod_data.area += double(design->module(cell->type)->attributes.at(ID::area).as_int()); + mod_data.unknown_cell_area.erase(cell->type); mod_data.num_cells -= - (mod_data.num_cells_by_type.count(cell->type_impl) != 0) ? mod_data.num_cells_by_type.at(cell->type_impl) : 0; - mod_data.num_cells_by_type.erase(cell->type_impl); - mod_data.local_num_cells -= (mod_data.local_num_cells_by_type.count(cell->type_impl) != 0) - ? mod_data.local_num_cells_by_type.at(cell->type_impl) + (mod_data.num_cells_by_type.count(cell->type) != 0) ? mod_data.num_cells_by_type.at(cell->type) : 0; + mod_data.num_cells_by_type.erase(cell->type); + mod_data.local_num_cells -= (mod_data.local_num_cells_by_type.count(cell->type) != 0) + ? mod_data.local_num_cells_by_type.at(cell->type) : 0; - mod_data.local_num_cells_by_type.erase(cell->type_impl); - mod_data.local_area_cells_by_type.erase(cell->type_impl); + mod_data.local_num_cells_by_type.erase(cell->type); + mod_data.local_area_cells_by_type.erase(cell->type); } } } @@ -795,7 +809,7 @@ statdata_t hierarchy_builder(RTLIL::Design *design, const RTLIL::Module *top_mod return mod_data; } -void read_liberty_cellarea(TwinePool& twines, dict &cell_area, string liberty_file) +void read_liberty_cellarea(dict &cell_area, string liberty_file) { std::istream *f = uncompressed(liberty_file.c_str()); yosys_input_files.insert(liberty_file); @@ -872,7 +886,8 @@ void read_liberty_cellarea(TwinePool& twines, dict &cell_ if (ar != nullptr && !ar->value.empty()) { string prefix = cell->args[0].substr(0, 1) == "$" ? "" : "\\"; - TwineRef t = twines.add(Twine{prefix + cell->args[0]}); + // TwineRef t = twines.add(Twine{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, port_names}; } @@ -926,8 +941,8 @@ struct StatPass : public Pass { { bool width_mode = false, json_mode = false, hierarchy_mode = false; RTLIL::Module *top_mod = nullptr; - std::map mod_stat; - dict cell_area; + std::map mod_stat; + dict cell_area; string techname; size_t argidx; @@ -939,7 +954,7 @@ struct StatPass : public Pass { if (args[argidx] == "-liberty" && argidx + 1 < args.size()) { string liberty_file = args[++argidx]; rewrite_filename(liberty_file); - read_liberty_cellarea(design->twines, cell_area, liberty_file); + read_liberty_cellarea(cell_area, liberty_file); continue; } if (args[argidx] == "-tech" && argidx + 1 < args.size()) { @@ -1004,13 +1019,13 @@ struct StatPass : public Pass { top_mod = mod; statdata_t data = mod_stat.at(mod->name); if (json_mode) { - data.log_data_json(design->twines, mod->name.c_str(), first_module, hierarchy_mode); + data.log_data_json(mod->name.c_str(), first_module, hierarchy_mode); first_module = false; } else { log("\n"); log("=== %s%s ===\n", design->twines.unescaped_str(mod->name), mod->is_selected_whole() ? "" : " (partially selected)"); log("\n"); - data.log_data(design->twines, mod->name, false, has_area, hierarchy_mode); + data.log_data(mod->name, false, has_area, hierarchy_mode); } } @@ -1033,10 +1048,10 @@ struct StatPass : public Pass { statdata_t data = hierarchy_worker(design->twines, mod_stat, top_mod->name, 0, /*quiet=*/json_mode, has_area, hierarchy_mode); if (json_mode) - data.log_data_json(design->twines, "design", true, hierarchy_mode, true); + data.log_data_json("design", true, hierarchy_mode, true); else if (GetSize(mod_stat) > 1) { log("\n"); - data.log_data(design->twines, top_mod->name, true, has_area, hierarchy_mode, true); + data.log_data(top_mod->name, true, has_area, hierarchy_mode, true); } design->scratchpad_set_int("stat.num_wires", data.num_wires); diff --git a/passes/cmds/timeest.cc b/passes/cmds/timeest.cc index ad055ac16..fa984c489 100644 --- a/passes/cmds/timeest.cc +++ b/passes/cmds/timeest.cc @@ -116,7 +116,7 @@ struct EstimateSta { continue; } else { // find or build AIG model of combinational cell - auto fingerprint = std::make_pair(cell->type, cell->parameters); + auto fingerprint = std::make_pair(RTLIL::IdString(cell->type), cell->parameters); if (!aigs.count(fingerprint)) { aigs.emplace(fingerprint, Aig(cell)); if (aigs.at(fingerprint).name.empty()) { @@ -133,7 +133,7 @@ struct EstimateSta { // since we're now taking reference into `aigs`, we can no longer modify it // and thus have to fill `cell_aigs` in a separate loop for (auto cell : combinational) { - auto fingerprint = std::make_pair(cell->type, cell->parameters); + auto fingerprint = std::make_pair(RTLIL::IdString(cell->type), cell->parameters); cell_aigs.emplace(cell, &aigs.at(fingerprint)); } @@ -188,7 +188,7 @@ struct EstimateSta { assert(cell_aigs.count(cell)); Aig &aig = *cell_aigs.at(cell); for (auto &node : aig.nodes) { - if (!node.portname.empty()) { + if (!node.portname == TwineRef{}) { topo.edge( desc_sig(cell->getPort(node.portname)[node.portbit]), desc_aig(cell, node) @@ -235,7 +235,7 @@ struct EstimateSta { if (aig_node) { Cell *cell = std::get<1>(node); Aig &aig = *cell_aigs.at(cell); - if (!aig_node->portname.empty()) { + if (!aig_node->portname == TwineRef{}) { // for a cell port, copy `levels` value from port bit SigBit bit = cell->getPort(aig_node->portname)[aig_node->portbit]; levels[node] = levels[desc_sig(bit)]; @@ -294,7 +294,7 @@ struct EstimateSta { critical[node] = true; } - if (!aig_node->portname.empty()) { + if (!aig_node->portname == TwineRef{}) { SigBit bit = cell->getPort(aig_node->portname)[aig_node->portbit]; if (critical.count(node)) critical[desc_sig(bit)] = true; @@ -359,13 +359,13 @@ struct EstimateSta { for (auto wire : m->wires()) { if (bits_to_select.check_any(sigmap(wire))) - to_select.insert(wire->name); + { RTLIL::IdString wn = wire->name; to_select.insert(wn); } } if (select) { RTLIL::Selection sel(false); for (auto member : to_select) - sel.selected_members[m->name].insert(member); + sel.selected_members[m->meta_->name].insert(m->design->twines.add(Twine{member.str()})); m->design->selection_stack.back() = sel; m->design->selection_stack.back().optimize(m->design); } @@ -424,12 +424,12 @@ struct TimeestPass : Pass { std::optional clk; if (clk_domain_specified) { - if (!m->wire(RTLIL::escape_id(clk_name))) { + if (!m->wire(m->design->twines.lookup(RTLIL::escape_id(clk_name)))) { log_warning("No domain '%s' in module %s\n", clk_name.c_str(), m); continue; } - clk = SigBit(m->wire(RTLIL::escape_id(clk_name)), 0); + clk = SigBit(m->wire(m->design->twines.lookup(RTLIL::escape_id(clk_name))), 0); } EstimateSta sta(m, clk, /*top_port_endpoints=*/ !clk_domain_specified); diff --git a/passes/cmds/viz.cc b/passes/cmds/viz.cc index ccbe8ae42..4f2b887c0 100644 --- a/passes/cmds/viz.cc +++ b/passes/cmds/viz.cc @@ -718,7 +718,7 @@ struct VizWorker void write_dot(FILE *f) { - fprintf(f, "digraph \"%s\" {\n", design->twines.unescaped_str(module->name).c_str()); + fprintf(f, "digraph \"%s\" {\n", module->design->twines.unescaped_str(module->meta_->name).c_str()); fprintf(f, " rankdir = LR;\n"); dict>> extra_lines; @@ -782,7 +782,7 @@ struct VizWorker g->names().sort(); std::string label; // = stringf("vg=%d\\n", g->index); for (auto n : g->names()) - label = label + (label.empty() ? "" : "\\n") + design->twines.unescaped_str(n); + label = label + (label.empty() ? "" : "\\n") + log_id(n); fprintf(f, "\tn%d [shape=rectangle,label=\"%s\"];\n", g->index, label.c_str()); } else { std::string label = stringf("vg=%d | %d cells", g->index, GetSize(g->names())); diff --git a/passes/cmds/wrapcell.cc b/passes/cmds/wrapcell.cc index f53d5849f..0f066edff 100644 --- a/passes/cmds/wrapcell.cc +++ b/passes/cmds/wrapcell.cc @@ -86,20 +86,20 @@ std::optional format_with_params(std::string fmt, const dictgetPort(port).size()) return port; - else if (len == 1) - return stringf("%s[%d]", port, base); - else - return stringf("%s[%d:%d]", port, base + len - 1, base); + auto &pool = cell->module->design->twines; + if (len == 1) + return pool.add(Twine{stringf("%s[%d]", pool.str(port).c_str(), base)}); + return pool.add(Twine{stringf("%s[%d:%d]", pool.str(port).c_str(), base + len - 1, base)}); } SigSpec sample(Cell *cell) @@ -109,10 +109,12 @@ struct Chunk { }; // Joins contiguous runs of bits into a 'Chunk' -std::vector collect_chunks(std::vector> bits) +std::vector collect_chunks(std::vector> bits) { std::vector ret; - std::sort(bits.begin(), bits.end()); + std::sort(bits.begin(), bits.end(), [](const auto &a, const auto &b) { + return a.first.value < b.first.value || (a.first.value == b.first.value && a.second < b.second); + }); for (auto it = bits.begin(); it != bits.end();) { auto sep = it + 1; for (; sep != bits.end() && @@ -212,7 +214,7 @@ struct WrapcellPass : Pass { log_error("Non-internal cell type '%s' on cell '%s' in module '%s' unsupported\n", cell->type.unescaped(), cell, module); - std::vector> unused_outputs, used_outputs; + std::vector> unused_outputs, used_outputs; for (auto conn : cell->connections()) { if (ct.cell_output(cell->type_impl, conn.first)) for (int i = 0; i < conn.second.size(); i++) { @@ -227,7 +229,7 @@ struct WrapcellPass : Pass { if (!unused_outputs.empty()) { context.unused_outputs += "_unused"; for (auto chunk : collect_chunks(unused_outputs)) - context.unused_outputs += "_" + design->twines.unescaped_str(chunk.format(cell)); + context.unused_outputs += "_" + module->design->twines.unescaped_str(chunk.format(cell)); } std::optional unescaped_name = format_with_params(name_fmt, cell->parameters, context); @@ -239,8 +241,8 @@ struct WrapcellPass : Pass { if (d->module(name)) goto replace_cell; - subm = d->addModule(name); - subcell = subm->addCell("$1", cell->type); + subm = d->addModule(d->twines.add(Twine{name.str()})); + subcell = subm->addCell(Twine{"$1"}, TwineRef(cell->type)); for (auto conn : cell->connections()) { if (ct.cell_output(cell->type_impl, conn.first)) { // Insert marker bits as placehodlers which need to be replaced @@ -283,7 +285,7 @@ struct WrapcellPass : Pass { replace_cell: cell->parameters.clear(); - dict new_connections; + dict new_connections; for (auto conn : cell->connections()) if (!ct.cell_output(cell->type_impl, conn.first)) diff --git a/passes/cmds/xprop.cc b/passes/cmds/xprop.cc index 993fc39d0..98cf9f8c1 100644 --- a/passes/cmds/xprop.cc +++ b/passes/cmds/xprop.cc @@ -55,18 +55,18 @@ struct XpropWorker Module *module; void invert() { std::swap(is_0, is_1); } - void auto_0() { connect_0(module->Not(NEW_ID, module->Or(NEW_TWINE, is_1, is_x))); } - void auto_1() { connect_1(module->Not(NEW_ID, module->Or(NEW_TWINE, is_0, is_x))); } - void auto_x() { connect_x(module->Not(NEW_ID, module->Or(NEW_TWINE, is_0, is_1))); } + void auto_0() { connect_0(module->Not(NEW_TWINE, module->Or(NEW_TWINE, is_1, is_x))); } + void auto_1() { connect_1(module->Not(NEW_TWINE, module->Or(NEW_TWINE, is_0, is_x))); } + void auto_x() { connect_x(module->Not(NEW_TWINE, module->Or(NEW_TWINE, is_0, is_1))); } void connect_0(SigSpec sig) { module->connect(is_0, sig); } void connect_1(SigSpec sig) { module->connect(is_1, sig); } void connect_x(SigSpec sig) { module->connect(is_x, sig); } - void connect_1_under_x(SigSpec sig) { connect_1(module->And(NEW_ID, sig, module->Not(NEW_TWINE, is_x))); } - void connect_0_under_x(SigSpec sig) { connect_0(module->And(NEW_ID, sig, module->Not(NEW_TWINE, is_x))); } + void connect_1_under_x(SigSpec sig) { connect_1(module->And(NEW_TWINE, sig, module->Not(NEW_TWINE, is_x))); } + void connect_0_under_x(SigSpec sig) { connect_0(module->And(NEW_TWINE, sig, module->Not(NEW_TWINE, is_x))); } - void connect_x_under_0(SigSpec sig) { connect_x(module->And(NEW_ID, sig, module->Not(NEW_TWINE, is_0))); } + void connect_x_under_0(SigSpec sig) { connect_x(module->And(NEW_TWINE, sig, module->Not(NEW_TWINE, is_0))); } void connect_as_bool() { int width = GetSize(is_0); @@ -265,9 +265,9 @@ struct XpropWorker auto not_1 = module->Not(NEW_TWINE, result.is_1); auto not_x = module->Not(NEW_TWINE, result.is_x); auto valid = module->ReduceAnd(NEW_TWINE, { - module->Eq(NEW_ID, result.is_0, module->And(NEW_TWINE, not_1, not_x)), - module->Eq(NEW_ID, result.is_1, module->And(NEW_TWINE, not_0, not_x)), - module->Eq(NEW_ID, result.is_x, module->And(NEW_TWINE, not_0, not_1)), + module->Eq(NEW_TWINE, result.is_0, module->And(NEW_TWINE, not_1, not_x)), + module->Eq(NEW_TWINE, result.is_1, module->And(NEW_TWINE, not_0, not_x)), + module->Eq(NEW_TWINE, result.is_x, module->And(NEW_TWINE, not_0, not_1)), }); if (options.assert_encoding) module->addAssert(NEW_TWINE_SUFFIX("xprop_enc"), valid, State::S1); @@ -486,9 +486,9 @@ struct XpropWorker auto sig_a = cell->getPort(TW::A); auto sig_b = cell->getPort(TW::B); - RTLIL::IdString name(cell->name); + std::string name_str = module->design->twines.str(cell->name.ref()); module->remove(cell); - module->addXnor(name, sig_a, sig_b, sig_y); + module->addXnor(Twine{name_str}, sig_a, sig_b, sig_y); return; } @@ -497,13 +497,13 @@ struct XpropWorker auto sig_a = cell->getPort(TW::A); auto sig_b = cell->getPort(TW::B); - RTLIL::IdString name(cell->name); - auto type = cell->type; + std::string name_str = module->design->twines.str(cell->name.ref()); + TwineRef type = cell->type.ref(); module->remove(cell); if (type == TW($eqx)) - module->addEq(name, sig_a, sig_b, sig_y); + module->addEq(Twine{name_str}, sig_a, sig_b, sig_y); else - module->addNe(name, sig_a, sig_b, sig_y); + module->addNe(Twine{name_str}, sig_a, sig_b, sig_y); return; } @@ -664,7 +664,7 @@ struct XpropWorker auto delta = module->Xor(NEW_TWINE, enc_a.is_1, enc_b.is_1); auto xpos = module->Or(NEW_TWINE, enc_a.is_x, enc_b.is_x); - enc_y.connect_0(module->ReduceOr(NEW_ID, module->And(NEW_ID, delta, module->Not(NEW_TWINE, xpos)))); + enc_y.connect_0(module->ReduceOr(NEW_TWINE, module->And(NEW_TWINE, delta, module->Not(NEW_TWINE, xpos)))); enc_y.connect_x_under_0(module->ReduceOr(NEW_TWINE, xpos)); enc_y.auto_1(); module->remove(cell); @@ -751,7 +751,7 @@ struct XpropWorker auto all_x = module->ReduceOr(NEW_TWINE, { enc_s.is_x, - module->And(NEW_ID, enc_s.is_1, module->Sub(NEW_TWINE, enc_s.is_1, Const(1, width))) + module->And(NEW_TWINE, enc_s.is_1, module->Sub(NEW_TWINE, enc_s.is_1, Const(1, width))) }); auto selected = enc_a; @@ -787,7 +787,7 @@ struct XpropWorker SigSpec y_1 = module->addWire(NEW_TWINE, GetSize(sig_y)); SigSpec y_x = module->addWire(NEW_TWINE, GetSize(sig_y)); - auto encoded_type = cell->type == TW($shiftx) ? TW($shift) : cell->type; + TwineRef encoded_type = cell->type == TW($shiftx) ? TwineRef{TW($shift)} : cell->type.ref(); if (cell->type == TW($shiftx)) { std::swap(enc_a.is_0, enc_a.is_x); @@ -982,8 +982,8 @@ struct XpropWorker if (wire->port_input == wire->port_output) { log_warning("Port %s not an input or an output port which is not supported by xprop\n", wire); } else if ((options.split_inputs && !options.assume_def_inputs && wire->port_input) || (options.split_outputs && wire->port_output)) { - auto port_d = module->uniquify(stringf("%s_d", port)); - auto port_x = module->uniquify(stringf("%s_x", port)); + auto port_d = module->uniquify(Twine{module->design->twines.str(port) + "_d"}); + auto port_x = module->uniquify(Twine{module->design->twines.str(port) + "_x"}); auto wire_d = module->addWire(port_d, GetSize(wire)); auto wire_x = module->addWire(port_x, GetSize(wire)); @@ -1003,7 +1003,7 @@ struct XpropWorker if (options.split_public) { // Need to hide the original wire so split_public doesn't try to split it again - module->rename(wire, NEW_ID_SUFFIX(wire->name.c_str())); + module->rename(wire, module->design->twines.add(NEW_TWINE_SUFFIX(RTLIL::IdString(wire->name).c_str()))); } } else { auto enc = encoded(wire, true); @@ -1035,8 +1035,9 @@ struct XpropWorker continue; int index_d = 0; int index_x = 0; - auto name_d = module->uniquify(stringf("%s_d", wire->name), index_d); - auto name_x = module->uniquify(stringf("%s_x", wire->name), index_x); + std::string wname = module->design->twines.str(wire->name.ref()); + auto name_d = module->uniquify(Twine{wname + "_d"}, index_d); + auto name_x = module->uniquify(Twine{wname + "_x"}, index_x); auto hdlname = wire->get_hdlname_attribute(); @@ -1056,7 +1057,7 @@ struct XpropWorker module->connect(wire_d, enc.is_1); module->connect(wire_x, enc.is_x); - module->rename(wire, NEW_ID_SUFFIX(wire->name.c_str())); + module->rename(wire, module->design->twines.add(NEW_TWINE_SUFFIX(RTLIL::IdString(wire->name).c_str()))); } } @@ -1234,7 +1235,7 @@ struct XpropPass : public Pass { continue; if (wire->port_input) { - module->addAssume(NEW_ID, module->Not(NEW_TWINE, module->ReduceOr(NEW_TWINE, module->Bweqx(NEW_TWINE, wire, Const(State::Sx, GetSize(wire))))), State::S1); + module->addAssume(NEW_TWINE, module->Not(NEW_TWINE, module->ReduceOr(NEW_TWINE, module->Bweqx(NEW_TWINE, wire, Const(State::Sx, GetSize(wire))))), State::S1); } } } diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index 185f95c4a..dcc79601c 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -164,7 +164,7 @@ struct EquivMakeWorker if (encdata.count(id)) { - log("Creating encoder/decoder for signal %s.\n", design->twines.unescaped_str(id)); + log("Creating encoder/decoder for signal %s.\n", log_id(id)); Wire *dec_wire = equiv_mod->addWire(Twine{id.str() + "_decoded"}, gold_wire->width); Wire *enc_wire = equiv_mod->addWire(Twine{id.str() + "_encoded"}, gate_wire->width); @@ -239,7 +239,7 @@ struct EquivMakeWorker log("Presumably equivalent wires: %s (%s), %s (%s) -> %s\n", gold_wire, log_signal(assign_map(gold_wire)), - gate_wire, log_signal(assign_map(gate_wire)), design->twines.unescaped_str(id)); + gate_wire, log_signal(assign_map(gate_wire)), log_id(id)); if (gold_wire->port_output || gate_wire->port_output) { @@ -318,7 +318,7 @@ struct EquivMakeWorker new_sig[i] = old_sig[i]; if (old_sig != new_sig) { log("Changing input %s of cell %s (%s): %s -> %s\n", - equiv_mod->design->twines.str(conn.first).c_str(), c, design->twines.unescaped_str(c->type), + equiv_mod->design->twines.str(conn.first).c_str(), c, c->type.unescape(), log_signal(old_sig), log_signal(new_sig)); c->setPort(conn.first, new_sig); } @@ -349,7 +349,7 @@ struct EquivMakeWorker goto try_next_cell_name; log("Presumably equivalent cells: %s %s (%s) -> %s\n", - gold_cell, gate_cell, design->twines.unescaped_str(gold_cell->type), design->twines.unescaped_str(id)); + gold_cell, gate_cell, gold_cell->type.unescape(), log_id(id)); for (auto gold_conn : gold_cell->connections()) { diff --git a/passes/equiv/equiv_miter.cc b/passes/equiv/equiv_miter.cc index 5a0754394..8f9c063a5 100644 --- a/passes/equiv/equiv_miter.cc +++ b/passes/equiv/equiv_miter.cc @@ -324,7 +324,7 @@ struct EquivMiterPass : public Pass { design->sigNormalize(false); if (design->module(design->twines.lookup(worker.miter_name.str()))) - log_cmd_error("Miter module %s already exists.\n", design->twines.unescaped_str(worker.miter_name)); + log_cmd_error("Miter module %s already exists.\n", log_id(worker.miter_name)); worker.source_module = nullptr; for (auto m : design->selected_modules()) { diff --git a/passes/equiv/equiv_purge.cc b/passes/equiv/equiv_purge.cc index 0ef35946e..af7415ca4 100644 --- a/passes/equiv/equiv_purge.cc +++ b/passes/equiv/equiv_purge.cc @@ -37,7 +37,7 @@ struct EquivPurgeWorker Wire *wire = sig.as_wire(); if (wire->name.isPublic()) { if (!wire->port_output) { - log(" Module output: %s (%s)\n", log_signal(wire), design->twines.unescaped_str(cellname)); + log(" Module output: %s (%s)\n", log_signal(wire), log_id(cellname)); wire->port_output = true; } return wire; @@ -53,7 +53,7 @@ struct EquivPurgeWorker Wire *wire = module->addWire(Twine{name}, GetSize(sig)); wire->port_output = true; module->connect(wire, sig); - log(" Module output: %s (%s)\n", log_signal(wire), design->twines.unescaped_str(cellname)); + log(" Module output: %s (%s)\n", log_signal(wire), log_id(cellname)); return wire; } } diff --git a/passes/equiv/equiv_struct.cc b/passes/equiv/equiv_struct.cc index 39291b6fb..b619c5745 100644 --- a/passes/equiv/equiv_struct.cc +++ b/passes/equiv/equiv_struct.cc @@ -264,7 +264,7 @@ struct EquivStructWorker run_strategy: int total_group_size = GetSize(gold_cells) + GetSize(gate_cells) + GetSize(other_cells); log(" %s merging %d %s cells (from group of %d) using strategy %s:\n", phase ? "Bwd" : "Fwd", - 2*GetSize(cell_pairs), design->twines.unescaped_str(cells_type), total_group_size, strategy); + 2*GetSize(cell_pairs), log_id(cells_type), total_group_size, strategy); for (auto it : cell_pairs) { log(" Merging cells %s and %s.\n", it.first, it.second); merge_cell_pair(it.first, it.second); @@ -314,7 +314,7 @@ struct EquivStructPass : public Pass { } void execute(std::vector args, Design *design) override { - pool fwonly_cells({ TW($equiv) }); + pool fwonly_cells({ ID($equiv) }); bool mode_icells = false; bool mode_fwd = false; int max_iter = -1; diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc index 62386154e..146035b6e 100644 --- a/passes/fsm/fsm_map.cc +++ b/passes/fsm/fsm_map.cc @@ -169,7 +169,7 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module) RTLIL::Wire *state_wire = module->addWire(module->uniquify(module->design->twines.add(Twine{fsm_cell->parameters[ID::NAME].decode_string()})), fsm_data.state_bits); RTLIL::Wire *next_state_wire = module->addWire(NEW_TWINE, fsm_data.state_bits); - RTLIL::Cell *state_dff = module->addCell(NEW_TWINE, ""); + RTLIL::Cell *state_dff = module->addCell(NEW_TWINE, TwineRef{}); if (fsm_cell->getPort(TW::ARST).is_fully_const()) { state_dff->type_impl = TW::$dff; } else { diff --git a/passes/hierarchy/flatten.cc b/passes/hierarchy/flatten.cc index 139a6dd00..54d9cc53f 100644 --- a/passes/hierarchy/flatten.cc +++ b/passes/hierarchy/flatten.cc @@ -316,7 +316,7 @@ struct FlattenWorker if (attr.first == ID::hdlname) scopeinfo->attributes.insert(attr); else - scopeinfo->attributes.emplace(stringf("\\cell_%s", design->twines.unescaped_str(attr.first)), attr.second); + scopeinfo->attributes.emplace(stringf("\\cell_%s", RTLIL::unescape_id(attr.first).c_str()), attr.second); } // src lives outside cell->attributes after the typed-src // migration — fold it into the renamed-attribute view by @@ -325,7 +325,7 @@ struct FlattenWorker scopeinfo->attributes.emplace(ID(cell_src), RTLIL::Const(cell->get_src_attribute())); for (auto const &attr : tpl->attributes) - scopeinfo->attributes.emplace(stringf("\\module_%s", design->twines.unescaped_str(attr.first)), attr.second); + scopeinfo->attributes.emplace(stringf("\\module_%s", RTLIL::unescape_id(attr.first).c_str()), attr.second); if (tpl->src_id() != Twine::Null) scopeinfo->attributes.emplace(ID(module_src), RTLIL::Const(tpl->get_src_attribute())); diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 5ce34119f..35d8ee3b7 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -132,7 +132,7 @@ void generate(RTLIL::Design *design, const std::vector &celltypes, mod->fixup_ports(); for (auto ¶ : parameters) - log(" ignoring parameter %s.\n", design->twines.unescaped_str(para)); + log(" ignoring parameter %s.\n", log_id(para)); log(" module %s created.\n", mod); } @@ -187,7 +187,7 @@ bool read_id_num(RTLIL::Design &design, TwineRef ref, int *dst) struct IFExpander { IFExpander (RTLIL::Design &design, RTLIL::Module &m) - : module(m), design(design), has_interfaces_not_found(false) + : design(design), module(m), has_interfaces_not_found(false) { // Keep track of all derived interfaces available in the current // module in 'interfaces_in_module': @@ -238,7 +238,7 @@ struct IFExpander // about it and don't set has_interfaces_not_found (to avoid a // loop). log_warning("Could not find interface instance for `%s' in `%s'\n", - design->twines.unescaped_str(interface_name), &module); + log_id(interface_name), &module); } // Handle an interface connection from the module @@ -282,8 +282,8 @@ struct IFExpander // Go over all wires in interface, and add replacements to lists. std::string conn_name_str(design.twines.str(conn_name)); for (auto mod_wire : mod_replace_ports->wires()) { - std::string signal_name1 = conn_name_str + "." + design->twines.unescaped_str(mod_wire->name); - std::string signal_name2 = interface_name.str() + "." + design->twines.unescaped_str(mod_wire->name); + 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()); connections_to_add.push_back(design.twines.add(Twine{signal_name1})); TwineRef signal_name2_ref = design.twines.lookup(signal_name2); if(module.wire(signal_name2_ref) == nullptr) { @@ -388,10 +388,10 @@ RTLIL::Module *get_module(RTLIL::Design &design, bool check, const std::vector &libdirs) { - std::string cell_type = cell.type.str(); + std::string cell_type = design.twines.str(cell.type.ref()); RTLIL::Module *abs_mod = design.module("$abstract" + cell_type); if (abs_mod) { - cell.type_impl = design.twines.add(Twine{abs_mod->derive(&design, cell.parameters).str()}); + cell.type_impl = design.twines.add(Twine{design.twines.str(abs_mod->derive(&design, cell.parameters))}); cell.parameters.clear(); RTLIL::Module *mod = design.module(cell.type); log_assert(mod); @@ -412,7 +412,7 @@ RTLIL::Module *get_module(RTLIL::Design &design, }; for (auto &ext : extensions_list) { - std::string filename = dir + "/" + design->twines.unescaped_str(cell.type) + ext.first; + std::string filename = dir + "/" + cell.type.unescape() + ext.first; if (!check_file_exists(filename)) continue; @@ -447,7 +447,7 @@ void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLI if (id <= 0 || id > GetSize(mod.ports)) log_error("Module `%s' referenced in module `%s' in cell `%s' " "has only %d ports, requested port %d.\n", - design->twines.unescaped_str(cell.type), &module, &cell, + cell.type.unescape(), &module, &cell, GetSize(mod.ports), id); continue; } @@ -456,7 +456,7 @@ void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLI if (!wire || wire->port_id == 0) { log_error("Module `%s' referenced in module `%s' in cell `%s' " "does not have a port named '%s'.\n", - design->twines.unescaped_str(cell.type), &module, &cell, + cell.type.unescape(), &module, &cell, module.design->twines.str(conn.first).data()); } } @@ -465,7 +465,7 @@ void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLI if (id <= 0 || id > GetSize(mod.avail_parameters)) log_error("Module `%s' referenced in module `%s' in cell `%s' " "has only %d parameters, requested parameter %d.\n", - design->twines.unescaped_str(cell.type), &module, &cell, + cell.type.unescape(), &module, &cell, GetSize(mod.avail_parameters), id); continue; } @@ -475,8 +475,8 @@ void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLI strchr(param.first.c_str(), '.') == NULL) { log_error("Module `%s' referenced in module `%s' in cell `%s' " "does not have a parameter named '%s'.\n", - design->twines.unescaped_str(cell.type), &module, &cell, - design->twines.unescaped_str(param.first)); + cell.type.unescape(), &module, &cell, + log_id(param.first)); } } } @@ -517,8 +517,8 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check cell->type_impl = cell->module->design->twines.add(Twine{cell->type.str().substr(pos_type + 1)}); } - dict interfaces_by_name; - dict modports_by_name; + dict interfaces_by_name; + dict modports_by_name; RTLIL::Module *mod = design->module(cell->type); if (!mod) @@ -573,13 +573,13 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } for (auto &p : if_expander.interfaces_to_add_to_submodule) - interfaces_by_name[RTLIL::IdString(design->twines.str(p.first))] = p.second; + interfaces_by_name[p.first] = p.second; for (auto &p : if_expander.modports_used_in_submodule) - modports_by_name[RTLIL::IdString(design->twines.str(p.first))] = p.second; - cell->type_impl = design->twines.add(Twine{mod->derive(design, + modports_by_name[p.first] = design->twines.add(Twine{p.second.str()}); + cell->type_impl = mod->derive(design, cell->parameters, interfaces_by_name, - modports_by_name).str()}); + modports_by_name); cell->parameters.clear(); did_something = true; @@ -1331,10 +1331,11 @@ struct HierarchyPass : public Pass { // Need accurate port widths for error checking; so must derive blackboxes with dynamic port widths if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute(ID::dynports)) { - IdString new_m_name = m->derive(design, cell->parameters, true); - if (new_m_name.empty()) + TwineRef new_m_ref = m->derive(design, cell->parameters, true); + if (new_m_ref == TwineRef{}) continue; - if (new_m_name != RTLIL::IdString(design->twines.str(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_name); blackbox_derivatives.insert(m); } @@ -1520,10 +1521,11 @@ struct HierarchyPass : public Pass { bool boxed_params = false; if (m->get_blackbox_attribute() && !cell->parameters.empty()) { if (m->get_bool_attribute(ID::dynports)) { - IdString new_m_name = m->derive(design, cell->parameters, true); - if (new_m_name.empty()) + TwineRef new_m_ref = m->derive(design, cell->parameters, true); + if (new_m_ref == TwineRef{}) continue; - if (new_m_name != RTLIL::IdString(design->twines.str(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_name); blackbox_derivatives.insert(m); } diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 5d90a561e..4834f20f0 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -93,7 +93,7 @@ struct SubmodWorker for (RTLIL::Cell *cell : submod.cells) { if (ct.cell_known(cell->type_impl)) { for (auto &conn : cell->connections()) - flag_signal(conn.second, true, ct.cell_output(cell->type, conn.first), ct.cell_input(cell->type_impl, conn.first), false, false); + flag_signal(conn.second, true, ct.cell_output(cell->type.ref(), conn.first), ct.cell_input(cell->type_impl, conn.first), false, false); } else { log_warning("Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name, cell->type); for (auto &conn : cell->connections()) @@ -105,7 +105,7 @@ struct SubmodWorker continue; if (ct.cell_known(cell->type_impl)) { for (auto &conn : cell->connections()) - flag_signal(conn.second, false, false, false, ct.cell_output(cell->type, conn.first), ct.cell_input(cell->type_impl, conn.first)); + flag_signal(conn.second, false, false, false, ct.cell_output(cell->type.ref(), conn.first), ct.cell_input(cell->type_impl, conn.first)); } else { flag_found_something = false; for (auto &conn : cell->connections()) @@ -219,7 +219,8 @@ struct SubmodWorker submod.cells.clear(); if (!copy_mode) { - RTLIL::Cell *new_cell = module->addCell(design->twines.add(Twine{submod.full_name}), ID(submod.full_name)); + TwineRef submod_type = design->twines.add(Twine{submod.full_name}); + RTLIL::Cell *new_cell = module->addCell(Twine{submod.full_name}, submod_type); for (auto &it : wire_flags) { RTLIL::SigSpec old_sig = sigmap(it.first); diff --git a/passes/hierarchy/uniquify.cc b/passes/hierarchy/uniquify.cc index 03aced9de..894d9ed7d 100644 --- a/passes/hierarchy/uniquify.cc +++ b/passes/hierarchy/uniquify.cc @@ -84,7 +84,7 @@ struct UniquifyPass : public Pass { if (tmod->get_bool_attribute(ID::unique) && newname_ref == tmod->meta_->name) continue; - log("Creating module %s from %s.\n", design->twines.unescaped_str(newname), tmod); + log("Creating module %s from %s.\n", log_id(newname), tmod); auto smod = tmod->clone(); smod->meta_->name = newname_ref; diff --git a/passes/memory/memlib.h b/passes/memory/memlib.h index 0d4116632..7394baf4e 100644 --- a/passes/memory/memlib.h +++ b/passes/memory/memlib.h @@ -140,7 +140,7 @@ struct RamClock { }; struct Ram { - TwineRef id; + IdString id; RamKind kind; dict options; std::vector port_groups; diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index bde9ec61f..27d66268f 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -44,7 +44,7 @@ struct rules_t void dump_config() const { - log(" bram %s # variant %d\n", design->twines.unescaped_str(name), variant); + log(" bram %s # variant %d\n", log_id(name), variant); log(" init %d\n", init); log(" abits %d\n", abits); log(" dbits %d\n", dbits); @@ -61,16 +61,16 @@ struct rules_t void check_vectors() const { - if (groups != GetSize(ports)) log_error("Bram %s variant %d has %d groups but only %d entries in 'ports'.\n", design->twines.unescaped_str(name), variant, groups, GetSize(ports)); - if (groups != GetSize(wrmode)) log_error("Bram %s variant %d has %d groups but only %d entries in 'wrmode'.\n", design->twines.unescaped_str(name), variant, groups, GetSize(wrmode)); - if (groups != GetSize(enable)) log_error("Bram %s variant %d has %d groups but only %d entries in 'enable'.\n", design->twines.unescaped_str(name), variant, groups, GetSize(enable)); - if (groups != GetSize(transp)) log_error("Bram %s variant %d has %d groups but only %d entries in 'transp'.\n", design->twines.unescaped_str(name), variant, groups, GetSize(transp)); - if (groups != GetSize(clocks)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clocks'.\n", design->twines.unescaped_str(name), variant, groups, GetSize(clocks)); - if (groups != GetSize(clkpol)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clkpol'.\n", design->twines.unescaped_str(name), variant, groups, GetSize(clkpol)); + if (groups != GetSize(ports)) log_error("Bram %s variant %d has %d groups but only %d entries in 'ports'.\n", log_id(name), variant, groups, GetSize(ports)); + if (groups != GetSize(wrmode)) log_error("Bram %s variant %d has %d groups but only %d entries in 'wrmode'.\n", log_id(name), variant, groups, GetSize(wrmode)); + if (groups != GetSize(enable)) log_error("Bram %s variant %d has %d groups but only %d entries in 'enable'.\n", log_id(name), variant, groups, GetSize(enable)); + if (groups != GetSize(transp)) log_error("Bram %s variant %d has %d groups but only %d entries in 'transp'.\n", log_id(name), variant, groups, GetSize(transp)); + if (groups != GetSize(clocks)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clocks'.\n", log_id(name), variant, groups, GetSize(clocks)); + if (groups != GetSize(clkpol)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clkpol'.\n", log_id(name), variant, groups, GetSize(clkpol)); int group = 0; for (auto e : enable) - if (e > dbits) log_error("Bram %s variant %d group %d has %d enable bits but only %d dbits.\n", design->twines.unescaped_str(name), variant, group, e, dbits); + if (e > dbits) log_error("Bram %s variant %d group %d has %d enable bits but only %d dbits.\n", log_id(name), variant, group, e, dbits); } vector make_portinfos() const @@ -100,7 +100,7 @@ struct rules_t log_assert(name == other.name); if (groups != other.groups) - log_error("Bram %s variants %d and %d have different values for 'groups'.\n", design->twines.unescaped_str(name), variant, other.variant); + log_error("Bram %s variants %d and %d have different values for 'groups'.\n", log_id(name), variant, other.variant); if (abits != other.abits) variant_params[ID::CFG_ABITS] = abits; @@ -112,7 +112,7 @@ struct rules_t for (int i = 0; i < groups; i++) { if (ports[i] != other.ports[i]) - log_error("Bram %s variants %d and %d have different number of %c-ports.\n", design->twines.unescaped_str(name), variant, other.variant, 'A'+i); + log_error("Bram %s variants %d and %d have different number of %c-ports.\n", log_id(name), variant, other.variant, 'A'+i); if (wrmode[i] != other.wrmode[i]) variant_params[stringf("\\CFG_WRMODE_%c", 'A' + i)] = wrmode[i]; if (enable[i] != other.enable[i]) @@ -490,7 +490,7 @@ bool replace_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals, const transp_max = max(transp_max, pi.transp); } - log(" Mapping to bram type %s (variant %d):\n", design->twines.unescaped_str(bram.name), bram.variant); + log(" Mapping to bram type %s (variant %d):\n", log_id(bram.name), bram.variant); // bram.dump_config(); std::vector shuffle_map; @@ -777,7 +777,7 @@ grow_read_ports:; for (auto it : match.min_limits) { if (!match_properties.count(it.first)) log_error("Unknown property '%s' in match rule for bram type %s.\n", - it.first.c_str(), design->twines.unescaped_str(match.name)); + it.first.c_str(), log_id(match.name)); if (match_properties[it.first] >= it.second) continue; log(" Rule for bram type %s rejected: requirement 'min %s %d' not met.\n", @@ -787,7 +787,7 @@ grow_read_ports:; for (auto it : match.max_limits) { if (!match_properties.count(it.first)) log_error("Unknown property '%s' in match rule for bram type %s.\n", - it.first.c_str(), design->twines.unescaped_str(match.name)); + it.first.c_str(), log_id(match.name)); if (match_properties[it.first] <= it.second) continue; log(" Rule for bram type %s rejected: requirement 'max %s %d' not met.\n", @@ -821,7 +821,7 @@ grow_read_ports:; if (!exists) ss << "!"; IdString key = std::get<1>(sums.front()); - ss << design->twines.unescaped_str(key); + ss << log_id(key); const Const &value = rules.map_case(std::get<2>(sums.front())); if (exists && value != Const(1)) ss << "=\"" << value.decode_string() << "\""; @@ -935,8 +935,8 @@ grow_read_ports:; for (int grid_a = 0; grid_a < acells; grid_a++) for (int dupidx = 0; dupidx < dup_count; dupidx++) { - Cell *c = module->addCell(module->uniquify(module->design->twines.add(Twine{stringf("%s.%d.%d.%d", mem.memid.str(), grid_d, grid_a, dupidx)})), bram.name); - log(" Creating %s cell at grid position <%d %d %d>: %s\n", design->twines.unescaped_str(bram.name), grid_d, grid_a, dupidx, c); + Cell *c = module->addCell(module->uniquify(module->design->twines.add(Twine{stringf("%s.%d.%d.%d", mem.memid.str(), grid_d, grid_a, dupidx)})), module->design->twines.add(Twine{bram.name.str()})); + log(" Creating %s cell at grid position <%d %d %d>: %s\n", log_id(bram.name), grid_d, grid_a, dupidx, c); for (auto &vp : variant_params) c->setParam(vp.first, vp.second); @@ -1066,7 +1066,7 @@ grow_read_ports:; void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) { - log("Processing %s.%s:\n", mem.module, design->twines.unescaped_str(mem.memid)); + log("Processing %s.%s:\n", mem.module, log_id(mem.memid)); mem.narrow(); bool cell_init = !mem.inits.empty(); @@ -1093,7 +1093,7 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) auto &match = rules.matches.at(i); if (!rules.brams.count(rules.matches[i].name)) - log_error("No bram description for resource %s found!\n", design->twines.unescaped_str(rules.matches[i].name)); + log_error("No bram description for resource %s found!\n", log_id(rules.matches[i].name)); for (int vi = 0; vi < GetSize(rules.brams.at(match.name)); vi++) { @@ -1109,7 +1109,7 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) avail_wr_ports += GetSize(bram.ports) < j ? bram.ports.at(j) : 0; } - log(" Checking rule #%d for bram type %s (variant %d):\n", i+1, design->twines.unescaped_str(bram.name), bram.variant); + log(" Checking rule #%d for bram type %s (variant %d):\n", i+1, log_id(bram.name), bram.variant); log(" Bram geometry: abits=%d dbits=%d wports=%d rports=%d\n", bram.abits, bram.dbits, avail_wr_ports, avail_rd_ports); int dups = avail_rd_ports ? (match_properties["rports"] + avail_rd_ports - 1) / avail_rd_ports : 1; @@ -1143,7 +1143,7 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) if (cell_init && bram.init == 0) { log(" Rule #%d for bram type %s (variant %d) rejected: cannot be initialized.\n", - i+1, design->twines.unescaped_str(bram.name), bram.variant); + i+1, log_id(bram.name), bram.variant); goto next_match_rule; } @@ -1152,11 +1152,11 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) continue; if (!match_properties.count(it.first)) log_error("Unknown property '%s' in match rule for bram type %s.\n", - it.first.c_str(), design->twines.unescaped_str(match.name)); + it.first.c_str(), log_id(match.name)); if (match_properties[it.first] >= it.second) continue; log(" Rule #%d for bram type %s (variant %d) rejected: requirement 'min %s %d' not met.\n", - i+1, design->twines.unescaped_str(bram.name), bram.variant, it.first.c_str(), it.second); + i+1, log_id(bram.name), bram.variant, it.first.c_str(), it.second); goto next_match_rule; } @@ -1165,11 +1165,11 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) continue; if (!match_properties.count(it.first)) log_error("Unknown property '%s' in match rule for bram type %s.\n", - it.first.c_str(), design->twines.unescaped_str(match.name)); + it.first.c_str(), log_id(match.name)); if (match_properties[it.first] <= it.second) continue; log(" Rule #%d for bram type %s (variant %d) rejected: requirement 'max %s %d' not met.\n", - i+1, design->twines.unescaped_str(bram.name), bram.variant, it.first.c_str(), it.second); + i+1, log_id(bram.name), bram.variant, it.first.c_str(), it.second); goto next_match_rule; } @@ -1199,7 +1199,7 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) if (!exists) ss << "!"; IdString key = std::get<1>(sums.front()); - ss << design->twines.unescaped_str(key); + ss << log_id(key); const Const &value = rules.map_case(std::get<2>(sums.front())); if (exists && value != Const(1)) ss << "=\"" << value.decode_string() << "\""; @@ -1210,7 +1210,7 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) } } - log(" Rule #%d for bram type %s (variant %d) accepted.\n", i+1, design->twines.unescaped_str(bram.name), bram.variant); + log(" Rule #%d for bram type %s (variant %d) accepted.\n", i+1, log_id(bram.name), bram.variant); if (or_next_if_better || !best_rule_cache.empty()) { @@ -1218,7 +1218,7 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) log_error("Found 'or_next_if_better' in last match rule.\n"); if (!replace_memory(mem, rules, initvals, bram, match, match_properties, 1)) { - log(" Mapping to bram type %s failed.\n", design->twines.unescaped_str(match.name)); + log(" Mapping to bram type %s failed.\n", log_id(match.name)); failed_brams.insert(pair(bram.name, bram.variant)); goto next_match_rule; } @@ -1245,12 +1245,12 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals) auto &best_bram = rules.brams.at(rules.matches.at(best_rule.first).name).at(best_rule.second); if (!replace_memory(mem, rules, initvals, best_bram, rules.matches.at(best_rule.first), match_properties, 2)) - log_error("Mapping to bram type %s (variant %d) after pre-selection failed.\n", design->twines.unescaped_str(best_bram.name), best_bram.variant); + log_error("Mapping to bram type %s (variant %d) after pre-selection failed.\n", log_id(best_bram.name), best_bram.variant); return; } if (!replace_memory(mem, rules, initvals, bram, match, match_properties, 0)) { - log(" Mapping to bram type %s failed.\n", design->twines.unescaped_str(match.name)); + log(" Mapping to bram type %s failed.\n", log_id(match.name)); failed_brams.insert(pair(bram.name, bram.variant)); goto next_match_rule; } diff --git a/passes/memory/memory_libmap.cc b/passes/memory/memory_libmap.cc index 61b499681..7ba60dff2 100644 --- a/passes/memory/memory_libmap.cc +++ b/passes/memory/memory_libmap.cc @@ -204,7 +204,7 @@ struct MemMapping { if (!check_init(rdef)) continue; if (rdef.prune_rom && mem.wr_ports.empty()) { - log_debug("memory %s.%s: rejecting mapping to %s: ROM mapping disabled (prune_rom set)\n", log_id(mem.module), design->twines.unescaped_str(mem.memid), mem.module->design->twines.unescaped_str(rdef.id)); + log_debug("memory %s.%s: rejecting mapping to %s: ROM mapping disabled (prune_rom set)\n", log_id(mem.module), log_id(mem.memid), log_id(rdef.id)); continue; } MemConfig cfg; @@ -323,7 +323,7 @@ struct MemMapping { void log_reject(const Ram &ram, std::string message) { if(ys_debug(1)) { - rejected_cfg_debug_msgs += stringf("can't map to to %s: ", mem.module->design->twines.unescaped_str(ram.id)); + rejected_cfg_debug_msgs += stringf("can't map to to %s: ", log_id(ram.id)); rejected_cfg_debug_msgs += message; rejected_cfg_debug_msgs += "\n"; } @@ -338,7 +338,7 @@ struct MemMapping { rejected_cfg_debug_msgs += portname; first = false; } - rejected_cfg_debug_msgs += stringf("] of %s: ", mem.module->design->twines.unescaped_str(ram.id)); + rejected_cfg_debug_msgs += stringf("] of %s: ", log_id(ram.id)); rejected_cfg_debug_msgs += message; rejected_cfg_debug_msgs += "\n"; } @@ -361,7 +361,7 @@ struct MemMapping { rejected_cfg_debug_msgs += portname; first = false; } - rejected_cfg_debug_msgs += stringf("] of %s: ", mem.module->design->twines.unescaped_str(ram.id)); + rejected_cfg_debug_msgs += stringf("] of %s: ", log_id(ram.id)); rejected_cfg_debug_msgs += message; rejected_cfg_debug_msgs += "\n"; } @@ -380,7 +380,7 @@ void MemMapping::dump_configs(int stage) { default: abort(); } - log_debug("Memory %s.%s mapping candidates (%s):\n", log_id(mem.module), design->twines.unescaped_str(mem.memid), stage_name); + log_debug("Memory %s.%s mapping candidates (%s):\n", log_id(mem.module), log_id(mem.memid), stage_name); if (logic_ok) { log_debug("- logic fallback\n"); log_debug(" - cost: %f\n", logic_cost); @@ -391,7 +391,7 @@ void MemMapping::dump_configs(int stage) { } void MemMapping::dump_config(MemConfig &cfg) { - log_debug("- %s:\n", mem.module->design->twines.unescaped_str(cfg.def->id)); + log_debug("- %s:\n", log_id(cfg.def->id)); for (auto &it: cfg.def->options) log_debug(" - option %s %s\n", it.first, log_const(it.second)); log_debug(" - emulation score: %d\n", cfg.score_emu); @@ -527,7 +527,7 @@ void MemMapping::determine_style() { auto find_attr = search_for_attribute(mem, ID::lram); if (find_attr.first && find_attr.second.as_bool()) { kind = RamKind::Huge; - log("found attribute 'lram' on memory %s.%s, forced mapping to huge RAM\n", log_id(mem.module), design->twines.unescaped_str(mem.memid)); + log("found attribute 'lram' on memory %s.%s, forced mapping to huge RAM\n", log_id(mem.module), log_id(mem.memid)); return; } for (auto attr: {ID::ram_block, ID::rom_block, ID::ram_style, ID::rom_style, ID::ramstyle, ID::romstyle, ID::syn_ramstyle, ID::syn_romstyle}) { @@ -536,7 +536,7 @@ void MemMapping::determine_style() { Const val = find_attr.second; if (val == 1) { kind = RamKind::NotLogic; - log("found attribute '%s = 1' on memory %s.%s, disabled mapping to FF\n", design->twines.unescaped_str(attr), log_id(mem.module), design->twines.unescaped_str(mem.memid)); + log("found attribute '%s = 1' on memory %s.%s, disabled mapping to FF\n", log_id(attr), log_id(mem.module), log_id(mem.memid)); return; } std::string val_s = val.decode_string(); @@ -549,20 +549,20 @@ void MemMapping::determine_style() { // Nothing. } else if (val_s == "logic" || val_s == "registers") { kind = RamKind::Logic; - log("found attribute '%s = %s' on memory %s.%s, forced mapping to FF\n", design->twines.unescaped_str(attr), val_s, log_id(mem.module), design->twines.unescaped_str(mem.memid)); + log("found attribute '%s = %s' on memory %s.%s, forced mapping to FF\n", log_id(attr), val_s, log_id(mem.module), log_id(mem.memid)); } else if (val_s == "distributed") { kind = RamKind::Distributed; - log("found attribute '%s = %s' on memory %s.%s, forced mapping to distributed RAM\n", design->twines.unescaped_str(attr), val_s, log_id(mem.module), design->twines.unescaped_str(mem.memid)); + log("found attribute '%s = %s' on memory %s.%s, forced mapping to distributed RAM\n", log_id(attr), val_s, log_id(mem.module), log_id(mem.memid)); } else if (val_s == "block" || val_s == "block_ram" || val_s == "ebr") { kind = RamKind::Block; - log("found attribute '%s = %s' on memory %s.%s, forced mapping to block RAM\n", design->twines.unescaped_str(attr), val_s, log_id(mem.module), design->twines.unescaped_str(mem.memid)); + log("found attribute '%s = %s' on memory %s.%s, forced mapping to block RAM\n", log_id(attr), val_s, log_id(mem.module), log_id(mem.memid)); } else if (val_s == "huge" || val_s == "ultra") { kind = RamKind::Huge; - log("found attribute '%s = %s' on memory %s.%s, forced mapping to huge RAM\n", design->twines.unescaped_str(attr), val_s, log_id(mem.module), design->twines.unescaped_str(mem.memid)); + log("found attribute '%s = %s' on memory %s.%s, forced mapping to huge RAM\n", log_id(attr), val_s, log_id(mem.module), log_id(mem.memid)); } else { kind = RamKind::NotLogic; style = val_s; - log("found attribute '%s = %s' on memory %s.%s, forced mapping to %s RAM\n", design->twines.unescaped_str(attr), val_s, log_id(mem.module), design->twines.unescaped_str(mem.memid), val_s); + log("found attribute '%s = %s' on memory %s.%s, forced mapping to %s RAM\n", log_id(attr), val_s, log_id(mem.module), log_id(mem.memid), val_s); } return; } @@ -1991,7 +1991,7 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector &cells, cons } void MemMapping::emit(const MemConfig &cfg) { - log("mapping memory %s.%s via %s\n", log_id(mem.module), design->twines.unescaped_str(mem.memid), mem.module->design->twines.unescaped_str(cfg.def->id)); + log("mapping memory %s.%s via %s\n", log_id(mem.module), log_id(mem.memid), log_id(cfg.def->id)); // First, handle emulations. if (cfg.emu_read_first) mem.emulate_read_first(&worker.initvals); @@ -2068,7 +2068,7 @@ void MemMapping::emit(const MemConfig &cfg) { for (int rp = 0; rp < cfg.repl_port; rp++) { std::vector cells; for (int rd = 0; rd < cfg.repl_d; rd++) { - Cell *cell = mem.module->addCell(Twine{stringf("%s.%d.%d", mem.memid.str(), rp, rd)}, cfg.def->id); + Cell *cell = mem.module->addCell(Twine{stringf("%s.%d.%d", mem.memid.str(), rp, rd)}, mem.module->design->twines.add(Twine{cfg.def->id.str()})); if (cfg.def->width_mode == WidthMode::Global || opts.force_params) cell->setParam(ID::WIDTH, cfg.def->dbits[cfg.base_width_log2]); if (opts.force_params) @@ -2252,9 +2252,9 @@ struct MemoryLibMapPass : public Pass { int best = map.logic_cost; if (!map.logic_ok) { if (map.cfgs.empty()) { - log_debug("Rejected candidates for mapping memory %s.%s:\n", log_id(module), design->twines.unescaped_str(mem.memid)); + log_debug("Rejected candidates for mapping memory %s.%s:\n", log_id(module), log_id(mem.memid)); log_debug("%s", map.rejected_cfg_debug_msgs); - log_error("no valid mapping found for memory %s.%s\n", log_id(module), design->twines.unescaped_str(mem.memid)); + log_error("no valid mapping found for memory %s.%s\n", log_id(module), log_id(mem.memid)); } idx = 0; best = map.cfgs[0].cost; @@ -2266,7 +2266,7 @@ struct MemoryLibMapPass : public Pass { } } if (idx == -1) { - log("using FF mapping for memory %s.%s\n", log_id(module), design->twines.unescaped_str(mem.memid)); + log("using FF mapping for memory %s.%s\n", log_id(module), log_id(mem.memid)); } else { map.emit(map.cfgs[idx]); // Rebuild indices after modifying module diff --git a/passes/memory/memory_memx.cc b/passes/memory/memory_memx.cc index 2093ace64..ed99290d2 100644 --- a/passes/memory/memory_memx.cc +++ b/passes/memory/memory_memx.cc @@ -60,7 +60,7 @@ struct MemoryMemxPass : public Pass { { if (port.clk_enable) log_error("Memory %s.%s has a synchronous read port. Synchronous read ports are not supported by memory_memx!\n", - module, design->twines.unescaped_str(mem.memid)); + module, log_id(mem.memid)); SigSpec addr_ok = make_addr_check(mem, port.addr); Wire *raw_rdata = module->addWire(NEW_TWINE, GetSize(port.data)); diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc index b4deeef35..d1f111e25 100644 --- a/passes/memory/memory_share.cc +++ b/passes/memory/memory_share.cc @@ -80,7 +80,7 @@ struct MemoryShareWorker if (GetSize(mem.rd_ports) <= 1) return false; - log("Consolidating read ports of memory %s.%s by address:\n", module, design->twines.unescaped_str(mem.memid)); + log("Consolidating read ports of memory %s.%s by address:\n", module, log_id(mem.memid)); bool changed = false; int abits = 0; @@ -197,7 +197,7 @@ struct MemoryShareWorker if (GetSize(mem.wr_ports) <= 1) return false; - log("Consolidating write ports of memory %s.%s by address:\n", module, design->twines.unescaped_str(mem.memid)); + log("Consolidating write ports of memory %s.%s by address:\n", module, log_id(mem.memid)); bool changed = false; int abits = 0; @@ -316,7 +316,7 @@ struct MemoryShareWorker if (eligible_ports.size() <= 1) return; - log("Consolidating write ports of memory %s.%s using sat-based resource sharing:\n", module, design->twines.unescaped_str(mem.memid)); + log("Consolidating write ports of memory %s.%s using sat-based resource sharing:\n", module, log_id(mem.memid)); // Group eligible ports by clock domain and width. diff --git a/passes/opt/opt_balance_tree.cc b/passes/opt/opt_balance_tree.cc index 2de24deef..db131d5ca 100644 --- a/passes/opt/opt_balance_tree.cc +++ b/passes/opt/opt_balance_tree.cc @@ -33,13 +33,13 @@ struct OptBalanceTreeWorker { SigMap sigmap; // Counts of each cell type that are getting balanced - dict cell_count; + dict cell_count; // Check if cell is of the right type and has matching input/output widths // Only allow cells with "natural" output widths (no truncation) to prevent // equivalence issues when rebalancing (see YosysHQ/yosys#5605) - bool is_right_type(Cell* cell, IdString cell_type) { - if (cell->type != cell_type) + bool is_right_type(Cell* cell, TwineRef cell_type) { + if (cell->type.ref() != cell_type) return false; int y_width = cell->getParam(ID::Y_WIDTH).as_int(); @@ -65,7 +65,7 @@ struct OptBalanceTreeWorker { } // Create a balanced binary tree from a vector of source signals - SigSpec create_balanced_tree(vector &sources, IdString cell_type, Cell* cell) { + SigSpec create_balanced_tree(vector &sources, TwineRef cell_type, Cell* cell) { // Base case: if we have no sources, return an empty signal if (sources.size() == 0) return SigSpec(); @@ -138,7 +138,7 @@ struct OptBalanceTreeWorker { return out_wire; } - OptBalanceTreeWorker(Module *module, const vector cell_types) : module(module), sigmap(module) { + OptBalanceTreeWorker(Module *module, const vector cell_types) : module(module), sigmap(module) { // Do for each cell type for (auto cell_type : cell_types) { // Index all of the nets in the module @@ -344,14 +344,14 @@ struct OptBalanceTreePass : public Pass { // Handle arguments size_t argidx; - vector cell_types = {TW($and), TW($or), TW($xor), TW($add), TW($mul)}; + vector cell_types = {TwineRef{TW($and)}, TwineRef{TW($or)}, TwineRef{TW($xor)}, TwineRef{TW($add)}, TwineRef{TW($mul)}}; for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-arith") { - cell_types = {TW($add), TW($mul)}; + cell_types = {TwineRef{TW($add)}, TwineRef{TW($mul)}}; continue; } if (args[argidx] == "-logic") { - cell_types = {TW($and), TW($or), TW($xor)}; + cell_types = {TwineRef{TW($and)}, TwineRef{TW($or)}, TwineRef{TW($xor)}}; continue; } break; @@ -359,7 +359,7 @@ struct OptBalanceTreePass : public Pass { extra_args(args, argidx, design); // Count of all cells that were packed - dict cell_count; + dict cell_count; for (auto module : design->selected_modules()) { OptBalanceTreeWorker worker(module, cell_types); for (auto cell : worker.cell_count) { diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index ee26c5131..5cc1679ef 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -2183,7 +2183,7 @@ skip_alu_split: // simplify comparisons if (do_fine && cell->type.in(TW($lt), TW($ge), TW($gt), TW($le))) { - IdString cmp_type = cell->type; + TwineRef cmp_type = cell->type.ref(); SigSpec var_sig = cell->getPort(TW::A); SigSpec const_sig = cell->getPort(TW::B); int var_width = cell->parameters[ID::A_WIDTH].as_int(); diff --git a/passes/opt/opt_hier.cc b/passes/opt/opt_hier.cc index 011b93bf6..adf7cf9e4 100644 --- a/passes/opt/opt_hier.cc +++ b/passes/opt/opt_hier.cc @@ -101,7 +101,7 @@ struct ModuleIndex { if (!port || (!port->port_input && !port->port_output) || port->width != value.size()) { log_error("Port %s connected on instance %s not found in module %s" " or width is not matching\n", - design->twines.unescaped_str(port_name), instantiation, module); + module->design->twines.unescaped_str(port_name), instantiation, module); } if (port->port_input && port->port_output) { @@ -145,12 +145,12 @@ struct ModuleIndex { if (nunused > 0) { log("Disconnected %d input bits of instance '%s' (type '%s') in '%s'\n", - nunused, instantiation, design->twines.unescaped_str(instantiation->type), parent.module); + nunused, instantiation, instantiation->type.unescape(), parent.module); changed = true; } if (nconstants > 0) { log("Substituting constant for %d output bits of instance '%s' (type '%s') in '%s'\n", - nconstants, instantiation, design->twines.unescaped_str(instantiation->type), parent.module); + nconstants, instantiation, instantiation->type.unescape(), parent.module); changed = true; } } @@ -189,7 +189,7 @@ struct ModuleIndex { if (ntie_togethers > 0) { log("Replacing %d output bits with tie-togethers on instance '%s' of '%s' in '%s'\n", - ntie_togethers, instantiation, design->twines.unescaped_str(instantiation->type), parent.module); + ntie_togethers, instantiation, instantiation->type.unescape(), parent.module); changed = true; } diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index cb7f5ea66..fa0a98f1e 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -31,7 +31,7 @@ PRIVATE_NAMESPACE_BEGIN struct dlogic_t { IdString cell_type; // LUT input idx -> hard cell's port name - dict lut_input_port; + dict lut_input_port; }; struct OptLutWorker @@ -136,7 +136,7 @@ struct OptLutWorker { if (dlogic[j].cell_type == port.cell->type) { - if (port.port == dlogic[j].lut_input_port.at(i, IdString())) + if (port.port == dlogic[j].lut_input_port.at(i, TwineRef{})) { lut_all_dlogics.insert({j, port.cell}); } @@ -557,15 +557,15 @@ struct OptLutPass : public Pass { dlogic = {{ ID(SB_CARRY), - dict{ - std::make_pair(1, ID(I0)), - std::make_pair(2, ID(I1)), - std::make_pair(3, ID(CI)) + dict{ + std::make_pair(1, TW(I0)), + std::make_pair(2, TW(I1)), + std::make_pair(3, TW(CI)) } }, { ID(SB_CARRY), - dict{ - std::make_pair(3, ID(CO)) + dict{ + std::make_pair(3, TW(CO)) } }}; continue; diff --git a/passes/opt/opt_mem.cc b/passes/opt/opt_mem.cc index 45b3adc7d..9c5a6d83e 100644 --- a/passes/opt/opt_mem.cc +++ b/passes/opt/opt_mem.cc @@ -108,13 +108,13 @@ struct OptMemPass : public Pass { } State bit; if (!always_0[i]) { - log("%s.%s: removing const-1 lane %d\n", design->twines.unescaped_str(module->name), design->twines.unescaped_str(mem.memid), i); + log("%s.%s: removing const-1 lane %d\n", log_id(module->name), log_id(mem.memid), i); bit = State::S1; } else if (!always_1[i]) { - log("%s.%s: removing const-0 lane %d\n", design->twines.unescaped_str(module->name), design->twines.unescaped_str(mem.memid), i); + log("%s.%s: removing const-0 lane %d\n", log_id(module->name), log_id(mem.memid), i); bit = State::S0; } else { - log("%s.%s: removing const-x lane %d\n", design->twines.unescaped_str(module->name), design->twines.unescaped_str(mem.memid), i); + log("%s.%s: removing const-x lane %d\n", log_id(module->name), log_id(mem.memid), i); bit = State::Sx; } // Reconnect read port data. diff --git a/passes/opt/opt_mem_feedback.cc b/passes/opt/opt_mem_feedback.cc index 88e752ba1..e562e1990 100644 --- a/passes/opt/opt_mem_feedback.cc +++ b/passes/opt/opt_mem_feedback.cc @@ -163,7 +163,7 @@ struct OptMemFeedbackWorker { auto &port = mem.wr_ports[i]; - log(" Analyzing %s.%s write port %d.\n", module, design->twines.unescaped_str(mem.memid), i); + log(" Analyzing %s.%s write port %d.\n", module, log_id(mem.memid), i); for (int sub = 0; sub < (1 << port.wide_log2); sub++) { @@ -232,7 +232,7 @@ struct OptMemFeedbackWorker // Okay, let's do it. - log("Populating enable bits on write ports of memory %s.%s with async read feedback:\n", module, design->twines.unescaped_str(mem.memid)); + log("Populating enable bits on write ports of memory %s.%s with async read feedback:\n", module, log_id(mem.memid)); // If a write port has a feedback path that we're about to bypass, // but also has priority over some other write port, the feedback diff --git a/passes/opt/opt_mem_widen.cc b/passes/opt/opt_mem_widen.cc index ff9158ae5..1554493c9 100644 --- a/passes/opt/opt_mem_widen.cc +++ b/passes/opt/opt_mem_widen.cc @@ -65,7 +65,7 @@ struct OptMemWidenPass : public Pass { factor_log2 = port.wide_log2; if (factor_log2 == 0) continue; - log("Widening base width of memory %s in module %s by factor %d.\n", design->twines.unescaped_str(mem.memid), design->twines.str(module->meta_->name).c_str(), 1 << factor_log2); + log("Widening base width of memory %s in module %s by factor %d.\n", log_id(mem.memid), design->twines.str(module->meta_->name).c_str(), 1 << factor_log2); total_count++; // The inits are too messy to expand one-by-one, for they may // collide with one another after expansion. Just hit it with diff --git a/passes/opt/opt_merge_inc.cc b/passes/opt/opt_merge_inc.cc index 6ec0f47d5..4c5ef9e11 100644 --- a/passes/opt/opt_merge_inc.cc +++ b/passes/opt/opt_merge_inc.cc @@ -44,20 +44,20 @@ using MergeableTypes = StaticCellTypes::Categories::Category; // is intentionally not included, so $anyinit stays excluded static constexpr MergeableTypes build_mergeable_types(bool nomux) { auto c = StaticCellTypes::categories.is_known; - c.set_id(TW($anyinit), false); - c.set_id(TW($tribuf), false); - c.set_id(TW($_TBUF_), false); - c.set_id(TW($anyseq), false); - c.set_id(TW($anyconst), false); - c.set_id(TW($allseq), false); - c.set_id(TW($allconst), false); - c.set_id(TW($connect), false); - c.set_id(TW($input_port), false); - c.set_id(TW($output_port), false); - c.set_id(TW($public), false); + c.set_id(ID($anyinit), false); + c.set_id(ID($tribuf), false); + c.set_id(ID($_TBUF_), false); + c.set_id(ID($anyseq), false); + c.set_id(ID($anyconst), false); + c.set_id(ID($allseq), false); + c.set_id(ID($allconst), false); + c.set_id(ID($connect), false); + c.set_id(ID($input_port), false); + c.set_id(ID($output_port), false); + c.set_id(ID($public), false); if (nomux) { - c.set_id(TW($mux), false); - c.set_id(TW($pmux), false); + c.set_id(ID($mux), false); + c.set_id(ID($pmux), false); } return c; } diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc index 2b17a6c46..12df3decd 100644 --- a/passes/opt/opt_reduce.cc +++ b/passes/opt/opt_reduce.cc @@ -553,7 +553,7 @@ struct OptReduceWorker // merge trees of reduce_* cells to one single cell and unify input vectors // (only handle reduce_and and reduce_or for various reasons) - const IdString type_list[] = { TW($reduce_or), TW($reduce_and) }; + const TwineRef type_list[] = { TW($reduce_or), TW($reduce_and) }; for (auto type : type_list) { SigSet drivers; diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index a8cfc9040..f13de6c2e 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -108,18 +108,18 @@ bool cell_supported(RTLIL::Cell *cell) return false; } -std::map mergeable_type_map; +dict mergeable_type_map; bool mergeable(RTLIL::Cell *a, RTLIL::Cell *b) { if (mergeable_type_map.empty()) { mergeable_type_map.insert({TW($sub), TW($add)}); } - auto a_type = a->type; + TwineRef a_type = a->type.ref(); if (mergeable_type_map.count(a_type)) a_type = mergeable_type_map.at(a_type); - auto b_type = b->type; + TwineRef b_type = b->type.ref(); if (mergeable_type_map.count(b_type)) b_type = mergeable_type_map.at(b_type); @@ -564,7 +564,7 @@ struct OptSharePass : public Pass { log(" Found cells that share an operand and can be merged by moving the %s %s in front " "of " "them:\n", - design->twines.unescaped_str(shared.mux->type), shared.mux); + shared.mux->type.unescape(), shared.mux); for (const auto& op : shared.ports) log(" %s\n", op.op); log("\n"); diff --git a/passes/opt/peepopt_formal_clockgateff.pmg b/passes/opt/peepopt_formal_clockgateff.pmg index 0ac378870..0f442ed2a 100644 --- a/passes/opt/peepopt_formal_clockgateff.pmg +++ b/passes/opt/peepopt_formal_clockgateff.pmg @@ -34,8 +34,8 @@ match and_gate select param(and_gate, \A_WIDTH) == 1 select param(and_gate, \B_WIDTH) == 1 select param(and_gate, \Y_WIDTH) == 1 - choice clk_port {\A, \B} - define latch_port {clk_port == \A ? \B : \A} + choice clk_port {\A, \B} + define latch_port {clk_port == \A ? \B : \A} index port(and_gate, clk_port) === clk index port(and_gate, latch_port) === latched_en set gated_clk port(and_gate, \Y) diff --git a/passes/opt/peepopt_shiftadd.pmg b/passes/opt/peepopt_shiftadd.pmg index 6144e44ef..33be7b803 100644 --- a/passes/opt/peepopt_shiftadd.pmg +++ b/passes/opt/peepopt_shiftadd.pmg @@ -48,10 +48,10 @@ match add index port(add, \Y) === shift_amount // one must be constant, the other is variable - choice constport {\A, \B} + choice constport {\A, \B} select !port(add, constport).empty() select port(add, constport).is_fully_const() - define varport (constport == \A ? \B : \A) + define varport (constport == \A ? \B : \A) // only optimize for constants up to a fixed width. this prevents cases // with a blowup in internal term size and prevents larger constants being @@ -142,9 +142,9 @@ code new_b.append(State::S0); shift->setPort(\A, new_a); - shift->setParam(\A_WIDTH, GetSize(new_a)); + setparam(shift, \A_WIDTH, GetSize(new_a)); shift->setPort(\B, new_b); - shift->setParam(\B_WIDTH, GetSize(new_b)); + setparam(shift, \B_WIDTH, GetSize(new_b)); blacklist(add); accept; } diff --git a/passes/opt/peepopt_shiftmul_left.pmg b/passes/opt/peepopt_shiftmul_left.pmg index 4e08b2dd2..636c89a86 100644 --- a/passes/opt/peepopt_shiftmul_left.pmg +++ b/passes/opt/peepopt_shiftmul_left.pmg @@ -64,10 +64,10 @@ match mul index port(mul, \Y) === shift_amount filter !param(mul, \A_SIGNED).as_bool() - choice constport {\A, \B} + choice constport {\A, \B} filter port(mul, constport).is_fully_const() - define varport (constport == \A ? \B : \A) + define varport (constport == \A ? \B : \A) set mul_const SigSpec({port(mul, constport), SigSpec(State::S0, log2scale)}).as_const() // get mul_din unmapped (so no `port()` shorthand) // because we will be using it to set the \A port @@ -141,17 +141,17 @@ code SigSpec new_b = {mul_din, SigSpec(State::S0, factor_bits)}; shift->setPort(\Y, new_y); - shift->setParam(\Y_WIDTH, GetSize(new_y)); + setparam(shift, \Y_WIDTH, GetSize(new_y)); if (shift->type == $shl) { if (param(shift, \B_SIGNED).as_bool()) new_b.append(State::S0); shift->setPort(\B, new_b); - shift->setParam(\B_WIDTH, GetSize(new_b)); + setparam(shift, \B_WIDTH, GetSize(new_b)); } else { SigSpec b_neg = module->addWire(NEW_TWINE, GetSize(new_b) + 1); module->addNeg(NEW_TWINE, new_b, b_neg); shift->setPort(\B, b_neg); - shift->setParam(\B_WIDTH, GetSize(b_neg)); + setparam(shift, \B_WIDTH, GetSize(b_neg)); } blacklist(shift); diff --git a/passes/opt/peepopt_shiftmul_right.pmg b/passes/opt/peepopt_shiftmul_right.pmg index ac0958bb8..447b584b8 100644 --- a/passes/opt/peepopt_shiftmul_right.pmg +++ b/passes/opt/peepopt_shiftmul_right.pmg @@ -48,10 +48,10 @@ match mul index port(mul, \Y) === shift_amount filter !param(mul, \A_SIGNED).as_bool() - choice constport {\A, \B} + choice constport {\A, \B} filter port(mul, constport).is_fully_const() - define varport (constport == \A ? \B : \A) + define varport (constport == \A ? \B : \A) set mul_const SigSpec({port(mul, constport), SigSpec(State::S0, log2scale)}).as_const() // get mul_din unmapped (so no `port()` shorthand) // because we will be using it to set the \A port @@ -98,9 +98,9 @@ code new_b.append(State::S0); shift->setPort(\A, new_a); - shift->setParam(\A_WIDTH, GetSize(new_a)); + setparam(shift, \A_WIDTH, GetSize(new_a)); shift->setPort(\B, new_b); - shift->setParam(\B_WIDTH, GetSize(new_b)); + setparam(shift, \B_WIDTH, GetSize(new_b)); blacklist(shift); accept; diff --git a/passes/opt/rmports.cc b/passes/opt/rmports.cc index 3a39570b4..a62c04a1a 100644 --- a/passes/opt/rmports.cc +++ b/passes/opt/rmports.cc @@ -70,18 +70,14 @@ struct RmportsPassPass : public Pass { for(auto cell : cells) { if(removed_ports.find(cell->type) == removed_ports.end()) - { - // log(" Not touching instance \"%s\" because we didn't remove any ports from module \"%s\"\n", - // cell->name.c_str(), cell->type.c_str()); continue; - } auto ports_to_remove = removed_ports[cell->type]; for(auto p : ports_to_remove) { log(" Removing port \"%s\" from instance \"%s\"\n", p.c_str(), cell->type.c_str()); - cell->unsetPort(p); + cell->unsetPort(cell->module->design->twines.add(Twine{p.str()})); } } } @@ -90,7 +86,7 @@ struct RmportsPassPass : public Pass { { log("Finding unconnected ports in module %s\n", module->name); - pool used_ports; + pool used_ports; // See what wires are used. // Start by checking connections between named wires @@ -113,13 +109,11 @@ struct RmportsPassPass : public Pass { if( (w1 == NULL) || (w2 == NULL) ) continue; - //log(" conn %s, %s\n", w1->name, w2->name); + if( (w1->port_input || w1->port_output) && !used_ports.count(w1->name.ref()) ) + used_ports.insert(w1->name.ref()); - if( (w1->port_input || w1->port_output) && (used_ports.find(w1->name) == used_ports.end()) ) - used_ports.insert(w1->name); - - if( (w2->port_input || w2->port_output) && (used_ports.find(w2->name) == used_ports.end()) ) - used_ports.insert(w2->name); + if( (w2->port_input || w2->port_output) && !used_ports.count(w2->name.ref()) ) + used_ports.insert(w2->name.ref()); } } @@ -136,18 +130,17 @@ struct RmportsPassPass : public Pass { if(sig == NULL) continue; - // log(" sig %s\n", sig->name); - if( (sig->port_input || sig->port_output) && (used_ports.find(sig->name) == used_ports.end()) ) - used_ports.insert(sig->name); + if( (sig->port_input || sig->port_output) && !used_ports.count(sig->name.ref()) ) + used_ports.insert(sig->name.ref()); } } } // Now that we know what IS used, get rid of anything that isn't in that list - pool unused_ports; + pool unused_ports; for(auto port : module->ports) { - if(used_ports.find(port) != used_ports.end()) + if(used_ports.count(port)) continue; unused_ports.insert(port); } @@ -155,8 +148,9 @@ struct RmportsPassPass : public Pass { // Print the ports out as we go through them for(auto port : unused_ports) { - log(" removing unused port %s\n", port); - removed_ports[module->name].insert(port); + log(" removing unused port %s\n", module->design->twines.unescaped_str(port).data()); + IdString port_id(std::string(module->design->twines.str(port))); + removed_ports[module->name].insert(port_id); // Remove from ports list for(size_t i=0; iports.size(); i++) diff --git a/passes/opt/share.cc b/passes/opt/share.cc index 580c181a6..843fef993 100644 --- a/passes/opt/share.cc +++ b/passes/opt/share.cc @@ -1123,7 +1123,7 @@ struct ShareWorker for (auto &loop : toposort.loops) { log("### loop ###\n"); for (auto &c : loop) - log("%s (%s)\n", c, design->twines.unescaped_str(c->type)); + log("%s (%s)\n", c, c->type.unescape()); } return found_scc; @@ -1280,7 +1280,7 @@ struct ShareWorker for (auto other_cell : candidates) { - log(" Analyzing resource sharing with %s (%s):\n", other_cell, design->twines.unescaped_str(other_cell->type)); + log(" Analyzing resource sharing with %s (%s):\n", other_cell, other_cell->type.unescape()); const pool &other_cell_activation_patterns = find_cell_activation_patterns(other_cell, " "); RTLIL::SigSpec other_cell_activation_signals = bits_from_activation_patterns(other_cell_activation_patterns); @@ -1431,7 +1431,7 @@ struct ShareWorker log(" Activation signal for %s: %s\n", other_cell, log_signal(act)); } - log(" New cell: %s (%s)\n", supercell, design->twines.unescaped_str(supercell->type)); + log(" New cell: %s (%s)\n", supercell, supercell->type.unescape()); cells_to_remove.insert(cell); cells_to_remove.insert(other_cell); @@ -1478,7 +1478,7 @@ struct ShareWorker if (!cells_to_remove.empty()) { log("Removing %d cells in module %s:\n", GetSize(cells_to_remove), module); for (auto c : cells_to_remove) { - log(" Removing cell %s (%s).\n", c, design->twines.unescaped_str(c->type)); + log(" Removing cell %s (%s).\n", c, c->type.unescape()); remove_cell(c); } } @@ -1532,45 +1532,45 @@ struct SharePass : public Pass { config.opt_aggressive = false; config.opt_fast = false; - config.generic_uni_ops.set_id(TW($not)); - // config.generic_uni_ops.set_id(TW($pos)); - config.generic_uni_ops.set_id(TW($neg)); + config.generic_uni_ops.set_id(ID($not)); + // config.generic_uni_ops.set_id(ID($pos)); + config.generic_uni_ops.set_id(ID($neg)); - config.generic_cbin_ops.set_id(TW($and)); - config.generic_cbin_ops.set_id(TW($or)); - config.generic_cbin_ops.set_id(TW($xor)); - config.generic_cbin_ops.set_id(TW($xnor)); + config.generic_cbin_ops.set_id(ID($and)); + config.generic_cbin_ops.set_id(ID($or)); + config.generic_cbin_ops.set_id(ID($xor)); + config.generic_cbin_ops.set_id(ID($xnor)); - config.generic_bin_ops.set_id(TW($shl)); - config.generic_bin_ops.set_id(TW($shr)); - config.generic_bin_ops.set_id(TW($sshl)); - config.generic_bin_ops.set_id(TW($sshr)); + config.generic_bin_ops.set_id(ID($shl)); + config.generic_bin_ops.set_id(ID($shr)); + config.generic_bin_ops.set_id(ID($sshl)); + config.generic_bin_ops.set_id(ID($sshr)); - config.generic_bin_ops.set_id(TW($lt)); - config.generic_bin_ops.set_id(TW($le)); - config.generic_bin_ops.set_id(TW($eq)); - config.generic_bin_ops.set_id(TW($ne)); - config.generic_bin_ops.set_id(TW($eqx)); - config.generic_bin_ops.set_id(TW($nex)); - config.generic_bin_ops.set_id(TW($ge)); - config.generic_bin_ops.set_id(TW($gt)); + config.generic_bin_ops.set_id(ID($lt)); + config.generic_bin_ops.set_id(ID($le)); + config.generic_bin_ops.set_id(ID($eq)); + config.generic_bin_ops.set_id(ID($ne)); + config.generic_bin_ops.set_id(ID($eqx)); + config.generic_bin_ops.set_id(ID($nex)); + config.generic_bin_ops.set_id(ID($ge)); + config.generic_bin_ops.set_id(ID($gt)); - config.generic_cbin_ops.set_id(TW($add)); - config.generic_cbin_ops.set_id(TW($mul)); + config.generic_cbin_ops.set_id(ID($add)); + config.generic_cbin_ops.set_id(ID($mul)); - config.generic_bin_ops.set_id(TW($sub)); - config.generic_bin_ops.set_id(TW($div)); - config.generic_bin_ops.set_id(TW($mod)); - config.generic_bin_ops.set_id(TW($divfloor)); - config.generic_bin_ops.set_id(TW($modfloor)); - // config.generic_bin_ops.set_id(TW($pow)); + config.generic_bin_ops.set_id(ID($sub)); + config.generic_bin_ops.set_id(ID($div)); + config.generic_bin_ops.set_id(ID($mod)); + config.generic_bin_ops.set_id(ID($divfloor)); + config.generic_bin_ops.set_id(ID($modfloor)); + // config.generic_bin_ops.set_id(ID($pow)); - config.generic_uni_ops.set_id(TW($logic_not)); - config.generic_cbin_ops.set_id(TW($logic_and)); - config.generic_cbin_ops.set_id(TW($logic_or)); + config.generic_uni_ops.set_id(ID($logic_not)); + config.generic_cbin_ops.set_id(ID($logic_and)); + config.generic_cbin_ops.set_id(ID($logic_or)); - config.generic_other_ops.set_id(TW($alu)); - config.generic_other_ops.set_id(TW($macc)); + config.generic_other_ops.set_id(ID($alu)); + config.generic_other_ops.set_id(ID($macc)); log_header(design, "Executing SHARE pass (SAT-based resource sharing).\n"); diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index ca7f2a914..c9e3bfffa 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -616,7 +616,7 @@ struct WreducePass : public Pass { } if (original_a_width != GetSize(A)) { log("Removed top %d bits (of %d) from port A of cell %s.%s (%s).\n", - original_a_width-GetSize(A), original_a_width, module, c, design->twines.unescaped_str(c->type)); + original_a_width-GetSize(A), original_a_width, module, c, c->type.unescape()); c->setPort(TW::A, A); c->setParam(ID::A_WIDTH, GetSize(A)); } @@ -632,7 +632,7 @@ struct WreducePass : public Pass { } if (original_b_width != GetSize(B)) { log("Removed top %d bits (of %d) from port B of cell %s.%s (%s).\n", - original_b_width-GetSize(B), original_b_width, module, c, design->twines.unescaped_str(c->type)); + original_b_width-GetSize(B), original_b_width, module, c, c->type.unescape()); c->setPort(TW::B, B); c->setParam(ID::B_WIDTH, GetSize(B)); } diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index 3ecb85fe0..95f4ddf04 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -417,9 +417,9 @@ with open(outfile, "w") as f: for v, n in sorted(ids.items()): if n[0] == "\\": - print(" IdString {}{{\"\\{}\"}};".format(v, n), file=f) + print(" TwineRef {}{{TW({})}};".format(v, n[1:]), file=f) else: - print(" IdString {}{{\"{}\"}};".format(v, n), file=f) + print(" TwineRef {}{{TW({})}};".format(v, n), file=f) print("", file=f) print(" void add_siguser(const SigSpec &sig, Cell *cell) {", file=f) @@ -467,12 +467,22 @@ with open(outfile, "w") as f: print(" return cell->getParam(paramname);", file=f) print(" } catch(std::out_of_range&) { log_error(\"Accessing non existing parameter %s\\n\",paramname); }", file=f) print(" }", file=f) + print(" Const param(Cell *cell, TwineRef paramname) {", file=f) + print(" return param(cell, IdString(std::string(module->design->twines.str(paramname))));", file=f) + print(" }", file=f) print("", file=f) print(" Const param(Cell *cell, IdString paramname, const Const& defval) {", file=f) print(" return cell->parameters.at(paramname, defval);", file=f) print(" }", file=f) + print(" Const param(Cell *cell, TwineRef paramname, const Const& defval) {", file=f) + print(" return param(cell, IdString(std::string(module->design->twines.str(paramname))), defval);", file=f) + print(" }", file=f) print("", file=f) + print(" void setparam(Cell *cell, TwineRef param, const Const& val) {", file=f) + print(" cell->setParam(IdString(std::string(module->design->twines.str(param))), val);", file=f) + print(" }", file=f) + print("", file=f) print(" int nusers(const SigSpec &sig) {", file=f) print(" pool users;", file=f) print(" for (auto bit : (*sigmap)(sig))", file=f) diff --git a/passes/pmgen/test_pmgen.pmg b/passes/pmgen/test_pmgen.pmg index c7b5ce539..ceb493262 100644 --- a/passes/pmgen/test_pmgen.pmg +++ b/passes/pmgen/test_pmgen.pmg @@ -115,8 +115,8 @@ state pmux_slice_eq pmux_slice_ne match eq select eq->type == $eq - choice AB {\A, \B} - define BA AB == \A ? \B : \A + choice AB {\A, \B} + define BA AB == \A ? \B : \A set eq_inA port(eq, \A) set eq_inB port(eq, \B) set eq_ne_signed param(eq, \A_SIGNED).as_bool() @@ -151,8 +151,8 @@ endmatch match ne select ne->type == $ne - choice AB {\A, \B} - define BA (AB == \A ? \B : \A) + choice AB {\A, \B} + define BA (AB == \A ? \B : \A) index port(ne, AB) === eq_inA index port(ne, BA) === eq_inB index param(ne, \A_SIGNED).as_bool() === eq_ne_signed diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index 1361cc50d..45555599e 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -215,7 +215,7 @@ void proc_arst(RTLIL::Module *mod, RTLIL::Process *proc, SigMap &assign_map) RTLIL::SigSpec en = apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.enable, memwr.enable); if (!en.is_fully_zero()) { log_error("Async reset %s causes memory write to %s.\n", - log_signal(sync->signal), design->twines.unescaped_str(memwr.memid)); + log_signal(sync->signal), log_id(memwr.memid)); } apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.address, memwr.address); apply_reset(mod, proc, sync, assign_map, root_sig, polarity, memwr.data, memwr.data); diff --git a/passes/sat/supercover.cc b/passes/sat/supercover.cc index 6e5e77163..b6a0e815b 100644 --- a/passes/sat/supercover.cc +++ b/passes/sat/supercover.cc @@ -68,7 +68,7 @@ struct SupercoverPass : public Pass { for (auto wire : module->selected_wires()) { bool counted_wire = false; - std::string src = wire->get_src_attribute(); + Twine src{wire->get_src_attribute()}; for (auto bit : sigmap(SigSpec(wire))) { diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index 259c32cd1..62e0199b1 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -55,31 +55,31 @@ static void logmap(IdString dff) static void logmap_all() { - logmap(TW($_DFF_N_)); - logmap(TW($_DFF_P_)); + logmap(ID($_DFF_N_)); + logmap(ID($_DFF_P_)); - logmap(TW($_DFF_NN0_)); - logmap(TW($_DFF_NN1_)); - logmap(TW($_DFF_NP0_)); - logmap(TW($_DFF_NP1_)); - logmap(TW($_DFF_PN0_)); - logmap(TW($_DFF_PN1_)); - logmap(TW($_DFF_PP0_)); - logmap(TW($_DFF_PP1_)); + logmap(ID($_DFF_NN0_)); + logmap(ID($_DFF_NN1_)); + logmap(ID($_DFF_NP0_)); + logmap(ID($_DFF_NP1_)); + logmap(ID($_DFF_PN0_)); + logmap(ID($_DFF_PN1_)); + logmap(ID($_DFF_PP0_)); + logmap(ID($_DFF_PP1_)); - logmap(TW($_DFFE_NN_)); - logmap(TW($_DFFE_NP_)); - logmap(TW($_DFFE_PN_)); - logmap(TW($_DFFE_PP_)); + logmap(ID($_DFFE_NN_)); + logmap(ID($_DFFE_NP_)); + logmap(ID($_DFFE_PN_)); + logmap(ID($_DFFE_PP_)); - logmap(TW($_DFFSR_NNN_)); - logmap(TW($_DFFSR_NNP_)); - logmap(TW($_DFFSR_NPN_)); - logmap(TW($_DFFSR_NPP_)); - logmap(TW($_DFFSR_PNN_)); - logmap(TW($_DFFSR_PNP_)); - logmap(TW($_DFFSR_PPN_)); - logmap(TW($_DFFSR_PPP_)); + logmap(ID($_DFFSR_NNN_)); + logmap(ID($_DFFSR_NNP_)); + logmap(ID($_DFFSR_NPN_)); + logmap(ID($_DFFSR_NPP_)); + logmap(ID($_DFFSR_PNN_)); + logmap(ID($_DFFSR_PNP_)); + logmap(ID($_DFFSR_PPN_)); + logmap(ID($_DFFSR_PPP_)); } static bool parse_next_state(const LibertyAst *cell, const LibertyAst *attr, std::string &data_name, bool &data_not_inverted, std::string &enable_name, bool &enable_not_inverted) @@ -504,14 +504,17 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) for (auto cell : module->cells()) { if (design->selected(module, cell) && cell_mappings.count(cell->type) > 0) cell_list.push_back(cell); - if (cell->type == TW($_NOT_)) + if (cell->type.in(TwineRef{TW($_NOT_)})) notmap[sigmap(cell->getPort(TW::A))].insert(cell); } + auto &twines = module->design->twines; + auto conn_key = [&](char c) { return twines.add(Twine{std::string("\\") + c}); }; + std::map stats; for (auto cell : cell_list) { - auto cell_type = cell->type; + IdString cell_type = cell->type; RTLIL::IdString cell_name(cell->name); auto cell_connections = cell->connections(); std::string src = cell->get_src_attribute(); @@ -519,7 +522,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) module->remove(cell); cell_mapping &cm = cell_mappings[cell_type]; - RTLIL::Cell *new_cell = module->addCell(cell_name, cm.cell_name); + RTLIL::Cell *new_cell = module->addCell(Twine{cell_name.str()}, twines.add(Twine{cm.cell_name.str()})); new_cell->set_src_attribute(src); @@ -532,10 +535,10 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) for (auto &port : cm.ports) { RTLIL::SigSpec sig; if ('A' <= port.second && port.second <= 'Z') { - sig = cell_connections[std::string("\\") + port.second]; + sig = cell_connections[conn_key(port.second)]; } else if (port.second == 'q') { - RTLIL::SigSpec old_sig = cell_connections[std::string("\\") + char(port.second - ('a' - 'A'))]; + RTLIL::SigSpec old_sig = cell_connections[conn_key(char(port.second - ('a' - 'A')))]; sig = module->addWire(NEW_TWINE, GetSize(old_sig)); if (has_q && has_qn) { for (auto &it : notmap[sigmap(old_sig)]) { @@ -547,7 +550,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) } } else if ('a' <= port.second && port.second <= 'z') { - sig = cell_connections[std::string("\\") + char(port.second - ('a' - 'A'))]; + sig = cell_connections[conn_key(char(port.second - ('a' - 'A')))]; sig = module->NotGate(NEW_TWINE, sig); } else if (port.second == '0' || port.second == '1') { @@ -557,10 +560,10 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) sig = module->addWire(NEW_TWINE); } else log_abort(); - new_cell->setPort("\\" + port.first, sig); + new_cell->setPort(twines.add(Twine{"\\" + port.first}), sig); } - stats[stringf("%s cells to %s cells", cell_type, new_cell->type)]++; + stats[stringf("%s cells to %s cells", cell_type.c_str(), new_cell->type.unescape())]++; } for (auto &stat: stats) @@ -660,31 +663,31 @@ struct DfflibmapPass : public Pass { delete f; } - find_cell(merged.cells, TW($_DFF_N_), false, false, false, false, false, false, dont_use_cells); - find_cell(merged.cells, TW($_DFF_P_), true, false, false, false, false, false, dont_use_cells); + find_cell(merged.cells, ID($_DFF_N_), false, false, false, false, false, false, dont_use_cells); + find_cell(merged.cells, ID($_DFF_P_), true, false, false, false, false, false, dont_use_cells); - find_cell(merged.cells, TW($_DFF_NN0_), false, true, false, false, false, false, dont_use_cells); - find_cell(merged.cells, TW($_DFF_NN1_), false, true, false, true, false, false, dont_use_cells); - find_cell(merged.cells, TW($_DFF_NP0_), false, true, true, false, false, false, dont_use_cells); - find_cell(merged.cells, TW($_DFF_NP1_), false, true, true, true, false, false, dont_use_cells); - find_cell(merged.cells, TW($_DFF_PN0_), true, true, false, false, false, false, dont_use_cells); - find_cell(merged.cells, TW($_DFF_PN1_), true, true, false, true, false, false, dont_use_cells); - find_cell(merged.cells, TW($_DFF_PP0_), true, true, true, false, false, false, dont_use_cells); - find_cell(merged.cells, TW($_DFF_PP1_), true, true, true, true, false, false, dont_use_cells); + find_cell(merged.cells, ID($_DFF_NN0_), false, true, false, false, false, false, dont_use_cells); + find_cell(merged.cells, ID($_DFF_NN1_), false, true, false, true, false, false, dont_use_cells); + find_cell(merged.cells, ID($_DFF_NP0_), false, true, true, false, false, false, dont_use_cells); + find_cell(merged.cells, ID($_DFF_NP1_), false, true, true, true, false, false, dont_use_cells); + find_cell(merged.cells, ID($_DFF_PN0_), true, true, false, false, false, false, dont_use_cells); + find_cell(merged.cells, ID($_DFF_PN1_), true, true, false, true, false, false, dont_use_cells); + find_cell(merged.cells, ID($_DFF_PP0_), true, true, true, false, false, false, dont_use_cells); + find_cell(merged.cells, ID($_DFF_PP1_), true, true, true, true, false, false, dont_use_cells); - find_cell(merged.cells, TW($_DFFE_NN_), false, false, false, false, true, false, dont_use_cells); - find_cell(merged.cells, TW($_DFFE_NP_), false, false, false, false, true, true, dont_use_cells); - find_cell(merged.cells, TW($_DFFE_PN_), true, false, false, false, true, false, dont_use_cells); - find_cell(merged.cells, TW($_DFFE_PP_), true, false, false, false, true, true, dont_use_cells); + find_cell(merged.cells, ID($_DFFE_NN_), false, false, false, false, true, false, dont_use_cells); + find_cell(merged.cells, ID($_DFFE_NP_), false, false, false, false, true, true, dont_use_cells); + find_cell(merged.cells, ID($_DFFE_PN_), true, false, false, false, true, false, dont_use_cells); + find_cell(merged.cells, ID($_DFFE_PP_), true, false, false, false, true, true, dont_use_cells); - find_cell_sr(merged.cells, TW($_DFFSR_NNN_), false, false, false, false, false, dont_use_cells); - find_cell_sr(merged.cells, TW($_DFFSR_NNP_), false, false, true, false, false, dont_use_cells); - find_cell_sr(merged.cells, TW($_DFFSR_NPN_), false, true, false, false, false, dont_use_cells); - find_cell_sr(merged.cells, TW($_DFFSR_NPP_), false, true, true, false, false, dont_use_cells); - find_cell_sr(merged.cells, TW($_DFFSR_PNN_), true, false, false, false, false, dont_use_cells); - find_cell_sr(merged.cells, TW($_DFFSR_PNP_), true, false, true, false, false, dont_use_cells); - find_cell_sr(merged.cells, TW($_DFFSR_PPN_), true, true, false, false, false, dont_use_cells); - find_cell_sr(merged.cells, TW($_DFFSR_PPP_), true, true, true, false, false, dont_use_cells); + find_cell_sr(merged.cells, ID($_DFFSR_NNN_), false, false, false, false, false, dont_use_cells); + find_cell_sr(merged.cells, ID($_DFFSR_NNP_), false, false, true, false, false, dont_use_cells); + find_cell_sr(merged.cells, ID($_DFFSR_NPN_), false, true, false, false, false, dont_use_cells); + find_cell_sr(merged.cells, ID($_DFFSR_NPP_), false, true, true, false, false, dont_use_cells); + find_cell_sr(merged.cells, ID($_DFFSR_PNN_), true, false, false, false, false, dont_use_cells); + find_cell_sr(merged.cells, ID($_DFFSR_PNP_), true, false, true, false, false, dont_use_cells); + find_cell_sr(merged.cells, ID($_DFFSR_PPN_), true, true, false, false, false, dont_use_cells); + find_cell_sr(merged.cells, ID($_DFFSR_PPP_), true, true, true, false, false, dont_use_cells); log(" final dff cell mappings:\n"); logmap_all(); diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 1963438de..9122d7c19 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -86,18 +86,18 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_b = cell->getPort(TW::B); RTLIL::SigSpec sig_y = cell->getPort(TW::Y); - if (cell->type != TW($bweqx)) { + if (!cell->type.in(TwineRef{TW($bweqx)})) { sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID::A_SIGNED).as_bool()); sig_b.extend_u0(GetSize(sig_y), cell->parameters.at(ID::B_SIGNED).as_bool()); } - IdString gate_type; - if (cell->type == TW($and)) gate_type = TW($_AND_); - if (cell->type == TW($or)) gate_type = TW($_OR_); - if (cell->type == TW($xor)) gate_type = TW($_XOR_); - if (cell->type == TW($xnor)) gate_type = TW($_XNOR_); - if (cell->type == TW($bweqx)) gate_type = TW($_XNOR_); - log_assert(!gate_type.empty()); + TwineRef gate_type; + if (cell->type.in(TwineRef{TW($and)})) gate_type = TwineRef{TW($_AND_)}; + if (cell->type.in(TwineRef{TW($or)})) gate_type = TwineRef{TW($_OR_)}; + if (cell->type.in(TwineRef{TW($xor)})) gate_type = TwineRef{TW($_XOR_)}; + if (cell->type.in(TwineRef{TW($xnor)})) gate_type = TwineRef{TW($_XNOR_)}; + if (cell->type.in(TwineRef{TW($bweqx)})) gate_type = TwineRef{TW($_XNOR_)}; + log_assert(gate_type != TwineRef{}); for (int i = 0; i < GetSize(sig_y); i++) { RTLIL::Cell *gate = module->addCell(NEW_TWINE, gate_type); @@ -117,11 +117,11 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) return; if (sig_a.size() == 0) { - if (cell->type == TW($reduce_and)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); - if (cell->type == TW($reduce_or)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); - if (cell->type == TW($reduce_xor)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); - if (cell->type == TW($reduce_xnor)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); - if (cell->type == TW($reduce_bool)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type.in(TwineRef{TW($reduce_and)})) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); + if (cell->type.in(TwineRef{TW($reduce_or)})) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type.in(TwineRef{TW($reduce_xor)})) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); + if (cell->type.in(TwineRef{TW($reduce_xnor)})) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); + if (cell->type.in(TwineRef{TW($reduce_bool)})) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); return; } @@ -130,13 +130,13 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) sig_y = sig_y.extract(0, 1); } - IdString gate_type; - if (cell->type == TW($reduce_and)) gate_type = TW($_AND_); - if (cell->type == TW($reduce_or)) gate_type = TW($_OR_); - if (cell->type == TW($reduce_xor)) gate_type = TW($_XOR_); - if (cell->type == TW($reduce_xnor)) gate_type = TW($_XOR_); - if (cell->type == TW($reduce_bool)) gate_type = TW($_OR_); - log_assert(!gate_type.empty()); + TwineRef gate_type; + if (cell->type.in(TwineRef{TW($reduce_and)})) gate_type = TwineRef{TW($_AND_)}; + if (cell->type.in(TwineRef{TW($reduce_or)})) gate_type = TwineRef{TW($_OR_)}; + if (cell->type.in(TwineRef{TW($reduce_xor)})) gate_type = TwineRef{TW($_XOR_)}; + if (cell->type.in(TwineRef{TW($reduce_xnor)})) gate_type = TwineRef{TW($_XOR_)}; + if (cell->type.in(TwineRef{TW($reduce_bool)})) gate_type = TwineRef{TW($_OR_)}; + log_assert(gate_type != TwineRef{}); RTLIL::Cell *last_output_cell = NULL; @@ -162,7 +162,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell) sig_a = sig_t; } - if (cell->type == TW($reduce_xnor)) { + if (cell->type.in(TwineRef{TW($reduce_xnor)})) { RTLIL::SigSpec sig_t = module->addWire(NEW_TWINE); RTLIL::Cell *gate = module->addCell(NEW_TWINE, TW($_NOT_)); transfer_src(gate, cell); @@ -245,10 +245,10 @@ void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell) sig_y = sig_y.extract(0, 1); } - IdString gate_type; - if (cell->type == TW($logic_and)) gate_type = TW($_AND_); - if (cell->type == TW($logic_or)) gate_type = TW($_OR_); - log_assert(!gate_type.empty()); + TwineRef gate_type; + if (cell->type.in(TwineRef{TW($logic_and)})) gate_type = TwineRef{TW($_AND_)}; + if (cell->type.in(TwineRef{TW($logic_or)})) gate_type = TwineRef{TW($_OR_)}; + log_assert(gate_type != TwineRef{}); RTLIL::Cell *gate = module->addCell(NEW_TWINE, gate_type); transfer_src(gate, cell); @@ -263,7 +263,7 @@ void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell) RTLIL::SigSpec sig_b = cell->getPort(TW::B); RTLIL::SigSpec sig_y = cell->getPort(TW::Y); bool is_signed = cell->parameters.at(ID::A_SIGNED).as_bool(); - bool is_ne = cell->type.in(TW($ne), TW($nex)); + bool is_ne = cell->type.in(TwineRef{TW($ne)}, TwineRef{TW($nex)}); RTLIL::SigSpec xor_out = module->addWire(NEW_TWINE, max(GetSize(sig_a), GetSize(sig_b))); RTLIL::Cell *xor_cell = module->addXor(NEW_TWINE, sig_a, sig_b, xor_out, is_signed); @@ -479,51 +479,51 @@ void simplemap_pmux(RTLIL::Module *module, RTLIL::Cell *cell) void simplemap_get_mappers(dict &mappers) { - mappers[TW($not)] = simplemap_not; - mappers[TW($pos)] = simplemap_pos; - mappers[TW($buf)] = simplemap_buf; - mappers[TW($and)] = simplemap_bitop; - mappers[TW($or)] = simplemap_bitop; - mappers[TW($xor)] = simplemap_bitop; - mappers[TW($xnor)] = simplemap_bitop; - mappers[TW($bweqx)] = simplemap_bitop; - mappers[TW($reduce_and)] = simplemap_reduce; - mappers[TW($reduce_or)] = simplemap_reduce; - mappers[TW($reduce_xor)] = simplemap_reduce; - mappers[TW($reduce_xnor)] = simplemap_reduce; - mappers[TW($reduce_bool)] = simplemap_reduce; - mappers[TW($logic_not)] = simplemap_lognot; - mappers[TW($logic_and)] = simplemap_logbin; - mappers[TW($logic_or)] = simplemap_logbin; - mappers[TW($eq)] = simplemap_eqne; - mappers[TW($eqx)] = simplemap_eqne; - mappers[TW($ne)] = simplemap_eqne; - mappers[TW($nex)] = simplemap_eqne; - mappers[TW($mux)] = simplemap_mux; - mappers[TW($pmux)] = simplemap_pmux; - mappers[TW($bwmux)] = simplemap_bwmux; - mappers[TW($tribuf)] = simplemap_tribuf; - mappers[TW($bmux)] = simplemap_bmux; - mappers[TW($lut)] = simplemap_lut; - mappers[TW($sop)] = simplemap_sop; - mappers[TW($slice)] = simplemap_slice; - mappers[TW($concat)] = simplemap_concat; - mappers[TW($sr)] = simplemap_ff; - mappers[TW($ff)] = simplemap_ff; - mappers[TW($dff)] = simplemap_ff; - mappers[TW($dffe)] = simplemap_ff; - mappers[TW($dffsr)] = simplemap_ff; - mappers[TW($dffsre)] = simplemap_ff; - mappers[TW($adff)] = simplemap_ff; - mappers[TW($sdff)] = simplemap_ff; - mappers[TW($adffe)] = simplemap_ff; - mappers[TW($sdffe)] = simplemap_ff; - mappers[TW($sdffce)] = simplemap_ff; - mappers[TW($aldff)] = simplemap_ff; - mappers[TW($aldffe)] = simplemap_ff; - mappers[TW($dlatch)] = simplemap_ff; - mappers[TW($adlatch)] = simplemap_ff; - mappers[TW($dlatchsr)] = simplemap_ff; + mappers[ID($not)] = simplemap_not; + mappers[ID($pos)] = simplemap_pos; + mappers[ID($buf)] = simplemap_buf; + mappers[ID($and)] = simplemap_bitop; + mappers[ID($or)] = simplemap_bitop; + mappers[ID($xor)] = simplemap_bitop; + mappers[ID($xnor)] = simplemap_bitop; + mappers[ID($bweqx)] = simplemap_bitop; + mappers[ID($reduce_and)] = simplemap_reduce; + mappers[ID($reduce_or)] = simplemap_reduce; + mappers[ID($reduce_xor)] = simplemap_reduce; + mappers[ID($reduce_xnor)] = simplemap_reduce; + mappers[ID($reduce_bool)] = simplemap_reduce; + mappers[ID($logic_not)] = simplemap_lognot; + mappers[ID($logic_and)] = simplemap_logbin; + mappers[ID($logic_or)] = simplemap_logbin; + mappers[ID($eq)] = simplemap_eqne; + mappers[ID($eqx)] = simplemap_eqne; + mappers[ID($ne)] = simplemap_eqne; + mappers[ID($nex)] = simplemap_eqne; + mappers[ID($mux)] = simplemap_mux; + mappers[ID($pmux)] = simplemap_pmux; + mappers[ID($bwmux)] = simplemap_bwmux; + mappers[ID($tribuf)] = simplemap_tribuf; + mappers[ID($bmux)] = simplemap_bmux; + mappers[ID($lut)] = simplemap_lut; + mappers[ID($sop)] = simplemap_sop; + mappers[ID($slice)] = simplemap_slice; + mappers[ID($concat)] = simplemap_concat; + mappers[ID($sr)] = simplemap_ff; + mappers[ID($ff)] = simplemap_ff; + mappers[ID($dff)] = simplemap_ff; + mappers[ID($dffe)] = simplemap_ff; + mappers[ID($dffsr)] = simplemap_ff; + mappers[ID($dffsre)] = simplemap_ff; + mappers[ID($adff)] = simplemap_ff; + mappers[ID($sdff)] = simplemap_ff; + mappers[ID($adffe)] = simplemap_ff; + mappers[ID($sdffe)] = simplemap_ff; + mappers[ID($sdffce)] = simplemap_ff; + mappers[ID($aldff)] = simplemap_ff; + mappers[ID($aldffe)] = simplemap_ff; + mappers[ID($dlatch)] = simplemap_ff; + mappers[ID($adlatch)] = simplemap_ff; + mappers[ID($dlatchsr)] = simplemap_ff; } void simplemap(RTLIL::Module *module, RTLIL::Cell *cell) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 2d146c0ee..26babd5da 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -54,8 +54,9 @@ void apply_prefix(IdString prefix, RTLIL::SigSpec &sig, RTLIL::Module *module) if (chunk.wire != nullptr) { IdString wire_name = chunk.wire->name; apply_prefix(prefix, wire_name); - log_assert(module->wire(wire_name) != nullptr); - chunk.wire = module->wire(wire_name); + TwineRef wire_ref = module->design->twines.add(Twine{wire_name.str()}); + log_assert(module->wire(wire_ref) != nullptr); + chunk.wire = module->wire(wire_ref); } sig = chunks; } @@ -86,28 +87,29 @@ struct TechmapWorker std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose) { std::string constmap_info; - dict> connbits_map; + auto &twines = cell->module->design->twines; + dict> connbits_map; for (auto &conn : cell->connections()) for (int i = 0; i < GetSize(conn.second); i++) { RTLIL::SigBit bit = sigmap(conn.second[i]); if (bit.wire == nullptr) { if (verbose) - log(" Constant input on bit %d of port %s: %s\n", i, design->twines.unescaped_str(conn.first), log_signal(bit)); - constmap_info += stringf("|%s %d %d", design->twines.unescaped_str(conn.first), i, bit.data); + log(" Constant input on bit %d of port %s: %s\n", i, twines.unescaped_str(conn.first).data(), log_signal(bit)); + constmap_info += stringf("|%s %d %d", twines.unescaped_str(conn.first).data(), i, bit.data); } else if (connbits_map.count(bit)) { if (verbose) - log(" Bit %d of port %s and bit %d of port %s are connected.\n", i, design->twines.unescaped_str(conn.first), - connbits_map.at(bit).second, design->twines.unescaped_str(connbits_map.at(bit).first)); - constmap_info += stringf("|%s %d %s %d", design->twines.unescaped_str(conn.first), i, - connbits_map.at(bit).first.unescape(), connbits_map.at(bit).second); + log(" Bit %d of port %s and bit %d of port %s are connected.\n", i, twines.unescaped_str(conn.first).data(), + connbits_map.at(bit).second, twines.unescaped_str(connbits_map.at(bit).first).data()); + constmap_info += stringf("|%s %d %s %d", twines.unescaped_str(conn.first).data(), i, + twines.unescaped_str(connbits_map.at(bit).first).data(), connbits_map.at(bit).second); } else { connbits_map.emplace(bit, std::make_pair(conn.first, i)); - constmap_info += stringf("|%s %d", design->twines.unescaped_str(conn.first), i); + constmap_info += stringf("|%s %d", twines.unescaped_str(conn.first).data(), i); } } - return stringf("$paramod$constmap:%s%s", sha1(constmap_info), tpl->name); + return stringf("$paramod$constmap:%s%s", sha1(constmap_info), log_id(tpl->name)); } TechmapWires techmap_find_special_wires(RTLIL::Module *module) @@ -146,7 +148,7 @@ struct TechmapWorker if (tpl->processes.size() != 0) { log("Technology map yielded processes:"); for (auto &it : tpl->processes) - log(" design->twines.unescaped_str(%s",it.first)); + log(" %s", tpl->design->twines.unescaped_str(it.first).data()); log("\n"); if (autoproc_mode) { Pass::call_on_module(tpl->design, tpl, "proc"); @@ -166,36 +168,38 @@ struct TechmapWorker orig_cell_name = cell->name.str(); for (auto tpl_cell : tpl->cells()) if (tpl_cell->name.ends_with("_TECHMAP_REPLACE_")) { - module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str()); + module->rename(cell, module->design->twines.add(Twine{stringf("$techmap%d", autoidx++) + cell->name.str()})); break; } dict memory_renames; for (auto &it : tpl->memories) { - IdString m_name = it.first; - apply_prefix(cell->name, m_name); - RTLIL::Memory *m = module->addMemory(m_name, it.second); + IdString old_m_id(std::string(tpl->design->twines.str(it.first))); + IdString m_name_id = old_m_id; + apply_prefix(cell->name, m_name_id); + TwineRef m_ref = module->design->twines.add(Twine{m_name_id.str()}); + RTLIL::Memory *m = module->addMemory(m_ref, it.second); if (m->has_attribute(ID::src)) design->merge_src(m, src_cell); - memory_renames[it.first] = m->name; + memory_renames[old_m_id] = m_name_id; design->select(module, m); } - dict positional_ports; - dict temp_renamed_wires; + dict positional_ports; + dict temp_renamed_wires; pool autopurge_tpl_bits; for (auto tpl_w : tpl->wires()) { if (tpl_w->port_id > 0) { - IdString posportname = stringf("$%d", tpl_w->port_id); - positional_ports.emplace(posportname, tpl_w->name); + TwineRef posportref = module->design->twines.add(Twine{stringf("$%d", tpl_w->port_id)}); + positional_ports.emplace(posportref, tpl_w->name.ref()); if (tpl_w->get_bool_attribute(ID::techmap_autopurge) && - (!cell->hasPort(tpl_w->name) || !GetSize(cell->getPort(tpl_w->name))) && - (!cell->hasPort(posportname) || !GetSize(cell->getPort(posportname)))) + (!cell->hasPort(tpl_w->name.ref()) || !GetSize(cell->getPort(tpl_w->name.ref()))) && + (!cell->hasPort(posportref) || !GetSize(cell->getPort(posportref)))) { if (sigmaps.count(tpl) == 0) sigmaps[tpl].set(tpl); @@ -207,14 +211,15 @@ struct TechmapWorker } IdString w_name = tpl_w->name; apply_prefix(cell->name, w_name); - RTLIL::Wire *w = module->wire(w_name); + TwineRef w_ref = module->design->twines.add(Twine{w_name.str()}); + RTLIL::Wire *w = module->wire(w_ref); if (w != nullptr) { - temp_renamed_wires[w] = w->name; - module->rename(w, NEW_ID); + temp_renamed_wires[w] = w->name.ref(); + module->rename(w, module->design->twines.add(NEW_TWINE)); w = nullptr; } if (w == nullptr) { - w = module->addWire(w_name, tpl_w); + w = module->addWire(Twine{w_name.str()}, tpl_w); w->port_input = false; w->port_output = false; w->port_id = 0; @@ -227,8 +232,7 @@ struct TechmapWorker design->select(module, w); if (const char *p = strstr(tpl_w->name.c_str(), "_TECHMAP_REPLACE_.")) { - IdString replace_name = stringf("%s%s", orig_cell_name, p + strlen("_TECHMAP_REPLACE_")); - Wire *replace_w = module->addWire(replace_name, tpl_w); + Wire *replace_w = module->addWire(Twine{std::string(orig_cell_name) + (p + strlen("_TECHMAP_REPLACE_"))}, tpl_w); module->connect(replace_w, w); } } @@ -251,8 +255,8 @@ struct TechmapWorker if (positional_ports.count(portname) > 0) portname = positional_ports.at(portname); if (tpl->wire(portname) == nullptr || tpl->wire(portname)->port_id == 0) { - if (portname.begins_with("$")) - log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", portname, cell->name, tpl->name); + if (design->twines.str(portname).starts_with("$")) + log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", design->twines.unescaped_str(portname).data(), log_id(cell->name), log_id(tpl->name)); continue; } @@ -336,15 +340,15 @@ struct TechmapWorker else apply_prefix(cell->name, c_name); - RTLIL::Cell *c = module->addCell(c_name, tpl_cell); + RTLIL::Cell *c = module->addCell(module->design->twines.add(Twine{c_name.str()}), tpl_cell); design->select(module, c); - - if (c->type == ID::_TECHMAP_PLACEHOLDER_ && tpl_cell->has_attribute(ID::techmap_chtype)) { - c->type = RTLIL::escape_id(tpl_cell->get_string_attribute(ID::techmap_chtype)); + + if (c->type.in(TwineRef{TW(_TECHMAP_PLACEHOLDER_)}) && tpl_cell->has_attribute(ID::techmap_chtype)) { + c->type_impl = module->design->twines.add(Twine{RTLIL::escape_id(tpl_cell->get_string_attribute(ID::techmap_chtype))}); c->attributes.erase(ID::techmap_chtype); } - vector autopurge_ports; + vector autopurge_ports; for (auto &conn : c->connections()) { @@ -406,8 +410,8 @@ struct TechmapWorker for (auto &it : temp_renamed_wires) { Wire *w = it.first; - IdString name = it.second; - IdString altname = module->uniquify(name); + TwineRef name = it.second; + TwineRef altname = module->uniquify(name); Wire *other_w = module->wire(name); module->rename(other_w, altname); module->rename(w, name); @@ -476,12 +480,12 @@ struct TechmapWorker for (auto cell : cells.sorted) { log_assert(handled_cells.count(cell) == 0); - log_assert(cell == module->cell(cell->name)); + log_assert(cell == module->cell(cell->name.ref())); bool mapped_cell = false; for (auto &tpl_name : celltypeMap.at(cell->type)) { - IdString derived_name = tpl_name; + TwineRef derived_name = map->twines.add(Twine{tpl_name.str()}); RTLIL::Module *tpl = map->module(tpl_name); dict parameters(cell->parameters); @@ -506,18 +510,18 @@ struct TechmapWorker std::string m_name = stringf("$extern:%s:%s", extmapper_name, cell->type.unescaped()); for (auto &c : cell->parameters) - m_name += stringf(":%s=%s", design->twines.unescaped_str(c.first), log_signal(c.second)); + m_name += stringf(":%s=%s", log_id(c.first), log_signal(c.second)); if (extmapper_name == "wrap") m_name += ":" + sha1(tpl->attributes.at(ID::techmap_wrap).decode_string()); RTLIL::Design *extmapper_design = extern_mode && !in_recursion ? design : tpl->design; - RTLIL::Module *extmapper_module = extmapper_design->module(m_name); + RTLIL::Module *extmapper_module = extmapper_design->module(IdString(m_name)); if (extmapper_module == nullptr) { - extmapper_module = extmapper_design->addModule(m_name); - RTLIL::Cell *extmapper_cell = extmapper_module->addCell(cell->type, cell); + extmapper_module = extmapper_design->addModule(extmapper_design->twines.add(Twine{m_name})); + RTLIL::Cell *extmapper_cell = extmapper_module->addCell(cell->type.ref(), cell); // addCell(name, cell) already migrated src across // designs via copy_src_into — no need for an // explicit set_src_attribute round-trip here. @@ -525,7 +529,7 @@ struct TechmapWorker int port_counter = 1; for (auto &c : extmapper_cell->connections_) { RTLIL::Wire *w = extmapper_module->addWire(c.first, GetSize(c.second)); - if (w->name.in(ID::Y, ID::Q)) + if (w->name.in(TwineRef{TW(Y)}, TwineRef{TW(Q)})) w->port_output = true; else w->port_input = true; @@ -537,24 +541,24 @@ struct TechmapWorker extmapper_module->check(); if (extmapper_name == "simplemap") { - log("Creating %s with simplemap.\n", extmapper_module); + log("Creating %s with simplemap.\n", log_id(extmapper_module->name)); if (simplemap_mappers.count(extmapper_cell->type) == 0) - log_error("No simplemap mapper for cell type %s found!\n", design->twines.unescaped_str(extmapper_cell->type)); + log_error("No simplemap mapper for cell type %s found!\n", extmapper_cell->type.unescape()); simplemap_mappers.at(extmapper_cell->type)(extmapper_module, extmapper_cell); extmapper_module->remove(extmapper_cell); } if (extmapper_name == "maccmap") { - log("Creating %s with maccmap.\n", extmapper_module); - if (!extmapper_cell->type.in(TW($macc), TW($macc_v2))) - log_error("The maccmap mapper can only map $macc/$macc_v2 (not %s) cells!\n", design->twines.unescaped_str(extmapper_cell->type)); + log("Creating %s with maccmap.\n", log_id(extmapper_module->name)); + if (!extmapper_cell->type.in(TwineRef{TW($macc)}, TwineRef{TW($macc_v2)})) + log_error("The maccmap mapper can only map $macc/$macc_v2 (not %s) cells!\n", extmapper_cell->type.unescape()); maccmap(extmapper_module, extmapper_cell); extmapper_module->remove(extmapper_cell); } if (extmapper_name == "wrap") { std::string cmd_string = tpl->attributes.at(ID::techmap_wrap).decode_string(); - log("Running \"%s\" on wrapper %s.\n", cmd_string, extmapper_module); + log("Running \"%s\" on wrapper %s.\n", cmd_string.c_str(), log_id(extmapper_module->name)); mkdebug.on(); Pass::call_on_module(extmapper_design, extmapper_module, cmd_string); extmapper_design->sigNormalize(false); @@ -608,13 +612,14 @@ struct TechmapWorker } for (auto &conn : cell->connections()) { - if (conn.first.begins_with("$")) + if (design->twines.str(conn.first).starts_with("$")) continue; if (tpl->wire(conn.first) != nullptr && tpl->wire(conn.first)->port_id > 0) continue; - if (!conn.second.is_fully_const() || parameters.count(conn.first) > 0 || tpl->avail_parameters.count(conn.first) == 0) + IdString conn_id(std::string(design->twines.str(conn.first))); + if (!conn.second.is_fully_const() || parameters.count(conn_id) > 0 || tpl->avail_parameters.count(conn_id) == 0) goto next_tpl; - parameters[conn.first] = conn.second.as_const(); + parameters[conn_id] = conn.second.as_const(); } if (0) { @@ -731,7 +736,7 @@ struct TechmapWorker RTLIL::SigSpec value = elem.value; if (value.is_fully_const() && value.as_bool()) { log("Not using module `%s' from techmap as it contains a %s marker wire with non-zero value %s.\n", - derived_name.c_str(), design->twines.unescaped_str(elem.wire->name), log_signal(value)); + design->twines.unescaped_str(derived_name).data(), design->twines.unescaped_str(elem.wire->name.ref()).data(), log_signal(value)); techmap_do_cache[tpl] = false; } } @@ -748,7 +753,7 @@ struct TechmapWorker auto &data = it.second.front(); if (!data.value.is_fully_const()) - log_error("Techmap yielded config wire %s with non-const value %s.\n", design->twines.unescaped_str(data.wire->name), log_signal(data.value)); + log_error("Techmap yielded config wire %s with non-const value %s.\n", design->twines.unescaped_str(data.wire->name.ref()).data(), log_signal(data.value)); techmap_wire_names.erase(it.first); @@ -765,10 +770,10 @@ struct TechmapWorker log("Analyzing pattern of constant bits for this cell:\n"); IdString new_tpl_name = constmap_tpl_name(sigmap, tpl, cell, true); - log("Creating constmapped module `%s'.\n", design->twines.unescaped_str(new_tpl_name)); + log("Creating constmapped module `%s'.\n", log_id(new_tpl_name)); log_assert(map->module(new_tpl_name) == nullptr); - RTLIL::Module *new_tpl = map->addModule(new_tpl_name); + RTLIL::Module *new_tpl = map->addModule(map->twines.add(Twine{new_tpl_name.str()})); tpl->cloneInto(new_tpl); techmap_do_cache.erase(tpl); @@ -785,9 +790,9 @@ struct TechmapWorker continue; IdString port_name = wire->name; - tpl->rename(wire, NEW_ID); + tpl->rename(wire, tpl->design->twines.add(NEW_TWINE)); - RTLIL::Wire *new_wire = tpl->addWire(port_name, wire); + RTLIL::Wire *new_wire = tpl->addWire(Twine{port_name.str()}, wire); wire->port_input = false; wire->port_id = 0; @@ -861,9 +866,9 @@ struct TechmapWorker log_assert(!strncmp(q, "_TECHMAP_DO_", 12)); std::string new_name = data.wire->name.substr(0, q-p) + "_TECHMAP_DONE_" + data.wire->name.substr(q-p+12); - while (tpl->wire(new_name) != nullptr) + while (tpl->wire(tpl->design->twines.add(Twine{new_name})) != nullptr) new_name += "_"; - tpl->rename(data.wire->name, new_name); + tpl->rename(data.wire->name.ref(), tpl->design->twines.add(Twine{new_name})); keep_running = true; break; @@ -873,16 +878,16 @@ struct TechmapWorker TechmapWires twd = techmap_find_special_wires(tpl); for (auto &it : twd) { if (!it.first.ends_with("_TECHMAP_FAIL_") && (!it.first.begins_with("\\_TECHMAP_REMOVEINIT_") || !it.first.ends_with("_")) && !it.first.contains("_TECHMAP_DO_") && !it.first.contains("_TECHMAP_DONE_")) - log_error("Techmap yielded unknown config wire %s.\n", design->twines.unescaped_str(it.first)); + log_error("Techmap yielded unknown config wire %s.\n", log_id(it.first)); if (techmap_do_cache[tpl]) for (auto &it2 : it.second) if (!it2.value.is_fully_const()) - log_error("Techmap yielded config wire %s with non-const value %s.\n", design->twines.unescaped_str(it2.wire->name), log_signal(it2.value)); + log_error("Techmap yielded config wire %s with non-const value %s.\n", log_id(it2.wire->name), log_signal(it2.value)); techmap_wire_names.erase(it.first); } for (auto &it : techmap_wire_names) - log_error("Techmap special wire %s disappeared. This is considered a fatal error.\n", design->twines.unescaped_str(it)); + log_error("Techmap special wire %s disappeared. This is considered a fatal error.\n", log_id(it)); if (recursive_mode) { if (log_continue) { @@ -909,7 +914,8 @@ struct TechmapWorker for (auto &it2 : it.second) { auto val = it2.value.as_const(); auto wirename = RTLIL::escape_id(it.first.substr(21, it.first.size() - 21 - 1)); - auto it = cell->connections().find(wirename); + TwineRef wirename_ref = cell->module->design->twines.add(Twine{wirename}); + auto it = cell->connections().find(wirename_ref); if (it != cell->connections().end()) { auto sig = sigmap(it->second); for (int i = 0; i < sig.size(); i++) @@ -922,28 +928,28 @@ struct TechmapWorker if (extern_mode && !in_recursion) { - std::string m_name = stringf("$extern:%s", tpl); + std::string m_name = stringf("$extern:%s", log_id(tpl->name)); - if (!design->module(m_name)) + if (!design->module(RTLIL::IdString(m_name))) { - RTLIL::Module *m = design->addModule(m_name); + RTLIL::Module *m = design->addModule(design->twines.add(Twine{m_name})); tpl->cloneInto(m); module_queue.insert(m); } - log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix, module, cell, m_name); - cell->type_impl = cell->module->design->twines.add(Twine{m_name.str()}); + log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix.c_str(), log_id(module->name), log_id(cell->name), m_name.c_str()); + cell->type_impl = cell->module->design->twines.add(Twine{m_name}); cell->parameters.clear(); } else { - auto msg = stringf("Using template %s for cells of type %s.", tpl, cell->type.unescaped()); + auto msg = stringf("Using template %s for cells of type %s.", log_id(tpl->name), cell->type.unescape()); if (!log_msg_cache.count(msg)) { log_msg_cache.insert(msg); log("%s\n", msg); } - log_debug("%s %s.%s (%s) using %s.\n", mapmsg_prefix, module, cell, cell->type.unescaped(), tpl); + log_debug("%s %s.%s (%s) using %s.\n", mapmsg_prefix.c_str(), log_id(module->name), log_id(cell->name), cell->type.unescape(), log_id(tpl->name)); techmap_module_worker(design, module, cell, tpl); cell = nullptr; } @@ -1224,7 +1230,7 @@ struct TechmapPass : public Pass { log_cmd_error("Can't open saved design `%s'.\n", fn.c_str()+1); } for (auto mod : saved_designs.at(fn.substr(1))->modules()) - if (!map->module(mod->name)) + if (!map->module(IdString(mod->name))) mod->clone(map); } else { Frontend::frontend_call(map, nullptr, fn, (fn.size() > 3 && fn.compare(fn.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : verilog_frontend)); @@ -1274,9 +1280,9 @@ struct TechmapPass : public Pass { for (auto &i : celltypeMap) { i.second.sort(RTLIL::sort_by_id_str()); std::string maps = ""; - for (auto &map : i.second) - maps += stringf(" %s", design->twines.unescaped_str(map)); - log_debug(" %s:%s\n", design->twines.unescaped_str(i.first), maps); + for (auto &m : i.second) + maps += stringf(" %s", log_id(m)); + log_debug(" %s:%s\n", log_id(i.first), maps.c_str()); } log_debug("\n"); diff --git a/techlibs/ice40/ice40_dsp.pmg b/techlibs/ice40/ice40_dsp.pmg index 05d19a896..7d499edf9 100644 --- a/techlibs/ice40/ice40_dsp.pmg +++ b/techlibs/ice40/ice40_dsp.pmg @@ -182,7 +182,7 @@ match add if mul->type != \SB_MAC16 || (param(mul, \TOPOUTPUT_SELECT).as_int() == 3 && param(mul, \BOTOUTPUT_SELECT).as_int() == 3) select add->type.in($add) - choice AB {\A, \B} + choice AB {\A, \B} select nusers(port(add, AB)) == 2 index port(add, AB)[0] === sigH[0] @@ -214,7 +214,7 @@ endcode match mux select mux->type == $mux - choice AB {\A, \B} + choice AB {\A, \B} select nusers(port(mux, AB)) == 2 index port(mux, AB) === sigO set muxAB AB diff --git a/techlibs/microchip/microchip_dsp.pmg b/techlibs/microchip/microchip_dsp.pmg index 2573135ee..80d000bc2 100644 --- a/techlibs/microchip/microchip_dsp.pmg +++ b/techlibs/microchip/microchip_dsp.pmg @@ -251,7 +251,7 @@ match postAdd select GetSize(port(postAdd, \Y)) <= 48 // AB is the port that connects MUL to ADD - choice AB {\A, \B} + choice AB {\A, \B} select nusers(port(postAdd, AB)) == 2 // has one input coming from multiplier diff --git a/techlibs/quicklogic/ql_dsp_macc.pmg b/techlibs/quicklogic/ql_dsp_macc.pmg index df18596d1..db5b28fe3 100644 --- a/techlibs/quicklogic/ql_dsp_macc.pmg +++ b/techlibs/quicklogic/ql_dsp_macc.pmg @@ -41,8 +41,8 @@ endcode match add select add->type.in($add, $sub) - choice AB {\A, \B} - define BA (AB == \A ? \B : \A) + choice AB {\A, \B} + define BA (AB == \A ? \B : \A) // One input to the adder is fed by the multiplier index port(add, AB) === port(mul, \Y) // Save the other input port, it needs to be fed by the flip-flop @@ -56,8 +56,8 @@ endmatch match mux if mux_in_pattern select mux->type.in($mux) - choice AB {\A, \B} - define BA (AB == \A ? \B : \A) + choice AB {\A, \B} + define BA (AB == \A ? \B : \A) index port(mux, AB) === port(mul, \Y) index port(mux, BA) === port(add, \Y) filter nusers(port(mux, \Y)) == (output_registered ? 2 : 3) diff --git a/techlibs/xilinx/xilinx_dsp.pmg b/techlibs/xilinx/xilinx_dsp.pmg index 6ec891290..6046cfa4e 100644 --- a/techlibs/xilinx/xilinx_dsp.pmg +++ b/techlibs/xilinx/xilinx_dsp.pmg @@ -136,10 +136,10 @@ match preAdd // Output has to be 25 bits or less select GetSize(port(preAdd, \Y)) <= 25 select nusers(port(preAdd, \Y)) == 2 - choice AB {\A, \B} + choice AB {\A, \B} // A port has to be 30 bits or less select GetSize(port(preAdd, AB)) <= 30 - define BA (AB == \A ? \B : \A) + define BA (AB == \A ? \B : \A) // D port has to be 25 bits or less select GetSize(port(preAdd, BA)) <= 25 index port(preAdd, \Y) === sigA @@ -316,7 +316,7 @@ match postAdd select postAdd->type.in($add) select GetSize(port(postAdd, \Y)) <= 48 - choice AB {\A, \B} + choice AB {\A, \B} select nusers(port(postAdd, AB)) == 2 index port(postAdd, AB)[0] === sigP[0] @@ -369,7 +369,7 @@ match postAddMux if ffP select postAddMux->type.in($mux) select nusers(port(postAddMux, \Y)) == 2 - choice AB {\A, \B} + choice AB {\A, \B} index port(postAddMux, AB) === sigP index port(postAddMux, \Y) === sigC set postAddMuxAB AB diff --git a/techlibs/xilinx/xilinx_dsp48a.pmg b/techlibs/xilinx/xilinx_dsp48a.pmg index f3bd9bc95..cef4beec6 100644 --- a/techlibs/xilinx/xilinx_dsp48a.pmg +++ b/techlibs/xilinx/xilinx_dsp48a.pmg @@ -242,7 +242,7 @@ match postAdd select postAdd->type.in($add) select GetSize(port(postAdd, \Y)) <= 48 - choice AB {\A, \B} + choice AB {\A, \B} select nusers(port(postAdd, AB)) == 2 index port(postAdd, AB)[0] === sigP[0] @@ -295,7 +295,7 @@ match postAddMux if ffP select postAddMux->type.in($mux) select nusers(port(postAddMux, \Y)) == 2 - choice AB {\A, \B} + choice AB {\A, \B} index port(postAddMux, AB) === sigP index port(postAddMux, \Y) === sigC set postAddMuxAB AB diff --git a/techlibs/xilinx/xilinx_dsp_cascade.pmg b/techlibs/xilinx/xilinx_dsp_cascade.pmg index 1a9c44f28..5b5599749 100644 --- a/techlibs/xilinx/xilinx_dsp_cascade.pmg +++ b/techlibs/xilinx/xilinx_dsp_cascade.pmg @@ -125,8 +125,8 @@ finally add_siguser(cascade, dsp); if (dsp->type.in(\DSP48E1)) - dsp->setParam(\ACASCREG, AREG); - dsp_pcin->setParam(\A_INPUT, Const("CASCADE")); + setparam(dsp, \ACASCREG, AREG); + setparam(dsp_pcin, \A_INPUT, Const("CASCADE")); log_debug("ACOUT -> ACIN cascade for %s -> %s\n", dsp, dsp_pcin); } @@ -149,7 +149,7 @@ finally add_siguser(cascade, dsp); if (dsp->type.in(\DSP48E1)) { - dsp->setParam(\BCASCREG, BREG); + setparam(dsp, \BCASCREG, BREG); // According to UG389 p13 [https://www.xilinx.com/support/documentation/user_guides/ug389.pdf] // "The attribute is only used by place and route tools and // is not necessary for the users to set for synthesis. The @@ -158,7 +158,7 @@ finally // BCOUT of another DSP48A1 slice, then the tools automatically // set the attribute to 'CASCADE', otherwise it is set to // 'DIRECT'". - dsp_pcin->setParam(\B_INPUT, Const("CASCADE")); + setparam(dsp_pcin, \B_INPUT, Const("CASCADE")); } log_debug("BCOUT -> BCIN cascade for %s -> %s\n", dsp, dsp_pcin);