diff --git a/Dockerfile b/Dockerfile index 2713d515..7256bcc2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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"] diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt index 9ed813c8..5f73688b 100644 Binary files a/doc/OpenSTA.odt and b/doc/OpenSTA.odt differ diff --git a/doc/OpenSTA.pdf b/doc/OpenSTA.pdf index c5ee6c39..e9ed33ce 100644 Binary files a/doc/OpenSTA.pdf and b/doc/OpenSTA.pdf differ diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index bb0a5c9e..ec2e9cf7 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -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); diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index 8ed5d600..9a0a42d7 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.cc @@ -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(); diff --git a/search/MakeTimingModel.hh b/search/MakeTimingModel.hh index 6d0236f5..d9627e6c 100644 --- a/search/MakeTimingModel.hh +++ b/search/MakeTimingModel.hh @@ -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); diff --git a/search/Power.cc b/search/Power.cc index 6a8281ef..eecb4086 100644 --- a/search/Power.cc +++ b/search/Power.cc @@ -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); } diff --git a/search/Power.hh b/search/Power.hh index bb7bb661..2958cab7 100644 --- a/search/Power.hh +++ b/search/Power.hh @@ -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); diff --git a/search/Property.cc b/search/Property.cc index 6f32f1a5..f2961f34 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -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); } diff --git a/search/Sta.cc b/search/Sta.cc index d2847902..f5ffb127 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -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 diff --git a/tcl/Power.tcl b/tcl/Power.tcl index 42d8d36f..2b611955 100644 --- a/tcl/Power.tcl +++ b/tcl/Power.tcl @@ -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 } } } diff --git a/tcl/Search.tcl b/tcl/Search.tcl index b90ec6dd..81c7865d 100644 --- a/tcl/Search.tcl +++ b/tcl/Search.tcl @@ -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 + } ################################################################ diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index f5f7888a..1a5e3287 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -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); } ////////////////////////////////////////////////////////////////