diff --git a/graph/Graph.cc b/graph/Graph.cc index 66cbc395..936f6d2b 100644 --- a/graph/Graph.cc +++ b/graph/Graph.cc @@ -520,6 +520,26 @@ Graph::arrivals(Vertex *vertex) return arrivals_.pointer(vertex->arrivals()); } +Required * +Graph::makeRequireds(Vertex *vertex, + uint32_t count) +{ + Required *requireds; + ArrivalId id; + { + UniqueLock lock(arrivals_lock_); + arrivals_.make(count, requireds, id); + } + vertex->setRequireds(id); + return requireds; +} + +Required * +Graph::requireds(Vertex *vertex) +{ + return arrivals_.pointer(vertex->requireds()); +} + void Graph::clearArrivals() { @@ -1025,8 +1045,8 @@ Vertex::init(Pin *pin, in_edges_ = edge_id_null; out_edges_ = edge_id_null; arrivals_ = arrival_null; + requireds_ = arrival_null; prev_paths_ = prev_path_null; - has_requireds_ = false; tag_group_index_ = tag_group_index_max; slew_annotated_ = false; sim_value_ = unsigned(LogicValue::unknown); @@ -1157,25 +1177,31 @@ Vertex::setArrivals(ArrivalId id) arrivals_ = id; } +void +Vertex::setRequireds(ArrivalId id) +{ + requireds_ = id; +} + +void +Vertex::deleteRequireds() +{ + requireds_ = arrival_null; +} + void Vertex::setPrevPaths(PrevPathId prev_paths) { prev_paths_ = prev_paths; } -void -Vertex::setHasRequireds(bool has_req) -{ - has_requireds_ = has_req; -} - void Vertex::deletePaths() { arrivals_ = arrival_null; + requireds_ = arrival_null; prev_paths_ = prev_path_null; tag_group_index_ = tag_group_index_max; - has_requireds_ = false; crpr_path_pruning_disabled_ = false; } diff --git a/include/sta/Graph.hh b/include/sta/Graph.hh index b6bc9876..70ed6a02 100644 --- a/include/sta/Graph.hh +++ b/include/sta/Graph.hh @@ -101,7 +101,11 @@ public: Arrival *makeArrivals(Vertex *vertex, uint32_t count); Arrival *arrivals(Vertex *vertex); + Required *makeRequireds(Vertex *vertex, + uint32_t count); + Required *requireds(Vertex *vertex); void clearArrivals(); + size_t arrivalCount() const { return arrivals_.size(); } PathVertexRep *makePrevPaths(Vertex *vertex, uint32_t count); PathVertexRep *prevPaths(Vertex *vertex) const; @@ -278,11 +282,11 @@ public: LevelColor color() const { return static_cast(color_); } void setColor(LevelColor color); ArrivalId arrivals() { return arrivals_; } + ArrivalId requireds() { return requireds_; } + bool hasRequireds() const { return requireds_ != arrival_null; } + void deleteRequireds(); PrevPathId prevPaths() const { return prev_paths_; } void setPrevPaths(PrevPathId id); - // Requireds optionally follow arrivals in the same array. - bool hasRequireds() const { return has_requireds_; } - void setHasRequireds(bool has_req); TagGroupIndex tagGroupIndex() const; void setTagGroupIndex(TagGroupIndex tag_index); // Slew is annotated by sdc set_annotated_transition cmd. @@ -337,9 +341,11 @@ protected: bool is_bidirect_drvr, bool is_reg_clk); void setArrivals(ArrivalId id); + void setRequireds(ArrivalId id); Pin *pin_; ArrivalId arrivals_; + ArrivalId requireds_; PrevPathId prev_paths_; EdgeId in_edges_; // Edges to this vertex. EdgeId out_edges_; // Edges from this vertex. @@ -357,7 +363,6 @@ protected: unsigned color_:2; // LogicValue gcc barfs if this is dcl'd. unsigned sim_value_:3; - bool has_requireds_:1; // Bidirect pins have two vertices. // This flag distinguishes the driver and load vertices. bool is_bidirect_drvr_:1; diff --git a/search/PathVertex.cc b/search/PathVertex.cc index 88e49bab..cf1355b4 100644 --- a/search/PathVertex.cc +++ b/search/PathVertex.cc @@ -245,15 +245,12 @@ PathVertex::setArrival(Arrival arrival, const Required & PathVertex::required(const StaState *sta) const { - if (tag_ && vertex_->hasRequireds()) { - const Search *search = sta->search(); - TagGroup *tag_group = search->tagGroup(vertex_); - int req_index = tag_group->requiredIndex(arrival_index_); - Arrival *arrivals = sta->graph()->arrivals(vertex_); - return arrivals[req_index]; + if (tag_) { + Required *requireds = sta->graph()->requireds(vertex_); + if (requireds) + return requireds[arrival_index_]; } - else - return delayInitValue(minMax(sta)->opposite()); + return delayInitValue(minMax(sta)->opposite()); } void @@ -261,27 +258,21 @@ PathVertex::setRequired(const Required &required, const StaState *sta) { Graph *graph = sta->graph(); - const Search *search = sta->search(); - TagGroup *tag_group = search->tagGroup(vertex_); - Arrival *arrivals = graph->arrivals(vertex_); - int arrival_count = tag_group->arrivalCount(); - if (!vertex_->hasRequireds()) { - Arrival *new_arrivals = graph->makeArrivals(vertex_, arrival_count * 2); - for (int i = 0; i < arrival_count; i++) - new_arrivals[i] =arrivals[i]; - vertex_->setHasRequireds(true); - arrivals = new_arrivals; + Required *requireds = graph->requireds(vertex_); + if (requireds == nullptr) { + const Search *search = sta->search(); + TagGroup *tag_group = search->tagGroup(vertex_); + int arrival_count = tag_group->arrivalCount(); + requireds = graph->makeRequireds(vertex_, arrival_count); } - int req_index = arrival_index_ + arrival_count; - arrivals[req_index] = required; + requireds[arrival_index_] = required; } void PathVertex::deleteRequireds(Vertex *vertex, const StaState *) { - vertex->setHasRequireds(false); - // Don't bother reclaiming requieds from arrival table. + vertex->deleteRequireds(); } bool diff --git a/search/Search.cc b/search/Search.cc index cd380f19..a8f4f564 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -2685,10 +2685,7 @@ Search::setVertexArrivals(Vertex *vertex, bool has_requireds = vertex->hasRequireds(); // Reuse arrival array if it is the same size. if (prev_tag_group - && arrival_count == prev_tag_group->arrivalCount() - && (!has_requireds - // Requireds can only be reused if the tag group is unchanged. - || tag_group == prev_tag_group)) { + && arrival_count == prev_tag_group->arrivalCount()) { if (tag_bldr->hasClkTag() || tag_bldr->hasGenClkSrcTag()) { if (prev_paths == nullptr) prev_paths = graph_->makePrevPaths(vertex, arrival_count); @@ -2700,6 +2697,13 @@ Search::setVertexArrivals(Vertex *vertex, } tag_bldr->copyArrivals(tag_group, prev_arrivals, prev_paths); vertex->setTagGroupIndex(tag_group->index()); + + if (has_requireds) { + requiredInvalid(vertex); + if (tag_group != prev_tag_group) + // Requireds can only be reused if the tag group is unchanged. + vertex->deleteRequireds(); + } } else { Arrival *arrivals = graph_->makeArrivals(vertex, arrival_count); @@ -2712,7 +2716,7 @@ Search::setVertexArrivals(Vertex *vertex, if (has_requireds) { requiredInvalid(vertex); - vertex->setHasRequireds(false); + vertex->deleteRequireds(); } } } @@ -2724,6 +2728,7 @@ Search::reportArrivals(Vertex *vertex) const report_->reportLine("Vertex %s", vertex->name(sdc_network_)); TagGroup *tag_group = tagGroup(vertex); Arrival *arrivals = graph_->arrivals(vertex); + Required *requireds = graph_->requireds(vertex); if (tag_group) { report_->reportLine("Group %u", tag_group->index()); ArrivalMap::Iterator arrival_iter(tag_group->arrivalMap()); @@ -2734,13 +2739,8 @@ Search::reportArrivals(Vertex *vertex) const PathAnalysisPt *path_ap = tag->pathAnalysisPt(this); const RiseFall *rf = tag->transition(); const char *req = "?"; - if (vertex->hasRequireds()) { - int req_index; - bool exists; - tag_group->requiredIndex(tag, req_index, exists); - if (exists) - req = delayAsString(arrivals[req_index], this); - } + if (requireds) + req = delayAsString(requireds[arrival_index], this); bool report_clk_prev = false; const char *clk_prev = ""; if (report_clk_prev diff --git a/search/TagGroup.cc b/search/TagGroup.cc index 7b015bd0..fcc230a3 100644 --- a/search/TagGroup.cc +++ b/search/TagGroup.cc @@ -86,22 +86,6 @@ TagGroup::arrivalIndex(Tag *tag, arrival_map_->findKey(tag, arrival_index, exists); } -void -TagGroup::requiredIndex(Tag *tag, - int &req_index, - bool &exists) const -{ - arrivalIndex(tag, req_index, exists); - if (exists) - req_index += arrivalCount(); -} - -int -TagGroup::requiredIndex(int arrival_index) const -{ - return arrival_index + arrivalCount(); -} - void TagGroup::report(const StaState *sta) const { diff --git a/search/TagGroup.hh b/search/TagGroup.hh index b08ac3ec..5d723779 100644 --- a/search/TagGroup.hh +++ b/search/TagGroup.hh @@ -57,10 +57,6 @@ public: void arrivalIndex(Tag *tag, int &arrival_index, bool &exists) const; - void requiredIndex(Tag *tag, - int &req_index, - bool &exists) const; - int requiredIndex(int arrival_index) const; ArrivalMap *arrivalMap() const { return arrival_map_; } bool hasTag(Tag *tag) const; diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index a05b966a..3fe2e0a4 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -5301,6 +5301,12 @@ arrival_count() return Sta::sta()->arrivalCount(); } +int +graph_arrival_count() +{ + return Sta::sta()->graph()->arrivalCount(); +} + void delete_all_memory() {