Merge remote-tracking branch 'opensta/master' into secure-sta-test-by-opus

Signed-off-by: Jaehyun Kim <[email protected]>
This commit is contained in:
Jaehyun Kim
2026-03-21 18:54:37 +09:00
176 changed files with 13586 additions and 13837 deletions
+6 -6
View File
@@ -119,15 +119,15 @@ public:
ArcDcalcResult(size_t load_count);
void setLoadCount(size_t load_count);
ArcDelay &gateDelay() { return gate_delay_; }
void setGateDelay(ArcDelay gate_delay);
void setGateDelay(const ArcDelay &gate_delay);
Slew &drvrSlew() { return drvr_slew_; }
void setDrvrSlew(Slew drvr_slew);
ArcDelay wireDelay(size_t load_idx) const;
void setDrvrSlew(const Slew &drvr_slew);
const ArcDelay &wireDelay(size_t load_idx) const;
void setWireDelay(size_t load_idx,
ArcDelay wire_delay);
Slew loadSlew(size_t load_idx) const;
const ArcDelay &wire_delay);
const Slew &loadSlew(size_t load_idx) const;
void setLoadSlew(size_t load_idx,
Slew load_slew);
const Slew &load_slew);
protected:
ArcDelay gate_delay_;
+3 -2
View File
@@ -25,6 +25,7 @@
#pragma once
#include <map>
#include <string>
#include "MinMax.hh"
#include "RiseFallMinMax.hh"
@@ -207,7 +208,7 @@ public:
~ClockEdge();
const RiseFall *transition() const { return rf_; }
float time() const { return time_; }
const char *name() const { return name_; }
const std::string &name() const { return name_; }
int index() const { return index_; }
ClockEdge *opposite() const;
// Pulse width if this is the leading edge of the pulse.
@@ -221,7 +222,7 @@ private:
Clock *clock_;
const RiseFall *rf_;
const char *name_;
std::string name_;
float time_;
int index_;
};
+5 -3
View File
@@ -24,6 +24,8 @@
#pragma once
#include <string>
#include "SdcCmdComment.hh"
#include "SdcClass.hh"
@@ -32,7 +34,7 @@ namespace sta {
class ClockGroups : public SdcCmdComment
{
public:
ClockGroups(const char *name,
ClockGroups(const std::string &name,
bool logically_exclusive,
bool physically_exclusive,
bool asynchronous,
@@ -40,7 +42,7 @@ public:
const char *comment);
~ClockGroups();
void makeClockGroup(ClockSet *clks);
const char *name() const { return name_; }
const std::string &name() const { return name_; }
ClockGroupSet *groups() { return &groups_; }
bool logicallyExclusive() const { return logically_exclusive_; }
bool physicallyExclusive() const { return physically_exclusive_; }
@@ -49,7 +51,7 @@ public:
void removeClock(Clock *clk);
private:
const char *name_;
std::string name_;
bool logically_exclusive_;
bool physically_exclusive_;
bool asynchronous_;
+15 -7
View File
@@ -25,10 +25,12 @@
#pragma once
#include <string>
#include <cstdarg>
#include <string_view>
#include <map>
#include <mutex>
#include "Format.hh"
#include "Report.hh"
#include "StringUtil.hh"
namespace sta {
@@ -48,10 +50,16 @@ public:
bool check(const char *what,
int level) const;
int statsLevel() const { return stats_level_; }
void reportLine(const char *what,
const char *fmt,
...)
__attribute__((format (printf, 3, 4)));
template <typename... Args>
void report(const char *what,
std::string_view fmt,
Args &&...args)
{
std::string msg = sta::format("{}: {}", what,
sta::formatRuntime(fmt, std::forward<Args>(args)...));
std::unique_lock<std::mutex> lock(buffer_lock_);
report_->reportLine(msg);
}
protected:
Report *report_;
@@ -63,9 +71,9 @@ protected:
// Inlining a varargs function would eval the args, which can
// be expensive, so use a macro.
#define debugPrint(debug, what, level, ...) \
#define debugPrint(debug, what, level, fmt, ...) \
if (debug->check(what, level)) { \
debug->reportLine(what __VA_OPT__(,) __VA_ARGS__); \
debug->report(what, fmt __VA_OPT__(,) __VA_ARGS__); \
}
} // namespace
+322 -13
View File
@@ -24,27 +24,336 @@
#pragma once
#include "StaConfig.hh"
#include <array>
#include <cstddef>
// IWYU pragma: begin_exports
#if (SSTA == 1)
// Delays are Normal PDFs.
#include "DelayNormal1.hh"
#elif (SSTA == 2)
// Delays are Normal PDFs with early/late sigma.
#include "DelayNormal2.hh"
#else
// Delays are floats.
#include "DelayFloat.hh"
#endif
// IWYU pragma: end_exports
#include "StaConfig.hh"
#include "MinMax.hh"
namespace sta {
class StaState;
class Delay
{
public:
Delay();
Delay(float mean);
Delay(float mean,
// std_dev^2
float std_dev2);
Delay(float mean,
float mean_shift,
// std_dev^2
float std_dev2,
float skewness);
void setValues(float mean,
float mean_shift,
float std_dev2,
float skewnes);
float mean() const { return values_[0]; }
void setMean(float mean);
float meanShift() const { return values_[1]; }
void setMeanShift(float mean_shift);
float stdDev() const;
// std_dev ^ 2
float stdDev2() const { return values_[2]; }
void setStdDev(float std_dev);
float skewness() const { return values_[3]; }
void setSkewness(float skewness);
void operator=(float delay);
// This allows applications that do not support statistical timing
// to treat Delays as floats without explicitly converting with
// delayAsFloat.
operator float() const { return mean(); }
private:
std::array<float, 4> values_;
};
// Delay with doubles for accumulating Delays.
// Only a subset of operations are required for DelayDbl.
class DelayDbl
{
public:
DelayDbl();
DelayDbl(double value);
double mean() const { return values_[0]; }
void setMean(double mean);
double meanShift() const { return values_[1]; }
// std_dev ^ 2
double stdDev2() const { return values_[2]; }
double stdDev() const;
double skewness() const { return values_[3]; }
void setValues(double mean,
double mean_shift,
double std_dev2,
double skewnes);
void operator=(double delay);
private:
std::array<double, 4> values_;
};
using ArcDelay = Delay;
using Slew = Delay;
using Arrival = Delay;
using Required = Delay;
using Slack = Delay;
const Delay delay_zero(0.0);
class DelayOps
{
public:
virtual ~DelayOps() {}
virtual float stdDev2(const Delay &delay,
const EarlyLate *early_late) const = 0;
virtual float asFloat(const Delay &delay,
const EarlyLate *early_late,
const StaState *sta) const = 0;
virtual double asFloat(const DelayDbl &delay,
const EarlyLate *early_late,
const StaState *sta) const = 0;
virtual bool isZero(const Delay &delay) const = 0;
virtual bool isInf(const Delay &delay) const = 0;
virtual bool equal(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const = 0;
virtual bool less(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const = 0;
virtual bool less(const DelayDbl &delay1,
const DelayDbl &delay2,
const StaState *sta) const = 0;
virtual bool lessEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const = 0;
virtual bool greater(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const = 0;
virtual bool greaterEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const = 0;
virtual Delay sum(const Delay &delay1,
const Delay &delay2) const = 0;
virtual Delay sum(const Delay &delay1,
float delay2) const = 0;
virtual Delay diff(const Delay &delay1,
const Delay &delay2) const = 0;
virtual Delay diff(const Delay &delay1,
float delay2) const = 0;
virtual Delay diff(float delay1,
const Delay &delay2) const = 0;
virtual void incr(Delay &delay1,
const Delay &delay2) const = 0;
virtual void incr(DelayDbl &delay1,
const Delay &delay2) const = 0;
virtual void decr(Delay &delay1,
const Delay &delay2) const = 0;
virtual void decr(DelayDbl &delay1,
const Delay &delay2) const = 0;
virtual Delay product(const Delay &delay1,
float delay2) const = 0;
virtual Delay div(float delay1,
const Delay &delay2) const = 0;
virtual std::string asStringVariance(const Delay &delay,
int digits,
const StaState *sta) const = 0;
};
void
initDelayConstants();
inline float
square(float x)
{
return x * x;
}
inline double
square(double x)
{
return x * x;
}
inline float
cube(float x)
{
return x * x * x;
}
inline double
cube(double x)
{
return x * x * x;
}
Delay
makeDelay(float mean,
float mean_shift,
float std_dev,
float skewness);
Delay
makeDelay(float mean,
float std_dev);
Delay
makeDelay2(float mean,
float std_dev);
void
delaySetMean(Delay &delay,
float mean);
// early_late == late
std::string
delayAsString(const Delay &delay,
const StaState *sta);
// early_late == late
std::string
delayAsString(const Delay &delay,
int digits,
const StaState *sta);
std::string
delayAsString(const Delay &delay,
const EarlyLate *early_late,
const StaState *sta);
std::string
delayAsString(const Delay &delay,
const EarlyLate *early_late,
int digits,
const StaState *sta);
std::string
delayAsString(const Delay &delay,
const EarlyLate *early_late,
bool report_variance,
int digits,
const StaState *sta);
float
delayAsFloat(const Delay &delay);
float
delayAsFloat(const Delay &delay,
const EarlyLate *early_late,
const StaState *sta);
float
delayAsFloat(const DelayDbl &delay,
const EarlyLate *early_late,
const StaState *sta);
Delay
delayDblAsDelay(DelayDbl &delay);
Delay
delaySum(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
Delay
delaySum(const Delay &delay1,
float delay2,
const StaState *sta);
Delay
delayDiff(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
Delay
delayDiff(const Delay &delay1,
float delay2,
const StaState *sta);
Delay
delayDiff(float delay1,
const Delay &delay2,
const StaState *sta);
void
delayIncr(Delay &delay1,
const Delay &delay2,
const StaState *sta);
void
delayIncr(DelayDbl &delay1,
const Delay &delay2,
const StaState *sta);
void
delayIncr(Delay &delay1,
float delay2,
const StaState *sta);
void
delayDecr(Delay &delay1,
const Delay &delay2,
const StaState *sta);
void
delayDecr(DelayDbl &delay1,
const Delay &delay2,
const StaState *sta);
Delay
delayProduct(const Delay &delay1,
float delay2,
const StaState *sta);
Delay
delayDiv(float delay1,
const Delay &delay2,
const StaState *sta);
const Delay &
delayInitValue(const MinMax *min_max);
bool
delayIsInitValue(const Delay &delay,
const MinMax *min_max);
bool
delayZero(const Delay &delay,
const StaState *sta);
bool
delayInf(const Delay &delay,
const StaState *sta);
bool
delayEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayLess(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayLess(const DelayDbl &delay1,
const DelayDbl &delay2,
const StaState *sta);
bool
delayLess(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
bool
delayLessEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayLessEqual(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
bool
delayGreater(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayGreaterEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayGreaterEqual(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
bool
delayGreater(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
// delay1-delay2 subtracting sigma instead of addiing.
Delay
delayRemove(const Delay &delay1,
const Delay &delay2);
} // namespace
-152
View File
@@ -1,152 +0,0 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2026, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// This notice may not be removed or altered from any source distribution.
#pragma once
#include "MinMax.hh"
// Delay values defined as floats.
namespace sta {
class StaState;
using Delay = float;
// Delay double for accumulating Delays.
using DelayDbl = double;
const Delay delay_zero = 0.0;
void
initDelayConstants();
const char *
delayAsString(const Delay &delay,
const StaState *sta);
const char *
delayAsString(const Delay &delay,
const StaState *sta,
int digits);
const char *
delayAsString(const Delay &delay,
const EarlyLate *early_late,
const StaState *sta,
int digits);
inline Delay
makeDelay(float delay,
float,
float)
{
return delay;
}
inline Delay
makeDelay2(float delay,
float,
float)
{
return delay;
}
inline float
delayAsFloat(const Delay &delay)
{
return delay;
}
// mean late+/early- sigma
inline float
delayAsFloat(const Delay &delay,
const EarlyLate *,
const StaState *)
{
return delay;
}
inline float
delaySigma2(const Delay &,
const EarlyLate *)
{
return 0.0;
}
const Delay &
delayInitValue(const MinMax *min_max);
bool
delayIsInitValue(const Delay &delay,
const MinMax *min_max);
bool
delayZero(const Delay &delay);
bool
delayInf(const Delay &delay);
bool
delayEqual(const Delay &delay1,
const Delay &delay2);
bool
delayLess(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayLess(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
bool
delayLessEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayLessEqual(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
bool
delayGreater(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayGreaterEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayGreaterEqual(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
bool
delayGreater(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
// delay1-delay2 subtracting sigma instead of addiing.
Delay
delayRemove(const Delay &delay1,
const Delay &delay2);
float
delayRatio(const Delay &delay1,
const Delay &delay2);
} // namespace
+90
View File
@@ -0,0 +1,90 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2025, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// This notice may not be removed or altered from any source distribution.
#pragma once
#include "Delay.hh"
namespace sta {
class DelayOpsNormal : public DelayOps
{
public:
float stdDev2(const Delay &delay,
const EarlyLate *early_late) const override;
float asFloat(const Delay &delay,
const EarlyLate *early_late,
const StaState *sta) const override;
double asFloat(const DelayDbl &delay,
const EarlyLate *early_late,
const StaState *sta) const override;
bool isZero(const Delay &delay) const override;
bool isInf(const Delay &delay) const override;
bool equal(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const override;
bool less(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const override;
bool less(const DelayDbl &delay1,
const DelayDbl &delay2,
const StaState *sta) const override;
bool lessEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const override;
bool greater(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const override;
bool greaterEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const override;
Delay sum(const Delay &delay1,
const Delay &delay2) const override;
Delay sum(const Delay &delay1,
float delay2) const override;
Delay diff(const Delay &delay1,
const Delay &delay2) const override;
Delay diff(const Delay &delay1,
float delay2) const override;
Delay diff(float delay1,
const Delay &delay2) const override;
void incr(Delay &delay1,
const Delay &delay2) const override;
void incr(DelayDbl &delay1,
const Delay &delay2) const override;
void decr(Delay &delay1,
const Delay &delay2) const override;
void decr(DelayDbl &delay1,
const Delay &delay2) const override;
Delay product(const Delay &delay1,
float delay2) const override;
Delay div(float delay1,
const Delay &delay2) const override;
std::string asStringVariance(const Delay &delay,
int digits,
const StaState *sta) const override;
};
} // namespace
-203
View File
@@ -1,203 +0,0 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2026, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// This notice may not be removed or altered from any source distribution.
#pragma once
#include "MinMax.hh"
namespace sta {
class Delay;
class DelayDbl;
class StaState;
// Normal distribution with std deviation.
class Delay
{
public:
Delay();
Delay(const Delay &delay);
Delay(const DelayDbl &delay);
Delay(float mean);
Delay(float mean,
float sigma2);
float mean() const { return mean_; }
float sigma() const;
// sigma^2
float sigma2() const;
void operator=(const Delay &delay);
void operator=(float delay);
void operator+=(const Delay &delay);
void operator+=(float delay);
Delay operator+(const Delay &delay) const;
Delay operator+(float delay) const;
Delay operator-(const Delay &delay) const;
Delay operator-(float delay) const;
Delay operator-() const;
void operator-=(float delay);
void operator-=(const Delay &delay);
bool operator==(const Delay &delay) const;
private:
float mean_;
// Sigma^2
float sigma2_;
friend class DelayDbl;
};
// Dwlay with doubles for accumulating delays.
class DelayDbl
{
public:
DelayDbl();
float mean() const { return mean_; }
float sigma() const;
// sigma^2
float sigma2() const;
void operator=(float delay);
void operator+=(const Delay &delay);
void operator-=(const Delay &delay);
private:
double mean_;
// Sigma^2
double sigma2_;
friend class Delay;
};
const Delay delay_zero(0.0);
void
initDelayConstants();
const char *
delayAsString(const Delay &delay,
const StaState *sta);
const char *
delayAsString(const Delay &delay,
const StaState *sta,
int digits);
const char *
delayAsString(const Delay &delay,
const EarlyLate *early_late,
const StaState *sta,
int digits);
Delay
makeDelay(float delay,
float sigma_early,
float sigma_late);
Delay
makeDelay2(float delay,
// sigma^2
float sigma_early,
float sigma_late);
inline float
delayAsFloat(const Delay &delay)
{
return delay.mean();
}
// mean late+/early- sigma
float
delayAsFloat(const Delay &delay,
const EarlyLate *early_late,
const StaState *sta);
float
delaySigma2(const Delay &delay,
const EarlyLate *early_late);
const Delay &
delayInitValue(const MinMax *min_max);
bool
delayIsInitValue(const Delay &delay,
const MinMax *min_max);
bool
delayZero(const Delay &delay);
bool
delayInf(const Delay &delay);
bool
delayEqual(const Delay &delay1,
const Delay &delay2);
bool
delayLess(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayLess(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
bool
delayLessEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayLessEqual(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
bool
delayGreater(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayGreaterEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayGreaterEqual(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
bool
delayGreater(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
// delay1-delay2 subtracting sigma instead of addiing.
Delay delayRemove(const Delay &delay1,
const Delay &delay2);
float
delayRatio(const Delay &delay1,
const Delay &delay2);
// Most non-operator functions on Delay are not defined as member
// functions so they can be defined on floats, where there is no class
// to define them.
Delay operator+(float delay1,
const Delay &delay2);
// Used for parallel gate delay calc.
Delay operator/(float delay1,
const Delay &delay2);
// Used for parallel gate delay calc.
Delay operator*(const Delay &delay1,
float delay2);
} // namespace
-214
View File
@@ -1,214 +0,0 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2026, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// This notice may not be removed or altered from any source distribution.
#pragma once
#include "MinMax.hh"
namespace sta {
class Delay;
class DelayDbl;
class StaState;
// Normal distribution with early(left)/late(right) std deviations.
class Delay
{
public:
Delay();
Delay(const Delay &delay);
Delay(const DelayDbl &delay);
Delay(float mean);
Delay(float mean,
float sigma2_early,
float sigma2_late);
float mean() const { return mean_; }
float sigma(const EarlyLate *early_late) const;
// sigma^2
float sigma2(const EarlyLate *early_late) const;
float sigma2Early() const;
float sigma2Late() const;
void operator=(const Delay &delay);
void operator=(float delay);
void operator+=(const Delay &delay);
void operator+=(float delay);
Delay operator+(const Delay &delay) const;
Delay operator+(float delay) const;
Delay operator-(const Delay &delay) const;
Delay operator-(float delay) const;
Delay operator-() const;
void operator-=(float delay);
void operator-=(const Delay &delay);
bool operator==(const Delay &delay) const;
protected:
static const int early_index = 0;
static const int late_index = 1;
private:
float mean_;
// Sigma^2
float sigma2_[EarlyLate::index_count];
friend class DelayDbl;
};
// Dwlay with doubles for accumulating delays.
class DelayDbl
{
public:
DelayDbl();
float mean() const { return mean_; }
float sigma() const;
// sigma^2
float sigma2() const;
void operator=(float delay);
void operator+=(const Delay &delay);
void operator-=(const Delay &delay);
protected:
static const int early_index = 0;
static const int late_index = 1;
private:
double mean_;
// Sigma^2
double sigma2_[EarlyLate::index_count];
friend class Delay;
};
const Delay delay_zero(0.0);
void
initDelayConstants();
const char *
delayAsString(const Delay &delay,
const StaState *sta);
const char *
delayAsString(const Delay &delay,
const StaState *sta,
int digits);
const char *
delayAsString(const Delay &delay,
const EarlyLate *early_late,
const StaState *sta,
int digits);
Delay
makeDelay(float delay,
float sigma_early,
float sigma_late);
Delay
makeDelay2(float delay,
// sigma^2
float sigma_early,
float sigma_late);
inline float
delayAsFloat(const Delay &delay)
{
return delay.mean();
}
// mean late+/early- sigma
float
delayAsFloat(const Delay &delay,
const EarlyLate *early_late,
const StaState *sta);
float
delaySigma2(const Delay &delay,
const EarlyLate *early_late);
const Delay &
delayInitValue(const MinMax *min_max);
bool
delayIsInitValue(const Delay &delay,
const MinMax *min_max);
bool
delayZero(const Delay &delay);
bool
delayInf(const Delay &delay);
bool
delayEqual(const Delay &delay1,
const Delay &delay2);
bool
delayLess(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayLess(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
bool
delayLessEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayLessEqual(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
bool
delayGreater(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayGreaterEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta);
bool
delayGreaterEqual(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
bool
delayGreater(const Delay &delay1,
const Delay &delay2,
const MinMax *min_max,
const StaState *sta);
// delay1-delay2 subtracting sigma instead of addiing.
Delay delayRemove(const Delay &delay1,
const Delay &delay2);
float
delayRatio(const Delay &delay1,
const Delay &delay2);
// Most non-operator functions on Delay are not defined as member
// functions so they can be defined on floats, where there is no class
// to define them.
Delay operator+(float delay1,
const Delay &delay2);
// Used for parallel gate delay calc.
Delay operator/(float delay1,
const Delay &delay2);
// Used for parallel gate delay calc.
Delay operator*(const Delay &delay1,
float delay2);
} // namespace
+90
View File
@@ -0,0 +1,90 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2025, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// This notice may not be removed or altered from any source distribution.
#pragma once
#include "Delay.hh"
namespace sta {
class DelayOpsScalar : public DelayOps
{
public:
float stdDev2(const Delay &delay,
const EarlyLate *early_late) const override;
float asFloat(const Delay &delay,
const EarlyLate *early_late,
const StaState *sta) const override;
double asFloat(const DelayDbl &delay,
const EarlyLate *early_late,
const StaState *sta) const override;
bool isZero(const Delay &delay) const override;
bool isInf(const Delay &delay) const override;
bool equal(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const override;
bool less(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const override;
bool less(const DelayDbl &delay1,
const DelayDbl &delay2,
const StaState *sta) const override;
bool lessEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const override;
bool greater(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const override;
bool greaterEqual(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const override;
Delay sum(const Delay &delay1,
const Delay &delay2) const override;
Delay sum(const Delay &delay1,
float delay2) const override;
Delay diff(const Delay &delay1,
const Delay &delay2) const override;
Delay diff(const Delay &delay1,
float delay2) const override;
Delay diff(float delay1,
const Delay &delay2) const override;
void incr(Delay &delay1,
const Delay &delay2) const override;
void incr(DelayDbl &delay1,
const Delay &delay2) const override;
void decr(Delay &delay1,
const Delay &delay2) const override;
void decr(DelayDbl &delay1,
const Delay &delay2) const override;
Delay product(const Delay &delay1,
float delay2) const override;
Delay div(float delay1,
const Delay &delay2) const override;
std::string asStringVariance(const Delay &delay,
int digits,
const StaState *sta) const override;
};
} // namespace
+98
View File
@@ -0,0 +1,98 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2025, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// This notice may not be removed or altered from any source distribution.
#pragma once
#include "Delay.hh"
namespace sta {
class DelayOpsSkewNormal : public DelayOps
{
public:
float stdDev2(const Delay &delay,
const EarlyLate *early_late) const override;
float asFloat(const Delay &delay,
const EarlyLate *early_late,
const StaState *sta) const override;
double asFloat(const DelayDbl &delay,
const EarlyLate *early_late,
const StaState *sta) const override;
bool isZero(const Delay &delay) const override;
bool isInf(const Delay &delay) const override;
bool equal(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const override;
bool less(const Delay &delay1,
const Delay &delay2,
const StaState *sta) const override;
bool less(const DelayDbl &delay1,
const DelayDbl &delay2,
const StaState *sta) const override;
bool lessEqual(const Delay &delay1,
const Delay &delay2,
const StaState *) const override;
bool greater(const Delay &delay1,
const Delay &delay2,
const StaState *) const override;
bool greaterEqual(const Delay &delay1,
const Delay &delay2,
const StaState *) const override;
Delay sum(const Delay &delay1,
const Delay &delay2) const override;
Delay sum(const Delay &delay1,
float delay2) const override;
Delay diff(const Delay &delay1,
const Delay &delay2) const override;
Delay diff(const Delay &delay1,
float delay2) const override;
Delay diff(float delay1,
const Delay &delay2) const override;
void incr(Delay &delay1,
const Delay &delay2) const override;
void incr(DelayDbl &delay1,
const Delay &delay2) const override;
void decr(Delay &delay1,
const Delay &delay2) const override;
void decr(DelayDbl &delay1,
const Delay &delay2) const override;
Delay product(const Delay &delay1,
float delay2) const override;
Delay div(float delay1,
const Delay &delay2) const override;
std::string asStringVariance(const Delay &delay,
int digits,
const StaState *sta) const override;
private:
float skewnessSum(const Delay &delay1,
const Delay &delay2) const;
double skewnessSum(double std_dev1,
double skewness1,
double std_dev2,
double skewness2) const;
};
} // namespace
+12 -9
View File
@@ -25,6 +25,7 @@
#pragma once
#include <exception>
#include <string>
#include "Report.hh"
@@ -42,7 +43,7 @@ public:
class ExceptionMsg : public Exception
{
public:
ExceptionMsg(const char *msg,
ExceptionMsg(const std::string &msg,
const bool suppressed);
virtual const char *what() const noexcept;
virtual bool suppressed() const { return suppressed_; }
@@ -55,11 +56,11 @@ private:
class ExceptionLine : public Exception
{
public:
ExceptionLine(const char *filename,
ExceptionLine(const std::string &filename,
int line);
protected:
const char *filename_;
std::string filename_;
int line_;
};
@@ -67,29 +68,31 @@ protected:
class FileNotReadable : public Exception
{
public:
FileNotReadable(const char *filename);
FileNotReadable(std::string filename);
virtual const char *what() const noexcept;
protected:
const char *filename_;
std::string filename_;
std::string msg_;
};
// Failure opening filename for writing.
class FileNotWritable : public Exception
{
public:
FileNotWritable(const char *filename);
FileNotWritable(std::string filename);
virtual const char *what() const noexcept;
protected:
const char *filename_;
std::string filename_;
std::string msg_;
};
// Report an error condition that should not be possible.
// The default handler prints msg to stderr and exits.
// The msg should NOT include a period or return.
// Only for use in those cases where a Report object is not available.
#define criticalError(id,msg) \
// Only for use in those cases where a Report object is not available.
#define criticalError(id, msg) \
Report::defaultReport()->fileCritical(id, __FILE__, __LINE__, msg)
} // namespace
+15 -14
View File
@@ -24,6 +24,7 @@
#pragma once
#include <string>
#include <vector>
#include "Error.hh"
@@ -67,7 +68,7 @@ public:
virtual bool isGroupPath() const { return false; }
virtual bool isFilter() const { return false; }
virtual ExceptionPathType type() const = 0;
virtual const char *asString(const Network *network) const;
virtual std::string to_string(const Network *network) const;
ExceptionFrom *from() const { return from_; }
ExceptionThruSeq *thrus() const { return thrus_; }
ExceptionTo *to() const { return to_; }
@@ -127,14 +128,14 @@ public:
virtual bool useEndClk() const { return false; }
virtual int pathMultiplier() const { return 0; }
virtual float delay() const { return 0.0; }
virtual const char *name() const { return nullptr; }
virtual std::string name() const { return ""; }
virtual bool isDefault() const { return false; }
virtual bool ignoreClkLatency() const { return false; }
virtual bool breakPath() const { return false; }
protected:
virtual const char *typeString() const = 0;
const char *fromThruToString(const Network *network) const;
std::string fromThruToString(const Network *network) const;
void makeStates();
ExceptionFrom *from_;
@@ -209,7 +210,7 @@ public:
bool own_pts) override;
bool isPathDelay() const override { return true; }
ExceptionPathType type() const override { return ExceptionPathType::path_delay; }
const char *asString(const Network *network) const override;
std::string to_string(const Network *network) const override;
const char *typeString() const override;
bool mergeable(ExceptionPath *exception) const override;
bool overrides(ExceptionPath *exception) const override;
@@ -245,7 +246,7 @@ public:
ExceptionPathType type() const override { return ExceptionPathType::multi_cycle; }
bool matches(const MinMax *min_max,
bool exactly) const override;
const char *asString(const Network *network) const override;
std::string to_string(const Network *network) const override;
const char *typeString() const override;
bool mergeable(ExceptionPath *exception) const override;
bool overrides(ExceptionPath *exception) const override;
@@ -292,7 +293,7 @@ public:
class GroupPath : public ExceptionPath
{
public:
GroupPath(const char *name,
GroupPath(const std::string &name,
bool is_default,
ExceptionFrom *from,
ExceptionThruSeq *thrus,
@@ -311,11 +312,11 @@ public:
bool overrides(ExceptionPath *exception) const override;
int typePriority() const override;
bool tighterThan(ExceptionPath *exception) const override;
const char *name() const override { return name_; }
std::string name() const override { return name_; }
bool isDefault() const override { return is_default_; }
protected:
const char *name_;
std::string name_;
bool is_default_;
};
@@ -343,7 +344,7 @@ public:
// All pins and instance/net pins.
virtual PinSet allPins(const Network *network) = 0;
virtual int typePriority() const = 0;
virtual const char *asString(const Network *network) const = 0;
virtual std::string to_string(const Network *network) const = 0;
virtual size_t objectCount() const = 0;
virtual void addPin(const Pin *pin,
const Network *network) = 0;
@@ -367,8 +368,8 @@ protected:
// exception merging.
size_t hash_;
// Maximum number of objects for asString() to show.
static const int as_string_max_objects_;
// Maximum number of objects for to_string() to show.
static const int to_string_max_objects_;
static const size_t hash_clk = 3;
static const size_t hash_pin = 5;
static const size_t hash_net = 7;
@@ -402,7 +403,7 @@ public:
const Network *network) const override;
void mergeInto(ExceptionPt *pt,
const Network *network) override;
const char *asString(const Network *network) const override;
std::string to_string(const Network *network) const override;
size_t objectCount() const override;
void deleteClock(Clock *clk);
void addPin(const Pin *pin,
@@ -467,7 +468,7 @@ public:
const Network *network);
ExceptionTo *clone(const Network *network);
bool isTo() const override { return true; }
const char *asString(const Network *network) const override;
std::string to_string(const Network *network) const override;
const RiseFallBoth *endTransition() { return end_rf_; }
bool intersectsPts(ExceptionTo *to,
const Network *network) const;
@@ -512,7 +513,7 @@ public:
const Network *network);
~ExceptionThru();
ExceptionThru *clone(const Network *network);
const char *asString(const Network *network) const override;
std::string to_string(const Network *network) const override;
bool isThru() const override { return true; }
PinSet *pins() override { return pins_; }
EdgePinsSet *edges() override { return edges_; }
+153
View File
@@ -0,0 +1,153 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2026, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// This notice may not be removed or altered from any source distribution.
#pragma once
#include <cstdio>
#include <fstream>
#include <string>
#include <string_view>
#include "StaConfig.hh"
#ifdef ZLIB_FOUND
#include <zlib.h>
#endif
// std::format is not supported in GCC 11 (e.g. Ubuntu 22.04).
// Use fmt library as fallback when __cpp_lib_format is not defined.
#if defined(__cpp_lib_format) && __cpp_lib_format >= 201907L
#include <format>
namespace sta {
template <typename... Args>
std::string format(std::format_string<Args...> fmt,
Args &&...args) {
return std::format(fmt, std::forward<Args>(args)...);
}
template <typename... Args>
void print(std::ofstream &stream,
std::format_string<Args...> fmt,
Args &&...args) {
stream << std::format(fmt, std::forward<Args>(args)...);
}
#ifdef ZLIB_FOUND
template <typename... Args>
void print(gzFile stream,
std::format_string<Args...> fmt,
Args &&...args) {
std::string s = sta::format(fmt, std::forward<Args>(args)...);
gzwrite(stream, s.c_str(), s.size());
}
#endif
template <typename... Args>
void print(FILE *stream,
std::format_string<Args...> fmt,
Args &&...args) {
std::string s = sta::format(fmt, std::forward<Args>(args)...);
std::fprintf(stream, "%s", s.c_str());
}
inline std::string vformat(std::string_view fmt,
std::format_args args) {
return std::vformat(fmt, args);
}
template <typename... Args>
auto make_format_args(Args &&...args) {
return std::make_format_args(std::forward<Args>(args)...);
}
// Format with runtime format string - captures args to avoid make_format_args
// rvalue reference issues.
template <typename... Args>
std::string formatRuntime(std::string_view fmt,
Args &&...args) {
auto args_tuple = std::make_tuple(std::forward<Args>(args)...);
return std::apply(
[fmt](auto &...a) {
return std::vformat(fmt, std::make_format_args(a...));
},
args_tuple);
}
} // namespace sta
#else
#include <fmt/core.h>
namespace sta {
template <typename... Args>
std::string format(fmt::format_string<Args...> fmt,
Args &&...args) {
return fmt::format(fmt, std::forward<Args>(args)...);
}
template <typename... Args>
void print(std::ofstream &stream,
fmt::format_string<Args...> fmt,
Args &&...args) {
stream << fmt::format(fmt, std::forward<Args>(args)...);
}
#ifdef ZLIB_FOUND
template <typename... Args>
void print(gzFile stream,
fmt::format_string<Args...> fmt,
Args &&...args) {
std::string s = sta::format(fmt, std::forward<Args>(args)...);
gzwrite(stream, s.c_str(), s.size());
}
#endif
template <typename... Args>
void print(FILE *stream,
fmt::format_string<Args...> fmt,
Args &&...args) {
std::string s = sta::format(fmt, std::forward<Args>(args)...);
std::fprintf(stream, "%s", s.c_str());
}
inline
std::string vformat(std::string_view fmt,
fmt::format_args args) {
return fmt::vformat(fmt, args);
}
template <typename... Args>
auto make_format_args(Args &&...args) {
return fmt::make_format_args(std::forward<Args>(args)...);
}
template <typename... Args>
std::string formatRuntime(std::string_view fmt,
Args &&...args) {
return fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...);
}
} // namespace sta
#endif
+19 -21
View File
@@ -58,13 +58,7 @@ static constexpr ObjectIdx vertex_idx_null = object_idx_null;
class Graph : public StaState
{
public:
// slew_rf_count is
// 0 no slews
// 1 one slew for rise/fall
// 2 rise/fall slews
// ap_count is the dcalc analysis point count.
Graph(StaState *sta,
int slew_rf_count,
DcalcAPIndex ap_count);
void makeGraph();
~Graph();
@@ -97,9 +91,11 @@ public:
// 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.
const Slew &slew(const Vertex *vertex,
const RiseFall *rf,
DcalcAPIndex ap_index);
Slew slew(const Vertex *vertex,
const RiseFall *rf,
DcalcAPIndex ap_index);
Slew slew(const Vertex *vertex,
size_t index);
void setSlew(Vertex *vertex,
const RiseFall *rf,
DcalcAPIndex ap_index,
@@ -134,11 +130,11 @@ public:
void setArcDelay(Edge *edge,
const TimingArc *arc,
DcalcAPIndex ap_index,
ArcDelay delay);
const ArcDelay &delay);
// Alias for arcDelays using library wire arcs.
const ArcDelay &wireArcDelay(const Edge *edge,
const RiseFall *rf,
DcalcAPIndex ap_index);
ArcDelay wireArcDelay(const Edge *edge,
const RiseFall *rf,
DcalcAPIndex ap_index);
void setWireArcDelay(Edge *edge,
const RiseFall *rf,
DcalcAPIndex ap_index,
@@ -222,7 +218,6 @@ protected:
// driver/source (top level input, instance pin output) vertex
// in pin_bidirect_drvr_vertex_map
PinVertexMap pin_bidirect_drvr_vertex_map_;
int slew_rf_count_;
DcalcAPIndex ap_count_;
// Sdf period check annotations.
PeriodCheckAnnotations *period_check_annotations_;
@@ -258,8 +253,6 @@ public:
[[nodiscard]] bool isRoot() const{ return level_ == 0; }
[[nodiscard]] bool hasFanin() const;
[[nodiscard]] bool hasFanout() const;
Slew *slews() { return slews_; }
const Slew *slews() const { return slews_; }
Path *paths() const { return paths_; }
Path *makePaths(uint32_t count);
void setPaths(Path *paths);
@@ -298,14 +291,18 @@ protected:
bool is_bidirect_drvr,
bool is_reg_clk);
void clear();
void setSlews(Slew *slews);
Slew *slews() { return std::bit_cast<Slew*>(slews_); }
const Slew *slews() const { return std::bit_cast<const Slew*>(slews_); }
float *slewsFloat() { return slews_; }
const float *slewsFloat() const { return slews_; }
void setSlews(float *slews);
Pin *pin_;
EdgeId in_edges_; // Edges to this vertex.
EdgeId out_edges_; // Edges from this vertex.
// Delay calc
Slew *slews_;
float *slews_;
// Search
Path *paths_;
@@ -356,8 +353,9 @@ public:
TimingSense sense() const;
TimingArcSet *timingArcSet() const { return arc_set_; }
void setTimingArcSet(TimingArcSet *set);
ArcDelay *arcDelays() const { return arc_delays_; }
void setArcDelays(ArcDelay *arc_delays);
float *arcDelays() { return arc_delays_; }
const float *arcDelays() const { return arc_delays_; }
void setArcDelays(float *delays);
bool delay_Annotation_Is_Incremental() const {return delay_annotation_is_incremental_;};
void setDelayAnnotationIsIncremental(bool is_incr);
// Edge is disabled to break combinational loops.
@@ -398,7 +396,7 @@ protected:
EdgeId vertex_in_link_; // Vertex in edges list.
EdgeId vertex_out_next_; // Vertex out edges doubly linked list.
EdgeId vertex_out_prev_;
ArcDelay *arc_delays_;
float *arc_delays_;
union {
uintptr_t bits_;
std::vector<bool> *seq_;
+2 -2
View File
@@ -245,8 +245,8 @@ protected:
bool annotateDelaySlew(Edge *edge,
const TimingArc *arc,
ArcDelay &gate_delay,
Slew &gate_slew,
const ArcDelay &gate_delay,
const Slew &gate_slew,
const Scene *scene,
const MinMax *min_max);
bool annotateLoadDelays(Vertex *drvr_vertex,
+33 -37
View File
@@ -33,44 +33,11 @@
namespace sta {
class InternalPowerModel;
using InternalPowerModels =
std::array<std::shared_ptr<InternalPowerModel>, RiseFall::index_count>;
class InternalPower
{
public:
InternalPower(LibertyPort *port,
LibertyPort *related_port,
LibertyPort *related_pg_pin,
const std::shared_ptr<FuncExpr> &when,
InternalPowerModels &models);
//InternalPower(InternalPower &&other) noexcept;
LibertyCell *libertyCell() const;
LibertyPort *port() const { return port_; }
LibertyPort *relatedPort() const { return related_port_; }
FuncExpr *when() const { return when_.get(); }
LibertyPort *relatedPgPin() const { return related_pg_pin_; }
float power(const RiseFall *rf,
const Pvt *pvt,
float in_slew,
float load_cap) const;
const InternalPowerModel *model(const RiseFall *rf) const;
protected:
LibertyPort *port_;
LibertyPort *related_port_;
LibertyPort *related_pg_pin_;
std::shared_ptr<FuncExpr> when_;
InternalPowerModels models_;
};
class InternalPowerModel
{
public:
InternalPowerModel(TableModel *model);
~InternalPowerModel();
InternalPowerModel();
InternalPowerModel(std::shared_ptr<TableModel> model);
float power(const LibertyCell *cell,
const Pvt *pvt,
float in_slew,
@@ -80,7 +47,7 @@ public:
float in_slew,
float load_cap,
int digits) const;
const TableModel *model() const { return model_; }
const TableModel *model() const { return model_.get(); }
protected:
void findAxisValues(float in_slew,
@@ -95,7 +62,36 @@ protected:
bool checkAxes(const TableModel *model);
bool checkAxis(const TableAxis *axis);
TableModel *model_;
std::shared_ptr<TableModel> model_;
};
using InternalPowerModels = std::array<InternalPowerModel, RiseFall::index_count>;
class InternalPower
{
public:
InternalPower(LibertyPort *port,
LibertyPort *related_port,
LibertyPort *related_pg_pin,
const std::shared_ptr<FuncExpr> &when,
const InternalPowerModels &models);
LibertyCell *libertyCell() const;
LibertyPort *port() const { return port_; }
LibertyPort *relatedPort() const { return related_port_; }
FuncExpr *when() const { return when_.get(); }
LibertyPort *relatedPgPin() const { return related_pg_pin_; }
float power(const RiseFall *rf,
const Pvt *pvt,
float in_slew,
float load_cap) const;
const InternalPowerModel &model(const RiseFall *rf) const;
protected:
LibertyPort *port_;
LibertyPort *related_port_;
LibertyPort *related_pg_pin_;
std::shared_ptr<FuncExpr> when_;
InternalPowerModels models_;
};
} // namespace
+1 -1
View File
@@ -589,7 +589,7 @@ public:
LibertyPort *related_port,
LibertyPort *related_pg_pin,
const std::shared_ptr<FuncExpr> &when,
InternalPowerModels &models);
const InternalPowerModels &models);
void makeLeakagePower(LibertyPort *related_pg_port,
FuncExpr *when,
float power);
+16 -6
View File
@@ -37,14 +37,22 @@ public:
void gateDelay(const Pvt *pvt,
float in_slew,
float load_cap,
bool pocv_enabled,
// Return values.
ArcDelay &gate_delay,
Slew &drvr_slew) const override;
float &gate_delay,
float &drvr_slew) const override;
void gateDelayPocv(const Pvt *pvt,
float in_slew,
float load_cap,
const MinMax *min_max,
PocvMode pocv_mode,
// Return values.
ArcDelay &gate_delay,
Slew &drvr_slew) const override;
std::string reportGateDelay(const Pvt *pvt,
float in_slew,
float load_cap,
bool pocv_enabled,
const MinMax *min_max,
PocvMode pocv_mode,
int digits) const override;
float driveResistance(const Pvt *pvt) const override;
@@ -64,13 +72,15 @@ public:
float from_slew,
float to_slew,
float related_out_cap,
bool pocv_enabled) const override;
const MinMax *min_max,
PocvMode pocv_mode) const override;
std::string reportCheckDelay(const Pvt *pvt,
float from_slew,
const char *from_slew_annotation,
float to_slew,
float related_out_cap,
bool pocv_enabled,
const MinMax *min_max,
PocvMode pocv_mode,
int digits) const override;
protected:
+11 -10
View File
@@ -25,12 +25,13 @@
#pragma once
#include <string>
#include <string_view>
namespace sta {
// Return true if name is a bus.
bool
isBusName(const char *name,
isBusName(std::string_view name,
const char brkt_left,
const char brkt_right,
char escape);
@@ -43,7 +44,7 @@ isBusName(const char *name,
// index = bit
// Caller must delete returned bus_name string.
void
parseBusName(const char *name,
parseBusName(std::string_view name,
const char brkt_left,
const char brkt_right,
char escape,
@@ -53,9 +54,9 @@ parseBusName(const char *name,
int &index);
// Allow multiple different left/right bus brackets.
void
parseBusName(const char *name,
const char *brkts_left,
const char *brkts_right,
parseBusName(std::string_view name,
std::string_view brkts_left,
std::string_view brkts_right,
char escape,
// Return values.
bool &is_bus,
@@ -66,7 +67,7 @@ parseBusName(const char *name,
// bus_name is set to null if name is not a range.
// Caller must delete returned bus_name string.
void
parseBusName(const char *name,
parseBusName(std::string_view name,
const char brkt_left,
const char brkt_right,
char escape,
@@ -81,9 +82,9 @@ parseBusName(const char *name,
// brkt_lefts and brkt_rights are corresponding strings of legal
// bus brackets such as "[(<" and "])>".
void
parseBusName(const char *name,
const char *brkts_left,
const char *brkts_right,
parseBusName(std::string_view name,
std::string_view brkts_left,
std::string_view brkts_right,
const char escape,
// Return values.
bool &is_bus,
@@ -95,7 +96,7 @@ parseBusName(const char *name,
// Insert escapes before ch1 and ch2 in token.
std::string
escapeChars(const char *token,
escapeChars(std::string_view token,
const char ch1,
const char ch2,
const char escape);
+6 -8
View File
@@ -45,14 +45,14 @@ public:
const StaState *sta);
Path(Vertex *vertex,
Tag *tag,
Arrival arrival,
const Arrival &arrival,
Path *prev_path,
Edge *prev_edge,
TimingArc *prev_arc,
const StaState *sta);
Path(Vertex *vertex,
Tag *tag,
Arrival arrival,
const Arrival &arrival,
Path *prev_path,
Edge *prev_edge,
TimingArc *prev_arc,
@@ -62,11 +62,11 @@ public:
bool isNull() const;
// prev_path null
void init(Vertex *vertex,
Arrival arrival,
const Arrival &arrival,
const StaState *sta);
void init(Vertex *vertex,
Tag *tag,
Arrival arrival,
const Arrival &arrival,
Path *prev_path,
Edge *prev_edge,
TimingArc *prev_arc,
@@ -76,7 +76,7 @@ public:
const StaState *sta);
void init(Vertex *vertex,
Tag *tag,
Arrival arrival,
const Arrival &arrival,
const StaState *sta);
Vertex *vertex(const StaState *sta) const;
@@ -98,14 +98,12 @@ public:
const MinMax *minMax(const StaState *sta) const;
PathAPIndex pathAnalysisPtIndex(const StaState *sta) const;
DcalcAPIndex dcalcAnalysisPtIndex(const StaState *sta) const;
Arrival &arrival() { return arrival_; }
const Arrival &arrival() const { return arrival_; }
void setArrival(Arrival arrival);
Required &required() { return required_; }
const Required &required() const {return required_; }
void setRequired(const Required &required);
Slack slack(const StaState *sta) const;
Slew slew(const StaState *sta) const;
const Slew slew(const StaState *sta) const;
// This takes the same time as prevPath and prevArc combined.
Path *prevPath() const;
void setPrevPath(Path *prev_path);
+1 -61
View File
@@ -98,7 +98,7 @@ public:
virtual const char *typeName() const = 0;
virtual int exceptPathCmp(const PathEnd *path_end,
const StaState *sta) const;
virtual Arrival dataArrivalTime(const StaState *sta) const;
virtual const Arrival &dataArrivalTime(const StaState *sta) const;
// Arrival time with source clock offset.
Arrival dataArrivalTimeOffset(const StaState *sta) const;
virtual Required requiredTime(const StaState *sta) const = 0;
@@ -270,11 +270,6 @@ public:
protected:
PathEndClkConstrained(Path *path,
Path *clk_path);
PathEndClkConstrained(Path *path,
Path *clk_path,
Crpr crpr,
bool crpr_valid);
float sourceClkOffset(const ClockEdge *src_clk_edge,
const ClockEdge *tgt_clk_edge,
const TimingRole *check_role,
@@ -300,11 +295,6 @@ protected:
PathEndClkConstrainedMcp(Path *path,
Path *clk_path,
MultiCyclePath *mcp);
PathEndClkConstrainedMcp(Path *path,
Path *clk_path,
MultiCyclePath *mcp,
Crpr crpr,
bool crpr_valid);
float checkMcpAdjustment(const Path *path,
const ClockEdge *tgt_clk_edge,
const StaState *sta) const;
@@ -341,13 +331,6 @@ public:
virtual Delay clkSkew(const StaState *sta);
protected:
PathEndCheck(Path *path,
TimingArc *check_arc,
Edge *check_edge,
Path *clk_path,
MultiCyclePath *mcp,
Crpr crpr,
bool crpr_valid);
Delay sourceClkDelay(const StaState *sta) const;
virtual Required requiredTimeNoCrpr(const StaState *sta) const;
@@ -404,18 +387,6 @@ public:
virtual bool ignoreClkLatency(const StaState *sta) const;
protected:
PathEndLatchCheck(Path *path,
TimingArc *check_arc,
Edge *check_edge,
Path *clk_path,
Path *disable,
MultiCyclePath *mcp,
PathDelay *path_delay,
Delay src_clk_arrival,
Crpr crpr,
bool crpr_valid);
private:
Path *disable_path_;
PathDelay *path_delay_;
// Source clk arrival for set_max_delay -ignore_clk_latency.
@@ -450,12 +421,6 @@ public:
const StaState *sta) const;
protected:
PathEndOutputDelay(OutputDelay *output_delay,
Path *path,
Path *clk_path,
MultiCyclePath *mcp,
Crpr crpr,
bool crpr_valid);
Arrival tgtClkDelay(const ClockEdge *tgt_clk_edge,
const TimingRole *check_role,
const StaState *sta) const;
@@ -491,14 +456,6 @@ public:
const StaState *sta) const;
protected:
PathEndGatedClock(Path *gating_ref,
Path *clk_path,
const TimingRole *check_role,
MultiCyclePath *mcp,
ArcDelay margin,
Crpr crpr,
bool crpr_valid);
const TimingRole *check_role_;
ArcDelay margin_;
};
@@ -525,20 +482,12 @@ public:
virtual const Path *dataClkPath() const { return data_clk_path_; }
protected:
PathEndDataCheck(DataCheck *check,
Path *data_path,
Path *data_clk_path,
Path *clk_path,
MultiCyclePath *mcp,
Crpr crpr,
bool crpr_valid);
Path *clkPath(Path *path,
const StaState *sta);
Arrival requiredTimeNoCrpr(const StaState *sta) const;
// setup uses zero cycle default
virtual int setupDefaultCycles() const { return 0; }
private:
Path *data_clk_path_;
DataCheck *check_;
};
@@ -588,15 +537,6 @@ public:
virtual bool ignoreClkLatency(const StaState *sta) const;
protected:
PathEndPathDelay(PathDelay *path_delay,
Path *path,
Path *clk_path,
TimingArc *check_arc,
Edge *check_edge,
OutputDelay *output_delay,
Arrival src_clk_arrival,
Crpr crpr,
bool crpr_valid);
void findSrcClkArrival(const StaState *sta);
PathDelay *path_delay_;
+10 -6
View File
@@ -29,7 +29,6 @@
#include <map>
#include <mutex>
#include "BoundedHeap.hh"
#include "SdcClass.hh"
#include "StaState.hh"
#include "SearchClass.hh"
@@ -43,7 +42,7 @@ class PathEndVisitor;
using PathGroupIterator = PathEndSeq::iterator;
using PathGroupClkMap = std::map<const Clock*, PathGroup*>;
using PathGroupNamedMap = std::map<const char*, PathGroup*, CharPtrLess>;
using PathGroupNamedMap = std::map<std::string, PathGroup*>;
using PathGroupSeq = std::vector<PathGroup*>;
// A collection of PathEnds grouped and sorted for reporting.
@@ -70,7 +69,7 @@ public:
~PathGroup();
const std::string &name() const { return name_; }
const MinMax *minMax() const { return min_max_;}
PathEndSeq pathEnds() const;
PathEndSeq pathEnds() const { return path_ends_; }
void insert(PathEnd *path_end);
// Push group_path_count into path_ends.
void pushEnds(PathEndSeq &path_ends);
@@ -93,6 +92,9 @@ protected:
bool cmp_slack,
const MinMax *min_max,
const StaState *sta);
void ensureSortedMaxPaths();
void prune();
void sort();
std::string name_;
int group_path_count_;
@@ -101,9 +103,11 @@ protected:
bool unique_edges_;
float slack_min_;
float slack_max_;
PathEndSeq path_ends_;
const MinMax *min_max_;
bool cmp_slack_;
BoundedHeap<PathEnd*, PathEndLess> heap_;
float threshold_;
std::mutex lock_;
const StaState *sta_;
};
@@ -136,7 +140,7 @@ public:
bool unconstrained_paths,
// Return value.
PathEndSeq &path_ends);
PathGroup *findPathGroup(const char *name,
PathGroup *findPathGroup(const std::string &name,
const MinMax *min_max) const;
PathGroup *findPathGroup(const Clock *clock,
const MinMax *min_max) const;
@@ -187,7 +191,7 @@ protected:
bool gated_clk,
bool unconstrained,
const MinMax *min_max);
bool reportGroup(const char *group_name,
bool reportGroup(const std::string &group_name,
StringSet &group_names) const;
static GroupPath *groupPathTo(const PathEnd *path_end,
const StaState *sta);
+36
View File
@@ -0,0 +1,36 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2025, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// This notice may not be removed or altered from any source distribution.
#pragma once
namespace sta {
enum class PocvMode { scalar, normal, skew_normal };
const char *
pocvModeName(PocvMode mode);
PocvMode
findPocvMode(const char *mode_name);
} // namespace
+131 -62
View File
@@ -1,25 +1,25 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2026, Parallax Software, Inc.
//
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
//
//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
//
// This notice may not be removed or altered from any source distribution.
#pragma once
@@ -27,15 +27,23 @@
#include <stdio.h>
#include <cstdarg>
#include <string>
#include <string_view>
#include <mutex>
#include <set>
#include "Machine.hh" // __attribute__
#include "Machine.hh" // __attribute__
#include "Format.hh"
struct Tcl_Interp;
namespace sta {
// Throws ExceptionMsg - implemented in Report.cc to avoid circular include with
// Error.hh
void
reportThrowExceptionMsg(const std::string &msg,
bool suppressed);
// Output streams used for printing.
// This is a wrapper for all printing. It supports logging output to
// a file and redirection of command output to a file.
@@ -45,74 +53,137 @@ public:
Report();
virtual ~Report();
// Print line with return.
virtual void reportLine(const char *fmt, ...)
__attribute__((format (printf, 2, 3)));
virtual void reportLineString(const char *line);
virtual void reportLineString(const std::string &line);
virtual void reportLine(const std::string &line);
virtual void reportBlankLine();
// Print formatted line using std::format (C++20).
template <typename... Args>
void report(std::string_view fmt,
Args &&...args)
{
reportMsg(sta::vformat(fmt, sta::make_format_args(args...)));
}
virtual void reportMsg(const std::string &formatted_msg)
{
reportLine(formatted_msg);
}
////////////////////////////////////////////////////////////////
// Report warning.
virtual void warn(int id,
const char *fmt, ...)
__attribute__((format (printf, 3, 4)));
virtual void vwarn(int id,
const char *fmt,
va_list args);
template <typename... Args>
void warn(int id,
std::string_view fmt,
Args &&...args)
{
if (!isSuppressed(id))
warnMsg(id, sta::vformat(fmt, sta::make_format_args(args...)));
}
virtual void warnMsg(int id,
const std::string &formatted_msg) {
reportLine(sta::format("Warning {}: {}", id, formatted_msg));
}
// Report warning in a file.
virtual void fileWarn(int id,
const char *filename,
int line,
const char *fmt, ...)
__attribute__((format (printf, 5, 6)));
virtual void vfileWarn(int id,
const char *filename,
int line,
const char *fmt,
va_list args);
template <typename... Args>
void fileWarn(int id,
std::string_view filename,
int line,
std::string_view fmt,
Args &&...args)
{
if (!isSuppressed(id)) {
fileWarnMsg(id, filename, line,
sta::vformat(fmt, sta::make_format_args(args...)));
}
}
virtual void
fileWarnMsg(int id,
std::string_view filename,
int line,
const std::string &formatted_msg) {
reportLine(sta::format("Warning {}: {} line {}, {}",
id, filename, line, formatted_msg));
}
virtual void error(int id,
const char *fmt, ...)
__attribute__((format (printf, 3, 4)));
virtual void verror(int id,
const char *fmt,
va_list args);
template <typename... Args>
void error(int id,
std::string_view fmt,
Args &&...args)
{
errorMsg(id, sta::vformat(fmt, sta::make_format_args(args...)));
}
virtual void errorMsg(int id,
const std::string &formatted_msg)
{
reportThrowExceptionMsg(sta::format("{} {}", id, formatted_msg), isSuppressed(id));
}
// Report error in a file.
virtual void fileError(int id,
const char *filename,
int line,
const char *fmt, ...)
__attribute__((format (printf, 5, 6)));
virtual void vfileError(int id,
const char *filename,
int line,
const char *fmt,
va_list args);
template <typename... Args>
void fileError(int id,
std::string_view filename,
int line,
std::string_view fmt,
Args &&...args)
{
fileErrorMsg(id, filename, line,
sta::vformat(fmt, sta::make_format_args(args...)));
}
virtual void fileErrorMsg(int id,
std::string_view filename,
int line,
const std::string &formatted_msg)
{
reportThrowExceptionMsg(sta::format("{} {} line {}, {}",
id, filename, line, formatted_msg),
isSuppressed(id));
}
// Critical.
// Critical.
// Report error condition that should not be possible or that prevents execution.
// The default handler prints msg to stderr and exits.
virtual void critical(int id,
const char *fmt,
...)
__attribute__((format (printf, 3, 4)));
virtual void fileCritical(int id,
const char *filename,
int line,
const char *fmt,
...)
__attribute__((format (printf, 5, 6)));
template <typename... Args>
void critical(int id,
std::string_view fmt,
Args &&...args)
{
criticalMsg(id, sta::vformat(fmt, sta::make_format_args(args...)));
}
virtual void criticalMsg(int id,
const std::string &formatted_msg)
{
reportLine(sta::format("Critical {}: {}", id, formatted_msg));
exit(1);
}
template <typename... Args>
void fileCritical(int id,
std::string_view filename,
int line,
std::string_view fmt,
Args &&...args)
{
fileCriticalMsg(id, filename, line,
sta::vformat(fmt, sta::make_format_args(args...)));
}
virtual void fileCriticalMsg(int id,
std::string_view filename,
int line,
const std::string &formatted_msg)
{
reportLine(sta::format("Critical {}: {} line {}, {}", id, filename, line,
formatted_msg));
exit(1);
}
// Log output to filename until logEnd is called.
virtual void logBegin(const char *filename);
virtual void logBegin(std::string filename);
virtual void logEnd();
// Redirect output to filename until redirectFileEnd is called.
virtual void redirectFileBegin(const char *filename);
virtual void redirectFileBegin(std::string filename);
// Redirect append output to filename until redirectFileEnd is called.
virtual void redirectFileAppendBegin(const char *filename);
virtual void redirectFileAppendBegin(std::string filename);
virtual void redirectFileEnd();
// Redirect output to a string until redirectStringEnd is called.
virtual void redirectStringBegin();
@@ -139,9 +210,7 @@ protected:
// Return the number of characters written.
virtual size_t printConsole(const char *buffer,
size_t length);
void printToBuffer(const char *fmt,
...)
__attribute__((format (printf, 2, 3)));
void printToBuffer(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
void printToBuffer(const char *fmt,
va_list args);
@@ -169,4 +238,4 @@ protected:
friend class Debug;
};
} // namespace
} // namespace sta
+10 -10
View File
@@ -44,20 +44,20 @@ class ReportTcl : public Report
public:
ReportTcl();
virtual ~ReportTcl();
virtual void logBegin(const char *filename);
virtual void logEnd();
virtual void redirectFileBegin(const char *filename);
virtual void redirectFileAppendBegin(const char *filename);
virtual void redirectFileEnd();
virtual void redirectStringBegin();
virtual const char *redirectStringEnd();
void logBegin(std::string filename) override;
void logEnd() override;
void redirectFileBegin(std::string filename) override;
void redirectFileAppendBegin(std::string filename) override;
void redirectFileEnd() override;
void redirectStringBegin() override;
const char *redirectStringEnd() override;
// This must be called after the Tcl interpreter has been constructed.
// It makes the encapsulated channels.
virtual void setTclInterp(Tcl_Interp *interp);
void setTclInterp(Tcl_Interp *interp) override;
protected:
virtual size_t printConsole(const char *buffer,
size_t length);
size_t printConsole(const char *buffer,
size_t length) override;
void flush();
private:
+12 -10
View File
@@ -179,11 +179,11 @@ using InstDeratingFactorsMap = std::map<const Instance*, DeratingFactorsCell*>;
using CellDeratingFactorsMap = std::map<const LibertyCell*, DeratingFactorsCell*>;
using ClockGroupsSet = std::set<ClockGroups*>;
using ClockGroupsClkMap = std::map<const Clock*, ClockGroupsSet*>;
using ClockGroupsNameMap = std::map<const char*, ClockGroups*, CharPtrLess>;
using ClockGroupsNameMap = std::map<std::string, ClockGroups*>;
using ClockSenseMap = std::map<PinClockPair, ClockSense, PinClockPairLess>;
using ClkHpinDisables = std::set<ClkHpinDisable*, ClkHpinDisableLess>;
using GroupPathSet = std::set<GroupPath*, ExceptionPathLess>;
using GroupPathMap = std::map<const char*, GroupPathSet*, CharPtrLess>;
using GroupPathMap = std::map<std::string, GroupPathSet*>;
using ClockPairSet = std::set<ClockPair, ClockPairLess>;
using NetVoltageMap = std::map<const Net*, MinMaxFloatValues>;
@@ -499,7 +499,7 @@ public:
Clock *to_clk,
const RiseFallBoth *to_rf,
const SetupHoldAll *setup_hold);
ClockGroups *makeClockGroups(const char *name,
ClockGroups *makeClockGroups(const std::string &name,
bool logically_exclusive,
bool physically_exclusive,
bool asynchronous,
@@ -507,11 +507,13 @@ public:
const char *comment);
void makeClockGroup(ClockGroups *clk_groups,
ClockSet *clks);
void removeClockGroups(const char *name);
// nullptr name removes all.
void removeClockGroupsLogicallyExclusive(const char *name);
void removeClockGroupsPhysicallyExclusive(const char *name);
void removeClockGroupsAsynchronous(const char *name);
void removeClockGroups(const std::string &name);
void removeClockGroupsLogicallyExclusive();
void removeClockGroupsLogicallyExclusive(const std::string &name);
void removeClockGroupsPhysicallyExclusive();
void removeClockGroupsPhysicallyExclusive(const std::string &name);
void removeClockGroupsAsynchronous();
void removeClockGroupsAsynchronous(const std::string &name);
bool sameClockGroup(const Clock *clk1,
const Clock *clk2) const;
// Clocks explicitly excluded by set_clock_group.
@@ -756,7 +758,7 @@ public:
ExceptionThruSeq *thrus,
ExceptionTo *to,
const MinMaxAll *min_max);
void makeGroupPath(const char *name,
void makeGroupPath(const std::string &name,
bool is_default,
ExceptionFrom *from,
ExceptionThruSeq *thrus,
@@ -1266,7 +1268,7 @@ protected:
void makeClkGroupExclusions(ClockGroupSet *groups);
void makeClkGroupSame(ClockGroup *group);
void clearClkGroupExclusions();
char *makeClockGroupsName();
std::string makeClockGroupsName();
void setClockSense(const Pin *pin,
const Clock *clk,
ClockSense sense);
+1 -1
View File
@@ -274,7 +274,7 @@ protected:
const PatternMatch *pattern,
InstanceSeq &matches) const;
const char *staToSdc(const char *sta_name) const;
const char *staToSdc(std::string_view sta_name) const;
};
// Encapsulate a network to map names to/from the sdc namespace.
+25 -15
View File
@@ -434,19 +434,21 @@ public:
const RiseFallBoth *to_rf,
const SetupHoldAll *setup_hold,
Sdc *sdc);
ClockGroups *makeClockGroups(const char *name,
ClockGroups *makeClockGroups(const std::string &name,
bool logically_exclusive,
bool physically_exclusive,
bool asynchronous,
bool allow_paths,
const char *comment,
Sdc *sdc);
// nullptr name removes all.
void removeClockGroupsLogicallyExclusive(const char *name,
void removeClockGroupsLogicallyExclusive(Sdc *sdc);
void removeClockGroupsLogicallyExclusive(const std::string &name,
Sdc *sdc);
void removeClockGroupsPhysicallyExclusive(const char *name,
void removeClockGroupsPhysicallyExclusive(Sdc *sdc);
void removeClockGroupsPhysicallyExclusive(const std::string &name,
Sdc *sdc);
void removeClockGroupsAsynchronous(const char *name,
void removeClockGroupsAsynchronous(Sdc *sdc);
void removeClockGroupsAsynchronous(const std::string &name,
Sdc *sdc);
void makeClockGroup(ClockGroups *clk_groups,
ClockSet *clks,
@@ -640,7 +642,7 @@ public:
float delay,
const char *comment,
Sdc *sdc);
void makeGroupPath(const char *name,
void makeGroupPath(const std::string &name,
bool is_default,
ExceptionFrom *from,
ExceptionThruSeq *thrus,
@@ -982,11 +984,11 @@ public:
bool report_cap,
bool report_slew,
bool report_fanout,
bool report_variation,
bool report_src_attr);
ReportField *findReportPathField(const char *name);
void setReportPathDigits(int digits);
void setReportPathNoSplit(bool no_split);
void setReportPathSigmas(bool report_sigmas);
void reportPathEnd(PathEnd *end);
void reportPathEnds(PathEndSeq *ends);
ReportPath *reportPath() { return report_path_; }
@@ -998,7 +1000,7 @@ public:
const SetupHold *setup_hold,
bool include_internal_latency,
int digits);
float findWorstClkSkew(const SetupHold *setup_hold,
Delay findWorstClkSkew(const SetupHold *setup_hold,
bool include_internal_latency);
void reportClkLatency(ConstClockSeq &clks,
@@ -1131,12 +1133,15 @@ public:
void reportArrivalWrtClks(const Pin *pin,
const Scene *scene,
bool report_variance,
int digits);
void reportRequiredWrtClks(const Pin *pin,
const Scene *scene,
bool report_variance,
int digits);
void reportSlackWrtClks(const Pin *pin,
const Scene *scene,
bool report_variance,
int digits);
Slew slew(Vertex *vertex,
@@ -1144,9 +1149,9 @@ public:
const SceneSeq &scenes,
const MinMax *min_max);
ArcDelay arcDelay(Edge *edge,
TimingArc *arc,
DcalcAPIndex ap_index);
const ArcDelay arcDelay(Edge *edge,
TimingArc *arc,
DcalcAPIndex ap_index);
// True if the timing arc has been back-annotated.
bool arcDelayAnnotated(Edge *edge,
TimingArc *arc,
@@ -1408,12 +1413,13 @@ public:
// TCL variable sta_crpr_mode.
CrprMode crprMode() const;
void setCrprMode(CrprMode mode);
// TCL variable sta_pocv_enabled.
// TCL variable sta_pocv_mode.
// Parametric on chip variation (statisical sta).
bool pocvEnabled() const;
void setPocvEnabled(bool enabled);
PocvMode pocvMode() const;
void setPocvMode(PocvMode mode);
// Number of std deviations from mean to use for normal distributions.
void setSigmaFactor(float factor);
float pocvQuantile();
void setPocvQuantile(float quantile);
// TCL variable sta_propagate_gated_clock_enable.
// Propagate gated clock enable arrivals.
bool propagateGatedClockEnable() const;
@@ -1510,17 +1516,20 @@ protected:
void reportDelaysWrtClks(const Pin *pin,
const Scene *scene,
bool report_variance,
int digits,
bool find_required,
PathDelayFunc get_path_delay);
void reportDelaysWrtClks(Vertex *vertex,
const Scene *scene,
bool report_variance,
int digits,
bool find_required,
PathDelayFunc get_path_delay);
void reportDelaysWrtClks(Vertex *vertex,
const ClockEdge *clk_edge,
const Scene *scene,
bool report_variance,
int digits,
PathDelayFunc get_path_delay);
RiseFallMinMaxDelay findDelaysWrtClks(Vertex *vertex,
@@ -1530,6 +1539,7 @@ protected:
std::string formatDelay(const RiseFall *rf,
const MinMax *min_max,
const RiseFallMinMaxDelay &delays,
bool report_variance,
int digits);
void connectDrvrPinAfter(Vertex *vertex);
+3 -2
View File
@@ -47,6 +47,7 @@ class GraphDelayCalc;
class Latches;
class DispatchQueue;
class Variables;
class DelayOps;
using ModeSeq = std::vector<Mode*>;
using ModeSet = std::set<Mode*>;
@@ -96,10 +97,10 @@ public:
GraphDelayCalc *graphDelayCalc() const { return graph_delay_calc_; }
Search *search() { return search_; }
Search *search() const { return search_; }
const DelayOps *delayOps() const { return delay_ops_; }
Latches *latches() { return latches_; }
Latches *latches() const { return latches_; }
unsigned threadCount() const { return thread_count_; }
float sigmaFactor() const { return sigma_factor_; }
bool crprActive(const Mode *mode) const;
Variables *variables() { return variables_; }
const Variables *variables() const { return variables_; }
@@ -133,11 +134,11 @@ protected:
ArcDelayCalc *arc_delay_calc_;
GraphDelayCalc *graph_delay_calc_;
Search *search_;
DelayOps *delay_ops_;
Latches *latches_;
Variables *variables_;
int thread_count_;
DispatchQueue *dispatch_queue_;
float sigma_factor_;
};
} // namespace
-34
View File
@@ -143,14 +143,6 @@ public:
char *
stringCopy(const char *str);
inline void
stringAppend(char *&str1,
const char *str2)
{
strcpy(str1, str2);
str1 += strlen(str2);
}
void
stringDeleteCheck(const char *str);
@@ -164,32 +156,6 @@ stringDelete(const char *str)
bool
isDigits(const char *str);
// Print to a new string.
// Caller owns returned string.
char *
stringPrint(const char *fmt,
...) __attribute__((format (printf, 1, 2)));
std::string
stdstrPrint(const char *fmt,
...) __attribute__((format (printf, 1, 2)));
char *
stringPrintArgs(const char *fmt,
va_list args);
void
stringPrint(std::string &str,
const char *fmt,
...) __attribute__((format (printf, 2, 3)));
// Formated append to std::string.
void
stringAppend(std::string &str,
const char *fmt,
...) __attribute__((format (printf, 2, 3)));
// Print to a temporary string.
char *
stringPrintTmp(const char *fmt,
...) __attribute__((format (printf, 1, 2)));
char *
makeTmpString(size_t length);
char *
+63 -37
View File
@@ -33,12 +33,14 @@
#include "Transition.hh"
#include "LibertyClass.hh"
#include "TimingModel.hh"
#include "Variables.hh"
namespace sta {
class Unit;
class Units;
class Report;
class TableModels;
class Table;
class TableModel;
class TableAxis;
@@ -63,43 +65,41 @@ class GateTableModel : public GateTimingModel
{
public:
GateTableModel(LibertyCell *cell,
TableModel *delay_model,
TableModelsEarlyLate delay_sigma_models,
TableModel *slew_model,
TableModelsEarlyLate slew_sigma_models,
TableModels *delay_models,
TableModels *slew_models,
ReceiverModelPtr receiver_model,
OutputWaveforms *output_waveforms);
GateTableModel(LibertyCell *cell,
TableModel *delay_model,
TableModel *slew_model);
TableModels *delay_models,
TableModels *slew_models);
~GateTableModel() override;
void gateDelay(const Pvt *pvt,
float in_slew,
float load_cap,
bool pocv_enabled,
// Return values.
ArcDelay &gate_delay,
Slew &drvr_slew) const override;
// deprecated 2024-01-07
// related_out_cap arg removed.
void gateDelay(const Pvt *pvt,
float in_slew,
float load_cap,
float related_out_cap,
bool pocv_enabled,
ArcDelay &gate_delay,
Slew &drvr_slew) const __attribute__ ((deprecated));
float &gate_delay,
float &drvr_slew) const override;
// Fill in pocv parameters in gate_delay, drvr_slew.
void gateDelayPocv(const Pvt *pvt,
float in_slew,
float load_cap,
const MinMax *min_max,
PocvMode pocv_mode,
// Return values.
ArcDelay &gate_delay,
Slew &drvr_slew) const override;
std::string reportGateDelay(const Pvt *pvt,
float in_slew,
float load_cap,
bool pocv_enabled,
const MinMax *min_max,
PocvMode pocv_mode,
int digits) const override;
float driveResistance(const Pvt *pvt) const override;
const TableModel *delayModel() const { return delay_model_.get(); }
const TableModel *slewModel() const { return slew_model_.get(); }
const TableModel *delaySigmaModel(const EarlyLate *el) const;
const TableModel *slewSigmaModel(const EarlyLate *el) const;
const TableModels *delayModels() const { return delay_models_.get(); }
const TableModel *delayModel() const;
const TableModels *slewModels() const { return slew_models_.get(); }
const TableModel *slewModel() const;
const ReceiverModel *receiverModel() const { return receiver_model_.get(); }
OutputWaveforms *outputWaveforms() const { return output_waveforms_.get(); }
// Check the axes before making the model.
@@ -138,10 +138,8 @@ protected:
float &axis_value3) const;
static bool checkAxis(const TableAxis *axis);
std::unique_ptr<TableModel> delay_model_;
TableModelsEarlyLate delay_sigma_models_;
std::unique_ptr<TableModel> slew_model_;
TableModelsEarlyLate slew_sigma_models_;
std::unique_ptr<TableModels> delay_models_;
std::unique_ptr<TableModels> slew_models_;
ReceiverModelPtr receiver_model_;
std::unique_ptr<OutputWaveforms> output_waveforms_;
};
@@ -150,25 +148,24 @@ class CheckTableModel : public CheckTimingModel
{
public:
CheckTableModel(LibertyCell *cell,
TableModel *model,
TableModelsEarlyLate sigma_models);
CheckTableModel(LibertyCell *cell,
TableModel *model);
TableModels *check_models);
~CheckTableModel() override;
ArcDelay checkDelay(const Pvt *pvt,
float from_slew,
float to_slew,
float related_out_cap,
bool pocv_enabled) const override;
const MinMax *min_max,
PocvMode pocv_mode) const override;
std::string reportCheckDelay(const Pvt *pvt,
float from_slew,
const char *from_slew_annotation,
float to_slew,
float related_out_cap,
bool pocv_enabled,
const MinMax *min_max,
PocvMode pocv_mode,
int digits) const override;
const TableModel *model() const { return model_.get(); }
const TableModel *sigmaModel(const EarlyLate *el) const;
const TableModels *checkModels() const { return check_models_.get(); }
const TableModel *checkModel() const;
// Check the axes before making the model.
// Return true if the model axes are supported.
@@ -202,8 +199,7 @@ protected:
int digits) const;
static bool checkAxis(const TableAxis *axis);
std::unique_ptr<TableModel> model_;
TableModelsEarlyLate sigma_models_;
std::unique_ptr<TableModels> check_models_;
};
class TableAxis
@@ -311,6 +307,8 @@ public:
private:
void clear();
float findValueOrder2(float axis_value1, float axis_value2) const;
float findValueOrder3(float axis_value1, float axis_value2, float axis_value3) const;
std::string reportValueOrder0(const char *result_name,
const char *comment1,
const Unit *table_unit,
@@ -408,6 +406,34 @@ protected:
bool is_scaled_:1;
};
// cell/transition/check nldm/ocv/lvf models for one rise/fall edge.
class TableModels
{
public:
TableModels();
TableModels(TableModel *model);
~TableModels();
TableModel *model() const { return model_.get(); }
void setModel(TableModel *model);
TableModel *sigma(const EarlyLate *early_late) const;
void setSigma(TableModel *table,
const EarlyLate *early_late);
TableModel *meanShift() const { return mean_shift_.get(); }
void setMeanShift(TableModel *table);
TableModel *skewness() const { return skewness_.get(); }
void setSkewness(TableModel *table);
TableModel *stdDev() const { return std_dev_.get(); }
void setStdDev(TableModel *table);
protected:
std::unique_ptr<TableModel> model_;
// Note early/late can point to the same model.
std::array<TableModel*, EarlyLate::index_count> sigma_;
std::unique_ptr<TableModel> std_dev_;
std::unique_ptr<TableModel> mean_shift_;
std::unique_ptr<TableModel> skewness_;
};
////////////////////////////////////////////////////////////////
class ReceiverModel
+18 -6
View File
@@ -28,6 +28,7 @@
#include "Delay.hh"
#include "LibertyClass.hh"
#include "Variables.hh"
namespace sta {
@@ -52,14 +53,23 @@ public:
virtual void gateDelay(const Pvt *pvt,
float in_slew,
float load_cap,
bool pocv_enabled,
// Return values.
ArcDelay &gate_delay,
Slew &drvr_slew) const = 0;
float &gate_delay,
float &drvr_slew) const = 0;
// Fill in pocv parameters in gate_delay, drvr_slew.
virtual void gateDelayPocv(const Pvt *pvt,
float in_slew,
float load_cap,
const MinMax *min_max,
PocvMode pocv_mode,
// Return values.
ArcDelay &gate_delay,
Slew &drvr_slew) const = 0;
virtual std::string reportGateDelay(const Pvt *pvt,
float in_slew,
float load_cap,
bool pocv_enabled,
const MinMax *min_max,
PocvMode pocv_mode,
int digits) const = 0;
virtual float driveResistance(const Pvt *pvt) const = 0;
};
@@ -74,13 +84,15 @@ public:
float from_slew,
float to_slew,
float related_out_cap,
bool pocv_enabled) const = 0;
const MinMax *min_max,
PocvMode pocv_mode) const = 0;
virtual std::string reportCheckDelay(const Pvt *pvt,
float from_slew,
const char *from_slew_annotation,
float to_slew,
float related_out_cap,
bool pocv_enabled,
const MinMax *min_max,
PocvMode pocv_mode,
int digits) const = 0;
};
+2 -3
View File
@@ -56,9 +56,8 @@ public:
void setDigits(int digits);
// Does not include suffix.
int width() const;
const char *asString(float value) const;
const char *asString(double value) const;
const char *asString(float value,
std::string asString(float value) const;
std::string asString(float value,
int digits) const;
private:
+9 -3
View File
@@ -24,6 +24,8 @@
#pragma once
#include "PocvMode.hh"
namespace sta {
enum class CrprMode { same_pin, same_transition };
@@ -72,8 +74,11 @@ public:
// TCL variable sta_input_port_default_clock.
bool useDefaultArrivalClock() { return use_default_arrival_clock_; }
void setUseDefaultArrivalClock(bool enable);
bool pocvEnabled() const { return pocv_enabled_; }
void setPocvEnabled(bool enabled);
bool pocvEnabled() const;
PocvMode pocvMode() const { return pocv_mode_; }
void setPocvMode(PocvMode mode);
float pocvQuantile() const { return pocv_quantile_; }
void setPocvQuantile(float quartile);
private:
bool crpr_enabled_;
@@ -88,7 +93,8 @@ private:
bool dynamic_loop_breaking_;
bool propagate_all_clks_;
bool use_default_arrival_clock_;
bool pocv_enabled_;
PocvMode pocv_mode_;
float pocv_quantile_;
};
} // namespace
+8 -8
View File
@@ -29,21 +29,21 @@
namespace sta {
std::string
cellVerilogName(const char *sta_name);
cellVerilogName(std::string sta_name);
std::string
instanceVerilogName(const char *sta_name);
instanceVerilogName(std::string sta_name);
std::string
netVerilogName(const char *sta_name);
netVerilogName(std::string sta_name);
std::string
portVerilogName(const char *sta_name);
portVerilogName(std::string sta_name);
std::string
moduleVerilogToSta(const std::string *sta_name);
moduleVerilogToSta(std::string sta_name);
std::string
instanceVerilogToSta(const std::string *sta_name);
instanceVerilogToSta(std::string sta_name);
std::string
netVerilogToSta(const std::string *sta_name);
netVerilogToSta(std::string sta_name);
std::string
portVerilogToSta(const std::string *sta_name);
portVerilogToSta(std::string sta_name);
} // namespace
+58 -11
View File
@@ -25,9 +25,12 @@
#pragma once
#include <string>
#include <string_view>
#include <vector>
#include <map>
#include "Format.hh"
#include "Report.hh"
#include "StringUtil.hh"
#include "NetworkClass.hh"
@@ -59,8 +62,32 @@ class StringRegistry;
class VerilogBindingTbl;
class VerilogNetNameIterator;
class VerilogNetPortRef;
class VerilogError;
class LibertyCell;
class VerilogErrorCmp;
class VerilogError
{
public:
VerilogError(int id,
std::string_view filename,
int line,
std::string_view msg,
bool warn);
const char *msg() const { return msg_.c_str(); }
const char *filename() const { return filename_.c_str(); }
int id() const { return id_; }
int line() const { return line_; }
bool warn() const { return warn_; }
private:
int id_;
std::string filename_;
int line_;
std::string msg_;
bool warn_;
friend class VerilogErrorCmp;
};
using VerilogModuleMap = std::map<Cell*, VerilogModule*>;
using VerilogStmtSeq = std::vector<VerilogStmt*>;
@@ -148,14 +175,24 @@ public:
const char *filename() const { return filename_.c_str(); }
void incrLine();
Report *report() const { return report_; }
template <typename... Args>
void error(int id,
const char *filename,
std::string_view filename,
int line,
const char *fmt, ...);
std::string_view fmt,
Args &&...args)
{
report_->fileError(id, filename, line, fmt, std::forward<Args>(args)...);
}
template <typename... Args>
void warn(int id,
const char *filename,
std::string_view filename,
int line,
const char *fmt, ...);
std::string_view fmt,
Args &&...args)
{
report_->fileWarn(id, filename, line, fmt, std::forward<Args>(args)...);
}
const std::string &zeroNetName() const { return zero_net_name_; }
const std::string &oneNetName() const { return one_net_name_; }
void deleteModules();
@@ -231,16 +268,26 @@ protected:
Instance *parent,
VerilogBindingTbl *parent_bindings,
bool is_leaf);
template <typename... Args>
void linkWarn(int id,
const char *filename,
std::string_view filename,
int line,
const char *msg, ...)
__attribute__((format (printf, 5, 6)));
std::string_view msg,
Args &&...args)
{
std::string msg_str = sta::formatRuntime(msg, std::forward<Args>(args)...);
link_errors_.push_back(new VerilogError(id, filename, line, msg_str, true));
}
template <typename... Args>
void linkError(int id,
const char *filename,
std::string_view filename,
int line,
const char *msg, ...)
__attribute__((format (printf, 5, 6)));
std::string_view msg,
Args &&...args)
{
std::string msg_str = sta::formatRuntime(msg, std::forward<Args>(args)...);
link_errors_.push_back(new VerilogError(id, filename, line, msg_str, false));
}
bool reportLinkErrors();
bool haveLinkErrors();
Cell *makeBlackBox(VerilogModuleInst *mod_inst,