diff --git a/techlibs/coolrunner2/coolrunner2_fixup.cc b/techlibs/coolrunner2/coolrunner2_fixup.cc index 2b2249596..7b62a346f 100644 --- a/techlibs/coolrunner2/coolrunner2_fixup.cc +++ b/techlibs/coolrunner2/coolrunner2_fixup.cc @@ -23,6 +23,11 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +static IdString uniq(RTLIL::Module *module, std::string name) +{ + return module->uniquify(std::move(name)); +} + RTLIL::Wire *makexorbuffer(RTLIL::Module *module, SigBit inwire, const char *cellname) { RTLIL::Wire *outwire = nullptr; @@ -31,9 +36,9 @@ RTLIL::Wire *makexorbuffer(RTLIL::Module *module, SigBit inwire, const char *cel { // Constant 1 outwire = module->addWire( - module->uniquify(stringf("$xc2fix$%s_BUF1_XOR_OUT", cellname))); + uniq(module, stringf("$xc2fix$%s_BUF1_XOR_OUT", cellname))); auto xor_cell = module->addCell( - module->uniquify(stringf("$xc2fix$%s_BUF1_XOR", cellname)), + uniq(module, stringf("$xc2fix$%s_BUF1_XOR", cellname)), ID(MACROCELL_XOR)); xor_cell->setParam(ID(INVERT_OUT), true); xor_cell->setPort(ID(OUT), outwire); @@ -42,9 +47,9 @@ RTLIL::Wire *makexorbuffer(RTLIL::Module *module, SigBit inwire, const char *cel { // Constant 0 outwire = module->addWire( - module->uniquify(stringf("$xc2fix$%s_BUF0_XOR_OUT", cellname))); + uniq(module, stringf("$xc2fix$%s_BUF0_XOR_OUT", cellname))); auto xor_cell = module->addCell( - module->uniquify(stringf("$xc2fix$%s_BUF0_XOR", cellname)), + uniq(module, stringf("$xc2fix$%s_BUF0_XOR", cellname)), ID(MACROCELL_XOR)); xor_cell->setParam(ID(INVERT_OUT), false); xor_cell->setPort(ID(OUT), outwire); @@ -54,25 +59,25 @@ RTLIL::Wire *makexorbuffer(RTLIL::Module *module, SigBit inwire, const char *cel // x; treat as 0 log_warning("While buffering, changing x to 0 into cell %s\n", cellname); outwire = module->addWire( - module->uniquify(stringf("$xc2fix$%s_BUF0_XOR_OUT", cellname))); + uniq(module, stringf("$xc2fix$%s_BUF0_XOR_OUT", cellname))); auto xor_cell = module->addCell( - module->uniquify(stringf("$xc2fix$%s_BUF0_XOR", cellname)), + uniq(module, stringf("$xc2fix$%s_BUF0_XOR", cellname)), ID(MACROCELL_XOR)); xor_cell->setParam(ID(INVERT_OUT), false); xor_cell->setPort(ID(OUT), outwire); } else { - auto inwire_name = inwire.wire->name.c_str(); + auto inwire_name_s = inwire.wire->name.unescape(); auto inwire_name = inwire_name_s.c_str(); outwire = module->addWire( - module->uniquify(stringf("$xc2fix$%s_BUF_XOR_OUT", inwire_name))); + uniq(module, stringf("$xc2fix$%s_BUF_XOR_OUT", inwire_name))); auto and_to_xor_wire = module->addWire( - module->uniquify(stringf("$xc2fix$%s_BUF_AND_OUT", inwire_name))); + uniq(module, stringf("$xc2fix$%s_BUF_AND_OUT", inwire_name))); auto and_cell = module->addCell( - module->uniquify(stringf("$xc2fix$%s_BUF_AND", inwire_name)), + uniq(module, stringf("$xc2fix$%s_BUF_AND", inwire_name)), ID(ANDTERM)); and_cell->setParam(ID(TRUE_INP), 1); and_cell->setParam(ID(COMP_INP), 0); @@ -81,7 +86,7 @@ RTLIL::Wire *makexorbuffer(RTLIL::Module *module, SigBit inwire, const char *cel and_cell->setPort(ID(IN_B), SigSpec()); auto xor_cell = module->addCell( - module->uniquify(stringf("$xc2fix$%s_BUF_XOR", inwire_name)), + uniq(module, stringf("$xc2fix$%s_BUF_XOR", inwire_name)), ID(MACROCELL_XOR)); xor_cell->setParam(ID(INVERT_OUT), false); xor_cell->setPort(ID(IN_PTC), and_to_xor_wire); @@ -93,13 +98,13 @@ RTLIL::Wire *makexorbuffer(RTLIL::Module *module, SigBit inwire, const char *cel RTLIL::Wire *makeptermbuffer(RTLIL::Module *module, SigBit inwire) { - auto inwire_name = inwire.wire->name.c_str(); + auto inwire_name_s = inwire.wire->name.unescape(); auto inwire_name = inwire_name_s.c_str(); auto outwire = module->addWire( - module->uniquify(stringf("$xc2fix$%s_BUF_AND_OUT", inwire_name))); + uniq(module, stringf("$xc2fix$%s_BUF_AND_OUT", inwire_name))); auto and_cell = module->addCell( - module->uniquify(stringf("$xc2fix$%s_BUF_AND", inwire_name)), + uniq(module, stringf("$xc2fix$%s_BUF_AND", inwire_name)), ID(ANDTERM)); and_cell->setParam(ID(TRUE_INP), 1); and_cell->setParam(ID(COMP_INP), 0); @@ -267,9 +272,9 @@ struct Coolrunner2FixupPass : public Pass { if (input == ibuf_out_wire) { log("Found IBUF %s that can be packed with FF %s (type %s)\n", - ibuf_out_wire.wire->name.c_str(), - maybe_ff_cell->name.c_str(), - maybe_ff_cell->type.c_str()); + ibuf_out_wire.wire->name.unescape().c_str(), + maybe_ff_cell->name.unescape().c_str(), + maybe_ff_cell->type.str().c_str()); ibuf_out_to_packed_reg_cell[ibuf_out_wire] = maybe_ff_cell; packed_reg_out.insert(output); @@ -300,7 +305,7 @@ struct Coolrunner2FixupPass : public Pass { { log("Buffering input to \"%s\"\n", cell->name); - auto xor_to_ff_wire = makexorbuffer(module, input, cell->name.c_str()); + auto xor_to_ff_wire = makexorbuffer(module, input, cell->name.unescape().c_str()); if (cell->type.in(ID(FTCP), ID(FTCP_N), ID(FTDCP))) cell->setPort(ID::T, xor_to_ff_wire); @@ -391,7 +396,7 @@ struct Coolrunner2FixupPass : public Pass { { log("Buffering input to \"%s\"\n", cell->name); - auto xor_to_io_wire = makexorbuffer(module, input, cell->name.c_str()); + auto xor_to_io_wire = makexorbuffer(module, input, cell->name.unescape().c_str()); cell->setPort(ID::I, xor_to_io_wire); } @@ -448,9 +453,9 @@ struct Coolrunner2FixupPass : public Pass { if (xor_fanout_once[wire_in]) { log("Additional fanout found for %s into %s (type %s), duplicating\n", - xor_cell->name.c_str(), - cell->name.c_str(), - cell->type.c_str()); + xor_cell->name.unescape().c_str(), + cell->name.unescape().c_str(), + cell->type.str().c_str()); auto new_xor_cell = module->addCell( module->uniquify(xor_cell->name), xor_cell); @@ -496,9 +501,9 @@ struct Coolrunner2FixupPass : public Pass { if (or_fanout_once[wire_in]) { log("Additional fanout found for %s into %s (type %s), duplicating\n", - or_cell->name.c_str(), - cell->name.c_str(), - cell->type.c_str()); + or_cell->name.unescape().c_str(), + cell->name.unescape().c_str(), + cell->type.str().c_str()); auto new_or_cell = module->addCell( module->uniquify(or_cell->name), or_cell); diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index 67d3813a7..9306965ff 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -117,37 +117,44 @@ static void run_ice40_opts(Module *module) if (GetSize(replacement_output)) { optimized_co.insert(sigmap(cell->getPort(ID::CO)[0])); - auto it = cell->attributes.find(IdString{"\\SB_LUT4.name"}); + TwinePool &twines = module->design->twines; + IdString lut_name_attr = twines.add(std::string("\\SB_LUT4.name")); + auto it = cell->attributes.find(lut_name_attr); if (it != cell->attributes.end()) { module->rename(cell, it->second.decode_string()); decltype(Cell::attributes) new_attr; - for (const auto &a : cell->attributes) - if (a.first.begins_with("\\SB_LUT4.\\")) - new_attr[a.first.c_str() + strlen("\\SB_LUT4.")] = a.second; + for (const auto &a : cell->attributes) { + std::string aname = twines.str(a.first); + if (aname.starts_with("\\SB_LUT4.\\")) + new_attr[twines.add(aname.substr(strlen("\\SB_LUT4.")))] = a.second; else if (a.first == ID::src) new_attr.insert(std::make_pair(a.first, a.second)); - else if (a.first.in(IdString{"\\SB_LUT4.name"}, ID::keep, ID::module_not_derived)) + else if (a.first.in(lut_name_attr, ID::keep, ID::module_not_derived)) continue; - else if (a.first.begins_with("\\SB_CARRY.\\")) + else if (aname.starts_with("\\SB_CARRY.\\")) continue; else log_abort(); + } cell->attributes = std::move(new_attr); } module->connect(cell->getPort(ID::CO)[0], replacement_output); module->design->scratchpad_set_bool("opt.did_something", true); log("Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n", module, cell, log_signal(replacement_output)); - cell->type = ID($lut); auto I3 = get_bit_or_zero(cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID::CI : ID(I3))); - cell->setPort(ID::A, { I3, inbit[1], inbit[0], get_bit_or_zero(cell->getPort(ID(I0))) }); - cell->setPort(ID::Y, cell->getPort(ID::O)); + RTLIL::SigSpec sig_a { I3, inbit[1], inbit[0], get_bit_or_zero(cell->getPort(ID(I0))) }; + RTLIL::SigSpec sig_y = cell->getPort(ID::O); + cell->unsetPort(ID::A); cell->unsetPort(ID::B); cell->unsetPort(ID::CI); cell->unsetPort(ID(I0)); cell->unsetPort(ID(I3)); cell->unsetPort(ID::CO); cell->unsetPort(ID::O); + cell->type = ID($lut); + cell->setPort(ID::A, std::move(sig_a)); + cell->setPort(ID::Y, std::move(sig_y)); cell->setParam(ID::WIDTH, 4); cell->unsetParam(ID(I3_IS_CI)); } diff --git a/techlibs/ice40/ice40_wrapcarry.cc b/techlibs/ice40/ice40_wrapcarry.cc index 63ebdbfcf..4276a4365 100644 --- a/techlibs/ice40/ice40_wrapcarry.cc +++ b/techlibs/ice40/ice40_wrapcarry.cc @@ -58,11 +58,12 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm) cell->setPort(ID::O, st.lut->getPort(ID::O)); cell->setParam(ID::LUT, st.lut->getParam(ID(LUT_INIT))); + TwinePool &twines = cell->module->design->twines; for (const auto &a : st.carry->attributes) - cell->attributes[stringf("\\SB_CARRY.%s", a.first)] = a.second; + cell->attributes[twines.add(stringf("\\SB_CARRY.%s", twines.str(a.first)))] = a.second; for (const auto &a : st.lut->attributes) - cell->attributes[stringf("\\SB_LUT4.%s", a.first)] = a.second; - cell->attributes[IdString{"\\SB_LUT4.name"}] = Const(st.lut->name.str()); + cell->attributes[twines.add(stringf("\\SB_LUT4.%s", twines.str(a.first)))] = a.second; + cell->attributes[twines.add(std::string("\\SB_LUT4.name"))] = Const(st.lut->name.str()); if (st.carry->get_bool_attribute(ID::keep) || st.lut->get_bool_attribute(ID::keep)) cell->attributes[ID::keep] = true; @@ -109,9 +110,9 @@ struct Ice40WrapCarryPass : public Pass { extra_args(args, argidx, design); for (auto module : design->selected_modules()) { - if (!unwrap) + if (!unwrap) { ice40_wrapcarry_pm(module, module->selected_cells()).run_ice40_wrapcarry(create_ice40_wrapcarry); - else { + } else { for (auto cell : module->selected_cells()) { if (cell->type != ID($__ICE40_CARRY_WRAPPER)) continue; @@ -122,8 +123,12 @@ struct Ice40WrapCarryPass : public Pass { carry->setPort(ID::CI, cell->getPort(ID::CI)); carry->setPort(ID::CO, cell->getPort(ID::CO)); module->swap_names(carry, cell); - auto lut_name = cell->attributes.at(IdString{"\\SB_LUT4.name"}, Const(NEW_ID.str())).decode_string(); - auto lut = module->addCell(lut_name, ID($lut)); + TwinePool &twines = module->design->twines; + IdString lut_name_attr = twines.add(std::string("\\SB_LUT4.name")); + auto lut_name = cell->attributes.find(lut_name_attr); + auto lut = lut_name != cell->attributes.end() + ? module->addCell(lut_name->second.decode_string(), ID($lut)) + : module->addCell(NEW_ID, ID($lut)); lut->setParam(ID::WIDTH, 4); lut->setParam(ID::LUT, cell->getParam(ID::LUT)); auto I3 = cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID::CI : ID(I3)); @@ -131,17 +136,19 @@ struct Ice40WrapCarryPass : public Pass { lut->setPort(ID::Y, cell->getPort(ID::O)); Const src; - for (const auto &a : cell->attributes) - if (a.first.begins_with("\\SB_CARRY.\\")) - carry->attributes[a.first.c_str() + strlen("\\SB_CARRY.")] = a.second; - else if (a.first.begins_with("\\SB_LUT4.\\")) - lut->attributes[a.first.c_str() + strlen("\\SB_LUT4.")] = a.second; + for (const auto &a : cell->attributes) { + std::string aname = twines.str(a.first); + if (aname.starts_with("\\SB_CARRY.\\")) + carry->attributes[twines.add(aname.substr(strlen("\\SB_CARRY.")))] = a.second; + else if (aname.starts_with("\\SB_LUT4.\\")) + lut->attributes[twines.add(aname.substr(strlen("\\SB_LUT4.")))] = a.second; else if (a.first == ID::src) src = a.second; - else if (a.first.in(IdString{"\\SB_LUT4.name"}, ID::keep, ID::module_not_derived, ID::src)) + else if (a.first.in(lut_name_attr, ID::keep, ID::module_not_derived)) continue; else log_abort(); + } if (!src.empty()) { carry->attributes.insert(std::make_pair(ID::src, src));