power use density instead of activity

commit f9ac0ee51e238b30c4ace2d925344da612ccccee
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Jan 17 13:00:30 2025 -0700

    doc

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 4619c083ef70c19e4cae71b351ccf25190983f11
Author: James Cherry <cherry@parallaxsw.com>
Date:   Fri Jan 17 10:02:50 2025 -0700

    activity -> density

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit aad7d4c03a9138f0b00a9d7a756bf183760df8eb
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 16 22:14:39 2025 -0700

    power all but 2 regressions

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 2d9465c6e5035d221fc4d3ec32f4997a28aa9877
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 16 16:22:32 2025 -0700

    power activity -> densiity

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit 5d3c6ef2c3b178cf8f4958fcc6cdc37ccac4a067
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 16 11:54:05 2025 -0700

    power1 passes

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

commit f8344e412eb398067d83387fec52b352bbd7eb06
Author: James Cherry <cherry@parallaxsw.com>
Date:   Thu Jan 16 10:30:04 2025 -0700

    set_power_activity -density

    Signed-off-by: James Cherry <cherry@parallaxsw.com>

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2025-01-17 13:02:13 -07:00
parent fbb4b8c6e6
commit b2646a96d0
16 changed files with 166 additions and 152 deletions

Binary file not shown.

Binary file not shown.

View File

@ -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

View File

@ -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,

View File

@ -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<PwrActivityOrigin> 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",
float var_density = var_activity.density() * diff_duty;
density += var_density;
debugPrint(debug_, "power_activity", 3, "var %s %.3e * %.3f = %.3e",
port->name(),
clk ? "" : " (unclocked)",
var_activity.activity() / clk_period,
var_activity.density(),
diff_duty,
var_act / clk_period);
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

View File

@ -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,

View File

@ -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

View File

@ -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
}
}
}

View File

@ -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<double>(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<int>(SaifState::T1)];
float duty = t1 / duration_;
double tc = durations[static_cast<int>(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);
}
}

View File

@ -95,7 +95,6 @@ private:
char escape_;
double timescale_;
int64_t duration_;
double clk_period_;
vector<string> saif_scope_; // Scope during parsing.
size_t in_scope_level_;

View File

@ -345,7 +345,6 @@ private:
const char *filename_;
VcdCountReader vcd_reader_;
VcdParse vcd_parse_;
double clk_period_;
Power *power_;
std::set<const Pin*> 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<double>(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<double>(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);

View File

@ -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 {

View File

@ -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);
}

View File

@ -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);
}
////////////////////////////////////////////////////////////////

View File

@ -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);

View File

@ -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%