diff --git a/doc/OpenSTA.odt b/doc/OpenSTA.odt index 6753d508..2269f15f 100644 Binary files a/doc/OpenSTA.odt and b/doc/OpenSTA.odt differ diff --git a/doc/OpenSTA.pdf b/doc/OpenSTA.pdf index 1b00712c..a5813f9e 100644 Binary files a/doc/OpenSTA.pdf and b/doc/OpenSTA.pdf differ diff --git a/include/sta/PowerClass.hh b/include/sta/PowerClass.hh index 580178b9..9eb7c63e 100644 --- a/include/sta/PowerClass.hh +++ b/include/sta/PowerClass.hh @@ -38,17 +38,17 @@ class PwrActivity { public: PwrActivity(); - PwrActivity(float activity, + PwrActivity(float density, float duty, PwrActivityOrigin origin); - float activity() const { return activity_; } - void setActivity(float activity); + float density() const { return density_; } + void setDensity(float density); float duty() const { return duty_; } void setDuty(float duty); PwrActivityOrigin origin() const { return origin_; } void setOrigin(PwrActivityOrigin origin); const char *originName() const; - void set(float activity, + void set(float density, float duty, PwrActivityOrigin origin); bool isSet() const; @@ -56,12 +56,11 @@ public: private: void check(); - // In general activity is per clock cycle, NOT per second. - float activity_; - float duty_; + float density_; // transitions / second + float duty_; // probability signal is high PwrActivityOrigin origin_; - static constexpr float min_activity = 1E-10; + static constexpr float min_density = 1E-10; }; class PowerResult diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index 46c9306b..0d327173 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -1292,7 +1292,7 @@ public: PowerResult &pad); PowerResult power(const Instance *inst, const Corner *corner); - PwrActivity findClkedActivity(const Pin *pin); + PwrActivity activity(const Pin *pin); void writeTimingModel(const char *lib_name, const char *cell_name, diff --git a/power/Power.cc b/power/Power.cc index da474214..fe081788 100644 --- a/power/Power.cc +++ b/power/Power.cc @@ -59,13 +59,12 @@ // input_voltage : default_VDD_VSS_input; // pin // output_voltage : default_VDD_VSS_output; -// -// transition_density = activity / clock_period namespace sta { using std::abs; using std::max; +using std::min; using std::isnormal; static bool @@ -87,8 +86,8 @@ static EnumNameMap pwr_activity_origin_map = Power::Power(StaState *sta) : StaState(sta), - global_activity_{0.0, 0.0, PwrActivityOrigin::unknown}, - input_activity_{0.1, 0.5, PwrActivityOrigin::input}, + global_activity_(), + input_activity_(), // default set in ensureActivities() seq_activity_map_(100, SeqPinHash(network_), SeqPinEqual()), activities_valid_(false), bdd_(sta) @@ -96,41 +95,41 @@ Power::Power(StaState *sta) : } void -Power::setGlobalActivity(float activity, +Power::setGlobalActivity(float density, float duty) { - global_activity_.set(activity, duty, PwrActivityOrigin::global); + global_activity_.set(density, duty, PwrActivityOrigin::global); activities_valid_ = false; } void -Power::setInputActivity(float activity, +Power::setInputActivity(float density, float duty) { - input_activity_.set(activity, duty, PwrActivityOrigin::input); + input_activity_.set(density, duty, PwrActivityOrigin::input); activities_valid_ = false; } void Power::setInputPortActivity(const Port *input_port, - float activity, + float density, float duty) { Instance *top_inst = network_->topInstance(); const Pin *pin = network_->findPin(top_inst, input_port); if (pin) { - user_activity_map_[pin] = {activity, duty, PwrActivityOrigin::user}; + user_activity_map_[pin] = {density, duty, PwrActivityOrigin::user}; activities_valid_ = false; } } void Power::setUserActivity(const Pin *pin, - float activity, + float density, float duty, PwrActivityOrigin origin) { - user_activity_map_[pin] = {activity, duty, origin}; + user_activity_map_[pin] = {density, duty, origin}; activities_valid_ = false; } @@ -152,7 +151,7 @@ Power::setActivity(const Pin *pin, { debugPrint(debug_, "power_activity", 3, "set %s %.2e %.2f %s", network_->pathName(pin), - activity.activity(), + activity.density(), activity.duty(), pwr_activity_origin_map.find(activity.origin())); activity_map_[pin] = activity; @@ -403,7 +402,7 @@ PropActivityVisitor::visit(Vertex *vertex) Vertex *from_vertex = edge->from(graph_); const Pin *from_pin = from_vertex->pin(); PwrActivity &from_activity = power_->activity(from_pin); - PwrActivity to_activity(from_activity.activity(), + PwrActivity to_activity(from_activity.density(), from_activity.duty(), PwrActivityOrigin::propagated); changed = setActivityCheck(pin, to_activity); @@ -426,13 +425,13 @@ PropActivityVisitor::visit(Vertex *vertex) PwrActivity activity2 = power_->findActivity(enable); float p1 = activity1.duty(); float p2 = activity2.duty(); - PwrActivity activity(activity1.activity() * p2 + activity2.activity() * p1, + PwrActivity activity(activity1.density() * p2 + activity2.density() * p1, p1 * p2, PwrActivityOrigin::propagated); changed = setActivityCheck(gclk, activity); debugPrint(debug_, "power_activity", 3, "gated_clk %s %.2e %.2f", network_->pathName(gclk), - activity.activity(), + activity.density(), activity.duty()); } } @@ -467,16 +466,16 @@ PropActivityVisitor::setActivityCheck(const Pin *pin, PwrActivity &activity) { float min_rf_slew = power_->getMinRfSlew(pin); - float max_activity = (min_rf_slew > 0.0) ? 1.0 / min_rf_slew : INF; - if (activity.activity() > max_activity) - activity.setActivity(max_activity); + float max_density = (min_rf_slew > 0.0) ? 1.0 / min_rf_slew : INF; + if (activity.density() > max_density) + activity.setDensity(max_density); PwrActivity &prev_activity = power_->activity(pin); - float activity_delta = abs(activity.activity() - prev_activity.activity()); + float density_delta = abs(activity.density() - prev_activity.density()); float duty_delta = abs(activity.duty() - prev_activity.duty()); - if (activity_delta > change_tolerance_ + if (density_delta > change_tolerance_ || duty_delta > change_tolerance_ || activity.origin() != prev_activity.origin()) { - max_change_ = max(max_change_, activity_delta); + max_change_ = max(max_change_, density_delta); max_change_ = max(max_change_, duty_delta); power_->setActivity(pin, activity); return true; @@ -521,11 +520,11 @@ Power::evalActivity(FuncExpr *expr, else { DdNode *bdd = bdd_.funcBdd(expr); float duty = evalBddDuty(bdd, inst); - float activity = evalBddActivity(bdd, inst); + float density = evalBddActivity(bdd, inst); Cudd_RecursiveDeref(bdd_.cuddMgr(), bdd); bdd_.clearVarMap(); - return PwrActivity(activity, duty, PwrActivityOrigin::propagated); + return PwrActivity(density, duty, PwrActivityOrigin::propagated); } } @@ -592,7 +591,7 @@ float Power::evalBddActivity(DdNode *bdd, const Instance *inst) { - float activity = 0.0; + float density = 0.0; for (const auto [port, var_node] : bdd_.portVarMap()) { const Pin *pin = findLinkPin(inst, port); if (pin) { @@ -602,21 +601,16 @@ Power::evalBddActivity(DdNode *bdd, Cudd_Ref(diff); float diff_duty = evalBddDuty(diff, inst); Cudd_RecursiveDeref(bdd_.cuddMgr(), diff); - float var_act = var_activity.activity() * diff_duty; - activity += var_act; - if (debug_->check("power_activity", 3)) { - const Clock *clk = findClk(pin); - float clk_period = clk ? clk->period() : 1.0; - debugPrint(debug_, "power_activity", 3, "var %s%s %.3e * %.3f = %.3e", - port->name(), - clk ? "" : " (unclocked)", - var_activity.activity() / clk_period, - diff_duty, - var_act / clk_period); - } + float var_density = var_activity.density() * diff_duty; + density += var_density; + debugPrint(debug_, "power_activity", 3, "var %s %.3e * %.3f = %.3e", + port->name(), + var_activity.density(), + diff_duty, + var_density); } } - return activity; + return density; } //////////////////////////////////////////////////////////////// @@ -632,6 +626,13 @@ Power::ensureActivities() activity_map_.clear(); seq_activity_map_.clear(); + // Initialize default input activity (after sdc is defined) + // unless it has been set by command. + if (input_activity_.density() == 0.0) { + float min_period = clockMinPeriod(); + float density = 0.1 / (min_period != 0.0 ? min_period : 0.0); + input_activity_.set(density, 0.5, PwrActivityOrigin::input); + } ActivitySrchPred activity_srch_pred(this); BfsFwdIterator bfs(BfsIndex::other, &activity_srch_pred, this); seedActivities(bfs); @@ -726,9 +727,17 @@ Power::seedRegOutputActivities(const Instance *reg, PwrActivity activity = evalActivity(seq->data(), reg); // Register output activity cannnot exceed one transition per clock cycle, // but latch output can. - if (seq->isRegister() - && activity.activity() > 1.0) - activity.setActivity(1.0); + if (seq->isRegister()) { + FuncExpr *clk_func = seq->clock(); + if (clk_func->port()) { + const Pin *pin = network_->findPin(reg, clk_func->port()); + const Clock *clk = findClk(pin); + if (clk) { + if (activity.density() > 1.0 / clk->period()) + activity.setDensity(1.0 / clk->period()); + } + } + } if (invert) activity.setDuty(1.0 - activity.duty()); activity.setOrigin(PwrActivityOrigin::propagated); @@ -744,9 +753,8 @@ Power::power(const Instance *inst, const Corner *corner) { PowerResult result; - const Clock *inst_clk = findInstClk(inst); - findInternalPower(inst, cell, corner, inst_clk, result); - findSwitchingPower(inst, cell, corner, inst_clk, result); + findInternalPower(inst, cell, corner, result); + findSwitchingPower(inst, cell, corner, result); findLeakagePower(inst, cell, corner, result); return result; } @@ -772,7 +780,6 @@ void Power::findInternalPower(const Instance *inst, LibertyCell *cell, const Corner *corner, - const Clock *inst_clk, // Return values. PowerResult &result) { @@ -785,7 +792,7 @@ Power::findInternalPower(const Instance *inst, float load_cap = to_port->direction()->isAnyOutput() ? graph_delay_calc_->loadCap(to_pin, dcalc_ap) : 0.0; - PwrActivity activity = findClkedActivity(to_pin, inst_clk); + PwrActivity activity = findActivity(to_pin); if (to_port->direction()->isAnyOutput()) findOutputInternalPower(to_port, inst, cell, activity, load_cap, corner, result); @@ -854,11 +861,11 @@ Power::findInputInternalPower(const Pin *pin, else duty = evalActivity(when, inst).duty(); } - float port_internal = energy * duty * activity.activity(); + float port_internal = energy * duty * activity.density(); debugPrint(debug_, "power", 2, " %3s %6s %.2f %.2f %9.2e %9.2e %s", port->name(), when ? when->asString() : "", - activity.activity() * 1e-9, + activity.density() * 1e-9, duty, energy, port_internal, @@ -961,11 +968,11 @@ Power::findOutputInternalPower(const LibertyPort *to_port, const LibertyPort *from_corner_port = pwr->relatedPort(); if (from_corner_port) { const Pin *from_pin = findLinkPin(inst, from_corner_port); - float from_activity = findActivity(from_pin).activity(); + float from_density = findActivity(from_pin).density(); float duty = findInputDuty(inst, func, pwr); const char *related_pg_pin = pwr->relatedPgPin(); // Note related_pg_pin may be null. - pg_duty_sum[related_pg_pin] += from_activity * duty; + pg_duty_sum[related_pg_pin] += from_density * duty; } } @@ -1007,16 +1014,16 @@ Power::findOutputInternalPower(const LibertyPort *to_port, if (duty_sum_iter != pg_duty_sum.end()) { float duty_sum = duty_sum_iter->second; if (duty_sum != 0.0 && from_pin) { - float from_activity = findActivity(from_pin).activity(); - weight = from_activity * duty / duty_sum; + float from_density = findActivity(from_pin).density(); + weight = from_density * duty / duty_sum; } } - float port_internal = weight * energy * to_activity.activity(); + float port_internal = weight * energy * to_activity.density(); debugPrint(debug_, "power", 2, "%3s -> %-3s %6s %.3f %.3f %.3f %9.2e %9.2e %s", from_corner_port ? from_corner_port->name() : "-" , to_port->name(), when ? when->asString() : "", - to_activity.activity() * 1e-9, + to_activity.density() * 1e-9, duty, weight, energy, @@ -1048,7 +1055,7 @@ Power::findInputDuty(const Instance *inst, else if (when) return evalActivity(when, inst).duty(); else if (search_->isClock(from_vertex)) - return 1.0; + return 0.5; return 0.5; } } @@ -1093,7 +1100,6 @@ void Power::findSwitchingPower(const Instance *inst, LibertyCell *cell, const Corner *corner, - const Clock *inst_clk, // Return values. PowerResult &result) { @@ -1107,14 +1113,14 @@ Power::findSwitchingPower(const Instance *inst, float load_cap = to_port->direction()->isAnyOutput() ? graph_delay_calc_->loadCap(to_pin, dcalc_ap) : 0.0; - PwrActivity activity = findClkedActivity(to_pin, inst_clk); + PwrActivity activity = findActivity(to_pin); if (to_port->direction()->isAnyOutput()) { float volt = portVoltage(corner_cell, to_port, dcalc_ap); - float switching = .5 * load_cap * volt * volt * activity.activity(); + float switching = .5 * load_cap * volt * volt * activity.density(); debugPrint(debug_, "power", 2, "switching %s/%s activity = %.2e volt = %.2f %.3e", cell->name(), to_port->name(), - activity.activity(), + activity.density(), volt, switching); result.incrSwitching(switching); @@ -1188,31 +1194,12 @@ Power::findLeakagePower(const Instance *inst, result.incrLeakage(leakage); } +// External. PwrActivity -Power::findClkedActivity(const Pin *pin) +Power::pinActivity(const Pin *pin) { - const Instance *inst = network_->instance(pin); - const Clock *inst_clk = findInstClk(inst); ensureActivities(); - return findClkedActivity(pin, inst_clk); -} - -PwrActivity -Power::findClkedActivity(const Pin *pin, - const Clock *inst_clk) -{ - PwrActivity activity = findActivity(pin); - const Clock *clk = findClk(pin); - if (clk == nullptr) - clk = inst_clk; - if (clk) { - float period = clk->period(); - if (period > 0.0) - return PwrActivity(activity.activity() / period, - activity.duty(), - activity.origin()); - } - return activity; + return findActivity(pin); } PwrActivity @@ -1229,7 +1216,7 @@ Power::findActivity(const Pin *pin) } const Clock *clk = findClk(pin); float duty = clockDuty(clk); - return PwrActivity(2.0, duty, PwrActivityOrigin::clock); + return PwrActivity(2.0 / clk->period(), duty, PwrActivityOrigin::clock); } else if (global_activity_.isSet()) return global_activity_; @@ -1438,6 +1425,20 @@ Power::pinCount() return count; } +float +Power::clockMinPeriod() +{ + ClockSeq *clks = sdc_->clocks(); + if (clks && !clks->empty()) { + float min_period = INF; + for (const Clock *clk : *clks) + min_period = min(min_period, clk->period()); + return min_period; + } + else + return 0.0; +} + //////////////////////////////////////////////////////////////// PowerResult::PowerResult() : @@ -1489,17 +1490,17 @@ PowerResult::incr(PowerResult &result) //////////////////////////////////////////////////////////////// -PwrActivity::PwrActivity(float activity, +PwrActivity::PwrActivity(float density, float duty, PwrActivityOrigin origin) : - activity_(activity), + density_(density), duty_(duty), origin_(origin) { } PwrActivity::PwrActivity() : - activity_(0.0), + density_(0.0), duty_(0.0), origin_(PwrActivityOrigin::unknown) { @@ -1507,9 +1508,9 @@ PwrActivity::PwrActivity() : } void -PwrActivity::setActivity(float activity) +PwrActivity::setDensity(float density) { - activity_ = activity; + density_ = density; } void @@ -1525,11 +1526,11 @@ PwrActivity::setOrigin(PwrActivityOrigin origin) } void -PwrActivity::set(float activity, +PwrActivity::set(float density, float duty, PwrActivityOrigin origin) { - activity_ = activity; + density_ = density; duty_ = duty; origin_ = origin; check(); @@ -1538,11 +1539,11 @@ PwrActivity::set(float activity, void PwrActivity::check() { - // Activities can get very small from multiplying probabilities + // Densities can get very small from multiplying probabilities // through deep chains of logic. Clip them to prevent floating // point anomalies. - if (abs(activity_) < min_activity) - activity_ = 0.0; + if (abs(density_) < min_density) + density_ = 0.0; } bool diff --git a/power/Power.hh b/power/Power.hh index bc4333ca..af93792b 100644 --- a/power/Power.hh +++ b/power/Power.hh @@ -84,17 +84,17 @@ public: void setInputPortActivity(const Port *input_port, float activity, float duty); - PwrActivity &activity(const Pin *pin); + PwrActivity pinActivity(const Pin *pin); void setUserActivity(const Pin *pin, float activity, float duty, PwrActivityOrigin origin); - // Activity is toggles per second. - PwrActivity findClkedActivity(const Pin *pin); void reportActivityAnnotation(bool report_unannotated, bool report_annotated); + float clockMinPeriod(); protected: + PwrActivity &activity(const Pin *pin); bool inClockNetwork(const Instance *inst); void powerInside(const Instance *hinst, const Corner *corner, @@ -112,6 +112,7 @@ protected: bool hasActivity(const Pin *pin); void setActivity(const Pin *pin, PwrActivity &activity); + PwrActivity findActivity(const Pin *pin); PowerResult power(const Instance *inst, LibertyCell *cell, @@ -119,7 +120,6 @@ protected: void findInternalPower(const Instance *inst, LibertyCell *cell, const Corner *corner, - const Clock *inst_clk, // Return values. PowerResult &result); void findInputInternalPower(const Pin *to_pin, @@ -147,7 +147,6 @@ protected: void findSwitchingPower(const Instance *inst, LibertyCell *cell, const Corner *corner, - const Clock *inst_clk, // Return values. PowerResult &result); float getSlew(Vertex *vertex, @@ -157,9 +156,6 @@ protected: const Clock *findInstClk(const Instance *inst); const Clock *findClk(const Pin *to_pin); float clockDuty(const Clock *clk); - PwrActivity findClkedActivity(const Pin *pin, - const Clock *inst_clk); - PwrActivity findActivity(const Pin *pin); PwrActivity findSeqActivity(const Instance *inst, LibertyPort *port); float portVoltage(LibertyCell *cell, diff --git a/power/Power.i b/power/Power.i index d0b45038..e9c0ea42 100644 --- a/power/Power.i +++ b/power/Power.i @@ -18,6 +18,7 @@ %{ #include "Sta.hh" +#include "Sdc.hh" #include "power/Power.hh" #include "power/VcdReader.hh" #include "power/SaifReader.hh" @@ -101,6 +102,13 @@ set_power_pin_activity(const Pin *pin, return power->setUserActivity(pin, activity, duty, PwrActivityOrigin::user); } +float +clock_min_period() +{ + Power *power = Sta::sta()->power(); + return power->clockMinPeriod(); +} + //////////////////////////////////////////////////////////////// void diff --git a/power/Power.tcl b/power/Power.tcl index a554c8c1..1c7e02fe 100644 --- a/power/Power.tcl +++ b/power/Power.tcl @@ -217,46 +217,67 @@ define_cmd_args "set_power_activity" { [-global]\ [-input]\ [-input_ports ports]\ [-pins pins]\ - [-activity activity]\ - [-duty duty] } + [-activity activity | -density density]\ + [-duty duty]\ + [-clock clock]} proc set_power_activity { args } { parse_key_args "set_power_activity" args \ - keys {-input_ports -pins -activity -duty} \ + keys {-input_ports -pins -activity -density -duty -clock} \ flags {-global -input} check_argc_eq0 "set_power_activity" $args - set activity 0.0 + if { [info exists keys(-activity)] && [info exists keys(-density)] \ + || ![info exists keys(-activity)] && ![info exists keys(-density)] } { + sta_error 306 "Specify -activity or -density." + } + + set density 0.0 if { [info exists keys(-activity)] } { set activity $keys(-activity) - check_float "activity" $activity - if { $activity < 0.0 } { - sta_warn 301 "activity should be 0.0 to 1.0 or 2.0" + check_positive_float "activity" $activity + if { [info exists keys(-clock)] } { + set clk [get_clock_warn "-clock" $keys(-clock)] + } else { + set clks [get_clocks] + if { $clks == {} } { + sta_error 307 "-activity requires a clock to be defined" + } + } + set density [expr $activity / [clock_min_period]] + } + + if { [info exists keys(-density)] } { + set density $keys(-density) + check_positive_float "density" $density + set density [expr $density / [time_ui_sta 1.0]] + if { [info exists keys(-clock)] } { + sta_warn 302 "-clock ignored for -density" } } set duty 0.5 if { [info exists keys(-duty)] } { set duty $keys(-duty) check_float "duty" $duty - if { $duty < 0.0 || $duty > 1.0 } { - sta_warn 302 "duty should be 0.0 to 1.0" + if { $duty < 0.0 || $duty > 1.0 } {i + sta_error 302 "duty should be 0.0 to 1.0" } } if { [info exists flags(-global)] } { - set_power_global_activity $activity $duty + set_power_global_activity $density $duty } if { [info exists flags(-input)] } { - set_power_input_activity $activity $duty + set_power_input_activity $density $duty } if { [info exists keys(-input_ports)] } { set ports [get_ports_error "input_ports" $keys(-input_ports)] foreach port $ports { if { [get_property $port "direction"] == "input" } { - if { [sta::is_clock_src [sta::get_port_pin $port]] } { + if { [is_clock_src [sta::get_port_pin $port]] } { sta_warn 303 "activity cannot be set on clock ports." } else { - set_power_input_port_activity $port $activity $duty + set_power_input_port_activity $port $density $duty } } } @@ -264,7 +285,7 @@ proc set_power_activity { args } { if { [info exists keys(-pins)] } { set pins [get_pins $keys(-pins)] foreach pin $pins { - set_power_pin_activity $pin $activity $duty + set_power_pin_activity $pin $density $duty } } } diff --git a/power/SaifReader.cc b/power/SaifReader.cc index da1cf059..0c0925f8 100644 --- a/power/SaifReader.cc +++ b/power/SaifReader.cc @@ -63,7 +63,6 @@ SaifReader::SaifReader(const char *filename, escape_('\\'), timescale_(1.0E-9F), // default units of ns duration_(0.0), - clk_period_(0.0), in_scope_level_(0), power_(sta->power()) { @@ -79,10 +78,6 @@ SaifReader::read() // Use zlib to uncompress gzip'd files automagically. stream_ = gzopen(filename_, "rb"); if (stream_) { - clk_period_ = INF; - for (Clock *clk : *sdc_->clocks()) - clk_period_ = min(static_cast(clk->period()), clk_period_); - saif_scope_.clear(); in_scope_level_ = 0; annotated_pins_.clear(); @@ -185,16 +180,16 @@ SaifReader::setNetDurations(const char *net_name, double t1 = durations[static_cast(SaifState::T1)]; float duty = t1 / duration_; double tc = durations[static_cast(SaifState::TC)]; - float activity = tc / (duration_ * timescale_ / clk_period_); + float density = tc / (duration_ * timescale_); debugPrint(debug_, "read_saif", 2, - "%s duty %.0f / %" PRIu64 " = %.2f tc %.0f activity %.2f", + "%s duty %.0f / %" PRIu64 " = %.2f tc %.0f density %.2f", sdc_network_->pathName(pin), t1, duration_, duty, tc, - activity); - power_->setUserActivity(pin, activity, duty, PwrActivityOrigin::saif); + density); + power_->setUserActivity(pin, density, duty, PwrActivityOrigin::saif); annotated_pins_.insert(pin); } } diff --git a/power/SaifReaderPvt.hh b/power/SaifReaderPvt.hh index 75705efb..c744cb08 100644 --- a/power/SaifReaderPvt.hh +++ b/power/SaifReaderPvt.hh @@ -95,7 +95,6 @@ private: char escape_; double timescale_; int64_t duration_; - double clk_period_; vector saif_scope_; // Scope during parsing. size_t in_scope_level_; diff --git a/power/VcdReader.cc b/power/VcdReader.cc index ed629e61..aacc2032 100644 --- a/power/VcdReader.cc +++ b/power/VcdReader.cc @@ -345,7 +345,6 @@ private: const char *filename_; VcdCountReader vcd_reader_; VcdParse vcd_parse_; - double clk_period_; Power *power_; std::set annotated_pins_; @@ -369,7 +368,6 @@ ReadVcdActivities::ReadVcdActivities(const char *filename, filename_(filename), vcd_reader_(scope, sdc_network_, report_, debug_), vcd_parse_(report_, debug_), - clk_period_(0.0), power_(sta->power()) { } @@ -380,9 +378,6 @@ ReadVcdActivities::readActivities() ClockSeq *clks = sdc_->clocks(); if (clks->empty()) report_->error(805, "No clocks have been defined."); - clk_period_ = INF; - for (Clock *clk : *clks) - clk_period_ = min(static_cast(clk->period()), clk_period_); vcd_parse_.read(filename_, &vcd_reader_); @@ -403,19 +398,19 @@ ReadVcdActivities::setActivities() double transition_count = vcd_count.transitionCount(); VcdTime high_time = vcd_count.highTime(time_max); float duty = static_cast(high_time) / time_max; - float activity = transition_count / (time_max * time_scale / clk_period_); + float density = transition_count / (time_max * time_scale); if (debug_->check("read_vcd_activities", 1)) { for (const Pin *pin : vcd_count.pins()) { debugPrint(debug_, "read_vcd_activities", 1, "%s transitions %.1f activity %.2f duty %.2f", sdc_network_->pathName(pin), transition_count, - activity, + density, duty); } } for (const Pin *pin : vcd_count.pins()) { - power_->setUserActivity(pin, activity, duty, PwrActivityOrigin::vcd); + power_->setUserActivity(pin, density, duty, PwrActivityOrigin::vcd); if (sdc_->isLeafPinClock(pin)) checkClkPeriod(pin, transition_count); annotated_pins_.insert(pin); diff --git a/sdf/Sdf.tcl b/sdf/Sdf.tcl index c1c63653..5bcf0f5b 100644 --- a/sdf/Sdf.tcl +++ b/sdf/Sdf.tcl @@ -56,7 +56,7 @@ proc_redirect read_sdf { ################################################################ define_cmd_args "report_annotated_delay" \ - {[-cell] [-net] [-from_in_ports] [-to_out_ports] [-max_lines liness]\ + {[-cell] [-net] [-from_in_ports] [-to_out_ports] [-max_lines lines]\ [-list_annotated] [-list_not_annotated] [-constant_arcs]} proc_redirect report_annotated_delay { @@ -92,7 +92,7 @@ proc_redirect report_annotated_delay { define_cmd_args "report_annotated_check" \ {[-setup] [-hold] [-recovery] [-removal] [-nochange] [-width] [-period]\ - [-max_skew] [-max_lines liness] [-list_annotated] [-list_not_annotated]\ + [-max_skew] [-max_lines lines] [-list_annotated] [-list_not_annotated]\ [-constant_arcs]} proc_redirect report_annotated_check { diff --git a/search/Property.cc b/search/Property.cc index 39562744..4b39f0df 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -780,7 +780,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->findClkedActivity(pin); + PwrActivity activity = sta->activity(pin); return PropertyValue(&activity); } @@ -998,7 +998,7 @@ getProperty(const Pin *pin, return PropertyValue(&clks); } else if (stringEqual(property, "activity")) { - PwrActivity activity = sta->findClkedActivity(pin); + PwrActivity activity = sta->activity(pin); return PropertyValue(&activity); } diff --git a/search/Sta.cc b/search/Sta.cc index 1cf5ea84..d5ccf4fe 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -5696,10 +5696,10 @@ Sta::power(const Instance *inst, } PwrActivity -Sta::findClkedActivity(const Pin *pin) +Sta::activity(const Pin *pin) { powerPreamble(); - return power_->findClkedActivity(pin); + return power_->pinActivity(pin); } //////////////////////////////////////////////////////////////// diff --git a/tcl/StaTclTypes.i b/tcl/StaTclTypes.i index f2c10779..d3668654 100644 --- a/tcl/StaTclTypes.i +++ b/tcl/StaTclTypes.i @@ -1370,7 +1370,7 @@ using namespace sta; Tcl_Obj *obj; const char *str; - str = stringPrintTmp("%.5e", activity.activity()); + str = stringPrintTmp("%.5e", activity.density()); obj = Tcl_NewStringObj(str, strlen(str)); Tcl_ListObjAppendElement(interp, list, obj); diff --git a/test/power.ok b/test/power.ok index 975a4228..19f4adfd 100644 --- a/test/power.ok +++ b/test/power.ok @@ -2,11 +2,11 @@ Warning: gcd_sky130hd.v line 527, module sky130_fd_sc_hd__tapvpwrvgnd_1 not foun Group Internal Switching Leakage Total Power Power Power Power (Watts) ---------------------------------------------------------------- -Sequential 3.07e-04 4.75e-05 2.96e-10 3.54e-04 40.1% -Combinational 1.58e-04 2.04e-04 6.86e-10 3.62e-04 41.0% +Sequential 3.07e-04 4.76e-05 2.96e-10 3.54e-04 40.0% +Combinational 1.59e-04 2.05e-04 6.86e-10 3.64e-04 41.1% Clock 4.68e-05 1.20e-04 2.30e-11 1.67e-04 18.9% Macro 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.0% Pad 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.0% ---------------------------------------------------------------- -Total 5.11e-04 3.72e-04 1.00e-09 8.84e-04 100.0% - 57.9% 42.1% 0.0% +Total 5.12e-04 3.73e-04 1.00e-09 8.85e-04 100.0% + 57.8% 42.2% 0.0%