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. # searching OSX system directories before unix directories.
set(TCL_POSSIBLE_NAMES set(TCL_POSSIBLE_NAMES
#tcl90 tcl9.0
tcl87 tcl8.7 tcl87 tcl8.7
tcl86 tcl8.6 tcl86 tcl8.6
tcl85 tcl8.5 tcl85 tcl8.5
@ -32,6 +33,7 @@ set(TCL_POSSIBLE_NAMES
if (NOT TCL_LIB_PATHS) if (NOT TCL_LIB_PATHS)
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(TCL_LIB_PATHS 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.17/lib
/opt/homebrew/Cellar/tcl-tk@8/8.6.16/lib /opt/homebrew/Cellar/tcl-tk@8/8.6.16/lib
/opt/homebrew/opt/tcl-tk/lib /usr/local/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. // This notice may not be removed or altered from any source distribution.
%module dcalc
%include <std_string.i> %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); bool arg_fail = checkArgs(dcalc_args, scene, min_max);
if (arg_fail) { if (arg_fail) {
const RiseFall *rf = arc->toEdge()->asRiseFall(); const RiseFall *rf = arc->toEdge()->asRiseFall();
const Parasitic *reduced = const Parasitic *reduced = table_dcalc_->findParasitic(drvr_pin, rf,
table_dcalc_->findParasitic(drvr_pin, rf, scene, min_max); scene, min_max);
return table_dcalc_->reportGateDelay(drvr_pin, arc, in_slew, load_cap, return table_dcalc_->reportGateDelay(drvr_pin, arc, in_slew, load_cap,
reduced, load_pin_index_map, scene, reduced, load_pin_index_map, scene,
min_max, digits); min_max, digits);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -707,7 +707,8 @@ LibertyLibrary::makeScaledCell(std::string_view name,
void void
LibertyLibrary::makeSceneMap(LibertyLibrary *lib, LibertyLibrary::makeSceneMap(LibertyLibrary *lib,
size_t lib_ap_index, Scene *scene,
const MinMaxAll *min_max,
Network *network, Network *network,
Report *report) Report *report)
{ {
@ -716,38 +717,33 @@ LibertyLibrary::makeSceneMap(LibertyLibrary *lib,
LibertyCell *cell = cell_iter.next(); LibertyCell *cell = cell_iter.next();
LibertyCell *link_cell = network->findLibertyCell(cell->name()); LibertyCell *link_cell = network->findLibertyCell(cell->name());
if (link_cell) 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 // 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
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 void
LibertyLibrary::makeSceneMap(LibertyCell *cell1, LibertyLibrary::makeSceneMap(LibertyCell *cell1,
LibertyCell *cell2, LibertyCell *cell2,
bool link, Scene *scene,
size_t lib_ap_index, const MinMaxAll *min_max,
Report *report) 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); LibertyCellPortBitIterator port_iter1(cell1);
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 = cell2->findLibertyPort(port1->name());
if (port2) { 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); port1->setScenePort(port2, lib_ap_index);
}
} }
else else
report->warn(1110, "cell {}/{} port {} not found in cell {}/{}.", 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_) { for (TimingArcSet *arc_set1 : cell1->timing_arc_sets_) {
TimingArcSet *arc_set2 = cell2->findTimingArcSet(arc_set1); TimingArcSet *arc_set2 = cell2->findTimingArcSet(arc_set1);
if (arc_set2) { if (arc_set2) {
if (link) { const TimingArcSeq &arcs1 = arc_set1->arcs();
const TimingArcSeq &arcs1 = arc_set1->arcs(); const TimingArcSeq &arcs2 = arc_set2->arcs();
const TimingArcSeq &arcs2 = arc_set2->arcs(); auto arc_itr1 = arcs1.begin(), arc_itr2 = arcs2.begin();
auto arc_itr1 = arcs1.begin(), arc_itr2 = arcs2.begin(); for (;
for (; arc_itr1 != arcs1.end() && arc_itr2 != arcs2.end();
arc_itr1 != arcs1.end() && arc_itr2 != arcs2.end(); arc_itr1++, arc_itr2++) {
arc_itr1++, arc_itr2++) { TimingArc *arc1 = *arc_itr1;
TimingArc *arc1 = *arc_itr1; TimingArc *arc2 = *arc_itr2;
TimingArc *arc2 = *arc_itr2; if (TimingArc::equiv(arc1, arc2)) {
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); arc1->setSceneArc(arc2, lib_ap_index);
}
} }
} }
} }
@ -2382,12 +2380,13 @@ LibertyPort::equiv(const LibertyPort *port1,
&& port1->pwr_gnd_type_ == port2->pwr_gnd_type_); && port1->pwr_gnd_type_ == port2->pwr_gnd_type_);
} }
// Note port1 and port2 may be from different cells (timingArcSetLess).
bool bool
LibertyPort::less(const LibertyPort *port1, LibertyPort::less(const LibertyPort *port1,
const LibertyPort *port2) const LibertyPort *port2)
{ {
if (port1 && port2) if (port1 && port2)
return port1->pinIndex() < port2->pinIndex(); return port1->name() < port2->name();
else else
return port1 == nullptr && port2 != nullptr; return port1 == nullptr && port2 != nullptr;
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -975,7 +975,10 @@ ConcreteParasitics::piModel(const Parasitic *parasitic,
float &c1) const float &c1) const
{ {
const ConcreteParasitic *cparasitic = static_cast<const ConcreteParasitic*>(parasitic); 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 void
@ -985,7 +988,10 @@ ConcreteParasitics::setPiModel(Parasitic *parasitic,
float c1) float c1)
{ {
ConcreteParasitic *cparasitic = static_cast<ConcreteParasitic*>(parasitic); 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. // This notice may not be removed or altered from any source distribution.
%module parasitics
%{ %{
#include "Sta.hh" #include "Sta.hh"

View File

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

View File

@ -22,8 +22,6 @@
// //
// This notice may not be removed or altered from any source distribution. // This notice may not be removed or altered from any source distribution.
%module power
%{ %{
#include "power/Power.hh" #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" 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)] } { if { [info exists keys(-density)] } {
@ -165,7 +165,7 @@ proc set_power_activity { args } {
set ports [get_ports_error "input_ports" $keys(-input_ports)] set ports [get_ports_error "input_ports" $keys(-input_ports)]
foreach port $ports { foreach port $ports {
if { [get_property $port "direction"] == "input" } { 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." sta_warn 310 "activity cannot be set on clock ports."
} else { } else {
set_power_input_port_activity $port $density $duty 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)] set ports [get_ports_error "input_ports" $keys(-input_ports)]
foreach port $ports { foreach port $ports {
if { [get_property $port "direction"] == "input" } { 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." sta_warn 303 "activity cannot be set on clock ports."
} else { } else {
unset_power_input_port_activity $port unset_power_input_port_activity $port
@ -255,7 +255,7 @@ proc read_vcd { args } {
if { [info exists keys(-scope)] } { if { [info exists keys(-scope)] } {
set scope $keys(-scope) set scope $keys(-scope)
} }
set mode_name [sta::cmd_mode] set mode_name [cmd_mode_name]
if { [info exists keys(-mode)] } { if { [info exists keys(-mode)] } {
set mode_name $keys(-mode) set mode_name $keys(-mode)
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -366,6 +366,8 @@ define_cmd_args "report_check_types" \
[> filename] [>> filename]} [> filename] [>> filename]}
proc_redirect report_check_types { proc_redirect report_check_types {
variable float_inf
variable group_path_count_max
variable path_options variable path_options
parse_key_args "report_check_types" args \ parse_key_args "report_check_types" args \
@ -484,13 +486,13 @@ proc_redirect report_check_types {
set path_min_max "min" set path_min_max "min"
} }
if { $violators } { if { $violators } {
set group_path_count $sta::group_path_count_max set group_path_count $group_path_count_max
set slack_min [expr -$sta::float_inf] set slack_min [expr -$float_inf]
set slack_max 0.0 set slack_max 0.0
} else { } else {
set group_path_count 1 set group_path_count 1
set slack_min [expr -$sta::float_inf] set slack_min [expr -$float_inf]
set slack_max $sta::float_inf set slack_max $float_inf
} }
set path_ends [find_path_ends "NULL" {} "NULL" 0 \ 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)] set include_port_paths [info exists flags(-include_port_paths)]
foreach clk $clks { 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 } { if { $min_period == 0.0 } {
set min_period 0 set min_period 0
set fmax "INF" set fmax "INF"
@ -983,7 +985,7 @@ proc_redirect report_clock_min_period {
# max frequency in MHz # max frequency in MHz
set fmax [expr 1.0e-6 / $min_period] 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 # max slew slack / limit
proc max_slew_check_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 # max cap slack / limit
proc max_capacitance_check_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 # max fanout slack / limit
proc max_fanout_check_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) { if (liberty) {
// Don't map liberty cells if they are redefined by reading another // Don't map liberty cells if they are redefined by reading another
// library with the same cell names. // library with the same cell names.
if (min_max == MinMaxAll::all()) { readLibertyAfter(liberty, scene, min_max);
readLibertyAfter(liberty, scene, MinMax::min());
readLibertyAfter(liberty, scene, MinMax::max());
}
else
readLibertyAfter(liberty, scene, min_max->asMinMax());
network_->readLibertyAfter(liberty); network_->readLibertyAfter(liberty);
} }
return liberty; return liberty;
@ -727,11 +722,11 @@ Sta::readLibertyFile(std::string_view filename,
void void
Sta::readLibertyAfter(LibertyLibrary *liberty, Sta::readLibertyAfter(LibertyLibrary *liberty,
Scene *scene, Scene *scene,
const MinMax *min_max) const MinMaxAll *min_max)
{ {
scene->addLiberty(liberty, min_max); for (const MinMax *mm : min_max->range())
LibertyLibrary::makeSceneMap(liberty, scene->libertyIndex(min_max), network_, scene->addLiberty(liberty, mm);
report_); LibertyLibrary::makeSceneMap(liberty, scene, min_max, network_, report_);
} }
bool bool
@ -1149,10 +1144,10 @@ Sta::setMaxArea(float area,
void void
Sta::makeClock(std::string_view name, Sta::makeClock(std::string_view name,
PinSet *pins, const PinSet &pins,
bool add_to_pins, bool add_to_pins,
float period, float period,
FloatSeq *waveform, const FloatSeq &waveform,
std::string_view comment, std::string_view comment,
const Mode *mode) const Mode *mode)
{ {
@ -1165,7 +1160,7 @@ Sta::makeClock(std::string_view name,
void void
Sta::makeGeneratedClock(std::string_view name, Sta::makeGeneratedClock(std::string_view name,
PinSet *pins, const PinSet &pins,
bool add_to_pins, bool add_to_pins,
Pin *src_pin, Pin *src_pin,
Clock *master_clk, Clock *master_clk,
@ -1174,8 +1169,8 @@ Sta::makeGeneratedClock(std::string_view name,
float duty_cycle, float duty_cycle,
bool invert, bool invert,
bool combinational, bool combinational,
IntSeq *edges, const IntSeq &edges,
FloatSeq *edge_shifts, const FloatSeq &edge_shifts,
std::string_view comment, std::string_view comment,
const Mode *mode) const Mode *mode)
{ {
@ -2624,22 +2619,27 @@ Sta::updateSceneLiberty(Scene *scene,
const StringSeq &liberty_min_files, const StringSeq &liberty_min_files,
const StringSeq &liberty_max_files) const StringSeq &liberty_max_files)
{ {
StringSet warned_files; if (liberty_min_files == liberty_max_files)
for (const MinMax *min_max : MinMax::range()) { updateSceneLiberty(scene, liberty_max_files, MinMaxAll::minMax());
const StringSeq &liberty_files = else {
min_max == MinMax::min() ? liberty_min_files : liberty_max_files; updateSceneLiberty(scene, liberty_min_files, MinMaxAll::min());
for (const std::string &lib_file : liberty_files) { updateSceneLiberty(scene, liberty_max_files, MinMaxAll::max());
LibertyLibrary *lib = network_->findLiberty(lib_file); }
if (lib == nullptr) }
lib = network_->findLibertyFilename(lib_file);
if (lib) void
LibertyLibrary::makeSceneMap(lib, scene->libertyIndex(min_max), network_, Sta::updateSceneLiberty(Scene *scene,
report_); const StringSeq &liberty_files,
else if (!warned_files.contains(lib_file)) { const MinMaxAll *min_max)
report_->warn(1555, "liberty name/filename {} not found.", lib_file); {
warned_files.insert(lib_file); 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(); LibertyLibraryIterator *iter = network_->libertyLibraryIterator();
while (iter->hasNext()) { while (iter->hasNext()) {
LibertyLibrary *lib = iter->next(); LibertyLibrary *lib = iter->next();
for (const MinMax *min_max : MinMax::range()) { LibertyLibrary::makeSceneMap(lib, scene, MinMaxAll::minMax(),
LibertyLibrary::makeSceneMap(lib, scene->libertyIndex(min_max), network_, network_, report_);
report_);
}
} }
} }
} }

View File

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

View File

@ -33,7 +33,7 @@ namespace eval sta {
define_cmd_args show_splash {} define_cmd_args show_splash {}
proc 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> 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 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)] } { if { [info exists keys(-mode)] } {
set mode_name $keys(-mode) set mode_name $keys(-mode)
} else { } else {
set mode_name [sta::cmd_mode_name] set mode_name [cmd_mode_name]
} }
set liberty_min_files {} set liberty_min_files {}

View File

@ -751,8 +751,28 @@ using namespace sta;
Tcl_SetObjResult(interp, list); 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 { %typemap(out) FloatSeq {
FloatSeq &floats = $1; const FloatSeq &floats = $1;
Tcl_Obj *list = Tcl_NewListObj(0, nullptr); Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
for (float f : floats) { for (float f : floats) {
Tcl_Obj *obj = Tcl_NewDoubleObj(f); Tcl_Obj *obj = Tcl_NewDoubleObj(f);
@ -761,21 +781,18 @@ using namespace sta;
Tcl_SetObjResult(interp, list); Tcl_SetObjResult(interp, list);
} }
%typemap(in) IntSeq* { %typemap(in) IntSeq {
Tcl_Size argc; Tcl_Size argc;
Tcl_Obj **argv; Tcl_Obj **argv;
IntSeq *ints = nullptr;
IntSeq ints;
if (Tcl_ListObjGetElements(interp, $input, &argc, &argv) == TCL_OK) { if (Tcl_ListObjGetElements(interp, $input, &argc, &argv) == TCL_OK) {
if (argc)
ints = new IntSeq;
for (int i = 0; i < argc; i++) { for (int i = 0; i < argc; i++) {
char *arg = Tcl_GetString(argv[i]); char *arg = Tcl_GetString(argv[i]);
int value; int value;
if (Tcl_GetInt(interp, arg, &value) == TCL_OK) if (Tcl_GetInt(interp, arg, &value) == TCL_OK)
ints->push_back(value); ints.push_back(value);
else { else {
delete ints;
tclArgError(interp, 2158, "{} is not an integer.", arg); tclArgError(interp, 2158, "{} is not an integer.", arg);
return TCL_ERROR; 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} *] report_object_full_names [get_cells -filter {name =~ .1} *]
puts [sta::filter_expr_to_postfix "direction == input && name =~ clk* && is_clock"] 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}; return {0.0, false};
#else #else
char *ptr; char *ptr;
errno = 0;
value = strtof(str.data(), &ptr); value = strtof(str.data(), &ptr);
if (!errno || *ptr != '\0') if (errno != 0 || *ptr != '\0')
return {0.0, false}; return {0.0, false};
else else
return {value, true}; return {value, true};

View File

@ -22,7 +22,6 @@
// //
// This notice may not be removed or altered from any source distribution. // This notice may not be removed or altered from any source distribution.
%module util
%include <std_string.i> %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 %{ %inline %{
float float_inf = INF; const float float_inf = INF;
const char * const char *
version() version()
@ -544,11 +536,3 @@ fuzzy_equal(float value1,
} }
%} // inline %} // inline
////////////////////////////////////////////////////////////////
//
// Object Methods
//
////////////////////////////////////////////////////////////////

View File

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