mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-12 20:18:20 +00:00
abc9: break SCC by setting (* keep *) on output wires
This commit is contained in:
parent
a2c4d98da7
commit
2c65e1abac
|
@ -436,15 +436,22 @@ struct XAigerWriter
|
||||||
for (const auto &bit : output_bits) {
|
for (const auto &bit : output_bits) {
|
||||||
ordered_outputs[bit] = aig_o++;
|
ordered_outputs[bit] = aig_o++;
|
||||||
int aig;
|
int aig;
|
||||||
// For inout/keep bits only, the output bit
|
// Unlike bit2aig() which checks aig_map first, for
|
||||||
// should be driven by logic, not the PI,
|
// inout/keep bits, since aig_map will point to
|
||||||
// so temporarily swap that out
|
// the PI, first attempt to find the NOT/AND driver
|
||||||
|
// before resorting to an aig_map lookup (which
|
||||||
|
// could be another PO)
|
||||||
if (input_bits.count(bit)) {
|
if (input_bits.count(bit)) {
|
||||||
auto it = aig_map.find(bit);
|
if (not_map.count(bit)) {
|
||||||
int input_aig = it->second;
|
aig = bit2aig(not_map.at(bit)) ^ 1;
|
||||||
aig_map.erase(it);
|
} else if (and_map.count(bit)) {
|
||||||
aig = bit2aig(bit);
|
auto args = and_map.at(bit);
|
||||||
aig_map.at(bit) = input_aig;
|
int a0 = bit2aig(args.first);
|
||||||
|
int a1 = bit2aig(args.second);
|
||||||
|
aig = mkgate(a0, a1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
aig = aig_map.at(bit);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
aig = bit2aig(bit);
|
aig = bit2aig(bit);
|
||||||
|
|
|
@ -831,6 +831,7 @@ void AigerReader::post_process()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wire->port_output = false;
|
wire->port_output = false;
|
||||||
|
existing->port_output = true;
|
||||||
module->connect(wire, existing);
|
module->connect(wire, existing);
|
||||||
wire = existing;
|
wire = existing;
|
||||||
}
|
}
|
||||||
|
@ -845,8 +846,9 @@ void AigerReader::post_process()
|
||||||
wideports_cache[escaped_s] = std::max(wideports_cache[escaped_s], index);
|
wideports_cache[escaped_s] = std::max(wideports_cache[escaped_s], index);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
module->connect(wire, existing);
|
|
||||||
wire->port_output = false;
|
wire->port_output = false;
|
||||||
|
existing->port_output = true;
|
||||||
|
module->connect(wire, existing);
|
||||||
}
|
}
|
||||||
log_debug(" -> %s\n", log_id(indexed_name));
|
log_debug(" -> %s\n", log_id(indexed_name));
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,7 +298,7 @@ struct Abc9Pass : public ScriptPass
|
||||||
num_outputs);
|
num_outputs);
|
||||||
if (num_outputs) {
|
if (num_outputs) {
|
||||||
run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()));
|
run(stringf("%s -cwd %s", exe_cmd.str().c_str(), tempdir_name.c_str()));
|
||||||
run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod->name), tempdir_name.c_str(), tempdir_name.c_str()));
|
run(stringf("read_aiger -xaiger -wideports -module_name %s$abc9 -map %s/input.sym %s/output.aig", log_id(mod), tempdir_name.c_str(), tempdir_name.c_str()));
|
||||||
run("abc9_ops -reintegrate");
|
run("abc9_ops -reintegrate");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -53,30 +53,7 @@ void break_scc(RTLIL::Module *module)
|
||||||
if (cell->output(c.first)) {
|
if (cell->output(c.first)) {
|
||||||
SigBit b = c.second.as_bit();
|
SigBit b = c.second.as_bit();
|
||||||
Wire *w = b.wire;
|
Wire *w = b.wire;
|
||||||
if (w->port_input) {
|
w->set_bool_attribute(ID::keep);
|
||||||
// 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 {
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -586,7 +563,9 @@ void reintegrate(RTLIL::Module *module)
|
||||||
}
|
}
|
||||||
if (cell->output(mapped_conn.first))
|
if (cell->output(mapped_conn.first))
|
||||||
for (auto i : mapped_conn.second)
|
for (auto i : mapped_conn.second)
|
||||||
bit_drivers[i].insert(mapped_cell->name);
|
// Ignore inouts for topo ordering
|
||||||
|
if (i.wire && !(i.wire->port_input && i.wire->port_output))
|
||||||
|
bit_drivers[i].insert(mapped_cell->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in a new issue