3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-15 03:35:40 +00:00

WIP migration to twine

This commit is contained in:
Emil J. Tywoniak 2026-06-18 19:27:41 +02:00
parent 96b0ba9581
commit 0c450ce8c8
110 changed files with 1225 additions and 1082 deletions

View file

@ -619,7 +619,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.unescaped().c_str());
if (bit.wire->width != 1)
s += stringf("[%d]", bit.offset);
if (isnew)
@ -762,7 +762,7 @@ void AbcModuleState::handle_loops(AbcSigMap &assign_map, RTLIL::Module *module)
std::stringstream sstr;
sstr << "$abcloop$" << (autoidx++);
RTLIL::Wire *wire = module->addWire(sstr.str());
RTLIL::Wire *wire = module->addWire(Twine{sstr.str()});
bool first_line = true;
for (int id2 : edges[id1]) {
@ -982,31 +982,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 (module->wire(module->design->twines.add(std::string{RTLIL::escape_id(clk_str)})) != nullptr)
clk_sig = assign_map(module->wire(module->design->twines.add(std::string{RTLIL::escape_id(clk_str)})));
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 (module->wire(module->design->twines.add(std::string{RTLIL::escape_id(en_str)})) != nullptr)
en_sig = assign_map(module->wire(module->design->twines.add(std::string{RTLIL::escape_id(en_str)})));
}
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 (module->wire(module->design->twines.add(std::string{RTLIL::escape_id(arst_str)})) != nullptr)
arst_sig = assign_map(module->wire(module->design->twines.add(std::string{RTLIL::escape_id(arst_str)})));
}
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 (module->wire(module->design->twines.add(std::string{RTLIL::escape_id(srst_str)})) != nullptr)
srst_sig = assign_map(module->wire(module->design->twines.add(std::string{RTLIL::escape_id(srst_str)})));
}
}
@ -1021,7 +1021,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.str().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());
run_abc.abc_script = stringf("read_blif \"%s/input.blif\"; ", run_abc.per_run_tempdir_name);
@ -1539,18 +1539,19 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
bool builtin_lib = run_abc.config.liberty_files.empty() && run_abc.config.genlib_files.empty();
RTLIL::Design *mapped_design = new RTLIL::Design;
parse_blif(mapped_design, ifs, builtin_lib ? ID(DFF) : ID(_dff_), false, run_abc.config.sop_mode);
parse_blif(mapped_design, ifs, builtin_lib ? TW(DFF) : TW(_dff_), false, run_abc.config.sop_mode);
ifs.close();
log_header(design, "Re-integrating ABC results.\n");
RTLIL::Module *mapped_mod = mapped_design->module(ID(netlist));
auto rn = [&](RTLIL::IdString n) { return module->design->twines.add(std::string{remap_name(n)}); };
RTLIL::Module *mapped_mod = mapped_design->module(TW::netlist);
if (mapped_mod == nullptr)
log_error("ABC output file does not contain a module `netlist'.\n");
bool markgroups = run_abc.config.markgroups;
for (auto w : mapped_mod->wires()) {
RTLIL::Wire *orig_wire = nullptr;
RTLIL::Wire *wire = module->addWire(remap_name(w->name, &orig_wire));
RTLIL::Wire *wire = module->addWire(module->design->twines.add(std::string{remap_name(w->name, &orig_wire)}));
if (orig_wire != nullptr && orig_wire->src_id() != Twine::Null && module->design)
wire->set_src_id(orig_wire->src_id());
if (markgroups) wire->attributes[ID::abcgroup] = map_autoidx;
@ -1568,7 +1569,7 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
cell_stats[c->type.unescape()]++;
if (c->type.in(ID(ZERO), ID(ONE))) {
RTLIL::SigSig conn;
RTLIL::IdString name_y = remap_name(c->getPort(TW::Y).as_wire()->name);
TwineRef name_y = rn(c->getPort(TW::Y).as_wire()->name);
conn.first = module->wire(name_y);
conn.second = RTLIL::SigSpec(c->type == ID(ZERO) ? 0 : 1, 1);
connect(assign_map, module, conn);
@ -1576,89 +1577,89 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
}
if (c->type == ID(BUF)) {
RTLIL::SigSig conn;
RTLIL::IdString name_y = remap_name(c->getPort(TW::Y).as_wire()->name);
RTLIL::IdString name_a = remap_name(c->getPort(TW::A).as_wire()->name);
TwineRef name_y = rn(c->getPort(TW::Y).as_wire()->name);
TwineRef name_a = rn(c->getPort(TW::A).as_wire()->name);
conn.first = module->wire(name_y);
conn.second = module->wire(name_a);
connect(assign_map, module, conn);
continue;
}
if (c->type == ID(NOT)) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), TW($_NOT_));
RTLIL::Cell *cell = module->addCell(rn(c->name), TW($_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);
for (auto name : {TW::A, TW::Y}) {
TwineRef remapped_name = rn(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(rn(c->name), Twine{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);
for (auto name : {TW::A, TW::B, TW::Y}) {
TwineRef remapped_name = rn(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(rn(c->name), Twine{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);
for (auto name : {TW::A, TW::B, TW::S, TW::Y}) {
TwineRef remapped_name = rn(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), TW($_MUX4_));
RTLIL::Cell *cell = module->addCell(rn(c->name), TW($_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);
for (auto name : {TW::A, TW::B, TW::C, TW::D, TW::S, TW::T, TW::Y}) {
TwineRef remapped_name = rn(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), TW($_MUX8_));
RTLIL::Cell *cell = module->addCell(rn(c->name), TW($_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);
for (auto name : {TW::A, TW::B, TW::C, TW::D, TW::E, TW::F, TW::G, TW::H, TW::S, TW::T, TW::U, TW::Y}) {
TwineRef remapped_name = rn(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), TW($_MUX16_));
RTLIL::Cell *cell = module->addCell(rn(c->name), TW($_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);
for (auto name : {TW::A, TW::B, TW::C, TW::D, TW::E, TW::F, TW::G, TW::H, TW::I, TW::J, TW::K,
TW::L, TW::M, TW::N, TW::O, TW::P, TW::S, TW::T, TW::U, TW::V, TW::Y}) {
TwineRef remapped_name = rn(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(rn(c->name), Twine{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);
for (auto name : {TW::A, TW::B, TW::C, TW::Y}) {
TwineRef remapped_name = rn(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(rn(c->name), Twine{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);
for (auto name : {TW::A, TW::B, TW::C, TW::D, TW::Y}) {
TwineRef remapped_name = rn(c->getPort(name).as_wire()->name);
cell->setPort(name, module->wire(remapped_name));
}
design->select(module, cell);
@ -1697,8 +1698,8 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
ff.sig_srst = srst_sig;
ff.val_srst = init;
}
ff.sig_d = module->wire(remap_name(c->getPort(TW::D).as_wire()->name));
ff.sig_q = module->wire(remap_name(c->getPort(TW::Q).as_wire()->name));
ff.sig_d = module->wire(rn(c->getPort(TW::D).as_wire()->name));
ff.sig_q = module->wire(rn(c->getPort(TW::Q).as_wire()->name));
RTLIL::Cell *cell = ff.emit();
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
design->select(module, cell);
@ -1710,7 +1711,7 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
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(rn(c->connections().begin()->second.as_wire()->name));
conn.second = RTLIL::SigSpec(c->type == ID(_const0_) ? 0 : 1, 1);
connect(assign_map, module, conn);
continue;
@ -1746,8 +1747,8 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
ff.sig_srst = srst_sig;
ff.val_srst = init;
}
ff.sig_d = module->wire(remap_name(c->getPort(TW::D).as_wire()->name));
ff.sig_q = module->wire(remap_name(c->getPort(TW::Q).as_wire()->name));
ff.sig_d = module->wire(rn(c->getPort(TW::D).as_wire()->name));
ff.sig_q = module->wire(rn(c->getPort(TW::Q).as_wire()->name));
RTLIL::Cell *cell = ff.emit();
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
design->select(module, cell);
@ -1755,13 +1756,13 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
}
if (c->type == TW($lut) && GetSize(c->getPort(TW::A)) == 1 && c->getParam(ID::LUT).as_int() == 2) {
SigSpec my_a = module->wire(remap_name(c->getPort(TW::A).as_wire()->name));
SigSpec my_y = module->wire(remap_name(c->getPort(TW::Y).as_wire()->name));
SigSpec my_a = module->wire(rn(c->getPort(TW::A).as_wire()->name));
SigSpec my_y = module->wire(rn(c->getPort(TW::Y).as_wire()->name));
connect(assign_map, module, RTLIL::SigSig(my_a, my_y));
continue;
}
RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type);
RTLIL::Cell *cell = module->addCell(rn(c->name), c->type_impl);
if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->parameters = c->parameters;
for (auto &conn : c->connections()) {
@ -1770,7 +1771,7 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
if (c.width == 0)
continue;
log_assert(c.width == 1);
newsig.append(module->wire(remap_name(c.wire->name)));
newsig.append(module->wire(rn(c.wire->name)));
}
cell->setPort(conn.first, newsig);
}
@ -1779,9 +1780,9 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
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(rn(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(rn(conn.second.as_wire()->name));
connect(assign_map, module, conn);
}
@ -1796,10 +1797,10 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
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(rn(buffer));
out_wires++;
} else {
conn.first = module->wire(remap_name(buffer));
conn.first = module->wire(rn(buffer));
conn.second = signal_bits[si.id];
in_wires++;
}

View file

@ -318,12 +318,13 @@ struct Abc9Pass : public ScriptPass
}
else {
// Rename all submod-s to _TECHMAP_REPLACE_ to inherit name + attrs
TwineSearch search(&active_design->twines);
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.ref();
if (module->cell(search.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 = Twine::Null;
}
run("abc9_ops -prep_dff_unmap", " (only if -dff)");
run("design -copy-to $abc9 =*_$abc9_flop", " (only if -dff)"); // copy submod out

View file

@ -37,7 +37,7 @@ inline std::string remap_name(RTLIL::IdString abc9_name)
void check(RTLIL::Design *design, bool dff_mode)
{
dict<IdString,IdString> box_lookup;
dict<IdString,TwineRef> box_lookup;
for (auto m : design->modules()) {
auto flop = m->get_bool_attribute(ID::abc9_flop);
auto it = m->attributes.find(ID::abc9_box_id);
@ -45,7 +45,7 @@ void check(RTLIL::Design *design, bool dff_mode)
if (it == m->attributes.end())
continue;
auto id = it->second.as_int();
auto r = box_lookup.insert(std::make_pair(stringf("$__boxid%d", id), RTLIL::IdString(m->name)));
auto r = box_lookup.insert(std::make_pair(stringf("$__boxid%d", id), m->name.ref()));
if (!r.second)
log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n",
m, id, design->twines.unescaped_str(r.first->second));
@ -53,27 +53,27 @@ void check(RTLIL::Design *design, bool dff_mode)
// Make carry in the last PI, and carry out the last PO
// since ABC requires it this way
IdString carry_in, carry_out;
TwineRef carry_in = Twine::Null, carry_out = Twine::Null;
for (const auto &port_name : m->ports) {
auto w = m->wire(port_name);
log_assert(w);
if (w->get_bool_attribute(ID::abc9_carry)) {
if (w->port_input) {
if (carry_in != IdString())
if (carry_in != Twine::Null)
log_error("Module '%s' contains more than one (* abc9_carry *) input port.\n", m);
carry_in = port_name;
}
if (w->port_output) {
if (carry_out != IdString())
if (carry_out != Twine::Null)
log_error("Module '%s' contains more than one (* abc9_carry *) output port.\n", m);
carry_out = port_name;
}
}
}
if (carry_in != IdString() && carry_out == IdString())
if (carry_in != Twine::Null && carry_out == Twine::Null)
log_error("Module '%s' contains an (* abc9_carry *) input port but no output port.\n", m);
if (carry_in == IdString() && carry_out != IdString())
if (carry_in == Twine::Null && carry_out != Twine::Null)
log_error("Module '%s' contains an (* abc9_carry *) output port but no input port.\n", m);
if (flop) {
@ -88,7 +88,7 @@ void check(RTLIL::Design *design, bool dff_mode)
}
if (dff_mode) {
static pool<IdString> unsupported{
static pool<TwineRef> unsupported{
TW($adff), TW($dlatch), TW($dlatchsr), TW($sr),
TW($_DFF_NN0_), TW($_DFF_NN1_), TW($_DFF_NP0_), TW($_DFF_NP1_),
TW($_DFF_PN0_), TW($_DFF_PN1_), TW($_DFF_PP0_), TW($_DFF_PP1_),
@ -102,10 +102,10 @@ void check(RTLIL::Design *design, bool dff_mode)
auto inst_module = design->module(cell->type_impl);
if (!inst_module)
continue;
IdString derived_type;
TwineRef derived_type;
Module *derived_module;
if (cell->parameters.empty()) {
derived_type = cell->type;
derived_type = cell->type_impl;
derived_module = inst_module;
}
else {
@ -136,13 +136,13 @@ void check(RTLIL::Design *design, bool dff_mode)
log_assert(GetSize(Q.wire) == 1);
if (!Q.wire->port_output)
log_error("Whitebox '%s' with (* abc9_flop *) contains a %s cell where its 'Q' port does not drive a module output.\n", derived_module, design->twines.unescaped_str(derived_cell->type));
log_error("Whitebox '%s' with (* abc9_flop *) contains a %s cell where its 'Q' port does not drive a module output.\n", derived_module, derived_cell->type.unescape());
Const init = Q.wire->attributes.at(ID::init, State::Sx);
log_assert(GetSize(init) == 1);
}
else if (unsupported.count(derived_cell->type))
log_error("Whitebox '%s' with (* abc9_flop *) contains a %s cell, which is not supported for sequential synthesis.\n", derived_module, design->twines.unescaped_str(derived_cell->type));
else if (unsupported.count(derived_cell->type.ref()))
log_error("Whitebox '%s' with (* abc9_flop *) contains a %s cell, which is not supported for sequential synthesis.\n", derived_module, derived_cell->type.unescape());
}
}
}
@ -154,19 +154,20 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
if (r.second)
r.first->second = new Design;
Design *unmap_design = r.first->second;
auto to_unmap = [&](TwineRef t) { return unmap_design->twines.add(std::string{design->twines.str(t)}); };
// Keep track of derived versions of modules that we haven't used, to prevent these being used for unwanted techmaps later on.
pool<IdString> unused_derived;
pool<TwineRef> unused_derived;
for (auto module : design->selected_modules())
for (auto cell : module->cells()) {
auto inst_module = design->module(cell->type_impl);
if (!inst_module)
continue;
IdString derived_type;
TwineRef derived_type;
Module *derived_module;
if (cell->parameters.empty()) {
derived_type = cell->type;
derived_type = cell->type_impl;
derived_module = inst_module;
}
else {
@ -190,11 +191,11 @@ 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(to_unmap(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
cell->type_impl = cell->module->design->twines.add(Twine{derived_type.str()});
cell->type_impl = derived_type;
cell->parameters.clear();
unused_derived.erase(derived_type);
}
@ -202,7 +203,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
}
}
if (!unmap_design->module(derived_type)) {
if (!unmap_design->module(to_unmap(derived_type))) {
if (derived_module->has_processes())
Pass::call_on_module(design, derived_module, "proc -noopt");
@ -216,7 +217,7 @@ void prep_hier(RTLIL::Design *design, bool dff_mode)
// Block sequential synthesis on cells with (* init *) != 1'b0
// because ABC9 doesn't support them
if (init != State::S0) {
log_warning("Whitebox '%s' with (* abc9_flop *) contains a %s cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox.\n", derived_module, design->twines.unescaped_str(derived_cell->type));
log_warning("Whitebox '%s' with (* abc9_flop *) contains a %s cell with non-zero initial state -- this is not supported for ABC9 sequential synthesis. Treating as a blackbox.\n", derived_module, derived_cell->type.unescape());
derived_module->set_bool_attribute(ID::abc9_flop, false);
}
break;
@ -231,11 +232,11 @@ 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);
if (derived_type != cell->type_impl) {
auto unmap_module = unmap_design->addModule(to_unmap(derived_type));
auto replace_cell = unmap_module->addCell(TW::_TECHMAP_REPLACE_, Twine{cell->type.str()});
for (auto port : derived_module->ports) {
auto w = unmap_module->addWire(port, derived_module->wire(port));
auto w = unmap_module->addWire(to_unmap(port), derived_module->wire(port));
// Do not propagate (* init *) values into the box,
// in fact, remove it from outside too
if (w->port_output)
@ -245,16 +246,18 @@ 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(to_unmap(port), w);
}
unmap_module->ports = derived_module->ports;
unmap_module->ports.clear();
for (auto port : derived_module->ports)
unmap_module->ports.push_back(to_unmap(port));
unmap_module->check();
replace_cell->parameters = cell->parameters;
}
}
cell->type_impl = cell->module->design->twines.add(Twine{derived_type.str()});
cell->type_impl = derived_type;
cell->parameters.clear();
unused_derived.erase(derived_type);
}
@ -274,11 +277,13 @@ void prep_bypass(RTLIL::Design *design)
if (r.second)
r.first->second = new Design;
Design *unmap_design = r.first->second;
auto to_map = [&](TwineRef t) { return map_design->twines.add(std::string{design->twines.str(t)}); };
auto to_unmap = [&](TwineRef t) { return unmap_design->twines.add(std::string{design->twines.str(t)}); };
pool<IdString> processed;
pool<TwineRef> processed;
for (auto module : design->selected_modules())
for (auto cell : module->cells()) {
if (!processed.insert(cell->type).second)
if (!processed.insert(cell->type.ref()).second)
continue;
auto inst_module = design->module(cell->type_impl);
if (!inst_module)
@ -320,26 +325,28 @@ 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.ref());
auto map_module = map_design->addModule(to_map(cell->type.ref()));
for (auto port_name : inst_module->ports) {
auto w = map_module->addWire(port_name, inst_module->wire(port_name));
auto w = map_module->addWire(to_map(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(to_map(port_name));
map_module->check();
map_module->set_bool_attribute(ID::whitebox);
// Create the bypass module in the user design, which has the same
// interface as the derived module but with additional input
// ports driven by the outputs of the replaced cell
auto bypass_module = design->addModule(cell->type.str() + "_$abc9_byp");
auto bypass_module = design->addModule(design->twines.add(cell->type.str() + "_$abc9_byp"));
for (auto port_name : inst_module->ports) {
auto port = inst_module->wire(port_name);
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(Twine{"$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:
@ -396,9 +403,9 @@ void prep_bypass(RTLIL::Design *design)
SigSpec new_sig;
for (auto c : sig.chunks()) {
if (c.wire) {
auto port = bypass_module->wire(c.wire->name);
auto port = bypass_module->wire(c.wire->name.ref());
if (!port)
port = bypass_module->addWire(c.wire->name, c.wire);
port = bypass_module->addWire(c.wire->name.ref(), c.wire);
c.wire = port;
}
new_sig.append(std::move(c));
@ -414,21 +421,21 @@ 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_TWINE, cell->type.str() + "_$abc9_byp");
auto replace_cell = map_module->addCell(TW::_TECHMAP_REPLACE_, Twine{cell->type.str()});
auto bypass_cell = map_module->addCell(NEW_TWINE, Twine{cell->type.str() + "_$abc9_byp"});
for (const auto &conn : cell->connections()) {
auto port = map_module->wire(conn.first);
auto port = map_module->wire(to_map(conn.first));
if (cell->input(conn.first)) {
replace_cell->setPort(conn.first, port);
replace_cell->setPort(to_map(conn.first), port);
if (bypass_module->wire(conn.first))
bypass_cell->setPort(conn.first, port);
bypass_cell->setPort(to_map(conn.first), port);
}
if (cell->output(conn.first)) {
bypass_cell->setPort(conn.first, port);
auto n = "$abc9byp$" + conn.first.str();
auto w = map_module->addWire(n, GetSize(conn.second));
replace_cell->setPort(conn.first, w);
bypass_cell->setPort(n, w);
bypass_cell->setPort(to_map(conn.first), port);
auto n = "$abc9byp$" + design->twines.str(conn.first);
auto w = map_module->addWire(Twine{n}, GetSize(conn.second));
replace_cell->setPort(to_map(conn.first), w);
bypass_cell->setPort(map_design->twines.add(Twine{n}), w);
}
}
@ -436,12 +443,12 @@ void prep_bypass(RTLIL::Design *design)
// Lastly, create a new module in the unmap_design that shorts
// out the bypass cell back to leave the replace cell behind
// driving the outputs
auto unmap_module = unmap_design->addModule(cell->type.str() + "_$abc9_byp");
auto unmap_module = unmap_design->addModule(unmap_design->twines.add(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(to_unmap(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(Twine{"$abc9byp$" + design->twines.str(port_name)}, GetSize(w));
w2->port_input = true;
unmap_module->connect(w, w2);
}
@ -454,7 +461,7 @@ void prep_bypass(RTLIL::Design *design)
void prep_dff(RTLIL::Design *design)
{
auto r = design->selection_vars.insert(std::make_pair(TW($abc9_flops), RTLIL::Selection::EmptySelection(design)));
auto r = design->selection_vars.insert(std::make_pair(ID($abc9_flops), RTLIL::Selection::EmptySelection(design)));
auto &modules_sel = r.first->second;
for (auto module : design->selected_modules())
@ -523,15 +530,16 @@ void prep_dff_submod(RTLIL::Design *design)
void prep_dff_unmap(RTLIL::Design *design)
{
Design *unmap_design = saved_designs.at("$abc9_unmap");
auto to_unmap = [&](TwineRef t) { return unmap_design->twines.add(std::string{design->twines.str(t)}); };
for (auto module : design->modules()) {
if (!module->get_bool_attribute(ID::abc9_flop) || module->get_bool_attribute(ID::abc9_box))
continue;
// Make sure the box module has all the same ports present on flop cell
auto replace_cell = module->cell(ID::_TECHMAP_REPLACE_);
auto replace_cell = module->cell(TW::_TECHMAP_REPLACE_);
log_assert(replace_cell);
auto box_module = design->module(module->name.str() + "_$abc9_flop");
auto box_module = design->module(design->twines.add(module->name.str() + "_$abc9_flop"));
log_assert(box_module);
for (auto port_name : module->ports) {
auto port = module->wire(port_name);
@ -547,14 +555,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(to_unmap(box_module->name.ref()));
replace_cell = unmap_module->addCell(TW::_TECHMAP_REPLACE_, Twine{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(to_unmap(port_name), box_module->wire(port_name));
if (module->wire(port_name))
replace_cell->setPort(port_name, w);
replace_cell->setPort(to_unmap(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(to_unmap(port_name));
unmap_module->check();
}
}
@ -647,7 +657,7 @@ void prep_delays(RTLIL::Design *design, bool dff_mode)
// as delays will be captured in the flop box
}
if (!timing.count(cell->type))
if (!timing.count(cell->type.ref()))
timing.setup_module(inst_module);
cells.emplace_back(cell);
@ -656,7 +666,7 @@ void prep_delays(RTLIL::Design *design, bool dff_mode)
// Insert $__ABC9_DELAY cells on all cells that instantiate blackboxes
// (or bypassed white-boxes with required times)
dict<int, IdString> box_cache;
dict<int, TwineRef> box_cache;
Module *delay_module = design->module(TW($__ABC9_DELAY));
log_assert(delay_module);
for (auto cell : cells) {
@ -664,11 +674,11 @@ void prep_delays(RTLIL::Design *design, bool dff_mode)
auto inst_module = design->module(cell->type_impl);
log_assert(inst_module);
for (auto &i : timing.at(cell->type).required) {
for (auto &i : timing.at(cell->type.ref()).required) {
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.unescaped(), module);
design->twines.unescaped_str(i.first.name), cell, cell->type.unescaped(), module);
log_assert(port_wire->port_input);
auto d = i.second.first;
@ -693,7 +703,7 @@ void prep_delays(RTLIL::Design *design, bool dff_mode)
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_TWINE, r.first->second);
box->setPort(TW::I, rhs[offset]);
@ -708,10 +718,11 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
{
auto design = module->design;
log_assert(design);
auto refof = [&](RTLIL::IdString n) { return design->twines.add(std::string{n.str()}); };
SigMap sigmap(module);
dict<IdString, std::vector<IdString>> box_ports;
dict<TwineRef, std::vector<TwineRef>> box_ports;
for (auto cell : module->cells()) {
if (cell->type.in(TW($_DFF_N_), TW($_DFF_P_)))
@ -725,11 +736,11 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
continue;
if (inst_module && inst_module->get_bool_attribute(ID::abc9_box)) {
auto r = box_ports.insert(cell->type);
auto r = box_ports.insert(cell->type.ref());
if (r.second) {
// Make carry in the last PI, and carry out the last PO
// since ABC requires it this way
IdString carry_in, carry_out;
TwineRef carry_in = Twine::Null, carry_out = Twine::Null;
for (const auto &port_name : inst_module->ports) {
auto w = inst_module->wire(port_name);
log_assert(w);
@ -743,7 +754,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
else
r.first->second.push_back(port_name);
}
if (carry_in != IdString()) {
if (carry_in != Twine::Null) {
r.first->second.push_back(carry_in);
r.first->second.push_back(carry_out);
}
@ -811,7 +822,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
// Loop reports can overlap; cut each cell at most once.
if (!broken_cells.insert(cell_name).second)
continue;
auto cell = module->cell(cell_name);
auto cell = module->cell(refof(cell_name));
log_assert(cell);
auto inst_module = design->module(cell->type_impl);
if (inst_module && inst_module->get_bool_attribute(ID::abc9_box))
@ -845,7 +856,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
for (auto &it : toposort.value().loops) {
log(" loop %d\n", i++);
for (auto cell_name : it) {
auto cell = module->cell(cell_name);
auto cell = module->cell(refof(cell_name));
log_assert(cell);
log("\t%s (%s @ %s)\n", cell, cell->type.unescaped(), cell->get_src_attribute());
}
@ -859,7 +870,8 @@ 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);
auto to_holes = [&](TwineRef t) { return holes_design->twines.add(std::string{design->twines.str(t)}); };
RTLIL::Module *holes_module = holes_design->addModule(to_holes(module->name.ref()));
log_assert(holes_module);
dict<IdString, Cell*> cell_cache;
@ -867,7 +879,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
int port_id = 1, box_count = 0;
for (auto cell_name : toposort.value().sorted) {
RTLIL::Cell *cell = module->cell(cell_name);
RTLIL::Cell *cell = module->cell(refof(cell_name));
log_assert(cell);
RTLIL::Module* box_module = design->module(cell->type_impl);
@ -881,7 +893,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", design->twines.unescaped_str(cell_name), cell->type.unescaped());
log_error("Not expecting parameters on cell '%s' instantiating module '%s' marked (* abc9_box *)\n", design->twines.unescaped_str(refof(cell_name)), cell->type.unescaped());
}
log_assert(box_module->get_blackbox_attribute());
@ -891,49 +903,49 @@ 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_TWINE, cell->type);
holes_cell = holes_module->addCell(NEW_TWINE, Twine{cell->type.str()});
if (box_module->has_processes())
Pass::call_on_module(design, box_module, "proc -noopt");
int box_inputs = 0;
for (auto port_name : box_ports.at(cell->type)) {
for (auto port_name : box_ports.at(cell->type.ref())) {
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_[to_holes(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.add(stringf("\\i%d", box_inputs)));
if (!holes_wire) {
holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs));
holes_wire = holes_module->addWire(holes_design->twines.add(stringf("\\i%d", box_inputs)));
holes_wire->port_input = true;
holes_wire->port_id = port_id++;
holes_module->ports.push_back(holes_wire->name);
holes_module->ports.push_back(holes_wire->name.ref());
}
conn.append(holes_wire);
}
}
else if (w->port_output)
conn = holes_module->addWire(stringf("%s.%s", cell->type, design->twines.unescaped_str(port_name)), GetSize(w));
conn = holes_module->addWire(Twine{stringf("%s.%s", cell->type, design->twines.unescaped_str(port_name))}, GetSize(w));
}
}
else // box_module is a blackbox
log_assert(holes_cell == nullptr);
}
for (auto port_name : box_ports.at(cell->type)) {
for (auto port_name : box_ports.at(cell->type.ref())) {
RTLIL::Wire *w = box_module->wire(port_name);
log_assert(w);
if (!w->port_output)
continue;
Wire *holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name, design->twines.unescaped_str(port_name)), GetSize(w));
Wire *holes_wire = holes_module->addWire(Twine{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);
holes_module->ports.push_back(holes_wire->name.ref());
if (holes_cell) // whitebox
holes_module->connect(holes_wire, holes_cell->getPort(port_name));
holes_module->connect(holes_wire, holes_cell->getPort(to_holes(port_name)));
else // blackbox
holes_module->connect(holes_wire, Const(State::S0, GetSize(w)));
}
@ -945,7 +957,7 @@ void prep_lut(RTLIL::Design *design, int maxlut)
TimingInfo timing;
struct t_lut {
IdString name;
TwineRef name;
int area;
std::vector<int> delays;
};
@ -976,7 +988,7 @@ void prep_lut(RTLIL::Design *design, int maxlut)
std::sort(delays.begin(), delays.end());
int K = GetSize(delays);
auto entry = t_lut{module->name, it->second.as_int(), std::move(delays)};
auto entry = t_lut{module->name.ref(), it->second.as_int(), std::move(delays)};
auto r = table.emplace(K, entry);
if (!r.second) {
if (r.first->second.area != entry.area)
@ -1023,7 +1035,7 @@ void prep_box(RTLIL::Design *design)
int abc9_box_id = 1;
std::stringstream ss;
dict<IdString,std::vector<IdString>> box_ports;
dict<TwineRef,std::vector<TwineRef>> box_ports;
for (auto module : design->modules()) {
auto it = module->attributes.find(ID::abc9_box);
if (it == module->attributes.end())
@ -1060,7 +1072,7 @@ void prep_box(RTLIL::Design *design)
first = false;
else
ss << " ";
ss << design->twines.unescaped_str(wire->name);
ss << design->twines.unescaped_str(wire->name.ref());
}
ss << std::endl;
@ -1087,9 +1099,9 @@ void prep_box(RTLIL::Design *design)
#ifndef NDEBUG
if (ys_debug(1)) {
static std::set<std::pair<IdString,IdString>> seen;
static std::set<std::pair<IdString,TwineRef>> 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
}
@ -1098,11 +1110,11 @@ void prep_box(RTLIL::Design *design)
ss << std::endl;
}
else {
auto r2 = box_ports.insert(module->name);
auto r2 = box_ports.insert(module->name.ref());
if (r2.second) {
// Make carry in the last PI, and carry out the last PO
// since ABC requires it this way
IdString carry_in, carry_out;
TwineRef carry_in = Twine::Null, carry_out = Twine::Null;
for (const auto &port_name : module->ports) {
auto w = module->wire(port_name);
log_assert(w);
@ -1117,7 +1129,7 @@ void prep_box(RTLIL::Design *design)
r2.first->second.push_back(port_name);
}
if (carry_in != IdString()) {
if (carry_in != Twine::Null) {
r2.first->second.push_back(carry_in);
r2.first->second.push_back(carry_out);
}
@ -1147,9 +1159,9 @@ void prep_box(RTLIL::Design *design)
else
ss << " ";
if (GetSize(i.wire) == 1)
ss << design->twines.unescaped_str(i.wire->name);
ss << design->twines.unescaped_str(i.wire->name.ref());
else
ss << design->twines.unescaped_str(i.wire->name) << "[" << i.offset << "]";
ss << design->twines.unescaped_str(i.wire->name.ref()) << "[" << i.offset << "]";
}
ss << std::endl;
@ -1173,9 +1185,9 @@ void prep_box(RTLIL::Design *design)
}
ss << " # ";
if (GetSize(o.wire) == 1)
ss << design->twines.unescaped_str(o.wire->name);
ss << design->twines.unescaped_str(o.wire->name.ref());
else
ss << design->twines.unescaped_str(o.wire->name) << "[" << o.offset << "]";
ss << design->twines.unescaped_str(o.wire->name.ref()) << "[" << o.offset << "]";
ss << std::endl;
}
ss << std::endl;
@ -1202,31 +1214,33 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
log_assert(design);
map_autoidx = autoidx++;
auto rn = [&](RTLIL::IdString n) { return design->twines.add(std::string{remap_name(n)}); };
auto refof = [&](RTLIL::IdString n) { return design->twines.add(std::string{n.str()}); };
RTLIL::Module *mapped_mod = design->module(stringf("%s$abc9", module->name));
RTLIL::Module *mapped_mod = design->module(design->twines.add(stringf("%s$abc9", module->name)));
if (mapped_mod == NULL)
log_error("ABC output file does not contain a module `%s$abc'.\n", module);
for (auto w : mapped_mod->wires()) {
auto nw = module->addWire(remap_name(w->name), GetSize(w));
auto nw = module->addWire(rn(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);
}
dict<IdString,std::vector<IdString>> box_ports;
dict<TwineRef,std::vector<TwineRef>> box_ports;
for (auto m : design->modules()) {
if (!m->attributes.count(ID::abc9_box_id))
continue;
auto r = box_ports.insert(m->name);
auto r = box_ports.insert(m->name.ref());
if (!r.second)
continue;
// Make carry in the last PI, and carry out the last PO
// since ABC requires it this way
IdString carry_in, carry_out;
TwineRef carry_in = Twine::Null, carry_out = Twine::Null;
for (const auto &port_name : m->ports) {
auto w = m->wire(port_name);
log_assert(w);
@ -1241,7 +1255,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
r.first->second.push_back(port_name);
}
if (carry_in != IdString()) {
if (carry_in != Twine::Null) {
r.first->second.push_back(carry_in);
r.first->second.push_back(carry_out);
}
@ -1298,8 +1312,8 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
SigBit D = mapped_cell->getPort(TW::D);
SigBit Q = mapped_cell->getPort(TW::Q);
if (D.wire)
D.wire = module->wire(remap_name(D.wire->name));
Q.wire = module->wire(remap_name(Q.wire->name));
D.wire = module->wire(rn(D.wire->name));
Q.wire = module->wire(rn(Q.wire->name));
module->connect(Q, D);
continue;
}
@ -1317,7 +1331,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
if (!a_bit.wire) {
mapped_cell->setPort(TW::Y, module->addWire(NEW_TWINE));
RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name));
RTLIL::Wire *wire = module->wire(rn(y_bit.wire->name));
log_assert(wire);
module->connect(RTLIL::SigBit(wire, y_bit.offset), State::S1);
}
@ -1334,18 +1348,18 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
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);
driver_lut = mapped_mod->cell(refof(driver_name));
}
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->wire(remap_name(a_bit.wire->name)), a_bit.offset),
RTLIL::SigBit(module->wire(remap_name(y_bit.wire->name)), y_bit.offset),
RTLIL::Cell *cell = module->addLut(Twine{remap_name(stringf("$lut%s", mapped_cell->name))},
RTLIL::SigBit(module->wire(rn(a_bit.wire->name)), a_bit.offset),
RTLIL::SigBit(module->wire(rn(y_bit.wire->name)), y_bit.offset),
RTLIL::Const::from_string("01"));
bit2sinks[cell->getPort(TW::A)].push_back(cell);
cell_stats[TW($lut)]++;
cell_stats[ID($lut)]++;
}
else
not2drivers[mapped_cell] = driver_lut;
@ -1354,7 +1368,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
}
if (mapped_cell->type == TW($lut)) {
RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
RTLIL::Cell *cell = module->addCell(rn(mapped_cell->name), mapped_cell->type_impl);
cell->parameters = mapped_cell->parameters;
cell->attributes = mapped_cell->attributes;
@ -1365,7 +1379,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
continue;
//log_assert(c.width == 1);
if (c.wire)
c.wire = module->wire(remap_name(c.wire->name));
c.wire = module->wire(rn(c.wire->name));
newsig.append(c);
}
cell->setPort(mapped_conn.first, newsig);
@ -1384,7 +1398,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
}
}
else {
RTLIL::Cell *existing_cell = module->cell(mapped_cell->name);
RTLIL::Cell *existing_cell = module->cell(mapped_cell->name.ref());
if (!existing_cell)
log_error("Cannot find existing box cell with name '%s' in original design.\n", mapped_cell);
@ -1392,28 +1406,28 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
SigBit I = mapped_cell->getPort(TW::i);
SigBit O = mapped_cell->getPort(TW::o);
if (I.wire)
I.wire = module->wire(remap_name(I.wire->name));
I.wire = module->wire(rn(I.wire->name));
log_assert(O.wire);
O.wire = module->wire(remap_name(O.wire->name));
O.wire = module->wire(rn(O.wire->name));
module->connect(O, I);
continue;
}
RTLIL::Module* box_module = design->module(existing_cell->type);
RTLIL::Module* box_module = design->module(existing_cell->type_impl);
log_assert(existing_cell->parameters.empty());
log_assert(mapped_cell->type == stringf("$__boxid%d", box_module->attributes.at(ID::abc9_box_id).as_int()));
mapped_cell->type_impl = existing_cell->type_impl;
RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
RTLIL::Cell *cell = module->addCell(rn(mapped_cell->name), mapped_cell->type_impl);
cell->parameters = existing_cell->parameters;
cell->attributes = existing_cell->attributes;
module->swap_names(cell, existing_cell);
auto jt = mapped_cell->connections_.find(ID(i));
auto jt = mapped_cell->connections_.find(TW::i);
log_assert(jt != mapped_cell->connections_.end());
SigSpec inputs = std::move(jt->second);
mapped_cell->connections_.erase(jt);
jt = mapped_cell->connections_.find(ID(o));
jt = mapped_cell->connections_.find(TW::o);
log_assert(jt != mapped_cell->connections_.end());
SigSpec outputs = std::move(jt->second);
mapped_cell->connections_.erase(jt);
@ -1424,7 +1438,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
// flop box, so that any (public) signal it drives will be
// preserved
SigBit old_q;
for (const auto &port_name : box_ports.at(existing_cell->type)) {
for (const auto &port_name : box_ports.at(existing_cell->type.ref())) {
RTLIL::Wire *w = box_module->wire(port_name);
log_assert(w);
if (!w->port_output)
@ -1434,7 +1448,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
old_q = existing_cell->getPort(port_name);
}
auto new_q = outputs[0];
new_q.wire = module->wire(remap_name(new_q.wire->name));
new_q.wire = module->wire(rn(new_q.wire->name));
module->connect(old_q, new_q);
}
else {
@ -1447,7 +1461,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
}
int input_count = 0, output_count = 0;
for (const auto &port_name : box_ports.at(existing_cell->type)) {
for (const auto &port_name : box_ports.at(existing_cell->type.ref())) {
RTLIL::Wire *w = box_module->wire(port_name);
log_assert(w);
@ -1467,7 +1481,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
continue;
//log_assert(c.width == 1);
if (c.wire)
c.wire = module->wire(remap_name(c.wire->name));
c.wire = module->wire(rn(c.wire->name));
newsig.append(c);
}
@ -1490,14 +1504,14 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
if (!conn.first.is_fully_const()) {
std::vector<RTLIL::SigChunk> chunks = conn.first.chunks();
for (auto &c : chunks)
c.wire = module->wire(remap_name(c.wire->name));
c.wire = module->wire(rn(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->wire(remap_name(c.wire->name));
c.wire = module->wire(rn(c.wire->name));
conn.second = std::move(chunks);
}
module->connect(conn);
@ -1513,7 +1527,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
RTLIL::Wire *wire = module->wire(port);
log_assert(wire);
RTLIL::Wire *remap_wire = module->wire(remap_name(port));
RTLIL::Wire *remap_wire = module->wire(rn(mapped_wire->name));
RTLIL::SigSpec signal(wire, remap_wire->start_offset-wire->start_offset, GetSize(remap_wire));
log_assert(GetSize(signal) >= GetSize(remap_wire));
@ -1552,7 +1566,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
log_assert(no_loops);
for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) {
RTLIL::Cell *not_cell = mapped_mod->cell(*ii);
RTLIL::Cell *not_cell = mapped_mod->cell(refof(*ii));
log_assert(not_cell);
if (not_cell->type != TW($_NOT_))
continue;
@ -1564,8 +1578,8 @@ void reintegrate(RTLIL::Module *module, bool dff_mode)
RTLIL::SigBit y_bit = not_cell->getPort(TW::Y);
RTLIL::Const driver_mask;
a_bit.wire = module->wire(remap_name(a_bit.wire->name));
y_bit.wire = module->wire(remap_name(y_bit.wire->name));
a_bit.wire = module->wire(rn(a_bit.wire->name));
y_bit.wire = module->wire(rn(y_bit.wire->name));
auto jt = bit2sinks.find(a_bit);
if (jt == bit2sinks.end())
@ -1613,8 +1627,8 @@ clone_lut:
driver_lut->getPort(TW::A),
y_bit,
driver_mask);
for (auto &bit : cell->connections_.at(ID::A)) {
bit.wire = module->wire(remap_name(bit.wire->name));
for (auto &bit : cell->connections_.at(TW::A)) {
bit.wire = module->wire(rn(bit.wire->name));
bit2sinks[bit].push_back(cell);
}
}
@ -1681,7 +1695,7 @@ static void restore_zbufs(Design *design)
for (auto cell : to_remove) {
SigSpec sig_y = cell->getPort(TW::Y);
mod->addBuf(NEW_ID, Const(State::Sz, GetSize(sig_y)), sig_y);
mod->addBuf(NEW_TWINE, Const(State::Sz, GetSize(sig_y)), sig_y);
mod->remove(cell);
}
}

View file

@ -27,7 +27,7 @@ PRIVATE_NAMESPACE_BEGIN
std::vector<Module*> order_modules(Design *design, std::vector<Module *> modules)
{
std::set<Module *> modules_set(modules.begin(), modules.end());
using Order = IdString::compare_ptr_by_name<RTLIL::NamedObject>;
using Order = IdString::compare_ptr_by_name<RTLIL::Module>;
TopoSort<Module*, Order> sort;
for (auto m : modules) {

View file

@ -132,14 +132,14 @@ struct BoothPassWorker {
// (y2_p1 & y2_n & y2_m1_n)
// )
twoi_n_o = module->NorGate(NEW_TWINE_SUFFIX(name),
module->AndGate(NEW_ID_SUFFIX(name), y2_p1_n, module->AndGate(NEW_TWINE_SUFFIX(name), y2_i, y2_m1_i)),
module->AndGate(NEW_ID_SUFFIX(name), y2_p1_i, module->AndGate(NEW_TWINE_SUFFIX(name), y2_n, y2_m1_n))
module->AndGate(NEW_TWINE_SUFFIX(name), y2_p1_n, module->AndGate(NEW_TWINE_SUFFIX(name), y2_i, y2_m1_i)),
module->AndGate(NEW_TWINE_SUFFIX(name), y2_p1_i, module->AndGate(NEW_TWINE_SUFFIX(name), y2_n, y2_m1_n))
);
// onei_n = ~(y2_m1_i ^ y2_i);
onei_n_o = module->XnorGate(NEW_TWINE_SUFFIX(name), y2_m1_i, y2_i);
// cori = (y2_m1_n | y2_n) & y2_p1_i;
cori_o = module->AndGate(NEW_ID_SUFFIX(name), module->OrGate(NEW_TWINE_SUFFIX(name), y2_m1_n, y2_n), y2_p1_i);
cori_o = module->AndGate(NEW_TWINE_SUFFIX(name), module->OrGate(NEW_TWINE_SUFFIX(name), y2_m1_n, y2_n), y2_p1_i);
}
//
@ -201,9 +201,10 @@ struct BoothPassWorker {
log_assert(sig_a.size() == sig_x.size());
log_assert(sig_a.size() == sig_y.size());
TwineRef src_ref = src.empty() ? Twine::Null : mod->design->twines.add(Twine{src});
for (int i = 0; i < sig_a.size(); i++)
mod->addFa(stringf("%s[%d]", name, i), sig_a[i], sig_b[i],
sig_c[i], sig_x[i], sig_y[i], src);
mod->addFa(Twine{stringf("%s[%d]", name, i)}, sig_a[i], sig_b[i],
sig_c[i], sig_x[i], sig_y[i], src_ref);
}
void run()
@ -431,7 +432,7 @@ struct BoothPassWorker {
// append the sign bits
if (is_signed) {
SigBit e = module->XorGate(NEW_ID, s_int[0], module->AndGate(NEW_ID, X.msb(), module->OrGate(NEW_TWINE, two_int[0], one_int[0])));
SigBit e = module->XorGate(NEW_TWINE, s_int[0], module->AndGate(NEW_TWINE, X.msb(), module->OrGate(NEW_TWINE, two_int[0], one_int[0])));
ppij_vec.append({module->NotGate(NEW_TWINE, e), e, e});
} else {
// append the sign bits
@ -465,7 +466,7 @@ struct BoothPassWorker {
one_int, two_int, s_int));
}
ppij_vec.append(!is_signed ? sb_int[0] : module->XorGate(NEW_ID, sb_int, module->AndGate(NEW_ID, X.msb(), module->OrGate(NEW_TWINE, two_int, one_int))));
ppij_vec.append(!is_signed ? sb_int[0] : module->XorGate(NEW_TWINE, sb_int, module->AndGate(NEW_TWINE, X.msb(), module->OrGate(NEW_TWINE, two_int, one_int))));
ppij_vec.append(State::S1);
}
@ -476,7 +477,7 @@ struct BoothPassWorker {
for (auto pp_row : aligned_pp) {
printf("PP_%d \t", pp_ix);
for (unsigned i = 0; i < pp_row.size(); i++)
printf("[%d] %s ", i, pp_row[i] == nullptr ? " 0 " : pp_row[i]->name.c_str());
printf("[%d] %s ", i, pp_row[i] == nullptr ? " 0 " : pp_row[i]->name.str().c_str());
printf("\n");
pp_ix++;
}
@ -504,7 +505,7 @@ struct BoothPassWorker {
ix++;
}
printf("\n");
printf("\tSign bit to add in: %s\n", sign_bit->name.c_str());
printf("\tSign bit to add in: %s\n", sign_bit->name.str().c_str());
pp_ix++;
}
@ -517,30 +518,30 @@ struct BoothPassWorker {
printf("CSA Tree column %d\n", i);
int ix = 0;
for (auto csa_elem : csa_tree) {
printf("\tCell %d %s type %s\n", ix, csa_elem->name.c_str(), csa_elem->type.c_str());
printf("\tCell %d %s type %s\n", ix, csa_elem->name.str().c_str(), csa_elem->type.str().c_str());
if (csa_elem->getPort(TW::A) == State::S0)
printf("\tA set to constant 0\n");
else if (csa_elem->getPort(TW::A) == State::S1)
printf("\tA set to constant 1\n");
else
printf("\tA driven by %s\n", csa_elem->getPort(TW::A).as_wire()->name.c_str());
printf("\tA driven by %s\n", csa_elem->getPort(TW::A).as_wire()->name.str().c_str());
if (csa_elem->getPort(TW::B) == State::S0)
printf("\tB set to constant 0\n");
else if (csa_elem->getPort(TW::B) == State::S1)
printf("\tB set to constant 1\n");
else
printf("\tB driven by %s\n", csa_elem->getPort(TW::B).as_wire()->name.c_str());
printf("\tB driven by %s\n", csa_elem->getPort(TW::B).as_wire()->name.str().c_str());
if (csa_elem->getPort(TW::C) == State::S0)
printf("\tC set to constant 0\n");
else if (csa_elem->getPort(TW::C) == State::S1)
printf("\tC set to constant 1\n");
else
printf("\tC driven by %s\n", csa_elem->getPort(TW::C).as_wire()->name.c_str());
printf("\tC driven by %s\n", csa_elem->getPort(TW::C).as_wire()->name.str().c_str());
printf("Carry out: %s\n", csa_elem->getPort(TW::X).as_wire()->name.c_str());
printf("Sum out: %s\n", csa_elem->getPort(TW::Y).as_wire()->name.c_str());
printf("Carry out: %s\n", csa_elem->getPort(TW::X).as_wire()->name.str().c_str());
printf("Sum out: %s\n", csa_elem->getPort(TW::Y).as_wire()->name.str().c_str());
ix++;
}
@ -569,7 +570,7 @@ struct BoothPassWorker {
}
for (auto c : carry_bits_to_add_to_next_column) {
#ifdef DEBUG_CSA
printf("\t Propagating column bit %s to column %d from column %d\n", c->name.c_str(), column_ix, column_ix - 1);
printf("\t Propagating column bit %s to column %d from column %d\n", c->name.str().c_str(), column_ix, column_ix - 1);
#endif
column_bits.append(c);
}
@ -579,7 +580,7 @@ struct BoothPassWorker {
#ifdef DEBUG_CSA
printf("Column %d Reducing %d bits\n", column_ix, column_bits.size());
for (auto b : column_bits) {
printf("\t %s\n", b->name.c_str());
printf("\t %s\n", b->name.str().c_str());
}
printf("\n");
#endif
@ -695,7 +696,7 @@ struct BoothPassWorker {
module->addBufGate(NEW_TWINE_SUFFIX(stringf("base_buf_%d_%d", cpa_id, n)), s_vec[0], result[0]);
#ifdef DEBUG_CPA
printf("CPA bit [%d] Cell %s IP 0 %s \n", n, buf->name.c_str(), s_vec[0]->name.c_str());
printf("CPA bit [%d] Cell %s IP 0 %s \n", n, buf->name.str().c_str(), s_vec[0]->name.str().c_str());
#endif
}
@ -710,8 +711,8 @@ struct BoothPassWorker {
module->connect(result[n], ha_op);
#ifdef DEBUG_CPA
printf("CPA bit [%d] Cell %s IPs [%s] [%s] \n", n, ha_cell->name.c_str(), s_vec[n]->name.c_str(),
c_vec[n - 1]->name.c_str());
printf("CPA bit [%d] Cell %s IPs [%s] [%s] \n", n, ha_cell->name.str().c_str(), s_vec[n]->name.str().c_str(),
c_vec[n - 1]->name.str().c_str());
#endif
}
@ -729,8 +730,8 @@ struct BoothPassWorker {
carry = carry_out;
#ifdef DEBUG_CPA
printf("CPA bit [%d] Cell %s IPs [%s] [%s] [%s]\n", n, fa_cell->name.c_str(), s_vec[n]->name.c_str(),
c_vec[n - 1]->name.c_str(), carry->name.c_str());
printf("CPA bit [%d] Cell %s IPs [%s] [%s] [%s]\n", n, fa_cell->name.str().c_str(), s_vec[n]->name.str().c_str(),
c_vec[n - 1]->name.str().c_str(), carry->name.str().c_str());
#endif
if (n + 1 < GetSize(result)) {
// Now make a half adder: c_vec[n] = carry
@ -756,8 +757,8 @@ struct BoothPassWorker {
);
carry = carry_out;
#ifdef DEBUG_CPA
printf("CPA bit [%d] Cell %s IPs [%s] [%s] [%s]\n", n, fa_cell->name.c_str(), s_vec[n]->name.c_str(),
c_vec[n - 1]->name.c_str(), carry->name.c_str());
printf("CPA bit [%d] Cell %s IPs [%s] [%s] [%s]\n", n, fa_cell->name.str().c_str(), s_vec[n]->name.str().c_str(),
c_vec[n - 1]->name.str().c_str(), carry->name.str().c_str());
#endif
}
}

View file

@ -271,7 +271,7 @@ struct BufnormPass : public Pass {
SigMap sigmap(module);
module->new_connections({});
dict<pair<IdString, SigSpec>, Cell*> old_buffers;
dict<pair<TwineRef, SigSpec>, Cell*> old_buffers;
{
vector<Cell*> old_dup_buffers;
@ -285,7 +285,7 @@ struct BufnormPass : public Pass {
for (int i = 0; i < GetSize(insig) && i < GetSize(outsig); i++)
sigmap.add(insig[i], outsig[i]);
pair<IdString,Wire*> key(cell->type, outsig.as_wire());
pair<TwineRef,Wire*> key(cell->type_impl, outsig.as_wire());
if (old_buffers.count(key))
old_dup_buffers.push_back(cell);
else
@ -432,9 +432,9 @@ struct BufnormPass : public Pass {
return mapped_bits.at(bit);
};
auto make_buffer_f = [&](IdString type, const SigSpec &src, const SigSpec &dst)
auto make_buffer_f = [&](TwineRef type, const SigSpec &src, const SigSpec &dst)
{
auto it = old_buffers.find(pair<IdString, SigSpec>(type, dst));
auto it = old_buffers.find(pair<TwineRef, SigSpec>(type, dst));
if (it != old_buffers.end())
{
@ -488,11 +488,11 @@ struct BufnormPass : public Pass {
}
} else {
if (bits_mode) {
IdString celltype = pos_mode ? TW($pos) : buf_mode ? TW($buf) : TW($_BUF_);
TwineRef celltype = pos_mode ? TW($pos) : buf_mode ? TW($buf) : TW($_BUF_);
for (int i = 0; i < GetSize(insig) && i < GetSize(outsig); i++)
make_buffer_f(celltype, insig[i], outsig[i]);
} else {
IdString celltype = pos_mode ? TW($pos) : buf_mode ? TW($buf) :
TwineRef celltype = pos_mode ? TW($pos) : buf_mode ? TW($buf) :
GetSize(outsig) == 1 ? TW($_BUF_) : TW($buf);
make_buffer_f(celltype, insig, outsig);
}

View file

@ -274,27 +274,27 @@ struct CellmatchPass : Pass {
log("Module %s matches %s\n", m, target.module);
// 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);
Module *map = map_design->addModule(map_design->twines.add(std::string{stringf("\\_60_%s_%s", m, target.module)}));
Cell *cell = map->addCell(TW::_TECHMAP_REPLACE_, Twine{target.module->name.str()});
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(Twine{outputs[i].wire->name.str()}, 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.add(std::string{target_outputs[output_map[i]].wire->name.str()}), 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(Twine{inputs[i].wire->name.str()}, 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.add(std::string{target_inputs[input_map[i]].wire->name.str()}), w);
}
map->fixup_ports();

View file

@ -117,17 +117,24 @@ struct ClkbufmapPass : public Pass {
log_error("Either the -buf option or -inpad option is required.\n");
// Cell type, port name, bit index.
pool<pair<IdString, pair<IdString, int>>> sink_ports;
pool<pair<IdString, pair<IdString, int>>> buf_ports;
dict<pair<IdString, pair<IdString, int>>, pair<IdString, int>> inv_ports_out;
dict<pair<IdString, pair<IdString, int>>, pair<IdString, int>> inv_ports_in;
pool<pair<TwineRef, pair<TwineRef, int>>> sink_ports;
pool<pair<TwineRef, pair<TwineRef, int>>> buf_ports;
dict<pair<TwineRef, pair<TwineRef, int>>, pair<TwineRef, int>> inv_ports_out;
dict<pair<TwineRef, pair<TwineRef, int>>, pair<TwineRef, int>> inv_ports_in;
// If true, use both ther -buf and -inpad cell for input ports that are clocks.
bool buffer_inputs = true;
Module *inpad_mod = design->module(RTLIL::escape_id(inpad_celltype));
TwineRef buf_celltype_ref = design->twines.add(Twine{RTLIL::escape_id(buf_celltype)});
TwineRef buf_portname_ref = design->twines.add(Twine{RTLIL::escape_id(buf_portname)});
TwineRef buf_portname2_ref = design->twines.add(Twine{RTLIL::escape_id(buf_portname2)});
TwineRef inpad_celltype_ref = design->twines.add(Twine{RTLIL::escape_id(inpad_celltype)});
TwineRef inpad_portname_ref = design->twines.add(Twine{RTLIL::escape_id(inpad_portname)});
TwineRef inpad_portname2_ref = design->twines.add(Twine{RTLIL::escape_id(inpad_portname2)});
Module *inpad_mod = design->module(inpad_celltype_ref);
if (inpad_mod) {
Wire *buf_wire = inpad_mod->wire(RTLIL::escape_id(buf_portname));
Wire *buf_wire = inpad_mod->wire(buf_portname_ref);
if (buf_wire && buf_wire->get_bool_attribute(ID::clkbuf_driver))
buffer_inputs = false;
}
@ -145,16 +152,16 @@ struct ClkbufmapPass : public Pass {
auto wire = module->wire(port);
if (wire->get_bool_attribute(ID::clkbuf_driver))
for (int i = 0; i < GetSize(wire); i++)
buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i)));
buf_ports.insert(make_pair(module->name.ref(), make_pair(wire->name.ref(), i)));
if (wire->get_bool_attribute(ID::clkbuf_sink))
for (int i = 0; i < GetSize(wire); i++)
sink_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i)));
sink_ports.insert(make_pair(module->name.ref(), make_pair(wire->name.ref(), i)));
auto it = wire->attributes.find(ID::clkbuf_inv);
if (it != wire->attributes.end()) {
IdString in_name = RTLIL::escape_id(it->second.decode_string());
TwineRef in_name = design->twines.add(Twine{RTLIL::escape_id(it->second.decode_string())});
for (int i = 0; i < GetSize(wire); i++) {
inv_ports_out[make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i))] = make_pair(in_name, i);
inv_ports_in[make_pair(RTLIL::IdString(module->name), make_pair(in_name, i))] = make_pair(RTLIL::IdString(wire->name), i);
inv_ports_out[make_pair(module->name.ref(), make_pair(wire->name.ref(), i))] = make_pair(in_name, i);
inv_ports_in[make_pair(module->name.ref(), make_pair(in_name, i))] = make_pair(wire->name.ref(), i);
}
}
}
@ -171,14 +178,14 @@ struct ClkbufmapPass : public Pass {
for (auto cell : module->cells())
for (auto port : cell->connections())
for (int i = 0; i < port.second.size(); i++)
if (sink_ports.count(make_pair(cell->type, make_pair(port.first, i))))
if (sink_ports.count(make_pair(cell->type_impl, make_pair(port.first, i))))
sink_wire_bits.insert(sigmap(port.second[i]));
// Second, collect ones that already have a clock buffer.
for (auto cell : module->cells())
for (auto port : cell->connections())
for (int i = 0; i < port.second.size(); i++)
if (buf_ports.count(make_pair(cell->type, make_pair(port.first, i))))
if (buf_ports.count(make_pair(cell->type_impl, make_pair(port.first, i))))
buf_wire_bits.insert(sigmap(port.second[i]));
// Third, propagate tags through inverters.
@ -188,7 +195,7 @@ struct ClkbufmapPass : public Pass {
for (auto cell : module->cells())
for (auto port : cell->connections())
for (int i = 0; i < port.second.size(); i++) {
auto it = inv_ports_out.find(make_pair(cell->type, make_pair(port.first, i)));
auto it = inv_ports_out.find(make_pair(cell->type_impl, make_pair(port.first, i)));
auto bit = sigmap(port.second[i]);
// If output of an inverter is connected to a sink, mark it as buffered,
// and request a buffer on the inverter's input instead.
@ -200,7 +207,7 @@ struct ClkbufmapPass : public Pass {
}
// If input of an inverter is marked as already-buffered,
// mark its output already-buffered as well.
auto it2 = inv_ports_in.find(make_pair(cell->type, make_pair(port.first, i)));
auto it2 = inv_ports_in.find(make_pair(cell->type_impl, make_pair(port.first, i)));
if (it2 != inv_ports_in.end() && buf_wire_bits.count(bit)) {
auto other_bit = sigmap(cell->getPort(it2->second.first)[it2->second.second]);
if (!buf_wire_bits.count(other_bit)) {
@ -236,7 +243,7 @@ struct ClkbufmapPass : public Pass {
// some buffer higher up in the hierarchy.
if (wire->port_output)
for (int i = 0; i < GetSize(wire); i++)
buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i)));
buf_ports.insert(make_pair(module->name.ref(), make_pair(wire->name.ref(), i)));
continue;
}
@ -249,7 +256,7 @@ struct ClkbufmapPass : public Pass {
if (buf_wire_bits.count(mapped_wire_bit)) {
// Already buffered downstream. If this is an output, mark it.
if (wire->port_output)
buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i)));
buf_ports.insert(make_pair(module->name.ref(), make_pair(wire->name.ref(), i)));
} else if (!sink_wire_bits.count(mapped_wire_bit)) {
// Nothing to do.
} else if (driven_wire_bits.count(wire_bit) || (wire->port_input && module->get_bool_attribute(ID::top))) {
@ -261,22 +268,22 @@ struct ClkbufmapPass : public Pass {
bool is_input = wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute(ID::top);
if (!buf_celltype.empty() && (!is_input || buffer_inputs)) {
log("Inserting %s on %s.%s[%d].\n", buf_celltype, module, wire, i);
cell = module->addCell(NEW_TWINE, RTLIL::escape_id(buf_celltype));
cell = module->addCell(NEW_TWINE, buf_celltype_ref);
iwire = module->addWire(NEW_TWINE);
cell->setPort(RTLIL::escape_id(buf_portname), mapped_wire_bit);
cell->setPort(RTLIL::escape_id(buf_portname2), iwire);
cell->setPort(buf_portname_ref, mapped_wire_bit);
cell->setPort(buf_portname2_ref, iwire);
}
if (is_input) {
log("Inserting %s on %s.%s[%d].\n", inpad_celltype, module, wire, i);
RTLIL::Cell *cell2 = module->addCell(NEW_TWINE, RTLIL::escape_id(inpad_celltype));
RTLIL::Cell *cell2 = module->addCell(NEW_TWINE, inpad_celltype_ref);
if (iwire) {
cell2->setPort(RTLIL::escape_id(inpad_portname), iwire);
cell2->setPort(inpad_portname_ref, iwire);
} else {
cell2->setPort(RTLIL::escape_id(inpad_portname), mapped_wire_bit);
cell2->setPort(inpad_portname_ref, mapped_wire_bit);
cell = cell2;
}
iwire = module->addWire(NEW_TWINE);
cell2->setPort(RTLIL::escape_id(inpad_portname2), iwire);
cell2->setPort(inpad_portname2_ref, iwire);
}
if (iwire)
buffered_bits[mapped_wire_bit] = make_pair(cell, iwire);
@ -288,7 +295,7 @@ struct ClkbufmapPass : public Pass {
// A clock input in a submodule -- mark it, let higher level
// worry about it.
if (wire->port_input)
sink_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i)));
sink_ports.insert(make_pair(module->name.ref(), make_pair(wire->name.ref(), i)));
}
}
if (!input_bits.empty()) {
@ -320,7 +327,7 @@ struct ClkbufmapPass : public Pass {
SigBit wire_bit(wire, i);
SigBit mapped_wire_bit = sigmap(wire_bit);
if (buffered_bits.count(mapped_wire_bit))
buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i)));
buf_ports.insert(make_pair(module->name.ref(), make_pair(wire->name.ref(), i)));
}
}

View file

@ -127,7 +127,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;
@ -153,14 +153,15 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
{
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", design->twines.unescaped_str(mod->name));
log(" Skipping module %s as it is not selected.\n", mod->name.unescaped());
return false;
}
if (mod->processes.size() > 0) {
log(" Skipping module %s as it contains unprocessed processes.\n", design->twines.unescaped_str(mod->name));
log(" Skipping module %s as it contains unprocessed processes.\n", mod->name.unescaped());
return false;
}
@ -206,9 +207,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<RTLIL::IdString, RTLIL::IdString>(IdString(cell->type.str()), IdString(tw.str(conn.first)))) > 0)
continue;
RTLIL::SigSpec conn_sig = conn.second;
@ -224,9 +225,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 +240,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,16 +290,17 @@ 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<TwineRef, 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(Twine{stringf("$extract$%s$%d", needle->name, autoidx++)}, Twine{needle->name.str()});
// create cell ports
for (auto wire : needle->wires()) {
if (wire->port_id > 0) {
for (int i = 0; i < wire->width; i++)
sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair<RTLIL::IdString, int>(wire->name, i));
sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair<TwineRef, int>(wire->meta_->name, i));
cell->setPort(wire->meta_->name, RTLIL::SigSpec(RTLIL::State::Sz, wire->width));
}
}
@ -315,10 +317,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);
@ -674,7 +676,7 @@ struct ExtractPass : public Pass {
}
RTLIL::Cell *new_cell = replace(needle_map.at(result.needleGraphId), haystack_map.at(result.haystackGraphId), result);
design->select(haystack_map.at(result.haystackGraphId), new_cell);
log(" new cell: %s\n", new_cell->module->design->twines.str(cell->meta_->name));
log(" new cell: %s\n", new_cell->name.str().c_str());
}
}
}
@ -691,12 +693,12 @@ struct ExtractPass : public Pass {
for (auto &result: results)
{
log("\nFrequent SubCircuit with %d nodes and %d matches:\n", int(result.nodes.size()), result.totalMatchesAfterLimits);
log(" primary match in %s:", design->twines.unescaped_str(haystack_map.at(result.graphId)->name));
log(" primary match in %s:", haystack_map.at(result.graphId)->name.unescaped());
for (auto &node : result.nodes)
log(" %s", RTLIL::unescape_id(node.nodeId));
log("\n");
for (auto &it : result.matchesPerGraph)
log(" matches in %s: %d\n", design->twines.unescaped_str(haystack_map.at(it.first)->name), it.second);
log(" matches in %s: %d\n", haystack_map.at(it.first)->name.unescaped(), it.second);
RTLIL::Module *mod = haystack_map.at(result.graphId);
std::set<RTLIL::Cell*> cells;
@ -715,13 +717,10 @@ struct ExtractPass : public Pass {
wires.insert(chunk.wire);
}
RTLIL::Module *newMod = new RTLIL::Module;
newMod->design = map;
newMod->name = stringf("\\needle%05d_%s_%dx", needleCounter++, design->twines.unescaped_str(haystack_map.at(result.graphId)->name), result.totalMatchesAfterLimits);
map->add(newMod);
RTLIL::Module *newMod = map->addModule(map->twines.add(stringf("\\needle%05d_%s_%dx", needleCounter++, haystack_map.at(result.graphId)->name.unescaped(), result.totalMatchesAfterLimits)));
for (auto wire : wires) {
RTLIL::Wire *newWire = newMod->addWire(wire->name, wire->width);
RTLIL::Wire *newWire = newMod->addWire(Twine{wire->name.str()}, wire->width);
newWire->port_input = true;
newWire->port_output = true;
}
@ -729,13 +728,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(Twine{cell->name.str()}, Twine{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(Twine{chunk.wire->name.str()}));
newCell->setPort(conn.first, chunks);
}
}

View file

@ -535,11 +535,9 @@ void counter_worker(
string count_reg_src = port_wire->get_src_attribute().c_str();
if(port_wire->attributes.find(ID(COUNT_EXTRACT)) != port_wire->attributes.end())
{
pool<string> sa = port_wire->get_strpool_attribute(ID(COUNT_EXTRACT));
string extract_value;
if(sa.size() >= 1)
string extract_value = port_wire->get_string_attribute(ID(COUNT_EXTRACT));
if(!extract_value.empty())
{
extract_value = *sa.begin();
log(" Signal %s declared at %s has COUNT_EXTRACT = %s\n",
port_wire,
count_reg_src.c_str(),
@ -611,7 +609,7 @@ void counter_worker(
}
//Get new cell name
string countname = string("$COUNTx$") + design->twines.unescaped_str(extract.rwire->name);
string countname = string("$COUNTx$") + extract.rwire->name.unescaped();
//Wipe all of the old connections to the ALU
cell->unsetPort(TW::A);
@ -697,7 +695,7 @@ void counter_worker(
//Hook up any parallel outputs
for(auto load : extract.pouts)
{
log(" Counter has parallel output to cell %s port %s\n", load.cell->module->design->twines.str(cell->meta_->name), design->twines.unescaped_str(load.port));
log(" Counter has parallel output to cell %s port %s\n", load.cell->module->design->twines.str(cell->meta_->name), load.cell->module->design->twines.unescaped_str(load.port));
}
if(extract.has_pout)
{
@ -894,7 +892,7 @@ struct ExtractCounterPass : public Pass {
for(auto cpair : cells_to_rename)
{
//log("Renaming cell %s to %s\n", cpair.first, cpair.second);
module->rename(cpair.first, cpair.second);
module->rename(cpair.first, module->design->twines.add(std::string{cpair.second}));
}
}

View file

@ -80,6 +80,10 @@ struct ExtractinvPass : public Pass {
if (inv_celltype.empty())
log_error("The -inv option is required.\n");
TwineRef inv_celltype_ref = design->twines.add(std::string{RTLIL::escape_id(inv_celltype)});
TwineRef inv_portname_ref = design->twines.add(std::string{RTLIL::escape_id(inv_portname)});
TwineRef inv_portname2_ref = design->twines.add(std::string{RTLIL::escape_id(inv_portname2)});
for (auto module : design->selected_modules())
{
for (auto cell : module->selected_cells())
@ -100,7 +104,7 @@ struct ExtractinvPass : public Pass {
continue;
SigSpec sig = port.second;
if (it2->second.size() != sig.size())
log_error("The inversion parameter needs to be the same width as the port (%s.%s port %s parameter %s)", design->twines.unescaped_str(module->name), cell->type.unescaped(), design->twines.unescaped_str(port.first), design->twines.unescaped_str(param_name));
log_error("The inversion parameter needs to be the same width as the port (%s.%s port %s parameter %s)", module->name.unescaped(), cell->type.unescaped(), design->twines.unescaped_str(port.first), RTLIL::unescape_id(param_name));
RTLIL::Const invmask = it2->second;
cell->parameters.erase(param_name);
if (invmask.is_fully_zero())
@ -108,9 +112,9 @@ struct ExtractinvPass : public Pass {
Wire *iwire = module->addWire(NEW_TWINE, sig.size());
for (int i = 0; i < sig.size(); i++)
if (invmask[i] == State::S1) {
RTLIL::Cell *icell = module->addCell(NEW_TWINE, RTLIL::escape_id(inv_celltype));
icell->setPort(RTLIL::escape_id(inv_portname), SigSpec(iwire, i));
icell->setPort(RTLIL::escape_id(inv_portname2), sig[i]);
RTLIL::Cell *icell = module->addCell(NEW_TWINE, inv_celltype_ref);
icell->setPort(inv_portname_ref, SigSpec(iwire, i));
icell->setPort(inv_portname2_ref, sig[i]);
log("Inserting %s on %s.%s.%s[%d].\n", inv_celltype, module, cell->type.unescaped(), design->twines.unescaped_str(port.first), i);
sig[i] = SigBit(iwire, i);
}

View file

@ -1376,10 +1376,10 @@ struct FlowmapWorker
auto gate_origin = node_origins[gate_node];
if (gate_origin.cell->getPort(gate_origin.port).size() == 1)
log(" Packing %s.%s.%s (%s).\n",
module, gate_origin.cell, gate_module->design->twines.str(origin.port).c_str(), log_signal(gate_node));
module, gate_origin.cell, gate_origin.cell->module->design->twines.str(gate_origin.port).c_str(), log_signal(gate_node));
else
log(" Packing %s.%s.%s [%d] (%s).\n",
module, gate_origin.cell, gate_module->design->twines.str(origin.port).c_str(), gate_origin.offset, log_signal(gate_node));
module, gate_origin.cell, gate_origin.cell->module->design->twines.str(gate_origin.port).c_str(), gate_origin.offset, log_signal(gate_node));
}
vector<RTLIL::SigBit> input_nodes(lut_edges_bw[node].begin(), lut_edges_bw[node].end());

View file

@ -202,7 +202,7 @@ struct IopadmapPass : public Pass {
// Recursively collect list of (module, port, bit) triples that already have buffers.
pool<pair<IdString, pair<IdString, int>>> buf_ports;
pool<pair<TwineRef, pair<TwineRef, int>>> buf_ports;
// Process submodules before module using them.
std::vector<Module *> modules_sorted;
@ -225,7 +225,7 @@ struct IopadmapPass : public Pass {
for (auto cell : module->cells())
for (auto port : cell->connections())
for (int i = 0; i < port.second.size(); i++)
if (buf_ports.count(make_pair(cell->type, make_pair(port.first, i))))
if (buf_ports.count(make_pair(cell->type_impl, make_pair(port.first, i))))
buf_bits.insert(sigmap(port.second[i]));
// Now fill buf_ports.
@ -233,7 +233,7 @@ struct IopadmapPass : public Pass {
if (wire->port_input || wire->port_output)
for (int i = 0; i < GetSize(wire); i++)
if (buf_bits.count(sigmap(SigBit(wire, i)))) {
buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i)));
buf_ports.insert(make_pair(module->name.ref(), make_pair(wire->name.ref(), i)));
log("Marking already mapped port: %s.%s[%d].\n", module, wire, i);
}
}
@ -242,7 +242,7 @@ struct IopadmapPass : public Pass {
for (auto module : design->selected_modules())
{
dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits;
dict<Wire *, dict<int, pair<Cell *, TwineRef>>> rewrite_bits;
dict<SigSig, pool<int>> remove_conns;
if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty())
@ -293,7 +293,7 @@ struct IopadmapPass : public Pass {
SigBit wire_bit(wire, i);
Cell *tbuf_cell = nullptr;
if (buf_ports.count(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i))))
if (buf_ports.count(make_pair(module->name.ref(), make_pair(wire->name.ref(), i))))
continue;
if (tbuf_bits.count(wire_bit))
@ -330,37 +330,37 @@ struct IopadmapPass : public Pass {
log("Mapping port %s.%s[%d] using %s.\n", module, wire, i, tinoutpad_celltype);
Cell *cell = module->addCell(
module->uniquify(stringf("$iopadmap$%s.%s[%d]", module, wire, i)),
RTLIL::escape_id(tinoutpad_celltype));
module->uniquify(Twine{stringf("$iopadmap$%s.%s[%d]", module, wire, i)}),
module->design->twines.add(Twine{RTLIL::escape_id(tinoutpad_celltype)}));
if (tinoutpad_neg_oe)
en_sig = module->NotGate(NEW_TWINE, en_sig);
cell->setPort(RTLIL::escape_id(tinoutpad_portname_oe), en_sig);
cell->setPort(module->design->twines.add(Twine{RTLIL::escape_id(tinoutpad_portname_oe)}), en_sig);
cell->attributes[ID::keep] = RTLIL::Const(1);
if (tbuf_cell) {
module->remove(tbuf_cell);
cell->setPort(RTLIL::escape_id(tinoutpad_portname_o), wire_bit);
cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), data_sig);
cell->setPort(module->design->twines.add(Twine{RTLIL::escape_id(tinoutpad_portname_o)}), wire_bit);
cell->setPort(module->design->twines.add(Twine{RTLIL::escape_id(tinoutpad_portname_i)}), data_sig);
} else if (is_driven) {
cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), wire_bit);
cell->setPort(module->design->twines.add(Twine{RTLIL::escape_id(tinoutpad_portname_i)}), wire_bit);
} else {
cell->setPort(RTLIL::escape_id(tinoutpad_portname_o), wire_bit);
cell->setPort(RTLIL::escape_id(tinoutpad_portname_i), data_sig);
cell->setPort(module->design->twines.add(Twine{RTLIL::escape_id(tinoutpad_portname_o)}), wire_bit);
cell->setPort(module->design->twines.add(Twine{RTLIL::escape_id(tinoutpad_portname_i)}), data_sig);
}
if (!tinoutpad_portname_pad.empty())
rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(tinoutpad_portname_pad));
rewrite_bits[wire][i] = make_pair(cell, module->design->twines.add(Twine{RTLIL::escape_id(tinoutpad_portname_pad)}));
} else {
log("Mapping port %s.%s[%d] using %s.\n", module, wire, i, toutpad_celltype);
Cell *cell = module->addCell(
module->uniquify(stringf("$iopadmap$%s.%s[%d]", module, wire, i)),
RTLIL::escape_id(toutpad_celltype));
module->uniquify(Twine{stringf("$iopadmap$%s.%s[%d]", module, wire, i)}),
module->design->twines.add(Twine{RTLIL::escape_id(toutpad_celltype)}));
if (toutpad_neg_oe)
en_sig = module->NotGate(NEW_TWINE, en_sig);
cell->setPort(RTLIL::escape_id(toutpad_portname_oe), en_sig);
cell->setPort(RTLIL::escape_id(toutpad_portname_i), data_sig);
cell->setPort(module->design->twines.add(Twine{RTLIL::escape_id(toutpad_portname_oe)}), en_sig);
cell->setPort(module->design->twines.add(Twine{RTLIL::escape_id(toutpad_portname_i)}), data_sig);
cell->attributes[ID::keep] = RTLIL::Const(1);
if (tbuf_cell) {
@ -368,9 +368,9 @@ struct IopadmapPass : public Pass {
module->connect(wire_bit, data_sig);
}
if (!toutpad_portname_pad.empty())
rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(toutpad_portname_pad));
rewrite_bits[wire][i] = make_pair(cell, module->design->twines.add(Twine{RTLIL::escape_id(toutpad_portname_pad)}));
}
buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i)));
buf_ports.insert(make_pair(module->name.ref(), make_pair(wire->name.ref(), i)));
}
}
}
@ -384,7 +384,7 @@ struct IopadmapPass : public Pass {
pool<int> skip_bit_indices;
for (int i = 0; i < GetSize(wire); i++)
if (buf_ports.count(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i))))
if (buf_ports.count(make_pair(module->name.ref(), make_pair(wire->name.ref(), i))))
skip_bit_indices.insert(i);
if (GetSize(wire) == GetSize(skip_bit_indices))
@ -436,12 +436,12 @@ struct IopadmapPass : public Pass {
SigBit wire_bit(wire, i);
RTLIL::Cell *cell = module->addCell(
module->uniquify(stringf("$iopadmap$%s.%s", design->twines.unescaped_str(module->name), design->twines.unescaped_str(wire->name))),
RTLIL::escape_id(celltype));
cell->setPort(RTLIL::escape_id(portname_int), wire_bit);
module->uniquify(Twine{stringf("$iopadmap$%s.%s", module->name.unescaped(), wire->name.unescaped())}),
module->design->twines.add(Twine{RTLIL::escape_id(celltype)}));
cell->setPort(module->design->twines.add(Twine{RTLIL::escape_id(portname_int)}), wire_bit);
if (!portname_pad.empty())
rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(portname_pad));
rewrite_bits[wire][i] = make_pair(cell, module->design->twines.add(Twine{RTLIL::escape_id(portname_pad)}));
if (!widthparam.empty())
cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(1);
if (!nameparam.empty())
@ -452,23 +452,23 @@ struct IopadmapPass : public Pass {
else
{
RTLIL::Cell *cell = module->addCell(
module->uniquify(stringf("$iopadmap$%s.%s", design->twines.unescaped_str(module->name), design->twines.unescaped_str(wire->name))),
RTLIL::escape_id(celltype));
cell->setPort(RTLIL::escape_id(portname_int), RTLIL::SigSpec(wire));
module->uniquify(Twine{stringf("$iopadmap$%s.%s", module->name.unescaped(), wire->name.unescaped())}),
module->design->twines.add(Twine{RTLIL::escape_id(celltype)}));
cell->setPort(module->design->twines.add(Twine{RTLIL::escape_id(portname_int)}), RTLIL::SigSpec(wire));
if (!portname_pad.empty()) {
RTLIL::Wire *new_wire = NULL;
new_wire = module->addWire(
module->uniquify(stringf("$iopadmap$%s", wire)),
module->uniquify(Twine{stringf("$iopadmap$%s", wire)}),
wire);
module->swap_names(new_wire, wire);
wire->attributes.clear();
cell->setPort(RTLIL::escape_id(portname_pad), RTLIL::SigSpec(new_wire));
cell->setPort(module->design->twines.add(Twine{RTLIL::escape_id(portname_pad)}), RTLIL::SigSpec(new_wire));
}
if (!widthparam.empty())
cell->parameters[RTLIL::escape_id(widthparam)] = RTLIL::Const(wire->width);
if (!nameparam.empty())
cell->parameters[RTLIL::escape_id(nameparam)] = design->twines.unescaped_str(RTLIL::Const(wire->name));
cell->parameters[RTLIL::escape_id(nameparam)] = RTLIL::Const(wire->name.unescape());
cell->attributes[ID::keep] = RTLIL::Const(1);
}
@ -503,7 +503,7 @@ struct IopadmapPass : public Pass {
for (auto &it : rewrite_bits) {
RTLIL::Wire *wire = it.first;
RTLIL::Wire *new_wire = module->addWire(
module->uniquify(stringf("$iopadmap$%s", wire)),
module->uniquify(Twine{stringf("$iopadmap$%s", wire)}),
wire);
module->swap_names(new_wire, wire);
wire->attributes.clear();

View file

@ -36,7 +36,7 @@ struct ShregmapOptions
int minlen, maxlen;
int keep_before, keep_after;
bool zinit, init, params, ffe;
dict<IdString, pair<IdString, IdString>> ffcells;
dict<TwineRef, pair<TwineRef, TwineRef>> ffcells;
ShregmapTech *tech;
ShregmapOptions()
@ -75,14 +75,14 @@ struct ShregmapTechGreenpak4 : ShregmapTech
auto D = cell->getPort(TW::D);
auto C = cell->getPort(TW::C);
auto newcell = cell->module->addCell(NEW_TWINE, ID(GP_SHREG));
auto newcell = cell->module->addCell(NEW_TWINE, TW::GP_SHREG);
newcell->setPort(TW::nRST, State::S1);
newcell->setPort(TW::CLK, C);
newcell->setPort(TW::IN, D);
int i = 0;
for (auto tap : taps) {
newcell->setPort(i ? ID(OUTB) : ID(OUTA), tap.second);
newcell->setPort(i ? TW::OUTB : TW::OUTA, tap.second);
newcell->setParam(i ? ID(OUTB_TAP) : ID(OUTA_TAP), tap.first + 1);
i++;
}
@ -120,10 +120,10 @@ struct ShregmapWorker
for (auto cell : module->cells())
{
if (opts.ffcells.count(cell->type) && !cell->get_bool_attribute(ID::keep))
if (opts.ffcells.count(cell->type_impl) && !cell->get_bool_attribute(ID::keep))
{
IdString d_port = opts.ffcells.at(cell->type).first;
IdString q_port = opts.ffcells.at(cell->type).second;
TwineRef d_port = opts.ffcells.at(cell->type_impl).first;
TwineRef q_port = opts.ffcells.at(cell->type_impl).second;
SigBit d_bit = sigmap(cell->getPort(d_port).as_bit());
SigBit q_bit = sigmap(cell->getPort(q_port).as_bit());
@ -178,8 +178,8 @@ struct ShregmapWorker
if (c1->parameters != c2->parameters)
goto start_cell;
IdString d_port = opts.ffcells.at(c1->type).first;
IdString q_port = opts.ffcells.at(c1->type).second;
TwineRef d_port = opts.ffcells.at(c1->type_impl).first;
TwineRef q_port = opts.ffcells.at(c1->type_impl).second;
auto c1_conn = c1->connections();
auto c2_conn = c2->connections();
@ -210,7 +210,7 @@ struct ShregmapWorker
{
chain.push_back(c);
IdString q_port = opts.ffcells.at(c->type).second;
TwineRef q_port = opts.ffcells.at(c->type_impl).second;
SigBit q_bit = sigmap(c->getPort(q_port).as_bit());
if (sigbit_chain_next.count(q_bit) == 0)
@ -238,7 +238,7 @@ struct ShregmapWorker
depth = std::min(opts.maxlen, depth);
Cell *first_cell = chain[cursor];
IdString q_port = opts.ffcells.at(first_cell->type).second;
TwineRef q_port = opts.ffcells.at(first_cell->type_impl).second;
dict<int, SigBit> taps_dict;
if (opts.tech)
@ -456,9 +456,9 @@ struct ShregmapPass : public Pass {
match_args.push_back("D");
if (GetSize(match_args) < 3)
match_args.push_back("Q");
IdString id_cell_type(RTLIL::escape_id(match_args[0]));
IdString id_d_port_name(RTLIL::escape_id(match_args[1]));
IdString id_q_port_name(RTLIL::escape_id(match_args[2]));
TwineRef id_cell_type = design->twines.add(std::string{RTLIL::escape_id(match_args[0])});
TwineRef id_d_port_name = design->twines.add(std::string{RTLIL::escape_id(match_args[1])});
TwineRef id_q_port_name = design->twines.add(std::string{RTLIL::escape_id(match_args[2])});
opts.ffcells[id_cell_type] = make_pair(id_d_port_name, id_q_port_name);
continue;
}
@ -519,19 +519,19 @@ struct ShregmapPass : public Pass {
bool en_neg = enpol == "neg" || enpol == "any" || enpol == "any_or_none";
if (clk_pos && en_none)
opts.ffcells[TW($_DFF_P_)] = make_pair(IdString(ID::D), IdString(ID::Q));
opts.ffcells[TW($_DFF_P_)] = make_pair(TW::D, TW::Q);
if (clk_neg && en_none)
opts.ffcells[TW($_DFF_N_)] = make_pair(IdString(ID::D), IdString(ID::Q));
opts.ffcells[TW($_DFF_N_)] = make_pair(TW::D, TW::Q);
if (clk_pos && en_pos)
opts.ffcells[TW($_DFFE_PP_)] = make_pair(IdString(ID::D), IdString(ID::Q));
opts.ffcells[TW($_DFFE_PP_)] = make_pair(TW::D, TW::Q);
if (clk_pos && en_neg)
opts.ffcells[TW($_DFFE_PN_)] = make_pair(IdString(ID::D), IdString(ID::Q));
opts.ffcells[TW($_DFFE_PN_)] = make_pair(TW::D, TW::Q);
if (clk_neg && en_pos)
opts.ffcells[TW($_DFFE_NP_)] = make_pair(IdString(ID::D), IdString(ID::Q));
opts.ffcells[TW($_DFFE_NP_)] = make_pair(TW::D, TW::Q);
if (clk_neg && en_neg)
opts.ffcells[TW($_DFFE_NN_)] = make_pair(IdString(ID::D), IdString(ID::Q));
opts.ffcells[TW($_DFFE_NN_)] = make_pair(TW::D, TW::Q);
if (en_pos || en_neg)
opts.ffe = true;

View file

@ -54,7 +54,7 @@ void apply_prefix(IdString prefix, RTLIL::SigSpec &sig, RTLIL::Module *module)
if (chunk.wire != nullptr) {
IdString wire_name = chunk.wire->name;
apply_prefix(prefix, wire_name);
TwineRef wire_ref = module->design->twines.add(Twine{wire_name.str()});
TwineRef wire_ref = module->design->twines.add(std::string{wire_name.str()});
log_assert(module->wire(wire_ref) != nullptr);
chunk.wire = module->wire(wire_ref);
}
@ -120,7 +120,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_")) {
@ -168,7 +168,7 @@ struct TechmapWorker
orig_cell_name = cell->name.str();
for (auto tpl_cell : tpl->cells())
if (tpl_cell->name.ends_with("_TECHMAP_REPLACE_")) {
module->rename(cell, module->design->twines.add(Twine{stringf("$techmap%d", autoidx++) + cell->name.str()}));
module->rename(cell, module->design->twines.add(std::string{stringf("$techmap%d", autoidx++) + cell->name.str()}));
break;
}
@ -178,7 +178,7 @@ struct TechmapWorker
IdString old_m_id(std::string(tpl->design->twines.str(it.first)));
IdString m_name_id = old_m_id;
apply_prefix(cell->name, m_name_id);
TwineRef m_ref = module->design->twines.add(Twine{m_name_id.str()});
TwineRef m_ref = module->design->twines.add(std::string{m_name_id.str()});
RTLIL::Memory *m = module->addMemory(m_ref, it.second);
if (m->has_attribute(ID::src))
design->merge_src(m, src_cell);
@ -194,7 +194,7 @@ struct TechmapWorker
{
if (tpl_w->port_id > 0)
{
TwineRef posportref = module->design->twines.add(Twine{stringf("$%d", tpl_w->port_id)});
TwineRef posportref = module->design->twines.add(std::string{stringf("$%d", tpl_w->port_id)});
positional_ports.emplace(posportref, tpl_w->name.ref());
if (tpl_w->get_bool_attribute(ID::techmap_autopurge) &&
@ -211,7 +211,7 @@ struct TechmapWorker
}
IdString w_name = tpl_w->name;
apply_prefix(cell->name, w_name);
TwineRef w_ref = module->design->twines.add(Twine{w_name.str()});
TwineRef w_ref = module->design->twines.add(std::string{w_name.str()});
RTLIL::Wire *w = module->wire(w_ref);
if (w != nullptr) {
temp_renamed_wires[w] = w->name.ref();
@ -219,7 +219,7 @@ struct TechmapWorker
w = nullptr;
}
if (w == nullptr) {
w = module->addWire(Twine{w_name.str()}, tpl_w);
w = module->addWire(w_ref, tpl_w);
w->port_input = false;
w->port_output = false;
w->port_id = 0;
@ -231,8 +231,8 @@ struct TechmapWorker
}
design->select(module, w);
if (const char *p = strstr(tpl_w->name.c_str(), "_TECHMAP_REPLACE_.")) {
Wire *replace_w = module->addWire(Twine{std::string(orig_cell_name) + (p + strlen("_TECHMAP_REPLACE_"))}, tpl_w);
if (const char *p = strstr(tpl_w->name.str().c_str(), "_TECHMAP_REPLACE_.")) {
Wire *replace_w = module->addWire(module->design->twines.add(std::string{std::string(orig_cell_name) + (p + strlen("_TECHMAP_REPLACE_"))}), tpl_w);
module->connect(replace_w, w);
}
}
@ -335,16 +335,16 @@ struct TechmapWorker
if (techmap_replace_cell)
c_name = orig_cell_name;
else if (const char *p = strstr(tpl_cell->name.c_str(), "_TECHMAP_REPLACE_."))
else if (const char *p = strstr(tpl_cell->name.str().c_str(), "_TECHMAP_REPLACE_."))
c_name = stringf("%s%s", orig_cell_name, p + strlen("_TECHMAP_REPLACE_"));
else
apply_prefix(cell->name, c_name);
RTLIL::Cell *c = module->addCell(module->design->twines.add(Twine{c_name.str()}), tpl_cell);
RTLIL::Cell *c = module->addCell(module->design->twines.add(std::string{c_name.str()}), tpl_cell);
design->select(module, c);
if (c->type.in(TwineRef{TW(_TECHMAP_PLACEHOLDER_)}) && tpl_cell->has_attribute(ID::techmap_chtype)) {
c->type_impl = module->design->twines.add(Twine{RTLIL::escape_id(tpl_cell->get_string_attribute(ID::techmap_chtype))});
c->type_impl = module->design->twines.add(std::string{RTLIL::escape_id(tpl_cell->get_string_attribute(ID::techmap_chtype))});
c->attributes.erase(ID::techmap_chtype);
}
@ -457,7 +457,7 @@ struct TechmapWorker
continue;
for (auto &tpl_name : celltypeMap.at(cell->type)) {
RTLIL::Module *tpl = map->module(tpl_name);
RTLIL::Module *tpl = map->module(map->twines.add(std::string{tpl_name.str()}));
RTLIL::Wire *port = tpl->wire(conn.first);
if (port && port->port_input)
cell_to_inbit[cell].insert(sig.begin(), sig.end());
@ -485,8 +485,8 @@ struct TechmapWorker
for (auto &tpl_name : celltypeMap.at(cell->type))
{
TwineRef derived_name = map->twines.add(Twine{tpl_name.str()});
RTLIL::Module *tpl = map->module(tpl_name);
TwineRef derived_name = map->twines.add(std::string{tpl_name.str()});
RTLIL::Module *tpl = map->module(derived_name);
dict<IdString, RTLIL::Const> parameters(cell->parameters);
if (tpl->get_blackbox_attribute(ignore_wb))
@ -516,11 +516,11 @@ struct TechmapWorker
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(IdString(m_name));
RTLIL::Module *extmapper_module = extmapper_design->module(extmapper_design->twines.add(std::string{m_name}));
if (extmapper_module == nullptr)
{
extmapper_module = extmapper_design->addModule(extmapper_design->twines.add(Twine{m_name}));
extmapper_module = extmapper_design->addModule(extmapper_design->twines.add(std::string{m_name}));
RTLIL::Cell *extmapper_cell = extmapper_module->addCell(cell->type.ref(), cell);
// addCell(name, cell) already migrated src across
// designs via copy_src_into — no need for an
@ -710,7 +710,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;
@ -757,10 +757,9 @@ struct TechmapWorker
techmap_wire_names.erase(it.first);
std::string final_id = data.wire->name.unescaped();
size_t start_idx = final_id.empty() ? 0 : 1;
size_t dot_pos = final_id.rfind('.', start_idx);
size_t split_idx = (dot_pos != std::string::npos) ? (dot_pos + 1) : start_idx;
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();
@ -772,9 +771,9 @@ struct TechmapWorker
log("Analyzing pattern of constant bits for this cell:\n");
IdString new_tpl_name = constmap_tpl_name(sigmap, tpl, cell, true);
log("Creating constmapped module `%s'.\n", log_id(new_tpl_name));
log_assert(map->module(new_tpl_name) == nullptr);
log_assert(map->module(map->twines.add(std::string{new_tpl_name.str()})) == nullptr);
RTLIL::Module *new_tpl = map->addModule(map->twines.add(Twine{new_tpl_name.str()}));
RTLIL::Module *new_tpl = map->addModule(map->twines.add(std::string{new_tpl_name.str()}));
tpl->cloneInto(new_tpl);
techmap_do_cache.erase(tpl);
@ -793,7 +792,7 @@ struct TechmapWorker
IdString port_name = wire->name;
tpl->rename(wire, tpl->design->twines.add(NEW_TWINE));
RTLIL::Wire *new_wire = tpl->addWire(Twine{port_name.str()}, wire);
RTLIL::Wire *new_wire = tpl->addWire(tpl->design->twines.add(std::string{port_name.str()}), wire);
wire->port_input = false;
wire->port_id = 0;
@ -865,13 +864,13 @@ struct TechmapWorker
Pass::call_on_module(map, tpl, cmd_string);
map->sigNormalize(false);
// log_assert(!strncmp(q, "_TECHMAP_DO_", 12));
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(Twine{new_name})) != nullptr)
while (tpl->wire(tpl->design->twines.add(std::string{new_name})) != nullptr)
new_name += "_";
tpl->rename(data.wire->name.ref(), tpl->design->twines.add(Twine{new_name}));
tpl->rename(data.wire->name.ref(), tpl->design->twines.add(std::string{new_name}));
keep_running = true;
break;
@ -917,7 +916,7 @@ struct TechmapWorker
for (auto &it2 : it.second) {
auto val = it2.value.as_const();
auto wirename = RTLIL::escape_id(it.first.substr(21, it.first.size() - 21 - 1));
TwineRef wirename_ref = cell->module->design->twines.add(Twine{wirename});
TwineRef 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);
@ -933,16 +932,16 @@ struct TechmapWorker
{
std::string m_name = stringf("$extern:%s", log_id(tpl->name));
if (!design->module(RTLIL::IdString(m_name)))
if (!design->module(design->twines.add(std::string{m_name})))
{
RTLIL::Module *m = design->addModule(design->twines.add(Twine{m_name}));
RTLIL::Module *m = design->addModule(design->twines.add(std::string{m_name}));
tpl->cloneInto(m);
module_queue.insert(m);
}
log_debug("%s %s.%s to imported %s.\n", mapmsg_prefix.c_str(), log_id(module->name), log_id(cell->name), m_name.c_str());
cell->type_impl = cell->module->design->twines.add(Twine{m_name});
cell->type_impl = cell->module->design->twines.add(std::string{m_name});
cell->parameters.clear();
}
else
@ -1233,7 +1232,7 @@ struct TechmapPass : public Pass {
log_cmd_error("Can't open saved design `%s'.\n", fn.c_str()+1);
}
for (auto mod : saved_designs.at(fn.substr(1))->modules())
if (!map->module(IdString(mod->name)))
if (!map->module(map->twines.add(std::string{mod->name.str()})))
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));