Skip to content

Commit c21c3f9

Browse files
committed
Merge remote-tracking branch 'origin/master' into 3dblox-check
2 parents 697e6ec + a34a87c commit c21c3f9

File tree

100 files changed

+162926
-4140
lines changed

Some content is hidden

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

100 files changed

+162926
-4140
lines changed

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: 242 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

@@ -3136,6 +3212,9 @@ Instance* dbNetwork::dbToSta(dbModInst* inst) const
31363212

31373213
Pin* dbNetwork::dbToSta(dbModITerm* mod_iterm) const
31383214
{
3215+
if (mod_iterm == nullptr) {
3216+
return nullptr;
3217+
}
31393218
char* unaligned_pointer = reinterpret_cast<char*>(mod_iterm);
31403219
return reinterpret_cast<Pin*>(
31413220
unaligned_pointer
@@ -3184,6 +3263,9 @@ const Net* dbNetwork::dbToSta(const dbModNet* net) const
31843263

31853264
Pin* dbNetwork::dbToSta(dbBTerm* bterm) const
31863265
{
3266+
if (bterm == nullptr) {
3267+
return nullptr;
3268+
}
31873269
char* unaligned_pointer = reinterpret_cast<char*>(bterm);
31883270
return reinterpret_cast<Pin*>(
31893271
unaligned_pointer
@@ -3192,6 +3274,9 @@ Pin* dbNetwork::dbToSta(dbBTerm* bterm) const
31923274

31933275
Pin* dbNetwork::dbToSta(dbITerm* iterm) const
31943276
{
3277+
if (iterm == nullptr) {
3278+
return nullptr;
3279+
}
31953280
char* unaligned_pointer = reinterpret_cast<char*>(iterm);
31963281
return reinterpret_cast<Pin*>(
31973282
unaligned_pointer
@@ -4720,4 +4805,153 @@ void dbNetwork::checkSanityModNetNamesInModule(odb::dbModule* module) const
47204805
}
47214806
}
47224807

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

0 commit comments

Comments
 (0)