abstract: no more bufnorm, -value has bit selection consistent with -state, -init temporarily gutted

This commit is contained in:
Emil J. Tywoniak 2025-02-10 13:06:40 +01:00
parent 355f5e3740
commit 6ffc12389f
1 changed files with 61 additions and 58 deletions

View File

@ -100,71 +100,78 @@ unsigned int abstract_state(Module* mod, EnableLogic enable) {
return changed; return changed;
} }
struct AbstractPortCtx {
Module* mod;
SigMap sigmap;
pool<std::pair<Cell*, IdString>> outs;
};
void collect_selected_ports(AbstractPortCtx& ctx) {
for (Cell* cell : ctx.mod->cells()) {
for (auto& conn : cell->connections()) {
// we bufnorm
log_assert(conn.second.is_wire() || conn.second.is_fully_const());
if (conn.second.is_wire() && cell->output(conn.first))
if (ctx.mod->selected(cell) || ctx.mod->selected(conn.second.as_wire()))
ctx.outs.insert(std::make_pair(cell, conn.first));
}
}
}
unsigned int abstract_value(Module* mod, EnableLogic enable) { unsigned int abstract_value(Module* mod, EnableLogic enable) {
AbstractPortCtx ctx {mod, SigMap(mod), {}}; SigMap sigmap(mod);
collect_selected_ports(ctx); pool<SigBit> selected_representatives = gather_selected_reps(mod, sigmap);
unsigned int changed = 0; unsigned int changed = 0;
for (auto [cell, port] : ctx.outs) { std::vector<Cell*> cells_snapshot = mod->cells();
SigSpec sig = cell->getPort(port); for (auto cell : cells_snapshot) {
log_assert(sig.is_wire()); for (auto conn : cell->connections())
Wire* original = mod->addWire(NEW_ID, sig.size()); if (cell->output(conn.first)) {
cell->setPort(port, original); std::set<int> offsets_to_abstract;
auto anyseq = mod->Anyseq(NEW_ID, sig.size()); for (int i = 0; i < conn.second.size(); i++) {
// This code differs from abstract_state if (selected_representatives.count(sigmap(conn.second[i]))) {
// in that we reuse the original signal as the mux output, offsets_to_abstract.insert(i);
// not input }
}
if (offsets_to_abstract.empty())
continue;
auto anyseq = mod->Anyseq(NEW_ID, offsets_to_abstract.size());
Wire* to_abstract = mod->addWire(NEW_ID, offsets_to_abstract.size());
SigSpec mux_input;
SigSpec mux_output;
SigSpec new_port = conn.second;
int to_abstract_idx = 0;
for (int port_idx = 0; port_idx < conn.second.size(); port_idx++) {
if (offsets_to_abstract.count(port_idx)) {
log_debug("bit %d: abstracted\n", port_idx);
mux_output.append(conn.second[port_idx]);
SigBit in_bit {to_abstract, to_abstract_idx};
new_port.replace(port_idx, in_bit);
conn.second[port_idx] = {mod->addWire(NEW_ID, 1), 0};
mux_input.append(in_bit);
log_assert(to_abstract_idx < to_abstract->width);
to_abstract_idx++;
}
}
cell->setPort(conn.first, new_port);
SigSpec mux_a, mux_b; SigSpec mux_a, mux_b;
if (enable.pol) { if (enable.pol) {
mux_a = original; mux_a = mux_input;
mux_b = anyseq; mux_b = anyseq;
} else { } else {
mux_a = anyseq; mux_a = anyseq;
mux_b = original; mux_b = mux_input;
} }
(void)mod->addMux(NEW_ID, (void)mod->addMux(NEW_ID,
mux_a, mux_a,
mux_b, mux_b,
enable.wire, enable.wire,
sig); mux_output);
changed++; changed++;
} }
}
return changed; return changed;
} }
unsigned int abstract_init(Module* mod) { unsigned int abstract_init(Module* mod) {
AbstractPortCtx ctx {mod, SigMap(mod), {}}; // AbstractPortCtx ctx {mod, SigMap(mod), {}};
collect_selected_ports(ctx); // collect_selected_ports(ctx);
unsigned int changed = 0; unsigned int changed = 0;
for (auto [cell, port] : ctx.outs) { // for (auto [cell, port] : ctx.outs) {
SigSpec sig = cell->getPort(port); // SigSpec sig = cell->getPort(port);
log_assert(sig.is_wire()); // log_assert(sig.is_wire());
if (!sig.as_wire()->has_attribute(ID::init)) // if (!sig.as_wire()->has_attribute(ID::init))
continue; // continue;
Const init = sig.as_wire()->attributes.at(ID::init); // Const init = sig.as_wire()->attributes.at(ID::init);
sig.as_wire()->attributes.erase(ID::init); // sig.as_wire()->attributes.erase(ID::init);
changed += sig.size(); // changed += sig.size();
} // }
log_cmd_error("Not implemented\n"); (void)mod;
return changed; return changed;
} }
@ -217,8 +224,6 @@ struct AbstractPass : public Pass {
} }
extra_args(args, argidx, design); extra_args(args, argidx, design);
if (mode != State)
design->bufNormalize(true);
unsigned int changed = 0; unsigned int changed = 0;
if ((mode == State) || (mode == Value)) { if ((mode == State) || (mode == Value)) {
@ -249,8 +254,6 @@ struct AbstractPass : public Pass {
} else { } else {
log_cmd_error("No mode selected, see help message\n"); log_cmd_error("No mode selected, see help message\n");
} }
if (mode != State)
design->bufNormalize(false);
} }
} AbstractPass; } AbstractPass;