3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-15 03:35:40 +00:00
This commit is contained in:
Emil J. Tywoniak 2026-06-12 16:25:07 +02:00
parent c3ffbf6fae
commit d22805bd47
65 changed files with 739 additions and 718 deletions

View file

@ -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

View file

@ -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()}));
}

View file

@ -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;
}

View file

@ -341,7 +341,7 @@ struct RTLILFrontendWorker {
error("No wires found for legalization");
int hash = hash_ops<RTLIL::IdString>::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;

View file

@ -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)

View file

@ -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<unsigned int, RTLIL::Module*>(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_)

View file

@ -130,6 +130,7 @@ namespace RTLIL
struct StaticIdString;
struct SigNormIndex;
struct ObjMeta;
template<typename Derived> 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<typename Derived>
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 <typename... Ts> bool in(Ts &&...args) const {
return RTLIL::IdString(self()).in(std::forward<Ts>(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<const Derived *>(this); }
};
} // namespace RTLIL
template<typename Derived>
inline bool operator==(RTLIL::IdString lhs, const RTLIL::NameMasqBase<Derived> &rhs) {
return lhs == RTLIL::IdString(rhs);
}
template<typename Derived>
inline bool operator!=(RTLIL::IdString lhs, const RTLIL::NameMasqBase<Derived> &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<RTLIL::WireNameMasq> {
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 <typename... Ts> bool in(Ts &&...args) const {
return RTLIL::IdString(*this).in(std::forward<Ts>(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<RTLIL::CellNameMasq> {
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 <typename... Ts> bool in(Ts &&...args) const {
return RTLIL::IdString(*this).in(std::forward<Ts>(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<NamedObject*>(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<RTLIL::ModuleNameMasq> {
// 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<typename... Ts> bool in(Ts&&... args) const {
return RTLIL::IdString(*this).in(std::forward<Ts>(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<RTLIL::Module>
@ -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<const RTLIL::Cell *>(
reinterpret_cast<const char *>(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<const RTLIL::Cell *>(
reinterpret_cast<const char *>(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<RTLIL::Module*>(
// reinterpret_cast<char*>(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<const RTLIL::Module *>(
reinterpret_cast<const char *>(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<const RTLIL::Module *>(
reinterpret_cast<const char *>(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<const RTLIL::Module *>(
reinterpret_cast<const char *>(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

View file

@ -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;

View file

@ -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<std::string>(&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<Twine::Suffix>(&t.data)) {
if (auto *sfx = std::get_if<Twine::Suffix>(&t.data)) {
is_public = twine_is_public(sfx->prefix);
} else if (auto *children = std::get_if<std::vector<TwineRef>>(&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;
}

View file

@ -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);

View file

@ -92,12 +92,12 @@ struct EdgetypePass : public Pass {
auto sink_bit_index = std::get<2>(sink);
string source_str = multibit_ports.count(std::pair<IdString, TwineRef>(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<IdString, TwineRef>(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);
}

View file

@ -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;

View file

@ -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);

View file

@ -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)

View file

@ -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

View file

@ -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 ? "<primary output>" : "<unknown>");
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), "<primary input>");

View file

@ -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<TwineRef, unsigned int, RTLIL::sort_by_id_str> num_submodules_by_type;
std::map<TwineRef, double, RTLIL::sort_by_id_str> submodules_area_by_type;
std::map<IdString, unsigned int, RTLIL::sort_by_id_str> num_submodules_by_type;
std::map<IdString, double, RTLIL::sort_by_id_str> submodules_area_by_type;
std::map<TwineRef, unsigned int, RTLIL::sort_by_id_str> local_num_cells_by_type;
std::map<TwineRef, double, RTLIL::sort_by_id_str> local_area_cells_by_type;
std::map<TwineRef, double, RTLIL::sort_by_id_str> local_seq_area_cells_by_type;
std::map<IdString, unsigned int, RTLIL::sort_by_id_str> local_num_cells_by_type;
std::map<IdString, double, RTLIL::sort_by_id_str> local_area_cells_by_type;
std::map<IdString, double, RTLIL::sort_by_id_str> local_seq_area_cells_by_type;
string tech;
std::map<TwineRef, unsigned int, RTLIL::sort_by_id_str> num_cells_by_type;
std::map<TwineRef, double, RTLIL::sort_by_id_str> area_cells_by_type;
std::map<TwineRef, double, RTLIL::sort_by_id_str> seq_area_cells_by_type;
std::set<TwineRef> unknown_cell_area;
std::map<TwineRef, unsigned int> num_cells_by_type_raw;
std::map<IdString, unsigned int, RTLIL::sort_by_id_str> num_cells_by_type;
std::map<IdString, double, RTLIL::sort_by_id_str> area_cells_by_type;
std::map<IdString, double, RTLIL::sort_by_id_str> seq_area_cells_by_type;
std::set<IdString> 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<TwineRef, cell_area_t> &cell_area, string techname)
statdata_t(RTLIL::Design *design, const RTLIL::Module *mod, bool width_mode, dict<IdString, cell_area_t> &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<int>({width_a, width_b, width_y}))});
cell_type = stringf("%s_%d", cell_type, max<int>({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<TwineRef, statdata_t> &mod_stat, TwineRef mod, int level, bool quiet = false, bool has_area = true,
statdata_t hierarchy_worker(const TwinePool& twines, std::map<IdString, statdata_t> &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<TwineRef, statdata
for (auto &it : mod_data.num_submodules_by_type) {
if (mod_stat.count(it.first) > 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<TwineRef, statdata
return mod_data;
}
statdata_t hierarchy_builder(RTLIL::Design *design, const RTLIL::Module *top_mod, std::map<TwineRef, statdata_t> &mod_stat,
bool width_mode, dict<TwineRef, cell_area_t> &cell_area, string techname)
statdata_t hierarchy_builder(RTLIL::Design *design, const RTLIL::Module *top_mod, std::map<IdString, statdata_t> &mod_stat,
bool width_mode, dict<IdString, cell_area_t> &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<TwineRef, cell_area_t> &cell_area, string liberty_file)
void read_liberty_cellarea(dict<IdString, cell_area_t> &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<TwineRef, cell_area_t> &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<TwineRef, statdata_t> mod_stat;
dict<TwineRef, cell_area_t> cell_area;
std::map<IdString, statdata_t> mod_stat;
dict<IdString, cell_area_t> 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);

View file

@ -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<SigBit> 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);

View file

@ -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<GraphNode*, std::vector<std::vector<std::string>>> 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()));

View file

@ -86,20 +86,20 @@ std::optional<std::string> format_with_params(std::string fmt, const dict<IdStri
}
struct Chunk {
IdString port;
TwineRef port;
int base, len;
Chunk(IdString id, int base, int len)
Chunk(TwineRef id, int base, int len)
: port(id), base(base), len(len) {}
IdString format(Cell *cell)
TwineRef format(Cell *cell)
{
if (len == cell->getPort(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<Chunk> collect_chunks(std::vector<std::pair<IdString, int>> bits)
std::vector<Chunk> collect_chunks(std::vector<std::pair<TwineRef, int>> bits)
{
std::vector<Chunk> 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<std::pair<IdString, int>> unused_outputs, used_outputs;
std::vector<std::pair<TwineRef, int>> 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<std::string> 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<IdString, SigSpec> new_connections;
dict<TwineRef, SigSpec> new_connections;
for (auto conn : cell->connections())
if (!ct.cell_output(cell->type_impl, conn.first))

View file

@ -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);
}
}
}

View file

@ -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())
{

View file

@ -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()) {

View file

@ -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;
}
}

View file

@ -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<std::string> args, Design *design) override
{
pool<IdString> fwonly_cells({ TW($equiv) });
pool<IdString> fwonly_cells({ ID($equiv) });
bool mode_icells = false;
bool mode_fwd = false;
int max_iter = -1;

View file

@ -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 {

View file

@ -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()));

View file

@ -132,7 +132,7 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
mod->fixup_ports();
for (auto &para : 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<std::string> &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<RTLIL::IdString, RTLIL::Module*> interfaces_by_name;
dict<RTLIL::IdString, RTLIL::IdString> modports_by_name;
dict<TwineRef, RTLIL::Module*> interfaces_by_name;
dict<TwineRef, TwineRef> 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);
}

View file

@ -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);

View file

@ -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;

View file

@ -140,7 +140,7 @@ struct RamClock {
};
struct Ram {
TwineRef id;
IdString id;
RamKind kind;
dict<std::string, Const> options;
std::vector<PortGroup> port_groups;

View file

@ -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<portinfo_t> 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<int> 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<IdString, int>(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<IdString, int>(bram.name, bram.variant));
goto next_match_rule;
}

View file

@ -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<Cell*> &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<Cell *> 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

View file

@ -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));

View file

@ -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.

View file

@ -33,13 +33,13 @@ struct OptBalanceTreeWorker {
SigMap sigmap;
// Counts of each cell type that are getting balanced
dict<IdString, int> cell_count;
dict<TwineRef, int> 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<SigSpec> &sources, IdString cell_type, Cell* cell) {
SigSpec create_balanced_tree(vector<SigSpec> &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<IdString> cell_types) : module(module), sigmap(module) {
OptBalanceTreeWorker(Module *module, const vector<TwineRef> 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<IdString> cell_types = {TW($and), TW($or), TW($xor), TW($add), TW($mul)};
vector<TwineRef> 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<IdString, int> cell_count;
dict<TwineRef, int> cell_count;
for (auto module : design->selected_modules()) {
OptBalanceTreeWorker worker(module, cell_types);
for (auto cell : worker.cell_count) {

View file

@ -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();

View file

@ -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;
}

View file

@ -31,7 +31,7 @@ PRIVATE_NAMESPACE_BEGIN
struct dlogic_t {
IdString cell_type;
// LUT input idx -> hard cell's port name
dict<int, IdString> lut_input_port;
dict<int, TwineRef> 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<int, IdString>{
std::make_pair(1, ID(I0)),
std::make_pair(2, ID(I1)),
std::make_pair(3, ID(CI))
dict<int, TwineRef>{
std::make_pair(1, TW(I0)),
std::make_pair(2, TW(I1)),
std::make_pair(3, TW(CI))
}
}, {
ID(SB_CARRY),
dict<int, IdString>{
std::make_pair(3, ID(CO))
dict<int, TwineRef>{
std::make_pair(3, TW(CO))
}
}};
continue;

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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<RTLIL::Cell*> drivers;

View file

@ -108,18 +108,18 @@ bool cell_supported(RTLIL::Cell *cell)
return false;
}
std::map<IdString, IdString> mergeable_type_map;
dict<TwineRef, TwineRef> 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");

View file

@ -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 <IdString> clk_port {\A, \B}
define <IdString> latch_port {clk_port == \A ? \B : \A}
choice <TwineRef> clk_port {\A, \B}
define <TwineRef> latch_port {clk_port == \A ? \B : \A}
index <SigSpec> port(and_gate, clk_port) === clk
index <SigSpec> port(and_gate, latch_port) === latched_en
set gated_clk port(and_gate, \Y)

View file

@ -48,10 +48,10 @@ match add
index <SigSpec> port(add, \Y) === shift_amount
// one must be constant, the other is variable
choice <IdString> constport {\A, \B}
choice <TwineRef> constport {\A, \B}
select !port(add, constport).empty()
select port(add, constport).is_fully_const()
define <IdString> varport (constport == \A ? \B : \A)
define <TwineRef> 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;
}

View file

@ -64,10 +64,10 @@ match mul
index <SigSpec> port(mul, \Y) === shift_amount
filter !param(mul, \A_SIGNED).as_bool()
choice <IdString> constport {\A, \B}
choice <TwineRef> constport {\A, \B}
filter port(mul, constport).is_fully_const()
define <IdString> varport (constport == \A ? \B : \A)
define <TwineRef> 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);

View file

@ -48,10 +48,10 @@ match mul
index <SigSpec> port(mul, \Y) === shift_amount
filter !param(mul, \A_SIGNED).as_bool()
choice <IdString> constport {\A, \B}
choice <TwineRef> constport {\A, \B}
filter port(mul, constport).is_fully_const()
define <IdString> varport (constport == \A ? \B : \A)
define <TwineRef> 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;

View file

@ -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<IdString> used_ports;
pool<TwineRef> 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<IdString> unused_ports;
pool<TwineRef> 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; i<module->ports.size(); i++)

View file

@ -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<ssc_pair_t> &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");

View file

@ -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));
}

View file

@ -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<Cell*> users;", file=f)
print(" for (auto bit : (*sigmap)(sig))", file=f)

View file

@ -115,8 +115,8 @@ state <int> pmux_slice_eq pmux_slice_ne
match eq
select eq->type == $eq
choice <IdString> AB {\A, \B}
define <IdString> BA AB == \A ? \B : \A
choice <TwineRef> AB {\A, \B}
define <TwineRef> 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 <IdString> AB {\A, \B}
define <IdString> BA (AB == \A ? \B : \A)
choice <TwineRef> AB {\A, \B}
define <TwineRef> BA (AB == \A ? \B : \A)
index <SigSpec> port(ne, AB) === eq_inA
index <SigSpec> port(ne, BA) === eq_inB
index <int> param(ne, \A_SIGNED).as_bool() === eq_ne_signed

View file

@ -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);

View file

@ -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)))
{

View file

@ -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<std::string, int> 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();

View file

@ -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<IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &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)

View file

@ -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<RTLIL::SigBit, std::pair<IdString, int>> connbits_map;
auto &twines = cell->module->design->twines;
dict<RTLIL::SigBit, std::pair<TwineRef, int>> 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<IdString, IdString> 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<IdString, IdString> positional_ports;
dict<Wire*, IdString> temp_renamed_wires;
dict<TwineRef, TwineRef> positional_ports;
dict<Wire*, TwineRef> temp_renamed_wires;
pool<SigBit> 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<IdString> autopurge_ports;
vector<TwineRef> 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<IdString, RTLIL::Const> 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");

View file

@ -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 <IdString> AB {\A, \B}
choice <TwineRef> AB {\A, \B}
select nusers(port(add, AB)) == 2
index <SigBit> port(add, AB)[0] === sigH[0]
@ -214,7 +214,7 @@ endcode
match mux
select mux->type == $mux
choice <IdString> AB {\A, \B}
choice <TwineRef> AB {\A, \B}
select nusers(port(mux, AB)) == 2
index <SigSpec> port(mux, AB) === sigO
set muxAB AB

View file

@ -251,7 +251,7 @@ match postAdd
select GetSize(port(postAdd, \Y)) <= 48
// AB is the port that connects MUL to ADD
choice <IdString> AB {\A, \B}
choice <TwineRef> AB {\A, \B}
select nusers(port(postAdd, AB)) == 2
// has one input coming from multiplier

View file

@ -41,8 +41,8 @@ endcode
match add
select add->type.in($add, $sub)
choice <IdString> AB {\A, \B}
define <IdString> BA (AB == \A ? \B : \A)
choice <TwineRef> AB {\A, \B}
define <TwineRef> BA (AB == \A ? \B : \A)
// One input to the adder is fed by the multiplier
index <SigSpec> 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 <IdString> AB {\A, \B}
define <IdString> BA (AB == \A ? \B : \A)
choice <TwineRef> AB {\A, \B}
define <TwineRef> BA (AB == \A ? \B : \A)
index <SigSpec> port(mux, AB) === port(mul, \Y)
index <SigSpec> port(mux, BA) === port(add, \Y)
filter nusers(port(mux, \Y)) == (output_registered ? 2 : 3)

View file

@ -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 <IdString> AB {\A, \B}
choice <TwineRef> AB {\A, \B}
// A port has to be 30 bits or less
select GetSize(port(preAdd, AB)) <= 30
define <IdString> BA (AB == \A ? \B : \A)
define <TwineRef> BA (AB == \A ? \B : \A)
// D port has to be 25 bits or less
select GetSize(port(preAdd, BA)) <= 25
index <SigSpec> port(preAdd, \Y) === sigA
@ -316,7 +316,7 @@ match postAdd
select postAdd->type.in($add)
select GetSize(port(postAdd, \Y)) <= 48
choice <IdString> AB {\A, \B}
choice <TwineRef> AB {\A, \B}
select nusers(port(postAdd, AB)) == 2
index <SigBit> 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 <IdString> AB {\A, \B}
choice <TwineRef> AB {\A, \B}
index <SigSpec> port(postAddMux, AB) === sigP
index <SigSpec> port(postAddMux, \Y) === sigC
set postAddMuxAB AB

View file

@ -242,7 +242,7 @@ match postAdd
select postAdd->type.in($add)
select GetSize(port(postAdd, \Y)) <= 48
choice <IdString> AB {\A, \B}
choice <TwineRef> AB {\A, \B}
select nusers(port(postAdd, AB)) == 2
index <SigBit> 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 <IdString> AB {\A, \B}
choice <TwineRef> AB {\A, \B}
index <SigSpec> port(postAddMux, AB) === sigP
index <SigSpec> port(postAddMux, \Y) === sigC
set postAddMuxAB AB

View file

@ -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);