// 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 .
//
// 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
#include
#include "StringSeq.hh"
#include "LibertyClass.hh"
#include "NetworkClass.hh"
#include "SdcClass.hh"
#include "GraphClass.hh"
#include "ParasiticsClass.hh"
#include "StaState.hh"
#include "VertexVisitor.hh"
#include "SearchClass.hh"
#include "PowerClass.hh"
#include "ArcDelayCalc.hh"
#include "CircuitSim.hh"
#include "Variables.hh"
#include "Property.hh"
struct Tcl_Interp;
namespace sta {
// Don't include headers to minimize dependencies.
class MinMax;
class MinMaxAll;
class RiseFallBoth;
class RiseFall;
class VerilogReader;
class ReportPath;
class CheckTiming;
class DcalcAnalysisPt;
class CheckSlewLimits;
class CheckFanoutLimits;
class CheckCapacitanceLimits;
class CheckMinPulseWidths;
class CheckMinPeriods;
class CheckMaxSkews;
class PatternMatch;
class CheckPeriods;
class LibertyReader;
class SearchPred;
class Corner;
class ClkSkews;
class ReportField;
class EquivCells;
typedef InstanceSeq::Iterator SlowDrvrIterator;
typedef Vector CheckError;
typedef Vector CheckErrorSeq;
typedef Vector CornerSeq;
typedef std::vector StdStringSeq;
enum class CmdNamespace { sta, sdc };
// Initialize sta functions that are not part of the Sta class.
void initSta();
// Call before exit to make leak detection simpler for purify and valgrind.
void
deleteAllMemory();
// The Lord, God, King, Master of the Timing Universe.
// This class is a FACADE used to present an API to the collection of
// objects that hold the collective state of the static timing analyzer.
// It should only hold pointers to objects so that only the referenced
// class declarations and not their definitions are needed by this header.
//
// The report object is not owned by the sta object.
class Sta : public StaState
{
public:
Sta();
// The Sta is a FACTORY for the components.
// makeComponents calls the make{Component} virtual functions.
// Ideally this would be called by the Sta constructor, but a
// virtual function called in a base class constructor does not
// call the derived class function.
virtual void makeComponents();
// Call copyState for each component to notify it that some
// pointers to some components have changed.
// This must be called after changing any of the StaState components.
virtual void updateComponentsState();
virtual ~Sta();
// Singleton accessor used by tcl command interpreter.
static Sta *sta();
static void setSta(Sta *sta);
// Default number of threads to use.
virtual int defaultThreadCount() const;
void setThreadCount(int thread_count);
virtual LibertyLibrary *readLiberty(const char *filename,
Corner *corner,
const MinMaxAll *min_max,
bool infer_latches);
bool readVerilog(const char *filename);
// Network readers call this to notify the Sta to delete any previously
// linked network.
void readNetlistBefore();
// Return true if successful.
bool linkDesign(const char *top_cell_name,
bool make_black_boxes);
// SDC Swig API.
Instance *currentInstance() const;
void setCurrentInstance(Instance *inst);
virtual void setAnalysisType(AnalysisType analysis_type);
void setOperatingConditions(OperatingConditions *op_cond,
const MinMaxAll *min_max);
void setTimingDerate(TimingDerateType type,
PathClkOrData clk_data,
const RiseFallBoth *rf,
const EarlyLate *early_late,
float derate);
// Delay type is always net for net derating.
void setTimingDerate(const Net *net,
PathClkOrData clk_data,
const RiseFallBoth *rf,
const EarlyLate *early_late,
float derate);
void setTimingDerate(const Instance *inst,
TimingDerateCellType type,
PathClkOrData clk_data,
const RiseFallBoth *rf,
const EarlyLate *early_late,
float derate);
void setTimingDerate(const LibertyCell *cell,
TimingDerateCellType type,
PathClkOrData clk_data,
const RiseFallBoth *rf,
const EarlyLate *early_late,
float derate);
void unsetTimingDerate();
void setInputSlew(const Port *port,
const RiseFallBoth *rf,
const MinMaxAll *min_max,
float slew);
// Set port external pin load (set_load -pin port).
void setPortExtPinCap(const Port *port,
const RiseFallBoth *rf,
const Corner *corner,
const MinMaxAll *min_max,
float cap);
void portExtCaps(const Port *port,
const Corner *corner,
const MinMax *min_max,
float &pin_cap,
float &wire_cap,
int &fanout);
// Set port external wire load (set_load -wire port).
void setPortExtWireCap(const Port *port,
bool subtract_pin_cap,
const RiseFallBoth *rf,
const Corner *corner,
const MinMaxAll *min_max,
float cap);
// Set net wire capacitance (set_load -wire net).
void setNetWireCap(const Net *net,
bool subtract_pin_load,
const Corner *corner,
const MinMaxAll *min_max,
float cap);
// Remove all "set_load net" annotations.
void removeNetLoadCaps() const;
// Set port external fanout (used by wireload models).
void setPortExtFanout(const Port *port,
int fanout,
const Corner *corner,
const MinMaxAll *min_max);
// Liberty port capacitance.
float capacitance(const LibertyPort *port,
Corner *corner,
const MinMax *min_max);
// pin_cap = net pin capacitances + port external pin capacitance,
// wire_cap = annotated net capacitance + port external wire capacitance.
void connectedCap(const Pin *drvr_pin,
const RiseFall *rf,
const Corner *corner,
const MinMax *min_max,
float &pin_cap,
float &wire_cap) const;
void connectedCap(const Net *net,
Corner *corner,
const MinMax *min_max,
float &pin_cap,
float &wire_cap) const;
void setResistance(const Net *net,
const MinMaxAll *min_max,
float res);
void setDriveCell(const LibertyLibrary *library,
const LibertyCell *cell,
const Port *port,
const LibertyPort *from_port,
float *from_slews,
const LibertyPort *to_port,
const RiseFallBoth *rf,
const MinMaxAll *min_max);
void setDriveResistance(const Port *port,
const RiseFallBoth *rf,
const MinMaxAll *min_max,
float res);
void setLatchBorrowLimit(const Pin *pin,
float limit);
void setLatchBorrowLimit(const Instance *inst,
float limit);
void setLatchBorrowLimit(const Clock *clk,
float limit);
void setMinPulseWidth(const RiseFallBoth *rf,
float min_width);
void setMinPulseWidth(const Pin *pin,
const RiseFallBoth *rf,
float min_width);
void setMinPulseWidth(const Instance *inst,
const RiseFallBoth *rf,
float min_width);
void setMinPulseWidth(const Clock *clk,
const RiseFallBoth *rf,
float min_width);
void setWireload(Wireload *wireload,
const MinMaxAll *min_max);
void setWireloadMode(WireloadMode mode);
void setWireloadSelection(WireloadSelection *selection,
const MinMaxAll *min_max);
void setSlewLimit(Clock *clk,
const RiseFallBoth *rf,
const PathClkOrData clk_data,
const MinMax *min_max,
float slew);
void setSlewLimit(Port *port,
const MinMax *min_max,
float slew);
void setSlewLimit(Cell *cell,
const MinMax *min_max,
float slew);
void setCapacitanceLimit(Cell *cell,
const MinMax *min_max,
float cap);
void setCapacitanceLimit(Port *port,
const MinMax *min_max,
float cap);
void setCapacitanceLimit(Pin *pin,
const MinMax *min_max,
float cap);
void setFanoutLimit(Cell *cell,
const MinMax *min_max,
float fanout);
void setFanoutLimit(Port *port,
const MinMax *min_max,
float fanout);
void setMaxArea(float area);
void makeClock(const char *name,
PinSet *pins,
bool add_to_pins,
float period,
FloatSeq *waveform,
char *comment);
// edges size must be 3.
void makeGeneratedClock(const char *name,
PinSet *pins,
bool add_to_pins,
Pin *src_pin,
Clock *master_clk,
int divide_by,
int multiply_by,
float duty_cycle,
bool invert,
bool combinational,
IntSeq *edges,
FloatSeq *edge_shifts,
char *comment);
void removeClock(Clock *clk);
// Update period/waveform for generated clocks from source pin clock.
void updateGeneratedClks();
// True if pin is defined as a clock source (pin may be hierarchical).
bool isClockSrc(const Pin *pin) const;
// Propagated (non-ideal) clocks.
void setPropagatedClock(Clock *clk);
void removePropagatedClock(Clock *clk);
void setPropagatedClock(Pin *pin);
void removePropagatedClock(Pin *pin);
void setClockSlew(Clock *clock,
const RiseFallBoth *rf,
const MinMaxAll *min_max,
float slew);
void removeClockSlew(Clock *clk);
// Clock latency.
// Latency can be on a clk, pin, or clk/pin combination.
void setClockLatency(Clock *clk,
Pin *pin,
const RiseFallBoth *rf,
const MinMaxAll *min_max,
float delay);
void removeClockLatency(const Clock *clk,
const Pin *pin);
// Clock insertion delay (source latency).
void setClockInsertion(const Clock *clk,
const Pin *pin,
const RiseFallBoth *rf,
const MinMaxAll *min_max,
const EarlyLateAll *early_late,
float delay);
void removeClockInsertion(const Clock *clk,
const Pin *pin);
// Clock uncertainty.
virtual void setClockUncertainty(Clock *clk,
const SetupHoldAll *setup_hold,
float uncertainty);
virtual void removeClockUncertainty(Clock *clk,
const SetupHoldAll *setup_hold);
virtual void setClockUncertainty(Pin *pin,
const SetupHoldAll *setup_hold,
float uncertainty);
virtual void removeClockUncertainty(Pin *pin,
const SetupHoldAll *setup_hold);
// Inter-clock uncertainty.
virtual void setClockUncertainty(Clock *from_clk,
const RiseFallBoth *from_rf,
Clock *to_clk,
const RiseFallBoth *to_rf,
const SetupHoldAll *setup_hold,
float uncertainty);
virtual void removeClockUncertainty(Clock *from_clk,
const RiseFallBoth *from_rf,
Clock *to_clk,
const RiseFallBoth *to_rf,
const SetupHoldAll *setup_hold);
ClockGroups *makeClockGroups(const char *name,
bool logically_exclusive,
bool physically_exclusive,
bool asynchronous,
bool allow_paths,
const char *comment);
// nullptr name removes all.
void removeClockGroupsLogicallyExclusive(const char *name);
void removeClockGroupsPhysicallyExclusive(const char *name);
void removeClockGroupsAsynchronous(const char *name);
void makeClockGroup(ClockGroups *clk_groups,
ClockSet *clks);
void setClockSense(PinSet *pins,
ClockSet *clks,
ClockSense sense);
void setClockGatingCheck(const RiseFallBoth *rf,
const SetupHold *setup_hold,
float margin);
void setClockGatingCheck(Clock *clk,
const RiseFallBoth *rf,
const SetupHold *setup_hold,
float margin);
void setClockGatingCheck(Instance *inst,
const RiseFallBoth *rf,
const SetupHold *setup_hold,
float margin,
LogicValue active_value);
void setClockGatingCheck(Pin *pin,
const RiseFallBoth *rf,
const SetupHold *setup_hold,
float margin,
LogicValue active_value);
void setDataCheck(Pin *from,
const RiseFallBoth *from_rf,
Pin *to,
const RiseFallBoth *to_rf,
Clock *clk,
const SetupHoldAll *setup_hold,
float margin);
void removeDataCheck(Pin *from,
const RiseFallBoth *from_rf,
Pin *to,
const RiseFallBoth *to_rf,
Clock *clk,
const SetupHoldAll *setup_hold);
// set_disable_timing cell [-from] [-to]
// Disable all edges thru cell if from/to are null.
// Bus and bundle ports are NOT supported.
void disable(LibertyCell *cell,
LibertyPort *from,
LibertyPort *to);
void removeDisable(LibertyCell *cell,
LibertyPort *from,
LibertyPort *to);
// set_disable_timing liberty port.
// Bus and bundle ports are NOT supported.
void disable(LibertyPort *port);
void removeDisable(LibertyPort *port);
// set_disable_timing port (top level instance port).
// Bus and bundle ports are NOT supported.
void disable(Port *port);
void removeDisable(Port *port);
// set_disable_timing instance [-from] [-to].
// Disable all edges thru instance if from/to are null.
// Bus and bundle ports are NOT supported.
// Hierarchical instances are NOT supported.
void disable(Instance *inst,
LibertyPort *from,
LibertyPort *to);
void removeDisable(Instance *inst,
LibertyPort *from,
LibertyPort *to);
// set_disable_timing pin
void disable(Pin *pin);
void removeDisable(Pin *pin);
// set_disable_timing [get_timing_arc -of_objects instance]]
void disable(Edge *edge);
void removeDisable(Edge *edge);
// set_disable_timing [get_timing_arc -of_objects lib_cell]]
void disable(TimingArcSet *arc_set);
void removeDisable(TimingArcSet *arc_set);
// Edge is disabled by constant.
bool isDisabledConstant(Edge *edge);
// Return a set of constant pins that disabled edge.
// Caller owns the returned set.
PinSet disabledConstantPins(Edge *edge);
// Edge timing sense with propagated constants.
TimingSense simTimingSense(Edge *edge);
// Edge is disabled by set_disable_timing constraint.
bool isDisabledConstraint(Edge *edge);
// Edge is disabled to break combinational loops.
bool isDisabledLoop(Edge *edge) const;
// Edge is disabled internal bidirect output path.
bool isDisabledBidirectInstPath(Edge *edge) const;
// Edge is disabled bidirect net path.
bool isDisabledBidirectNetPath(Edge *edge) const;
bool isDisabledPresetClr(Edge *edge) const;
// Return a vector of graph edges that are disabled, sorted by
// from/to vertex names. Caller owns the returned vector.
EdgeSeq disabledEdges();
EdgeSeq disabledEdgesSorted();
void disableClockGatingCheck(Instance *inst);
void disableClockGatingCheck(Pin *pin);
void removeDisableClockGatingCheck(Instance *inst);
void removeDisableClockGatingCheck(Pin *pin);
void setLogicValue(Pin *pin,
LogicValue value);
void setCaseAnalysis(Pin *pin,
LogicValue value);
void removeCaseAnalysis(Pin *pin);
void setInputDelay(const Pin *pin,
const RiseFallBoth *rf,
const Clock *clk,
const RiseFall *clk_rf,
const Pin *ref_pin,
bool source_latency_included,
bool network_latency_included,
const MinMaxAll *min_max,
bool add,
float delay);
void removeInputDelay(const Pin *pin,
const RiseFallBoth *rf,
const Clock *clk,
const RiseFall *clk_rf,
const MinMaxAll *min_max);
void setOutputDelay(const Pin *pin,
const RiseFallBoth *rf,
const Clock *clk,
const RiseFall *clk_rf,
const Pin *ref_pin,
bool source_latency_included,
bool network_latency_included,
const MinMaxAll *min_max,
bool add,
float delay);
void removeOutputDelay(const Pin *pin,
const RiseFallBoth *rf,
const Clock *clk,
const RiseFall *clk_rf,
const MinMaxAll *min_max);
void makeFalsePath(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
const char *comment);
void makeMulticyclePath(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max,
bool use_end_clk,
int path_multiplier,
const char *comment);
void makePathDelay(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMax *min_max,
bool ignore_clk_latency,
bool break_path,
float delay,
const char *comment);
void makeGroupPath(const char *name,
bool is_default,
ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const char *comment);
// Deprecated 10/24/2025
bool isGroupPathName(const char *group_name) __attribute__ ((deprecated));
bool isPathGroupName(const char *group_name) const;
StdStringSeq pathGroupNames() const;
void resetPath(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max);
// Make an exception -from specification.
ExceptionFrom *makeExceptionFrom(PinSet *from_pins,
ClockSet *from_clks,
InstanceSet *from_insts,
const RiseFallBoth *from_rf);
void checkExceptionFromPins(ExceptionFrom *from,
const char *file,
int line) const;
void deleteExceptionFrom(ExceptionFrom *from);
// Make an exception -through specification.
ExceptionThru *makeExceptionThru(PinSet *pins,
NetSet *nets,
InstanceSet *insts,
const RiseFallBoth *rf);
void deleteExceptionThru(ExceptionThru *thru);
// Make an exception -to specification.
ExceptionTo *makeExceptionTo(PinSet *to_pins,
ClockSet *to_clks,
InstanceSet *to_insts,
const RiseFallBoth *rf,
const RiseFallBoth *end_rf);
void checkExceptionToPins(ExceptionTo *to,
const char *file, int) const;
void deleteExceptionTo(ExceptionTo *to);
InstanceSet findRegisterInstances(ClockSet *clks,
const RiseFallBoth *clk_rf,
bool edge_triggered,
bool latches);
PinSet findRegisterDataPins(ClockSet *clks,
const RiseFallBoth *clk_rf,
bool registers,
bool latches);
PinSet findRegisterClkPins(ClockSet *clks,
const RiseFallBoth *clk_rf,
bool registers,
bool latches);
PinSet findRegisterAsyncPins(ClockSet *clks,
const RiseFallBoth *clk_rf,
bool registers,
bool latches);
PinSet findRegisterOutputPins(ClockSet *clks,
const RiseFallBoth *clk_rf,
bool registers,
bool latches);
PinSet findFaninPins(PinSeq *to,
bool flat,
bool startpoints_only,
int inst_levels,
int pin_levels,
bool thru_disabled,
bool thru_constants);
InstanceSet
findFaninInstances(PinSeq *to,
bool flat,
bool startpoints_only,
int inst_levels,
int pin_levels,
bool thru_disabled,
bool thru_constants);
PinSet
findFanoutPins(PinSeq *from,
bool flat,
bool endpoints_only,
int inst_levels,
int pin_levels,
bool thru_disabled,
bool thru_constants);
InstanceSet
findFanoutInstances(PinSeq *from,
bool flat,
bool endpoints_only,
int inst_levels,
int pin_levels,
bool thru_disabled,
bool thru_constants);
// The set of clocks that arrive at vertex in the clock network.
ClockSet clocks(const Pin *pin);
// Clock domains for a pin.
ClockSet clockDomains(const Pin *pin);
void checkSlewLimitPreamble();
// Return pins with the min/max slew limit slack.
// net=null check all nets
// corner=nullptr checks all corners.
PinSeq checkSlewLimits(Net *net,
bool violators,
const Corner *corner,
const MinMax *min_max);
void reportSlewLimitShortHeader();
void reportSlewLimitShort(Pin *pin,
const Corner *corner,
const MinMax *min_max);
void reportSlewLimitVerbose(Pin *pin,
const Corner *corner,
const MinMax *min_max);
// requires checkSlewLimitPreamble()
void checkSlew(const Pin *pin,
const Corner *corner,
const MinMax *min_max,
bool check_clks,
// Return values.
const Corner *&corner1,
const RiseFall *&tr,
Slew &slew,
float &limit,
float &slack);
void maxSlewCheck(// Return values.
const Pin *&pin,
Slew &slew,
float &slack,
float &limit);
void findSlewLimit(const LibertyPort *port,
const Corner *corner,
const MinMax *min_max,
// Return values.
float &limit,
bool &exists);
void checkFanoutLimitPreamble();
// Return pins with the min/max fanout limit slack.
// net=null check all nets
// corner=nullptr checks all corners.
PinSeq checkFanoutLimits(Net *net,
bool violators,
const MinMax *min_max);
void reportFanoutLimitShortHeader();
void reportFanoutLimitShort(Pin *pin,
const MinMax *min_max);
void reportFanoutLimitVerbose(Pin *pin,
const MinMax *min_max);
// requires checkFanoutLimitPreamble()
void checkFanout(const Pin *pin,
const MinMax *min_max,
// Return values.
float &fanout,
float &limit,
float &slack);
void maxFanoutCheck(// Return values.
const Pin *&pin,
float &fanout,
float &slack,
float &limit);
void checkCapacitanceLimitPreamble();
// Return pins with the min/max slew limit slack.
// net=null check all nets
// corner=nullptr checks all corners.
PinSeq checkCapacitanceLimits(Net *net,
bool violators,
const Corner *corner,
const MinMax *min_max);
void reportCapacitanceLimitShortHeader();
void reportCapacitanceLimitShort(Pin *pin,
const Corner *corner,
const MinMax *min_max);
void reportCapacitanceLimitVerbose(Pin *pin,
const Corner *corner,
const MinMax *min_max);
// requires checkCapacitanceLimitPreamble()
void checkCapacitance(const Pin *pin,
const Corner *corner,
const MinMax *min_max,
// Return values.
const Corner *&corner1,
const RiseFall *&tr,
float &capacitance,
float &limit,
float &slack);
void maxCapacitanceCheck(// Return values.
const Pin *&pin,
float &capacitance,
float &slack,
float &limit);
// Min pulse width check with the least slack.
// corner=nullptr checks all corners.
MinPulseWidthCheck *minPulseWidthSlack(const Corner *corner);
// All violating min pulse width checks.
// corner=nullptr checks all corners.
MinPulseWidthCheckSeq &minPulseWidthViolations(const Corner *corner);
// Min pulse width checks for pins.
// corner=nullptr checks all corners.
MinPulseWidthCheckSeq &minPulseWidthChecks(PinSeq *pins,
const Corner *corner);
// All min pulse width checks.
// corner=nullptr checks all corners.
MinPulseWidthCheckSeq &minPulseWidthChecks(const Corner *corner);
void reportMpwChecks(MinPulseWidthCheckSeq *checks,
bool verbose);
void reportMpwCheck(MinPulseWidthCheck *check,
bool verbose);
// Min period check with the least slack.
MinPeriodCheck *minPeriodSlack();
// All violating min period checks.
MinPeriodCheckSeq &minPeriodViolations();
void reportChecks(MinPeriodCheckSeq *checks,
bool verbose);
void reportCheck(MinPeriodCheck *check,
bool verbose);
// Max skew check with the least slack.
MaxSkewCheck *maxSkewSlack();
// All violating min period checks.
MaxSkewCheckSeq &maxSkewViolations();
void reportChecks(MaxSkewCheckSeq *checks,
bool verbose);
void reportCheck(MaxSkewCheck *check,
bool verbose);
////////////////////////////////////////////////////////////////
// User visible but non SDC commands.
// Instance specific process/voltage/temperature.
// Defaults to operating condition if instance is not annotated.
const Pvt *pvt(Instance *inst,
const MinMax *min_max);
void setPvt(Instance *inst,
const MinMaxAll *min_max,
float process,
float voltage,
float temperature);
// Pvt may be shared among multiple instances.
void setPvt(const Instance *inst,
const MinMaxAll *min_max,
const Pvt &pvt);
void setVoltage(const MinMax *min_max,
float voltage);
void setVoltage(const Net *net,
const MinMax *min_max,
float voltage);
// Clear all state except network.
virtual void clear();
// Remove all constraints.
virtual void removeConstraints();
// Notify the sta that the constraints have changed directly rather
// than thru this sta API.
virtual void constraintsChanged();
// Namespace used by command interpreter.
CmdNamespace cmdNamespace();
void setCmdNamespace(CmdNamespace namespc);
OperatingConditions *operatingConditions(const MinMax *min_max) const;
// Set the delay on a timing arc.
// Required/arrival times are incrementally updated.
void setArcDelay(Edge *edge,
TimingArc *arc,
const Corner *corner,
const MinMaxAll *min_max,
ArcDelay delay);
// Set annotated slew on a vertex for delay calculation.
void setAnnotatedSlew(Vertex *vertex,
const Corner *corner,
const MinMaxAll *min_max,
const RiseFallBoth *rf,
float slew);
void writeSdf(const char *filename,
const Corner *corner,
char divider,
bool include_typ,
int digits,
bool gzip,
bool no_timestamp,
bool no_version);
// Remove all delay and slew annotations.
void removeDelaySlewAnnotations();
virtual CheckErrorSeq &checkTiming(bool no_input_delay,
bool no_output_delay,
bool reg_multiple_clks,
bool reg_no_clks,
bool unconstrained_endpoints,
bool loops,
bool generated_clks);
// Path from/thrus/to filter.
// from/thrus/to are owned and deleted by Search.
// PathEnds in the returned PathEndSeq are owned by Search PathGroups
// and deleted on next call.
virtual PathEndSeq findPathEnds(ExceptionFrom *from,
ExceptionThruSeq *thrus,
ExceptionTo *to,
bool unconstrained,
// Use corner nullptr to report timing
// for all corners.
const Corner *corner,
// max for setup checks.
// min for hold checks.
// min_max for setup and hold checks.
const MinMaxAll *min_max,
// Number of path ends to report in
// each group.
int group_path_count,
// Number of paths to report for
// each endpoint.
int endpoint_path_count,
// endpoint_path_count paths report paths with
// unique pins.
bool unique_pins,
// endpoint_path_count paths report paths with
// unique pins and rise/fall edges.
bool unique_edges,
// Min/max bounds for slack of
// returned path ends.
float slack_min,
float slack_max,
// Sort path ends by slack ignoring path groups.
bool sort_by_slack,
// Path groups to report.
// Null or empty list reports all groups.
PathGroupNameSet *group_names,
// Predicates to filter the type of path
// ends returned.
bool setup,
bool hold,
bool recovery,
bool removal,
bool clk_gating_setup,
bool clk_gating_hold);
void setReportPathFormat(ReportPathFormat format);
void setReportPathFieldOrder(StringSeq *field_names);
void setReportPathFields(bool report_input_pin,
bool report_hier_pins,
bool report_net,
bool report_cap,
bool report_slew,
bool report_fanout,
bool report_src_attr);
ReportField *findReportPathField(const char *name);
void setReportPathDigits(int digits);
void setReportPathNoSplit(bool no_split);
void setReportPathSigmas(bool report_sigmas);
// Header above reportPathEnd results.
void reportPathEndHeader();
// Footer below reportPathEnd results.
void reportPathEndFooter();
// Format report_path_endpoint only:
// Previous path end is used to detect path group changes
// so headers are reported by group.
void reportPathEnd(PathEnd *end,
PathEnd *prev_end,
bool last);
void reportPathEnd(PathEnd *end);
void reportPathEnds(PathEndSeq *ends);
ReportPath *reportPath() { return report_path_; }
void reportPath(const Path *path);
// Report clk skews for clks.
void reportClkSkew(ConstClockSeq &clks,
const Corner *corner,
const SetupHold *setup_hold,
bool include_internal_latency,
int digits);
float findWorstClkSkew(const SetupHold *setup_hold,
bool include_internal_latency);
void reportClkLatency(ConstClockSeq &clks,
const Corner *corner,
bool include_internal_latency,
int digits);
// Find min/max/rise/fall delays for clk.
ClkDelays findClkDelays(const Clock *clk,
bool include_internal_latency);
// Update arrival times for all pins.
// If necessary updateTiming propagates arrivals around latch
// loops until the arrivals converge.
// If full=false update arrivals incrementally.
// If full=true update all arrivals from scratch.
// NOTE WELL: There is rarely any reason to call updateTiming directly because
// arrival/required/slack functions implicitly update timing incrementally.
// If you are calling this function you are either very confused or there is
// bug that should be reported.
void updateTiming(bool full);
// Invalidate all delay calculations. Arrivals also invalidated.
void delaysInvalid() const;
// Invalidate all arrival and required times.
void arrivalsInvalid();
PinSet startpointPins();
PinSet endpointPins();
VertexSet *endpoints();
int endpointViolationCount(const MinMax *min_max);
// Find the fanin vertices for a group path.
// Vertices in the clock network are NOT included.
PinSet findGroupPathPins(const char *group_path_name);
// Find all required times after updateTiming().
void findRequireds();
std::string reportDelayCalc(Edge *edge,
TimingArc *arc,
const Corner *corner,
const MinMax *min_max,
int digits);
void writeSdc(const char *filename,
// Map hierarchical pins and instances to leaf pins and instances.
bool leaf,
// Replace non-sdc get functions with OpenSTA equivalents.
bool native,
int digits,
bool gzip,
bool no_timestamp);
// The sum of all negative endpoints slacks.
// Incrementally updated.
Slack totalNegativeSlack(const MinMax *min_max);
Slack totalNegativeSlack(const Corner *corner,
const MinMax *min_max);
// Worst endpoint slack and vertex.
// Incrementally updated.
Slack worstSlack(const MinMax *min_max);
void worstSlack(const MinMax *min_max,
// Return values.
Slack &worst_slack,
Vertex *&worst_vertex);
void worstSlack(const Corner *corner,
const MinMax *min_max,
// Return values.
Slack &worst_slack,
Vertex *&worst_vertex);
VertexPathIterator *vertexPathIterator(Vertex *vertex,
const RiseFall *rf,
const PathAnalysisPt *path_ap);
VertexPathIterator *vertexPathIterator(Vertex *vertex,
const RiseFall *rf,
const MinMax *min_max);
Path *vertexWorstArrivalPath(Vertex *vertex,
const RiseFall *rf,
const MinMax *min_max);
Path *vertexWorstArrivalPath(Vertex *vertex,
const MinMax *min_max);
Path *vertexWorstRequiredPath(Vertex *vertex,
const RiseFall *rf,
const MinMax *min_max);
Path *vertexWorstRequiredPath(Vertex *vertex,
const MinMax *min_max);
Path *vertexWorstSlackPath(Vertex *vertex,
const MinMax *min_max);
Path *vertexWorstSlackPath(Vertex *vertex,
const RiseFall *rf,
const MinMax *min_max);
// Find the min clock period for rise/rise and fall/fall paths of a clock
// using the slack. This does NOT correctly predict min period when there
// are paths between different clocks.
float findClkMinPeriod(const Clock *clk,
bool include_port_paths);
// The following arrival/required/slack functions incrementally
// update timing to the level of the vertex. They do NOT do multiple
// passes required propagate arrivals around latch loops.
// See Sta::updateTiming() to propagate arrivals around latch loops.
Arrival vertexArrival(Vertex *vertex,
const RiseFall *rf,
const ClockEdge *clk_edge,
const PathAnalysisPt *path_ap,
const MinMax *min_max);
// Min/max across all clock tags.
Arrival vertexArrival(Vertex *vertex,
const RiseFall *rf,
const PathAnalysisPt *path_ap);
Arrival vertexArrival(Vertex *vertex,
const MinMax *min_max);
Arrival pinArrival(const Pin *pin,
const RiseFall *rf,
const MinMax *min_max);
Required vertexRequired(Vertex *vertex,
const MinMax *min_max);
Required vertexRequired(Vertex *vertex,
const RiseFall *rf,
const MinMax *min_max);
// Min/max across all clock tags.
Required vertexRequired(Vertex *vertex,
const RiseFall *rf,
const PathAnalysisPt *path_ap);
Required vertexRequired(Vertex *vertex,
const RiseFall *rf,
const ClockEdge *clk_edge,
const PathAnalysisPt *path_ap);
Slack netSlack(const Net *net,
const MinMax *min_max);
Slack pinSlack(const Pin *pin,
const RiseFall *rf,
const MinMax *min_max);
Slack pinSlack(const Pin *pin,
const MinMax *min_max);
// Worst slack for an endpoint in a path group.
Slack endpointSlack(const Pin *pin,
const std::string &path_group_name,
const MinMax *min_max);
Slack vertexSlack(Vertex *vertex,
const MinMax *min_max);
Slack vertexSlack(Vertex *vertex,
const RiseFall *rf,
const MinMax *min_max);
// Slack with respect to clk_edge.
Slack vertexSlack(Vertex *vertex,
const RiseFall *rf,
const ClockEdge *clk_edge,
const PathAnalysisPt *path_ap);
// Min slack across all clock tags.
Slack vertexSlack(Vertex *vertex,
const RiseFall *rf,
const PathAnalysisPt *path_ap);
void vertexSlacks(Vertex *vertex,
Slack (&slacks)[RiseFall::index_count][MinMax::index_count]);
// Slew for one corner.
Slew vertexSlew(Vertex *vertex,
const RiseFall *rf,
const Corner *corner,
const MinMax *min_max);
// Slew for one delay calc analysis pt (corner min/max).
Slew vertexSlew(Vertex *vertex,
const RiseFall *rf,
const DcalcAnalysisPt *dcalc_ap);
// Slew across all corners.
Slew vertexSlew(Vertex *vertex,
const RiseFall *rf,
const MinMax *min_max);
Slew vertexSlew(Vertex *vertex,
const MinMax *min_max);
ArcDelay arcDelay(Edge *edge,
TimingArc *arc,
const DcalcAnalysisPt *dcalc_ap);
// True if the timing arc has been back-annotated.
bool arcDelayAnnotated(Edge *edge,
TimingArc *arc,
DcalcAnalysisPt *dcalc_ap);
// Set/unset the back-annotation flag for a timing arc.
void setArcDelayAnnotated(Edge *edge,
TimingArc *arc,
DcalcAnalysisPt *dcalc_ap,
bool annotated);
// Make sure levels are up to date and return vertex level.
Level vertexLevel(Vertex *vertex);
GraphLoopSeq &graphLoops();
PathAnalysisPt *pathAnalysisPt(Path *path);
DcalcAnalysisPt *pathDcalcAnalysisPt(Path *path);
TagIndex tagCount() const;
TagGroupIndex tagGroupCount() const;
int clkInfoCount() const;
int pathCount() const;
int vertexPathCount(Vertex *vertex) const;
Vertex *maxPathCountVertex() const;
LogicValue simLogicValue(const Pin *pin);
// Propagate liberty constant functions and pins tied high/low through
// combinational logic and registers.
void findLogicConstants();
// Clear the constants found by findLogicConstants so they do not interfere
// with normal constant propagate for timing.
void clearLogicConstants();
// Instances sorted by max driver pin slew.
InstanceSeq slowDrivers(int count);
// Make parasitic analysis points.
// per_corner ap_count
// false 2
// true corners*2
void setParasiticAnalysisPts(bool per_corner);
// Annotate hierarchical "instance" with parasitics.
// The parasitic analysis point is ap_name.
// The parasitic memory footprint is much smaller if parasitic
// networks (dspf) are reduced and deleted after reading each net
// with reduce_to and delete_after_reduce.
// Return true if successful.
bool readSpef(const char *filename,
Instance *instance,
const Corner *corner,
const MinMaxAll *min_max,
bool pin_cap_included,
bool keep_coupling_caps,
float coupling_cap_factor,
bool reduce);
void reportParasiticAnnotation(bool report_unannotated,
const Corner *corner);
// Parasitics.
void findPiElmore(Pin *drvr_pin,
const RiseFall *rf,
const MinMax *min_max,
float &c2,
float &rpi,
float &c1,
bool &exists) const;
void findElmore(Pin *drvr_pin,
Pin *load_pin,
const RiseFall *rf,
const MinMax *min_max,
float &elmore,
bool &exists) const;
void makePiElmore(Pin *drvr_pin,
const RiseFall *rf,
const MinMaxAll *min_max,
float c2,
float rpi,
float c1);
void setElmore(Pin *drvr_pin,
Pin *load_pin,
const RiseFall *rf,
const MinMaxAll *min_max,
float elmore);
void deleteParasitics();
Parasitic *makeParasiticNetwork(const Net *net,
bool includes_pin_caps,
const ParasiticAnalysisPt *ap);
////////////////////////////////////////////////////////////////
// TCL network edit function support.
virtual Instance *makeInstance(const char *name,
LibertyCell *cell,
Instance *parent);
virtual void deleteInstance(Instance *inst);
// replace_cell
virtual void replaceCell(Instance *inst,
Cell *to_cell);
virtual void replaceCell(Instance *inst,
LibertyCell *to_lib_cell);
virtual Net *makeNet(const char *name,
Instance *parent);
virtual void deleteNet(Net *net);
// connect_net
virtual void connectPin(Instance *inst,
Port *port,
Net *net);
virtual void connectPin(Instance *inst,
LibertyPort *port,
Net *net);
// disconnect_net
virtual void disconnectPin(Pin *pin);
virtual void makePortPin(const char *port_name,
PortDirection *dir);
// Notify STA of network change.
void networkChanged();
void deleteLeafInstanceBefore(const Instance *inst);
void deleteInstancePinsBefore(const Instance *inst);
// Network edit before/after methods.
void makeInstanceAfter(const Instance *inst);
// Replace the instance cell with to_cell.
// equivCells(from_cell, to_cell) must be true.
virtual void replaceEquivCellBefore(const Instance *inst,
const LibertyCell *to_cell);
virtual void replaceEquivCellAfter(const Instance *inst);
// Replace the instance cell with to_cell.
// equivCellPorts(from_cell, to_cell) must be true.
virtual void replaceCellBefore(const Instance *inst,
const LibertyCell *to_cell);
virtual void replaceCellAfter(const Instance *inst);
virtual void makePortPinAfter(Pin *pin);
virtual void connectPinAfter(const Pin *pin);
virtual void disconnectPinBefore(const Pin *pin);
virtual void deleteNetBefore(const Net *net);
virtual void deleteInstanceBefore(const Instance *inst);
virtual void deletePinBefore(const Pin *pin);
////////////////////////////////////////////////////////////////
void ensureClkNetwork();
void clkPinsInvalid();
// The following functions assume ensureClkNetwork() has been called.
bool isClock(const Pin *pin) const;
bool isClock(const Net *net) const;
bool isIdealClock(const Pin *pin) const;
bool isPropagatedClock(const Pin *pin) const;
const PinSet *pins(const Clock *clk);
////////////////////////////////////////////////////////////////
void setTclInterp(Tcl_Interp *interp);
Tcl_Interp *tclInterp();
// Ensure a network has been read, and linked.
Network *ensureLinked();
// Ensure a network has been read, linked and liberty libraries exist.
Network *ensureLibLinked();
void ensureLevelized();
// Ensure that the timing graph has been built.
Graph *ensureGraph();
void ensureClkArrivals();
Corner *cmdCorner() const;
void setCmdCorner(Corner *corner);
Corner *findCorner(const char *corner_name);
bool multiCorner();
virtual void makeCorners(StringSet *corner_names);
// Find all arc delays and vertex slews with delay calculator.
virtual void findDelays();
// Find arc delays and vertex slews thru to level of to_vertex.
virtual void findDelays(Vertex *to_vertex);
// Find arc delays and vertex slews thru to level.
virtual void findDelays(Level level);
// Percentage (0.0:1.0) change in delay that causes downstream
// delays to be recomputed during incremental delay calculation.
// Defaults to 0.0 for maximum accuracy and slowest incremental speed.
void setIncrementalDelayTolerance(float tol);
// Make graph and find delays.
void searchPreamble();
// Define the delay calculator implementation.
void setArcDelayCalc(const char *delay_calc_name);
void setDebugLevel(const char *what,
int level);
// Delays and arrivals downsteam from inst are invalid.
void delaysInvalidFrom(const Instance *inst);
// Delays and arrivals downsteam from pin are invalid.
void delaysInvalidFrom(const Pin *pin);
void delaysInvalidFrom(Vertex *vertex);
// Delays to driving pins of net (fanin) are invalid.
// Arrivals downsteam from net are invalid.
void delaysInvalidFromFanin(const Net *net);
void delaysInvalidFromFanin(const Pin *pin);
void delaysInvalidFromFanin(Vertex *vertex);
void replaceCellPinInvalidate(const LibertyPort *from_port,
Vertex *vertex,
const LibertyCell *to_cell);
// Power API.
Power *power() { return power_; }
const Power *power() const { return power_; }
void power(const Corner *corner,
// Return values.
PowerResult &total,
PowerResult &sequential,
PowerResult &combinational,
PowerResult &clock,
PowerResult ¯o,
PowerResult &pad);
PowerResult power(const Instance *inst,
const Corner *corner);
PwrActivity activity(const Pin *pin);
void writeTimingModel(const char *lib_name,
const char *cell_name,
const char *filename,
const Corner *corner);
// Find equivalent cells in equiv_libs.
// Optionally add mappings for cells in map_libs.
void makeEquivCells(LibertyLibrarySeq *equiv_libs,
LibertyLibrarySeq *map_libs);
LibertyCellSeq *equivCells(LibertyCell *cell);
void writePathSpice(Path *path,
const char *spice_filename,
const char *subckt_filename,
const char *lib_subckt_filename,
const char *model_filename,
const char *power_name,
const char *gnd_name,
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);
////////////////////////////////////////////////////////////////
Properties &properties() { return properties_; }
protected:
// Default constructors that are called by makeComponents in the Sta
// constructor. These can be redefined by a derived class to
// specialize the sta components.
virtual void makeVariables();
virtual void makeReport();
virtual void makeDebug();
virtual void makeUnits();
virtual void makeNetwork();
virtual void makeSdcNetwork();
virtual void makeSdc();
virtual void makeGraph();
virtual void makeCorners();
virtual void makeLevelize();
virtual void makeParasitics();
virtual void makeArcDelayCalc();
virtual void makeGraphDelayCalc();
virtual void makeSim();
virtual void makeSearch();
virtual void makeLatches();
virtual void makeClkNetwork();
virtual void makeCheckTiming();
virtual void makeCheckSlewLimits();
virtual void makeCheckFanoutLimits();
virtual void makeCheckCapacitanceLimits();
virtual void makeCheckMinPulseWidths();
virtual void makeCheckMinPeriods();
virtual void makeCheckMaxSkews();
virtual void makeReportPath();
virtual void makePower();
virtual void makeObservers();
NetworkEdit *networkCmdEdit();
LibertyLibrary *readLibertyFile(const char *filename,
Corner *corner,
const MinMaxAll *min_max,
bool infer_latches);
// Allow external Liberty reader to parse forms not used by Sta.
virtual LibertyLibrary *readLibertyFile(const char *filename,
bool infer_latches);
void delayCalcPreamble();
void delaysInvalidFrom(const Port *port);
void delaysInvalidFromFanin(const Port *port);
void deleteEdge(Edge *edge);
void netParasiticCaps(Net *net,
const RiseFall *rf,
const MinMax *min_max,
float &pin_cap,
float &wire_cap) const;
const Pin *findNetParasiticDrvrPin(const Net *net) const;
void exprConstantPins(FuncExpr *expr,
const Instance *inst,
PinSet &pins);
Slack vertexSlack1(Vertex *vertex,
const RiseFall *rf,
const ClockEdge *clk_edge,
const PathAnalysisPt *path_ap);
void findRequired(Vertex *vertex);
Required vertexRequired(Vertex *vertex,
const RiseFall *rf,
const ClockEdge *clk_edge,
const PathAnalysisPt *path_ap,
const MinMax *min_max);
void connectDrvrPinAfter(Vertex *vertex);
void connectLoadPinAfter(Vertex *vertex);
Path *latchEnablePath(Path *q_path,
Edge *d_q_edge,
const ClockEdge *en_clk_edge);
void clockSlewChanged(Clock *clk);
void minPulseWidthPreamble();
void minPeriodPreamble();
void maxSkewPreamble();
bool idealClockMode();
void disableAfter();
void findFaninPins(Vertex *vertex,
bool flat,
bool startpoints_only,
int inst_levels,
int pin_levels,
PinSet &fanin,
SearchPred &pred);
void findFaninPins(Vertex *to,
bool flat,
int inst_levels,
int pin_levels,
VertexSet &visited,
SearchPred *pred,
int inst_level,
int pin_level);
void findFanoutPins(Vertex *vertex,
bool flat,
bool endpoints_only,
int inst_levels,
int pin_levels,
PinSet &fanout,
SearchPred &pred);
void findFanoutPins(Vertex *from,
bool flat,
int inst_levels,
int pin_levels,
VertexSet &visited,
SearchPred *pred,
int inst_level,
int pin_level);
void findRegisterPreamble();
bool crossesHierarchy(Edge *edge) const;
void readLibertyAfter(LibertyLibrary *liberty,
Corner *corner,
const MinMax *min_max);
void powerPreamble();
virtual void replaceCell(Instance *inst,
Cell *to_cell,
LibertyCell *to_lib_cell);
void sdcChangedGraph();
void ensureGraphSdcAnnotated();
CornerSeq makeCornerSeq(Corner *corner) const;
void makeParasiticAnalysisPts();
void clkSkewPreamble();
void setCmdNamespace1(CmdNamespace namespc);
void setThreadCount1(int thread_count);
CmdNamespace cmd_namespace_;
Instance *current_instance_;
Corner *cmd_corner_;
VerilogReader *verilog_reader_;
CheckTiming *check_timing_;
CheckSlewLimits *check_slew_limits_;
CheckFanoutLimits *check_fanout_limits_;
CheckCapacitanceLimits *check_capacitance_limits_;
CheckMinPulseWidths *check_min_pulse_widths_;
CheckMinPeriods *check_min_periods_;
CheckMaxSkews *check_max_skews_;
ClkSkews *clk_skews_;
ReportPath *report_path_;
Power *power_;
Tcl_Interp *tcl_interp_;
bool update_genclks_;
EquivCells *equiv_cells_;
bool graph_sdc_annotated_;
bool parasitics_per_corner_;
bool parasitics_per_min_max_;
Properties properties_;
// Singleton sta used by tcl command interpreter.
static Sta *sta_;
};
} // namespace