mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-13 04:28:18 +00:00
Cleanup/optimise toposort in write_xaiger
This commit is contained in:
parent
a5425a2f7e
commit
1948e7c846
|
@ -167,51 +167,12 @@ struct XAigerWriter
|
||||||
if (!bit.wire->port_input)
|
if (!bit.wire->port_input)
|
||||||
unused_bits.erase(bit);
|
unused_bits.erase(bit);
|
||||||
|
|
||||||
dict<SigBit, pool<IdString>> bit_drivers, bit_users;
|
SigMap topomap;
|
||||||
TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
|
topomap.database = sigmap.database;
|
||||||
|
|
||||||
bool abc_box_seen = false;
|
bool abc_box_seen = false;
|
||||||
|
|
||||||
for (auto cell : module->cells()) {
|
for (auto cell : module->cells()) {
|
||||||
RTLIL::Module* inst_module = module->design->module(cell->type);
|
|
||||||
bool builtin_type = yosys_celltypes.cell_known(cell->type);
|
|
||||||
bool abc_type = inst_module && inst_module->attributes.count("\\abc_box_id");
|
|
||||||
|
|
||||||
if (!holes_mode) {
|
|
||||||
toposort.node(cell->name);
|
|
||||||
for (const auto &conn : cell->connections()) {
|
|
||||||
if (!builtin_type && !abc_type)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!cell->type.in("$_NOT_", "$_AND_")) {
|
|
||||||
if (builtin_type) {
|
|
||||||
if (conn.first.in("\\Q", "\\CTRL_OUT", "\\RD_DATA"))
|
|
||||||
continue;
|
|
||||||
if (cell->type == "$memrd" && conn.first == "\\DATA")
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inst_module) {
|
|
||||||
RTLIL::Wire* inst_module_port = inst_module->wire(conn.first);
|
|
||||||
log_assert(inst_module_port);
|
|
||||||
|
|
||||||
if (inst_module_port->port_output && inst_module_port->attributes.count("\\abc_flop_q"))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cell->input(conn.first)) {
|
|
||||||
// Ignore inout for the sake of topographical ordering
|
|
||||||
if (cell->output(conn.first)) continue;
|
|
||||||
for (auto bit : sigmap(conn.second))
|
|
||||||
bit_users[bit].insert(cell->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cell->output(conn.first))
|
|
||||||
for (auto bit : sigmap(conn.second))
|
|
||||||
bit_drivers[bit].insert(cell->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cell->type == "$_NOT_")
|
if (cell->type == "$_NOT_")
|
||||||
{
|
{
|
||||||
SigBit A = sigmap(cell->getPort("\\A").as_bit());
|
SigBit A = sigmap(cell->getPort("\\A").as_bit());
|
||||||
|
@ -219,6 +180,8 @@ struct XAigerWriter
|
||||||
unused_bits.erase(A);
|
unused_bits.erase(A);
|
||||||
undriven_bits.erase(Y);
|
undriven_bits.erase(Y);
|
||||||
not_map[Y] = A;
|
not_map[Y] = A;
|
||||||
|
if (!holes_mode)
|
||||||
|
topomap.add(Y, A);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,6 +204,10 @@ struct XAigerWriter
|
||||||
unused_bits.erase(B);
|
unused_bits.erase(B);
|
||||||
undriven_bits.erase(Y);
|
undriven_bits.erase(Y);
|
||||||
and_map[Y] = make_pair(A, B);
|
and_map[Y] = make_pair(A, B);
|
||||||
|
if (!holes_mode) {
|
||||||
|
topomap.add(Y, A);
|
||||||
|
topomap.add(Y, B);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,6 +219,7 @@ struct XAigerWriter
|
||||||
// continue;
|
// continue;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
RTLIL::Module* inst_module = module->design->module(cell->type);
|
||||||
bool inst_flop = inst_module ? inst_module->attributes.count("\\abc_flop") : false;
|
bool inst_flop = inst_module ? inst_module->attributes.count("\\abc_flop") : false;
|
||||||
if (inst_flop) {
|
if (inst_flop) {
|
||||||
SigBit d, q;
|
SigBit d, q;
|
||||||
|
@ -322,20 +290,46 @@ 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abc_box_seen) {
|
if (abc_box_seen && !holes_mode) {
|
||||||
|
TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
|
||||||
|
dict<SigBit, pool<IdString>> bit_drivers, bit_users;
|
||||||
|
|
||||||
|
for (auto cell : module->cells()) {
|
||||||
|
RTLIL::Module* inst_module = module->design->module(cell->type);
|
||||||
|
if (!inst_module || !inst_module->attributes.count("\\abc_box_id"))
|
||||||
|
continue;
|
||||||
|
toposort.node(cell->name);
|
||||||
|
for (const auto &conn : cell->connections()) {
|
||||||
|
if (cell->input(conn.first)) {
|
||||||
|
// Ignore inout for the sake of topographical ordering
|
||||||
|
if (cell->output(conn.first)) continue;
|
||||||
|
for (auto bit : topomap(conn.second))
|
||||||
|
if (bit.wire)
|
||||||
|
bit_users[bit].insert(cell->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell->output(conn.first)) {
|
||||||
|
RTLIL::Wire* inst_module_port = inst_module->wire(conn.first);
|
||||||
|
log_assert(inst_module_port);
|
||||||
|
if (inst_module_port->attributes.count("\\abc_flop_q"))
|
||||||
|
continue;
|
||||||
|
for (auto bit : topomap(conn.second))
|
||||||
|
bit_drivers[bit].insert(cell->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &it : bit_users)
|
for (auto &it : bit_users)
|
||||||
if (bit_drivers.count(it.first))
|
if (bit_drivers.count(it.first))
|
||||||
for (auto driver_cell : bit_drivers.at(it.first))
|
for (auto driver_cell : bit_drivers.at(it.first))
|
||||||
for (auto user_cell : it.second)
|
for (auto user_cell : it.second)
|
||||||
toposort.edge(driver_cell, user_cell);
|
toposort.edge(driver_cell, user_cell);
|
||||||
|
|
||||||
pool<RTLIL::Module*> abc_carry_modules;
|
#if 1
|
||||||
|
|
||||||
#if 0
|
|
||||||
toposort.analyze_loops = true;
|
toposort.analyze_loops = true;
|
||||||
#endif
|
#endif
|
||||||
bool no_loops = toposort.sort();
|
bool no_loops = toposort.sort();
|
||||||
#if 0
|
#if 1
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (auto &it : toposort.loops) {
|
for (auto &it : toposort.loops) {
|
||||||
log(" loop %d", i++);
|
log(" loop %d", i++);
|
||||||
|
@ -346,13 +340,14 @@ struct XAigerWriter
|
||||||
#endif
|
#endif
|
||||||
log_assert(no_loops);
|
log_assert(no_loops);
|
||||||
|
|
||||||
|
pool<RTLIL::Module*> abc_carry_modules;
|
||||||
for (auto cell_name : toposort.sorted) {
|
for (auto cell_name : toposort.sorted) {
|
||||||
RTLIL::Cell *cell = module->cell(cell_name);
|
RTLIL::Cell *cell = module->cell(cell_name);
|
||||||
RTLIL::Module* box_module = module->design->module(cell->type);
|
RTLIL::Module* box_module = module->design->module(cell->type);
|
||||||
if (!box_module || !box_module->attributes.count("\\abc_box_id"))
|
log_assert(box_module);
|
||||||
continue;
|
log_assert(box_module->attributes.count("\\abc_box_id"));
|
||||||
|
|
||||||
if (box_module->attributes.count("\\abc_carry") && !abc_carry_modules.count(box_module)) {
|
if (!abc_carry_modules.count(box_module) && box_module->attributes.count("\\abc_carry")) {
|
||||||
RTLIL::Wire* carry_in = nullptr, *carry_out = nullptr;
|
RTLIL::Wire* carry_in = nullptr, *carry_out = nullptr;
|
||||||
RTLIL::Wire* last_in = nullptr, *last_out = nullptr;
|
RTLIL::Wire* last_in = nullptr, *last_out = nullptr;
|
||||||
for (const auto &port_name : box_module->ports) {
|
for (const auto &port_name : box_module->ports) {
|
||||||
|
@ -448,8 +443,6 @@ struct XAigerWriter
|
||||||
}
|
}
|
||||||
box_list.emplace_back(cell);
|
box_list.emplace_back(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Free memory from toposort, bit_drivers, bit_users
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto bit : input_bits) {
|
for (auto bit : input_bits) {
|
||||||
|
|
Loading…
Reference in a new issue