Clock embed sequence members

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry
2026-04-16 18:42:26 -07:00
parent e629909aaf
commit 7838986dc4
12 changed files with 157 additions and 171 deletions

View File

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

View File

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

View File

@@ -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,

View File

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

View File

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

View File

@@ -148,9 +148,9 @@ Sdc::Sdc(Mode *mode,
void
Sdc::makeDefaultArrivalClock()
{
FloatSeq *waveform = new FloatSeq;
waveform->push_back(0.0);
waveform->push_back(0.0);
FloatSeq waveform;
waveform.push_back(0.0);
waveform.push_back(0.0);
default_arrival_clk_ = new Clock("input port clock", clk_index_++, network_);
default_arrival_clk_->initClk(nullptr, false, 0.0, waveform, "", network_);
}
@@ -959,10 +959,10 @@ Sdc::maxArea() const
Clock *
Sdc::makeClock(std::string_view name,
PinSet *pins,
const PinSet &pins,
bool add_to_pins,
float period,
FloatSeq *waveform,
const FloatSeq &waveform,
std::string_view comment)
{
Clock *clk = findStringKey(clock_name_map_, name);
@@ -989,7 +989,7 @@ Sdc::makeClock(std::string_view name,
Clock *
Sdc::makeGeneratedClock(std::string_view name,
PinSet *pins,
const PinSet &pins,
bool add_to_pins,
Pin *src_pin,
Clock *master_clk,
@@ -998,8 +998,8 @@ Sdc::makeGeneratedClock(std::string_view name,
float duty_cycle,
bool invert,
bool combinational,
IntSeq *edges,
FloatSeq *edge_shifts,
const IntSeq &edges,
const FloatSeq &edge_shifts,
std::string_view comment)
{
Clock *clk = findStringKey(clock_name_map_, name);
@@ -1039,13 +1039,12 @@ 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) {
for (const Pin *pin : pins) {
ClockSet *pin_clks = findKey(clock_pin_map_, pin);
if (pin_clks) {
for (Clock *clk : *pin_clks)
@@ -1054,7 +1053,7 @@ Sdc::deletePinClocks(Clock *defining_clk,
}
for (Clock *clk : clks) {
deleteClkPinMappings(clk);
for (const Pin *pin : *pins)
for (const Pin *pin : pins)
clk->deletePin(pin);
if (clk != defining_clk) {
if (clk->pins().empty())
@@ -1068,7 +1067,6 @@ Sdc::deletePinClocks(Clock *defining_clk,
}
}
}
}
void
Sdc::deleteClkPinMappings(Clock *clk)

View File

@@ -292,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,
@@ -315,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
@@ -1673,7 +1673,7 @@ pin_is_constrained(const Pin *pin)
%extend Clock {
float period() { return self->period(); }
FloatSeq *waveform() { return self->waveform(); }
FloatSeq waveform() { return self->waveform(); }
float time(RiseFall *rf) { return self->edge(rf)->time(); }
bool is_generated() { return self->isGenerated(); }
bool waveform_valid() { return self->waveformValid(); }

View File

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

View File

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

View File

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

View File

@@ -1149,10 +1149,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 +1165,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 +1174,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)
{

View File

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