Speed up simplemap_map by 11.6x by directly inserting the cell source attribute in the new object's 'attributes' map instead of calling set_attr_pool to create a new pool and then copying that. Based on a suggestion by Martin Poviser in a comment on https://github.com/YosysHQ/yosys/pull/3959

This commit is contained in:
Rasmus Munk Larsen 2023-09-29 10:53:37 -07:00 committed by Lofty
parent 98d2c9088a
commit abd9c51963
2 changed files with 252 additions and 250 deletions

View File

@ -18,10 +18,10 @@
*/ */
#include "simplemap.h" #include "simplemap.h"
#include "kernel/sigtools.h"
#include "kernel/ff.h" #include "kernel/ff.h"
#include <stdlib.h> #include "kernel/sigtools.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
USING_YOSYS_NAMESPACE USING_YOSYS_NAMESPACE
@ -36,7 +36,7 @@ void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell)
for (int i = 0; i < GetSize(sig_y); i++) { for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_)); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); gate->attributes[ID::src] = cell->attributes[ID::src];
gate->setPort(ID::A, sig_a[i]); gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::Y, sig_y[i]); gate->setPort(ID::Y, sig_y[i]);
} }
@ -64,16 +64,21 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
} }
IdString gate_type; IdString gate_type;
if (cell->type == ID($and)) gate_type = ID($_AND_); if (cell->type == ID($and))
if (cell->type == ID($or)) gate_type = ID($_OR_); gate_type = ID($_AND_);
if (cell->type == ID($xor)) gate_type = ID($_XOR_); if (cell->type == ID($or))
if (cell->type == ID($xnor)) gate_type = ID($_XNOR_); gate_type = ID($_OR_);
if (cell->type == ID($bweqx)) gate_type = ID($_XNOR_); if (cell->type == ID($xor))
gate_type = ID($_XOR_);
if (cell->type == ID($xnor))
gate_type = ID($_XNOR_);
if (cell->type == ID($bweqx))
gate_type = ID($_XNOR_);
log_assert(!gate_type.empty()); log_assert(!gate_type.empty());
for (int i = 0; i < GetSize(sig_y); i++) { for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); gate->attributes[ID::src] = cell->attributes[ID::src];
gate->setPort(ID::A, sig_a[i]); gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::B, sig_b[i]); gate->setPort(ID::B, sig_b[i]);
gate->setPort(ID::Y, sig_y[i]); gate->setPort(ID::Y, sig_y[i]);
@ -89,11 +94,16 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
return; return;
if (sig_a.size() == 0) { if (sig_a.size() == 0) {
if (cell->type == ID($reduce_and)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); if (cell->type == ID($reduce_and))
if (cell->type == ID($reduce_or)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size())));
if (cell->type == ID($reduce_xor)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); if (cell->type == ID($reduce_or))
if (cell->type == ID($reduce_xnor)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size()))); module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
if (cell->type == ID($reduce_bool)) module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size()))); if (cell->type == ID($reduce_xor))
module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
if (cell->type == ID($reduce_xnor))
module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(1, sig_y.size())));
if (cell->type == ID($reduce_bool))
module->connect(RTLIL::SigSig(sig_y, RTLIL::SigSpec(0, sig_y.size())));
return; return;
} }
@ -103,28 +113,31 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
} }
IdString gate_type; IdString gate_type;
if (cell->type == ID($reduce_and)) gate_type = ID($_AND_); if (cell->type == ID($reduce_and))
if (cell->type == ID($reduce_or)) gate_type = ID($_OR_); gate_type = ID($_AND_);
if (cell->type == ID($reduce_xor)) gate_type = ID($_XOR_); if (cell->type == ID($reduce_or))
if (cell->type == ID($reduce_xnor)) gate_type = ID($_XOR_); gate_type = ID($_OR_);
if (cell->type == ID($reduce_bool)) gate_type = ID($_OR_); if (cell->type == ID($reduce_xor))
gate_type = ID($_XOR_);
if (cell->type == ID($reduce_xnor))
gate_type = ID($_XOR_);
if (cell->type == ID($reduce_bool))
gate_type = ID($_OR_);
log_assert(!gate_type.empty()); log_assert(!gate_type.empty());
RTLIL::Cell *last_output_cell = NULL; RTLIL::Cell *last_output_cell = NULL;
while (sig_a.size() > 1) while (sig_a.size() > 1) {
{
RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig_a.size() / 2); RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig_a.size() / 2);
for (int i = 0; i < sig_a.size(); i += 2) for (int i = 0; i < sig_a.size(); i += 2) {
{
if (i + 1 == sig_a.size()) { if (i + 1 == sig_a.size()) {
sig_t.append(sig_a[i]); sig_t.append(sig_a[i]);
continue; continue;
} }
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); gate->attributes[ID::src] = cell->attributes[ID::src];
gate->setPort(ID::A, sig_a[i]); gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::B, sig_a[i + 1]); gate->setPort(ID::B, sig_a[i + 1]);
gate->setPort(ID::Y, sig_t[i / 2]); gate->setPort(ID::Y, sig_t[i / 2]);
@ -137,7 +150,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
if (cell->type == ID($reduce_xnor)) { if (cell->type == ID($reduce_xnor)) {
RTLIL::SigSpec sig_t = module->addWire(NEW_ID); RTLIL::SigSpec sig_t = module->addWire(NEW_ID);
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_)); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); gate->attributes[ID::src] = cell->attributes[ID::src];
gate->setPort(ID::A, sig_a); gate->setPort(ID::A, sig_a);
gate->setPort(ID::Y, sig_t); gate->setPort(ID::Y, sig_t);
last_output_cell = gate; last_output_cell = gate;
@ -153,19 +166,17 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell *cell) static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell *cell)
{ {
while (sig.size() > 1) while (sig.size() > 1) {
{
RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig.size() / 2); RTLIL::SigSpec sig_t = module->addWire(NEW_ID, sig.size() / 2);
for (int i = 0; i < sig.size(); i += 2) for (int i = 0; i < sig.size(); i += 2) {
{
if (i + 1 == sig.size()) { if (i + 1 == sig.size()) {
sig_t.append(sig[i]); sig_t.append(sig[i]);
continue; continue;
} }
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_OR_)); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_OR_));
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); gate->attributes[ID::src] = cell->attributes[ID::src];
gate->setPort(ID::A, sig[i]); gate->setPort(ID::A, sig[i]);
gate->setPort(ID::B, sig[i + 1]); gate->setPort(ID::B, sig[i + 1]);
gate->setPort(ID::Y, sig_t[i / 2]); gate->setPort(ID::Y, sig_t[i / 2]);
@ -194,7 +205,7 @@ void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell)
} }
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_)); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); gate->attributes[ID::src] = cell->attributes[ID::src];
gate->setPort(ID::A, sig_a); gate->setPort(ID::A, sig_a);
gate->setPort(ID::Y, sig_y); gate->setPort(ID::Y, sig_y);
} }
@ -218,12 +229,14 @@ void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell)
} }
IdString gate_type; IdString gate_type;
if (cell->type == ID($logic_and)) gate_type = ID($_AND_); if (cell->type == ID($logic_and))
if (cell->type == ID($logic_or)) gate_type = ID($_OR_); gate_type = ID($_AND_);
if (cell->type == ID($logic_or))
gate_type = ID($_OR_);
log_assert(!gate_type.empty()); log_assert(!gate_type.empty());
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type); RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); gate->attributes[ID::src] = cell->attributes[ID::src];
gate->setPort(ID::A, sig_a); gate->setPort(ID::A, sig_a);
gate->setPort(ID::B, sig_b); gate->setPort(ID::B, sig_b);
gate->setPort(ID::Y, sig_y); gate->setPort(ID::Y, sig_y);
@ -239,19 +252,22 @@ void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell)
RTLIL::SigSpec xor_out = module->addWire(NEW_ID, max(GetSize(sig_a), GetSize(sig_b))); RTLIL::SigSpec xor_out = module->addWire(NEW_ID, max(GetSize(sig_a), GetSize(sig_b)));
RTLIL::Cell *xor_cell = module->addXor(NEW_ID, sig_a, sig_b, xor_out, is_signed); RTLIL::Cell *xor_cell = module->addXor(NEW_ID, sig_a, sig_b, xor_out, is_signed);
xor_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); xor_cell->attributes[ID::src] = cell->attributes[ID::src];
// xor_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
simplemap_bitop(module, xor_cell); simplemap_bitop(module, xor_cell);
module->remove(xor_cell); module->remove(xor_cell);
RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID); RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID);
RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID, xor_out, reduce_out); RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID, xor_out, reduce_out);
reduce_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); reduce_cell->attributes[ID::src] = cell->attributes[ID::src];
// reduce_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
simplemap_reduce(module, reduce_cell); simplemap_reduce(module, reduce_cell);
module->remove(reduce_cell); module->remove(reduce_cell);
if (!is_ne) { if (!is_ne) {
RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID, reduce_out, sig_y); RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID, reduce_out, sig_y);
not_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); not_cell->attributes[ID::src] = cell->attributes[ID::src];
// not_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
simplemap_lognot(module, not_cell); simplemap_lognot(module, not_cell);
module->remove(not_cell); module->remove(not_cell);
} }
@ -265,7 +281,7 @@ void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell)
for (int i = 0; i < GetSize(sig_y); i++) { for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_)); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); gate->attributes[ID::src] = cell->attributes[ID::src];
gate->setPort(ID::A, sig_a[i]); gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::B, sig_b[i]); gate->setPort(ID::B, sig_b[i]);
gate->setPort(ID::S, cell->getPort(ID::S)); gate->setPort(ID::S, cell->getPort(ID::S));
@ -282,7 +298,7 @@ void simplemap_bwmux(RTLIL::Module *module, RTLIL::Cell *cell)
for (int i = 0; i < GetSize(sig_y); i++) { for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_)); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); gate->attributes[ID::src] = cell->attributes[ID::src];
gate->setPort(ID::A, sig_a[i]); gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::B, sig_b[i]); gate->setPort(ID::B, sig_b[i]);
gate->setPort(ID::S, sig_s[i]); gate->setPort(ID::S, sig_s[i]);
@ -298,7 +314,7 @@ void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell)
for (int i = 0; i < GetSize(sig_y); i++) { for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_TBUF_)); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_TBUF_));
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); gate->attributes[ID::src] = cell->attributes[ID::src];
gate->setPort(ID::A, sig_a[i]); gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::E, sig_e); gate->setPort(ID::E, sig_e);
gate->setPort(ID::Y, sig_y[i]); gate->setPort(ID::Y, sig_y[i]);
@ -316,7 +332,7 @@ void simplemap_bmux(RTLIL::Module *module, RTLIL::Cell *cell)
for (int i = 0; i < GetSize(new_data); i += width) { for (int i = 0; i < GetSize(new_data); i += width) {
for (int k = 0; k < width; k++) { for (int k = 0; k < width; k++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_)); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); gate->attributes[ID::src] = cell->attributes[ID::src];
gate->setPort(ID::A, data[i * 2 + k]); gate->setPort(ID::A, data[i * 2 + k]);
gate->setPort(ID::B, data[i * 2 + width + k]); gate->setPort(ID::B, data[i * 2 + width + k]);
gate->setPort(ID::S, sel[idx]); gate->setPort(ID::S, sel[idx]);
@ -339,7 +355,7 @@ void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell)
SigSpec new_lut_data = module->addWire(NEW_ID, GetSize(lut_data) / 2); SigSpec new_lut_data = module->addWire(NEW_ID, GetSize(lut_data) / 2);
for (int i = 0; i < GetSize(lut_data); i += 2) { for (int i = 0; i < GetSize(lut_data); i += 2) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_)); RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); gate->attributes[ID::src] = cell->attributes[ID::src];
gate->setPort(ID::A, lut_data[i]); gate->setPort(ID::A, lut_data[i]);
gate->setPort(ID::B, lut_data[i + 1]); gate->setPort(ID::B, lut_data[i + 1]);
gate->setPort(ID::S, lut_ctrl[idx]); gate->setPort(ID::S, lut_ctrl[idx]);

View File

@ -17,14 +17,14 @@
* *
*/ */
#include "kernel/yosys.h"
#include "kernel/utils.h"
#include "kernel/sigtools.h"
#include "kernel/ffinit.h" #include "kernel/ffinit.h"
#include "kernel/sigtools.h"
#include "kernel/utils.h"
#include "kernel/yosys.h"
#include "libs/sha1/sha1.h" #include "libs/sha1/sha1.h"
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "simplemap.h" #include "simplemap.h"
@ -60,8 +60,7 @@ void apply_prefix(IdString prefix, RTLIL::SigSpec &sig, RTLIL::Module *module)
sig = chunks; sig = chunks;
} }
struct TechmapWorker struct TechmapWorker {
{
dict<IdString, void (*)(RTLIL::Module *, RTLIL::Cell *)> simplemap_mappers; dict<IdString, void (*)(RTLIL::Module *, RTLIL::Cell *)> simplemap_mappers;
dict<std::pair<IdString, dict<IdString, RTLIL::Const>>, RTLIL::Module *> techmap_cache; dict<std::pair<IdString, dict<IdString, RTLIL::Const>>, RTLIL::Module *> techmap_cache;
dict<RTLIL::Module *, bool> techmap_do_cache; dict<RTLIL::Module *, bool> techmap_do_cache;
@ -99,8 +98,8 @@ struct TechmapWorker
if (verbose) if (verbose)
log(" Bit %d of port %s and bit %d of port %s are connected.\n", i, log_id(conn.first), log(" Bit %d of port %s and bit %d of port %s are connected.\n", i, log_id(conn.first),
connbits_map.at(bit).second, log_id(connbits_map.at(bit).first)); connbits_map.at(bit).second, log_id(connbits_map.at(bit).first));
constmap_info += stringf("|%s %d %s %d", log_id(conn.first), i, constmap_info += stringf("|%s %d %s %d", log_id(conn.first), i, log_id(connbits_map.at(bit).first),
log_id(connbits_map.at(bit).first), connbits_map.at(bit).second); connbits_map.at(bit).second);
} else { } else {
connbits_map.emplace(bit, std::make_pair(conn.first, i)); connbits_map.emplace(bit, std::make_pair(conn.first, i));
constmap_info += stringf("|%s %d", log_id(conn.first), i); constmap_info += stringf("|%s %d", log_id(conn.first), i);
@ -156,7 +155,6 @@ struct TechmapWorker
} }
std::string orig_cell_name; std::string orig_cell_name;
pool<string> extra_src_attrs = cell->get_strpool_attribute(ID::src);
orig_cell_name = cell->name.str(); orig_cell_name = cell->name.str();
for (auto tpl_cell : tpl->cells()) for (auto tpl_cell : tpl->cells())
@ -166,13 +164,12 @@ struct TechmapWorker
} }
dict<IdString, IdString> memory_renames; dict<IdString, IdString> memory_renames;
for (auto &it : tpl->memories) { for (auto &it : tpl->memories) {
IdString m_name = it.first; IdString m_name = it.first;
apply_prefix(cell->name, m_name); apply_prefix(cell->name, m_name);
RTLIL::Memory *m = module->addMemory(m_name, it.second); RTLIL::Memory *m = module->addMemory(m_name, it.second);
if (m->attributes.count(ID::src)) if (m->attributes.count(ID::src))
m->add_strpool_attribute(ID::src, extra_src_attrs); m->attributes[ID::src] = cell->attributes[ID::src];
memory_renames[it.first] = m->name; memory_renames[it.first] = m->name;
design->select(module, m); design->select(module, m);
} }
@ -181,17 +178,14 @@ struct TechmapWorker
dict<Wire *, IdString> temp_renamed_wires; dict<Wire *, IdString> temp_renamed_wires;
pool<SigBit> autopurge_tpl_bits; pool<SigBit> autopurge_tpl_bits;
for (auto tpl_w : tpl->wires()) for (auto tpl_w : tpl->wires()) {
{ if (tpl_w->port_id > 0) {
if (tpl_w->port_id > 0)
{
IdString posportname = stringf("$%d", tpl_w->port_id); IdString posportname = stringf("$%d", tpl_w->port_id);
positional_ports.emplace(posportname, tpl_w->name); positional_ports.emplace(posportname, tpl_w->name);
if (tpl_w->get_bool_attribute(ID::techmap_autopurge) && if (tpl_w->get_bool_attribute(ID::techmap_autopurge) &&
(!cell->hasPort(tpl_w->name) || !GetSize(cell->getPort(tpl_w->name))) && (!cell->hasPort(tpl_w->name) || !GetSize(cell->getPort(tpl_w->name))) &&
(!cell->hasPort(posportname) || !GetSize(cell->getPort(posportname)))) (!cell->hasPort(posportname) || !GetSize(cell->getPort(posportname)))) {
{
if (sigmaps.count(tpl) == 0) if (sigmaps.count(tpl) == 0)
sigmaps[tpl].set(tpl); sigmaps[tpl].set(tpl);
@ -217,7 +211,7 @@ struct TechmapWorker
if (tpl_w->get_bool_attribute(ID::_techmap_special_)) if (tpl_w->get_bool_attribute(ID::_techmap_special_))
w->attributes.clear(); w->attributes.clear();
if (w->attributes.count(ID::src)) if (w->attributes.count(ID::src))
w->add_strpool_attribute(ID::src, extra_src_attrs); w->attributes[ID::src] = cell->attributes[ID::src];
} }
design->select(module, w); design->select(module, w);
@ -240,14 +234,14 @@ struct TechmapWorker
SigMap port_signal_map; SigMap port_signal_map;
for (auto &it : cell->connections()) for (auto &it : cell->connections()) {
{
IdString portname = it.first; IdString portname = it.first;
if (positional_ports.count(portname) > 0) if (positional_ports.count(portname) > 0)
portname = positional_ports.at(portname); portname = positional_ports.at(portname);
if (tpl->wire(portname) == nullptr || tpl->wire(portname)->port_id == 0) { if (tpl->wire(portname) == nullptr || tpl->wire(portname)->port_id == 0) {
if (portname.begins_with("$")) if (portname.begins_with("$"))
log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", portname.c_str(), cell->name.c_str(), tpl->name.c_str()); log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", portname.c_str(), cell->name.c_str(),
tpl->name.c_str());
continue; continue;
} }
@ -297,8 +291,7 @@ struct TechmapWorker
if (w->port_output && !w->port_input) { if (w->port_output && !w->port_input) {
port_signal_map.add(c.second, c.first); port_signal_map.add(c.second, c.first);
} else } else if (!w->port_output && w->port_input) {
if (!w->port_output && w->port_input) {
port_signal_map.add(c.first, c.second); port_signal_map.add(c.first, c.second);
} else { } else {
module->connect(c); module->connect(c);
@ -319,8 +312,7 @@ struct TechmapWorker
} }
} }
for (auto tpl_cell : tpl->cells()) for (auto tpl_cell : tpl->cells()) {
{
IdString c_name = tpl_cell->name; IdString c_name = tpl_cell->name;
bool techmap_replace_cell = c_name.ends_with("_TECHMAP_REPLACE_"); bool techmap_replace_cell = c_name.ends_with("_TECHMAP_REPLACE_");
@ -339,8 +331,7 @@ struct TechmapWorker
vector<IdString> autopurge_ports; vector<IdString> autopurge_ports;
for (auto &conn : c->connections()) for (auto &conn : c->connections()) {
{
bool autopurge = false; bool autopurge = false;
if (!autopurge_tpl_bits.empty()) { if (!autopurge_tpl_bits.empty()) {
autopurge = GetSize(conn.second) != 0; autopurge = GetSize(conn.second) != 0;
@ -375,7 +366,7 @@ struct TechmapWorker
} }
if (c->attributes.count(ID::src)) if (c->attributes.count(ID::src))
c->add_strpool_attribute(ID::src, extra_src_attrs); c->attributes[ID::src] = cell->attributes[ID::src];
if (techmap_replace_cell) { if (techmap_replace_cell) {
for (auto attr : cell->attributes) for (auto attr : cell->attributes)
@ -396,8 +387,7 @@ struct TechmapWorker
module->remove(cell); module->remove(cell);
for (auto &it : temp_renamed_wires) for (auto &it : temp_renamed_wires) {
{
Wire *w = it.first; Wire *w = it.first;
IdString name = it.second; IdString name = it.second;
IdString altname = module->uniquify(name); IdString altname = module->uniquify(name);
@ -426,8 +416,7 @@ struct TechmapWorker
dict<RTLIL::Cell *, pool<RTLIL::SigBit>> cell_to_inbit; dict<RTLIL::Cell *, pool<RTLIL::SigBit>> cell_to_inbit;
dict<RTLIL::SigBit, pool<RTLIL::Cell *>> outbit_to_cell; dict<RTLIL::SigBit, pool<RTLIL::Cell *>> outbit_to_cell;
for (auto cell : module->selected_cells()) for (auto cell : module->selected_cells()) {
{
if (handled_cells.count(cell) > 0) if (handled_cells.count(cell) > 0)
continue; continue;
@ -441,8 +430,7 @@ struct TechmapWorker
continue; continue;
} }
for (auto &conn : cell->connections()) for (auto &conn : cell->connections()) {
{
RTLIL::SigSpec sig = sigmap(conn.second); RTLIL::SigSpec sig = sigmap(conn.second);
sig.remove_const(); sig.remove_const();
@ -470,8 +458,7 @@ struct TechmapWorker
cells.sort(); cells.sort();
for (auto cell : cells.sorted) for (auto cell : cells.sorted) {
{
log_assert(handled_cells.count(cell) == 0); log_assert(handled_cells.count(cell) == 0);
log_assert(cell == module->cell(cell->name)); log_assert(cell == module->cell(cell->name));
bool mapped_cell = false; bool mapped_cell = false;
@ -481,8 +468,7 @@ struct TechmapWorker
if (in_recursion && cell->type.begins_with("\\$")) if (in_recursion && cell->type.begins_with("\\$"))
cell_type = cell_type.substr(1); cell_type = cell_type.substr(1);
for (auto &tpl_name : celltypeMap.at(cell_type)) for (auto &tpl_name : celltypeMap.at(cell_type)) {
{
IdString derived_name = tpl_name; IdString derived_name = tpl_name;
RTLIL::Module *tpl = map->module(tpl_name); RTLIL::Module *tpl = map->module(tpl_name);
dict<IdString, RTLIL::Const> parameters(cell->parameters); dict<IdString, RTLIL::Const> parameters(cell->parameters);
@ -501,12 +487,10 @@ struct TechmapWorker
if (tpl->attributes.count(ID::techmap_wrap)) if (tpl->attributes.count(ID::techmap_wrap))
extmapper_name = "wrap"; extmapper_name = "wrap";
if (!extmapper_name.empty()) if (!extmapper_name.empty()) {
{
cell->type = cell_type; cell->type = cell_type;
if ((extern_mode && !in_recursion) || extmapper_name == "wrap") if ((extern_mode && !in_recursion) || extmapper_name == "wrap") {
{
std::string m_name = stringf("$extern:%s:%s", extmapper_name.c_str(), log_id(cell->type)); std::string m_name = stringf("$extern:%s:%s", extmapper_name.c_str(), log_id(cell->type));
for (auto &c : cell->parameters) for (auto &c : cell->parameters)
@ -518,8 +502,7 @@ struct TechmapWorker
RTLIL::Design *extmapper_design = extern_mode && !in_recursion ? design : tpl->design; 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(m_name);
if (extmapper_module == nullptr) if (extmapper_module == nullptr) {
{
extmapper_module = extmapper_design->addModule(m_name); extmapper_module = extmapper_design->addModule(m_name);
RTLIL::Cell *extmapper_cell = extmapper_module->addCell(cell->type, cell); RTLIL::Cell *extmapper_cell = extmapper_module->addCell(cell->type, cell);
@ -542,7 +525,8 @@ struct TechmapWorker
if (extmapper_name == "simplemap") { if (extmapper_name == "simplemap") {
log("Creating %s with simplemap.\n", log_id(extmapper_module)); log("Creating %s with simplemap.\n", log_id(extmapper_module));
if (simplemap_mappers.count(extmapper_cell->type) == 0) if (simplemap_mappers.count(extmapper_cell->type) == 0)
log_error("No simplemap mapper for cell type %s found!\n", log_id(extmapper_cell->type)); log_error("No simplemap mapper for cell type %s found!\n",
log_id(extmapper_cell->type));
simplemap_mappers.at(extmapper_cell->type)(extmapper_module, extmapper_cell); simplemap_mappers.at(extmapper_cell->type)(extmapper_module, extmapper_cell);
extmapper_module->remove(extmapper_cell); extmapper_module->remove(extmapper_cell);
} }
@ -550,7 +534,8 @@ struct TechmapWorker
if (extmapper_name == "maccmap") { if (extmapper_name == "maccmap") {
log("Creating %s with maccmap.\n", log_id(extmapper_module)); log("Creating %s with maccmap.\n", log_id(extmapper_module));
if (extmapper_cell->type != ID($macc)) if (extmapper_cell->type != ID($macc))
log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(extmapper_cell->type)); log_error("The maccmap mapper can only map $macc (not %s) cells!\n",
log_id(extmapper_cell->type));
maccmap(extmapper_module, extmapper_cell); maccmap(extmapper_module, extmapper_cell);
extmapper_module->remove(extmapper_cell); extmapper_module->remove(extmapper_cell);
} }
@ -572,21 +557,23 @@ struct TechmapWorker
goto use_wrapper_tpl; goto use_wrapper_tpl;
} }
auto msg = stringf("Using extmapper %s for cells of type %s.", log_id(extmapper_module), log_id(cell->type)); auto msg =
stringf("Using extmapper %s for cells of type %s.", log_id(extmapper_module), log_id(cell->type));
if (!log_msg_cache.count(msg)) { if (!log_msg_cache.count(msg)) {
log_msg_cache.insert(msg); log_msg_cache.insert(msg);
log("%s\n", msg.c_str()); log("%s\n", msg.c_str());
} }
log_debug("%s %s.%s (%s) to %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), log_id(extmapper_module)); log_debug("%s %s.%s (%s) to %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell),
} log_id(cell->type), log_id(extmapper_module));
else } else {
{ auto msg =
auto msg = stringf("Using extmapper %s for cells of type %s.", extmapper_name.c_str(), log_id(cell->type)); stringf("Using extmapper %s for cells of type %s.", extmapper_name.c_str(), log_id(cell->type));
if (!log_msg_cache.count(msg)) { if (!log_msg_cache.count(msg)) {
log_msg_cache.insert(msg); log_msg_cache.insert(msg);
log("%s\n", msg.c_str()); log("%s\n", msg.c_str());
} }
log_debug("%s %s.%s (%s) with %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), extmapper_name.c_str()); log_debug("%s %s.%s (%s) with %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell),
log_id(cell->type), extmapper_name.c_str());
if (extmapper_name == "simplemap") { if (extmapper_name == "simplemap") {
if (simplemap_mappers.count(cell->type) == 0) if (simplemap_mappers.count(cell->type) == 0)
@ -596,7 +583,8 @@ struct TechmapWorker
if (extmapper_name == "maccmap") { if (extmapper_name == "maccmap") {
if (cell->type != ID($macc)) if (cell->type != ID($macc))
log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(cell->type)); log_error("The maccmap mapper can only map $macc (not %s) cells!\n",
log_id(cell->type));
maccmap(module, cell); maccmap(module, cell);
} }
@ -614,7 +602,8 @@ struct TechmapWorker
continue; continue;
if (tpl->wire(conn.first) != nullptr && tpl->wire(conn.first)->port_id > 0) if (tpl->wire(conn.first) != nullptr && tpl->wire(conn.first)->port_id > 0)
continue; continue;
if (!conn.second.is_fully_const() || parameters.count(conn.first) > 0 || tpl->avail_parameters.count(conn.first) == 0) if (!conn.second.is_fully_const() || parameters.count(conn.first) > 0 ||
tpl->avail_parameters.count(conn.first) == 0)
goto next_tpl; goto next_tpl;
parameters[conn.first] = conn.second.as_const(); parameters[conn.first] = conn.second.as_const();
} }
@ -634,14 +623,16 @@ struct TechmapWorker
std::vector<RTLIL::SigBit> v = sigmap(conn.second).to_sigbit_vector(); std::vector<RTLIL::SigBit> v = sigmap(conn.second).to_sigbit_vector();
for (auto &bit : v) for (auto &bit : v)
bit = RTLIL::SigBit(bit.wire == nullptr ? RTLIL::State::S1 : RTLIL::State::S0); bit = RTLIL::SigBit(bit.wire == nullptr ? RTLIL::State::S1 : RTLIL::State::S0);
parameters.emplace(stringf("\\_TECHMAP_CONSTMSK_%s_", log_id(conn.first)), RTLIL::SigSpec(v).as_const()); parameters.emplace(stringf("\\_TECHMAP_CONSTMSK_%s_", log_id(conn.first)),
RTLIL::SigSpec(v).as_const());
} }
if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTVAL_%s_", log_id(conn.first))) != 0) { if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTVAL_%s_", log_id(conn.first))) != 0) {
std::vector<RTLIL::SigBit> v = sigmap(conn.second).to_sigbit_vector(); std::vector<RTLIL::SigBit> v = sigmap(conn.second).to_sigbit_vector();
for (auto &bit : v) for (auto &bit : v)
if (bit.wire != nullptr) if (bit.wire != nullptr)
bit = RTLIL::SigBit(RTLIL::State::Sx); bit = RTLIL::SigBit(RTLIL::State::Sx);
parameters.emplace(stringf("\\_TECHMAP_CONSTVAL_%s_", log_id(conn.first)), RTLIL::SigSpec(v).as_const()); parameters.emplace(stringf("\\_TECHMAP_CONSTVAL_%s_", log_id(conn.first)),
RTLIL::SigSpec(v).as_const());
} }
if (tpl->avail_parameters.count(stringf("\\_TECHMAP_WIREINIT_%s_", log_id(conn.first))) != 0) { if (tpl->avail_parameters.count(stringf("\\_TECHMAP_WIREINIT_%s_", log_id(conn.first))) != 0) {
parameters.emplace(stringf("\\_TECHMAP_WIREINIT_%s_", log_id(conn.first)), initvals(conn.second)); parameters.emplace(stringf("\\_TECHMAP_WIREINIT_%s_", log_id(conn.first)), initvals(conn.second));
@ -710,15 +701,13 @@ struct TechmapWorker
if (constmapped_tpl != nullptr) if (constmapped_tpl != nullptr)
tpl = constmapped_tpl; tpl = constmapped_tpl;
if (techmap_do_cache.count(tpl) == 0) if (techmap_do_cache.count(tpl) == 0) {
{
bool keep_running = true; bool keep_running = true;
techmap_do_cache[tpl] = true; techmap_do_cache[tpl] = true;
pool<IdString> techmap_wire_names; pool<IdString> techmap_wire_names;
while (keep_running) while (keep_running) {
{
TechmapWires twd = techmap_find_special_wires(tpl); TechmapWires twd = techmap_find_special_wires(tpl);
keep_running = false; keep_running = false;
@ -731,7 +720,8 @@ struct TechmapWorker
for (const TechmapWireData &elem : it.second) { for (const TechmapWireData &elem : it.second) {
RTLIL::SigSpec value = elem.value; RTLIL::SigSpec value = elem.value;
if (value.is_fully_const() && value.as_bool()) { 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", log("Not using module `%s' from techmap as it contains a %s marker wire with "
"non-zero value %s.\n",
derived_name.c_str(), log_id(elem.wire->name), log_signal(value)); derived_name.c_str(), log_id(elem.wire->name), log_signal(value));
techmap_do_cache[tpl] = false; techmap_do_cache[tpl] = false;
} }
@ -741,15 +731,15 @@ struct TechmapWorker
if (!techmap_do_cache[tpl]) if (!techmap_do_cache[tpl])
break; break;
for (auto &it : twd) for (auto &it : twd) {
{
if (!it.first.contains("_TECHMAP_DO_") || it.second.empty()) if (!it.first.contains("_TECHMAP_DO_") || it.second.empty())
continue; continue;
auto &data = it.second.front(); auto &data = it.second.front();
if (!data.value.is_fully_const()) if (!data.value.is_fully_const())
log_error("Techmap yielded config wire %s with non-const value %s.\n", log_id(data.wire->name), log_signal(data.value)); log_error("Techmap yielded config wire %s with non-const value %s.\n",
log_id(data.wire->name), log_signal(data.value));
techmap_wire_names.erase(it.first); techmap_wire_names.erase(it.first);
@ -760,8 +750,7 @@ struct TechmapWorker
std::string cmd_string = data.value.as_const().decode_string(); std::string cmd_string = data.value.as_const().decode_string();
restart_eval_cmd_string: restart_eval_cmd_string:
if (cmd_string.rfind("CONSTMAP; ", 0) == 0) if (cmd_string.rfind("CONSTMAP; ", 0) == 0) {
{
cmd_string = cmd_string.substr(strlen("CONSTMAP; ")); cmd_string = cmd_string.substr(strlen("CONSTMAP; "));
log("Analyzing pattern of constant bits for this cell:\n"); log("Analyzing pattern of constant bits for this cell:\n");
@ -780,8 +769,7 @@ struct TechmapWorker
dict<RTLIL::SigBit, RTLIL::SigBit> port_connmap; dict<RTLIL::SigBit, RTLIL::SigBit> port_connmap;
dict<RTLIL::SigBit, RTLIL::SigBit> cellbits_to_tplbits; dict<RTLIL::SigBit, RTLIL::SigBit> cellbits_to_tplbits;
for (auto wire : tpl->wires().to_vector()) for (auto wire : tpl->wires().to_vector()) {
{
if (!wire->port_input || wire->port_output) if (!wire->port_input || wire->port_output)
continue; continue;
@ -793,14 +781,15 @@ struct TechmapWorker
wire->port_id = 0; wire->port_id = 0;
for (int i = 0; i < wire->width; i++) { for (int i = 0; i < wire->width; i++) {
port_new2old_map.emplace(RTLIL::SigBit(new_wire, i), RTLIL::SigBit(wire, i)); port_new2old_map.emplace(RTLIL::SigBit(new_wire, i),
port_connmap.emplace(RTLIL::SigBit(wire, i), RTLIL::SigBit(new_wire, i)); RTLIL::SigBit(wire, i));
port_connmap.emplace(RTLIL::SigBit(wire, i),
RTLIL::SigBit(new_wire, i));
} }
} }
// Handle outputs first, as these cannot be remapped. // Handle outputs first, as these cannot be remapped.
for (auto &conn : cell->connections()) for (auto &conn : cell->connections()) {
{
Wire *twire = tpl->wire(conn.first); Wire *twire = tpl->wire(conn.first);
if (!twire->port_output) if (!twire->port_output)
continue; continue;
@ -813,28 +802,22 @@ struct TechmapWorker
} }
// Now handle inputs, remapping as necessary. // Now handle inputs, remapping as necessary.
for (auto &conn : cell->connections()) for (auto &conn : cell->connections()) {
{
Wire *twire = tpl->wire(conn.first); Wire *twire = tpl->wire(conn.first);
if (twire->port_output) if (twire->port_output)
continue; continue;
for (int i = 0; i < GetSize(conn.second); i++) for (int i = 0; i < GetSize(conn.second); i++) {
{
RTLIL::SigBit bit = sigmap(conn.second[i]); RTLIL::SigBit bit = sigmap(conn.second[i]);
RTLIL::SigBit tplbit(twire, i); RTLIL::SigBit tplbit(twire, i);
if (bit.wire == nullptr) if (bit.wire == nullptr) {
{
RTLIL::SigBit oldbit = port_new2old_map.at(tplbit); RTLIL::SigBit oldbit = port_new2old_map.at(tplbit);
port_connmap.at(oldbit) = bit; port_connmap.at(oldbit) = bit;
} } else if (cellbits_to_tplbits.count(bit)) {
else if (cellbits_to_tplbits.count(bit))
{
RTLIL::SigBit oldbit = port_new2old_map.at(tplbit); RTLIL::SigBit oldbit = port_new2old_map.at(tplbit);
port_connmap.at(oldbit) = cellbits_to_tplbits[bit]; port_connmap.at(oldbit) = cellbits_to_tplbits[bit];
} } else
else
cellbits_to_tplbits[bit] = tplbit; cellbits_to_tplbits[bit] = tplbit;
} }
} }
@ -850,17 +833,18 @@ struct TechmapWorker
goto restart_eval_cmd_string; goto restart_eval_cmd_string;
} }
if (cmd_string.rfind("RECURSION; ", 0) == 0) if (cmd_string.rfind("RECURSION; ", 0) == 0) {
{
cmd_string = cmd_string.substr(strlen("RECURSION; ")); cmd_string = cmd_string.substr(strlen("RECURSION; "));
while (techmap_module(map, tpl, map, handled_cells, celltypeMap, true)) { } while (techmap_module(map, tpl, map, handled_cells, celltypeMap, true)) {
}
goto restart_eval_cmd_string; goto restart_eval_cmd_string;
} }
Pass::call_on_module(map, tpl, cmd_string); Pass::call_on_module(map, tpl, cmd_string);
log_assert(!strncmp(q, "_TECHMAP_DO_", 12)); 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); std::string new_name =
data.wire->name.substr(0, q - p) + "_TECHMAP_DONE_" + data.wire->name.substr(q - p + 12);
while (tpl->wire(new_name) != nullptr) while (tpl->wire(new_name) != nullptr)
new_name += "_"; new_name += "_";
tpl->rename(data.wire->name, new_name); tpl->rename(data.wire->name, new_name);
@ -872,12 +856,15 @@ struct TechmapWorker
TechmapWires twd = techmap_find_special_wires(tpl); TechmapWires twd = techmap_find_special_wires(tpl);
for (auto &it : twd) { 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_")) 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", log_id(it.first)); log_error("Techmap yielded unknown config wire %s.\n", log_id(it.first));
if (techmap_do_cache[tpl]) if (techmap_do_cache[tpl])
for (auto &it2 : it.second) for (auto &it2 : it.second)
if (!it2.value.is_fully_const()) if (!it2.value.is_fully_const())
log_error("Techmap yielded config wire %s with non-const value %s.\n", log_id(it2.wire->name), log_signal(it2.value)); log_error("Techmap yielded config wire %s with non-const value %s.\n",
log_id(it2.wire->name), log_signal(it2.value));
techmap_wire_names.erase(it.first); techmap_wire_names.erase(it.first);
} }
@ -890,7 +877,8 @@ struct TechmapWorker
log_continue = false; log_continue = false;
mkdebug.off(); mkdebug.off();
} }
while (techmap_module(map, tpl, map, handled_cells, celltypeMap, true)) { } while (techmap_module(map, tpl, map, handled_cells, celltypeMap, true)) {
}
} }
} }
@ -920,12 +908,10 @@ struct TechmapWorker
} }
} }
if (extern_mode && !in_recursion) if (extern_mode && !in_recursion) {
{
std::string m_name = stringf("$extern:%s", log_id(tpl)); std::string m_name = stringf("$extern:%s", log_id(tpl));
if (!design->module(m_name)) if (!design->module(m_name)) {
{
RTLIL::Module *m = design->addModule(m_name); RTLIL::Module *m = design->addModule(m_name);
tpl->cloneInto(m); tpl->cloneInto(m);
@ -940,15 +926,14 @@ struct TechmapWorker
log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(m_name)); log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(m_name));
cell->type = m_name; cell->type = m_name;
cell->parameters.clear(); cell->parameters.clear();
} } else {
else
{
auto msg = stringf("Using template %s for cells of type %s.", log_id(tpl), log_id(cell->type)); auto msg = stringf("Using template %s for cells of type %s.", log_id(tpl), log_id(cell->type));
if (!log_msg_cache.count(msg)) { if (!log_msg_cache.count(msg)) {
log_msg_cache.insert(msg); log_msg_cache.insert(msg);
log("%s\n", msg.c_str()); log("%s\n", msg.c_str());
} }
log_debug("%s %s.%s (%s) using %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), log_id(tpl)); log_debug("%s %s.%s (%s) using %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell),
log_id(cell->type), log_id(tpl));
techmap_module_worker(design, module, cell, tpl); techmap_module_worker(design, module, cell, tpl);
cell = nullptr; cell = nullptr;
} }
@ -1209,7 +1194,9 @@ struct TechmapPass : public Pass {
if (!map->module(mod->name)) if (!map->module(mod->name))
map->add(mod->clone()); map->add(mod->clone());
} else { } else {
Frontend::frontend_call(map, nullptr, fn, (fn.size() > 3 && fn.compare(fn.size()-3, std::string::npos, ".il") == 0 ? "rtlil" : verilog_frontend)); Frontend::frontend_call(
map, nullptr, fn,
(fn.size() > 3 && fn.compare(fn.size() - 3, std::string::npos, ".il") == 0 ? "rtlil" : verilog_frontend));
} }
} }
@ -1235,15 +1222,15 @@ struct TechmapPass : public Pass {
if (epos == std::string::npos) if (epos == std::string::npos)
log_error("Malformed techmap_celltype pattern %s\n", q); log_error("Malformed techmap_celltype pattern %s\n", q);
for (size_t i = pos + 1; i < epos; i++) { for (size_t i = pos + 1; i < epos; i++) {
queue.push_back(name.substr(0, pos) + name[i] + name.substr(epos + 1, std::string::npos)); queue.push_back(name.substr(0, pos) + name[i] +
name.substr(epos + 1, std::string::npos));
} }
} }
} }
} }
free(p); free(p);
} else { } else {
IdString module_name = module->name.begins_with("\\$") ? IdString module_name = module->name.begins_with("\\$") ? module->name.substr(1) : module->name.str();
module->name.substr(1) : module->name.str();
celltypeMap[module_name].insert(module->name); celltypeMap[module_name].insert(module->name);
} }
} }
@ -1260,8 +1247,7 @@ struct TechmapPass : public Pass {
for (auto module : design->modules()) for (auto module : design->modules())
worker.module_queue.insert(module); worker.module_queue.insert(module);
while (!worker.module_queue.empty()) while (!worker.module_queue.empty()) {
{
RTLIL::Module *module = *worker.module_queue.begin(); RTLIL::Module *module = *worker.module_queue.begin();
worker.module_queue.erase(module); worker.module_queue.erase(module);