From 1bf9530fcc0a83938c69ef95b8f960c2c930f74c Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 6 Aug 2025 16:51:14 +1200 Subject: [PATCH 1/3] cutpoint_blackbox.ys: Add verific-style unknown module --- tests/various/cutpoint_blackbox.ys | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/various/cutpoint_blackbox.ys b/tests/various/cutpoint_blackbox.ys index ee479b968..61001d6b6 100644 --- a/tests/various/cutpoint_blackbox.ys +++ b/tests/various/cutpoint_blackbox.ys @@ -70,3 +70,20 @@ design -load gold select -read cutpoint.gate.sel # nothing in gold but not gate select -assert-none % %n + +# replacing the blackbox with a verific-style unknown module should work too +# (note this specific example loses the values of SOME_PARAM which would +# normally be retained by verific) +design -load hier +delete =bb +read_rtlil << EOT +attribute \blackbox 1 +module \bb + parameter \SOME_PARAM 0 + wire inout 3 \o + wire inout 2 \b + wire inout 1 \a +end +EOT +cutpoint -blackbox +check -assert From 4ac100fe137e79baf50363e94aa088854c21838f Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 6 Aug 2025 18:11:05 +1200 Subject: [PATCH 2/3] cutpoint: Track wire drivers Necessary to avoid multiple drivers being inserted when a blackbox has inout ports (like when importing an unknown module with `verific`). If any bits of an inout port have a known driver, treat the port as an input. If there are no bits with a known driver, treat the port as an output, and mark each bit as having a driver. --- passes/sat/cutpoint.cc | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc index 485e44fd6..41fa9fac4 100644 --- a/passes/sat/cutpoint.cc +++ b/passes/sat/cutpoint.cc @@ -109,13 +109,43 @@ struct CutpointPass : public Pass { SigMap sigmap(module); pool cutpoint_bits; + pool wire_drivers; + for (auto cell : module->cells()) + for (auto &conn : cell->connections()) + if (cell->output(conn.first) && !cell->input(conn.first)) + for (auto bit : sigmap(conn.second)) + if (bit.wire) + wire_drivers.insert(bit); + + for (auto wire : module->wires()) + if (wire->port_input) + for (auto bit : sigmap(wire)) + wire_drivers.insert(bit); + for (auto cell : module->selected_cells()) { if (cell->type == ID($anyseq)) continue; log("Removing cell %s.%s, making all cell outputs cutpoints.\n", log_id(module), log_id(cell)); for (auto &conn : cell->connections()) { - if (cell->output(conn.first)) - module->connect(conn.second, flag_undef ? Const(State::Sx, GetSize(conn.second)) : module->Anyseq(NEW_ID, GetSize(conn.second))); + if (cell->output(conn.first)) { + bool do_cut = true; + if (cell->input(conn.first)) + for (auto bit : sigmap(conn.second)) + if (wire_drivers.count(bit)) { + log_debug(" Treating inout port '%s' as input.\n", id2cstr(conn.first)); + do_cut = false; + break; + } + + if (do_cut) { + module->connect(conn.second, flag_undef ? Const(State::Sx, GetSize(conn.second)) : module->Anyseq(NEW_ID, GetSize(conn.second))); + if (cell->input(conn.first)) { + log_debug(" Treating inout port '%s' as output.\n", id2cstr(conn.first)); + for (auto bit : sigmap(conn.second)) + wire_drivers.insert(bit); + } + } + } } RTLIL::Cell *scopeinfo = nullptr; From af7d1d3f4f44c82986e70d7188f7fe24e85b5154 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 6 Aug 2025 18:11:35 +1200 Subject: [PATCH 3/3] cutpoint_blackbox.ys: Extra edge case --- tests/various/cutpoint_blackbox.ys | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/various/cutpoint_blackbox.ys b/tests/various/cutpoint_blackbox.ys index 61001d6b6..1ba9a95df 100644 --- a/tests/various/cutpoint_blackbox.ys +++ b/tests/various/cutpoint_blackbox.ys @@ -87,3 +87,27 @@ end EOT cutpoint -blackbox check -assert + +# also concatenated signals, and signals between two inout ports +design -load hier +delete top =bb +read_verilog << EOT +module top(input [1:0] a, b, output [1:0] o); + wire [1:0] c, d, e; + bb #(.SOME_PARAM(1)) bb1 (.a ({a[0], e[1]}), .b (b), .o (c)); + bb #(.SOME_PARAM(2)) bb2 (.a ({c[1], a[0]}), .b (c), .o (d)); + wb wb1 (.a (a), .b (b), .o (e)); + some_mod some_inst (.a (c), .b (d), .c (e), .o (o)); +endmodule +EOT +read_rtlil << EOT +attribute \blackbox 1 +module \bb + parameter \SOME_PARAM 0 + wire inout 3 width 2 \o + wire inout 2 width 2 \b + wire inout 1 width 2 \a +end +EOT +cutpoint -blackbox +check -assert