mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-13 12:28:44 +00:00
opt_expr: chop up the kitchen sink
This commit is contained in:
parent
39006c9145
commit
95be73467d
|
@ -428,10 +428,9 @@ private:
|
|||
did_something = true;
|
||||
return true;
|
||||
}
|
||||
public:
|
||||
bool run(bool consume_x) {
|
||||
did_something = false;
|
||||
assign_map = SigMap(module);
|
||||
|
||||
void handle_inversions()
|
||||
{
|
||||
if (!options.noclkinv)
|
||||
for (auto cell : module->cells())
|
||||
if (design->selected(module, cell)) {
|
||||
|
@ -509,52 +508,8 @@ public:
|
|||
handle_clkpol_celltype_swap(cell, "$_DLATCHSR_?N?_", "$_DLATCHSR_?P?_", ID::S, assign_map, invert_map);
|
||||
handle_clkpol_celltype_swap(cell, "$_DLATCHSR_??N_", "$_DLATCHSR_??P_", ID::R, assign_map, invert_map);
|
||||
}
|
||||
|
||||
std::vector<Cell*> module_cells = module->cells();
|
||||
auto visitor = [&](auto&& do_action) {
|
||||
if (sort_fails >= options.effort) {
|
||||
for (auto cell : module_cells)
|
||||
if (design->selected(module, cell) && yosys_celltypes.cell_evaluable(cell->type))
|
||||
do_action(cell);
|
||||
} else {
|
||||
TopoSort<RTLIL::Cell*, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> cells;
|
||||
dict<RTLIL::SigBit, Cell*> outbit_to_cell;
|
||||
|
||||
for (auto cell : module->cells())
|
||||
if (design->selected(module, cell) && yosys_celltypes.cell_evaluable(cell->type)) {
|
||||
for (auto &conn : cell->connections())
|
||||
if (yosys_celltypes.cell_output(cell->type, conn.first))
|
||||
for (auto bit : assign_map(conn.second))
|
||||
outbit_to_cell[bit] = cell;
|
||||
cells.node(cell);
|
||||
}
|
||||
|
||||
for (auto cell : module->cells())
|
||||
if (design->selected(module, cell) && yosys_celltypes.cell_evaluable(cell->type)) {
|
||||
const int r_index = cells.node(cell);
|
||||
for (auto &conn : cell->connections())
|
||||
if (yosys_celltypes.cell_input(cell->type, conn.first))
|
||||
for (auto bit : assign_map(conn.second))
|
||||
if (outbit_to_cell.count(bit))
|
||||
cells.edge(cells.node(outbit_to_cell.at(bit)), r_index);
|
||||
}
|
||||
|
||||
if (!cells.sort()) {
|
||||
// There might be a combinational loop, or there might be constants on the output of cells. 'check' may find out more.
|
||||
// ...unless this is a coarse-grained cell loop, but not a bit loop, in which case it won't, and all is good.
|
||||
log("Couldn't topologically sort cells, optimizing module %s may take a longer time.\n", log_id(module));
|
||||
sort_fails++;
|
||||
if (sort_fails >= options.effort)
|
||||
log("Effort of %d exceeded, no longer attempting toposort on module %s.\n",
|
||||
options.effort, log_id(module));
|
||||
}
|
||||
for (auto cell : cells.sorted) {
|
||||
do_action(cell);
|
||||
}
|
||||
}
|
||||
};
|
||||
visitor([&](auto& cell)
|
||||
{
|
||||
void const_prop(Cell* cell, bool consume_x) {
|
||||
#define ACTION_DO(_p_, _s_) do { cover("opt.opt_expr.action_" S__LINE__); replace_cell(cell, input.as_string(), _p_, _s_); goto next_cell; } while (0)
|
||||
#define ACTION_DO_Y(_v_) ACTION_DO(ID::Y, RTLIL::SigSpec(RTLIL::State::S ## _v_))
|
||||
|
||||
|
@ -2233,7 +2188,57 @@ public:
|
|||
#undef ACTION_DO_Y
|
||||
#undef FOLD_1ARG_CELL
|
||||
#undef FOLD_2ARG_CELL
|
||||
});
|
||||
}
|
||||
void sort_and_const_prop(bool consume_x) {
|
||||
std::vector<Cell*> module_cells = module->cells();
|
||||
if (sort_fails >= options.effort) {
|
||||
for (auto cell : module_cells)
|
||||
if (design->selected(module, cell) && yosys_celltypes.cell_evaluable(cell->type))
|
||||
const_prop(cell, consume_x);
|
||||
} else {
|
||||
TopoSort<RTLIL::Cell*, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> cells;
|
||||
dict<RTLIL::SigBit, Cell*> outbit_to_cell;
|
||||
|
||||
for (auto cell : module->cells())
|
||||
if (design->selected(module, cell) && yosys_celltypes.cell_evaluable(cell->type)) {
|
||||
for (auto &conn : cell->connections())
|
||||
if (yosys_celltypes.cell_output(cell->type, conn.first))
|
||||
for (auto bit : assign_map(conn.second))
|
||||
outbit_to_cell[bit] = cell;
|
||||
cells.node(cell);
|
||||
}
|
||||
|
||||
for (auto cell : module->cells())
|
||||
if (design->selected(module, cell) && yosys_celltypes.cell_evaluable(cell->type)) {
|
||||
const int r_index = cells.node(cell);
|
||||
for (auto &conn : cell->connections())
|
||||
if (yosys_celltypes.cell_input(cell->type, conn.first))
|
||||
for (auto bit : assign_map(conn.second))
|
||||
if (outbit_to_cell.count(bit))
|
||||
cells.edge(cells.node(outbit_to_cell.at(bit)), r_index);
|
||||
}
|
||||
|
||||
if (!cells.sort()) {
|
||||
// There might be a combinational loop, or there might be constants on the output of cells. 'check' may find out more.
|
||||
// ...unless this is a coarse-grained cell loop, but not a bit loop, in which case it won't, and all is good.
|
||||
log("Couldn't topologically sort cells, optimizing module %s may take a longer time.\n", log_id(module));
|
||||
sort_fails++;
|
||||
if (sort_fails >= options.effort)
|
||||
log("Effort of %d exceeded, no longer attempting toposort on module %s.\n",
|
||||
options.effort, log_id(module));
|
||||
}
|
||||
for (auto cell : cells.sorted) {
|
||||
const_prop(cell, consume_x);
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
bool run(bool consume_x) {
|
||||
did_something = false;
|
||||
assign_map = SigMap(module);
|
||||
// For some reason, simplifying invertors doesn't count as "doing something"
|
||||
handle_inversions();
|
||||
sort_and_const_prop(consume_x);
|
||||
return did_something;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue