gated clock power

This commit is contained in:
James Cherry 2020-11-17 10:59:19 -07:00
parent df69e18a4b
commit 7662c12482
3 changed files with 62 additions and 20 deletions

View File

@ -340,7 +340,7 @@ PropActivityVisitor::foundRegWithoutActivity() const
void
PropActivityVisitor::visit(Vertex *vertex)
{
auto pin = vertex->pin();
Pin *pin = vertex->pin();
debugPrint1(debug_, "power_activity", 3, "visit %s\n",
vertex->name(network_));
if (power_->hasUserActivity(pin))
@ -1012,22 +1012,18 @@ 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) {
PwrActivity activity = findActivity(pin);
if (period > 0.0)
return PwrActivity(activity.activity() / period,
activity.duty(),
activity.origin());
}
}
// gotta find a clock someplace...
return PwrActivity(input_activity_.activity(),
input_activity_.duty(),
PwrActivityOrigin::defaulted);
return activity;
}
PwrActivity
@ -1038,6 +1034,8 @@ Power::findActivity(const Pin *pin)
return PwrActivity(2.0, 0.5, PwrActivityOrigin::clock);
else if (global_activity_.isSet())
return global_activity_;
else if (vertex && vertex->isConstant())
return PwrActivity(0.0, 0.0, PwrActivityOrigin::constant);
else if (activity_map_.hasKey(pin)) {
PwrActivity &activity = activity_map_[pin];
if (activity.origin() != PwrActivityOrigin::unknown)

View File

@ -913,26 +913,69 @@ Sim::evalInstance(const Instance *inst)
if (dir->isAnyOutput()) {
LibertyPort *port = network_->libertyPort(pin);
if (port) {
LogicValue value = LogicValue::unknown;
FuncExpr *expr = port->function();
if (expr) {
LogicValue value = evalExpr(expr, inst);
FuncExpr *tri_en_expr = port->tristateEnable();
if (tri_en_expr == nullptr
|| evalExpr(tri_en_expr, inst) == LogicValue::one) {
debugPrint3(debug_, "sim", 2, " %s %s = %c\n",
port->name(),
expr->asString(),
logicValueString(value));
if (value != logicValue(pin))
setPinValue(pin, value, true);
}
}
FuncExpr *tri_en_expr = port->tristateEnable();
if (tri_en_expr) {
if (evalExpr(tri_en_expr, inst) == LogicValue::one) {
value = evalExpr(expr, inst);
debugPrint3(debug_, "sim", 2, " %s tri_en=1 %s = %c\n",
port->name(),
expr->asString(),
logicValueString(value));
}
}
else {
value = evalExpr(expr, inst);
debugPrint3(debug_, "sim", 2, " %s %s = %c\n",
port->name(),
expr->asString(),
logicValueString(value));
}
}
else if (port->isClockGateOutPin()) {
value = clockGateOutValue(inst);
debugPrint2(debug_, "sim", 2, " %s gated_clk = %c\n",
port->name(),
logicValueString(value));
}
FuncExpr *tri_en_expr = port->tristateEnable();
if (tri_en_expr == nullptr
|| evalExpr(tri_en_expr, inst) == LogicValue::one) {
debugPrint3(debug_, "sim", 2, " %s %s = %c\n",
port->name(),
expr ? expr->asString() : "gated_clk",
logicValueString(value));
if (value != logicValue(pin))
setPinValue(pin, value, true);
}
}
}
}
delete pin_iter;
}
LogicValue
Sim::clockGateOutValue(const Instance *inst)
{
LibertyCell *cell = network_->libertyCell(inst);
LibertyCellPortIterator port_iter(cell);
while (port_iter.hasNext()) {
LibertyPort *port = port_iter.next();
if (port->isClockGateClockPin()
|| port->isClockGateEnablePin()) {
Pin *gclk_pin = network_->findPin(inst, port);
if (gclk_pin) {
Vertex *gclk_vertex = graph_->pinLoadVertex(gclk_pin);
if (gclk_vertex->simValue() == LogicValue::zero)
return LogicValue::zero;
}
}
}
return LogicValue::unknown;
}
void
Sim::setSimValue(Vertex *vertex,
LogicValue value)

View File

@ -84,6 +84,7 @@ protected:
bool propagate);
void enqueue(const Instance *inst);
void evalInstance(const Instance *inst);
LogicValue clockGateOutValue(const Instance *inst);
TimingSense functionSense(const FuncExpr *expr,
const Pin *input_pin,
const Instance *inst);