resizer support
This commit is contained in:
parent
8242035b22
commit
53df9472d7
|
|
@ -56,9 +56,6 @@ message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}")
|
||||||
|
|
||||||
set(STA_SOURCE
|
set(STA_SOURCE
|
||||||
app/StaMain.cc
|
app/StaMain.cc
|
||||||
app/StaApp_wrap.cc
|
|
||||||
app/TclInitVar.cc
|
|
||||||
app/StaApp_wrap.cc
|
|
||||||
|
|
||||||
dcalc/ArcDelayCalc.cc
|
dcalc/ArcDelayCalc.cc
|
||||||
dcalc/ArnoldiDelayCalc.cc
|
dcalc/ArnoldiDelayCalc.cc
|
||||||
|
|
@ -213,6 +210,11 @@ set(STA_SOURCE
|
||||||
verilog/VerilogParse.cc
|
verilog/VerilogParse.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(STA_CMD_SOURCE
|
||||||
|
app/TclInitVar.cc
|
||||||
|
app/StaApp_wrap.cc
|
||||||
|
)
|
||||||
|
|
||||||
set(STA_HEADERS
|
set(STA_HEADERS
|
||||||
app/StaMain.hh
|
app/StaMain.hh
|
||||||
|
|
||||||
|
|
@ -648,7 +650,6 @@ add_custom_command(OUTPUT ${STA_HOME}/app/TclInitVar.cc
|
||||||
set(STA_INCLUDE_DIRS
|
set(STA_INCLUDE_DIRS
|
||||||
app
|
app
|
||||||
dcalc
|
dcalc
|
||||||
dcalc/verilog
|
|
||||||
graph
|
graph
|
||||||
liberty
|
liberty
|
||||||
network
|
network
|
||||||
|
|
@ -663,13 +664,29 @@ set(STA_INCLUDE_DIRS
|
||||||
)
|
)
|
||||||
|
|
||||||
###########################################################
|
###########################################################
|
||||||
# Library
|
# Library without TCL commands.
|
||||||
|
# This is used to build applications that define
|
||||||
|
# their own SWIG and TCL commands.
|
||||||
###########################################################
|
###########################################################
|
||||||
|
|
||||||
# compatibility with configure
|
# compatibility with configure
|
||||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${STA_HOME}/app)
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${STA_HOME}/app)
|
||||||
|
|
||||||
add_library(OpenSTA ${STA_SOURCE})
|
add_library(OpenSTAnoCmds ${STA_SOURCE})
|
||||||
|
|
||||||
|
target_include_directories(OpenSTAnoCmds PUBLIC ${STA_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
target_compile_features(OpenSTAnoCmds
|
||||||
|
PUBLIC cxx_auto_type
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(OpenSTAnoCmds PUBLIC ${STA_COMPILE_OPTIONS})
|
||||||
|
|
||||||
|
###########################################################
|
||||||
|
# Library
|
||||||
|
###########################################################
|
||||||
|
|
||||||
|
add_library(OpenSTA ${STA_SOURCE} ${STA_CMD_SOURCE})
|
||||||
|
|
||||||
target_include_directories(OpenSTA PUBLIC ${STA_INCLUDE_DIRS})
|
target_include_directories(OpenSTA PUBLIC ${STA_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
|
@ -677,6 +694,8 @@ target_compile_features(OpenSTA
|
||||||
PUBLIC cxx_auto_type
|
PUBLIC cxx_auto_type
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_compile_options(OpenSTA PUBLIC ${STA_COMPILE_OPTIONS})
|
||||||
|
|
||||||
###########################################################
|
###########################################################
|
||||||
# Executable
|
# Executable
|
||||||
###########################################################
|
###########################################################
|
||||||
|
|
@ -704,9 +723,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
target_link_libraries(sta -pthread)
|
target_link_libraries(sta -pthread)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_compile_options(OpenSTA PUBLIC ${STA_COMPILE_OPTIONS})
|
|
||||||
target_compile_options(sta PUBLIC ${STA_COMPILE_OPTIONS})
|
target_compile_options(sta PUBLIC ${STA_COMPILE_OPTIONS})
|
||||||
message(STATUS "Compiler options: ${STA_COMPILE_OPTIONS}")
|
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# Install
|
# Install
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,13 @@ GraphDelayCalc::loadCap(const Pin *,
|
||||||
return 0.0F;
|
return 0.0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
GraphDelayCalc::loadCap(const Pin *,
|
||||||
|
const DcalcAnalysisPt *) const
|
||||||
|
{
|
||||||
|
return 0.0F;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GraphDelayCalc::netCaps(const Pin *,
|
GraphDelayCalc::netCaps(const Pin *,
|
||||||
const TransRiseFall *,
|
const TransRiseFall *,
|
||||||
|
|
|
||||||
|
|
@ -79,10 +79,13 @@ public:
|
||||||
// Return values.
|
// Return values.
|
||||||
float &pin_cap,
|
float &pin_cap,
|
||||||
float &wire_cap) const;
|
float &wire_cap) const;
|
||||||
// Load pin_cap + wire_cap.
|
// Load pin_cap + wire_cap including parasitic.
|
||||||
virtual float loadCap(const Pin *drvr_pin,
|
virtual float loadCap(const Pin *drvr_pin,
|
||||||
const TransRiseFall *to_tr,
|
const TransRiseFall *to_tr,
|
||||||
const DcalcAnalysisPt *dcalc_ap) const;
|
const DcalcAnalysisPt *dcalc_ap) const;
|
||||||
|
// Load pin_cap + wire_cap including parasitic min/max for rise/fall.
|
||||||
|
virtual float loadCap(const Pin *drvr_pin,
|
||||||
|
const DcalcAnalysisPt *dcalc_ap) const;
|
||||||
// Load pin_cap + wire_cap.
|
// Load pin_cap + wire_cap.
|
||||||
virtual float loadCap(const Pin *drvr_pin,
|
virtual float loadCap(const Pin *drvr_pin,
|
||||||
Parasitic *drvr_parasitic,
|
Parasitic *drvr_parasitic,
|
||||||
|
|
|
||||||
|
|
@ -1039,6 +1039,24 @@ GraphDelayCalc1::findDriverEdgeDelays(LibertyCell *drvr_cell,
|
||||||
return delay_changed;
|
return delay_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
GraphDelayCalc1::loadCap(const Pin *drvr_pin,
|
||||||
|
const DcalcAnalysisPt *dcalc_ap) const
|
||||||
|
{
|
||||||
|
const MinMax *min_max = dcalc_ap->constraintMinMax();
|
||||||
|
float load_cap = 0.0;
|
||||||
|
TransRiseFallIterator drvr_tr_iter;
|
||||||
|
while (drvr_tr_iter.hasNext()) {
|
||||||
|
TransRiseFall *drvr_tr = drvr_tr_iter.next();
|
||||||
|
Parasitic *drvr_parasitic = arc_delay_calc_->findParasitic(drvr_pin, drvr_tr,
|
||||||
|
dcalc_ap);
|
||||||
|
float cap = loadCap(drvr_pin, nullptr, drvr_parasitic, drvr_tr, dcalc_ap);
|
||||||
|
if (min_max->compare(cap, load_cap))
|
||||||
|
load_cap = cap;
|
||||||
|
}
|
||||||
|
return load_cap;
|
||||||
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
GraphDelayCalc1::loadCap(const Pin *drvr_pin,
|
GraphDelayCalc1::loadCap(const Pin *drvr_pin,
|
||||||
const TransRiseFall *drvr_tr,
|
const TransRiseFall *drvr_tr,
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ public:
|
||||||
virtual float loadCap(const Pin *drvr_pin,
|
virtual float loadCap(const Pin *drvr_pin,
|
||||||
const TransRiseFall *drvr_tr,
|
const TransRiseFall *drvr_tr,
|
||||||
const DcalcAnalysisPt *dcalc_ap) const;
|
const DcalcAnalysisPt *dcalc_ap) const;
|
||||||
|
virtual float loadCap(const Pin *drvr_pin,
|
||||||
|
const DcalcAnalysisPt *dcalc_ap) const;
|
||||||
virtual void loadCap(const Pin *drvr_pin,
|
virtual void loadCap(const Pin *drvr_pin,
|
||||||
Parasitic *drvr_parasitic,
|
Parasitic *drvr_parasitic,
|
||||||
const TransRiseFall *tr,
|
const TransRiseFall *tr,
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,6 @@ 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);
|
||||||
static float
|
static float
|
||||||
cellDriveResistance(const LibertyCell *cell);
|
cellDriveResistance(const LibertyCell *cell);
|
||||||
|
|
@ -58,7 +56,7 @@ static bool
|
||||||
equivCellSequentials(const LibertyCell *cell1,
|
equivCellSequentials(const LibertyCell *cell1,
|
||||||
const LibertyCell *cell2);
|
const LibertyCell *cell2);
|
||||||
|
|
||||||
void
|
LibertyCellEquivMap *
|
||||||
findEquivCells(const LibertyLibrary *library)
|
findEquivCells(const LibertyLibrary *library)
|
||||||
{
|
{
|
||||||
// Build a map from each cell in the library to a group (CellSeq) of
|
// Build a map from each cell in the library to a group (CellSeq) of
|
||||||
|
|
@ -66,11 +64,11 @@ findEquivCells(const LibertyLibrary *library)
|
||||||
LibertyCellEquivMap *cell_equivs = findEquivCells1(library);
|
LibertyCellEquivMap *cell_equivs = findEquivCells1(library);
|
||||||
// Sort by drive strength.
|
// Sort by drive strength.
|
||||||
sortCellEquivs(cell_equivs);
|
sortCellEquivs(cell_equivs);
|
||||||
deleteEquivCellMap(cell_equivs);
|
return cell_equivs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the LibertyCellEquivMap returned by makeEquivCellMap.
|
// Delete the LibertyCellEquivMap returned by makeEquivCellMap.
|
||||||
static void
|
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
|
||||||
|
|
@ -129,12 +127,7 @@ findEquivCells1(const LibertyLibrary *library)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LibertyCellHashMap::Iterator hash_iter(cell_hash);
|
cell_hash.deleteContents();
|
||||||
while (hash_iter.hasNext()) {
|
|
||||||
LibertyCellSeq *cells = hash_iter.next();
|
|
||||||
delete cells;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cell_equivs;
|
return cell_equivs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,11 @@ namespace sta {
|
||||||
|
|
||||||
// Find equivalent cells, sort by drive strength and
|
// Find equivalent cells, sort by drive strength and
|
||||||
// and set cell->higherDrive/lowerDrive.
|
// and set cell->higherDrive/lowerDrive.
|
||||||
void
|
LibertyCellEquivMap *
|
||||||
findEquivCells(const LibertyLibrary *library);
|
findEquivCells(const LibertyLibrary *library);
|
||||||
|
// Delete findEquivCells return value.
|
||||||
|
void
|
||||||
|
deleteEquivCellMap(LibertyCellEquivMap *equiv_map);
|
||||||
|
|
||||||
// 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.
|
||||||
|
|
|
||||||
|
|
@ -83,12 +83,15 @@ LibertyLibrary::LibertyLibrary(const char *name,
|
||||||
default_wire_load_selection_(nullptr),
|
default_wire_load_selection_(nullptr),
|
||||||
default_operating_conditions_(nullptr),
|
default_operating_conditions_(nullptr),
|
||||||
ocv_arc_depth_(0.0),
|
ocv_arc_depth_(0.0),
|
||||||
default_ocv_derate_(nullptr)
|
default_ocv_derate_(nullptr),
|
||||||
|
equiv_cell_map_(nullptr),
|
||||||
|
buffers_(nullptr)
|
||||||
{
|
{
|
||||||
// Scalar templates are builtin.
|
// Scalar templates are builtin.
|
||||||
for (int i = 0; i != int(TableTemplateType::count); i++) {
|
for (int i = 0; i != int(TableTemplateType::count); i++) {
|
||||||
TableTemplateType type = static_cast<TableTemplateType>(i);
|
TableTemplateType type = static_cast<TableTemplateType>(i);
|
||||||
TableTemplate *scalar_template = new TableTemplate("scalar", nullptr, nullptr, nullptr);
|
TableTemplate *scalar_template = new TableTemplate("scalar", nullptr,
|
||||||
|
nullptr, nullptr);
|
||||||
addTableTemplate(scalar_template, type);
|
addTableTemplate(scalar_template, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,6 +132,8 @@ LibertyLibrary::~LibertyLibrary()
|
||||||
const char *supply_name = name_volt.first;
|
const char *supply_name = name_volt.first;
|
||||||
stringDelete(supply_name);
|
stringDelete(supply_name);
|
||||||
}
|
}
|
||||||
|
deleteEquivCellMap(equiv_cell_map_);
|
||||||
|
delete buffers_;
|
||||||
}
|
}
|
||||||
|
|
||||||
LibertyCell *
|
LibertyCell *
|
||||||
|
|
@ -149,6 +154,22 @@ LibertyLibrary::findLibertyCellsMatching(PatternMatch *pattern,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LibertyCellSeq *
|
||||||
|
LibertyLibrary::buffers()
|
||||||
|
{
|
||||||
|
if (buffers_ == nullptr) {
|
||||||
|
buffers_ = new LibertyCellSeq;
|
||||||
|
LibertyCellIterator cell_iter(this);
|
||||||
|
while (cell_iter.hasNext()) {
|
||||||
|
LibertyCell *cell = cell_iter.next();
|
||||||
|
if (!cell->dontUse()
|
||||||
|
&& cell->isBuffer())
|
||||||
|
buffers_->push_back(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffers_;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LibertyLibrary::setDelayModelType(DelayModelType type)
|
LibertyLibrary::setDelayModelType(DelayModelType type)
|
||||||
{
|
{
|
||||||
|
|
@ -737,9 +758,17 @@ LibertyLibrary::makeCornerMap(LibertyCell *cell1,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LibertyLibrary::finish()
|
LibertyLibrary::ensureEquivCells()
|
||||||
{
|
{
|
||||||
findEquivCells(this);
|
if (equiv_cell_map_ == nullptr)
|
||||||
|
equiv_cell_map_ = sta::findEquivCells(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
LibertyCellSeq *
|
||||||
|
LibertyLibrary::findEquivCells(LibertyCell *cell)
|
||||||
|
{
|
||||||
|
ensureEquivCells();
|
||||||
|
return equiv_cell_map_->findKey(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -1022,33 +1051,16 @@ LibertyCell::setClockGateType(ClockGateType type)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
LibertyCell::isBuffer() const
|
LibertyCell::isBuffer() const
|
||||||
{
|
|
||||||
LibertyPort *input, *output;
|
|
||||||
return isBuffer(input, output);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
LibertyCell::isBuffer(// Return values.
|
|
||||||
LibertyPort *&input,
|
|
||||||
LibertyPort *&output) const
|
|
||||||
{
|
{
|
||||||
if (ports_.size() == 2) {
|
if (ports_.size() == 2) {
|
||||||
LibertyPort *port1 = static_cast<LibertyPort*>(ports_[0]);
|
LibertyPort *port1 = static_cast<LibertyPort*>(ports_[0]);
|
||||||
LibertyPort *port2 = static_cast<LibertyPort*>(ports_[1]);
|
LibertyPort *port2 = static_cast<LibertyPort*>(ports_[1]);
|
||||||
if (port1->direction()->isInput()
|
return (port1->direction()->isInput()
|
||||||
&& port2->direction()->isOutput()
|
&& port2->direction()->isOutput()
|
||||||
&& hasBufferFunc(port1, port2)) {
|
&& hasBufferFunc(port1, port2))
|
||||||
input = port1;
|
|| (port2->direction()->isInput()
|
||||||
output = port2;
|
&& port1->direction()->isOutput()
|
||||||
return true;
|
&& hasBufferFunc(port2, port1));
|
||||||
}
|
|
||||||
else if (port2->direction()->isInput()
|
|
||||||
&& port1->direction()->isOutput()
|
|
||||||
&& hasBufferFunc(port2, port1)) {
|
|
||||||
input = port2;
|
|
||||||
output = port1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1063,6 +1075,24 @@ LibertyCell::hasBufferFunc(const LibertyPort *input,
|
||||||
&& func->port() == input;
|
&& func->port() == input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LibertyCell::bufferPorts(// Return values.
|
||||||
|
LibertyPort *&input,
|
||||||
|
LibertyPort *&output)
|
||||||
|
{
|
||||||
|
LibertyPort *port1 = static_cast<LibertyPort*>(ports_[0]);
|
||||||
|
LibertyPort *port2 = static_cast<LibertyPort*>(ports_[1]);
|
||||||
|
if (port1->direction()->isInput()
|
||||||
|
&& port2->direction()->isOutput()) {
|
||||||
|
input = port1;
|
||||||
|
output = port2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
input = port2;
|
||||||
|
output = port1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
LibertyCell::addTimingArcSet(TimingArcSet *arc_set)
|
LibertyCell::addTimingArcSet(TimingArcSet *arc_set)
|
||||||
{
|
{
|
||||||
|
|
@ -1427,6 +1457,20 @@ LibertyCell::setCornerCell(LibertyCell *corner_cell,
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
LibertyCell *
|
||||||
|
LibertyCell::higherDrive() const
|
||||||
|
{
|
||||||
|
liberty_library_->ensureEquivCells();
|
||||||
|
return higher_drive_;
|
||||||
|
}
|
||||||
|
|
||||||
|
LibertyCell *
|
||||||
|
LibertyCell::lowerDrive() const
|
||||||
|
{
|
||||||
|
liberty_library_->ensureEquivCells();
|
||||||
|
return lower_drive_;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LibertyCell::setHigherDrive(LibertyCell *cell)
|
LibertyCell::setHigherDrive(LibertyCell *cell)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,10 @@ public:
|
||||||
LibertyCell *findLibertyCell(const char *name) const;
|
LibertyCell *findLibertyCell(const char *name) const;
|
||||||
void findLibertyCellsMatching(PatternMatch *pattern,
|
void findLibertyCellsMatching(PatternMatch *pattern,
|
||||||
LibertyCellSeq *cells);
|
LibertyCellSeq *cells);
|
||||||
|
LibertyCellSeq *findEquivCells(LibertyCell *cell);
|
||||||
|
// Liberty cells that are buffers.
|
||||||
|
LibertyCellSeq *buffers();
|
||||||
|
|
||||||
DelayModelType delayModelType() const { return delay_model_type_; }
|
DelayModelType delayModelType() const { return delay_model_type_; }
|
||||||
void setDelayModelType(DelayModelType type);
|
void setDelayModelType(DelayModelType type);
|
||||||
void addBusDcl(BusDcl *bus_dcl);
|
void addBusDcl(BusDcl *bus_dcl);
|
||||||
|
|
@ -262,6 +266,7 @@ public:
|
||||||
// Make scaled cell. Call LibertyCell::addScaledCell after it is complete.
|
// Make scaled cell. Call LibertyCell::addScaledCell after it is complete.
|
||||||
LibertyCell *makeScaledCell(const char *name,
|
LibertyCell *makeScaledCell(const char *name,
|
||||||
const char *filename);
|
const char *filename);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
makeCornerMap(LibertyLibrary *lib,
|
makeCornerMap(LibertyLibrary *lib,
|
||||||
int ap_index,
|
int ap_index,
|
||||||
|
|
@ -278,7 +283,6 @@ 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,
|
||||||
|
|
@ -286,6 +290,7 @@ protected:
|
||||||
const TableModel *model,
|
const TableModel *model,
|
||||||
float in_slew,
|
float in_slew,
|
||||||
float wire_delay) const;
|
float wire_delay) const;
|
||||||
|
void ensureEquivCells();
|
||||||
|
|
||||||
Units *units_;
|
Units *units_;
|
||||||
DelayModelType delay_model_type_;
|
DelayModelType delay_model_type_;
|
||||||
|
|
@ -326,6 +331,8 @@ protected:
|
||||||
OcvDerate *default_ocv_derate_;
|
OcvDerate *default_ocv_derate_;
|
||||||
OcvDerateMap ocv_derate_map_;
|
OcvDerateMap ocv_derate_map_;
|
||||||
SupplyVoltageMap supply_voltage_map_;
|
SupplyVoltageMap supply_voltage_map_;
|
||||||
|
LibertyCellEquivMap *equiv_cell_map_;
|
||||||
|
LibertyCellSeq *buffers_;
|
||||||
|
|
||||||
// Set if any library has rise/fall capacitances.
|
// Set if any library has rise/fall capacitances.
|
||||||
static bool found_rise_fall_caps_;
|
static bool found_rise_fall_caps_;
|
||||||
|
|
@ -337,6 +344,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(LibertyLibrary);
|
DISALLOW_COPY_AND_ASSIGN(LibertyLibrary);
|
||||||
|
|
||||||
|
friend class LibertyCell;
|
||||||
friend class LibertyCellIterator;
|
friend class LibertyCellIterator;
|
||||||
friend class TableTemplateIterator;
|
friend class TableTemplateIterator;
|
||||||
friend class OperatingConditionsIterator;
|
friend class OperatingConditionsIterator;
|
||||||
|
|
@ -448,8 +456,8 @@ public:
|
||||||
OcvDerate *findOcvDerate(const char *derate_name);
|
OcvDerate *findOcvDerate(const char *derate_name);
|
||||||
|
|
||||||
// Next higher/lower drive equivalent cells.
|
// Next higher/lower drive equivalent cells.
|
||||||
LibertyCell *higherDrive() const { return higher_drive_; }
|
LibertyCell *higherDrive() const;
|
||||||
LibertyCell *lowerDrive() const { return lower_drive_; }
|
LibertyCell *lowerDrive() const;
|
||||||
|
|
||||||
// Build helpers.
|
// Build helpers.
|
||||||
void makeSequential(int size,
|
void makeSequential(int size,
|
||||||
|
|
@ -488,9 +496,10 @@ public:
|
||||||
void setHigherDrive(LibertyCell *cell);
|
void setHigherDrive(LibertyCell *cell);
|
||||||
void setLowerDrive(LibertyCell *cell);
|
void setLowerDrive(LibertyCell *cell);
|
||||||
bool isBuffer() const;
|
bool isBuffer() const;
|
||||||
bool isBuffer(// Return values.
|
// Only valid when isBuffer() returns true.
|
||||||
LibertyPort *&input,
|
void bufferPorts(// Return values.
|
||||||
LibertyPort *&output) const;
|
LibertyPort *&input,
|
||||||
|
LibertyPort *&output);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void addPort(ConcretePort *port);
|
virtual void addPort(ConcretePort *port);
|
||||||
|
|
|
||||||
|
|
@ -578,7 +578,6 @@ void
|
||||||
LibertyReader::endLibrary(LibertyGroup *group)
|
LibertyReader::endLibrary(LibertyGroup *group)
|
||||||
{
|
{
|
||||||
endLibraryAttrs(group);
|
endLibraryAttrs(group);
|
||||||
library_->finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -500,7 +500,7 @@ Power::power(const Instance *inst,
|
||||||
const Pin *to_pin = pin_iter->next();
|
const Pin *to_pin = pin_iter->next();
|
||||||
const LibertyPort *to_port = network_->libertyPort(to_pin);
|
const LibertyPort *to_port = network_->libertyPort(to_pin);
|
||||||
float load_cap = to_port->direction()->isAnyOutput()
|
float load_cap = to_port->direction()->isAnyOutput()
|
||||||
? graph_delay_calc_->loadCap(to_pin, TransRiseFall::rise(), dcalc_ap)
|
? graph_delay_calc_->loadCap(to_pin, dcalc_ap)
|
||||||
: 0.0;
|
: 0.0;
|
||||||
PwrActivity activity = findClkedActivity(to_pin, inst_clk);
|
PwrActivity activity = findClkedActivity(to_pin, inst_clk);
|
||||||
if (to_port->direction()->isAnyOutput())
|
if (to_port->direction()->isAnyOutput())
|
||||||
|
|
|
||||||
|
|
@ -1907,6 +1907,14 @@ proc get_full_name { object } {
|
||||||
return [get_object_property $object "full_name"]
|
return [get_object_property $object "full_name"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc sort_by_name { objects } {
|
||||||
|
return [lsort -command name_cmp $objects]
|
||||||
|
}
|
||||||
|
|
||||||
|
proc name_cmp { obj1 obj2 } {
|
||||||
|
return [string compare [get_name $obj1] [get_name $obj2]]
|
||||||
|
}
|
||||||
|
|
||||||
proc sort_by_full_name { objects } {
|
proc sort_by_full_name { objects } {
|
||||||
return [lsort -command full_name_cmp $objects]
|
return [lsort -command full_name_cmp $objects]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -225,8 +225,8 @@ proc replace_cell { instances lib_cell } {
|
||||||
set insts [get_instances_error "instances" $instances]
|
set insts [get_instances_error "instances" $instances]
|
||||||
foreach inst $insts {
|
foreach inst $insts {
|
||||||
set inst_cell [$inst liberty_cell]
|
set inst_cell [$inst liberty_cell]
|
||||||
if { $inst_cell != "NULL" \
|
if { $inst_cell == "NULL" \
|
||||||
&& ![cells_equiv_ports $inst_cell $cell] } {
|
|| ![equiv_cell_ports $inst_cell $cell] } {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -956,7 +956,7 @@ proc_redirect report_clock_properties {
|
||||||
define_sta_cmd_args "report_object_full_names" {[-verbose] objects}
|
define_sta_cmd_args "report_object_full_names" {[-verbose] objects}
|
||||||
|
|
||||||
proc report_object_full_names { args } {
|
proc report_object_full_names { args } {
|
||||||
parse_key_args "report_object_names" args keys {} flags {-verbose}
|
parse_key_args "report_object_full_names" args keys {} flags {-verbose}
|
||||||
|
|
||||||
set objects [lindex $args 0]
|
set objects [lindex $args 0]
|
||||||
if { [info exists flags(-verbose)] } {
|
if { [info exists flags(-verbose)] } {
|
||||||
|
|
@ -986,7 +986,7 @@ proc report_object_names { args } {
|
||||||
if { [info exists flags(-verbose)] } {
|
if { [info exists flags(-verbose)] } {
|
||||||
puts -nonewline "{"
|
puts -nonewline "{"
|
||||||
set first 1
|
set first 1
|
||||||
foreach obj [sort_by_full_name $objects] {
|
foreach obj [sort_by_name $objects] {
|
||||||
if { !$first } {
|
if { !$first } {
|
||||||
puts -nonewline ", "
|
puts -nonewline ", "
|
||||||
}
|
}
|
||||||
|
|
@ -995,7 +995,7 @@ proc report_object_names { args } {
|
||||||
}
|
}
|
||||||
puts "}"
|
puts "}"
|
||||||
} else {
|
} else {
|
||||||
foreach obj [sort_by_full_name $objects] {
|
foreach obj [sort_by_name $objects] {
|
||||||
puts [get_name $obj]
|
puts [get_name $obj]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
tcl/StaTcl.i
15
tcl/StaTcl.i
|
|
@ -2273,8 +2273,21 @@ find_cells_matching(const char *pattern,
|
||||||
return cells;
|
return cells;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LibertyCellSeq *
|
||||||
|
find_library_buffers(LibertyLibrary *library)
|
||||||
|
{
|
||||||
|
return library->buffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
LibertyCellSeq *
|
||||||
|
equiv_cells(LibertyCell *cell)
|
||||||
|
{
|
||||||
|
LibertyLibrary *library = cell->libertyLibrary();
|
||||||
|
return library->findEquivCells(cell);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
cells_equiv_ports(LibertyCell *cell1,
|
equiv_cell_ports(LibertyCell *cell1,
|
||||||
LibertyCell *cell2)
|
LibertyCell *cell2)
|
||||||
{
|
{
|
||||||
return equivCellPorts(cell1, cell2);
|
return equivCellPorts(cell1, cell2);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue