From 7d46ab08d57e3d66e8f6b3522285024c58bce513 Mon Sep 17 00:00:00 2001 From: Alain Dargelas Date: Wed, 5 Mar 2025 10:28:49 -0800 Subject: [PATCH] clocks, resets filters --- passes/silimate/annotate_cell_fanout.cc | 50 ++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/passes/silimate/annotate_cell_fanout.cc b/passes/silimate/annotate_cell_fanout.cc index 2f6034fa9..886be5f04 100644 --- a/passes/silimate/annotate_cell_fanout.cc +++ b/passes/silimate/annotate_cell_fanout.cc @@ -436,7 +436,7 @@ void fixfanout(RTLIL::Module *module, SigMap &sigmap, dict> &sig2CellsInFanout, dict &cellFanout, dict &sigFanout) { @@ -574,6 +574,10 @@ struct AnnotateCellFanout : public ScriptPass { log(" For formal verification to pass, will prevent splitnets passes on ports, even if they have large fanout.\n"); log(" -inputs\n"); log(" Fix module inputs fanout.\n"); + log(" -clocks\n"); + log(" Fix module clocks fanout.\n"); + log(" -resets\n"); + log(" Fix module resets fanout.\n"); log(" -debug\n"); log(" Debug trace.\n"); log("\n"); @@ -582,7 +586,9 @@ struct AnnotateCellFanout : public ScriptPass { { int limit = -1; bool formalFriendly = false; - bool inputs = false; + bool buffer_inputs = false; + bool buffer_clocks = false; + bool buffer_resets = false; bool debug = false; if (design == nullptr) { log_error("No design object\n"); @@ -606,7 +612,15 @@ struct AnnotateCellFanout : public ScriptPass { continue; } if (args[argidx] == "-inputs") { - inputs = true; + buffer_inputs = true; + continue; + } + if (args[argidx] == "-clocks") { + buffer_clocks = true; + continue; + } + if (args[argidx] == "-resets") { + buffer_resets = true; continue; } break; @@ -646,7 +660,7 @@ struct AnnotateCellFanout : public ScriptPass { } splitNets(design, netsToSplitS, cellOutputsToSplit, formalFriendly, debug); - if (inputs) { + if (buffer_inputs) { // Split module input nets with high fanout std::vector wiresToSplit; for (Wire *wire : module->wires()) { @@ -690,14 +704,40 @@ struct AnnotateCellFanout : public ScriptPass { } } + // Mark clocks, resets + std::set clock_sigs; + std::set reset_sigs; + for (auto cell : module->selected_cells()) { + if (cell->type.in(ID($dff), ID($dffe), ID($dffsr), ID($dffsre), ID($adff), ID($adffe), ID($aldff), + ID($aldffe), ID($sdff), ID($sdffe), ID($sdffce), ID($fsm), ID($memrd), ID($memrd_v2), + ID($memwr), ID($memwr_v2))) { + // Check for clock input connection + if (cell->hasPort(ID(CLK))) { + RTLIL::SigSpec clk_sig = sigmap(cell->getPort(ID(CLK))); + clock_sigs.insert(clk_sig); + } + if (cell->hasPort(ID(RST))) { + RTLIL::SigSpec clk_sig = sigmap(cell->getPort(ID(RST))); + reset_sigs.insert(clk_sig); + } + if (cell->hasPort(ID(ARST))) { + RTLIL::SigSpec clk_sig = sigmap(cell->getPort(ID(ARST))); + reset_sigs.insert(clk_sig); + } + } + } + // Fix module input nets with high fanout std::map sigsToFix; for (Wire *wire : module->wires()) { if (wire->port_input) { SigSpec inp = sigmap(wire); + bool is_clock = clock_sigs.find(inp) != clock_sigs.end(); + bool is_reset = reset_sigs.find(inp) != reset_sigs.end(); + bool filter_sig = (is_clock && !buffer_clocks) || (is_reset && !buffer_resets); int fanout = sigFanout[inp]; if (limit > 0 && (fanout > limit)) { - if (inputs) { + if (buffer_inputs && !(filter_sig)) { sigsToFix.emplace(inp, fanout); } else { wire->set_string_attribute("$FANOUT", std::to_string(fanout));