odb: add dbCorner object and add_corner command#10753
Conversation
Signed-off-by: Arthur Koucher <arthurkoucher@precisioninno.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a new dbCorner object to the ODB database, including its schema, serialization, memory tracking, and a Tcl command add_corner to create corners. The review feedback highlights several critical issues: a potential segmentation fault in the Tcl binding if the block is null, incorrect extraction of the Tcl command argument, a missing public getter for corners in dbBlock, and the lack of duplicate name checking when creating a new corner.
| set block [$chip getBlock] | ||
| odb::dbCorner_create $block $name |
There was a problem hiding this comment.
If the design is loaded but the top block has not been created yet, $chip getBlock will return "NULL". Calling odb::dbCorner_create with a null block will cause a segmentation fault in C++. Add a check to ensure the block is valid before creating the corner.
set block [$chip getBlock]
if { $block == "NULL" } {
utl::error ODB 567 "Could not add corner $name. No block is loaded."
}
set corner [odb::dbCorner_create $block $name]
if { $corner == "NULL" } {
utl::error ODB 568 "Could not create corner $name. A corner with this name may already exist."
}
| corner_tbl_ = new dbTable<_dbCorner>( | ||
| db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbCornerObj); |
There was a problem hiding this comment.
The dbCorner table and vector are added to _dbBlock, but there is no public getter (e.g., dbSet<dbCorner> getCorners() const) exposed in the public dbBlock class in db.h. Without a public getter, external tools and SWIG bindings cannot retrieve or iterate over the corners of a block. Please add dbSet<dbCorner> getCorners() const; to dbBlock in db.h and implement it in dbBlock.cpp.
| sta::parse_key_args "add_corner" args keys {} flags {} | ||
| sta::check_argc_eq1 "add_corner" $args | ||
|
|
||
| set name $args |
| dbCorner* dbCorner::create(dbBlock* block_, const std::string& name) | ||
| { | ||
| _dbBlock* block = (_dbBlock*) block_; | ||
| _dbCorner* corner = block->corner_tbl_->create(); | ||
| corner->name_ = name; | ||
| block->corners_.push_back(corner->getOID()); | ||
|
|
||
| return (dbCorner*) corner; | ||
| } |
There was a problem hiding this comment.
To prevent duplicate process corners with the same name, check if a corner with the given name already exists in the block before creating a new one.
dbCorner* dbCorner::create(dbBlock* block_, const std::string& name)
{
_dbBlock* block = (_dbBlock*) block_;
for (auto id : block->corners_) {
_dbCorner* c = block->corner_tbl_->getPtr(id);
if (c->name_ == name) {
return nullptr;
}
}
_dbCorner* corner = block->corner_tbl_->create();
corner->name_ = name;
block->corners_.push_back(corner->getOID());
return (dbCorner*) corner;
}
Summary
Adds the object which will hold the information regarding each process corner. With this, tools like RCX will only need to consume the ODB data rather than expecting user input.
Type of Change
Impact
[How does this change the tool's behavior?]
Verification
./etc/Build.sh).