Latest pulled in changes on 4/20 from upstream to push all together with latest from 4/16

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
This commit is contained in:
dsengupta0628 2026-04-20 14:21:16 +00:00
commit 05b4e3a1d9
39 changed files with 258 additions and 306 deletions

View File

@ -23,6 +23,7 @@
# searching OSX system directories before unix directories.
set(TCL_POSSIBLE_NAMES
#tcl90 tcl9.0
tcl87 tcl8.7
tcl86 tcl8.6
tcl85 tcl8.5
@ -32,6 +33,7 @@ set(TCL_POSSIBLE_NAMES
if (NOT TCL_LIB_PATHS)
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(TCL_LIB_PATHS
#/opt/homebrew/Cellar/tcl-tk/9.0.3/lib
/opt/homebrew/Cellar/tcl-tk@8/8.6.17/lib
/opt/homebrew/Cellar/tcl-tk@8/8.6.16/lib
/opt/homebrew/opt/tcl-tk/lib /usr/local/lib)

View File

@ -22,8 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module dcalc
%include <std_string.i>
%{

View File

@ -989,8 +989,8 @@ PrimaDelayCalc::reportGateDelay(const Pin *drvr_pin,
bool arg_fail = checkArgs(dcalc_args, scene, min_max);
if (arg_fail) {
const RiseFall *rf = arc->toEdge()->asRiseFall();
const Parasitic *reduced =
table_dcalc_->findParasitic(drvr_pin, rf, scene, min_max);
const Parasitic *reduced = table_dcalc_->findParasitic(drvr_pin, rf,
scene, min_max);
return table_dcalc_->reportGateDelay(drvr_pin, arc, in_slew, load_cap,
reduced, load_pin_index_map, scene,
min_max, digits);

View File

@ -22,8 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module graph
%{
#include "Clock.hh"
#include "FuncExpr.hh"

View File

@ -57,8 +57,7 @@ public:
const Pin *defaultPin() const;
bool addToPins() const { return add_to_pins_; }
void setAddToPins(bool add_to_pins);
FloatSeq *waveform() { return waveform_; }
const FloatSeq *waveform() const { return waveform_; }
const FloatSeq &waveform() const { return waveform_; }
ClockEdge *edge(const RiseFall *rf) const;
int index() const { return index_; }
bool isPropagated() const { return is_propagated_; }
@ -120,8 +119,8 @@ public:
int multiplyBy() const { return multiply_by_; }
float dutyCycle() const { return duty_cycle_; }
bool invert() const { return invert_; }
IntSeq *edges() const { return edges_; }
FloatSeq *edgeShifts() const { return edge_shifts_; }
const IntSeq &edges() const { return edges_; }
const FloatSeq &edgeShifts() const { return edge_shifts_; }
const RiseFall *masterClkEdgeTr(const RiseFall *rf) const;
bool combinational() const { return combinational_; }
bool isDivideByOneCombinational() const;
@ -138,13 +137,13 @@ protected:
Clock(std::string_view name,
int index,
const Network *network);
void initClk(PinSet *pins,
void initClk(const PinSet &pins,
bool add_to_pins,
float period,
FloatSeq *waveform,
const FloatSeq &waveform,
std::string_view comment,
const Network *network);
void initGeneratedClk(PinSet *pins,
void initGeneratedClk(const PinSet &pins,
bool add_to_pins,
Pin *src_pin,
Clock *master_clk,
@ -153,12 +152,12 @@ protected:
float duty_cycle,
bool invert,
bool combinational,
IntSeq *edges,
FloatSeq *edge_shifts,
const IntSeq &edges,
const FloatSeq &edge_shifts,
bool is_propagated,
std::string_view comment,
const Network *network);
void setPins(PinSet *pins,
void setPins(const PinSet &pins,
const Network *network);
void setMasterClk(Clock *master);
void makeClkEdges();
@ -174,10 +173,10 @@ protected:
// Hierarchical pins in pins_ become driver pins through the pin.
PinSet leaf_pins_;
float period_{0.0};
FloatSeq *waveform_{nullptr};
FloatSeq waveform_;
bool waveform_valid_{false};
const int index_;
ClockEdge **clk_edges_{nullptr};
std::array<ClockEdge*, RiseFall::index_count> clk_edges_;
bool is_propagated_{false};
RiseFallMinMax slews_;
RiseFallMinMax slew_limits_[path_clk_or_data_count];
@ -193,8 +192,8 @@ protected:
float duty_cycle_{0};
bool invert_{false};
bool combinational_{false};
IntSeq *edges_{nullptr};
FloatSeq *edge_shifts_{nullptr};
IntSeq edges_;
FloatSeq edge_shifts_;
private:
friend class Sdc;

View File

@ -374,19 +374,15 @@ public:
static void
makeSceneMap(LibertyLibrary *lib,
size_t lib_ap_index,
Scene *scene,
const MinMaxAll *min_max,
Network *network,
Report *report);
static void
makeSceneMap(LibertyCell *link_cell,
LibertyCell *scene_cell,
size_t lib_ap_index,
Report *report);
static void
makeSceneMap(LibertyCell *cell1,
LibertyCell *cell2,
bool link,
size_t lib_ap_index,
Scene *scene,
const MinMaxAll *min_max,
Report *report);
static void
checkScenes(LibertyCell *cell,

View File

@ -378,14 +378,14 @@ public:
void setMaxArea(float area);
float maxArea() const;
Clock *makeClock(std::string_view name,
PinSet *pins,
const PinSet &pins,
bool add_to_pins,
float period,
FloatSeq *waveform,
const FloatSeq &waveform,
std::string_view comment);
// edges size must be 3.
Clock *makeGeneratedClock(std::string_view name,
PinSet *pins,
const PinSet &pins,
bool add_to_pins,
Pin *src_pin,
Clock *master_clk,
@ -394,8 +394,8 @@ public:
float duty_cycle,
bool invert,
bool combinational,
IntSeq *edges,
FloatSeq *edge_shifts,
const IntSeq &edges,
const FloatSeq &dge_shifts,
std::string_view comment);
// Invalidate all generated clock waveforms.
void invalidateGeneratedClks() const;
@ -1071,7 +1071,7 @@ protected:
void deleteClkPinMappings(Clock *clk);
void makeClkPinMappings(Clock *clk);
void deletePinClocks(Clock *defining_clk,
PinSet *pins);
const PinSet &pins);
void makeDefaultArrivalClock();
InputDrive *ensureInputDrive(const Port *port);
ExceptionPath *findMergeMatch(ExceptionPath *exception);

View File

@ -154,7 +154,7 @@ public:
// tmp public
void readLibertyAfter(LibertyLibrary *liberty,
Scene *scene,
const MinMax *min_max);
const MinMaxAll *min_max);
bool readVerilog(std::string_view filename);
// Network readers call this to notify the Sta to delete any previously
// linked network.
@ -347,15 +347,15 @@ public:
Sdc *sdc);
void makeClock(std::string_view name,
PinSet *pins,
const PinSet &pins,
bool add_to_pins,
float period,
FloatSeq *waveform,
const FloatSeq &waveform,
std::string_view comment,
const Mode *mode);
// edges size must be 3.
void makeGeneratedClock(std::string_view name,
PinSet *pins,
const PinSet &pins,
bool add_to_pins,
Pin *src_pin,
Clock *master_clk,
@ -364,8 +364,8 @@ public:
float duty_cycle,
bool invert,
bool combinational,
IntSeq *edges,
FloatSeq *edge_shifts,
const IntSeq &edges,
const FloatSeq &edge_shifts,
std::string_view comment,
const Mode *mode);
void removeClock(Clock *clk,
@ -1604,6 +1604,9 @@ protected:
void updateSceneLiberty(Scene *scene,
const StringSeq &liberty_min_files,
const StringSeq &liberty_max_files);
void updateSceneLiberty(Scene *scene,
const StringSeq &liberty_files,
const MinMaxAll *min_max);
Scene *makeScene(const std::string &name,
Mode *mode,

View File

@ -146,7 +146,7 @@ class TimingArcSet
public:
~TimingArcSet();
std::string to_string();
std::string to_string() const;
LibertyCell *libertyCell() const;
LibertyPort *from() const { return from_; }
LibertyPort *to() const { return to_; }

View File

@ -707,7 +707,8 @@ LibertyLibrary::makeScaledCell(std::string_view name,
void
LibertyLibrary::makeSceneMap(LibertyLibrary *lib,
size_t lib_ap_index,
Scene *scene,
const MinMaxAll *min_max,
Network *network,
Report *report)
{
@ -716,38 +717,33 @@ LibertyLibrary::makeSceneMap(LibertyLibrary *lib,
LibertyCell *cell = cell_iter.next();
LibertyCell *link_cell = network->findLibertyCell(cell->name());
if (link_cell)
makeSceneMap(link_cell, cell, lib_ap_index, report);
makeSceneMap(link_cell, cell, scene, min_max, report);
}
}
// Map a cell linked in the network to the corresponding liberty cell
// to use for delay calculation at a scene.
void
LibertyLibrary::makeSceneMap(LibertyCell *link_cell,
LibertyCell *scene_cell,
size_t lib_ap_index,
Report *report)
{
link_cell->setSceneCell(scene_cell, lib_ap_index);
makeSceneMap(link_cell, scene_cell, true, lib_ap_index, report);
// Check for brain damage in the other direction.
makeSceneMap(scene_cell, link_cell, false, lib_ap_index, report);
}
void
LibertyLibrary::makeSceneMap(LibertyCell *cell1,
LibertyCell *cell2,
bool link,
size_t lib_ap_index,
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);
}
LibertyCellPortBitIterator port_iter1(cell1);
while (port_iter1.hasNext()) {
LibertyPort *port1 = port_iter1.next();
LibertyPort *port2 = cell2->findLibertyPort(port1->name());
if (port2) {
if (link)
for (const MinMax *mm : min_max->range()) {
size_t lib_ap_index = scene->libertyIndex(mm);
port1->setScenePort(port2, lib_ap_index);
}
}
else
report->warn(1110, "cell {}/{} port {} not found in cell {}/{}.",
@ -761,17 +757,19 @@ LibertyLibrary::makeSceneMap(LibertyCell *cell1,
for (TimingArcSet *arc_set1 : cell1->timing_arc_sets_) {
TimingArcSet *arc_set2 = cell2->findTimingArcSet(arc_set1);
if (arc_set2) {
if (link) {
const TimingArcSeq &arcs1 = arc_set1->arcs();
const TimingArcSeq &arcs2 = arc_set2->arcs();
auto arc_itr1 = arcs1.begin(), arc_itr2 = arcs2.begin();
for (;
arc_itr1 != arcs1.end() && arc_itr2 != arcs2.end();
arc_itr1++, arc_itr2++) {
TimingArc *arc1 = *arc_itr1;
TimingArc *arc2 = *arc_itr2;
if (TimingArc::equiv(arc1, arc2))
const TimingArcSeq &arcs1 = arc_set1->arcs();
const TimingArcSeq &arcs2 = arc_set2->arcs();
auto arc_itr1 = arcs1.begin(), arc_itr2 = arcs2.begin();
for (;
arc_itr1 != arcs1.end() && arc_itr2 != arcs2.end();
arc_itr1++, arc_itr2++) {
TimingArc *arc1 = *arc_itr1;
TimingArc *arc2 = *arc_itr2;
if (TimingArc::equiv(arc1, arc2)) {
for (const MinMax *mm : min_max->range()) {
size_t lib_ap_index = scene->libertyIndex(mm);
arc1->setSceneArc(arc2, lib_ap_index);
}
}
}
}
@ -2382,12 +2380,13 @@ LibertyPort::equiv(const LibertyPort *port1,
&& port1->pwr_gnd_type_ == port2->pwr_gnd_type_);
}
// Note port1 and port2 may be from different cells (timingArcSetLess).
bool
LibertyPort::less(const LibertyPort *port1,
const LibertyPort *port2)
{
if (port1 && port2)
return port1->pinIndex() < port2->pinIndex();
return port1->name() < port2->name();
else
return port1 == nullptr && port2 != nullptr;
}

View File

@ -22,8 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module liberty
%{
#include "PatternMatch.hh"
#include "PortDirection.hh"

View File

@ -212,7 +212,7 @@ TimingArcSet::TimingArcSet(const TimingRole *role,
}
std::string
TimingArcSet::to_string()
TimingArcSet::to_string() const
{
std::string str = from_->name();
str += " -> ";

View File

@ -22,8 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module network
%include <std_string.i>
%{

View File

@ -22,8 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module NetworkEdit
%{
using sta::Cell;
using sta::Instance;

View File

@ -975,7 +975,10 @@ ConcreteParasitics::piModel(const Parasitic *parasitic,
float &c1) const
{
const ConcreteParasitic *cparasitic = static_cast<const ConcreteParasitic*>(parasitic);
cparasitic->piModel(c2, rpi, c1);
if (cparasitic->isPiModel())
cparasitic->piModel(c2, rpi, c1);
else
criticalError(2700, "piModel called on non-PiElmore parasitic.");
}
void
@ -985,7 +988,10 @@ ConcreteParasitics::setPiModel(Parasitic *parasitic,
float c1)
{
ConcreteParasitic *cparasitic = static_cast<ConcreteParasitic*>(parasitic);
cparasitic->setPiModel(c2, rpi, c1);
if (cparasitic->isPiModel())
cparasitic->setPiModel(c2, rpi, c1);
else
criticalError(2701, "setPiModel called on non-PiElmore parasitic.");
}
////////////////////////////////////////////////////////////////

View File

@ -22,8 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module parasitics
%{
#include "Sta.hh"

View File

@ -1584,9 +1584,9 @@ Power::clockDuty(const Clock *clk)
return clockDuty(master);
}
else {
const FloatSeq *waveform = clk->waveform();
float rise_time = (*waveform)[0];
float fall_time = (*waveform)[1];
const FloatSeq &waveform = clk->waveform();
float rise_time = waveform[0];
float fall_time = waveform[1];
float duty = (fall_time - rise_time) / clk->period();
return duty;
}

View File

@ -22,8 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module power
%{
#include "power/Power.hh"

View File

@ -135,7 +135,7 @@ proc set_power_activity { args } {
sta_error 307 "-activity requires a clock to be defined"
}
}
set density [expr $activity / [clock_min_period [sta::cmd_mode]]]
set density [expr $activity / [clock_min_period [cmd_mode_name]]]
}
if { [info exists keys(-density)] } {
@ -165,7 +165,7 @@ proc set_power_activity { args } {
set ports [get_ports_error "input_ports" $keys(-input_ports)]
foreach port $ports {
if { [get_property $port "direction"] == "input" } {
if { [is_clock_src [sta::get_port_pin $port]] } {
if { [is_clock_src [get_port_pin $port]] } {
sta_warn 310 "activity cannot be set on clock ports."
} else {
set_power_input_port_activity $port $density $duty
@ -206,7 +206,7 @@ proc unset_power_activity { args } {
set ports [get_ports_error "input_ports" $keys(-input_ports)]
foreach port $ports {
if { [get_property $port "direction"] == "input" } {
if { [is_clock_src [sta::get_port_pin $port]] } {
if { [is_clock_src [get_port_pin $port]] } {
sta_warn 303 "activity cannot be set on clock ports."
} else {
unset_power_input_port_activity $port
@ -255,7 +255,7 @@ proc read_vcd { args } {
if { [info exists keys(-scope)] } {
set scope $keys(-scope)
}
set mode_name [sta::cmd_mode]
set mode_name [cmd_mode_name]
if { [info exists keys(-mode)] } {
set mode_name $keys(-mode)
}

View File

@ -55,17 +55,16 @@ Clock::Clock(std::string_view name,
}
void
Clock::initClk(PinSet *pins,
Clock::initClk(const PinSet &pins,
bool add_to_pins,
float period,
FloatSeq *waveform,
const FloatSeq &waveform,
std::string_view comment,
const Network *network)
{
is_generated_ = false;
setPins(pins, network);
add_to_pins_ = add_to_pins;
delete waveform_;
waveform_ = waveform;
waveform_valid_ = true;
period_ = period;
@ -80,12 +79,10 @@ Clock::isVirtual() const
}
void
Clock::setPins(PinSet *pins,
Clock::setPins(const PinSet &pins,
const Network *network)
{
if (pins)
pins_ = *pins;
delete pins;
pins_ = pins;
makeLeafPins(network);
}
@ -107,23 +104,15 @@ Clock::setMasterClk(Clock *master)
void
Clock::makeClkEdges()
{
clk_edges_ = new ClockEdge*[RiseFall::index_count];
for (auto rf : RiseFall::range()) {
for (const RiseFall *rf : RiseFall::range()) {
clk_edges_[rf->index()] = new ClockEdge(this, rf);
}
}
Clock::~Clock()
{
if (clk_edges_) {
delete clk_edges_[RiseFall::riseIndex()];
delete clk_edges_[RiseFall::fallIndex()];
delete [] clk_edges_;
}
delete waveform_;
delete edges_;
delete edge_shifts_;
delete uncertainties_;
for (size_t rf_index : RiseFall::rangeIndex())
delete clk_edges_[rf_index];
}
void
@ -155,7 +144,7 @@ Clock::setClkEdgeTimes()
void
Clock::setClkEdgeTime(const RiseFall *rf)
{
float time = (rf == RiseFall::rise()) ? (*waveform_)[0]:(*waveform_)[1];
float time = waveform_[rf->index()];
clk_edges_[rf->index()]->setTime(time);
}
@ -298,7 +287,7 @@ Clock::waveformInvalid()
////////////////////////////////////////////////////////////////
void
Clock::initGeneratedClk(PinSet *pins,
Clock::initGeneratedClk(const PinSet &pins,
bool add_to_pins,
Pin *src_pin,
Clock *master_clk,
@ -307,8 +296,8 @@ Clock::initGeneratedClk(PinSet *pins,
float duty_cycle,
bool invert,
bool combinational,
IntSeq *edges,
FloatSeq *edge_shifts,
const IntSeq &edges,
const FloatSeq &edge_shifts,
bool is_propagated,
std::string_view comment,
const Network *network)
@ -328,20 +317,7 @@ Clock::initGeneratedClk(PinSet *pins,
is_propagated_ = is_propagated;
setComment(comment);
delete edges_;
if (edges
&& edges->empty()) {
delete edges;
edges = nullptr;
}
edges_ = edges;
delete edge_shifts_;
if (edge_shifts
&& edge_shifts->empty()) {
delete edge_shifts;
edge_shifts = nullptr;
}
edge_shifts_ = edge_shifts;
}
@ -371,40 +347,36 @@ Clock::isGeneratedWithPropagatedMaster() const
void
Clock::generate(const Clock *src_clk)
{
if (waveform_ == nullptr)
waveform_ = new FloatSeq;
else
waveform_->clear();
waveform_.clear();
if (divide_by_ == 1.0) {
period_ = src_clk->period();
const FloatSeq *src_wave = src_clk->waveform();
waveform_->push_back((*src_wave)[0]);
waveform_->push_back((*src_wave)[1]);
const FloatSeq &src_wave = src_clk->waveform();
waveform_.push_back(src_wave[0]);
waveform_.push_back(src_wave[1]);
}
else if (divide_by_ > 1) {
if (isPowerOfTwo(divide_by_)) {
period_ = src_clk->period() * divide_by_;
const FloatSeq *src_wave = src_clk->waveform();
float rise = (*src_wave)[0];
waveform_->push_back(rise);
waveform_->push_back(rise + period_ / 2);
const FloatSeq &src_wave = src_clk->waveform();
float rise = src_wave[0];
waveform_.push_back(rise);
waveform_.push_back(rise + period_ / 2);
}
else
generateScaledClk(src_clk, static_cast<float>(divide_by_));
}
else if (multiply_by_ >= 1)
generateScaledClk(src_clk, 1.0F / multiply_by_);
else if (edges_)
else if (!edges_.empty())
generateEdgesClk(src_clk);
if (invert_) {
float first_time = (*waveform_)[0];
float first_time = waveform_[0];
float offset = (first_time >= period_) ? period_ : 0.0F;
size_t edge_count = waveform_->size();
size_t edge_count = waveform_.size();
for (size_t i = 0; i < edge_count - 1; i++)
(*waveform_)[i] = (*waveform_)[i + 1] - offset;
(*waveform_)[edge_count - 1] = first_time - offset + period_;
waveform_[i] = waveform_[i + 1] - offset;
waveform_[edge_count - 1] = first_time - offset + period_;
}
setClkEdgeTimes();
waveform_valid_ = true;
@ -416,13 +388,13 @@ Clock::generateScaledClk(const Clock *src_clk,
{
period_ = src_clk->period() * scale;
if (duty_cycle_ != 0.0) {
float rise = (*src_clk->waveform())[0] * scale;
waveform_->push_back(rise);
waveform_->push_back(rise + period_ * duty_cycle_ / 100.0F);
float rise = src_clk->waveform()[0] * scale;
waveform_.push_back(rise);
waveform_.push_back(rise + period_ * duty_cycle_ / 100.0F);
}
else {
for (float time : *src_clk->waveform())
waveform_->push_back(time * scale);
for (float time : src_clk->waveform())
waveform_.push_back(time * scale);
}
}
@ -431,34 +403,34 @@ Clock::generateEdgesClk(const Clock *src_clk)
{
// The create_generated_clock tcl cmd and Sta::makeClock
// enforce this restriction.
if (edges_->size() == 3) {
const FloatSeq *src_wave = src_clk->waveform();
size_t src_size = src_wave->size();
if (edges_.size() == 3) {
const FloatSeq &src_wave = src_clk->waveform();
size_t src_size = src_wave.size();
int src_size_int = static_cast<int>(src_size);
float src_period = src_clk->period();
int edge0_1 = (*edges_)[0] - 1;
int edge0_1 = edges_[0] - 1;
div_t edge0_div = std::div(edge0_1, src_size_int);
float rise = (*src_wave)[edge0_div.rem]
float rise = src_wave[edge0_div.rem]
+ static_cast<float>(edge0_div.quot) * src_period;
if (edge_shifts_)
rise += (*edge_shifts_)[0];
waveform_->push_back(rise);
if (!edge_shifts_.empty())
rise += edge_shifts_[0];
waveform_.push_back(rise);
int edge1_1 = (*edges_)[1] - 1;
int edge1_1 = edges_[1] - 1;
div_t edge1_div = std::div(edge1_1, src_size_int);
float fall = (*src_wave)[edge1_div.rem]
float fall = src_wave[edge1_div.rem]
+ static_cast<float>(edge1_div.quot) * src_period;
if (edge_shifts_)
fall += (*edge_shifts_)[1];
waveform_->push_back(fall);
if (!edge_shifts_.empty())
fall += edge_shifts_[1];
waveform_.push_back(fall);
int edge2_1 = (*edges_)[2] - 1;
int edge2_1 = edges_[2] - 1;
div_t edge2_div = std::div(edge2_1, src_size_int);
period_ = (*src_wave)[edge2_div.rem]
period_ = src_wave[edge2_div.rem]
+ static_cast<float>(edge2_div.quot) * src_period - rise;
if (edge_shifts_)
period_ += (*edge_shifts_)[2];
if (!edge_shifts_.empty())
period_ += edge_shifts_[2];
}
else
criticalError(244, "generated clock edges size is not three.");
@ -474,7 +446,7 @@ const RiseFall *
Clock::masterClkEdgeTr(const RiseFall *rf) const
{
int edge_index = (rf == RiseFall::rise()) ? 0 : 1;
return ((*edges_)[edge_index] - 1) % 2
return (edges_[edge_index] - 1) % 2
? RiseFall::fall()
: RiseFall::rise();
}
@ -509,7 +481,7 @@ Clock::isDivideByOneCombinational() const
return combinational_
&& divide_by_ == 1
&& multiply_by_ == 0
&& edge_shifts_ == nullptr;
&& edge_shifts_.empty();
}
////////////////////////////////////////////////////////////////

View File

@ -148,9 +148,9 @@ Sdc::Sdc(Mode *mode,
void
Sdc::makeDefaultArrivalClock()
{
FloatSeq *waveform = new FloatSeq;
waveform->push_back(0.0);
waveform->push_back(0.0);
FloatSeq waveform;
waveform.push_back(0.0);
waveform.push_back(0.0);
default_arrival_clk_ = new Clock("input port clock", clk_index_++, network_);
default_arrival_clk_->initClk(nullptr, false, 0.0, waveform, "", network_);
}
@ -959,10 +959,10 @@ Sdc::maxArea() const
Clock *
Sdc::makeClock(std::string_view name,
PinSet *pins,
const PinSet &pins,
bool add_to_pins,
float period,
FloatSeq *waveform,
const FloatSeq &waveform,
std::string_view comment)
{
Clock *clk = findStringKey(clock_name_map_, name);
@ -989,7 +989,7 @@ Sdc::makeClock(std::string_view name,
Clock *
Sdc::makeGeneratedClock(std::string_view name,
PinSet *pins,
const PinSet &pins,
bool add_to_pins,
Pin *src_pin,
Clock *master_clk,
@ -998,8 +998,8 @@ Sdc::makeGeneratedClock(std::string_view name,
float duty_cycle,
bool invert,
bool combinational,
IntSeq *edges,
FloatSeq *edge_shifts,
const IntSeq &edges,
const FloatSeq &edge_shifts,
std::string_view comment)
{
Clock *clk = findStringKey(clock_name_map_, name);
@ -1039,32 +1039,30 @@ Sdc::invalidateGeneratedClks() const
// is not the clock being defined and has no pins it is removed.
void
Sdc::deletePinClocks(Clock *defining_clk,
PinSet *pins)
const PinSet &pins)
{
// Find all the clocks defined on pins to avoid finding the clock's
// vertex pins multiple times.
if (pins) {
ClockSet clks;
for (const Pin *pin : *pins) {
ClockSet *pin_clks = findKey(clock_pin_map_, pin);
if (pin_clks) {
for (Clock *clk : *pin_clks)
clks.insert(clk);
}
ClockSet clks;
for (const Pin *pin : pins) {
ClockSet *pin_clks = findKey(clock_pin_map_, pin);
if (pin_clks) {
for (Clock *clk : *pin_clks)
clks.insert(clk);
}
for (Clock *clk : clks) {
deleteClkPinMappings(clk);
for (const Pin *pin : *pins)
clk->deletePin(pin);
if (clk != defining_clk) {
if (clk->pins().empty())
removeClock(clk);
else {
clk->makeLeafPins(network_);
// One of the remaining clock pins may use a vertex pin that
// was deleted above.
makeClkPinMappings(clk);
}
}
for (Clock *clk : clks) {
deleteClkPinMappings(clk);
for (const Pin *pin : pins)
clk->deletePin(pin);
if (clk != defining_clk) {
if (clk->pins().empty())
removeClock(clk);
else {
clk->makeLeafPins(network_);
// One of the remaining clock pins may use a vertex pin that
// was deleted above.
makeClkPinMappings(clk);
}
}
}

View File

@ -22,8 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module sdc
%include "std_string.i"
%{
@ -294,21 +292,21 @@ set_net_resistance(Net *net,
void
make_clock(std::string name,
PinSet *pins,
PinSet pins,
bool add_to_pins,
float period,
FloatSeq *waveform,
FloatSeq waveform,
std::string comment)
{
Sta *sta = Sta::sta();
const Mode *mode = sta->cmdMode();
sta->makeClock(name.c_str(), pins, add_to_pins, period, waveform,
std::move(comment), mode);
sta->makeClock(name, pins, add_to_pins, period, waveform,
comment, mode);
}
void
make_generated_clock(std::string name,
PinSet *pins,
PinSet pins,
bool add_to_pins,
Pin *src_pin,
Clock *master_clk,
@ -317,17 +315,17 @@ make_generated_clock(std::string name,
float duty_cycle,
bool invert,
bool combinational,
IntSeq *edges,
FloatSeq *edge_shifts,
IntSeq edges,
FloatSeq edge_shifts,
std::string comment)
{
Sta *sta = Sta::sta();
const Mode *mode = sta->cmdMode();
sta->makeGeneratedClock(name.c_str(), pins, add_to_pins,
sta->makeGeneratedClock(name, pins, add_to_pins,
src_pin, master_clk,
divide_by, multiply_by, duty_cycle, invert,
combinational, edges, edge_shifts,
std::move(comment), mode);
comment, mode);
}
void
@ -1675,7 +1673,7 @@ pin_is_constrained(const Pin *pin)
%extend Clock {
float period() { return self->period(); }
FloatSeq *waveform() { return self->waveform(); }
FloatSeq waveform() { return self->waveform(); }
float time(RiseFall *rf) { return self->edge(rf)->time(); }
bool is_generated() { return self->isGenerated(); }
bool waveform_valid() { return self->waveformValid(); }

View File

@ -419,10 +419,10 @@ WriteSdc::writeClock(Clock *clk) const
sta::print(stream_, " -period ");
float period = clk->period();
writeTime(period);
FloatSeq *waveform = clk->waveform();
if (!(waveform->size() == 2
&& (*waveform)[0] == 0.0
&& fuzzyEqual((*waveform)[1], period / 2.0))) {
const FloatSeq &waveform = clk->waveform();
if (!(waveform.size() == 2
&& waveform[0] == 0.0
&& fuzzyEqual(waveform[1], period / 2.0))) {
sta::print(stream_, " -waveform ");
writeFloatSeq(waveform, scaleTime(1.0));
}
@ -461,12 +461,12 @@ WriteSdc::writeGeneratedClock(Clock *clk) const
}
if (clk->invert())
sta::print(stream_, " -invert");
IntSeq *edges = clk->edges();
if (edges && !edges->empty()) {
const IntSeq &edges = clk->edges();
if (!edges.empty()) {
sta::print(stream_, " -edges ");
writeIntSeq(edges);
FloatSeq *edge_shifts = clk->edgeShifts();
if (edge_shifts && !edge_shifts->empty()) {
const FloatSeq &edge_shifts = clk->edgeShifts();
if (!edge_shifts.empty()) {
sta::print(stream_, " -edge_shift ");
writeFloatSeq(edge_shifts, scaleTime(1.0));
}
@ -2762,12 +2762,12 @@ WriteSdc::writeResistance(float res) const
}
void
WriteSdc::writeFloatSeq(FloatSeq *floats,
WriteSdc::writeFloatSeq(const FloatSeq &floats,
float scale) const
{
sta::print(stream_, "{{");
bool first = true;
for (float flt : *floats) {
for (float flt : floats) {
if (!first)
sta::print(stream_, " ");
writeFloat(flt * scale);
@ -2777,11 +2777,11 @@ WriteSdc::writeFloatSeq(FloatSeq *floats,
}
void
WriteSdc::writeIntSeq(IntSeq *ints) const
WriteSdc::writeIntSeq(const IntSeq &ints) const
{
sta::print(stream_, "{{");
bool first = true;
for (int i : *ints) {
for (int i : ints) {
if (!first)
sta::print(stream_, " ");
sta::print(stream_, "{}", i);

View File

@ -72,9 +72,9 @@ public:
void writeClock(Clock *clk) const;
void writeGeneratedClock(Clock *clk) const;
void writeClockPins(const Clock *clk) const;
void writeFloatSeq(FloatSeq *floats,
void writeFloatSeq(const FloatSeq &floats,
float scale) const;
void writeIntSeq(IntSeq *ints) const;
void writeIntSeq(const IntSeq &ints) const;
void writeClockSlews(const Clock *clk) const;
void writeClockUncertainty(const Clock *clk) const;
void writeClockUncertainty(const Clock *clk,

View File

@ -22,8 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module sdf
%{
#include <string>

View File

@ -833,7 +833,7 @@ Genclks::recordSrcPaths(Clock *gclk)
bool divide_by_1 = gclk->isDivideByOneCombinational();
bool invert = gclk->invert();
bool has_edges = gclk->edges() != nullptr;
bool has_edges = !gclk->edges().empty();
for (const Pin *gclk_pin : gclk->leafPins()) {
std::vector<Path> &src_paths = genclk_src_paths_[ClockPinPair(gclk, gclk_pin)];

View File

@ -42,6 +42,7 @@
#include "Sta.hh"
#include "StringUtil.hh"
#include "TimingArc.hh"
#include "TimingRole.hh"
#include "Transition.hh"
#include "Units.hh"
#include "power/Power.hh"
@ -1152,10 +1153,11 @@ Properties::getProperty(TimingArcSet *arc_set,
if (arc_set->isWire())
return PropertyValue("wire");
else {
std::string name = sta::format("{} {} -> {}",
std::string name = sta::format("{} {} -> {} {}",
arc_set->libertyCell()->name(),
arc_set->from()->name(),
arc_set->to()->name());
arc_set->to()->name(),
arc_set->role()->to_string());
return PropertyValue(name);
}
}

View File

@ -22,8 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module properties
%{
#include "Property.hh"

View File

@ -22,8 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module search
%include "std_string.i"
%{

View File

@ -366,6 +366,8 @@ define_cmd_args "report_check_types" \
[> filename] [>> filename]}
proc_redirect report_check_types {
variable float_inf
variable group_path_count_max
variable path_options
parse_key_args "report_check_types" args \
@ -484,13 +486,13 @@ proc_redirect report_check_types {
set path_min_max "min"
}
if { $violators } {
set group_path_count $sta::group_path_count_max
set slack_min [expr -$sta::float_inf]
set group_path_count $group_path_count_max
set slack_min [expr -$float_inf]
set slack_max 0.0
} else {
set group_path_count 1
set slack_min [expr -$sta::float_inf]
set slack_max $sta::float_inf
set slack_min [expr -$float_inf]
set slack_max $float_inf
}
set path_ends [find_path_ends "NULL" {} "NULL" 0 \
@ -975,7 +977,7 @@ proc_redirect report_clock_min_period {
set include_port_paths [info exists flags(-include_port_paths)]
foreach clk $clks {
set min_period [sta::find_clk_min_period $clk $include_port_paths]
set min_period [find_clk_min_period $clk $include_port_paths]
if { $min_period == 0.0 } {
set min_period 0
set fmax "INF"
@ -983,7 +985,7 @@ proc_redirect report_clock_min_period {
# max frequency in MHz
set fmax [expr 1.0e-6 / $min_period]
}
report_line "[get_name $clk] period_min = [sta::format_time $min_period 2] fmax = [format %.2f $fmax]"
report_line "[get_name $clk] period_min = [format_time $min_period 2] fmax = [format %.2f $fmax]"
}
}
@ -1027,17 +1029,17 @@ proc unset_disable_inferred_clock_gating_cmd { objects } {
# max slew slack / limit
proc max_slew_check_slack_limit {} {
return [expr "[sta::max_slew_check_slack] / [sta::max_slew_check_limit]"]
return [expr "[max_slew_check_slack] / [max_slew_check_limit]"]
}
# max cap slack / limit
proc max_capacitance_check_slack_limit {} {
return [expr [sta::max_capacitance_check_slack] / [sta::max_capacitance_check_limit]]
return [expr [max_capacitance_check_slack] / [max_capacitance_check_limit]]
}
# max fanout slack / limit
proc max_fanout_check_slack_limit {} {
return [expr [sta::max_fanout_check_slack] / [sta::max_fanout_check_limit]]
return [expr [max_fanout_check_slack] / [max_fanout_check_limit]]
}
################################################################

View File

@ -713,12 +713,7 @@ Sta::readLibertyFile(std::string_view filename,
if (liberty) {
// Don't map liberty cells if they are redefined by reading another
// library with the same cell names.
if (min_max == MinMaxAll::all()) {
readLibertyAfter(liberty, scene, MinMax::min());
readLibertyAfter(liberty, scene, MinMax::max());
}
else
readLibertyAfter(liberty, scene, min_max->asMinMax());
readLibertyAfter(liberty, scene, min_max);
network_->readLibertyAfter(liberty);
}
return liberty;
@ -727,11 +722,11 @@ Sta::readLibertyFile(std::string_view filename,
void
Sta::readLibertyAfter(LibertyLibrary *liberty,
Scene *scene,
const MinMax *min_max)
const MinMaxAll *min_max)
{
scene->addLiberty(liberty, min_max);
LibertyLibrary::makeSceneMap(liberty, scene->libertyIndex(min_max), network_,
report_);
for (const MinMax *mm : min_max->range())
scene->addLiberty(liberty, mm);
LibertyLibrary::makeSceneMap(liberty, scene, min_max, network_, report_);
}
bool
@ -1149,10 +1144,10 @@ Sta::setMaxArea(float area,
void
Sta::makeClock(std::string_view name,
PinSet *pins,
const PinSet &pins,
bool add_to_pins,
float period,
FloatSeq *waveform,
const FloatSeq &waveform,
std::string_view comment,
const Mode *mode)
{
@ -1165,7 +1160,7 @@ Sta::makeClock(std::string_view name,
void
Sta::makeGeneratedClock(std::string_view name,
PinSet *pins,
const PinSet &pins,
bool add_to_pins,
Pin *src_pin,
Clock *master_clk,
@ -1174,8 +1169,8 @@ Sta::makeGeneratedClock(std::string_view name,
float duty_cycle,
bool invert,
bool combinational,
IntSeq *edges,
FloatSeq *edge_shifts,
const IntSeq &edges,
const FloatSeq &edge_shifts,
std::string_view comment,
const Mode *mode)
{
@ -2624,22 +2619,27 @@ Sta::updateSceneLiberty(Scene *scene,
const StringSeq &liberty_min_files,
const StringSeq &liberty_max_files)
{
StringSet warned_files;
for (const MinMax *min_max : MinMax::range()) {
const StringSeq &liberty_files =
min_max == MinMax::min() ? liberty_min_files : liberty_max_files;
for (const std::string &lib_file : liberty_files) {
LibertyLibrary *lib = network_->findLiberty(lib_file);
if (lib == nullptr)
lib = network_->findLibertyFilename(lib_file);
if (lib)
LibertyLibrary::makeSceneMap(lib, scene->libertyIndex(min_max), network_,
report_);
else if (!warned_files.contains(lib_file)) {
report_->warn(1555, "liberty name/filename {} not found.", lib_file);
warned_files.insert(lib_file);
}
}
if (liberty_min_files == liberty_max_files)
updateSceneLiberty(scene, liberty_max_files, MinMaxAll::minMax());
else {
updateSceneLiberty(scene, liberty_min_files, MinMaxAll::min());
updateSceneLiberty(scene, liberty_max_files, MinMaxAll::max());
}
}
void
Sta::updateSceneLiberty(Scene *scene,
const StringSeq &liberty_files,
const MinMaxAll *min_max)
{
for (const std::string &lib_file : liberty_files) {
LibertyLibrary *lib = network_->findLiberty(lib_file);
if (lib == nullptr)
lib = network_->findLibertyFilename(lib_file);
if (lib)
LibertyLibrary::makeSceneMap(lib, scene, min_max, network_, report_);
else
report_->warn(1555, "liberty name/filename {} not found.", lib_file);
}
}
@ -2650,10 +2650,8 @@ Sta::updateLibertyScenes()
LibertyLibraryIterator *iter = network_->libertyLibraryIterator();
while (iter->hasNext()) {
LibertyLibrary *lib = iter->next();
for (const MinMax *min_max : MinMax::range()) {
LibertyLibrary::makeSceneMap(lib, scene->libertyIndex(min_max), network_,
report_);
}
LibertyLibrary::makeSceneMap(lib, scene, MinMaxAll::minMax(),
network_, report_);
}
}
}

View File

@ -22,8 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module write_gate_spice
%{
#include "spice/WritePathSpice.hh"

View File

@ -33,7 +33,7 @@ namespace eval sta {
define_cmd_args show_splash {}
proc show_splash {} {
report_line "OpenSTA [sta::version] [string range [sta::git_sha1] 0 9] Copyright (c) 2026, Parallax Software, Inc.
report_line "OpenSTA [version] [string range [git_sha1] 0 9] Copyright (c) 2026, Parallax Software, Inc.
License GPLv3: GNU GPL version 3 <http://gnu.org/licenses/gpl.html>
This is free software, and you are free to change and redistribute it

View File

@ -47,7 +47,7 @@ proc define_scene { args } {
if { [info exists keys(-mode)] } {
set mode_name $keys(-mode)
} else {
set mode_name [sta::cmd_mode_name]
set mode_name [cmd_mode_name]
}
set liberty_min_files {}

View File

@ -751,8 +751,28 @@ using namespace sta;
Tcl_SetObjResult(interp, list);
}
%typemap(in) FloatSeq {
Tcl_Size argc;
Tcl_Obj **argv;
FloatSeq floats;
if (Tcl_ListObjGetElements(interp, $input, &argc, &argv) == TCL_OK) {
for (int i = 0; i < argc; i++) {
char *arg = Tcl_GetString(argv[i]);
double value;
if (Tcl_GetDouble(interp, arg, &value) == TCL_OK)
floats.push_back(static_cast<float>(value));
else {
tclArgError(interp, 2175, "{} is not a floating point number.", arg);
return TCL_ERROR;
}
}
}
$1 = floats;
}
%typemap(out) FloatSeq {
FloatSeq &floats = $1;
const FloatSeq &floats = $1;
Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
for (float f : floats) {
Tcl_Obj *obj = Tcl_NewDoubleObj(f);
@ -761,21 +781,18 @@ using namespace sta;
Tcl_SetObjResult(interp, list);
}
%typemap(in) IntSeq* {
%typemap(in) IntSeq {
Tcl_Size argc;
Tcl_Obj **argv;
IntSeq *ints = nullptr;
IntSeq ints;
if (Tcl_ListObjGetElements(interp, $input, &argc, &argv) == TCL_OK) {
if (argc)
ints = new IntSeq;
for (int i = 0; i < argc; i++) {
char *arg = Tcl_GetString(argv[i]);
int value;
if (Tcl_GetInt(interp, arg, &value) == TCL_OK)
ints->push_back(value);
ints.push_back(value);
else {
delete ints;
tclArgError(interp, 2158, "{} is not an integer.", arg);
return TCL_ERROR;
}

View File

@ -70,4 +70,3 @@ report_object_full_names [get_clocks -filter is_virtual==true *]
report_object_full_names [get_cells -filter {name =~ .1} *]
puts [sta::filter_expr_to_postfix "direction == input && name =~ clk* && is_clock"]

View File

@ -67,8 +67,9 @@ stringFloat(const std::string &str)
return {0.0, false};
#else
char *ptr;
errno = 0;
value = strtof(str.data(), &ptr);
if (!errno || *ptr != '\0')
if (errno != 0 || *ptr != '\0')
return {0.0, false};
else
return {value, true};

View File

@ -22,7 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module util
%include <std_string.i>
%{
@ -40,16 +39,9 @@ using namespace sta;
%}
////////////////////////////////////////////////////////////////
//
// Empty class definitions to make swig happy.
// Private constructor/destructor so swig doesn't emit them.
//
////////////////////////////////////////////////////////////////
%inline %{
float float_inf = INF;
const float float_inf = INF;
const char *
version()
@ -544,11 +536,3 @@ fuzzy_equal(float value1,
}
%} // inline
////////////////////////////////////////////////////////////////
//
// Object Methods
//
////////////////////////////////////////////////////////////////

View File

@ -22,8 +22,6 @@
//
// This notice may not be removed or altered from any source distribution.
%module verilog
%{
#include "Sta.hh"
#include "VerilogWriter.hh"