Skip to content

Commit 182f51b

Browse files
authored
Merge pull request #8980 from The-OpenROAD-Project-staging/secure-override-highest-net-above
dbNetwork: Overridden `Net* Network::highestNetAbove(Net*)` to resolve hang issue
2 parents bc25e51 + a30fae4 commit 182f51b

File tree

6 files changed

+143
-2
lines changed

6 files changed

+143
-2
lines changed

src/dbSta/include/db_sta/dbNetwork.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,11 @@ class dbNetwork : public ConcreteNetwork
337337

338338
bool hasPort(const Net* net) const;
339339

340+
// Return the highest net above the given net.
341+
// - If the net is a flat net, return it.
342+
// - If the net is a hier net, return the modnet in the highest hierarchy.
343+
Net* highestNetAbove(Net* net) const override;
344+
340345
////////////////////////////////////////////////////////////////
341346
// Edit functions
342347
Instance* makeInstance(LibertyCell* cell,

src/dbSta/src/dbNetwork.cc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5014,4 +5014,36 @@ bool dbNetwork::isPGSupply(dbNet* net) const
50145014
return net->isSpecial() && net->getSigType().isSupply();
50155015
}
50165016

5017+
Net* dbNetwork::highestNetAbove(Net* net) const
5018+
{
5019+
if (net == nullptr) {
5020+
return nullptr;
5021+
}
5022+
5023+
dbNet* dbnet;
5024+
dbModNet* modnet;
5025+
staToDb(net, dbnet, modnet);
5026+
5027+
if (dbnet) {
5028+
// If a flat net, return it.
5029+
// - We should not return the highest modnet related to the flat net.
5030+
// - Otherwise, it breaks estimate_parasitics function.
5031+
// . est module uses flat nets for parasitic estimation
5032+
// . It has (highestNetAbove(flat_net) != flat_net) comparison.
5033+
// . If highestNetAbove(flat_net) returns the highest modnet, it
5034+
// changes the estimate_parasitics behavior.
5035+
return net;
5036+
}
5037+
5038+
if (modnet) {
5039+
if (dbNet* related_dbnet = modnet->findRelatedNet()) {
5040+
if (dbModNet* highest_modnet = related_dbnet->findModNetInHighestHier()) {
5041+
return dbToSta(highest_modnet); // Found the highest modnet
5042+
}
5043+
}
5044+
}
5045+
5046+
return net;
5047+
}
5048+
50175049
} // namespace sta

src/dbSta/test/cpp/TestDbSta.cc

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <cstdio>
66
#include <string>
77

8+
#include "db_sta/dbNetwork.hh"
89
#include "gtest/gtest.h"
910
#include "odb/db.h"
1011
#include "sta/NetworkClass.hh"
@@ -22,7 +23,7 @@ class TestDbSta : public tst::IntegratedFixture
2223
}
2324
};
2425

25-
TEST_F(TestDbSta, TestIsConnected)
26+
TEST_F(TestDbSta, TestHierarchyConnectivity)
2627
{
2728
std::string test_name = "TestDbSta_0";
2829
readVerilogAndSetup(test_name + ".v");
@@ -59,6 +60,41 @@ TEST_F(TestDbSta, TestIsConnected)
5960

6061
bool_return = db_network_->isConnected(sta_net, sta_modnet);
6162
ASSERT_TRUE(bool_return);
63+
64+
// Check Network::highestNetAbove(Net* net)
65+
odb::dbNet* dbnet_out2 = block_->findNet("out2");
66+
ASSERT_NE(dbnet_out2, nullptr);
67+
Net* sta_dbnet_out2 = db_network_->dbToSta(dbnet_out2);
68+
ASSERT_NE(sta_dbnet_out2, nullptr);
69+
Net* sta_highest_net = db_network_->highestNetAbove(sta_dbnet_out2);
70+
ASSERT_EQ(sta_highest_net, sta_dbnet_out2);
71+
72+
odb::dbModNet* modnet_mod_out = block_->findModNet("sub_inst/mod_out");
73+
ASSERT_NE(modnet_mod_out, nullptr);
74+
Net* sta_modnet_mod_out = db_network_->dbToSta(modnet_mod_out);
75+
ASSERT_NE(sta_modnet_mod_out, nullptr);
76+
odb::dbModNet* modnet_out2 = block_->findModNet("out2");
77+
ASSERT_NE(modnet_out2, nullptr);
78+
Net* sta_modnet_out2 = db_network_->dbToSta(modnet_out2);
79+
ASSERT_NE(sta_modnet_out2, nullptr);
80+
Net* sta_highest_modnet_out
81+
= db_network_->highestNetAbove(sta_modnet_mod_out);
82+
ASSERT_EQ(sta_highest_modnet_out, sta_modnet_out2);
83+
84+
// Check get_ports -of_object Net*
85+
NetTermIterator* term_iter = db_network_->termIterator(sta_dbnet_out2);
86+
while (term_iter->hasNext()) {
87+
Term* term = term_iter->next();
88+
Pin* pin = db_network_->pin(term);
89+
Port* port = db_network_->port(pin);
90+
ASSERT_EQ(db_network_->name(port), block_->findBTerm("out2")->getName());
91+
}
92+
93+
// Check dbBTerm::getITerm()
94+
odb::dbBTerm* bterm_clk = block_->findBTerm("in1");
95+
ASSERT_NE(bterm_clk, nullptr);
96+
// There is no related dbITerm for a dbBTerm
97+
ASSERT_EQ(bterm_clk->getITerm(), nullptr);
6298
}
6399

64100
} // namespace sta

src/odb/include/odb/db.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,20 @@ class dbBlock : public dbObject
786786
///
787787
dbModInst* findModInst(const char* path);
788788

789+
///
790+
/// Find a specific moditerm in this block. path is
791+
/// master_module_name/modinst_name/term_name Returns nullptr if the object
792+
/// was not found.
793+
///
794+
dbModITerm* findModITerm(const char* hierarchical_name);
795+
796+
///
797+
/// Find a specific modbterm in this block. path is
798+
/// master_module_name/modinst_name/term_name Returns nullptr if the object
799+
/// was not found.
800+
///
801+
dbModBTerm* findModBTerm(const char* hierarchical_name);
802+
789803
///
790804
/// Find a specific PowerDomain in this block.
791805
/// Returns nullptr if the object was not found.

src/odb/src/db/dbBlock.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3885,4 +3885,52 @@ const char* dbBlock::getBaseName(const char* full_name) const
38853885
return full_name;
38863886
}
38873887

3888+
dbModITerm* dbBlock::findModITerm(const char* hierarchical_name)
3889+
{
3890+
if (hierarchical_name == nullptr) {
3891+
return nullptr;
3892+
}
3893+
3894+
const char* last_delim = strrchr(hierarchical_name, getHierarchyDelimiter());
3895+
if (last_delim == nullptr) {
3896+
return nullptr;
3897+
}
3898+
3899+
std::string inst_path(hierarchical_name, last_delim - hierarchical_name);
3900+
const char* term_name = last_delim + 1;
3901+
3902+
dbModInst* inst = findModInst(inst_path.c_str());
3903+
if (inst) {
3904+
return inst->findModITerm(term_name);
3905+
}
3906+
return nullptr;
3907+
}
3908+
3909+
dbModBTerm* dbBlock::findModBTerm(const char* hierarchical_name)
3910+
{
3911+
if (hierarchical_name == nullptr) {
3912+
return nullptr;
3913+
}
3914+
3915+
const char* last_delim = strrchr(hierarchical_name, getHierarchyDelimiter());
3916+
if (last_delim == nullptr) {
3917+
// Top level port
3918+
if (dbModule* top_module = getTopModule()) {
3919+
return top_module->findModBTerm(hierarchical_name);
3920+
}
3921+
return nullptr;
3922+
}
3923+
3924+
std::string inst_path(hierarchical_name, last_delim - hierarchical_name);
3925+
const char* term_name = last_delim + 1;
3926+
3927+
dbModInst* inst = findModInst(inst_path.c_str());
3928+
if (inst) {
3929+
if (dbModule* master = inst->getMaster()) {
3930+
return master->findModBTerm(term_name);
3931+
}
3932+
}
3933+
return nullptr;
3934+
}
3935+
38883936
} // namespace odb

src/odb/src/db/dbNet.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2531,10 +2531,16 @@ dbModNet* dbNet::findModNetInHighestHier() const
25312531
size_t min_delimiters = (size_t) -1;
25322532
char delim = getBlock()->getHierarchyDelimiter();
25332533

2534+
// Network::highestConnectedNet(Net *net) compares level of hierarchy and
2535+
// hierarchical net name as a tie breaker.
2536+
// For consistency, this API also uses the hierarchical net name as a tie
2537+
// breaker.
25342538
for (dbModNet* modnet : modnets) {
25352539
std::string name = modnet->getHierarchicalName();
25362540
size_t num_delimiters = std::count(name.begin(), name.end(), delim);
2537-
if (highest == nullptr || num_delimiters < min_delimiters) {
2541+
if (highest == nullptr || num_delimiters < min_delimiters
2542+
|| (num_delimiters == min_delimiters
2543+
&& name < highest->getHierarchicalName())) { // name = tie breaker
25382544
min_delimiters = num_delimiters;
25392545
highest = modnet;
25402546
}

0 commit comments

Comments
 (0)