2018-09-28 17:54:21 +02:00
|
|
|
// OpenSTA, Static Timing Analyzer
|
2019-01-01 21:26:11 +01:00
|
|
|
// Copyright (c) 2019, Parallax Software, Inc.
|
2018-09-28 17:54:21 +02:00
|
|
|
//
|
|
|
|
|
// 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/>.
|
|
|
|
|
|
|
|
|
|
#ifndef STA_STA_H
|
|
|
|
|
#define STA_STA_H
|
|
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
|
#include "DisallowCopyAssign.hh"
|
|
|
|
|
#include "StringSeq.hh"
|
|
|
|
|
#include "StaState.hh"
|
|
|
|
|
#include "LibertyClass.hh"
|
|
|
|
|
#include "NetworkClass.hh"
|
|
|
|
|
#include "SdcClass.hh"
|
|
|
|
|
#include "GraphClass.hh"
|
|
|
|
|
#include "SearchClass.hh"
|
|
|
|
|
#include "ParasiticsClass.hh"
|
|
|
|
|
#include "VertexVisitor.hh"
|
|
|
|
|
|
|
|
|
|
struct Tcl_Interp;
|
|
|
|
|
|
|
|
|
|
namespace sta {
|
|
|
|
|
|
|
|
|
|
using std::string;
|
|
|
|
|
using ::Tcl_Interp;
|
|
|
|
|
|
|
|
|
|
// Don't include headers to minimize dependencies.
|
|
|
|
|
class MinMax;
|
|
|
|
|
class MinMaxAll;
|
2019-11-11 23:30:19 +01:00
|
|
|
class RiseFallBoth;
|
|
|
|
|
class RiseFall;
|
2018-09-28 17:54:21 +02:00
|
|
|
class ReportPath;
|
|
|
|
|
class CheckTiming;
|
|
|
|
|
class DcalcAnalysisPt;
|
|
|
|
|
class CheckSlewLimits;
|
|
|
|
|
class CheckMinPulseWidths;
|
|
|
|
|
class CheckMinPeriods;
|
|
|
|
|
class CheckMaxSkews;
|
|
|
|
|
class PatternMatch;
|
|
|
|
|
class CheckPeriods;
|
|
|
|
|
class LibertyReader;
|
|
|
|
|
class SearchPred;
|
|
|
|
|
class Corner;
|
|
|
|
|
class ClkSkews;
|
|
|
|
|
class ReportField;
|
2018-11-26 18:15:52 +01:00
|
|
|
class Power;
|
|
|
|
|
class PowerResult;
|
2019-03-13 01:25:53 +01:00
|
|
|
class ClockIterator;
|
2019-06-21 06:41:49 +02:00
|
|
|
class EquivCells;
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
typedef InstanceSeq::Iterator SlowDrvrIterator;
|
|
|
|
|
typedef Vector<const char*> CheckError;
|
|
|
|
|
typedef Vector<CheckError*> CheckErrorSeq;
|
|
|
|
|
|
2019-03-13 01:25:53 +01:00
|
|
|
enum class CmdNamespace { sta, sdc };
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
// 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 setMinLibrary(const char *min_filename,
|
|
|
|
|
const char *max_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 linkMakeBlackBoxes() const;
|
|
|
|
|
void setLinkMakeBlackBoxes(bool make);
|
|
|
|
|
|
|
|
|
|
// 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,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const EarlyLate *early_late,
|
|
|
|
|
float derate);
|
|
|
|
|
// Delay type is always net for net derating.
|
|
|
|
|
void setTimingDerate(const Net *net,
|
|
|
|
|
PathClkOrData clk_data,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const EarlyLate *early_late,
|
|
|
|
|
float derate);
|
|
|
|
|
void setTimingDerate(const Instance *inst,
|
|
|
|
|
TimingDerateType type,
|
|
|
|
|
PathClkOrData clk_data,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const EarlyLate *early_late,
|
|
|
|
|
float derate);
|
|
|
|
|
void setTimingDerate(const LibertyCell *cell,
|
|
|
|
|
TimingDerateType type,
|
|
|
|
|
PathClkOrData clk_data,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const EarlyLate *early_late,
|
|
|
|
|
float derate);
|
|
|
|
|
void unsetTimingDerate();
|
|
|
|
|
void setInputSlew(Port *port,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMaxAll *min_max,
|
|
|
|
|
float slew);
|
|
|
|
|
// Port external pin load.
|
|
|
|
|
float portExtPinCap(Port *port,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max);
|
|
|
|
|
// Set port external pin load (set_load -pin port).
|
|
|
|
|
void setPortExtPinCap(Port *port,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMaxAll *min_max,
|
|
|
|
|
float cap);
|
|
|
|
|
// Port external wire load.
|
|
|
|
|
float portExtWireCap(Port *port,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max);
|
|
|
|
|
// Set port external wire load (set_load -wire port).
|
|
|
|
|
void setPortExtWireCap(Port *port,
|
|
|
|
|
bool subtract_pin_cap,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMaxAll *min_max,
|
|
|
|
|
float cap);
|
|
|
|
|
// Set net wire capacitance (set_load -wire net).
|
|
|
|
|
void setNetWireCap(Net *net,
|
|
|
|
|
bool subtract_pin_load,
|
2018-11-09 19:04:16 +01:00
|
|
|
const Corner *corner,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMaxAll *min_max,
|
|
|
|
|
float cap);
|
|
|
|
|
// Port external fanout (used by wireload models).
|
|
|
|
|
int portExtFanout(Port *port,
|
|
|
|
|
const MinMax *min_max);
|
|
|
|
|
// Set port external fanout (used by wireload models).
|
|
|
|
|
void setPortExtFanout(Port *port,
|
|
|
|
|
int fanout,
|
|
|
|
|
const MinMaxAll *min_max);
|
|
|
|
|
// Remove all "set_load net" annotations.
|
|
|
|
|
void removeNetLoadCaps() const;
|
|
|
|
|
// pin_cap = net pin capacitances + port external pin capacitance,
|
|
|
|
|
// wire_cap = annotated net capacitance + port external wire capacitance.
|
|
|
|
|
void connectedCap(Pin *drvr_pin,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-11-09 19:04:16 +01:00
|
|
|
const Corner *corner,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max,
|
|
|
|
|
float &pin_cap,
|
|
|
|
|
float &wire_cap) const;
|
|
|
|
|
void connectedCap(Net *net,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-11-09 19:04:16 +01:00
|
|
|
const Corner *corner,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max,
|
|
|
|
|
float &pin_cap,
|
|
|
|
|
float &wire_cap) const;
|
|
|
|
|
void setResistance(Net *net,
|
|
|
|
|
const MinMaxAll *min_max,
|
|
|
|
|
float res);
|
2019-02-16 21:07:59 +01:00
|
|
|
void setDriveCell(LibertyLibrary *library,
|
2018-09-28 17:54:21 +02:00
|
|
|
LibertyCell *cell,
|
2019-02-16 21:07:59 +01:00
|
|
|
Port *port,
|
2018-09-28 17:54:21 +02:00
|
|
|
LibertyPort *from_port,
|
|
|
|
|
float *from_slews,
|
|
|
|
|
LibertyPort *to_port,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMaxAll *min_max);
|
|
|
|
|
void setDriveResistance(Port *port,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMaxAll *min_max,
|
|
|
|
|
float res);
|
|
|
|
|
void setLatchBorrowLimit(Pin *pin,
|
|
|
|
|
float limit);
|
|
|
|
|
void setLatchBorrowLimit(Instance *inst,
|
|
|
|
|
float limit);
|
|
|
|
|
void setLatchBorrowLimit(Clock *clk,
|
|
|
|
|
float limit);
|
2019-11-11 23:30:19 +01:00
|
|
|
void setMinPulseWidth(const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
float min_width);
|
|
|
|
|
void setMinPulseWidth(const Pin *pin,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
float min_width);
|
|
|
|
|
void setMinPulseWidth(const Instance *inst,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
float min_width);
|
|
|
|
|
void setMinPulseWidth(const Clock *clk,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
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,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const PathClkOrData clk_data,
|
|
|
|
|
const MinMax *min_max,
|
|
|
|
|
float slew);
|
|
|
|
|
void setSlewLimit(Port *port,
|
|
|
|
|
const MinMax *min_max,
|
|
|
|
|
float slew);
|
|
|
|
|
void setSlewLimit(Pin *pin,
|
|
|
|
|
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,
|
|
|
|
|
Pin *pll_out,
|
|
|
|
|
Pin *pll_fdbk,
|
|
|
|
|
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();
|
2019-03-13 01:25:53 +01:00
|
|
|
// Use Sdc::findClock
|
|
|
|
|
Clock *findClock(const char *name) const __attribute__ ((deprecated));
|
|
|
|
|
// Use findClocksMatching.
|
2018-09-28 17:54:21 +02:00
|
|
|
void findClocksMatching(PatternMatch *pattern,
|
2019-03-13 01:25:53 +01:00
|
|
|
ClockSeq *clks) const __attribute__ ((deprecated));
|
|
|
|
|
// Use Sdc::clockIterator.
|
|
|
|
|
ClockIterator *clockIterator() const __attribute__ ((deprecated));
|
2018-09-28 17:54:21 +02:00
|
|
|
// True if pin is defined as a clock source (pin may be hierarchical).
|
|
|
|
|
bool isClockSrc(const Pin *pin) const;
|
2019-03-13 01:25:53 +01:00
|
|
|
// Use Sdc::defaultArrivalClock.
|
|
|
|
|
Clock *defaultArrivalClock() const __attribute__ ((deprecated));
|
2018-09-28 17:54:21 +02:00
|
|
|
// Propagated (non-ideal) clocks.
|
|
|
|
|
void setPropagatedClock(Clock *clk);
|
|
|
|
|
void removePropagatedClock(Clock *clk);
|
|
|
|
|
void setPropagatedClock(Pin *pin);
|
|
|
|
|
void removePropagatedClock(Pin *pin);
|
|
|
|
|
void setClockSlew(Clock *clock,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
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,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
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,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
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,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *from_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
Clock *to_clk,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *to_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const SetupHoldAll *setup_hold,
|
|
|
|
|
float uncertainty);
|
|
|
|
|
virtual void removeClockUncertainty(Clock *from_clk,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *from_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
Clock *to_clk,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *to_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const SetupHoldAll *setup_hold);
|
|
|
|
|
ClockGroups *makeClockGroups(const char *name,
|
|
|
|
|
bool logically_exclusive,
|
|
|
|
|
bool physically_exclusive,
|
|
|
|
|
bool asynchronous,
|
|
|
|
|
bool allow_paths,
|
|
|
|
|
const char *comment);
|
2019-03-13 01:25:53 +01:00
|
|
|
// nullptr name removes all.
|
2018-09-28 17:54:21 +02:00
|
|
|
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);
|
2019-11-11 23:30:19 +01:00
|
|
|
void setClockGatingCheck(const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const SetupHold *setup_hold,
|
|
|
|
|
float margin);
|
|
|
|
|
void setClockGatingCheck(Clock *clk,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const SetupHold *setup_hold,
|
|
|
|
|
float margin);
|
|
|
|
|
void setClockGatingCheck(Instance *inst,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const SetupHold *setup_hold,
|
|
|
|
|
float margin,
|
|
|
|
|
LogicValue active_value);
|
|
|
|
|
void setClockGatingCheck(Pin *pin,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const SetupHold *setup_hold,
|
|
|
|
|
float margin,
|
|
|
|
|
LogicValue active_value);
|
|
|
|
|
void setDataCheck(Pin *from,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *from_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
Pin *to,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *to_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
Clock *clk,
|
2019-06-27 00:58:23 +02:00
|
|
|
const SetupHoldAll *setup_hold,
|
2018-09-28 17:54:21 +02:00
|
|
|
float margin);
|
|
|
|
|
void removeDataCheck(Pin *from,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *from_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
Pin *to,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *to_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
Clock *clk,
|
2019-06-27 00:58:23 +02:00
|
|
|
const SetupHoldAll *setup_hold);
|
2018-09-28 17:54:21 +02:00
|
|
|
// 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);
|
|
|
|
|
// Edge is default cond disabled by timing_disable_cond_default_arcs var.
|
|
|
|
|
bool isDisabledCondDefault(Edge *edge);
|
|
|
|
|
// Edge is disabled to prpath a clock from propagating.
|
|
|
|
|
bool isDisabledClock(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(Pin *pin,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
Clock *clk,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *clk_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
Pin *ref_pin,
|
|
|
|
|
bool source_latency_included,
|
|
|
|
|
bool network_latency_included,
|
|
|
|
|
const MinMaxAll *min_max,
|
|
|
|
|
bool add,
|
|
|
|
|
float delay);
|
|
|
|
|
void removeInputDelay(Pin *pin,
|
2019-11-11 23:30:19 +01:00
|
|
|
RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
Clock *clk,
|
2019-11-11 23:30:19 +01:00
|
|
|
RiseFall *clk_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
MinMaxAll *min_max);
|
|
|
|
|
void setOutputDelay(Pin *pin,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
Clock *clk,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *clk_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
Pin *ref_pin,
|
|
|
|
|
bool source_latency_included,
|
|
|
|
|
bool network_latency_included,
|
|
|
|
|
const MinMaxAll *min_max,
|
|
|
|
|
bool add,
|
|
|
|
|
float delay);
|
|
|
|
|
void removeOutputDelay(Pin *pin,
|
2019-11-11 23:30:19 +01:00
|
|
|
RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
Clock *clk,
|
2019-11-11 23:30:19 +01:00
|
|
|
RiseFall *clk_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
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,
|
|
|
|
|
float delay,
|
|
|
|
|
const char *comment);
|
|
|
|
|
void makeGroupPath(const char *name,
|
|
|
|
|
bool is_default,
|
|
|
|
|
ExceptionFrom *from,
|
|
|
|
|
ExceptionThruSeq *thrus,
|
|
|
|
|
ExceptionTo *to,
|
|
|
|
|
const char *comment);
|
|
|
|
|
bool isGroupPathName(const char *group_name);
|
|
|
|
|
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,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *from_rf);
|
2018-09-28 17:54:21 +02:00
|
|
|
void checkExceptionFromPins(ExceptionFrom *from,
|
|
|
|
|
const char *file,
|
|
|
|
|
int line) const;
|
|
|
|
|
bool exceptionFromInvalid(const Pin *pin) const;
|
|
|
|
|
void deleteExceptionFrom(ExceptionFrom *from);
|
|
|
|
|
// Make an exception -through specification.
|
|
|
|
|
ExceptionThru *makeExceptionThru(PinSet *pins,
|
|
|
|
|
NetSet *nets,
|
|
|
|
|
InstanceSet *insts,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf);
|
2018-09-28 17:54:21 +02:00
|
|
|
void deleteExceptionThru(ExceptionThru *thru);
|
|
|
|
|
// Make an exception -to specification.
|
|
|
|
|
ExceptionTo *makeExceptionTo(PinSet *to_pins,
|
|
|
|
|
ClockSet *to_clks,
|
|
|
|
|
InstanceSet *to_insts,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
|
|
|
|
RiseFallBoth *end_rf);
|
2018-09-28 17:54:21 +02:00
|
|
|
void checkExceptionToPins(ExceptionTo *to,
|
|
|
|
|
const char *file, int) const;
|
|
|
|
|
void deleteExceptionTo(ExceptionTo *to);
|
|
|
|
|
InstanceSet *findRegisterInstances(ClockSet *clks,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *clk_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
bool edge_triggered,
|
|
|
|
|
bool latches);
|
|
|
|
|
PinSet *findRegisterDataPins(ClockSet *clks,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *clk_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
bool registers,
|
|
|
|
|
bool latches);
|
|
|
|
|
PinSet *findRegisterClkPins(ClockSet *clks,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *clk_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
bool registers,
|
|
|
|
|
bool latches);
|
|
|
|
|
PinSet *findRegisterAsyncPins(ClockSet *clks,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *clk_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
bool registers,
|
|
|
|
|
bool latches);
|
|
|
|
|
PinSet *findRegisterOutputPins(ClockSet *clks,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *clk_rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
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 reach pin.
|
|
|
|
|
void clocks(const Pin *pin,
|
|
|
|
|
// Return value.
|
|
|
|
|
ClockSet &clks);
|
|
|
|
|
|
|
|
|
|
// Return the pin with the min/max slew limit slack.
|
2019-03-13 01:25:53 +01:00
|
|
|
// corner=nullptr checks all corners.
|
2018-11-09 19:04:16 +01:00
|
|
|
Pin *pinMinSlewLimitSlack(const Corner *corner,
|
|
|
|
|
const MinMax *min_max);
|
2018-09-28 17:54:21 +02:00
|
|
|
// Return all pins with min/max slew violations.
|
2019-03-13 01:25:53 +01:00
|
|
|
// corner=nullptr checks all corners.
|
2018-11-09 19:04:16 +01:00
|
|
|
PinSeq *pinSlewLimitViolations(const Corner *corner,
|
|
|
|
|
const MinMax *min_max);
|
2018-09-28 17:54:21 +02:00
|
|
|
void reportSlewLimitShortHeader();
|
|
|
|
|
void reportSlewLimitShort(Pin *pin,
|
2018-11-09 19:04:16 +01:00
|
|
|
const Corner *corner,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max);
|
|
|
|
|
void reportSlewLimitVerbose(Pin *pin,
|
2018-11-09 19:04:16 +01:00
|
|
|
const Corner *corner,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max);
|
|
|
|
|
void checkSlews(const Pin *pin,
|
2018-11-09 19:04:16 +01:00
|
|
|
const Corner *corner,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max,
|
|
|
|
|
// Return values.
|
2018-11-09 19:04:16 +01:00
|
|
|
const Corner *&corner1,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *&tr,
|
2018-09-28 17:54:21 +02:00
|
|
|
Slew &slew,
|
|
|
|
|
float &limit,
|
|
|
|
|
float &slack);
|
|
|
|
|
// Min pulse width check with the least slack.
|
2019-03-13 01:25:53 +01:00
|
|
|
// corner=nullptr checks all corners.
|
2018-11-09 19:04:16 +01:00
|
|
|
MinPulseWidthCheck *minPulseWidthSlack(const Corner *corner);
|
2018-09-28 17:54:21 +02:00
|
|
|
// All violating min pulse width checks.
|
2019-03-13 01:25:53 +01:00
|
|
|
// corner=nullptr checks all corners.
|
2018-11-09 19:04:16 +01:00
|
|
|
MinPulseWidthCheckSeq &minPulseWidthViolations(const Corner *corner);
|
2018-09-28 17:54:21 +02:00
|
|
|
// Min pulse width checks for pins.
|
2019-03-13 01:25:53 +01:00
|
|
|
// corner=nullptr checks all corners.
|
2018-11-09 19:04:16 +01:00
|
|
|
MinPulseWidthCheckSeq &minPulseWidthChecks(PinSeq *pins,
|
|
|
|
|
const Corner *corner);
|
2018-09-28 17:54:21 +02:00
|
|
|
// All min pulse width checks.
|
2019-03-13 01:25:53 +01:00
|
|
|
// corner=nullptr checks all corners.
|
2018-11-09 19:04:16 +01:00
|
|
|
MinPulseWidthCheckSeq &minPulseWidthChecks(const Corner *corner);
|
2018-09-28 17:54:21 +02:00
|
|
|
void reportMpwChecks(MinPulseWidthCheckSeq *checks,
|
|
|
|
|
bool verbose);
|
|
|
|
|
void reportMpwCheck(MinPulseWidthCheck *check,
|
|
|
|
|
bool verbose);
|
|
|
|
|
|
|
|
|
|
// Min period check with the least slack.
|
2019-03-13 01:25:53 +01:00
|
|
|
MinPeriodCheck *minPeriodSlack();
|
2018-09-28 17:54:21 +02:00
|
|
|
// All violating min period checks.
|
2019-03-13 01:25:53 +01:00
|
|
|
MinPeriodCheckSeq &minPeriodViolations();
|
2018-09-28 17:54:21 +02:00
|
|
|
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);
|
|
|
|
|
|
2018-11-26 18:15:52 +01:00
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
// User visible but non SDC commands.
|
|
|
|
|
|
|
|
|
|
// Instance specific process/voltage/temperature.
|
|
|
|
|
// Defaults to operating condition if instance is not annotated.
|
|
|
|
|
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(Instance *inst,
|
|
|
|
|
const MinMaxAll *min_max,
|
|
|
|
|
Pvt *pvt);
|
|
|
|
|
// 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,
|
2019-05-26 02:08:53 +02:00
|
|
|
ArcDelay delay);
|
2018-09-28 17:54:21 +02:00
|
|
|
// Set annotated slew on a vertex for delay calculation.
|
|
|
|
|
void setAnnotatedSlew(Vertex *vertex,
|
|
|
|
|
const Corner *corner,
|
|
|
|
|
const MinMaxAll *min_max,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFallBoth *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
float slew);
|
|
|
|
|
void writeSdf(const char *filename,
|
|
|
|
|
Corner *corner,
|
|
|
|
|
char sdf_divider,
|
|
|
|
|
int digits,
|
|
|
|
|
bool gzip,
|
|
|
|
|
bool no_timestamp,
|
|
|
|
|
bool no_version);
|
|
|
|
|
// Remove all delay and slew annotations.
|
|
|
|
|
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);
|
2019-01-27 08:03:01 +01:00
|
|
|
// TCL variable sta_pocv_enabled.
|
|
|
|
|
// Parametric on chip variation (statisical sta).
|
|
|
|
|
bool pocvEnabled() const;
|
|
|
|
|
void setPocvEnabled(bool enabled);
|
2019-03-13 01:25:53 +01:00
|
|
|
// Number of std deviations from mean to use for normal distributions.
|
|
|
|
|
void setSigmaFactor(float factor);
|
2018-09-28 17:54:21 +02:00
|
|
|
// 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,
|
|
|
|
|
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.
|
|
|
|
|
// Returned sequence is owned by the caller.
|
|
|
|
|
// PathEnds are owned by Search PathGroups and deleted on next call.
|
|
|
|
|
virtual PathEndSeq *findPathEnds(ExceptionFrom *from,
|
|
|
|
|
ExceptionThruSeq *thrus,
|
|
|
|
|
ExceptionTo *to,
|
2019-01-06 01:09:27 +01:00
|
|
|
bool unconstrained,
|
2019-03-13 01:25:53 +01:00
|
|
|
// Use corner nullptr to report timing
|
2018-09-28 17:54:21 +02:00
|
|
|
// 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.
|
2018-10-24 01:28:41 +02:00
|
|
|
int group_count,
|
2018-09-28 17:54:21 +02:00
|
|
|
// Number of paths to report for
|
|
|
|
|
// each endpoint.
|
2018-10-24 01:28:41 +02:00
|
|
|
int endpoint_count,
|
|
|
|
|
// endpoint_count paths report unique pins
|
2018-09-28 17:54:21 +02:00
|
|
|
// without rise/fall variations.
|
|
|
|
|
bool unique_pins,
|
|
|
|
|
// 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);
|
|
|
|
|
PathEndSeq *reportTiming(ExceptionFrom *from,
|
|
|
|
|
ExceptionThruSeq *thrus,
|
|
|
|
|
ExceptionTo *to,
|
2019-03-13 01:25:53 +01:00
|
|
|
// Use corner nullptr to report timing
|
2018-09-28 17:54:21 +02:00
|
|
|
// 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.
|
2018-10-24 01:28:41 +02:00
|
|
|
int group_count,
|
2018-09-28 17:54:21 +02:00
|
|
|
// Number of paths to report for
|
|
|
|
|
// each endpoint.
|
2018-10-24 01:28:41 +02:00
|
|
|
int endpoint_count,
|
|
|
|
|
// endpoint_count paths report unique pins
|
2018-09-28 17:54:21 +02:00
|
|
|
// without rise/fall variations.
|
|
|
|
|
bool unique_pins,
|
|
|
|
|
// 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) __attribute__ ((deprecated));
|
|
|
|
|
void setReportPathFormat(ReportPathFormat format);
|
|
|
|
|
void setReportPathFieldOrder(StringSeq *field_names);
|
|
|
|
|
void setReportPathFields(bool report_input_pin,
|
|
|
|
|
bool report_net,
|
|
|
|
|
bool report_cap,
|
|
|
|
|
bool report_slew);
|
|
|
|
|
ReportField *findReportPathField(const char *name);
|
|
|
|
|
void setReportPathDigits(int digits);
|
|
|
|
|
void setReportPathNoSplit(bool no_split);
|
|
|
|
|
// Report clk skews for clks.
|
|
|
|
|
void reportClkSkew(ClockSet *clks,
|
2018-11-09 19:04:16 +01:00
|
|
|
const Corner *corner,
|
2018-09-28 17:54:21 +02:00
|
|
|
const SetupHold *setup_hold,
|
|
|
|
|
int digits);
|
2018-12-21 07:41:54 +01:00
|
|
|
// 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);
|
|
|
|
|
void reportPathEnd(PathEnd *end);
|
2018-09-28 17:54:21 +02:00
|
|
|
void reportPathEnds(PathEndSeq *ends);
|
|
|
|
|
ReportPath *reportPath() { return report_path_; }
|
|
|
|
|
void reportPath(Path *path);
|
|
|
|
|
// 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.
|
|
|
|
|
void updateTiming(bool full);
|
|
|
|
|
// Invalidate all arrival and required times.
|
|
|
|
|
void arrivalsInvalid();
|
|
|
|
|
void setPathMinMax(const MinMaxAll *min_max) __attribute__ ((deprecated));
|
|
|
|
|
void visitStartpoints(VertexVisitor *visitor);
|
|
|
|
|
void visitEndpoints(VertexVisitor *visitor);
|
|
|
|
|
// Find the fanin vertices for a group path.
|
|
|
|
|
// Vertices in the clock network are NOT included.
|
|
|
|
|
// Return value is owned by the caller.
|
|
|
|
|
PinSet *findGroupPathPins(const char *group_path_name);
|
|
|
|
|
// Find all required times after updateTiming().
|
|
|
|
|
void findRequireds();
|
|
|
|
|
string *reportDelayCalc(Edge *edge,
|
|
|
|
|
TimingArc *arc,
|
|
|
|
|
const Corner *corner,
|
|
|
|
|
const MinMax *min_max,
|
|
|
|
|
int digits);
|
|
|
|
|
void writeSdc(const char *filename,
|
2019-10-25 17:51:59 +02:00
|
|
|
// Map hierarchical pins and instances to leaf pins and instances.
|
|
|
|
|
bool leaf,
|
|
|
|
|
// Replace non-sdc get functions with OpenSTA equivalents.
|
2018-09-28 17:54:21 +02:00
|
|
|
bool native,
|
|
|
|
|
bool no_timestamp,
|
|
|
|
|
int digits);
|
|
|
|
|
|
|
|
|
|
// The sum of all negative endpoints slacks.
|
|
|
|
|
// Incrementally updated.
|
|
|
|
|
Slack totalNegativeSlack(const MinMax *min_max);
|
2018-12-05 23:18:41 +01:00
|
|
|
Slack totalNegativeSlack(const Corner *corner,
|
|
|
|
|
const MinMax *min_max);
|
|
|
|
|
// Worst endpoint slack and vertex.
|
2018-09-28 17:54:21 +02:00
|
|
|
// Incrementally updated.
|
2018-12-05 23:18:41 +01:00
|
|
|
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);
|
2018-09-28 17:54:21 +02:00
|
|
|
VertexPathIterator *vertexPathIterator(Vertex *vertex,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const PathAnalysisPt *path_ap);
|
|
|
|
|
VertexPathIterator *vertexPathIterator(Vertex *vertex,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max);
|
|
|
|
|
void
|
|
|
|
|
vertexWorstArrivalPath(Vertex *vertex,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max,
|
|
|
|
|
// Return value.
|
|
|
|
|
PathRef &worst_path);
|
|
|
|
|
void
|
|
|
|
|
vertexWorstArrivalPath(Vertex *vertex,
|
|
|
|
|
const MinMax *min_max,
|
|
|
|
|
// Return value.
|
|
|
|
|
PathRef &worst_path);
|
|
|
|
|
void
|
|
|
|
|
vertexWorstSlackPath(Vertex *vertex,
|
|
|
|
|
const MinMax *min_max,
|
|
|
|
|
// Return value.
|
|
|
|
|
PathRef &worst_path);
|
|
|
|
|
void
|
|
|
|
|
vertexWorstSlackPath(Vertex *vertex,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max,
|
|
|
|
|
// Return value.
|
|
|
|
|
PathRef &worst_path);
|
|
|
|
|
|
|
|
|
|
// 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,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const ClockEdge *clk_edge,
|
|
|
|
|
const PathAnalysisPt *path_ap);
|
|
|
|
|
// Min/max across all clock tags.
|
|
|
|
|
Arrival vertexArrival(Vertex *vertex,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const PathAnalysisPt *path_ap);
|
2019-11-03 18:48:22 +01:00
|
|
|
Required vertexRequired(Vertex *vertex,
|
|
|
|
|
const MinMax *min_max);
|
|
|
|
|
// Min/max across all clock tags.
|
2018-09-28 17:54:21 +02:00
|
|
|
Required vertexRequired(Vertex *vertex,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const PathAnalysisPt *path_ap);
|
|
|
|
|
Required vertexRequired(Vertex *vertex,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2019-11-03 18:48:22 +01:00
|
|
|
const ClockEdge *clk_edge,
|
2018-09-28 17:54:21 +02:00
|
|
|
const PathAnalysisPt *path_ap);
|
2019-11-06 17:55:04 +01:00
|
|
|
|
|
|
|
|
Slack netSlack(const Net *net,
|
|
|
|
|
const MinMax *min_max);
|
2018-09-28 17:54:21 +02:00
|
|
|
Slack pinSlack(const Pin *pin,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max);
|
|
|
|
|
Slack pinSlack(const Pin *pin,
|
|
|
|
|
const MinMax *min_max);
|
|
|
|
|
Slack vertexSlack(Vertex *vertex,
|
|
|
|
|
const MinMax *min_max);
|
|
|
|
|
Slack vertexSlack(Vertex *vertex,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max);
|
|
|
|
|
// Slack with respect to clk_edge.
|
|
|
|
|
Slack vertexSlack(Vertex *vertex,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const ClockEdge *clk_edge,
|
|
|
|
|
const PathAnalysisPt *path_ap);
|
|
|
|
|
// Min slack across all clock tags.
|
|
|
|
|
Slack vertexSlack(Vertex *vertex,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const PathAnalysisPt *path_ap);
|
2018-11-26 18:15:52 +01:00
|
|
|
// Slew for one delay calc analysis pt(corner).
|
2018-09-28 17:54:21 +02:00
|
|
|
Slew vertexSlew(Vertex *vertex,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const DcalcAnalysisPt *dcalc_ap);
|
2018-11-26 18:15:52 +01:00
|
|
|
// Slew across all corners.
|
2018-09-28 17:54:21 +02:00
|
|
|
Slew vertexSlew(Vertex *vertex,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
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.
|
2018-11-09 19:04:16 +01:00
|
|
|
void setArcDelayAnnotated(Edge *edge,
|
2018-09-28 17:54:21 +02:00
|
|
|
TimingArc *arc,
|
2018-11-09 19:04:16 +01:00
|
|
|
DcalcAnalysisPt *dcalc_ap,
|
|
|
|
|
bool annotated);
|
2018-09-28 17:54:21 +02:00
|
|
|
// 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;
|
2019-03-25 07:04:20 +01:00
|
|
|
int arrivalCount() const;
|
|
|
|
|
int vertexArrivalCount(Vertex *vertex) const;
|
|
|
|
|
Vertex *maxArrivalCountVertex() const;
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
LogicValue simLogicValue(const Pin *pin);
|
|
|
|
|
// Iterator for instances sorted by max driver pin slew.
|
2019-03-13 01:25:53 +01:00
|
|
|
// Caller owns iterator and iterator->container().
|
2018-09-28 17:54:21 +02:00
|
|
|
SlowDrvrIterator *slowDrvrIterator();
|
|
|
|
|
|
|
|
|
|
// Annotate hierarchical "instance" with parasitics.
|
|
|
|
|
// The parasitic analysis point is ap_name.
|
|
|
|
|
// The parasitics are used by delay calculation analysis points
|
|
|
|
|
// specfied by min_max.
|
|
|
|
|
// 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.
|
2019-01-17 00:37:31 +01:00
|
|
|
bool readSpef(const char *filename,
|
|
|
|
|
Instance *instance,
|
|
|
|
|
const MinMaxAll *min_max,
|
|
|
|
|
bool increment,
|
|
|
|
|
bool pin_cap_included,
|
|
|
|
|
bool keep_coupling_caps,
|
|
|
|
|
float coupling_cap_factor,
|
|
|
|
|
ReduceParasiticsTo reduce_to,
|
|
|
|
|
bool delete_after_reduce,
|
|
|
|
|
bool save,
|
|
|
|
|
bool quiet);
|
2018-09-28 17:54:21 +02:00
|
|
|
// Parasitics.
|
|
|
|
|
void findPiElmore(Pin *drvr_pin,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max,
|
|
|
|
|
float &c2,
|
|
|
|
|
float &rpi,
|
|
|
|
|
float &c1,
|
|
|
|
|
bool &exists) const;
|
|
|
|
|
void findElmore(Pin *drvr_pin,
|
|
|
|
|
Pin *load_pin,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max,
|
|
|
|
|
float &elmore,
|
|
|
|
|
bool &exists) const;
|
|
|
|
|
void makePiElmore(Pin *drvr_pin,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMaxAll *min_max,
|
|
|
|
|
float c2,
|
|
|
|
|
float rpi,
|
|
|
|
|
float c1);
|
|
|
|
|
void setElmore(Pin *drvr_pin,
|
|
|
|
|
Pin *load_pin,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMaxAll *min_max,
|
|
|
|
|
float elmore);
|
|
|
|
|
|
|
|
|
|
// 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,
|
2019-06-14 21:05:34 +02:00
|
|
|
Cell *to_cell);
|
|
|
|
|
virtual void replaceCell(Instance *inst,
|
|
|
|
|
LibertyCell *to_lib_cell);
|
2018-09-28 17:54:21 +02:00
|
|
|
virtual Net *makeNet(const char *name,
|
|
|
|
|
Instance *parent);
|
|
|
|
|
virtual void deleteNet(Net *net);
|
|
|
|
|
// connect_net
|
|
|
|
|
virtual void connectPin(Instance *inst,
|
|
|
|
|
Port *port,
|
|
|
|
|
Net *net);
|
2019-05-03 17:07:00 +02:00
|
|
|
virtual void connectPin(Instance *inst,
|
|
|
|
|
LibertyPort *port,
|
|
|
|
|
Net *net);
|
2018-09-28 17:54:21 +02:00
|
|
|
// disconnect_net
|
|
|
|
|
virtual void disconnectPin(Pin *pin);
|
|
|
|
|
|
|
|
|
|
// Network edit before/after methods.
|
|
|
|
|
void makeInstanceAfter(Instance *inst);
|
|
|
|
|
// Not used by Sta (connectPinAfter).
|
|
|
|
|
void makePinAfter(Pin *pin) __attribute__ ((deprecated));
|
|
|
|
|
// Replace the instance cell with to_cell.
|
|
|
|
|
// equivCells(from_cell, to_cell) must be true.
|
2019-04-11 05:36:48 +02:00
|
|
|
virtual void replaceEquivCellBefore(Instance *inst,
|
|
|
|
|
LibertyCell *to_cell);
|
|
|
|
|
virtual void replaceEquivCellAfter(Instance *inst);
|
2018-09-28 17:54:21 +02:00
|
|
|
// Replace the instance cell with to_cell.
|
|
|
|
|
// equivCellPorts(from_cell, to_cell) must be true.
|
2019-04-11 05:36:48 +02:00
|
|
|
virtual void replaceCellBefore(Instance *inst,
|
|
|
|
|
LibertyCell *to_cell);
|
|
|
|
|
virtual void replaceCellAfter(Instance *inst);
|
2018-09-28 17:54:21 +02:00
|
|
|
virtual void connectPinAfter(Pin *pin);
|
|
|
|
|
virtual void disconnectPinBefore(Pin *pin);
|
|
|
|
|
virtual void deleteNetBefore(Net *net);
|
|
|
|
|
virtual void deleteInstanceBefore(Instance *inst);
|
|
|
|
|
virtual void deletePinBefore(Pin *pin);
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
void setTclInterp(Tcl_Interp *interp);
|
|
|
|
|
Tcl_Interp *tclInterp();
|
2019-11-03 18:48:22 +01:00
|
|
|
void ensureLevelized();
|
2018-09-28 17:54:21 +02:00
|
|
|
// Ensure that the timing graph has been built.
|
|
|
|
|
Graph *ensureGraph();
|
2019-11-03 18:48:22 +01:00
|
|
|
void ensureClkArrivals();
|
2019-04-01 18:05:07 +02:00
|
|
|
Corner *cmdCorner() const;
|
|
|
|
|
void setCmdCorner(Corner *corner);
|
2018-09-28 17:54:21 +02:00
|
|
|
Corner *findCorner(const char *corner_name);
|
|
|
|
|
bool multiCorner();
|
|
|
|
|
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(Instance *inst);
|
|
|
|
|
// Delays and arrivals downsteam from pin are invalid.
|
|
|
|
|
void delaysInvalidFrom(Pin *pin);
|
|
|
|
|
void delaysInvalidFrom(Vertex *vertex);
|
|
|
|
|
// Delays to driving pins of net (fanin) are invalid.
|
|
|
|
|
// Arrivals downsteam from net are invalid.
|
|
|
|
|
void delaysInvalidFromFanin(Net *net);
|
|
|
|
|
void delaysInvalidFromFanin(Pin *pin);
|
|
|
|
|
void delaysInvalidFromFanin(Vertex *vertex);
|
2019-04-11 05:36:48 +02:00
|
|
|
void replaceCellPinInvalidate(LibertyPort *from_port,
|
|
|
|
|
Vertex *vertex,
|
|
|
|
|
LibertyCell *to_cell);
|
2018-09-28 17:54:21 +02:00
|
|
|
|
2018-11-26 18:15:52 +01:00
|
|
|
// 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 ¯o,
|
|
|
|
|
PowerResult &pad);
|
|
|
|
|
void power(const Instance *inst,
|
|
|
|
|
const Corner *corner,
|
|
|
|
|
// Return values.
|
|
|
|
|
PowerResult &result);
|
|
|
|
|
|
2019-06-21 06:41:49 +02:00
|
|
|
// 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);
|
|
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
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 makeReport();
|
|
|
|
|
virtual void makeDebug();
|
|
|
|
|
virtual void makeUnits();
|
|
|
|
|
virtual void makeNetwork();
|
2019-11-03 03:32:09 +01:00
|
|
|
virtual void makeSdcNetwork();
|
2018-09-28 17:54:21 +02:00
|
|
|
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 makeCheckTiming();
|
|
|
|
|
virtual void makeCheckSlewLimits();
|
|
|
|
|
virtual void makeCheckMinPulseWidths();
|
|
|
|
|
virtual void makeCheckMinPeriods();
|
|
|
|
|
virtual void makeCheckMaxSkews();
|
|
|
|
|
virtual void makeReportPath();
|
2018-11-26 18:15:52 +01:00
|
|
|
virtual void makePower();
|
2018-09-28 17:54:21 +02:00
|
|
|
virtual void makeObservers();
|
|
|
|
|
NetworkEdit *networkCmdEdit();
|
|
|
|
|
|
|
|
|
|
LibertyLibrary *readLibertyFile(const char *filename,
|
|
|
|
|
Corner *corner,
|
|
|
|
|
const MinMaxAll *min_max,
|
|
|
|
|
bool infer_latches,
|
|
|
|
|
Network *network);
|
|
|
|
|
// Allow external Liberty reader to parse forms not used by Sta.
|
|
|
|
|
virtual LibertyLibrary *readLibertyFile(const char *filename,
|
|
|
|
|
bool infer_latches,
|
|
|
|
|
Network *network);
|
|
|
|
|
void delayCalcPreamble();
|
|
|
|
|
void delaysInvalidFrom(Port *port);
|
|
|
|
|
void delaysInvalidFromFanin(Port *port);
|
|
|
|
|
void deleteEdge(Edge *edge);
|
|
|
|
|
void netParasiticCaps(Net *net,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const MinMax *min_max,
|
|
|
|
|
float &pin_cap,
|
|
|
|
|
float &wire_cap) const;
|
|
|
|
|
Pin *findNetParasiticDrvrPin(Net *net) const;
|
|
|
|
|
void exprConstantPins(FuncExpr *expr,
|
|
|
|
|
Instance *inst,
|
|
|
|
|
PinSet *pins);
|
|
|
|
|
Slack vertexSlack1(Vertex *vertex,
|
2019-11-11 23:30:19 +01:00
|
|
|
const RiseFall *rf,
|
2018-09-28 17:54:21 +02:00
|
|
|
const ClockEdge *clk_edge,
|
|
|
|
|
const PathAnalysisPt *path_ap);
|
|
|
|
|
void findRequired(Vertex *vertex);
|
|
|
|
|
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 checkSlewLimitPreamble();
|
|
|
|
|
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 deleteLeafInstanceBefore(Instance *inst);
|
|
|
|
|
void readLibertyAfter(LibertyLibrary *liberty,
|
|
|
|
|
Corner *corner,
|
|
|
|
|
const MinMax *min_max);
|
2018-11-26 18:15:52 +01:00
|
|
|
void powerPreamble();
|
2019-02-26 17:26:12 +01:00
|
|
|
void disableFanoutCrprPruning(Vertex *vertex,
|
|
|
|
|
int &fanou);
|
2019-05-03 17:07:00 +02:00
|
|
|
LibertyPort *findCellPort(LibertyCell *cell,
|
|
|
|
|
PortDirection *dir);
|
2019-06-14 21:05:34 +02:00
|
|
|
void replaceCell(Instance *inst,
|
|
|
|
|
Cell *to_cell,
|
|
|
|
|
LibertyCell *to_lib_cell);
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
CmdNamespace cmd_namespace_;
|
|
|
|
|
Instance *current_instance_;
|
2019-04-01 18:05:07 +02:00
|
|
|
Corner *cmd_corner_;
|
2018-09-28 17:54:21 +02:00
|
|
|
CheckTiming *check_timing_;
|
|
|
|
|
CheckSlewLimits *check_slew_limits_;
|
|
|
|
|
CheckMinPulseWidths *check_min_pulse_widths_;
|
|
|
|
|
CheckMinPeriods *check_min_periods_;
|
|
|
|
|
CheckMaxSkews *check_max_skews_;
|
|
|
|
|
ClkSkews *clk_skews_;
|
|
|
|
|
ReportPath *report_path_;
|
2018-11-26 18:15:52 +01:00
|
|
|
Power *power_;
|
2018-09-28 17:54:21 +02:00
|
|
|
Tcl_Interp *tcl_interp_;
|
|
|
|
|
bool link_make_black_boxes_;
|
|
|
|
|
bool update_genclks_;
|
2019-06-21 06:41:49 +02:00
|
|
|
EquivCells *equiv_cells_;
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
// Singleton sta used by tcl command interpreter.
|
|
|
|
|
static Sta *sta_;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(Sta);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
#endif
|