pickup changes from upstream, latest on 4/27

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
This commit is contained in:
dsengupta0628 2026-04-27 18:45:35 +00:00
commit ae37dc6238
28 changed files with 188 additions and 137 deletions

View File

@ -76,5 +76,7 @@ HeaderFilterRegex: '.*/(app|cmake|dcalc|graph|liberty|network|parasitics|power|s
# util/gzstream.hh
# util/FlexDisableRegister.hh
# Bison-generated parser headers (build/{Liberty,Verilog,...}Parse.hh)
ExcludeHeaderFilterRegex: '(.*/)?(gzstream\.hh|FlexDisableRegister\.hh|(Liberty|Verilog|Sdf|Spef|Saif|LibExpr)Parse\.hh)$'
# Homebrew and MacPorts third-party headers.
ExcludeHeaderFilterRegex: '(^/opt/(homebrew|local)/.*)|((.*/)?(gzstream\.hh|FlexDisableRegister\.hh|(Liberty|Verilog|Sdf|Spef|Saif|LibExpr)Parse\.hh)$)'
SystemHeaders: false
FormatStyle: none

View File

@ -0,0 +1,13 @@
---
description: Where OpenSTA regression tests live (pvt/test vs public test/)
alwaysApply: true
---
# OpenSTA tests and regression
- **Primary suite:** Most regression tests, Tcl drivers, and golden `.ok` files live under **`pvt/test/`** (private / separate repo, often opened as a second workspace root alongside `master`).
- **Public subset:** **`test/`** at the OpenSTA repo root holds a smaller set of tests shipped with the public tree (e.g. `test/regression`, `*.tcl`, `*.ok` there).
When searching for a test name, regression lists, or updating goldens, **check `pvt/test` first**, then `test/`.
Typical driver: `pvt/test/regression` (or `test/regression` for the public list). Built `sta` binary is usually `master/build/sta` relative to the main checkout.

View File

@ -69,7 +69,6 @@ class rcmodel : public ConcreteParasitic,
public arnoldi1
{
public:
rcmodel();
~rcmodel() override;
float capacitance() const override;
PinSet unannotatedLoads(const Pin *drvr_pin,

View File

@ -43,12 +43,11 @@ namespace sta {
// This is legacy C-style code.
// NOLINTBEGIN(modernize-avoid-c-style-cast, bugprone-multi-level-implicit-pointer-conversion, bugprone-implicit-widening-of-multiplication-result)
rcmodel::rcmodel()
rcmodel::~rcmodel()
{
free(pinV);
}
rcmodel::~rcmodel() { free(pinV); }
float
rcmodel::capacitance() const
{

View File

@ -121,7 +121,7 @@ DelayOpsNormal::greater(const Delay &delay1,
const StaState *sta) const
{
return fuzzyGreater(delayAsFloat(delay1, EarlyLate::late(), sta),
delayAsFloat(delay2, EarlyLate::late(), sta));
delayAsFloat(delay2, EarlyLate::late(), sta));
}
bool
@ -130,7 +130,7 @@ DelayOpsNormal::greaterEqual(const Delay &delay1,
const StaState *sta) const
{
return fuzzyGreaterEqual(delayAsFloat(delay1, EarlyLate::late(), sta),
delayAsFloat(delay2, EarlyLate::late(), sta));
delayAsFloat(delay2, EarlyLate::late(), sta));
}
Delay
@ -138,7 +138,7 @@ DelayOpsNormal::sum(const Delay &delay1,
const Delay &delay2) const
{
return Delay(delay1.mean() + delay2.mean(),
delay1.stdDev2() + delay2.stdDev2());
delay1.stdDev2() + delay2.stdDev2());
}
Delay
@ -146,7 +146,7 @@ DelayOpsNormal::sum(const Delay &delay1,
float delay2) const
{
return Delay(delay1.mean() + delay2,
delay1.stdDev2());
delay1.stdDev2());
}
Delay

View File

@ -142,8 +142,10 @@ LumpedCapDelayCalc::gateDelay(const Pin *drvr_pin,
float gate_delay, drvr_slew;
float in_slew1 = delayAsFloat(in_slew);
// NaNs cause seg faults during table lookup.
if (std::isnan(load_cap) || std::isnan(in_slew.mean()))
report_->error(1350, "gate delay input variable is NaN");
if (std::isnan(load_cap))
report_->error(1350, "gate delay load cap is NaN");
if (std::isnan(in_slew.mean()))
report_->error(1351, "gate delay input slew is NaN");
const Pvt *pvt = pinPvt(drvr_pin, scene, min_max);
model->gateDelay(pvt, in_slew1, load_cap, gate_delay, drvr_slew);

View File

@ -90,7 +90,7 @@ public:
// Return values.
float &slew,
bool &exists) const;
ClockUncertainties *uncertainties() const { return uncertainties_; }
const ClockUncertainties &uncertainties() const { return uncertainties_; }
void uncertainty(const SetupHold *setup_hold,
// Return values.
float &uncertainty,
@ -180,7 +180,7 @@ protected:
bool is_propagated_{false};
RiseFallMinMax slews_;
RiseFallMinMax slew_limits_[path_clk_or_data_count];
ClockUncertainties *uncertainties_{nullptr};
ClockUncertainties uncertainties_;
bool is_generated_{false};
// Generated clock variables.
Pin *src_pin_{nullptr};

View File

@ -169,6 +169,11 @@ public:
static int cmp(const MinMaxValues *values1,
const MinMaxValues *values2)
{
if (!values1->exists_[MinMax::minIndex()]
&& !values2->exists_[MinMax::minIndex()]
&& !values1->exists_[MinMax::maxIndex()]
&& !values2->exists_[MinMax::maxIndex()])
return 0;
if (!values1->exists_[MinMax::minIndex()]
&& values2->exists_[MinMax::minIndex()])
return -1;

View File

@ -99,25 +99,25 @@ public:
// return PropertyValue("bar");
// });
void defineProperty(std::string_view property,
PropertyRegistry<const Library *>::PropertyHandler &handler);
const PropertyRegistry<const Library *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
PropertyRegistry<const LibertyLibrary *>::PropertyHandler &handler);
const PropertyRegistry<const LibertyLibrary *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
PropertyRegistry<const Cell *>::PropertyHandler &handler);
const PropertyRegistry<const Cell *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
PropertyRegistry<const LibertyCell *>::PropertyHandler &handler);
const PropertyRegistry<const LibertyCell *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
PropertyRegistry<const Port *>::PropertyHandler &handler);
const PropertyRegistry<const Port *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
PropertyRegistry<const LibertyPort *>::PropertyHandler &handler);
const PropertyRegistry<const LibertyPort *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
PropertyRegistry<const Instance *>::PropertyHandler &handler);
const PropertyRegistry<const Instance *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
PropertyRegistry<const Pin *>::PropertyHandler &handler);
const PropertyRegistry<const Pin *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
PropertyRegistry<const Net *>::PropertyHandler &handler);
const PropertyRegistry<const Net *>::PropertyHandler &handler);
void defineProperty(std::string_view property,
PropertyRegistry<const Clock *>::PropertyHandler &handler);
const PropertyRegistry<const Clock *>::PropertyHandler &handler);
protected:
PropertyValue portSlew(const Port *port,

View File

@ -89,7 +89,7 @@ protected:
std::string name_;
size_t index_;
Mode *mode_;
LibertySeq liberty_[MinMax::index_count];
std::array<LibertySeq, MinMax::index_count> liberty_;
std::array<Parasitics*, MinMax::index_count> parasitics_;
friend class Scenes;

View File

@ -409,6 +409,11 @@ public:
void saveEnumPath(Path *path);
bool isSrchRoot(Vertex *vertex,
const Mode *mode) const;
DelaysWrtClks arrivalsWrtClks(Vertex *vertex,
const Scene *scene);
DelaysWrtClks delaysWrtClks(Vertex *vertex,
const Scene *scene,
const PathDelayFunc &get_path_delay);
protected:
void initVars();

View File

@ -24,14 +24,18 @@
#pragma once
#include <functional>
#include <limits>
#include <map>
#include <vector>
#include "Delay.hh"
#include "GraphClass.hh"
#include "LibertyClass.hh"
#include "MinMaxValues.hh"
#include "NetworkClass.hh"
#include "RiseFallMinMaxDelay.hh"
#include "SdcClass.hh"
#include "VectorMap.hh"
namespace sta {
@ -111,6 +115,9 @@ using SlackSeq = std::vector<Slack>;
using Crpr = Delay;
using PathSeq = std::vector<Path*>;
using ConstPathSeq = std::vector<const Path*>;
// Path::slack/arrival/required function.
using PathDelayFunc = std::function<Delay (const Path *path)>;
using DelaysWrtClks = std::map<const ClockEdge*, RiseFallMinMaxDelay>;
enum class ReportPathFormat { full,
full_clock,

View File

@ -24,7 +24,7 @@
#pragma once
#include <functional>
#include <map>
#include <string>
#include <string_view>
#include <vector>
@ -82,8 +82,6 @@ using CheckError = StringSeq;
using CheckErrorSeq = std::vector<CheckError*>;
enum class CmdNamespace { sta, sdc };
using ParasiticsNameMap = std::map<std::string, Parasitics*, std::less<>>;
// Path::slack/arrival/required function.
using PathDelayFunc = std::function<Delay (const Path *path)>;
using GraphLoopSeq = std::vector<GraphLoop*>;
// Initialize sta functions that are not part of the Sta class.
@ -1531,16 +1529,10 @@ protected:
int digits,
bool find_required,
const PathDelayFunc &get_path_delay);
void reportDelaysWrtClks(Vertex *vertex,
const ClockEdge *clk_edge,
const Scene *scene,
void reportDelaysWrtClks(const ClockEdge *clk_edge,
bool report_variance,
int digits,
const PathDelayFunc &get_path_delay);
RiseFallMinMaxDelay findDelaysWrtClks(Vertex *vertex,
const ClockEdge *clk_edge,
const Scene *scene,
const PathDelayFunc &get_path_delay);
DelaysWrtClks &clk_delays);
std::string formatDelay(const RiseFall *rf,
const MinMax *min_max,
const RiseFallMinMaxDelay &delays,
@ -1616,6 +1608,7 @@ protected:
Mode *mode,
Parasitics *parasitics);
void deleteScenes();
void checkLibrarayPocv();
Scene *cmd_scene_{nullptr};
CmdNamespace cmd_namespace_{CmdNamespace::sdc};

View File

@ -724,21 +724,21 @@ LibertyLibrary::makeSceneMap(LibertyLibrary *lib,
// Map a cell linked in the network to the corresponding liberty cell
// to use for delay calculation at a scene.
void
LibertyLibrary::makeSceneMap(LibertyCell *cell1,
LibertyCell *cell2,
LibertyLibrary::makeSceneMap(LibertyCell *link_cell,
LibertyCell *scene_cell,
Scene *scene,
const MinMaxAll *min_max,
Report *report)
{
for (const MinMax *mm : min_max->range()) {
size_t lib_ap_index = scene->libertyIndex(mm);
cell1->setSceneCell(cell2, lib_ap_index);
link_cell->setSceneCell(scene_cell, lib_ap_index);
}
LibertyCellPortBitIterator port_iter1(cell1);
LibertyCellPortBitIterator port_iter1(link_cell);
while (port_iter1.hasNext()) {
LibertyPort *port1 = port_iter1.next();
LibertyPort *port2 = cell2->findLibertyPort(port1->name());
LibertyPort *port2 = scene_cell->findLibertyPort(port1->name());
if (port2) {
for (const MinMax *mm : min_max->range()) {
size_t lib_ap_index = scene->libertyIndex(mm);
@ -747,15 +747,15 @@ LibertyLibrary::makeSceneMap(LibertyCell *cell1,
}
else
report->warn(1110, "cell {}/{} port {} not found in cell {}/{}.",
cell1->library()->name(),
cell1->name(),
link_cell->library()->name(),
link_cell->name(),
port1->name(),
cell2->library()->name(),
cell2->name());
scene_cell->library()->name(),
scene_cell->name());
}
for (TimingArcSet *arc_set1 : cell1->timing_arc_sets_) {
TimingArcSet *arc_set2 = cell2->findTimingArcSet(arc_set1);
for (TimingArcSet *arc_set1 : link_cell->timing_arc_sets_) {
TimingArcSet *arc_set2 = scene_cell->findTimingArcSet(arc_set1);
if (arc_set2) {
const TimingArcSeq &arcs1 = arc_set1->arcs();
const TimingArcSeq &arcs2 = arc_set2->arcs();
@ -775,13 +775,13 @@ LibertyLibrary::makeSceneMap(LibertyCell *cell1,
}
else
report->warn(1111, "cell {}/{} {} -> {} timing group {} not found in cell {}/{}.",
cell1->library()->name(),
cell1->name(),
link_cell->library()->name(),
link_cell->name(),
arc_set1->from() ? arc_set1->from()->name() : "",
arc_set1->to()->name(),
arc_set1->role()->to_string(),
cell2->library()->name(),
cell2->name());
scene_cell->library()->name(),
scene_cell->name());
}
}

View File

@ -134,16 +134,16 @@ Network::readLibertyAfter(LibertyLibrary *)
LibertyCell *
Network::findLibertyCell(std::string_view name) const
{
LibertyLibraryIterator *iter = libertyLibraryIterator();
while (iter->hasNext()) {
LibertyLibrary *lib = iter->next();
LibertyLibraryIterator *lib_iter = libertyLibraryIterator();
while (lib_iter->hasNext()) {
LibertyLibrary *lib = lib_iter->next();
LibertyCell *cell = lib->findLibertyCell(name);
if (cell) {
delete iter;
delete lib_iter;
return cell;
}
}
delete iter;
delete lib_iter;
return nullptr;
}

View File

@ -73,11 +73,11 @@ FLOAT {DECIMAL}|{FRACTION}|{EXP}
HCHAR "."|"/"|"|"|":"
PREFIX_BUS_DELIM "["|"{"|"("|"<"
SUFFIX_BUS_DELIM "]"|"}"|")"|">"
SPECIAL_CHAR "!"|"#"|"$"|"%"|"&"|"`"|"("|")"|"*"|"+"|","|"-"|"."|"/"|":"|";"|"<"|"="|">"|"?"|"@"|"["|"\\"|"]"|"^"|"'"|"{"|"|"|"}"|"~"
SPECIAL_CHAR "#"|"$"|"%"|"&"|"`"|"("|")"|"*"|"+"|","|"-"|"."|"/"|":"|";"|"<"|"="|">"|"?"|"@"|"["|"\\"|"]"|"^"|"'"|"{"|"|"|"}"|"~"
ESCAPED_CHAR_SET {SPECIAL_CHAR}|\"
ESCAPED_CHAR \\{ESCAPED_CHAR_SET}
IDENT_ACHAR {ESCAPED_CHAR}|{ALPHA}|"_"
IDENT_CHAR {IDENT_ACHAR}|{DIGIT}
IDENT_CHAR {IDENT_ACHAR}|{DIGIT}|"!"
ID {IDENT_ACHAR}{IDENT_CHAR}*
BUS_SUB {DIGIT}|{ALPHA}|"_"
BIT_IDENT {ID}({PREFIX_BUS_DELIM}{BUS_SUB}+{SUFFIX_BUS_DELIM})+

View File

@ -240,42 +240,27 @@ Clock::uncertainty(const SetupHold *setup_hold,
float &uncertainty,
bool &exists) const
{
if (uncertainties_)
uncertainties_->value(setup_hold, uncertainty, exists);
else {
uncertainty = 0.0F;
exists = false;
}
uncertainties_.value(setup_hold, uncertainty, exists);
}
void
Clock::setUncertainty(const SetupHoldAll *setup_hold,
float uncertainty)
{
if (uncertainties_ == nullptr)
uncertainties_ = new ClockUncertainties;
uncertainties_->setValue(setup_hold, uncertainty);
uncertainties_.setValue(setup_hold, uncertainty);
}
void
Clock::setUncertainty(const SetupHold *setup_hold,
float uncertainty)
{
if (uncertainties_ == nullptr)
uncertainties_ = new ClockUncertainties;
uncertainties_->setValue(setup_hold, uncertainty);
uncertainties_.setValue(setup_hold, uncertainty);
}
void
Clock::removeUncertainty(const SetupHoldAll *setup_hold)
{
if (uncertainties_) {
uncertainties_->removeValue(setup_hold);
if (uncertainties_->empty()) {
delete uncertainties_;
uncertainties_ = nullptr;
}
}
uncertainties_.removeValue(setup_hold);
}
void

View File

@ -231,7 +231,7 @@ MakeTimingModel::checkClock(Clock *clk)
{
for (const Pin *pin : clk->leafPins()) {
if (!network_->isTopLevelPort(pin))
report_->warn(1355, "clock {} pin {} is inside model block.", clk->name(),
report_->warn(1380, "clock {} pin {} is inside model block.", clk->name(),
network_->pathName(pin));
}
}

View File

@ -379,7 +379,7 @@ PathEnd::checkTgtClkUncertainty(const Path *tgt_clk_path,
if (tgt_clk_path && tgt_clk_path->isClock(sta))
uncertainties = tgt_clk_path->clkInfo(sta)->uncertainties();
else if (tgt_clk_edge)
uncertainties = tgt_clk_edge->clock()->uncertainties();
uncertainties = &tgt_clk_edge->clock()->uncertainties();
float uncertainty = 0.0;
if (uncertainties) {
bool exists;

View File

@ -1265,70 +1265,70 @@ Properties::capacitancePropertyValue(float cap)
void
Properties::defineProperty(std::string_view property,
PropertyRegistry<const Library *>::PropertyHandler &handler)
const PropertyRegistry<const Library *>::PropertyHandler &handler)
{
registry_library_.defineProperty(property, handler);
}
void
Properties::defineProperty(std::string_view property,
PropertyRegistry<const LibertyLibrary *>::PropertyHandler &handler)
const PropertyRegistry<const LibertyLibrary *>::PropertyHandler &handler)
{
registry_liberty_library_.defineProperty(property, handler);
}
void
Properties::defineProperty(std::string_view property,
PropertyRegistry<const Cell *>::PropertyHandler &handler)
const PropertyRegistry<const Cell *>::PropertyHandler &handler)
{
registry_cell_.defineProperty(property, handler);
}
void
Properties::defineProperty(std::string_view property,
PropertyRegistry<const LibertyCell *>::PropertyHandler &handler)
const PropertyRegistry<const LibertyCell *>::PropertyHandler &handler)
{
registry_liberty_cell_.defineProperty(property, handler);
}
void
Properties::defineProperty(std::string_view property,
PropertyRegistry<const Port *>::PropertyHandler &handler)
const PropertyRegistry<const Port *>::PropertyHandler &handler)
{
registry_port_.defineProperty(property, handler);
}
void
Properties::defineProperty(std::string_view property,
PropertyRegistry<const LibertyPort *>::PropertyHandler &handler)
const PropertyRegistry<const LibertyPort *>::PropertyHandler &handler)
{
registry_liberty_port_.defineProperty(property, handler);
}
void
Properties::defineProperty(std::string_view property,
PropertyRegistry<const Instance *>::PropertyHandler &handler)
const PropertyRegistry<const Instance *>::PropertyHandler &handler)
{
registry_instance_.defineProperty(property, handler);
}
void
Properties::defineProperty(std::string_view property,
PropertyRegistry<const Pin *>::PropertyHandler &handler)
const PropertyRegistry<const Pin *>::PropertyHandler &handler)
{
registry_pin_.defineProperty(property, handler);
}
void
Properties::defineProperty(std::string_view property,
PropertyRegistry<const Net *>::PropertyHandler &handler)
const PropertyRegistry<const Net *>::PropertyHandler &handler)
{
registry_net_.defineProperty(property, handler);
}
void
Properties::defineProperty(std::string_view property,
PropertyRegistry<const Clock *>::PropertyHandler &handler)
const PropertyRegistry<const Clock *>::PropertyHandler &handler)
{
registry_clock_.defineProperty(property, handler);
}
@ -1355,7 +1355,7 @@ void
PropertyRegistry<TYPE>::defineProperty(std::string_view property,
PropertyHandler handler)
{
registry_[std::string(property)] = std::move(std::move(std::move(std::move(std::move(std::move(std::move(std::move(std::move(std::move(handler))))))))));
registry_[std::string(property)] = std::move(handler);
}
} // namespace sta

View File

@ -57,6 +57,7 @@
#include "PortDelay.hh"
#include "PortDirection.hh"
#include "Report.hh"
#include "RiseFallMinMaxDelay.hh"
#include "Scene.hh"
#include "Sdc.hh"
#include "SdcClass.hh"
@ -1546,7 +1547,7 @@ Search::seedClkArrival(const Pin *pin,
const ClockUncertainties *uncertainties = sdc->clockUncertainties(pin);
if (uncertainties == nullptr)
uncertainties = clk->uncertainties();
uncertainties = &clk->uncertainties();
// Propagate liberty "pulse_clock" transition to transitive fanout.
LibertyPort *port = network_->libertyPort(pin);
const RiseFall *pulse_clk_sense = (port ? port->pulseClkSense() : nullptr);
@ -1913,13 +1914,13 @@ Search::inputDelayTag(const Pin *pin,
const Pin *clk_pin = nullptr;
const RiseFall *clk_rf = nullptr;
bool is_propagated = false;
ClockUncertainties *clk_uncertainties = nullptr;
const ClockUncertainties *clk_uncertainties = nullptr;
if (clk_edge) {
clk = clk_edge->clock();
clk_rf = clk_edge->transition();
clk_pin = clk->defaultPin();
is_propagated = clk->isPropagated();
clk_uncertainties = clk->uncertainties();
clk_uncertainties = &clk->uncertainties();
}
Sdc *sdc = scene->sdc();
@ -3997,4 +3998,37 @@ Search::wnsSlack(Vertex *vertex,
return slacks[path_ap_index];
}
////////////////////////////////////////////////////////////////
DelaysWrtClks
Search::arrivalsWrtClks(Vertex *vertex,
const Scene *scene)
{
return delaysWrtClks(vertex, scene,
[] (const Path *path) {
return path->arrival();
});
}
DelaysWrtClks
Search::delaysWrtClks(Vertex *vertex,
const Scene *scene,
const PathDelayFunc &get_path_delay)
{
DelaysWrtClks delays_wrt_clks;
VertexPathIterator path_iter(vertex, scene, nullptr, nullptr, this);
while (path_iter.hasNext()) {
Path *path = path_iter.next();
Delay delay = get_path_delay(path);
if (!delayInf(delay, this)) {
const RiseFall *rf = path->transition(this);
const MinMax *min_max = path->minMax(this);
const ClockEdge *clk_edge = path->clkEdge(this);
RiseFallMinMaxDelay &delays = delays_wrt_clks[clk_edge];
delays.mergeValue(rf, min_max, delay, this);
}
}
return delays_wrt_clks;
}
} // namespace sta

View File

@ -237,7 +237,7 @@ endpoint_slack(const Pin *pin,
sta->ensureLibLinked();
if (!path_group_name.empty()
&& !sta->isPathGroupName(path_group_name, sta->cmdSdc())) {
sta->report()->error(1577, "{} is not a known path group name.",
sta->report()->error(1590, "{} is not a known path group name.",
path_group_name);
return INF;
}
@ -438,7 +438,7 @@ set_report_path_field_properties(const char *field_name,
if (field)
field->setProperties(title, width, left_justify);
else
sta->report()->warn(1575, "unknown report path field {}", field_name);
sta->report()->warn(1591, "unknown report path field {}", field_name);
}
void
@ -963,7 +963,7 @@ set_crpr_mode(std::string mode)
else if (stringEqual(mode, "same_transition"))
sta->setCrprMode(CrprMode::same_transition);
else
sta->report()->error(1573, "unknown common clk pessimism mode.");
sta->report()->error(1592, "unknown common clk pessimism mode.");
}
const std::string &

View File

@ -26,6 +26,7 @@
#include <algorithm>
#include <cstddef>
#include <map>
#include <string>
#include "ArcDelayCalc.hh"
@ -2281,9 +2282,11 @@ Sta::setPocvMode(PocvMode mode)
delay_ops_ = new DelayOpsScalar();
break;
case PocvMode::normal:
checkLibrarayPocv();
delay_ops_ = new DelayOpsNormal();
break;
case PocvMode::skew_normal:
checkLibrarayPocv();
delay_ops_ = new DelayOpsSkewNormal();
break;
}
@ -2292,6 +2295,33 @@ Sta::setPocvMode(PocvMode mode)
}
}
void
Sta::checkLibrarayPocv()
{
LibertyLibraryIterator *lib_iter = network_->libertyLibraryIterator();
while (lib_iter->hasNext()) {
LibertyLibrary *lib = lib_iter->next();
LibertyCellIterator cell_iter(lib);
while (cell_iter.hasNext()) {
LibertyCell *cell = cell_iter.next();
for (const TimingArcSet *arc_set : cell->timingArcSets()) {
for (const TimingArc *arc : arc_set->arcs()) {
GateTableModel *gate_model = arc->gateTableModel();
if (gate_model) {
const TableModels *models = gate_model->delayModels();
if (models->sigma(EarlyLate::early()) != nullptr) {
delete lib_iter;
return;
}
}
}
}
}
}
delete lib_iter;
report_->warn(1578, "No liberty POCV/LVF models found.");
}
float
Sta::pocvQuantile()
{
@ -3353,29 +3383,25 @@ Sta::reportDelaysWrtClks(Vertex *vertex,
else
search_->findArrivals(vertex->level());
const Sdc *sdc = scene->sdc();
reportDelaysWrtClks(vertex, nullptr, scene, report_variance, digits, get_path_delay);
DelaysWrtClks clk_delays = search_->delaysWrtClks(vertex, scene, get_path_delay);
reportDelaysWrtClks(nullptr, report_variance, digits, clk_delays);
const ClockEdge *default_clk_edge = sdc->defaultArrivalClock()->edge(RiseFall::rise());
reportDelaysWrtClks(vertex, default_clk_edge, scene, report_variance,
digits, get_path_delay);
reportDelaysWrtClks(default_clk_edge, report_variance, digits, clk_delays);
for (const Clock *clk : sdc->sortedClocks()) {
for (const RiseFall *rf : RiseFall::range()) {
const ClockEdge *clk_edge = clk->edge(rf);
reportDelaysWrtClks(vertex, clk_edge, scene, report_variance, digits,
get_path_delay);
reportDelaysWrtClks(clk_edge, report_variance, digits, clk_delays);
}
}
}
void
Sta::reportDelaysWrtClks(Vertex *vertex,
const ClockEdge *clk_edge,
const Scene *scene,
Sta::reportDelaysWrtClks(const ClockEdge *clk_edge,
bool report_variance,
int digits,
const PathDelayFunc &get_path_delay)
DelaysWrtClks &clk_delays)
{
RiseFallMinMaxDelay delays =
findDelaysWrtClks(vertex, clk_edge, scene, get_path_delay);
const RiseFallMinMaxDelay &delays = clk_delays[clk_edge];
if (!delays.empty()) {
std::string clk_name;
if (clk_edge)
@ -3392,27 +3418,6 @@ Sta::reportDelaysWrtClks(Vertex *vertex,
}
}
RiseFallMinMaxDelay
Sta::findDelaysWrtClks(Vertex *vertex,
const ClockEdge *clk_edge,
const Scene *scene,
const PathDelayFunc &get_path_delay)
{
RiseFallMinMaxDelay delays;
VertexPathIterator path_iter(vertex, scene, nullptr, nullptr, this);
while (path_iter.hasNext()) {
Path *path = path_iter.next();
Delay delay = get_path_delay(path);
const RiseFall *rf = path->transition(this);
const MinMax *min_max = path->minMax(this);
const ClockEdge *path_clk_edge = path->clkEdge(this);
if (path_clk_edge == clk_edge
&& !delayInf(delay, this))
delays.mergeValue(rf, min_max, delay, this);
}
return delays;
}
std::string
Sta::formatDelay(const RiseFall *rf,
const MinMax *min_max,

View File

@ -311,7 +311,7 @@ TagGroupBldr::copyPaths(TagGroup *tag_group,
if (exists2)
paths[path_index2] = paths_[path_index1];
else
sta_->report()->critical(1351, "tag group missing tag");
sta_->report()->critical(1360, "tag group missing tag");
}
}

View File

@ -193,7 +193,7 @@ WritePathSpice::WritePathSpice(const Path *path,
void
WritePathSpice::writeSpice()
{
spice_stream_.open(std::string(spice_filename_));
spice_stream_.open(spice_filename_);
if (spice_stream_.is_open()) {
path_expanded_.expand(path_, true);
// Find subckt port names as a side-effect of writeSubckts.

View File

@ -165,12 +165,12 @@ protected:
std::string replaceFileExt(std::string_view filename,
std::string_view ext);
const std::string_view spice_filename_;
const std::string_view subckt_filename_;
const std::string_view lib_subckt_filename_;
const std::string_view model_filename_;
const std::string_view power_name_;
const std::string_view gnd_name_;
const std::string spice_filename_;
const std::string subckt_filename_;
const std::string lib_subckt_filename_;
const std::string model_filename_;
const std::string power_name_;
const std::string gnd_name_;
CircuitSim ckt_sim_;
const Scene *scene_;
const MinMax *min_max_;

View File

@ -26,7 +26,9 @@
#include <algorithm>
#include <cctype>
#include <cerrno>
#include <charconv>
#include <cstdlib>
#include <system_error>
#include <version>

View File

@ -1490,12 +1490,12 @@ VerilogReader::linkNetwork(std::string_view top_cell_name,
return top_instance;
}
else {
report_->error(1398, "{} is not a verilog module.", top_cell_name);
report_->error(1390, "{} is not a verilog module.", top_cell_name);
return nullptr;
}
}
else {
report_->error(1399, "{} is not a verilog module.", top_cell_name);
report_->error(1391, "{} is not a verilog module.", top_cell_name);
return nullptr;
}
}