Skip to content

Commit 12c486c

Browse files
committed
consider max cap violations during sizing
Signed-off-by: Cho Moon <[email protected]>
1 parent 37305e9 commit 12c486c

File tree

9 files changed

+1531
-1429
lines changed

9 files changed

+1531
-1429
lines changed

src/rsz/src/BaseMove.cc

Lines changed: 117 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -681,26 +681,127 @@ bool BaseMove::replaceCell(Instance* inst, const LibertyCell* replacement)
681681
const char* replacement_name = replacement->name();
682682
dbMaster* replacement_master = db_->findMaster(replacement_name);
683683

684-
if (replacement_master) {
685-
dbInst* dinst = db_network_->staToDb(inst);
686-
dbMaster* master = dinst->getMaster();
687-
resizer_->designAreaIncr(-area(master));
688-
Cell* replacement_cell1 = db_network_->dbToSta(replacement_master);
689-
sta_->replaceCell(inst, replacement_cell1);
690-
resizer_->designAreaIncr(area(replacement_master));
691-
692-
// Legalize the position of the instance in case it leaves the die
693-
if (estimate_parasitics_->getParasiticsSrc()
694-
== est::ParasiticsSrc::global_routing
695-
|| estimate_parasitics_->getParasiticsSrc()
696-
== est::ParasiticsSrc::detailed_routing) {
697-
opendp_->legalCellPos(db_network_->staToDb(inst));
684+
if (!replacement_master) {
685+
return false;
686+
}
687+
688+
// Check if replacement would cause max_cap violations on input nets
689+
if (!checkMaxCapViolation(inst, replacement)) {
690+
return false;
691+
}
692+
693+
dbInst* dinst = db_network_->staToDb(inst);
694+
dbMaster* master = dinst->getMaster();
695+
resizer_->designAreaIncr(-area(master));
696+
Cell* replacement_cell1 = db_network_->dbToSta(replacement_master);
697+
sta_->replaceCell(inst, replacement_cell1);
698+
resizer_->designAreaIncr(area(replacement_master));
699+
700+
// Legalize the position of the instance in case it leaves the die
701+
if (estimate_parasitics_->getParasiticsSrc()
702+
== est::ParasiticsSrc::global_routing
703+
|| estimate_parasitics_->getParasiticsSrc()
704+
== est::ParasiticsSrc::detailed_routing) {
705+
opendp_->legalCellPos(db_network_->staToDb(inst));
706+
}
707+
708+
return true;
709+
}
710+
711+
// Check if replacing inst with replacement cell would cause max_cap violation
712+
// on any of the fanin nets.
713+
bool BaseMove::checkMaxCapViolation(Instance* inst,
714+
const LibertyCell* replacement)
715+
{
716+
LibertyCell* current_cell = network_->libertyCell(inst);
717+
if (!current_cell) {
718+
return true; // Nothing to check, just allow it
719+
}
720+
721+
// Iterate through all input pins of the instance
722+
InstancePinIterator* pin_iter = network_->pinIterator(inst);
723+
while (pin_iter->hasNext()) {
724+
Pin* pin = pin_iter->next();
725+
726+
// Only check input pins
727+
if (!network_->direction(pin)->isAnyInput()) {
728+
continue;
729+
}
730+
PinSet* drivers = network_->drivers(pin);
731+
if (drivers) {
732+
// Calculate capacitance delta (new - old)
733+
float old_cap = getInputPinCapacitance(pin, current_cell);
734+
float new_cap = getInputPinCapacitance(pin, replacement);
735+
float cap_delta = new_cap - old_cap;
736+
if (cap_delta <= 0.0) {
737+
continue;
738+
}
739+
for (const Pin* drvr_pin : *drivers) {
740+
if (!checkMaxCapOK(drvr_pin, cap_delta)) {
741+
delete pin_iter;
742+
return false;
743+
}
744+
}
698745
}
746+
}
699747

700-
return true;
748+
delete pin_iter;
749+
return true;
750+
}
751+
752+
// Get input capacitance for a specific port in a liberty cell
753+
float BaseMove::getInputPinCapacitance(Pin* pin, const LibertyCell* cell)
754+
{
755+
LibertyPort* port = network_->libertyPort(pin);
756+
if (!port) {
757+
return 0.0;
701758
}
702-
return false;
759+
760+
// Find corresponding port in the new cell
761+
LibertyPort* cell_port = cell->findLibertyPort(port->name());
762+
if (!cell_port) {
763+
return 0.0;
764+
}
765+
766+
// Get worst capacitance
767+
float cap = 0.0;
768+
for (auto rf : RiseFall::range()) {
769+
float port_cap = cell_port->capacitance(rf, resizer_->max_);
770+
cap = max(cap, port_cap);
771+
}
772+
773+
return cap;
774+
}
775+
776+
// Check for possible max cap violation with new cap_delta
777+
// If max cap is already violating, accept a solution only if
778+
// it does not worsen the violation
779+
bool BaseMove::checkMaxCapOK(const Pin* drvr_pin, float cap_delta)
780+
{
781+
float cap, max_cap, cap_slack;
782+
const Corner* corner;
783+
const RiseFall* tr;
784+
sta_->checkCapacitance(drvr_pin,
785+
nullptr /* corner */,
786+
resizer_->max_,
787+
// return values
788+
corner,
789+
tr,
790+
cap,
791+
max_cap,
792+
cap_slack);
793+
794+
if (max_cap > 0.0 && corner) {
795+
float new_cap = cap + cap_delta;
796+
// If it is already violating, accept only if violation is no worse
797+
if (cap_slack < 0.0) {
798+
return new_cap <= cap;
799+
}
800+
return new_cap <= max_cap;
801+
}
802+
return true;
703803
}
804+
704805
Slack BaseMove::getWorstInputSlack(Instance* inst)
705806
{
706807
Slack worst_slack = INF;

src/rsz/src/BaseMove.hh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ class BaseMove : public sta::dbStaState
227227
float prev_drive,
228228
const DcalcAnalysisPt* dcalc_ap);
229229
bool replaceCell(Instance* inst, const LibertyCell* replacement);
230+
bool checkMaxCapViolation(Instance* inst, const LibertyCell* replacement);
231+
float getInputPinCapacitance(Pin* pin, const LibertyCell* cell);
232+
bool checkMaxCapOK(const Pin* drvr_pin, float cap_delta);
230233

231234
bool checkMaxCapViolation(const Pin* output_pin,
232235
LibertyPort* output_port,

0 commit comments

Comments
 (0)