From e899588269a735af1121d305762116bf696e2a59 Mon Sep 17 00:00:00 2001 From: Abhinav Choudhary Date: Sun, 4 Oct 2026 04:02:08 +0000 Subject: [PATCH 1/3] dbSta: retain top port local nets through child feedthroughs Signed-off-by: Abhinav Choudhary --- src/dbSta/src/dbReadVerilog.cc | 10 +++--- src/dbSta/test/cpp/TestReadVerilog.cpp | 34 +++++++++++++++++++ ...opPortsStayOnLocalNetsThroughFeedthrough.v | 12 +++++++ 3 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 src/dbSta/test/cpp/TestReadVerilog_TopPortsStayOnLocalNetsThroughFeedthrough.v diff --git a/src/dbSta/src/dbReadVerilog.cc b/src/dbSta/src/dbReadVerilog.cc index 5283740330b..c673dc7e637 100644 --- a/src/dbSta/src/dbReadVerilog.cc +++ b/src/dbSta/src/dbReadVerilog.cc @@ -863,10 +863,12 @@ void Verilog2db::makeModNetsForSubmodule(const Instance* inst, // make sure any top level bterms are connected to this net too... if (parent_module == block_->getTopModule()) { - std::unique_ptr pin_iter{ - network_->connectedPinIterator(inst_pin_net)}; - while (pin_iter->hasNext()) { - const Pin* pin = pin_iter->next(); + // Only terminals on this local net belong to the top module. + // Traversing through child feedthroughs would reconnect unrelated ports. + std::unique_ptr term_iter{ + network_->termIterator(inst_pin_net)}; + while (term_iter->hasNext()) { + const Pin* pin = network_->pin(term_iter->next()); staToDb(parent_module, pin, bterm, iterm, mod_bterm, mod_iterm); if (bterm) { bterm->connect(upper_mod_net); diff --git a/src/dbSta/test/cpp/TestReadVerilog.cpp b/src/dbSta/test/cpp/TestReadVerilog.cpp index d79a999a6e3..8f7b51403da 100644 --- a/src/dbSta/test/cpp/TestReadVerilog.cpp +++ b/src/dbSta/test/cpp/TestReadVerilog.cpp @@ -35,6 +35,40 @@ class TestReadVerilog : public tst::IntegratedFixture } }; +// A child feedthrough shares a physical dbNet across its boundary, while +// the parent input and output still belong to distinct local module nets. +TEST_F(TestReadVerilog, TopPortsStayOnLocalNetsThroughFeedthrough) +{ + readVerilogAndSetup( + "TestReadVerilog_TopPortsStayOnLocalNetsThroughFeedthrough.v", + /*init_default_sdc=*/false); + + odb::dbModule* top = block_->getTopModule(); + for (int bit = 0; bit < 2; ++bit) { + const std::string suffix = "[" + std::to_string(bit) + "]"; + odb::dbBTerm* input = block_->findBTerm(("ti" + suffix).c_str()); + odb::dbBTerm* output = block_->findBTerm(("to" + suffix).c_str()); + odb::dbModITerm* child_input + = findChildModITerm(top, "u_top", ("wi" + suffix).c_str()); + odb::dbModITerm* child_output + = findChildModITerm(top, "u_top", ("wo" + suffix).c_str()); + ASSERT_NE(input, nullptr); + ASSERT_NE(output, nullptr); + ASSERT_NE(child_input, nullptr); + ASSERT_NE(child_output, nullptr); + ASSERT_NE(input->getModNet(), nullptr); + ASSERT_NE(output->getModNet(), nullptr); + EXPECT_EQ(input->getModNet(), child_input->getModNet()); + EXPECT_EQ(output->getModNet(), child_output->getModNet()); + EXPECT_NE(input->getModNet(), output->getModNet()); + EXPECT_EQ(input->getNet(), output->getNet()); + } + + odb::dbBTerm* direct = block_->findBTerm("direct"); + ASSERT_NE(direct, nullptr); + EXPECT_EQ(direct->getModNet(), block_->findBTerm("ti[0]")->getModNet()); +} + TEST_F(TestReadVerilog, FeedThrough) { // FeedThrough test: diff --git a/src/dbSta/test/cpp/TestReadVerilog_TopPortsStayOnLocalNetsThroughFeedthrough.v b/src/dbSta/test/cpp/TestReadVerilog_TopPortsStayOnLocalNetsThroughFeedthrough.v new file mode 100644 index 00000000000..47ae4ed2731 --- /dev/null +++ b/src/dbSta/test/cpp/TestReadVerilog_TopPortsStayOnLocalNetsThroughFeedthrough.v @@ -0,0 +1,12 @@ +module top(input [1:0] ti, output [1:0] to, output direct); + wrapper u_top(.wi(ti), .wo(to)); + assign direct = ti[0]; +endmodule + +module wrapper(input [1:0] wi, output [1:0] wo); + feedthrough u_child(.li(wi), .lo(wo)); +endmodule + +module feedthrough(input [1:0] li, output [1:0] lo); + assign lo = li; +endmodule From cdf196b1493826918ee438c432d0945d59c9b0f7 Mon Sep 17 00:00:00 2001 From: Abhinav Choudhary Date: Sun, 4 Oct 2026 04:02:08 +0000 Subject: [PATCH 2/3] sta: adopt input alias repair and refresh affected expectations Signed-off-by: Abhinav Choudhary --- src/dbSta/test/hier_expected_fail.bzl | 49 ------------------- ...TestInsertBuffer_BeforeLoads_Case10_post.v | 1 + ...TestInsertBuffer_BeforeLoads_Case11_post.v | 1 + .../TestInsertBuffer_BeforeLoads_Case3_post.v | 2 + .../TestInsertBuffer_BeforeLoads_Case8_post.v | 1 + src/sta | 2 +- 6 files changed, 6 insertions(+), 50 deletions(-) diff --git a/src/dbSta/test/hier_expected_fail.bzl b/src/dbSta/test/hier_expected_fail.bzl index fdbe592ce61..afcad5c70c4 100644 --- a/src/dbSta/test/hier_expected_fail.bzl +++ b/src/dbSta/test/hier_expected_fail.bzl @@ -310,18 +310,6 @@ CONFORMANCE_EXPECTED_FAIL = [ "wb_sta_reader_module_shadows_cell_after.v", ], ), - # The flat writer drops sub_module's `assign out_bus = in_bus[3:2];` - # entirely, leaving sub_out_bus undriven and taking top_out_bus[1] and - # top_out_single with it (SEC coverage 4/6). The hier path emits the assigns - # correctly. - xfail( - path = "flat", - mode = "partial", - symptom = "flat write drops a submodule bus-slice feedthrough assign, leaving two top outputs undriven", - netlists = [ - "get_ports1.v", - ], - ), # The flat writer builds an instance name by joining the hierarchy path with # '/' and escapes the result, so the path instance `x` -> instance `y` is # emitted as `\x/y ` -- colliding with an instance whose name is literally @@ -655,24 +643,6 @@ CONFORMANCE_EXPECTED_FAIL = [ "bx_bus_geometry_concat_all_const.v", ], ), - xfail( - path = "flat", - mode = "partial", - symptom = "SEC coverage 25.00%", - netlists = [ - "getports_wholein.v", - "gp_bitassign_top.v", - ], - ), - xfail( - path = "flat", - mode = "partial", - symptom = "SEC coverage 33.33%", - netlists = [ - "gp_no_bus_ft.v", - "gp_no_scalar_ft.v", - ], - ), xfail( path = "hier", mode = "partial", @@ -690,9 +660,6 @@ CONFORMANCE_EXPECTED_FAIL = [ "bx_bus_geometry_const_gatepin_top.v", "bx_bus_geometry_const_scalar_port.v", "bx_constants_mixed_cell_literal.v", - "getports_nocell.v", - "min_ft_one_read_only.v", - "nameorder_wire_before.v", "wb_dbsta_link_supply_net_hier_boundary.v", ], ), @@ -729,8 +696,6 @@ CONFORMANCE_EXPECTED_FAIL = [ symptom = "SEC coverage 66.67%", netlists = [ "bx_constants_assign_out_bitsel.v", - "getports_bitassign.v", - "getports_replica.v", ], ), xfail( @@ -1061,14 +1026,6 @@ CONFORMANCE_EXPECTED_FAIL = [ "bx_collisions_port_in_vs_flatnet.v", ], ), - xfail( - path = "flat", - mode = "tool-error", - symptom = "SEC cannot run on this design pair - Missing observed output expression for `197.0.`", - netlists = [ - "nameorder_out_before_in.v", - ], - ), xfail( path = "flat", mode = "tool-error", @@ -1076,12 +1033,6 @@ CONFORMANCE_EXPECTED_FAIL = [ netlists = [ "bx_dangling_positional_inv_live.v", "bx_dangling_positional_leaf_live.v", - "gp_full_inbus.v", - "gp_no_topin_in_concat.v", - "nameorder_busslice.v", - "nameorder_deep_chain.v", - "nameorder_h_before_i.v", - "nameorder_minimal_repro.v", "wb_sta_reader_supply_tie.v", ], ), diff --git a/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case10_post.v b/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case10_post.v index a5d461c9686..57bfe1ace44 100644 --- a/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case10_post.v +++ b/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case10_post.v @@ -7,4 +7,5 @@ module top (in, BUF_X4 new_buf1 (.A(n1), .Z(out)); + assign n1 = in; endmodule diff --git a/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case11_post.v b/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case11_post.v index 3b6034dc8ce..d5fbe5a0016 100644 --- a/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case11_post.v +++ b/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case11_post.v @@ -8,4 +8,5 @@ module top (in); BUF_X1 load2 (.A(n1)); BUF_X4 new_buf1 (.A(n1), .Z(net1)); + assign n1 = in; endmodule diff --git a/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case3_post.v b/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case3_post.v index 7c4e2542131..b3e04c5a4b9 100644 --- a/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case3_post.v +++ b/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case3_post.v @@ -10,6 +10,7 @@ module top (in, .in(n1)); BUF_X4 new_buf22 (.A(n2), .Z(out)); + assign n1 = in; endmodule module MOD0 (out, in); @@ -25,4 +26,5 @@ module MOD0 (out, BUF_X4 new_buf11 (.A(n1), .Z(net1)); assign out = n2; + assign n1 = in; endmodule diff --git a/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case8_post.v b/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case8_post.v index f701c2a2f81..9bda9d26c56 100644 --- a/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case8_post.v +++ b/src/rsz/test/cpp/TestInsertBuffer_BeforeLoads_Case8_post.v @@ -7,4 +7,5 @@ module top (in); BUF_X1 load1 (.A(net1)); BUF_X4 new_buf1 (.A(n1), .Z(net1)); + assign n1 = in; endmodule diff --git a/src/sta b/src/sta index e983e15b2cb..d39cf5eba37 160000 --- a/src/sta +++ b/src/sta @@ -1 +1 @@ -Subproject commit e983e15b2cb346badf8f23725fd3914d25312c44 +Subproject commit d39cf5eba377fdd82b3af5c6933f7e009e135fef From 5386453d3a345dde9c2d6e9d4bb94efdf3d15b8f Mon Sep 17 00:00:00 2001 From: Abhinav Choudhary Date: Sun, 4 Oct 2026 07:02:14 +0000 Subject: [PATCH 3/3] dbSta: retire passing hierarchy conformance expectations Signed-off-by: Abhinav Choudhary --- src/dbSta/test/hier_expected_fail.bzl | 61 --------------------------- 1 file changed, 61 deletions(-) diff --git a/src/dbSta/test/hier_expected_fail.bzl b/src/dbSta/test/hier_expected_fail.bzl index afcad5c70c4..cd1799d95f5 100644 --- a/src/dbSta/test/hier_expected_fail.bzl +++ b/src/dbSta/test/hier_expected_fail.bzl @@ -325,18 +325,6 @@ CONFORMANCE_EXPECTED_FAIL = [ "escaped_name_path_collision.v", ], ), - # The hier writer hoists MOD0's internal feedthrough (`assign Z_b = Z_a;`) - # into the parent as `assign port_a = net1;`. port_a is already driven by - # mod0.Z_a, so the emitted netlist has two drivers on it. The flat path is - # clean. - xfail( - path = "hier", - mode = "tool-error", - symptom = "hier write adds a duplicate driver on an already-driven output port", - netlists = [ - "TestInsertBuffer_BeforeLoads_Case33_post.v", - ], - ), # Not an OpenROAD defect. Under dual_rail_steady the oracle refuses any pair # containing an integrated clock gate: "SNLLogicCloud arity mismatch for # model CLKGATE_X1 -- TT arity=0, model non-output term count=2". The @@ -643,14 +631,6 @@ CONFORMANCE_EXPECTED_FAIL = [ "bx_bus_geometry_concat_all_const.v", ], ), - xfail( - path = "hier", - mode = "partial", - symptom = "SEC coverage 33.33%", - netlists = [ - "sub_three_outs_one_driver.v", - ], - ), xfail( path = "flat", mode = "partial", @@ -677,19 +657,9 @@ CONFORMANCE_EXPECTED_FAIL = [ "bx_constants_esc_subzero_net_buf.v", "bx_constants_mixed_cell_literal.v", "bx_constants_sub_tiehi_sibling.v", - "sub_two_outs_one_driver.v", - "sub_two_outs_one_to_gate.v", "wb_dbsta_link_supply_net_hier_boundary.v", ], ), - xfail( - path = "hier", - mode = "partial", - symptom = "SEC coverage 60.00%", - netlists = [ - "busslice_same_in_two_outs.v", - ], - ), xfail( path = "flat", mode = "partial", @@ -704,19 +674,9 @@ CONFORMANCE_EXPECTED_FAIL = [ symptom = "SEC coverage 66.67%", netlists = [ "bx_constants_assign_out_bitsel.v", - "fanout_two_subs.v", - "sub_in_to_two_outs.v", "wb_writer_nc_drift_captures_user_net.v", ], ), - xfail( - path = "hier", - mode = "partial", - symptom = "SEC coverage 80.00%", - netlists = [ - "overlap_rhs_sub.v", - ], - ), xfail( path = "flat", mode = "tool-error", @@ -1041,9 +1001,6 @@ CONFORMANCE_EXPECTED_FAIL = [ mode = "tool-error", symptom = "SEC cannot run on this design pair - No aligned observed outputs remain after skipping cones with no", netlists = [ - "sub_out_from_out.v", - "sub_out_from_out_bus.v", - "sub_out_from_out_deep3.v", "wb_dbnetwork_overlay_depth0_escslash_rename_port.v", "wb_dbnetwork_overlay_netname_erase_overshoot_port.v", "wb_sta_reader_supply_tie.v", @@ -2821,24 +2778,6 @@ STRUCTURAL_EXPECTED_FAIL = [ "wb_writer_hier_input_alias_orphan.v", ], ), - structural_xfail( - path = "hier", - check = "assigns", - symptom = "an extra continuous assign is added", - netlists = [ - "busslice_same_in_two_outs.v", - "fanout_two_subs.v", - "inherited/TestInsertBuffer_BeforeLoads_Case33_post.v", - "overlap_rhs_sub.v", - "sub_in_to_two_outs.v", - "sub_out_from_out.v", - "sub_out_from_out_bus.v", - "sub_out_from_out_deep3.v", - "sub_three_outs_one_driver.v", - "sub_two_outs_one_driver.v", - "sub_two_outs_one_to_gate.v", - ], - ), structural_xfail( path = "hier", check = "assigns",