Skip to content

Commit 234e9cc

Browse files
authored
Merge pull request #8839 from The-OpenROAD-Project-staging/secure-fix-hier-qor-mismatch
rsz: Fixed UnbufferMove::removeBuffer() for hierarchical flow
2 parents 3113e7b + 7bc521f commit 234e9cc

63 files changed

Lines changed: 155322 additions & 343 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/dbSta/include/db_sta/dbNetwork.hh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class dbNetwork : public ConcreteNetwork
7171
void clear() override;
7272
CellPortIterator* portIterator(const Cell* cell) const override;
7373

74-
// sanity checkers
74+
// Sanity checkers
7575
void checkAxioms(odb::dbObject* obj = nullptr) const;
7676
void checkSanityModBTerms() const;
7777
void checkSanityModITerms() const;
@@ -83,6 +83,7 @@ class dbNetwork : public ConcreteNetwork
8383
void checkSanityInstNames() const;
8484
void checkSanityNetNames() const;
8585
void checkSanityModNetNamesInModule(odb::dbModule* module) const;
86+
void checkSanityNetDrvrPinMapConsistency() const;
8687

8788
void readLefAfter(dbLib* lib);
8889
void readDefAfter(dbBlock* block);
@@ -93,6 +94,7 @@ class dbNetwork : public ConcreteNetwork
9394
void removeObserver(dbNetworkObserver* observer);
9495

9596
dbBlock* block() const { return block_; }
97+
utl::Logger* getLogger() const { return logger_; }
9698
void makeLibrary(dbLib* lib);
9799
void makeCell(Library* library, dbMaster* master);
98100
void makeVerilogCell(Library* library, dbModInst*);
@@ -278,7 +280,6 @@ class dbNetwork : public ConcreteNetwork
278280

279281
////////////////////////////////////////////////////////////////
280282
// Port functions
281-
282283
Cell* cell(const Port* port) const override;
283284
void registerConcretePort(const Port*);
284285

@@ -383,6 +384,7 @@ class dbNetwork : public ConcreteNetwork
383384
bool hasMembers(const Port* port) const override;
384385
Port* findMember(const Port* port, int index) const override;
385386
PortMemberIterator* memberIterator(const Port* port) const override;
387+
void removeDriverFromCache(const Net* net, const Pin* drvr);
386388

387389
using Network::cell;
388390
using Network::direction;
@@ -411,6 +413,10 @@ class dbNetwork : public ConcreteNetwork
411413
bool portMsbFirst(const char* port_name, const char* cell_name);
412414
ObjectId getDbNwkObjectId(const dbObject* object) const;
413415

416+
////////////////////////////////////////////////////////////////
417+
// Debug functions
418+
void dumpNetDrvrPinMap() const;
419+
414420
dbDatabase* db_ = nullptr;
415421
Logger* logger_ = nullptr;
416422
dbBlock* block_ = nullptr;

src/dbSta/src/dbNetwork.cc

Lines changed: 233 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ Recommended conclusion: use map for concrete cells. They are invariant.
6464
#include "odb/dbObject.h"
6565
#include "odb/dbSet.h"
6666
#include "odb/dbTypes.h"
67+
#include "odb/dbUtil.h"
6768
#include "sta/Liberty.hh"
6869
#include "sta/Network.hh"
6970
#include "sta/NetworkClass.hh"
@@ -107,6 +108,8 @@ using odb::dbPlacementStatus;
107108
using odb::dbSet;
108109
using odb::dbSigType;
109110

111+
namespace {
112+
110113
// TODO: move to StringUtil
111114
char* tmpStringCopy(const char* str)
112115
{
@@ -115,6 +118,58 @@ char* tmpStringCopy(const char* str)
115118
return tmp;
116119
}
117120

121+
// This struct contains common information about Pins
122+
// (dbITerm, dbBTerm or dbModITerm) for debugging purposes.
123+
struct PinInfo
124+
{
125+
const char* name = "NOT_ALLOC"; // Pin hierarchical name
126+
int id = 0; // dbObject ID
127+
const char* type_name = "NULL"; // dbObject type name
128+
bool valid = false; // false if it is a freed dbObject
129+
void* addr = nullptr;
130+
};
131+
132+
PinInfo getPinInfo(const dbNetwork* network, const Pin* pin)
133+
{
134+
PinInfo info{"NOT_ALLOC", 0, "NULL", false, nullptr};
135+
dbITerm* iterm;
136+
dbBTerm* bterm;
137+
dbModITerm* moditerm;
138+
network->staToDb(pin, iterm, bterm, moditerm);
139+
140+
if (iterm) {
141+
info.id = iterm->getId();
142+
info.type_name = iterm->getTypeName();
143+
info.valid = iterm->isValid();
144+
info.addr = static_cast<void*>(iterm);
145+
} else if (bterm) {
146+
info.id = bterm->getId();
147+
info.type_name = bterm->getTypeName();
148+
info.valid = bterm->isValid();
149+
info.addr = static_cast<void*>(bterm);
150+
} else if (moditerm) {
151+
info.id = moditerm->getId();
152+
info.type_name = moditerm->getTypeName();
153+
info.valid = moditerm->isValid();
154+
info.addr = static_cast<void*>(moditerm);
155+
}
156+
157+
if (info.valid) {
158+
info.name = network->pathName(pin);
159+
} else {
160+
network->getLogger()->error(
161+
ORD,
162+
2014,
163+
"Attempted to access invalid pin {}({}). Check if it is "
164+
"deleted.",
165+
info.type_name,
166+
info.id);
167+
}
168+
169+
return info;
170+
}
171+
} // namespace
172+
118173
//
119174
// Handling of object ids (Hierachy Mode)
120175
//--------------------------------------
@@ -1554,11 +1609,12 @@ PortDirection* dbNetwork::direction(const Pin* pin) const
15541609
return dir;
15551610
}
15561611
if (moditerm) {
1557-
// get the direction off the modbterm
1612+
// get the direction of the modbterm
15581613
std::string pin_name = moditerm->getName();
15591614
dbModInst* mod_inst = moditerm->getParent();
15601615
dbModule* module = mod_inst->getMaster();
15611616
dbModBTerm* modbterm_local = module->findModBTerm(pin_name.c_str());
1617+
assert(modbterm_local != nullptr);
15621618
PortDirection* dir
15631619
= dbToSta(modbterm_local->getSigType(), modbterm_local->getIoType());
15641620
return dir;
@@ -1957,7 +2013,9 @@ void dbNetwork::visitConnectedPins(const Net* net,
19572013
visitor(above_pin);
19582014
// traverse along rest of net
19592015
Net* above_net = this->net(above_pin);
1960-
visitConnectedPins(above_net, visitor, visited_nets);
2016+
if (above_net) {
2017+
visitConnectedPins(above_net, visitor, visited_nets);
2018+
}
19612019
}
19622020
}
19632021
} else if (db_net) {
@@ -2697,13 +2755,31 @@ void dbNetwork::disconnectPin(Pin* pin)
26972755

26982756
void dbNetwork::disconnectPinBefore(const Pin* pin)
26992757
{
2700-
Net* net = this->net(pin);
2701-
// Incrementally update drivers.
2702-
if (net && isDriver(pin)) {
2703-
PinSet* drvrs = net_drvr_pin_map_.findKey(net);
2704-
if (drvrs) {
2705-
drvrs->erase(pin);
2758+
if (isDriver(pin) == false) {
2759+
return; // No need to update net_drvr_pin_map_ cache.
2760+
}
2761+
2762+
// Get all the related dbNet & dbModNet with the pin.
2763+
// Incrementally update the net-drvr cache.
2764+
dbNet* db_net;
2765+
dbModNet* mod_net;
2766+
net(pin, db_net, mod_net);
2767+
2768+
if (db_net) {
2769+
// A dbNet can be associated with multiple dbModNets.
2770+
// We need to update the cache for all of them.
2771+
std::set<odb::dbModNet*> related_mod_nets;
2772+
db_net->findRelatedModNets(related_mod_nets);
2773+
for (dbModNet* related_mod_net : related_mod_nets) {
2774+
removeDriverFromCache(dbToSta(related_mod_net), pin);
27062775
}
2776+
2777+
removeDriverFromCache(dbToSta(db_net), pin);
2778+
return;
2779+
}
2780+
2781+
if (mod_net) {
2782+
removeDriverFromCache(dbToSta(mod_net), pin);
27072783
}
27082784
}
27092785

@@ -4720,4 +4796,153 @@ void dbNetwork::checkSanityModNetNamesInModule(odb::dbModule* module) const
47204796
}
47214797
}
47224798

4799+
void dbNetwork::checkSanityNetDrvrPinMapConsistency() const
4800+
{
4801+
if (block_ == nullptr) {
4802+
logger_->error(ORD, 2000, "No block found.");
4803+
return;
4804+
}
4805+
4806+
// For each cache element
4807+
for (const auto& [net, cached_drivers_ptr] : net_drvr_pin_map_) {
4808+
dbNet* dbnet = nullptr;
4809+
dbModNet* modnet = nullptr;
4810+
staToDb(net, dbnet, modnet);
4811+
4812+
if (dbnet == nullptr && modnet == nullptr) {
4813+
logger_->warn(ORD,
4814+
2009,
4815+
"Found net {} in cache that is not in the netlist.",
4816+
pathName(net));
4817+
continue;
4818+
}
4819+
4820+
// Find drivers from the netlist for the current net
4821+
std::vector<odb::dbObject*> drivers;
4822+
if (dbnet) {
4823+
odb::dbUtil::findITermDrivers(dbnet, drivers);
4824+
odb::dbUtil::findBTermDrivers(dbnet, drivers);
4825+
} else if (modnet) {
4826+
odb::dbUtil::findITermDrivers(modnet, drivers);
4827+
odb::dbUtil::findBTermDrivers(modnet, drivers);
4828+
odb::dbUtil::findModITermDrivers(modnet, drivers);
4829+
4830+
// Also, find drivers from the related flat net
4831+
dbNet* related_dbnet = findRelatedDbNet(modnet);
4832+
if (related_dbnet) {
4833+
odb::dbUtil::findITermDrivers(related_dbnet, drivers);
4834+
odb::dbUtil::findBTermDrivers(related_dbnet, drivers);
4835+
}
4836+
4837+
// Remove duplicates
4838+
std::sort(drivers.begin(), drivers.end());
4839+
drivers.erase(std::unique(drivers.begin(), drivers.end()), drivers.end());
4840+
}
4841+
4842+
// Convert to PinSet
4843+
PinSet netlist_drivers(this);
4844+
for (auto driver : drivers) {
4845+
Pin* pin = nullptr;
4846+
switch (driver->getObjectType()) {
4847+
case odb::dbITermObj:
4848+
pin = dbToSta(static_cast<odb::dbITerm*>(driver));
4849+
break;
4850+
case odb::dbBTermObj:
4851+
pin = dbToSta(static_cast<odb::dbBTerm*>(driver));
4852+
break;
4853+
case odb::dbModITermObj:
4854+
// Skip hierarchical pin.
4855+
break;
4856+
default:
4857+
// Should not be here
4858+
break;
4859+
}
4860+
if (pin != nullptr) {
4861+
netlist_drivers.insert(pin);
4862+
}
4863+
}
4864+
4865+
// Compare netlist drivers with cached drivers
4866+
bool consistent = true;
4867+
if (cached_drivers_ptr == nullptr
4868+
|| netlist_drivers.size() != cached_drivers_ptr->size()) {
4869+
consistent = false;
4870+
} else {
4871+
for (const Pin* pin : netlist_drivers) {
4872+
if (cached_drivers_ptr->find(pin) == cached_drivers_ptr->end()) {
4873+
consistent = false;
4874+
break;
4875+
}
4876+
}
4877+
}
4878+
4879+
// Report inconsistent point details
4880+
if (consistent == false) {
4881+
logger_->warn(ORD, 2006, "Inconsistency found for net {}", pathName(net));
4882+
logger_->report(" Netlist drivers:");
4883+
for (const Pin* pin : netlist_drivers) {
4884+
const PinInfo pin_info = getPinInfo(this, pin);
4885+
logger_->report(" - {} (type: {}, id: {})",
4886+
pin_info.name,
4887+
pin_info.type_name,
4888+
pin_info.id);
4889+
}
4890+
logger_->report(" Cached drivers:");
4891+
if (cached_drivers_ptr) {
4892+
for (const Pin* pin : *cached_drivers_ptr) {
4893+
const PinInfo pin_info = getPinInfo(this, pin);
4894+
logger_->report(" - {} (type: {}, id: {})",
4895+
pin_info.name,
4896+
pin_info.type_name,
4897+
pin_info.id);
4898+
}
4899+
}
4900+
}
4901+
}
4902+
}
4903+
4904+
void dbNetwork::dumpNetDrvrPinMap() const
4905+
{
4906+
const auto& net_drvr_pin_map = net_drvr_pin_map_;
4907+
logger_->report("--------------------------------------------------");
4908+
logger_->report("Dumping net_drvr_pin_map_ cache (size: {})",
4909+
net_drvr_pin_map.size());
4910+
4911+
for (auto const& [net, pin_set] : net_drvr_pin_map) {
4912+
// Get the underlying dbObject for the net to report its type and ID.
4913+
const dbObject* net_obj
4914+
= reinterpret_cast<const dbObject*>(const_cast<Net*>(net));
4915+
logger_->report("Net: {} {}({}, {:p})",
4916+
pathName(net),
4917+
net_obj->getTypeName(),
4918+
net_obj->getId(),
4919+
(void*) net_obj);
4920+
if (pin_set == nullptr) {
4921+
logger_->report(" Drivers: null pin set");
4922+
continue;
4923+
}
4924+
if (pin_set->empty()) {
4925+
logger_->report(" Drivers: empty pin set");
4926+
continue;
4927+
}
4928+
for (const Pin* pin : *pin_set) {
4929+
const PinInfo pin_info = getPinInfo(this, pin);
4930+
logger_->report(" - {} {}({}, {:p})",
4931+
pin_info.name,
4932+
pin_info.type_name,
4933+
pin_info.id,
4934+
pin_info.addr);
4935+
}
4936+
}
4937+
logger_->report("--------------------------------------------------");
4938+
}
4939+
4940+
void dbNetwork::removeDriverFromCache(const Net* net, const Pin* drvr)
4941+
{
4942+
PinSet* drvrs = net_drvr_pin_map_.findKey(net);
4943+
if (drvrs) {
4944+
drvrs->erase(drvr);
4945+
}
4946+
}
4947+
47234948
} // namespace sta

src/dbSta/src/dbSta.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,13 @@ class dbStaCbk : public dbBlockCallBackObj
155155
void inDbInstSwapMasterBefore(dbInst* inst, dbMaster* master) override;
156156
void inDbInstSwapMasterAfter(dbInst* inst) override;
157157
void inDbNetDestroy(dbNet* net) override;
158+
void inDbModNetDestroy(dbModNet* modnet) override;
158159
void inDbITermPostConnect(dbITerm* iterm) override;
159160
void inDbITermPreDisconnect(dbITerm* iterm) override;
160161
void inDbITermDestroy(dbITerm* iterm) override;
162+
void inDbModITermPostConnect(dbModITerm* moditerm) override;
163+
void inDbModITermPreDisconnect(dbModITerm* moditerm) override;
164+
void inDbModITermDestroy(dbModITerm* moditerm) override;
161165
void inDbBTermPostConnect(dbBTerm* bterm) override;
162166
void inDbBTermPreDisconnect(dbBTerm* bterm) override;
163167
void inDbBTermCreate(dbBTerm*) override;
@@ -990,6 +994,12 @@ void dbStaCbk::inDbNetDestroy(dbNet* db_net)
990994
network_->deleteNetBefore(net);
991995
}
992996

997+
void dbStaCbk::inDbModNetDestroy(dbModNet* modnet)
998+
{
999+
Net* net = network_->dbToSta(modnet);
1000+
network_->deleteNetBefore(net);
1001+
}
1002+
9931003
void dbStaCbk::inDbITermPostConnect(dbITerm* iterm)
9941004
{
9951005
Pin* pin = network_->dbToSta(iterm);
@@ -1009,6 +1019,25 @@ void dbStaCbk::inDbITermDestroy(dbITerm* iterm)
10091019
sta_->deletePinBefore(network_->dbToSta(iterm));
10101020
}
10111021

1022+
void dbStaCbk::inDbModITermPostConnect(dbModITerm* moditerm)
1023+
{
1024+
Pin* pin = network_->dbToSta(moditerm);
1025+
network_->connectPinAfter(pin);
1026+
sta_->connectPinAfter(pin);
1027+
}
1028+
1029+
void dbStaCbk::inDbModITermPreDisconnect(dbModITerm* moditerm)
1030+
{
1031+
Pin* pin = network_->dbToSta(moditerm);
1032+
sta_->disconnectPinBefore(pin);
1033+
network_->disconnectPinBefore(pin);
1034+
}
1035+
1036+
void dbStaCbk::inDbModITermDestroy(dbModITerm* moditerm)
1037+
{
1038+
sta_->deletePinBefore(network_->dbToSta(moditerm));
1039+
}
1040+
10121041
void dbStaCbk::inDbBTermPostConnect(dbBTerm* bterm)
10131042
{
10141043
Pin* pin = network_->dbToSta(bterm);

0 commit comments

Comments
 (0)