From 6b5fbe37f054e85c483f226f6c6c3dde610ed25b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Fri, 24 Nov 2023 16:16:33 +0100 Subject: [PATCH] sim: Evaluate all cells once If a cell starts with undefined inputs and the value of those inputs is never changed, `sim` code will never evaluate that cell. This means its output will be left at undefined, but in some edge cases such cell can evaluate to a defined value. To address those cases evaluate all cells at least once. --- passes/sat/sim.cc | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index a8516470c..0134f085f 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -287,16 +287,18 @@ struct SimInstance if (mod != nullptr) { dirty_children.insert(new SimInstance(shared, scope + "." + RTLIL::unescape_id(cell->name), mod, cell, this)); - } - - for (auto &port : cell->connections()) { + } else { + for (auto &port : cell->connections()) if (cell->input(port.first)) - for (auto bit : sigmap(port.second)) { - upd_cells[bit].insert(cell); - // Make sure cell inputs connected to constants are updated in the first cycle - if (bit.wire == nullptr) - dirty_bits.insert(bit); - } + for (auto bit : sigmap(port.second)) + upd_cells[bit].insert(cell); + + // Update all cells in the first cycle (to propagate constants but also to + // handle edge cases in which cells have defined output values in presence of + // undefined inputs). This is with the exception of few cells which don't have + // any inputs and should never be queued up for updating. + if (!cell->type.in(ID($initstate), ID($anyconst), ID($anyseq), ID($allconst), ID($allseq))) + dirty_cells.insert(cell); } if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) { @@ -492,6 +494,8 @@ struct SimInstance void update_cell(Cell *cell) { + log_assert(!cell->type.in(ID($initstate), ID($anyconst), ID($anyseq), ID($allconst), ID($allseq))); + if (ff_database.count(cell)) return;