-
Notifications
You must be signed in to change notification settings - Fork 55
Description
OpenSTA computes power here
Lines 670 to 694 in c4b94c3
| float | |
| Power::evalBddActivity(DdNode *bdd, | |
| const Instance *inst) | |
| { | |
| float density = 0.0; | |
| for (const auto [port, var_node] : bdd_.portVarMap()) { | |
| const Pin *pin = findLinkPin(inst, port); | |
| if (pin) { | |
| PwrActivity var_activity = findActivity(pin); | |
| unsigned int var_index = Cudd_NodeReadIndex(var_node); | |
| DdNode *diff = Cudd_bddBooleanDiff(bdd_.cuddMgr(), bdd, var_index); | |
| Cudd_Ref(diff); | |
| float diff_duty = evalBddDuty(diff, inst); | |
| Cudd_RecursiveDeref(bdd_.cuddMgr(), diff); | |
| 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 density; | |
| } |
Density Output = Sum ( Probability(Output switches given input signal Xi switches) * Probability(Xi switches))
where Probability(Output switches given input signal Xi switches) is Duty(BooleanDiff for Xi)).
This incorrectly propagates probability as it does not take into account that multiple inputs may switch simultaneously.
Consider a 2-input NAND gate Z=!(AB), with Density 0.5/cycle and Duty 0.5 at both inputs. OpenSTA computes the output density at 0.5/cycle. Instead it should be 0.375/cycle all other assumptions other than propagation being equal:
All input transitions XX to YY are equally likely at 1/16.
There are 6 possible input transitions that cause the output to switch: 00->11, 01->11, 10->11, 11->00, 11->01, 11->10.
So output density is 6/16 = 0.375.