From 4ca4392e9b135f23c556884fd4db487aedc254b7 Mon Sep 17 00:00:00 2001 From: AdvaySingh1 Date: Wed, 11 Feb 2026 14:56:46 -0800 Subject: [PATCH] Simplied recursion in sat_clockgate pass --- passes/silimate/sat_clockgate.cc | 68 +++++++++++--------------------- 1 file changed, 24 insertions(+), 44 deletions(-) diff --git a/passes/silimate/sat_clockgate.cc b/passes/silimate/sat_clockgate.cc index 7d2f1b70a..b8c61f88f 100644 --- a/passes/silimate/sat_clockgate.cc +++ b/passes/silimate/sat_clockgate.cc @@ -71,34 +71,6 @@ struct SatClockgateWorker return inputs; } - // BFS to find potential enable signals up to a certain depth - pool bfs_find_potential_enable_inputs(SigSpec sig, int max_depth) - { - pool visited; - pool frontier; - - for (auto bit : sigmap(sig)) - if (bit.wire != nullptr) - frontier.insert(bit); - - for (int depth = 0; depth < max_depth && !frontier.empty(); depth++) { - pool next_frontier; - for (auto bit : frontier) { - if (visited.count(bit)) - continue; - visited.insert(bit); - - for (auto input_bit : get_input_signals(bit)) { - if (!visited.count(input_bit)) - next_frontier.insert(input_bit); - } - } - frontier = next_frontier; - } - - return visited; - } - // Check if fixing the input_set to specific values makes D == Q always true // Returns true if input_set can serve as an enable (when all bits are 0, D == Q) bool input_set_is_enable(const pool &input_set, SigSpec sig_d, SigSpec sig_q) @@ -137,6 +109,7 @@ struct SatClockgateWorker } // Recursively determine the enable input set via BFS expansion + // Seeds initial input set from sig_d, excludes sig_q bits bool determine_enable_recursive(pool &input_set, SigSpec sig_d, SigSpec sig_q, int depth) { if (depth > MAX_INPUT_DEPTH) { @@ -144,6 +117,26 @@ struct SatClockgateWorker return false; } + // Seed initial input set from sig_d on first call + if (depth == 1 && input_set.empty()) { + for (auto bit : sigmap(sig_d)) { + if (bit.wire != nullptr) { + for (auto input_bit : get_input_signals(bit)) { + input_set.insert(input_bit); + } + } + } + // Remove Q bits (feedback, not control) + for (auto bit : sigmap(sig_q)) + input_set.erase(bit); + + if (input_set.empty()) { + log_debug(" No inputs to D (besides Q)\n"); + return false; + } + log_debug(" Initial input set has %zu signals\n", input_set.size()); + } + // Check if current input set works as enable if (input_set_is_enable(input_set, sig_d, sig_q)) { log_debug(" Found enable at depth %d with %zu signals\n", depth, input_set.size()); @@ -227,23 +220,10 @@ struct SatClockgateWorker log("Processing FF: %s\n", log_id(cell)); - // Start with direct inputs of D - pool input_set = bfs_find_potential_enable_inputs(ff.sig_d, 1); - - // Remove Q from input set (it's the feedback, not a control signal) - for (auto bit : sigmap(ff.sig_q)) - input_set.erase(bit); - - if (input_set.empty()) { - log_debug(" No inputs to D (besides Q)\n"); - return false; - } - - log_debug(" Initial input set has %zu signals\n", input_set.size()); - - // Try to find enable + // Find enable via recursive BFS + SAT validation + pool input_set; if (determine_enable_recursive(input_set, ff.sig_d, ff.sig_q, 1)) { - // Remove Q bits again (in case BFS added them back) + // Remove Q bits (in case BFS added them back) for (auto bit : sigmap(ff.sig_q)) input_set.erase(bit);