Merge remote-tracking branch 'upstream/master'

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
This commit is contained in:
Matt Liberty 2025-09-03 23:00:11 +00:00
commit e475ee2c98
24 changed files with 981 additions and 880 deletions

View File

@ -263,12 +263,16 @@ protected:
// Driver parameter Newton-Raphson state.
int nr_order_;
double *x_;
double *fvec_;
double **fjac_;
double *scale_;
double *p_;
int *index_;
static constexpr int max_nr_order_ = 3;
double x_[max_nr_order_];
double fvec_[max_nr_order_];
double fjac_storage_[max_nr_order_ * max_nr_order_];
double *fjac_[max_nr_order_];
double scale_[max_nr_order_];
double p_[max_nr_order_ ];
int index_[max_nr_order_];
// Driver slew used to check load delay.
double drvr_slew_;
@ -288,27 +292,12 @@ DmpAlg::DmpAlg(int nr_order,
c1_(0.0),
nr_order_(nr_order)
{
x_ = new double[nr_order_];
fvec_ = new double[nr_order_];
scale_ = new double[nr_order_];
p_ = new double[nr_order_];
fjac_ = new double*[nr_order_];
for (int i = 0; i < nr_order_; i++)
fjac_[i] = new double[nr_order_];
index_ = new int[nr_order_];
// Only use the upper left block of the matrix
fjac_[i] = fjac_storage_ + i * max_nr_order_;
}
DmpAlg::~DmpAlg()
{
delete [] x_;
delete [] fvec_;
delete [] scale_;
delete [] p_;
for (int i = 0; i < nr_order_; i++)
delete [] fjac_[i];
delete [] fjac_;
delete [] index_;
}
DmpAlg::~DmpAlg() = default;
void
DmpAlg::init(const LibertyLibrary *drvr_library,

View File

@ -260,8 +260,10 @@ GraphDelayCalc::findDelays(Level level)
if (incremental_)
seedInvalidDelays();
FindVertexDelays visitor(this);
dcalc_count += iter_->visitParallel(level, &visitor);
if (!iter_->empty()) {
FindVertexDelays visitor(this);
dcalc_count += iter_->visitParallel(level, &visitor);
}
// Timing checks require slews at both ends of the arc,
// so find their delays after all slews are known.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -375,6 +375,8 @@ public:
virtual const TimingRole *checkRole(const StaState *sta) const;
virtual Required requiredTime(const StaState *sta) const;
virtual Arrival borrow(const StaState *sta) const;
virtual float targetClkTime(const StaState *sta) const;
virtual float targetClkOffset(const StaState *sta) const;
Arrival targetClkWidth(const StaState *sta) const;
virtual int exceptPathCmp(const PathEnd *path_end,
const StaState *sta) const;

View File

@ -356,7 +356,8 @@ public:
TagGroup *tagGroup(const Vertex *vertex) const;
TagGroup *tagGroup(TagGroupIndex index) const;
void reportArrivals(Vertex *vertex) const;
void reportArrivals(Vertex *vertex,
bool report_tag_index) const;
Slack wnsSlack(Vertex *vertex,
PathAPIndex path_ap_index);
void levelsChangedBefore();
@ -410,6 +411,7 @@ public:
TagGroupIndex tag_index);
void checkPrevPaths() const;
void deletePaths(Vertex *vertex);
void deleteTagGroup(TagGroup *group);
protected:
void init(StaState *sta);
@ -645,6 +647,7 @@ protected:
// Capacity of tag_groups_.
TagGroupIndex tag_group_capacity_;
std::mutex tag_group_lock_;
std::mutex tag_group_ref_count_lock_;
// Latches data outputs to queue on the next search pass.
VertexSet *pending_latch_outputs_;
std::mutex pending_latch_outputs_lock_;

View File

@ -559,6 +559,8 @@ LibertyReader::defineVisitors()
defineGroupVisitor("ecsm_waveform", &LibertyReader::beginEcsmWaveform,
&LibertyReader::endEcsmWaveform);
defineGroupVisitor("ecsm_waveform_set", &LibertyReader::beginEcsmWaveform,
&LibertyReader::endEcsmWaveform);
}
void

View File

@ -303,12 +303,14 @@ BfsIterator::checkInQueue(Vertex *vertex)
if (vertex->bfsInQueue(bfs_index_))
return;
else
printf("extra %s\n", vertex->to_string(this).c_str());
debugPrint(debug_, "bfs", 1, "extra %s",
vertex->to_string(this).c_str());
}
}
}
if (vertex->bfsInQueue(bfs_index_))
printf("missing %s\n", vertex->to_string(this).c_str());
debugPrint(debug_, "brs", 1, "missing %s",
vertex->to_string(this).c_str());
}
void

View File

@ -93,7 +93,7 @@ Latches::latchRequired(const Path *data_path,
CycleAccting *acct = sdc_->cycleAccting(data_clk_edge,
enable_clk_edge);
// checkTgtClkTime
float tgt_clk_time = acct->requiredTime(check_role);
float tgt_clk_time = path_delay ? 0.0 : acct->requiredTime(check_role);
// checkTgtClkArrival broken down into components.
Arrival enable_arrival = max_delay
+ tgt_clk_time

View File

@ -52,7 +52,6 @@ Levelize::Levelize(StaState *sta) :
levels_valid_(false),
max_level_(0),
level_space_(10),
max_incremental_level_(std::numeric_limits<size_t>::max()),
roots_(graph_),
relevelize_from_(graph_),
observer_(nullptr)
@ -106,8 +105,7 @@ void
Levelize::ensureLevelized()
{
if (!levels_valid_) {
if (levelized_
&& relevelize_from_.size() < max_incremental_level_)
if (levelized_)
relevelize();
else
levelize();

View File

@ -108,7 +108,6 @@ protected:
bool levels_valid_;
Level max_level_;
Level level_space_;
size_t max_incremental_level_;
VertexSet roots_;
VertexSet relevelize_from_;
GraphLoopSeq loops_;

View File

@ -1193,6 +1193,24 @@ PathEndLatchCheck::checkRole(const StaState *sta) const
return TimingRole::latchSetup();
}
float
PathEndLatchCheck::targetClkTime(const StaState *sta) const
{
if (path_delay_)
return 0.0;
else
return PathEndClkConstrained::targetClkTime(sta);
}
float
PathEndLatchCheck::targetClkOffset(const StaState *sta) const
{
if (path_delay_)
return -targetClkEdge(sta)->time();
else
return PathEndClkConstrained::targetClkOffset(sta);
}
Required
PathEndLatchCheck::requiredTime(const StaState *sta) const
{

View File

@ -35,6 +35,7 @@
#include "PathAnalysisPt.hh"
#include "Tag.hh"
#include "Search.hh"
#include "Latches.hh"
#include "PathEnd.hh"
#include "Path.hh"
@ -219,7 +220,8 @@ PathEnum::reportDiversionPath(Diversion *div)
p->to_string(this).c_str(),
delayAsString(p->arrival(), this),
Path::equal(p, after_div, this) ? " <-after diversion" : "");
if (p != path && network_->isLatchData(p->pin(this)))
if (p != path
&& network_->isLatchData(p->pin(this)))
break;
p = p->prevPath();
}
@ -529,13 +531,23 @@ PathEnum::divSlack(Path *before_div,
const TimingArc *div_arc,
const PathAnalysisPt *path_ap)
{
Arrival arc_arrival = before_div->arrival();
Arrival before_div_arrival = before_div->arrival();
if (div_edge) {
ArcDelay div_delay = search_->deratedDelay(div_edge->from(graph_),
div_arc, div_edge,
false, path_ap);
Arrival div_arrival = search_->clkPathArrival(after_div) + div_delay;
return div_arrival - arc_arrival;
if (div_edge->role()->isLatchDtoQ()) {
Arrival div_arrival;
ArcDelay div_delay;
Tag *q_tag;
latches_->latchOutArrival(after_div, div_arc, div_edge, path_ap,
q_tag, div_delay, div_arrival);
return div_arrival - before_div_arrival;
}
else {
ArcDelay div_delay = search_->deratedDelay(div_edge->from(graph_),
div_arc, div_edge,
false, path_ap);
Arrival div_arrival = search_->clkPathArrival(after_div) + div_delay;
return div_arrival - before_div_arrival;
}
}
else {
report()->error(1370, "path diversion missing edge.");
@ -634,39 +646,56 @@ PathEnum::updatePathHeadDelays(PathSeq &paths,
Tag *prev_tag = after_div->tag(this);
ClkInfo *prev_clk_info = prev_tag->clkInfo();
Arrival prev_arrival = search_->clkPathArrival(after_div);
for (int i = paths.size() - 1; i >= 0; i--) {
int path_idx_max = paths.size() - 1;
// paths[0] is the path endpoint
for (int i = path_idx_max; i >= 0; i--) {
Path *path = paths[i];
TimingArc *arc = path->prevArc(this);
Edge *edge = path->prevEdge(this);
if (edge) {
Arrival arrival;
PathAnalysisPt *path_ap = path->pathAnalysisPt(this);
ArcDelay arc_delay = search_->deratedDelay(edge->from(graph_),
arc, edge, false, path_ap);
Arrival arrival = prev_arrival + arc_delay;
debugPrint(debug_, "path_enum", 5, "update arrival %s %s %s -> %s",
path->vertex(this)->to_string(this).c_str(),
path->tag(this)->to_string(this).c_str(),
delayAsString(path->arrival(), this),
delayAsString(arrival, this));
path->setArrival(arrival);
prev_arrival = arrival;
const Tag *tag = path->tag(this);
const ClkInfo *clk_info = tag->clkInfo();
if (crprActive()
&& clk_info != prev_clk_info
// D->Q paths use the EN->Q clk info so no need to update.
&& arc->role() != TimingRole::latchDtoQ()) {
// When crpr is enabled the diverion may be from another crpr clk pin,
// so update the tags to use the corresponding ClkInfo.
Tag *updated_tag = search_->findTag(path->transition(this),
path_ap,
prev_clk_info,
tag->isClock(),
tag->inputDelay(),
tag->isSegmentStart(),
tag->states(), false);
path->setTag(updated_tag);
const MinMax *min_max = path->minMax(this);
if (i == path_idx_max
&& edge->role()->isLatchDtoQ()
&& min_max == MinMax::max()) {
ArcDelay arc_delay;
Tag *q_tag;
latches_->latchOutArrival(after_div, arc, edge, path_ap,
q_tag, arc_delay, arrival);
path->setArrival(arrival);
path->setTag(q_tag);
prev_clk_info = q_tag->clkInfo();
}
else {
ArcDelay arc_delay = search_->deratedDelay(edge->from(graph_),
arc, edge, false, path_ap);
arrival = prev_arrival + arc_delay;
path->setArrival(arrival);
const Tag *tag = path->tag(this);
const ClkInfo *clk_info = tag->clkInfo();
if (crprActive()
&& clk_info != prev_clk_info
// D->Q paths use the EN->Q clk info so no need to update.
&& arc->role() != TimingRole::latchDtoQ()) {
// When crpr is enabled the diverion may be from another crpr clk pin,
// so update the tags to use the corresponding ClkInfo.
Tag *updated_tag = search_->findTag(path->transition(this),
path_ap,
prev_clk_info,
tag->isClock(),
tag->inputDelay(),
tag->isSegmentStart(),
tag->states(), false);
path->setTag(updated_tag);
}
debugPrint(debug_, "path_enum", 5, "update arrival %s %s %s -> %s",
path->vertex(this)->to_string(this).c_str(),
path->tag(this)->to_string(this).c_str(),
delayAsString(path->arrival(), this),
delayAsString(arrival, this));
}
prev_arrival = arrival;
}
}
}

View File

@ -549,8 +549,7 @@ ReportPath::reportFull(const PathEndLatchCheck *end) const
if (ignore_clk_latency) {
// Based on reportSrcPath.
reportPathHeader();
reportPath3(end->path(), expanded, false, false, 0.0,
end->sourceClkOffset(this));
reportPath3(end->path(), expanded, false, end->sourceClkOffset(this));
}
else
reportSrcPath(end, expanded);
@ -716,8 +715,7 @@ ReportPath::reportFull(const PathEndPathDelay *end) const
if (end->ignoreClkLatency(this)) {
// Based on reportSrcPath.
reportPathHeader();
reportPath3(end->path(), expanded, false, false, 0.0,
end->sourceClkOffset(this));
reportPath3(end->path(), expanded, false, end->sourceClkOffset(this));
}
else
reportSrcPath(end, expanded);
@ -935,11 +933,9 @@ ReportPath::reportFull(const PathEndDataCheck *end) const
const ClockEdge *tgt_clk_edge = end->targetClkEdge(this);
float prev = delayAsFloat(clk_arrival) + src_offset;
float offset = prev - delayAsFloat(clk_delay) - tgt_clk_edge->time();
reportPath5(data_clk_path, clk_expanded, clk_expanded.startIndex(),
clk_expanded.size() - 1,
data_clk_path->clkInfo(search_)->isPropagated(), false,
// Delay to startpoint is already included.
prev, offset);
// Delay to startpoint is already included.
reportPath6(data_clk_path, clk_expanded, clk_expanded.startIndex(),
true, false, prev, offset);
}
reportRequired(end, checkRoleReason(end));
reportSlack(end);
@ -1103,6 +1099,7 @@ ReportPath::reportJson(const PathEnd *end,
sdc_network_->pathName(endpoint));
const ClockEdge *src_clk_edge = end->sourceClkEdge(this);
const Path *src_clk_path = expanded.clkPath();
const Path *tgt_clk_path = end->targetClkPath();
if (src_clk_edge) {
stringAppend(result, " \"source_clock\": \"%s\",\n",
@ -1110,6 +1107,8 @@ ReportPath::reportJson(const PathEnd *end,
stringAppend(result, " \"source_clock_edge\": \"%s\",\n",
src_clk_edge->transition()->name());
}
if (src_clk_path)
reportJson(src_clk_path, "source_clock_path", 2, true, result);
reportJson(expanded, "source_path", 2, !end->isUnconstrained(), result);
const ClockEdge *tgt_clk_edge = end->targetClkEdge(this);
@ -1180,7 +1179,7 @@ ReportPath::reportJson(const PathExpanded &expanded,
string &result) const
{
stringAppend(result, "%*s\"%s\": [\n", indent, "", path_name);
for (size_t i = 0; i < expanded.size(); i++) {
for (size_t i = expanded.startIndex(); i < expanded.size(); i++) {
const Path *path = expanded.path(i);
const Pin *pin = path->vertex(this)->pin();
const Net *net = network_->net(pin);
@ -1657,7 +1656,7 @@ ReportPath::reportSkewClkPath(const char *arrival_msg,
insertion, latency);
reportClkSrcLatency(insertion, clk_time, early_late);
PathExpanded clk_expanded(clk_path, this);
reportPath2(clk_path, clk_expanded, false, 0.0);
reportPath1(clk_path, clk_expanded, false, 0.0);
}
}
else {
@ -2226,8 +2225,8 @@ ReportPath::reportTgtClk(const PathEnd *end,
PathExpanded clk_expanded(clk_path, this);
float insertion_offset = tgtClkInsertionOffet(clk_path, early_late,
path_ap);
reportPath5(clk_path, clk_expanded, 0, clk_expanded.size() - 1, is_prop,
reportClkPath(), delay_zero, time_offset + insertion_offset);
reportPath6(clk_path, clk_expanded, 0, is_prop, reportClkPath(),
delay_zero, time_offset + insertion_offset);
}
else {
// Output departure.
@ -2374,7 +2373,7 @@ ReportPath::reportGenClkSrcAndPath(const Path *path,
time_offset, clk_used_as_data);
if (path) {
PathExpanded expanded(path, this);
reportPath4(path, expanded, skip_first_path, false, clk_used_as_data,
reportPath2(path, expanded, skip_first_path, clk_used_as_data,
path_time_offset);
}
}
@ -2416,7 +2415,7 @@ ReportPath::reportGenClkSrcPath1(const Clock *clk,
reportClkSrcLatency(insertion, gclk_time, early_late);
}
PathExpanded src_expanded(src_path, this);
reportPath4(src_path, src_expanded, skip_first_path, false,
reportPath2(src_path, src_expanded, skip_first_path,
clk_used_as_data, gclk_time);
if (!clk->isPropagated())
reportLine("clock network delay (ideal)", 0.0,
@ -2600,11 +2599,51 @@ ReportPath::reportPathFull(const Path *path) const
////////////////////////////////////////////////////////////////
// Main entry point for reporting a path.
void
ReportPath::reportPath1(const Path *path,
const PathExpanded &expanded,
bool clk_used_as_data,
float time_offset) const
{
reportPath2(path, expanded, false, clk_used_as_data, time_offset);
}
// Alternate entry point with skip_first_path arg.
void
ReportPath::reportPath2(const Path *path,
const PathExpanded &expanded,
bool skip_first_path,
bool clk_used_as_data,
float time_offset) const
{
bool clk_is_propagated = path->clkInfo(search_)->isPropagated();
bool report_clk_path = (reportClkPath() && clk_is_propagated)
|| clk_used_as_data;
bool propagated_clk = clk_is_propagated || clk_used_as_data;
reportPath4(path, expanded, skip_first_path, propagated_clk,
report_clk_path, time_offset);
}
// Alternate entry point with report_clk_path arg.
void
ReportPath::reportPath3(const Path *path,
const PathExpanded &expanded,
bool report_clk_path,
float time_offset) const
{
bool propagated_clk = path->clkInfo(search_)->isPropagated();
reportPath4(path, expanded, false, propagated_clk,
report_clk_path, time_offset);
}
void
ReportPath::reportPath4(const Path *path,
const PathExpanded &expanded,
bool skip_first_path,
bool propagated_clk,
bool report_clk_path,
float time_offset) const
{
const Path *d_path, *q_path;
Edge *d_q_edge;
@ -2617,11 +2656,11 @@ ReportPath::reportPath1(const Path *path,
if (latch_enable_path) {
const EarlyLate *early_late = latch_enable_path->minMax(this);
latch_enable_time = search_->clkPathArrival(latch_enable_path);
if (reportClkPath()) {
if (report_clk_path) {
PathExpanded enable_expanded(latch_enable_path, this);
// Report the path to the latch enable.
reportPath2(latch_enable_path, enable_expanded, false,
time_offset);
reportPath5(latch_enable_path, enable_expanded, skip_first_path,
propagated_clk, report_clk_path, time_offset);
}
Arrival time = latch_enable_time + latch_time_given;
Arrival incr = latch_time_given;
@ -2631,86 +2670,45 @@ ReportPath::reportPath1(const Path *path,
reportLine("time borrowed from startpoint", incr, time, early_late);
// Override latch D arrival with enable + given.
reportPathLine(expanded.path(0), delay_zero, time, "latch_D");
bool propagated_clk = path->clkInfo(search_)->isPropagated();
bool report_clk_path = path->isClock(search_) || reportClkPath();
reportPath5(path, expanded, 1, expanded.size() - 1,
propagated_clk, report_clk_path,
reportPath6(path, expanded, 1, propagated_clk, report_clk_path,
latch_enable_time + latch_time_given, time_offset);
}
}
else
reportPath2(path, expanded, clk_used_as_data, time_offset);
}
void
ReportPath::reportPath2(const Path *path,
const PathExpanded &expanded,
bool clk_used_as_data,
float time_offset) const
{
// Report the clock path if the end is a clock or we wouldn't have
// anything to report.
bool report_clk_path = clk_used_as_data
|| (reportClkPath()
&& path->clkInfo(search_)->isPropagated());
reportPath3(path, expanded, clk_used_as_data, report_clk_path,
delay_zero, time_offset);
}
void
ReportPath::reportPath3(const Path *path,
const PathExpanded &expanded,
bool clk_used_as_data,
bool report_clk_path,
Arrival prev_time,
float time_offset) const
{
bool propagated_clk = clk_used_as_data
|| path->clkInfo(search_)->isPropagated();
size_t path_last_index = expanded.size() - 1;
reportPath5(path, expanded, 0, path_last_index, propagated_clk,
report_clk_path, prev_time, time_offset);
}
void
ReportPath::reportPath4(const Path *path,
const PathExpanded &expanded,
bool skip_first_path,
bool skip_last_path,
bool clk_used_as_data,
float time_offset) const
{
size_t path_first_index = 0;
Arrival prev_time(0.0);
if (skip_first_path) {
path_first_index = 1;
const Path *start = expanded.path(0);
prev_time = start->arrival() + time_offset;
}
size_t path_last_index = expanded.size() - 1;
if (skip_last_path
&& path_last_index > 1)
path_last_index--;
bool propagated_clk = clk_used_as_data
|| path->clkInfo(search_)->isPropagated();
// Report the clock path if the end is a clock or we wouldn't have
// anything to report.
bool report_clk_path = path->isClock(search_)
|| (reportClkPath() && propagated_clk);
reportPath5(path, expanded, path_first_index, path_last_index,
propagated_clk, report_clk_path, prev_time, time_offset);
reportPath5(path, expanded, skip_first_path, propagated_clk,
report_clk_path, time_offset);
}
void
ReportPath::reportPath5(const Path *path,
const PathExpanded &expanded,
bool skip_first_path,
bool propagated_clk,
bool report_clk_path,
float time_offset) const
{
size_t path_first_index = 0;
Arrival prev_time = 0.0;
if (skip_first_path) {
path_first_index = 1;
const Path *start = expanded.path(0);
prev_time = start->arrival() + time_offset;
}
reportPath6(path, expanded, path_first_index, propagated_clk,
report_clk_path, prev_time, time_offset);
}
// This does the real workk of reporting an expanded path.
void
ReportPath::reportPath6(const Path *path,
const PathExpanded &expanded,
size_t path_first_index,
size_t path_last_index,
bool propagated_clk,
bool report_clk_path,
Arrival prev_time,
float time_offset) const
{
size_t path_last_index = expanded.size() - 1;
const MinMax *min_max = path->minMax(this);
DcalcAnalysisPt *dcalc_ap = path->pathAnalysisPt(this)->dcalcAnalysisPt();
DcalcAPIndex ap_index = dcalc_ap->index();
@ -2986,8 +2984,7 @@ ReportPath::reportInputExternalDelay(const Path *first_path,
pathInputDelayRefPath(first_path, input_delay, ref_path);
if (!ref_path.isNull() && reportClkPath()) {
PathExpanded ref_expanded(&ref_path, this);
reportPath3(&ref_path, ref_expanded, false, true,
delay_zero, 0.0);
reportPath3(&ref_path, ref_expanded, true, 0.0);
}
}
float input_arrival =

View File

@ -302,24 +302,28 @@ protected:
float time_offset) const;
void reportPath2(const Path *path,
const PathExpanded &expanded,
bool skip_first_path,
bool clk_used_as_data,
float time_offset) const;
void reportPath3(const Path *path,
const PathExpanded &expanded,
bool clk_used_as_data,
bool report_clk_path,
Arrival prev_time,
float time_offset) const;
void reportPath4(const Path *path,
const PathExpanded &expanded,
bool clk_used_as_data,
bool skip_first_path,
bool skip_last_path,
bool propagated_clk,
bool report_clk_path,
float time_offset) const;
void reportPath5(const Path *path,
const PathExpanded &expanded,
bool skip_first_path,
bool propagated_clk,
bool report_clk_path,
float time_offset) const;
void reportPath6(const Path *path,
const PathExpanded &expanded,
size_t path_first_index,
size_t path_last_index,
bool propagated_clk,
bool report_clk_path,
Arrival prev_time,

View File

@ -554,15 +554,20 @@ Search::deleteFilterTagGroups()
for (TagGroupIndex i = 0; i < tag_group_next_; i++) {
TagGroup *group = tag_groups_[i];
if (group
&& group->hasFilterTag()) {
tag_group_set_->erase(group);
tag_groups_[group->index()] = nullptr;
tag_group_free_indices_.push_back(i);
delete group;
}
&& group->hasFilterTag())
deleteTagGroup(group);
}
}
void
Search::deleteTagGroup(TagGroup *group)
{
tag_group_set_->erase(group);
tag_groups_[group->index()] = nullptr;
tag_group_free_indices_.push_back(group->index());
delete group;
}
void
Search::deleteFilterTags()
{
@ -2777,6 +2782,15 @@ Search::setVertexArrivals(Vertex *vertex,
filtered_arrivals_->insert(vertex);
}
}
if (tag_group != prev_tag_group) {
LockGuard lock(tag_group_ref_count_lock_);
tag_group->incrRefCount();
if (prev_tag_group) {
prev_tag_group->decrRefCount();
if (prev_tag_group->refCount() == 0)
deleteTagGroup(prev_tag_group);
}
}
}
}
@ -2819,12 +2833,14 @@ ReportPathLess::operator()(const Path *path1,
}
void
Search::reportArrivals(Vertex *vertex) const
Search::reportArrivals(Vertex *vertex,
bool report_tag_index) const
{
report_->reportLine("Vertex %s", vertex->to_string(this).c_str());
TagGroup *tag_group = tagGroup(vertex);
if (tag_group) {
report_->reportLine("Group %u", tag_group->index());
if (report_tag_index)
report_->reportLine("Group %u", tag_group->index());
std::vector<const Path*> paths;
VertexPathIterator path_iter(vertex, this);
while (path_iter.hasNext()) {
@ -2859,7 +2875,7 @@ Search::reportArrivals(Vertex *vertex) const
path_ap->pathMinMax()->to_string().c_str(),
delayAsString(path->arrival(), this),
req,
tag->to_string(true, false, this).c_str(),
tag->to_string(report_tag_index, false, this).c_str(),
prev_str.c_str());
}
}

View File

@ -264,9 +264,10 @@ report_tag_groups()
}
void
report_tag_arrivals_cmd(Vertex *vertex)
report_tag_arrivals_cmd(Vertex *vertex,
bool report_tag_index)
{
Sta::sta()->search()->reportArrivals(vertex);
Sta::sta()->search()->reportArrivals(vertex, report_tag_index);
}
void

View File

@ -355,7 +355,7 @@ tagCmp(const Tag *tag1,
return tagStateCmp(tag1, tag2);
}
int
bool
tagEqual(const Tag *tag1,
const Tag *tag2)
{

View File

@ -140,6 +140,9 @@ public:
const Tag *tag2) const;
};
bool
tagEqual(const Tag *tag1,
const Tag *tag2);
int
tagCmp(const Tag *tag1,
const Tag *tag2,

View File

@ -44,6 +44,7 @@ TagGroup::TagGroup(TagGroupIndex index,
bool has_loop_tag) :
path_index_map_(path_index_map),
hash_(pathIndexMapHash(path_index_map)),
ref_count_(0),
index_(index),
has_clk_tag_(has_clk_tag),
has_genclk_src_tag_(has_genclk_src_tag),
@ -56,6 +57,7 @@ TagGroup::TagGroup(TagGroupIndex index,
TagGroup::TagGroup(TagGroupBldr *tag_bldr) :
path_index_map_(&tag_bldr->pathIndexMap()),
hash_(pathIndexMapHash(path_index_map_)),
ref_count_(0),
own_path_map_(false)
{
}
@ -66,6 +68,18 @@ TagGroup::~TagGroup()
delete path_index_map_;
}
void
TagGroup::incrRefCount()
{
ref_count_++;
}
void
TagGroup::decrRefCount()
{
ref_count_--;
}
size_t
TagGroup::pathIndexMapHash(PathIndexMap *path_index_map)
{

View File

@ -65,6 +65,9 @@ public:
size_t pathIndex(Tag *tag) const;
PathIndexMap *pathIndexMap() const { return path_index_map_; }
bool hasTag(Tag *tag) const;
void incrRefCount();
void decrRefCount();
int refCount() const { return ref_count_; }
protected:
static size_t pathIndexMapHash(PathIndexMap *path_index_map);
@ -72,6 +75,7 @@ protected:
// tag -> path index
PathIndexMap *path_index_map_;
size_t hash_;
int ref_count_;
unsigned int index_:tag_group_index_bits;
bool has_clk_tag_:1;
bool has_genclk_src_tag_:1;

View File

@ -7,7 +7,7 @@
"endpoint": "_1416_[0]/D",
"source_clock": "clk",
"source_clock_edge": "rise",
"source_path": [
"source_clock_path": [
{
"instance": "",
"cell": "counter",
@ -25,7 +25,9 @@
"net": "clk",
"arrival": 0.000e+00,
"slew": 0.000e+00
},
}
],
"source_path": [
{
"instance": "_1415_",
"cell": "sky130_fd_sc_hd__dfrtp_1",

View File

@ -89,7 +89,9 @@ PatternMatch::compileRegexp()
anchored_pattern += '$';
Tcl_Obj *pattern_obj = Tcl_NewStringObj(anchored_pattern.c_str(),
anchored_pattern.size());
Tcl_IncrRefCount(pattern_obj);
regexp_ = Tcl_GetRegExpFromObj(interp_, pattern_obj, flags);
Tcl_DecrRefCount(pattern_obj);
if (regexp_ == nullptr && interp_)
throw RegexpCompileError(pattern_);
}

View File

@ -117,7 +117,7 @@ public:
int n_putback = gptr() - eback();
if ( n_putback > 4)
n_putback = 4;
memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
memmove( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
int num = gzread( file, buffer+4, bufferSize-4);
if (num <= 0) // ERROR or EOF