abc9: Fix breaking of SCCs

Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
David Shah 2019-12-01 20:44:56 +00:00
parent 5f4c35c753
commit e9ce4e658b
2 changed files with 46 additions and 29 deletions

View File

@ -94,20 +94,30 @@ void handle_loops(RTLIL::Design *design)
if (cell->output(c.first)) {
SigBit b = c.second.as_bit();
Wire *w = b.wire;
log_assert(!w->port_input);
w->port_input = true;
w = module->wire(stringf("%s.abci", w->name.c_str()));
if (!w) {
w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire));
w->port_output = true;
if (w->port_input) {
// In this case, hopefully the loop break has been already created
// Get the non-prefixed wire
Wire *wo = module->wire(stringf("%s.abco", b.wire->name.c_str()));
log_assert(wo != nullptr);
log_assert(wo->port_output);
log_assert(b.offset < GetSize(wo));
c.second = RTLIL::SigBit(wo, b.offset);
}
else {
log_assert(w->port_input);
log_assert(b.offset < GetSize(w));
// Create a new output/input loop break
w->port_input = true;
w = module->wire(stringf("%s.abco", w->name.c_str()));
if (!w) {
w = module->addWire(stringf("%s.abco", b.wire->name.c_str()), GetSize(b.wire));
w->port_output = true;
}
else {
log_assert(w->port_input);
log_assert(b.offset < GetSize(w));
}
w->set_bool_attribute(ID(abc9_scc_break));
c.second = RTLIL::SigBit(w, b.offset);
}
w->set_bool_attribute(ID(abc9_scc_break));
module->swap_names(b.wire, w);
c.second = RTLIL::SigBit(w, b.offset);
}
}
}
@ -420,24 +430,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
design->selection_stack.pop_back();
// Now 'unexpose' those wires by undoing
// the expose operation -- remove them from PO/PI
// and re-connecting them back together
for (auto wire : module->wires()) {
auto it = wire->attributes.find(ID(abc9_scc_break));
if (it != wire->attributes.end()) {
wire->attributes.erase(it);
log_assert(wire->port_output);
wire->port_output = false;
RTLIL::Wire *i_wire = module->wire(wire->name.str() + ".abci");
log_assert(i_wire);
log_assert(i_wire->port_input);
i_wire->port_input = false;
module->connect(i_wire, wire);
}
}
module->fixup_ports();
log_header(design, "Executing ABC9.\n");
if (!lut_costs.empty()) {
@ -781,6 +773,25 @@ clone_lut:
}
}
// Now 'unexpose' those wires by undoing
// the expose operation -- remove them from PO/PI
// and re-connecting them back together
for (auto wire : module->wires()) {
auto it = wire->attributes.find(ID(abc9_scc_break));
if (it != wire->attributes.end()) {
wire->attributes.erase(it);
log_assert(wire->port_output);
wire->port_output = false;
std::string name = wire->name.str();
RTLIL::Wire *i_wire = module->wire(name.substr(0, GetSize(name) - 5));
log_assert(i_wire);
log_assert(i_wire->port_input);
i_wire->port_input = false;
module->connect(i_wire, wire);
}
}
module->fixup_ports();
//log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires);
log("ABC RESULTS: input signals: %8d\n", in_wires);
log("ABC RESULTS: output signals: %8d\n", out_wires);

View File

@ -258,3 +258,9 @@ module abc9_test026(output [3:0] o, p);
assign o = { 1'b1, 1'bx };
assign p = { 1'b1, 1'bx, 1'b0 };
endmodule
module abc9_test030(input [3:0] d, input en, output reg [3:0] q);
always @*
if (en)
q <= d;
endmodule