From 7662c12482b45ce34efa16a018978df2a02e916e Mon Sep 17 00:00:00 2001 From: James Cherry Date: Tue, 17 Nov 2020 10:59:19 -0700 Subject: [PATCH] gated clock power --- search/Power.cc | 14 +++++------ search/Sim.cc | 67 ++++++++++++++++++++++++++++++++++++++++--------- search/Sim.hh | 1 + 3 files changed, 62 insertions(+), 20 deletions(-) diff --git a/search/Power.cc b/search/Power.cc index a9e7edec..f20c3b9e 100644 --- a/search/Power.cc +++ b/search/Power.cc @@ -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) diff --git a/search/Sim.cc b/search/Sim.cc index 21fe0bf1..60cca76d 100644 --- a/search/Sim.cc +++ b/search/Sim.cc @@ -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) diff --git a/search/Sim.hh b/search/Sim.hh index aeda7f45..584224f2 100644 --- a/search/Sim.hh +++ b/search/Sim.hh @@ -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);