abstract: -init MVP

This commit is contained in:
Emil J. Tywoniak 2025-02-03 22:25:09 +01:00
parent 7ce938a071
commit 497a6e0c59
2 changed files with 59 additions and 22 deletions

View File

@ -67,17 +67,63 @@ bool abstract_value(Module* mod, Wire* wire, Wire* enable, bool enable_pol) {
return false; return false;
} }
bool abstract_init(Module* mod, Cell* cell) { struct AbstractInitCtx {
CellTypes ct; Module* mod;
ct.setup_internals_ff(); SigMap sigmap;
if (!ct.cell_types.count(cell->type)) pool<SigBit> init_bits;
return false; };
// TODO figure out memory cells?
cell->unsetParam(ID::init); void collect_init_bits_cells(AbstractInitCtx& ctx) {
return true; // TODO Should this discriminate between FFs and other cells?
for (auto cell : ctx.mod->selected_cells()) {
// Add all sigbits on all cell outputs to init_bits
for (auto &conn : cell->connections()) {
if (cell->output(conn.first)) {
for (auto bit : conn.second) {
log_debug("init: cell %s output %s\n", cell->name.c_str(), log_signal(bit));
ctx.init_bits.insert(ctx.sigmap(bit));
}
}
}
}
} }
void collect_init_bits_wires(AbstractInitCtx& ctx) {
for (auto wire : ctx.mod->selected_wires()) {
auto canonical = ctx.sigmap(wire);
// Find canonical drivers of all the wire bits and add them to init_bits
for (auto bit : canonical.bits()) {
log_debug("init: wire %s bit %s\n", wire->name.c_str(), log_signal(bit));
ctx.init_bits.insert(ctx.sigmap(bit));
}
}
}
unsigned int abstract_init(Module* mod) {
AbstractInitCtx ctx {mod, SigMap(mod), pool<SigBit>()};
pool<SigBit> init_bits;
collect_init_bits_cells(ctx);
collect_init_bits_wires(ctx);
unsigned int changed = 0;
for (SigBit bit : ctx.init_bits) {
next_sigbit:
if (!bit.is_wire() || !bit.wire->has_attribute(ID::init))
continue;
Const init = bit.wire->attributes.at(ID::init);
std::vector<RTLIL::State>& bits = init.bits();
bits[bit.offset] = RTLIL::State::Sx;
changed++;
for (auto bit : bits)
if (bit != RTLIL::State::Sx)
goto next_sigbit;
// All bits are Sx, erase init attribute entirely
bit.wire->attributes.erase(ID::init);
}
return changed;
}
struct AbstractPass : public Pass { struct AbstractPass : public Pass {
AbstractPass() : Pass("abstract", "extract clock gating out of flip flops") { } AbstractPass() : Pass("abstract", "extract clock gating out of flip flops") { }
@ -155,11 +201,9 @@ struct AbstractPass : public Pass {
log("Abstracted %d cells.\n", changed); log("Abstracted %d cells.\n", changed);
} else if (mode == Initial) { } else if (mode == Initial) {
for (auto mod : design->selected_modules()) { for (auto mod : design->selected_modules()) {
for (auto cell : mod->selected_cells()) { changed += abstract_init(mod);
changed += abstract_init(mod, cell);
}
} }
log("Abstracted %d wires.\n", changed); log("Abstracted %d bits.\n", changed);
} else { } else {
log_cmd_error("No mode selected, see help message\n"); log_cmd_error("No mode selected, see help message\n");
} }

View File

@ -10,12 +10,10 @@ endmodule
EOT EOT
proc proc
# dump
# show -prefix before_base # show -prefix before_base
abstract -state -enablen magic abstract -state -enablen magic
check check
# show -prefix after_base # show -prefix after_base
# dump
design -reset design -reset
read_verilog <<EOT read_verilog <<EOT
@ -33,8 +31,6 @@ EOT
proc proc
opt_expr opt_expr
opt_dff opt_dff
# show
# dump
# show -prefix before_en # show -prefix before_en
abstract -state -enablen magic abstract -state -enablen magic
check check
@ -87,11 +83,8 @@ EOT
proc proc
opt_expr opt_expr
opt_dff opt_dff
# show # show -prefix before_a
# dump
show -prefix before_a
abstract -state -enablen magic abstract -state -enablen magic
check check
show -prefix after_a # show -prefix after_a
# opt_clean # opt_clean
# show