factor variables out of sdc
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
5bb4d58d69
commit
6ebd162d42
|
|
@ -155,6 +155,7 @@ set(STA_SOURCE
|
||||||
sdc/Sdc.cc
|
sdc/Sdc.cc
|
||||||
sdc/SdcGraph.cc
|
sdc/SdcGraph.cc
|
||||||
sdc/SdcCmdComment.cc
|
sdc/SdcCmdComment.cc
|
||||||
|
sdc/Variables.cc
|
||||||
sdc/WriteSdc.cc
|
sdc/WriteSdc.cc
|
||||||
|
|
||||||
sdf/ReportAnnotation.cc
|
sdf/ReportAnnotation.cc
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@
|
||||||
#include "ArcDelayCalc.hh"
|
#include "ArcDelayCalc.hh"
|
||||||
#include "LumpedCapDelayCalc.hh"
|
#include "LumpedCapDelayCalc.hh"
|
||||||
#include "GraphDelayCalc.hh"
|
#include "GraphDelayCalc.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
#include "Arnoldi.hh"
|
#include "Arnoldi.hh"
|
||||||
#include "ArnoldiReduce.hh"
|
#include "ArnoldiReduce.hh"
|
||||||
|
|
||||||
|
|
@ -234,6 +235,7 @@ private:
|
||||||
ArnoldiReduce *reduce_;
|
ArnoldiReduce *reduce_;
|
||||||
delay_work *delay_work_;
|
delay_work *delay_work_;
|
||||||
vector<rcmodel*> unsaved_parasitics_;
|
vector<rcmodel*> unsaved_parasitics_;
|
||||||
|
bool pocv_enabled_;
|
||||||
};
|
};
|
||||||
|
|
||||||
ArcDelayCalc *
|
ArcDelayCalc *
|
||||||
|
|
@ -391,6 +393,7 @@ ArnoldiDelayCalc::gateDelay(const Pin *drvr_pin,
|
||||||
ConcreteParasitic *cparasitic =
|
ConcreteParasitic *cparasitic =
|
||||||
reinterpret_cast<ConcreteParasitic*>(const_cast<Parasitic*>(parasitic));
|
reinterpret_cast<ConcreteParasitic*>(const_cast<Parasitic*>(parasitic));
|
||||||
rcmodel_ = dynamic_cast<rcmodel*>(cparasitic);
|
rcmodel_ = dynamic_cast<rcmodel*>(cparasitic);
|
||||||
|
pocv_enabled_ = variables_->pocvEnabled();
|
||||||
GateTableModel *table_model = arc->gateTableModel(dcalc_ap);
|
GateTableModel *table_model = arc->gateTableModel(dcalc_ap);
|
||||||
if (table_model && rcmodel_) {
|
if (table_model && rcmodel_) {
|
||||||
const Pvt *pvt = pinPvt(drvr_pin, dcalc_ap);
|
const Pvt *pvt = pinPvt(drvr_pin, dcalc_ap);
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#include "Corner.hh"
|
#include "Corner.hh"
|
||||||
#include "DcalcAnalysisPt.hh"
|
#include "DcalcAnalysisPt.hh"
|
||||||
#include "GraphDelayCalc.hh"
|
#include "GraphDelayCalc.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -167,7 +168,8 @@ DelayCalcBase::checkDelay(const Pin *check_pin,
|
||||||
float from_slew1 = delayAsFloat(from_slew);
|
float from_slew1 = delayAsFloat(from_slew);
|
||||||
float to_slew1 = delayAsFloat(to_slew);
|
float to_slew1 = delayAsFloat(to_slew);
|
||||||
return model->checkDelay(pinPvt(check_pin, dcalc_ap), from_slew1, to_slew1,
|
return model->checkDelay(pinPvt(check_pin, dcalc_ap), from_slew1, to_slew1,
|
||||||
related_out_cap, pocv_enabled_);
|
related_out_cap,
|
||||||
|
variables_->pocvEnabled());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return delay_zero;
|
return delay_zero;
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@
|
||||||
#include "DcalcAnalysisPt.hh"
|
#include "DcalcAnalysisPt.hh"
|
||||||
#include "ArcDelayCalc.hh"
|
#include "ArcDelayCalc.hh"
|
||||||
#include "FindRoot.hh"
|
#include "FindRoot.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -371,7 +372,8 @@ DmpAlg::gateCapDelaySlew(double ceff,
|
||||||
{
|
{
|
||||||
ArcDelay model_delay;
|
ArcDelay model_delay;
|
||||||
Slew model_slew;
|
Slew model_slew;
|
||||||
gate_model_->gateDelay(pvt_, in_slew_, ceff, pocv_enabled_,
|
gate_model_->gateDelay(pvt_, in_slew_, ceff,
|
||||||
|
variables_->pocvEnabled(),
|
||||||
model_delay, model_slew);
|
model_delay, model_slew);
|
||||||
delay = delayAsFloat(model_delay);
|
delay = delayAsFloat(model_delay);
|
||||||
slew = delayAsFloat(model_slew);
|
slew = delayAsFloat(model_slew);
|
||||||
|
|
@ -1562,7 +1564,7 @@ DmpCeffDelayCalc::setCeffAlgorithm(const LibertyLibrary *drvr_library,
|
||||||
double rd = 0.0;
|
double rd = 0.0;
|
||||||
if (gate_model) {
|
if (gate_model) {
|
||||||
rd = gateModelRd(drvr_cell, gate_model, rf, in_slew, c2, c1,
|
rd = gateModelRd(drvr_cell, gate_model, rf, in_slew, c2, c1,
|
||||||
pvt, pocv_enabled_);
|
pvt, variables_->pocvEnabled());
|
||||||
// Zero Rd means the table is constant and thus independent of load cap.
|
// Zero Rd means the table is constant and thus independent of load cap.
|
||||||
if (rd < 1e-2
|
if (rd < 1e-2
|
||||||
// Rpi is small compared to Rd, which makes the load capacitive.
|
// Rpi is small compared to Rd, which makes the load capacitive.
|
||||||
|
|
@ -1630,9 +1632,10 @@ DmpCeffDelayCalc::reportGateDelay(const Pin *drvr_pin,
|
||||||
const Unit *time_unit = units->timeUnit();
|
const Unit *time_unit = units->timeUnit();
|
||||||
float in_slew1 = delayAsFloat(in_slew);
|
float in_slew1 = delayAsFloat(in_slew);
|
||||||
result += model->reportGateDelay(pinPvt(drvr_pin, dcalc_ap), in_slew1, c_eff,
|
result += model->reportGateDelay(pinPvt(drvr_pin, dcalc_ap), in_slew1, c_eff,
|
||||||
pocv_enabled_, digits);
|
variables_->pocvEnabled(), digits);
|
||||||
result += "Driver waveform slew = ";
|
result += "Driver waveform slew = ";
|
||||||
result += time_unit->asString(dcalc_result.drvrSlew(), digits);
|
float drvr_slew = delayAsFloat(dcalc_result.drvrSlew());
|
||||||
|
result += time_unit->asString(drvr_slew, digits);
|
||||||
result += '\n';
|
result += '\n';
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@
|
||||||
#include "DcalcAnalysisPt.hh"
|
#include "DcalcAnalysisPt.hh"
|
||||||
#include "NetCaps.hh"
|
#include "NetCaps.hh"
|
||||||
#include "ClkNetwork.hh"
|
#include "ClkNetwork.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -365,7 +366,7 @@ GraphDelayCalc::seedNoDrvrCellSlew(Vertex *drvr_vertex,
|
||||||
else {
|
else {
|
||||||
// Top level bidirect driver uses load slew unless
|
// Top level bidirect driver uses load slew unless
|
||||||
// bidirect instance paths are disabled.
|
// bidirect instance paths are disabled.
|
||||||
if (sdc_->bidirectDrvrSlewFromLoad(drvr_pin)) {
|
if (bidirectDrvrSlewFromLoad(drvr_pin)) {
|
||||||
Vertex *load_vertex = graph_->pinLoadVertex(drvr_pin);
|
Vertex *load_vertex = graph_->pinLoadVertex(drvr_pin);
|
||||||
slew = graph_->slew(load_vertex, rf, ap_index);
|
slew = graph_->slew(load_vertex, rf, ap_index);
|
||||||
}
|
}
|
||||||
|
|
@ -393,6 +394,17 @@ GraphDelayCalc::seedNoDrvrCellSlew(Vertex *drvr_vertex,
|
||||||
arc_delay_calc->finishDrvrPin();
|
arc_delay_calc->finishDrvrPin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delay calculation propagates slews from a bidirect driver
|
||||||
|
// to the bidirect port and back through the bidirect driver when
|
||||||
|
// sta_bidirect_inst_paths_enabled_ is true.
|
||||||
|
bool
|
||||||
|
GraphDelayCalc::bidirectDrvrSlewFromLoad(const Pin *pin) const
|
||||||
|
{
|
||||||
|
return variables_->bidirectInstPathsEnabled()
|
||||||
|
&& network_->direction(pin)->isBidirect()
|
||||||
|
&& network_->isTopLevelPort(pin);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GraphDelayCalc::seedNoDrvrSlew(Vertex *drvr_vertex,
|
GraphDelayCalc::seedNoDrvrSlew(Vertex *drvr_vertex,
|
||||||
const Pin *drvr_pin,
|
const Pin *drvr_pin,
|
||||||
|
|
@ -405,7 +417,7 @@ GraphDelayCalc::seedNoDrvrSlew(Vertex *drvr_vertex,
|
||||||
Slew slew(default_slew);
|
Slew slew(default_slew);
|
||||||
// Top level bidirect driver uses load slew unless
|
// Top level bidirect driver uses load slew unless
|
||||||
// bidirect instance paths are disabled.
|
// bidirect instance paths are disabled.
|
||||||
if (sdc_->bidirectDrvrSlewFromLoad(drvr_pin)) {
|
if (bidirectDrvrSlewFromLoad(drvr_pin)) {
|
||||||
Vertex *load_vertex = graph_->pinLoadVertex(drvr_pin);
|
Vertex *load_vertex = graph_->pinLoadVertex(drvr_pin);
|
||||||
slew = graph_->slew(load_vertex, rf, ap_index);
|
slew = graph_->slew(load_vertex, rf, ap_index);
|
||||||
}
|
}
|
||||||
|
|
@ -1185,7 +1197,7 @@ GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex,
|
||||||
if (load_changed && observer_)
|
if (load_changed && observer_)
|
||||||
observer_->delayChangedTo(load_vertex);
|
observer_->delayChangedTo(load_vertex);
|
||||||
// Enqueue bidirect driver from load vertex.
|
// Enqueue bidirect driver from load vertex.
|
||||||
if (sdc_->bidirectDrvrSlewFromLoad(load_pin))
|
if (bidirectDrvrSlewFromLoad(load_pin))
|
||||||
iter_->enqueue(graph_->pinDrvrVertex(load_pin));
|
iter_->enqueue(graph_->pinDrvrVertex(load_pin));
|
||||||
changed |= load_changed;
|
changed |= load_changed;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include "Parasitics.hh"
|
#include "Parasitics.hh"
|
||||||
#include "DcalcAnalysisPt.hh"
|
#include "DcalcAnalysisPt.hh"
|
||||||
#include "GraphDelayCalc.hh"
|
#include "GraphDelayCalc.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -144,7 +145,8 @@ LumpedCapDelayCalc::gateDelay(const Pin *drvr_pin,
|
||||||
// NaNs cause seg faults during table lookup.
|
// NaNs cause seg faults during table lookup.
|
||||||
if (isnan(load_cap) || isnan(delayAsFloat(in_slew)))
|
if (isnan(load_cap) || isnan(delayAsFloat(in_slew)))
|
||||||
report_->error(1350, "gate delay input variable is NaN");
|
report_->error(1350, "gate delay input variable is NaN");
|
||||||
model->gateDelay(pinPvt(drvr_pin, dcalc_ap), in_slew1, load_cap, pocv_enabled_,
|
model->gateDelay(pinPvt(drvr_pin, dcalc_ap), in_slew1, load_cap,
|
||||||
|
variables_->pocvEnabled(),
|
||||||
gate_delay, drvr_slew);
|
gate_delay, drvr_slew);
|
||||||
return makeResult(drvr_library, rf, gate_delay, drvr_slew, load_pin_index_map);
|
return makeResult(drvr_library, rf, gate_delay, drvr_slew, load_pin_index_map);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "Fuzzy.hh"
|
#include "Fuzzy.hh"
|
||||||
#include "Units.hh"
|
#include "Units.hh"
|
||||||
#include "StaState.hh"
|
#include "StaState.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
|
||||||
// SSTA compilation.
|
// SSTA compilation.
|
||||||
#if (SSTA == 1)
|
#if (SSTA == 1)
|
||||||
|
|
@ -237,7 +238,7 @@ delayAsFloat(const Delay &delay,
|
||||||
const EarlyLate *early_late,
|
const EarlyLate *early_late,
|
||||||
const StaState *sta)
|
const StaState *sta)
|
||||||
{
|
{
|
||||||
if (sta->pocvEnabled()) {
|
if (sta->variables()->pocvEnabled()) {
|
||||||
if (early_late == EarlyLate::early())
|
if (early_late == EarlyLate::early())
|
||||||
return delay.mean() - delay.sigma() * sta->sigmaFactor();
|
return delay.mean() - delay.sigma() * sta->sigmaFactor();
|
||||||
else if (early_late == EarlyLate::late())
|
else if (early_late == EarlyLate::late())
|
||||||
|
|
@ -268,7 +269,7 @@ delayAsString(const Delay &delay,
|
||||||
int digits)
|
int digits)
|
||||||
{
|
{
|
||||||
const Unit *unit = sta->units()->timeUnit();
|
const Unit *unit = sta->units()->timeUnit();
|
||||||
if (sta->pocvEnabled()) {
|
if (sta->variables()->pocvEnabled()) {
|
||||||
float sigma = delay.sigma();
|
float sigma = delay.sigma();
|
||||||
return stringPrintTmp("%s[%s]",
|
return stringPrintTmp("%s[%s]",
|
||||||
unit->asString(delay.mean(), digits),
|
unit->asString(delay.mean(), digits),
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,7 @@ public:
|
||||||
const RiseFall *from_rf,
|
const RiseFall *from_rf,
|
||||||
const TimingRole *role,
|
const TimingRole *role,
|
||||||
const DcalcAnalysisPt *dcalc_ap);
|
const DcalcAnalysisPt *dcalc_ap);
|
||||||
|
bool bidirectDrvrSlewFromLoad(const Pin *pin) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void seedInvalidDelays();
|
void seedInvalidDelays();
|
||||||
|
|
@ -246,7 +247,6 @@ protected:
|
||||||
Slew checkEdgeClkSlew(const Vertex *from_vertex,
|
Slew checkEdgeClkSlew(const Vertex *from_vertex,
|
||||||
const RiseFall *from_rf,
|
const RiseFall *from_rf,
|
||||||
const DcalcAnalysisPt *dcalc_ap);
|
const DcalcAnalysisPt *dcalc_ap);
|
||||||
bool bidirectDrvrSlewFromLoad(const Vertex *vertex) const;
|
|
||||||
float loadCap(const Pin *drvr_pin,
|
float loadCap(const Pin *drvr_pin,
|
||||||
const RiseFall *rf,
|
const RiseFall *rf,
|
||||||
const DcalcAnalysisPt *dcalc_ap,
|
const DcalcAnalysisPt *dcalc_ap,
|
||||||
|
|
|
||||||
|
|
@ -733,6 +733,7 @@ public:
|
||||||
// combinational loops when dynamic loop breaking is enabled.
|
// combinational loops when dynamic loop breaking is enabled.
|
||||||
void makeLoopExceptions();
|
void makeLoopExceptions();
|
||||||
void makeLoopExceptions(GraphLoop *loop);
|
void makeLoopExceptions(GraphLoop *loop);
|
||||||
|
void deleteLoopExceptions();
|
||||||
void makeMulticyclePath(ExceptionFrom *from,
|
void makeMulticyclePath(ExceptionFrom *from,
|
||||||
ExceptionThruSeq *thrus,
|
ExceptionThruSeq *thrus,
|
||||||
ExceptionTo *to,
|
ExceptionTo *to,
|
||||||
|
|
@ -793,54 +794,6 @@ public:
|
||||||
const WireloadSelection *wireloadSelection(const MinMax *min_max);
|
const WireloadSelection *wireloadSelection(const MinMax *min_max);
|
||||||
void setWireloadSelection(WireloadSelection *selection,
|
void setWireloadSelection(WireloadSelection *selection,
|
||||||
const MinMaxAll *min_max);
|
const MinMaxAll *min_max);
|
||||||
// Common reconvergent clock pessimism.
|
|
||||||
// TCL variable sta_crpr_enabled.
|
|
||||||
bool crprEnabled() const;
|
|
||||||
void setCrprEnabled(bool enabled);
|
|
||||||
// TCL variable sta_crpr_mode.
|
|
||||||
CrprMode crprMode() const;
|
|
||||||
void setCrprMode(CrprMode mode);
|
|
||||||
// True when analysis type is on chip variation and crpr is enabled.
|
|
||||||
bool crprActive() const;
|
|
||||||
// TCL variable sta_propagate_gated_clock_enable.
|
|
||||||
// Propagate gated clock enable arrivals.
|
|
||||||
bool propagateGatedClockEnable() const;
|
|
||||||
void setPropagateGatedClockEnable(bool enable);
|
|
||||||
// TCL variable sta_preset_clear_arcs_enabled.
|
|
||||||
// Enable search through preset/clear arcs.
|
|
||||||
bool presetClrArcsEnabled() const;
|
|
||||||
void setPresetClrArcsEnabled(bool enable);
|
|
||||||
// TCL variable sta_cond_default_arcs_enabled.
|
|
||||||
// Enable/disable default arcs when conditional arcs exist.
|
|
||||||
bool condDefaultArcsEnabled() const;
|
|
||||||
void setCondDefaultArcsEnabled(bool enabled);
|
|
||||||
bool isDisabledCondDefault(Edge *edge) const;
|
|
||||||
// TCL variable sta_internal_bidirect_instance_paths_enabled.
|
|
||||||
// Enable/disable timing from bidirect pins back into the instance.
|
|
||||||
bool bidirectInstPathsEnabled() const;
|
|
||||||
void setBidirectInstPathsEnabled(bool enabled);
|
|
||||||
// TCL variable sta_bidirect_net_paths_enabled.
|
|
||||||
// Enable/disable timing from bidirect driver pins to their own loads.
|
|
||||||
bool bidirectNetPathsEnabled() const;
|
|
||||||
void setBidirectNetPathsEnabled(bool enabled);
|
|
||||||
// TCL variable sta_recovery_removal_checks_enabled.
|
|
||||||
bool recoveryRemovalChecksEnabled() const;
|
|
||||||
void setRecoveryRemovalChecksEnabled(bool enabled);
|
|
||||||
// TCL variable sta_gated_clock_checks_enabled.
|
|
||||||
bool gatedClkChecksEnabled() const;
|
|
||||||
void setGatedClkChecksEnabled(bool enabled);
|
|
||||||
// TCL variable sta_dynamic_loop_breaking.
|
|
||||||
bool dynamicLoopBreaking() const;
|
|
||||||
void setDynamicLoopBreaking(bool enable);
|
|
||||||
// TCL variable sta_propagate_all_clocks.
|
|
||||||
bool propagateAllClocks() const;
|
|
||||||
void setPropagateAllClocks(bool prop);
|
|
||||||
// TCL var sta_clock_through_tristate_enabled.
|
|
||||||
bool clkThruTristateEnabled() const;
|
|
||||||
void setClkThruTristateEnabled(bool enable);
|
|
||||||
// TCL variable sta_input_port_default_clock.
|
|
||||||
bool useDefaultArrivalClock();
|
|
||||||
void setUseDefaultArrivalClock(bool enable);
|
|
||||||
|
|
||||||
// STA interface.
|
// STA interface.
|
||||||
InputDelaySet *refPinInputDelays(const Pin *ref_pin) const;
|
InputDelaySet *refPinInputDelays(const Pin *ref_pin) const;
|
||||||
|
|
@ -1071,7 +1024,6 @@ public:
|
||||||
const Pin *drvr,
|
const Pin *drvr,
|
||||||
const Pin *load);
|
const Pin *load);
|
||||||
void ensureClkHpinDisables();
|
void ensureClkHpinDisables();
|
||||||
bool bidirectDrvrSlewFromLoad(const Pin *pin) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void portMembers(const Port *port,
|
void portMembers(const Port *port,
|
||||||
|
|
@ -1214,7 +1166,6 @@ protected:
|
||||||
const Pin *loop_prev_pin);
|
const Pin *loop_prev_pin);
|
||||||
void makeLoopExceptionThru(const Pin *pin,
|
void makeLoopExceptionThru(const Pin *pin,
|
||||||
ExceptionThruSeq *thrus);
|
ExceptionThruSeq *thrus);
|
||||||
void deleteLoopExceptions();
|
|
||||||
void deleteConstraints();
|
void deleteConstraints();
|
||||||
InputDelay *findInputDelay(const Pin *pin,
|
InputDelay *findInputDelay(const Pin *pin,
|
||||||
const ClockEdge *clk_edge);
|
const ClockEdge *clk_edge);
|
||||||
|
|
@ -1317,7 +1268,6 @@ protected:
|
||||||
int clk_index_;
|
int clk_index_;
|
||||||
// Default clock used for unclocked input arrivals.
|
// Default clock used for unclocked input arrivals.
|
||||||
Clock *default_arrival_clk_;
|
Clock *default_arrival_clk_;
|
||||||
bool use_default_arrival_clock_;
|
|
||||||
ClockNameMap clock_name_map_;
|
ClockNameMap clock_name_map_;
|
||||||
ClockPinMap clock_pin_map_;
|
ClockPinMap clock_pin_map_;
|
||||||
// Clocks on hierarchical pins are indexed by the load pins.
|
// Clocks on hierarchical pins are indexed by the load pins.
|
||||||
|
|
@ -1430,19 +1380,6 @@ protected:
|
||||||
Wireload *wireload_[MinMax::index_count];
|
Wireload *wireload_[MinMax::index_count];
|
||||||
WireloadMode wireload_mode_;
|
WireloadMode wireload_mode_;
|
||||||
WireloadSelection *wireload_selection_[MinMax::index_count];
|
WireloadSelection *wireload_selection_[MinMax::index_count];
|
||||||
bool crpr_enabled_;
|
|
||||||
CrprMode crpr_mode_;
|
|
||||||
bool pocv_enabled_;
|
|
||||||
bool propagate_gated_clock_enable_;
|
|
||||||
bool preset_clr_arcs_enabled_;
|
|
||||||
bool cond_default_arcs_enabled_;
|
|
||||||
bool bidirect_net_paths_enabled_;
|
|
||||||
bool bidirect_inst_paths_enabled_;
|
|
||||||
bool recovery_removal_checks_enabled_;
|
|
||||||
bool gated_clk_checks_enabled_;
|
|
||||||
bool clk_thru_tristate_enabled_;
|
|
||||||
bool dynamic_loop_breaking_;
|
|
||||||
bool propagate_all_clks_;
|
|
||||||
|
|
||||||
// Annotations on graph objects that are stored in constraints
|
// Annotations on graph objects that are stored in constraints
|
||||||
// rather on the graph itself.
|
// rather on the graph itself.
|
||||||
|
|
|
||||||
|
|
@ -122,8 +122,6 @@ public:
|
||||||
class ExceptionPath;
|
class ExceptionPath;
|
||||||
typedef Set<ExceptionState*, ExceptionStateLess> ExceptionStateSet;
|
typedef Set<ExceptionState*, ExceptionStateLess> ExceptionStateSet;
|
||||||
|
|
||||||
enum class CrprMode { same_pin, same_transition };
|
|
||||||
|
|
||||||
// Constraint applies to clock or data paths.
|
// Constraint applies to clock or data paths.
|
||||||
enum class PathClkOrData { clk, data };
|
enum class PathClkOrData { clk, data };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -861,11 +861,11 @@ protected:
|
||||||
class DynLoopSrchPred
|
class DynLoopSrchPred
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DynLoopSrchPred(TagGroupBldr *tag_bldr);
|
DynLoopSrchPred(TagGroupBldr *tag_bldr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool loopEnabled(Edge *edge,
|
bool loopEnabled(Edge *edge,
|
||||||
const Sdc *sdc,
|
bool dynamic_loop_breaking_enabled,
|
||||||
const Graph *graph,
|
const Graph *graph,
|
||||||
Search *search);
|
Search *search);
|
||||||
bool hasPendingLoopPaths(Edge *edge,
|
bool hasPendingLoopPaths(Edge *edge,
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
#include "PowerClass.hh"
|
#include "PowerClass.hh"
|
||||||
#include "ArcDelayCalc.hh"
|
#include "ArcDelayCalc.hh"
|
||||||
#include "CircuitSim.hh"
|
#include "CircuitSim.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
|
||||||
struct Tcl_Interp;
|
struct Tcl_Interp;
|
||||||
|
|
||||||
|
|
@ -436,8 +437,6 @@ public:
|
||||||
void removeDisable(TimingArcSet *arc_set);
|
void removeDisable(TimingArcSet *arc_set);
|
||||||
// Edge is disabled by constant.
|
// Edge is disabled by constant.
|
||||||
bool isDisabledConstant(Edge *edge);
|
bool isDisabledConstant(Edge *edge);
|
||||||
// Edge is default cond disabled by timing_disable_cond_default_arcs var.
|
|
||||||
bool isDisabledCondDefault(Edge *edge);
|
|
||||||
// Return a set of constant pins that disabled edge.
|
// Return a set of constant pins that disabled edge.
|
||||||
// Caller owns the returned set.
|
// Caller owns the returned set.
|
||||||
PinSet disabledConstantPins(Edge *edge);
|
PinSet disabledConstantPins(Edge *edge);
|
||||||
|
|
@ -793,61 +792,7 @@ public:
|
||||||
bool no_version);
|
bool no_version);
|
||||||
// Remove all delay and slew annotations.
|
// Remove all delay and slew annotations.
|
||||||
void removeDelaySlewAnnotations();
|
void removeDelaySlewAnnotations();
|
||||||
// TCL variable sta_crpr_enabled.
|
|
||||||
// Common Reconvergent Clock Removal (CRPR).
|
|
||||||
// Timing check source/target common clock path overlap for search
|
|
||||||
// with analysis mode on_chip_variation.
|
|
||||||
bool crprEnabled() const;
|
|
||||||
void setCrprEnabled(bool enabled);
|
|
||||||
// TCL variable sta_crpr_mode.
|
|
||||||
CrprMode crprMode() const;
|
|
||||||
void setCrprMode(CrprMode mode);
|
|
||||||
// TCL variable sta_pocv_enabled.
|
|
||||||
// Parametric on chip variation (statisical sta).
|
|
||||||
bool pocvEnabled() const;
|
|
||||||
void setPocvEnabled(bool enabled);
|
|
||||||
// Number of std deviations from mean to use for normal distributions.
|
|
||||||
void setSigmaFactor(float factor);
|
|
||||||
// TCL variable sta_propagate_gated_clock_enable.
|
|
||||||
// Propagate gated clock enable arrivals.
|
|
||||||
bool propagateGatedClockEnable() const;
|
|
||||||
void setPropagateGatedClockEnable(bool enable);
|
|
||||||
// TCL variable sta_preset_clear_arcs_enabled.
|
|
||||||
// Enable search through preset/clear arcs.
|
|
||||||
bool presetClrArcsEnabled() const;
|
|
||||||
void setPresetClrArcsEnabled(bool enable);
|
|
||||||
// TCL variable sta_cond_default_arcs_enabled.
|
|
||||||
// Enable/disable default arcs when conditional arcs exist.
|
|
||||||
bool condDefaultArcsEnabled() const;
|
|
||||||
void setCondDefaultArcsEnabled(bool enabled);
|
|
||||||
// TCL variable sta_internal_bidirect_instance_paths_enabled.
|
|
||||||
// Enable/disable timing from bidirect pins back into the instance.
|
|
||||||
bool bidirectInstPathsEnabled() const;
|
|
||||||
void setBidirectInstPathsEnabled(bool enabled);
|
|
||||||
// TCL variable sta_bidirect_net_paths_enabled.
|
|
||||||
// Enable/disable timing from bidirect driver pins to their own loads.
|
|
||||||
bool bidirectNetPathsEnabled() const;
|
|
||||||
void setBidirectNetPathsEnabled(bool enabled);
|
|
||||||
// TCL variable sta_recovery_removal_checks_enabled.
|
|
||||||
bool recoveryRemovalChecksEnabled() const;
|
|
||||||
void setRecoveryRemovalChecksEnabled(bool enabled);
|
|
||||||
// TCL variable sta_gated_clock_checks_enabled.
|
|
||||||
bool gatedClkChecksEnabled() const;
|
|
||||||
void setGatedClkChecksEnabled(bool enabled);
|
|
||||||
// TCL variable sta_dynamic_loop_breaking.
|
|
||||||
bool dynamicLoopBreaking() const;
|
|
||||||
void setDynamicLoopBreaking(bool enable);
|
|
||||||
// TCL variable sta_propagate_all_clocks.
|
|
||||||
// Clocks defined after sta_propagate_all_clocks is true
|
|
||||||
// are propagated (existing clocks are not effected).
|
|
||||||
bool propagateAllClocks() const;
|
|
||||||
void setPropagateAllClocks(bool prop);
|
|
||||||
// TCL var sta_clock_through_tristate_enabled.
|
|
||||||
bool clkThruTristateEnabled() const;
|
|
||||||
void setClkThruTristateEnabled(bool enable);
|
|
||||||
// TCL variable sta_input_port_default_clock.
|
|
||||||
bool useDefaultArrivalClock() const;
|
|
||||||
void setUseDefaultArrivalClock(bool enable);
|
|
||||||
virtual CheckErrorSeq &checkTiming(bool no_input_delay,
|
virtual CheckErrorSeq &checkTiming(bool no_input_delay,
|
||||||
bool no_output_delay,
|
bool no_output_delay,
|
||||||
bool reg_multiple_clks,
|
bool reg_multiple_clks,
|
||||||
|
|
@ -1178,7 +1123,9 @@ public:
|
||||||
bool includes_pin_caps,
|
bool includes_pin_caps,
|
||||||
const ParasiticAnalysisPt *ap);
|
const ParasiticAnalysisPt *ap);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
// TCL network edit function support.
|
// TCL network edit function support.
|
||||||
|
|
||||||
virtual Instance *makeInstance(const char *name,
|
virtual Instance *makeInstance(const char *name,
|
||||||
LibertyCell *cell,
|
LibertyCell *cell,
|
||||||
Instance *parent);
|
Instance *parent);
|
||||||
|
|
@ -1322,10 +1269,71 @@ public:
|
||||||
const char *gnd_name,
|
const char *gnd_name,
|
||||||
CircuitSim ckt_sim);
|
CircuitSim ckt_sim);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
// TCL Variables
|
||||||
|
|
||||||
|
// TCL variable sta_crpr_enabled.
|
||||||
|
// Common Reconvergent Clock Removal (CRPR).
|
||||||
|
// Timing check source/target common clock path overlap for search
|
||||||
|
// with analysis mode on_chip_variation.
|
||||||
|
bool crprEnabled() const;
|
||||||
|
void setCrprEnabled(bool enabled);
|
||||||
|
// TCL variable sta_crpr_mode.
|
||||||
|
CrprMode crprMode() const;
|
||||||
|
void setCrprMode(CrprMode mode);
|
||||||
|
// TCL variable sta_pocv_enabled.
|
||||||
|
// Parametric on chip variation (statisical sta).
|
||||||
|
bool pocvEnabled() const;
|
||||||
|
void setPocvEnabled(bool enabled);
|
||||||
|
// Number of std deviations from mean to use for normal distributions.
|
||||||
|
void setSigmaFactor(float factor);
|
||||||
|
// TCL variable sta_propagate_gated_clock_enable.
|
||||||
|
// Propagate gated clock enable arrivals.
|
||||||
|
bool propagateGatedClockEnable() const;
|
||||||
|
void setPropagateGatedClockEnable(bool enable);
|
||||||
|
// TCL variable sta_preset_clear_arcs_enabled.
|
||||||
|
// Enable search through preset/clear arcs.
|
||||||
|
bool presetClrArcsEnabled() const;
|
||||||
|
void setPresetClrArcsEnabled(bool enable);
|
||||||
|
// TCL variable sta_cond_default_arcs_enabled.
|
||||||
|
// Enable/disable default arcs when conditional arcs exist.
|
||||||
|
bool condDefaultArcsEnabled() const;
|
||||||
|
void setCondDefaultArcsEnabled(bool enabled);
|
||||||
|
// TCL variable sta_internal_bidirect_instance_paths_enabled.
|
||||||
|
// Enable/disable timing from bidirect pins back into the instance.
|
||||||
|
bool bidirectInstPathsEnabled() const;
|
||||||
|
void setBidirectInstPathsEnabled(bool enabled);
|
||||||
|
// TCL variable sta_bidirect_net_paths_enabled.
|
||||||
|
// Enable/disable timing from bidirect driver pins to their own loads.
|
||||||
|
bool bidirectNetPathsEnabled() const;
|
||||||
|
void setBidirectNetPathsEnabled(bool enabled);
|
||||||
|
// TCL variable sta_recovery_removal_checks_enabled.
|
||||||
|
bool recoveryRemovalChecksEnabled() const;
|
||||||
|
void setRecoveryRemovalChecksEnabled(bool enabled);
|
||||||
|
// TCL variable sta_gated_clock_checks_enabled.
|
||||||
|
bool gatedClkChecksEnabled() const;
|
||||||
|
void setGatedClkChecksEnabled(bool enabled);
|
||||||
|
// TCL variable sta_dynamic_loop_breaking.
|
||||||
|
bool dynamicLoopBreaking() const;
|
||||||
|
void setDynamicLoopBreaking(bool enable);
|
||||||
|
// TCL variable sta_propagate_all_clocks.
|
||||||
|
// Clocks defined after sta_propagate_all_clocks is true
|
||||||
|
// are propagated (existing clocks are not effected).
|
||||||
|
bool propagateAllClocks() const;
|
||||||
|
void setPropagateAllClocks(bool prop);
|
||||||
|
// TCL var sta_clock_through_tristate_enabled.
|
||||||
|
bool clkThruTristateEnabled() const;
|
||||||
|
void setClkThruTristateEnabled(bool enable);
|
||||||
|
// TCL variable sta_input_port_default_clock.
|
||||||
|
bool useDefaultArrivalClock() const;
|
||||||
|
void setUseDefaultArrivalClock(bool enable);
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Default constructors that are called by makeComponents in the Sta
|
// Default constructors that are called by makeComponents in the Sta
|
||||||
// constructor. These can be redefined by a derived class to
|
// constructor. These can be redefined by a derived class to
|
||||||
// specialize the sta components.
|
// specialize the sta components.
|
||||||
|
virtual void makeVariables();
|
||||||
virtual void makeReport();
|
virtual void makeReport();
|
||||||
virtual void makeDebug();
|
virtual void makeDebug();
|
||||||
virtual void makeUnits();
|
virtual void makeUnits();
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ class NetworkReader;
|
||||||
class Sdc;
|
class Sdc;
|
||||||
class Corners;
|
class Corners;
|
||||||
class Graph;
|
class Graph;
|
||||||
|
class Edge;
|
||||||
class Levelize;
|
class Levelize;
|
||||||
class Sim;
|
class Sim;
|
||||||
class Search;
|
class Search;
|
||||||
|
|
@ -44,6 +45,7 @@ class GraphDelayCalc;
|
||||||
class Latches;
|
class Latches;
|
||||||
class ClkNetwork;
|
class ClkNetwork;
|
||||||
class DispatchQueue;
|
class DispatchQueue;
|
||||||
|
class Variables;
|
||||||
|
|
||||||
// Most STA components use functionality in other components.
|
// Most STA components use functionality in other components.
|
||||||
// This class simplifies the process of copying pointers to the
|
// This class simplifies the process of copying pointers to the
|
||||||
|
|
@ -54,7 +56,7 @@ class StaState
|
||||||
public:
|
public:
|
||||||
// Make an empty state.
|
// Make an empty state.
|
||||||
StaState();
|
StaState();
|
||||||
explicit StaState(const StaState *sta);
|
StaState(const StaState *sta);
|
||||||
// Copy the state from sta. This is virtual so that a component
|
// Copy the state from sta. This is virtual so that a component
|
||||||
// can notify sub-components.
|
// can notify sub-components.
|
||||||
virtual void copyState(const StaState *sta);
|
virtual void copyState(const StaState *sta);
|
||||||
|
|
@ -102,8 +104,12 @@ public:
|
||||||
ClkNetwork *clkNetwork() { return clk_network_; }
|
ClkNetwork *clkNetwork() { return clk_network_; }
|
||||||
ClkNetwork *clkNetwork() const { return clk_network_; }
|
ClkNetwork *clkNetwork() const { return clk_network_; }
|
||||||
unsigned threadCount() const { return thread_count_; }
|
unsigned threadCount() const { return thread_count_; }
|
||||||
bool pocvEnabled() const { return pocv_enabled_; }
|
|
||||||
float sigmaFactor() const { return sigma_factor_; }
|
float sigmaFactor() const { return sigma_factor_; }
|
||||||
|
bool crprActive() const;
|
||||||
|
Variables *variables() { return variables_; }
|
||||||
|
const Variables *variables() const { return variables_; }
|
||||||
|
// Edge is default cond disabled by timing_disable_cond_default_arcs var.
|
||||||
|
bool isDisabledCondDefault(Edge *edge) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Report *report_;
|
Report *report_;
|
||||||
|
|
@ -126,8 +132,8 @@ protected:
|
||||||
ClkNetwork *clk_network_;
|
ClkNetwork *clk_network_;
|
||||||
int thread_count_;
|
int thread_count_;
|
||||||
DispatchQueue *dispatch_queue_;
|
DispatchQueue *dispatch_queue_;
|
||||||
bool pocv_enabled_;
|
|
||||||
float sigma_factor_;
|
float sigma_factor_;
|
||||||
|
Variables *variables_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
// OpenSTA, Static Timing Analyzer
|
||||||
|
// Copyright (c) 2025, Parallax Software, Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software.
|
||||||
|
//
|
||||||
|
// Altered source versions must be plainly marked as such, and must not be
|
||||||
|
// misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace sta {
|
||||||
|
|
||||||
|
enum class CrprMode { same_pin, same_transition };
|
||||||
|
|
||||||
|
// TCL Variables
|
||||||
|
class Variables
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Variables();
|
||||||
|
// TCL variable sta_propagate_gated_clock_enable.
|
||||||
|
bool crprEnabled() const { return crpr_enabled_; }
|
||||||
|
void setCrprEnabled(bool enabled);
|
||||||
|
CrprMode crprMode() const { return crpr_mode_; }
|
||||||
|
void setCrprMode(CrprMode mode);
|
||||||
|
// Propagate gated clock enable arrivals.
|
||||||
|
bool propagateGatedClockEnable() const { return propagate_gated_clock_enable_; }
|
||||||
|
void setPropagateGatedClockEnable(bool enable);
|
||||||
|
// TCL variable sta_preset_clear_arcs_enabled.
|
||||||
|
// Enable search through preset/clear arcs.
|
||||||
|
bool presetClrArcsEnabled() const { return preset_clr_arcs_enabled_; }
|
||||||
|
void setPresetClrArcsEnabled(bool enable);
|
||||||
|
// TCL variable sta_cond_default_arcs_enabled.
|
||||||
|
// Enable/disable default arcs when conditional arcs exist.
|
||||||
|
bool condDefaultArcsEnabled() const { return cond_default_arcs_enabled_; }
|
||||||
|
void setCondDefaultArcsEnabled(bool enabled);
|
||||||
|
// TCL variable sta_internal_bidirect_instance_paths_enabled.
|
||||||
|
// Enable/disable timing from bidirect pins back into the instance.
|
||||||
|
bool bidirectInstPathsEnabled() const { return bidirect_inst_paths_enabled_; }
|
||||||
|
void setBidirectInstPathsEnabled(bool enabled);
|
||||||
|
// TCL variable sta_bidirect_net_paths_enabled.
|
||||||
|
// Enable/disable timing from bidirect driver pins to their own loads.
|
||||||
|
bool bidirectNetPathsEnabled() const { return bidirect_net_paths_enabled_; }
|
||||||
|
void setBidirectNetPathsEnabled(bool enabled);
|
||||||
|
// TCL variable sta_recovery_removal_checks_enabled.
|
||||||
|
bool recoveryRemovalChecksEnabled() const { return recovery_removal_checks_enabled_; }
|
||||||
|
void setRecoveryRemovalChecksEnabled(bool enabled);
|
||||||
|
// TCL variable sta_gated_clock_checks_enabled.
|
||||||
|
bool gatedClkChecksEnabled() const { return gated_clk_checks_enabled_; }
|
||||||
|
void setGatedClkChecksEnabled(bool enabled);
|
||||||
|
// TCL variable sta_dynamic_loop_breaking.
|
||||||
|
bool dynamicLoopBreaking() const { return dynamic_loop_breaking_; }
|
||||||
|
void setDynamicLoopBreaking(bool enable);
|
||||||
|
// TCL variable sta_propagate_all_clocks.
|
||||||
|
bool propagateAllClocks() const { return propagate_all_clks_; }
|
||||||
|
void setPropagateAllClocks(bool prop);
|
||||||
|
// TCL var sta_clock_through_tristate_enabled.
|
||||||
|
bool clkThruTristateEnabled() const { return clk_thru_tristate_enabled_; }
|
||||||
|
void setClkThruTristateEnabled(bool enable);
|
||||||
|
// TCL variable sta_input_port_default_clock.
|
||||||
|
bool useDefaultArrivalClock() { return use_default_arrival_clock_; }
|
||||||
|
void setUseDefaultArrivalClock(bool enable);
|
||||||
|
bool pocvEnabled() const { return pocv_enabled_; }
|
||||||
|
void setPocvEnabled(bool enabled);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool crpr_enabled_;
|
||||||
|
CrprMode crpr_mode_;
|
||||||
|
bool propagate_gated_clock_enable_;
|
||||||
|
bool preset_clr_arcs_enabled_;
|
||||||
|
bool cond_default_arcs_enabled_;
|
||||||
|
bool bidirect_net_paths_enabled_;
|
||||||
|
bool bidirect_inst_paths_enabled_;
|
||||||
|
bool recovery_removal_checks_enabled_;
|
||||||
|
bool gated_clk_checks_enabled_;
|
||||||
|
bool clk_thru_tristate_enabled_;
|
||||||
|
bool dynamic_loop_breaking_;
|
||||||
|
bool propagate_all_clks_;
|
||||||
|
bool use_default_arrival_clock_;
|
||||||
|
bool pocv_enabled_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
@ -942,7 +942,7 @@ Power::getMinRfSlew(const Pin *pin)
|
||||||
if (delayGreater(slew, mm_slew, min_max, this))
|
if (delayGreater(slew, mm_slew, min_max, this))
|
||||||
mm_slew = slew;
|
mm_slew = slew;
|
||||||
}
|
}
|
||||||
return mm_slew;
|
return delayAsFloat(mm_slew);
|
||||||
}
|
}
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
222
sdc/Sdc.cc
222
sdc/Sdc.cc
|
|
@ -30,6 +30,7 @@
|
||||||
#include "Debug.hh"
|
#include "Debug.hh"
|
||||||
#include "Mutex.hh"
|
#include "Mutex.hh"
|
||||||
#include "Report.hh"
|
#include "Report.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
#include "PatternMatch.hh"
|
#include "PatternMatch.hh"
|
||||||
#include "MinMax.hh"
|
#include "MinMax.hh"
|
||||||
#include "TimingRole.hh"
|
#include "TimingRole.hh"
|
||||||
|
|
@ -233,19 +234,6 @@ void
|
||||||
Sdc::initVariables()
|
Sdc::initVariables()
|
||||||
{
|
{
|
||||||
analysis_type_ = AnalysisType::ocv;
|
analysis_type_ = AnalysisType::ocv;
|
||||||
use_default_arrival_clock_ = false;
|
|
||||||
crpr_enabled_ = true;
|
|
||||||
crpr_mode_ = CrprMode::same_pin;
|
|
||||||
propagate_gated_clock_enable_ = true;
|
|
||||||
preset_clr_arcs_enabled_ = false;
|
|
||||||
cond_default_arcs_enabled_ = true;
|
|
||||||
bidirect_net_paths_enabled_ = false;
|
|
||||||
bidirect_inst_paths_enabled_ = false;
|
|
||||||
recovery_removal_checks_enabled_ = true;
|
|
||||||
gated_clk_checks_enabled_ = true;
|
|
||||||
clk_thru_tristate_enabled_ = false;
|
|
||||||
dynamic_loop_breaking_ = false;
|
|
||||||
propagate_all_clks_ = false;
|
|
||||||
wireload_mode_ = WireloadMode::unknown;
|
wireload_mode_ = WireloadMode::unknown;
|
||||||
max_area_ = 0.0;
|
max_area_ = 0.0;
|
||||||
path_delays_without_to_ = false;
|
path_delays_without_to_ = false;
|
||||||
|
|
@ -1000,7 +988,7 @@ Sdc::makeClock(const char *name,
|
||||||
else {
|
else {
|
||||||
// Fresh clock definition.
|
// Fresh clock definition.
|
||||||
clk = new Clock(name, clk_index_++, network_);
|
clk = new Clock(name, clk_index_++, network_);
|
||||||
clk->setIsPropagated(propagate_all_clks_);
|
clk->setIsPropagated(variables_->propagateAllClocks());
|
||||||
clocks_.push_back(clk);
|
clocks_.push_back(clk);
|
||||||
// Use the copied name in the map.
|
// Use the copied name in the map.
|
||||||
clock_name_map_[clk->name()] = clk;
|
clock_name_map_[clk->name()] = clk;
|
||||||
|
|
@ -1041,7 +1029,8 @@ Sdc::makeGeneratedClock(const char *name,
|
||||||
clk->initGeneratedClk(pins, add_to_pins, src_pin, master_clk,
|
clk->initGeneratedClk(pins, add_to_pins, src_pin, master_clk,
|
||||||
divide_by, multiply_by, duty_cycle,
|
divide_by, multiply_by, duty_cycle,
|
||||||
invert, combinational,
|
invert, combinational,
|
||||||
edges, edge_shifts, propagate_all_clks_,
|
edges, edge_shifts,
|
||||||
|
variables_->propagateAllClocks(),
|
||||||
comment, network_);
|
comment, network_);
|
||||||
makeClkPinMappings(clk);
|
makeClkPinMappings(clk);
|
||||||
clearCycleAcctings();
|
clearCycleAcctings();
|
||||||
|
|
@ -1249,6 +1238,12 @@ Sdc::sortedClocks(ClockSeq &clks)
|
||||||
sort(clks, ClkNameLess());
|
sort(clks, ClkNameLess());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClockEdge *
|
||||||
|
Sdc::defaultArrivalClockEdge() const
|
||||||
|
{
|
||||||
|
return default_arrival_clk_->edge(RiseFall::rise());
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class ClkHpinDisable
|
class ClkHpinDisable
|
||||||
|
|
@ -5481,203 +5476,6 @@ Sdc::setWireloadSelection(WireloadSelection *selection,
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::crprEnabled() const
|
|
||||||
{
|
|
||||||
return crpr_enabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sdc::setCrprEnabled(bool enabled)
|
|
||||||
{
|
|
||||||
crpr_enabled_ = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
CrprMode
|
|
||||||
Sdc::crprMode() const
|
|
||||||
{
|
|
||||||
return crpr_mode_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sdc::setCrprMode(CrprMode mode)
|
|
||||||
{
|
|
||||||
crpr_mode_ = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::crprActive() const
|
|
||||||
{
|
|
||||||
return analysis_type_ == AnalysisType::ocv
|
|
||||||
&& crpr_enabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::propagateGatedClockEnable() const
|
|
||||||
{
|
|
||||||
return propagate_gated_clock_enable_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sdc::setPropagateGatedClockEnable(bool enable)
|
|
||||||
{
|
|
||||||
propagate_gated_clock_enable_ = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::presetClrArcsEnabled() const
|
|
||||||
{
|
|
||||||
return preset_clr_arcs_enabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sdc::setPresetClrArcsEnabled(bool enable)
|
|
||||||
{
|
|
||||||
preset_clr_arcs_enabled_ = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::condDefaultArcsEnabled() const
|
|
||||||
{
|
|
||||||
return cond_default_arcs_enabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sdc::setCondDefaultArcsEnabled(bool enabled)
|
|
||||||
{
|
|
||||||
cond_default_arcs_enabled_ = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::isDisabledCondDefault(Edge *edge) const
|
|
||||||
{
|
|
||||||
return !cond_default_arcs_enabled_
|
|
||||||
&& edge->timingArcSet()->isCondDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::bidirectInstPathsEnabled() const
|
|
||||||
{
|
|
||||||
return bidirect_inst_paths_enabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sdc::setBidirectInstPathsEnabled(bool enabled)
|
|
||||||
{
|
|
||||||
bidirect_inst_paths_enabled_ = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delay calculation propagates slews from a bidirect driver
|
|
||||||
// to the bidirect port and back through the bidirect driver when
|
|
||||||
// sta_bidirect_inst_paths_enabled_ is true.
|
|
||||||
bool
|
|
||||||
Sdc::bidirectDrvrSlewFromLoad(const Pin *pin) const
|
|
||||||
{
|
|
||||||
return bidirect_inst_paths_enabled_
|
|
||||||
&& network_->direction(pin)->isBidirect()
|
|
||||||
&& network_->isTopLevelPort(pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::bidirectNetPathsEnabled() const
|
|
||||||
{
|
|
||||||
return bidirect_inst_paths_enabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sdc::setBidirectNetPathsEnabled(bool enabled)
|
|
||||||
{
|
|
||||||
bidirect_inst_paths_enabled_ = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::recoveryRemovalChecksEnabled() const
|
|
||||||
{
|
|
||||||
return recovery_removal_checks_enabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sdc::setRecoveryRemovalChecksEnabled(bool enabled)
|
|
||||||
{
|
|
||||||
recovery_removal_checks_enabled_ = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::gatedClkChecksEnabled() const
|
|
||||||
{
|
|
||||||
return gated_clk_checks_enabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sdc::setGatedClkChecksEnabled(bool enabled)
|
|
||||||
{
|
|
||||||
gated_clk_checks_enabled_ = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::dynamicLoopBreaking() const
|
|
||||||
{
|
|
||||||
return dynamic_loop_breaking_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sdc::setDynamicLoopBreaking(bool enable)
|
|
||||||
{
|
|
||||||
if (dynamic_loop_breaking_ != enable) {
|
|
||||||
if (levelize_->levelized()) {
|
|
||||||
if (enable)
|
|
||||||
makeLoopExceptions();
|
|
||||||
else
|
|
||||||
deleteLoopExceptions();
|
|
||||||
}
|
|
||||||
dynamic_loop_breaking_ = enable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::propagateAllClocks() const
|
|
||||||
{
|
|
||||||
return propagate_all_clks_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sdc::setPropagateAllClocks(bool prop)
|
|
||||||
{
|
|
||||||
propagate_all_clks_ = prop;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::clkThruTristateEnabled() const
|
|
||||||
{
|
|
||||||
return clk_thru_tristate_enabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sdc::setClkThruTristateEnabled(bool enable)
|
|
||||||
{
|
|
||||||
clk_thru_tristate_enabled_ = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClockEdge *
|
|
||||||
Sdc::defaultArrivalClockEdge() const
|
|
||||||
{
|
|
||||||
return default_arrival_clk_->edge(RiseFall::rise());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Sdc::useDefaultArrivalClock()
|
|
||||||
{
|
|
||||||
return use_default_arrival_clock_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Sdc::setUseDefaultArrivalClock(bool enable)
|
|
||||||
{
|
|
||||||
use_default_arrival_clock_ = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Sdc::connectPinAfter(const Pin *pin)
|
Sdc::connectPinAfter(const Pin *pin)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
// OpenSTA, Static Timing Analyzer
|
||||||
|
// Copyright (c) 2025, Parallax Software, Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software.
|
||||||
|
//
|
||||||
|
// Altered source versions must be plainly marked as such, and must not be
|
||||||
|
// misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
#include "Variables.hh"
|
||||||
|
|
||||||
|
namespace sta {
|
||||||
|
|
||||||
|
Variables::Variables() :
|
||||||
|
crpr_enabled_(true),
|
||||||
|
crpr_mode_(CrprMode::same_pin),
|
||||||
|
propagate_gated_clock_enable_(true),
|
||||||
|
preset_clr_arcs_enabled_(false),
|
||||||
|
cond_default_arcs_enabled_(true),
|
||||||
|
bidirect_net_paths_enabled_(false),
|
||||||
|
bidirect_inst_paths_enabled_(false),
|
||||||
|
recovery_removal_checks_enabled_(true),
|
||||||
|
gated_clk_checks_enabled_(true),
|
||||||
|
clk_thru_tristate_enabled_(false),
|
||||||
|
dynamic_loop_breaking_(false),
|
||||||
|
propagate_all_clks_(false),
|
||||||
|
use_default_arrival_clock_(false),
|
||||||
|
pocv_enabled_(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setCrprEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
crpr_enabled_ = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setCrprMode(CrprMode mode)
|
||||||
|
{
|
||||||
|
crpr_mode_ = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setPropagateGatedClockEnable(bool enable)
|
||||||
|
{
|
||||||
|
propagate_gated_clock_enable_ = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setPresetClrArcsEnabled(bool enable)
|
||||||
|
{
|
||||||
|
preset_clr_arcs_enabled_ = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setCondDefaultArcsEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
cond_default_arcs_enabled_ = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setBidirectInstPathsEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
bidirect_inst_paths_enabled_ = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setBidirectNetPathsEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
bidirect_net_paths_enabled_ = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setRecoveryRemovalChecksEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
recovery_removal_checks_enabled_ = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setGatedClkChecksEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
gated_clk_checks_enabled_ = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setDynamicLoopBreaking(bool enable)
|
||||||
|
{
|
||||||
|
dynamic_loop_breaking_ = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setPropagateAllClocks(bool prop)
|
||||||
|
{
|
||||||
|
propagate_all_clks_ = prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setClkThruTristateEnabled(bool enable)
|
||||||
|
{
|
||||||
|
clk_thru_tristate_enabled_ = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setUseDefaultArrivalClock(bool enable)
|
||||||
|
{
|
||||||
|
use_default_arrival_clock_ = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Variables::setPocvEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
pocv_enabled_ = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
@ -55,6 +55,7 @@
|
||||||
#include "Fuzzy.hh"
|
#include "Fuzzy.hh"
|
||||||
#include "StaState.hh"
|
#include "StaState.hh"
|
||||||
#include "Corner.hh"
|
#include "Corner.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
#include "WriteSdcPvt.hh"
|
#include "WriteSdcPvt.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
@ -2324,13 +2325,13 @@ WriteSdc::writeFanoutLimits(const MinMax *min_max,
|
||||||
void
|
void
|
||||||
WriteSdc::writeVariables() const
|
WriteSdc::writeVariables() const
|
||||||
{
|
{
|
||||||
if (sdc_->propagateAllClocks()) {
|
if (variables_->propagateAllClocks()) {
|
||||||
if (native_)
|
if (native_)
|
||||||
gzprintf(stream_, "set sta_propagate_all_clocks 1\n");
|
gzprintf(stream_, "set sta_propagate_all_clocks 1\n");
|
||||||
else
|
else
|
||||||
gzprintf(stream_, "set timing_all_clocks_propagated true\n");
|
gzprintf(stream_, "set timing_all_clocks_propagated true\n");
|
||||||
}
|
}
|
||||||
if (sdc_->presetClrArcsEnabled()) {
|
if (variables_->presetClrArcsEnabled()) {
|
||||||
if (native_)
|
if (native_)
|
||||||
gzprintf(stream_, "set sta_preset_clear_arcs_enabled 1\n");
|
gzprintf(stream_, "set sta_preset_clear_arcs_enabled 1\n");
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
#include "PathEnd.hh"
|
#include "PathEnd.hh"
|
||||||
#include "Search.hh"
|
#include "Search.hh"
|
||||||
#include "Genclks.hh"
|
#include "Genclks.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -109,7 +110,7 @@ CheckCrpr::checkCrpr(const Path *src_path,
|
||||||
crpr_pin = nullptr;
|
crpr_pin = nullptr;
|
||||||
if (sdc_->crprActive()
|
if (sdc_->crprActive()
|
||||||
&& src_path && tgt_clk_path) {
|
&& src_path && tgt_clk_path) {
|
||||||
bool same_pin = (sdc_->crprMode() == CrprMode::same_pin);
|
bool same_pin = (variables_->crprMode() == CrprMode::same_pin);
|
||||||
checkCrpr1(src_path, tgt_clk_path, same_pin, crpr, crpr_pin);
|
checkCrpr1(src_path, tgt_clk_path, same_pin, crpr, crpr_pin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -267,7 +268,7 @@ Crpr
|
||||||
CheckCrpr::findCrpr1(const Path *src_clk_path,
|
CheckCrpr::findCrpr1(const Path *src_clk_path,
|
||||||
const Path *tgt_clk_path)
|
const Path *tgt_clk_path)
|
||||||
{
|
{
|
||||||
if (pocv_enabled_) {
|
if (variables_->pocvEnabled()) {
|
||||||
// Remove variation on the common path.
|
// Remove variation on the common path.
|
||||||
// Note that the crpr sigma is negative to offset the
|
// Note that the crpr sigma is negative to offset the
|
||||||
// sigma of the common clock path.
|
// sigma of the common clock path.
|
||||||
|
|
@ -332,7 +333,7 @@ CheckCrpr::outputDelayCrpr(const Path *src_path,
|
||||||
if (sdc_->crprActive()) {
|
if (sdc_->crprActive()) {
|
||||||
const PathAnalysisPt *path_ap = src_path->pathAnalysisPt(this);
|
const PathAnalysisPt *path_ap = src_path->pathAnalysisPt(this);
|
||||||
const PathAnalysisPt *tgt_path_ap = path_ap->tgtClkAnalysisPt();
|
const PathAnalysisPt *tgt_path_ap = path_ap->tgtClkAnalysisPt();
|
||||||
bool same_pin = (sdc_->crprMode() == CrprMode::same_pin);
|
bool same_pin = (variables_->crprMode() == CrprMode::same_pin);
|
||||||
outputDelayCrpr1(src_path,tgt_clk_edge,tgt_path_ap, same_pin,
|
outputDelayCrpr1(src_path,tgt_clk_edge,tgt_path_ap, same_pin,
|
||||||
crpr, crpr_pin);
|
crpr, crpr_pin);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
#include "Levelize.hh"
|
#include "Levelize.hh"
|
||||||
#include "Path.hh"
|
#include "Path.hh"
|
||||||
#include "Search.hh"
|
#include "Search.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -249,7 +250,7 @@ GenClkMasterSearchPred::searchFrom(const Vertex *from_vertex)
|
||||||
bool
|
bool
|
||||||
GenClkMasterSearchPred::searchThru(Edge *edge)
|
GenClkMasterSearchPred::searchThru(Edge *edge)
|
||||||
{
|
{
|
||||||
const Sdc *sdc = sta_->sdc();
|
const Variables *variables = sta_->variables();
|
||||||
const TimingRole *role = edge->role();
|
const TimingRole *role = edge->role();
|
||||||
// Propagate clocks through constants.
|
// Propagate clocks through constants.
|
||||||
return !(edge->role()->isTimingCheck()
|
return !(edge->role()->isTimingCheck()
|
||||||
|
|
@ -257,14 +258,14 @@ GenClkMasterSearchPred::searchThru(Edge *edge)
|
||||||
|| edge->isDisabledConstraint()
|
|| edge->isDisabledConstraint()
|
||||||
// Constants disable edge cond expression.
|
// Constants disable edge cond expression.
|
||||||
|| edge->isDisabledCond()
|
|| edge->isDisabledCond()
|
||||||
|| sdc->isDisabledCondDefault(edge)
|
|| sta_->isDisabledCondDefault(edge)
|
||||||
// Register/latch preset/clr edges are disabled by default.
|
// Register/latch preset/clr edges are disabled by default.
|
||||||
|| (!sdc->presetClrArcsEnabled()
|
|| (!variables->presetClrArcsEnabled()
|
||||||
&& role == TimingRole::regSetClr())
|
&& role == TimingRole::regSetClr())
|
||||||
|| (edge->isBidirectInstPath()
|
|| (edge->isBidirectInstPath()
|
||||||
&& !sdc->bidirectInstPathsEnabled())
|
&& !variables->bidirectInstPathsEnabled())
|
||||||
|| (edge->isBidirectNetPath()
|
|| (edge->isBidirectNetPath()
|
||||||
&& !sdc->bidirectNetPathsEnabled()));
|
&& !variables->bidirectNetPathsEnabled()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -481,7 +482,7 @@ GenClkInsertionSearchPred::searchThru(Edge *edge)
|
||||||
EdgeSet *fdbk_edges = genclk_info_->fdbkEdges();
|
EdgeSet *fdbk_edges = genclk_info_->fdbkEdges();
|
||||||
return SearchPred0::searchThru(edge)
|
return SearchPred0::searchThru(edge)
|
||||||
&& !role->isTimingCheck()
|
&& !role->isTimingCheck()
|
||||||
&& (sdc->clkThruTristateEnabled()
|
&& (sta_->variables()->clkThruTristateEnabled()
|
||||||
|| !(role == TimingRole::tristateEnable()
|
|| !(role == TimingRole::tristateEnable()
|
||||||
|| role == TimingRole::tristateDisable()))
|
|| role == TimingRole::tristateDisable()))
|
||||||
&& !(fdbk_edges && fdbk_edges->hasKey(edge))
|
&& !(fdbk_edges && fdbk_edges->hasKey(edge))
|
||||||
|
|
@ -740,13 +741,12 @@ GenClkArrivalSearchPred::GenClkArrivalSearchPred(Clock *gclk,
|
||||||
bool
|
bool
|
||||||
GenClkArrivalSearchPred::searchThru(Edge *edge)
|
GenClkArrivalSearchPred::searchThru(Edge *edge)
|
||||||
{
|
{
|
||||||
const Sdc *sdc = sta_->sdc();
|
|
||||||
const TimingRole *role = edge->role();
|
const TimingRole *role = edge->role();
|
||||||
return EvalPred::searchThru(edge)
|
return EvalPred::searchThru(edge)
|
||||||
&& (role == TimingRole::combinational()
|
&& (role == TimingRole::combinational()
|
||||||
|| role->isWire()
|
|| role->isWire()
|
||||||
|| !combinational_)
|
|| !combinational_)
|
||||||
&& (sdc->clkThruTristateEnabled()
|
&& (sta_->variables()->clkThruTristateEnabled()
|
||||||
|| !(role == TimingRole::tristateEnable()
|
|| !(role == TimingRole::tristateEnable()
|
||||||
|| role == TimingRole::tristateDisable()));
|
|| role == TimingRole::tristateDisable()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@
|
||||||
#include "Graph.hh"
|
#include "Graph.hh"
|
||||||
#include "GraphCmp.hh"
|
#include "GraphCmp.hh"
|
||||||
#include "SearchPred.hh"
|
#include "SearchPred.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
#include "GraphDelayCalc.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -185,7 +187,7 @@ Levelize::isRoot(Vertex *vertex)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Bidirect pins are not treated as roots in this case.
|
// Bidirect pins are not treated as roots in this case.
|
||||||
return !sdc_->bidirectDrvrSlewFromLoad(vertex->pin());
|
return !graph_delay_calc_->bidirectDrvrSlewFromLoad(vertex->pin());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -250,7 +252,7 @@ Levelize::visit(Vertex *vertex,
|
||||||
latch_d_to_q_edges_.insert(edge);
|
latch_d_to_q_edges_.insert(edge);
|
||||||
}
|
}
|
||||||
// Levelize bidirect driver as if it was a fanout of the bidirect load.
|
// Levelize bidirect driver as if it was a fanout of the bidirect load.
|
||||||
if (sdc_->bidirectDrvrSlewFromLoad(from_pin)
|
if (graph_delay_calc_->bidirectDrvrSlewFromLoad(from_pin)
|
||||||
&& !vertex->isBidirectDriver()) {
|
&& !vertex->isBidirectDriver()) {
|
||||||
Vertex *to_vertex = graph_->pinDrvrVertex(from_pin);
|
Vertex *to_vertex = graph_->pinDrvrVertex(from_pin);
|
||||||
if (search_pred_->searchTo(to_vertex)
|
if (search_pred_->searchTo(to_vertex)
|
||||||
|
|
@ -288,7 +290,7 @@ Levelize::recordLoop(Edge *edge,
|
||||||
EdgeSeq *loop_edges = loopEdges(path, edge);
|
EdgeSeq *loop_edges = loopEdges(path, edge);
|
||||||
GraphLoop *loop = new GraphLoop(loop_edges);
|
GraphLoop *loop = new GraphLoop(loop_edges);
|
||||||
loops_->push_back(loop);
|
loops_->push_back(loop);
|
||||||
if (sdc_->dynamicLoopBreaking())
|
if (variables_->dynamicLoopBreaking())
|
||||||
sdc_->makeLoopExceptions(loop);
|
sdc_->makeLoopExceptions(loop);
|
||||||
}
|
}
|
||||||
// Record disabled loop edges so they can be cleared without
|
// Record disabled loop edges so they can be cleared without
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,8 @@ PathGroup::enumMinSlackUnderMin(PathEnd *path_end)
|
||||||
if (tagMatchCrpr(other->tag(sta_), tag)) {
|
if (tagMatchCrpr(other->tag(sta_), tag)) {
|
||||||
PathEnd *end_min = path_end->copy();
|
PathEnd *end_min = path_end->copy();
|
||||||
end_min->setPath(other);
|
end_min->setPath(other);
|
||||||
bool slack_under = fuzzyGreater(end_min->slackNoCrpr(sta_), slack_min_);
|
float slack = delayAsFloat(end_min->slackNoCrpr(sta_));
|
||||||
|
bool slack_under = fuzzyGreater(slack, slack_min_);
|
||||||
delete end_min;
|
delete end_min;
|
||||||
if (slack_under)
|
if (slack_under)
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@
|
||||||
#include "Latches.hh"
|
#include "Latches.hh"
|
||||||
#include "Corner.hh"
|
#include "Corner.hh"
|
||||||
#include "Genclks.hh"
|
#include "Genclks.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -1397,7 +1398,7 @@ ReportPath::reportVerbose(const MinPulseWidthCheck *check) const
|
||||||
reportLine(clk_ideal_prop, check->closeDelay(this), close_arrival, close_el);
|
reportLine(clk_ideal_prop, check->closeDelay(this), close_arrival, close_el);
|
||||||
reportLine(pin_name, delay_zero, close_arrival, close_el);
|
reportLine(pin_name, delay_zero, close_arrival, close_el);
|
||||||
|
|
||||||
if (sdc_->crprEnabled()) {
|
if (variables_->crprEnabled()) {
|
||||||
Crpr pessimism = check->checkCrpr(this);
|
Crpr pessimism = check->checkCrpr(this);
|
||||||
close_arrival += pessimism;
|
close_arrival += pessimism;
|
||||||
reportLine("clock reconvergence pessimism", pessimism, close_arrival, close_el);
|
reportLine("clock reconvergence pessimism", pessimism, close_arrival, close_el);
|
||||||
|
|
@ -2530,7 +2531,7 @@ void
|
||||||
ReportPath::reportCommonClkPessimism(const PathEnd *end,
|
ReportPath::reportCommonClkPessimism(const PathEnd *end,
|
||||||
Arrival &clk_arrival) const
|
Arrival &clk_arrival) const
|
||||||
{
|
{
|
||||||
if (sdc_->crprEnabled()) {
|
if (variables_->crprEnabled()) {
|
||||||
Crpr pessimism = end->checkCrpr(this);
|
Crpr pessimism = end->checkCrpr(this);
|
||||||
clk_arrival += pessimism;
|
clk_arrival += pessimism;
|
||||||
reportLine("clock reconvergence pessimism", pessimism, clk_arrival,
|
reportLine("clock reconvergence pessimism", pessimism, clk_arrival,
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@
|
||||||
#include "Latches.hh"
|
#include "Latches.hh"
|
||||||
#include "Crpr.hh"
|
#include "Crpr.hh"
|
||||||
#include "Genclks.hh"
|
#include "Genclks.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -91,10 +92,9 @@ EvalPred::setSearchThruLatches(bool thru_latches)
|
||||||
bool
|
bool
|
||||||
EvalPred::searchThru(Edge *edge)
|
EvalPred::searchThru(Edge *edge)
|
||||||
{
|
{
|
||||||
const Sdc *sdc = sta_->sdc();
|
|
||||||
const TimingRole *role = edge->role();
|
const TimingRole *role = edge->role();
|
||||||
return SearchPred0::searchThru(edge)
|
return SearchPred0::searchThru(edge)
|
||||||
&& (sdc->dynamicLoopBreaking()
|
&& (sta_->variables()->dynamicLoopBreaking()
|
||||||
|| !edge->isDisabledLoop())
|
|| !edge->isDisabledLoop())
|
||||||
&& !role->isTimingCheck()
|
&& !role->isTimingCheck()
|
||||||
&& (search_thru_latches_
|
&& (search_thru_latches_
|
||||||
|
|
@ -121,12 +121,12 @@ DynLoopSrchPred::DynLoopSrchPred(TagGroupBldr *tag_bldr) :
|
||||||
|
|
||||||
bool
|
bool
|
||||||
DynLoopSrchPred::loopEnabled(Edge *edge,
|
DynLoopSrchPred::loopEnabled(Edge *edge,
|
||||||
const Sdc *sdc,
|
bool dynamic_loop_breaking_enabled,
|
||||||
const Graph *graph,
|
const Graph *graph,
|
||||||
Search *search)
|
Search *search)
|
||||||
{
|
{
|
||||||
return !edge->isDisabledLoop()
|
return !edge->isDisabledLoop()
|
||||||
|| (sdc->dynamicLoopBreaking()
|
|| (dynamic_loop_breaking_enabled
|
||||||
&& hasPendingLoopPaths(edge, graph, search));
|
&& hasPendingLoopPaths(edge, graph, search));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,14 +179,14 @@ bool
|
||||||
SearchThru::searchThru(Edge *edge)
|
SearchThru::searchThru(Edge *edge)
|
||||||
{
|
{
|
||||||
const Graph *graph = sta_->graph();
|
const Graph *graph = sta_->graph();
|
||||||
const Sdc *sdc = sta_->sdc();
|
|
||||||
Search *search = sta_->search();
|
Search *search = sta_->search();
|
||||||
return EvalPred::searchThru(edge)
|
return EvalPred::searchThru(edge)
|
||||||
// Only search thru latch D->Q if it is always open.
|
// Only search thru latch D->Q if it is always open.
|
||||||
// Enqueue thru latches is handled explicitly by search.
|
// Enqueue thru latches is handled explicitly by search.
|
||||||
&& (edge->role() != TimingRole::latchDtoQ()
|
&& (edge->role() != TimingRole::latchDtoQ()
|
||||||
|| sta_->latches()->latchDtoQState(edge) == LatchEnableState::open)
|
|| sta_->latches()->latchDtoQState(edge) == LatchEnableState::open)
|
||||||
&& loopEnabled(edge, sdc, graph, search);
|
&& loopEnabled(edge, sta_->variables()->dynamicLoopBreaking(),
|
||||||
|
graph, search);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClkArrivalSearchPred::ClkArrivalSearchPred(const StaState *sta) :
|
ClkArrivalSearchPred::ClkArrivalSearchPred(const StaState *sta) :
|
||||||
|
|
@ -460,9 +460,9 @@ Search::findPathEnds(ExceptionFrom *from,
|
||||||
bool clk_gating_hold)
|
bool clk_gating_hold)
|
||||||
{
|
{
|
||||||
findFilteredArrivals(from, thrus, to, unconstrained, true);
|
findFilteredArrivals(from, thrus, to, unconstrained, true);
|
||||||
if (!sdc_->recoveryRemovalChecksEnabled())
|
if (!variables_->recoveryRemovalChecksEnabled())
|
||||||
recovery = removal = false;
|
recovery = removal = false;
|
||||||
if (!sdc_->gatedClkChecksEnabled())
|
if (!variables_->gatedClkChecksEnabled())
|
||||||
clk_gating_setup = clk_gating_hold = false;
|
clk_gating_setup = clk_gating_hold = false;
|
||||||
makePathGroups(group_path_count, endpoint_path_count, unique_pins,
|
makePathGroups(group_path_count, endpoint_path_count, unique_pins,
|
||||||
slack_min, slack_max,
|
slack_min, slack_max,
|
||||||
|
|
@ -1231,7 +1231,7 @@ ArrivalVisitor::constrainedRequiredsInvalid(Vertex *vertex,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Gated clocks.
|
// Gated clocks.
|
||||||
if (is_clk && sdc_->gatedClkChecksEnabled()) {
|
if (is_clk && variables_->gatedClkChecksEnabled()) {
|
||||||
PinSet enable_pins(network_);
|
PinSet enable_pins(network_);
|
||||||
search_->gatedClk()->gatedClkEnables(vertex, enable_pins);
|
search_->gatedClk()->gatedClkEnables(vertex, enable_pins);
|
||||||
for (const Pin *enable : enable_pins)
|
for (const Pin *enable : enable_pins)
|
||||||
|
|
@ -1798,11 +1798,11 @@ Search::seedInputDelayArrival(const Pin *pin,
|
||||||
if (input_delay) {
|
if (input_delay) {
|
||||||
clk_edge = input_delay->clkEdge();
|
clk_edge = input_delay->clkEdge();
|
||||||
if (clk_edge == nullptr
|
if (clk_edge == nullptr
|
||||||
&& sdc_->useDefaultArrivalClock())
|
&& variables_->useDefaultArrivalClock())
|
||||||
clk_edge = sdc_->defaultArrivalClockEdge();
|
clk_edge = sdc_->defaultArrivalClockEdge();
|
||||||
ref_pin = input_delay->refPin();
|
ref_pin = input_delay->refPin();
|
||||||
}
|
}
|
||||||
else if (sdc_->useDefaultArrivalClock())
|
else if (variables_->useDefaultArrivalClock())
|
||||||
clk_edge = sdc_->defaultArrivalClockEdge();
|
clk_edge = sdc_->defaultArrivalClockEdge();
|
||||||
if (ref_pin) {
|
if (ref_pin) {
|
||||||
Vertex *ref_vertex = graph_->pinLoadVertex(ref_pin);
|
Vertex *ref_vertex = graph_->pinLoadVertex(ref_pin);
|
||||||
|
|
@ -2124,7 +2124,7 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
||||||
Arrival to_arrival;
|
Arrival to_arrival;
|
||||||
if (from_clk_info->isGenClkSrcPath()) {
|
if (from_clk_info->isGenClkSrcPath()) {
|
||||||
if (!sdc_->clkStopPropagation(clk,from_pin,from_rf,to_pin,to_rf)
|
if (!sdc_->clkStopPropagation(clk,from_pin,from_rf,to_pin,to_rf)
|
||||||
&& (sdc_->clkThruTristateEnabled()
|
&& (variables_->clkThruTristateEnabled()
|
||||||
|| !(role == TimingRole::tristateEnable()
|
|| !(role == TimingRole::tristateEnable()
|
||||||
|| role == TimingRole::tristateDisable()))) {
|
|| role == TimingRole::tristateDisable()))) {
|
||||||
const Clock *gclk = from_tag->genClkSrcPathClk(this);
|
const Clock *gclk = from_tag->genClkSrcPathClk(this);
|
||||||
|
|
@ -2148,7 +2148,8 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
||||||
path_ap->corner()->findPathAnalysisPt(min_max->opposite());
|
path_ap->corner()->findPathAnalysisPt(min_max->opposite());
|
||||||
Delay arc_delay_opp = search_->deratedDelay(from_vertex, arc, edge,
|
Delay arc_delay_opp = search_->deratedDelay(from_vertex, arc, edge,
|
||||||
true, path_ap_opp);
|
true, path_ap_opp);
|
||||||
bool arc_delay_min_max_eq = fuzzyEqual(arc_delay, arc_delay_opp);
|
bool arc_delay_min_max_eq =
|
||||||
|
fuzzyEqual(delayAsFloat(arc_delay), delayAsFloat(arc_delay_opp));
|
||||||
to_tag = search_->thruClkTag(from_path, from_vertex, from_tag, true,
|
to_tag = search_->thruClkTag(from_path, from_vertex, from_tag, true,
|
||||||
edge, to_rf, arc_delay_min_max_eq,
|
edge, to_rf, arc_delay_min_max_eq,
|
||||||
min_max, path_ap);
|
min_max, path_ap);
|
||||||
|
|
@ -2227,7 +2228,7 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
||||||
// Propagate arrival as non-clock at the end of the clock tree.
|
// Propagate arrival as non-clock at the end of the clock tree.
|
||||||
bool to_propagates_clk =
|
bool to_propagates_clk =
|
||||||
!sdc_->clkStopPropagation(clk,from_pin,from_rf,to_pin,to_rf)
|
!sdc_->clkStopPropagation(clk,from_pin,from_rf,to_pin,to_rf)
|
||||||
&& (sdc_->clkThruTristateEnabled()
|
&& (variables_->clkThruTristateEnabled()
|
||||||
|| !(role == TimingRole::tristateEnable()
|
|| !(role == TimingRole::tristateEnable()
|
||||||
|| role == TimingRole::tristateDisable()));
|
|| role == TimingRole::tristateDisable()));
|
||||||
arc_delay = search_->deratedDelay(from_vertex, arc, edge,
|
arc_delay = search_->deratedDelay(from_vertex, arc, edge,
|
||||||
|
|
@ -2236,7 +2237,8 @@ PathVisitor::visitFromPath(const Pin *from_pin,
|
||||||
path_ap->corner()->findPathAnalysisPt(min_max->opposite());
|
path_ap->corner()->findPathAnalysisPt(min_max->opposite());
|
||||||
Delay arc_delay_opp = search_->deratedDelay(from_vertex, arc, edge,
|
Delay arc_delay_opp = search_->deratedDelay(from_vertex, arc, edge,
|
||||||
to_propagates_clk, path_ap_opp);
|
to_propagates_clk, path_ap_opp);
|
||||||
bool arc_delay_min_max_eq = fuzzyEqual(arc_delay, arc_delay_opp);
|
bool arc_delay_min_max_eq =
|
||||||
|
fuzzyEqual(delayAsFloat(arc_delay), delayAsFloat(arc_delay_opp));
|
||||||
to_tag = search_->thruClkTag(from_path, from_vertex, from_tag,
|
to_tag = search_->thruClkTag(from_path, from_vertex, from_tag,
|
||||||
to_propagates_clk, edge, to_rf,
|
to_propagates_clk, edge, to_rf,
|
||||||
arc_delay_min_max_eq,
|
arc_delay_min_max_eq,
|
||||||
|
|
@ -3244,7 +3246,7 @@ Search::isEndpoint(Vertex *vertex,
|
||||||
return hasFanin(vertex, pred, graph_)
|
return hasFanin(vertex, pred, graph_)
|
||||||
&& ((vertex->hasChecks()
|
&& ((vertex->hasChecks()
|
||||||
&& hasEnabledChecks(vertex))
|
&& hasEnabledChecks(vertex))
|
||||||
|| (sdc_->gatedClkChecksEnabled()
|
|| (variables_->gatedClkChecksEnabled()
|
||||||
&& gated_clk_->isGatedClkEnable(vertex))
|
&& gated_clk_->isGatedClkEnable(vertex))
|
||||||
|| vertex->isConstrained()
|
|| vertex->isConstrained()
|
||||||
|| sdc_->isPathDelayInternalEndpoint(pin)
|
|| sdc_->isPathDelayInternalEndpoint(pin)
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
#include "Levelize.hh"
|
#include "Levelize.hh"
|
||||||
#include "Search.hh"
|
#include "Search.hh"
|
||||||
#include "Latches.hh"
|
#include "Latches.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -59,19 +60,20 @@ SearchPred0::searchThru(Edge *edge)
|
||||||
{
|
{
|
||||||
const TimingRole *role = edge->role();
|
const TimingRole *role = edge->role();
|
||||||
const Sdc *sdc = sta_->sdc();
|
const Sdc *sdc = sta_->sdc();
|
||||||
|
const Variables *variables = sta_->variables();
|
||||||
return !(edge->isDisabledConstraint()
|
return !(edge->isDisabledConstraint()
|
||||||
// Constants disable edge cond expression.
|
// Constants disable edge cond expression.
|
||||||
|| edge->isDisabledCond()
|
|| edge->isDisabledCond()
|
||||||
|| sdc->isDisabledCondDefault(edge)
|
|| sdc->isDisabledCondDefault(edge)
|
||||||
// Register/latch preset/clr edges are disabled by default.
|
// Register/latch preset/clr edges are disabled by default.
|
||||||
|| (role == TimingRole::regSetClr()
|
|| (role == TimingRole::regSetClr()
|
||||||
&& !sdc->presetClrArcsEnabled())
|
&& !variables->presetClrArcsEnabled())
|
||||||
// Constants on other pins disable this edge (ie, a mux select).
|
// Constants on other pins disable this edge (ie, a mux select).
|
||||||
|| edge->simTimingSense() == TimingSense::none
|
|| edge->simTimingSense() == TimingSense::none
|
||||||
|| (edge->isBidirectInstPath()
|
|| (edge->isBidirectInstPath()
|
||||||
&& !sdc->bidirectInstPathsEnabled())
|
&& !variables->bidirectInstPathsEnabled())
|
||||||
|| (edge->isBidirectNetPath()
|
|| (edge->isBidirectNetPath()
|
||||||
&& !sdc->bidirectNetPathsEnabled())
|
&& !variables->bidirectNetPathsEnabled())
|
||||||
|| (role == TimingRole::latchDtoQ()
|
|| (role == TimingRole::latchDtoQ()
|
||||||
&& sta_->latches()->latchDtoQState(edge)
|
&& sta_->latches()->latchDtoQState(edge)
|
||||||
== LatchEnableState::closed));
|
== LatchEnableState::closed));
|
||||||
|
|
@ -152,12 +154,11 @@ ClkTreeSearchPred::ClkTreeSearchPred(const StaState *sta) :
|
||||||
bool
|
bool
|
||||||
ClkTreeSearchPred::searchThru(Edge *edge)
|
ClkTreeSearchPred::searchThru(Edge *edge)
|
||||||
{
|
{
|
||||||
const Sdc *sdc = sta_->sdc();
|
|
||||||
// Propagate clocks through constants.
|
// Propagate clocks through constants.
|
||||||
const TimingRole *role = edge->role();
|
const TimingRole *role = edge->role();
|
||||||
return (role->isWire()
|
return (role->isWire()
|
||||||
|| role == TimingRole::combinational())
|
|| role == TimingRole::combinational())
|
||||||
&& (sdc->clkThruTristateEnabled()
|
&& (sta_->variables()->clkThruTristateEnabled()
|
||||||
|| !(role == TimingRole::tristateEnable()
|
|| !(role == TimingRole::tristateEnable()
|
||||||
|| role == TimingRole::tristateDisable()))
|
|| role == TimingRole::tristateDisable()))
|
||||||
&& SearchPred1::searchThru(edge);
|
&& SearchPred1::searchThru(edge);
|
||||||
|
|
|
||||||
119
search/Sta.cc
119
search/Sta.cc
|
|
@ -44,6 +44,7 @@
|
||||||
#include "Graph.hh"
|
#include "Graph.hh"
|
||||||
#include "GraphCmp.hh"
|
#include "GraphCmp.hh"
|
||||||
#include "Sdc.hh"
|
#include "Sdc.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
#include "WriteSdc.hh"
|
#include "WriteSdc.hh"
|
||||||
#include "ExceptionPath.hh"
|
#include "ExceptionPath.hh"
|
||||||
#include "MakeConcreteParasitics.hh"
|
#include "MakeConcreteParasitics.hh"
|
||||||
|
|
@ -283,6 +284,7 @@ Sta::Sta() :
|
||||||
void
|
void
|
||||||
Sta::makeComponents()
|
Sta::makeComponents()
|
||||||
{
|
{
|
||||||
|
makeVariables();
|
||||||
makeReport();
|
makeReport();
|
||||||
makeDebug();
|
makeDebug();
|
||||||
makeUnits();
|
makeUnits();
|
||||||
|
|
@ -505,6 +507,12 @@ Sta::makePower()
|
||||||
power_ = new Power(this);
|
power_ = new Power(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Sta::makeVariables()
|
||||||
|
{
|
||||||
|
variables_ = new Variables();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setSta(Sta *sta)
|
Sta::setSta(Sta *sta)
|
||||||
{
|
{
|
||||||
|
|
@ -519,6 +527,7 @@ Sta::sta()
|
||||||
|
|
||||||
Sta::~Sta()
|
Sta::~Sta()
|
||||||
{
|
{
|
||||||
|
delete variables_;
|
||||||
// Verilog modules refer to the network in the sta so it has
|
// Verilog modules refer to the network in the sta so it has
|
||||||
// to deleted before the network.
|
// to deleted before the network.
|
||||||
delete verilog_reader_;
|
delete verilog_reader_;
|
||||||
|
|
@ -1693,12 +1702,6 @@ Sta::isDisabledLoop(Edge *edge) const
|
||||||
return levelize_->isDisabledLoop(edge);
|
return levelize_->isDisabledLoop(edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
Sta::isDisabledCondDefault(Edge *edge)
|
|
||||||
{
|
|
||||||
return sdc_->isDisabledCondDefault(edge);
|
|
||||||
}
|
|
||||||
|
|
||||||
PinSet
|
PinSet
|
||||||
Sta::disabledConstantPins(Edge *edge)
|
Sta::disabledConstantPins(Edge *edge)
|
||||||
{
|
{
|
||||||
|
|
@ -1768,21 +1771,21 @@ Sta::exprConstantPins(FuncExpr *expr,
|
||||||
bool
|
bool
|
||||||
Sta::isDisabledBidirectInstPath(Edge *edge) const
|
Sta::isDisabledBidirectInstPath(Edge *edge) const
|
||||||
{
|
{
|
||||||
return !sdc_->bidirectInstPathsEnabled()
|
return !variables_->bidirectInstPathsEnabled()
|
||||||
&& edge->isBidirectInstPath();
|
&& edge->isBidirectInstPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sta::isDisabledBidirectNetPath(Edge *edge) const
|
Sta::isDisabledBidirectNetPath(Edge *edge) const
|
||||||
{
|
{
|
||||||
return !sdc_->bidirectNetPathsEnabled()
|
return !variables_->bidirectNetPathsEnabled()
|
||||||
&& edge->isBidirectNetPath();
|
&& edge->isBidirectNetPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sta::isDisabledPresetClr(Edge *edge) const
|
Sta::isDisabledPresetClr(Edge *edge) const
|
||||||
{
|
{
|
||||||
return !sdc_->presetClrArcsEnabled()
|
return !variables_->presetClrArcsEnabled()
|
||||||
&& edge->role() == TimingRole::regSetClr();
|
&& edge->role() == TimingRole::regSetClr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2161,10 +2164,12 @@ Sta::checkTiming(bool no_input_delay,
|
||||||
loops, generated_clks);
|
loops, generated_clks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sta::crprEnabled() const
|
Sta::crprEnabled() const
|
||||||
{
|
{
|
||||||
return sdc_->crprEnabled();
|
return variables_->crprEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2172,15 +2177,15 @@ Sta::setCrprEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
// Pessimism is only relevant for on_chip_variation analysis.
|
// Pessimism is only relevant for on_chip_variation analysis.
|
||||||
if (sdc_->analysisType() == AnalysisType::ocv
|
if (sdc_->analysisType() == AnalysisType::ocv
|
||||||
&& enabled != sdc_->crprEnabled())
|
&& enabled != variables_->crprEnabled())
|
||||||
search_->arrivalsInvalid();
|
search_->arrivalsInvalid();
|
||||||
sdc_->setCrprEnabled(enabled);
|
variables_->setCrprEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
CrprMode
|
CrprMode
|
||||||
Sta::crprMode() const
|
Sta::crprMode() const
|
||||||
{
|
{
|
||||||
return sdc_->crprMode();
|
return variables_->crprMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2188,25 +2193,24 @@ Sta::setCrprMode(CrprMode mode)
|
||||||
{
|
{
|
||||||
// Pessimism is only relevant for on_chip_variation analysis.
|
// Pessimism is only relevant for on_chip_variation analysis.
|
||||||
if (sdc_->analysisType() == AnalysisType::ocv
|
if (sdc_->analysisType() == AnalysisType::ocv
|
||||||
&& sdc_->crprEnabled()
|
&& variables_->crprEnabled()
|
||||||
&& sdc_->crprMode() != mode)
|
&& variables_->crprMode() != mode)
|
||||||
search_->arrivalsInvalid();
|
search_->arrivalsInvalid();
|
||||||
sdc_->setCrprMode(mode);
|
variables_->setCrprMode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sta::pocvEnabled() const
|
Sta::pocvEnabled() const
|
||||||
{
|
{
|
||||||
return pocv_enabled_;
|
return variables_->pocvEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setPocvEnabled(bool enabled)
|
Sta::setPocvEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
if (enabled != pocv_enabled_)
|
if (enabled != variables_->pocvEnabled())
|
||||||
delaysInvalid();
|
delaysInvalid();
|
||||||
pocv_enabled_ = enabled;
|
variables_->setPocvEnabled(enabled);
|
||||||
updateComponentsState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2222,135 +2226,141 @@ Sta::setSigmaFactor(float factor)
|
||||||
bool
|
bool
|
||||||
Sta::propagateGatedClockEnable() const
|
Sta::propagateGatedClockEnable() const
|
||||||
{
|
{
|
||||||
return sdc_->propagateGatedClockEnable();
|
return variables_->propagateGatedClockEnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setPropagateGatedClockEnable(bool enable)
|
Sta::setPropagateGatedClockEnable(bool enable)
|
||||||
{
|
{
|
||||||
if (sdc_->propagateGatedClockEnable() != enable)
|
if (variables_->propagateGatedClockEnable() != enable)
|
||||||
search_->arrivalsInvalid();
|
search_->arrivalsInvalid();
|
||||||
sdc_->setPropagateGatedClockEnable(enable);
|
variables_->setPropagateGatedClockEnable(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sta::presetClrArcsEnabled() const
|
Sta::presetClrArcsEnabled() const
|
||||||
{
|
{
|
||||||
return sdc_->presetClrArcsEnabled();
|
return variables_->presetClrArcsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setPresetClrArcsEnabled(bool enable)
|
Sta::setPresetClrArcsEnabled(bool enable)
|
||||||
{
|
{
|
||||||
if (sdc_->presetClrArcsEnabled() != enable) {
|
if (variables_->presetClrArcsEnabled() != enable) {
|
||||||
levelize_->invalid();
|
levelize_->invalid();
|
||||||
delaysInvalid();
|
delaysInvalid();
|
||||||
}
|
}
|
||||||
sdc_->setPresetClrArcsEnabled(enable);
|
variables_->setPresetClrArcsEnabled(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sta::condDefaultArcsEnabled() const
|
Sta::condDefaultArcsEnabled() const
|
||||||
{
|
{
|
||||||
return sdc_->condDefaultArcsEnabled();
|
return variables_->condDefaultArcsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setCondDefaultArcsEnabled(bool enabled)
|
Sta::setCondDefaultArcsEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
if (sdc_->condDefaultArcsEnabled() != enabled) {
|
if (variables_->condDefaultArcsEnabled() != enabled) {
|
||||||
delaysInvalid();
|
delaysInvalid();
|
||||||
sdc_->setCondDefaultArcsEnabled(enabled);
|
variables_->setCondDefaultArcsEnabled(enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sta::bidirectInstPathsEnabled() const
|
Sta::bidirectInstPathsEnabled() const
|
||||||
{
|
{
|
||||||
return sdc_->bidirectInstPathsEnabled();
|
return variables_->bidirectInstPathsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setBidirectInstPathsEnabled(bool enabled)
|
Sta::setBidirectInstPathsEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
if (sdc_->bidirectInstPathsEnabled() != enabled) {
|
if (variables_->bidirectInstPathsEnabled() != enabled) {
|
||||||
levelize_->invalid();
|
levelize_->invalid();
|
||||||
delaysInvalid();
|
delaysInvalid();
|
||||||
sdc_->setBidirectInstPathsEnabled(enabled);
|
variables_->setBidirectInstPathsEnabled(enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sta::bidirectNetPathsEnabled() const
|
Sta::bidirectNetPathsEnabled() const
|
||||||
{
|
{
|
||||||
return sdc_->bidirectNetPathsEnabled();
|
return variables_->bidirectNetPathsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setBidirectNetPathsEnabled(bool enabled)
|
Sta::setBidirectNetPathsEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
if (sdc_->bidirectNetPathsEnabled() != enabled) {
|
if (variables_->bidirectNetPathsEnabled() != enabled) {
|
||||||
delaysInvalid();
|
delaysInvalid();
|
||||||
sdc_->setBidirectNetPathsEnabled(enabled);
|
variables_->setBidirectNetPathsEnabled(enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sta::recoveryRemovalChecksEnabled() const
|
Sta::recoveryRemovalChecksEnabled() const
|
||||||
{
|
{
|
||||||
return sdc_->recoveryRemovalChecksEnabled();
|
return variables_->recoveryRemovalChecksEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setRecoveryRemovalChecksEnabled(bool enabled)
|
Sta::setRecoveryRemovalChecksEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
if (sdc_->recoveryRemovalChecksEnabled() != enabled) {
|
if (variables_->recoveryRemovalChecksEnabled() != enabled) {
|
||||||
search_->arrivalsInvalid();
|
search_->arrivalsInvalid();
|
||||||
sdc_->setRecoveryRemovalChecksEnabled(enabled);
|
variables_->setRecoveryRemovalChecksEnabled(enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sta::gatedClkChecksEnabled() const
|
Sta::gatedClkChecksEnabled() const
|
||||||
{
|
{
|
||||||
return sdc_->gatedClkChecksEnabled();
|
return variables_->gatedClkChecksEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setGatedClkChecksEnabled(bool enabled)
|
Sta::setGatedClkChecksEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
if (sdc_->gatedClkChecksEnabled() != enabled) {
|
if (variables_->gatedClkChecksEnabled() != enabled) {
|
||||||
search_->arrivalsInvalid();
|
search_->arrivalsInvalid();
|
||||||
sdc_->setGatedClkChecksEnabled(enabled);
|
variables_->setGatedClkChecksEnabled(enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sta::dynamicLoopBreaking() const
|
Sta::dynamicLoopBreaking() const
|
||||||
{
|
{
|
||||||
return sdc_->dynamicLoopBreaking();
|
return variables_->dynamicLoopBreaking();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setDynamicLoopBreaking(bool enable)
|
Sta::setDynamicLoopBreaking(bool enable)
|
||||||
{
|
{
|
||||||
if (sdc_->dynamicLoopBreaking() != enable) {
|
if (variables_->dynamicLoopBreaking() != enable) {
|
||||||
sdc_->setDynamicLoopBreaking(enable);
|
if (levelize_->levelized()) {
|
||||||
|
if (enable)
|
||||||
|
sdc_->makeLoopExceptions();
|
||||||
|
else
|
||||||
|
sdc_->deleteLoopExceptions();
|
||||||
|
}
|
||||||
search_->arrivalsInvalid();
|
search_->arrivalsInvalid();
|
||||||
|
variables_->setDynamicLoopBreaking(enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sta::useDefaultArrivalClock() const
|
Sta::useDefaultArrivalClock() const
|
||||||
{
|
{
|
||||||
return sdc_->useDefaultArrivalClock();
|
return variables_->useDefaultArrivalClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setUseDefaultArrivalClock(bool enable)
|
Sta::setUseDefaultArrivalClock(bool enable)
|
||||||
{
|
{
|
||||||
if (sdc_->useDefaultArrivalClock() != enable) {
|
if (variables_->useDefaultArrivalClock() != enable) {
|
||||||
sdc_->setUseDefaultArrivalClock(enable);
|
variables_->setUseDefaultArrivalClock(enable);
|
||||||
search_->arrivalsInvalid();
|
search_->arrivalsInvalid();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2358,27 +2368,27 @@ Sta::setUseDefaultArrivalClock(bool enable)
|
||||||
bool
|
bool
|
||||||
Sta::propagateAllClocks() const
|
Sta::propagateAllClocks() const
|
||||||
{
|
{
|
||||||
return sdc_->propagateAllClocks();
|
return variables_->propagateAllClocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setPropagateAllClocks(bool prop)
|
Sta::setPropagateAllClocks(bool prop)
|
||||||
{
|
{
|
||||||
sdc_->setPropagateAllClocks(prop);
|
variables_->setPropagateAllClocks(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Sta::clkThruTristateEnabled() const
|
Sta::clkThruTristateEnabled() const
|
||||||
{
|
{
|
||||||
return sdc_->clkThruTristateEnabled();
|
return variables_->clkThruTristateEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::setClkThruTristateEnabled(bool enable)
|
Sta::setClkThruTristateEnabled(bool enable)
|
||||||
{
|
{
|
||||||
if (enable != sdc_->clkThruTristateEnabled()) {
|
if (enable != variables_->clkThruTristateEnabled()) {
|
||||||
search_->arrivalsInvalid();
|
search_->arrivalsInvalid();
|
||||||
sdc_->setClkThruTristateEnabled(enable);
|
variables_->setClkThruTristateEnabled(enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3207,7 +3217,7 @@ Sta::findRequired(Vertex *vertex)
|
||||||
searchPreamble();
|
searchPreamble();
|
||||||
search_->findAllArrivals();
|
search_->findAllArrivals();
|
||||||
search_->findRequireds(vertex->level());
|
search_->findRequireds(vertex->level());
|
||||||
if (sdc_->crprEnabled()
|
if (variables_->crprEnabled()
|
||||||
&& search_->crprPathPruningEnabled()
|
&& search_->crprPathPruningEnabled()
|
||||||
&& !search_->crprApproxMissingRequireds()
|
&& !search_->crprApproxMissingRequireds()
|
||||||
// Clocks invariably have requireds that are pruned but it isn't
|
// Clocks invariably have requireds that are pruned but it isn't
|
||||||
|
|
@ -4856,12 +4866,11 @@ FanInOutSrchPred::searchFrom(const Vertex *from_vertex)
|
||||||
bool
|
bool
|
||||||
FanInOutSrchPred::searchThru(Edge *edge)
|
FanInOutSrchPred::searchThru(Edge *edge)
|
||||||
{
|
{
|
||||||
const Sdc *sdc = sta_->sdc();
|
|
||||||
return searchThruRole(edge)
|
return searchThruRole(edge)
|
||||||
&& (thru_disabled_
|
&& (thru_disabled_
|
||||||
|| !(edge->isDisabledConstraint()
|
|| !(edge->isDisabledConstraint()
|
||||||
|| edge->isDisabledCond()
|
|| edge->isDisabledCond()
|
||||||
|| sdc->isDisabledCondDefault(edge)))
|
|| sta_->isDisabledCondDefault(edge)))
|
||||||
&& (thru_constants_
|
&& (thru_constants_
|
||||||
|| edge->simTimingSense() != TimingSense::none);
|
|| edge->simTimingSense() != TimingSense::none);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,10 @@
|
||||||
#include "DispatchQueue.hh"
|
#include "DispatchQueue.hh"
|
||||||
#include "Units.hh"
|
#include "Units.hh"
|
||||||
#include "Network.hh"
|
#include "Network.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
#include "Sdc.hh"
|
||||||
|
#include "Graph.hh"
|
||||||
|
#include "TimingArc.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -50,8 +54,8 @@ StaState::StaState() :
|
||||||
clk_network_(nullptr),
|
clk_network_(nullptr),
|
||||||
thread_count_(1),
|
thread_count_(1),
|
||||||
dispatch_queue_(nullptr),
|
dispatch_queue_(nullptr),
|
||||||
pocv_enabled_(false),
|
sigma_factor_(1.0),
|
||||||
sigma_factor_(1.0)
|
variables_(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,4 +112,18 @@ StaState::setDebug(Debug *debug)
|
||||||
debug_ = debug;
|
debug_ = debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
StaState::crprActive() const
|
||||||
|
{
|
||||||
|
return sdc_->analysisType() == AnalysisType::ocv
|
||||||
|
&& variables_->crprEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
StaState::isDisabledCondDefault(Edge *edge) const
|
||||||
|
{
|
||||||
|
return !variables_->condDefaultArcsEnabled()
|
||||||
|
&& edge->timingArcSet()->isCondDefault();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include "PathEnd.hh"
|
#include "PathEnd.hh"
|
||||||
#include "Search.hh"
|
#include "Search.hh"
|
||||||
#include "GatedClk.hh"
|
#include "GatedClk.hh"
|
||||||
|
#include "Variables.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
||||||
|
|
@ -122,7 +123,7 @@ VisitPathEnds::visitClkedPathEnds(const Pin *pin,
|
||||||
is_constrained = true;
|
is_constrained = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sdc_->gatedClkChecksEnabled())
|
if (variables_->gatedClkChecksEnabled())
|
||||||
visitGatedClkEnd(pin, vertex, path, end_rf, path_ap, filtered, visitor,
|
visitGatedClkEnd(pin, vertex, path, end_rf, path_ap, filtered, visitor,
|
||||||
is_constrained);
|
is_constrained);
|
||||||
visitDataCheckEnd(pin, path, end_rf, path_ap, filtered, visitor,
|
visitDataCheckEnd(pin, path, end_rf, path_ap, filtered, visitor,
|
||||||
|
|
@ -288,7 +289,7 @@ VisitPathEnds::checkEdgeEnabled(Edge *edge) const
|
||||||
&& !sdc_->isDisabledCondDefault(edge)
|
&& !sdc_->isDisabledCondDefault(edge)
|
||||||
&& !((check_role == TimingRole::recovery()
|
&& !((check_role == TimingRole::recovery()
|
||||||
|| check_role == TimingRole::removal())
|
|| check_role == TimingRole::removal())
|
||||||
&& !sdc_->recoveryRemovalChecksEnabled());
|
&& !variables_->recoveryRemovalChecksEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue