3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-22 23:25:51 +00:00
This commit is contained in:
Emil J. Tywoniak 2026-06-12 00:18:53 +02:00
parent afdae7b87e
commit c3ffbf6fae
229 changed files with 3902 additions and 3835 deletions

View file

@ -74,7 +74,7 @@ struct ShareWorker
queue_bits.insert(modwalker.signal_outputs.begin(), modwalker.signal_outputs.end());
for (auto &it : module->cells_)
if (!StaticCellTypes::Compat::internals_nomem_noff(it.second->type)) {
if (!StaticCellTypes::Compat::internals_nomem_noff(it.second->type_impl)) {
pool<RTLIL::SigBit> &bits = modwalker.cell_inputs[it.second];
queue_bits.insert(bits.begin(), bits.end());
}
@ -88,13 +88,13 @@ struct ShareWorker
queue_bits.clear();
for (auto &pbit : portbits) {
if ((pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) && visited_cells.count(pbit.cell) == 0) {
if ((pbit.cell->type == TW($mux) || pbit.cell->type == TW($pmux)) && visited_cells.count(pbit.cell) == 0) {
pool<RTLIL::SigBit> bits = modwalker.sigmap(pbit.cell->getPort(TW::S)).to_sigbit_pool();
terminal_bits.insert(bits.begin(), bits.end());
queue_bits.insert(bits.begin(), bits.end());
visited_cells.insert(pbit.cell);
}
if (StaticCellTypes::Compat::internals_nomem_noff(pbit.cell->type) && visited_cells.count(pbit.cell) == 0) {
if (StaticCellTypes::Compat::internals_nomem_noff(pbit.cell->type_impl) && visited_cells.count(pbit.cell) == 0) {
pool<RTLIL::SigBit> &bits = modwalker.cell_inputs[pbit.cell];
terminal_bits.insert(bits.begin(), bits.end());
queue_bits.insert(bits.begin(), bits.end());
@ -351,7 +351,7 @@ struct ShareWorker
{
for (auto cell : module->cells())
{
if (!design->selected(module, cell) || !modwalker.ct.cell_known(cell->type))
if (!design->selected(module, cell) || !modwalker.ct.cell_known(cell->type_impl))
continue;
for (auto &bit : modwalker.cell_outputs[cell])
@ -362,7 +362,7 @@ struct ShareWorker
not_a_muxed_cell:
continue;
if (cell->type.in(ID($memrd), ID($memrd_v2))) {
if (cell->type.in(TW($memrd), TW($memrd_v2))) {
if (cell->parameters.at(ID::CLK_ENABLE).as_bool())
continue;
if (config.opt_aggressive || !modwalker.sigmap(cell->getPort(TW::ADDR)).is_fully_const())
@ -370,19 +370,19 @@ struct ShareWorker
continue;
}
if (cell->type.in(ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor))) {
if (cell->type.in(TW($mul), TW($div), TW($mod), TW($divfloor), TW($modfloor))) {
if (config.opt_aggressive || cell->parameters.at(ID::Y_WIDTH).as_int() >= 4)
shareable_cells.insert(cell);
continue;
}
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) {
if (cell->type.in(TW($shl), TW($shr), TW($sshl), TW($sshr))) {
if (config.opt_aggressive || cell->parameters.at(ID::Y_WIDTH).as_int() >= 8)
shareable_cells.insert(cell);
continue;
}
if (generic_ops(cell->type)) {
if (generic_ops(cell->type_impl)) {
if (config.opt_aggressive)
shareable_cells.insert(cell);
continue;
@ -395,7 +395,7 @@ struct ShareWorker
if (c1->type != c2->type)
return false;
if (c1->type.in(ID($memrd), ID($memrd_v2)))
if (c1->type.in(TW($memrd), TW($memrd_v2)))
{
if (c1->parameters.at(ID::MEMID).decode_string() != c2->parameters.at(ID::MEMID).decode_string())
return false;
@ -406,7 +406,7 @@ struct ShareWorker
return true;
}
if (config.generic_uni_ops(c1->type))
if (config.generic_uni_ops(c1->type_impl))
{
if (!config.opt_aggressive)
{
@ -423,7 +423,7 @@ struct ShareWorker
return true;
}
if (config.generic_bin_ops(c1->type) || c1->type == ID($alu))
if (config.generic_bin_ops(c1->type_impl) || c1->type == TW($alu))
{
if (!config.opt_aggressive)
{
@ -443,7 +443,7 @@ struct ShareWorker
return true;
}
if (config.generic_cbin_ops(c1->type))
if (config.generic_cbin_ops(c1->type_impl))
{
if (!config.opt_aggressive)
{
@ -469,7 +469,7 @@ struct ShareWorker
return true;
}
if (c1->type == ID($macc))
if (c1->type == TW($macc))
{
if (!config.opt_aggressive)
if (share_macc(c1, c2) > 2 * min(bits_macc(c1), bits_macc(c2))) return false;
@ -505,7 +505,7 @@ struct ShareWorker
{
log_assert(c1->type == c2->type);
if (config.generic_uni_ops(c1->type))
if (config.generic_uni_ops(c1->type_impl))
{
if (c1->parameters.at(ID::A_SIGNED).as_bool() != c2->parameters.at(ID::A_SIGNED).as_bool())
{
@ -540,7 +540,7 @@ struct ShareWorker
RTLIL::Wire *y = module->addWire(NEW_TWINE, y_width);
RTLIL::Cell *supercell = module->addCell(NEW_TWINE, c1->type);
RTLIL::Cell *supercell = module->addCell(NEW_TWINE, c1->type_impl);
supercell->parameters[ID::A_SIGNED] = a_signed;
supercell->parameters[ID::A_WIDTH] = a_width;
supercell->parameters[ID::Y_WIDTH] = y_width;
@ -554,11 +554,11 @@ struct ShareWorker
return supercell;
}
if (config.generic_bin_ops(c1->type) || config.generic_cbin_ops(c1->type) || c1->type == ID($alu))
if (config.generic_bin_ops(c1->type_impl) || config.generic_cbin_ops(c1->type_impl) || c1->type_impl == TW($alu))
{
bool modified_src_cells = false;
if (config.generic_cbin_ops(c1->type))
if (config.generic_cbin_ops(c1->type_impl))
{
int score_unflipped = max(c1->parameters.at(ID::A_WIDTH).as_int(), c2->parameters.at(ID::A_WIDTH).as_int()) +
max(c1->parameters.at(ID::B_WIDTH).as_int(), c2->parameters.at(ID::B_WIDTH).as_int());
@ -616,7 +616,7 @@ struct ShareWorker
log_assert(a_signed == c2->parameters.at(ID::A_SIGNED).as_bool());
log_assert(b_signed == c2->parameters.at(ID::B_SIGNED).as_bool());
if (c1->type == ID($shl) || c1->type == ID($shr) || c1->type == ID($sshl) || c1->type == ID($sshr))
if (c1->type == TW($shl) || c1->type == TW($shr) || c1->type == TW($sshl) || c1->type == TW($sshr))
b_signed = false;
RTLIL::SigSpec a1 = c1->getPort(TW::A);
@ -631,7 +631,7 @@ struct ShareWorker
int b_width = max(b1.size(), b2.size());
int y_width = max(y1.size(), y2.size());
if (c1->type == ID($shr) && a_signed)
if (c1->type == TW($shr) && a_signed)
{
a_width = max(y_width, a_width);
@ -657,10 +657,10 @@ struct ShareWorker
supercell_aux.insert(module->addMux(NEW_TWINE, b2, b1, act, b));
RTLIL::Wire *y = module->addWire(NEW_TWINE, y_width);
RTLIL::Wire *x = c1->type == ID($alu) ? module->addWire(NEW_TWINE, y_width) : nullptr;
RTLIL::Wire *co = c1->type == ID($alu) ? module->addWire(NEW_TWINE, y_width) : nullptr;
RTLIL::Wire *x = c1->type == TW($alu) ? module->addWire(NEW_TWINE, y_width) : nullptr;
RTLIL::Wire *co = c1->type == TW($alu) ? module->addWire(NEW_TWINE, y_width) : nullptr;
RTLIL::Cell *supercell = module->addCell(NEW_TWINE, c1->type);
RTLIL::Cell *supercell = module->addCell(NEW_TWINE, c1->type_impl);
supercell->parameters[ID::A_SIGNED] = a_signed;
supercell->parameters[ID::B_SIGNED] = b_signed;
supercell->parameters[ID::A_WIDTH] = a_width;
@ -669,7 +669,7 @@ struct ShareWorker
supercell->setPort(TW::A, a);
supercell->setPort(TW::B, b);
supercell->setPort(TW::Y, y);
if (c1->type == ID($alu)) {
if (c1->type == TW($alu)) {
RTLIL::Wire *ci = module->addWire(NEW_TWINE), *bi = module->addWire(NEW_TWINE);
supercell_aux.insert(module->addMux(NEW_TWINE, c2->getPort(TW::CI), c1->getPort(TW::CI), act, ci));
supercell_aux.insert(module->addMux(NEW_TWINE, c2->getPort(TW::BI), c1->getPort(TW::BI), act, bi));
@ -682,7 +682,7 @@ struct ShareWorker
supercell_aux.insert(module->addPos(NEW_TWINE, y, y1));
supercell_aux.insert(module->addPos(NEW_TWINE, y, y2));
if (c1->type == ID($alu)) {
if (c1->type == TW($alu)) {
supercell_aux.insert(module->addPos(NEW_TWINE, co, c1->getPort(TW::CO)));
supercell_aux.insert(module->addPos(NEW_TWINE, co, c2->getPort(TW::CO)));
supercell_aux.insert(module->addPos(NEW_TWINE, x, c1->getPort(TW::X)));
@ -693,16 +693,16 @@ struct ShareWorker
return supercell;
}
if (c1->type == ID($macc))
if (c1->type == TW($macc))
{
RTLIL::Cell *supercell = module->addCell(NEW_TWINE, c1->type);
RTLIL::Cell *supercell = module->addCell(NEW_TWINE, c1->type_impl);
supercell_aux.insert(supercell);
share_macc(c1, c2, act, supercell, &supercell_aux);
supercell->check();
return supercell;
}
if (c1->type.in(ID($memrd), ID($memrd_v2)))
if (c1->type.in(TW($memrd), TW($memrd_v2)))
{
RTLIL::Cell *supercell = module->addCell(NEW_TWINE, c1);
RTLIL::SigSpec addr1 = c1->getPort(TW::ADDR);
@ -744,7 +744,7 @@ struct ShareWorker
modwalker.get_consumers(pbits, modwalker.cell_outputs[cell]);
for (auto &bit : pbits) {
if ((bit.cell->type == ID($mux) || bit.cell->type == ID($pmux)) && bit.port == TW::S)
if ((bit.cell->type == TW($mux) || bit.cell->type == TW($pmux)) && bit.port == TW::S)
forbidden_controls_cache[cell].insert(bit.cell->getPort(TW::S).extract(bit.offset, 1));
consumer_cells.insert(bit.cell);
}
@ -752,7 +752,7 @@ struct ShareWorker
recursion_state.insert(cell);
for (auto c : consumer_cells)
if (StaticCellTypes::Compat::internals_nomem_noff(c->type)) {
if (StaticCellTypes::Compat::internals_nomem_noff(c->type_impl)) {
const pool<RTLIL::SigBit> &bits = find_forbidden_controls(c);
forbidden_controls_cache[cell].insert(bits.begin(), bits.end());
}
@ -891,8 +891,8 @@ struct ShareWorker
return activation_patterns_cache.at(cell);
}
for (auto &pbit : modwalker.signal_consumers[bit]) {
log_assert(StaticCellTypes::Compat::internals_nomem_noff(pbit.cell->type));
if ((pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) && (pbit.port == TW::A || pbit.port == TW::B))
log_assert(StaticCellTypes::Compat::internals_nomem_noff(pbit.cell->type_impl));
if ((pbit.cell->type == TW($mux) || pbit.cell->type == TW($pmux)) && (pbit.port == TW::A || pbit.port == TW::B))
driven_data_muxes.insert(pbit.cell);
else
driven_cells.insert(pbit.cell);
@ -1095,9 +1095,9 @@ struct ShareWorker
dict<RTLIL::SigBit, pool<RTLIL::Cell*>> bit_to_cells;
for (auto cell : module->cells())
if (ct.cell_known(cell->type))
if (ct.cell_known(cell->type_impl))
for (auto &conn : cell->connections()) {
if (ct.cell_output(cell->type, conn.first))
if (ct.cell_output(cell->type_impl, conn.first))
for (auto bit : topo_sigmap(conn.second)) {
cell_to_bits[cell].insert(bit);
topo_bit_drivers[bit].insert(cell);
@ -1123,7 +1123,7 @@ struct ShareWorker
for (auto &loop : toposort.loops) {
log("### loop ###\n");
for (auto &c : loop)
log("%s (%s)\n", c, c->type.unescape());
log("%s (%s)\n", c, design->twines.unescaped_str(c->type));
}
return found_scc;
@ -1167,13 +1167,13 @@ struct ShareWorker
pool<RTLIL::Cell*> new_queue;
for (auto c : queue) {
if (!ct.cell_known(c->type))
if (!ct.cell_known(c->type_impl))
continue;
for (auto &conn : c->connections())
if (ct.cell_input(c->type, conn.first))
if (ct.cell_input(c->type_impl, conn.first))
for (auto bit : conn.second)
for (auto &pi : mi.query_ports(bit))
if (ct.cell_known(pi.cell->type) && ct.cell_output(pi.cell->type, pi.port))
if (ct.cell_known(pi.cell->type_impl) && ct.cell_output(pi.cell->type_impl, pi.port))
new_queue.insert(pi.cell);
covered.insert(c);
}
@ -1247,7 +1247,7 @@ struct ShareWorker
RTLIL::Cell *cell = *shareable_cells.begin();
shareable_cells.erase(cell);
log(" Analyzing resource sharing options for %s (%s):\n", cell, cell->type.unescape());
log(" Analyzing resource sharing options for %s (%s):\n", cell, cell->type.unescaped());
const pool<ssc_pair_t> &cell_activation_patterns = find_cell_activation_patterns(cell, " ");
RTLIL::SigSpec cell_activation_signals = bits_from_activation_patterns(cell_activation_patterns);
@ -1280,7 +1280,7 @@ struct ShareWorker
for (auto other_cell : candidates)
{
log(" Analyzing resource sharing with %s (%s):\n", other_cell, other_cell->type.unescape());
log(" Analyzing resource sharing with %s (%s):\n", other_cell, design->twines.unescaped_str(other_cell->type));
const pool<ssc_pair_t> &other_cell_activation_patterns = find_cell_activation_patterns(other_cell, " ");
RTLIL::SigSpec other_cell_activation_signals = bits_from_activation_patterns(other_cell_activation_patterns);
@ -1431,7 +1431,7 @@ struct ShareWorker
log(" Activation signal for %s: %s\n", other_cell, log_signal(act));
}
log(" New cell: %s (%s)\n", supercell, supercell->type.unescape());
log(" New cell: %s (%s)\n", supercell, design->twines.unescaped_str(supercell->type));
cells_to_remove.insert(cell);
cells_to_remove.insert(other_cell);
@ -1478,7 +1478,7 @@ struct ShareWorker
if (!cells_to_remove.empty()) {
log("Removing %d cells in module %s:\n", GetSize(cells_to_remove), module);
for (auto c : cells_to_remove) {
log(" Removing cell %s (%s).\n", c, c->type.unescape());
log(" Removing cell %s (%s).\n", c, design->twines.unescaped_str(c->type));
remove_cell(c);
}
}
@ -1532,45 +1532,45 @@ struct SharePass : public Pass {
config.opt_aggressive = false;
config.opt_fast = false;
config.generic_uni_ops.set_id(ID($not));
// config.generic_uni_ops.set_id(ID($pos));
config.generic_uni_ops.set_id(ID($neg));
config.generic_uni_ops.set_id(TW($not));
// config.generic_uni_ops.set_id(TW($pos));
config.generic_uni_ops.set_id(TW($neg));
config.generic_cbin_ops.set_id(ID($and));
config.generic_cbin_ops.set_id(ID($or));
config.generic_cbin_ops.set_id(ID($xor));
config.generic_cbin_ops.set_id(ID($xnor));
config.generic_cbin_ops.set_id(TW($and));
config.generic_cbin_ops.set_id(TW($or));
config.generic_cbin_ops.set_id(TW($xor));
config.generic_cbin_ops.set_id(TW($xnor));
config.generic_bin_ops.set_id(ID($shl));
config.generic_bin_ops.set_id(ID($shr));
config.generic_bin_ops.set_id(ID($sshl));
config.generic_bin_ops.set_id(ID($sshr));
config.generic_bin_ops.set_id(TW($shl));
config.generic_bin_ops.set_id(TW($shr));
config.generic_bin_ops.set_id(TW($sshl));
config.generic_bin_ops.set_id(TW($sshr));
config.generic_bin_ops.set_id(ID($lt));
config.generic_bin_ops.set_id(ID($le));
config.generic_bin_ops.set_id(ID($eq));
config.generic_bin_ops.set_id(ID($ne));
config.generic_bin_ops.set_id(ID($eqx));
config.generic_bin_ops.set_id(ID($nex));
config.generic_bin_ops.set_id(ID($ge));
config.generic_bin_ops.set_id(ID($gt));
config.generic_bin_ops.set_id(TW($lt));
config.generic_bin_ops.set_id(TW($le));
config.generic_bin_ops.set_id(TW($eq));
config.generic_bin_ops.set_id(TW($ne));
config.generic_bin_ops.set_id(TW($eqx));
config.generic_bin_ops.set_id(TW($nex));
config.generic_bin_ops.set_id(TW($ge));
config.generic_bin_ops.set_id(TW($gt));
config.generic_cbin_ops.set_id(ID($add));
config.generic_cbin_ops.set_id(ID($mul));
config.generic_cbin_ops.set_id(TW($add));
config.generic_cbin_ops.set_id(TW($mul));
config.generic_bin_ops.set_id(ID($sub));
config.generic_bin_ops.set_id(ID($div));
config.generic_bin_ops.set_id(ID($mod));
config.generic_bin_ops.set_id(ID($divfloor));
config.generic_bin_ops.set_id(ID($modfloor));
// config.generic_bin_ops.set_id(ID($pow));
config.generic_bin_ops.set_id(TW($sub));
config.generic_bin_ops.set_id(TW($div));
config.generic_bin_ops.set_id(TW($mod));
config.generic_bin_ops.set_id(TW($divfloor));
config.generic_bin_ops.set_id(TW($modfloor));
// config.generic_bin_ops.set_id(TW($pow));
config.generic_uni_ops.set_id(ID($logic_not));
config.generic_cbin_ops.set_id(ID($logic_and));
config.generic_cbin_ops.set_id(ID($logic_or));
config.generic_uni_ops.set_id(TW($logic_not));
config.generic_cbin_ops.set_id(TW($logic_and));
config.generic_cbin_ops.set_id(TW($logic_or));
config.generic_other_ops.set_id(ID($alu));
config.generic_other_ops.set_id(ID($macc));
config.generic_other_ops.set_id(TW($alu));
config.generic_other_ops.set_id(TW($macc));
log_header(design, "Executing SHARE pass (SAT-based resource sharing).\n");