report_net min/max cap instead of rise/fall/min/max

This commit is contained in:
James Cherry 2021-04-02 14:46:30 -07:00
parent 7f0ee1b686
commit e10258d9e5
11 changed files with 180 additions and 136 deletions

View File

@ -660,6 +660,7 @@ public:
bool &exists) const;
void setFanoutLoad(float fanout_load);
float capacitance() const;
float capacitance(const MinMax *min_max) const;
float capacitance(const RiseFall *rf,
const MinMax *min_max) const;
void capacitance(const RiseFall *rf,

View File

@ -53,6 +53,9 @@ public:
// Max value1 > value2, Min value1 < value2.
bool compare(float value1,
float value2) const;
// min/max(value1, value2)
float minMax(float value1,
float value2) const;
MinMaxAll *asMinMaxAll() const;
MinMax *opposite() const;
// for range support.
@ -60,8 +63,9 @@ public:
static const std::array<MinMax*, 2> &range() { return range_; }
// for (auto mm_index : MinMax::rangeIndex()) {}
static const std::array<int, 2> &rangeIndex() { return range_index_; }
// Find MinMax from name.
static MinMax *find(const char *min_max);
// Find transition from index.
// Find MinMax from index.
static MinMax *find(int index);
static const int index_max = 1;
static const int index_count = 2;

View File

@ -31,6 +31,7 @@ public:
explicit RiseFallMinMax(float init_value);
float value(const RiseFall *rf,
const MinMax *min_max) const;
float value(const MinMax *min_max) const;
void value(const RiseFall *rf,
const MinMax *min_max,
float &value,

View File

@ -66,6 +66,7 @@ class EquivCells;
typedef InstanceSeq::Iterator SlowDrvrIterator;
typedef Vector<const char*> CheckError;
typedef Vector<CheckError*> CheckErrorSeq;
typedef Vector<Corner*> CornerSeq;
enum class CmdNamespace { sta, sdc };
@ -155,19 +156,16 @@ public:
const RiseFallBoth *rf,
const MinMaxAll *min_max,
float slew);
// Port external pin load.
float portExtPinCap(Port *port,
const RiseFall *rf,
const MinMax *min_max);
// Set port external pin load (set_load -pin port).
void setPortExtPinCap(Port *port,
const RiseFallBoth *rf,
const MinMaxAll *min_max,
float cap);
// Port external wire load.
float portExtWireCap(Port *port,
const RiseFall *rf,
const MinMax *min_max);
void portExtCaps(Port *port,
const MinMax *min_max,
float &pin_cap,
float &wire_cap,
int &fanout);
// Set port external wire load (set_load -wire port).
void setPortExtWireCap(Port *port,
bool subtract_pin_cap,
@ -180,15 +178,16 @@ public:
const Corner *corner,
const MinMaxAll *min_max,
float cap);
// Port external fanout (used by wireload models).
int portExtFanout(Port *port,
const MinMax *min_max);
// Set port external fanout (used by wireload models).
void setPortExtFanout(Port *port,
int fanout,
const MinMaxAll *min_max);
// Remove all "set_load net" annotations.
void removeNetLoadCaps() const;
// Liberty port capacitance.
float capacitance(const LibertyPort *port,
Corner *corner,
const MinMax *min_max);
// pin_cap = net pin capacitances + port external pin capacitance,
// wire_cap = annotated net capacitance + port external wire capacitance.
void connectedCap(Pin *drvr_pin,
@ -198,8 +197,7 @@ public:
float &pin_cap,
float &wire_cap) const;
void connectedCap(Net *net,
const RiseFall *rf,
const Corner *corner,
Corner *corner,
const MinMax *min_max,
float &pin_cap,
float &wire_cap) const;
@ -1338,6 +1336,7 @@ protected:
LibertyCell *to_lib_cell);
void sdcChangedGraph();
void ensureGraphSdcAnnotated();
CornerSeq makeCornerSeq(Corner *corner) const;
CmdNamespace cmd_namespace_;
Instance *current_instance_;

View File

@ -202,7 +202,7 @@ private:
};
// Obsolete. Use range iteration instead.
// for (auto tr : RiseFall::range()) {}
// for (RiseFall *rf : RiseFall::range()) {}
class RiseFallIterator : public Iterator<RiseFall*>
{
public:

View File

@ -1948,6 +1948,12 @@ LibertyPort::capacitance() const
return 0.0;
}
float
LibertyPort::capacitance(const MinMax *min_max) const
{
return capacitance_.value(min_max);
}
float
LibertyPort::capacitance(const RiseFall *rf,
const MinMax *min_max) const

View File

@ -150,6 +150,18 @@ RiseFallMinMax::value(const RiseFall *rf,
value = values_[rf->index()][min_max->index()];
}
float
RiseFallMinMax::value(const MinMax *min_max) const
{
int mm_index = min_max->index();
float rise = values_[RiseFall::riseIndex()][mm_index];
float fall = values_[RiseFall::fallIndex()][mm_index];
if (min_max->compare(rise, fall))
return rise;
else
return fall;
}
float
RiseFallMinMax::value(const RiseFall *rf,
const MinMax *min_max) const
@ -201,9 +213,9 @@ RiseFallMinMax::hasValue(const RiseFall *rf, const MinMax *min_max) const
void
RiseFallMinMax::mergeWith(RiseFallMinMax *rfmm)
{
for (auto min_max : MinMax::range()) {
for (MinMax *min_max : MinMax::range()) {
int mm_index = min_max->index();
for (auto rf_index : RiseFall::rangeIndex()) {
for (int rf_index : RiseFall::rangeIndex()) {
bool exists1 = exists_[rf_index][mm_index];
bool exists2 = rfmm->exists_[rf_index][mm_index];
if (exists1 && exists2) {

View File

@ -3403,24 +3403,6 @@ Sta::simLogicValue(const Pin *pin)
return sim_->logicValue(pin);
}
float
Sta::portExtPinCap(Port *port,
const RiseFall *rf,
const MinMax *min_max)
{
float pin_cap, wire_cap;
int fanout;
bool pin_exists, wire_exists, fanout_exists;
sdc_->portExtCap(port, rf, min_max,
pin_cap, pin_exists,
wire_cap, wire_exists,
fanout, fanout_exists);
if (pin_exists)
return pin_cap;
else
return 0.0;
}
void
Sta::setPortExtPinCap(Port *port,
const RiseFallBoth *rf,
@ -3435,22 +3417,43 @@ Sta::setPortExtPinCap(Port *port,
delaysInvalidFromFanin(port);
}
float
Sta::portExtWireCap(Port *port,
const RiseFall *rf,
const MinMax *min_max)
void
Sta::portExtCaps(Port *port,
const MinMax *min_max,
float &pin_cap,
float &wire_cap,
int &fanout)
{
float pin_cap, wire_cap;
int fanout;
bool pin_exists, wire_exists, fanout_exists;
sdc_->portExtCap(port, rf, min_max,
pin_cap, pin_exists,
wire_cap, wire_exists,
fanout, fanout_exists);
if (wire_exists)
return wire_cap;
else
return 0.0;
bool pin_exists = false;
bool wire_exists = false;
bool fanout_exists = false;
for (RiseFall *rf : RiseFall::range()) {
float pin_cap1, wire_cap1;
int fanout1;
bool pin_exists1, wire_exists1, fanout_exists1;
sdc_->portExtCap(port, rf, min_max,
pin_cap1, pin_exists1,
wire_cap1, wire_exists1,
fanout1, fanout_exists1);
if (pin_exists1) {
pin_cap = min_max->minMax(pin_cap, pin_cap1);
pin_exists = true;
}
if (wire_exists1) {
wire_cap = min_max->minMax(wire_cap, wire_cap1);
wire_exists = true;
}
if (fanout_exists1) {
fanout = min_max->minMax(fanout, fanout1);
fanout_exists = true;
}
}
if (!pin_exists)
pin_cap = 0.0;
if (!wire_exists)
wire_cap = 0.0;
if (!fanout_exists)
fanout = 0;
}
void
@ -3476,13 +3479,6 @@ Sta::removeNetLoadCaps() const
graph_delay_calc_->delaysInvalid();
}
int
Sta::portExtFanout(Port *port,
const MinMax *min_max)
{
return sdc_->portExtFanout(port, min_max);
}
void
Sta::setPortExtFanout(Port *port,
int fanout,
@ -3541,21 +3537,57 @@ Sta::connectedCap(Pin *drvr_pin,
void
Sta::connectedCap(Net *net,
const RiseFall *rf,
const Corner *corner,
Corner *corner,
const MinMax *min_max,
float &pin_cap,
float &wire_cap) const
{
Pin *drvr_pin = findNetParasiticDrvrPin(net);
if (drvr_pin)
connectedCap(drvr_pin, rf, corner, min_max, pin_cap, wire_cap);
if (drvr_pin) {
pin_cap = min_max->initValue();
wire_cap = min_max->initValue();
for (const Corner *corner : makeCornerSeq(corner)) {
for (RiseFall *rf : RiseFall::range()) {
float pin_cap1, wire_cap1;
connectedCap(drvr_pin, rf, corner, min_max, pin_cap1, wire_cap1);
pin_cap = min_max->minMax(pin_cap, pin_cap1);
wire_cap = min_max->minMax(wire_cap, wire_cap1);
}
}
}
else {
pin_cap = 0.0;
wire_cap = 0.0;
}
}
CornerSeq
Sta::makeCornerSeq(Corner *corner) const
{
CornerSeq corners;
if (corner)
corners.push_back(corner);
else
corners = corners_->corners();
return corners;
}
float
Sta::capacitance(const LibertyPort *port,
Corner *corner,
const MinMax *min_max)
{
OperatingConditions *op_cond = operatingConditions(min_max);
float cap = min_max->initValue();
for (const Corner *corner : makeCornerSeq(corner)) {
int lib_ap = corner->libertyIndex(min_max);
const LibertyPort *corner_port = port->cornerPort(lib_ap);
for (RiseFall *rf : RiseFall::range())
cap = min_max->minMax(cap, corner_port->capacitance(rf, min_max, op_cond, op_cond));
}
return cap;
}
// Look for a driver to find a parasitic if the net has one.
// Settle for a load pin if there are no drivers.
Pin *

View File

@ -232,7 +232,7 @@ proc_redirect report_pin {
parse_key_args "report_pin" args keys {-corner -digits} \
flags {-connections -verbose -hier_pins}
set corner [parse_corner_or_default keys]
set corner [parse_corner_or_all keys]
set digits $sta_report_default_digits
if { [info exists keys(-digits)] } {
set digits $keys(-digits)
@ -260,7 +260,7 @@ proc_redirect report_net {
flags {-connections -verbose -hier_pins}
check_argc_eq1 "report_net" $args
set corner [parse_corner_or_default keys]
set corner [parse_corner_or_all keys]
set digits $sta_report_default_digits
if { [info exists keys(-digits)] } {
set digits $keys(-digits)
@ -347,11 +347,9 @@ proc report_net_caps { net pins corner digits } {
}
proc report_net_cap { net caption cap_msg corner digits } {
set cap_r_min [$net $cap_msg "rise" $corner "min"]
set cap_r_max [$net $cap_msg "rise" $corner "max"]
set cap_f_min [$net $cap_msg "fall" $corner "min"]
set cap_f_max [$net $cap_msg "fall" $corner "max"]
report_line " $caption capacitance: [capacitances_str $cap_r_min $cap_r_max $cap_f_min $cap_f_max $digits]"
set cap_min [$net $cap_msg $corner "min"]
set cap_max [$net $cap_msg $corner "max"]
report_line " $caption capacitance: [capacitance_range_str $cap_min $cap_max $digits]"
}
proc report_net_pins { pins pin_pred verbose corner digits } {
@ -392,21 +390,17 @@ proc report_net_pin { pin verbose corner digits } {
set pin_cap ""
if { $verbose } {
set port [$pin port]
set cap_r_min [port_ext_wire_cap $port "rise" "min"]
set cap_r_max [port_ext_wire_cap $port "rise" "max"]
set cap_f_min [port_ext_wire_cap $port "fall" "min"]
set cap_f_max [port_ext_wire_cap $port "fall" "max"]
if { $cap_r_min > 0 || $cap_r_max > 0 || $cap_f_min > 0 || $cap_r_max > 0 } {
set wire_cap " wire [capacitances_str $cap_r_min $cap_r_max $cap_f_min $cap_f_max $digits]"
set cap_min [port_ext_wire_cap $port "min"]
set cap_max [port_ext_wire_cap $port "max"]
if { $cap_min > 0 || $cap_max > 0 } {
set wire_cap " wire [capacitance_range_str $cap_min $cap_max $digits]"
}
set port [$pin port]
set cap_r_min [port_ext_pin_cap $port "rise" "min"]
set cap_r_max [port_ext_pin_cap $port "rise" "max"]
set cap_f_min [port_ext_pin_cap $port "fall" "min"]
set cap_f_max [port_ext_pin_cap $port "fall" "max"]
if { $cap_r_min > 0 || $cap_r_max > 0 || $cap_f_min > 0 || $cap_r_max > 0} {
set pin_cap " pin [capacitances_str $cap_r_min $cap_r_max $cap_f_min $cap_f_max $digits]"
set cap_r_min [port_ext_pin_cap $port "min"]
set cap_r_max [port_ext_pin_cap $port "max"]
if { $cap_min > 0 || $cap_max > 0} {
set pin_cap " pin [capacitance_range_str $cap_min $cap_max $digits]"
}
}
report_line " [get_full_name $pin] [pin_direction $pin] port$wire_cap$pin_cap[pin_location_str $pin]"
@ -466,17 +460,23 @@ proc pin_direction_desc { pin } {
# Do not preceed this field by a space in the caller.
proc port_capacitance_str { liberty_port corner digits } {
set cap_r_min [$liberty_port capacitance "rise" "min"]
set cap_r_max [$liberty_port capacitance "rise" "max"]
set cap_f_min [$liberty_port capacitance "fall" "min"]
set cap_f_max [$liberty_port capacitance "fall" "max"]
if { $cap_r_min > 0 || $cap_r_max > 0 || $cap_f_min > 0 || $cap_r_max > 0 } {
return " [capacitances_str $cap_r_min $cap_r_max $cap_f_min $cap_f_max $digits]"
set cap_min [$liberty_port capacitance $corner "min"]
set cap_max [$liberty_port capacitance $corner "max"]
if { $cap_min > 0 || $cap_max > 0 } {
return " [capacitance_range_str $cap_min $cap_max $digits]"
} else {
return ""
}
}
proc capacitance_range_str { cap_min cap_max digits } {
if { $cap_min == $cap_max } {
return "[format_capacitance $cap_max $digits]"
} else {
return "[format_capacitance $cap_min $digits]-[format_capacitance $cap_max $digits]"
}
}
proc capacitances_str { cap_r_min cap_r_max cap_f_min cap_f_max digits } {
if { $cap_r_min == $cap_r_max \
&& $cap_f_min == $cap_f_max \

View File

@ -177,30 +177,6 @@ tclListSeq(Tcl_Obj *const source,
return nullptr;
}
template <class TYPE>
vector<TYPE> *
tclListStdSeq(Tcl_Obj *const source,
swig_type_info *swig_type,
Tcl_Interp *interp)
{
int argc;
Tcl_Obj **argv;
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK
&& argc > 0) {
vector<TYPE> *seq = new vector<TYPE>;
for (int i = 0; i < argc; i++) {
void *obj;
// Ignore returned TCL_ERROR because can't get swig_type_info.
SWIG_ConvertPtr(argv[i], &obj, swig_type, false);
seq->push_back(reinterpret_cast<TYPE>(obj));
}
return seq;
}
else
return nullptr;
}
LibertyLibrarySeq *
tclListSeqLibertyLibrary(Tcl_Obj *const source,
Tcl_Interp *interp)
@ -212,7 +188,7 @@ vector<LibertyCell*> *
tclListSeqLibertyCell(Tcl_Obj *const source,
Tcl_Interp *interp)
{
return tclListStdSeq<LibertyCell*>(source, SWIGTYPE_p_LibertyCell, interp);
return tclListSeq<LibertyCell*>(source, SWIGTYPE_p_LibertyCell, interp);
}
template <class TYPE>
@ -2853,11 +2829,13 @@ set_instance_pvt(Instance *inst,
float
port_ext_pin_cap(Port *port,
const RiseFall *rf,
const MinMax *min_max)
{
cmdLinkedNetwork();
return Sta::sta()->portExtPinCap(port, rf, min_max);
float pin_cap, wire_cap;
int fanout;
Sta::sta()->portExtCaps(port, min_max, pin_cap, wire_cap, fanout);
return pin_cap;
}
void
@ -2871,11 +2849,13 @@ set_port_pin_cap(Port *port,
float
port_ext_wire_cap(Port *port,
const RiseFall *rf,
const MinMax *min_max)
const MinMax *min_max)
{
cmdLinkedNetwork();
return Sta::sta()->portExtWireCap(port, rf, min_max);
float pin_cap, wire_cap;
int fanout;
Sta::sta()->portExtCaps(port, min_max, pin_cap, wire_cap, fanout);
return wire_cap;
}
void
@ -2888,14 +2868,6 @@ set_port_wire_cap(Port *port,
Sta::sta()->setPortExtWireCap(port, subtract_pin_cap, rf, min_max, cap);
}
int
port_ext_fanout(Port *port,
const MinMax *min_max)
{
cmdLinkedNetwork();
return Sta::sta()->portExtFanout(port, min_max);
}
void
set_port_ext_fanout_cmd(Port *port,
int fanout,
@ -2904,6 +2876,17 @@ set_port_ext_fanout_cmd(Port *port,
Sta::sta()->setPortExtFanout(port, fanout, min_max);
}
float
port_ext_fanout(Port *port,
const MinMax *min_max)
{
cmdLinkedNetwork();
float pin_cap, wire_cap;
int fanout;
Sta::sta()->portExtCaps(port, min_max, pin_cap, wire_cap, fanout);
return fanout;
}
void
set_net_wire_cap(Net *net,
bool subtract_pin_cap,
@ -5582,12 +5565,11 @@ tristate_enable()
}
float
capacitance(const RiseFall *rf,
capacitance(Corner *corner,
const MinMax *min_max)
{
Sta *sta = Sta::sta();
OperatingConditions *op_cond = sta->operatingConditions(min_max);
return self->capacitance(rf, min_max, op_cond, op_cond);
return sta->capacitance(self, corner, min_max);
}
} // LibertyPort methods
@ -5780,35 +5762,32 @@ bool is_power() { return cmdLinkedNetwork()->isPower(self);}
bool is_ground() { return cmdLinkedNetwork()->isGround(self);}
float
capacitance(const RiseFall *rf,
const Corner *corner,
capacitance(Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
float pin_cap, wire_cap;
Sta::sta()->connectedCap(self, rf, corner, min_max, pin_cap, wire_cap);
Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap);
return pin_cap + wire_cap;
}
float
pin_capacitance(const RiseFall *rf,
const Corner *corner,
pin_capacitance(Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
float pin_cap, wire_cap;
Sta::sta()->connectedCap(self, rf, corner, min_max, pin_cap, wire_cap);
Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap);
return pin_cap;
}
float
wire_capacitance(const RiseFall *rf,
const Corner *corner,
wire_capacitance(Corner *corner,
const MinMax *min_max)
{
cmdLinkedNetwork();
float pin_cap, wire_cap;
Sta::sta()->connectedCap(self, rf, corner, min_max, pin_cap, wire_cap);
Sta::sta()->connectedCap(self, corner, min_max, pin_cap, wire_cap);
return wire_cap;
}

View File

@ -105,6 +105,16 @@ MinMax::compare(float value1,
return compare_(value1, value2);
}
float
MinMax::minMax(float value1,
float value2) const
{
if (compare_(value1, value2))
return value1;
else
return value2;
}
////////////////////////////////////////////////////////////////
MinMaxAll MinMaxAll::min_("min", 0, {MinMax::min()}, {MinMax::min()->index()});