mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-15 03:35:40 +00:00
WIP
This commit is contained in:
parent
c3ffbf6fae
commit
d22805bd47
65 changed files with 739 additions and 718 deletions
6
Makefile
6
Makefile
|
|
@ -744,9 +744,13 @@ OBJS += passes/cmds/stat.o
|
|||
OBJS += passes/cmds/design.o
|
||||
OBJS += passes/cmds/plugin.o
|
||||
|
||||
include $(YOSYS_SRC)/kernel/unstable/Makefile.inc
|
||||
include $(YOSYS_SRC)/passes/proc/Makefile.inc
|
||||
include $(YOSYS_SRC)/passes/opt/Makefile.inc
|
||||
include $(YOSYS_SRC)/passes/techmap/Makefile.inc
|
||||
OBJS += passes/techmap/simplemap.o
|
||||
OBJS += passes/techmap/libcache.o
|
||||
OBJS += passes/techmap/libparse.o
|
||||
# include $(YOSYS_SRC)/passes/techmap/Makefile.inc
|
||||
|
||||
include $(YOSYS_SRC)/backends/verilog/Makefile.inc
|
||||
include $(YOSYS_SRC)/backends/rtlil/Makefile.inc
|
||||
|
|
|
|||
|
|
@ -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()}));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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_)
|
||||
|
|
|
|||
211
kernel/rtlil.h
211
kernel/rtlil.h
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
|
|||
mod->fixup_ports();
|
||||
|
||||
for (auto ¶ : parameters)
|
||||
log(" ignoring parameter %s.\n", design->twines.unescaped_str(para));
|
||||
log(" ignoring parameter %s.\n", log_id(para));
|
||||
|
||||
log(" module %s created.\n", mod);
|
||||
}
|
||||
|
|
@ -187,7 +187,7 @@ bool read_id_num(RTLIL::Design &design, TwineRef ref, int *dst)
|
|||
struct IFExpander
|
||||
{
|
||||
IFExpander (RTLIL::Design &design, RTLIL::Module &m)
|
||||
: module(m), design(design), has_interfaces_not_found(false)
|
||||
: design(design), module(m), has_interfaces_not_found(false)
|
||||
{
|
||||
// Keep track of all derived interfaces available in the current
|
||||
// module in 'interfaces_in_module':
|
||||
|
|
@ -238,7 +238,7 @@ struct IFExpander
|
|||
// about it and don't set has_interfaces_not_found (to avoid a
|
||||
// loop).
|
||||
log_warning("Could not find interface instance for `%s' in `%s'\n",
|
||||
design->twines.unescaped_str(interface_name), &module);
|
||||
log_id(interface_name), &module);
|
||||
}
|
||||
|
||||
// Handle an interface connection from the module
|
||||
|
|
@ -282,8 +282,8 @@ struct IFExpander
|
|||
// Go over all wires in interface, and add replacements to lists.
|
||||
std::string conn_name_str(design.twines.str(conn_name));
|
||||
for (auto mod_wire : mod_replace_ports->wires()) {
|
||||
std::string signal_name1 = conn_name_str + "." + design->twines.unescaped_str(mod_wire->name);
|
||||
std::string signal_name2 = interface_name.str() + "." + design->twines.unescaped_str(mod_wire->name);
|
||||
std::string signal_name1 = conn_name_str + "." + design.twines.unescaped_str(mod_wire->name.ref());
|
||||
std::string signal_name2 = interface_name.str() + "." + design.twines.unescaped_str(mod_wire->name.ref());
|
||||
connections_to_add.push_back(design.twines.add(Twine{signal_name1}));
|
||||
TwineRef signal_name2_ref = design.twines.lookup(signal_name2);
|
||||
if(module.wire(signal_name2_ref) == nullptr) {
|
||||
|
|
@ -388,10 +388,10 @@ RTLIL::Module *get_module(RTLIL::Design &design,
|
|||
bool check,
|
||||
const std::vector<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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ struct RamClock {
|
|||
};
|
||||
|
||||
struct Ram {
|
||||
TwineRef id;
|
||||
IdString id;
|
||||
RamKind kind;
|
||||
dict<std::string, Const> options;
|
||||
std::vector<PortGroup> port_groups;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue