mirror of
https://github.com/YosysHQ/yosys.git
synced 2026-10-06 01:53:53 +02:00
passes: rework passes that search, rekey or cross name pools
This commit is contained in:
@@ -271,7 +271,7 @@ unsigned int abstract_value(Module* mod, EnableLogic enable, const std::vector<S
|
||||
for (int i = 0; i < conn.second.size(); i++) {
|
||||
if (selected_reps.count(sigmap(conn.second[i]))) {
|
||||
log_debug("Abstracting value for %s.%s[%i] in module %s due to selections:\n",
|
||||
cell, conn.first.unescape(), i, mod);
|
||||
cell, PooledName(cell->module, conn.first).unescape(), i, mod);
|
||||
explain_selections(selected_reps.at(sigmap(conn.second[i])));
|
||||
offsets_to_abstract.insert(i);
|
||||
}
|
||||
@@ -484,6 +484,10 @@ struct AbstractPass : public Pass {
|
||||
|
||||
unsigned int changed = 0;
|
||||
if ((mode == State) || (mode == Value)) {
|
||||
std::optional<TwineSearch> enable_search;
|
||||
if (enable == Enable::ActiveLow || enable == Enable::ActiveHigh)
|
||||
enable_search.emplace(&design->twines);
|
||||
|
||||
for (auto mod : design->selected_modules()) {
|
||||
EnableLogic enable_logic;
|
||||
|
||||
@@ -493,12 +497,12 @@ struct AbstractPass : public Pass {
|
||||
} break;
|
||||
case Enable::ActiveLow:
|
||||
case Enable::ActiveHigh: {
|
||||
Wire *enable_wire = mod->wire("\\" + enable_name);
|
||||
Wire *enable_wire = mod->wire(enable_search->find("\\" + enable_name));
|
||||
if (!enable_wire)
|
||||
log_cmd_error("Enable wire %s not found in module %s\n", enable_name, mod->name);
|
||||
if (GetSize(enable_wire) != 1)
|
||||
log_cmd_error("Enable wire %s must have width 1 but has width %d in module %s\n",
|
||||
enable_name.c_str(), GetSize(enable_wire), mod->name.c_str());
|
||||
enable_name.c_str(), GetSize(enable_wire), mod->name);
|
||||
enable_logic = { enable_wire, enable == Enable::ActiveHigh };
|
||||
} break;
|
||||
case Enable::Initstates: {
|
||||
|
||||
+11
-6
@@ -34,7 +34,8 @@ static void add_formal(RTLIL::Module *module, const std::string &celltype, const
|
||||
{
|
||||
std::string escaped_name = RTLIL::escape_id(name);
|
||||
std::string escaped_enable_name = (enable_name != "") ? RTLIL::escape_id(enable_name) : "";
|
||||
RTLIL::Wire *wire = module->wire(escaped_name);
|
||||
TwineSearch search(&module->design->twines);
|
||||
RTLIL::Wire *wire = module->wire(search.find(escaped_name));
|
||||
log_assert(is_formal_celltype(celltype));
|
||||
|
||||
if (wire == nullptr) {
|
||||
@@ -48,7 +49,7 @@ static void add_formal(RTLIL::Module *module, const std::string &celltype, const
|
||||
log("Added $%s cell for wire \"%s.%s\"\n", celltype, module->name.str(), name);
|
||||
}
|
||||
else {
|
||||
RTLIL::Wire *enable_wire = module->wire(escaped_enable_name);
|
||||
RTLIL::Wire *enable_wire = module->wire(search.find(escaped_enable_name));
|
||||
if(enable_wire == nullptr)
|
||||
log_error("Could not find enable wire with name \"%s\".\n", enable_name);
|
||||
|
||||
@@ -62,10 +63,12 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
|
||||
{
|
||||
RTLIL::Wire *wire = nullptr;
|
||||
name = RTLIL::escape_id(name);
|
||||
TwineSearch search(&design->twines);
|
||||
IdString name_ref = search.find(name);
|
||||
|
||||
if (module->count_id(name) != 0)
|
||||
if (module->count_id(name_ref) != 0)
|
||||
{
|
||||
wire = module->wire(name);
|
||||
wire = module->wire(name_ref);
|
||||
|
||||
if (wire != nullptr && wire->width != width)
|
||||
wire = nullptr;
|
||||
@@ -97,6 +100,8 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
|
||||
if (!flag_global)
|
||||
return;
|
||||
|
||||
IdString port_id = design->twines.add(name);
|
||||
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
RTLIL::Module *mod = design->module(cell->type);
|
||||
@@ -106,10 +111,10 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
|
||||
continue;
|
||||
if (mod->get_blackbox_attribute())
|
||||
continue;
|
||||
if (cell->hasPort(name))
|
||||
if (cell->hasPort(port_id))
|
||||
continue;
|
||||
|
||||
cell->setPort(name, wire);
|
||||
cell->setPort(port_id, wire);
|
||||
log("Added connection %s to cell %s.%s (%s).\n", name, module->name, cell->name, cell->type);
|
||||
}
|
||||
}
|
||||
|
||||
+16
-13
@@ -60,8 +60,8 @@ struct BoxDerivePass : Pass {
|
||||
log_header(d, "Executing BOX_DERIVE pass. (derive modules for boxes)\n");
|
||||
|
||||
size_t argidx;
|
||||
IdString naming_attr;
|
||||
IdString base_name;
|
||||
std::string naming_attr;
|
||||
std::string base_name;
|
||||
bool apply_mode = false;
|
||||
for (argidx = 1; argidx < args.size(); argidx++) {
|
||||
if (args[argidx] == "-naming_attr" && argidx + 1 < args.size())
|
||||
@@ -75,11 +75,14 @@ struct BoxDerivePass : Pass {
|
||||
}
|
||||
extra_args(args, argidx, d);
|
||||
|
||||
IdString naming_attr_ref = naming_attr.empty() ? IdString::Null : d->twines.find(naming_attr);
|
||||
|
||||
Module *base_override = nullptr;
|
||||
if (!base_name.empty()) {
|
||||
base_override = d->module(base_name);
|
||||
IdString base_ref = d->twines.find(base_name);
|
||||
base_override = base_ref == IdString::Null ? nullptr : d->module(base_ref);
|
||||
if (!base_override)
|
||||
log_cmd_error("Base module %s not found.\n", base_name.unescape());
|
||||
log_cmd_error("Base module %s not found.\n", RTLIL::unescape_id(base_name));
|
||||
}
|
||||
|
||||
dict<std::pair<RTLIL::IdString, dict<RTLIL::IdString, RTLIL::Const>>, Module*> done;
|
||||
@@ -94,7 +97,7 @@ struct BoxDerivePass : Pass {
|
||||
if (base_override)
|
||||
base = base_override;
|
||||
|
||||
auto index = std::make_pair(base->name, cell->parameters);
|
||||
auto index = std::make_pair(IdString(base->name), cell->parameters);
|
||||
|
||||
if (cell->parameters.empty())
|
||||
continue;
|
||||
@@ -103,22 +106,22 @@ struct BoxDerivePass : Pass {
|
||||
IdString derived_type = base->derive(d, cell->parameters);
|
||||
Module *derived = d->module(derived_type);
|
||||
log_assert(derived && "Failed to derive module\n");
|
||||
log("derived %s\n", derived_type);
|
||||
log("derived %s\n", d->twines.str(derived_type).c_str());
|
||||
|
||||
if (!naming_attr.empty() && derived->has_attribute(naming_attr)) {
|
||||
IdString new_name = RTLIL::escape_id(derived->get_string_attribute(naming_attr));
|
||||
if (!new_name.isPublic())
|
||||
if (naming_attr_ref != IdString::Null && derived->has_attribute(naming_attr_ref)) {
|
||||
std::string new_name = RTLIL::escape_id(derived->get_string_attribute(naming_attr_ref));
|
||||
if (new_name.empty() || new_name[0] != '\\')
|
||||
log_error("Derived module %s cannot be renamed to private name %s.\n",
|
||||
derived, new_name.unescape());
|
||||
derived->attributes.erase(naming_attr);
|
||||
d->rename(derived, new_name);
|
||||
derived, RTLIL::unescape_id(new_name));
|
||||
derived->attributes.erase(naming_attr_ref);
|
||||
d->rename(derived, std::move(new_name));
|
||||
}
|
||||
|
||||
done[index] = derived;
|
||||
}
|
||||
|
||||
if (apply_mode)
|
||||
cell->type = done[index]->name;
|
||||
cell->type = cell->module->design->twines.copy_from(done[index]->design->twines, done[index]->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-15
@@ -22,23 +22,25 @@
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
static void publish(RTLIL::IdString& id) {
|
||||
if (id.begins_with("$")) {
|
||||
log_debug("publishing %s\n", id.c_str());
|
||||
id = "\\" + id.str();
|
||||
log_debug("published %s\n", id.c_str());
|
||||
}
|
||||
static IdString publish(TwinePool &twines, IdString id) {
|
||||
std::string name = twines.str(id);
|
||||
if (!name.starts_with("$"))
|
||||
return id;
|
||||
log_debug("publishing %s\n", name.c_str());
|
||||
IdString published = twines.add("\\" + name);
|
||||
log_debug("published %s\n", twines.str(published).c_str());
|
||||
return published;
|
||||
}
|
||||
|
||||
static void publish_design(RTLIL::Design* design) {
|
||||
auto saved_modules = design->modules_;
|
||||
design->modules_.clear();
|
||||
for (auto& [name, mod] : saved_modules) {
|
||||
publish(mod->name);
|
||||
design->modules_[mod->name] = mod;
|
||||
for (auto* cell : mod->cells()) {
|
||||
publish(cell->type);
|
||||
}
|
||||
for (auto& [_, mod] : saved_modules) {
|
||||
IdString new_name = publish(design->twines, mod->name);
|
||||
mod->name = new_name;
|
||||
design->modules_[new_name] = mod;
|
||||
for (auto* cell : mod->cells())
|
||||
cell->type = publish(design->twines, cell->type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,12 +76,12 @@ struct ChtypePass : public Pass {
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
if (set_type == IdString() && args[argidx] == "-set" && argidx+1 < args.size()) {
|
||||
set_type = RTLIL::escape_id(args[++argidx]);
|
||||
set_type = design->twines.add(RTLIL::escape_id(args[++argidx]));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-map" && argidx+2 < args.size()) {
|
||||
IdString old_type = RTLIL::escape_id(args[++argidx]);
|
||||
IdString new_type = RTLIL::escape_id(args[++argidx]);
|
||||
IdString old_type = design->twines.add(RTLIL::escape_id(args[++argidx]));
|
||||
IdString new_type = design->twines.add(RTLIL::escape_id(args[++argidx]));
|
||||
map_types[old_type] = new_type;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ struct ConnectPass : public Pass {
|
||||
RTLIL::Module *module = nullptr;
|
||||
for (auto mod : design->selected_modules()) {
|
||||
if (module != nullptr)
|
||||
log_cmd_error("Multiple modules selected: %s, %s\n", module->name.unescape(), mod->name.unescape());
|
||||
log_cmd_error("Multiple modules selected: %s, %s\n", module, mod);
|
||||
module = mod;
|
||||
}
|
||||
if (module == nullptr)
|
||||
@@ -184,17 +184,20 @@ struct ConnectPass : public Pass {
|
||||
if (flag_nounset)
|
||||
log_cmd_error("Can't use -port together with -nounset.\n");
|
||||
|
||||
if (module->cell(RTLIL::escape_id(port_cell)) == nullptr)
|
||||
TwineSearch search(&module->design->twines);
|
||||
RTLIL::Cell *port_cell_obj = module->cell(search.find(RTLIL::escape_id(port_cell)));
|
||||
if (port_cell_obj == nullptr)
|
||||
log_cmd_error("Can't find cell %s.\n", port_cell);
|
||||
|
||||
RTLIL::SigSpec sig;
|
||||
if (!RTLIL::SigSpec::parse_sel(sig, design, module, port_expr))
|
||||
log_cmd_error("Failed to parse port expression `%s'.\n", port_expr);
|
||||
|
||||
IdString port_port_ref = module->design->twines.add(RTLIL::escape_id(port_port));
|
||||
if (!flag_assert) {
|
||||
module->cell(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig));
|
||||
port_cell_obj->setPort(port_port_ref, sigmap(sig));
|
||||
} else {
|
||||
SigSpec cur = module->cell(RTLIL::escape_id(port_cell))->getPort(RTLIL::escape_id(port_port));
|
||||
SigSpec cur = port_cell_obj->getPort(port_port_ref);
|
||||
if (sigmap(sig) != sigmap(cur)) {
|
||||
log_cmd_error("Expected connection not present: expected %s, found %s.\n", log_signal(sig), log_signal(cur));
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ struct ConnwrappersWorker
|
||||
bool is_signed;
|
||||
};
|
||||
|
||||
std::set<RTLIL::IdString> decl_celltypes;
|
||||
std::map<std::pair<RTLIL::IdString, RTLIL::IdString>, portdecl_t> decls;
|
||||
std::set<std::string> decl_celltypes;
|
||||
std::map<std::pair<std::string, std::string>, portdecl_t> decls;
|
||||
|
||||
void add_port(std::string celltype, std::string portname, std::string widthparam, std::string signparam)
|
||||
{
|
||||
@@ -77,22 +77,24 @@ struct ConnwrappersWorker
|
||||
|
||||
for (auto &conn : cell->connections())
|
||||
{
|
||||
std::pair<RTLIL::IdString, RTLIL::IdString> key(cell->type, conn.first);
|
||||
std::pair<std::string, std::string> key(cell->type, module->design->twines.str(conn.first));
|
||||
|
||||
if (!decls.count(key))
|
||||
continue;
|
||||
|
||||
portdecl_t &decl = decls.at(key);
|
||||
|
||||
if (!cell->parameters.count(decl.widthparam))
|
||||
IdString widthparam = module->design->twines.find(decl.widthparam);
|
||||
if (widthparam == IdString::Null || !cell->parameters.count(widthparam))
|
||||
continue;
|
||||
|
||||
if (!decl.signparam.empty() && !cell->parameters.count(decl.signparam))
|
||||
IdString signparam = decl.signparam.empty() ? IdString::Null : module->design->twines.find(decl.signparam);
|
||||
if (!decl.signparam.empty() && (signparam == IdString::Null || !cell->parameters.count(signparam)))
|
||||
continue;
|
||||
|
||||
int inner_width = cell->parameters.at(decl.widthparam).as_int();
|
||||
int inner_width = cell->parameters.at(widthparam).as_int();
|
||||
int outer_width = conn.second.size();
|
||||
bool is_signed = decl.signparam.empty() ? decl.is_signed : cell->parameters.at(decl.signparam).as_bool();
|
||||
bool is_signed = decl.signparam.empty() ? decl.is_signed : cell->parameters.at(signparam).as_bool();
|
||||
|
||||
if (inner_width >= outer_width)
|
||||
continue;
|
||||
@@ -135,7 +137,7 @@ struct ConnwrappersWorker
|
||||
|
||||
if (old_sig.size())
|
||||
log("Connected extended bits of %s.%s:%s: %s -> %s\n", module->name.unescape(), cell->name.unescape(),
|
||||
conn.first.unescape(), log_signal(old_sig), log_signal(conn.second));
|
||||
PooledName(module, conn.first).unescape(), log_signal(old_sig), log_signal(conn.second));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -44,15 +44,15 @@ struct CopyPass : public Pass {
|
||||
std::string src_name = RTLIL::escape_id(args[1]);
|
||||
std::string trg_name = RTLIL::escape_id(args[2]);
|
||||
|
||||
if (design->module(src_name) == nullptr)
|
||||
log_cmd_error("Can't find source module %s.\n", src_name);
|
||||
TwineSearch search(&design->twines);
|
||||
IdString src_ref = search.find(src_name);
|
||||
if (design->module(src_ref) == nullptr)
|
||||
log_cmd_error("Can't find source module %s.\n", src_name.c_str());
|
||||
|
||||
if (design->module(trg_name) != nullptr)
|
||||
if (design->module(search.find(trg_name)) != nullptr)
|
||||
log_cmd_error("Target module name %s already exists.\n", trg_name);
|
||||
|
||||
RTLIL::Module *new_mod = design->module(src_name)->clone();
|
||||
new_mod->name = trg_name;
|
||||
design->add(new_mod);
|
||||
design->module(src_ref)->clone(design, design->twines.add(std::string{trg_name}));
|
||||
}
|
||||
} CopyPass;
|
||||
|
||||
|
||||
@@ -91,14 +91,14 @@ struct DeletePass : public Pass {
|
||||
pool<RTLIL::Wire*> delete_wires;
|
||||
pool<RTLIL::Cell*> delete_cells;
|
||||
pool<RTLIL::Process*> delete_procs;
|
||||
pool<RTLIL::IdString> delete_mems;
|
||||
dict<std::string, RTLIL::IdString> delete_mems;
|
||||
|
||||
for (auto wire : module->selected_wires())
|
||||
delete_wires.insert(wire);
|
||||
|
||||
for (auto &it : module->memories)
|
||||
if (design->selected(module, it.second))
|
||||
delete_mems.insert(it.first);
|
||||
delete_mems[design->twines.str(it.first)] = it.first;
|
||||
|
||||
for (auto cell : module->cells()) {
|
||||
if (design->selected(module, cell))
|
||||
@@ -113,8 +113,8 @@ struct DeletePass : public Pass {
|
||||
delete_procs.insert(it.second);
|
||||
|
||||
for (auto &it : delete_mems) {
|
||||
delete module->memories.at(it);
|
||||
module->memories.erase(it);
|
||||
delete module->memories.at(it.second);
|
||||
module->memories.erase(it.second);
|
||||
}
|
||||
|
||||
for (auto &it : delete_cells)
|
||||
|
||||
+26
-29
@@ -254,30 +254,32 @@ struct DesignPass : public Pass {
|
||||
if (import_mode)
|
||||
{
|
||||
std::string prefix = RTLIL::escape_id(as_name);
|
||||
IdString as_name_ref = copy_to_design->twines.add(std::string{prefix});
|
||||
|
||||
pool<Module*> queue;
|
||||
dict<IdString, IdString> done;
|
||||
|
||||
if (copy_to_design->module(prefix) != nullptr)
|
||||
copy_to_design->remove(copy_to_design->module(prefix));
|
||||
if (copy_to_design->module(as_name_ref) != nullptr)
|
||||
copy_to_design->remove(copy_to_design->module(as_name_ref));
|
||||
|
||||
if (GetSize(copy_src_modules) != 1)
|
||||
log_cmd_error("No top module found in source design.\n");
|
||||
|
||||
for (auto mod : copy_src_modules)
|
||||
{
|
||||
log("Importing %s as %s.\n", mod, RTLIL::unescape_id(prefix));
|
||||
log("Importing %s as %s.\n", mod, PooledName(design, as_name_ref).unescape());
|
||||
|
||||
RTLIL::Module *t = mod->clone();
|
||||
t->name = prefix;
|
||||
t->design = copy_to_design;
|
||||
RTLIL::Module *t = mod->clone(copy_to_design, as_name_ref);
|
||||
t->attributes.erase(ID::top);
|
||||
copy_to_design->add(t);
|
||||
|
||||
queue.insert(t);
|
||||
done[mod->name] = prefix;
|
||||
done[mod->name] = as_name_ref;
|
||||
}
|
||||
|
||||
std::optional<TwineSearch> src_search;
|
||||
if (copy_from_design)
|
||||
src_search.emplace(©_from_design->twines);
|
||||
|
||||
while (!queue.empty() && copy_from_design)
|
||||
{
|
||||
pool<Module*> old_queue;
|
||||
@@ -286,28 +288,27 @@ struct DesignPass : public Pass {
|
||||
for (auto mod : old_queue)
|
||||
for (auto cell : mod->cells())
|
||||
{
|
||||
Module *fmod = copy_from_design->module(cell->type);
|
||||
Module *fmod = copy_from_design->module(
|
||||
src_search->find(copy_to_design->twines.str(cell->type)));
|
||||
|
||||
if (fmod == nullptr)
|
||||
continue;
|
||||
|
||||
if (done.count(cell->type) == 0)
|
||||
{
|
||||
std::string trg_name = prefix + "." + (cell->type.c_str() + (*cell->type.c_str() == '\\'));
|
||||
IdString trg_ref = copy_to_design->twines.add(
|
||||
Twine::Suffix{as_name_ref, "." + cell->type.unescape()});
|
||||
|
||||
log("Importing %s as %s.\n", fmod, RTLIL::unescape_id(trg_name));
|
||||
log("Importing %s as %s.\n", fmod, PooledName(copy_to_design, trg_ref).unescape());
|
||||
|
||||
if (copy_to_design->module(trg_name) != nullptr)
|
||||
copy_to_design->remove(copy_to_design->module(trg_name));
|
||||
if (copy_to_design->module(trg_ref) != nullptr)
|
||||
copy_to_design->remove(copy_to_design->module(trg_ref));
|
||||
|
||||
RTLIL::Module *t = fmod->clone();
|
||||
t->name = trg_name;
|
||||
t->design = copy_to_design;
|
||||
RTLIL::Module *t = fmod->clone(copy_to_design, trg_ref);
|
||||
t->attributes.erase(ID::top);
|
||||
copy_to_design->add(t);
|
||||
|
||||
queue.insert(t);
|
||||
done[cell->type] = trg_name;
|
||||
done[cell->type] = trg_ref;
|
||||
}
|
||||
|
||||
cell->type = done.at(cell->type);
|
||||
@@ -323,14 +324,12 @@ struct DesignPass : public Pass {
|
||||
for (auto mod : copy_src_modules)
|
||||
{
|
||||
std::string trg_name = as_name.empty() ? mod->name.str() : RTLIL::escape_id(as_name);
|
||||
IdString trg_ref = copy_to_design->twines.add(std::string{trg_name});
|
||||
|
||||
if (copy_to_design->module(trg_name) != nullptr)
|
||||
copy_to_design->remove(copy_to_design->module(trg_name));
|
||||
if (copy_to_design->module(trg_ref) != nullptr)
|
||||
copy_to_design->remove(copy_to_design->module(trg_ref));
|
||||
|
||||
RTLIL::Module *t = mod->clone();
|
||||
t->name = trg_name;
|
||||
t->design = copy_to_design;
|
||||
copy_to_design->add(t);
|
||||
mod->clone(copy_to_design, trg_ref);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,8 +337,7 @@ struct DesignPass : public Pass {
|
||||
{
|
||||
RTLIL::Design *design_copy = new RTLIL::Design;
|
||||
|
||||
for (auto mod : design->modules())
|
||||
design_copy->add(mod->clone());
|
||||
design->clone_into(design_copy);
|
||||
|
||||
design_copy->selection_stack = design->selection_stack;
|
||||
design_copy->selection_vars = design->selection_vars;
|
||||
@@ -361,7 +359,7 @@ struct DesignPass : public Pass {
|
||||
|
||||
design->selection_stack.clear();
|
||||
design->selection_vars.clear();
|
||||
design->selected_active_module.clear();
|
||||
design->selected_active_module = IdString::Null;
|
||||
|
||||
design->push_full_selection();
|
||||
}
|
||||
@@ -377,8 +375,7 @@ struct DesignPass : public Pass {
|
||||
{
|
||||
RTLIL::Design *saved_design = pop_mode ? pushed_designs.back() : saved_designs.at(load_name);
|
||||
|
||||
for (auto mod : saved_design->modules())
|
||||
design->add(mod->clone());
|
||||
saved_design->clone_into(design);
|
||||
|
||||
design->selection_stack = saved_design->selection_stack;
|
||||
design->selection_vars = saved_design->selection_vars;
|
||||
|
||||
+102
-70
@@ -22,13 +22,33 @@
|
||||
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
class PoolBridge
|
||||
{
|
||||
const TwinePool *pool_a;
|
||||
const TwinePool *pool_b;
|
||||
TwineSearch search_a;
|
||||
TwineSearch search_b;
|
||||
|
||||
public:
|
||||
PoolBridge(RTLIL::Design *design_a, RTLIL::Design *design_b) :
|
||||
pool_a(&design_a->twines), pool_b(&design_b->twines),
|
||||
search_a(&design_a->twines), search_b(&design_b->twines) {}
|
||||
|
||||
IdString a_to_b(IdString ref) const { return search_b.find(pool_a->str(ref)); }
|
||||
IdString b_to_a(IdString ref) const { return search_a.find(pool_b->str(ref)); }
|
||||
|
||||
bool same(IdString a, IdString b) const { return pool_a->str(a) == pool_b->str(b); }
|
||||
};
|
||||
|
||||
class ModuleComparator
|
||||
{
|
||||
RTLIL::Module *mod_a;
|
||||
RTLIL::Module *mod_b;
|
||||
const PoolBridge &bridge;
|
||||
|
||||
public:
|
||||
ModuleComparator(RTLIL::Module *mod_a, RTLIL::Module *mod_b) : mod_a(mod_a), mod_b(mod_b) {}
|
||||
ModuleComparator(RTLIL::Module *mod_a, RTLIL::Module *mod_b, const PoolBridge &bridge) :
|
||||
mod_a(mod_a), mod_b(mod_b), bridge(bridge) {}
|
||||
|
||||
template <typename... Args>
|
||||
[[noreturn]] void error(FmtString<TypeIdentity<Args>...> fmt, const Args &... args)
|
||||
@@ -38,9 +58,9 @@ public:
|
||||
[[noreturn]]
|
||||
void formatted_error(std::string err)
|
||||
{
|
||||
log("Module A: %s\n", mod_a->name.unescape());
|
||||
log("Module A: %s\n", mod_a);
|
||||
log_module(mod_a, " ");
|
||||
log("Module B: %s\n", mod_b->name.unescape());
|
||||
log("Module B: %s\n", mod_b);
|
||||
log_module(mod_b, " ");
|
||||
log_cmd_error("Designs are different: %s\n", err);
|
||||
}
|
||||
@@ -50,7 +70,7 @@ public:
|
||||
if (a.wire == nullptr && b.wire == nullptr)
|
||||
return a.data == b.data;
|
||||
if (a.wire != nullptr && b.wire != nullptr)
|
||||
return a.wire->name == b.wire->name && a.offset == b.offset;
|
||||
return bridge.same(a.wire->name, b.wire->name) && a.offset == b.offset;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -67,20 +87,21 @@ public:
|
||||
std::string compare_attributes(const RTLIL::AttrObject *a, const RTLIL::AttrObject *b)
|
||||
{
|
||||
for (const auto &it : a->attributes) {
|
||||
if (b->attributes.count(it.first) == 0)
|
||||
return "missing attribute " + std::string(it.first.unescape()) + " in second design";
|
||||
if (it.second != b->attributes.at(it.first))
|
||||
return "attribute " + std::string(it.first.unescape()) + " mismatch: " + log_const(it.second) + " != " + log_const(b->attributes.at(it.first));
|
||||
IdString in_b = bridge.a_to_b(it.first);
|
||||
if (b->attributes.count(in_b) == 0)
|
||||
return "missing attribute " + std::string(mod_a->design->twines.unescaped_str(it.first)) + " in second design";
|
||||
if (it.second != b->attributes.at(in_b))
|
||||
return "attribute " + std::string(mod_a->design->twines.unescaped_str(it.first)) + " mismatch: " + log_const(it.second) + " != " + log_const(b->attributes.at(in_b));
|
||||
}
|
||||
for (const auto &it : b->attributes)
|
||||
if (a->attributes.count(it.first) == 0)
|
||||
return "missing attribute " + std::string(it.first.unescape()) + " in first design";
|
||||
if (a->attributes.count(bridge.b_to_a(it.first)) == 0)
|
||||
return "missing attribute " + std::string(mod_b->design->twines.unescaped_str(it.first)) + " in first design";
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string compare_wires(const RTLIL::Wire *a, const RTLIL::Wire *b)
|
||||
{
|
||||
if (a->name != b->name)
|
||||
if (!bridge.same(a->name, b->name))
|
||||
return "name mismatch: " + std::string(a->name.unescape()) + " != " + b->name.unescape();
|
||||
if (a->width != b->width)
|
||||
return "width mismatch: " + std::to_string(a->width) + " != " + std::to_string(b->width);
|
||||
@@ -104,19 +125,21 @@ public:
|
||||
void check_wires()
|
||||
{
|
||||
for (const auto &it : mod_a->wires_) {
|
||||
if (mod_b->wires_.count(it.first) == 0)
|
||||
error("Module %s missing wire %s in second design.\n", mod_a->name.unescape(), it.first.unescape());
|
||||
if (std::string mismatch = compare_wires(it.second, mod_b->wires_.at(it.first)); !mismatch.empty())
|
||||
error("Module %s wire %s %s.\n", mod_a->name.unescape(), it.first.unescape(), mismatch);
|
||||
RTLIL::Wire *wb = mod_b->wire(bridge.a_to_b(it.first));
|
||||
if (!wb)
|
||||
error("Module %s missing wire %s in second design.\n", mod_a, it.second);
|
||||
else if (std::string mismatch = compare_wires(it.second, wb); !mismatch.empty())
|
||||
error("Module %s wire %s %s.\n", mod_a, it.second, mismatch);
|
||||
}
|
||||
for (const auto &it : mod_b->wires_) {
|
||||
if (!mod_a->wire(bridge.b_to_a(it.first)))
|
||||
error("Module %s missing wire %s in first design.\n", mod_b, it.second);
|
||||
}
|
||||
for (const auto &it : mod_b->wires_)
|
||||
if (mod_a->wires_.count(it.first) == 0)
|
||||
error("Module %s missing wire %s in first design.\n", mod_b->name.unescape(), it.first.unescape());
|
||||
}
|
||||
|
||||
std::string compare_memories(const RTLIL::Memory *a, const RTLIL::Memory *b)
|
||||
{
|
||||
if (a->name != b->name)
|
||||
if (!bridge.same(a->name, b->name))
|
||||
return "name mismatch: " + std::string(a->name.unescape()) + " != " + b->name.unescape();
|
||||
if (a->width != b->width)
|
||||
return "width mismatch: " + std::to_string(a->width) + " != " + std::to_string(b->width);
|
||||
@@ -131,32 +154,34 @@ public:
|
||||
|
||||
std::string compare_cells(const RTLIL::Cell *a, const RTLIL::Cell *b)
|
||||
{
|
||||
if (a->name != b->name)
|
||||
if (!bridge.same(a->name, b->name))
|
||||
return "name mismatch: " + std::string(a->name.unescape()) + " != " + b->name.unescape();
|
||||
if (a->type != b->type)
|
||||
if (!bridge.same(a->type, b->type))
|
||||
return "type mismatch: " + std::string(a->type.unescape()) + " != " + b->type.unescape();
|
||||
if (std::string mismatch = compare_attributes(a, b); !mismatch.empty())
|
||||
return mismatch;
|
||||
|
||||
for (const auto &it : a->parameters) {
|
||||
if (b->parameters.count(it.first) == 0)
|
||||
return "parameter mismatch: missing parameter " + std::string(it.first.unescape()) + " in second design";
|
||||
if (it.second != b->parameters.at(it.first))
|
||||
return "parameter mismatch: " + std::string(it.first.unescape()) + " mismatch: " + log_const(it.second) + " != " + log_const(b->parameters.at(it.first));
|
||||
IdString in_b = bridge.a_to_b(it.first);
|
||||
if (b->parameters.count(in_b) == 0)
|
||||
return "parameter mismatch: missing parameter " + std::string(mod_a->design->twines.unescaped_str(it.first)) + " in second design";
|
||||
if (it.second != b->parameters.at(in_b))
|
||||
return "parameter mismatch: " + std::string(mod_a->design->twines.unescaped_str(it.first)) + " mismatch: " + log_const(it.second) + " != " + log_const(b->parameters.at(in_b));
|
||||
}
|
||||
for (const auto &it : b->parameters)
|
||||
if (a->parameters.count(it.first) == 0)
|
||||
return "parameter mismatch: missing parameter " + std::string(it.first.unescape()) + " in first design";
|
||||
if (a->parameters.count(bridge.b_to_a(it.first)) == 0)
|
||||
return "parameter mismatch: missing parameter " + std::string(mod_b->design->twines.unescaped_str(it.first)) + " in first design";
|
||||
|
||||
for (const auto &it : a->connections()) {
|
||||
if (b->connections().count(it.first) == 0)
|
||||
return "connection mismatch: missing connection " + std::string(it.first.unescape()) + " in second design";
|
||||
if (!compare_sigspec(it.second, b->connections().at(it.first)))
|
||||
return "connection " + std::string(it.first.unescape()) + " mismatch: " + log_signal(it.second) + " != " + log_signal(b->connections().at(it.first));
|
||||
IdString in_b = bridge.a_to_b(it.first);
|
||||
if (b->connections().count(in_b) == 0)
|
||||
return "connection mismatch: missing connection " + a->module->design->twines.unescaped_str(it.first) + " in second design";
|
||||
if (!compare_sigspec(it.second, b->connections().at(in_b)))
|
||||
return "connection " + a->module->design->twines.unescaped_str(it.first) + " mismatch: " + log_signal(it.second) + " != " + log_signal(b->connections().at(in_b));
|
||||
}
|
||||
for (const auto &it : b->connections())
|
||||
if (a->connections().count(it.first) == 0)
|
||||
return "connection mismatch: missing connection " + std::string(it.first.unescape()) + " in first design";
|
||||
if (a->connections().count(bridge.b_to_a(it.first)) == 0)
|
||||
return "connection mismatch: missing connection " + a->module->design->twines.unescaped_str(it.first) + " in first design";
|
||||
|
||||
return "";
|
||||
}
|
||||
@@ -164,27 +189,30 @@ public:
|
||||
void check_cells()
|
||||
{
|
||||
for (const auto &it : mod_a->cells_) {
|
||||
if (mod_b->cells_.count(it.first) == 0)
|
||||
error("Module %s missing cell %s in second design.\n", mod_a->name.unescape(), it.first.unescape());
|
||||
if (std::string mismatch = compare_cells(it.second, mod_b->cells_.at(it.first)); !mismatch.empty())
|
||||
error("Module %s cell %s %s.\n", mod_a->name.unescape(), it.first.unescape(), mismatch);
|
||||
RTLIL::Cell *cb = mod_b->cell(bridge.a_to_b(it.first));
|
||||
if (!cb)
|
||||
error("Module %s missing cell %s in second design.\n", mod_a, it.second);
|
||||
else if (std::string mismatch = compare_cells(it.second, cb); !mismatch.empty())
|
||||
error("Module %s cell %s %s.\n", mod_a, it.second, mismatch);
|
||||
}
|
||||
for (const auto &it : mod_b->cells_) {
|
||||
if (!mod_a->cell(bridge.b_to_a(it.first)))
|
||||
error("Module %s missing cell %s in first design.\n", mod_b, it.second);
|
||||
}
|
||||
for (const auto &it : mod_b->cells_)
|
||||
if (mod_a->cells_.count(it.first) == 0)
|
||||
error("Module %s missing cell %s in first design.\n", mod_b->name.unescape(), it.first.unescape());
|
||||
}
|
||||
|
||||
void check_memories()
|
||||
{
|
||||
for (const auto &it : mod_a->memories) {
|
||||
if (mod_b->memories.count(it.first) == 0)
|
||||
error("Module %s missing memory %s in second design.\n", mod_a->name.unescape(), it.first.unescape());
|
||||
if (std::string mismatch = compare_memories(it.second, mod_b->memories.at(it.first)); !mismatch.empty())
|
||||
error("Module %s memory %s %s.\n", mod_a->name.unescape(), it.first.unescape(), mismatch);
|
||||
IdString in_b = bridge.a_to_b(it.first);
|
||||
if (mod_b->memories.count(in_b) == 0)
|
||||
error("Module %s missing memory %s in second design.\n", mod_a, it.second);
|
||||
if (std::string mismatch = compare_memories(it.second, mod_b->memories.at(in_b)); !mismatch.empty())
|
||||
error("Module %s memory %s %s.\n", mod_a, it.second, mismatch);
|
||||
}
|
||||
for (const auto &it : mod_b->memories)
|
||||
if (mod_a->memories.count(it.first) == 0)
|
||||
error("Module %s missing memory %s in first design.\n", mod_b->name.unescape(), it.first.unescape());
|
||||
if (mod_a->memories.count(bridge.b_to_a(it.first)) == 0)
|
||||
error("Module %s missing memory %s in first design.\n", mod_b, it.second);
|
||||
}
|
||||
|
||||
std::string compare_case_rules(const RTLIL::CaseRule *a, const RTLIL::CaseRule *b)
|
||||
@@ -201,9 +229,9 @@ public:
|
||||
return "actions size mismatch: " + std::to_string(a->actions.size()) + " != " + std::to_string(b->actions.size());
|
||||
for (size_t i = 0; i < a->actions.size(); i++) {
|
||||
if (!compare_sigspec(a->actions[i].first, b->actions[i].first))
|
||||
return "action " + std::to_string(i) + " first mismatch: " + log_signal(a->actions[i].first) + " != " + log_signal(b->actions[i].first);
|
||||
return "action " + std::to_string(i) + " lhs mismatch: " + log_signal(a->actions[i].first) + " != " + log_signal(b->actions[i].first);
|
||||
if (!compare_sigspec(a->actions[i].second, b->actions[i].second))
|
||||
return "action " + std::to_string(i) + " second mismatch: " + log_signal(a->actions[i].second) + " != " + log_signal(b->actions[i].second);
|
||||
return "action " + std::to_string(i) + " rhs mismatch: " + log_signal(a->actions[i].second) + " != " + log_signal(b->actions[i].second);
|
||||
}
|
||||
|
||||
if (a->switches.size() != b->switches.size())
|
||||
@@ -241,17 +269,17 @@ public:
|
||||
return "actions size mismatch: " + std::to_string(a->actions.size()) + " != " + std::to_string(b->actions.size());
|
||||
for (size_t i = 0; i < a->actions.size(); i++) {
|
||||
if (!compare_sigspec(a->actions[i].first, b->actions[i].first))
|
||||
return "action " + std::to_string(i) + " first mismatch: " + log_signal(a->actions[i].first) + " != " + log_signal(b->actions[i].first);
|
||||
return "action " + std::to_string(i) + " lhs mismatch: " + log_signal(a->actions[i].first) + " != " + log_signal(b->actions[i].first);
|
||||
if (!compare_sigspec(a->actions[i].second, b->actions[i].second))
|
||||
return "action " + std::to_string(i) + " second mismatch: " + log_signal(a->actions[i].second) + " != " + log_signal(b->actions[i].second);
|
||||
return "action " + std::to_string(i) + " rhs mismatch: " + log_signal(a->actions[i].second) + " != " + log_signal(b->actions[i].second);
|
||||
}
|
||||
if (a->mem_write_actions.size() != b->mem_write_actions.size())
|
||||
return "mem_write_actions size mismatch: " + std::to_string(a->mem_write_actions.size()) + " != " + std::to_string(b->mem_write_actions.size());
|
||||
for (size_t i = 0; i < a->mem_write_actions.size(); i++) {
|
||||
const auto &ma = a->mem_write_actions[i];
|
||||
const auto &mb = b->mem_write_actions[i];
|
||||
if (ma.memid != mb.memid)
|
||||
return "mem_write_actions " + std::to_string(i) + " memid mismatch: " + ma.memid.unescape() + " != " + mb.memid.unescape();
|
||||
if (!bridge.same(ma.memid, mb.memid))
|
||||
return "mem_write_actions " + std::to_string(i) + " memid mismatch: " + mod_a->design->twines.unescaped_str(ma.memid) + " != " + mod_b->design->twines.unescaped_str(mb.memid);
|
||||
if (!compare_sigspec(ma.address, mb.address))
|
||||
return "mem_write_actions " + std::to_string(i) + " address mismatch: " + log_signal(ma.address) + " != " + log_signal(mb.address);
|
||||
if (!compare_sigspec(ma.data, mb.data))
|
||||
@@ -268,7 +296,7 @@ public:
|
||||
|
||||
std::string compare_processes(const RTLIL::Process *a, const RTLIL::Process *b)
|
||||
{
|
||||
if (a->name != b->name) return "name mismatch: " + std::string(a->name.unescape()) + " != " + b->name.unescape();
|
||||
if (!bridge.same(a->name, b->name)) return "name mismatch: " + std::string(a->name.unescape()) + " != " + b->name.unescape();
|
||||
if (std::string mismatch = compare_attributes(a, b); !mismatch.empty())
|
||||
return mismatch;
|
||||
if (std::string mismatch = compare_case_rules(&a->root_case, &b->root_case); !mismatch.empty())
|
||||
@@ -284,14 +312,15 @@ public:
|
||||
void check_processes()
|
||||
{
|
||||
for (auto &it : mod_a->processes) {
|
||||
if (mod_b->processes.count(it.first) == 0)
|
||||
error("Module %s missing process %s in second design.\n", mod_a->name.unescape(), it.first.unescape());
|
||||
if (std::string mismatch = compare_processes(it.second, mod_b->processes.at(it.first)); !mismatch.empty())
|
||||
error("Module %s process %s %s.\n", mod_a->name.unescape(), it.first.unescape(), mismatch.c_str());
|
||||
IdString in_b = bridge.a_to_b(it.first);
|
||||
if (mod_b->processes.count(in_b) == 0)
|
||||
error("Module %s missing process %s in second design.\n", mod_a, it.second);
|
||||
if (std::string mismatch = compare_processes(it.second, mod_b->processes.at(in_b)); !mismatch.empty())
|
||||
error("Module %s process %s %s.\n", mod_a, it.second, mismatch.c_str());
|
||||
}
|
||||
for (auto &it : mod_b->processes)
|
||||
if (mod_a->processes.count(it.first) == 0)
|
||||
error("Module %s missing process %s in first design.\n", mod_b->name.unescape(), it.first.unescape());
|
||||
if (mod_a->processes.count(bridge.b_to_a(it.first)) == 0)
|
||||
error("Module %s missing process %s in first design.\n", mod_b, it.second);
|
||||
}
|
||||
|
||||
void check_connections()
|
||||
@@ -299,23 +328,23 @@ public:
|
||||
const auto &conns_a = mod_a->connections();
|
||||
const auto &conns_b = mod_b->connections();
|
||||
if (conns_a.size() != conns_b.size()) {
|
||||
error("Module %s connection count differs: %zu != %zu\n", mod_a->name.unescape(), conns_a.size(), conns_b.size());
|
||||
error("Module %s connection count differs: %zu != %zu\n", mod_a, conns_a.size(), conns_b.size());
|
||||
} else {
|
||||
for (size_t i = 0; i < conns_a.size(); i++) {
|
||||
if (!compare_sigspec(conns_a[i].first, conns_b[i].first))
|
||||
error("Module %s connection %zu LHS %s != %s.\n", mod_a->name.unescape(), i, log_signal(conns_a[i].first), log_signal(conns_b[i].first));
|
||||
error("Module %s connection %zu LHS %s != %s.\n", mod_a, i, log_signal(conns_a[i].first), log_signal(conns_b[i].first));
|
||||
if (!compare_sigspec(conns_a[i].second, conns_b[i].second))
|
||||
error("Module %s connection %zu RHS %s != %s.\n", mod_a->name.unescape(), i, log_signal(conns_a[i].second), log_signal(conns_b[i].second));
|
||||
error("Module %s connection %zu RHS %s != %s.\n", mod_a, i, log_signal(conns_a[i].second), log_signal(conns_b[i].second));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void check()
|
||||
{
|
||||
if (mod_a->name != mod_b->name)
|
||||
error("Modules have different names: %s != %s\n", mod_a->name.unescape(), mod_b->name.unescape());
|
||||
if (!bridge.same(mod_a->name, mod_b->name))
|
||||
error("Modules have different names: %s != %s\n", mod_a, mod_b);
|
||||
if (std::string mismatch = compare_attributes(mod_a, mod_b); !mismatch.empty())
|
||||
error("Module %s %s.\n", mod_a->name.unescape(), mismatch);
|
||||
error("Module %s %s.\n", mod_a, mismatch);
|
||||
check_wires();
|
||||
check_cells();
|
||||
check_memories();
|
||||
@@ -346,18 +375,21 @@ struct DesignEqualPass : public Pass {
|
||||
|
||||
RTLIL::Design *other = saved_designs.at(check_name);
|
||||
|
||||
PoolBridge bridge(design, other);
|
||||
|
||||
for (auto &it : design->modules_) {
|
||||
RTLIL::Module *mod = it.second;
|
||||
if (!other->has(mod->name))
|
||||
log_error("Second design missing module %s.\n", mod->name.unescape());
|
||||
RTLIL::Module *other_mod = other->module(bridge.a_to_b(it.first));
|
||||
if (!other_mod)
|
||||
log_error("Second design missing module %s.\n", mod);
|
||||
|
||||
ModuleComparator cmp(mod, other->module(mod->name));
|
||||
ModuleComparator cmp(mod, other_mod, bridge);
|
||||
cmp.check();
|
||||
}
|
||||
for (auto &it : other->modules_) {
|
||||
RTLIL::Module *mod = it.second;
|
||||
if (!design->has(mod->name))
|
||||
log_error("First design missing module %s.\n", mod->name.unescape());
|
||||
if (!design->has(bridge.b_to_a(it.first)))
|
||||
log_error("First design missing module %s.\n", mod);
|
||||
}
|
||||
|
||||
log("Designs are identical.\n");
|
||||
|
||||
+42
-34
@@ -369,13 +369,20 @@ struct DftTagWorker {
|
||||
pending_cells.erase(cell);
|
||||
}
|
||||
|
||||
IdString tag_id(const Cell *cell)
|
||||
{
|
||||
return module->design->twines.add(RTLIL::escape_id(cell->getParam(ID::TAG).decode_string()));
|
||||
}
|
||||
|
||||
void propagate_tags(Cell *cell)
|
||||
{
|
||||
if (cell->type == ID($set_tag)) {
|
||||
IdString tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string());
|
||||
IdString tag = tag_id(cell);
|
||||
if (all_tags.insert(tag).second) {
|
||||
auto group_sep = tag.str().find(':');
|
||||
IdString tag_group = group_sep != std::string::npos ? tag.str().substr(0, group_sep) : tag;
|
||||
std::string tag_str = module->design->twines.str(tag);
|
||||
auto group_sep = tag_str.find(':');
|
||||
IdString tag_group = group_sep != std::string::npos
|
||||
? module->design->twines.add(tag_str.substr(0, group_sep)) : tag;
|
||||
tag_groups[tag_group].insert(tag);
|
||||
group_of_tag[tag] = tag_group;
|
||||
}
|
||||
@@ -478,7 +485,7 @@ struct DftTagWorker {
|
||||
void process_cell(IdString tag, Cell *cell)
|
||||
{
|
||||
if (cell->type == ID($set_tag)) {
|
||||
IdString cell_tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string());
|
||||
IdString cell_tag = tag_id(cell);
|
||||
|
||||
auto tag_sig_a = tag_signal(tag, cell->getPort(ID::A));
|
||||
auto &sig_y = cell->getPort(ID::Y);
|
||||
@@ -628,7 +635,7 @@ struct DftTagWorker {
|
||||
|
||||
auto prop = autoEq(NEW_ID, masked_a, masked_b);
|
||||
|
||||
auto tag_sig = autoAnd(NEW_ID, prop, autoReduceOr(NEW_ID, {tag_sig_a, tag_sig_b}));
|
||||
auto tag_sig = autoAnd(NEW_ID, prop, autoReduceOr(NEW_ID, SigSpec{tag_sig_a, tag_sig_b}));
|
||||
tag_sig.extend_u0(GetSize(sig_y), false);
|
||||
emit_tag_signal(tag, sig_y, tag_sig);
|
||||
return;
|
||||
@@ -660,7 +667,7 @@ struct DftTagWorker {
|
||||
|
||||
auto prop = autoGe(NEW_ID, masked_a, masked_b);
|
||||
|
||||
auto tag_sig = autoAnd(NEW_ID, prop, autoReduceOr(NEW_ID, {tag_sig_a, tag_sig_b}));
|
||||
auto tag_sig = autoAnd(NEW_ID, prop, autoReduceOr(NEW_ID, SigSpec{tag_sig_a, tag_sig_b}));
|
||||
tag_sig.extend_u0(GetSize(sig_y), false);
|
||||
emit_tag_signal(tag, sig_y, tag_sig);
|
||||
return;
|
||||
@@ -698,7 +705,7 @@ struct DftTagWorker {
|
||||
auto sig_q = ff.sig_q;
|
||||
auto sig_d = ff.sig_d;
|
||||
|
||||
ff.name = NEW_ID;
|
||||
ff.name = module->design->twines.add(NEW_ID);
|
||||
ff.cell = nullptr;
|
||||
ff.sig_d = tag_signal(tag, ff.sig_d);
|
||||
ff.sig_q = module->addWire(NEW_ID, width);
|
||||
@@ -752,7 +759,7 @@ struct DftTagWorker {
|
||||
|
||||
for (auto cell : get_tag_cells) {
|
||||
auto &sig_a = cell->getPort(ID::A);
|
||||
IdString tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string());
|
||||
IdString tag = tag_id(cell);
|
||||
|
||||
tag_signal(tag, sig_a);
|
||||
}
|
||||
@@ -772,13 +779,14 @@ struct DftTagWorker {
|
||||
continue;
|
||||
|
||||
int index = 0;
|
||||
auto name = module->uniquify(stringf("%s:%s", wire->name, tag.c_str() + 1), index);
|
||||
std::string tag_str = module->design->twines.unescaped_str(tag);
|
||||
auto name = module->uniquify(stringf("%s:%s", wire->name, tag_str), index);
|
||||
auto hdlname = wire->get_hdlname_attribute();
|
||||
|
||||
if (!hdlname.empty())
|
||||
hdlname.back() += index ?
|
||||
stringf(":%s_%d", tag.c_str() + 1, index) :
|
||||
stringf(":%s", tag.c_str() + 1);
|
||||
stringf(":%s_%d", tag_str, index) :
|
||||
stringf(":%s", tag_str);
|
||||
|
||||
auto tag_wire = module->addWire(name, wire->width);
|
||||
|
||||
@@ -817,7 +825,7 @@ struct DftTagWorker {
|
||||
for (auto cell : get_tag_cells) {
|
||||
auto &sig_a = cell->getPort(ID::A);
|
||||
auto &sig_y = cell->getPort(ID::Y);
|
||||
IdString tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string());
|
||||
IdString tag = tag_id(cell);
|
||||
|
||||
auto tag_sig = tag_signal(tag, sig_a);
|
||||
module->connect(sig_y, tag_sig);
|
||||
@@ -826,7 +834,7 @@ struct DftTagWorker {
|
||||
}
|
||||
|
||||
|
||||
SigSpec autoAnd(IdString name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
SigSpec autoAnd(Twine &&name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
{
|
||||
log_assert(GetSize(sig_a) == GetSize(sig_b));
|
||||
if (sig_a.is_fully_zero() || sig_b.is_fully_ones() || sig_a == sig_b)
|
||||
@@ -834,10 +842,10 @@ struct DftTagWorker {
|
||||
if (sig_a.is_fully_ones() || sig_b.is_fully_zero())
|
||||
return sig_b;
|
||||
|
||||
return module->And(name, sig_a, sig_b);
|
||||
return module->And(std::move(name), sig_a, sig_b);
|
||||
}
|
||||
|
||||
SigSpec autoOr(IdString name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
SigSpec autoOr(Twine &&name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
{
|
||||
log_assert(GetSize(sig_a) == GetSize(sig_b));
|
||||
if (sig_a.is_fully_ones() || sig_b.is_fully_zero() || sig_a == sig_b)
|
||||
@@ -845,10 +853,10 @@ struct DftTagWorker {
|
||||
if (sig_a.is_fully_zero() || sig_b.is_fully_ones())
|
||||
return sig_b;
|
||||
|
||||
return module->Or(name, sig_a, sig_b);
|
||||
return module->Or(std::move(name), sig_a, sig_b);
|
||||
}
|
||||
|
||||
SigSpec autoXor(IdString name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
SigSpec autoXor(Twine &&name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
{
|
||||
log_assert(GetSize(sig_a) == GetSize(sig_b));
|
||||
if (sig_a == sig_b)
|
||||
@@ -858,13 +866,13 @@ struct DftTagWorker {
|
||||
if (sig_b.is_fully_zero())
|
||||
return sig_a;
|
||||
if (sig_a.is_fully_ones())
|
||||
return autoNot(name, sig_b);
|
||||
return autoNot(std::move(name), sig_b);
|
||||
if (sig_b.is_fully_ones())
|
||||
return autoNot(name, sig_a);
|
||||
return module->Xor(name, sig_a, sig_b);
|
||||
return autoNot(std::move(name), sig_a);
|
||||
return module->Xor(std::move(name), sig_a, sig_b);
|
||||
}
|
||||
|
||||
SigSpec autoXnor(IdString name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
SigSpec autoXnor(Twine &&name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
{
|
||||
log_assert(GetSize(sig_a) == GetSize(sig_b));
|
||||
if (sig_a == sig_b)
|
||||
@@ -874,13 +882,13 @@ struct DftTagWorker {
|
||||
if (sig_b.is_fully_ones())
|
||||
return sig_a;
|
||||
if (sig_a.is_fully_zero())
|
||||
return autoNot(name, sig_b);
|
||||
return autoNot(std::move(name), sig_b);
|
||||
if (sig_b.is_fully_zero())
|
||||
return autoNot(name, sig_a);
|
||||
return module->Xnor(name, sig_a, sig_b);
|
||||
return autoNot(std::move(name), sig_a);
|
||||
return module->Xnor(std::move(name), sig_a, sig_b);
|
||||
}
|
||||
|
||||
SigSpec autoNot(IdString name, const SigSpec &sig_a)
|
||||
SigSpec autoNot(Twine &&name, const SigSpec &sig_a)
|
||||
{
|
||||
if (sig_a.is_fully_const()) {
|
||||
auto const_val = sig_a.as_const();
|
||||
@@ -890,10 +898,10 @@ struct DftTagWorker {
|
||||
}
|
||||
return const_val;
|
||||
}
|
||||
return module->Not(name, sig_a);
|
||||
return module->Not(std::move(name), sig_a);
|
||||
}
|
||||
|
||||
SigSpec autoEq(IdString name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
SigSpec autoEq(Twine &&name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
{
|
||||
log_assert(GetSize(sig_a) == GetSize(sig_b));
|
||||
if (sig_a == sig_b)
|
||||
@@ -908,10 +916,10 @@ struct DftTagWorker {
|
||||
return State::S0;
|
||||
}
|
||||
|
||||
return module->Eq(name, sig_a, sig_b);
|
||||
return module->Eq(std::move(name), sig_a, sig_b);
|
||||
}
|
||||
|
||||
SigSpec autoGe(IdString name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
SigSpec autoGe(Twine &&name, const SigSpec &sig_a, const SigSpec &sig_b)
|
||||
{
|
||||
log_assert(GetSize(sig_a) == GetSize(sig_b));
|
||||
if (sig_a == sig_b || sig_a.is_fully_ones())
|
||||
@@ -919,10 +927,10 @@ struct DftTagWorker {
|
||||
if (sig_b.is_fully_zero())
|
||||
return State::S1;
|
||||
|
||||
return module->Ge(name, sig_a, sig_b);
|
||||
return module->Ge(std::move(name), sig_a, sig_b);
|
||||
}
|
||||
|
||||
SigSpec autoReduceAnd(IdString name, const SigSpec &sig_a)
|
||||
SigSpec autoReduceAnd(Twine &&name, const SigSpec &sig_a)
|
||||
{
|
||||
if (GetSize(sig_a) == 0)
|
||||
return State::S1;
|
||||
@@ -934,10 +942,10 @@ struct DftTagWorker {
|
||||
return State::S0;
|
||||
if (sig_a.is_fully_ones())
|
||||
return State::S1;
|
||||
return module->ReduceAnd(name, sig_a);
|
||||
return module->ReduceAnd(std::move(name), sig_a);
|
||||
}
|
||||
|
||||
SigSpec autoReduceOr(IdString name, const SigSpec &sig_a)
|
||||
SigSpec autoReduceOr(Twine &&name, const SigSpec &sig_a)
|
||||
{
|
||||
if (GetSize(sig_a) == 0)
|
||||
return State::S0;
|
||||
@@ -949,7 +957,7 @@ struct DftTagWorker {
|
||||
return State::S1;
|
||||
if (sig_a.is_fully_zero())
|
||||
return State::S0;
|
||||
return module->ReduceOr(name, sig_a);
|
||||
return module->ReduceOr(std::move(name), sig_a);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ private:
|
||||
std::vector<std::pair<RTLIL::SigSpec, RTLIL::IdString>> meta_mux_selects;
|
||||
RTLIL::Module *module = nullptr;
|
||||
|
||||
const RTLIL::IdString cost_model_wire_name = ID(__glift_weight);
|
||||
const RTLIL::IdString glift_attribute_name = ID(glift);
|
||||
const IdString cost_model_wire_name = ID::__glift_weight;
|
||||
const IdString glift_attribute_name = ID::glift;
|
||||
|
||||
|
||||
RTLIL::SigSpec get_corresponding_taint_signal(RTLIL::SigSpec sig) {
|
||||
@@ -47,7 +47,8 @@ private:
|
||||
|
||||
//Get a SigSpec for the corresponding taint signal for the cell port, creating one if necessary:
|
||||
if (sig.is_wire()) {
|
||||
RTLIL::Wire *w = module->wire(sig.as_wire()->name.str() + "_t");
|
||||
IdString taint_name_ref = module->design->twines.add(sig.as_wire()->name.str() + "_t");
|
||||
RTLIL::Wire *w = module->wire(taint_name_ref);
|
||||
if (w == nullptr) w = module->addWire(sig.as_wire()->name.str() + "_t", 1);
|
||||
ret = w;
|
||||
}
|
||||
@@ -385,8 +386,8 @@ private:
|
||||
meta_mux_select_sums.swap(meta_mux_select_sums_buf);
|
||||
}
|
||||
if (meta_mux_select_sums.size() > 0) {
|
||||
meta_mux_select_sums[0].as_wire()->set_bool_attribute("\\minimize");
|
||||
meta_mux_select_sums[0].as_wire()->set_bool_attribute("\\keep");
|
||||
meta_mux_select_sums[0].as_wire()->set_bool_attribute(ID::minimize);
|
||||
meta_mux_select_sums[0].as_wire()->set_bool_attribute(ID::keep);
|
||||
module->rename(meta_mux_select_sums[0].as_wire(), cost_model_wire_name);
|
||||
}
|
||||
}
|
||||
@@ -600,7 +601,7 @@ struct GliftPass : public Pass {
|
||||
|
||||
for (auto i = 0; i < GetSize(topo_modules.sorted); ++i) {
|
||||
RTLIL::Module *module = topo_modules.sorted[i];
|
||||
GliftWorker(module, !non_top_modules[module->name], opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model, opt_taintconstants, opt_keepoutputs, opt_simplecostmodel, opt_nocostmodel, opt_instrumentmore);
|
||||
GliftWorker(module, !non_top_modules.count(module->name), opt_create_precise_model, opt_create_imprecise_model, opt_create_instrumented_model, opt_taintconstants, opt_keepoutputs, opt_simplecostmodel, opt_nocostmodel, opt_instrumentmore);
|
||||
}
|
||||
}
|
||||
} GliftPass;
|
||||
|
||||
+48
-40
@@ -21,6 +21,7 @@
|
||||
#include "kernel/rtlil.h"
|
||||
#include "kernel/log.h"
|
||||
#include "backends/verilog/verilog_backend.h"
|
||||
#include "kernel/twine.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
@@ -30,11 +31,14 @@ static void rename_in_module(RTLIL::Module *module, std::string from_name, std::
|
||||
from_name = RTLIL::escape_id(from_name);
|
||||
to_name = RTLIL::escape_id(to_name);
|
||||
|
||||
if (module->count_id(to_name))
|
||||
log_cmd_error("There is already an object `%s' in module `%s'.\n", RTLIL::unescape_id(to_name), module->name);
|
||||
TwineSearch search(&module->design->twines);
|
||||
IdString to_ref = search.find(to_name);
|
||||
if (module->count_id(to_ref))
|
||||
log_cmd_error("There is already an object `%s' in module `%s'.\n", RTLIL::unescape_id(to_name), module);
|
||||
|
||||
RTLIL::Wire *wire_to_rename = module->wire(from_name);
|
||||
RTLIL::Cell *cell_to_rename = module->cell(from_name);
|
||||
IdString from_ref = search.find(from_name);
|
||||
RTLIL::Wire *wire_to_rename = module->wire(from_ref);
|
||||
RTLIL::Cell *cell_to_rename = module->cell(from_ref);
|
||||
|
||||
if (wire_to_rename != nullptr) {
|
||||
log("Renaming wire %s to %s in module %s.\n", wire_to_rename, RTLIL::unescape_id(to_name), module);
|
||||
@@ -105,13 +109,16 @@ static IdString derive_name_from_cell_output_wire(const RTLIL::Cell *cell, strin
|
||||
|
||||
RTLIL::Wire *wire;
|
||||
|
||||
if (move_to_cell && (!(wire = cell->module->wire(name)) || !(wire->port_input || wire->port_output)))
|
||||
return name;
|
||||
if (move_to_cell) {
|
||||
IdString name_ref = cell->module->design->twines.find(name);
|
||||
if (!(wire = cell->module->wire(name_ref)) || !(wire->port_input || wire->port_output))
|
||||
return cell->module->design->twines.add(std::move(name));
|
||||
}
|
||||
|
||||
if (suffix.empty()) {
|
||||
suffix = cell->type.str();
|
||||
}
|
||||
return name + suffix;
|
||||
return cell->module->design->twines.add(name + suffix);
|
||||
}
|
||||
|
||||
static bool rename_witness(RTLIL::Design *design, dict<RTLIL::Module *, int> &cache, RTLIL::Module *module)
|
||||
@@ -134,12 +141,12 @@ static bool rename_witness(RTLIL::Design *design, dict<RTLIL::Module *, int> &ca
|
||||
bool witness_in_cell = rename_witness(design, cache, impl);
|
||||
has_witness_signals |= witness_in_cell;
|
||||
if (witness_in_cell && !cell->name.isPublic()) {
|
||||
std::string name = cell->name.c_str() + 1;
|
||||
std::string name = cell->name.str().substr(1);
|
||||
for (auto &c : name)
|
||||
if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '_')
|
||||
c = '_';
|
||||
auto new_id = module->uniquify("\\_witness_." + name);
|
||||
cell->set_hdlname_attribute({ "_witness_", strstr(new_id.c_str(), ".") + 1 });
|
||||
cell->set_hdlname_attribute({ "_witness_", strstr(module->design->twines.str(new_id).c_str(), ".") + 1 });
|
||||
renames.emplace_back(cell, new_id);
|
||||
}
|
||||
}
|
||||
@@ -156,13 +163,13 @@ static bool rename_witness(RTLIL::Design *design, dict<RTLIL::Module *, int> &ca
|
||||
|
||||
for (auto chunk : sig_out.chunks()) {
|
||||
if (chunk.is_wire() && !chunk.wire->name.isPublic()) {
|
||||
std::string name = stringf("%s_%s", cell->type.c_str() + 1, cell->name.c_str() + 1);
|
||||
std::string name = stringf("%s_%s", cell->type.str().substr(1), cell->name.str().substr(1));
|
||||
for (auto &c : name)
|
||||
if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '_')
|
||||
c = '_';
|
||||
auto new_id = module->uniquify("\\_witness_." + name);
|
||||
auto new_wire = module->addWire(new_id, GetSize(sig_out));
|
||||
new_wire->set_hdlname_attribute({ "_witness_", strstr(new_id.c_str(), ".") + 1 });
|
||||
new_wire->set_hdlname_attribute({ "_witness_", strstr(module->design->twines.str(new_id).c_str(), ".") + 1 });
|
||||
if (clk2fflogic)
|
||||
module->connect({new_wire, sig_out});
|
||||
else
|
||||
@@ -178,13 +185,13 @@ static bool rename_witness(RTLIL::Design *design, dict<RTLIL::Module *, int> &ca
|
||||
has_witness_signals = true;
|
||||
if (cell->name.isPublic())
|
||||
continue;
|
||||
std::string name = stringf("%s_%s", cell->type.c_str() + 1, cell->name.c_str() + 1);
|
||||
std::string name = stringf("%s_%s", cell->type.str().substr(1), cell->name.str().substr(1));
|
||||
for (auto &c : name)
|
||||
if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '_')
|
||||
c = '_';
|
||||
auto new_id = module->uniquify("\\_witness_." + name);
|
||||
renames.emplace_back(cell, new_id);
|
||||
cell->set_hdlname_attribute({ "_witness_", strstr(new_id.c_str(), ".") + 1 });
|
||||
cell->set_hdlname_attribute({ "_witness_", strstr(module->design->twines.str(new_id).c_str(), ".") + 1 });
|
||||
}
|
||||
}
|
||||
for (auto rename : renames) {
|
||||
@@ -389,12 +396,12 @@ struct RenamePass : public Pass {
|
||||
dict<RTLIL::Cell *, IdString> new_cell_names;
|
||||
|
||||
for (auto wire : module->selected_wires())
|
||||
if (wire->name[0] == '$')
|
||||
new_wire_names.emplace(wire, derive_name_from_src(wire->get_src_attribute(), counter++));
|
||||
if (!wire->name.isPublic())
|
||||
new_wire_names.emplace(wire, module->design->twines.add(derive_name_from_src(wire->get_src_attribute(), counter++)));
|
||||
|
||||
for (auto cell : module->selected_cells())
|
||||
if (cell->name[0] == '$')
|
||||
new_cell_names.emplace(cell, derive_name_from_src(cell->get_src_attribute(), counter++));
|
||||
if (!cell->name.isPublic())
|
||||
new_cell_names.emplace(cell, module->design->twines.add(derive_name_from_src(cell->get_src_attribute(), counter++)));
|
||||
|
||||
for (auto &it : new_wire_names)
|
||||
module->rename(it.first, it.second);
|
||||
@@ -411,7 +418,7 @@ struct RenamePass : public Pass {
|
||||
for (auto module : design->selected_modules()) {
|
||||
dict<RTLIL::Cell *, IdString> new_cell_names;
|
||||
for (auto cell : module->selected_cells())
|
||||
if (cell->name[0] == '$')
|
||||
if (!cell->name.isPublic())
|
||||
new_cell_names[cell] = derive_name_from_cell_output_wire(cell, cell_suffix, flag_move_to_cell);
|
||||
for (auto &[cell, new_name] : new_cell_names) {
|
||||
if (flag_move_to_cell) {
|
||||
@@ -421,13 +428,12 @@ struct RenamePass : public Pass {
|
||||
if (wire_suffix.empty()) {
|
||||
for (auto const &[port, _] : cell->connections()) {
|
||||
if (cell->output(port)) {
|
||||
wire_suffix += stringf("%s.%s", cell->type, port.c_str() + 1);
|
||||
wire_suffix += stringf("%s.%s", cell->type, module->design->twines.str(port).c_str() + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
IdString new_wire_name = found_wire->name.str() + wire_suffix;
|
||||
module->rename(found_wire, new_wire_name);
|
||||
module->rename(found_wire, found_wire->name.unescape() + wire_suffix);
|
||||
}
|
||||
}
|
||||
module->rename(cell, new_name);
|
||||
@@ -446,19 +452,19 @@ struct RenamePass : public Pass {
|
||||
dict<RTLIL::Cell *, IdString> new_cell_names;
|
||||
|
||||
for (auto wire : module->selected_wires())
|
||||
if (wire->name[0] == '$') {
|
||||
RTLIL::IdString buf;
|
||||
if (!wire->name.isPublic()) {
|
||||
std::string buf;
|
||||
do buf = stringf("\\%s%d%s", pattern_prefix, counter++, pattern_suffix);
|
||||
while (module->wire(buf) != nullptr);
|
||||
new_wire_names[wire] = buf;
|
||||
while (module->wire(design->twines.find(buf)) != nullptr);
|
||||
new_wire_names[wire] = design->twines.add(std::move(buf));
|
||||
}
|
||||
|
||||
for (auto cell : module->selected_cells())
|
||||
if (cell->name[0] == '$') {
|
||||
RTLIL::IdString buf;
|
||||
if (!cell->name.isPublic()) {
|
||||
std::string buf;
|
||||
do buf = stringf("\\%s%d%s", pattern_prefix, counter++, pattern_suffix);
|
||||
while (module->cell(buf) != nullptr);
|
||||
new_cell_names[cell] = buf;
|
||||
while (module->cell(design->twines.find(buf)) != nullptr);
|
||||
new_cell_names[cell] = design->twines.add(std::move(buf));
|
||||
}
|
||||
|
||||
for (auto &it : new_wire_names)
|
||||
@@ -493,11 +499,11 @@ struct RenamePass : public Pass {
|
||||
|
||||
for (auto wire : module->selected_wires())
|
||||
if (wire->name.isPublic() && wire->port_id == 0)
|
||||
new_wire_names[wire] = NEW_ID;
|
||||
new_wire_names[wire] = module->design->twines.add(NEW_ID);
|
||||
|
||||
for (auto cell : module->selected_cells())
|
||||
if (cell->name.isPublic())
|
||||
new_cell_names[cell] = NEW_ID;
|
||||
new_cell_names[cell] = module->design->twines.add(NEW_ID);
|
||||
|
||||
for (auto &it : new_wire_names)
|
||||
module->rename(it.first, it.second);
|
||||
@@ -512,13 +518,13 @@ struct RenamePass : public Pass {
|
||||
if (argidx+1 != args.size())
|
||||
log_cmd_error("Invalid number of arguments!\n");
|
||||
|
||||
IdString new_name = RTLIL::escape_id(args[argidx]);
|
||||
IdString new_name = design->twines.add(std::string{RTLIL::escape_id(args[argidx])});
|
||||
RTLIL::Module *module = design->top_module();
|
||||
|
||||
if (module == nullptr)
|
||||
log_cmd_error("No top module found!\n");
|
||||
|
||||
log("Renaming module %s to %s.\n", module, new_name.unescape());
|
||||
log("Renaming module %s to %s.\n", module, PooledName(design, new_name).unescape());
|
||||
design->rename(module, new_name);
|
||||
}
|
||||
else
|
||||
@@ -542,12 +548,12 @@ struct RenamePass : public Pass {
|
||||
for (auto wire : module->selected_wires())
|
||||
if (wire->port_id == 0) {
|
||||
seed = mkhash_xorshift(seed);
|
||||
new_wire_names[wire] = stringf("$_%u_", seed);
|
||||
new_wire_names[wire] = module->design->twines.add(stringf("$_%u_", seed));
|
||||
}
|
||||
|
||||
for (auto cell : module->selected_cells()) {
|
||||
seed = mkhash_xorshift(seed);
|
||||
new_cell_names[cell] = stringf("$_%u_", seed);
|
||||
new_cell_names[cell] = module->design->twines.add(stringf("$_%u_", seed));
|
||||
}
|
||||
|
||||
for (auto &it : new_wire_names)
|
||||
@@ -574,7 +580,7 @@ struct RenamePass : public Pass {
|
||||
if (!VERILOG_BACKEND::id_is_verilog_escaped(name))
|
||||
continue;
|
||||
new_wire_names[wire] = module->uniquify("\\" + renamed_unescaped(name));
|
||||
auto new_name = new_wire_names[wire].str().substr(1);
|
||||
auto new_name = module->design->twines.str(new_wire_names[wire]).substr(1);
|
||||
if (VERILOG_BACKEND::id_is_verilog_escaped(new_name))
|
||||
log_error("Failed to rename wire %s -> %s\n", name, new_name);
|
||||
}
|
||||
@@ -587,7 +593,7 @@ struct RenamePass : public Pass {
|
||||
if (!VERILOG_BACKEND::id_is_verilog_escaped(name))
|
||||
continue;
|
||||
new_cell_names[cell] = module->uniquify("\\" + renamed_unescaped(name));
|
||||
auto new_name = new_cell_names[cell].str().substr(1);
|
||||
auto new_name = module->design->twines.str(new_cell_names[cell]).substr(1);
|
||||
if (VERILOG_BACKEND::id_is_verilog_escaped(new_name))
|
||||
log_error("Failed to rename cell %s -> %s\n", name, new_name);
|
||||
}
|
||||
@@ -609,7 +615,7 @@ struct RenamePass : public Pass {
|
||||
std::string from_name = args[argidx++];
|
||||
std::string to_name = args[argidx++];
|
||||
|
||||
if (!design->selected_active_module.empty())
|
||||
if (design->selected_active_module != IdString::Null)
|
||||
{
|
||||
if (design->module(design->selected_active_module) != nullptr)
|
||||
rename_in_module(design->module(design->selected_active_module), from_name, to_name, flag_output);
|
||||
@@ -620,11 +626,13 @@ struct RenamePass : public Pass {
|
||||
log_cmd_error("Mode -output requires that there is an active module selected.\n");
|
||||
|
||||
RTLIL::Module *module_to_rename = nullptr;
|
||||
for (auto module : design->modules())
|
||||
if (module->name == from_name || module->name.unescape() == from_name) {
|
||||
for (auto module : design->modules()) {
|
||||
std::string module_name_str = module->name.str();
|
||||
if (module_name_str == from_name || RTLIL::unescape_id(module_name_str) == from_name) {
|
||||
module_to_rename = module;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (module_to_rename != nullptr) {
|
||||
to_name = RTLIL::escape_id(to_name);
|
||||
|
||||
+98
-68
@@ -17,6 +17,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "kernel/rtlil.h"
|
||||
#include "kernel/twine.h"
|
||||
#include "kernel/yosys.h"
|
||||
#include "kernel/newcelltypes.h"
|
||||
#include "kernel/sigtools.h"
|
||||
@@ -27,14 +29,14 @@ PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
static std::vector<RTLIL::Selection> work_stack;
|
||||
|
||||
static bool match_ids(RTLIL::IdString id, const std::string &pattern)
|
||||
static bool match_ids(const std::string &id, const std::string &pattern)
|
||||
{
|
||||
if (id == pattern)
|
||||
return true;
|
||||
|
||||
const char *id_c = id.c_str();
|
||||
const char *pat_c = pattern.c_str();
|
||||
size_t id_size = strlen(id_c);
|
||||
size_t id_size = id.size();
|
||||
size_t pat_size = pattern.size();
|
||||
|
||||
if (*id_c == '\\' && id_size == 1 + pat_size && memcmp(id_c + 1, pat_c, pat_size) == 0)
|
||||
@@ -103,39 +105,44 @@ static bool match_attr_val(const RTLIL::Const &value, const std::string &pattern
|
||||
log_abort();
|
||||
}
|
||||
|
||||
static bool match_attr(const dict<RTLIL::IdString, RTLIL::Const> &attributes, const std::string &name_pat, const std::string &value_pat, char match_op)
|
||||
static bool match_attr(const TwinePool &pool, const dict<IdString, RTLIL::Const> &attributes, const std::string &name_pat, const std::string &value_pat, char match_op)
|
||||
{
|
||||
if (name_pat.find('*') != std::string::npos || name_pat.find('?') != std::string::npos || name_pat.find('[') != std::string::npos) {
|
||||
for (auto &it : attributes) {
|
||||
if (patmatch(name_pat.c_str(), it.first.c_str()) && match_attr_val(it.second, value_pat, match_op))
|
||||
std::string name = pool.str(it.first);
|
||||
if (patmatch(name_pat.c_str(), name.c_str()) && match_attr_val(it.second, value_pat, match_op))
|
||||
return true;
|
||||
if (it.first.size() > 0 && it.first[0] == '\\' && patmatch(name_pat.c_str(), it.first.substr(1).c_str()) && match_attr_val(it.second, value_pat, match_op))
|
||||
if (name.size() > 0 && name[0] == '\\' && patmatch(name_pat.c_str(), name.c_str() + 1) && match_attr_val(it.second, value_pat, match_op))
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (name_pat.size() > 0 && (name_pat[0] == '\\' || name_pat[0] == '$') && attributes.count(name_pat) && match_attr_val(attributes.at(name_pat), value_pat, match_op))
|
||||
return true;
|
||||
if (attributes.count("\\" + name_pat) && match_attr_val(attributes.at("\\" + name_pat), value_pat, match_op))
|
||||
if (name_pat.size() > 0 && (name_pat[0] == '\\' || name_pat[0] == '$')) {
|
||||
IdString key = pool.find(name_pat);
|
||||
if (key != IdString::Null && attributes.count(key) && match_attr_val(attributes.at(key), value_pat, match_op))
|
||||
return true;
|
||||
}
|
||||
IdString key = pool.find("\\" + name_pat);
|
||||
if (key != IdString::Null && attributes.count(key) && match_attr_val(attributes.at(key), value_pat, match_op))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool match_attr(const dict<RTLIL::IdString, RTLIL::Const> &attributes, const std::string &match_expr)
|
||||
static bool match_attr(const TwinePool &pool, const dict<IdString, RTLIL::Const> &attributes, const std::string &match_expr)
|
||||
{
|
||||
size_t pos = match_expr.find_first_of("<!=>");
|
||||
|
||||
if (pos != std::string::npos) {
|
||||
if (match_expr.compare(pos, 2, "!=") == 0)
|
||||
return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '!');
|
||||
return match_attr(pool, attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '!');
|
||||
if (match_expr.compare(pos, 2, "<=") == 0)
|
||||
return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '[');
|
||||
return match_attr(pool, attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), '[');
|
||||
if (match_expr.compare(pos, 2, ">=") == 0)
|
||||
return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), ']');
|
||||
return match_attr(attributes, match_expr.substr(0, pos), match_expr.substr(pos+1), match_expr[pos]);
|
||||
return match_attr(pool, attributes, match_expr.substr(0, pos), match_expr.substr(pos+2), ']');
|
||||
return match_attr(pool, attributes, match_expr.substr(0, pos), match_expr.substr(pos+1), match_expr[pos]);
|
||||
}
|
||||
|
||||
return match_attr(attributes, match_expr, std::string(), 0);
|
||||
return match_attr(pool, attributes, match_expr, std::string(), 0);
|
||||
}
|
||||
|
||||
static void select_all(RTLIL::Design *design, RTLIL::Selection &lhs)
|
||||
@@ -466,11 +473,11 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co
|
||||
namespace {
|
||||
struct expand_rule_t {
|
||||
char mode;
|
||||
std::set<RTLIL::IdString> cell_types, port_names;
|
||||
std::set<std::string> cell_types, port_names;
|
||||
};
|
||||
}
|
||||
|
||||
static int parse_comma_list(std::set<RTLIL::IdString> &tokens, const std::string &str, size_t pos, std::string stopchar)
|
||||
static int parse_comma_list(std::set<std::string> &tokens, const std::string &str, size_t pos, std::string stopchar)
|
||||
{
|
||||
stopchar += ',';
|
||||
while (1) {
|
||||
@@ -517,6 +524,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
|
||||
}
|
||||
}
|
||||
|
||||
auto &twines = design->twines;
|
||||
for (auto cell : mod->cells())
|
||||
for (auto &conn : cell->connections())
|
||||
{
|
||||
@@ -527,7 +535,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
|
||||
last_mode = rule.mode;
|
||||
if (rule.cell_types.size() > 0 && rule.cell_types.count(cell->type) == 0)
|
||||
continue;
|
||||
if (rule.port_names.size() > 0 && rule.port_names.count(conn.first) == 0)
|
||||
if (rule.port_names.size() > 0 && rule.port_names.count(twines.str(conn.first)) == 0)
|
||||
continue;
|
||||
if (rule.mode == '+')
|
||||
goto include_match;
|
||||
@@ -610,14 +618,15 @@ static void select_op_expand(RTLIL::Design *design, const std::string &arg, char
|
||||
std::string str = arg.substr(pos, endpos-pos);
|
||||
if (str[0] == '@') {
|
||||
str = RTLIL::escape_id(str.substr(1));
|
||||
if (design->selection_vars.count(str) > 0) {
|
||||
for (auto i1 : design->selection_vars.at(str).selected_members)
|
||||
IdString sel_name = design->twines.find(str);
|
||||
if (sel_name != IdString::Null && design->selection_vars.count(sel_name) > 0) {
|
||||
for (auto i1 : design->selection_vars.at(sel_name).selected_members)
|
||||
for (auto i2 : i1.second)
|
||||
limits.insert(i2);
|
||||
} else
|
||||
log_cmd_error("Selection %s is not defined!\n", RTLIL::unescape_id(str));
|
||||
} else
|
||||
limits.insert(RTLIL::escape_id(str));
|
||||
limits.insert(design->twines.add(RTLIL::escape_id(str)));
|
||||
}
|
||||
pos = endpos;
|
||||
}
|
||||
@@ -661,7 +670,7 @@ static void select_op_expand(RTLIL::Design *design, const std::string &arg, char
|
||||
|
||||
static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &sel)
|
||||
{
|
||||
if (design->selected_active_module.empty())
|
||||
if (design->selected_active_module == IdString::Null)
|
||||
return;
|
||||
|
||||
if (sel.full_selection) {
|
||||
@@ -810,8 +819,9 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
|
||||
|
||||
if (arg[0] == '@') {
|
||||
std::string set_name = RTLIL::escape_id(arg.substr(1));
|
||||
if (design->selection_vars.count(set_name) > 0)
|
||||
work_stack.push_back(design->selection_vars[set_name]);
|
||||
IdString set_twine = design->twines.find(set_name);
|
||||
if (set_twine != IdString::Null && design->selection_vars.count(set_twine) > 0)
|
||||
work_stack.push_back(design->selection_vars[set_twine]);
|
||||
else
|
||||
log_cmd_error("Selection @%s is not defined!\n", RTLIL::unescape_id(set_name));
|
||||
select_filter_active_mod(design, work_stack.back());
|
||||
@@ -824,8 +834,8 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
|
||||
select_blackboxes = true;
|
||||
}
|
||||
|
||||
if (!design->selected_active_module.empty()) {
|
||||
arg_mod = design->selected_active_module;
|
||||
if (design->selected_active_module != IdString::Null) {
|
||||
arg_mod = design->twines.str(design->selected_active_module);
|
||||
arg_memb = arg;
|
||||
if (!isprefixed(arg_memb))
|
||||
arg_memb_found[arg_memb] = false;
|
||||
@@ -864,7 +874,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
|
||||
continue;
|
||||
|
||||
if (arg_mod.compare(0, 2, "A:") == 0) {
|
||||
if (!match_attr(mod->attributes, arg_mod.substr(2)))
|
||||
if (!match_attr(design->twines, mod->attributes, arg_mod.substr(2)))
|
||||
continue;
|
||||
} else
|
||||
if (arg_mod.compare(0, 2, "N:") == 0) {
|
||||
@@ -920,7 +930,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
|
||||
} else
|
||||
if (arg_memb.compare(0, 2, "m:") == 0) {
|
||||
for (auto &it : mod->memories)
|
||||
if (match_ids(it.first, arg_memb.substr(2)))
|
||||
if (match_ids(design->twines.str(it.first), arg_memb.substr(2)))
|
||||
sel.selected_members[mod->name].insert(it.first);
|
||||
} else
|
||||
if (arg_memb.compare(0, 2, "c:") == 0) {
|
||||
@@ -931,10 +941,11 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
|
||||
if (arg_memb.compare(0, 2, "t:") == 0) {
|
||||
if (arg_memb.compare(2, 1, "@") == 0) {
|
||||
std::string set_name = RTLIL::escape_id(arg_memb.substr(3));
|
||||
if (!design->selection_vars.count(set_name))
|
||||
IdString set_twine = design->twines.find(set_name);
|
||||
if (set_twine == IdString::Null || !design->selection_vars.count(set_twine))
|
||||
log_cmd_error("Selection @%s is not defined!\n", RTLIL::unescape_id(set_name));
|
||||
|
||||
auto &muster = design->selection_vars[set_name];
|
||||
auto &muster = design->selection_vars[set_twine];
|
||||
for (auto cell : mod->cells())
|
||||
if (muster.selected_modules.count(cell->type))
|
||||
sel.selected_members[mod->name].insert(cell->name);
|
||||
@@ -946,26 +957,26 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
|
||||
} else
|
||||
if (arg_memb.compare(0, 2, "p:") == 0) {
|
||||
for (auto &it : mod->processes)
|
||||
if (match_ids(it.first, arg_memb.substr(2)))
|
||||
if (match_ids(design->twines.str(it.first), arg_memb.substr(2)))
|
||||
sel.selected_members[mod->name].insert(it.first);
|
||||
} else
|
||||
if (arg_memb.compare(0, 2, "a:") == 0) {
|
||||
for (auto wire : mod->wires())
|
||||
if (match_attr(wire->attributes, arg_memb.substr(2)))
|
||||
if (match_attr(design->twines, wire->attributes, arg_memb.substr(2)))
|
||||
sel.selected_members[mod->name].insert(wire->name);
|
||||
for (auto &it : mod->memories)
|
||||
if (match_attr(it.second->attributes, arg_memb.substr(2)))
|
||||
if (match_attr(design->twines, it.second->attributes, arg_memb.substr(2)))
|
||||
sel.selected_members[mod->name].insert(it.first);
|
||||
for (auto cell : mod->cells())
|
||||
if (match_attr(cell->attributes, arg_memb.substr(2)))
|
||||
if (match_attr(design->twines, cell->attributes, arg_memb.substr(2)))
|
||||
sel.selected_members[mod->name].insert(cell->name);
|
||||
for (auto &it : mod->processes)
|
||||
if (match_attr(it.second->attributes, arg_memb.substr(2)))
|
||||
if (match_attr(design->twines, it.second->attributes, arg_memb.substr(2)))
|
||||
sel.selected_members[mod->name].insert(it.first);
|
||||
} else
|
||||
if (arg_memb.compare(0, 2, "r:") == 0) {
|
||||
for (auto cell : mod->cells())
|
||||
if (match_attr(cell->parameters, arg_memb.substr(2)))
|
||||
if (match_attr(design->twines, cell->parameters, arg_memb.substr(2)))
|
||||
sel.selected_members[mod->name].insert(cell->name);
|
||||
} else {
|
||||
std::string orig_arg_memb = arg_memb;
|
||||
@@ -977,7 +988,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
|
||||
arg_memb_found[orig_arg_memb] = true;
|
||||
}
|
||||
for (auto &it : mod->memories)
|
||||
if (match_ids(it.first, arg_memb)) {
|
||||
if (match_ids(design->twines.str(it.first), arg_memb)) {
|
||||
sel.selected_members[mod->name].insert(it.first);
|
||||
arg_memb_found[orig_arg_memb] = true;
|
||||
}
|
||||
@@ -987,7 +998,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp
|
||||
arg_memb_found[orig_arg_memb] = true;
|
||||
}
|
||||
for (auto &it : mod->processes)
|
||||
if (match_ids(it.first, arg_memb)) {
|
||||
if (match_ids(design->twines.str(it.first), arg_memb)) {
|
||||
sel.selected_members[mod->name].insert(it.first);
|
||||
arg_memb_found[orig_arg_memb] = true;
|
||||
}
|
||||
@@ -1022,7 +1033,7 @@ static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::S
|
||||
if (whole_modules && sel->selected_whole_module(mod->name))
|
||||
desc += stringf("%s\n", mod);
|
||||
for (auto it : mod->selected_members())
|
||||
desc += stringf("%s/%s\n", mod, it);
|
||||
desc += stringf("%s/%s\n", mod, design->obj_name(it).c_str());
|
||||
}
|
||||
if (push_selection) design->pop_selection();
|
||||
return desc;
|
||||
@@ -1344,6 +1355,7 @@ struct SelectPass : public Pass {
|
||||
|
||||
work_stack.clear();
|
||||
|
||||
std::optional<TwineSearch> search;
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
@@ -1410,10 +1422,13 @@ struct SelectPass : public Pass {
|
||||
continue;
|
||||
}
|
||||
if (arg == "-module" && argidx+1 < args.size()) {
|
||||
RTLIL::IdString mod_name = RTLIL::escape_id(args[++argidx]);
|
||||
if (design->module(mod_name) == nullptr)
|
||||
log_cmd_error("No such module: %s\n", mod_name.unescape());
|
||||
design->selected_active_module = mod_name.str();
|
||||
std::string mod_name = RTLIL::escape_id(args[++argidx]);
|
||||
if (!search)
|
||||
search.emplace(&design->twines);
|
||||
IdString t = search->find(mod_name);
|
||||
if (t == IdString::Null || design->module(t) == nullptr)
|
||||
log_cmd_error("No such module: %s\n", RTLIL::unescape_id(mod_name));
|
||||
design->selected_active_module = t;
|
||||
got_module = true;
|
||||
continue;
|
||||
}
|
||||
@@ -1452,9 +1467,15 @@ struct SelectPass : public Pass {
|
||||
log_warning("Ignoring line without slash in 'select -read': %s\n", line);
|
||||
continue;
|
||||
}
|
||||
IdString mod_name = RTLIL::escape_id(line.substr(0, slash_pos));
|
||||
IdString obj_name = RTLIL::escape_id(line.substr(slash_pos+1));
|
||||
sel.selected_members[mod_name].insert(obj_name);
|
||||
std::string mod_name = RTLIL::escape_id(line.substr(0, slash_pos));
|
||||
std::string obj_name = RTLIL::escape_id(line.substr(slash_pos+1));
|
||||
if (!search)
|
||||
search.emplace(&design->twines);
|
||||
IdString mod_ref = search->find(mod_name);
|
||||
IdString obj_ref = search->find(obj_name);
|
||||
if (mod_ref == IdString::Null || obj_ref == IdString::Null)
|
||||
continue;
|
||||
sel.selected_members[mod_ref].insert(obj_ref);
|
||||
}
|
||||
|
||||
select_filter_active_mod(design, sel);
|
||||
@@ -1498,7 +1519,7 @@ struct SelectPass : public Pass {
|
||||
|
||||
if (clear_mode) {
|
||||
design->selection() = RTLIL::Selection::FullSelection(design);
|
||||
design->selected_active_module = std::string();
|
||||
design->selected_active_module = IdString::Null;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1528,7 +1549,7 @@ struct SelectPass : public Pass {
|
||||
log("%s\n", mod);
|
||||
if (!list_mod_mode)
|
||||
for (auto it : mod->selected_members())
|
||||
LOG_OBJECT("%s/%s\n", mod->name.unescape().c_str(), it->name.unescape().c_str())
|
||||
LOG_OBJECT("%s/%s\n", mod->name.unescape().c_str(), mod->design->twines.unescaped_str(it->name_).c_str())
|
||||
}
|
||||
if (count_mode)
|
||||
{
|
||||
@@ -1633,16 +1654,18 @@ struct SelectPass : public Pass {
|
||||
|
||||
if (!set_name.empty())
|
||||
{
|
||||
IdString set_twine = design->twines.add(std::string(set_name));
|
||||
if (work_stack.size() == 0)
|
||||
design->selection_vars[set_name] = RTLIL::Selection::EmptySelection(design);
|
||||
design->selection_vars[set_twine] = RTLIL::Selection::EmptySelection(design);
|
||||
else
|
||||
design->selection_vars[set_name] = work_stack.back();
|
||||
design->selection_vars[set_twine] = work_stack.back();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!unset_name.empty())
|
||||
{
|
||||
if (!design->selection_vars.erase(unset_name))
|
||||
IdString unset_twine = design->twines.find(unset_name);
|
||||
if (unset_twine == IdString::Null || !design->selection_vars.erase(unset_twine))
|
||||
log_error("Selection '%s' does not exist!\n", unset_name);
|
||||
return;
|
||||
}
|
||||
@@ -1652,10 +1675,10 @@ struct SelectPass : public Pass {
|
||||
if (sel.full_selection)
|
||||
log("*\n");
|
||||
for (auto &it : sel.selected_modules)
|
||||
log("%s\n", it.unescape());
|
||||
log("%s\n", PooledName(design, it).unescape());
|
||||
for (auto &it : sel.selected_members)
|
||||
for (auto &it2 : it.second)
|
||||
log("%s/%s\n", it.first.unescape(), it2.unescape());
|
||||
log("%s/%s\n", PooledName(design, it.first).unescape(), PooledName(design, it2).unescape());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1707,18 +1730,19 @@ struct CdPass : public Pass {
|
||||
if (args.size() == 1 || args[1] == "/") {
|
||||
design->pop_selection();
|
||||
design->push_full_selection();
|
||||
design->selected_active_module = std::string();
|
||||
design->selected_active_module = IdString::Null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (args[1] == "..")
|
||||
{
|
||||
string modname = design->selected_active_module;
|
||||
string modname = design->twines.str(design->selected_active_module);
|
||||
|
||||
design->pop_selection();
|
||||
design->push_full_selection();
|
||||
design->selected_active_module = std::string();
|
||||
design->selected_active_module = IdString::Null;
|
||||
|
||||
TwineSearch search(&design->twines);
|
||||
while (1)
|
||||
{
|
||||
size_t pos = modname.rfind('.');
|
||||
@@ -1727,12 +1751,13 @@ struct CdPass : public Pass {
|
||||
break;
|
||||
|
||||
modname = modname.substr(0, pos);
|
||||
Module *mod = design->module(modname);
|
||||
IdString mod_ref = search.find(modname);
|
||||
Module *mod = design->module(mod_ref);
|
||||
|
||||
if (mod == nullptr)
|
||||
continue;
|
||||
|
||||
design->selected_active_module = modname;
|
||||
design->selected_active_module = mod_ref;
|
||||
design->pop_selection();
|
||||
design->push_full_selection();
|
||||
select_filter_active_mod(design, design->selection());
|
||||
@@ -1743,12 +1768,14 @@ struct CdPass : public Pass {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string modname = RTLIL::escape_id(args[1]);
|
||||
TwineSearch search(&design->twines);
|
||||
IdString modname = search.find(RTLIL::escape_id(args[1]));
|
||||
|
||||
if (design->module(modname) == nullptr && !design->selected_active_module.empty()) {
|
||||
if (design->module(modname) == nullptr && design->selected_active_module != IdString::Null) {
|
||||
RTLIL::Module *module = design->module(design->selected_active_module);
|
||||
if (module != nullptr && module->cell(modname) != nullptr)
|
||||
modname = module->cell(modname)->type.str();
|
||||
IdString cell_ref = modname;
|
||||
if (module != nullptr && cell_ref != IdString::Null && module->cell(cell_ref) != nullptr)
|
||||
modname = module->cell(cell_ref)->type;
|
||||
}
|
||||
|
||||
if (design->module(modname) != nullptr) {
|
||||
@@ -1760,7 +1787,7 @@ struct CdPass : public Pass {
|
||||
return;
|
||||
}
|
||||
|
||||
log_cmd_error("No such module `%s' found!\n", RTLIL::unescape_id(modname));
|
||||
log_cmd_error("No such module `%s' found!\n", PooledName(design, modname).unescape());
|
||||
}
|
||||
} CdPass;
|
||||
|
||||
@@ -1775,9 +1802,12 @@ static void log_matches(const char *title, Module *module, const T &list)
|
||||
|
||||
if (!matches.empty()) {
|
||||
log("\n%d %s:\n", int(matches.size()), title);
|
||||
std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str());
|
||||
for (auto id : matches)
|
||||
log(" %s\n", id.unescape());
|
||||
auto &twines = module->design->twines;
|
||||
std::sort(matches.begin(), matches.end(), [&](IdString a, IdString b) {
|
||||
return twines.str(a) < twines.str(b);
|
||||
});
|
||||
for (auto ref : matches)
|
||||
log(" %s\n", twines.unescaped_str(ref).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1804,7 +1834,7 @@ struct LsPass : public Pass {
|
||||
size_t argidx = 1;
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
if (design->selected_active_module.empty())
|
||||
if (design->selected_active_module == IdString::Null)
|
||||
{
|
||||
std::vector<IdString> matches;
|
||||
|
||||
@@ -1813,9 +1843,9 @@ struct LsPass : public Pass {
|
||||
|
||||
if (!matches.empty()) {
|
||||
log("\n%d %s:\n", int(matches.size()), "modules");
|
||||
std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str());
|
||||
std::sort(matches.begin(), matches.end(), RTLIL::sort_by_id_str(design->twines));
|
||||
for (auto id : matches)
|
||||
log(" %s%s\n", id.unescape(), design->selected_whole_module(design->module(id)) ? "" : "*");
|
||||
log(" %s%s\n", PooledName(design, id).unescape(), design->selected_whole_module(design->module(id)) ? "" : "*");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
+17
-14
@@ -26,7 +26,7 @@ PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
struct setunset_t
|
||||
{
|
||||
RTLIL::IdString name;
|
||||
std::string name;
|
||||
RTLIL::Const value;
|
||||
bool unset;
|
||||
|
||||
@@ -46,13 +46,15 @@ struct setunset_t
|
||||
}
|
||||
};
|
||||
|
||||
static void do_setunset(dict<RTLIL::IdString, RTLIL::Const> &attrs, const std::vector<setunset_t> &list)
|
||||
static void do_setunset(RTLIL::Design *design, dict<IdString, RTLIL::Const> &attrs, const std::vector<setunset_t> &list)
|
||||
{
|
||||
for (auto &item : list)
|
||||
if (item.unset)
|
||||
attrs.erase(item.name);
|
||||
else
|
||||
attrs[item.name] = item.value;
|
||||
if (item.unset) {
|
||||
IdString name = design->twines.find(item.name);
|
||||
if (name != IdString::Null)
|
||||
attrs.erase(name);
|
||||
} else
|
||||
attrs[design->twines.add(std::string(item.name))] = item.value;
|
||||
}
|
||||
|
||||
struct SetattrPass : public Pass {
|
||||
@@ -101,12 +103,12 @@ struct SetattrPass : public Pass {
|
||||
{
|
||||
if (flag_mod) {
|
||||
if (module->is_selected_whole())
|
||||
do_setunset(module->attributes, setunset_list);
|
||||
do_setunset(design, module->attributes, setunset_list);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto memb : module->selected_members())
|
||||
do_setunset(memb->attributes, setunset_list);
|
||||
do_setunset(design, memb->attributes, setunset_list);
|
||||
}
|
||||
}
|
||||
} SetattrPass;
|
||||
@@ -187,8 +189,8 @@ struct SetparamPass : public Pass {
|
||||
{
|
||||
for (auto cell : module->selected_cells()) {
|
||||
if (!new_cell_type.empty())
|
||||
cell->type = new_cell_type;
|
||||
do_setunset(cell->parameters, setunset_list);
|
||||
cell->type = cell->module->design->twines.add(new_cell_type);
|
||||
do_setunset(design, cell->parameters, setunset_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,14 +236,15 @@ struct ChparamPass : public Pass {
|
||||
break;
|
||||
}
|
||||
|
||||
TwineSearch search(&design->twines);
|
||||
for (int i = argidx; i < GetSize(args); i++)
|
||||
if (design->module("$abstract\\" + args[i]) != nullptr &&
|
||||
design->module(RTLIL::escape_id(args[i])) == nullptr)
|
||||
if (design->module(search.find("$abstract\\" + args[i])) != nullptr &&
|
||||
design->module(search.find(RTLIL::escape_id(args[i]))) == nullptr)
|
||||
args[i] = "$abstract\\" + args[i];
|
||||
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
do_setunset(new_parameters, setunset_list);
|
||||
do_setunset(design, new_parameters, setunset_list);
|
||||
|
||||
if (list_mode) {
|
||||
if (!new_parameters.empty())
|
||||
@@ -249,7 +252,7 @@ struct ChparamPass : public Pass {
|
||||
for (auto module : design->selected_modules()) {
|
||||
log("%s:\n", module);
|
||||
for (auto param : module->avail_parameters)
|
||||
log(" %s\n", param.unescape());
|
||||
log(" %s\n", PooledName(design, param).unescape());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
+21
-15
@@ -17,6 +17,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "kernel/rtlil.h"
|
||||
#include "kernel/yosys.h"
|
||||
#include "kernel/celltypes.h"
|
||||
#include "kernel/log_help.h"
|
||||
@@ -48,7 +49,7 @@ struct ShowWorker
|
||||
|
||||
vector<shared_str> dot_escape_store;
|
||||
std::map<RTLIL::IdString, int> dot_id2num_store;
|
||||
std::map<RTLIL::IdString, int> autonames;
|
||||
std::map<std::string, int> autonames;
|
||||
int single_idx_count;
|
||||
|
||||
struct net_conn { std::set<std::pair<std::string, int>> in, out; std::string color; };
|
||||
@@ -56,6 +57,7 @@ struct ShowWorker
|
||||
|
||||
FILE *f;
|
||||
RTLIL::Design *design;
|
||||
TwineSearch search;
|
||||
RTLIL::Module *module;
|
||||
uint32_t currentColor;
|
||||
bool genWidthLabels;
|
||||
@@ -146,16 +148,16 @@ struct ShowWorker
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string findColor(IdString member_name)
|
||||
std::string findColor(IdString member_ref)
|
||||
{
|
||||
for (auto &s : color_selections)
|
||||
if (s.second.selected_member(module->name, member_name)) {
|
||||
if (member_ref != IdString::Null && s.second.selected_member(module->name, member_ref)) {
|
||||
return stringf("color=\"%s\", fontcolor=\"%s\"", s.first, s.first);
|
||||
}
|
||||
|
||||
RTLIL::Const colorattr_value;
|
||||
RTLIL::Cell *cell = module->cell(member_name);
|
||||
RTLIL::Wire *wire = module->wire(member_name);
|
||||
RTLIL::Cell *cell = member_ref != IdString::Null ? module->cell(member_ref) : nullptr;
|
||||
RTLIL::Wire *wire = member_ref != IdString::Null ? module->wire(member_ref) : nullptr;
|
||||
|
||||
if (cell && cell->attributes.count(colorattr))
|
||||
colorattr_value = cell->attributes.at(colorattr);
|
||||
@@ -174,8 +176,9 @@ struct ShowWorker
|
||||
|
||||
const char *findLabel(std::string member_name)
|
||||
{
|
||||
IdString member_ref = search.find(member_name);
|
||||
for (auto &s : label_selections)
|
||||
if (s.second.selected_member(module->name, member_name))
|
||||
if (member_ref != IdString::Null && s.second.selected_member(module->name, member_ref))
|
||||
return escape(s.first);
|
||||
return escape(member_name, true);
|
||||
}
|
||||
@@ -478,19 +481,22 @@ struct ShowWorker
|
||||
out_ports.push_back(conn.first);
|
||||
}
|
||||
|
||||
std::sort(in_ports.begin(), in_ports.end(), RTLIL::sort_by_id_str());
|
||||
std::sort(out_ports.begin(), out_ports.end(), RTLIL::sort_by_id_str());
|
||||
std::sort(in_ports.begin(), in_ports.end(), RTLIL::sort_by_id_str(design->twines));
|
||||
std::sort(out_ports.begin(), out_ports.end(), RTLIL::sort_by_id_str(design->twines));
|
||||
|
||||
for (auto &p : in_ports) {
|
||||
bool signed_suffix = genSignedLabels && cell->hasParam(p.str() + "_SIGNED")
|
||||
&& cell->getParam(p.str() + "_SIGNED").as_bool();
|
||||
std::string p_str = design->twines.str(p);
|
||||
IdString signed_param = design->twines.find(p_str + "_SIGNED");
|
||||
bool signed_suffix = genSignedLabels && signed_param != IdString::Null
|
||||
&& cell->hasParam(signed_param)
|
||||
&& cell->getParam(signed_param).as_bool();
|
||||
|
||||
in_label_pieces.push_back(stringf("<p%d> %s%s", id2num(p), escape(p.str()),
|
||||
in_label_pieces.push_back(stringf("<p%d> %s%s", id2num(p), escape(p_str),
|
||||
signed_suffix ? "*" : ""));
|
||||
}
|
||||
|
||||
for (auto &p : out_ports)
|
||||
out_label_pieces.push_back(stringf("<p%d> %s", id2num(p), escape(p.str())));
|
||||
out_label_pieces.push_back(stringf("<p%d> %s", id2num(p), escape(design->twines.str(p))));
|
||||
|
||||
std::string in_label = join_label_pieces(in_label_pieces);
|
||||
std::string out_label = join_label_pieces(out_label_pieces);
|
||||
@@ -523,7 +529,7 @@ struct ShowWorker
|
||||
{
|
||||
RTLIL::Process *proc = it.second;
|
||||
|
||||
if (!design->selected_member(module->name, proc->name))
|
||||
if (!design->selected_member(module->name, it.first))
|
||||
continue;
|
||||
|
||||
std::set<RTLIL::SigSpec> input_signals, output_signals;
|
||||
@@ -624,7 +630,7 @@ struct ShowWorker
|
||||
const std::string wireshape, bool genSignedLabels, bool stretchIO, bool enumerateIds, bool abbreviateIds, bool notitle, bool href,
|
||||
const std::vector<std::pair<std::string, RTLIL::Selection>> &color_selections,
|
||||
const std::vector<std::pair<std::string, RTLIL::Selection>> &label_selections, RTLIL::IdString colorattr) :
|
||||
f(f), design(design), currentColor(colorSeed), genWidthLabels(genWidthLabels), wireshape(wireshape),
|
||||
f(f), design(design), search(&design->twines), currentColor(colorSeed), genWidthLabels(genWidthLabels), wireshape(wireshape),
|
||||
genSignedLabels(genSignedLabels), stretchIO(stretchIO), enumerateIds(enumerateIds), abbreviateIds(abbreviateIds),
|
||||
notitle(notitle), href(href), color_selections(color_selections), label_selections(label_selections), colorattr(colorattr)
|
||||
{
|
||||
@@ -836,7 +842,7 @@ struct ShowPass : public Pass {
|
||||
continue;
|
||||
}
|
||||
if (arg == "-colorattr" && argidx+1 < args.size()) {
|
||||
colorattr = RTLIL::escape_id(args[++argidx]);
|
||||
colorattr = design->twines.add(RTLIL::escape_id(args[++argidx]));
|
||||
continue;
|
||||
}
|
||||
if (arg == "-format" && argidx+1 < args.size()) {
|
||||
|
||||
+65
-49
@@ -23,10 +23,10 @@
|
||||
#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"
|
||||
#include <charconv>
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
@@ -59,18 +59,19 @@ struct statdata_t {
|
||||
double local_sequential_area = 0;
|
||||
double submodule_area = 0;
|
||||
int num_submodules = 0;
|
||||
std::map<RTLIL::IdString, unsigned int, RTLIL::sort_by_id_str> num_submodules_by_type;
|
||||
std::map<RTLIL::IdString, double, RTLIL::sort_by_id_str> submodules_area_by_type;
|
||||
std::map<std::string, unsigned int> num_submodules_by_type;
|
||||
std::map<std::string, double> submodules_area_by_type;
|
||||
|
||||
std::map<RTLIL::IdString, unsigned int, RTLIL::sort_by_id_str> local_num_cells_by_type;
|
||||
std::map<RTLIL::IdString, double, RTLIL::sort_by_id_str> local_area_cells_by_type;
|
||||
std::map<RTLIL::IdString, double, RTLIL::sort_by_id_str> local_seq_area_cells_by_type;
|
||||
std::map<std::string, unsigned int> local_num_cells_by_type;
|
||||
std::map<std::string, double> local_area_cells_by_type;
|
||||
std::map<std::string, double> local_seq_area_cells_by_type;
|
||||
string tech;
|
||||
|
||||
std::map<RTLIL::IdString, unsigned int, RTLIL::sort_by_id_str> num_cells_by_type;
|
||||
std::map<RTLIL::IdString, double, RTLIL::sort_by_id_str> area_cells_by_type;
|
||||
std::map<RTLIL::IdString, double, RTLIL::sort_by_id_str> seq_area_cells_by_type;
|
||||
std::set<RTLIL::IdString> unknown_cell_area;
|
||||
std::map<IdString, unsigned int> num_cells_by_type_raw;
|
||||
std::map<std::string, unsigned int> num_cells_by_type;
|
||||
std::map<std::string, double> area_cells_by_type;
|
||||
std::map<std::string, double> seq_area_cells_by_type;
|
||||
std::set<std::string> unknown_cell_area;
|
||||
|
||||
statdata_t operator+(const statdata_t &other) const
|
||||
{
|
||||
@@ -80,6 +81,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 +91,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 +108,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 +152,7 @@ struct statdata_t {
|
||||
}
|
||||
}
|
||||
|
||||
statdata_t(const RTLIL::Design *design, const RTLIL::Module *mod, bool width_mode, dict<IdString, cell_area_t> &cell_area, string techname)
|
||||
statdata_t(RTLIL::Design *design, const RTLIL::Module *mod, bool width_mode, dict<std::string, cell_area_t> &cell_area, string techname)
|
||||
{
|
||||
tech = techname;
|
||||
|
||||
@@ -183,9 +194,9 @@ struct statdata_t {
|
||||
local_num_memory_bits += it.second->width * it.second->size;
|
||||
}
|
||||
for (auto cell : mod->selected_cells()) {
|
||||
RTLIL::IdString cell_type = cell->type;
|
||||
std::string cell_type = cell->type.str();
|
||||
if (width_mode) {
|
||||
if (cell_type.in(ID($not), ID($pos), ID($neg), ID($logic_not), ID($logic_and), ID($logic_or), ID($reduce_and),
|
||||
if (cell->type.in(ID($not), ID($pos), ID($neg), ID($logic_not), ID($logic_and), ID($logic_or), ID($reduce_and),
|
||||
ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($lut), ID($and), ID($or),
|
||||
ID($xor), ID($xnor), ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx), ID($lt),
|
||||
ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), ID($add), ID($sub), ID($mul),
|
||||
@@ -194,15 +205,15 @@ struct statdata_t {
|
||||
int width_b = cell->hasPort(ID::B) ? GetSize(cell->getPort(ID::B)) : 0;
|
||||
int width_y = cell->hasPort(ID::Y) ? GetSize(cell->getPort(ID::Y)) : 0;
|
||||
cell_type = stringf("%s_%d", cell_type, max<int>({width_a, width_b, width_y}));
|
||||
} else if (cell_type.in(ID($mux)))
|
||||
} else if (cell->type.in(ID($mux)))
|
||||
cell_type = stringf("%s_%d", cell_type, GetSize(cell->getPort(ID::Y)));
|
||||
else if (cell_type.in(ID($bmux), ID($pmux)))
|
||||
else if (cell->type.in(ID($bmux), ID($pmux)))
|
||||
cell_type =
|
||||
stringf("%s_%d_%d", cell_type, GetSize(cell->getPort(ID::Y)), GetSize(cell->getPort(ID::S)));
|
||||
else if (cell_type == ID($demux))
|
||||
else if (cell->type == ID($demux))
|
||||
cell_type =
|
||||
stringf("%s_%d_%d", cell_type, GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::S)));
|
||||
else if (cell_type.in(ID($sr), ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe),
|
||||
else if (cell->type.in(ID($sr), ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe),
|
||||
ID($sdff), ID($sdffe), ID($sdffce), ID($aldff), ID($aldffe), ID($dlatch), ID($adlatch),
|
||||
ID($dlatchsr)))
|
||||
cell_type = stringf("%s_%d", cell_type, GetSize(cell->getPort(ID::Q)));
|
||||
@@ -249,7 +260,7 @@ struct statdata_t {
|
||||
} else if (it == "S") {
|
||||
port_name = ID::S;
|
||||
} else {
|
||||
port_name = ID(it);
|
||||
port_name = design->twines.add(std::string{it});
|
||||
}
|
||||
if (cell->hasPort(port_name)) {
|
||||
int width = GetSize(cell->getPort(port_name));
|
||||
@@ -311,6 +322,7 @@ struct statdata_t {
|
||||
} else {
|
||||
unknown_cell_area.insert(cell_type);
|
||||
num_cells++;
|
||||
num_cells_by_type_raw[cell->type]++;
|
||||
num_cells_by_type[cell_type]++;
|
||||
local_num_cells++;
|
||||
local_num_cells_by_type[cell_type]++;
|
||||
@@ -321,6 +333,7 @@ struct statdata_t {
|
||||
}
|
||||
} else {
|
||||
num_cells++;
|
||||
num_cells_by_type_raw[cell->type]++;
|
||||
num_cells_by_type[cell_type]++;
|
||||
area_cells_by_type[cell_type] = 0;
|
||||
seq_area_cells_by_type[cell_type] = 0;
|
||||
@@ -337,18 +350,16 @@ struct statdata_t {
|
||||
num_processes++;
|
||||
local_num_processes++;
|
||||
}
|
||||
RTLIL::IdString cell_name = mod->name;
|
||||
auto s = cell_name.str();
|
||||
}
|
||||
|
||||
unsigned int estimate_xilinx_lc()
|
||||
{
|
||||
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 lut6_cnt = num_cells_by_type[ID::str(ID::LUT6)];
|
||||
unsigned int lut5_cnt = num_cells_by_type[ID::str(ID::LUT5)];
|
||||
unsigned int lut4_cnt = num_cells_by_type[ID::str(ID::LUT4)];
|
||||
unsigned int lut3_cnt = num_cells_by_type[ID::str(ID::LUT3)];
|
||||
unsigned int lut2_cnt = num_cells_by_type[ID::str(ID::LUT2)];
|
||||
unsigned int lut1_cnt = num_cells_by_type[ID::str(ID::LUT1)];
|
||||
unsigned int lc_cnt = 0;
|
||||
|
||||
lc_cnt += lut6_cnt;
|
||||
@@ -398,7 +409,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;
|
||||
|
||||
@@ -505,7 +516,7 @@ struct statdata_t {
|
||||
}
|
||||
}
|
||||
|
||||
void log_data(RTLIL::IdString mod_name, bool top_mod, bool print_area = true, bool print_hierarchical = true, bool print_global_only = false)
|
||||
void log_data(const std::string &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);
|
||||
@@ -523,7 +534,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 = string(it.first.unescape());
|
||||
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);
|
||||
@@ -533,7 +544,7 @@ struct statdata_t {
|
||||
print_global_only);
|
||||
for (auto &it : num_submodules_by_type)
|
||||
if (it.second)
|
||||
print_log_line(string(it.first.unescape()), 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);
|
||||
}
|
||||
@@ -607,7 +618,7 @@ struct statdata_t {
|
||||
if (it.second) {
|
||||
if (!first_line)
|
||||
log(",\n");
|
||||
log(" %s: %s", json11::Json(it.first.unescape()).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))
|
||||
@@ -621,7 +632,7 @@ struct statdata_t {
|
||||
if (it.second) {
|
||||
if (!first_line)
|
||||
log(",\n");
|
||||
log(" %s: %s", json11::Json(it.first.unescape()).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());
|
||||
@@ -662,14 +673,14 @@ struct statdata_t {
|
||||
if (it.second) {
|
||||
if (!first_line)
|
||||
log(",\n");
|
||||
log(" %s: %u", json11::Json(it.first.unescape()).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(it.first.unescape()).dump(), it.second);
|
||||
log(" %s: %u", json11::Json(RTLIL::unescape_id(it.first)).dump(), it.second);
|
||||
first_line = false;
|
||||
}
|
||||
log("\n");
|
||||
@@ -697,14 +708,14 @@ struct statdata_t {
|
||||
if (it.second) {
|
||||
if (!first_line)
|
||||
log(",\n");
|
||||
log(" %s: %u", json11::Json(it.first.unescape()).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(it.first.unescape()).dump(), it.second);
|
||||
log(" %s: %u", json11::Json(RTLIL::unescape_id(it.first)).dump(), it.second);
|
||||
first_line = false;
|
||||
}
|
||||
log("\n");
|
||||
@@ -726,26 +737,27 @@ struct statdata_t {
|
||||
}
|
||||
};
|
||||
|
||||
statdata_t hierarchy_worker(std::map<RTLIL::IdString, statdata_t> &mod_stat, RTLIL::IdString mod, int level, bool quiet = false, bool has_area = true,
|
||||
statdata_t hierarchy_worker(const TwineSearch &search, 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);
|
||||
|
||||
for (auto &it : mod_data.num_submodules_by_type) {
|
||||
if (mod_stat.count(it.first) > 0) {
|
||||
IdString sub = search.find(it.first);
|
||||
if (sub != IdString::Null && mod_stat.count(sub) > 0) {
|
||||
if (!quiet)
|
||||
mod_data.print_log_line(string(it.first.unescape()), 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,
|
||||
mod_data.print_log_line(RTLIL::unescape_id(it.first), mod_stat.at(sub).local_num_cells,
|
||||
mod_stat.at(sub).local_area, mod_stat.at(sub).num_cells, mod_stat.at(sub).area,
|
||||
level, has_area, hierarchy_mode);
|
||||
hierarchy_worker(mod_stat, it.first, level + 1, quiet, has_area, hierarchy_mode) * it.second;
|
||||
hierarchy_worker(search, mod_stat, sub, level + 1, quiet, has_area, hierarchy_mode) * it.second;
|
||||
}
|
||||
}
|
||||
|
||||
return mod_data;
|
||||
}
|
||||
|
||||
statdata_t hierarchy_builder(const RTLIL::Design *design, const RTLIL::Module *top_mod, std::map<RTLIL::IdString, statdata_t> &mod_stat,
|
||||
bool width_mode, dict<IdString, 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<std::string, cell_area_t> &cell_area, string techname)
|
||||
{
|
||||
if (top_mod == nullptr)
|
||||
top_mod = design->top_module();
|
||||
@@ -797,7 +809,7 @@ statdata_t hierarchy_builder(const RTLIL::Design *design, const RTLIL::Module *t
|
||||
return mod_data;
|
||||
}
|
||||
|
||||
void read_liberty_cellarea(dict<IdString, cell_area_t> &cell_area, string liberty_file)
|
||||
void read_liberty_cellarea(dict<std::string, cell_area_t> &cell_area, string liberty_file)
|
||||
{
|
||||
std::istream *f = uncompressed(liberty_file.c_str());
|
||||
yosys_input_files.insert(liberty_file);
|
||||
@@ -928,7 +940,7 @@ struct StatPass : public Pass {
|
||||
bool width_mode = false, json_mode = false, hierarchy_mode = false;
|
||||
RTLIL::Module *top_mod = nullptr;
|
||||
std::map<RTLIL::IdString, statdata_t> mod_stat;
|
||||
dict<IdString, cell_area_t> cell_area;
|
||||
dict<std::string, cell_area_t> cell_area;
|
||||
string techname;
|
||||
|
||||
size_t argidx;
|
||||
@@ -948,9 +960,12 @@ struct StatPass : public Pass {
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-top" && argidx + 1 < args.size()) {
|
||||
if (design->module(RTLIL::escape_id(args[argidx + 1])) == nullptr)
|
||||
TwineSearch search(&design->twines);
|
||||
IdString top_ref = search.find(RTLIL::escape_id(args[argidx + 1]));
|
||||
if (design->module(top_ref) == nullptr)
|
||||
log_cmd_error("Can't find module %s.\n", args[argidx + 1]);
|
||||
top_mod = design->module(RTLIL::escape_id(args[++argidx]));
|
||||
top_mod = design->module(top_ref);
|
||||
argidx++;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-json") {
|
||||
@@ -1005,7 +1020,7 @@ struct StatPass : public Pass {
|
||||
top_mod = mod;
|
||||
statdata_t data = mod_stat.at(mod->name);
|
||||
if (json_mode) {
|
||||
data.log_data_json(mod->name.c_str(), first_module, hierarchy_mode);
|
||||
data.log_data_json(mod->name.str().c_str(), first_module, hierarchy_mode);
|
||||
first_module = false;
|
||||
} else {
|
||||
log("\n");
|
||||
@@ -1031,7 +1046,8 @@ struct StatPass : public Pass {
|
||||
mod_stat[top_mod->name].area, 0, has_area, hierarchy_mode, true);
|
||||
}
|
||||
|
||||
statdata_t data = hierarchy_worker(mod_stat, top_mod->name, 0, /*quiet=*/json_mode, has_area, hierarchy_mode);
|
||||
TwineSearch search(&design->twines);
|
||||
statdata_t data = hierarchy_worker(search, mod_stat, top_mod->name, 0, /*quiet=*/json_mode, has_area, hierarchy_mode);
|
||||
|
||||
if (json_mode)
|
||||
data.log_data_json("design", true, hierarchy_mode, true);
|
||||
|
||||
+10
-8
@@ -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(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(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 != IdString{}) {
|
||||
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 != IdString{}) {
|
||||
// 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 != IdString{}) {
|
||||
SigBit bit = cell->getPort(aig_node->portname)[aig_node->portbit];
|
||||
if (critical.count(node))
|
||||
critical[desc_sig(bit)] = true;
|
||||
@@ -359,7 +359,7 @@ struct EstimateSta {
|
||||
|
||||
for (auto wire : m->wires()) {
|
||||
if (bits_to_select.check_any(sigmap(wire)))
|
||||
to_select.insert(wire->name);
|
||||
{ IdString wn = wire->name; to_select.insert(wn); }
|
||||
}
|
||||
|
||||
if (select) {
|
||||
@@ -420,16 +420,18 @@ struct TimeestPass : Pass {
|
||||
if (select && d->selected_modules().size() > 1)
|
||||
log_cmd_error("The -select option operates on a single selected module\n");
|
||||
|
||||
TwineSearch search(&d->twines);
|
||||
for (auto m : d->selected_modules()) {
|
||||
std::optional<SigBit> clk;
|
||||
|
||||
if (clk_domain_specified) {
|
||||
if (!m->wire(RTLIL::escape_id(clk_name))) {
|
||||
IdString clk_ref = search.find(RTLIL::escape_id(clk_name));
|
||||
if (!m->wire(clk_ref)) {
|
||||
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(clk_ref), 0);
|
||||
}
|
||||
|
||||
EstimateSta sta(m, clk, /*top_port_endpoints=*/ !clk_domain_specified);
|
||||
|
||||
+23
-19
@@ -48,7 +48,7 @@ struct ContextData {
|
||||
std::string unused_outputs;
|
||||
};
|
||||
|
||||
std::optional<std::string> format_with_params(std::string fmt, const dict<IdString, Const> ¶meters,
|
||||
std::optional<std::string> format_with_params(const TwinePool &twines, std::string fmt, const dict<IdString, Const> ¶meters,
|
||||
const ContextData &context)
|
||||
{
|
||||
std::stringstream result;
|
||||
@@ -69,9 +69,10 @@ std::optional<std::string> format_with_params(std::string fmt, const dict<IdStri
|
||||
if (param_name == "%unused") {
|
||||
result << context.unused_outputs;
|
||||
} else {
|
||||
auto id = RTLIL::escape_id(std::string(beg, it));
|
||||
if (!parameters.count(id)) {
|
||||
log("Parameter %s referenced in format string '%s' not found\n", id, fmt);
|
||||
auto name = RTLIL::escape_id(std::string(beg, it));
|
||||
IdString id = twines.find(name);
|
||||
if (id == IdString::Null || !parameters.count(id)) {
|
||||
log("Parameter %s referenced in format string '%s' not found\n", name, fmt);
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -97,10 +98,10 @@ struct Chunk {
|
||||
{
|
||||
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(stringf("%s[%d]", pool.str(port).c_str(), base));
|
||||
return pool.add(stringf("%s[%d:%d]", pool.str(port).c_str(), base + len - 1, base));
|
||||
}
|
||||
|
||||
SigSpec sample(Cell *cell)
|
||||
@@ -113,7 +114,9 @@ struct Chunk {
|
||||
std::vector<Chunk> collect_chunks(std::vector<std::pair<IdString, 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.raw() < b.first.raw() || (a.first.raw() == b.first.raw() && a.second < b.second);
|
||||
});
|
||||
for (auto it = bits.begin(); it != bits.end();) {
|
||||
auto sep = it + 1;
|
||||
for (; sep != bits.end() &&
|
||||
@@ -171,9 +174,9 @@ struct WrapcellPass : Pass {
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++) {
|
||||
if (args[argidx] == "-setattr" && argidx+1 < args.size()) {
|
||||
attributes.emplace_back(RTLIL::escape_id(args[++argidx]), "");
|
||||
attributes.emplace_back(d->twines.add(RTLIL::escape_id(args[++argidx])), "");
|
||||
} else if (args[argidx] == "-formatattr" && argidx+2 < args.size()) {
|
||||
IdString id = RTLIL::escape_id(args[++argidx]);
|
||||
IdString id = d->twines.add(RTLIL::escape_id(args[++argidx]));
|
||||
attributes.emplace_back(id, args[++argidx]);
|
||||
} else if (args[argidx] == "-name" && argidx+1 < args.size()) {
|
||||
name_fmt = args[++argidx];
|
||||
@@ -199,6 +202,7 @@ struct WrapcellPass : Pass {
|
||||
for (auto cell : module->selected_cells()) {
|
||||
Module *subm;
|
||||
Cell *subcell;
|
||||
IdString name_ref;
|
||||
|
||||
if (!ct.cell_known(cell->type))
|
||||
log_error("Non-internal cell type '%s' on cell '%s' in module '%s' unsupported\n",
|
||||
@@ -219,20 +223,20 @@ struct WrapcellPass : Pass {
|
||||
if (!unused_outputs.empty()) {
|
||||
context.unused_outputs += "_unused";
|
||||
for (auto chunk : collect_chunks(unused_outputs))
|
||||
context.unused_outputs += "_" + chunk.format(cell).unescape();
|
||||
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);
|
||||
std::optional<std::string> unescaped_name = format_with_params(d->twines, name_fmt, cell->parameters, context);
|
||||
if (!unescaped_name)
|
||||
log_error("Formatting error when processing cell '%s' in module '%s'\n",
|
||||
cell, module);
|
||||
|
||||
IdString name = RTLIL::escape_id(unescaped_name.value());
|
||||
if (d->module(name))
|
||||
name_ref = d->twines.add(RTLIL::escape_id(unescaped_name.value()));
|
||||
if (d->module(name_ref))
|
||||
goto replace_cell;
|
||||
|
||||
subm = d->addModule(name);
|
||||
subcell = subm->addCell("$1", cell->type);
|
||||
subm = d->addModule(name_ref);
|
||||
subcell = subm->addCell("$1", IdString(cell->type));
|
||||
for (auto conn : cell->connections()) {
|
||||
if (ct.cell_output(cell->type, conn.first)) {
|
||||
// Insert marker bits as placehodlers which need to be replaced
|
||||
@@ -262,7 +266,7 @@ struct WrapcellPass : Pass {
|
||||
if (rule.value_fmt.empty()) {
|
||||
subm->set_bool_attribute(rule.name);
|
||||
} else {
|
||||
std::optional<std::string> value = format_with_params(rule.value_fmt, cell->parameters, context);
|
||||
std::optional<std::string> value = format_with_params(d->twines, rule.value_fmt, cell->parameters, context);
|
||||
|
||||
if (!value)
|
||||
log_error("Formatting error when processing cell '%s' in module '%s'\n",
|
||||
@@ -284,7 +288,7 @@ struct WrapcellPass : Pass {
|
||||
for (auto chunk : collect_chunks(used_outputs))
|
||||
new_connections[chunk.format(cell)] = chunk.sample(cell);
|
||||
|
||||
cell->type = name;
|
||||
cell->type = name_ref;
|
||||
cell->connections_ = new_connections;
|
||||
}
|
||||
}
|
||||
|
||||
+29
-25
@@ -41,7 +41,7 @@ struct EquivMakeWorker
|
||||
pool<SigBit> undriven_bits;
|
||||
SigMap assign_map;
|
||||
|
||||
void read_blacklists()
|
||||
void read_blacklists(const TwineSearch &search)
|
||||
{
|
||||
for (auto fn : blacklists)
|
||||
{
|
||||
@@ -55,13 +55,15 @@ struct EquivMakeWorker
|
||||
token = next_token(line);
|
||||
if (token.empty())
|
||||
break;
|
||||
blacklist_names.insert(RTLIL::escape_id(token));
|
||||
IdString name = search.find(RTLIL::escape_id(token));
|
||||
if (name != IdString::Null)
|
||||
blacklist_names.insert(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void read_encfiles()
|
||||
void read_encfiles(const TwineSearch &search)
|
||||
{
|
||||
for (auto fn : encfiles)
|
||||
{
|
||||
@@ -78,11 +80,11 @@ struct EquivMakeWorker
|
||||
continue;
|
||||
|
||||
if (token == ".fsm") {
|
||||
IdString modname = RTLIL::escape_id(next_token(line));
|
||||
IdString modname = search.find(RTLIL::escape_id(next_token(line)));
|
||||
(void)modname;
|
||||
IdString signame = RTLIL::escape_id(next_token(line));
|
||||
IdString signame = search.find(RTLIL::escape_id(next_token(line)));
|
||||
if (encdata.count(signame))
|
||||
log_cmd_error("Re-definition of signal '%s' in encfile '%s'!\n", signame, fn);
|
||||
log_cmd_error("Re-definition of signal '%s' in encfile '%s'!\n", PooledName(gold_mod->design, signame).unescape(), fn);
|
||||
encdata[signame] = dict<Const, Const>();
|
||||
ed = &encdata[signame];
|
||||
continue;
|
||||
@@ -141,7 +143,7 @@ struct EquivMakeWorker
|
||||
equiv_mod->addAssert(NEW_ID_SUFFIX("assert"), eq_wire, State::S1);
|
||||
}
|
||||
|
||||
void find_same_wires()
|
||||
void find_same_wires(const TwineSearch &search)
|
||||
{
|
||||
SigMap assign_map(equiv_mod);
|
||||
SigMap rd_signal_map;
|
||||
@@ -152,18 +154,18 @@ struct EquivMakeWorker
|
||||
|
||||
for (auto id : wire_names)
|
||||
{
|
||||
IdString gold_id = id.str() + "_gold";
|
||||
IdString gate_id = id.str() + "_gate";
|
||||
IdString gold_id = search.find(equiv_mod->design->twines.str(id) + "_gold");
|
||||
IdString gate_id = search.find(equiv_mod->design->twines.str(id) + "_gate");
|
||||
|
||||
Wire *gold_wire = equiv_mod->wire(gold_id);
|
||||
Wire *gate_wire = equiv_mod->wire(gate_id);
|
||||
|
||||
if (encdata.count(id))
|
||||
{
|
||||
log("Creating encoder/decoder for signal %s.\n", id.unescape());
|
||||
log("Creating encoder/decoder for signal %s.\n", PooledName(equiv_mod->design, id).unescape());
|
||||
|
||||
Wire *dec_wire = equiv_mod->addWire(id.str() + "_decoded", gold_wire->width);
|
||||
Wire *enc_wire = equiv_mod->addWire(id.str() + "_encoded", gate_wire->width);
|
||||
Wire *dec_wire = equiv_mod->addWire(equiv_mod->design->twines.str(id) + "_decoded", gold_wire->width);
|
||||
Wire *enc_wire = equiv_mod->addWire(equiv_mod->design->twines.str(id) + "_encoded", gate_wire->width);
|
||||
|
||||
SigSpec dec_a, dec_b, dec_s;
|
||||
SigSpec enc_a, enc_b, enc_s;
|
||||
@@ -235,7 +237,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)), id.unescape());
|
||||
gate_wire, log_signal(assign_map(gate_wire)), PooledName(equiv_mod->design, id).unescape());
|
||||
|
||||
if (gold_wire->port_output || gate_wire->port_output)
|
||||
{
|
||||
@@ -314,7 +316,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",
|
||||
conn.first.unescape(), c, c->type.unescape(),
|
||||
PooledName(equiv_mod, conn.first).unescape(), c, c->type.unescape(),
|
||||
log_signal(old_sig), log_signal(new_sig));
|
||||
c->setPort(conn.first, new_sig);
|
||||
}
|
||||
@@ -323,14 +325,14 @@ struct EquivMakeWorker
|
||||
equiv_mod->fixup_ports();
|
||||
}
|
||||
|
||||
void find_same_cells()
|
||||
void find_same_cells(const TwineSearch &search)
|
||||
{
|
||||
SigMap assign_map(equiv_mod);
|
||||
|
||||
for (auto id : cell_names)
|
||||
{
|
||||
IdString gold_id = id.str() + "_gold";
|
||||
IdString gate_id = id.str() + "_gate";
|
||||
IdString gold_id = search.find(equiv_mod->design->twines.str(id) + "_gold");
|
||||
IdString gate_id = search.find(equiv_mod->design->twines.str(id) + "_gate");
|
||||
|
||||
Cell *gold_cell = equiv_mod->cell(gold_id);
|
||||
Cell *gate_cell = equiv_mod->cell(gate_id);
|
||||
@@ -345,7 +347,7 @@ struct EquivMakeWorker
|
||||
goto try_next_cell_name;
|
||||
|
||||
log("Presumably equivalent cells: %s %s (%s) -> %s\n",
|
||||
gold_cell, gate_cell, gold_cell->type.unescape(), id.unescape());
|
||||
gold_cell, gate_cell, gold_cell->type.unescape(), PooledName(equiv_mod->design, id).unescape());
|
||||
|
||||
for (auto gold_conn : gold_cell->connections())
|
||||
{
|
||||
@@ -419,8 +421,9 @@ struct EquivMakeWorker
|
||||
{
|
||||
copy_to_equiv();
|
||||
find_undriven_nets(false);
|
||||
find_same_wires();
|
||||
find_same_cells();
|
||||
TwineSearch search(&equiv_mod->design->twines);
|
||||
find_same_wires(search);
|
||||
find_same_cells(search);
|
||||
find_undriven_nets(true);
|
||||
}
|
||||
};
|
||||
@@ -488,9 +491,10 @@ struct EquivMakePass : public Pass {
|
||||
if (argidx+3 != args.size())
|
||||
log_cmd_error("Invalid number of arguments.\n");
|
||||
|
||||
worker.gold_mod = design->module(RTLIL::escape_id(args[argidx]));
|
||||
worker.gate_mod = design->module(RTLIL::escape_id(args[argidx+1]));
|
||||
worker.equiv_mod = design->module(RTLIL::escape_id(args[argidx+2]));
|
||||
TwineSearch search(&design->twines);
|
||||
worker.gold_mod = design->module(search.find(RTLIL::escape_id(args[argidx])));
|
||||
worker.gate_mod = design->module(search.find(RTLIL::escape_id(args[argidx+1])));
|
||||
worker.equiv_mod = design->module(search.find(RTLIL::escape_id(args[argidx+2])));
|
||||
|
||||
if (worker.gold_mod == nullptr)
|
||||
log_cmd_error("Can't find gold module %s.\n", args[argidx]);
|
||||
@@ -507,8 +511,8 @@ struct EquivMakePass : public Pass {
|
||||
if (worker.gate_mod->has_memories() || worker.gate_mod->has_processes())
|
||||
log_cmd_error("Gate module contains memories or processes. Run 'memory' or 'proc' respectively.\n");
|
||||
|
||||
worker.read_blacklists();
|
||||
worker.read_encfiles();
|
||||
worker.read_blacklists(search);
|
||||
worker.read_encfiles(search);
|
||||
|
||||
log_header(design, "Executing EQUIV_MAKE pass (creating equiv checking module).\n");
|
||||
|
||||
|
||||
@@ -78,8 +78,8 @@ struct EquivStructWorker
|
||||
if (bits_a[i] != bits_b[i]) {
|
||||
inputs_a.append(bits_a[i]);
|
||||
inputs_b.append(bits_b[i]);
|
||||
input_names.push_back(GetSize(bits_a) == 1 ? port_a.first.str() :
|
||||
stringf("%s[%d]", port_a.first.unescape(), i));
|
||||
input_names.push_back(GetSize(bits_a) == 1 ? module->design->twines.str(port_a.first) :
|
||||
stringf("%s[%d]", module->design->twines.unescaped_str(port_a.first).c_str(), i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,9 +110,7 @@ struct EquivStructWorker
|
||||
module->connect(sig_b, sig_a);
|
||||
}
|
||||
|
||||
auto merged_attr = cell_b->get_strpool_attribute(ID::equiv_merged);
|
||||
merged_attr.insert(cell_b->name.unescape());
|
||||
cell_a->add_strpool_attribute(ID::equiv_merged, merged_attr);
|
||||
cell_a->set_bool_attribute(ID::equiv_merged);
|
||||
module->remove(cell_b);
|
||||
}
|
||||
|
||||
@@ -175,14 +173,14 @@ struct EquivStructWorker
|
||||
if (cell->input(conn.first)) {
|
||||
SigSpec sig = sigmap(conn.second);
|
||||
for (int i = 0; i < GetSize(sig); i++)
|
||||
fwd_connections.push_back(make_tuple(conn.first, i, sig[i]));
|
||||
fwd_connections.push_back(std::make_tuple(conn.first, i, sig[i]));
|
||||
}
|
||||
|
||||
if (cell->output(conn.first)) {
|
||||
SigSpec sig = equiv_bits(conn.second);
|
||||
for (int i = 0; i < GetSize(sig); i++) {
|
||||
key.connections.clear();
|
||||
key.connections.push_back(make_tuple(conn.first, i, sig[i]));
|
||||
key.connections.push_back(std::make_tuple(conn.first, i, sig[i]));
|
||||
|
||||
if (merge_cache.count(key))
|
||||
bwd_merge_cache.insert(key);
|
||||
@@ -213,7 +211,7 @@ struct EquivStructWorker
|
||||
for (auto cell_name : merge_cache[key]) {
|
||||
Cell *c = module->cell(cell_name);
|
||||
if (c != nullptr) {
|
||||
string n = cell_name.str();
|
||||
string n = module->design->twines.str(cell_name);
|
||||
cells_type = c->type;
|
||||
if (GetSize(n) > 5 && n.compare(GetSize(n)-5, std::string::npos, "_gold") == 0)
|
||||
gold_cells.push_back(c);
|
||||
@@ -266,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), cells_type.unescape(), total_group_size, strategy);
|
||||
2*GetSize(cell_pairs), PooledName(module->design, cells_type).unescape(), 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);
|
||||
@@ -334,7 +332,7 @@ struct EquivStructPass : public Pass {
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-fwonly" && argidx+1 < args.size()) {
|
||||
fwonly_cells.insert(RTLIL::escape_id(args[++argidx]));
|
||||
fwonly_cells.insert(design->twines.add(RTLIL::escape_id(args[++argidx])));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-maxiter" && argidx+1 < args.size()) {
|
||||
|
||||
@@ -69,7 +69,7 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL
|
||||
|
||||
for (auto &cellport : cellport_list)
|
||||
{
|
||||
RTLIL::Cell *cell = module->cells_.at(cellport.first);
|
||||
RTLIL::Cell *cell = module->cell(cellport.first);
|
||||
if ((cell->type != ID($mux) && cell->type != ID($pmux)) || cellport.second != ID::Y) {
|
||||
log(" unexpected cell type %s (%s) found in state selection tree.\n", cell->type, cell->name);
|
||||
return false;
|
||||
@@ -271,7 +271,7 @@ static void extract_fsm(RTLIL::Wire *wire)
|
||||
std::set<sig2driver_entry_t> cellport_list;
|
||||
sig2driver.find(dff_out, cellport_list);
|
||||
for (auto &cellport : cellport_list) {
|
||||
RTLIL::Cell *cell = module->cells_.at(cellport.first);
|
||||
RTLIL::Cell *cell = module->cell(cellport.first);
|
||||
if ((cell->type != ID($dff) && cell->type != ID($adff)) || cellport.second != ID::Q)
|
||||
continue;
|
||||
log(" found %s cell for state register: %s\n", cell->type, cell->name);
|
||||
@@ -319,7 +319,7 @@ static void extract_fsm(RTLIL::Wire *wire)
|
||||
cellport_list.clear();
|
||||
sig2trigger.find(dff_out, cellport_list);
|
||||
for (auto &cellport : cellport_list) {
|
||||
RTLIL::Cell *cell = module->cells_.at(cellport.first);
|
||||
RTLIL::Cell *cell = module->cell(cellport.first);
|
||||
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
|
||||
RTLIL::SigSpec sig_b;
|
||||
if (cell->hasPort(ID::B))
|
||||
@@ -388,10 +388,8 @@ static void extract_fsm(RTLIL::Wire *wire)
|
||||
|
||||
// rename original state wire
|
||||
|
||||
module->wires_.erase(wire->name);
|
||||
wire->attributes.erase(ID::fsm_encoding);
|
||||
wire->name = stringf("$fsm$oldstate%s", wire->name);
|
||||
module->wires_[wire->name] = wire;
|
||||
module->rename(wire, stringf("$fsm$oldstate%s", wire->name));
|
||||
if(wire->attributes.count(ID::hdlname)) {
|
||||
auto hdlname = wire->get_hdlname_attribute();
|
||||
hdlname.pop_back();
|
||||
@@ -405,7 +403,7 @@ static void extract_fsm(RTLIL::Wire *wire)
|
||||
cellport_list.clear();
|
||||
sig2driver.find(ctrl_out, cellport_list);
|
||||
for (auto &cellport : cellport_list) {
|
||||
RTLIL::Cell *cell = module->cells_.at(cellport.first);
|
||||
RTLIL::Cell *cell = module->cell(cellport.first);
|
||||
RTLIL::SigSpec port_sig = assign_map(cell->getPort(cellport.second));
|
||||
RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out);
|
||||
RTLIL::Wire *unconn_wire = module->addWire(stringf("$fsm_unconnect$%d", autoidx++), unconn_sig.size());
|
||||
|
||||
+102
-60
@@ -42,24 +42,55 @@ template <typename... Args>
|
||||
return result;
|
||||
}
|
||||
|
||||
IdString concat_name(RTLIL::Cell *cell, IdString const &object_name, const std::string &separator = ".")
|
||||
{
|
||||
std::string_view object_name_view(object_name.c_str());
|
||||
if (object_name_view[0] == '\\'){
|
||||
return concat_views(cell->name.c_str(), separator, object_name_view.substr(1));
|
||||
struct module_ptr_compare {
|
||||
bool operator()(RTLIL::Module *a, RTLIL::Module *b) const {
|
||||
return a < b;
|
||||
}
|
||||
};
|
||||
|
||||
std::pair<std::string, std::string> hier_name_parts(RTLIL::Cell *cell, std::string_view object_name_view, const std::string &separator)
|
||||
{
|
||||
if (!object_name_view.empty() && object_name_view[0] == '\\')
|
||||
return {cell->name.str() + separator, std::string(object_name_view.substr(1))};
|
||||
|
||||
constexpr std::string_view prefix = "$flatten";
|
||||
if (object_name_view.substr(0, prefix.size()) == prefix){
|
||||
if (object_name_view.substr(0, prefix.size()) == prefix)
|
||||
object_name_view.remove_prefix(prefix.size());
|
||||
}
|
||||
return concat_views(prefix, cell->name.c_str(), separator, object_name_view);
|
||||
return {"$flatten" + cell->name.str() + separator, std::string(object_name_view)};
|
||||
}
|
||||
|
||||
template<class T>
|
||||
IdString map_name(RTLIL::Cell *cell, T *object, const std::string &separator = ".")
|
||||
std::string concat_name(RTLIL::Cell *cell, std::string_view object_name_view, const std::string &separator = ".")
|
||||
{
|
||||
return cell->module->uniquify(concat_name(cell, object->name, separator));
|
||||
auto [prefix, tail] = hier_name_parts(cell, object_name_view, separator);
|
||||
return prefix + tail;
|
||||
}
|
||||
|
||||
IdString remap_flattened_name(RTLIL::Design *design, IdString obj_ref,
|
||||
IdString pub_prefix_ref, IdString priv_prefix_ref, const std::string &separator, dict<IdString, IdString> &memo)
|
||||
{
|
||||
if (auto it = memo.find(obj_ref); it != memo.end())
|
||||
return it->second;
|
||||
|
||||
const TwineNode &node = design->twines[obj_ref];
|
||||
IdString result;
|
||||
if (node.is_suffix()) {
|
||||
const Twine::Suffix &sfx = node.suffix();
|
||||
IdString prefix = remap_flattened_name(design, sfx.prefix.tag(obj_ref.isPublic()),
|
||||
pub_prefix_ref, priv_prefix_ref, separator, memo);
|
||||
result = design->twines.add(Twine::Suffix{prefix, sfx.tail});
|
||||
} else {
|
||||
std::string_view obj = node.leaf();
|
||||
if (obj_ref.isPublic()) {
|
||||
result = design->twines.add(Twine::Suffix{pub_prefix_ref, separator + std::string(obj)});
|
||||
} else {
|
||||
constexpr std::string_view flatten_prefix = "$flatten";
|
||||
if (obj.substr(0, flatten_prefix.size()) == flatten_prefix)
|
||||
obj.remove_prefix(flatten_prefix.size());
|
||||
result = design->twines.add(Twine::Suffix{priv_prefix_ref, std::string(obj)});
|
||||
}
|
||||
}
|
||||
memo[obj_ref] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
void map_sigspec(const dict<RTLIL::Wire*, RTLIL::Wire*> &map, RTLIL::SigSpec &sig, RTLIL::Module *into = nullptr)
|
||||
@@ -78,6 +109,9 @@ struct FlattenWorker
|
||||
bool create_scopename = false;
|
||||
std::string separator = ".";
|
||||
|
||||
std::string cell_hdlname;
|
||||
std::string cell_scopename;
|
||||
|
||||
template<class T>
|
||||
void map_attributes(RTLIL::Cell *cell, T *object, IdString orig_object_name)
|
||||
{
|
||||
@@ -86,53 +120,50 @@ struct FlattenWorker
|
||||
|
||||
// Preserve original names via the hdlname attribute, but only for objects with a fully public name.
|
||||
// If the '-scopename' option is used, also preserve the containing scope of private objects if their scope is fully public.
|
||||
if (cell->name[0] == '\\') {
|
||||
if (object->has_attribute(ID::hdlname) || orig_object_name[0] == '\\') {
|
||||
std::string new_hdlname;
|
||||
|
||||
if (cell->has_attribute(ID::hdlname)) {
|
||||
new_hdlname = cell->get_string_attribute(ID(hdlname));
|
||||
} else {
|
||||
log_assert(!cell->name.empty());
|
||||
new_hdlname = cell->name.c_str() + 1;
|
||||
}
|
||||
if (cell->name.isPublic()) {
|
||||
if (object->has_attribute(ID::hdlname) || orig_object_name.isPublic()) {
|
||||
std::string new_hdlname = cell_hdlname;
|
||||
new_hdlname += ' ';
|
||||
|
||||
if (object->has_attribute(ID::hdlname)) {
|
||||
new_hdlname += object->get_string_attribute(ID(hdlname));
|
||||
} else {
|
||||
log_assert(!orig_object_name.empty());
|
||||
new_hdlname += orig_object_name.c_str() + 1;
|
||||
new_hdlname += cell->module->design->twines.unescaped_str(orig_object_name);
|
||||
}
|
||||
object->set_string_attribute(ID(hdlname), new_hdlname);
|
||||
} else if (object->has_attribute(ID(scopename))) {
|
||||
std::string new_scopename;
|
||||
|
||||
if (cell->has_attribute(ID::hdlname)) {
|
||||
new_scopename = cell->get_string_attribute(ID(hdlname));
|
||||
} else {
|
||||
log_assert(!cell->name.empty());
|
||||
new_scopename = cell->name.c_str() + 1;
|
||||
}
|
||||
std::string new_scopename = cell_hdlname;
|
||||
new_scopename += ' ';
|
||||
new_scopename += object->get_string_attribute(ID(scopename));
|
||||
object->set_string_attribute(ID(scopename), new_scopename);
|
||||
} else if (create_scopename) {
|
||||
log_assert(!cell->name.empty());
|
||||
object->set_string_attribute(ID(scopename), cell->name.c_str() + 1);
|
||||
object->set_string_attribute(ID::scopename, cell_scopename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void flatten_cell(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl, SigMap &sigmap, std::vector<RTLIL::Cell*> &new_cells, const std::string &separator)
|
||||
void flatten_cell(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl, SigMap &sigmap, std::vector<RTLIL::Cell*> &new_cells, const std::string &separator, const dict<std::string, RTLIL::Wire*> &hier_wires)
|
||||
{
|
||||
// Copy the contents of the flattened cell
|
||||
|
||||
dict<IdString, IdString> memory_map;
|
||||
if (cell->name.isPublic()) {
|
||||
log_assert(!cell->name.empty());
|
||||
cell_hdlname = cell->has_attribute(ID::hdlname) ? cell->get_string_attribute(ID(hdlname)) : cell->name.unescape();
|
||||
cell_scopename = create_scopename ? cell->name.unescape() : std::string();
|
||||
}
|
||||
|
||||
IdString pub_prefix_ref = cell->name;
|
||||
IdString priv_prefix_ref = design->twines.add("$flatten" + cell->name.str() + separator);
|
||||
dict<IdString, IdString> remap_memo;
|
||||
auto make_name = [&](IdString obj_ref) -> IdString {
|
||||
return module->uniquify(remap_flattened_name(design, obj_ref, pub_prefix_ref, priv_prefix_ref, separator, remap_memo));
|
||||
};
|
||||
|
||||
dict<std::string, IdString> memory_map;
|
||||
for (auto &tpl_memory_it : tpl->memories) {
|
||||
RTLIL::Memory *new_memory = module->addMemory(map_name(cell, tpl_memory_it.second, separator), tpl_memory_it.second);
|
||||
RTLIL::Memory *new_memory = module->addMemory(make_name(tpl_memory_it.second->name), tpl_memory_it.second);
|
||||
map_attributes(cell, new_memory, tpl_memory_it.second->name);
|
||||
memory_map[tpl_memory_it.first] = new_memory->name;
|
||||
memory_map[design->twines.str(tpl_memory_it.first)] = new_memory->name;
|
||||
design->select(module, new_memory);
|
||||
}
|
||||
|
||||
@@ -140,11 +171,13 @@ struct FlattenWorker
|
||||
dict<IdString, IdString> positional_ports;
|
||||
for (auto tpl_wire : tpl->wires()) {
|
||||
if (tpl_wire->port_id > 0)
|
||||
positional_ports.emplace(stringf("$%d", tpl_wire->port_id), tpl_wire->name);
|
||||
positional_ports.emplace(design->twines.add(stringf("$%d", tpl_wire->port_id)), tpl_wire->name);
|
||||
|
||||
RTLIL::Wire *new_wire = nullptr;
|
||||
if (tpl_wire->name[0] == '\\') {
|
||||
RTLIL::Wire *hier_wire = module->wire(concat_name(cell, tpl_wire->name, separator));
|
||||
if (tpl_wire->name.isPublic() && !hier_wires.empty()) {
|
||||
std::string wire_name = concat_name(cell, tpl_wire->name.str(), separator);
|
||||
auto hwit = hier_wires.find(wire_name);
|
||||
RTLIL::Wire *hier_wire = (hwit != hier_wires.end()) ? hwit->second : nullptr;
|
||||
if (hier_wire != nullptr && hier_wire->get_bool_attribute(ID::hierconn)) {
|
||||
hier_wire->attributes.erase(ID::hierconn);
|
||||
if (GetSize(hier_wire) < GetSize(tpl_wire)) {
|
||||
@@ -156,7 +189,7 @@ struct FlattenWorker
|
||||
}
|
||||
}
|
||||
if (new_wire == nullptr) {
|
||||
new_wire = module->addWire(map_name(cell, tpl_wire, separator), tpl_wire);
|
||||
new_wire = module->addWire(make_name(tpl_wire->name), tpl_wire);
|
||||
new_wire->port_input = new_wire->port_output = false;
|
||||
new_wire->port_id = false;
|
||||
}
|
||||
@@ -167,25 +200,26 @@ struct FlattenWorker
|
||||
}
|
||||
|
||||
for (auto &tpl_proc_it : tpl->processes) {
|
||||
RTLIL::Process *new_proc = module->addProcess(map_name(cell, tpl_proc_it.second, separator), tpl_proc_it.second);
|
||||
RTLIL::Process *new_proc = module->addProcess(make_name(tpl_proc_it.second->name), tpl_proc_it.second);
|
||||
map_attributes(cell, new_proc, tpl_proc_it.second->name);
|
||||
for (auto new_proc_sync : new_proc->syncs)
|
||||
for (auto &memwr_action : new_proc_sync->mem_write_actions)
|
||||
memwr_action.memid = memory_map.at(memwr_action.memid).str();
|
||||
for (auto &memwr_action : new_proc_sync->mem_write_actions) {
|
||||
memwr_action.memid = memory_map.at(design->twines.str(memwr_action.memid));
|
||||
}
|
||||
auto rewriter = [&](RTLIL::SigSpec &sig) { map_sigspec(wire_map, sig); };
|
||||
new_proc->rewrite_sigspecs(rewriter);
|
||||
design->select(module, new_proc);
|
||||
}
|
||||
|
||||
for (auto tpl_cell : tpl->cells()) {
|
||||
RTLIL::Cell *new_cell = module->addCell(map_name(cell, tpl_cell, separator), tpl_cell);
|
||||
RTLIL::Cell *new_cell = module->addCell(make_name(tpl_cell->name), tpl_cell);
|
||||
map_attributes(cell, new_cell, tpl_cell->name);
|
||||
if (new_cell->has_memid()) {
|
||||
IdString memid = new_cell->getParam(ID::MEMID).decode_string();
|
||||
new_cell->setParam(ID::MEMID, Const(memory_map.at(memid).str()));
|
||||
std::string memid = new_cell->getParam(ID::MEMID).decode_string();
|
||||
new_cell->setParam(ID::MEMID, Const(design->twines.str(memory_map.at(memid))));
|
||||
} else if (new_cell->is_mem_cell()) {
|
||||
IdString memid = new_cell->getParam(ID::MEMID).decode_string();
|
||||
new_cell->setParam(ID::MEMID, Const(concat_name(cell, memid, separator).str()));
|
||||
std::string memid = new_cell->getParam(ID::MEMID).decode_string();
|
||||
new_cell->setParam(ID::MEMID, Const(concat_name(cell, memid, separator)));
|
||||
}
|
||||
auto rewriter = [&](RTLIL::SigSpec &sig) { map_sigspec(wire_map, sig); };
|
||||
new_cell->rewrite_sigspecs(rewriter);
|
||||
@@ -218,9 +252,10 @@ struct FlattenWorker
|
||||
if (positional_ports.count(port_name) > 0)
|
||||
port_name = positional_ports.at(port_name);
|
||||
if (tpl->wire(port_name) == nullptr || tpl->wire(port_name)->port_id == 0) {
|
||||
if (port_name.begins_with("$"))
|
||||
std::string port_name_str = design->twines.str(port_name);
|
||||
if (!port_name_str.empty() && port_name_str[0] == '$')
|
||||
log_error("Can't map port `%s' of cell `%s' to template `%s'!\n",
|
||||
port_name.c_str(), cell->name.c_str(), tpl->name.c_str());
|
||||
port_name_str, cell->name, tpl->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -261,7 +296,7 @@ struct FlattenWorker
|
||||
|
||||
if (sigmap(new_conn.first).has_const())
|
||||
log_error("Cell port %s.%s.%s is driving constant bits: %s <= %s\n",
|
||||
module, cell, port_it.first.unescape(), log_signal(new_conn.first), log_signal(new_conn.second));
|
||||
module, cell, PooledName(design, port_it.first).unescape(), log_signal(new_conn.first), log_signal(new_conn.second));
|
||||
|
||||
module->connect(new_conn);
|
||||
sigmap.add(new_conn.first, new_conn.second);
|
||||
@@ -281,13 +316,13 @@ struct FlattenWorker
|
||||
if (attr.first == ID::hdlname)
|
||||
scopeinfo->attributes.insert(attr);
|
||||
else
|
||||
scopeinfo->attributes.emplace(stringf("\\cell_%s", attr.first.unescape()), attr.second);
|
||||
scopeinfo->attributes.emplace(design->twines.add(stringf("\\cell_%s", design->twines.unescaped_str(attr.first))), attr.second);
|
||||
}
|
||||
|
||||
for (auto const &attr : tpl->attributes)
|
||||
scopeinfo->attributes.emplace(stringf("\\module_%s", attr.first.unescape()), attr.second);
|
||||
scopeinfo->attributes.emplace(design->twines.add(stringf("\\module_%s", design->twines.unescaped_str(attr.first))), attr.second);
|
||||
|
||||
scopeinfo->attributes.emplace(ID(module), tpl->name.unescape());
|
||||
scopeinfo->attributes.emplace(ID::module, RTLIL::Const(tpl->name.unescape()));
|
||||
}
|
||||
|
||||
module->remove(cell);
|
||||
@@ -298,20 +333,27 @@ struct FlattenWorker
|
||||
|
||||
void flatten_module(RTLIL::Design *design, RTLIL::Module *module, pool<RTLIL::Module*> &used_modules, const std::string &separator)
|
||||
{
|
||||
if (!design->selected(module) || module->get_blackbox_attribute(ignore_wb))
|
||||
if (!design->selected_module(module) || module->get_blackbox_attribute(ignore_wb))
|
||||
return;
|
||||
|
||||
SigMap sigmap(module);
|
||||
|
||||
dict<std::string, RTLIL::Wire*> hier_wires;
|
||||
for (auto wire : module->wires())
|
||||
if (wire->get_bool_attribute(ID::hierconn))
|
||||
hier_wires[wire->name.str()] = wire;
|
||||
|
||||
std::vector<RTLIL::Cell*> worklist = module->selected_cells();
|
||||
while (!worklist.empty())
|
||||
{
|
||||
RTLIL::Cell *cell = worklist.back();
|
||||
worklist.pop_back();
|
||||
|
||||
if (!design->has(cell->type))
|
||||
IdString cell_type_ref = cell->type;
|
||||
if (!design->has(cell_type_ref))
|
||||
continue;
|
||||
|
||||
RTLIL::Module *tpl = design->module(cell->type);
|
||||
RTLIL::Module *tpl = design->module(cell_type_ref);
|
||||
if (tpl->get_blackbox_attribute(ignore_wb))
|
||||
continue;
|
||||
|
||||
@@ -325,7 +367,7 @@ struct FlattenWorker
|
||||
// If a design is fully selected and has a top module defined, topological sorting ensures that all cells
|
||||
// added during flattening are black boxes, and flattening is finished in one pass. However, when flattening
|
||||
// individual modules, this isn't the case, and the newly added cells might have to be flattened further.
|
||||
flatten_cell(design, module, cell, tpl, sigmap, worklist, separator);
|
||||
flatten_cell(design, module, cell, tpl, sigmap, worklist, separator, hier_wires);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -420,7 +462,7 @@ struct FlattenPass : public Pass {
|
||||
else
|
||||
used_modules.insert(top);
|
||||
|
||||
TopoSort<RTLIL::Module*, IdString::compare_ptr_by_name<RTLIL::Module>> topo_modules;
|
||||
TopoSort<RTLIL::Module*, module_ptr_compare> topo_modules;
|
||||
pool<RTLIL::Module*> worklist = used_modules;
|
||||
while (!worklist.empty()) {
|
||||
RTLIL::Module *module = worklist.pop();
|
||||
|
||||
+158
-110
@@ -21,6 +21,7 @@
|
||||
#include "kernel/yosys.h"
|
||||
#include "kernel/celltypes.h"
|
||||
#include "frontends/verific/verific.h"
|
||||
#include "frontends/ast/ast.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <set>
|
||||
@@ -57,18 +58,19 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
|
||||
|
||||
for (auto &celltype : found_celltypes)
|
||||
{
|
||||
std::set<RTLIL::IdString> portnames;
|
||||
std::set<std::string> portnames;
|
||||
std::set<RTLIL::IdString> parameters;
|
||||
std::map<RTLIL::IdString, int> portwidths;
|
||||
log("Generate module for cell type %s:\n", celltype);
|
||||
std::map<std::string, int> portwidths;
|
||||
log("Generate module for cell type %s:\n", design->twines.str(celltype));
|
||||
|
||||
for (auto mod : design->modules())
|
||||
for (auto cell : mod->cells())
|
||||
if (cell->type == celltype) {
|
||||
for (auto &conn : cell->connections()) {
|
||||
if (conn.first[0] != '$')
|
||||
portnames.insert(conn.first);
|
||||
portwidths[conn.first] = max(portwidths[conn.first], conn.second.size());
|
||||
std::string port_name = design->twines.str(conn.first);
|
||||
if (!port_name.empty() && port_name[0] != '$')
|
||||
portnames.insert(std::string(port_name));
|
||||
portwidths[std::string(port_name)] = max(portwidths[std::string(port_name)], conn.second.size());
|
||||
}
|
||||
for (auto ¶ : cell->parameters)
|
||||
parameters.insert(para.first);
|
||||
@@ -99,11 +101,11 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
|
||||
}
|
||||
|
||||
while (portnames.size() > 0) {
|
||||
RTLIL::IdString portname = *portnames.begin();
|
||||
std::string portname = *portnames.begin();
|
||||
for (auto &decl : portdecls)
|
||||
if (decl.index == 0 && patmatch(decl.portname.c_str(), portname.unescape().c_str())) {
|
||||
if (decl.index == 0 && patmatch(decl.portname.c_str(), RTLIL::unescape_id(portname).c_str())) {
|
||||
generate_port_decl_t d = decl;
|
||||
d.portname = portname.str();
|
||||
d.portname = portname;
|
||||
d.index = *indices.begin();
|
||||
log_assert(!indices.empty());
|
||||
indices.erase(d.index);
|
||||
@@ -112,17 +114,15 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
|
||||
log(" port %d: %s [%d:0] %s\n", d.index, d.input ? d.output ? "inout" : "input" : "output", portwidths[d.portname]-1, RTLIL::unescape_id(d.portname));
|
||||
goto found_matching_decl;
|
||||
}
|
||||
log_error("Can't match port %s.\n", portname.unescape());
|
||||
log_error("Can't match port %s.\n", RTLIL::unescape_id(portname).c_str());
|
||||
found_matching_decl:;
|
||||
portnames.erase(portname);
|
||||
}
|
||||
|
||||
log_assert(indices.empty());
|
||||
|
||||
RTLIL::Module *mod = new RTLIL::Module;
|
||||
mod->name = celltype;
|
||||
RTLIL::Module *mod = design->addModule(celltype);
|
||||
mod->attributes[ID::blackbox] = RTLIL::Const(1);
|
||||
design->add(mod);
|
||||
|
||||
for (auto &decl : ports) {
|
||||
RTLIL::Wire *wire = mod->addWire(decl.portname, portwidths.at(decl.portname));
|
||||
@@ -134,7 +134,7 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
|
||||
mod->fixup_ports();
|
||||
|
||||
for (auto ¶ : parameters)
|
||||
log(" ignoring parameter %s.\n", para.unescape());
|
||||
log(" ignoring parameter %s.\n", PooledName(design, para).unescape());
|
||||
|
||||
log(" module %s created.\n", mod);
|
||||
}
|
||||
@@ -157,18 +157,18 @@ std::string basic_cell_type(const std::string celltype, int pos[3] = nullptr) {
|
||||
return basicType;
|
||||
}
|
||||
|
||||
// Try to read an IdString as a numbered connection name ("$123" or similar),
|
||||
// Try to read a IdString as a numbered connection name ("$123" or similar),
|
||||
// writing the result to dst. If the string isn't of the right format, ignore
|
||||
// dst and return false.
|
||||
bool read_id_num(RTLIL::IdString str, int *dst)
|
||||
bool read_id_num(RTLIL::Design &design, IdString ref, int *dst)
|
||||
{
|
||||
log_assert(dst);
|
||||
|
||||
const char *c_str = str.c_str();
|
||||
if (c_str[0] != '$' || !('0' <= c_str[1] && c_str[1] <= '9'))
|
||||
std::string sv = design.twines.str(ref);
|
||||
if (sv.empty() || sv[0] != '$' || !('0' <= sv[1] && sv[1] <= '9'))
|
||||
return false;
|
||||
|
||||
*dst = atoi(c_str + 1);
|
||||
*dst = atoi(std::string(sv).c_str() + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ bool read_id_num(RTLIL::IdString str, int *dst)
|
||||
struct IFExpander
|
||||
{
|
||||
IFExpander (RTLIL::Design &design, RTLIL::Module &m)
|
||||
: module(m), 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':
|
||||
@@ -188,12 +188,13 @@ struct IFExpander
|
||||
}
|
||||
}
|
||||
|
||||
RTLIL::Design &design;
|
||||
RTLIL::Module &module;
|
||||
dict<RTLIL::IdString, RTLIL::Module*> interfaces_in_module;
|
||||
|
||||
bool has_interfaces_not_found;
|
||||
std::vector<RTLIL::IdString> connections_to_remove;
|
||||
std::vector<RTLIL::IdString> connections_to_add_name;
|
||||
std::vector<IdString> connections_to_add;
|
||||
std::vector<RTLIL::SigSpec> connections_to_add_signal;
|
||||
dict<RTLIL::IdString, RTLIL::Module*> interfaces_to_add_to_submodule;
|
||||
dict<RTLIL::IdString, RTLIL::IdString> modports_used_in_submodule;
|
||||
@@ -203,7 +204,7 @@ struct IFExpander
|
||||
{
|
||||
has_interfaces_not_found = false;
|
||||
connections_to_remove.clear();
|
||||
connections_to_add_name.clear();
|
||||
connections_to_add.clear();
|
||||
connections_to_add_signal.clear();
|
||||
interfaces_to_add_to_submodule.clear();
|
||||
modports_used_in_submodule.clear();
|
||||
@@ -226,7 +227,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",
|
||||
interface_name.unescape(), &module);
|
||||
PooledName(module.design, interface_name).unescape(), &module);
|
||||
}
|
||||
|
||||
// Handle an interface connection from the module
|
||||
@@ -239,7 +240,7 @@ struct IFExpander
|
||||
// Strip the prefix '$dummywireforinterface' from the dummy wire to get the name
|
||||
interface_name_str.replace(0,23,"");
|
||||
interface_name_str = "\\" + interface_name_str;
|
||||
RTLIL::IdString interface_name = interface_name_str;
|
||||
IdString interface_name = design.twines.add(std::string(interface_name_str));
|
||||
|
||||
// If 'interfaces' in the cell have not be been handled yet, we aren't
|
||||
// ready to derive the sub-module either
|
||||
@@ -253,7 +254,7 @@ struct IFExpander
|
||||
// '_inst_from_top_dummy'. Check for both of them here
|
||||
int nexactmatch = interfaces_in_module.count(interface_name) > 0;
|
||||
std::string interface_name_str2 = interface_name_str + "_inst_from_top_dummy";
|
||||
RTLIL::IdString interface_name2 = interface_name_str2;
|
||||
IdString interface_name2 = design.twines.add(std::string(interface_name_str2));
|
||||
int nmatch2 = interfaces_in_module.count(interface_name2) > 0;
|
||||
|
||||
// If we can't find either name, this is a missing interface.
|
||||
@@ -268,16 +269,19 @@ struct IFExpander
|
||||
RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name2);
|
||||
|
||||
// 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() + "." + mod_wire->name.unescape();
|
||||
std::string signal_name2 = interface_name.str() + "." + mod_wire->name.unescape();
|
||||
connections_to_add_name.push_back(RTLIL::IdString(signal_name1));
|
||||
if(module.wire(signal_name2) == nullptr) {
|
||||
std::string member = mod_wire->name.unescape();
|
||||
std::string signal_name1 = conn_name_str + "." + member;
|
||||
std::string signal_name2 = interface_name_str + "." + member;
|
||||
connections_to_add.push_back(AST::intern_hier_name(&design, signal_name1));
|
||||
IdString signal_name2_ref = AST::intern_hier_name(&design, signal_name2);
|
||||
if(module.wire(signal_name2_ref) == nullptr) {
|
||||
log_error("Could not find signal '%s' in '%s'\n",
|
||||
signal_name2.c_str(), module.name.unescape());
|
||||
}
|
||||
else {
|
||||
RTLIL::Wire *wire_in_parent = module.wire(signal_name2);
|
||||
RTLIL::Wire *wire_in_parent = module.wire(signal_name2_ref);
|
||||
connections_to_add_signal.push_back(wire_in_parent);
|
||||
}
|
||||
}
|
||||
@@ -289,7 +293,7 @@ struct IFExpander
|
||||
// AstModule::derive
|
||||
string modport_name = submodule.wire(conn_name)->get_string_attribute(ID::interface_modport);
|
||||
if (!modport_name.empty()) {
|
||||
modports_used_in_submodule[conn_name] = "\\" + modport_name;
|
||||
modports_used_in_submodule[conn_name] = design.twines.add("\\" + modport_name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,7 +314,7 @@ struct IFExpander
|
||||
|
||||
// Check if the connection is present as an interface in the sub-module's port list
|
||||
int id;
|
||||
if (read_id_num(conn_name, &id)) {
|
||||
if (read_id_num(design, conn_name, &id)) {
|
||||
/* Interface expansion is incompatible with positional arguments
|
||||
* during expansion, the port list gets each interface signal
|
||||
* inserted after the interface itself which means that the argument
|
||||
@@ -351,8 +355,8 @@ struct IFExpander
|
||||
// interface port connection with the individual signal connections.
|
||||
void rewrite_interface_connections(RTLIL::Cell &cell) const
|
||||
{
|
||||
for(unsigned int i=0;i<connections_to_add_name.size();i++) {
|
||||
cell.connections_[connections_to_add_name[i]] = connections_to_add_signal[i];
|
||||
for(unsigned int i=0;i<connections_to_add.size();i++) {
|
||||
cell.connections_[connections_to_add[i]] = connections_to_add_signal[i];
|
||||
}
|
||||
// Remove the connection for the interface itself:
|
||||
for(unsigned int i=0;i<connections_to_remove.size();i++) {
|
||||
@@ -375,7 +379,7 @@ RTLIL::Module *get_module(RTLIL::Design &design,
|
||||
const std::vector<std::string> &libdirs)
|
||||
{
|
||||
std::string cell_type = cell.type.str();
|
||||
RTLIL::Module *abs_mod = design.module("$abstract" + cell_type);
|
||||
RTLIL::Module *abs_mod = design.module(design.twines.find("$abstract" + cell_type));
|
||||
if (abs_mod) {
|
||||
cell.type = abs_mod->derive(&design, cell.parameters);
|
||||
cell.parameters.clear();
|
||||
@@ -418,7 +422,7 @@ RTLIL::Module *get_module(RTLIL::Design &design,
|
||||
// We couldn't find the module anywhere. Complain if check is set.
|
||||
if (check)
|
||||
log_error("Module `%s' referenced in module `%s' in cell `%s' is not part of the design.\n",
|
||||
cell_type.c_str(), parent.name.c_str(), cell.name.c_str());
|
||||
cell_type.c_str(), parent.name.str().data(), cell.name);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -433,7 +437,7 @@ void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLI
|
||||
{
|
||||
int id;
|
||||
for (auto &conn : cell.connections()) {
|
||||
if (read_id_num(conn.first, &id)) {
|
||||
if (read_id_num(*module.design, conn.first, &id)) {
|
||||
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",
|
||||
@@ -447,11 +451,11 @@ void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLI
|
||||
log_error("Module `%s' referenced in module `%s' in cell `%s' "
|
||||
"does not have a port named '%s'.\n",
|
||||
cell.type.unescape(), &module, &cell,
|
||||
conn.first.unescape());
|
||||
PooledName(module.design, conn.first).unescape());
|
||||
}
|
||||
}
|
||||
for (auto ¶m : cell.parameters) {
|
||||
if (read_id_num(param.first, &id)) {
|
||||
if (read_id_num(*module.design, param.first, &id)) {
|
||||
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",
|
||||
@@ -460,13 +464,14 @@ void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLI
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string param_name = module.design->twines.str(param.first);
|
||||
if (mod.avail_parameters.count(param.first) == 0 &&
|
||||
param.first[0] != '$' &&
|
||||
strchr(param.first.c_str(), '.') == NULL) {
|
||||
param_name[0] != '$' &&
|
||||
param_name.find('.') == std::string::npos) {
|
||||
log_error("Module `%s' referenced in module `%s' in cell `%s' "
|
||||
"does not have a parameter named '%s'.\n",
|
||||
cell.type.unescape(), &module, &cell,
|
||||
param.first.unescape());
|
||||
RTLIL::unescape_id(param_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -504,9 +509,12 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
||||
int idx = atoi(cell->type.substr(pos_idx + 1, pos_num).c_str());
|
||||
int num = atoi(cell->type.substr(pos_num + 1, pos_type).c_str());
|
||||
array_cells[cell] = std::pair<int, int>(idx, num);
|
||||
cell->type = cell->type.substr(pos_type + 1);
|
||||
cell->type = cell->module->design->twines.add(std::string{cell->type.str().substr(pos_type + 1)});
|
||||
}
|
||||
|
||||
dict<IdString, RTLIL::Module*> interfaces_by_name;
|
||||
dict<IdString, IdString> modports_by_name;
|
||||
|
||||
RTLIL::Module *mod = design->module(cell->type);
|
||||
if (!mod)
|
||||
{
|
||||
@@ -534,7 +542,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
||||
if (mod->get_blackbox_attribute()) {
|
||||
if (flag_simcheck || (flag_smtcheck && !mod->get_bool_attribute(ID::smtlib2_module)))
|
||||
log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox/whitebox module.\n",
|
||||
cell->type.c_str(), module->name.c_str(), cell->name.c_str());
|
||||
cell->type, module->name.str().data(), cell->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -559,10 +567,14 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto &p : if_expander.interfaces_to_add_to_submodule)
|
||||
interfaces_by_name[p.first] = p.second;
|
||||
for (auto &p : if_expander.modports_used_in_submodule)
|
||||
modports_by_name[p.first] = p.second;
|
||||
cell->type = mod->derive(design,
|
||||
cell->parameters,
|
||||
if_expander.interfaces_to_add_to_submodule,
|
||||
if_expander.modports_used_in_submodule);
|
||||
interfaces_by_name,
|
||||
modports_by_name);
|
||||
cell->parameters.clear();
|
||||
did_something = true;
|
||||
|
||||
@@ -608,9 +620,11 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
||||
|
||||
for (auto &conn : cell->connections_) {
|
||||
int conn_size = conn.second.size();
|
||||
RTLIL::IdString portname = conn.first;
|
||||
if (portname.begins_with("$")) {
|
||||
int port_id = atoi(portname.substr(1).c_str());
|
||||
IdString portname = conn.first;
|
||||
std::string portname_str = module->design->twines.str(conn.first);
|
||||
if (portname_str.empty() || portname_str[0] != '$') {
|
||||
} else {
|
||||
int port_id = atoi(portname_str.substr(1).data());
|
||||
for (auto wire : mod->wires())
|
||||
if (wire->port_id == port_id) {
|
||||
portname = wire->name;
|
||||
@@ -618,12 +632,12 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
||||
}
|
||||
}
|
||||
if (mod->wire(portname) == nullptr)
|
||||
log_error("Array cell `%s.%s' connects to unknown port `%s'.\n", module, cell, conn.first.unescape());
|
||||
log_error("Array cell `%s.%s' connects to unknown port `%s'.\n", module, cell, PooledName(module, conn.first).unescape());
|
||||
int port_size = mod->wire(portname)->width;
|
||||
if (conn_size == port_size || conn_size == 0)
|
||||
continue;
|
||||
if (conn_size != port_size*num)
|
||||
log_error("Array cell `%s.%s' has invalid port vs. signal size for port `%s'.\n", module, cell, conn.first.unescape());
|
||||
log_error("Array cell `%s.%s' has invalid port vs. signal size for port `%s'.\n", module, cell, PooledName(module, conn.first).unescape());
|
||||
conn.second = conn.second.extract(port_size*idx, port_size);
|
||||
}
|
||||
}
|
||||
@@ -631,7 +645,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
|
||||
return did_something;
|
||||
}
|
||||
|
||||
void hierarchy_worker(RTLIL::Design *design, std::set<RTLIL::Module*, IdString::compare_ptr_by_name<Module>> &used, RTLIL::Module *mod, int indent)
|
||||
void hierarchy_worker(RTLIL::Design *design, std::set<RTLIL::Module*> &used, RTLIL::Module *mod, int indent)
|
||||
{
|
||||
if (used.count(mod) > 0)
|
||||
return;
|
||||
@@ -643,17 +657,19 @@ void hierarchy_worker(RTLIL::Design *design, std::set<RTLIL::Module*, IdString::
|
||||
used.insert(mod);
|
||||
|
||||
for (auto cell : mod->cells()) {
|
||||
std::string celltype = cell->type.str();
|
||||
if (celltype.compare(0, strlen("$array:"), "$array:") == 0)
|
||||
celltype = basic_cell_type(celltype);
|
||||
if (design->module(celltype))
|
||||
hierarchy_worker(design, used, design->module(celltype), indent+4);
|
||||
RTLIL::Module *cm;
|
||||
if (cell->type.begins_with("$array:"))
|
||||
cm = design->module(design->twines.find(basic_cell_type(cell->type.str())));
|
||||
else
|
||||
cm = design->module(cell->type);
|
||||
if (cm)
|
||||
hierarchy_worker(design, used, cm, indent+4);
|
||||
}
|
||||
}
|
||||
|
||||
void hierarchy_clean(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib)
|
||||
{
|
||||
std::set<RTLIL::Module*, IdString::compare_ptr_by_name<Module>> used;
|
||||
std::set<RTLIL::Module*> used;
|
||||
hierarchy_worker(design, used, top, 0);
|
||||
|
||||
std::vector<RTLIL::Module*> del_modules;
|
||||
@@ -692,6 +708,8 @@ bool set_keep_print(std::map<RTLIL::Module*, bool> &cache, RTLIL::Module *mod)
|
||||
if (cache.count(mod) == 0) {
|
||||
cache[mod] = false;
|
||||
for (auto c : mod->cells()) {
|
||||
if (mod->name == c->type)
|
||||
continue;
|
||||
RTLIL::Module *m = mod->design->module(c->type);
|
||||
if ((m != nullptr && set_keep_print(cache, m)) || c->type == ID($print)) {
|
||||
cache[mod] = true;
|
||||
@@ -707,6 +725,8 @@ bool set_keep_assert(std::map<RTLIL::Module*, bool> &cache, RTLIL::Module *mod)
|
||||
if (cache.count(mod) == 0) {
|
||||
cache[mod] = false;
|
||||
for (auto c : mod->cells()) {
|
||||
if (mod->name == c->type)
|
||||
continue;
|
||||
RTLIL::Module *m = mod->design->module(c->type);
|
||||
if ((m != nullptr && set_keep_assert(cache, m)) || c->type.in(ID($check), ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) {
|
||||
cache[mod] = true;
|
||||
@@ -722,13 +742,21 @@ int find_top_mod_score(Design *design, Module *module, dict<Module*, int> &db)
|
||||
if (db.count(module) == 0) {
|
||||
int score = 0;
|
||||
db[module] = 0;
|
||||
std::optional<TwineSearch> search;
|
||||
for (auto cell : module->cells()) {
|
||||
std::string celltype = cell->type.str();
|
||||
// Is this an array instance
|
||||
if (celltype.compare(0, strlen("$array:"), "$array:") == 0)
|
||||
celltype = basic_cell_type(celltype);
|
||||
// Is this cell a module instance?
|
||||
auto instModule = design->module(celltype);
|
||||
RTLIL::Module *instModule;
|
||||
if (cell->type.begins_with("$array:")) {
|
||||
std::string type = basic_cell_type(cell->type.str());
|
||||
instModule = design->module(design->twines.find(type));
|
||||
if (instModule == nullptr) {
|
||||
if (!search)
|
||||
search.emplace(&design->twines);
|
||||
instModule = design->module(search->find(type));
|
||||
}
|
||||
}
|
||||
else
|
||||
instModule = design->module(cell->type);
|
||||
// If there is no instance for this, issue a warning.
|
||||
if (instModule != nullptr) {
|
||||
score = max(score, find_top_mod_score(design, instModule, db) + 1);
|
||||
@@ -754,16 +782,26 @@ RTLIL::Module *check_if_top_has_changed(Design *design, Module *top_mod)
|
||||
}
|
||||
|
||||
// Find a matching wire for an implicit port connection; traversing generate block scope
|
||||
RTLIL::Wire *find_implicit_port_wire(Module *module, Cell *cell, const std::string& port)
|
||||
RTLIL::Wire *find_implicit_port_wire(Module *module, Cell *cell, const std::string& port,
|
||||
std::optional<TwineSearch> &search)
|
||||
{
|
||||
if (!search)
|
||||
search.emplace(&module->design->twines);
|
||||
const std::string &cellname = cell->name.str();
|
||||
size_t idx = cellname.size();
|
||||
while ((idx = cellname.find_last_of('.', idx-1)) != std::string::npos) {
|
||||
Wire *found = module->wire(cellname.substr(0, idx+1) + port.substr(1));
|
||||
if (found != nullptr)
|
||||
return found;
|
||||
std::string wire_name = cellname.substr(0, idx+1) + port.substr(1);
|
||||
IdString ref = search->find(wire_name);
|
||||
if (ref != IdString::Null) {
|
||||
Wire *found = module->wire(ref);
|
||||
if (found != nullptr)
|
||||
return found;
|
||||
}
|
||||
}
|
||||
return module->wire(port);
|
||||
IdString ref = search->find(port);
|
||||
if (ref != IdString::Null)
|
||||
return module->wire(ref);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct HierarchyPass : public Pass {
|
||||
@@ -988,31 +1026,33 @@ struct HierarchyPass : public Pass {
|
||||
|
||||
if (!load_top_mod.empty())
|
||||
{
|
||||
IdString top_name = RTLIL::escape_id(load_top_mod);
|
||||
IdString abstract_id = "$abstract" + RTLIL::escape_id(load_top_mod);
|
||||
IdString top_name = design->twines.add(RTLIL::escape_id(load_top_mod));
|
||||
IdString abstract_id = design->twines.add("$abstract" + RTLIL::escape_id(load_top_mod));
|
||||
top_mod = design->module(top_name);
|
||||
RTLIL::Module *abstract_mod = design->module(abstract_id);
|
||||
|
||||
dict<RTLIL::IdString, RTLIL::Const> top_parameters;
|
||||
if ((top_mod == nullptr && design->module(abstract_id)) || top_mod != nullptr) {
|
||||
if ((top_mod == nullptr && abstract_mod) || top_mod != nullptr) {
|
||||
for (auto ¶ : parameters) {
|
||||
SigSpec sig_value;
|
||||
if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second))
|
||||
log_cmd_error("Can't decode value '%s'!\n", para.second);
|
||||
RTLIL::Const c = sig_value.as_const();
|
||||
c.tag_bare_integer_const(para.second);
|
||||
top_parameters[RTLIL::escape_id(para.first)] = c;
|
||||
top_parameters[design->twines.add(RTLIL::escape_id(para.first))] = c;
|
||||
}
|
||||
}
|
||||
|
||||
if (top_mod == nullptr && design->module(abstract_id))
|
||||
top_mod = design->module(design->module(abstract_id)->derive(design, top_parameters));
|
||||
if (top_mod == nullptr && abstract_mod)
|
||||
top_mod = design->module(abstract_mod->derive(design, top_parameters));
|
||||
else if (top_mod != nullptr && !top_parameters.empty())
|
||||
top_mod = design->module(top_mod->derive(design, top_parameters));
|
||||
|
||||
if (top_mod != nullptr && top_mod->name != top_name) {
|
||||
IdString top_name_ref = top_name;
|
||||
if (top_mod != nullptr && top_mod->name != top_name_ref) {
|
||||
Module *m = top_mod->clone();
|
||||
m->name = top_name;
|
||||
Module *old_mod = design->module(top_name);
|
||||
m->name = top_name_ref;
|
||||
Module *old_mod = design->module(top_name_ref);
|
||||
if (old_mod)
|
||||
design->remove(old_mod);
|
||||
design->add(m);
|
||||
@@ -1081,7 +1121,7 @@ struct HierarchyPass : public Pass {
|
||||
}
|
||||
|
||||
if (top_mod != nullptr && top_mod->name.begins_with("$abstract")) {
|
||||
IdString top_name = top_mod->name.substr(strlen("$abstract"));
|
||||
IdString top_name = design->twines.add(top_mod->name.str().substr(strlen("$abstract")));
|
||||
|
||||
dict<RTLIL::IdString, RTLIL::Const> top_parameters;
|
||||
for (auto ¶ : parameters) {
|
||||
@@ -1090,15 +1130,16 @@ struct HierarchyPass : public Pass {
|
||||
log_cmd_error("Can't decode value '%s'!\n", para.second);
|
||||
RTLIL::Const c = sig_value.as_const();
|
||||
c.tag_bare_integer_const(para.second);
|
||||
top_parameters[RTLIL::escape_id(para.first)] = c;
|
||||
top_parameters[design->twines.add(RTLIL::escape_id(para.first))] = c;
|
||||
}
|
||||
|
||||
top_mod = design->module(top_mod->derive(design, top_parameters));
|
||||
|
||||
if (top_mod != nullptr && top_mod->name != top_name) {
|
||||
IdString top_name_ref = top_name;
|
||||
if (top_mod != nullptr && top_mod->name != top_name_ref) {
|
||||
Module *m = top_mod->clone();
|
||||
m->name = top_name;
|
||||
Module *old_mod = design->module(top_name);
|
||||
m->name = top_name_ref;
|
||||
Module *old_mod = design->module(top_name_ref);
|
||||
if (old_mod)
|
||||
design->remove(old_mod);
|
||||
design->add(m);
|
||||
@@ -1122,7 +1163,7 @@ struct HierarchyPass : public Pass {
|
||||
{
|
||||
did_something = false;
|
||||
|
||||
std::set<RTLIL::Module*, IdString::compare_ptr_by_name<Module>> used_modules;
|
||||
std::set<RTLIL::Module*> used_modules;
|
||||
if (top_mod != NULL) {
|
||||
log_header(design, "Analyzing design hierarchy..\n");
|
||||
hierarchy_worker(design, used_modules, top_mod, 0);
|
||||
@@ -1223,17 +1264,19 @@ struct HierarchyPass : public Pass {
|
||||
RTLIL::Module *cell_mod = design->module(cell->type);
|
||||
if (cell_mod == nullptr)
|
||||
continue;
|
||||
for (auto &conn : cell->connections())
|
||||
if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') {
|
||||
for (auto &conn : cell->connections()) {
|
||||
std::string conn_name = design->twines.str(conn.first);
|
||||
if (!conn_name.empty() && conn_name[0] == '$' && '0' <= conn_name[1] && conn_name[1] <= '9') {
|
||||
pos_mods.insert(design->module(cell->type));
|
||||
pos_work.push_back(std::pair<RTLIL::Module*,RTLIL::Cell*>(mod, cell));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pool<std::pair<IdString, IdString>> params_rename;
|
||||
for (const auto &p : cell->parameters) {
|
||||
int id;
|
||||
if (read_id_num(p.first, &id)) {
|
||||
if (read_id_num(*design, p.first, &id)) {
|
||||
if (id <= 0 || id > GetSize(cell_mod->avail_parameters)) {
|
||||
log(" Failed to map positional parameter %d of cell %s.%s (%s).\n",
|
||||
id, mod, cell, cell->type.unescape());
|
||||
@@ -1251,7 +1294,7 @@ struct HierarchyPass : public Pass {
|
||||
for (auto module : pos_mods)
|
||||
for (auto wire : module->wires()) {
|
||||
if (wire->port_id > 0)
|
||||
pos_map[std::pair<RTLIL::Module*,int>(module, wire->port_id)] = wire->name;
|
||||
pos_map[std::pair<RTLIL::Module*,int>(module, wire->port_id)] = IdString(wire->name);
|
||||
}
|
||||
|
||||
for (auto &work : pos_work) {
|
||||
@@ -1259,21 +1302,21 @@ struct HierarchyPass : public Pass {
|
||||
RTLIL::Cell *cell = work.second;
|
||||
log("Mapping positional arguments of cell %s.%s (%s).\n",
|
||||
module, cell, cell->type.unescape());
|
||||
dict<RTLIL::IdString, RTLIL::SigSpec> new_connections;
|
||||
dict<IdString, RTLIL::SigSpec> new_connections_twine;
|
||||
for (auto &conn : cell->connections()) {
|
||||
int id;
|
||||
if (read_id_num(conn.first, &id)) {
|
||||
if (read_id_num(*design, conn.first, &id)) {
|
||||
std::pair<RTLIL::Module*,int> key(design->module(cell->type), id);
|
||||
if (pos_map.count(key) == 0) {
|
||||
log(" Failed to map positional argument %d of cell %s.%s (%s).\n",
|
||||
id, module, cell, cell->type.unescape());
|
||||
new_connections[conn.first] = conn.second;
|
||||
new_connections_twine[conn.first] = conn.second;
|
||||
} else
|
||||
new_connections[pos_map.at(key)] = conn.second;
|
||||
new_connections_twine[pos_map.at(key)] = conn.second;
|
||||
} else
|
||||
new_connections[conn.first] = conn.second;
|
||||
new_connections_twine[conn.first] = conn.second;
|
||||
}
|
||||
cell->connections_ = new_connections;
|
||||
cell->connections_ = new_connections_twine;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1289,6 +1332,7 @@ struct HierarchyPass : public Pass {
|
||||
// Process SV implicit wildcard port connections
|
||||
std::set<Module*> blackbox_derivatives;
|
||||
std::vector<Module*> design_modules = design->modules();
|
||||
std::optional<TwineSearch> implicit_port_search;
|
||||
|
||||
for (auto module : design_modules)
|
||||
{
|
||||
@@ -1304,11 +1348,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())
|
||||
IdString new_m_ref = m->derive(design, cell->parameters, true);
|
||||
if (new_m_ref == IdString{})
|
||||
continue;
|
||||
if (new_m_name != m->name) {
|
||||
m = design->module(new_m_name);
|
||||
if (new_m_ref != m->name) {
|
||||
m = design->module(new_m_ref);
|
||||
blackbox_derivatives.insert(m);
|
||||
}
|
||||
}
|
||||
@@ -1321,7 +1365,7 @@ struct HierarchyPass : public Pass {
|
||||
if (old_connections.count(wire->name))
|
||||
continue;
|
||||
// Make sure a wire of correct name exists in the parent
|
||||
Wire* parent_wire = find_implicit_port_wire(module, cell, wire->name.str());
|
||||
Wire* parent_wire = find_implicit_port_wire(module, cell, wire->name.str(), implicit_port_search);
|
||||
|
||||
// Missing wires are OK when a default value is set
|
||||
if (!nodefaults && parent_wire == nullptr && defaults_db.count(cell->type) && defaults_db.at(cell->type).count(wire->name))
|
||||
@@ -1350,16 +1394,20 @@ struct HierarchyPass : public Pass {
|
||||
|
||||
if (keep_positionals) {
|
||||
bool found_positionals = false;
|
||||
for (auto &conn : cell->connections())
|
||||
if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9')
|
||||
for (auto &conn : cell->connections()) {
|
||||
std::string conn_name = design->twines.str(conn.first);
|
||||
if (!conn_name.empty() && conn_name[0] == '$' && '0' <= conn_name[1] && conn_name[1] <= '9')
|
||||
found_positionals = true;
|
||||
}
|
||||
if (found_positionals)
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto &it : defaults_db.at(cell->type))
|
||||
if (!cell->hasPort(it.first))
|
||||
cell->setPort(it.first, it.second);
|
||||
for (auto &it : defaults_db.at(cell->type)) {
|
||||
IdString port_ref = it.first;
|
||||
if (!cell->hasPort(port_ref))
|
||||
cell->setPort(port_ref, it.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1489,11 +1537,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())
|
||||
IdString new_m_ref = m->derive(design, cell->parameters, true);
|
||||
if (new_m_ref == IdString{})
|
||||
continue;
|
||||
if (new_m_name != m->name) {
|
||||
m = design->module(new_m_name);
|
||||
if (new_m_ref != m->name) {
|
||||
m = design->module(new_m_ref);
|
||||
blackbox_derivatives.insert(m);
|
||||
}
|
||||
} else {
|
||||
@@ -1516,7 +1564,7 @@ struct HierarchyPass : public Pass {
|
||||
bool resize_widths = !keep_portwidths && GetSize(w) != GetSize(conn.second);
|
||||
if (resize_widths && verific_mod && boxed_params)
|
||||
log_debug("Ignoring width mismatch on %s.%s.%s from verific, is port width parametrizable?\n",
|
||||
module, cell, conn.first.unescape()
|
||||
module, cell, PooledName(design, conn.first).unescape()
|
||||
);
|
||||
else if (resize_widths) {
|
||||
if (GetSize(w) < GetSize(conn.second))
|
||||
@@ -1541,13 +1589,13 @@ struct HierarchyPass : public Pass {
|
||||
|
||||
if (!conn.second.is_fully_const() || !w->port_input || w->port_output)
|
||||
log_warning("Resizing cell port %s.%s.%s from %d bits to %d bits.\n", module, cell,
|
||||
conn.first.unescape(), GetSize(conn.second), GetSize(sig));
|
||||
PooledName(design, conn.first).unescape(), GetSize(conn.second), GetSize(sig));
|
||||
cell->setPort(conn.first, sig);
|
||||
}
|
||||
|
||||
if (w->port_output && !w->port_input && sig.has_const())
|
||||
log_error("Output port %s.%s.%s (%s) is connected to constants: %s\n",
|
||||
module, cell, conn.first.unescape(), cell->type.unescape(), log_signal(sig));
|
||||
module, cell, PooledName(design, conn.first).unescape(), cell->type.unescape(), log_signal(sig));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,25 +71,27 @@ struct UniquifyPass : public Pass {
|
||||
for (auto cell : module->selected_cells())
|
||||
{
|
||||
Module *tmod = design->module(cell->type);
|
||||
IdString newname = module->name.str() + "." + cell->name.unescape();
|
||||
|
||||
if (tmod == nullptr)
|
||||
continue;
|
||||
|
||||
std::string newname = module->name.str() + "." + cell->name.unescape();
|
||||
|
||||
if (tmod->get_blackbox_attribute())
|
||||
continue;
|
||||
|
||||
if (tmod->get_bool_attribute(ID::unique) && newname == tmod->name)
|
||||
IdString newname_ref = design->twines.add(std::string(newname));
|
||||
if (tmod->get_bool_attribute(ID::unique) && newname_ref == tmod->name)
|
||||
continue;
|
||||
|
||||
log("Creating module %s from %s.\n", newname.unescape(), tmod);
|
||||
log("Creating module %s from %s.\n", RTLIL::unescape_id(newname), tmod->name.unescape());
|
||||
|
||||
auto smod = tmod->clone();
|
||||
smod->name = newname;
|
||||
cell->type = newname;
|
||||
smod->name = newname_ref;
|
||||
cell->type = newname_ref;
|
||||
smod->set_bool_attribute(ID::unique);
|
||||
if (smod->attributes.count(ID::hdlname) == 0)
|
||||
smod->attributes[ID::hdlname] = string(tmod->name.unescape());
|
||||
smod->attributes[ID::hdlname] = RTLIL::Const(tmod->name.unescape());
|
||||
design->add(smod);
|
||||
|
||||
did_something = true;
|
||||
|
||||
@@ -26,6 +26,8 @@ PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
struct rules_t
|
||||
{
|
||||
Design *design = nullptr;
|
||||
|
||||
struct portinfo_t {
|
||||
int group, index, dupidx;
|
||||
int wrmode, enable, transp, clocks, clkpol;
|
||||
@@ -36,7 +38,7 @@ struct rules_t
|
||||
};
|
||||
|
||||
struct bram_t {
|
||||
IdString name;
|
||||
PooledName name;
|
||||
int variant;
|
||||
|
||||
int groups, abits, dbits, init;
|
||||
@@ -95,7 +97,7 @@ struct rules_t
|
||||
return portinfos;
|
||||
}
|
||||
|
||||
void find_variant_params(dict<IdString, Const> &variant_params, const bram_t &other) const
|
||||
void find_variant_params(TwinePool &twines, dict<IdString, Const> &variant_params, const bram_t &other) const
|
||||
{
|
||||
log_assert(name == other.name);
|
||||
|
||||
@@ -114,21 +116,22 @@ struct rules_t
|
||||
if (ports[i] != other.ports[i])
|
||||
log_error("Bram %s variants %d and %d have different number of %c-ports.\n", name.unescape(), variant, other.variant, 'A'+i);
|
||||
if (wrmode[i] != other.wrmode[i])
|
||||
variant_params[stringf("\\CFG_WRMODE_%c", 'A' + i)] = wrmode[i];
|
||||
variant_params[twines.add(stringf("\\CFG_WRMODE_%c", 'A' + i))] = wrmode[i];
|
||||
if (enable[i] != other.enable[i])
|
||||
variant_params[stringf("\\CFG_ENABLE_%c", 'A' + i)] = enable[i];
|
||||
variant_params[twines.add(stringf("\\CFG_ENABLE_%c", 'A' + i))] = enable[i];
|
||||
if (transp[i] != other.transp[i])
|
||||
variant_params[stringf("\\CFG_TRANSP_%c", 'A' + i)] = transp[i];
|
||||
variant_params[twines.add(stringf("\\CFG_TRANSP_%c", 'A' + i))] = transp[i];
|
||||
if (clocks[i] != other.clocks[i])
|
||||
variant_params[stringf("\\CFG_CLOCKS_%c", 'A' + i)] = clocks[i];
|
||||
variant_params[twines.add(stringf("\\CFG_CLOCKS_%c", 'A' + i))] = clocks[i];
|
||||
if (clkpol[i] != other.clkpol[i])
|
||||
variant_params[stringf("\\CFG_CLKPOL_%c", 'A' + i)] = clkpol[i];
|
||||
variant_params[twines.add(stringf("\\CFG_CLKPOL_%c", 'A' + i))] = clkpol[i];
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct match_t {
|
||||
IdString name;
|
||||
PooledName name;
|
||||
dict<string, int> min_limits, max_limits;
|
||||
bool or_next_if_better, make_transp, make_outreg;
|
||||
char shuffle_enable;
|
||||
@@ -211,7 +214,7 @@ struct rules_t
|
||||
|
||||
void parse_bram()
|
||||
{
|
||||
IdString bram_name = RTLIL::escape_id(tokens[1]);
|
||||
PooledName bram_name(design, design->twines.add(RTLIL::escape_id(tokens[1])));
|
||||
|
||||
if (GetSize(tokens) != 2)
|
||||
syntax_error();
|
||||
@@ -296,7 +299,7 @@ struct rules_t
|
||||
syntax_error();
|
||||
|
||||
match_t data;
|
||||
data.name = RTLIL::escape_id(tokens[1]);
|
||||
data.name = PooledName(design, design->twines.add(RTLIL::escape_id(tokens[1])));
|
||||
data.or_next_if_better = false;
|
||||
data.make_transp = false;
|
||||
data.make_outreg = false;
|
||||
@@ -349,7 +352,7 @@ struct rules_t
|
||||
size_t c1 = tokens[idx][0] == '!' ? 1 : 0;
|
||||
size_t c2 = tokens[idx].find("=");
|
||||
bool exists = (c1 == 0);
|
||||
IdString key = RTLIL::escape_id(tokens[idx].substr(c1, c2));
|
||||
IdString key = design->twines.add(RTLIL::escape_id(tokens[idx].substr(c1, c2)));
|
||||
Const val = c2 != std::string::npos ? tokens[idx].substr(c2+1) : RTLIL::Const(1);
|
||||
|
||||
data.attributes.back().emplace_back(exists, key, map_case(val));
|
||||
@@ -361,8 +364,9 @@ struct rules_t
|
||||
}
|
||||
}
|
||||
|
||||
void parse(string filename)
|
||||
void parse(string filename, Design *design)
|
||||
{
|
||||
this->design = design;
|
||||
rewrite_filename(filename);
|
||||
infile.open(filename);
|
||||
linecount = 0;
|
||||
@@ -759,7 +763,7 @@ grow_read_ports:;
|
||||
if (!exists)
|
||||
ss << "!";
|
||||
IdString key = std::get<1>(sums.front());
|
||||
ss << key.unescape();
|
||||
ss << PooledName(mem.module, key).unescape();
|
||||
const Const &value = rules.map_case(std::get<2>(sums.front()));
|
||||
if (exists && value != Const(1))
|
||||
ss << "=\"" << value.decode_string() << "\"";
|
||||
@@ -862,7 +866,7 @@ grow_read_ports:;
|
||||
|
||||
dict<IdString, Const> variant_params;
|
||||
for (auto &other_bram : rules.brams.at(bram.name))
|
||||
bram.find_variant_params(variant_params, other_bram);
|
||||
bram.find_variant_params(module->design->twines, variant_params, other_bram);
|
||||
|
||||
// actually replace that memory cell
|
||||
|
||||
@@ -873,7 +877,7 @@ 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(stringf("%s.%d.%d.%d", mem.memid, grid_d, grid_a, dupidx)), bram.name);
|
||||
Cell *c = module->addCell(module->uniquify(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", bram.name.unescape(), grid_d, grid_a, dupidx, c);
|
||||
|
||||
for (auto &vp : variant_params)
|
||||
@@ -1137,7 +1141,7 @@ void handle_memory(Mem &mem, const rules_t &rules, FfInitVals *initvals)
|
||||
if (!exists)
|
||||
ss << "!";
|
||||
IdString key = std::get<1>(sums.front());
|
||||
ss << key.unescape();
|
||||
ss << PooledName(mem.module, key).unescape();
|
||||
const Const &value = rules.map_case(std::get<2>(sums.front()));
|
||||
if (exists && value != Const(1))
|
||||
ss << "=\"" << value.decode_string() << "\"";
|
||||
@@ -1313,7 +1317,7 @@ struct MemoryBramPass : public Pass {
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++) {
|
||||
if (args[argidx] == "-rules" && argidx+1 < args.size()) {
|
||||
rules.parse(args[++argidx]);
|
||||
rules.parse(args[++argidx], design);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -130,6 +130,11 @@ struct MemConfig {
|
||||
|
||||
typedef std::vector<MemConfig> MemConfigs;
|
||||
|
||||
static void set_ram_port(RTLIL::Cell *cell, const std::string &port_name, const RTLIL::SigSpec &sig)
|
||||
{
|
||||
cell->setPort(cell->module->design->twines.add(port_name), sig);
|
||||
}
|
||||
|
||||
struct MapWorker {
|
||||
Module *module;
|
||||
ModWalker modwalker;
|
||||
@@ -204,7 +209,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", mem.module->name.unescape(), mem.memid.unescape(), rdef.id.unescape());
|
||||
log_debug("memory %s.%s: rejecting mapping to %s: ROM mapping disabled (prune_rom set)\n", mem.module, mem.memid.unescape(), RTLIL::unescape_id(rdef.id));
|
||||
continue;
|
||||
}
|
||||
MemConfig cfg;
|
||||
@@ -323,7 +328,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: ", ram.id.unescape());
|
||||
rejected_cfg_debug_msgs += stringf("can't map to to %s: ", RTLIL::unescape_id(ram.id));
|
||||
rejected_cfg_debug_msgs += message;
|
||||
rejected_cfg_debug_msgs += "\n";
|
||||
}
|
||||
@@ -338,7 +343,7 @@ struct MemMapping {
|
||||
rejected_cfg_debug_msgs += portname;
|
||||
first = false;
|
||||
}
|
||||
rejected_cfg_debug_msgs += stringf("] of %s: ", ram.id.unescape());
|
||||
rejected_cfg_debug_msgs += stringf("] of %s: ", RTLIL::unescape_id(ram.id));
|
||||
rejected_cfg_debug_msgs += message;
|
||||
rejected_cfg_debug_msgs += "\n";
|
||||
}
|
||||
@@ -361,7 +366,7 @@ struct MemMapping {
|
||||
rejected_cfg_debug_msgs += portname;
|
||||
first = false;
|
||||
}
|
||||
rejected_cfg_debug_msgs += stringf("] of %s: ", ram.id.unescape());
|
||||
rejected_cfg_debug_msgs += stringf("] of %s: ", RTLIL::unescape_id(ram.id));
|
||||
rejected_cfg_debug_msgs += message;
|
||||
rejected_cfg_debug_msgs += "\n";
|
||||
}
|
||||
@@ -380,7 +385,7 @@ void MemMapping::dump_configs(int stage) {
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
log_debug("Memory %s.%s mapping candidates (%s):\n", mem.module->name.unescape(), mem.memid.unescape(), stage_name);
|
||||
log_debug("Memory %s.%s mapping candidates (%s):\n", mem.module, mem.memid.unescape(), stage_name);
|
||||
if (logic_ok) {
|
||||
log_debug("- logic fallback\n");
|
||||
log_debug(" - cost: %f\n", logic_cost);
|
||||
@@ -391,7 +396,7 @@ void MemMapping::dump_configs(int stage) {
|
||||
}
|
||||
|
||||
void MemMapping::dump_config(MemConfig &cfg) {
|
||||
log_debug("- %s:\n", cfg.def->id.unescape());
|
||||
log_debug("- %s:\n", RTLIL::unescape_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 +532,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", mem.module->name.unescape(), mem.memid.unescape());
|
||||
log("found attribute 'lram' on memory %s.%s, forced mapping to huge RAM\n", mem.module, mem.memid.unescape());
|
||||
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 +541,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", attr.unescape(), mem.module->name.unescape(), mem.memid.unescape());
|
||||
log("found attribute '%s = 1' on memory %s.%s, disabled mapping to FF\n", ID::unescaped_str(attr), mem.module, mem.memid.unescape());
|
||||
return;
|
||||
}
|
||||
std::string val_s = val.decode_string();
|
||||
@@ -549,20 +554,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", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape());
|
||||
log("found attribute '%s = %s' on memory %s.%s, forced mapping to FF\n", ID::unescaped_str(attr), val_s, mem.module, mem.memid.unescape());
|
||||
} else if (val_s == "distributed") {
|
||||
kind = RamKind::Distributed;
|
||||
log("found attribute '%s = %s' on memory %s.%s, forced mapping to distributed RAM\n", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape());
|
||||
log("found attribute '%s = %s' on memory %s.%s, forced mapping to distributed RAM\n", ID::unescaped_str(attr), val_s, mem.module, mem.memid.unescape());
|
||||
} 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", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape());
|
||||
log("found attribute '%s = %s' on memory %s.%s, forced mapping to block RAM\n", ID::unescaped_str(attr), val_s, mem.module, mem.memid.unescape());
|
||||
} 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", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape());
|
||||
log("found attribute '%s = %s' on memory %s.%s, forced mapping to huge RAM\n", ID::unescaped_str(attr), val_s, mem.module, mem.memid.unescape());
|
||||
} else {
|
||||
kind = RamKind::NotLogic;
|
||||
style = val_s;
|
||||
log("found attribute '%s = %s' on memory %s.%s, forced mapping to %s RAM\n", attr.unescape(), val_s, mem.module->name.unescape(), mem.memid.unescape(), val_s);
|
||||
log("found attribute '%s = %s' on memory %s.%s, forced mapping to %s RAM\n", ID::unescaped_str(attr), val_s, mem.module, mem.memid.unescape(), val_s);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1755,9 +1760,9 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
|
||||
cell->setParam(stringf("\\PORT_%s_CLK_POL", name), clk_pol);
|
||||
}
|
||||
for (auto cell: cells) {
|
||||
cell->setPort(stringf("\\PORT_%s_CLK", name), clk);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_CLK", name), clk);
|
||||
if (pdef.clk_en)
|
||||
cell->setPort(stringf("\\PORT_%s_CLK_EN", name), clk_en);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_CLK_EN", name), clk_en);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1819,7 +1824,7 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
|
||||
for (int i = 0; i < hw_wr_wide_log2 && i < hw_rd_wide_log2; i++)
|
||||
hw_addr[i] = State::S0;
|
||||
for (auto cell: cells)
|
||||
cell->setPort(stringf("\\PORT_%s_ADDR", name), hw_addr);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_ADDR", name), hw_addr);
|
||||
|
||||
// Write part.
|
||||
if (pdef.kind != PortKind::Ar && pdef.kind != PortKind::Sr) {
|
||||
@@ -1850,31 +1855,31 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
|
||||
hw_wren.append(big_wren[bit.mux_idx][bit.bit]);
|
||||
}
|
||||
}
|
||||
cell->setPort(stringf("\\PORT_%s_WR_DATA", name), hw_wdata);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_WR_DATA", name), hw_wdata);
|
||||
if (pdef.wrbe_separate) {
|
||||
// TODO make some use of it
|
||||
SigSpec en = mem.module->ReduceOr(NEW_ID, hw_wren);
|
||||
cell->setPort(stringf("\\PORT_%s_WR_EN", name), en);
|
||||
cell->setPort(stringf("\\PORT_%s_WR_BE", name), hw_wren);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_WR_EN", name), en);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_WR_BE", name), hw_wren);
|
||||
if (cfg.def->width_mode != WidthMode::Single)
|
||||
cell->setParam(stringf("\\PORT_%s_WR_BE_WIDTH", name), GetSize(hw_wren));
|
||||
} else {
|
||||
cell->setPort(stringf("\\PORT_%s_WR_EN", name), hw_wren);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_WR_EN", name), hw_wren);
|
||||
if (cfg.def->byte != 0 && (cfg.def->width_mode != WidthMode::Single || opts.force_params))
|
||||
cell->setParam(stringf("\\PORT_%s_WR_EN_WIDTH", name), GetSize(hw_wren));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (auto cell: cells) {
|
||||
cell->setPort(stringf("\\PORT_%s_WR_DATA", name), Const(State::Sx, width));
|
||||
set_ram_port(cell, stringf("\\PORT_%s_WR_DATA", name), Const(State::Sx, width));
|
||||
SigSpec hw_wren = Const(State::S0, width / effective_byte);
|
||||
if (pdef.wrbe_separate) {
|
||||
cell->setPort(stringf("\\PORT_%s_WR_EN", name), State::S0);
|
||||
cell->setPort(stringf("\\PORT_%s_WR_BE", name), hw_wren);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_WR_EN", name), State::S0);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_WR_BE", name), hw_wren);
|
||||
if (cfg.def->width_mode != WidthMode::Single)
|
||||
cell->setParam(stringf("\\PORT_%s_WR_BE_WIDTH", name), GetSize(hw_wren));
|
||||
} else {
|
||||
cell->setPort(stringf("\\PORT_%s_WR_EN", name), hw_wren);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_WR_EN", name), hw_wren);
|
||||
if (cfg.def->byte != 0 && cfg.def->width_mode != WidthMode::Single)
|
||||
cell->setParam(stringf("\\PORT_%s_WR_EN_WIDTH", name), GetSize(hw_wren));
|
||||
}
|
||||
@@ -1894,11 +1899,11 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
|
||||
auto cell = cells[rd];
|
||||
if (pdef.kind == PortKind::Sr || pdef.kind == PortKind::Srsw) {
|
||||
if (pdef.rd_en)
|
||||
cell->setPort(stringf("\\PORT_%s_RD_EN", name), rpcfg.rd_en_to_clk_en ? State::S1 : rport.en);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_RD_EN", name), rpcfg.rd_en_to_clk_en ? State::S1 : rport.en);
|
||||
if (pdef.rdarstval != ResetValKind::None)
|
||||
cell->setPort(stringf("\\PORT_%s_RD_ARST", name), rport.arst);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_RD_ARST", name), rport.arst);
|
||||
if (pdef.rdsrstval != ResetValKind::None)
|
||||
cell->setPort(stringf("\\PORT_%s_RD_SRST", name), rport.srst);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_RD_SRST", name), rport.srst);
|
||||
if (pdef.rdinitval == ResetValKind::Any || pdef.rdinitval == ResetValKind::NoUndef) {
|
||||
Const val = rport.init_value;
|
||||
if (pdef.rdarstval == ResetValKind::Init && rport.arst != State::S0) {
|
||||
@@ -1949,7 +1954,7 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
|
||||
}
|
||||
}
|
||||
SigSpec hw_rdata = mem.module->addWire(NEW_ID, width);
|
||||
cell->setPort(stringf("\\PORT_%s_RD_DATA", name), hw_rdata);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_RD_DATA", name), hw_rdata);
|
||||
SigSpec lhs;
|
||||
SigSpec rhs;
|
||||
for (int i = 0; i < GetSize(hw_rdata); i++) {
|
||||
@@ -1965,11 +1970,11 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
|
||||
for (auto cell: cells) {
|
||||
if (pdef.kind == PortKind::Sr || pdef.kind == PortKind::Srsw) {
|
||||
if (pdef.rd_en)
|
||||
cell->setPort(stringf("\\PORT_%s_RD_EN", name), State::S0);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_RD_EN", name), State::S0);
|
||||
if (pdef.rdarstval != ResetValKind::None)
|
||||
cell->setPort(stringf("\\PORT_%s_RD_ARST", name), State::S0);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_RD_ARST", name), State::S0);
|
||||
if (pdef.rdsrstval != ResetValKind::None)
|
||||
cell->setPort(stringf("\\PORT_%s_RD_SRST", name), State::S0);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_RD_SRST", name), State::S0);
|
||||
if (pdef.rdinitval == ResetValKind::Any)
|
||||
cell->setParam(stringf("\\PORT_%s_RD_INIT_VALUE", name), Const(State::Sx, width));
|
||||
else if (pdef.rdinitval == ResetValKind::NoUndef)
|
||||
@@ -1984,14 +1989,14 @@ void MemMapping::emit_port(const MemConfig &cfg, std::vector<Cell*> &cells, cons
|
||||
cell->setParam(stringf("\\PORT_%s_RD_SRST_VALUE", name), Const(State::S0, width));
|
||||
}
|
||||
SigSpec hw_rdata = mem.module->addWire(NEW_ID, width);
|
||||
cell->setPort(stringf("\\PORT_%s_RD_DATA", name), hw_rdata);
|
||||
set_ram_port(cell, stringf("\\PORT_%s_RD_DATA", name), hw_rdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MemMapping::emit(const MemConfig &cfg) {
|
||||
log("mapping memory %s.%s via %s\n", mem.module->name.unescape(), mem.memid.unescape(), cfg.def->id.unescape());
|
||||
log("mapping memory %s.%s via %s\n", mem.module, mem.memid.unescape(), RTLIL::unescape_id(cfg.def->id));
|
||||
// First, handle emulations.
|
||||
if (cfg.emu_read_first)
|
||||
mem.emulate_read_first(&worker.initvals);
|
||||
@@ -2068,7 +2073,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(stringf("%s.%d.%d", mem.memid, rp, rd), cfg.def->id);
|
||||
Cell *cell = mem.module->addCell(stringf("%s.%d.%d", mem.memid.str(), rp, rd), mem.module->design->twines.add(std::string(cfg.def->id)));
|
||||
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)
|
||||
@@ -2086,12 +2091,12 @@ void MemMapping::emit(const MemConfig &cfg) {
|
||||
auto &ccfg = cfg.shared_clocks[i];
|
||||
if (cdef.anyedge) {
|
||||
cell->setParam(stringf("\\CLK_%s_POL", cdef.name), ccfg.used ? ccfg.polarity : true);
|
||||
cell->setPort(stringf("\\CLK_%s", cdef.name), ccfg.used ? ccfg.clk : State::S0);
|
||||
set_ram_port(cell, stringf("\\CLK_%s", cdef.name), ccfg.used ? ccfg.clk : State::S0);
|
||||
} else {
|
||||
SigSpec sig = ccfg.used ? ccfg.clk : State::S0;
|
||||
if (ccfg.used && ccfg.invert)
|
||||
sig = mem.module->Not(NEW_ID, sig);
|
||||
cell->setPort(stringf("\\CLK_%s", cdef.name), sig);
|
||||
set_ram_port(cell, stringf("\\CLK_%s", cdef.name), sig);
|
||||
}
|
||||
}
|
||||
if (cfg.def->init == MemoryInitKind::Any || cfg.def->init == MemoryInitKind::NoUndef) {
|
||||
@@ -2252,9 +2257,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", module->name.unescape(), mem.memid.unescape());
|
||||
log_debug("Rejected candidates for mapping memory %s.%s:\n", module, mem.memid.unescape());
|
||||
log_debug("%s", map.rejected_cfg_debug_msgs);
|
||||
log_error("no valid mapping found for memory %s.%s\n", module->name.unescape(), mem.memid.unescape());
|
||||
log_error("no valid mapping found for memory %s.%s\n", module, mem.memid.unescape());
|
||||
}
|
||||
idx = 0;
|
||||
best = map.cfgs[0].cost;
|
||||
@@ -2266,7 +2271,7 @@ struct MemoryLibMapPass : public Pass {
|
||||
}
|
||||
}
|
||||
if (idx == -1) {
|
||||
log("using FF mapping for memory %s.%s\n", module->name.unescape(), mem.memid.unescape());
|
||||
log("using FF mapping for memory %s.%s\n", module, mem.memid.unescape());
|
||||
} else {
|
||||
map.emit(map.cfgs[idx]);
|
||||
// Rebuild indices after modifying module
|
||||
|
||||
+24
-16
@@ -33,7 +33,7 @@ struct MemoryMapWorker
|
||||
bool rom_only = false;
|
||||
bool keepdc = false;
|
||||
bool formal = false;
|
||||
dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes;
|
||||
dict<std::string, std::vector<RTLIL::Const>> attributes;
|
||||
|
||||
RTLIL::Design *design;
|
||||
RTLIL::Module *module;
|
||||
@@ -42,6 +42,9 @@ struct MemoryMapWorker
|
||||
|
||||
std::map<std::pair<RTLIL::SigSpec, RTLIL::SigSpec>, RTLIL::SigBit> decoder_cache;
|
||||
|
||||
|
||||
pool<std::string> wire_names;
|
||||
|
||||
MemoryMapWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module), sigmap(module), initvals(&sigmap, module) {}
|
||||
|
||||
std::string map_case(std::string value) const
|
||||
@@ -63,7 +66,7 @@ struct MemoryMapWorker
|
||||
std::string genid(RTLIL::IdString name, std::string token1 = "", int i = -1, std::string token2 = "", int j = -1, std::string token3 = "", int k = -1, std::string token4 = "")
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << "$memory" << name.str() << token1;
|
||||
sstr << "$memory" << design->twines.str(name) << token1;
|
||||
|
||||
if (i >= 0)
|
||||
sstr << "[" << i << "]";
|
||||
@@ -115,11 +118,12 @@ struct MemoryMapWorker
|
||||
|
||||
// check if attributes allow us to infer FFRAM for this memory
|
||||
for (const auto &attr : attributes) {
|
||||
if (mem.attributes.count(attr.first)) {
|
||||
const auto &cell_attr = mem.attributes[attr.first];
|
||||
IdString attr_ref = design->twines.find(attr.first);
|
||||
if (attr_ref != IdString::Null && mem.attributes.count(attr_ref)) {
|
||||
const auto &cell_attr = mem.attributes[attr_ref];
|
||||
if (attr.second.empty()) {
|
||||
log("Not mapping memory %s in module %s (attribute %s is set).\n",
|
||||
mem.memid.c_str(), module->name.c_str(), attr.first.c_str());
|
||||
mem.memid, module->name, attr.first);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -133,10 +137,10 @@ struct MemoryMapWorker
|
||||
if (!found) {
|
||||
if (cell_attr.flags & RTLIL::CONST_FLAG_STRING) {
|
||||
log("Not mapping memory %s in module %s (attribute %s is set to \"%s\").\n",
|
||||
mem.memid.c_str(), module->name.c_str(), attr.first.c_str(), cell_attr.decode_string().c_str());
|
||||
mem.memid, module->name, attr.first, cell_attr.decode_string().c_str());
|
||||
} else {
|
||||
log("Not mapping memory %s in module %s (attribute %s is set to %d).\n",
|
||||
mem.memid.c_str(), module->name.c_str(), attr.first.c_str(), cell_attr.as_int());
|
||||
mem.memid, module->name, attr.first, cell_attr.as_int());
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -170,24 +174,24 @@ struct MemoryMapWorker
|
||||
static_only = false;
|
||||
if (GetSize(refclock) != 0)
|
||||
log("Not mapping memory %s in module %s (mixed clocked and async write ports).\n",
|
||||
mem.memid.c_str(), module->name.c_str());
|
||||
mem.memid, module->name);
|
||||
if (!formal)
|
||||
log("Not mapping memory %s in module %s (write port %d has no clock).\n",
|
||||
mem.memid.c_str(), module->name.c_str(), i);
|
||||
mem.memid, module->name, i);
|
||||
async_wr = true;
|
||||
continue;
|
||||
}
|
||||
static_only = false;
|
||||
if (async_wr)
|
||||
log("Not mapping memory %s in module %s (mixed clocked and async write ports).\n",
|
||||
mem.memid.c_str(), module->name.c_str());
|
||||
mem.memid, module->name);
|
||||
if (refclock.size() == 0) {
|
||||
refclock = port.clk;
|
||||
refclock_pol = port.clk_polarity;
|
||||
}
|
||||
if (port.clk != refclock || port.clk_polarity != refclock_pol) {
|
||||
log("Not mapping memory %s in module %s (write clock %d is incompatible with other clocks).\n",
|
||||
mem.memid.c_str(), module->name.c_str(), i);
|
||||
mem.memid, module->name, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -244,16 +248,17 @@ struct MemoryMapWorker
|
||||
data_reg_in[idx] = w_in;
|
||||
c->setPort(ID::D, w_in);
|
||||
|
||||
std::string w_out_name = stringf("%s[%d]", mem.memid, addr);
|
||||
if (module->wires_.count(w_out_name) > 0)
|
||||
std::string w_out_name = stringf("%s[%d]", mem.memid.str(), addr);
|
||||
if (wire_names.count(w_out_name))
|
||||
w_out_name = genid(mem.memid, "", addr, "$q");
|
||||
|
||||
RTLIL::Wire *w_out = module->addWire(w_out_name, mem.width);
|
||||
wire_names.insert(w_out->name.str());
|
||||
|
||||
if (formal && mem.packed && mem.cell->name.c_str()[0] == '\\') {
|
||||
if (formal && mem.packed && mem.cell->name.isPublic()) {
|
||||
auto hdlname = mem.cell->get_hdlname_attribute();
|
||||
if (hdlname.empty())
|
||||
hdlname.push_back(mem.cell->name.c_str() + 1);
|
||||
hdlname.push_back(mem.cell->name.unescape());
|
||||
hdlname.push_back(stringf("[%d]", addr));
|
||||
w_out->set_hdlname_attribute(hdlname);
|
||||
}
|
||||
@@ -389,6 +394,9 @@ struct MemoryMapWorker
|
||||
|
||||
void run()
|
||||
{
|
||||
for (auto wire : module->wires())
|
||||
wire_names.insert(wire->name.str());
|
||||
|
||||
for (auto &mem : Mem::get_selected_memories(module))
|
||||
handle_memory(mem);
|
||||
}
|
||||
@@ -436,7 +444,7 @@ struct MemoryMapPass : public Pass {
|
||||
bool rom_only = false;
|
||||
bool keepdc = false;
|
||||
bool formal = false;
|
||||
dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes;
|
||||
dict<std::string, std::vector<RTLIL::Const>> attributes;
|
||||
|
||||
log_header(design, "Executing MEMORY_MAP pass (converting memories to logic and flip-flops).\n");
|
||||
|
||||
|
||||
@@ -200,9 +200,10 @@ ConflictLogs explore(CellAnalysis& analysis, CellTraversal& traversal, const Sig
|
||||
continue;
|
||||
auto bit = actx.assign_map(raw_bit);
|
||||
if (bit.wire == nullptr && clean_ctx.ct_all.cell_known(cell->type)) {
|
||||
const TwinePool &twines = cell->module->design->twines;
|
||||
std::string msg = stringf("Driver-driver conflict "
|
||||
"for %s between cell %s.%s and constant %s in %s: Resolved using constant.",
|
||||
log_signal(raw_bit), cell->name.unescape(), it2.first.unescape(), log_signal(bit), actx.mod->name.unescape());
|
||||
log_signal(raw_bit), cell->name.unescape(), twines.unescaped_str(it2.first), log_signal(bit), actx.mod->name.unescape());
|
||||
logs.logs.insert(ctx, {wire_map(raw_bit), msg});
|
||||
}
|
||||
if (bit.wire != nullptr)
|
||||
@@ -237,7 +238,7 @@ struct MemAnalysis {
|
||||
dict<std::string, int> indices;
|
||||
MemAnalysis(const RTLIL::Module* mod) : unused(mod->memories.size()), indices() {
|
||||
for (int i = 0; i < GetSize(mod->memories); ++i) {
|
||||
indices[mod->memories.element(i)->first.str()] = i;
|
||||
indices[mod->design->twines.str(mod->memories.element(i)->first)] = i;
|
||||
unused[i].store(true, std::memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
@@ -324,9 +325,9 @@ void remove_mems(RTLIL::Module* mod, const MemAnalysis& mem_analysis, bool verbo
|
||||
for (const auto &it : mem_analysis.indices) {
|
||||
if (!mem_analysis.unused[it.second].load(std::memory_order_relaxed))
|
||||
continue;
|
||||
RTLIL::IdString id(it.first);
|
||||
IdString id = mod->design->twines.add(it.first);
|
||||
if (verbose)
|
||||
log_debug(" removing unused memory `%s'.\n", id.unescape());
|
||||
log_debug(" removing unused memory `%s'.\n", mod->memories.at(id)->name.unescape());
|
||||
delete mod->memories.at(id);
|
||||
mod->memories.erase(id);
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ bool compare_signals(const RTLIL::SigBit &s1, const RTLIL::SigBit &s2, const Sha
|
||||
if (w1->port_output != w2->port_output)
|
||||
return w2->port_output;
|
||||
|
||||
if (w1->name[0] != w2->name[0])
|
||||
if (w1->name.isPublic() != w2->name.isPublic())
|
||||
return w2->name.isPublic();
|
||||
|
||||
int attrs1 = count_nontrivial_wire_attrs(w1);
|
||||
@@ -142,14 +142,14 @@ bool compare_signals(const RTLIL::SigBit &s1, const RTLIL::SigBit &s2, const Sha
|
||||
return w2->name.lt_by_name(w1->name);
|
||||
}
|
||||
|
||||
bool check_public_name(RTLIL::IdString id)
|
||||
bool check_public_name(RTLIL::Wire *wire)
|
||||
{
|
||||
if (id.begins_with("$"))
|
||||
if (!wire->name.isPublic())
|
||||
return false;
|
||||
const std::string &id_str = id.str();
|
||||
if (id.begins_with("\\_") && (id.ends_with("_") || id_str.find("_[") != std::string::npos))
|
||||
std::string name = wire->name.unescape();
|
||||
if (name[0] == '_' && (name.back() == '_' || name.find("_[") != std::string::npos))
|
||||
return false;
|
||||
if (id_str.find(".$") != std::string::npos)
|
||||
if (name.find(".$") != std::string::npos)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -415,7 +415,7 @@ struct WireDeleter {
|
||||
if (wire->port_id != 0 || wire->get_bool_attribute(ID::keep) || !initval.is_fully_undef()) {
|
||||
// do not delete anything with "keep" or module ports or initialized wires
|
||||
} else
|
||||
if (!purge_mode && check_public_name(wire->name) && (check_any(used_sig_analysis.raw_connected, s1) || check_any(used_sig_analysis.connected, s2) || s1 != s2)) {
|
||||
if (!purge_mode && check_public_name(wire) && (check_any(used_sig_analysis.raw_connected, s1) || check_any(used_sig_analysis.connected, s2) || s1 != s2)) {
|
||||
// do not get rid of public names unless in purge mode or if the wire is entirely unused, not even aliased
|
||||
} else
|
||||
if (!check_any(used_sig_analysis.raw_connected, s1)) {
|
||||
@@ -467,7 +467,7 @@ struct WireDeleter {
|
||||
int delete_wires(RTLIL::Module* mod, bool verbose) {
|
||||
int deleted_and_unreported = 0;
|
||||
for (auto wire : del_wires_queue) {
|
||||
if (ys_debug() || (check_public_name(wire->name) && verbose))
|
||||
if (ys_debug() || (check_public_name(wire) && verbose))
|
||||
log_debug(" removing unused non-port wire %s.\n", wire->name);
|
||||
else
|
||||
deleted_and_unreported++;
|
||||
|
||||
+26
-26
@@ -73,7 +73,7 @@ void replace_undriven(RTLIL::Module *module, const NewCellTypes &ct)
|
||||
{
|
||||
RTLIL::SigSpec sig = c;
|
||||
|
||||
if (c.wire->name[0] == '$')
|
||||
if (!c.wire->name.isPublic())
|
||||
sig = used_signals.extract(sig);
|
||||
if (sig.size() == 0)
|
||||
continue;
|
||||
@@ -124,8 +124,8 @@ void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell,
|
||||
out_val.extend_u0(Y.size(), false);
|
||||
|
||||
log_debug("Replacing %s cell `%s' (%s) in module `%s' with constant driver `%s = %s'.\n",
|
||||
cell->type.c_str(), cell->name.c_str(), info.c_str(),
|
||||
module->name.c_str(), log_signal(Y), log_signal(out_val));
|
||||
cell->type, cell->name, info,
|
||||
module->name, log_signal(Y), log_signal(out_val));
|
||||
// log_cell(cell);
|
||||
assign_map.add(Y, out_val);
|
||||
module->connect(Y, out_val);
|
||||
@@ -138,7 +138,7 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ
|
||||
IdString b_name = cell->hasPort(ID::B) ? ID::B : ID::A;
|
||||
|
||||
bool a_signed = cell->parameters.at(ID::A_SIGNED).as_bool();
|
||||
bool b_signed = cell->parameters.at(b_name.str() + "_SIGNED").as_bool();
|
||||
bool b_signed = cell->parameters.at(b_name == ID::B ? ID::B_SIGNED : ID::A_SIGNED).as_bool();
|
||||
|
||||
RTLIL::SigSpec sig_a = sigmap(cell->getPort(ID::A));
|
||||
RTLIL::SigSpec sig_b = sigmap(cell->getPort(b_name));
|
||||
@@ -308,7 +308,7 @@ void handle_polarity_inv(Cell *cell, IdString port, IdString param, const SigMap
|
||||
SigSpec sig = assign_map(cell->getPort(port));
|
||||
if (invert_map.count(sig)) {
|
||||
log_debug("Inverting %s of %s cell `%s' in module `%s': %s -> %s\n",
|
||||
port.unescape(), cell->type.unescape(), cell, cell->module,
|
||||
PooledName(cell->module, port).unescape(), cell->type.unescape(), cell, cell->module,
|
||||
log_signal(sig), log_signal(invert_map.at(sig)));
|
||||
cell->setPort(port, (invert_map.at(sig)));
|
||||
cell->setParam(param, !cell->getParam(param).as_bool());
|
||||
@@ -333,14 +333,14 @@ void handle_clkpol_celltype_swap(Cell *cell, string type1, string type2, IdStrin
|
||||
}
|
||||
}
|
||||
|
||||
if (cell->type.in(type1, type2)) {
|
||||
if (cell->type == type1 || cell->type == type2) {
|
||||
SigSpec sig = assign_map(cell->getPort(port));
|
||||
if (invert_map.count(sig)) {
|
||||
log_debug("Inverting %s of %s cell `%s' in module `%s': %s -> %s\n",
|
||||
port.unescape(), cell->type.unescape(), cell, cell->module,
|
||||
PooledName(cell->module, port).unescape(), cell->type.unescape(), cell, cell->module,
|
||||
log_signal(sig), log_signal(invert_map.at(sig)));
|
||||
cell->setPort(port, (invert_map.at(sig)));
|
||||
cell->type = cell->type == type1 ? type2 : type1;
|
||||
cell->type = cell->module->design->twines.add(cell->type == type1 ? type2 : type1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,7 +398,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||
dict<RTLIL::SigSpec, RTLIL::SigSpec> invert_map;
|
||||
|
||||
for (auto cell : module->cells()) {
|
||||
if (design->selected(module, cell) && cell->type[0] == '$') {
|
||||
if (design->selected(module, cell) && !cell->type.isPublic()) {
|
||||
if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) &&
|
||||
GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::Y)) == 1)
|
||||
invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::A));
|
||||
@@ -802,7 +802,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||
|
||||
if (GetSize(new_sig_a) < GetSize(sig_a)) {
|
||||
log_debug("Replacing port A of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n",
|
||||
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_sig_a));
|
||||
cell->type, cell->name, module->name, log_signal(sig_a), log_signal(new_sig_a));
|
||||
cell->setPort(ID::A, new_sig_a);
|
||||
cell->parameters.at(ID::A_WIDTH) = GetSize(new_sig_a);
|
||||
did_something = true;
|
||||
@@ -824,7 +824,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||
|
||||
if (GetSize(new_sig_b) < GetSize(sig_b)) {
|
||||
log_debug("Replacing port B of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n",
|
||||
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_sig_b));
|
||||
cell->type, cell->name, module->name, log_signal(sig_b), log_signal(new_sig_b));
|
||||
cell->setPort(ID::B, new_sig_b);
|
||||
cell->parameters.at(ID::B_WIDTH) = GetSize(new_sig_b);
|
||||
did_something = true;
|
||||
@@ -849,7 +849,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||
|
||||
if (new_a != RTLIL::State::Sm && RTLIL::SigSpec(new_a) != sig_a) {
|
||||
log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n",
|
||||
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a));
|
||||
cell->type, cell->name, module->name, log_signal(sig_a), log_signal(new_a));
|
||||
cell->setPort(ID::A, sig_a = new_a);
|
||||
cell->parameters.at(ID::A_WIDTH) = 1;
|
||||
did_something = true;
|
||||
@@ -874,7 +874,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||
|
||||
if (new_a != RTLIL::State::Sm && RTLIL::SigSpec(new_a) != sig_a) {
|
||||
log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n",
|
||||
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a));
|
||||
cell->type, cell->name, module->name, log_signal(sig_a), log_signal(new_a));
|
||||
cell->setPort(ID::A, sig_a = new_a);
|
||||
cell->parameters.at(ID::A_WIDTH) = 1;
|
||||
did_something = true;
|
||||
@@ -899,7 +899,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||
|
||||
if (new_b != RTLIL::State::Sm && RTLIL::SigSpec(new_b) != sig_b) {
|
||||
log_debug("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n",
|
||||
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b));
|
||||
cell->type, cell->name, module->name, log_signal(sig_b), log_signal(new_b));
|
||||
cell->setPort(ID::B, sig_b = new_b);
|
||||
cell->parameters.at(ID::B_WIDTH) = 1;
|
||||
did_something = true;
|
||||
@@ -1171,7 +1171,7 @@ skip_fine_alu:
|
||||
ACTION_DO(ID::Y, cell->getPort(ID::A));
|
||||
if (input == State::S0 && !a.is_fully_undef()) {
|
||||
log_debug("Replacing data input of %s cell `%s' in module `%s' with constant undef.\n",
|
||||
cell->type.c_str(), cell->name.c_str(), module->name.c_str());
|
||||
cell->type, cell->name, module->name);
|
||||
cell->setPort(ID::A, SigSpec(State::Sx, GetSize(a)));
|
||||
did_something = true;
|
||||
goto next_cell;
|
||||
@@ -1375,7 +1375,7 @@ skip_fine_alu:
|
||||
if (identity_wrt_a || identity_wrt_b)
|
||||
{
|
||||
log_debug("Replacing %s cell `%s' in module `%s' with identity for port %c.\n",
|
||||
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B');
|
||||
cell->type, cell->name, module->name, identity_wrt_a ? 'A' : 'B');
|
||||
|
||||
if (cell->type == ID($alu)) {
|
||||
bool a_signed = cell->parameters[ID::A_SIGNED].as_bool();
|
||||
@@ -1672,14 +1672,14 @@ skip_identity:
|
||||
// 2^B = 1<<B
|
||||
if (bit_idx == 1) {
|
||||
log_debug("Replacing pow cell `%s' in module `%s' with left-shift\n",
|
||||
cell->name.c_str(), module->name.c_str());
|
||||
cell->name, module->name);
|
||||
cell->type = ID($shl);
|
||||
cell->parameters[ID::A_WIDTH] = 1;
|
||||
cell->setPort(ID::A, Const(State::S1, 1));
|
||||
}
|
||||
else {
|
||||
log_debug("Replacing pow cell `%s' in module `%s' with multiply and left-shift\n",
|
||||
cell->name.c_str(), module->name.c_str());
|
||||
cell->name, module->name);
|
||||
cell->type = ID($mul);
|
||||
cell->setPort(ID::A, Const(bit_idx, cell->parameters[ID::A_WIDTH].as_int()));
|
||||
|
||||
@@ -1710,7 +1710,7 @@ skip_identity:
|
||||
if (sig_a.is_fully_zero())
|
||||
{
|
||||
log_debug("Replacing multiply-by-zero cell `%s' in module `%s' with zero-driver.\n",
|
||||
cell->name.c_str(), module->name.c_str());
|
||||
cell->name, module->name);
|
||||
|
||||
module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
|
||||
module->remove(cell);
|
||||
@@ -1723,7 +1723,7 @@ skip_identity:
|
||||
if (sig_a.is_onehot(&exp) && !(a_signed && exp == GetSize(sig_a) - 1))
|
||||
{
|
||||
log_debug("Replacing multiply-by-%s cell `%s' in module `%s' with shift-by-%d.\n",
|
||||
log_signal(sig_a), cell->name.c_str(), module->name.c_str(), exp);
|
||||
log_signal(sig_a), cell->name, module->name, exp);
|
||||
|
||||
if (!swapped_ab) {
|
||||
cell->setPort(ID::A, cell->getPort(ID::B));
|
||||
@@ -1756,7 +1756,7 @@ skip_identity:
|
||||
if (a_zeros || b_zeros) {
|
||||
int y_zeros = a_zeros + b_zeros;
|
||||
log_debug("Removing low %d A and %d B bits from cell `%s' in module `%s'.\n",
|
||||
a_zeros, b_zeros, cell->name.c_str(), module->name.c_str());
|
||||
a_zeros, b_zeros, cell->name, module->name);
|
||||
|
||||
if (y_zeros >= GetSize(sig_y)) {
|
||||
module->connect(sig_y, RTLIL::SigSpec(0, GetSize(sig_y)));
|
||||
@@ -1797,7 +1797,7 @@ skip_identity:
|
||||
if (sig_b.is_fully_zero())
|
||||
{
|
||||
log_debug("Replacing divide-by-zero cell `%s' in module `%s' with undef-driver.\n",
|
||||
cell->name.c_str(), module->name.c_str());
|
||||
cell->name, module->name);
|
||||
|
||||
module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(State::Sx, sig_y.size())));
|
||||
module->remove(cell);
|
||||
@@ -1814,7 +1814,7 @@ skip_identity:
|
||||
bool is_truncating = cell->type == ID($div);
|
||||
log_debug("Replacing %s-divide-by-%s cell `%s' in module `%s' with shift-by-%d.\n",
|
||||
is_truncating ? "truncating" : "flooring",
|
||||
log_signal(sig_b), cell->name.c_str(), module->name.c_str(), exp);
|
||||
log_signal(sig_b), cell->name, module->name, exp);
|
||||
|
||||
Const new_b = exp;
|
||||
|
||||
@@ -1842,7 +1842,7 @@ skip_identity:
|
||||
bool is_truncating = cell->type == ID($mod);
|
||||
log_debug("Replacing %s-modulo-by-%s cell `%s' in module `%s' with bitmask.\n",
|
||||
is_truncating ? "truncating" : "flooring",
|
||||
log_signal(sig_b), cell->name.c_str(), module->name.c_str());
|
||||
log_signal(sig_b), cell->name, module->name);
|
||||
|
||||
// truncating modulo has the same masked bits as flooring modulo, but
|
||||
// the sign bits are those of A (except when R=0)
|
||||
@@ -1924,7 +1924,7 @@ skip_identity:
|
||||
|
||||
for (auto &p : split_points)
|
||||
log_debug("Splitting $alu cell `%s' in module `%s' at const-carry point %d.\n",
|
||||
cell->name.c_str(), module->name.c_str(), p.first);
|
||||
cell->name, module->name, p.first);
|
||||
|
||||
if (split_points.back().first != GetSize(sig_y))
|
||||
split_points.push_back(std::make_pair(GetSize(sig_y), State::Sx));
|
||||
@@ -2010,7 +2010,7 @@ skip_alu_split:
|
||||
sig_y.append(RTLIL::SigSpec(State::S0, y_width - k));
|
||||
|
||||
log_debug("Replacing `(2^%d-1) - B` $sub cell `%s' in module `%s' with $not.\n",
|
||||
k, cell->name.c_str(), module->name.c_str());
|
||||
k, cell->name, module->name);
|
||||
module->connect(cell->getPort(ID::Y), sig_y);
|
||||
module->remove(cell);
|
||||
did_something = true;
|
||||
|
||||
@@ -59,7 +59,7 @@ struct ExtSigSpec {
|
||||
|
||||
ExtSigSpec() {}
|
||||
|
||||
ExtSigSpec(RTLIL::SigSpec s, RTLIL::SigSpec sign = RTLIL::Const(0, 1), bool is_signed = false, RTLIL::IdString semantics = RTLIL::IdString()) : sig(s), sign(sign), is_signed(is_signed), semantics(semantics) {}
|
||||
ExtSigSpec(RTLIL::SigSpec s, RTLIL::SigSpec sign = RTLIL::Const(0, 1), bool is_signed = false, RTLIL::IdString semantics = RTLIL::IdString::Null) : sig(s), sign(sign), is_signed(is_signed), semantics(semantics) {}
|
||||
|
||||
bool empty() const { return sig.empty(); }
|
||||
|
||||
@@ -115,11 +115,11 @@ bool mergeable(RTLIL::Cell *a, RTLIL::Cell *b)
|
||||
if (mergeable_type_map.empty()) {
|
||||
mergeable_type_map.insert({ID($sub), ID($add)});
|
||||
}
|
||||
auto a_type = a->type;
|
||||
IdString a_type = a->type;
|
||||
if (mergeable_type_map.count(a_type))
|
||||
a_type = mergeable_type_map.at(a_type);
|
||||
|
||||
auto b_type = b->type;
|
||||
IdString b_type = b->type;
|
||||
if (mergeable_type_map.count(b_type))
|
||||
b_type = mergeable_type_map.at(b_type);
|
||||
|
||||
@@ -134,7 +134,7 @@ RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_na
|
||||
if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_)))
|
||||
return port_name;
|
||||
|
||||
return "";
|
||||
return RTLIL::IdString::Null;
|
||||
}
|
||||
|
||||
RTLIL::SigSpec decode_port_sign(RTLIL::Cell *cell, RTLIL::IdString port_name) {
|
||||
@@ -152,8 +152,9 @@ bool decode_port_signed(RTLIL::Cell *cell, RTLIL::IdString port_name)
|
||||
if (cell->type.in(BITWISE_OPS, LOGICAL_OPS))
|
||||
return false;
|
||||
|
||||
if (cell->hasParam(port_name.str() + "_SIGNED"))
|
||||
return cell->getParam(port_name.str() + "_SIGNED").as_bool();
|
||||
RTLIL::IdString param_name = port_name == ID::A ? ID::A_SIGNED : ID::B_SIGNED;
|
||||
if (cell->hasParam(param_name))
|
||||
return cell->getParam(param_name).as_bool();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
+11
-6
@@ -234,8 +234,9 @@ struct WreduceWorker
|
||||
|
||||
void run_reduce_inport(Cell *cell, char port, int max_port_size, bool &port_signed, bool &did_something)
|
||||
{
|
||||
port_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool();
|
||||
SigSpec sig = mi.sigmap(cell->getPort(stringf("\\%c", port)));
|
||||
IdString port_name = port == 'A' ? ID::A : ID::B;
|
||||
port_signed = cell->getParam(port == 'A' ? ID::A_SIGNED : ID::B_SIGNED).as_bool();
|
||||
SigSpec sig = mi.sigmap(cell->getPort(port_name));
|
||||
|
||||
if (port == 'B' && cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr)))
|
||||
port_signed = false;
|
||||
@@ -259,7 +260,7 @@ struct WreduceWorker
|
||||
if (bits_removed) {
|
||||
log("Removed top %d bits (of %d) from port %c of cell %s.%s (%s).\n",
|
||||
bits_removed, GetSize(sig) + bits_removed, port, module, cell, cell->type.unescape());
|
||||
cell->setPort(stringf("\\%c", port), sig);
|
||||
cell->setPort(port_name, sig);
|
||||
did_something = true;
|
||||
}
|
||||
}
|
||||
@@ -575,6 +576,10 @@ struct WreducePass : public Pass {
|
||||
if (module->has_processes_warn())
|
||||
continue;
|
||||
|
||||
dict<std::string, RTLIL::Memory*> memory_by_name;
|
||||
for (auto &it : module->memories)
|
||||
memory_by_name[design->twines.str(it.first)] = it.second;
|
||||
|
||||
for (auto c : module->selected_cells())
|
||||
{
|
||||
if (c->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
|
||||
@@ -625,8 +630,8 @@ struct WreducePass : public Pass {
|
||||
}
|
||||
|
||||
if (!opt_memx && c->type.in(ID($memrd), ID($memrd_v2), ID($memwr), ID($memwr_v2), ID($meminit), ID($meminit_v2))) {
|
||||
IdString memid = c->getParam(ID::MEMID).decode_string();
|
||||
RTLIL::Memory *mem = module->memories.at(memid);
|
||||
std::string memid = c->getParam(ID::MEMID).decode_string();
|
||||
RTLIL::Memory *mem = memory_by_name.at(memid);
|
||||
if (mem->start_offset >= 0) {
|
||||
int cur_addrbits = c->getParam(ID::ABITS).as_int();
|
||||
int max_addrbits = ceil_log2(mem->start_offset + mem->size);
|
||||
@@ -634,7 +639,7 @@ struct WreducePass : public Pass {
|
||||
log("Removed top %d address bits (of %d) from memory %s port %s.%s (%s).\n",
|
||||
cur_addrbits-max_addrbits, cur_addrbits,
|
||||
c->type == ID($memrd) ? "read" : c->type == ID($memwr) ? "write" : "init",
|
||||
module, c, memid.unescape());
|
||||
module, c, mem->name.unescape());
|
||||
c->setParam(ID::ABITS, max_addrbits);
|
||||
c->setPort(ID::ADDR, c->getPort(ID::ADDR).extract(0, max_addrbits));
|
||||
}
|
||||
|
||||
@@ -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), memwr.memid.unescape());
|
||||
log_signal(sync->signal), PooledName(mod, memwr.memid).unescape());
|
||||
}
|
||||
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);
|
||||
@@ -288,11 +288,14 @@ struct ProcArstPass : public Pass {
|
||||
extra_args(args, argidx, design);
|
||||
pool<Wire*> delete_initattr_wires;
|
||||
|
||||
IdString global_arst_ref = global_arst.empty() ? IdString::Null
|
||||
: design->twines.find(global_arst);
|
||||
|
||||
for (auto mod : design->all_selected_modules()) {
|
||||
SigMap assign_map(mod);
|
||||
for (auto proc : mod->selected_processes()) {
|
||||
proc_arst(mod, proc, assign_map);
|
||||
if (global_arst.empty() || mod->wire(global_arst) == nullptr)
|
||||
if (global_arst_ref == IdString::Null || mod->wire(global_arst_ref) == nullptr)
|
||||
continue;
|
||||
std::vector<RTLIL::SigSig> arst_actions;
|
||||
for (auto sync : proc->syncs)
|
||||
@@ -309,14 +312,14 @@ struct ProcArstPass : public Pass {
|
||||
}
|
||||
if (arst_sig.size()) {
|
||||
log("Added global reset to process %s: %s <- %s\n",
|
||||
proc->name.c_str(), log_signal(arst_sig), log_signal(arst_val));
|
||||
proc->name, log_signal(arst_sig), log_signal(arst_val));
|
||||
arst_actions.push_back(RTLIL::SigSig(arst_sig, arst_val));
|
||||
}
|
||||
}
|
||||
if (!arst_actions.empty()) {
|
||||
RTLIL::SyncRule *sync = new RTLIL::SyncRule;
|
||||
sync->type = global_arst_neg ? RTLIL::SyncType::ST0 : RTLIL::SyncType::ST1;
|
||||
sync->signal = mod->wire(global_arst);
|
||||
sync->signal = mod->wire(global_arst_ref);
|
||||
sync->actions = arst_actions;
|
||||
proc->syncs.push_back(sync);
|
||||
}
|
||||
|
||||
@@ -29,13 +29,14 @@
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
void proc_memwr(RTLIL::Module *mod, RTLIL::Process *proc, dict<IdString, int> &next_port_id)
|
||||
void proc_memwr(RTLIL::Module *mod, RTLIL::Process *proc, dict<std::string, int> &next_port_id)
|
||||
{
|
||||
for (auto sr : proc->syncs)
|
||||
{
|
||||
std::vector<int> prev_port_ids;
|
||||
for (auto memwr : sr->mem_write_actions) {
|
||||
int port_id = next_port_id[memwr.memid]++;
|
||||
std::string memid = mod->design->twines.str(memwr.memid);
|
||||
int port_id = next_port_id[memid]++;
|
||||
Const priority_mask(State::S0, port_id);
|
||||
for (int i = 0; i < GetSize(prev_port_ids); i++)
|
||||
if (memwr.priority_mask[i] == State::S1)
|
||||
@@ -44,7 +45,7 @@ void proc_memwr(RTLIL::Module *mod, RTLIL::Process *proc, dict<IdString, int> &n
|
||||
|
||||
RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($memwr_v2));
|
||||
cell->attributes = memwr.attributes;
|
||||
cell->setParam(ID::MEMID, Const(memwr.memid.str()));
|
||||
cell->setParam(ID::MEMID, Const(memid));
|
||||
cell->setParam(ID::ABITS, GetSize(memwr.address));
|
||||
cell->setParam(ID::WIDTH, GetSize(memwr.data));
|
||||
cell->setParam(ID::PORTID, port_id);
|
||||
@@ -100,11 +101,11 @@ struct ProcMemWrPass : public Pass {
|
||||
extra_args(args, 1, design);
|
||||
|
||||
for (auto mod : design->all_selected_modules()) {
|
||||
dict<IdString, int> next_port_id;
|
||||
dict<std::string, int> next_port_id;
|
||||
for (auto cell : mod->cells()) {
|
||||
if (cell->type.in(ID($memwr), ID($memwr_v2))) {
|
||||
bool is_compat = cell->type == ID($memwr);
|
||||
IdString memid = cell->parameters.at(ID::MEMID).decode_string();
|
||||
std::string memid = cell->parameters.at(ID::MEMID).decode_string();
|
||||
int port_id = cell->parameters.at(is_compat ? ID::PRIORITY : ID::PORTID).as_int();
|
||||
if (port_id >= next_port_id[memid])
|
||||
next_port_id[memid] = port_id + 1;
|
||||
|
||||
+14
-13
@@ -71,16 +71,16 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
|
||||
if (argidx+3 != args.size() || args[argidx].compare(0, 1, "-") == 0)
|
||||
that->cmd_error(args, argidx, "command argument error");
|
||||
|
||||
RTLIL::IdString gold_name = RTLIL::escape_id(args[argidx++]);
|
||||
RTLIL::IdString gate_name = RTLIL::escape_id(args[argidx++]);
|
||||
RTLIL::IdString miter_name = RTLIL::escape_id(args[argidx++]);
|
||||
IdString gold_name = design->twines.add(RTLIL::escape_id(args[argidx++]));
|
||||
IdString gate_name = design->twines.add(RTLIL::escape_id(args[argidx++]));
|
||||
IdString miter_name = design->twines.add(RTLIL::escape_id(args[argidx++]));
|
||||
|
||||
if (design->module(gold_name) == nullptr)
|
||||
log_cmd_error("Can't find gold module %s!\n", gold_name);
|
||||
log_cmd_error("Can't find gold module %s!\n", design->twines.str(gold_name));
|
||||
if (design->module(gate_name) == nullptr)
|
||||
log_cmd_error("Can't find gate module %s!\n", gate_name);
|
||||
log_cmd_error("Can't find gate module %s!\n", design->twines.str(gate_name));
|
||||
if (design->module(miter_name) != nullptr)
|
||||
log_cmd_error("There is already a module %s!\n", miter_name);
|
||||
log_cmd_error("There is already a module %s!\n", design->twines.str(miter_name));
|
||||
|
||||
RTLIL::Module *gold_module = design->module(gold_name);
|
||||
RTLIL::Module *gate_module = design->module(gate_name);
|
||||
@@ -128,14 +128,15 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
|
||||
log_cmd_error("No matching port in gold module was found for %s!\n", gate_wire->name);
|
||||
}
|
||||
|
||||
log("Creating miter cell \"%s\" with gold cell \"%s\" and gate cell \"%s\".\n", miter_name.unescape(), gold_name.unescape(), gate_name.unescape());
|
||||
log("Creating miter cell \"%s\" with gold cell \"%s\" and gate cell \"%s\".\n", PooledName(design, miter_name).unescape(), PooledName(design, gold_name).unescape(), PooledName(design, gate_name).unescape());
|
||||
|
||||
RTLIL::Module *miter_module = new RTLIL::Module;
|
||||
miter_module->design = design;
|
||||
miter_module->name = miter_name;
|
||||
design->add(miter_module);
|
||||
|
||||
RTLIL::Cell *gold_cell = miter_module->addCell(ID(gold), gold_name);
|
||||
RTLIL::Cell *gate_cell = miter_module->addCell(ID(gate), gate_name);
|
||||
RTLIL::Cell *gold_cell = miter_module->addCell(ID::gold, gold_module->name);
|
||||
RTLIL::Cell *gate_cell = miter_module->addCell(ID::gate, gate_module->name);
|
||||
|
||||
RTLIL::SigSpec all_conditions;
|
||||
|
||||
@@ -318,13 +319,13 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL
|
||||
if ((argidx+1 != args.size() && argidx+2 != args.size()) || args[argidx].compare(0, 1, "-") == 0)
|
||||
that->cmd_error(args, argidx, "command argument error");
|
||||
|
||||
IdString module_name = RTLIL::escape_id(args[argidx++]);
|
||||
IdString miter_name = argidx < args.size() ? RTLIL::escape_id(args[argidx++]) : "";
|
||||
IdString module_name = design->twines.add(RTLIL::escape_id(args[argidx++]));
|
||||
IdString miter_name = argidx < args.size() ? design->twines.add(RTLIL::escape_id(args[argidx++])) : IdString::Null;
|
||||
|
||||
if (design->module(module_name) == nullptr)
|
||||
log_cmd_error("Can't find module %s!\n", module_name);
|
||||
log_cmd_error("Can't find module %s!\n", design->twines.str(module_name));
|
||||
if (!miter_name.empty() && design->module(miter_name) != nullptr)
|
||||
log_cmd_error("There is already a module %s!\n", miter_name);
|
||||
log_cmd_error("There is already a module %s!\n", design->twines.str(miter_name));
|
||||
|
||||
Module *module = design->module(module_name);
|
||||
|
||||
|
||||
+25
-23
@@ -47,11 +47,11 @@ pool<std::string> validate_design_and_get_inputs(RTLIL::Module *module, bool ass
|
||||
found_1bit_output = true;
|
||||
}
|
||||
for (auto cell : module->cells()) {
|
||||
if (cell->type == "$allconst")
|
||||
if (cell->type == ID($allconst))
|
||||
found_input = true;
|
||||
if (cell->type == "$anyconst")
|
||||
if (cell->type == ID($anyconst))
|
||||
found_hole = true;
|
||||
if (cell->type.in("$assert", "$assume"))
|
||||
if (cell->type.in(ID($assert), ID($assume)))
|
||||
found_assert_assume = true;
|
||||
}
|
||||
if (!found_input)
|
||||
@@ -82,6 +82,7 @@ void specialize_from_file(RTLIL::Module *module, const std::string &file) {
|
||||
log_cmd_error("could not read solution file.\n");
|
||||
|
||||
std::string buf;
|
||||
TwineSearch search(&module->design->twines);
|
||||
while (std::getline(fin, buf)) {
|
||||
bool bit_assn = true;
|
||||
if (!std::regex_search(buf, bit_m, hole_bit_assn_regex)) {
|
||||
@@ -100,8 +101,8 @@ void specialize_from_file(RTLIL::Module *module, const std::string &file) {
|
||||
//We have two options to identify holes. First, try to match wire names. If we can't find a matching wire,
|
||||
//then try to find a cell with a matching location.
|
||||
RTLIL::SigBit hole_sigbit;
|
||||
if (module->wire(hole_name) != nullptr) {
|
||||
RTLIL::Wire *hole_wire = module->wire(hole_name);
|
||||
if (module->wire(search.find(hole_name)) != nullptr) {
|
||||
RTLIL::Wire *hole_wire = module->wire(search.find(hole_name));
|
||||
hole_sigbit = RTLIL::SigSpec(hole_wire)[hole_offset];
|
||||
} else {
|
||||
auto locs = split_tokens(hole_loc, "|");
|
||||
@@ -159,11 +160,12 @@ void specialize(RTLIL::Module *module, const QbfSolutionType &sol, bool quiet =
|
||||
}
|
||||
|
||||
void allconstify_inputs(RTLIL::Module *module, const pool<std::string> &input_wires) {
|
||||
TwineSearch search(&module->design->twines);
|
||||
for (auto &n : input_wires) {
|
||||
RTLIL::Wire *input = module->wire(n);
|
||||
RTLIL::Wire *input = module->wire(search.find(n));
|
||||
log_assert(input != nullptr);
|
||||
|
||||
RTLIL::Cell *allconst = module->addCell("$allconst$" + n, "$allconst");
|
||||
RTLIL::Cell *allconst = module->addCell("$allconst$" + n, ID($allconst));
|
||||
allconst->setParam(ID(WIDTH), input->width);
|
||||
allconst->setPort(ID::Y, input);
|
||||
allconst->set_src_attribute(input->get_src_attribute());
|
||||
@@ -255,8 +257,8 @@ QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) {
|
||||
const std::string tempdir_name = make_temp_dir(get_base_tmpdir() + "/yosys-qbfsat-XXXXXX");
|
||||
RTLIL::Module *module = mod;
|
||||
RTLIL::Design *design = module->design;
|
||||
std::string module_name = module->name.str();
|
||||
RTLIL::IdString wire_to_optimize_name = "";
|
||||
IdString module_name = module->name;
|
||||
IdString wire_to_optimize_name = IdString::Null;
|
||||
bool maximize = false;
|
||||
log_assert(module->design != nullptr);
|
||||
|
||||
@@ -270,14 +272,14 @@ QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) {
|
||||
|
||||
//Find the wire to be optimized, if any:
|
||||
for (auto wire : module->wires()) {
|
||||
if (wire->get_bool_attribute("\\maximize") || wire->get_bool_attribute("\\minimize")) {
|
||||
if (wire->get_bool_attribute(ID::maximize) || wire->get_bool_attribute(ID::minimize)) {
|
||||
wire_to_optimize_name = wire->name;
|
||||
maximize = wire->get_bool_attribute("\\maximize");
|
||||
maximize = wire->get_bool_attribute(ID::maximize);
|
||||
if (opt.nooptimize) {
|
||||
if (maximize)
|
||||
wire->set_bool_attribute("\\maximize", false);
|
||||
wire->set_bool_attribute(ID::maximize, false);
|
||||
else
|
||||
wire->set_bool_attribute("\\minimize", false);
|
||||
wire->set_bool_attribute(ID::minimize, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -292,7 +294,7 @@ QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) {
|
||||
Pass::call(module->design, "opt");
|
||||
}
|
||||
|
||||
if (opt.nobisection || opt.nooptimize || wire_to_optimize_name == "") {
|
||||
if (opt.nobisection || opt.nooptimize || wire_to_optimize_name == IdString::Null) {
|
||||
ret = call_qbf_solver(module, opt, tempdir_name, false, 0);
|
||||
} else {
|
||||
//Do the iterated bisection method:
|
||||
@@ -301,9 +303,9 @@ QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) {
|
||||
unsigned int failure = 0;
|
||||
unsigned int cur_thresh = 0;
|
||||
|
||||
log_assert(wire_to_optimize_name != "");
|
||||
log_assert(wire_to_optimize_name != IdString::Null);
|
||||
log_assert(module->wire(wire_to_optimize_name) != nullptr);
|
||||
log("%s wire \"%s\".\n", (maximize? "Maximizing" : "Minimizing"), wire_to_optimize_name);
|
||||
log("%s wire \"%s\".\n", (maximize? "Maximizing" : "Minimizing"), design->twines.str(wire_to_optimize_name));
|
||||
|
||||
//If maximizing, grow until we get a failure. Then bisect success and failure.
|
||||
while (failure == 0 || difference(success, failure) > 1) {
|
||||
@@ -315,8 +317,8 @@ QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) {
|
||||
RTLIL::SigSpec comparator = maximize? module->Ge(NEW_ID, module->wire(wire_to_optimize_name), RTLIL::Const(cur_thresh), false)
|
||||
: module->Le(NEW_ID, module->wire(wire_to_optimize_name), RTLIL::Const(cur_thresh), false);
|
||||
|
||||
module->addAssume(wire_to_optimize_name.str() + "__threshold", comparator, RTLIL::Const(1, 1));
|
||||
log("Trying to solve with %s %s %d.\n", wire_to_optimize_name, (maximize? ">=" : "<="), cur_thresh);
|
||||
module->addAssume(design->twines.str(wire_to_optimize_name) + "__threshold", comparator, RTLIL::Const(1, 1));
|
||||
log("Trying to solve with %s %s %d.\n", design->twines.str(wire_to_optimize_name), (maximize? ">=" : "<="), cur_thresh);
|
||||
}
|
||||
|
||||
ret = call_qbf_solver(module, opt, tempdir_name, false, iter_num);
|
||||
@@ -328,7 +330,7 @@ QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) {
|
||||
specialize(module, ret, true);
|
||||
|
||||
RTLIL::SigSpec wire, value, undef;
|
||||
RTLIL::SigSpec::parse_sel(wire, design, module, wire_to_optimize_name.str());
|
||||
RTLIL::SigSpec::parse_sel(wire, design, module, design->twines.str(wire_to_optimize_name));
|
||||
|
||||
ConstEval ce(module);
|
||||
value = wire;
|
||||
@@ -337,7 +339,7 @@ QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) {
|
||||
log_assert(value.is_fully_const());
|
||||
success = value.as_const().as_int();
|
||||
best_soln = ret;
|
||||
log("Problem is satisfiable with %s = %d.\n", wire_to_optimize_name, success);
|
||||
log("Problem is satisfiable with %s = %d.\n", design->twines.str(wire_to_optimize_name), success);
|
||||
Pass::call(design, "design -pop");
|
||||
module = design->module(module_name);
|
||||
|
||||
@@ -355,7 +357,7 @@ QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) {
|
||||
break;
|
||||
}
|
||||
else
|
||||
log("Problem is NOT satisfiable with %s %s %d.\n", wire_to_optimize_name, (maximize? ">=" : "<="), failure);
|
||||
log("Problem is NOT satisfiable with %s %s %d.\n", design->twines.str(wire_to_optimize_name), (maximize? ">=" : "<="), failure);
|
||||
}
|
||||
|
||||
iter_num++;
|
||||
@@ -367,7 +369,7 @@ QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) {
|
||||
cur_thresh = (success + failure) / 2; //bisection
|
||||
}
|
||||
if (success != 0 || failure != 0) {
|
||||
log("Wire %s is %s at %d.\n", wire_to_optimize_name, (maximize? "maximized" : "minimized"), success);
|
||||
log("Wire %s is %s at %d.\n", design->twines.str(wire_to_optimize_name), (maximize? "maximized" : "minimized"), success);
|
||||
ret = best_soln;
|
||||
}
|
||||
}
|
||||
@@ -606,7 +608,7 @@ struct QbfSatPass : public Pass {
|
||||
log_push();
|
||||
if (!opt.specialize_from_file) {
|
||||
//Save the design to restore after modiyfing the current module.
|
||||
std::string module_name = module->name.str();
|
||||
IdString module_name = module->name;
|
||||
|
||||
QbfSolutionType ret = qbf_solve(module, opt);
|
||||
module = design->module(module_name);
|
||||
|
||||
+77
-61
@@ -277,7 +277,7 @@ struct SimInstance
|
||||
}
|
||||
}
|
||||
|
||||
if ((shared->fst) && !(shared->hide_internal && wire->name[0] == '$')) {
|
||||
if ((shared->fst) && !(shared->hide_internal && !wire->name.isPublic())) {
|
||||
fstHandle id = shared->fst->getHandle(scope + "." + wire->name.unescape());
|
||||
if (id==0 && wire->name.isPublic())
|
||||
log_warning("Unable to find wire %s in input file.\n", (scope + "." + wire->name.unescape()));
|
||||
@@ -302,8 +302,10 @@ struct SimInstance
|
||||
}
|
||||
|
||||
memories = Mem::get_all_memories(module);
|
||||
dict<std::string, IdString> memid_by_name;
|
||||
for (auto &mem : memories) {
|
||||
auto &mdb = mem_database[mem.memid];
|
||||
memid_by_name[mem.memid.unescape()] = mem.memid;
|
||||
mdb.mem = &mem;
|
||||
for (auto &port : mem.wr_ports) {
|
||||
mdb.past_wr_clk.push_back(Const(State::Sx));
|
||||
@@ -351,10 +353,13 @@ struct SimInstance
|
||||
|
||||
if (cell->is_mem_cell())
|
||||
{
|
||||
std::string name = cell->parameters.at(ID::MEMID).decode_string();
|
||||
std::string name_str = cell->parameters.at(ID::MEMID).decode_string();
|
||||
auto mit = memid_by_name.find(RTLIL::unescape_id(name_str));
|
||||
IdString name = mit != memid_by_name.end() ? mit->second
|
||||
: module->design->twines.add(std::string(name_str));
|
||||
mem_cells[cell] = name;
|
||||
if (shared->fst)
|
||||
fst_memories[name] = shared->fst->getMemoryHandles(scope + "." + RTLIL::unescape_id(name));
|
||||
fst_memories[name] = shared->fst->getMemoryHandles(scope + "." + RTLIL::unescape_id(name_str));
|
||||
}
|
||||
|
||||
if (cell->type.in(ID($assert), ID($cover), ID($assume)))
|
||||
@@ -523,7 +528,7 @@ struct SimInstance
|
||||
{
|
||||
auto &state = mem_database[memid];
|
||||
if (offset >= state.mem->size * state.mem->width)
|
||||
log_error("Addressing out of bounds bit %d/%d of memory %s\n", offset, state.mem->size * state.mem->width, memid.unescape());
|
||||
log_error("Addressing out of bounds bit %d/%d of memory %s\n", offset, state.mem->size * state.mem->width, PooledName(state.mem->module, memid).unescape());
|
||||
if (state.data[offset] != data) {
|
||||
state.data.set(offset, data);
|
||||
dirty_memories.insert(memid);
|
||||
@@ -1016,7 +1021,7 @@ struct SimInstance
|
||||
{
|
||||
for (auto wire : module->wires())
|
||||
{
|
||||
if (shared->hide_internal && wire->name[0] == '$')
|
||||
if (shared->hide_internal && !wire->name.isPublic())
|
||||
continue;
|
||||
|
||||
signal_database[wire] = {id, Const(), sigmap(wire)};
|
||||
@@ -1027,17 +1032,17 @@ struct SimInstance
|
||||
child.second->register_signals(id);
|
||||
}
|
||||
|
||||
void write_output_header(std::function<void(IdString)> enter_scope, std::function<void()> exit_scope, std::function<void(const char*, int, Wire*, int, bool)> register_signal)
|
||||
void write_output_header(std::function<void(const std::string&)> enter_scope, std::function<void()> exit_scope, std::function<void(const char*, int, Wire*, int, bool)> register_signal)
|
||||
{
|
||||
int exit_scopes = 1;
|
||||
if (shared->hdlname && instance != nullptr && instance->name.isPublic() && instance->has_attribute(ID::hdlname)) {
|
||||
auto hdlname = instance->get_hdlname_attribute();
|
||||
log_assert(!hdlname.empty());
|
||||
for (auto name : hdlname)
|
||||
enter_scope("\\" + name);
|
||||
enter_scope(name);
|
||||
exit_scopes = hdlname.size();
|
||||
} else
|
||||
enter_scope(name());
|
||||
enter_scope(module->design->twines.unescaped_str(name()));
|
||||
|
||||
dict<Wire*,bool> registers;
|
||||
for (auto cell : module->cells())
|
||||
@@ -1059,7 +1064,7 @@ struct SimInstance
|
||||
auto signal_name = std::move(hdlname.back());
|
||||
hdlname.pop_back();
|
||||
for (auto name : hdlname)
|
||||
enter_scope("\\" + name);
|
||||
enter_scope(name);
|
||||
register_signal(signal_name.c_str(), GetSize(signal.first), signal.first, signal.second.id, registers.count(signal.first)!=0);
|
||||
for (auto name : hdlname)
|
||||
exit_scope();
|
||||
@@ -1083,9 +1088,9 @@ struct SimInstance
|
||||
signal_name = std::move(hdlname.back());
|
||||
hdlname.pop_back();
|
||||
for (auto name : hdlname)
|
||||
enter_scope("\\" + name);
|
||||
enter_scope(name);
|
||||
} else {
|
||||
signal_name = memid.unescape();
|
||||
signal_name = module->design->twines.unescaped_str(memid);
|
||||
}
|
||||
|
||||
for (auto &trace_index : trace_mem.second) {
|
||||
@@ -1181,7 +1186,7 @@ struct SimInstance
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->is_mem_cell()) {
|
||||
std::string memid = cell->parameters.at(ID::MEMID).decode_string();
|
||||
IdString memid = module->design->twines.add(cell->parameters.at(ID::MEMID).decode_string());
|
||||
for (auto &data : fst_memories[memid])
|
||||
{
|
||||
std::string v = shared->fst->valueOf(data.second);
|
||||
@@ -1212,7 +1217,7 @@ struct SimInstance
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
log_error("Unable to find required '%s' signal in file\n",(scope + "." + sig_y.as_wire()->name.unescape()));
|
||||
log_error("Unable to find required '%s' signal in file\n",(scope + "." + module->design->twines.unescaped_str(sig_y.as_wire()->name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1257,7 +1262,7 @@ struct SimInstance
|
||||
|
||||
issue_count++;
|
||||
any_undriven_found = true;
|
||||
std::string wire_name = scope + "." + RTLIL::unescape_id(wire->name);
|
||||
std::string wire_name = scope + "." + wire->name.unescape();
|
||||
log_warning("Input trace contains undriven signal `%s` (%s).\n", wire_name.c_str(), log_signal(undriven));
|
||||
}
|
||||
}
|
||||
@@ -1295,7 +1300,7 @@ struct SimInstance
|
||||
}
|
||||
}
|
||||
|
||||
void setMemState(dict<int, std::pair<std::string,int>> bits, std::string values)
|
||||
void setMemState(dict<int, std::pair<IdString,int>> bits, std::string values)
|
||||
{
|
||||
for(auto bit : bits) {
|
||||
if (bit.first >= GetSize(values))
|
||||
@@ -1457,10 +1462,11 @@ struct SimWorker : SimShared
|
||||
{
|
||||
for (auto portname : ports)
|
||||
{
|
||||
Wire *w = top->module->wire(portname);
|
||||
IdString portref = portname;
|
||||
Wire *w = top->module->wire(portref);
|
||||
|
||||
if (w == nullptr)
|
||||
log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module);
|
||||
log_error("Can't find port %s on module %s.\n", PooledName(top->module, portref).unescape(), top->module);
|
||||
|
||||
top->set_state(w, value);
|
||||
}
|
||||
@@ -1541,26 +1547,28 @@ struct SimWorker : SimShared
|
||||
|
||||
for (auto portname : clock)
|
||||
{
|
||||
Wire *w = topmod->wire(portname);
|
||||
IdString portref = portname;
|
||||
Wire *w = topmod->wire(portref);
|
||||
if (!w)
|
||||
log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module);
|
||||
log_error("Can't find port %s on module %s.\n", PooledName(topmod, portref).unescape(), top->module);
|
||||
if (!w->port_input)
|
||||
log_error("Clock port %s on module %s is not input.\n", portname.unescape(), top->module);
|
||||
fstHandle id = fst->getHandle(scope + "." + portname.unescape());
|
||||
log_error("Clock port %s on module %s is not input.\n", PooledName(topmod, portref).unescape(), top->module);
|
||||
fstHandle id = fst->getHandle(scope + "." + topmod->design->twines.unescaped_str(portref));
|
||||
if (id==0)
|
||||
log_error("Can't find port %s.%s in FST.\n", scope, portname.unescape());
|
||||
log_error("Can't find port %s.%s in FST.\n", scope, PooledName(topmod, portref).unescape());
|
||||
fst_clock.push_back(id);
|
||||
}
|
||||
for (auto portname : clockn)
|
||||
{
|
||||
Wire *w = topmod->wire(portname);
|
||||
IdString portref = portname;
|
||||
Wire *w = topmod->wire(portref);
|
||||
if (!w)
|
||||
log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module);
|
||||
log_error("Can't find port %s on module %s.\n", PooledName(topmod, portref).unescape(), top->module);
|
||||
if (!w->port_input)
|
||||
log_error("Clock port %s on module %s is not input.\n", portname.unescape(), top->module);
|
||||
fstHandle id = fst->getHandle(scope + "." + portname.unescape());
|
||||
log_error("Clock port %s on module %s is not input.\n", PooledName(topmod, portref).unescape(), top->module);
|
||||
fstHandle id = fst->getHandle(scope + "." + topmod->design->twines.unescaped_str(portref));
|
||||
if (id==0)
|
||||
log_error("Can't find port %s.%s in FST.\n", scope, portname.unescape());
|
||||
log_error("Can't find port %s.%s in FST.\n", scope, PooledName(topmod, portref).unescape());
|
||||
fst_clock.push_back(id);
|
||||
}
|
||||
|
||||
@@ -1680,20 +1688,20 @@ struct SimWorker : SimShared
|
||||
std::string type, symbol;
|
||||
int variable, index;
|
||||
dict<int, std::pair<SigBit,bool>> inputs, inits, latches;
|
||||
dict<int, std::pair<std::string,int>> mem_inits, mem_latches;
|
||||
dict<int, std::pair<IdString,int>> mem_inits, mem_latches;
|
||||
if (mf.fail())
|
||||
log_cmd_error("Not able to read AIGER witness map file.\n");
|
||||
while (mf >> type >> variable >> index >> symbol) {
|
||||
RTLIL::IdString escaped_s = RTLIL::escape_id(symbol);
|
||||
IdString escaped_s = topmod->design->twines.add(RTLIL::escape_id(symbol));
|
||||
Wire *w = topmod->wire(escaped_s);
|
||||
if (!w) {
|
||||
escaped_s = RTLIL::escape_id(cell_name(symbol));
|
||||
escaped_s = topmod->design->twines.add(RTLIL::escape_id(cell_name(symbol)));
|
||||
Cell *c = topmod->cell(escaped_s);
|
||||
if (!c)
|
||||
log_warning("Wire/cell %s not present in module %s\n",symbol,topmod);
|
||||
|
||||
if (c->is_mem_cell()) {
|
||||
std::string memid = c->parameters.at(ID::MEMID).decode_string();
|
||||
IdString memid = topmod->design->twines.add(c->parameters.at(ID::MEMID).decode_string());
|
||||
auto &state = top->mem_database[memid];
|
||||
|
||||
int offset = (mem_cell_addr(symbol) - state.mem->start_offset) * state.mem->width + index;
|
||||
@@ -1833,6 +1841,8 @@ struct SimWorker : SimShared
|
||||
int curr_cycle = 0;
|
||||
std::vector<std::string> parts;
|
||||
size_t len = 0;
|
||||
TwinePool& twines = topmod->design->twines;
|
||||
std::optional<TwineSearch> search;
|
||||
while (!f.eof())
|
||||
{
|
||||
std::string line;
|
||||
@@ -1865,6 +1875,8 @@ struct SimWorker : SimShared
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!search)
|
||||
search.emplace(&twines);
|
||||
switch(state)
|
||||
{
|
||||
case 0:
|
||||
@@ -1883,13 +1895,15 @@ struct SimWorker : SimShared
|
||||
if (len<3 || len>4)
|
||||
log_error("Invalid set state line content.\n");
|
||||
|
||||
RTLIL::IdString escaped_s = RTLIL::escape_id(signal_name(parts[len-1]));
|
||||
std::string unescaped_s = signal_name(parts[len-1]);
|
||||
std::string escaped_s = RTLIL::escape_id(unescaped_s);
|
||||
IdString found = search->find(escaped_s);
|
||||
if (len==3) {
|
||||
Wire *w = topmod->wire(escaped_s);
|
||||
Wire *w = topmod->wire(found);
|
||||
if (!w) {
|
||||
Cell *c = topmod->cell(escaped_s);
|
||||
Cell *c = topmod->cell(found);
|
||||
if (!c)
|
||||
log_warning("Wire/cell %s not present in module %s\n",escaped_s.unescape(),topmod);
|
||||
log_warning("Wire/cell %s not present in module %s\n", unescaped_s, topmod);
|
||||
else if (c->type.in(ID($anyconst), ID($anyseq))) {
|
||||
SigSpec sig_y= c->getPort(ID::Y);
|
||||
if ((int)parts[1].size() != GetSize(sig_y))
|
||||
@@ -1902,15 +1916,15 @@ struct SimWorker : SimShared
|
||||
top->set_state(w, Const::from_string(parts[1]));
|
||||
}
|
||||
} else {
|
||||
Cell *c = topmod->cell(escaped_s);
|
||||
Cell *c = topmod->cell(found);
|
||||
if (!c)
|
||||
log_error("Cell %s not present in module %s\n",escaped_s.unescape(),topmod);
|
||||
log_error("Cell %s not present in module %s\n", unescaped_s,topmod);
|
||||
if (!c->is_mem_cell())
|
||||
log_error("Cell %s is not memory cell in module %s\n",escaped_s.unescape(),topmod);
|
||||
log_error("Cell %s is not memory cell in module %s\n", unescaped_s,topmod);
|
||||
|
||||
Const addr = Const::from_string(parts[1].substr(1,parts[1].size()-2));
|
||||
Const data = Const::from_string(parts[2]);
|
||||
top->set_memory_state(c->parameters.at(ID::MEMID).decode_string(), addr, data);
|
||||
top->set_memory_state(topmod->design->twines.add(c->parameters.at(ID::MEMID).decode_string()), addr, data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1935,7 +1949,7 @@ struct SimWorker : SimShared
|
||||
{
|
||||
YwHierarchy hierarchy;
|
||||
pool<IdPath> paths;
|
||||
dict<IdPath, pool<IdString>> mem_paths;
|
||||
dict<IdPath, pool<std::string>> mem_paths;
|
||||
|
||||
for (auto &signal : yw.signals)
|
||||
paths.insert(signal.path);
|
||||
@@ -2206,27 +2220,29 @@ struct SimWorker : SimShared
|
||||
|
||||
for (auto portname : clock)
|
||||
{
|
||||
Wire *w = topmod->wire(portname);
|
||||
IdString portref = portname;
|
||||
Wire *w = topmod->wire(portref);
|
||||
if (!w)
|
||||
log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module);
|
||||
log_error("Can't find port %s on module %s.\n", PooledName(topmod, portref).unescape(), top->module);
|
||||
if (!w->port_input)
|
||||
log_error("Clock port %s on module %s is not input.\n", portname.unescape(), top->module);
|
||||
fstHandle id = fst->getHandle(scope + "." + portname.unescape());
|
||||
log_error("Clock port %s on module %s is not input.\n", PooledName(topmod, portref).unescape(), top->module);
|
||||
fstHandle id = fst->getHandle(scope + "." + topmod->design->twines.unescaped_str(portref));
|
||||
if (id==0)
|
||||
log_error("Can't find port %s.%s in FST.\n", scope, portname.unescape());
|
||||
log_error("Can't find port %s.%s in FST.\n", scope, PooledName(topmod, portref).unescape());
|
||||
fst_clock.push_back(id);
|
||||
clocks[w] = id;
|
||||
}
|
||||
for (auto portname : clockn)
|
||||
{
|
||||
Wire *w = topmod->wire(portname);
|
||||
IdString portref = portname;
|
||||
Wire *w = topmod->wire(portref);
|
||||
if (!w)
|
||||
log_error("Can't find port %s on module %s.\n", portname.unescape(), top->module);
|
||||
log_error("Can't find port %s on module %s.\n", PooledName(topmod, portref).unescape(), top->module);
|
||||
if (!w->port_input)
|
||||
log_error("Clock port %s on module %s is not input.\n", portname.unescape(), top->module);
|
||||
fstHandle id = fst->getHandle(scope + "." + portname.unescape());
|
||||
log_error("Clock port %s on module %s is not input.\n", PooledName(topmod, portref).unescape(), top->module);
|
||||
fstHandle id = fst->getHandle(scope + "." + topmod->design->twines.unescaped_str(portref));
|
||||
if (id==0)
|
||||
log_error("Can't find port %s.%s in FST.\n", scope, portname.unescape());
|
||||
log_error("Can't find port %s.%s in FST.\n", scope, PooledName(topmod, portref).unescape());
|
||||
fst_clock.push_back(id);
|
||||
clocks[w] = id;
|
||||
}
|
||||
@@ -2419,7 +2435,7 @@ struct VCDWriter : public OutputWriter
|
||||
vcdfile << stringf("$timescale %s $end\n", worker->timescale);
|
||||
|
||||
worker->top->write_output_header(
|
||||
[this](IdString name) { vcdfile << stringf("$scope module %s $end\n", name.unescape()); },
|
||||
[this](const std::string& name) { vcdfile << stringf("$scope module %s $end\n", name); },
|
||||
[this]() { vcdfile << stringf("$upscope $end\n");},
|
||||
[this,use_signal](const char *name, int size, Wire *w, int id, bool is_reg) {
|
||||
if (!use_signal.at(id)) return;
|
||||
@@ -2485,7 +2501,7 @@ struct FSTWriter : public OutputWriter
|
||||
fstWriterSetRepackOnClose(fstfile, 1);
|
||||
|
||||
worker->top->write_output_header(
|
||||
[this](IdString name) { fstWriterSetScope(fstfile, FST_ST_VCD_MODULE, stringf("%s",name.unescape()).c_str(), nullptr); },
|
||||
[this](const std::string& name) { fstWriterSetScope(fstfile, FST_ST_VCD_MODULE, name.c_str(), nullptr); },
|
||||
[this]() { fstWriterSetUpscope(fstfile); },
|
||||
[this,use_signal](const char *name, int size, Wire *w, int id, bool is_reg) {
|
||||
if (!use_signal.at(id)) return;
|
||||
@@ -2545,10 +2561,10 @@ struct AIWWriter : public OutputWriter
|
||||
if (mf.fail())
|
||||
log_cmd_error("Not able to read AIGER witness map file.\n");
|
||||
while (mf >> type >> variable >> index >> symbol) {
|
||||
RTLIL::IdString escaped_s = RTLIL::escape_id(symbol);
|
||||
IdString escaped_s = worker->top->module->design->twines.add(RTLIL::escape_id(symbol));
|
||||
Wire *w = worker->top->module->wire(escaped_s);
|
||||
if (!w)
|
||||
log_error("Wire %s not present in module %s\n",escaped_s.unescape(),worker->top->module);
|
||||
log_error("Wire %s not present in module %s\n", PooledName(worker->top->module, escaped_s).unescape(), worker->top->module);
|
||||
if (index < w->start_offset || index > w->start_offset + w->width)
|
||||
log_error("Index %d for wire %s is out of range\n", index, log_signal(w));
|
||||
if (type == "input") {
|
||||
@@ -2571,7 +2587,7 @@ struct AIWWriter : public OutputWriter
|
||||
}
|
||||
|
||||
worker->top->write_output_header(
|
||||
[](IdString) {},
|
||||
[](const std::string&) {},
|
||||
[]() {},
|
||||
[this](const char */*name*/, int /*size*/, Wire *wire, int id, bool) { if (wire != nullptr) mapping[wire] = id; }
|
||||
);
|
||||
@@ -2826,19 +2842,19 @@ struct SimPass : public Pass {
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-clock" && argidx+1 < args.size()) {
|
||||
worker.clock.insert(RTLIL::escape_id(args[++argidx]));
|
||||
worker.clock.insert(design->twines.add(RTLIL::escape_id(args[++argidx])));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-clockn" && argidx+1 < args.size()) {
|
||||
worker.clockn.insert(RTLIL::escape_id(args[++argidx]));
|
||||
worker.clockn.insert(design->twines.add(RTLIL::escape_id(args[++argidx])));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-reset" && argidx+1 < args.size()) {
|
||||
worker.reset.insert(RTLIL::escape_id(args[++argidx]));
|
||||
worker.reset.insert(design->twines.add(RTLIL::escape_id(args[++argidx])));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-resetn" && argidx+1 < args.size()) {
|
||||
worker.resetn.insert(RTLIL::escape_id(args[++argidx]));
|
||||
worker.resetn.insert(design->twines.add(RTLIL::escape_id(args[++argidx])));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-timescale" && argidx+1 < args.size()) {
|
||||
@@ -3053,11 +3069,11 @@ struct Fst2TbPass : public Pass {
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++) {
|
||||
if (args[argidx] == "-clock" && argidx+1 < args.size()) {
|
||||
worker.clock.insert(RTLIL::escape_id(args[++argidx]));
|
||||
worker.clock.insert(design->twines.add(RTLIL::escape_id(args[++argidx])));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-clockn" && argidx+1 < args.size()) {
|
||||
worker.clockn.insert(RTLIL::escape_id(args[++argidx]));
|
||||
worker.clockn.insert(design->twines.add(RTLIL::escape_id(args[++argidx])));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-r" && argidx+1 < args.size()) {
|
||||
|
||||
+56
-50
@@ -329,7 +329,8 @@ struct AbcModuleState {
|
||||
int map_signal(const AbcSigMap &assign_map, RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1, int in2 = -1, int in3 = -1, int in4 = -1);
|
||||
void mark_port(const AbcSigMap &assign_map, RTLIL::SigSpec sig);
|
||||
bool prepare_cell(const AbcSigMap &assign_map, RTLIL::Cell *cell, bool keepff);
|
||||
std::string remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire = nullptr);
|
||||
std::string remap_name(const std::string &abc_name, RTLIL::Wire **orig_wire = nullptr);
|
||||
RTLIL::IdString remap_ref(RTLIL::Module *module, const std::string &abc_name);
|
||||
void dump_loop_graph(FILE *f, int &nr, dict<int, pool<int>> &edges, pool<int> &workpool, std::vector<int> &in_counts);
|
||||
void handle_loops(AbcSigMap &assign_map, RTLIL::Module *module);
|
||||
void prepare_module(RTLIL::Design *design, RTLIL::Module *module, AbcSigMap &assign_map, const std::vector<RTLIL::Cell*> &cells,
|
||||
@@ -599,7 +600,12 @@ bool AbcModuleState::prepare_cell(const AbcSigMap &assign_map, RTLIL::Cell *cell
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string AbcModuleState::remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire)
|
||||
RTLIL::IdString AbcModuleState::remap_ref(RTLIL::Module *module, const std::string &abc_name)
|
||||
{
|
||||
return module->design->twines.add(remap_name(abc_name));
|
||||
}
|
||||
|
||||
std::string AbcModuleState::remap_name(const std::string &abc_name, RTLIL::Wire **orig_wire)
|
||||
{
|
||||
std::string abc_sname = abc_name.substr(1);
|
||||
bool isnew = false;
|
||||
@@ -622,7 +628,7 @@ std::string AbcModuleState::remap_name(RTLIL::IdString abc_name, RTLIL::Wire **o
|
||||
const auto &bit = signal_bits.at(sid);
|
||||
if (bit.wire != nullptr)
|
||||
{
|
||||
std::string s = stringf("$abc$%d$%s", map_autoidx, bit.wire->name.c_str()+1);
|
||||
std::string s = stringf("$abc$%d$%s", map_autoidx, bit.wire->name.str().substr(1));
|
||||
if (bit.wire->width != 1)
|
||||
s += stringf("[%d]", bit.offset);
|
||||
if (isnew)
|
||||
@@ -740,9 +746,9 @@ void AbcModuleState::handle_loops(AbcSigMap &assign_map, RTLIL::Module *module)
|
||||
id1 = id2;
|
||||
else if (w2 == nullptr)
|
||||
continue;
|
||||
else if (w1->name[0] == '$' && w2->name[0] == '\\')
|
||||
else if (!w1->name.isPublic() && w2->name.isPublic())
|
||||
id1 = id2;
|
||||
else if (w1->name[0] == '\\' && w2->name[0] == '$')
|
||||
else if (w1->name.isPublic() && !w2->name.isPublic())
|
||||
continue;
|
||||
else if (edges[id1].size() < edges[id2].size())
|
||||
id1 = id2;
|
||||
@@ -980,31 +986,31 @@ void AbcModuleState::prepare_module(RTLIL::Design *design, RTLIL::Module *module
|
||||
clk_polarity = false;
|
||||
clk_str = clk_str.substr(1);
|
||||
}
|
||||
if (module->wire(RTLIL::escape_id(clk_str)) != nullptr)
|
||||
clk_sig = assign_map(module->wire(RTLIL::escape_id(clk_str)));
|
||||
if (RTLIL::Wire *wire = RTLIL::wire_by_name(module, clk_str))
|
||||
clk_sig = assign_map(wire);
|
||||
if (en_str != "") {
|
||||
if (en_str[0] == '!') {
|
||||
en_polarity = false;
|
||||
en_str = en_str.substr(1);
|
||||
}
|
||||
if (module->wire(RTLIL::escape_id(en_str)) != nullptr)
|
||||
en_sig = assign_map(module->wire(RTLIL::escape_id(en_str)));
|
||||
if (RTLIL::Wire *wire = RTLIL::wire_by_name(module, en_str))
|
||||
en_sig = assign_map(wire);
|
||||
}
|
||||
if (arst_str != "") {
|
||||
if (arst_str[0] == '!') {
|
||||
arst_polarity = false;
|
||||
arst_str = arst_str.substr(1);
|
||||
}
|
||||
if (module->wire(RTLIL::escape_id(arst_str)) != nullptr)
|
||||
arst_sig = assign_map(module->wire(RTLIL::escape_id(arst_str)));
|
||||
if (RTLIL::Wire *wire = RTLIL::wire_by_name(module, arst_str))
|
||||
arst_sig = assign_map(wire);
|
||||
}
|
||||
if (srst_str != "") {
|
||||
if (srst_str[0] == '!') {
|
||||
srst_polarity = false;
|
||||
srst_str = srst_str.substr(1);
|
||||
}
|
||||
if (module->wire(RTLIL::escape_id(srst_str)) != nullptr)
|
||||
srst_sig = assign_map(module->wire(RTLIL::escape_id(srst_str)));
|
||||
if (RTLIL::Wire *wire = RTLIL::wire_by_name(module, srst_str))
|
||||
srst_sig = assign_map(wire);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1019,7 +1025,7 @@ void AbcModuleState::prepare_module(RTLIL::Design *design, RTLIL::Module *module
|
||||
run_abc.per_run_tempdir_name += proc_program_prefix() + "yosys-abc-XXXXXX";
|
||||
run_abc.per_run_tempdir_name = make_temp_dir(run_abc.per_run_tempdir_name);
|
||||
log_header(design, "Extracting gate netlist of module `%s' to `%s/input.blif'..\n",
|
||||
module->name.c_str(), replace_tempdir(run_abc.per_run_tempdir_name, config.global_tempdir_name, run_abc.per_run_tempdir_name, config.show_tempdir).c_str());
|
||||
module->name, replace_tempdir(run_abc.per_run_tempdir_name, config.global_tempdir_name, run_abc.per_run_tempdir_name, config.show_tempdir).c_str());
|
||||
|
||||
run_abc.abc_script = stringf("read_blif \"%s/input.blif\"; ", run_abc.per_run_tempdir_name);
|
||||
|
||||
@@ -1542,7 +1548,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
|
||||
ifs.close();
|
||||
|
||||
log_header(design, "Re-integrating ABC results.\n");
|
||||
RTLIL::Module *mapped_mod = mapped_design->module(ID(netlist));
|
||||
RTLIL::Module *mapped_mod = mapped_design->module(ID::netlist);
|
||||
if (mapped_mod == nullptr)
|
||||
log_error("ABC output file does not contain a module `netlist'.\n");
|
||||
bool markgroups = run_abc.config.markgroups;
|
||||
@@ -1566,7 +1572,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
|
||||
cell_stats[c->type.unescape()]++;
|
||||
if (c->type.in(ID(ZERO), ID(ONE))) {
|
||||
RTLIL::SigSig conn;
|
||||
RTLIL::IdString name_y = remap_name(c->getPort(ID::Y).as_wire()->name);
|
||||
IdString name_y = remap_ref(module, c->getPort(ID::Y).as_wire()->name);
|
||||
conn.first = module->wire(name_y);
|
||||
conn.second = RTLIL::SigSpec(c->type == ID(ZERO) ? 0 : 1, 1);
|
||||
module->connect(conn);
|
||||
@@ -1574,89 +1580,89 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
|
||||
}
|
||||
if (c->type == ID(BUF)) {
|
||||
RTLIL::SigSig conn;
|
||||
RTLIL::IdString name_y = remap_name(c->getPort(ID::Y).as_wire()->name);
|
||||
RTLIL::IdString name_a = remap_name(c->getPort(ID::A).as_wire()->name);
|
||||
IdString name_y = remap_ref(module, c->getPort(ID::Y).as_wire()->name);
|
||||
IdString name_a = remap_ref(module, c->getPort(ID::A).as_wire()->name);
|
||||
conn.first = module->wire(name_y);
|
||||
conn.second = module->wire(name_a);
|
||||
module->connect(conn);
|
||||
continue;
|
||||
}
|
||||
if (c->type == ID(NOT)) {
|
||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_NOT_));
|
||||
RTLIL::Cell *cell = module->addCell(remap_ref(module, c->name), ID($_NOT_));
|
||||
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
|
||||
for (auto name : {ID::A, ID::Y}) {
|
||||
RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name);
|
||||
IdString remapped_name = remap_ref(module, c->getPort(name).as_wire()->name);
|
||||
cell->setPort(name, module->wire(remapped_name));
|
||||
}
|
||||
design->select(module, cell);
|
||||
continue;
|
||||
}
|
||||
if (c->type.in(ID(AND), ID(OR), ID(XOR), ID(NAND), ID(NOR), ID(XNOR), ID(ANDNOT), ID(ORNOT))) {
|
||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
|
||||
RTLIL::Cell *cell = module->addCell(remap_ref(module, c->name), stringf("$_%s_", c->type.unescape().c_str()));
|
||||
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
|
||||
for (auto name : {ID::A, ID::B, ID::Y}) {
|
||||
RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name);
|
||||
IdString remapped_name = remap_ref(module, c->getPort(name).as_wire()->name);
|
||||
cell->setPort(name, module->wire(remapped_name));
|
||||
}
|
||||
design->select(module, cell);
|
||||
continue;
|
||||
}
|
||||
if (c->type.in(ID(MUX), ID(NMUX))) {
|
||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
|
||||
RTLIL::Cell *cell = module->addCell(remap_ref(module, c->name), stringf("$_%s_", c->type.unescape().c_str()));
|
||||
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
|
||||
for (auto name : {ID::A, ID::B, ID::S, ID::Y}) {
|
||||
RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name);
|
||||
IdString remapped_name = remap_ref(module, c->getPort(name).as_wire()->name);
|
||||
cell->setPort(name, module->wire(remapped_name));
|
||||
}
|
||||
design->select(module, cell);
|
||||
continue;
|
||||
}
|
||||
if (c->type == ID(MUX4)) {
|
||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX4_));
|
||||
RTLIL::Cell *cell = module->addCell(remap_ref(module, c->name), ID($_MUX4_));
|
||||
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
|
||||
for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::S, ID::T, ID::Y}) {
|
||||
RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name);
|
||||
IdString remapped_name = remap_ref(module, c->getPort(name).as_wire()->name);
|
||||
cell->setPort(name, module->wire(remapped_name));
|
||||
}
|
||||
design->select(module, cell);
|
||||
continue;
|
||||
}
|
||||
if (c->type == ID(MUX8)) {
|
||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX8_));
|
||||
RTLIL::Cell *cell = module->addCell(remap_ref(module, c->name), ID($_MUX8_));
|
||||
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
|
||||
for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::S, ID::T, ID::U, ID::Y}) {
|
||||
RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name);
|
||||
IdString remapped_name = remap_ref(module, c->getPort(name).as_wire()->name);
|
||||
cell->setPort(name, module->wire(remapped_name));
|
||||
}
|
||||
design->select(module, cell);
|
||||
continue;
|
||||
}
|
||||
if (c->type == ID(MUX16)) {
|
||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX16_));
|
||||
RTLIL::Cell *cell = module->addCell(remap_ref(module, c->name), ID($_MUX16_));
|
||||
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
|
||||
for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::I, ID::J, ID::K,
|
||||
ID::L, ID::M, ID::N, ID::O, ID::P, ID::S, ID::T, ID::U, ID::V, ID::Y}) {
|
||||
RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name);
|
||||
IdString remapped_name = remap_ref(module, c->getPort(name).as_wire()->name);
|
||||
cell->setPort(name, module->wire(remapped_name));
|
||||
}
|
||||
design->select(module, cell);
|
||||
continue;
|
||||
}
|
||||
if (c->type.in(ID(AOI3), ID(OAI3))) {
|
||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
|
||||
RTLIL::Cell *cell = module->addCell(remap_ref(module, c->name), stringf("$_%s_", c->type.unescape().c_str()));
|
||||
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
|
||||
for (auto name : {ID::A, ID::B, ID::C, ID::Y}) {
|
||||
RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name);
|
||||
IdString remapped_name = remap_ref(module, c->getPort(name).as_wire()->name);
|
||||
cell->setPort(name, module->wire(remapped_name));
|
||||
}
|
||||
design->select(module, cell);
|
||||
continue;
|
||||
}
|
||||
if (c->type.in(ID(AOI4), ID(OAI4))) {
|
||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
|
||||
RTLIL::Cell *cell = module->addCell(remap_ref(module, c->name), stringf("$_%s_", c->type.unescape().c_str()));
|
||||
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
|
||||
for (auto name : {ID::A, ID::B, ID::C, ID::D, ID::Y}) {
|
||||
RTLIL::IdString remapped_name = remap_name(c->getPort(name).as_wire()->name);
|
||||
IdString remapped_name = remap_ref(module, c->getPort(name).as_wire()->name);
|
||||
cell->setPort(name, module->wire(remapped_name));
|
||||
}
|
||||
design->select(module, cell);
|
||||
@@ -1664,7 +1670,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
|
||||
}
|
||||
if (c->type == ID(DFF)) {
|
||||
log_assert(clk_sig.size() == 1);
|
||||
FfData ff(module, &initvals, remap_name(c->name));
|
||||
FfData ff(module, &initvals, remap_ref(module, c->name));
|
||||
ff.width = 1;
|
||||
ff.is_fine = true;
|
||||
ff.has_clk = true;
|
||||
@@ -1695,8 +1701,8 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
|
||||
ff.sig_srst = srst_sig;
|
||||
ff.val_srst = init;
|
||||
}
|
||||
ff.sig_d = module->wire(remap_name(c->getPort(ID::D).as_wire()->name));
|
||||
ff.sig_q = module->wire(remap_name(c->getPort(ID::Q).as_wire()->name));
|
||||
ff.sig_d = module->wire(remap_ref(module, c->getPort(ID::D).as_wire()->name));
|
||||
ff.sig_q = module->wire(remap_ref(module, c->getPort(ID::Q).as_wire()->name));
|
||||
RTLIL::Cell *cell = ff.emit();
|
||||
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
|
||||
design->select(module, cell);
|
||||
@@ -1708,7 +1714,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
|
||||
|
||||
if (c->type.in(ID(_const0_), ID(_const1_))) {
|
||||
RTLIL::SigSig conn;
|
||||
conn.first = module->wire(remap_name(c->connections().begin()->second.as_wire()->name));
|
||||
conn.first = module->wire(remap_ref(module, c->connections().begin()->second.as_wire()->name));
|
||||
conn.second = RTLIL::SigSpec(c->type == ID(_const0_) ? 0 : 1, 1);
|
||||
module->connect(conn);
|
||||
continue;
|
||||
@@ -1716,7 +1722,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
|
||||
|
||||
if (c->type == ID(_dff_)) {
|
||||
log_assert(clk_sig.size() == 1);
|
||||
FfData ff(module, &initvals, remap_name(c->name));
|
||||
FfData ff(module, &initvals, remap_ref(module, c->name));
|
||||
ff.width = 1;
|
||||
ff.is_fine = true;
|
||||
ff.has_clk = true;
|
||||
@@ -1744,8 +1750,8 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
|
||||
ff.sig_srst = srst_sig;
|
||||
ff.val_srst = init;
|
||||
}
|
||||
ff.sig_d = module->wire(remap_name(c->getPort(ID::D).as_wire()->name));
|
||||
ff.sig_q = module->wire(remap_name(c->getPort(ID::Q).as_wire()->name));
|
||||
ff.sig_d = module->wire(remap_ref(module, c->getPort(ID::D).as_wire()->name));
|
||||
ff.sig_q = module->wire(remap_ref(module, c->getPort(ID::Q).as_wire()->name));
|
||||
RTLIL::Cell *cell = ff.emit();
|
||||
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
|
||||
design->select(module, cell);
|
||||
@@ -1753,22 +1759,22 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
|
||||
}
|
||||
|
||||
if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID::LUT).as_int() == 2) {
|
||||
SigSpec my_a = module->wire(remap_name(c->getPort(ID::A).as_wire()->name));
|
||||
SigSpec my_y = module->wire(remap_name(c->getPort(ID::Y).as_wire()->name));
|
||||
SigSpec my_a = module->wire(remap_ref(module, c->getPort(ID::A).as_wire()->name));
|
||||
SigSpec my_y = module->wire(remap_ref(module, c->getPort(ID::Y).as_wire()->name));
|
||||
module->connect(RTLIL::SigSig(my_a, my_y));
|
||||
continue;
|
||||
}
|
||||
|
||||
RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type);
|
||||
RTLIL::Cell *cell = module->addCell(remap_ref(module, c->name), module->design->twines.copy_from(mapped_design->twines, c->type));
|
||||
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
|
||||
cell->parameters = c->parameters;
|
||||
RTLIL::copy_attr_dict(cell->parameters, c->parameters, c->module->design, module->design);
|
||||
for (auto &conn : c->connections()) {
|
||||
RTLIL::SigSpec newsig;
|
||||
for (auto &c : conn.second.chunks()) {
|
||||
if (c.width == 0)
|
||||
continue;
|
||||
log_assert(c.width == 1);
|
||||
newsig.append(module->wire(remap_name(c.wire->name)));
|
||||
newsig.append(module->wire(remap_ref(module, c.wire->name)));
|
||||
}
|
||||
cell->setPort(conn.first, newsig);
|
||||
}
|
||||
@@ -1777,9 +1783,9 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
|
||||
|
||||
for (auto conn : mapped_mod->connections()) {
|
||||
if (!conn.first.is_fully_const())
|
||||
conn.first = module->wire(remap_name(conn.first.as_wire()->name));
|
||||
conn.first = module->wire(remap_ref(module, conn.first.as_wire()->name));
|
||||
if (!conn.second.is_fully_const())
|
||||
conn.second = module->wire(remap_name(conn.second.as_wire()->name));
|
||||
conn.second = module->wire(remap_ref(module, conn.second.as_wire()->name));
|
||||
module->connect(conn);
|
||||
}
|
||||
|
||||
@@ -1794,10 +1800,10 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
|
||||
RTLIL::SigSig conn;
|
||||
if (si.type != G(NONE)) {
|
||||
conn.first = signal_bits[si.id];
|
||||
conn.second = module->wire(remap_name(buffer));
|
||||
conn.second = module->wire(remap_ref(module, buffer));
|
||||
out_wires++;
|
||||
} else {
|
||||
conn.first = module->wire(remap_name(buffer));
|
||||
conn.first = module->wire(remap_ref(module, buffer));
|
||||
conn.second = signal_bits[si.id];
|
||||
in_wires++;
|
||||
}
|
||||
|
||||
@@ -325,11 +325,11 @@ struct Abc9Pass : public ScriptPass
|
||||
else {
|
||||
// Rename all submod-s to _TECHMAP_REPLACE_ to inherit name + attrs
|
||||
for (auto module : active_design->selected_modules()) {
|
||||
active_design->selected_active_module = module->name.str();
|
||||
if (module->cell(stringf("%s_$abc9_flop", module->name)))
|
||||
active_design->selected_active_module = module->name;
|
||||
if (module->cell(active_design->twines.find(stringf("%s_$abc9_flop", module->name))))
|
||||
run(stringf("rename %s_$abc9_flop _TECHMAP_REPLACE_", module->name));
|
||||
}
|
||||
active_design->selected_active_module.clear();
|
||||
active_design->selected_active_module = IdString::Null;
|
||||
}
|
||||
run("abc9_ops -prep_dff_unmap", " (only if -dff)");
|
||||
run("design -copy-to $abc9 =*_$abc9_flop", " (only if -dff)"); // copy submod out
|
||||
@@ -400,6 +400,8 @@ struct Abc9Pass : public ScriptPass
|
||||
log_push();
|
||||
active_design->select(mod);
|
||||
|
||||
GarbageCollectionGuard gc_guard(false);
|
||||
|
||||
// this check does nothing because the above line adds the whole module to the selection
|
||||
if (!active_design->selected_whole_module(mod))
|
||||
log_error("Can't handle partially selected module %s!\n", mod);
|
||||
|
||||
+61
-48
@@ -28,6 +28,12 @@
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
// Bring a name handle from `src`'s twine pool into `dst`'s.
|
||||
IdString translate(RTLIL::Design *dst, RTLIL::Design *src, IdString name)
|
||||
{
|
||||
return dst->twines.copy_from(src->twines, name);
|
||||
}
|
||||
|
||||
void check(RTLIL::Design *design, bool dff_mode)
|
||||
{
|
||||
dict<IdString,IdString> box_lookup;
|
||||
@@ -40,10 +46,10 @@ void check(RTLIL::Design *design, bool dff_mode)
|
||||
continue;
|
||||
if (it != m->attributes.end()) {
|
||||
auto id = it->second.as_int();
|
||||
auto r = box_lookup.insert(std::make_pair(stringf("$__boxid%d", id), m->name));
|
||||
auto r = box_lookup.insert(std::make_pair(design->twines.add(stringf("$__boxid%d", id)), IdString(m->name)));
|
||||
if (!r.second)
|
||||
log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n",
|
||||
m, id, r.first->second.unescape());
|
||||
m, id, design->twines.unescaped_str(r.first->second));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +136,7 @@ void check(RTLIL::Design *design, bool dff_mode)
|
||||
if (!derived_module->get_bool_attribute(ID::abc9_flop))
|
||||
continue;
|
||||
if (derived_module->get_blackbox_attribute(true /* ignore_wb */))
|
||||
log_error("Module '%s' with (* abc9_flop *) is a blackbox.\n", derived_type.unescape());
|
||||
log_error("Module '%s' with (* abc9_flop *) is a blackbox.\n", design->twines.unescaped_str(derived_type));
|
||||
|
||||
if (derived_module->has_processes())
|
||||
Pass::call_on_module(design, derived_module, "proc -noopt");
|
||||
@@ -200,7 +206,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
|
||||
}
|
||||
}
|
||||
if (!derived_module->get_bool_attribute(ID::abc9_box) && !derived_module->get_bool_attribute(ID::abc9_bypass) && !has_timing) {
|
||||
if (unmap_design->module(derived_type)) {
|
||||
if (unmap_design->module(translate(unmap_design, design, derived_type))) {
|
||||
// If derived_type is present in unmap_design, it means that it was processed previously, but found to be incompatible -- e.g. if
|
||||
// it contained a non-zero initial state. In this case, continue to replace the cell type/parameters so that it has the same properties
|
||||
// as a compatible type, yet will be safely unmapped later
|
||||
@@ -212,7 +218,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
|
||||
}
|
||||
}
|
||||
|
||||
if (!unmap_design->module(derived_type)) {
|
||||
if (!unmap_design->module(translate(unmap_design, design, derived_type))) {
|
||||
if (derived_module->has_processes())
|
||||
Pass::call_on_module(design, derived_module, "proc -noopt");
|
||||
|
||||
@@ -242,10 +248,10 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
|
||||
}
|
||||
|
||||
if (derived_type != cell->type) {
|
||||
auto unmap_module = unmap_design->addModule(derived_type);
|
||||
auto replace_cell = unmap_module->addCell(ID::_TECHMAP_REPLACE_, cell->type);
|
||||
auto unmap_module = unmap_design->addModule(translate(unmap_design, design, derived_type));
|
||||
auto replace_cell = unmap_module->addCell(ID::_TECHMAP_REPLACE_, translate(unmap_design, cell->module->design, cell->type));
|
||||
for (auto port : derived_module->ports) {
|
||||
auto w = unmap_module->addWire(port, derived_module->wire(port));
|
||||
auto w = unmap_module->addWire(translate(unmap_design, design, port), derived_module->wire(port));
|
||||
// Do not propagate (* init *) values into the box,
|
||||
// in fact, remove it from outside too
|
||||
if (w->port_output)
|
||||
@@ -255,12 +261,15 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
|
||||
// the techmapped cell
|
||||
w->attributes[ID::techmap_autopurge] = 1;
|
||||
|
||||
replace_cell->setPort(port, w);
|
||||
replace_cell->setPort(translate(unmap_design, design, port), w);
|
||||
}
|
||||
unmap_module->ports = derived_module->ports;
|
||||
unmap_module->ports.clear();
|
||||
for (auto port : derived_module->ports)
|
||||
unmap_module->ports.push_back(translate(unmap_design, design, port));
|
||||
unmap_module->check();
|
||||
|
||||
replace_cell->parameters = cell->parameters;
|
||||
RTLIL::copy_attr_dict(replace_cell->parameters, cell->parameters,
|
||||
cell->module->design, unmap_design);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,13 +339,15 @@ void prep_bypass(RTLIL::Design *design)
|
||||
|
||||
// Copy inst_module into map_design, with the same interface
|
||||
// and duplicate $abc9$* wires for its output ports
|
||||
auto map_module = map_design->addModule(cell->type);
|
||||
auto map_module = map_design->addModule(translate(map_design, design, cell->type));
|
||||
for (auto port_name : inst_module->ports) {
|
||||
auto w = map_module->addWire(port_name, inst_module->wire(port_name));
|
||||
auto w = map_module->addWire(translate(map_design, design, port_name), inst_module->wire(port_name));
|
||||
if (w->port_output)
|
||||
w->attributes.erase(ID::init);
|
||||
}
|
||||
map_module->ports = inst_module->ports;
|
||||
map_module->ports.clear();
|
||||
for (auto port_name : inst_module->ports)
|
||||
map_module->ports.push_back(translate(map_design, design, port_name));
|
||||
map_module->check();
|
||||
map_module->set_bool_attribute(ID::whitebox);
|
||||
|
||||
@@ -349,7 +360,7 @@ void prep_bypass(RTLIL::Design *design)
|
||||
if (!port->port_output)
|
||||
continue;
|
||||
auto dst = bypass_module->addWire(port_name, port);
|
||||
auto src = bypass_module->addWire("$abc9byp$" + port_name.str(), GetSize(port));
|
||||
auto src = bypass_module->addWire("$abc9byp$" + design->twines.str(port_name), GetSize(port));
|
||||
src->port_input = true;
|
||||
// For these new input ports driven by the replaced
|
||||
// cell, then create a new simple-path specify entry:
|
||||
@@ -424,20 +435,20 @@ void prep_bypass(RTLIL::Design *design)
|
||||
// and a bypass cell that has the same inputs/outputs as the
|
||||
// original cell, but with additional inputs taken from the
|
||||
// replaced cell
|
||||
auto replace_cell = map_module->addCell(ID::_TECHMAP_REPLACE_, cell->type);
|
||||
auto bypass_cell = map_module->addCell(NEW_ID, cell->type.str() + "_$abc9_byp");
|
||||
auto replace_cell = map_module->addCell(ID::_TECHMAP_REPLACE_, translate(map_design, cell->module->design, cell->type));
|
||||
auto bypass_cell = map_module->addCell(NEW_ID, map_module->design->twines.add(std::string{cell->type.str() + "_$abc9_byp"}));
|
||||
for (const auto &conn : cell->connections()) {
|
||||
auto port = map_module->wire(conn.first);
|
||||
auto port = map_module->wire(translate(map_design, design, conn.first));
|
||||
if (cell->input(conn.first)) {
|
||||
replace_cell->setPort(conn.first, port);
|
||||
replace_cell->setPort(translate(map_design, design, conn.first), port);
|
||||
if (bypass_module->wire(conn.first))
|
||||
bypass_cell->setPort(conn.first, port);
|
||||
bypass_cell->setPort(translate(map_design, design, conn.first), port);
|
||||
}
|
||||
if (cell->output(conn.first)) {
|
||||
bypass_cell->setPort(conn.first, port);
|
||||
auto n = "$abc9byp$" + conn.first.str();
|
||||
bypass_cell->setPort(translate(map_design, design, conn.first), port);
|
||||
auto n = "$abc9byp$" + design->twines.str(conn.first);
|
||||
auto w = map_module->addWire(n, GetSize(conn.second));
|
||||
replace_cell->setPort(conn.first, w);
|
||||
replace_cell->setPort(translate(map_design, design, conn.first), w);
|
||||
bypass_cell->setPort(n, w);
|
||||
}
|
||||
}
|
||||
@@ -448,10 +459,10 @@ void prep_bypass(RTLIL::Design *design)
|
||||
// driving the outputs
|
||||
auto unmap_module = unmap_design->addModule(cell->type.str() + "_$abc9_byp");
|
||||
for (auto port_name : inst_module->ports) {
|
||||
auto w = unmap_module->addWire(port_name, inst_module->wire(port_name));
|
||||
auto w = unmap_module->addWire(translate(unmap_design, design, port_name), inst_module->wire(port_name));
|
||||
if (w->port_output) {
|
||||
w->attributes.erase(ID::init);
|
||||
auto w2 = unmap_module->addWire("$abc9byp$" + port_name.str(), GetSize(w));
|
||||
auto w2 = unmap_module->addWire("$abc9byp$" + design->twines.str(port_name), GetSize(w));
|
||||
w2->port_input = true;
|
||||
unmap_module->connect(w, w2);
|
||||
}
|
||||
@@ -541,7 +552,7 @@ void prep_dff_unmap(RTLIL::Design *design)
|
||||
// Make sure the box module has all the same ports present on flop cell
|
||||
auto replace_cell = module->cell(ID::_TECHMAP_REPLACE_);
|
||||
log_assert(replace_cell);
|
||||
auto box_module = design->module(module->name.str() + "_$abc9_flop");
|
||||
auto box_module = design->module(design->twines.find(module->name.str() + "_$abc9_flop"));
|
||||
log_assert(box_module);
|
||||
for (auto port_name : module->ports) {
|
||||
auto port = module->wire(port_name);
|
||||
@@ -557,14 +568,16 @@ void prep_dff_unmap(RTLIL::Design *design)
|
||||
}
|
||||
box_module->fixup_ports();
|
||||
|
||||
auto unmap_module = unmap_design->addModule(box_module->name);
|
||||
replace_cell = unmap_module->addCell(ID::_TECHMAP_REPLACE_, module->name);
|
||||
auto unmap_module = unmap_design->addModule(translate(unmap_design, design, box_module->name));
|
||||
replace_cell = unmap_module->addCell(ID::_TECHMAP_REPLACE_, module->name.str());
|
||||
for (auto port_name : box_module->ports) {
|
||||
auto w = unmap_module->addWire(port_name, box_module->wire(port_name));
|
||||
auto w = unmap_module->addWire(translate(unmap_design, design, port_name), box_module->wire(port_name));
|
||||
if (module->wire(port_name))
|
||||
replace_cell->setPort(port_name, w);
|
||||
replace_cell->setPort(translate(unmap_design, design, port_name), w);
|
||||
}
|
||||
unmap_module->ports = box_module->ports;
|
||||
unmap_module->ports.clear();
|
||||
for (auto port_name : box_module->ports)
|
||||
unmap_module->ports.push_back(translate(unmap_design, design, port_name));
|
||||
unmap_module->check();
|
||||
}
|
||||
}
|
||||
@@ -678,7 +691,7 @@ void prep_delays(RTLIL::Design *design, bool dff_mode)
|
||||
auto port_wire = inst_module->wire(i.first.name);
|
||||
if (!port_wire)
|
||||
log_error("Port %s in cell %s (type %s) from module %s does not actually exist",
|
||||
i.first.name.unescape(), cell, cell->type.unescape(), module);
|
||||
design->twines.unescaped_str(i.first.name), cell, cell->type.unescape(), module);
|
||||
log_assert(port_wire->port_input);
|
||||
|
||||
auto d = i.second.first;
|
||||
@@ -697,13 +710,13 @@ void prep_delays(RTLIL::Design *design, bool dff_mode)
|
||||
if (ys_debug(1)) {
|
||||
static pool<std::pair<IdString,TimingInfo::NameBit>> seen;
|
||||
if (seen.emplace(cell->type, i.first).second) log("%s.%s[%d] abc9_required = %d\n",
|
||||
cell->type.unescape(), i.first.name.unescape(), offset, d);
|
||||
cell->type.unescape(), design->twines.unescaped_str(i.first.name), offset, d);
|
||||
}
|
||||
#endif
|
||||
auto r = box_cache.insert(d);
|
||||
if (r.second) {
|
||||
r.first->second = delay_module->derive(design, {{ID::DELAY, d}});
|
||||
log_assert(r.first->second.begins_with("$paramod$__ABC9_DELAY\\DELAY="));
|
||||
log_assert(design->twines.str(r.first->second).starts_with("$paramod$__ABC9_DELAY\\DELAY="));
|
||||
}
|
||||
auto box = module->addCell(NEW_ID, r.first->second);
|
||||
box->setPort(ID::I, rhs[offset]);
|
||||
@@ -765,7 +778,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
|
||||
return;
|
||||
|
||||
// Build the same topo graph for the initial pass and the optional retry.
|
||||
auto build_toposort = [&](TopoSort<IdString, RTLIL::sort_by_id_str> &toposort) {
|
||||
auto build_toposort = [&](TopoSort<IdString> &toposort) {
|
||||
dict<SigBit, pool<IdString>> bit_drivers, bit_users;
|
||||
|
||||
for (auto cell : module->cells()) {
|
||||
@@ -806,7 +819,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
|
||||
};
|
||||
|
||||
// Build TopoSort in a container, as we may need to conditionally rebuild it on retry.
|
||||
std::optional<TopoSort<IdString, RTLIL::sort_by_id_str>> toposort;
|
||||
std::optional<TopoSort<IdString>> toposort;
|
||||
toposort.emplace();
|
||||
bool no_loops = build_toposort(toposort.value());
|
||||
|
||||
@@ -869,7 +882,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
|
||||
r.first->second = new Design;
|
||||
RTLIL::Design *holes_design = r.first->second;
|
||||
log_assert(holes_design);
|
||||
RTLIL::Module *holes_module = holes_design->addModule(module->name);
|
||||
RTLIL::Module *holes_module = holes_design->addModule(translate(holes_design, design, module->name));
|
||||
log_assert(holes_module);
|
||||
|
||||
dict<IdString, Cell*> cell_cache;
|
||||
@@ -891,7 +904,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
|
||||
// be instantiating the derived module which will have had any parameters constant-propagated.
|
||||
// This task is expected to be performed by `abc9_ops -prep_hier`, but it looks like it failed to do so for this design.
|
||||
// Please file a bug report!
|
||||
log_error("Not expecting parameters on cell '%s' instantiating module '%s' marked (* abc9_box *)\n", cell_name.unescape(), cell->type.unescape());
|
||||
log_error("Not expecting parameters on cell '%s' instantiating module '%s' marked (* abc9_box *)\n", design->twines.unescaped_str(cell_name), cell->type.unescape());
|
||||
}
|
||||
log_assert(box_module->get_blackbox_attribute());
|
||||
|
||||
@@ -901,7 +914,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
|
||||
auto &holes_cell = r.first->second;
|
||||
if (r.second) {
|
||||
if (box_module->get_bool_attribute(ID::whitebox)) {
|
||||
holes_cell = holes_module->addCell(NEW_ID, cell->type);
|
||||
holes_cell = holes_module->addCell(NEW_ID, translate(holes_design, cell->module->design, cell->type));
|
||||
|
||||
if (box_module->has_processes())
|
||||
Pass::call_on_module(design, box_module, "proc -noopt");
|
||||
@@ -911,11 +924,11 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
|
||||
RTLIL::Wire *w = box_module->wire(port_name);
|
||||
log_assert(w);
|
||||
log_assert(!w->port_input || !w->port_output);
|
||||
auto &conn = holes_cell->connections_[port_name];
|
||||
auto &conn = holes_cell->connections_[translate(holes_design, design, port_name)];
|
||||
if (w->port_input) {
|
||||
for (int i = 0; i < GetSize(w); i++) {
|
||||
box_inputs++;
|
||||
RTLIL::Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs));
|
||||
RTLIL::Wire *holes_wire = holes_module->wire(holes_design->twines.find(stringf("\\i%d", box_inputs)));
|
||||
if (!holes_wire) {
|
||||
holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs));
|
||||
holes_wire->port_input = true;
|
||||
@@ -926,7 +939,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
|
||||
}
|
||||
}
|
||||
else if (w->port_output)
|
||||
conn = holes_module->addWire(stringf("%s.%s", cell->type, port_name.unescape()), GetSize(w));
|
||||
conn = holes_module->addWire(stringf("%s.%s", cell->type, design->twines.unescaped_str(port_name)), GetSize(w));
|
||||
}
|
||||
}
|
||||
else // box_module is a blackbox
|
||||
@@ -938,12 +951,12 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
|
||||
log_assert(w);
|
||||
if (!w->port_output)
|
||||
continue;
|
||||
Wire *holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name, port_name.unescape()), GetSize(w));
|
||||
Wire *holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name, design->twines.unescaped_str(port_name)), GetSize(w));
|
||||
holes_wire->port_output = true;
|
||||
holes_wire->port_id = port_id++;
|
||||
holes_module->ports.push_back(holes_wire->name);
|
||||
if (holes_cell) // whitebox
|
||||
holes_module->connect(holes_wire, holes_cell->getPort(port_name));
|
||||
holes_module->connect(holes_wire, holes_cell->getPort(translate(holes_design, design, port_name)));
|
||||
else // blackbox
|
||||
holes_module->connect(holes_wire, Const(State::S0, GetSize(w)));
|
||||
}
|
||||
@@ -990,9 +1003,9 @@ void prep_lut(RTLIL::Design *design, int maxlut)
|
||||
auto r = table.emplace(K, entry);
|
||||
if (!r.second) {
|
||||
if (r.first->second.area != entry.area)
|
||||
log_error("Modules '%s' and '%s' have conflicting (* abc9_lut *) values.\n", module, r.first->second.name.unescape());
|
||||
log_error("Modules '%s' and '%s' have conflicting (* abc9_lut *) values.\n", module, design->twines.unescaped_str(r.first->second.name));
|
||||
if (r.first->second.delays != entry.delays)
|
||||
log_error("Modules '%s' and '%s' have conflicting specify entries.\n", module, r.first->second.name.unescape());
|
||||
log_error("Modules '%s' and '%s' have conflicting specify entries.\n", module, design->twines.unescaped_str(r.first->second.name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1011,7 +1024,7 @@ void prep_lut(RTLIL::Design *design, int maxlut)
|
||||
ss << std::endl;
|
||||
}
|
||||
for (const auto &i : table) {
|
||||
ss << "# " << i.second.name.unescape() << std::endl;
|
||||
ss << "# " << design->twines.unescaped_str(i.second.name) << std::endl;
|
||||
ss << i.first << " " << i.second.area;
|
||||
for (const auto &j : i.second.delays)
|
||||
ss << " " << j;
|
||||
@@ -1099,7 +1112,7 @@ void prep_box(RTLIL::Design *design)
|
||||
if (ys_debug(1)) {
|
||||
static std::set<std::pair<IdString,IdString>> seen;
|
||||
if (seen.emplace(module->name, port_name).second) log("%s.%s abc9_required = %d\n", module,
|
||||
port_name.unescape(), it->second.first);
|
||||
design->twines.unescaped_str(port_name), it->second.first);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -170,6 +170,7 @@ struct AbcNewPass : public ScriptPass {
|
||||
}
|
||||
|
||||
for (auto mod : selected_modules) {
|
||||
GarbageCollectionGuard gc_guard(false);
|
||||
std::string tmpdir = "<abc-temp-dir>";
|
||||
std::string modname = "<module>";
|
||||
std::string exe_options = "[options]";
|
||||
@@ -192,7 +193,7 @@ struct AbcNewPass : public ScriptPass {
|
||||
}
|
||||
|
||||
run(stringf(" abc9_ops -write_box %s/input.box", tmpdir));
|
||||
run(stringf(" write_xaiger2 -mapping_prep -map-refs -map2 %s/input.map2 %s/input.xaig", tmpdir, tmpdir));
|
||||
run(stringf(" write_xaiger2 -mapping_prep -map2 %s/input.map2 %s/input.xaig", tmpdir, tmpdir));
|
||||
run(stringf(" abc9_exe %s -cwd %s -box %s/input.box", exe_options, tmpdir, tmpdir));
|
||||
run(stringf(" read_aiger -xaiger -module_name %s$abc9 %s/output.aig",
|
||||
modname, tmpdir));
|
||||
|
||||
@@ -29,9 +29,28 @@ PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
int map_autoidx;
|
||||
|
||||
inline std::string remap_name(RTLIL::IdString abc9_name)
|
||||
inline std::string remap_name(const std::string &abc9_name)
|
||||
{
|
||||
return stringf("$abc$%d$%s", map_autoidx, abc9_name.c_str()+1);
|
||||
return stringf("$abc$%d$%s", map_autoidx, abc9_name.c_str() + 1);
|
||||
}
|
||||
|
||||
inline IdString remap_ref(RTLIL::Design *design, IdString n)
|
||||
{
|
||||
return design->twines.add(remap_name(design->twines.str(n)));
|
||||
}
|
||||
|
||||
inline IdString ref_from_token(RTLIL::Design *design, const std::string &tok)
|
||||
{
|
||||
IdString ref = design->twines.ref_from_token(tok);
|
||||
if (ref == IdString::Null)
|
||||
log_error("Bad map file: '%s' is not a live name reference of this yosys run.\n", tok.c_str());
|
||||
return ref;
|
||||
}
|
||||
|
||||
inline IdString indexed_name(RTLIL::Design *design, IdString base, int index)
|
||||
{
|
||||
return design->twines.add(Twine::Suffix{base.untag(), stringf("[%d]", index)})
|
||||
.tag(base.isPublic());
|
||||
}
|
||||
|
||||
struct PseudoPo {
|
||||
@@ -57,7 +76,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
|
||||
map_autoidx = autoidx++;
|
||||
|
||||
RTLIL::Module *mapped_mod = design->module(stringf("%s$abc9", module->name));
|
||||
RTLIL::Module *mapped_mod = design->module(design->twines.find(stringf("%s$abc9", module->name)));
|
||||
if (mapped_mod == NULL)
|
||||
log_error("ABC output file does not contain a module `%s$abc'.\n", module);
|
||||
|
||||
@@ -73,43 +92,46 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
std::ifstream mf(map_filename);
|
||||
std::string type, symbol;
|
||||
int variable, index;
|
||||
|
||||
while (mf >> type >> variable >> index >> symbol) {
|
||||
RTLIL::IdString escaped_s = RTLIL::escape_id(symbol);
|
||||
IdString escaped_ref = ref_from_token(design, symbol);
|
||||
if (type == "input") {
|
||||
log_assert(variable < input_count);
|
||||
RTLIL::Wire* wire = mapped_mod->wire(stringf("$aiger$i%d", variable + 1));
|
||||
RTLIL::Wire* wire = mapped_mod->wire(design->twines.find(stringf("$aiger$i%d", variable + 1)));
|
||||
log_assert(wire);
|
||||
log_assert(wire->port_input);
|
||||
log_debug("Renaming input %s", wire);
|
||||
|
||||
RTLIL::Wire *existing = nullptr;
|
||||
IdString name_ref;
|
||||
if (index == 0) {
|
||||
name_ref = escaped_ref;
|
||||
// Cope with the fact that a CI might be identical
|
||||
// to a PI (necessary due to ABC); in those cases
|
||||
// simply connect the latter to the former
|
||||
existing = mapped_mod->wire(escaped_s);
|
||||
existing = mapped_mod->wire(name_ref);
|
||||
if (!existing)
|
||||
mapped_mod->rename(wire, escaped_s);
|
||||
mapped_mod->rename(wire, name_ref);
|
||||
else {
|
||||
wire->port_input = false;
|
||||
mapped_mod->connect(wire, existing);
|
||||
}
|
||||
log_debug(" -> %s\n", escaped_s);
|
||||
log_debug(" -> %s\n", design->twines.unescaped_str(escaped_ref));
|
||||
}
|
||||
else {
|
||||
RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index);
|
||||
existing = mapped_mod->wire(indexed_name);
|
||||
name_ref = indexed_name(design, escaped_ref, index);
|
||||
existing = mapped_mod->wire(name_ref);
|
||||
if (!existing)
|
||||
mapped_mod->rename(wire, indexed_name);
|
||||
mapped_mod->rename(wire, name_ref);
|
||||
else {
|
||||
mapped_mod->connect(wire, existing);
|
||||
wire->port_input = false;
|
||||
}
|
||||
log_debug(" -> %s\n", indexed_name);
|
||||
log_debug(" -> %s\n", design->twines.unescaped_str(name_ref));
|
||||
}
|
||||
|
||||
if (!existing) {
|
||||
auto r = wideports_cache.insert(escaped_s);
|
||||
auto r = wideports_cache.insert(escaped_ref);
|
||||
if (r.second) {
|
||||
r.first->second.first = index;
|
||||
r.first->second.second = index;
|
||||
@@ -122,42 +144,44 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
}
|
||||
else if (type == "output") {
|
||||
log_assert(variable + co_count < output_count);
|
||||
RTLIL::Wire* wire = mapped_mod->wire(stringf("$aiger$o%d", variable + co_count));
|
||||
RTLIL::Wire* wire = mapped_mod->wire(design->twines.find(stringf("$aiger$o%d", variable + co_count)));
|
||||
log_assert(wire);
|
||||
log_assert(wire->port_output);
|
||||
log_debug("Renaming output %s", wire);
|
||||
|
||||
RTLIL::Wire *existing;
|
||||
IdString name_ref;
|
||||
if (index == 0) {
|
||||
name_ref = escaped_ref;
|
||||
// Cope with the fact that a CO might be identical
|
||||
// to a PO (necessary due to ABC); in those cases
|
||||
// simply connect the latter to the former
|
||||
existing = mapped_mod->wire(escaped_s);
|
||||
existing = mapped_mod->wire(name_ref);
|
||||
if (!existing)
|
||||
mapped_mod->rename(wire, escaped_s);
|
||||
mapped_mod->rename(wire, name_ref);
|
||||
else {
|
||||
wire->port_output = false;
|
||||
existing->port_output = true;
|
||||
mapped_mod->connect(wire, existing);
|
||||
wire = existing;
|
||||
}
|
||||
log_debug(" -> %s\n", escaped_s);
|
||||
log_debug(" -> %s\n", design->twines.unescaped_str(escaped_ref));
|
||||
}
|
||||
else {
|
||||
RTLIL::IdString indexed_name = stringf("%s[%d]", escaped_s, index);
|
||||
existing = mapped_mod->wire(indexed_name);
|
||||
name_ref = indexed_name(design, escaped_ref, index);
|
||||
existing = mapped_mod->wire(name_ref);
|
||||
if (!existing)
|
||||
mapped_mod->rename(wire, indexed_name);
|
||||
mapped_mod->rename(wire, name_ref);
|
||||
else {
|
||||
wire->port_output = false;
|
||||
existing->port_output = true;
|
||||
mapped_mod->connect(wire, existing);
|
||||
}
|
||||
log_debug(" -> %s\n", indexed_name);
|
||||
log_debug(" -> %s\n", design->twines.unescaped_str(name_ref));
|
||||
}
|
||||
|
||||
if (!existing) {
|
||||
auto r = wideports_cache.insert(escaped_s);
|
||||
auto r = wideports_cache.insert(escaped_ref);
|
||||
if (r.second) {
|
||||
r.first->second.first = index;
|
||||
r.first->second.second = index;
|
||||
@@ -171,35 +195,35 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
else if (type == "pseudopo") {
|
||||
std::string port;
|
||||
mf >> port;
|
||||
RTLIL::IdString escaped_p = RTLIL::escape_id(port);
|
||||
IdString escaped_p = ref_from_token(design, port);
|
||||
|
||||
log_assert(variable + co_count < output_count);
|
||||
RTLIL::IdString wire_name = stringf("$aiger$o%d", variable + co_count);
|
||||
IdString wire_name = design->twines.find(stringf("$aiger$o%d", variable + co_count));
|
||||
RTLIL::Wire* wire = mapped_mod->wire(wire_name);
|
||||
log_assert(wire);
|
||||
log_assert(wire->port_output);
|
||||
log_debug("Mapping pseudo output %s", wire);
|
||||
|
||||
pseudopos.insert({wire_name, PseudoPo{escaped_s, escaped_p, index}});
|
||||
log_debug(" -> %s.%s[%d]\n", escaped_s, escaped_p, index);
|
||||
pseudopos.insert({wire_name, PseudoPo{escaped_ref, escaped_p, index}});
|
||||
log_debug(" -> %s.%s[%d]\n", design->twines.unescaped_str(escaped_ref), design->twines.unescaped_str(escaped_p), index);
|
||||
}
|
||||
else if (type == "keepwire") {
|
||||
log_assert(variable + co_count < output_count);
|
||||
RTLIL::IdString wire_name = stringf("$aiger$o%d", variable + co_count);
|
||||
RTLIL::IdString wire_name = design->twines.add(stringf("$aiger$o%d", variable + co_count));
|
||||
RTLIL::Wire* wire = mapped_mod->wire(wire_name);
|
||||
log_assert(wire);
|
||||
log_assert(wire->port_output);
|
||||
log_debug("Mapping kept wire %s", wire);
|
||||
|
||||
keptwires.insert({wire_name, KeptWire{escaped_s, index}});
|
||||
log_debug(" -> %s[%d]\n", escaped_s, index);
|
||||
keptwires.insert({wire_name, KeptWire{escaped_ref, index}});
|
||||
log_debug(" -> %s[%d]\n", PooledName(design, escaped_ref), index);
|
||||
}
|
||||
else if (type == "box") {
|
||||
RTLIL::Cell* cell = mapped_mod->cell(stringf("$box%d", variable));
|
||||
RTLIL::Cell* cell = mapped_mod->cell(design->twines.find(stringf("$box%d", variable)));
|
||||
if (!cell)
|
||||
log_debug("Box %d (%s) no longer exists.\n", variable, escaped_s.unescape());
|
||||
log_debug("Box %d (%s) no longer exists.\n", variable, design->twines.unescaped_str(escaped_ref));
|
||||
else
|
||||
mapped_mod->rename(cell, escaped_s);
|
||||
mapped_mod->rename(cell, escaped_ref);
|
||||
}
|
||||
else
|
||||
log_error("Symbol type '%s' not recognised.\n", type);
|
||||
@@ -207,7 +231,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
}
|
||||
|
||||
for (auto &wp : wideports_cache) {
|
||||
auto name = wp.first;
|
||||
IdString name = wp.first;
|
||||
int min = wp.second.first;
|
||||
int max = wp.second.second;
|
||||
if (min == 0 && max == 0)
|
||||
@@ -215,13 +239,13 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
|
||||
RTLIL::Wire *wire = mapped_mod->wire(name);
|
||||
if (wire)
|
||||
mapped_mod->rename(wire, RTLIL::escape_id(stringf("%s[%d]", name, 0)));
|
||||
mapped_mod->rename(wire, indexed_name(design, name, 0));
|
||||
|
||||
// Do not make ports with a mix of input/output into
|
||||
// wide ports
|
||||
bool port_input = false, port_output = false;
|
||||
for (int i = min; i <= max; i++) {
|
||||
RTLIL::IdString other_name = name.str() + stringf("[%d]", i);
|
||||
IdString other_name = indexed_name(design, name, i);
|
||||
RTLIL::Wire *other_wire = mapped_mod->wire(other_name);
|
||||
if (other_wire) {
|
||||
port_input = port_input || other_wire->port_input;
|
||||
@@ -235,7 +259,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
wire->port_output = port_output;
|
||||
|
||||
for (int i = min; i <= max; i++) {
|
||||
RTLIL::IdString other_name = stringf("%s[%d]", name, i);
|
||||
IdString other_name = indexed_name(design, name, i);
|
||||
RTLIL::Wire *other_wire = mapped_mod->wire(other_name);
|
||||
if (other_wire) {
|
||||
other_wire->port_input = false;
|
||||
@@ -251,7 +275,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
mapped_mod->fixup_ports();
|
||||
|
||||
for (auto w : mapped_mod->wires()) {
|
||||
auto nw = module->addWire(remap_name(w->name), GetSize(w));
|
||||
auto nw = module->addWire(remap_ref(design, w->name), GetSize(w));
|
||||
nw->start_offset = w->start_offset;
|
||||
// Remove all (* init *) since they only exist on $_DFF_[NP]_
|
||||
w->attributes.erase(ID::init);
|
||||
@@ -328,7 +352,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
}
|
||||
|
||||
dict<SigBit, pool<IdString>> bit_drivers, bit_users;
|
||||
TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
|
||||
TopoSort<IdString> toposort;
|
||||
dict<RTLIL::Cell*,RTLIL::Cell*> not2drivers;
|
||||
dict<SigBit, std::vector<RTLIL::Cell*>> bit2sinks;
|
||||
|
||||
@@ -341,8 +365,8 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
SigBit D = mapped_cell->getPort(ID::D);
|
||||
SigBit Q = mapped_cell->getPort(ID::Q);
|
||||
if (D.wire)
|
||||
D.wire = module->wires_.at(remap_name(D.wire->name));
|
||||
Q.wire = module->wires_.at(remap_name(Q.wire->name));
|
||||
D.wire = module->wire(remap_ref(design, D.wire->name));
|
||||
Q.wire = module->wire(remap_ref(design, Q.wire->name));
|
||||
module->connect(Q, D);
|
||||
continue;
|
||||
}
|
||||
@@ -362,7 +386,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
|
||||
if (!a_bit.wire) {
|
||||
mapped_cell->setPort(ID::Y, module->addWire(NEW_ID));
|
||||
RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name));
|
||||
RTLIL::Wire *wire = module->wire(remap_ref(design, y_bit.wire->name));
|
||||
log_assert(wire);
|
||||
module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1);
|
||||
}
|
||||
@@ -374,20 +398,21 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
// find the driver LUT and clone that to guarantee that we won't
|
||||
// increase the max logic depth
|
||||
// (TODO: Optimise by not cloning unless will increase depth)
|
||||
RTLIL::IdString driver_name;
|
||||
std::string driver_name;
|
||||
if (GetSize(a_bit.wire) == 1)
|
||||
driver_name = stringf("$lut%s", a_bit.wire->name);
|
||||
else
|
||||
driver_name = stringf("$lut%s[%d]", a_bit.wire->name, a_bit.offset);
|
||||
driver_lut = mapped_mod->cell(driver_name);
|
||||
IdString driver_ref = design->twines.find(driver_name);
|
||||
driver_lut = driver_ref.empty() ? nullptr : mapped_mod->cell(driver_ref);
|
||||
}
|
||||
|
||||
if (!driver_lut) {
|
||||
// If a driver couldn't be found (could be from PI or box CI)
|
||||
// then implement using a LUT
|
||||
RTLIL::Cell *cell = module->addLut(remap_name(stringf("$lut%s", mapped_cell->name)),
|
||||
RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset),
|
||||
RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset),
|
||||
RTLIL::SigBit(module->wire(remap_ref(design, a_bit.wire->name)), a_bit.offset),
|
||||
RTLIL::SigBit(module->wire(remap_ref(design, y_bit.wire->name)), y_bit.offset),
|
||||
RTLIL::Const::from_string("01"));
|
||||
bit2sinks[cell->getPort(ID::A)].push_back(cell);
|
||||
cell_stats[ID($lut)]++;
|
||||
@@ -402,9 +427,9 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
unmapped_error(mapped_cell);
|
||||
|
||||
if (mapped_cell->type == ID($lut) || mapped_cell->get_bool_attribute(ID::abc9_cell)) {
|
||||
RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
|
||||
cell->parameters = mapped_cell->parameters;
|
||||
cell->attributes = mapped_cell->attributes;
|
||||
RTLIL::Cell *cell = module->addCell(remap_ref(design, mapped_cell->name), mapped_cell->type);
|
||||
RTLIL::copy_attr_dict(cell->parameters, mapped_cell->parameters, mapped_mod->design, design);
|
||||
RTLIL::copy_attr_dict(cell->attributes, mapped_cell->attributes, mapped_mod->design, design);
|
||||
|
||||
for (auto &mapped_conn : mapped_cell->connections()) {
|
||||
RTLIL::SigSpec newsig;
|
||||
@@ -413,7 +438,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
continue;
|
||||
//log_assert(c.width == 1);
|
||||
if (c.wire)
|
||||
c.wire = module->wires_.at(remap_name(c.wire->name));
|
||||
c.wire = module->wire(remap_ref(design, c.wire->name));
|
||||
newsig.append(c);
|
||||
}
|
||||
cell->setPort(mapped_conn.first, newsig);
|
||||
@@ -440,9 +465,9 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
SigBit I = mapped_cell->getPort(ID(i));
|
||||
SigBit O = mapped_cell->getPort(ID(o));
|
||||
if (I.wire)
|
||||
I.wire = module->wires_.at(remap_name(I.wire->name));
|
||||
I.wire = module->wire(remap_ref(design, I.wire->name));
|
||||
log_assert(O.wire);
|
||||
O.wire = module->wires_.at(remap_name(O.wire->name));
|
||||
O.wire = module->wire(remap_ref(design, O.wire->name));
|
||||
module->connect(O, I);
|
||||
continue;
|
||||
}
|
||||
@@ -452,9 +477,9 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
log_assert(mapped_cell->type == stringf("$__boxid%d", box_module->attributes.at(ID::abc9_box_id).as_int()));
|
||||
mapped_cell->type = existing_cell->type;
|
||||
|
||||
RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
|
||||
cell->parameters = existing_cell->parameters;
|
||||
cell->attributes = existing_cell->attributes;
|
||||
RTLIL::Cell *cell = module->addCell(remap_ref(design, mapped_cell->name), mapped_cell->type);
|
||||
RTLIL::copy_attr_dict(cell->parameters, existing_cell->parameters, existing_cell->module->design, design);
|
||||
RTLIL::copy_attr_dict(cell->attributes, existing_cell->attributes, existing_cell->module->design, design);
|
||||
module->swap_names(cell, existing_cell);
|
||||
boxes.insert(existing_cell);
|
||||
|
||||
@@ -483,7 +508,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
old_q = existing_cell->getPort(port_name);
|
||||
}
|
||||
auto new_q = outputs[0];
|
||||
new_q.wire = module->wires_.at(remap_name(new_q.wire->name));
|
||||
new_q.wire = module->wire(remap_ref(design, new_q.wire->name));
|
||||
module->connect(old_q, new_q);
|
||||
}
|
||||
else {
|
||||
@@ -516,7 +541,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
continue;
|
||||
//log_assert(c.width == 1);
|
||||
if (c.wire)
|
||||
c.wire = module->wires_.at(remap_name(c.wire->name));
|
||||
c.wire = module->wire(remap_ref(design, c.wire->name));
|
||||
newsig.append(c);
|
||||
}
|
||||
|
||||
@@ -539,21 +564,21 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
if (!conn.first.is_fully_const()) {
|
||||
std::vector<RTLIL::SigChunk> chunks = conn.first.chunks();
|
||||
for (auto &c : chunks)
|
||||
c.wire = module->wires_.at(remap_name(c.wire->name));
|
||||
c.wire = module->wire(remap_ref(design, c.wire->name));
|
||||
conn.first = std::move(chunks);
|
||||
}
|
||||
if (!conn.second.is_fully_const()) {
|
||||
std::vector<RTLIL::SigChunk> chunks = conn.second.chunks();
|
||||
for (auto &c : chunks)
|
||||
if (c.wire)
|
||||
c.wire = module->wires_.at(remap_name(c.wire->name));
|
||||
c.wire = module->wire(remap_ref(design, c.wire->name));
|
||||
conn.second = std::move(chunks);
|
||||
}
|
||||
module->connect(conn);
|
||||
}
|
||||
|
||||
for (auto &it : cell_stats)
|
||||
log("ABC RESULTS: %15s cells: %8d\n", it.first, it.second);
|
||||
log("ABC RESULTS: %15s cells: %8d\n", design->twines.str(it.first), it.second);
|
||||
int in_wires = 0, out_wires = 0;
|
||||
|
||||
for (auto pseudopo : pseudopos) {
|
||||
@@ -566,7 +591,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
log_assert(box);
|
||||
|
||||
// replace only the driven bit
|
||||
RTLIL::Wire *remap_wire = module->wire(remap_name(wire_name));
|
||||
RTLIL::Wire *remap_wire = module->wire(remap_ref(design, wire_name));
|
||||
RTLIL::SigSpec port = box->getPort(target.port);
|
||||
log_assert(target.offset < GetSize(port));
|
||||
port[target.offset] = remap_wire;
|
||||
@@ -579,7 +604,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
for (auto &[wire_name, kept] : keptwires) {
|
||||
RTLIL::Wire *mapped_wire = mapped_mod->wire(wire_name);
|
||||
log_assert(mapped_wire);
|
||||
RTLIL::Wire *remap_wire = module->wire(remap_name(wire_name));
|
||||
RTLIL::Wire *remap_wire = module->wire(remap_ref(design, wire_name));
|
||||
log_assert(remap_wire);
|
||||
|
||||
RTLIL::Wire *wire = module->wire(kept.wire);
|
||||
@@ -597,7 +622,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
RTLIL::Wire *wire = module->wire(port);
|
||||
log_assert(wire);
|
||||
|
||||
RTLIL::Wire *remap_wire = module->wire(remap_name(port));
|
||||
RTLIL::Wire *remap_wire = module->wire(remap_ref(design, mapped_wire->name));
|
||||
RTLIL::SigSpec signal(wire, remap_wire->start_offset-wire->start_offset, GetSize(remap_wire));
|
||||
log_assert(GetSize(signal) >= GetSize(remap_wire));
|
||||
|
||||
@@ -648,8 +673,8 @@ void reintegrate(RTLIL::Module *module, bool dff_mode, bool stdcell_mode, std::s
|
||||
RTLIL::SigBit y_bit = not_cell->getPort(ID::Y);
|
||||
RTLIL::Const driver_mask;
|
||||
|
||||
a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name));
|
||||
y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name));
|
||||
a_bit.wire = module->wire(remap_ref(design, a_bit.wire->name));
|
||||
y_bit.wire = module->wire(remap_ref(design, y_bit.wire->name));
|
||||
|
||||
auto jt = bit2sinks.find(a_bit);
|
||||
if (jt == bit2sinks.end())
|
||||
@@ -698,7 +723,7 @@ clone_lut:
|
||||
y_bit,
|
||||
driver_mask);
|
||||
for (auto &bit : cell->connections_.at(ID::A)) {
|
||||
bit.wire = module->wires_.at(remap_name(bit.wire->name));
|
||||
bit.wire = module->wire(remap_ref(design, bit.wire->name));
|
||||
bit2sinks[bit].push_back(cell);
|
||||
}
|
||||
}
|
||||
|
||||
+22
-19
@@ -52,10 +52,10 @@ bool string_compare_nocase(const string &str1, const string &str2)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_name(string &name, IdString &id, bool ignore_case=false)
|
||||
bool match_name(string &name, const string &id, bool ignore_case=false)
|
||||
{
|
||||
string str1 = RTLIL::escape_id(name);
|
||||
string str2 = id.str();
|
||||
string str2 = id;
|
||||
|
||||
if (ignore_case)
|
||||
return string_compare_nocase(str1, str2);
|
||||
@@ -76,12 +76,12 @@ bool match_value(string &value, Const &val, bool ignore_case=false)
|
||||
|
||||
struct AttrmapAction {
|
||||
virtual ~AttrmapAction() { }
|
||||
virtual bool apply(IdString &id, Const &val) = 0;
|
||||
virtual bool apply(string &id, Const &val) = 0;
|
||||
};
|
||||
|
||||
struct AttrmapTocase : AttrmapAction {
|
||||
string name;
|
||||
bool apply(IdString &id, Const&) override {
|
||||
bool apply(string &id, Const&) override {
|
||||
if (match_name(name, id, true))
|
||||
id = RTLIL::escape_id(name);
|
||||
return true;
|
||||
@@ -90,7 +90,7 @@ struct AttrmapTocase : AttrmapAction {
|
||||
|
||||
struct AttrmapRename : AttrmapAction {
|
||||
string old_name, new_name;
|
||||
bool apply(IdString &id, Const&) override {
|
||||
bool apply(string &id, Const&) override {
|
||||
if (match_name(old_name, id))
|
||||
id = RTLIL::escape_id(new_name);
|
||||
return true;
|
||||
@@ -101,7 +101,7 @@ struct AttrmapMap : AttrmapAction {
|
||||
bool imap;
|
||||
string old_name, new_name;
|
||||
string old_value, new_value;
|
||||
bool apply(IdString &id, Const &val) override {
|
||||
bool apply(string &id, Const &val) override {
|
||||
if (match_name(old_name, id) && match_value(old_value, val, true)) {
|
||||
id = RTLIL::escape_id(new_name);
|
||||
val = make_value(new_value);
|
||||
@@ -113,31 +113,34 @@ struct AttrmapMap : AttrmapAction {
|
||||
struct AttrmapRemove : AttrmapAction {
|
||||
bool has_value;
|
||||
string name, value;
|
||||
bool apply(IdString &id, Const &val) override {
|
||||
bool apply(string &id, Const &val) override {
|
||||
return !(match_name(name, id) && (!has_value || match_value(value, val)));
|
||||
}
|
||||
};
|
||||
|
||||
void attrmap_apply(string objname, vector<std::unique_ptr<AttrmapAction>> &actions, dict<RTLIL::IdString, RTLIL::Const> &attributes)
|
||||
void attrmap_apply(RTLIL::Design *design, string objname, vector<std::unique_ptr<AttrmapAction>> &actions, dict<IdString, RTLIL::Const> &attributes)
|
||||
{
|
||||
dict<RTLIL::IdString, RTLIL::Const> new_attributes;
|
||||
|
||||
for (auto attr : attributes)
|
||||
{
|
||||
auto new_attr = attr;
|
||||
string old_name = design->twines.str(attr.first);
|
||||
string new_name = old_name;
|
||||
Const new_value = attr.second;
|
||||
for (auto &action : actions)
|
||||
if (!action->apply(new_attr.first, new_attr.second))
|
||||
if (!action->apply(new_name, new_value))
|
||||
goto delete_this_attr;
|
||||
|
||||
if (new_attr != attr)
|
||||
if (new_name != old_name || new_value != attr.second)
|
||||
log("Changed attribute on %s: %s=%s -> %s=%s\n", objname,
|
||||
attr.first.unescape(), log_const(attr.second), new_attr.first.unescape(), log_const(new_attr.second));
|
||||
RTLIL::unescape_id(old_name), log_const(attr.second),
|
||||
RTLIL::unescape_id(new_name), log_const(new_value));
|
||||
|
||||
new_attributes[new_attr.first] = new_attr.second;
|
||||
new_attributes[design->twines.add(std::move(new_name))] = new_value;
|
||||
|
||||
if (0)
|
||||
delete_this_attr:
|
||||
log("Removed attribute on %s: %s=%s\n", objname, attr.first.unescape(), log_const(attr.second));
|
||||
log("Removed attribute on %s: %s=%s\n", objname, RTLIL::unescape_id(old_name), log_const(attr.second));
|
||||
}
|
||||
|
||||
attributes.swap(new_attributes);
|
||||
@@ -264,14 +267,14 @@ struct AttrmapPass : public Pass {
|
||||
if (modattr_mode)
|
||||
{
|
||||
for (auto module : design->all_selected_whole_modules())
|
||||
attrmap_apply(stringf("%s", module), actions, module->attributes);
|
||||
attrmap_apply(design, stringf("%s", module), actions, module->attributes);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto module : design->all_selected_modules())
|
||||
{
|
||||
for (auto memb : module->selected_members())
|
||||
attrmap_apply(stringf("%s.%s", module, memb), actions, memb->attributes);
|
||||
attrmap_apply(design, stringf("%s.%s", module, design->obj_name(memb).c_str()), actions, memb->attributes);
|
||||
|
||||
// attrmap already applied to process itself during above loop, but not its children
|
||||
for (auto proc : module->selected_processes())
|
||||
@@ -280,10 +283,10 @@ struct AttrmapPass : public Pass {
|
||||
while (!all_cases.empty()) {
|
||||
RTLIL::CaseRule *cs = all_cases.back();
|
||||
all_cases.pop_back();
|
||||
attrmap_apply(stringf("%s.%s (case)", module, proc), actions, cs->attributes);
|
||||
attrmap_apply(design, stringf("%s.%s (case)", module, proc), actions, cs->attributes);
|
||||
|
||||
for (auto &sw : cs->switches) {
|
||||
attrmap_apply(stringf("%s.%s (switch)", module, proc), actions, sw->attributes);
|
||||
attrmap_apply(design, stringf("%s.%s (switch)", module, proc), actions, sw->attributes);
|
||||
all_cases.insert(all_cases.end(), sw->cases.begin(), sw->cases.end());
|
||||
}
|
||||
}
|
||||
@@ -328,7 +331,7 @@ struct ParamapPass : public Pass {
|
||||
|
||||
for (auto module : design->selected_modules())
|
||||
for (auto cell : module->selected_cells())
|
||||
attrmap_apply(stringf("%s.%s", module, cell), actions, cell->parameters);
|
||||
attrmap_apply(design, stringf("%s.%s", module, cell), actions, cell->parameters);
|
||||
}
|
||||
} ParamapPass;
|
||||
|
||||
|
||||
@@ -275,26 +275,26 @@ struct CellmatchPass : Pass {
|
||||
// Add target.module to map_design ("$cellmatch")
|
||||
// as a techmap rule to match m and replace it with target.module
|
||||
Module *map = map_design->addModule(stringf("\\_60_%s_%s", m, target.module));
|
||||
Cell *cell = map->addCell(ID::_TECHMAP_REPLACE_, target.module->name);
|
||||
Cell *cell = map->addCell(ID::_TECHMAP_REPLACE_, map_design->twines.copy_from(target.module->design->twines, target.module->name));
|
||||
|
||||
map->attributes[ID(techmap_celltype)] = m->name.str();
|
||||
|
||||
for (int i = 0; i < outputs.size(); i++) {
|
||||
log_assert(outputs[i].is_wire());
|
||||
Wire *w = map->addWire(outputs[i].wire->name, 1);
|
||||
Wire *w = map->addWire(map_design->twines.copy_from(m->design->twines, outputs[i].wire->name), 1);
|
||||
w->port_id = outputs[i].wire->port_id;
|
||||
w->port_output = true;
|
||||
log_assert(target_outputs[output_map[i]].is_wire());
|
||||
cell->setPort(target_outputs[output_map[i]].wire->name, w);
|
||||
cell->setPort(map_design->twines.copy_from(target.module->design->twines, target_outputs[output_map[i]].wire->name), w);
|
||||
}
|
||||
|
||||
for (int i = 0; i < inputs.size(); i++) {
|
||||
log_assert(inputs[i].is_wire());
|
||||
Wire *w = map->addWire(inputs[i].wire->name, 1);
|
||||
Wire *w = map->addWire(map_design->twines.copy_from(m->design->twines, inputs[i].wire->name), 1);
|
||||
w->port_id = inputs[i].wire->port_id;
|
||||
w->port_input = true;
|
||||
log_assert(target_inputs[input_map[i]].is_wire());
|
||||
cell->setPort(target_inputs[input_map[i]].wire->name, w);
|
||||
cell->setPort(map_design->twines.copy_from(target.module->design->twines, target_inputs[input_map[i]].wire->name), w);
|
||||
}
|
||||
|
||||
map->fixup_ports();
|
||||
|
||||
+19
-12
@@ -29,7 +29,7 @@ USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
struct cell_mapping {
|
||||
IdString cell_name;
|
||||
std::string cell_name;
|
||||
std::map<std::string, char> ports;
|
||||
};
|
||||
static std::map<RTLIL::IdString, cell_mapping> cell_mappings;
|
||||
@@ -37,9 +37,9 @@ static std::map<RTLIL::IdString, cell_mapping> cell_mappings;
|
||||
static void logmap(IdString dff)
|
||||
{
|
||||
if (cell_mappings.count(dff) == 0) {
|
||||
log(" unmapped dff/dlatch cell: %s\n", dff);
|
||||
log(" unmapped dff/dlatch cell: %s\n", ID::str(dff));
|
||||
} else {
|
||||
log(" %s %s (", cell_mappings[dff].cell_name, dff.substr(1));
|
||||
log(" %s %s (", cell_mappings[dff].cell_name, ID::str(dff).substr(1));
|
||||
bool first = true;
|
||||
for (auto &port : cell_mappings[dff].ports) {
|
||||
char arg[3] = { port.second, 0, 0 };
|
||||
@@ -423,12 +423,17 @@ static void find_cell(std::vector<const LibertyAst *> cells, IdString cell_type,
|
||||
}
|
||||
|
||||
if (best.cell != nullptr) {
|
||||
log(" cell %s (%s) is a direct match for cell type %s.\n", best.cell->args[0], best.rank.description(), cell_type);
|
||||
log(" cell %s (%s) is a direct match for cell type %s.\n", best.cell->args[0], best.rank.description(), ID::str(cell_type));
|
||||
cell_mappings[cell_type].cell_name = RTLIL::escape_id(best.cell->args[0]);
|
||||
cell_mappings[cell_type].ports = best.ports;
|
||||
}
|
||||
}
|
||||
|
||||
static IdString port_name_ref(TwinePool &twines, char port)
|
||||
{
|
||||
return twines.add(stringf("\\%c", port));
|
||||
}
|
||||
|
||||
static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module)
|
||||
{
|
||||
log("Mapping DFF/DLATCH cells in module `%s':\n", module->name);
|
||||
@@ -449,18 +454,20 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module)
|
||||
notmap[sigmap(cell->getPort(ID::A))].insert(cell);
|
||||
}
|
||||
|
||||
auto &twines = module->design->twines;
|
||||
|
||||
std::map<std::string, int> stats;
|
||||
for (auto cell : cell_list)
|
||||
{
|
||||
auto cell_type = cell->type;
|
||||
auto cell_name = cell->name;
|
||||
IdString cell_type = cell->type;
|
||||
IdString cell_name = cell->name;
|
||||
auto cell_connections = cell->connections();
|
||||
dict<RTLIL::IdString, RTLIL::Const> attributes = std::move(cell->attributes);
|
||||
|
||||
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(cell_name, twines.add(cm.cell_name));
|
||||
|
||||
new_cell->attributes = std::move(attributes);
|
||||
|
||||
@@ -473,10 +480,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[port_name_ref(twines, 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[port_name_ref(twines, char(port.second - ('a' - 'A')))];
|
||||
sig = module->addWire(NEW_ID, GetSize(old_sig));
|
||||
if (has_q && has_qn) {
|
||||
for (auto &it : notmap[sigmap(old_sig)]) {
|
||||
@@ -488,7 +495,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[port_name_ref(twines, char(port.second - ('a' - 'A')))];
|
||||
sig = module->NotGate(NEW_ID, sig);
|
||||
} else
|
||||
if (port.second == '0' || port.second == '1') {
|
||||
@@ -501,7 +508,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module)
|
||||
new_cell->setPort("\\" + port.first, sig);
|
||||
}
|
||||
|
||||
stats[stringf("%s cells to %s cells", cell_type, new_cell->type)]++;
|
||||
stats[stringf("%s cells to %s cells", twines.str(cell_type), new_cell->type.str())]++;
|
||||
}
|
||||
|
||||
for (auto &stat: stats)
|
||||
@@ -654,7 +661,7 @@ struct DfflibmapPass : public Pass {
|
||||
if (!map_only_mode) {
|
||||
std::string dfflegalize_cmd = "dfflegalize";
|
||||
for (auto it : cell_mappings)
|
||||
dfflegalize_cmd += stringf(" -cell %s 01", it.first);
|
||||
dfflegalize_cmd += stringf(" -cell %s 01", ID::str(it.first));
|
||||
dfflegalize_cmd += " t:$_DFF* t:$_SDFF* t:$_DLATCH*";
|
||||
if (info_mode) {
|
||||
log("dfflegalize command line: %s\n", dfflegalize_cmd);
|
||||
|
||||
+33
-31
@@ -50,9 +50,9 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
RTLIL::Const unified_param(RTLIL::IdString cell_type, RTLIL::IdString param, RTLIL::Const value)
|
||||
RTLIL::Const unified_param(const std::string &type_str, RTLIL::IdString param, RTLIL::Const value)
|
||||
{
|
||||
if (!cell_type.begins_with("$") || cell_type.begins_with("$_"))
|
||||
if (!type_str.starts_with("$") || type_str.starts_with("$_"))
|
||||
return value;
|
||||
|
||||
#define param_bool(_n) if (param == _n) return value.as_bool();
|
||||
@@ -105,12 +105,14 @@ public:
|
||||
|
||||
if (!ignore_parameters) {
|
||||
std::map<RTLIL::IdString, RTLIL::Const> needle_param, haystack_param;
|
||||
std::string needle_type = needleCell->type.str();
|
||||
std::string haystack_type = haystackCell->type.str();
|
||||
for (auto &it : needleCell->parameters)
|
||||
if (!ignored_parameters.count(std::pair<RTLIL::IdString, RTLIL::IdString>(needleCell->type, it.first)))
|
||||
needle_param[it.first] = unified_param(needleCell->type, it.first, it.second);
|
||||
needle_param[it.first] = unified_param(needle_type, it.first, it.second);
|
||||
for (auto &it : haystackCell->parameters)
|
||||
if (!ignored_parameters.count(std::pair<RTLIL::IdString, RTLIL::IdString>(haystackCell->type, it.first)))
|
||||
haystack_param[it.first] = unified_param(haystackCell->type, it.first, it.second);
|
||||
haystack_param[it.first] = unified_param(haystack_type, it.first, it.second);
|
||||
if (needle_param != haystack_param)
|
||||
return false;
|
||||
}
|
||||
@@ -127,7 +129,7 @@ public:
|
||||
for (auto &conn : needleCell->connections())
|
||||
{
|
||||
RTLIL::SigSpec needleSig = conn.second;
|
||||
RTLIL::SigSpec haystackSig = haystackCell->getPort(portMapping.at(conn.first.str()));
|
||||
RTLIL::SigSpec haystackSig = haystackCell->getPort(haystackCell->module->design->twines.add(std::string{portMapping.at(needleCell->module->design->twines.str(conn.first))}));
|
||||
|
||||
for (int i = 0; i < min(needleSig.size(), haystackSig.size()); i++) {
|
||||
RTLIL::Wire *needleWire = needleSig[i].wire, *haystackWire = haystackSig[i].wire;
|
||||
@@ -149,10 +151,11 @@ struct bit_ref_t {
|
||||
};
|
||||
|
||||
bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports, RTLIL::Design *sel = nullptr,
|
||||
int max_fanout = -1, std::set<std::pair<RTLIL::IdString, RTLIL::IdString>> *split = nullptr)
|
||||
int max_fanout = -1, std::set<std::pair<std::string, std::string>> *split = nullptr)
|
||||
{
|
||||
SigMap sigmap(mod);
|
||||
std::map<RTLIL::SigBit, bit_ref_t> sig_bit_ref;
|
||||
auto &tw = mod->design->twines;
|
||||
|
||||
if (sel && !sel->selected(mod)) {
|
||||
log(" Skipping module %s as it is not selected.\n", mod->name.unescape());
|
||||
@@ -206,9 +209,9 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
|
||||
|
||||
for (auto &conn : cell->connections())
|
||||
{
|
||||
graph.createPort(cell->name.str(), conn.first.str(), conn.second.size());
|
||||
graph.createPort(cell->name.str(), tw.str(conn.first), conn.second.size());
|
||||
|
||||
if (split && split->count(std::pair<RTLIL::IdString, RTLIL::IdString>(cell->type, conn.first)) > 0)
|
||||
if (split && split->count(std::pair<std::string, std::string>(cell->type.str(), tw.str(conn.first))) > 0)
|
||||
continue;
|
||||
|
||||
RTLIL::SigSpec conn_sig = conn.second;
|
||||
@@ -224,9 +227,9 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
|
||||
if (bit == RTLIL::State::S0) node = "$const$0";
|
||||
if (bit == RTLIL::State::S1) node = "$const$1";
|
||||
if (bit == RTLIL::State::Sz) node = "$const$z";
|
||||
graph.createConnection(cell->name.str(), conn.first.str(), i, node, "\\Y", 0);
|
||||
graph.createConnection(cell->name.str(), tw.str(conn.first), i, node, "\\Y", 0);
|
||||
} else
|
||||
graph.createConstant(cell->name.str(), conn.first.str(), i, int(bit.data));
|
||||
graph.createConstant(cell->name.str(), tw.str(conn.first), i, int(bit.data));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -239,12 +242,12 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
|
||||
if (sig_bit_ref.count(bit) == 0) {
|
||||
bit_ref_t &bit_ref = sig_bit_ref[bit];
|
||||
bit_ref.cell = cell->name.str();
|
||||
bit_ref.port = conn.first.str();
|
||||
bit_ref.port = tw.str(conn.first);
|
||||
bit_ref.bit = i;
|
||||
}
|
||||
|
||||
bit_ref_t &bit_ref = sig_bit_ref[bit];
|
||||
graph.createConnection(bit_ref.cell, bit_ref.port, bit_ref.bit, cell->name.str(), conn.first.str(), i);
|
||||
graph.createConnection(bit_ref.cell, bit_ref.port, bit_ref.bit, cell->name.str(), tw.str(conn.first), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -289,17 +292,18 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
|
||||
RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit::Solver::Result &match)
|
||||
{
|
||||
SigMap sigmap(needle);
|
||||
SigSet<std::pair<RTLIL::IdString, int>> sig2port;
|
||||
SigSet<std::pair<IdString, int>> sig2port;
|
||||
auto &tw = needle->design->twines;
|
||||
|
||||
// create new cell
|
||||
RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name, autoidx++), needle->name);
|
||||
RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name, autoidx++), haystack->design->twines.copy_from(tw, needle->name));
|
||||
|
||||
// create cell ports
|
||||
for (auto wire : needle->wires()) {
|
||||
if (wire->port_id > 0) {
|
||||
IdString portname = haystack->design->twines.add(tw.str(wire->name));
|
||||
for (int i = 0; i < wire->width; i++)
|
||||
sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair<RTLIL::IdString, int>(wire->name, i));
|
||||
cell->setPort(wire->name, RTLIL::SigSpec(RTLIL::State::Sz, wire->width));
|
||||
sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair<IdString, int>(portname, i));
|
||||
cell->setPort(portname, RTLIL::SigSpec(RTLIL::State::Sz, wire->width));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,10 +319,10 @@ RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit:
|
||||
|
||||
for (auto &conn : needle_cell->connections()) {
|
||||
RTLIL::SigSpec sig = sigmap(conn.second);
|
||||
if (mapping.portMapping.count(conn.first.str()) > 0 && sig2port.has(sigmap(sig))) {
|
||||
if (mapping.portMapping.count(tw.str(conn.first)) > 0 && sig2port.has(sigmap(sig))) {
|
||||
for (int i = 0; i < sig.size(); i++)
|
||||
for (auto &port : sig2port.find(sig[i])) {
|
||||
RTLIL::SigSpec bitsig = haystack_cell->getPort(mapping.portMapping[conn.first.str()]).extract(i, 1);
|
||||
RTLIL::SigSpec bitsig = haystack_cell->getPort(haystack_cell->module->design->twines.add(std::string{mapping.portMapping[tw.str(conn.first)]})).extract(i, 1);
|
||||
RTLIL::SigSpec new_sig = cell->getPort(port.first);
|
||||
new_sig.replace(port.second, bitsig);
|
||||
cell->setPort(port.first, new_sig);
|
||||
@@ -452,7 +456,7 @@ struct ExtractPass : public Pass {
|
||||
int mine_min_freq = 10;
|
||||
int mine_limit_mod = -1;
|
||||
int mine_max_fanout = -1;
|
||||
std::set<std::pair<RTLIL::IdString, RTLIL::IdString>> mine_split;
|
||||
std::set<std::pair<std::string, std::string>> mine_split;
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++) {
|
||||
@@ -483,7 +487,7 @@ struct ExtractPass : public Pass {
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-mine_split" && argidx+2 < args.size()) {
|
||||
mine_split.insert(std::pair<RTLIL::IdString, RTLIL::IdString>(RTLIL::escape_id(args[argidx+1]), RTLIL::escape_id(args[argidx+2])));
|
||||
mine_split.insert(std::pair<std::string, std::string>(RTLIL::escape_id(args[argidx+1]), RTLIL::escape_id(args[argidx+2])));
|
||||
argidx += 2;
|
||||
continue;
|
||||
}
|
||||
@@ -540,11 +544,11 @@ struct ExtractPass : public Pass {
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-cell_attr" && argidx+1 < args.size()) {
|
||||
solver.cell_attr.insert(RTLIL::escape_id(args[++argidx]));
|
||||
solver.cell_attr.insert(design->twines.add(RTLIL::escape_id(args[++argidx])));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-wire_attr" && argidx+1 < args.size()) {
|
||||
solver.wire_attr.insert(RTLIL::escape_id(args[++argidx]));
|
||||
solver.wire_attr.insert(design->twines.add(RTLIL::escape_id(args[++argidx])));
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-ignore_parameters") {
|
||||
@@ -552,7 +556,7 @@ struct ExtractPass : public Pass {
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-ignore_param" && argidx+2 < args.size()) {
|
||||
solver.ignored_parameters.insert(std::pair<RTLIL::IdString, RTLIL::IdString>(RTLIL::escape_id(args[argidx+1]), RTLIL::escape_id(args[argidx+2])));
|
||||
solver.ignored_parameters.insert(std::pair<IdString, IdString>(design->twines.add(RTLIL::escape_id(args[argidx+1])), design->twines.add(RTLIL::escape_id(args[argidx+2]))));
|
||||
argidx += 2;
|
||||
continue;
|
||||
}
|
||||
@@ -596,7 +600,7 @@ struct ExtractPass : public Pass {
|
||||
}
|
||||
for (auto mod : saved_designs.at(filename.substr(1))->modules())
|
||||
if (!map->has(mod->name))
|
||||
map->add(mod->clone());
|
||||
mod->clone(map);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -715,12 +719,10 @@ struct ExtractPass : public Pass {
|
||||
wires.insert(chunk.wire);
|
||||
}
|
||||
|
||||
RTLIL::Module *newMod = new RTLIL::Module;
|
||||
newMod->name = stringf("\\needle%05d_%s_%dx", needleCounter++, haystack_map.at(result.graphId)->name.unescape(), result.totalMatchesAfterLimits);
|
||||
map->add(newMod);
|
||||
RTLIL::Module *newMod = map->addModule(stringf("\\needle%05d_%s_%dx", needleCounter++, haystack_map.at(result.graphId)->name.unescape(), result.totalMatchesAfterLimits));
|
||||
|
||||
for (auto wire : wires) {
|
||||
RTLIL::Wire *newWire = newMod->addWire(wire->name, wire->width);
|
||||
RTLIL::Wire *newWire = newMod->addWire(wire->name.unescape(), wire->width);
|
||||
newWire->port_input = true;
|
||||
newWire->port_output = true;
|
||||
}
|
||||
@@ -728,13 +730,13 @@ struct ExtractPass : public Pass {
|
||||
newMod->fixup_ports();
|
||||
|
||||
for (auto cell : cells) {
|
||||
RTLIL::Cell *newCell = newMod->addCell(cell->name, cell->type);
|
||||
RTLIL::Cell *newCell = newMod->addCell(cell->name.unescape(), cell->type.str());
|
||||
newCell->parameters = cell->parameters;
|
||||
for (auto &conn : cell->connections()) {
|
||||
std::vector<SigChunk> chunks = sigmap(conn.second);
|
||||
for (auto &chunk : chunks)
|
||||
if (chunk.wire != nullptr)
|
||||
chunk.wire = newMod->wire(chunk.wire->name);
|
||||
chunk.wire = newMod->wire(map->twines.add(chunk.wire->name.unescape()));
|
||||
newCell->setPort(conn.first, chunks);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,7 +438,7 @@ struct McmWorker {
|
||||
auto value = constant.try_as_int(is_signed);
|
||||
if (!value || *value == std::numeric_limits<int>::min()) {
|
||||
log_debug("Skipping constant multiplier %s: coefficient %s is outside the supported range.\n",
|
||||
log_id(cell), log_const(constant));
|
||||
cell, log_const(constant));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -479,7 +479,7 @@ struct McmWorker {
|
||||
int depth = graph.depth.at(odd) + (group.items[i].coefficient < 0 ? 1 : 0);
|
||||
if (depth > config.search.max_depth) {
|
||||
log_debug("Skipping constant multiplier %s: output negation exceeds depth %d.\n",
|
||||
log_id(group.items[i].cell), config.search.max_depth);
|
||||
group.items[i].cell, config.search.max_depth);
|
||||
continue;
|
||||
}
|
||||
plan.active_items.push_back(i);
|
||||
@@ -566,7 +566,7 @@ struct McmWorker {
|
||||
if (is_profitable(plan))
|
||||
return true;
|
||||
log_debug("Skipping MCM group in module %s: estimated bit cost %lld vs %lld "
|
||||
"does not meet %d%% minimum gain.\n", log_id(module), plan.shared_cost,
|
||||
"does not meet %d%% minimum gain.\n", module, plan.shared_cost,
|
||||
plan.independent_cost, config.min_gain);
|
||||
return false;
|
||||
}
|
||||
@@ -761,7 +761,7 @@ struct McmPass : public Pass {
|
||||
worker.run();
|
||||
if (worker.n_muls)
|
||||
log("Module %s: replaced %d constant multiplier(s) in %d group(s) "
|
||||
"with %d adder(s).\n", log_id(module), worker.n_muls, worker.n_groups, worker.n_adders);
|
||||
"with %d adder(s).\n", module, worker.n_muls, worker.n_groups, worker.n_adders);
|
||||
total_groups += worker.n_groups;
|
||||
total_muls += worker.n_muls;
|
||||
total_adders += worker.n_adders;
|
||||
|
||||
+178
-116
@@ -39,7 +39,7 @@ YOSYS_NAMESPACE_END
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
void apply_prefix(IdString prefix, IdString &id)
|
||||
void apply_prefix(const std::string &prefix, std::string &id)
|
||||
{
|
||||
if (id[0] == '\\')
|
||||
id = stringf("%s.%s", prefix, id.c_str()+1);
|
||||
@@ -47,17 +47,63 @@ void apply_prefix(IdString prefix, IdString &id)
|
||||
id = stringf("$techmap%s.%s", prefix, id);
|
||||
}
|
||||
|
||||
void apply_prefix(IdString prefix, RTLIL::SigSpec &sig, RTLIL::Module *module)
|
||||
struct PrefixApplier
|
||||
{
|
||||
vector<SigChunk> chunks = sig;
|
||||
for (auto &chunk : chunks)
|
||||
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);
|
||||
RTLIL::Design *dst;
|
||||
RTLIL::Design *src;
|
||||
IdString cell_name;
|
||||
IdString pub_prefix;
|
||||
IdString priv_prefix = IdString::Null;
|
||||
dict<IdString, IdString> memo;
|
||||
|
||||
PrefixApplier(RTLIL::Design *dst, IdString prefix, RTLIL::Design *src)
|
||||
: dst(dst), src(src), cell_name(prefix)
|
||||
{
|
||||
pub_prefix = dst->twines.add(Twine::Suffix{prefix, "."});
|
||||
}
|
||||
|
||||
IdString techmap_prefix()
|
||||
{
|
||||
if (priv_prefix == IdString::Null)
|
||||
priv_prefix = dst->twines.add("$techmap" + dst->twines.str(cell_name) + ".");
|
||||
return priv_prefix;
|
||||
}
|
||||
|
||||
IdString name(IdString obj_ref)
|
||||
{
|
||||
if (auto it = memo.find(obj_ref); it != memo.end())
|
||||
return it->second;
|
||||
|
||||
const TwineNode &node = src->twines[obj_ref];
|
||||
IdString result;
|
||||
if (node.is_suffix()) {
|
||||
const Twine::Suffix &sfx = node.suffix();
|
||||
IdString prefix = name(sfx.prefix.tag(obj_ref.isPublic()));
|
||||
result = dst->twines.add(Twine::Suffix{prefix, sfx.tail});
|
||||
} else {
|
||||
IdString prefix = obj_ref.isPublic() ? pub_prefix : techmap_prefix();
|
||||
result = dst->twines.add(Twine::Suffix{prefix, node.leaf()});
|
||||
}
|
||||
sig = chunks;
|
||||
memo[obj_ref] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
void apply(RTLIL::SigSpec &sig, RTLIL::Module *module)
|
||||
{
|
||||
vector<SigChunk> chunks = sig;
|
||||
for (auto &chunk : chunks)
|
||||
if (chunk.wire != nullptr) {
|
||||
IdString wire_ref = name(chunk.wire->name);
|
||||
log_assert(module->wire(wire_ref) != nullptr);
|
||||
chunk.wire = module->wire(wire_ref);
|
||||
}
|
||||
sig = chunks;
|
||||
}
|
||||
};
|
||||
|
||||
static RTLIL::Wire *map_port(RTLIL::Module *tpl, RTLIL::Design *src, IdString name)
|
||||
{
|
||||
return tpl->wire(tpl->design->twines.find(src->twines.str(name)));
|
||||
}
|
||||
|
||||
struct TechmapWorker
|
||||
@@ -75,7 +121,7 @@ struct TechmapWorker
|
||||
RTLIL::SigSpec value;
|
||||
};
|
||||
|
||||
typedef dict<IdString, std::vector<TechmapWireData>> TechmapWires;
|
||||
typedef dict<std::string, std::vector<TechmapWireData>> TechmapWires;
|
||||
|
||||
bool extern_mode = false;
|
||||
bool assert_mode = false;
|
||||
@@ -86,6 +132,7 @@ struct TechmapWorker
|
||||
std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose)
|
||||
{
|
||||
std::string constmap_info;
|
||||
auto &twines = cell->module->design->twines;
|
||||
dict<RTLIL::SigBit, std::pair<IdString, int>> connbits_map;
|
||||
|
||||
for (auto &conn : cell->connections())
|
||||
@@ -93,17 +140,17 @@ struct TechmapWorker
|
||||
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, conn.first.unescape(), log_signal(bit));
|
||||
constmap_info += stringf("|%s %d %d", conn.first.unescape(), 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, conn.first.unescape(),
|
||||
connbits_map.at(bit).second, connbits_map.at(bit).first.unescape());
|
||||
constmap_info += stringf("|%s %d %s %d", conn.first.unescape(), 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", conn.first.unescape(), i);
|
||||
constmap_info += stringf("|%s %d", twines.unescaped_str(conn.first).data(), i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +165,7 @@ struct TechmapWorker
|
||||
return result;
|
||||
|
||||
for (auto w : module->wires()) {
|
||||
if (*w->name.c_str() == '$')
|
||||
if (w->name.str()[0] == '$')
|
||||
continue;
|
||||
|
||||
if (w->name.contains("_TECHMAP_") && !w->name.contains("_TECHMAP_REPLACE_")) {
|
||||
@@ -146,7 +193,7 @@ struct TechmapWorker
|
||||
if (tpl->processes.size() != 0) {
|
||||
log("Technology map yielded processes:");
|
||||
for (auto &it : tpl->processes)
|
||||
log(" %s",it.first.unescape());
|
||||
log(" %s", PooledName(tpl, it.first).unescape());
|
||||
log("\n");
|
||||
if (autoproc_mode) {
|
||||
Pass::call_on_module(tpl->design, tpl, "proc");
|
||||
@@ -165,15 +212,19 @@ struct TechmapWorker
|
||||
break;
|
||||
}
|
||||
|
||||
dict<IdString, IdString> memory_renames;
|
||||
PrefixApplier ap(module->design, cell->name, tpl->design);
|
||||
|
||||
dict<std::string, std::string> 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);
|
||||
if (m->attributes.count(ID::src))
|
||||
std::string old_m_id = tpl->design->twines.str(it.first);
|
||||
std::string m_name_id = old_m_id;
|
||||
apply_prefix(cell->name, m_name_id);
|
||||
IdString m_ref = module->design->twines.add(std::string(m_name_id));
|
||||
RTLIL::Memory *m = module->addMemory(m_ref, it.second);
|
||||
if (m->has_attribute(ID::src))
|
||||
m->add_strpool_attribute(ID::src, extra_src_attrs);
|
||||
memory_renames[it.first] = m->name;
|
||||
memory_renames[old_m_id] = m_name_id;
|
||||
design->select(module, m);
|
||||
}
|
||||
|
||||
@@ -185,12 +236,13 @@ struct TechmapWorker
|
||||
{
|
||||
if (tpl_w->port_id > 0)
|
||||
{
|
||||
IdString posportname = stringf("$%d", tpl_w->port_id);
|
||||
positional_ports.emplace(posportname, tpl_w->name);
|
||||
IdString posportref = module->design->twines.add(std::string{stringf("$%d", tpl_w->port_id)});
|
||||
positional_ports.emplace(posportref, tpl_w->name);
|
||||
|
||||
IdString tpl_portname = module->design->twines.find(tpl_w->name.str());
|
||||
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_portname) || !GetSize(cell->getPort(tpl_portname))) &&
|
||||
(!cell->hasPort(posportref) || !GetSize(cell->getPort(posportref))))
|
||||
{
|
||||
if (sigmaps.count(tpl) == 0)
|
||||
sigmaps[tpl].set(tpl);
|
||||
@@ -200,16 +252,15 @@ struct TechmapWorker
|
||||
autopurge_tpl_bits.insert(bit);
|
||||
}
|
||||
}
|
||||
IdString w_name = tpl_w->name;
|
||||
apply_prefix(cell->name, w_name);
|
||||
RTLIL::Wire *w = module->wire(w_name);
|
||||
IdString w_ref = ap.name(tpl_w->name);
|
||||
RTLIL::Wire *w = module->wire(w_ref);
|
||||
if (w != nullptr) {
|
||||
temp_renamed_wires[w] = w->name;
|
||||
module->rename(w, NEW_ID);
|
||||
w = nullptr;
|
||||
}
|
||||
if (w == nullptr) {
|
||||
w = module->addWire(w_name, tpl_w);
|
||||
w = module->addWire(w_ref, tpl_w);
|
||||
w->port_input = false;
|
||||
w->port_output = false;
|
||||
w->port_id = 0;
|
||||
@@ -221,9 +272,9 @@ 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);
|
||||
std::string tpl_w_name = tpl_w->name.str();
|
||||
if (const char *p = strstr(tpl_w_name.c_str(), "_TECHMAP_REPLACE_.")) {
|
||||
Wire *replace_w = module->addWire(std::string(orig_cell_name) + (p + strlen("_TECHMAP_REPLACE_")), tpl_w);
|
||||
module->connect(replace_w, w);
|
||||
}
|
||||
}
|
||||
@@ -243,35 +294,37 @@ struct TechmapWorker
|
||||
for (auto &it : cell->connections())
|
||||
{
|
||||
IdString portname = it.first;
|
||||
RTLIL::Wire *w;
|
||||
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);
|
||||
w = tpl->wire(positional_ports.at(portname));
|
||||
else
|
||||
w = map_port(tpl, design, portname);
|
||||
if (w == nullptr || w->port_id == 0) {
|
||||
if (design->twines.str(portname).starts_with("$"))
|
||||
log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", PooledName(design, portname).unescape(), cell->name.unescape(), tpl->name.unescape());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (GetSize(it.second) == 0)
|
||||
continue;
|
||||
|
||||
RTLIL::Wire *w = tpl->wire(portname);
|
||||
RTLIL::SigSig c, extra_connect;
|
||||
|
||||
if (w->port_output && !w->port_input) {
|
||||
c.first = it.second;
|
||||
c.second = RTLIL::SigSpec(w);
|
||||
apply_prefix(cell->name, c.second, module);
|
||||
ap.apply(c.second, module);
|
||||
extra_connect.first = c.second;
|
||||
extra_connect.second = c.first;
|
||||
} else if (!w->port_output && w->port_input) {
|
||||
c.first = RTLIL::SigSpec(w);
|
||||
c.second = it.second;
|
||||
apply_prefix(cell->name, c.first, module);
|
||||
ap.apply(c.first, module);
|
||||
extra_connect.first = c.first;
|
||||
extra_connect.second = c.second;
|
||||
} else {
|
||||
SigSpec sig_tpl = w, sig_tpl_pf = w, sig_mod = it.second;
|
||||
apply_prefix(cell->name, sig_tpl_pf, module);
|
||||
ap.apply(sig_tpl_pf, module);
|
||||
for (int i = 0; i < GetSize(sig_tpl) && i < GetSize(sig_mod); i++) {
|
||||
if (tpl_written_bits.count(sig_tpl[i])) {
|
||||
c.first.append(sig_mod[i]);
|
||||
@@ -321,21 +374,22 @@ struct TechmapWorker
|
||||
|
||||
for (auto tpl_cell : tpl->cells())
|
||||
{
|
||||
IdString c_name = tpl_cell->name;
|
||||
bool techmap_replace_cell = c_name.ends_with("_TECHMAP_REPLACE_");
|
||||
bool techmap_replace_cell = tpl_cell->name.ends_with("_TECHMAP_REPLACE_");
|
||||
|
||||
std::string tpl_cell_name = tpl_cell->name.str();
|
||||
IdString c_ref;
|
||||
if (techmap_replace_cell)
|
||||
c_name = orig_cell_name;
|
||||
else if (const char *p = strstr(tpl_cell->name.c_str(), "_TECHMAP_REPLACE_."))
|
||||
c_name = stringf("%s%s", orig_cell_name, p + strlen("_TECHMAP_REPLACE_"));
|
||||
c_ref = module->design->twines.add(std::string{orig_cell_name});
|
||||
else if (const char *p = strstr(tpl_cell_name.c_str(), "_TECHMAP_REPLACE_."))
|
||||
c_ref = module->design->twines.add(stringf("%s%s", orig_cell_name, p + strlen("_TECHMAP_REPLACE_")));
|
||||
else
|
||||
apply_prefix(cell->name, c_name);
|
||||
c_ref = ap.name(tpl_cell->name);
|
||||
|
||||
RTLIL::Cell *c = module->addCell(c_name, tpl_cell);
|
||||
RTLIL::Cell *c = module->addCell(c_ref, 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));
|
||||
c->type = module->design->twines.add(std::string{RTLIL::escape_id(tpl_cell->get_string_attribute(ID::techmap_chtype))});
|
||||
c->attributes.erase(ID::techmap_chtype);
|
||||
}
|
||||
|
||||
@@ -357,7 +411,7 @@ struct TechmapWorker
|
||||
autopurge_ports.push_back(conn.first);
|
||||
} else {
|
||||
RTLIL::SigSpec new_conn = conn.second;
|
||||
apply_prefix(cell->name, new_conn, module);
|
||||
ap.apply(new_conn, module);
|
||||
port_signal_map.apply(new_conn);
|
||||
c->setPort(conn.first, std::move(new_conn));
|
||||
}
|
||||
@@ -367,11 +421,11 @@ struct TechmapWorker
|
||||
c->unsetPort(it2);
|
||||
|
||||
if (c->has_memid()) {
|
||||
IdString memid = c->getParam(ID::MEMID).decode_string();
|
||||
std::string memid = c->getParam(ID::MEMID).decode_string();
|
||||
log_assert(memory_renames.count(memid) != 0);
|
||||
c->setParam(ID::MEMID, Const(memory_renames[memid].str()));
|
||||
c->setParam(ID::MEMID, Const(memory_renames[memid]));
|
||||
} else if (c->is_mem_cell()) {
|
||||
IdString memid = c->getParam(ID::MEMID).decode_string();
|
||||
std::string memid = c->getParam(ID::MEMID).decode_string();
|
||||
apply_prefix(cell->name, memid);
|
||||
c->setParam(ID::MEMID, Const(memid.c_str()));
|
||||
}
|
||||
@@ -389,8 +443,8 @@ struct TechmapWorker
|
||||
|
||||
for (auto &it : tpl->connections()) {
|
||||
RTLIL::SigSig c = it;
|
||||
apply_prefix(cell->name.str(), c.first, module);
|
||||
apply_prefix(cell->name.str(), c.second, module);
|
||||
ap.apply(c.first, module);
|
||||
ap.apply(c.second, module);
|
||||
port_signal_map.apply(c.first);
|
||||
port_signal_map.apply(c.second);
|
||||
module->connect(c);
|
||||
@@ -449,7 +503,7 @@ struct TechmapWorker
|
||||
|
||||
for (auto &tpl_name : celltypeMap.at(cell->type)) {
|
||||
RTLIL::Module *tpl = map->module(tpl_name);
|
||||
RTLIL::Wire *port = tpl->wire(conn.first);
|
||||
RTLIL::Wire *port = map_port(tpl, design, conn.first);
|
||||
if (port && port->port_input)
|
||||
cell_to_inbit[cell].insert(sig.begin(), sig.end());
|
||||
if (port && port->port_output)
|
||||
@@ -477,8 +531,10 @@ struct TechmapWorker
|
||||
for (auto &tpl_name : celltypeMap.at(cell->type))
|
||||
{
|
||||
IdString derived_name = tpl_name;
|
||||
RTLIL::Module *tpl = map->module(tpl_name);
|
||||
dict<IdString, RTLIL::Const> parameters(cell->parameters);
|
||||
RTLIL::Module *tpl = map->module(derived_name);
|
||||
dict<IdString, RTLIL::Const> parameters;
|
||||
for (auto &p : cell->parameters)
|
||||
parameters[map->twines.copy_from(design->twines, p.first)] = p.second;
|
||||
|
||||
if (tpl->get_blackbox_attribute(ignore_wb))
|
||||
continue;
|
||||
@@ -501,13 +557,13 @@ struct TechmapWorker
|
||||
std::string m_name = stringf("$extern:%s:%s", extmapper_name, cell->type.unescape());
|
||||
|
||||
for (auto &c : cell->parameters)
|
||||
m_name += stringf(":%s=%s", c.first.unescape(), log_signal(c.second));
|
||||
m_name += stringf(":%s=%s", PooledName(cell->module, c.first).unescape(), 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(extmapper_design->twines.add(std::string{m_name}));
|
||||
|
||||
if (extmapper_module == nullptr)
|
||||
{
|
||||
@@ -519,7 +575,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(IdString{ID::Y}, IdString{ID::Q}))
|
||||
w->port_output = true;
|
||||
else
|
||||
w->port_input = true;
|
||||
@@ -540,7 +596,7 @@ struct TechmapWorker
|
||||
|
||||
if (extmapper_name == "maccmap") {
|
||||
log("Creating %s with maccmap.\n", extmapper_module);
|
||||
if (!extmapper_cell->type.in(ID($macc), ID($macc_v2)))
|
||||
if (!extmapper_cell->type.in(IdString{ID($macc)}, IdString{ID($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);
|
||||
@@ -555,7 +611,7 @@ struct TechmapWorker
|
||||
}
|
||||
}
|
||||
|
||||
cell->type = extmapper_module->name;
|
||||
cell->type = cell->module->design->twines.add(std::string{m_name});
|
||||
cell->parameters.clear();
|
||||
|
||||
if (!extern_mode || in_recursion) {
|
||||
@@ -601,13 +657,15 @@ struct TechmapWorker
|
||||
}
|
||||
|
||||
for (auto &conn : cell->connections()) {
|
||||
if (conn.first.begins_with("$"))
|
||||
if (!conn.first.isPublic())
|
||||
continue;
|
||||
if (tpl->wire(conn.first) != nullptr && tpl->wire(conn.first)->port_id > 0)
|
||||
RTLIL::Wire *tpl_port = map_port(tpl, design, conn.first);
|
||||
if (tpl_port != nullptr && tpl_port->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 = map->twines.copy_from(design->twines, 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) {
|
||||
@@ -621,21 +679,21 @@ struct TechmapWorker
|
||||
parameters.emplace(ID::_TECHMAP_CELLNAME_, cell->name.unescape());
|
||||
|
||||
for (auto &conn : cell->connections()) {
|
||||
if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", conn.first.unescape())) != 0) {
|
||||
if (tpl->avail_parameters.count(map->twines.add(stringf("\\_TECHMAP_CONSTMSK_%s_", design->twines.unescaped_str(conn.first)))) != 0) {
|
||||
std::vector<RTLIL::SigBit> v = sigmap(conn.second).to_sigbit_vector();
|
||||
for (auto &bit : v)
|
||||
bit = RTLIL::SigBit(bit.wire == nullptr ? RTLIL::State::S1 : RTLIL::State::S0);
|
||||
parameters.emplace(stringf("\\_TECHMAP_CONSTMSK_%s_", conn.first.unescape()), RTLIL::SigSpec(v).as_const());
|
||||
parameters.emplace(map->twines.add(stringf("\\_TECHMAP_CONSTMSK_%s_", design->twines.unescaped_str(conn.first))), RTLIL::SigSpec(v).as_const());
|
||||
}
|
||||
if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTVAL_%s_", conn.first.unescape())) != 0) {
|
||||
if (tpl->avail_parameters.count(map->twines.add(stringf("\\_TECHMAP_CONSTVAL_%s_", design->twines.unescaped_str(conn.first)))) != 0) {
|
||||
std::vector<RTLIL::SigBit> v = sigmap(conn.second).to_sigbit_vector();
|
||||
for (auto &bit : v)
|
||||
if (bit.wire != nullptr)
|
||||
bit = RTLIL::SigBit(RTLIL::State::Sx);
|
||||
parameters.emplace(stringf("\\_TECHMAP_CONSTVAL_%s_", conn.first.unescape()), RTLIL::SigSpec(v).as_const());
|
||||
parameters.emplace(map->twines.add(stringf("\\_TECHMAP_CONSTVAL_%s_", design->twines.unescaped_str(conn.first))), RTLIL::SigSpec(v).as_const());
|
||||
}
|
||||
if (tpl->avail_parameters.count(stringf("\\_TECHMAP_WIREINIT_%s_", conn.first.unescape())) != 0) {
|
||||
parameters.emplace(stringf("\\_TECHMAP_WIREINIT_%s_", conn.first.unescape()), initvals(conn.second));
|
||||
if (tpl->avail_parameters.count(map->twines.add(stringf("\\_TECHMAP_WIREINIT_%s_", design->twines.unescaped_str(conn.first)))) != 0) {
|
||||
parameters.emplace(map->twines.add(stringf("\\_TECHMAP_WIREINIT_%s_", design->twines.unescaped_str(conn.first))), initvals(conn.second));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,7 +706,7 @@ struct TechmapWorker
|
||||
unique_bit_id[RTLIL::State::Sz] = unique_bit_id_counter++;
|
||||
|
||||
for (auto &conn : cell->connections())
|
||||
if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", conn.first.unescape())) != 0) {
|
||||
if (tpl->avail_parameters.count(map->twines.add(stringf("\\_TECHMAP_CONNMAP_%s_", design->twines.unescaped_str(conn.first)))) != 0) {
|
||||
for (auto &bit : sigmap(conn.second))
|
||||
if (unique_bit_id.count(bit) == 0)
|
||||
unique_bit_id[bit] = unique_bit_id_counter++;
|
||||
@@ -665,7 +723,7 @@ struct TechmapWorker
|
||||
parameters[ID::_TECHMAP_BITS_CONNMAP_] = bits;
|
||||
|
||||
for (auto &conn : cell->connections())
|
||||
if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", conn.first.unescape())) != 0) {
|
||||
if (tpl->avail_parameters.count(map->twines.add(stringf("\\_TECHMAP_CONNMAP_%s_", design->twines.unescaped_str(conn.first)))) != 0) {
|
||||
SigSpec sm = sigmap(conn.second);
|
||||
RTLIL::Const::Builder builder(GetSize(sm) * bits);
|
||||
for (auto &bit : sm) {
|
||||
@@ -675,7 +733,7 @@ struct TechmapWorker
|
||||
val = val >> 1;
|
||||
}
|
||||
}
|
||||
parameters.emplace(stringf("\\_TECHMAP_CONNMAP_%s_", conn.first.unescape()), builder.build());
|
||||
parameters.emplace(map->twines.add(stringf("\\_TECHMAP_CONNMAP_%s_", design->twines.unescaped_str(conn.first))), builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -698,7 +756,7 @@ struct TechmapWorker
|
||||
}
|
||||
}
|
||||
|
||||
RTLIL::Module *constmapped_tpl = map->module(constmap_tpl_name(sigmap, tpl, cell, false));
|
||||
RTLIL::Module *constmapped_tpl = map->module(map->twines.add(std::string{constmap_tpl_name(sigmap, tpl, cell, false)}));
|
||||
if (constmapped_tpl != nullptr)
|
||||
tpl = constmapped_tpl;
|
||||
|
||||
@@ -707,7 +765,7 @@ struct TechmapWorker
|
||||
bool keep_running = true;
|
||||
techmap_do_cache[tpl] = true;
|
||||
|
||||
pool<IdString> techmap_wire_names;
|
||||
pool<std::string> techmap_wire_names;
|
||||
|
||||
while (keep_running)
|
||||
{
|
||||
@@ -724,7 +782,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(), elem.wire->name.unescape(), log_signal(value));
|
||||
PooledName(map, derived_name).unescape(), elem.wire->name.unescape().data(), log_signal(value));
|
||||
techmap_do_cache[tpl] = false;
|
||||
}
|
||||
}
|
||||
@@ -735,7 +793,7 @@ struct TechmapWorker
|
||||
|
||||
for (auto &it : twd)
|
||||
{
|
||||
if (!it.first.contains("_TECHMAP_DO_") || it.second.empty())
|
||||
if (!(it.first.find("_TECHMAP_DO_") != std::string::npos) || it.second.empty())
|
||||
continue;
|
||||
|
||||
auto &data = it.second.front();
|
||||
@@ -745,9 +803,9 @@ struct TechmapWorker
|
||||
|
||||
techmap_wire_names.erase(it.first);
|
||||
|
||||
const char *p = data.wire->name.c_str();
|
||||
const char *q = strrchr(p+1, '.');
|
||||
q = q ? q+1 : p+1;
|
||||
std::string final_id = data.wire->name.escaped();
|
||||
size_t last_dot = final_id.find_last_of('.');
|
||||
size_t split_idx = (last_dot != std::string::npos) ? (last_dot + 1) : 1;
|
||||
|
||||
std::string cmd_string = data.value.as_const().decode_string();
|
||||
|
||||
@@ -757,8 +815,8 @@ struct TechmapWorker
|
||||
cmd_string = cmd_string.substr(strlen("CONSTMAP; "));
|
||||
|
||||
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", new_tpl_name.unescape());
|
||||
IdString new_tpl_name = map->twines.add(constmap_tpl_name(sigmap, tpl, cell, true));
|
||||
log("Creating constmapped module `%s'.\n", PooledName(map, new_tpl_name).unescape());
|
||||
log_assert(map->module(new_tpl_name) == nullptr);
|
||||
|
||||
RTLIL::Module *new_tpl = map->addModule(new_tpl_name);
|
||||
@@ -793,7 +851,7 @@ struct TechmapWorker
|
||||
// Handle outputs first, as these cannot be remapped.
|
||||
for (auto &conn : cell->connections())
|
||||
{
|
||||
Wire *twire = tpl->wire(conn.first);
|
||||
Wire *twire = map_port(tpl, design, conn.first);
|
||||
if (!twire->port_output)
|
||||
continue;
|
||||
|
||||
@@ -807,7 +865,7 @@ struct TechmapWorker
|
||||
// Now handle inputs, remapping as necessary.
|
||||
for (auto &conn : cell->connections())
|
||||
{
|
||||
Wire *twire = tpl->wire(conn.first);
|
||||
Wire *twire = map_port(tpl, design, conn.first);
|
||||
if (twire->port_output)
|
||||
continue;
|
||||
|
||||
@@ -851,9 +909,11 @@ struct TechmapWorker
|
||||
|
||||
Pass::call_on_module(map, tpl, cmd_string);
|
||||
|
||||
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)
|
||||
log_assert(final_id.compare(split_idx, 12, "_TECHMAP_DO_") == 0);
|
||||
std::string new_name = final_id.substr(0, split_idx)
|
||||
+ "_TECHMAP_DONE_"
|
||||
+ final_id.substr(split_idx + 12);
|
||||
while (tpl->wire(tpl->design->twines.add(std::string{new_name})) != nullptr)
|
||||
new_name += "_";
|
||||
tpl->rename(data.wire->name, new_name);
|
||||
|
||||
@@ -864,8 +924,8 @@ 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", it.first.unescape());
|
||||
if (!it.first.ends_with("_TECHMAP_FAIL_") && (!it.first.starts_with("\\_TECHMAP_REMOVEINIT_") || !it.first.ends_with("_")) && !(it.first.find("_TECHMAP_DO_") != std::string::npos) && !(it.first.find("_TECHMAP_DONE_") != std::string::npos))
|
||||
log_error("Techmap yielded unknown config wire %s.\n", RTLIL::unescape_id(it.first));
|
||||
if (techmap_do_cache[tpl])
|
||||
for (auto &it2 : it.second)
|
||||
if (!it2.value.is_fully_const())
|
||||
@@ -874,7 +934,7 @@ struct TechmapWorker
|
||||
}
|
||||
|
||||
for (auto &it : techmap_wire_names)
|
||||
log_error("Techmap special wire %s disappeared. This is considered a fatal error.\n", it.unescape());
|
||||
log_error("Techmap special wire %s disappeared. This is considered a fatal error.\n", RTLIL::unescape_id(it));
|
||||
|
||||
if (recursive_mode) {
|
||||
if (log_continue) {
|
||||
@@ -897,11 +957,12 @@ struct TechmapWorker
|
||||
|
||||
TechmapWires twd = techmap_find_special_wires(tpl);
|
||||
for (auto &it : twd) {
|
||||
if (it.first.begins_with("\\_TECHMAP_REMOVEINIT_")) {
|
||||
if (it.first.starts_with("\\_TECHMAP_REMOVEINIT_")) {
|
||||
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);
|
||||
IdString wirename_ref = cell->module->design->twines.add(std::string{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++)
|
||||
@@ -914,9 +975,9 @@ struct TechmapWorker
|
||||
|
||||
if (extern_mode && !in_recursion)
|
||||
{
|
||||
std::string m_name = stringf("$extern:%s", tpl);
|
||||
std::string m_name = stringf("$extern:%s", tpl->name.unescape());
|
||||
|
||||
if (!design->module(m_name))
|
||||
if (!design->module(design->twines.add(std::string{m_name})))
|
||||
{
|
||||
RTLIL::Module *m = design->addModule(m_name);
|
||||
tpl->cloneInto(m);
|
||||
@@ -924,18 +985,18 @@ struct TechmapWorker
|
||||
module_queue.insert(m);
|
||||
}
|
||||
|
||||
log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix, module, cell, m_name);
|
||||
cell->type = m_name;
|
||||
log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix.c_str(), module->name.unescape(), cell->name.unescape(), m_name.c_str());
|
||||
cell->type = cell->module->design->twines.add(std::string{m_name});
|
||||
cell->parameters.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto msg = stringf("Using template %s for cells of type %s.", tpl, cell->type.unescape());
|
||||
auto msg = stringf("Using template %s for cells of type %s.", tpl->name.unescape(), 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.unescape(), tpl);
|
||||
log_debug("%s %s.%s (%s) using %s.\n", mapmsg_prefix.c_str(), module->name.unescape(), cell->name.unescape(), cell->type.unescape(), tpl->name.unescape());
|
||||
techmap_module_worker(design, module, cell, tpl);
|
||||
cell = nullptr;
|
||||
}
|
||||
@@ -1196,7 +1257,7 @@ struct TechmapPass : public Pass {
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-dont_map" && argidx+1 < args.size()) {
|
||||
dont_map.push_back(RTLIL::escape_id(args[++argidx]));
|
||||
dont_map.push_back(design->twines.add(RTLIL::escape_id(args[++argidx])));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@@ -1213,9 +1274,10 @@ struct TechmapPass : public Pass {
|
||||
delete map;
|
||||
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))
|
||||
map->add(mod->clone());
|
||||
auto saved = saved_designs.at(fn.substr(1));
|
||||
for (auto mod : saved->modules())
|
||||
if (!map->module(map->twines.copy_from(saved->twines, 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));
|
||||
}
|
||||
@@ -1236,7 +1298,7 @@ struct TechmapPass : public Pass {
|
||||
auto pos = name.find('[');
|
||||
if (pos == std::string::npos) {
|
||||
// No further expansion.
|
||||
celltypeMap[RTLIL::escape_id(name)].insert(module->name);
|
||||
celltypeMap[design->twines.add(RTLIL::escape_id(name))].insert(module->name);
|
||||
} else {
|
||||
// Expand [] in this name.
|
||||
auto epos = name.find(']', pos);
|
||||
@@ -1250,9 +1312,9 @@ struct TechmapPass : public Pass {
|
||||
}
|
||||
free(p);
|
||||
} else {
|
||||
IdString module_name = module->name.begins_with("\\$") ?
|
||||
std::string module_name = module->name.begins_with("\\$") ?
|
||||
module->name.substr(1) : module->name.str();
|
||||
celltypeMap[module_name].insert(module->name);
|
||||
celltypeMap[design->twines.add(std::move(module_name))].insert(module->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1262,11 +1324,11 @@ struct TechmapPass : public Pass {
|
||||
|
||||
log_debug("Cell type mappings to use:\n");
|
||||
for (auto &i : celltypeMap) {
|
||||
i.second.sort(RTLIL::sort_by_id_str());
|
||||
i.second.sort(RTLIL::sort_by_id_str(map->twines));
|
||||
std::string maps = "";
|
||||
for (auto &map : i.second)
|
||||
maps += stringf(" %s", map.unescape());
|
||||
log_debug(" %s:%s\n", i.first.unescape(), maps);
|
||||
for (auto &m : i.second)
|
||||
maps += stringf(" %s", PooledName(map, m).unescape());
|
||||
log_debug(" %s:%s\n", PooledName(design, i.first).unescape(), maps.c_str());
|
||||
}
|
||||
log_debug("\n");
|
||||
|
||||
|
||||
+30
-18
@@ -602,15 +602,19 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std::
|
||||
}
|
||||
|
||||
vlog_file << stringf(" %s_expr uut_expr(", uut_name);
|
||||
for (int i = 0; i < GetSize(gold_mod->ports); i++)
|
||||
vlog_file << stringf("%s.%s(%s%s)", i ? ", " : "", gold_mod->ports[i].unescape(), gold_mod->ports[i].unescape(),
|
||||
for (int i = 0; i < GetSize(gold_mod->ports); i++) {
|
||||
std::string port_name = gold_mod->design->twines.str(gold_mod->ports[i]);
|
||||
vlog_file << stringf("%s.%s(%s%s)", i ? ", " : "", port_name, port_name,
|
||||
gold_mod->wire(gold_mod->ports[i])->port_input ? "" : "_expr");
|
||||
}
|
||||
vlog_file << stringf(");\n");
|
||||
|
||||
vlog_file << stringf(" %s_expr uut_noexpr(", uut_name);
|
||||
for (int i = 0; i < GetSize(gold_mod->ports); i++)
|
||||
vlog_file << stringf("%s.%s(%s%s)", i ? ", " : "", gold_mod->ports[i].unescape(), gold_mod->ports[i].unescape(),
|
||||
for (int i = 0; i < GetSize(gold_mod->ports); i++) {
|
||||
std::string port_name = gold_mod->design->twines.str(gold_mod->ports[i]);
|
||||
vlog_file << stringf("%s.%s(%s%s)", i ? ", " : "", port_name, port_name,
|
||||
gold_mod->wire(gold_mod->ports[i])->port_input ? "" : "_noexpr");
|
||||
}
|
||||
vlog_file << stringf(");\n");
|
||||
|
||||
vlog_file << stringf(" task run;\n");
|
||||
@@ -1076,6 +1080,13 @@ struct TestCellPass : public Pass {
|
||||
cell_types[ID($_AOI4_)] = "ABCDYb";
|
||||
cell_types[ID($_OAI4_)] = "ABCDYb";
|
||||
|
||||
auto find_type = [&](const std::string &s) -> IdString {
|
||||
for (auto &it : cell_types)
|
||||
if (ID::str(it.first) == s)
|
||||
return it.first;
|
||||
return IdString::Null;
|
||||
};
|
||||
|
||||
for (; argidx < GetSize(args); argidx++)
|
||||
{
|
||||
if (args[argidx].rfind("-", 0) == 0)
|
||||
@@ -1091,29 +1102,30 @@ struct TestCellPass : public Pass {
|
||||
if (args[argidx].compare(0, 1, "/") == 0) {
|
||||
std::vector<IdString> new_selected_cell_types;
|
||||
for (auto it : selected_cell_types)
|
||||
if (it != args[argidx].substr(1))
|
||||
if (ID::str(it) != args[argidx].substr(1))
|
||||
new_selected_cell_types.push_back(it);
|
||||
new_selected_cell_types.swap(selected_cell_types);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cell_types.count(args[argidx]) == 0) {
|
||||
IdString arg_type = find_type(args[argidx]);
|
||||
if (arg_type == IdString::Null) {
|
||||
std::string cell_type_list;
|
||||
int charcount = 100;
|
||||
for (auto &it : cell_types) {
|
||||
if (charcount > 60) {
|
||||
cell_type_list += stringf("\n%s", it.first.unescape());
|
||||
cell_type_list += stringf("\n%s", ID::str(it.first).c_str());
|
||||
charcount = 0;
|
||||
} else
|
||||
cell_type_list += stringf(" %s", it.first.unescape());
|
||||
charcount += GetSize(it.first);
|
||||
cell_type_list += stringf(" %s", ID::str(it.first).c_str());
|
||||
charcount += GetSize(ID::str(it.first));
|
||||
}
|
||||
log_cmd_error("The cell type `%s' is currently not supported. Try one of these:%s\n",
|
||||
args[argidx].c_str(), cell_type_list.c_str());
|
||||
}
|
||||
|
||||
if (std::count(selected_cell_types.begin(), selected_cell_types.end(), args[argidx]) == 0)
|
||||
selected_cell_types.push_back(args[argidx]);
|
||||
if (std::count(selected_cell_types.begin(), selected_cell_types.end(), arg_type) == 0)
|
||||
selected_cell_types.push_back(arg_type);
|
||||
}
|
||||
|
||||
if (!rtlil_file.empty()) {
|
||||
@@ -1151,13 +1163,13 @@ struct TestCellPass : public Pass {
|
||||
bool is_unconverted = false;
|
||||
for (auto *mod : design->selected_modules())
|
||||
for (auto *cell : mod->selected_cells())
|
||||
if (!cell->type.in(ID::$_NOT_, ID::$_AND_)) {
|
||||
if (!cell->type.in(ID($_NOT_), ID($_AND_))) {
|
||||
is_unconverted = true;
|
||||
break;
|
||||
}
|
||||
if (is_unconverted) {
|
||||
// skip unconverted cells
|
||||
log_warning("Skipping %s\n", cell_type);
|
||||
log_warning("Skipping %s\n", ID::str(cell_type).c_str());
|
||||
delete design;
|
||||
break;
|
||||
} else {
|
||||
@@ -1165,7 +1177,7 @@ struct TestCellPass : public Pass {
|
||||
suffix = "aag";
|
||||
}
|
||||
}
|
||||
Pass::call(design, stringf("%s %s_%s_%05d.%s", writer, write_prefix, cell_type.c_str()+1, i, suffix));
|
||||
Pass::call(design, stringf("%s %s_%s_%05d.%s", writer, write_prefix, ID::str(cell_type).c_str()+1, i, suffix));
|
||||
} else if (edges) {
|
||||
Pass::call(design, "dump gold");
|
||||
run_edges_test(design, verbose);
|
||||
@@ -1180,7 +1192,7 @@ struct TestCellPass : public Pass {
|
||||
Pass::call(design, "dump gold");
|
||||
if (!nosat)
|
||||
Pass::call(design, "sat -verify -enable_undef -prove trigger 0 -show-inputs -show-outputs miter");
|
||||
std::string uut_name = stringf("uut_%s_%d", cell_type.substr(1), i);
|
||||
std::string uut_name = stringf("uut_%s_%d", ID::str(cell_type).substr(1), i);
|
||||
if (vlog_file.is_open()) {
|
||||
Pass::call(design, stringf("copy gold %s_expr; select %s_expr", uut_name, uut_name));
|
||||
Backend::backend_call(design, &vlog_file, "<test_cell -vlog>", "verilog -selected");
|
||||
@@ -1207,14 +1219,14 @@ struct TestCellPass : public Pass {
|
||||
// Expected to run once
|
||||
int num_cells_estimate = costs.get(uut);
|
||||
if (num_cells <= num_cells_estimate) {
|
||||
log_debug("Correct upper bound for %s: %d <= %d\n", cell_type, num_cells, num_cells_estimate);
|
||||
log_debug("Correct upper bound for %s: %d <= %d\n", design->twines.str(cell_type).c_str(), num_cells, num_cells_estimate);
|
||||
} else {
|
||||
failed++;
|
||||
if (worst_abs < num_cells - num_cells_estimate) {
|
||||
worst_abs = num_cells - num_cells_estimate;
|
||||
worst_rel = (float)(num_cells - num_cells_estimate) / (float)num_cells_estimate;
|
||||
}
|
||||
log_warning("Upper bound violated for %s: %d > %d\n", cell_type, num_cells, num_cells_estimate);
|
||||
log_warning("Upper bound violated for %s: %d > %d\n", design->twines.str(cell_type).c_str(), num_cells, num_cells_estimate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1224,7 +1236,7 @@ struct TestCellPass : public Pass {
|
||||
if (check_cost && failed) {
|
||||
log_warning("Cell type %s cost underestimated in %.1f%% cases "
|
||||
"with worst offender being by %d (%.1f%%)\n",
|
||||
cell_type.c_str(), 100 * (float)failed / (float)num_iter,
|
||||
ID::str(cell_type).c_str(), 100 * (float)failed / (float)num_iter,
|
||||
worst_abs, 100 * worst_rel);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user