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/gzstream.hh
|
||||||
# util/FlexDisableRegister.hh
|
# util/FlexDisableRegister.hh
|
||||||
# Bison-generated parser headers (build/{Liberty,Verilog,...}Parse.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
|
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 arnoldi1
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
rcmodel();
|
|
||||||
~rcmodel() override;
|
~rcmodel() override;
|
||||||
float capacitance() const override;
|
float capacitance() const override;
|
||||||
PinSet unannotatedLoads(const Pin *drvr_pin,
|
PinSet unannotatedLoads(const Pin *drvr_pin,
|
||||||
|
|
|
||||||
|
|
@ -43,12 +43,11 @@ namespace sta {
|
||||||
// This is legacy C-style code.
|
// This is legacy C-style code.
|
||||||
// NOLINTBEGIN(modernize-avoid-c-style-cast, bugprone-multi-level-implicit-pointer-conversion, bugprone-implicit-widening-of-multiplication-result)
|
// 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
|
float
|
||||||
rcmodel::capacitance() const
|
rcmodel::capacitance() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ DelayOpsNormal::greater(const Delay &delay1,
|
||||||
const StaState *sta) const
|
const StaState *sta) const
|
||||||
{
|
{
|
||||||
return fuzzyGreater(delayAsFloat(delay1, EarlyLate::late(), sta),
|
return fuzzyGreater(delayAsFloat(delay1, EarlyLate::late(), sta),
|
||||||
delayAsFloat(delay2, EarlyLate::late(), sta));
|
delayAsFloat(delay2, EarlyLate::late(), sta));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -130,7 +130,7 @@ DelayOpsNormal::greaterEqual(const Delay &delay1,
|
||||||
const StaState *sta) const
|
const StaState *sta) const
|
||||||
{
|
{
|
||||||
return fuzzyGreaterEqual(delayAsFloat(delay1, EarlyLate::late(), sta),
|
return fuzzyGreaterEqual(delayAsFloat(delay1, EarlyLate::late(), sta),
|
||||||
delayAsFloat(delay2, EarlyLate::late(), sta));
|
delayAsFloat(delay2, EarlyLate::late(), sta));
|
||||||
}
|
}
|
||||||
|
|
||||||
Delay
|
Delay
|
||||||
|
|
@ -138,7 +138,7 @@ DelayOpsNormal::sum(const Delay &delay1,
|
||||||
const Delay &delay2) const
|
const Delay &delay2) const
|
||||||
{
|
{
|
||||||
return Delay(delay1.mean() + delay2.mean(),
|
return Delay(delay1.mean() + delay2.mean(),
|
||||||
delay1.stdDev2() + delay2.stdDev2());
|
delay1.stdDev2() + delay2.stdDev2());
|
||||||
}
|
}
|
||||||
|
|
||||||
Delay
|
Delay
|
||||||
|
|
@ -146,7 +146,7 @@ DelayOpsNormal::sum(const Delay &delay1,
|
||||||
float delay2) const
|
float delay2) const
|
||||||
{
|
{
|
||||||
return Delay(delay1.mean() + delay2,
|
return Delay(delay1.mean() + delay2,
|
||||||
delay1.stdDev2());
|
delay1.stdDev2());
|
||||||
}
|
}
|
||||||
|
|
||||||
Delay
|
Delay
|
||||||
|
|
|
||||||
|
|
@ -142,8 +142,10 @@ LumpedCapDelayCalc::gateDelay(const Pin *drvr_pin,
|
||||||
float gate_delay, drvr_slew;
|
float gate_delay, drvr_slew;
|
||||||
float in_slew1 = delayAsFloat(in_slew);
|
float in_slew1 = delayAsFloat(in_slew);
|
||||||
// NaNs cause seg faults during table lookup.
|
// NaNs cause seg faults during table lookup.
|
||||||
if (std::isnan(load_cap) || std::isnan(in_slew.mean()))
|
if (std::isnan(load_cap))
|
||||||
report_->error(1350, "gate delay input variable is NaN");
|
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);
|
const Pvt *pvt = pinPvt(drvr_pin, scene, min_max);
|
||||||
model->gateDelay(pvt, in_slew1, load_cap, gate_delay, drvr_slew);
|
model->gateDelay(pvt, in_slew1, load_cap, gate_delay, drvr_slew);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ public:
|
||||||
// Return values.
|
// Return values.
|
||||||
float &slew,
|
float &slew,
|
||||||
bool &exists) const;
|
bool &exists) const;
|
||||||
ClockUncertainties *uncertainties() const { return uncertainties_; }
|
const ClockUncertainties &uncertainties() const { return uncertainties_; }
|
||||||
void uncertainty(const SetupHold *setup_hold,
|
void uncertainty(const SetupHold *setup_hold,
|
||||||
// Return values.
|
// Return values.
|
||||||
float &uncertainty,
|
float &uncertainty,
|
||||||
|
|
@ -180,7 +180,7 @@ protected:
|
||||||
bool is_propagated_{false};
|
bool is_propagated_{false};
|
||||||
RiseFallMinMax slews_;
|
RiseFallMinMax slews_;
|
||||||
RiseFallMinMax slew_limits_[path_clk_or_data_count];
|
RiseFallMinMax slew_limits_[path_clk_or_data_count];
|
||||||
ClockUncertainties *uncertainties_{nullptr};
|
ClockUncertainties uncertainties_;
|
||||||
bool is_generated_{false};
|
bool is_generated_{false};
|
||||||
// Generated clock variables.
|
// Generated clock variables.
|
||||||
Pin *src_pin_{nullptr};
|
Pin *src_pin_{nullptr};
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,11 @@ public:
|
||||||
static int cmp(const MinMaxValues *values1,
|
static int cmp(const MinMaxValues *values1,
|
||||||
const MinMaxValues *values2)
|
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()]
|
if (!values1->exists_[MinMax::minIndex()]
|
||||||
&& values2->exists_[MinMax::minIndex()])
|
&& values2->exists_[MinMax::minIndex()])
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -99,25 +99,25 @@ public:
|
||||||
// return PropertyValue("bar");
|
// return PropertyValue("bar");
|
||||||
// });
|
// });
|
||||||
void defineProperty(std::string_view property,
|
void defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Library *>::PropertyHandler &handler);
|
const PropertyRegistry<const Library *>::PropertyHandler &handler);
|
||||||
void defineProperty(std::string_view property,
|
void defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const LibertyLibrary *>::PropertyHandler &handler);
|
const PropertyRegistry<const LibertyLibrary *>::PropertyHandler &handler);
|
||||||
void defineProperty(std::string_view property,
|
void defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Cell *>::PropertyHandler &handler);
|
const PropertyRegistry<const Cell *>::PropertyHandler &handler);
|
||||||
void defineProperty(std::string_view property,
|
void defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const LibertyCell *>::PropertyHandler &handler);
|
const PropertyRegistry<const LibertyCell *>::PropertyHandler &handler);
|
||||||
void defineProperty(std::string_view property,
|
void defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Port *>::PropertyHandler &handler);
|
const PropertyRegistry<const Port *>::PropertyHandler &handler);
|
||||||
void defineProperty(std::string_view property,
|
void defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const LibertyPort *>::PropertyHandler &handler);
|
const PropertyRegistry<const LibertyPort *>::PropertyHandler &handler);
|
||||||
void defineProperty(std::string_view property,
|
void defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Instance *>::PropertyHandler &handler);
|
const PropertyRegistry<const Instance *>::PropertyHandler &handler);
|
||||||
void defineProperty(std::string_view property,
|
void defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Pin *>::PropertyHandler &handler);
|
const PropertyRegistry<const Pin *>::PropertyHandler &handler);
|
||||||
void defineProperty(std::string_view property,
|
void defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Net *>::PropertyHandler &handler);
|
const PropertyRegistry<const Net *>::PropertyHandler &handler);
|
||||||
void defineProperty(std::string_view property,
|
void defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Clock *>::PropertyHandler &handler);
|
const PropertyRegistry<const Clock *>::PropertyHandler &handler);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PropertyValue portSlew(const Port *port,
|
PropertyValue portSlew(const Port *port,
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ protected:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
size_t index_;
|
size_t index_;
|
||||||
Mode *mode_;
|
Mode *mode_;
|
||||||
LibertySeq liberty_[MinMax::index_count];
|
std::array<LibertySeq, MinMax::index_count> liberty_;
|
||||||
std::array<Parasitics*, MinMax::index_count> parasitics_;
|
std::array<Parasitics*, MinMax::index_count> parasitics_;
|
||||||
|
|
||||||
friend class Scenes;
|
friend class Scenes;
|
||||||
|
|
|
||||||
|
|
@ -409,6 +409,11 @@ public:
|
||||||
void saveEnumPath(Path *path);
|
void saveEnumPath(Path *path);
|
||||||
bool isSrchRoot(Vertex *vertex,
|
bool isSrchRoot(Vertex *vertex,
|
||||||
const Mode *mode) const;
|
const Mode *mode) const;
|
||||||
|
DelaysWrtClks arrivalsWrtClks(Vertex *vertex,
|
||||||
|
const Scene *scene);
|
||||||
|
DelaysWrtClks delaysWrtClks(Vertex *vertex,
|
||||||
|
const Scene *scene,
|
||||||
|
const PathDelayFunc &get_path_delay);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void initVars();
|
void initVars();
|
||||||
|
|
|
||||||
|
|
@ -24,14 +24,18 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Delay.hh"
|
#include "Delay.hh"
|
||||||
#include "GraphClass.hh"
|
#include "GraphClass.hh"
|
||||||
|
#include "LibertyClass.hh"
|
||||||
#include "MinMaxValues.hh"
|
#include "MinMaxValues.hh"
|
||||||
#include "NetworkClass.hh"
|
#include "NetworkClass.hh"
|
||||||
|
#include "RiseFallMinMaxDelay.hh"
|
||||||
|
#include "SdcClass.hh"
|
||||||
#include "VectorMap.hh"
|
#include "VectorMap.hh"
|
||||||
|
|
||||||
namespace sta {
|
namespace sta {
|
||||||
|
|
@ -111,6 +115,9 @@ using SlackSeq = std::vector<Slack>;
|
||||||
using Crpr = Delay;
|
using Crpr = Delay;
|
||||||
using PathSeq = std::vector<Path*>;
|
using PathSeq = std::vector<Path*>;
|
||||||
using ConstPathSeq = std::vector<const 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,
|
enum class ReportPathFormat { full,
|
||||||
full_clock,
|
full_clock,
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <functional>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -82,8 +82,6 @@ using CheckError = StringSeq;
|
||||||
using CheckErrorSeq = std::vector<CheckError*>;
|
using CheckErrorSeq = std::vector<CheckError*>;
|
||||||
enum class CmdNamespace { sta, sdc };
|
enum class CmdNamespace { sta, sdc };
|
||||||
using ParasiticsNameMap = std::map<std::string, Parasitics*, std::less<>>;
|
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*>;
|
using GraphLoopSeq = std::vector<GraphLoop*>;
|
||||||
|
|
||||||
// Initialize sta functions that are not part of the Sta class.
|
// Initialize sta functions that are not part of the Sta class.
|
||||||
|
|
@ -1531,16 +1529,10 @@ protected:
|
||||||
int digits,
|
int digits,
|
||||||
bool find_required,
|
bool find_required,
|
||||||
const PathDelayFunc &get_path_delay);
|
const PathDelayFunc &get_path_delay);
|
||||||
void reportDelaysWrtClks(Vertex *vertex,
|
void reportDelaysWrtClks(const ClockEdge *clk_edge,
|
||||||
const ClockEdge *clk_edge,
|
|
||||||
const Scene *scene,
|
|
||||||
bool report_variance,
|
bool report_variance,
|
||||||
int digits,
|
int digits,
|
||||||
const PathDelayFunc &get_path_delay);
|
DelaysWrtClks &clk_delays);
|
||||||
RiseFallMinMaxDelay findDelaysWrtClks(Vertex *vertex,
|
|
||||||
const ClockEdge *clk_edge,
|
|
||||||
const Scene *scene,
|
|
||||||
const PathDelayFunc &get_path_delay);
|
|
||||||
std::string formatDelay(const RiseFall *rf,
|
std::string formatDelay(const RiseFall *rf,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
const RiseFallMinMaxDelay &delays,
|
const RiseFallMinMaxDelay &delays,
|
||||||
|
|
@ -1616,6 +1608,7 @@ protected:
|
||||||
Mode *mode,
|
Mode *mode,
|
||||||
Parasitics *parasitics);
|
Parasitics *parasitics);
|
||||||
void deleteScenes();
|
void deleteScenes();
|
||||||
|
void checkLibrarayPocv();
|
||||||
|
|
||||||
Scene *cmd_scene_{nullptr};
|
Scene *cmd_scene_{nullptr};
|
||||||
CmdNamespace cmd_namespace_{CmdNamespace::sdc};
|
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
|
// Map a cell linked in the network to the corresponding liberty cell
|
||||||
// to use for delay calculation at a scene.
|
// to use for delay calculation at a scene.
|
||||||
void
|
void
|
||||||
LibertyLibrary::makeSceneMap(LibertyCell *cell1,
|
LibertyLibrary::makeSceneMap(LibertyCell *link_cell,
|
||||||
LibertyCell *cell2,
|
LibertyCell *scene_cell,
|
||||||
Scene *scene,
|
Scene *scene,
|
||||||
const MinMaxAll *min_max,
|
const MinMaxAll *min_max,
|
||||||
Report *report)
|
Report *report)
|
||||||
{
|
{
|
||||||
for (const MinMax *mm : min_max->range()) {
|
for (const MinMax *mm : min_max->range()) {
|
||||||
size_t lib_ap_index = scene->libertyIndex(mm);
|
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()) {
|
while (port_iter1.hasNext()) {
|
||||||
LibertyPort *port1 = port_iter1.next();
|
LibertyPort *port1 = port_iter1.next();
|
||||||
LibertyPort *port2 = cell2->findLibertyPort(port1->name());
|
LibertyPort *port2 = scene_cell->findLibertyPort(port1->name());
|
||||||
if (port2) {
|
if (port2) {
|
||||||
for (const MinMax *mm : min_max->range()) {
|
for (const MinMax *mm : min_max->range()) {
|
||||||
size_t lib_ap_index = scene->libertyIndex(mm);
|
size_t lib_ap_index = scene->libertyIndex(mm);
|
||||||
|
|
@ -747,15 +747,15 @@ LibertyLibrary::makeSceneMap(LibertyCell *cell1,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
report->warn(1110, "cell {}/{} port {} not found in cell {}/{}.",
|
report->warn(1110, "cell {}/{} port {} not found in cell {}/{}.",
|
||||||
cell1->library()->name(),
|
link_cell->library()->name(),
|
||||||
cell1->name(),
|
link_cell->name(),
|
||||||
port1->name(),
|
port1->name(),
|
||||||
cell2->library()->name(),
|
scene_cell->library()->name(),
|
||||||
cell2->name());
|
scene_cell->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TimingArcSet *arc_set1 : cell1->timing_arc_sets_) {
|
for (TimingArcSet *arc_set1 : link_cell->timing_arc_sets_) {
|
||||||
TimingArcSet *arc_set2 = cell2->findTimingArcSet(arc_set1);
|
TimingArcSet *arc_set2 = scene_cell->findTimingArcSet(arc_set1);
|
||||||
if (arc_set2) {
|
if (arc_set2) {
|
||||||
const TimingArcSeq &arcs1 = arc_set1->arcs();
|
const TimingArcSeq &arcs1 = arc_set1->arcs();
|
||||||
const TimingArcSeq &arcs2 = arc_set2->arcs();
|
const TimingArcSeq &arcs2 = arc_set2->arcs();
|
||||||
|
|
@ -775,13 +775,13 @@ LibertyLibrary::makeSceneMap(LibertyCell *cell1,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
report->warn(1111, "cell {}/{} {} -> {} timing group {} not found in cell {}/{}.",
|
report->warn(1111, "cell {}/{} {} -> {} timing group {} not found in cell {}/{}.",
|
||||||
cell1->library()->name(),
|
link_cell->library()->name(),
|
||||||
cell1->name(),
|
link_cell->name(),
|
||||||
arc_set1->from() ? arc_set1->from()->name() : "",
|
arc_set1->from() ? arc_set1->from()->name() : "",
|
||||||
arc_set1->to()->name(),
|
arc_set1->to()->name(),
|
||||||
arc_set1->role()->to_string(),
|
arc_set1->role()->to_string(),
|
||||||
cell2->library()->name(),
|
scene_cell->library()->name(),
|
||||||
cell2->name());
|
scene_cell->name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,16 +134,16 @@ Network::readLibertyAfter(LibertyLibrary *)
|
||||||
LibertyCell *
|
LibertyCell *
|
||||||
Network::findLibertyCell(std::string_view name) const
|
Network::findLibertyCell(std::string_view name) const
|
||||||
{
|
{
|
||||||
LibertyLibraryIterator *iter = libertyLibraryIterator();
|
LibertyLibraryIterator *lib_iter = libertyLibraryIterator();
|
||||||
while (iter->hasNext()) {
|
while (lib_iter->hasNext()) {
|
||||||
LibertyLibrary *lib = iter->next();
|
LibertyLibrary *lib = lib_iter->next();
|
||||||
LibertyCell *cell = lib->findLibertyCell(name);
|
LibertyCell *cell = lib->findLibertyCell(name);
|
||||||
if (cell) {
|
if (cell) {
|
||||||
delete iter;
|
delete lib_iter;
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete iter;
|
delete lib_iter;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,11 +73,11 @@ FLOAT {DECIMAL}|{FRACTION}|{EXP}
|
||||||
HCHAR "."|"/"|"|"|":"
|
HCHAR "."|"/"|"|"|":"
|
||||||
PREFIX_BUS_DELIM "["|"{"|"("|"<"
|
PREFIX_BUS_DELIM "["|"{"|"("|"<"
|
||||||
SUFFIX_BUS_DELIM "]"|"}"|")"|">"
|
SUFFIX_BUS_DELIM "]"|"}"|")"|">"
|
||||||
SPECIAL_CHAR "!"|"#"|"$"|"%"|"&"|"`"|"("|")"|"*"|"+"|","|"-"|"."|"/"|":"|";"|"<"|"="|">"|"?"|"@"|"["|"\\"|"]"|"^"|"'"|"{"|"|"|"}"|"~"
|
SPECIAL_CHAR "#"|"$"|"%"|"&"|"`"|"("|")"|"*"|"+"|","|"-"|"."|"/"|":"|";"|"<"|"="|">"|"?"|"@"|"["|"\\"|"]"|"^"|"'"|"{"|"|"|"}"|"~"
|
||||||
ESCAPED_CHAR_SET {SPECIAL_CHAR}|\"
|
ESCAPED_CHAR_SET {SPECIAL_CHAR}|\"
|
||||||
ESCAPED_CHAR \\{ESCAPED_CHAR_SET}
|
ESCAPED_CHAR \\{ESCAPED_CHAR_SET}
|
||||||
IDENT_ACHAR {ESCAPED_CHAR}|{ALPHA}|"_"
|
IDENT_ACHAR {ESCAPED_CHAR}|{ALPHA}|"_"
|
||||||
IDENT_CHAR {IDENT_ACHAR}|{DIGIT}
|
IDENT_CHAR {IDENT_ACHAR}|{DIGIT}|"!"
|
||||||
ID {IDENT_ACHAR}{IDENT_CHAR}*
|
ID {IDENT_ACHAR}{IDENT_CHAR}*
|
||||||
BUS_SUB {DIGIT}|{ALPHA}|"_"
|
BUS_SUB {DIGIT}|{ALPHA}|"_"
|
||||||
BIT_IDENT {ID}({PREFIX_BUS_DELIM}{BUS_SUB}+{SUFFIX_BUS_DELIM})+
|
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,
|
float &uncertainty,
|
||||||
bool &exists) const
|
bool &exists) const
|
||||||
{
|
{
|
||||||
if (uncertainties_)
|
uncertainties_.value(setup_hold, uncertainty, exists);
|
||||||
uncertainties_->value(setup_hold, uncertainty, exists);
|
|
||||||
else {
|
|
||||||
uncertainty = 0.0F;
|
|
||||||
exists = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Clock::setUncertainty(const SetupHoldAll *setup_hold,
|
Clock::setUncertainty(const SetupHoldAll *setup_hold,
|
||||||
float uncertainty)
|
float uncertainty)
|
||||||
{
|
{
|
||||||
if (uncertainties_ == nullptr)
|
uncertainties_.setValue(setup_hold, uncertainty);
|
||||||
uncertainties_ = new ClockUncertainties;
|
|
||||||
uncertainties_->setValue(setup_hold, uncertainty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Clock::setUncertainty(const SetupHold *setup_hold,
|
Clock::setUncertainty(const SetupHold *setup_hold,
|
||||||
float uncertainty)
|
float uncertainty)
|
||||||
{
|
{
|
||||||
if (uncertainties_ == nullptr)
|
uncertainties_.setValue(setup_hold, uncertainty);
|
||||||
uncertainties_ = new ClockUncertainties;
|
|
||||||
uncertainties_->setValue(setup_hold, uncertainty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Clock::removeUncertainty(const SetupHoldAll *setup_hold)
|
Clock::removeUncertainty(const SetupHoldAll *setup_hold)
|
||||||
{
|
{
|
||||||
if (uncertainties_) {
|
uncertainties_.removeValue(setup_hold);
|
||||||
uncertainties_->removeValue(setup_hold);
|
|
||||||
if (uncertainties_->empty()) {
|
|
||||||
delete uncertainties_;
|
|
||||||
uncertainties_ = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ MakeTimingModel::checkClock(Clock *clk)
|
||||||
{
|
{
|
||||||
for (const Pin *pin : clk->leafPins()) {
|
for (const Pin *pin : clk->leafPins()) {
|
||||||
if (!network_->isTopLevelPort(pin))
|
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));
|
network_->pathName(pin));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -379,7 +379,7 @@ PathEnd::checkTgtClkUncertainty(const Path *tgt_clk_path,
|
||||||
if (tgt_clk_path && tgt_clk_path->isClock(sta))
|
if (tgt_clk_path && tgt_clk_path->isClock(sta))
|
||||||
uncertainties = tgt_clk_path->clkInfo(sta)->uncertainties();
|
uncertainties = tgt_clk_path->clkInfo(sta)->uncertainties();
|
||||||
else if (tgt_clk_edge)
|
else if (tgt_clk_edge)
|
||||||
uncertainties = tgt_clk_edge->clock()->uncertainties();
|
uncertainties = &tgt_clk_edge->clock()->uncertainties();
|
||||||
float uncertainty = 0.0;
|
float uncertainty = 0.0;
|
||||||
if (uncertainties) {
|
if (uncertainties) {
|
||||||
bool exists;
|
bool exists;
|
||||||
|
|
|
||||||
|
|
@ -1265,70 +1265,70 @@ Properties::capacitancePropertyValue(float cap)
|
||||||
|
|
||||||
void
|
void
|
||||||
Properties::defineProperty(std::string_view property,
|
Properties::defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Library *>::PropertyHandler &handler)
|
const PropertyRegistry<const Library *>::PropertyHandler &handler)
|
||||||
{
|
{
|
||||||
registry_library_.defineProperty(property, handler);
|
registry_library_.defineProperty(property, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Properties::defineProperty(std::string_view property,
|
Properties::defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const LibertyLibrary *>::PropertyHandler &handler)
|
const PropertyRegistry<const LibertyLibrary *>::PropertyHandler &handler)
|
||||||
{
|
{
|
||||||
registry_liberty_library_.defineProperty(property, handler);
|
registry_liberty_library_.defineProperty(property, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Properties::defineProperty(std::string_view property,
|
Properties::defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Cell *>::PropertyHandler &handler)
|
const PropertyRegistry<const Cell *>::PropertyHandler &handler)
|
||||||
{
|
{
|
||||||
registry_cell_.defineProperty(property, handler);
|
registry_cell_.defineProperty(property, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Properties::defineProperty(std::string_view property,
|
Properties::defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const LibertyCell *>::PropertyHandler &handler)
|
const PropertyRegistry<const LibertyCell *>::PropertyHandler &handler)
|
||||||
{
|
{
|
||||||
registry_liberty_cell_.defineProperty(property, handler);
|
registry_liberty_cell_.defineProperty(property, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Properties::defineProperty(std::string_view property,
|
Properties::defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Port *>::PropertyHandler &handler)
|
const PropertyRegistry<const Port *>::PropertyHandler &handler)
|
||||||
{
|
{
|
||||||
registry_port_.defineProperty(property, handler);
|
registry_port_.defineProperty(property, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Properties::defineProperty(std::string_view property,
|
Properties::defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const LibertyPort *>::PropertyHandler &handler)
|
const PropertyRegistry<const LibertyPort *>::PropertyHandler &handler)
|
||||||
{
|
{
|
||||||
registry_liberty_port_.defineProperty(property, handler);
|
registry_liberty_port_.defineProperty(property, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Properties::defineProperty(std::string_view property,
|
Properties::defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Instance *>::PropertyHandler &handler)
|
const PropertyRegistry<const Instance *>::PropertyHandler &handler)
|
||||||
{
|
{
|
||||||
registry_instance_.defineProperty(property, handler);
|
registry_instance_.defineProperty(property, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Properties::defineProperty(std::string_view property,
|
Properties::defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Pin *>::PropertyHandler &handler)
|
const PropertyRegistry<const Pin *>::PropertyHandler &handler)
|
||||||
{
|
{
|
||||||
registry_pin_.defineProperty(property, handler);
|
registry_pin_.defineProperty(property, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Properties::defineProperty(std::string_view property,
|
Properties::defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Net *>::PropertyHandler &handler)
|
const PropertyRegistry<const Net *>::PropertyHandler &handler)
|
||||||
{
|
{
|
||||||
registry_net_.defineProperty(property, handler);
|
registry_net_.defineProperty(property, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Properties::defineProperty(std::string_view property,
|
Properties::defineProperty(std::string_view property,
|
||||||
PropertyRegistry<const Clock *>::PropertyHandler &handler)
|
const PropertyRegistry<const Clock *>::PropertyHandler &handler)
|
||||||
{
|
{
|
||||||
registry_clock_.defineProperty(property, handler);
|
registry_clock_.defineProperty(property, handler);
|
||||||
}
|
}
|
||||||
|
|
@ -1355,7 +1355,7 @@ void
|
||||||
PropertyRegistry<TYPE>::defineProperty(std::string_view property,
|
PropertyRegistry<TYPE>::defineProperty(std::string_view property,
|
||||||
PropertyHandler handler)
|
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
|
} // namespace sta
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@
|
||||||
#include "PortDelay.hh"
|
#include "PortDelay.hh"
|
||||||
#include "PortDirection.hh"
|
#include "PortDirection.hh"
|
||||||
#include "Report.hh"
|
#include "Report.hh"
|
||||||
|
#include "RiseFallMinMaxDelay.hh"
|
||||||
#include "Scene.hh"
|
#include "Scene.hh"
|
||||||
#include "Sdc.hh"
|
#include "Sdc.hh"
|
||||||
#include "SdcClass.hh"
|
#include "SdcClass.hh"
|
||||||
|
|
@ -1546,7 +1547,7 @@ Search::seedClkArrival(const Pin *pin,
|
||||||
|
|
||||||
const ClockUncertainties *uncertainties = sdc->clockUncertainties(pin);
|
const ClockUncertainties *uncertainties = sdc->clockUncertainties(pin);
|
||||||
if (uncertainties == nullptr)
|
if (uncertainties == nullptr)
|
||||||
uncertainties = clk->uncertainties();
|
uncertainties = &clk->uncertainties();
|
||||||
// Propagate liberty "pulse_clock" transition to transitive fanout.
|
// Propagate liberty "pulse_clock" transition to transitive fanout.
|
||||||
LibertyPort *port = network_->libertyPort(pin);
|
LibertyPort *port = network_->libertyPort(pin);
|
||||||
const RiseFall *pulse_clk_sense = (port ? port->pulseClkSense() : nullptr);
|
const RiseFall *pulse_clk_sense = (port ? port->pulseClkSense() : nullptr);
|
||||||
|
|
@ -1913,13 +1914,13 @@ Search::inputDelayTag(const Pin *pin,
|
||||||
const Pin *clk_pin = nullptr;
|
const Pin *clk_pin = nullptr;
|
||||||
const RiseFall *clk_rf = nullptr;
|
const RiseFall *clk_rf = nullptr;
|
||||||
bool is_propagated = false;
|
bool is_propagated = false;
|
||||||
ClockUncertainties *clk_uncertainties = nullptr;
|
const ClockUncertainties *clk_uncertainties = nullptr;
|
||||||
if (clk_edge) {
|
if (clk_edge) {
|
||||||
clk = clk_edge->clock();
|
clk = clk_edge->clock();
|
||||||
clk_rf = clk_edge->transition();
|
clk_rf = clk_edge->transition();
|
||||||
clk_pin = clk->defaultPin();
|
clk_pin = clk->defaultPin();
|
||||||
is_propagated = clk->isPropagated();
|
is_propagated = clk->isPropagated();
|
||||||
clk_uncertainties = clk->uncertainties();
|
clk_uncertainties = &clk->uncertainties();
|
||||||
}
|
}
|
||||||
|
|
||||||
Sdc *sdc = scene->sdc();
|
Sdc *sdc = scene->sdc();
|
||||||
|
|
@ -3997,4 +3998,37 @@ Search::wnsSlack(Vertex *vertex,
|
||||||
return slacks[path_ap_index];
|
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
|
} // namespace sta
|
||||||
|
|
|
||||||
|
|
@ -237,7 +237,7 @@ endpoint_slack(const Pin *pin,
|
||||||
sta->ensureLibLinked();
|
sta->ensureLibLinked();
|
||||||
if (!path_group_name.empty()
|
if (!path_group_name.empty()
|
||||||
&& !sta->isPathGroupName(path_group_name, sta->cmdSdc())) {
|
&& !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);
|
path_group_name);
|
||||||
return INF;
|
return INF;
|
||||||
}
|
}
|
||||||
|
|
@ -438,7 +438,7 @@ set_report_path_field_properties(const char *field_name,
|
||||||
if (field)
|
if (field)
|
||||||
field->setProperties(title, width, left_justify);
|
field->setProperties(title, width, left_justify);
|
||||||
else
|
else
|
||||||
sta->report()->warn(1575, "unknown report path field {}", field_name);
|
sta->report()->warn(1591, "unknown report path field {}", field_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -963,7 +963,7 @@ set_crpr_mode(std::string mode)
|
||||||
else if (stringEqual(mode, "same_transition"))
|
else if (stringEqual(mode, "same_transition"))
|
||||||
sta->setCrprMode(CrprMode::same_transition);
|
sta->setCrprMode(CrprMode::same_transition);
|
||||||
else
|
else
|
||||||
sta->report()->error(1573, "unknown common clk pessimism mode.");
|
sta->report()->error(1592, "unknown common clk pessimism mode.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &
|
const std::string &
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "ArcDelayCalc.hh"
|
#include "ArcDelayCalc.hh"
|
||||||
|
|
@ -2281,9 +2282,11 @@ Sta::setPocvMode(PocvMode mode)
|
||||||
delay_ops_ = new DelayOpsScalar();
|
delay_ops_ = new DelayOpsScalar();
|
||||||
break;
|
break;
|
||||||
case PocvMode::normal:
|
case PocvMode::normal:
|
||||||
|
checkLibrarayPocv();
|
||||||
delay_ops_ = new DelayOpsNormal();
|
delay_ops_ = new DelayOpsNormal();
|
||||||
break;
|
break;
|
||||||
case PocvMode::skew_normal:
|
case PocvMode::skew_normal:
|
||||||
|
checkLibrarayPocv();
|
||||||
delay_ops_ = new DelayOpsSkewNormal();
|
delay_ops_ = new DelayOpsSkewNormal();
|
||||||
break;
|
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
|
float
|
||||||
Sta::pocvQuantile()
|
Sta::pocvQuantile()
|
||||||
{
|
{
|
||||||
|
|
@ -3353,29 +3383,25 @@ Sta::reportDelaysWrtClks(Vertex *vertex,
|
||||||
else
|
else
|
||||||
search_->findArrivals(vertex->level());
|
search_->findArrivals(vertex->level());
|
||||||
const Sdc *sdc = scene->sdc();
|
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());
|
const ClockEdge *default_clk_edge = sdc->defaultArrivalClock()->edge(RiseFall::rise());
|
||||||
reportDelaysWrtClks(vertex, default_clk_edge, scene, report_variance,
|
reportDelaysWrtClks(default_clk_edge, report_variance, digits, clk_delays);
|
||||||
digits, get_path_delay);
|
|
||||||
for (const Clock *clk : sdc->sortedClocks()) {
|
for (const Clock *clk : sdc->sortedClocks()) {
|
||||||
for (const RiseFall *rf : RiseFall::range()) {
|
for (const RiseFall *rf : RiseFall::range()) {
|
||||||
const ClockEdge *clk_edge = clk->edge(rf);
|
const ClockEdge *clk_edge = clk->edge(rf);
|
||||||
reportDelaysWrtClks(vertex, clk_edge, scene, report_variance, digits,
|
reportDelaysWrtClks(clk_edge, report_variance, digits, clk_delays);
|
||||||
get_path_delay);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sta::reportDelaysWrtClks(Vertex *vertex,
|
Sta::reportDelaysWrtClks(const ClockEdge *clk_edge,
|
||||||
const ClockEdge *clk_edge,
|
|
||||||
const Scene *scene,
|
|
||||||
bool report_variance,
|
bool report_variance,
|
||||||
int digits,
|
int digits,
|
||||||
const PathDelayFunc &get_path_delay)
|
DelaysWrtClks &clk_delays)
|
||||||
{
|
{
|
||||||
RiseFallMinMaxDelay delays =
|
const RiseFallMinMaxDelay &delays = clk_delays[clk_edge];
|
||||||
findDelaysWrtClks(vertex, clk_edge, scene, get_path_delay);
|
|
||||||
if (!delays.empty()) {
|
if (!delays.empty()) {
|
||||||
std::string clk_name;
|
std::string clk_name;
|
||||||
if (clk_edge)
|
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
|
std::string
|
||||||
Sta::formatDelay(const RiseFall *rf,
|
Sta::formatDelay(const RiseFall *rf,
|
||||||
const MinMax *min_max,
|
const MinMax *min_max,
|
||||||
|
|
|
||||||
|
|
@ -311,7 +311,7 @@ TagGroupBldr::copyPaths(TagGroup *tag_group,
|
||||||
if (exists2)
|
if (exists2)
|
||||||
paths[path_index2] = paths_[path_index1];
|
paths[path_index2] = paths_[path_index1];
|
||||||
else
|
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
|
void
|
||||||
WritePathSpice::writeSpice()
|
WritePathSpice::writeSpice()
|
||||||
{
|
{
|
||||||
spice_stream_.open(std::string(spice_filename_));
|
spice_stream_.open(spice_filename_);
|
||||||
if (spice_stream_.is_open()) {
|
if (spice_stream_.is_open()) {
|
||||||
path_expanded_.expand(path_, true);
|
path_expanded_.expand(path_, true);
|
||||||
// Find subckt port names as a side-effect of writeSubckts.
|
// Find subckt port names as a side-effect of writeSubckts.
|
||||||
|
|
|
||||||
|
|
@ -165,12 +165,12 @@ protected:
|
||||||
std::string replaceFileExt(std::string_view filename,
|
std::string replaceFileExt(std::string_view filename,
|
||||||
std::string_view ext);
|
std::string_view ext);
|
||||||
|
|
||||||
const std::string_view spice_filename_;
|
const std::string spice_filename_;
|
||||||
const std::string_view subckt_filename_;
|
const std::string subckt_filename_;
|
||||||
const std::string_view lib_subckt_filename_;
|
const std::string lib_subckt_filename_;
|
||||||
const std::string_view model_filename_;
|
const std::string model_filename_;
|
||||||
const std::string_view power_name_;
|
const std::string power_name_;
|
||||||
const std::string_view gnd_name_;
|
const std::string gnd_name_;
|
||||||
CircuitSim ckt_sim_;
|
CircuitSim ckt_sim_;
|
||||||
const Scene *scene_;
|
const Scene *scene_;
|
||||||
const MinMax *min_max_;
|
const MinMax *min_max_;
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,9 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <cerrno>
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
|
#include <cstdlib>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <version>
|
#include <version>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1490,12 +1490,12 @@ VerilogReader::linkNetwork(std::string_view top_cell_name,
|
||||||
return top_instance;
|
return top_instance;
|
||||||
}
|
}
|
||||||
else {
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue