Merge branch 'master' into read_vcd
This commit is contained in:
commit
3f5b22d3b0
|
|
@ -26,7 +26,8 @@ RUN wget https://cmake.org/files/v3.14/cmake-3.14.0-Linux-x86_64.sh && \
|
|||
&& yum clean -y all
|
||||
|
||||
# Install any git version > 2.6.5
|
||||
RUN yum remove -y git* && yum install -y git224
|
||||
RUN yum remove -y git* && yum install -y rh-git227
|
||||
RUN rm -f /usr/bin/git; ln -s /opt/rh/rh-git227/root/bin/git /usr/bin/git
|
||||
|
||||
# Install SWIG
|
||||
RUN yum remove -y swig \
|
||||
|
|
@ -58,9 +59,8 @@ WORKDIR /OpenSTA
|
|||
|
||||
# Build
|
||||
RUN mkdir build
|
||||
#RUN cd buld && cmake .. -DCUDD=$HOME/cudd
|
||||
RUN cd build && cmake ..
|
||||
RUN make -j 8
|
||||
#RUN cd buld && cmake .. -DCUDD=$HOME/cudd && make -j 8
|
||||
RUN cd build && cmake .. && make -j 8
|
||||
|
||||
# Run sta on entry
|
||||
ENTRYPOINT ["OpenSTA/app/sta"]
|
||||
|
|
|
|||
BIN
doc/OpenSTA.odt
BIN
doc/OpenSTA.odt
Binary file not shown.
BIN
doc/OpenSTA.pdf
BIN
doc/OpenSTA.pdf
Binary file not shown.
|
|
@ -1266,8 +1266,10 @@ public:
|
|||
const Corner *corner,
|
||||
// Return values.
|
||||
PowerResult &result);
|
||||
PwrActivity findClkedActivity(const Pin *pin);
|
||||
|
||||
void writeTimingModel(const char *cell_name,
|
||||
void writeTimingModel(const char *lib_name,
|
||||
const char *cell_name,
|
||||
const char *filename,
|
||||
const Corner *corner);
|
||||
|
||||
|
|
|
|||
|
|
@ -62,11 +62,12 @@ MakeTimingModel::~MakeTimingModel()
|
|||
}
|
||||
|
||||
LibertyLibrary *
|
||||
MakeTimingModel::makeTimingModel(const char *cell_name,
|
||||
MakeTimingModel::makeTimingModel(const char *lib_name,
|
||||
const char *cell_name,
|
||||
const char *filename)
|
||||
{
|
||||
tbl_template_index_ = 1;
|
||||
makeLibrary(cell_name, filename);
|
||||
makeLibrary(lib_name, filename);
|
||||
makeCell(cell_name, filename);
|
||||
makePorts();
|
||||
|
||||
|
|
@ -84,10 +85,10 @@ MakeTimingModel::makeTimingModel(const char *cell_name,
|
|||
}
|
||||
|
||||
void
|
||||
MakeTimingModel::makeLibrary(const char *cell_name,
|
||||
MakeTimingModel::makeLibrary(const char *lib_name,
|
||||
const char *filename)
|
||||
{
|
||||
library_ = network_->makeLibertyLibrary(cell_name, filename);
|
||||
library_ = network_->makeLibertyLibrary(lib_name, filename);
|
||||
LibertyLibrary *default_lib = network_->defaultLibertyLibrary();
|
||||
*library_->units()->timeUnit() = *default_lib->units()->timeUnit();
|
||||
*library_->units()->capacitanceUnit() = *default_lib->units()->capacitanceUnit();
|
||||
|
|
|
|||
|
|
@ -49,11 +49,12 @@ public:
|
|||
MakeTimingModel(const Corner *corner,
|
||||
Sta *sta);
|
||||
~MakeTimingModel();
|
||||
LibertyLibrary *makeTimingModel(const char *cell_name,
|
||||
LibertyLibrary *makeTimingModel(const char *lib_name,
|
||||
const char *cell_name,
|
||||
const char *filename);
|
||||
|
||||
private:
|
||||
void makeLibrary(const char *cell_name,
|
||||
void makeLibrary(const char *lib_name,
|
||||
const char *filename);
|
||||
void makeCell(const char *cell_name,
|
||||
const char *filename);
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ Power::power(const Corner *corner,
|
|||
macro.clear();
|
||||
pad.clear();
|
||||
|
||||
preamble();
|
||||
ensureActivities();
|
||||
LeafInstanceIterator *inst_iter = network_->leafInstanceIterator();
|
||||
while (inst_iter->hasNext()) {
|
||||
Instance *inst = inst_iter->next();
|
||||
|
|
@ -235,7 +235,7 @@ Power::power(const Instance *inst,
|
|||
{
|
||||
LibertyCell *cell = network_->libertyCell(inst);
|
||||
if (cell) {
|
||||
preamble();
|
||||
ensureActivities();
|
||||
power(inst, cell, corner, result);
|
||||
}
|
||||
}
|
||||
|
|
@ -330,10 +330,16 @@ PropActivityVisitor::visit(Vertex *vertex)
|
|||
Pin *pin = vertex->pin();
|
||||
debugPrint(debug_, "power_activity", 3, "visit %s",
|
||||
vertex->name(network_));
|
||||
if (power_->hasUserActivity(pin))
|
||||
power_->setActivity(pin, power_->userActivity(pin));
|
||||
bool input_without_activity = false;
|
||||
if (power_->hasUserActivity(pin)) {
|
||||
PwrActivity &activity = power_->userActivity(pin);
|
||||
debugPrint(debug_, "power_activity", 3, "set %s %.2e %.2f",
|
||||
vertex->name(network_),
|
||||
activity.activity(),
|
||||
activity.duty());
|
||||
power_->setActivity(pin, activity);
|
||||
}
|
||||
else {
|
||||
bool input_without_activity = false;
|
||||
if (network_->isLoad(pin)) {
|
||||
VertexInEdgeIterator edge_iter(vertex, graph_);
|
||||
if (edge_iter.hasNext()) {
|
||||
|
|
@ -350,14 +356,6 @@ PropActivityVisitor::visit(Vertex *vertex)
|
|||
power_->setActivity(pin, to_activity);
|
||||
}
|
||||
}
|
||||
Instance *inst = network_->instance(pin);
|
||||
LibertyCell *cell = network_->libertyCell(inst);
|
||||
if (cell && cell->hasSequentials()) {
|
||||
debugPrint(debug_, "power_activity", 3, "pending reg %s",
|
||||
network_->pathName(inst));
|
||||
visited_regs_->insert(inst);
|
||||
found_reg_without_activity_ = input_without_activity;
|
||||
}
|
||||
}
|
||||
if (network_->isDriver(pin)) {
|
||||
LibertyPort *port = network_->libertyPort(pin);
|
||||
|
|
@ -375,6 +373,16 @@ PropActivityVisitor::visit(Vertex *vertex)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (network_->isLoad(pin)) {
|
||||
Instance *inst = network_->instance(pin);
|
||||
LibertyCell *cell = network_->libertyCell(inst);
|
||||
if (cell && cell->hasSequentials()) {
|
||||
debugPrint(debug_, "power_activity", 3, "pending reg %s",
|
||||
network_->pathName(inst));
|
||||
visited_regs_->insert(inst);
|
||||
found_reg_without_activity_ |= input_without_activity;
|
||||
}
|
||||
}
|
||||
bfs_->enqueueAdjacentVertices(vertex);
|
||||
}
|
||||
|
||||
|
|
@ -425,8 +433,7 @@ Power::evalActivity(FuncExpr *expr,
|
|||
cofactor_port, cofactor_positive);
|
||||
float p1 = 1.0 - activity1.duty();
|
||||
float p2 = 1.0 - activity2.duty();
|
||||
return PwrActivity(activity1.activity() * p2
|
||||
+ activity2.activity() * p1,
|
||||
return PwrActivity(activity1.activity() * p2 + activity2.activity() * p1,
|
||||
1.0 - p1 * p2,
|
||||
PwrActivityOrigin::propagated);
|
||||
}
|
||||
|
|
@ -446,9 +453,11 @@ Power::evalActivity(FuncExpr *expr,
|
|||
cofactor_port, cofactor_positive);
|
||||
PwrActivity activity2 = evalActivity(expr->right(), inst,
|
||||
cofactor_port, cofactor_positive);
|
||||
float p1 = activity1.duty() * (1.0 - activity2.duty());
|
||||
float p2 = activity2.duty() * (1.0 - activity1.duty());
|
||||
return PwrActivity(activity1.activity() * p1 + activity2.activity() * p2,
|
||||
float d1 = activity1.duty();
|
||||
float d2 = activity2.duty();
|
||||
float p1 = d1 * (1.0 - d2);
|
||||
float p2 = (1.0 - d1) * d2;
|
||||
return PwrActivity(activity1.activity() + activity2.activity(),
|
||||
p1 + p2,
|
||||
PwrActivityOrigin::propagated);
|
||||
}
|
||||
|
|
@ -462,12 +471,6 @@ Power::evalActivity(FuncExpr *expr,
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Power::preamble()
|
||||
{
|
||||
ensureActivities();
|
||||
}
|
||||
|
||||
void
|
||||
Power::ensureActivities()
|
||||
{
|
||||
|
|
@ -1010,6 +1013,7 @@ Power::findClkedActivity(const Pin *pin)
|
|||
{
|
||||
const Instance *inst = network_->instance(pin);
|
||||
const Clock *inst_clk = findInstClk(inst);
|
||||
ensureActivities();
|
||||
return findClkedActivity(pin, inst_clk);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,6 @@ public:
|
|||
PwrActivity findClkedActivity(const Pin *pin);
|
||||
|
||||
protected:
|
||||
void preamble();
|
||||
void ensureActivities();
|
||||
bool hasUserActivity(const Pin *pin);
|
||||
PwrActivity &userActivity(const Pin *pin);
|
||||
|
|
|
|||
|
|
@ -655,7 +655,7 @@ getProperty(const Port *port,
|
|||
else if (stringEqual(property, "activity")) {
|
||||
const Instance *top_inst = network->topInstance();
|
||||
const Pin *pin = network->findPin(top_inst, port);
|
||||
PwrActivity activity = sta->power()->findClkedActivity(pin);
|
||||
PwrActivity activity = sta->findClkedActivity(pin);
|
||||
return PropertyValue(&activity);
|
||||
}
|
||||
|
||||
|
|
@ -821,7 +821,7 @@ getProperty(const Pin *pin,
|
|||
return PropertyValue(&clks);
|
||||
}
|
||||
else if (stringEqual(property, "activity")) {
|
||||
PwrActivity activity = sta->power()->findClkedActivity(pin);
|
||||
PwrActivity activity = sta->findClkedActivity(pin);
|
||||
return PropertyValue(&activity);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5567,12 +5567,14 @@ Sta::equivCells(LibertyCell *cell)
|
|||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Sta::writeTimingModel(const char *cell_name,
|
||||
Sta::writeTimingModel(const char *lib_name,
|
||||
const char *cell_name,
|
||||
const char *filename,
|
||||
const Corner *corner)
|
||||
{
|
||||
MakeTimingModel maker(corner, this);
|
||||
LibertyLibrary *library = maker.makeTimingModel(cell_name, filename);
|
||||
LibertyLibrary *library = maker.makeTimingModel(lib_name, cell_name,
|
||||
filename);
|
||||
writeLiberty(library, filename, this);
|
||||
}
|
||||
|
||||
|
|
@ -5610,6 +5612,13 @@ Sta::power(const Instance *inst,
|
|||
power_->power(inst, corner, result);
|
||||
}
|
||||
|
||||
PwrActivity
|
||||
Sta::findClkedActivity(const Pin *pin)
|
||||
{
|
||||
powerPreamble();
|
||||
return power_->findClkedActivity(pin);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -241,9 +241,7 @@ proc set_power_activity { args } {
|
|||
if { [info exists keys(-pins)] } {
|
||||
set pins [get_pins $keys(-pins)]
|
||||
foreach pin $pins {
|
||||
if { [get_property $pin "direction"] == "input" } {
|
||||
set_power_pin_activity $pin $activity $duty
|
||||
}
|
||||
set_power_pin_activity $pin $activity $duty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1033,22 +1033,29 @@ proc worst_clock_skew { args } {
|
|||
################################################################
|
||||
|
||||
define_cmd_args "write_timing_model" {[-corner corner] \
|
||||
[-library_name lib_name]\
|
||||
[-cell_name cell_name]\
|
||||
filename}
|
||||
|
||||
proc write_timing_model { args } {
|
||||
parse_key_args "write_timing_model" args \
|
||||
keys {-cell_name -corner} flags {}
|
||||
keys {-library_name -cell_name -corner} flags {}
|
||||
check_argc_eq1 "write_timing_model" $args
|
||||
|
||||
set filename [lindex $args 0]
|
||||
set filename [file nativename [lindex $args 0]]
|
||||
if { [info exists keys(-cell_name)] } {
|
||||
set cell_name $keys(-cell_name)
|
||||
} else {
|
||||
set cell_name [get_name [[top_instance] cell]]
|
||||
}
|
||||
if { [info exists keys(-library_name)] } {
|
||||
set lib_name $keys(-library_name)
|
||||
} else {
|
||||
set lib_name $cell_name
|
||||
}
|
||||
set corner [parse_corner keys]
|
||||
write_timing_model_cmd $cell_name [file nativename $filename] $corner
|
||||
write_timing_model_cmd $lib_name $cell_name $filename $corner
|
||||
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
|
|
|||
|
|
@ -5045,11 +5045,12 @@ write_path_spice_cmd(PathRef *path,
|
|||
}
|
||||
|
||||
void
|
||||
write_timing_model_cmd(const char *cell_name,
|
||||
write_timing_model_cmd(const char *lib_name,
|
||||
const char *cell_name,
|
||||
const char *filename,
|
||||
const Corner *corner)
|
||||
{
|
||||
Sta::sta()->writeTimingModel(cell_name, filename, corner);
|
||||
Sta::sta()->writeTimingModel(lib_name, cell_name, filename, corner);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
Loading…
Reference in New Issue