mirror of
https://github.com/YosysHQ/yosys.git
synced 2026-09-05 19:36:55 +02:00
techlibs: rebuild attribute name handling on the pool
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user