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:
commit
05b4e3a1d9
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module dcalc
|
||||
|
||||
%include <std_string.i>
|
||||
|
||||
%{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module graph
|
||||
|
||||
%{
|
||||
#include "Clock.hh"
|
||||
#include "FuncExpr.hh"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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_; }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module liberty
|
||||
|
||||
%{
|
||||
#include "PatternMatch.hh"
|
||||
#include "PortDirection.hh"
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ TimingArcSet::TimingArcSet(const TimingRole *role,
|
|||
}
|
||||
|
||||
std::string
|
||||
TimingArcSet::to_string()
|
||||
TimingArcSet::to_string() const
|
||||
{
|
||||
std::string str = from_->name();
|
||||
str += " -> ";
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module network
|
||||
|
||||
%include <std_string.i>
|
||||
|
||||
%{
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module NetworkEdit
|
||||
|
||||
%{
|
||||
using sta::Cell;
|
||||
using sta::Instance;
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module parasitics
|
||||
|
||||
%{
|
||||
#include "Sta.hh"
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module power
|
||||
|
||||
%{
|
||||
#include "power/Power.hh"
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
124
sdc/Clock.cc
124
sdc/Clock.cc
|
|
@ -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();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
58
sdc/Sdc.cc
58
sdc/Sdc.cc
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
22
sdc/Sdc.i
22
sdc/Sdc.i
|
|
@ -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(); }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module sdf
|
||||
|
||||
%{
|
||||
#include <string>
|
||||
|
||||
|
|
|
|||
|
|
@ -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)];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module properties
|
||||
|
||||
%{
|
||||
|
||||
#include "Property.hh"
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module search
|
||||
|
||||
%include "std_string.i"
|
||||
|
||||
%{
|
||||
|
|
|
|||
|
|
@ -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]]
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
|
|
|||
|
|
@ -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_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module write_gate_spice
|
||||
|
||||
%{
|
||||
|
||||
#include "spice/WritePathSpice.hh"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
18
util/Util.i
18
util/Util.i
|
|
@ -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
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%module verilog
|
||||
|
||||
%{
|
||||
#include "Sta.hh"
|
||||
#include "VerilogWriter.hh"
|
||||
|
|
|
|||
Loading…
Reference in New Issue