pickup changes from upstream, latest on 4/27
Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
This commit is contained in:
commit
ae37dc6238
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -69,7 +69,6 @@ class rcmodel : public ConcreteParasitic,
|
|||
public arnoldi1
|
||||
{
|
||||
public:
|
||||
rcmodel();
|
||||
~rcmodel() override;
|
||||
float capacitance() const override;
|
||||
PinSet unannotatedLoads(const Pin *drvr_pin,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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})+
|
||||
|
|
|
|||
23
sdc/Clock.cc
23
sdc/Clock.cc
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 &
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cerrno>
|
||||
#include <charconv>
|
||||
#include <cstdlib>
|
||||
#include <system_error>
|
||||
#include <version>
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue