From 2451c897da1f7f2d8cce432d62478d5e533ed10a Mon Sep 17 00:00:00 2001 From: James Cherry Date: Mon, 21 Jun 2021 17:49:46 -0700 Subject: [PATCH] Sta::findLogicConstants for openroad restructuring --- include/sta/Sta.hh | 4 ++ search/Sim.cc | 132 +++++++++++++++++++++++++-------------------- search/Sim.hh | 16 +++--- search/Sta.cc | 6 +++ 4 files changed, 92 insertions(+), 66 deletions(-) diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index 4e2025a7..c0522dfb 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -1049,6 +1049,10 @@ public: Vertex *maxArrivalCountVertex() const; LogicValue simLogicValue(const Pin *pin); + // Propagate liberty constant functions and pins tied high/low through + // combinational logic and registers. + void findLogicConstants(); + // Iterator for instances sorted by max driver pin slew. // Caller owns iterator and iterator->container(). SlowDrvrIterator *slowDrvrIterator(); diff --git a/search/Sim.cc b/search/Sim.cc index 3e1a4402..dc19e8a0 100644 --- a/search/Sim.cc +++ b/search/Sim.cc @@ -27,6 +27,7 @@ #include "TimingArc.hh" #include "Liberty.hh" #include "PortDirection.hh" +#include "Sequential.hh" #include "Network.hh" #include "Sdc.hh" #include "Graph.hh" @@ -552,7 +553,7 @@ Sim::ensureConstantsPropagated() seedConstants(); } invalid_insts_.clear(); - propagateConstants(); + propagateConstants(false); annotateGraphEdges(); valid_ = true; incremental_ = true; @@ -561,6 +562,15 @@ Sim::ensureConstantsPropagated() } } +void +Sim::findLogicConstants() +{ + clear(); + enqueueConstantPinInputs(); + setConstFuncPins(); + propagateConstants(true); +} + void Sim::seedInvalidConstants() { @@ -579,9 +589,9 @@ Sim::propagateToInvalidLoads() Pin *load_pin = load_iter.next(); Net *net = network_->net(load_pin); if (net && network_->isGround(net)) - setPinValue(load_pin, LogicValue::zero, true); + setPinValue(load_pin, LogicValue::zero); else if (net && network_->isPower(net)) - setPinValue(load_pin, LogicValue::one, true); + setPinValue(load_pin, LogicValue::one); else { Pin *drvr_pin = findDrvrPin(load_pin, network_); if (drvr_pin) @@ -605,7 +615,7 @@ Sim::propagateFromInvalidDrvrsToLoads() Pin *load_pin = load_iter->next(); if (load_pin != drvr_pin && network_->isLoad(load_pin)) - setPinValue(load_pin, value, true); + setPinValue(load_pin, value); } delete load_iter; } @@ -617,7 +627,7 @@ Sim::propagateDrvrToLoad(Pin *drvr_pin, Pin *load_pin) { LogicValue value = logicValue(drvr_pin); - setPinValue(load_pin, value, true); + setPinValue(load_pin, value); } void @@ -729,28 +739,27 @@ void Sim::seedConstants() { // Propagate constants from inputs tied hi/low in the network. - enqueueConstantPinInputs(true); + enqueueConstantPinInputs(); // Propagate set_LogicValue::zero, set_LogicValue::one, set_logic_dc constants. - setConstraintConstPins(sdc_->logicValues(), true); + setConstraintConstPins(sdc_->logicValues()); // Propagate set_case_analysis constants. - setConstraintConstPins(sdc_->caseLogicValues(), true); + setConstraintConstPins(sdc_->caseLogicValues()); // Propagate 0/1 constant functions. - setConstFuncPins(true); + setConstFuncPins(); } void -Sim::propagateConstants() +Sim::propagateConstants(bool thru_sequentials) { while (!eval_queue_.empty()) { const Instance *inst = eval_queue_.front(); eval_queue_.pop(); - evalInstance(inst); + evalInstance(inst, thru_sequentials); } } void -Sim::setConstraintConstPins(LogicValueMap *value_map, - bool propagate) +Sim::setConstraintConstPins(LogicValueMap *value_map) { LogicValueMap::ConstIterator value_iter(value_map); while (value_iter.hasNext()) { @@ -770,25 +779,25 @@ Sim::setConstraintConstPins(LogicValueMap *value_map, && network_->direction(pin1)->isAnyInput() && ((pin_is_output && !network_->isInside(pin1, pin)) || (!pin_is_output && network_->isInside(pin1, pin)))) - setPinValue(pin1, value, propagate); + setPinValue(pin1, value); } delete pin_iter; } else - setPinValue(pin, value, propagate); + setPinValue(pin, value); } } // Propagate constants from outputs with constant functions // (tie high and tie low cell instances). void -Sim::setConstFuncPins(bool propagate) +Sim::setConstFuncPins() { PinSet::Iterator const_pin_iter(const_func_pins_); while (const_pin_iter.hasNext()) { Pin *pin = const_pin_iter.next(); LogicValue value = pinConstFuncValue(pin); - setPinValue(pin, value, propagate); + setPinValue(pin, value); debugPrint(debug_, "sim", 2, "func pin %s = %c", network_->pathName(pin), logicValueString(value)); @@ -810,7 +819,7 @@ Sim::pinConstFuncValue(Pin *pin) } void -Sim::enqueueConstantPinInputs(bool propagate) +Sim::enqueueConstantPinInputs() { ConstantPinIterator *const_iter = network_->constantPinIterator(); while (const_iter->hasNext()) { @@ -820,7 +829,7 @@ Sim::enqueueConstantPinInputs(bool propagate) debugPrint(debug_, "sim", 2, "network constant pin %s = %c", network_->pathName(pin), logicValueString(value)); - setPinValue(pin, value, propagate); + setPinValue(pin, value); } delete const_iter; } @@ -854,8 +863,7 @@ Sim::removePropagatedValue(const Pin *pin) void Sim::setPinValue(const Pin *pin, - LogicValue value, - bool propagate) + LogicValue value) { LogicValue constraint_value; bool exists; @@ -885,41 +893,42 @@ Sim::setPinValue(const Pin *pin, if (logicValueZeroOne(value)) instances_with_const_pins_.insert(inst); instances_to_annotate_.insert(inst); - if (propagate) { - if (network_->isLeaf(inst) - && network_->direction(pin)->isAnyInput()) { - if (eval_queue_.empty() - || (eval_queue_.back() != inst)) - eval_queue_.push(inst); - } - else if (network_->isDriver(pin)) { - // Enqueue instances with input pins connected to net. - PinConnectedPinIterator *pin_iter=network_->connectedPinIterator(pin); - while (pin_iter->hasNext()) { - Pin *pin1 = pin_iter->next(); - if (pin1 != pin - && network_->isLoad(pin1)) - setPinValue(pin1, value, propagate); - } - delete pin_iter; + + if (network_->isLeaf(inst) + && network_->direction(pin)->isAnyInput()) { + if (eval_queue_.empty() + || (eval_queue_.back() != inst)) + eval_queue_.push(inst); + } + else if (network_->isDriver(pin)) { + // Enqueue instances with input pins connected to net. + PinConnectedPinIterator *pin_iter=network_->connectedPinIterator(pin); + while (pin_iter->hasNext()) { + Pin *pin1 = pin_iter->next(); + if (pin1 != pin + && network_->isLoad(pin1)) + setPinValue(pin1, value); } + delete pin_iter; } } } void -Sim::evalInstance(const Instance *inst) +Sim::evalInstance(const Instance *inst, + bool thru_sequentials) { debugPrint(debug_, "sim", 2, "eval %s", network_->pathName(inst)); InstancePinIterator *pin_iter = network_->pinIterator(inst); while (pin_iter->hasNext()) { Pin *pin = pin_iter->next(); - PortDirection *dir = network_->direction(pin); - if (dir->isAnyOutput()) { - LibertyPort *port = network_->libertyPort(pin); - if (port) { + LibertyPort *port = network_->libertyPort(pin); + if (port) { + PortDirection *dir = port->direction(); + if (dir->isAnyOutput()) { LogicValue value = LogicValue::unknown; FuncExpr *expr = port->function(); + LibertyCell *cell = port->libertyCell(); if (expr) { FuncExpr *tri_en_expr = port->tristateEnable(); if (tri_en_expr) { @@ -932,11 +941,26 @@ Sim::evalInstance(const Instance *inst) } } else { - value = evalExpr(expr, inst); - debugPrint(debug_, "sim", 2, " %s %s = %c", - port->name(), - expr->asString(), - logicValueString(value)); + Sequential *sequential = nullptr; + if (thru_sequentials) { + LibertyPort *expr_port = expr->port(); + if (expr_port) + sequential = cell->outputPortSequential(expr_port); + } + if (sequential) { + value = evalExpr(sequential->data(), inst); + debugPrint(debug_, "sim", 2, " %s seq %s = %c", + port->name(), + expr->asString(), + logicValueString(value)); + } + else { + value = evalExpr(expr, inst); + debugPrint(debug_, "sim", 2, " %s %s = %c", + port->name(), + expr->asString(), + logicValueString(value)); + } } } else if (port->isClockGateOutPin()) { @@ -945,16 +969,8 @@ Sim::evalInstance(const Instance *inst) port->name(), logicValueString(value)); } - FuncExpr *tri_en_expr = port->tristateEnable(); - if (tri_en_expr == nullptr - || evalExpr(tri_en_expr, inst) == LogicValue::one) { - debugPrint(debug_, "sim", 2, " %s %s = %c", - port->name(), - expr ? expr->asString() : "gated_clk", - logicValueString(value)); - if (value != logicValue(pin)) - setPinValue(pin, value, true); - } + if (value != logicValue(pin)) + setPinValue(pin, value); } } } diff --git a/search/Sim.hh b/search/Sim.hh index 21e46a94..a9ee4f99 100644 --- a/search/Sim.hh +++ b/search/Sim.hh @@ -60,6 +60,7 @@ public: virtual TimingSense functionSense(const Instance *inst, const Pin *from_pin, const Pin *to_pin); + void findLogicConstants(); // Network edits. void deleteInstanceBefore(Instance *inst); @@ -74,17 +75,16 @@ protected: void recordConstPinFunc(Pin *pin); virtual void seedConstants(); void seedInvalidConstants(); - void propagateConstants(); - void setConstraintConstPins(LogicValueMap *pin_value_map, - bool propagate); - void setConstFuncPins(bool propagate); + void propagateConstants(bool thru_sequentials); + void setConstraintConstPins(LogicValueMap *pin_value_map); + void setConstFuncPins(); LogicValue pinConstFuncValue(Pin *pin); - void enqueueConstantPinInputs(bool propagate); + void enqueueConstantPinInputs(); virtual void setPinValue(const Pin *pin, - LogicValue value, - bool propagate); + LogicValue value); void enqueue(const Instance *inst); - void evalInstance(const Instance *inst); + void evalInstance(const Instance *inst, + bool thru_sequentials); LogicValue clockGateOutValue(const Instance *inst); TimingSense functionSense(const FuncExpr *expr, const Pin *input_pin, diff --git a/search/Sta.cc b/search/Sta.cc index 262e4193..f2fc200e 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -3444,6 +3444,12 @@ Sta::simLogicValue(const Pin *pin) return sim_->logicValue(pin); } +void +Sta::findLogicConstants() +{ + sim_->findLogicConstants(); +} + void Sta::setPortExtPinCap(Port *port, const RiseFallBoth *rf,