Skip to content

Commit

Permalink
Propagate hierarchy flag to dbNetwork. Signed-off-by: Andy Fox <andy@…
Browse files Browse the repository at this point in the history
…rushc.com>

Signed-off-by: andyfox-rushc <[email protected]>
  • Loading branch information
andyfox-rushc committed May 15, 2024
1 parent 81af039 commit 002b951
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 24 deletions.
4 changes: 4 additions & 0 deletions src/OpenRoad.cc
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,10 @@ void OpenRoad::linkDesign(const char* design_name, bool hierarchy)

{
dbLinkDesign(design_name, verilog_network_, db_, logger_, hierarchy);
if (hierarchy) {
sta::dbSta* sta = getSta();
sta->getDbNetwork()->setHierarchy();
}
for (OpenRoadObserver* observer : observers_) {
observer->postReadDb(db_);
}
Expand Down
16 changes: 12 additions & 4 deletions src/dbSta/include/db_sta/dbNetwork.hh
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ using odb::dbITerm;
using odb::dbLib;
using odb::dbMaster;
using odb::dbModInst;
using odb::dbModule;
using odb::dbMTerm;
using odb::dbNet;
using odb::dbObject;
Expand Down Expand Up @@ -102,7 +103,7 @@ class dbNetwork : public ConcreteNetwork
dbBlock* block() const { return block_; }
void makeLibrary(dbLib* lib);
void makeCell(Library* library, dbMaster* master);

void makeVerilogCell(Library* library, dbModInst*);
void location(const Pin* pin,
// Return values.
double& x,
Expand All @@ -127,6 +128,7 @@ class dbNetwork : public ConcreteNetwork
dbBTerm*& bterm) const;
dbBTerm* staToDb(const Term* term) const;
dbMaster* staToDb(const Cell* cell) const;
void staToDb(const Cell* cell, dbMaster*& master, dbModule*& module) const;
dbMaster* staToDb(const LibertyCell* cell) const;
dbMTerm* staToDb(const Port* port) const;
dbMTerm* staToDb(const LibertyPort* port) const;
Expand All @@ -143,6 +145,7 @@ class dbNetwork : public ConcreteNetwork
Net* dbToSta(dbNet* net) const;
const Net* dbToSta(const dbNet* net) const;
Cell* dbToSta(dbMaster* master) const;
Cell* dbToSta(dbModule* master) const;
Port* dbToSta(dbMTerm* mterm) const;
PortDirection* dbToSta(const dbSigType& sig_type,
const dbIoType& io_type) const;
Expand Down Expand Up @@ -240,6 +243,10 @@ class dbNetwork : public ConcreteNetwork
double dbuToMeters(int dist) const;
int metersToDbu(double dist) const;

// hierarchy handler, set in openroad tested in network child traverserser
void setHierarchy() { hierarchy_ = true; }
bool hasHierarchy() const { return hierarchy_; }

using Network::cell;
using Network::direction;
using Network::findCellsMatching;
Expand All @@ -263,15 +270,16 @@ class dbNetwork : public ConcreteNetwork
void visitConnectedPins(const Net* net,
PinVisitor& visitor,
NetSet& visited_nets) const override;
bool portMsbFirst(const char* port_name);

bool portMsbFirst(const char* port_name, const char* cell_name);
dbDatabase* db_ = nullptr;
Logger* logger_ = nullptr;
dbBlock* block_ = nullptr;
Instance* top_instance_;
Cell* top_cell_ = nullptr;

std::set<dbNetworkObserver*> observers_;

private:
bool hierarchy_ = false;
};

} // namespace sta
191 changes: 174 additions & 17 deletions src/dbSta/src/dbNetwork.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@ using odb::dbITerm;
using odb::dbITermObj;
using odb::dbLib;
using odb::dbMaster;
using odb::dbModBTerm;
using odb::dbModBTermObj;
using odb::dbModInstObj;
using odb::dbModITerm;
using odb::dbModITermObj;
using odb::dbModNet;
using odb::dbModule;
using odb::dbMTerm;
using odb::dbNet;
Expand Down Expand Up @@ -110,6 +115,11 @@ Library* DbLibraryIterator1::next()
return reinterpret_cast<Library*>(iter_->next());
}

//
// check the leaves accessible from the network
// match those accessible from block.
//

////////////////////////////////////////////////////////////////

class DbInstanceChildIterator : public InstanceChildIterator
Expand All @@ -121,36 +131,78 @@ class DbInstanceChildIterator : public InstanceChildIterator

private:
const dbNetwork* network_;
dbModule* module_;
bool top_;
dbSet<dbInst>::iterator iter_;
dbSet<dbInst>::iterator end_;
dbSet<dbInst>::iterator dbinst_iter_;
dbSet<dbInst>::iterator dbinst_end_;
dbSet<dbModInst>::iterator modinst_iter_;
dbSet<dbModInst>::iterator modinst_end_;
};

DbInstanceChildIterator::DbInstanceChildIterator(const Instance* instance,
const dbNetwork* network)
: network_(network)
{
dbBlock* block = network->block();
if (instance == network->topInstance() && block) {
dbSet<dbInst> insts = block->getInsts();
top_ = true;
iter_ = insts.begin();
end_ = insts.end();
module_ = block->getTopModule();
modinst_iter_ = module_->getModInsts().begin();
modinst_end_ = modinst_iter_;
dbinst_iter_ = module_->getInsts().begin();
dbinst_end_ = dbinst_iter_;

// original code for non hierarchy
if (!network->hasHierarchy()) {
if (instance == network->topInstance() && block) {
dbSet<dbInst> insts = block->getInsts();
top_ = true;
dbinst_iter_ = insts.begin();
dbinst_end_ = insts.end();
} else {
top_ = false;
}
} else {
top_ = false;
if (instance == network->topInstance() && block) {
module_ = block->getTopModule();
top_ = true;
modinst_iter_ = module_->getModInsts().begin();
modinst_end_ = module_->getModInsts().end();
dbinst_iter_ = module_->getInsts().begin();
dbinst_end_ = module_->getInsts().end();
} else {
top_ = false;
// need to get module for instance
dbInst* db_inst = nullptr;
dbModInst* mod_inst = nullptr;
network->staToDb(instance, db_inst, mod_inst);
if (mod_inst) {
module_ = mod_inst->getMaster();
modinst_iter_ = module_->getModInsts().begin();
modinst_end_ = module_->getModInsts().end();
dbinst_iter_ = module_->getInsts().begin();
dbinst_end_ = module_->getInsts().end();
}
}
}
}

bool DbInstanceChildIterator::hasNext()
{
return top_ && iter_ != end_;
return !((dbinst_iter_ == dbinst_end_) && (modinst_iter_ == modinst_end_));
}

Instance* DbInstanceChildIterator::next()
{
dbInst* child = *iter_;
iter_++;
return network_->dbToSta(child);
Instance* ret = nullptr;
if (dbinst_iter_ != dbinst_end_) {
dbInst* child = *dbinst_iter_;
dbinst_iter_++;
ret = network_->dbToSta(child);
} else if (modinst_iter_ != modinst_end_) {
dbModInst* child = *modinst_iter_;
modinst_iter_++;
ret = network_->dbToSta(child);
}
return ret;
}

class DbInstanceNetIterator : public InstanceNetIterator
Expand Down Expand Up @@ -424,6 +476,54 @@ const char* dbNetwork::name(const Instance* instance) const
return tmpStringCopy(mod_inst->getName());
}

void dbNetwork::makeVerilogCell(Library* library, dbModInst* mod_inst)
{
dbModule* master = mod_inst->getMaster();
Cell* local_cell
= ConcreteNetwork::makeCell(library, master->getName(), false, nullptr);
master->staSetCell((void*) (local_cell));

std::map<std::string, dbModBTerm*> name2modbterm;

for (auto modbterm : master->getModBTerms()) {
const char* port_name = modbterm->getName();
Port* port = ConcreteNetwork::makePort(local_cell, port_name);
PortDirection* dir = dbToSta(modbterm->getSigType(), modbterm->getIoType());
setDirection(port, dir);
name2modbterm[std::string(port_name)] = modbterm;
}

// make the bus ports. This will generate the bus bits.
groupBusPorts(local_cell, [=](const char* port_name) {
return portMsbFirst(port_name, master->getName());
});

CellPortIterator* ccport_iter = portIterator(local_cell);
while (ccport_iter->hasNext()) {
Port* cport = ccport_iter->next();
const ConcretePort* ccport = reinterpret_cast<const ConcretePort*>(cport);
std::string port_name = ccport->name();

if (ccport->isBus()) {
PortMemberIterator* pmi = memberIterator(cport);
while (pmi->hasNext()) {
Port* bitport = pmi->next();
const ConcretePort* cbitport
= reinterpret_cast<const ConcretePort*>(bitport);
dbModBTerm* modbterm = name2modbterm[std::string(cbitport->name())];
modbterm->staSetPort(bitport);
}
} else if (ccport->isBundle()) {
;
} else if (ccport->isBusBit()) {
;
} else {
dbModBTerm* modbterm = name2modbterm[port_name];
modbterm->staSetPort(cport);
}
}
}

Cell* dbNetwork::cell(const Instance* instance) const
{
if (instance == top_instance_) {
Expand All @@ -437,6 +537,11 @@ Cell* dbNetwork::cell(const Instance* instance) const
dbMaster* master = db_inst->getMaster();
return dbToSta(master);
}
if (mod_inst) {
dbModule* master = mod_inst->getMaster();
// look up the cell in the verilog library.
return dbToSta(master);
}
// no traversal of the hierarchy this way; we would have to split
// Cell into dbMaster and dbModule otherwise. When we have full
// odb hierarchy this can be revisited.
Expand Down Expand Up @@ -464,7 +569,21 @@ Instance* dbNetwork::parent(const Instance* instance) const

bool dbNetwork::isLeaf(const Instance* instance) const
{
return instance != top_instance_;
if (instance == top_instance_) {
return false;
}
if (hierarchy_) {
dbMaster* db_master;
dbModule* db_module;
Cell* cur_cell = cell(instance);
staToDb(cur_cell, db_master, db_module);
if (db_module) {
return false;
}
return true;
} else {
return instance != top_instance_;
}
}

Instance* dbNetwork::findInstance(const char* path_name) const
Expand Down Expand Up @@ -867,6 +986,19 @@ void dbNetwork::readDbAfter(odb::dbDatabase* db)
makeLibrary(lib);
}
readDbNetlistAfter();
if (hierarchy_) {
// we make the library for the verilog hierarchical cells
// this is in the same fashion as the original dbInst code
// which uses the void* staGetCell to associate a cell with
// concrete cell. We do same for verilog hierarchical cells.
Library* verilog_library = makeLibrary("verilog", nullptr);
dbSet<dbModInst> modinsts = block_->getModInsts();
dbSet<dbModInst>::iterator modinst_iter_ = modinsts.begin();
dbSet<dbModInst>::iterator modinst_end_ = modinsts.end();
for (; modinst_iter_ != modinst_end_; modinst_iter_++) {
makeVerilogCell(verilog_library, *modinst_iter_);
}
}
}

for (auto* observer : observers_) {
Expand Down Expand Up @@ -966,8 +1098,9 @@ void dbNetwork::makeTopCell()
for (dbBTerm* bterm : block_->getBTerms()) {
makeTopPort(bterm);
}
groupBusPorts(top_cell_,
[=](const char* port_name) { return portMsbFirst(port_name); });
groupBusPorts(top_cell_, [=](const char* port_name) {
return portMsbFirst(port_name, design_name);
});
}

Port* dbNetwork::makeTopPort(dbBTerm* bterm)
Expand All @@ -988,10 +1121,11 @@ void dbNetwork::setTopPortDirection(dbBTerm* bterm, const dbIoType& io_type)

// read_verilog / Verilog2db::makeDbPins leaves a cookie to know if a bus port
// is msb first or lsb first.
bool dbNetwork::portMsbFirst(const char* port_name)
bool dbNetwork::portMsbFirst(const char* port_name, const char* cell_name)
{
string key = "bus_msb_first ";
key += port_name;
// key += port_name;
key = key + port_name + " " + cell_name;
dbBoolProperty* property = odb::dbBoolProperty::find(block_, key.c_str());
if (property) {
return property->getValue();
Expand Down Expand Up @@ -1350,6 +1484,24 @@ dbBTerm* dbNetwork::staToDb(const Term* term) const
return reinterpret_cast<dbBTerm*>(const_cast<Term*>(term));
}

void dbNetwork::staToDb(const Cell* cell,
dbMaster*& master,
dbModule*& module) const
{
module = nullptr;
master = nullptr;
if (findLibertyCell(name(cell))) {
master = reinterpret_cast<dbMaster*>(const_cast<Cell*>(cell));
} else {
if (block_) {
if (block_->findModule(name(cell)))
module = reinterpret_cast<dbModule*>(const_cast<Cell*>(cell));
else
master = reinterpret_cast<dbMaster*>(const_cast<Cell*>(cell));
}
}
}

dbMaster* dbNetwork::staToDb(const Cell* cell) const
{
const ConcreteCell* ccell = reinterpret_cast<const ConcreteCell*>(cell);
Expand Down Expand Up @@ -1445,6 +1597,11 @@ Cell* dbNetwork::dbToSta(dbMaster* master) const
return reinterpret_cast<Cell*>(master->staCell());
}

Cell* dbNetwork::dbToSta(dbModule* master) const
{
return ((Cell*) (master->getStaCell()));
}

PortDirection* dbNetwork::dbToSta(const dbSigType& sig_type,
const dbIoType& io_type) const
{
Expand Down
5 changes: 2 additions & 3 deletions src/dbSta/src/dbReadVerilog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,10 @@ void Verilog2db::recordBusPortsOrder()
Port* port = bus_iter->next();
if (network_->isBus(port)) {
const char* port_name = network_->name(port);
const char* cell_name = network_->name(top_cell);
int from = network_->fromIndex(port);
int to = network_->toIndex(port);
string key = "bus_msb_first ";
key += port_name;
string key = std::string("bus_msb_first ") + port_name + " " + cell_name;
odb::dbBoolProperty::create(block_, key.c_str(), from > to);
}
}
Expand Down Expand Up @@ -432,7 +432,6 @@ void Verilog2db::makeDbModule(
module->getName());
continue;
}
module->addInst(db_inst);
}
}
delete child_iter;
Expand Down

0 comments on commit 002b951

Please sign in to comment.