3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-14 04:48:46 +00:00

Fix writing non-whole modules, including inouts and keeps

This commit is contained in:
Eddie Hung 2019-12-06 16:19:10 -08:00
parent ec0acc9f85
commit 1f96de04c9

View file

@ -142,7 +142,7 @@ struct XAigerWriter
{ {
pool<SigBit> undriven_bits; pool<SigBit> undriven_bits;
pool<SigBit> unused_bits; pool<SigBit> unused_bits;
pool<SigBit> keep_bits; pool<SigBit> inout_bits;
// promote public wires // promote public wires
for (auto wire : module->wires()) for (auto wire : module->wires())
@ -154,42 +154,34 @@ struct XAigerWriter
if (wire->port_input) if (wire->port_input)
sigmap.add(wire); sigmap.add(wire);
// promote output wires // promote keep wires
for (auto wire : module->wires()) for (auto wire : module->wires())
if (wire->port_output) if (wire->get_bool_attribute(ID::keep))
sigmap.add(wire); sigmap.add(wire);
for (auto wire : module->wires()) for (auto wire : module->wires())
{
bool keep = wire->attributes.count("\\keep");
for (int i = 0; i < GetSize(wire); i++) for (int i = 0; i < GetSize(wire); i++)
{ {
SigBit wirebit(wire, i); SigBit wirebit(wire, i);
SigBit bit = sigmap(wirebit); SigBit bit = sigmap(wirebit);
if (bit.wire) { if (bit.wire == nullptr) {
undriven_bits.insert(bit); if (wire->port_output) {
unused_bits.insert(bit); aig_map[wirebit] = (bit == State::S1) ? 1 : 0;
} if (holes_mode)
if (keep) {
keep_bits.insert(wirebit);
if (bit != wirebit)
alias_map[wirebit] = bit;
input_bits.insert(wirebit);
output_bits.insert(wirebit); output_bits.insert(wirebit);
//external_bits.insert(wirebit);
}
continue; continue;
} }
if (wire->port_input) { undriven_bits.insert(bit);
if (bit != wirebit) unused_bits.insert(bit);
alias_map[bit] = wirebit;
input_bits.insert(wirebit); if (wire->port_input)
} input_bits.insert(bit);
if (wire->port_output) { if (wire->port_output) {
if (bit != RTLIL::Sx) {
if (bit != wirebit) if (bit != wirebit)
alias_map[wirebit] = bit; alias_map[wirebit] = bit;
if (holes_mode) if (holes_mode)
@ -197,17 +189,10 @@ struct XAigerWriter
else else
external_bits.insert(wirebit); external_bits.insert(wirebit);
} }
else
log_debug("Skipping PO '%s' driven by 1'bx\n", log_signal(wirebit));
}
}
}
// Cannot fold into above due to use of sigmap if (wire->port_input && wire->port_output)
for (auto bit : input_bits) inout_bits.insert(bit);
undriven_bits.erase(sigmap(bit)); }
for (auto bit : output_bits)
unused_bits.erase(sigmap(bit));
// TODO: Speed up toposort -- ultimately we care about // TODO: Speed up toposort -- ultimately we care about
// box ordering, but not individual AIG cells // box ordering, but not individual AIG cells
@ -307,10 +292,9 @@ struct XAigerWriter
if (I != b) if (I != b)
alias_map[b] = I; alias_map[b] = I;
output_bits.insert(b); output_bits.insert(b);
unused_bits.erase(I);
if (!cell_known) if (!cell_known)
keep_bits.insert(b); inout_bits.insert(b);
} }
} }
} }
@ -328,11 +312,10 @@ struct XAigerWriter
for (auto b : c.second) { for (auto b : c.second) {
Wire *w = b.wire; Wire *w = b.wire;
if (!w) continue; if (!w) continue;
input_bits.insert(b);
SigBit O = sigmap(b); SigBit O = sigmap(b);
if (O != b) if (O != b)
alias_map[O] = b; alias_map[O] = b;
undriven_bits.erase(O); input_bits.insert(b);
if (arrival) if (arrival)
arrival_times[b] = arrival; arrival_times[b] = arrival;
@ -343,12 +326,6 @@ struct XAigerWriter
//log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); //log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell));
} }
for (auto cell : module->cells())
if (!module->selected(cell))
for (auto &conn : cell->connections())
for (auto bit : sigmap(conn.second))
external_bits.insert(bit);
if (abc9_box_seen) { if (abc9_box_seen) {
dict<IdString, std::pair<IdString,int>> flop_q; dict<IdString, std::pair<IdString,int>> flop_q;
for (auto cell : flop_boxes) { for (auto cell : flop_boxes) {
@ -494,8 +471,8 @@ struct XAigerWriter
SigBit O = sigmap(b); SigBit O = sigmap(b);
if (O != b) if (O != b)
alias_map[O] = b; alias_map[O] = b;
undriven_bits.erase(O);
input_bits.erase(b); input_bits.erase(b);
undriven_bits.erase(O);
} }
} }
} }
@ -528,15 +505,48 @@ struct XAigerWriter
// TODO: Free memory from toposort, bit_drivers, bit_users // TODO: Free memory from toposort, bit_drivers, bit_users
} }
for (auto bit : input_bits) { if (!holes_mode)
if (!output_bits.count(bit)) for (auto cell : module->cells())
if (!module->selected(cell))
for (auto &conn : cell->connections())
if (cell->input(conn.first))
for (auto wirebit : conn.second)
if (sigmap(wirebit).wire)
external_bits.insert(wirebit);
// For all bits consumed outside of the selected cells,
// but driven from a selected cell, then add it as
// a primary output
for (auto wirebit : external_bits) {
SigBit bit = sigmap(wirebit);
if (!bit.wire)
continue; continue;
RTLIL::Wire *wire = bit.wire; if (!undriven_bits.count(bit)) {
// If encountering an inout port, or a keep-ed wire, then create a new wire if (bit != wirebit)
// with $inout.out suffix, make it a PO driven by the existing inout, and alias_map[wirebit] = bit;
output_bits.insert(wirebit);
}
}
for (auto bit : input_bits)
undriven_bits.erase(sigmap(bit));
for (auto bit : output_bits)
unused_bits.erase(sigmap(bit));
for (auto bit : unused_bits)
undriven_bits.erase(bit);
// Make all undriven bits a primary input
if (!holes_mode)
for (auto bit : undriven_bits) {
input_bits.insert(bit);
undriven_bits.erase(bit);
}
// For inout ports, or keep-ed wires, then create a new wire with an
// $inout.out suffix, make it a PO driven by the existing inout, and
// inherit existing inout's drivers // inherit existing inout's drivers
if ((wire->port_input && wire->port_output && !undriven_bits.count(bit)) for (auto bit : inout_bits) {
|| keep_bits.count(bit)) { RTLIL::Wire *wire = bit.wire;
RTLIL::IdString wire_name = stringf("$%s$inout.out", wire->name.c_str()); RTLIL::IdString wire_name = stringf("$%s$inout.out", wire->name.c_str());
RTLIL::Wire *new_wire = module->wire(wire_name); RTLIL::Wire *new_wire = module->wire(wire_name);
if (!new_wire) if (!new_wire)
@ -560,25 +570,6 @@ struct XAigerWriter
output_bits.erase(bit); output_bits.erase(bit);
output_bits.insert(new_bit); output_bits.insert(new_bit);
} }
}
for (auto bit : external_bits)
if (!undriven_bits.count(sigmap(bit))) {
output_bits.insert(bit);
unused_bits.erase(sigmap(bit));
}
for (auto bit : unused_bits)
undriven_bits.erase(bit);
if (!undriven_bits.empty() && !holes_mode) {
//undriven_bits.sort();
for (auto bit : undriven_bits) {
//log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit));
input_bits.insert(bit);
}
//log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module));
}
if (holes_mode) { if (holes_mode) {
struct sort_by_port_id { struct sort_by_port_id {