Create block within the top block with the insts in top block #5984
Replies: 3 comments 3 replies
-
In ORFS you use BLOCKS to build sub-blocks. You can see https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts/blob/master/flow/designs/gf180/uart-blocks/config.mk for an example |
Beta Was this translation helpful? Give feedback.
-
Here is my detailed code, I want to finish the method createBlock with my code, and I'm trying to create a child block with insts in the std::setodb::dbInsts*. I wonder if I can do this? class ModuleConstraintGroup
{
/**
* @class ModuleConstraintGroup
* @brief A class that manages a group of instances within a module and
* provides functionality to create a child block and move instances to it.
*
* This class encapsulates a set of instances (`insts`) that belong to the
* same module and provides methods to manage these instances. It also allows
* creating a child block, moving instances to it, and reconstructing the
* connections within the child block.
*
* @details
* - `insts`: A set containing the instances of the same module.
* - `wrapper_inst`: A block that contains the instances.
* - `block_name`: The name of the block.
*
* @note The destructor deletes the `wrapper_inst`.
*/
private:
// insts is a set that contains the insts of the same module
std::set<odb::dbInst*> insts;
// wrapper_inst is a block that contains the insts
odb::dbInst* wrapper_inst;
// block_name is the name of the block
std::string block_name;
public:
/**
* @brief Constructor to initialize the ModuleConstraintGroup with a block
* name.
* @param block_name The name of the block.
*/
ModuleConstraintGroup(std::string block_name) : block_name(block_name) {}
/**
* @brief Destructor to clean up resources.
*/
~ModuleConstraintGroup() { delete wrapper_inst; }
/**
* @brief Get the set of instances.
* @return A reference to the set of instances.
*/
std::set<odb::dbInst*>& getInsts() const { return insts; }
/**
* @brief Add an instance to the set.
* @param inst The instance to add.
*/
// Function to add an instance to the set
void addInst(odb::dbInst* inst) { insts.insert(inst); }
/**
* @brief Remove an instance from the set.
* @param inst The instance to remove.
*/
// Function to remove an instance from the set
void removeInst(odb::dbInst* inst) { insts.erase(inst); }
/**
* @brief Check if an instance is in the set.
* @param inst The instance to check.
* @return `true` if the instance is in the set, `false` otherwise.
*/
// Function to check if an instance is in the set
bool hasInst(odb::dbInst* inst) const
{
return insts.find(inst) != insts.end();
}
/**
* @brief Create a child block and move instances to it.
*
* A wrapper instance is then created based on the child block and the child
* block name, and it is connected to the top block based on the iterms
* obtained during the traversal phase.
*
* @param top_block The top block.
* @param child_block_name The name of the child block.
* @return `true` if the child block and wrapper instance are successfully
* created, `false` otherwise.
*/
bool createBlock(odb::dbBlock* top_block, const std::string& child_block_name)
{
// travel the insts to get the area of the block, set the aspect ratio as 1,
// and the utilization as 0.3
float utilization = 0.5;
auto area = 0;
for (auto& inst : insts) {
odb::dbMaster* master = inst->getMaster();
area += master->getArea();
}
area = area / utilization;
// Create a new child block
odb::dbBlock* child_block
= odb::dbBlock::create(top_block, child_block_name.c_str());
if (!child_block) {
std::cerr << "Failed to create child block" << std::endl;
return false;
}
// get cross nets that connect the insts in the group and the insts outside
// the group
std::set<odb::dbNet*> cross_nets;
for (auto& inst : insts) {
for (auto& net : inst->getNets()) {
if (cross_nets.find(net) != cross_nets.end()) {
continue;
}
bool net_cross = false;
for (auto& iterm : net->getITerms()) {
if (net_cross) {
break;
}
if (insts.find(iterm->getInst()) != insts.end()) {
cross_nets.insert(net);
net_cross = true;
}
}
for (auto& bterm : net->getBTerms()) {
if (net_cross) {
break;
}
if (insts.find(bterm->getInst()) != insts.end()) {
cross_nets.insert(net);
net_cross = true;
}
}
}
}
// spilt the cross net into two nets, one is outside, one is inside
for (auto& net : cross_nets) {
odb::dbNet* outside_net
= net; // the net in the parent block is the outside net
odb::dbNet* inside_net
= odb::dbNet::create(child_block, outside_net->getName().c_str());
if (!inside_net) {
std::cerr << "Failed to create net in child block" << std::endl;
return false;
}
if (!wrapper_inst) {
std::cerr << "Failed to create wrapper instance" << std::endl;
return false;
}
// create iterm for wrapper_inst, map the iterm and the bterm
odb::dbITerm* iterm = odb::dbITerm::create(wrapper_inst);
iterm->connect(outside_net);
odb::dbBTerm* bterm = odb::dbBTerm::create(child_block);
bterm->connect(inside_net);
for (auto& iterm : outside_net->getITerms()) {
if (insts.find(iterm->getInst()) != insts.end()) {
iterm->connect(inside_net);
}
}
}
wrapper_inst = odb::dbInst::create(top_block, child_block, child_block_name.c_str());
if (!wrapper_inst) {
std::cerr << "Failed to create wrapper instance" << std::endl;
return false;
}
return true;
}
}; |
Beta Was this translation helpful? Give feedback.
-
I wouldn't do this as OR doesn't do any cross physical hierarchy operations. You should just harden the IPs as ORFS does. |
Beta Was this translation helpful? Give feedback.
-
I want to get some insts together and then place them as a whole, how can I do this? I wonder if I can create a block with the insts, then how can I create a block?
Beta Was this translation helpful? Give feedback.
All reactions