mirror of
https://github.com/The-OpenROAD-Project/OpenSTA.git
synced 2026-09-08 04:31:14 +02:00
@@ -50,24 +50,41 @@ class ArcDcalcArg
|
||||
{
|
||||
public:
|
||||
ArcDcalcArg();
|
||||
ArcDcalcArg(const Pin *drvr_pin,
|
||||
Edge *edge,
|
||||
const TimingArc *arc,
|
||||
const Slew in_slew,
|
||||
const Parasitic *parasitic);
|
||||
ArcDcalcArg(const ArcDcalcArg &arg);
|
||||
ArcDcalcArg(const Pin *in_pin,
|
||||
const Pin *drvr_pin,
|
||||
Edge *edge,
|
||||
const TimingArc *arc,
|
||||
const Slew in_slew,
|
||||
const Parasitic *parasitic);
|
||||
ArcDcalcArg(const Pin *in_pin,
|
||||
const Pin *drvr_pin,
|
||||
Edge *edge,
|
||||
const TimingArc *arc,
|
||||
float in_delay);
|
||||
const Pin *inPin() const { return in_pin_; }
|
||||
const RiseFall *inEdge() const;
|
||||
const Pin *drvrPin() const { return drvr_pin_; }
|
||||
LibertyCell *drvrCell() const;
|
||||
const LibertyLibrary *drvrLibrary() const;
|
||||
const RiseFall *drvrEdge() const;
|
||||
const Net *drvrNet(const Network *network) const;
|
||||
Edge *edge() const { return edge_; }
|
||||
const TimingArc *arc() const { return arc_; }
|
||||
Slew inSlew() const { return in_slew_; }
|
||||
void setInSlew(Slew in_slew);
|
||||
const Parasitic *parasitic() { return parasitic_; }
|
||||
void setParasitic(const Parasitic *parasitic);
|
||||
float inputDelay() const { return input_delay_; }
|
||||
|
||||
protected:
|
||||
const Pin *in_pin_;
|
||||
const Pin *drvr_pin_;
|
||||
Edge *edge_;
|
||||
const TimingArc *arc_;
|
||||
Slew in_slew_;
|
||||
const Parasitic *parasitic_;
|
||||
float input_delay_;
|
||||
};
|
||||
|
||||
// Arc delay calc result.
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2024, Parallax Software, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "StaState.hh"
|
||||
#include "LibertyClass.hh"
|
||||
|
||||
#if CUDD
|
||||
#include "cudd.h"
|
||||
#else
|
||||
struct DdNode;
|
||||
struct DdManager;
|
||||
#endif
|
||||
|
||||
namespace sta {
|
||||
|
||||
typedef std::map<const LibertyPort*, DdNode*> BddPortVarMap;
|
||||
typedef std::map<unsigned, const LibertyPort*> BddVarIdxPortMap;
|
||||
|
||||
class Bdd : public StaState
|
||||
{
|
||||
public:
|
||||
Bdd(const StaState *sta);
|
||||
~Bdd();
|
||||
DdNode *funcBdd(const FuncExpr *expr);
|
||||
DdNode *findNode(const LibertyPort *port);
|
||||
const LibertyPort *nodePort(DdNode *node);
|
||||
DdNode *ensureNode(const LibertyPort *port);
|
||||
const LibertyPort *varIndexPort(int var_index);
|
||||
BddPortVarMap &portVarMap() { return bdd_port_var_map_; }
|
||||
|
||||
void clearVarMap();
|
||||
DdManager *cuddMgr() const { return cudd_mgr_; }
|
||||
|
||||
private:
|
||||
DdManager *cudd_mgr_;
|
||||
BddPortVarMap bdd_port_var_map_;
|
||||
BddVarIdxPortMap bdd_var_idx_port_map_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,23 @@
|
||||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2024, Parallax Software, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace sta {
|
||||
|
||||
enum class CircuitSim { hspice, ngspice, xyce };
|
||||
|
||||
} // namespace
|
||||
@@ -93,12 +93,12 @@ funcExprNot(FuncExpr *expr);
|
||||
class FuncExprPortIterator : public Iterator<LibertyPort*>
|
||||
{
|
||||
public:
|
||||
explicit FuncExprPortIterator(FuncExpr *expr);
|
||||
explicit FuncExprPortIterator(const FuncExpr *expr);
|
||||
virtual bool hasNext() { return iter_.hasNext(); }
|
||||
virtual LibertyPort *next() { return iter_.next(); }
|
||||
|
||||
private:
|
||||
void findPorts(FuncExpr *expr);
|
||||
void findPorts(const FuncExpr *expr);
|
||||
|
||||
LibertyPortSet ports_;
|
||||
LibertyPortSet::ConstIterator iter_;
|
||||
|
||||
@@ -115,7 +115,6 @@ public:
|
||||
uint32_t count);
|
||||
PathVertexRep *prevPaths(Vertex *vertex) const;
|
||||
void clearPrevPaths();
|
||||
// Slews are reported slews in seconds.
|
||||
// Reported slew are the same as those in the liberty tables.
|
||||
// reported_slews = measured_slews / slew_derate_from_library
|
||||
// Measured slews are between slew_lower_threshold and slew_upper_threshold.
|
||||
@@ -141,6 +140,15 @@ public:
|
||||
void makeWireEdgesThruPin(const Pin *hpin);
|
||||
virtual void makeWireEdgesFromPin(const Pin *drvr_pin);
|
||||
virtual void deleteEdge(Edge *edge);
|
||||
// Find the edge and timing arc on a gate between in_pin and drvr_pin.
|
||||
void gateEdgeArc(const Pin *in_pin,
|
||||
const RiseFall *in_rf,
|
||||
const Pin *drvr_pin,
|
||||
const RiseFall *drvr_rf,
|
||||
// Return values.
|
||||
Edge *&edge,
|
||||
const TimingArc *&arc) const;
|
||||
|
||||
virtual ArcDelay arcDelay(const Edge *edge,
|
||||
const TimingArc *arc,
|
||||
DcalcAPIndex ap_index) const;
|
||||
|
||||
@@ -92,6 +92,14 @@ public:
|
||||
float &wire_cap,
|
||||
float &fanout,
|
||||
bool &has_set_load) const;
|
||||
void parasiticLoad(const Pin *drvr_pin,
|
||||
const RiseFall *rf,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
const MultiDrvrNet *multi_drvr,
|
||||
ArcDelayCalc *arc_delay_calc,
|
||||
// Return values.
|
||||
float &cap,
|
||||
const Parasitic *¶sitic) const;
|
||||
LoadPinIndexMap makeLoadPinIndexMap(Vertex *drvr_vertex);
|
||||
void findDriverArcDelays(Vertex *drvr_vertex,
|
||||
Edge *edge,
|
||||
@@ -231,14 +239,6 @@ protected:
|
||||
const RiseFall *rf,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
ArcDelayCalc *arc_delay_calc) const;
|
||||
void parasiticLoad(const Pin *drvr_pin,
|
||||
const RiseFall *rf,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
const MultiDrvrNet *multi_drvr,
|
||||
ArcDelayCalc *arc_delay_calc,
|
||||
// Return values.
|
||||
float &cap,
|
||||
const Parasitic *¶sitic) const;
|
||||
void parasiticLoad(const Pin *drvr_pin,
|
||||
const RiseFall *rf,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
|
||||
+13
-3
@@ -319,7 +319,6 @@ public:
|
||||
DriverWaveform *findDriverWaveform(const char *name);
|
||||
DriverWaveform *driverWaveformDefault() { return driver_waveform_default_; }
|
||||
void addDriverWaveform(DriverWaveform *driver_waveform);
|
||||
void ensureVoltageWaveforms();
|
||||
|
||||
protected:
|
||||
float degradeWireSlew(const TableModel *model,
|
||||
@@ -371,7 +370,6 @@ protected:
|
||||
DriverWaveformMap driver_waveform_map_;
|
||||
// Unnamed driver waveform.
|
||||
DriverWaveform *driver_waveform_default_;
|
||||
bool have_voltage_waveforms_;
|
||||
|
||||
static constexpr float input_threshold_default_ = .5;
|
||||
static constexpr float output_threshold_default_ = .5;
|
||||
@@ -533,6 +531,7 @@ public:
|
||||
// Check all liberty cells to make sure they exist
|
||||
// for all the defined corners.
|
||||
static void checkLibertyCorners();
|
||||
void ensureVoltageWaveforms();
|
||||
|
||||
protected:
|
||||
void addPort(ConcretePort *port);
|
||||
@@ -608,6 +607,7 @@ protected:
|
||||
bool leakage_power_exists_;
|
||||
LibertyPgPortMap pg_port_map_;
|
||||
bool has_internal_ports_;
|
||||
bool have_voltage_waveforms_;
|
||||
|
||||
private:
|
||||
friend class LibertyLibrary;
|
||||
@@ -795,7 +795,15 @@ public:
|
||||
DriverWaveform *driverWaveform(const RiseFall *rf) const;
|
||||
void setDriverWaveform(DriverWaveform *driver_waveform,
|
||||
const RiseFall *rf);
|
||||
RiseFallMinMax clockTreePathDelays();
|
||||
void setClkTreeDelay(const TableModel *model,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max);
|
||||
float clkTreeDelay(float in_slew,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max) const;
|
||||
// Assumes input slew of 0.0.
|
||||
RiseFallMinMax clkTreeDelays() const;
|
||||
RiseFallMinMax clockTreePathDelays() const; // __attribute__ ((deprecated))
|
||||
|
||||
static bool equiv(const LibertyPort *port1,
|
||||
const LibertyPort *port2);
|
||||
@@ -837,6 +845,8 @@ protected:
|
||||
Vector<LibertyPort*> corner_ports_;
|
||||
ReceiverModelPtr receiver_model_;
|
||||
DriverWaveform *driver_waveform_[RiseFall::index_count];
|
||||
// Redundant with clock_tree_path_delay timing arcs but faster to access.
|
||||
const TableModel *clk_tree_delay_[RiseFall::index_count][MinMax::index_count];
|
||||
|
||||
unsigned int min_pulse_width_exists_:RiseFall::index_count;
|
||||
bool min_period_exists_:1;
|
||||
|
||||
@@ -50,6 +50,7 @@ typedef Iterator<Port*> PortMemberIterator;
|
||||
typedef Vector<const Pin*> PinSeq;
|
||||
typedef Vector<const Instance*> InstanceSeq;
|
||||
typedef Vector<const Net*> NetSeq;
|
||||
typedef std::vector<const Net*> ConstNetSeq;
|
||||
typedef Iterator<Instance*> InstanceChildIterator;
|
||||
typedef Iterator<Pin*> InstancePinIterator;
|
||||
typedef Iterator<Net*> InstanceNetIterator;
|
||||
|
||||
@@ -163,11 +163,20 @@ public:
|
||||
// True if the parasitic network caps include pin capacitances.
|
||||
virtual bool includesPinCaps(const Parasitic *parasitic) const = 0;
|
||||
// Parasitic network component builders.
|
||||
virtual ParasiticNode *findParasiticNode(Parasitic *parasitic,
|
||||
const Net *net,
|
||||
int id,
|
||||
const Network *network) const = 0;
|
||||
// Make a subnode of the parasitic network net.
|
||||
virtual ParasiticNode *ensureParasiticNode(Parasitic *parasitic,
|
||||
const Net *net,
|
||||
int id,
|
||||
const Network *network) = 0;
|
||||
// Find the parasitic node connected to pin.
|
||||
virtual ParasiticNode *findParasiticNode(const Parasitic *parasitic,
|
||||
const Pin *pin) const = 0;
|
||||
virtual ParasiticNode *findNode(const Parasitic *parasitic,
|
||||
const Pin *pin) const __attribute__ ((deprecated));
|
||||
// Make a subnode of the parasitic network net connected to pin.
|
||||
virtual ParasiticNode *ensureParasiticNode(Parasitic *parasitic,
|
||||
const Pin *pin,
|
||||
@@ -175,14 +184,11 @@ public:
|
||||
// Increment the grounded capacitance on node.
|
||||
virtual void incrCap(ParasiticNode *node,
|
||||
float cap) = 0;
|
||||
virtual const char *name(const ParasiticNode *node) = 0;
|
||||
virtual const char *name(const ParasiticNode *node) const = 0;
|
||||
virtual const Pin *pin(const ParasiticNode *node) const = 0;
|
||||
virtual const Net *net(const ParasiticNode *node,
|
||||
const Network *network) const = 0;
|
||||
virtual bool isExternal(const ParasiticNode *node) const = 0;
|
||||
// Find the parasitic node connected to pin.
|
||||
virtual ParasiticNode *findNode(const Parasitic *parasitic,
|
||||
const Pin *pin) const = 0;
|
||||
// Node capacitance to ground.
|
||||
virtual float nodeGndCap(const ParasiticNode *node) const = 0;
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
namespace sta {
|
||||
|
||||
class Power;
|
||||
|
||||
enum class PwrActivityOrigin
|
||||
{
|
||||
global,
|
||||
|
||||
@@ -75,7 +75,9 @@ public:
|
||||
typedef Vector<float> FloatSeq;
|
||||
typedef Vector<int> IntSeq;
|
||||
typedef Vector<Clock*> ClockSeq;
|
||||
typedef std::vector<const Clock*> ConstClockSeq;
|
||||
typedef Set<Clock*, ClockIndexLess> ClockSet;
|
||||
typedef std::set<const Clock*, ClockIndexLess> ConstClockSet;
|
||||
typedef ClockSet ClockGroup;
|
||||
typedef Vector<PinSet*> PinSetSeq;
|
||||
typedef MinMax SetupHold;
|
||||
|
||||
@@ -61,6 +61,7 @@ class MaxSkewCheck;
|
||||
class CharPtrLess;
|
||||
class SearchPred;
|
||||
class BfsFwdIterator;
|
||||
class ClkDelays;
|
||||
|
||||
// Tag compare using tag matching (tagMatch) critera.
|
||||
class TagMatchLess
|
||||
@@ -116,7 +117,6 @@ typedef Vector<PathVertex> PathVertexSeq;
|
||||
typedef Vector<Slack> SlackSeq;
|
||||
typedef Delay Crpr;
|
||||
typedef Vector<PathRef> PathRefSeq;
|
||||
typedef MinMaxValues<Delay> ClkDelays[RiseFall::index_count][RiseFall::index_count];
|
||||
|
||||
enum class ReportPathFormat { full,
|
||||
full_clock,
|
||||
|
||||
+6
-6
@@ -57,8 +57,6 @@ class SearchPred;
|
||||
class Corner;
|
||||
class ClkSkews;
|
||||
class ReportField;
|
||||
class Power;
|
||||
class PowerResult;
|
||||
class EquivCells;
|
||||
|
||||
typedef InstanceSeq::Iterator SlowDrvrIterator;
|
||||
@@ -913,15 +911,17 @@ public:
|
||||
void reportPath(Path *path);
|
||||
|
||||
// Report clk skews for clks.
|
||||
void reportClkSkew(ClockSet *clks,
|
||||
void reportClkSkew(ConstClockSeq clks,
|
||||
const Corner *corner,
|
||||
const SetupHold *setup_hold,
|
||||
int digits);
|
||||
float findWorstClkSkew(const SetupHold *setup_hold);
|
||||
|
||||
void reportClkLatency(ConstClockSeq clks,
|
||||
const Corner *corner,
|
||||
int digits);
|
||||
// Find min/max/rise/fall delays for clk.
|
||||
void findClkDelays(const Clock *clk,
|
||||
// Return values.
|
||||
ClkDelays &delays);
|
||||
ClkDelays findClkDelays(const Clock *clk);
|
||||
|
||||
// Update arrival times for all pins.
|
||||
// If necessary updateTiming propagates arrivals around latch
|
||||
|
||||
@@ -318,6 +318,7 @@ public:
|
||||
TableAxisPtr axis1);
|
||||
virtual ~Table1();
|
||||
Table1(Table1 &&table);
|
||||
Table1(const Table1 &table);
|
||||
Table1 &operator= (Table1 &&table);
|
||||
int order() const override { return 1; }
|
||||
const TableAxis *axis1() const override { return axis1_.get(); }
|
||||
|
||||
@@ -16,16 +16,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
#include "StringSet.hh"
|
||||
#include "CircuitSim.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
using std::string;
|
||||
using std::set;
|
||||
|
||||
class Path;
|
||||
class StaState;
|
||||
|
||||
@@ -41,11 +36,9 @@ writePathSpice(Path *path,
|
||||
const char *lib_subckt_filename,
|
||||
// Device model file included in spice file.
|
||||
const char *model_filename,
|
||||
// Nets off of path to include in the spice run.
|
||||
StdStringSet *off_path_pin_names,
|
||||
const char *power_name,
|
||||
const char *gnd_name,
|
||||
bool measure_stmts,
|
||||
CircuitSim ckt_sim,
|
||||
StaState *sta);
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user