LibertyCell::higherDrive(), slowerDrive()
This commit is contained in:
parent
cfaef559e6
commit
6a194ef6ee
|
|
@ -626,7 +626,7 @@ add_flex_bison_dependency(SdfLex SdfParser)
|
||||||
include(FindSWIG)
|
include(FindSWIG)
|
||||||
|
|
||||||
add_custom_command(OUTPUT ${STA_HOME}/app/StaApp_wrap.cc
|
add_custom_command(OUTPUT ${STA_HOME}/app/StaApp_wrap.cc
|
||||||
COMMAND ${SWIG_EXECUTABLE} -tcl8 -c++ -namespace -prefix sta -o ${STA_HOME}/app/StaApp_wrap.cc ${STA_HOME}/app/StaApp.i
|
COMMAND ${SWIG_EXECUTABLE} -tcl8 -c++ -namespace -prefix sta -I${STA_HOME}/tcl -I${STA_HOME}/sdf -I${STA_HOME}/dcalc -I${STA_HOME}/parasitics -I${STA_HOME}/verilog -o ${STA_HOME}/app/StaApp_wrap.cc ${STA_HOME}/app/StaApp.i
|
||||||
COMMAND ${STA_HOME}/etc/SwigCleanup.tcl ${STA_HOME}/app/StaApp_wrap.cc
|
COMMAND ${STA_HOME}/etc/SwigCleanup.tcl ${STA_HOME}/app/StaApp_wrap.cc
|
||||||
WORKING_DIRECTORY ${STA_HOME}
|
WORKING_DIRECTORY ${STA_HOME}
|
||||||
DEPENDS ${STA_SWIG_FILES}
|
DEPENDS ${STA_SWIG_FILES}
|
||||||
|
|
|
||||||
14
app/StaApp.i
14
app/StaApp.i
|
|
@ -16,10 +16,10 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
%include "../tcl/StaException.i"
|
%include "StaException.i"
|
||||||
%include "../tcl/StaTcl.i"
|
%include "StaTcl.i"
|
||||||
%include "../verilog/Verilog.i"
|
%include "Verilog.i"
|
||||||
%include "../tcl/NetworkEdit.i"
|
%include "NetworkEdit.i"
|
||||||
%include "../sdf/Sdf.i"
|
%include "Sdf.i"
|
||||||
%include "../dcalc/DelayCalc.i"
|
%include "DelayCalc.i"
|
||||||
%include "../parasitics/Parasitics.i"
|
%include "Parasitics.i"
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include "Machine.hh"
|
#include "Machine.hh"
|
||||||
|
#include "UnorderedMap.hh"
|
||||||
#include "PortDirection.hh"
|
#include "PortDirection.hh"
|
||||||
#include "Transition.hh"
|
#include "Transition.hh"
|
||||||
#include "MinMax.hh"
|
#include "MinMax.hh"
|
||||||
|
|
@ -28,14 +29,16 @@
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
typedef Map<unsigned,LibertyCellSeq*, std::less<unsigned> > LibertyCellHashMap;
|
typedef UnorderedMap<unsigned, LibertyCellSeq*> LibertyCellHashMap;
|
||||||
typedef Set<LibertyCellSeq*> LibertyCellSeqSet;
|
typedef Set<LibertyCellSeq*> LibertyCellSeqSet;
|
||||||
|
|
||||||
static LibertyCellEquivMap *
|
static LibertyCellEquivMap *
|
||||||
findEquivCells1(const LibertyLibrary *library);
|
findEquivCells1(const LibertyLibrary *library);
|
||||||
static void
|
static void
|
||||||
|
deleteEquivCellMap(LibertyCellEquivMap *equiv_map);
|
||||||
|
static void
|
||||||
sortCellEquivs(LibertyCellEquivMap *cell_equivs);
|
sortCellEquivs(LibertyCellEquivMap *cell_equivs);
|
||||||
float
|
static float
|
||||||
cellDriveResistance(const LibertyCell *cell);
|
cellDriveResistance(const LibertyCell *cell);
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
|
|
@ -55,15 +58,19 @@ static bool
|
||||||
equivCellSequentials(const LibertyCell *cell1,
|
equivCellSequentials(const LibertyCell *cell1,
|
||||||
const LibertyCell *cell2);
|
const LibertyCell *cell2);
|
||||||
|
|
||||||
LibertyCellEquivMap *
|
void
|
||||||
makeEquivCellMap(const LibertyLibrary *library)
|
findEquivCells(const LibertyLibrary *library)
|
||||||
{
|
{
|
||||||
|
// Build a map from each cell in the library to a group (CellSeq) of
|
||||||
|
// cells with equivalent functionality.
|
||||||
LibertyCellEquivMap *cell_equivs = findEquivCells1(library);
|
LibertyCellEquivMap *cell_equivs = findEquivCells1(library);
|
||||||
|
// Sort by drive strength.
|
||||||
sortCellEquivs(cell_equivs);
|
sortCellEquivs(cell_equivs);
|
||||||
return cell_equivs;
|
deleteEquivCellMap(cell_equivs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
// Delete the LibertyCellEquivMap returned by makeEquivCellMap.
|
||||||
|
static void
|
||||||
deleteEquivCellMap(LibertyCellEquivMap *equiv_map)
|
deleteEquivCellMap(LibertyCellEquivMap *equiv_map)
|
||||||
{
|
{
|
||||||
// Multiple cells can point to the same cell sequence, so collect
|
// Multiple cells can point to the same cell sequence, so collect
|
||||||
|
|
@ -147,14 +154,21 @@ sortCellEquivs(LibertyCellEquivMap *cell_equivs)
|
||||||
while (equivs_iter.hasNext()) {
|
while (equivs_iter.hasNext()) {
|
||||||
LibertyCellSeq *equivs = equivs_iter.next();
|
LibertyCellSeq *equivs = equivs_iter.next();
|
||||||
sort(equivs, CellDriveResistanceLess());
|
sort(equivs, CellDriveResistanceLess());
|
||||||
|
LibertyCell *lower = nullptr;
|
||||||
|
LibertyCellSeq::Iterator cell_iter(equivs);
|
||||||
|
while (cell_iter.hasNext()) {
|
||||||
|
LibertyCell *cell = cell_iter.next();
|
||||||
|
if (lower) {
|
||||||
|
lower->setHigherDrive(cell);
|
||||||
|
cell->setLowerDrive(lower);
|
||||||
|
}
|
||||||
|
lower = cell;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the worst "drive" for all the timing arcs in the cell.
|
// Use the worst "drive" for all the timing arcs in the cell.
|
||||||
// Note that this function can NOT be static for sun's compiler to
|
static float
|
||||||
// be happy with using it in a sort predicate (presumably because the
|
|
||||||
// template functions are compiled outside the scope of this file).
|
|
||||||
float
|
|
||||||
cellDriveResistance(const LibertyCell *cell)
|
cellDriveResistance(const LibertyCell *cell)
|
||||||
{
|
{
|
||||||
float max_drive = 0.0;
|
float max_drive = 0.0;
|
||||||
|
|
|
||||||
|
|
@ -22,14 +22,10 @@
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
// Build a map from each cell in the library to a group (CellSeq) of
|
// Find equivalent cells, sort by drive strength and
|
||||||
// cells with equivalent functionality, sorted by drive strength.
|
// and set cell->higherDrive/lowerDrive.
|
||||||
LibertyCellEquivMap *
|
|
||||||
makeEquivCellMap(const LibertyLibrary *library);
|
|
||||||
|
|
||||||
// Delete the LibertyCellEquivMap returned by makeEquivCellMap.
|
|
||||||
void
|
void
|
||||||
deleteEquivCellMap(LibertyCellEquivMap *equiv_map);
|
findEquivCells(const LibertyLibrary *library);
|
||||||
|
|
||||||
// Predicate that is true when the ports, functions, sequentials and
|
// Predicate that is true when the ports, functions, sequentials and
|
||||||
// timing arcs match.
|
// timing arcs match.
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,6 @@ LibertyLibrary::LibertyLibrary(const char *name,
|
||||||
default_wire_load_mode_(WireloadMode::unknown),
|
default_wire_load_mode_(WireloadMode::unknown),
|
||||||
default_wire_load_selection_(nullptr),
|
default_wire_load_selection_(nullptr),
|
||||||
default_operating_conditions_(nullptr),
|
default_operating_conditions_(nullptr),
|
||||||
equiv_cell_map_(nullptr),
|
|
||||||
ocv_arc_depth_(0.0),
|
ocv_arc_depth_(0.0),
|
||||||
default_ocv_derate_(nullptr)
|
default_ocv_derate_(nullptr)
|
||||||
{
|
{
|
||||||
|
|
@ -123,8 +122,6 @@ LibertyLibrary::~LibertyLibrary()
|
||||||
operating_conditions_.deleteContents();
|
operating_conditions_.deleteContents();
|
||||||
wireloads_.deleteContents();
|
wireloads_.deleteContents();
|
||||||
wire_load_selections_.deleteContents();
|
wire_load_selections_.deleteContents();
|
||||||
if (equiv_cell_map_)
|
|
||||||
deleteEquivCellMap(equiv_cell_map_);
|
|
||||||
delete units_;
|
delete units_;
|
||||||
ocv_derate_map_.deleteContents();
|
ocv_derate_map_.deleteContents();
|
||||||
|
|
||||||
|
|
@ -500,15 +497,6 @@ LibertyLibrary::setDefaultOutputPinRes(const TransRiseFall *tr,
|
||||||
default_output_pin_res_.setValue(tr, value);
|
default_output_pin_res_.setValue(tr, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
LibertyCellSeq *
|
|
||||||
LibertyLibrary::findEquivCells(LibertyCell *cell)
|
|
||||||
{
|
|
||||||
if (equiv_cell_map_ == nullptr)
|
|
||||||
equiv_cell_map_ = makeEquivCellMap(this);
|
|
||||||
LibertyCellSeq *equivs = equiv_cell_map_->findKey(cell);
|
|
||||||
return equivs;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LibertyLibrary::addWireload(Wireload *wireload)
|
LibertyLibrary::addWireload(Wireload *wireload)
|
||||||
{
|
{
|
||||||
|
|
@ -748,6 +736,12 @@ LibertyLibrary::makeCornerMap(LibertyCell *cell1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LibertyLibrary::finish()
|
||||||
|
{
|
||||||
|
findEquivCells(this);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
float
|
float
|
||||||
|
|
@ -849,7 +843,9 @@ LibertyCell::LibertyCell(LibertyLibrary *library,
|
||||||
ocv_derate_(nullptr),
|
ocv_derate_(nullptr),
|
||||||
is_disabled_constraint_(false),
|
is_disabled_constraint_(false),
|
||||||
leakage_power_(0.0),
|
leakage_power_(0.0),
|
||||||
leakage_power_exists_(false)
|
leakage_power_exists_(false),
|
||||||
|
higher_drive_(nullptr),
|
||||||
|
lower_drive_(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1388,6 +1384,20 @@ LibertyCell::setCornerCell(LibertyCell *corner_cell,
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void
|
||||||
|
LibertyCell::setHigherDrive(LibertyCell *cell)
|
||||||
|
{
|
||||||
|
higher_drive_ = cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LibertyCell::setLowerDrive(LibertyCell *cell)
|
||||||
|
{
|
||||||
|
lower_drive_ = cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
float
|
float
|
||||||
LibertyCell::ocvArcDepth() const
|
LibertyCell::ocvArcDepth() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,6 @@ public:
|
||||||
float slewDerateFromLibrary() const;
|
float slewDerateFromLibrary() const;
|
||||||
void setSlewDerateFromLibrary(float derate);
|
void setSlewDerateFromLibrary(float derate);
|
||||||
|
|
||||||
LibertyCellSeq *findEquivCells(LibertyCell *cell);
|
|
||||||
Units *units() { return units_; }
|
Units *units() { return units_; }
|
||||||
const Units *units() const { return units_; }
|
const Units *units() const { return units_; }
|
||||||
|
|
||||||
|
|
@ -279,6 +278,7 @@ public:
|
||||||
bool link,
|
bool link,
|
||||||
int ap_index,
|
int ap_index,
|
||||||
Report *report);
|
Report *report);
|
||||||
|
void finish();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float degradeWireSlew(const LibertyCell *cell,
|
float degradeWireSlew(const LibertyCell *cell,
|
||||||
|
|
@ -322,7 +322,6 @@ protected:
|
||||||
WireloadSelectionMap wire_load_selections_;
|
WireloadSelectionMap wire_load_selections_;
|
||||||
OperatingConditionsMap operating_conditions_;
|
OperatingConditionsMap operating_conditions_;
|
||||||
OperatingConditions *default_operating_conditions_;
|
OperatingConditions *default_operating_conditions_;
|
||||||
LibertyCellEquivMap *equiv_cell_map_;
|
|
||||||
float ocv_arc_depth_;
|
float ocv_arc_depth_;
|
||||||
OcvDerate *default_ocv_derate_;
|
OcvDerate *default_ocv_derate_;
|
||||||
OcvDerateMap ocv_derate_map_;
|
OcvDerateMap ocv_derate_map_;
|
||||||
|
|
@ -391,9 +390,6 @@ public:
|
||||||
void setScaleFactors(ScaleFactors *scale_factors);
|
void setScaleFactors(ScaleFactors *scale_factors);
|
||||||
ModeDef *makeModeDef(const char *name);
|
ModeDef *makeModeDef(const char *name);
|
||||||
ModeDef *findModeDef(const char *name);
|
ModeDef *findModeDef(const char *name);
|
||||||
// Add scaled cell after it is complete.
|
|
||||||
void addScaledCell(OperatingConditions *op_cond,
|
|
||||||
LibertyCell *scaled_cell);
|
|
||||||
|
|
||||||
float area() const { return area_; }
|
float area() const { return area_; }
|
||||||
void setArea(float area);
|
void setArea(float area);
|
||||||
|
|
@ -410,15 +406,6 @@ public:
|
||||||
bool isClockGateOther() const;
|
bool isClockGateOther() const;
|
||||||
bool isClockGate() const;
|
bool isClockGate() const;
|
||||||
void setClockGateType(ClockGateType type);
|
void setClockGateType(ClockGateType type);
|
||||||
virtual unsigned addTimingArcSet(TimingArcSet *set);
|
|
||||||
void addTimingArcAttrs(TimingArcAttrs *attrs);
|
|
||||||
virtual void addInternalPower(InternalPower *power);
|
|
||||||
void addInternalPowerAttrs(InternalPowerAttrs *attrs);
|
|
||||||
virtual void addLeakagePower(LeakagePower *power);
|
|
||||||
// Call after cell is finished being constructed.
|
|
||||||
virtual void finish(bool infer_latches,
|
|
||||||
Report *report,
|
|
||||||
Debug *debug);
|
|
||||||
// Internal to LibertyCellTimingArcSetIterator.
|
// Internal to LibertyCellTimingArcSetIterator.
|
||||||
TimingArcSetSeq *timingArcSets(const LibertyPort *from,
|
TimingArcSetSeq *timingArcSets(const LibertyPort *from,
|
||||||
const LibertyPort *to) const;
|
const LibertyPort *to) const;
|
||||||
|
|
@ -427,13 +414,44 @@ public:
|
||||||
TimingArcSet *findTimingArcSet(TimingArcSet *key) const;
|
TimingArcSet *findTimingArcSet(TimingArcSet *key) const;
|
||||||
TimingArcSet *findTimingArcSet(unsigned arc_set_index) const;
|
TimingArcSet *findTimingArcSet(unsigned arc_set_index) const;
|
||||||
bool hasTimingArcs(LibertyPort *port) const;
|
bool hasTimingArcs(LibertyPort *port) const;
|
||||||
|
|
||||||
InternalPowerSeq *internalPowers() { return &internal_powers_; }
|
InternalPowerSeq *internalPowers() { return &internal_powers_; }
|
||||||
LeakagePowerSeq *leakagePowers() { return &leakage_powers_; }
|
LeakagePowerSeq *leakagePowers() { return &leakage_powers_; }
|
||||||
void leakagePower(// Return values.
|
void leakagePower(// Return values.
|
||||||
float &leakage,
|
float &leakage,
|
||||||
bool &exists) const;
|
bool &exists) const;
|
||||||
bool leakagePowerEx() const { return leakage_power_exists_; }
|
bool leakagePowerEx() const { return leakage_power_exists_; }
|
||||||
|
|
||||||
bool hasSequentials() const;
|
bool hasSequentials() const;
|
||||||
|
// Find the sequential with the output connected to an (internal) port.
|
||||||
|
Sequential *outputPortSequential(LibertyPort *port);
|
||||||
|
|
||||||
|
// Find bus declaration local to this cell.
|
||||||
|
BusDcl *findBusDcl(const char *name) const;
|
||||||
|
// True when TimingArcSetBuilder::makeRegLatchArcs infers register
|
||||||
|
// timing arcs.
|
||||||
|
bool hasInferedRegTimingArcs() const { return has_infered_reg_timing_arcs_; }
|
||||||
|
TestCell *testCell() const { return test_cell_; }
|
||||||
|
bool isLatchData(LibertyPort *port);
|
||||||
|
void latchEnable(TimingArcSet *arc_set,
|
||||||
|
// Return values.
|
||||||
|
LibertyPort *&enable_port,
|
||||||
|
FuncExpr *&enable_func,
|
||||||
|
TransRiseFall *&enable_tr) const;
|
||||||
|
TransRiseFall *latchCheckEnableTrans(TimingArcSet *check_set);
|
||||||
|
bool isDisabledConstraint() const { return is_disabled_constraint_; }
|
||||||
|
LibertyCell *cornerCell(int ap_index);
|
||||||
|
|
||||||
|
// AOCV
|
||||||
|
float ocvArcDepth() const;
|
||||||
|
OcvDerate *ocvDerate() const;
|
||||||
|
OcvDerate *findOcvDerate(const char *derate_name);
|
||||||
|
|
||||||
|
// Next higher/lower drive equivalent cells.
|
||||||
|
LibertyCell *higherDrive() const { return higher_drive_; }
|
||||||
|
LibertyCell *lowerDrive() const { return lower_drive_; }
|
||||||
|
|
||||||
|
// Build helpers.
|
||||||
void makeSequential(int size,
|
void makeSequential(int size,
|
||||||
bool is_register,
|
bool is_register,
|
||||||
FuncExpr *clk,
|
FuncExpr *clk,
|
||||||
|
|
@ -444,40 +462,31 @@ public:
|
||||||
LogicValue clr_preset_out_inv,
|
LogicValue clr_preset_out_inv,
|
||||||
LibertyPort *output,
|
LibertyPort *output,
|
||||||
LibertyPort *output_inv);
|
LibertyPort *output_inv);
|
||||||
// Find the sequential with the output connected to an (internal) port.
|
|
||||||
Sequential *outputPortSequential(LibertyPort *port);
|
|
||||||
// Find bus declaration local to this cell.
|
|
||||||
BusDcl *findBusDcl(const char *name) const;
|
|
||||||
void addBusDcl(BusDcl *bus_dcl);
|
void addBusDcl(BusDcl *bus_dcl);
|
||||||
// True when TimingArcSetBuilder::makeRegLatchArcs infers register
|
// Add scaled cell after it is complete.
|
||||||
// timing arcs.
|
void addScaledCell(OperatingConditions *op_cond,
|
||||||
bool hasInferedRegTimingArcs() const { return has_infered_reg_timing_arcs_; }
|
LibertyCell *scaled_cell);
|
||||||
void setHasInferedRegTimingArcs(bool infered);
|
virtual unsigned addTimingArcSet(TimingArcSet *set);
|
||||||
TestCell *testCell() const { return test_cell_; }
|
void addTimingArcAttrs(TimingArcAttrs *attrs);
|
||||||
|
virtual void addInternalPower(InternalPower *power);
|
||||||
|
void addInternalPowerAttrs(InternalPowerAttrs *attrs);
|
||||||
|
virtual void addLeakagePower(LeakagePower *power);
|
||||||
|
void setLeakagePower(float leakage);
|
||||||
|
void setOcvArcDepth(float depth);
|
||||||
|
void setOcvDerate(OcvDerate *derate);
|
||||||
|
void addOcvDerate(OcvDerate *derate);
|
||||||
|
void addPgPort(LibertyPgPort *pg_port);
|
||||||
void setTestCell(TestCell *test);
|
void setTestCell(TestCell *test);
|
||||||
bool isLatchData(LibertyPort *port);
|
void setHasInferedRegTimingArcs(bool infered);
|
||||||
void latchEnable(TimingArcSet *arc_set,
|
|
||||||
// Return values.
|
|
||||||
LibertyPort *&enable_port,
|
|
||||||
FuncExpr *&enable_func,
|
|
||||||
TransRiseFall *&enable_tr) const;
|
|
||||||
TransRiseFall *latchCheckEnableTrans(TimingArcSet *check_set);
|
|
||||||
bool isDisabledConstraint() const { return is_disabled_constraint_; }
|
|
||||||
void setIsDisabledConstraint(bool is_disabled);
|
void setIsDisabledConstraint(bool is_disabled);
|
||||||
LibertyCell *cornerCell(int ap_index);
|
|
||||||
void setCornerCell(LibertyCell *corner_cell,
|
void setCornerCell(LibertyCell *corner_cell,
|
||||||
int ap_index);
|
int ap_index);
|
||||||
void setLeakagePower(float leakage);
|
// Call after cell is finished being constructed.
|
||||||
|
virtual void finish(bool infer_latches,
|
||||||
// AOCV
|
Report *report,
|
||||||
float ocvArcDepth() const;
|
Debug *debug);
|
||||||
void setOcvArcDepth(float depth);
|
void setHigherDrive(LibertyCell *cell);
|
||||||
OcvDerate *ocvDerate() const;
|
void setLowerDrive(LibertyCell *cell);
|
||||||
void setOcvDerate(OcvDerate *derate);
|
|
||||||
OcvDerate *findOcvDerate(const char *derate_name);
|
|
||||||
void addOcvDerate(OcvDerate *derate);
|
|
||||||
|
|
||||||
void addPgPort(LibertyPgPort *pg_port);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void addPort(ConcretePort *port);
|
virtual void addPort(ConcretePort *port);
|
||||||
|
|
@ -511,7 +520,6 @@ protected:
|
||||||
bool interface_timing_;
|
bool interface_timing_;
|
||||||
ClockGateType clock_gate_type_;
|
ClockGateType clock_gate_type_;
|
||||||
TimingArcSetSeq timing_arc_sets_;
|
TimingArcSetSeq timing_arc_sets_;
|
||||||
// Used to find matching arc sets in equivalent cells.
|
|
||||||
TimingArcSetMap timing_arc_set_map_;
|
TimingArcSetMap timing_arc_set_map_;
|
||||||
LibertyPortPairTimingArcMap port_timing_arc_set_map_;
|
LibertyPortPairTimingArcMap port_timing_arc_set_map_;
|
||||||
LibertyPortTimingArcMap timing_arc_set_from_map_;
|
LibertyPortTimingArcMap timing_arc_set_from_map_;
|
||||||
|
|
@ -542,6 +550,9 @@ protected:
|
||||||
float leakage_power_;
|
float leakage_power_;
|
||||||
bool leakage_power_exists_;
|
bool leakage_power_exists_;
|
||||||
LibertyPgPortMap pg_port_map_;
|
LibertyPgPortMap pg_port_map_;
|
||||||
|
// Next higher/lower drive equivalent cells.
|
||||||
|
LibertyCell *higher_drive_;
|
||||||
|
LibertyCell *lower_drive_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(LibertyCell);
|
DISALLOW_COPY_AND_ASSIGN(LibertyCell);
|
||||||
|
|
|
||||||
|
|
@ -578,6 +578,7 @@ void
|
||||||
LibertyReader::endLibrary(LibertyGroup *group)
|
LibertyReader::endLibrary(LibertyGroup *group)
|
||||||
{
|
{
|
||||||
endLibraryAttrs(group);
|
endLibraryAttrs(group);
|
||||||
|
library_->finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -509,6 +509,10 @@ getProperty(const LibertyCell *cell,
|
||||||
return PropertyValue(cell->filename());
|
return PropertyValue(cell->filename());
|
||||||
else if (stringEqual(property, "library"))
|
else if (stringEqual(property, "library"))
|
||||||
return PropertyValue(cell->libertyLibrary());
|
return PropertyValue(cell->libertyLibrary());
|
||||||
|
else if (stringEqual(property, "higher_drive"))
|
||||||
|
return PropertyValue(cell->higherDrive());
|
||||||
|
else if (stringEqual(property, "lower_drive"))
|
||||||
|
return PropertyValue(cell->lowerDrive());
|
||||||
else
|
else
|
||||||
throw PropertyUnknown("liberty cell", property);
|
throw PropertyUnknown("liberty cell", property);
|
||||||
}
|
}
|
||||||
|
|
@ -706,7 +710,7 @@ pinSlewProperty(const Pin *pin,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
Sta *sta)
|
Sta *sta)
|
||||||
{
|
{
|
||||||
auto graph = sta->graph();
|
auto graph = sta->ensureGraph();
|
||||||
Vertex *vertex, *bidirect_drvr_vertex;
|
Vertex *vertex, *bidirect_drvr_vertex;
|
||||||
graph->pinVertices(pin, vertex, bidirect_drvr_vertex);
|
graph->pinVertices(pin, vertex, bidirect_drvr_vertex);
|
||||||
Slew slew = min_max->initValue();
|
Slew slew = min_max->initValue();
|
||||||
|
|
|
||||||
|
|
@ -3214,7 +3214,7 @@ Sta::setArcDelay(Edge *edge,
|
||||||
TimingArc *arc,
|
TimingArc *arc,
|
||||||
const Corner *corner,
|
const Corner *corner,
|
||||||
const MinMaxAll *min_max,
|
const MinMaxAll *min_max,
|
||||||
float delay)
|
ArcDelay delay)
|
||||||
{
|
{
|
||||||
MinMaxIterator mm_iter(min_max);
|
MinMaxIterator mm_iter(min_max);
|
||||||
while (mm_iter.hasNext()) {
|
while (mm_iter.hasNext()) {
|
||||||
|
|
|
||||||
|
|
@ -705,7 +705,7 @@ public:
|
||||||
TimingArc *arc,
|
TimingArc *arc,
|
||||||
const Corner *corner,
|
const Corner *corner,
|
||||||
const MinMaxAll *min_max,
|
const MinMaxAll *min_max,
|
||||||
float delay);
|
ArcDelay delay);
|
||||||
// Set annotated slew on a vertex for delay calculation.
|
// Set annotated slew on a vertex for delay calculation.
|
||||||
void setAnnotatedSlew(Vertex *vertex,
|
void setAnnotatedSlew(Vertex *vertex,
|
||||||
const Corner *corner,
|
const Corner *corner,
|
||||||
|
|
|
||||||
10
tcl/StaTcl.i
10
tcl/StaTcl.i
|
|
@ -2275,13 +2275,6 @@ cells_equiv_ports(LibertyCell *cell1,
|
||||||
return equivCellPorts(cell1, cell2);
|
return equivCellPorts(cell1, cell2);
|
||||||
}
|
}
|
||||||
|
|
||||||
LibertyCellSeq *
|
|
||||||
find_equiv_cells(LibertyCell *cell)
|
|
||||||
{
|
|
||||||
LibertyLibrary *library = cell->libertyLibrary();
|
|
||||||
return library->findEquivCells(cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
set_cmd_namespace_cmd(const char *namespc)
|
set_cmd_namespace_cmd(const char *namespc)
|
||||||
{
|
{
|
||||||
|
|
@ -2652,6 +2645,7 @@ PropertyValue
|
||||||
pin_property(const Pin *pin,
|
pin_property(const Pin *pin,
|
||||||
const char *property)
|
const char *property)
|
||||||
{
|
{
|
||||||
|
cmdLinkedNetwork();
|
||||||
return getProperty(pin, property, Sta::sta());
|
return getProperty(pin, property, Sta::sta());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2659,6 +2653,7 @@ PropertyValue
|
||||||
instance_property(const Instance *inst,
|
instance_property(const Instance *inst,
|
||||||
const char *property)
|
const char *property)
|
||||||
{
|
{
|
||||||
|
cmdLinkedNetwork();
|
||||||
return getProperty(inst, property, Sta::sta());
|
return getProperty(inst, property, Sta::sta());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2666,6 +2661,7 @@ PropertyValue
|
||||||
net_property(const Net *net,
|
net_property(const Net *net,
|
||||||
const char *property)
|
const char *property)
|
||||||
{
|
{
|
||||||
|
cmdLinkedNetwork();
|
||||||
return getProperty(net, property, Sta::sta());
|
return getProperty(net, property, Sta::sta());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue