Skip to content

Commit ff29559

Browse files
authored
Merge pull request #10317 from gadfort/sta-flat-fix
sta: fix flatNet for Mod*
2 parents f22e386 + 0610434 commit ff29559

1 file changed

Lines changed: 145 additions & 0 deletions

File tree

src/dbSta/test/cpp/TestDbSta.cc

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,151 @@ TEST_F(TestDbSta, TestHierarchyConnectivity)
102102
ASSERT_EQ(bterm_clk->getITerm(), nullptr);
103103
}
104104

105+
// Coverage for dbNetwork::findFlatDbNet overloads. Verifies that a flat
106+
// dbNet can be reached from any of: a leaf iterm pin, a top-level bterm
107+
// pin, a hierarchical moditerm pin, a flat dbNet, and a hierarchical
108+
// dbModNet. Pair this with the FlatNet test, which characterizes the
109+
// non-hierarchy-resolving flatNet overloads.
110+
TEST_F(TestDbSta, FindFlatDbNet)
111+
{
112+
std::string test_name = "TestDbSta_0";
113+
readVerilogAndSetup(test_name + ".v");
114+
115+
odb::dbNet* dbnet_net2 = block_->findNet("net2");
116+
ASSERT_NE(dbnet_net2, nullptr);
117+
118+
odb::dbModNet* modnet_mod_in = block_->findModNet("sub_inst/mod_in");
119+
ASSERT_NE(modnet_mod_in, nullptr);
120+
// The hier net for sub_inst/mod_in shares the flat net "net2".
121+
ASSERT_EQ(modnet_mod_in->findRelatedNet(), dbnet_net2);
122+
123+
// 1. findFlatDbNet(Pin*) on an iterm pin (buf/Z drives net2).
124+
odb::dbInst* buf_inst = block_->findInst("buf");
125+
ASSERT_NE(buf_inst, nullptr);
126+
Pin* iterm_pin = db_network_->dbToSta(buf_inst->findITerm("Z"));
127+
ASSERT_NE(iterm_pin, nullptr);
128+
EXPECT_EQ(db_network_->findFlatDbNet(iterm_pin), dbnet_net2);
129+
130+
// 2. findFlatDbNet(Pin*) on a top-level bterm pin (in1).
131+
odb::dbBTerm* bterm_in1 = block_->findBTerm("in1");
132+
ASSERT_NE(bterm_in1, nullptr);
133+
Pin* bterm_pin = db_network_->dbToSta(bterm_in1);
134+
ASSERT_NE(bterm_pin, nullptr);
135+
EXPECT_EQ(db_network_->findFlatDbNet(bterm_pin), bterm_in1->getNet());
136+
137+
// 3. findFlatDbNet(Pin*) on a moditerm pin (sub_inst/mod_in).
138+
Pin* moditerm_pin = db_network_->findPin("sub_inst/mod_in");
139+
ASSERT_NE(moditerm_pin, nullptr);
140+
EXPECT_EQ(db_network_->findFlatDbNet(moditerm_pin), dbnet_net2);
141+
142+
// 4. findFlatDbNet(Net*) on a flat dbNet returns the same dbNet.
143+
Net* sta_dbnet = db_network_->dbToSta(dbnet_net2);
144+
EXPECT_EQ(db_network_->findFlatDbNet(sta_dbnet), dbnet_net2);
145+
146+
// 5. findFlatDbNet(Net*) on a dbModNet resolves to the related flat
147+
// dbNet.
148+
Net* sta_modnet = db_network_->dbToSta(modnet_mod_in);
149+
EXPECT_EQ(db_network_->findFlatDbNet(sta_modnet), dbnet_net2);
150+
151+
// 6. findFlatDbNet(Net*) on null returns null.
152+
EXPECT_EQ(db_network_->findFlatDbNet(static_cast<Net*>(nullptr)), nullptr);
153+
}
154+
155+
// Characterization tests for dbNetwork::flatNet in the presence of
156+
// hierarchy. flatNet does NOT walk the hierarchy: a hierarchical input
157+
// (moditerm Pin*, dbModNet Net*) yields nullptr even when a related flat
158+
// dbNet exists. Callers that need hierarchical resolution must use
159+
// findFlatDbNet. These expectations pin down the current behavior so any
160+
// future change to flatNet is intentional and reviewed.
161+
TEST_F(TestDbSta, FlatNet)
162+
{
163+
std::string test_name = "TestDbSta_0";
164+
readVerilogAndSetup(test_name + ".v");
165+
166+
odb::dbNet* dbnet_net2 = block_->findNet("net2");
167+
ASSERT_NE(dbnet_net2, nullptr);
168+
169+
odb::dbModNet* modnet_mod_in = block_->findModNet("sub_inst/mod_in");
170+
ASSERT_NE(modnet_mod_in, nullptr);
171+
// Sanity: the hierarchical net for sub_inst/mod_in shares flat net "net2".
172+
ASSERT_EQ(modnet_mod_in->findRelatedNet(), dbnet_net2);
173+
174+
// 1. flatNet(Pin*) on a leaf iterm pin returns the directly attached
175+
// flat dbNet.
176+
odb::dbInst* buf_inst = block_->findInst("buf");
177+
ASSERT_NE(buf_inst, nullptr);
178+
Pin* iterm_pin = db_network_->dbToSta(buf_inst->findITerm("Z"));
179+
ASSERT_NE(iterm_pin, nullptr);
180+
EXPECT_EQ(db_network_->flatNet(iterm_pin), dbnet_net2);
181+
182+
// 2. flatNet(Pin*) on a top-level bterm pin returns the directly
183+
// attached flat dbNet.
184+
odb::dbBTerm* bterm_in1 = block_->findBTerm("in1");
185+
ASSERT_NE(bterm_in1, nullptr);
186+
Pin* bterm_pin = db_network_->dbToSta(bterm_in1);
187+
ASSERT_NE(bterm_pin, nullptr);
188+
EXPECT_EQ(db_network_->flatNet(bterm_pin), bterm_in1->getNet());
189+
190+
// 3. flatNet(Pin*) on a hierarchical moditerm pin returns nullptr —
191+
// moditerms attach only to modnets, and flatNet does not resolve through
192+
// the modnet. Callers needing the related flat dbNet must use
193+
// findFlatDbNet instead.
194+
Pin* moditerm_pin = db_network_->findPin("sub_inst/mod_in");
195+
ASSERT_NE(moditerm_pin, nullptr);
196+
EXPECT_EQ(db_network_->flatNet(moditerm_pin), nullptr);
197+
198+
// 4. flatNet(Net*) on a flat dbNet returns the same dbNet.
199+
Net* sta_dbnet = db_network_->dbToSta(dbnet_net2);
200+
EXPECT_EQ(db_network_->flatNet(sta_dbnet), dbnet_net2);
201+
202+
// 5. flatNet(Net*) on a hierarchical dbModNet returns nullptr — flatNet
203+
// does not resolve through the modnet to its related flat dbNet.
204+
Net* sta_modnet = db_network_->dbToSta(modnet_mod_in);
205+
EXPECT_EQ(db_network_->flatNet(sta_modnet), nullptr);
206+
207+
// 6. flatNet(Net*) on null returns null.
208+
EXPECT_EQ(db_network_->flatNet(static_cast<Net*>(nullptr)), nullptr);
209+
210+
// 7. flatNet(Term*) on a top-level bterm returns its dbNet.
211+
Term* bterm_term = db_network_->dbToStaTerm(bterm_in1);
212+
ASSERT_NE(bterm_term, nullptr);
213+
EXPECT_EQ(db_network_->flatNet(bterm_term), bterm_in1->getNet());
214+
}
215+
216+
// Reassociating a moditerm pin must preserve its modnet connection and not
217+
// trip ORD-2026 in connectPin. moditerms only attach to modnets, so the
218+
// flat-net leg of reassociatePinConnection must resolve to nullptr for
219+
// these pins. Regression for the hierarchical repair_tie_fanout flow.
220+
TEST_F(TestDbSta, ReassociateModITermPin)
221+
{
222+
std::string test_name = "TestDbSta_0";
223+
readVerilogAndSetup(test_name + ".v");
224+
225+
Pin* moditerm_pin = db_network_->findPin("sub_inst/mod_in");
226+
ASSERT_NE(moditerm_pin, nullptr);
227+
228+
odb::dbITerm* iterm = nullptr;
229+
odb::dbBTerm* bterm = nullptr;
230+
odb::dbModITerm* moditerm = nullptr;
231+
db_network_->staToDb(moditerm_pin, iterm, bterm, moditerm);
232+
ASSERT_EQ(iterm, nullptr);
233+
ASSERT_EQ(bterm, nullptr);
234+
ASSERT_NE(moditerm, nullptr);
235+
236+
odb::dbModNet* original_modnet = moditerm->getModNet();
237+
ASSERT_NE(original_modnet, nullptr);
238+
// The pin's modnet has a related flat dbNet, so a buggy reassociate that
239+
// forwarded findFlatDbNet's result into connectPin would trigger ORD-2026.
240+
ASSERT_NE(db_network_->findFlatDbNet(moditerm_pin), nullptr);
241+
242+
db_network_->reassociatePinConnection(moditerm_pin);
243+
244+
EXPECT_EQ(moditerm->getModNet(), original_modnet);
245+
EXPECT_TRUE(db_network_->isConnected(db_network_->dbToSta(original_modnet),
246+
moditerm_pin));
247+
db_network_->checkAxioms();
248+
}
249+
105250
// Regression for #10210 (stale Path* dereference in rsz).
106251
//
107252
// Topology (TestDbSta_StalePrevPath.v):

0 commit comments

Comments
 (0)