bfs update kahns prep
commit 4075953c9798444b9d5275f8fa0320f74b9bf1ef
Author: James Cherry <cherry@CerezoBook.local>
Date: Sat Jul 4 09:00:48 2026 -0700
bfs resort hasNext
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit 4fb0dd19e479f507935129fe940bcd1cf93b29d0
Author: James Cherry <cherry@CerezoBook.local>
Date: Thu Jul 2 12:23:54 2026 -0700
ApiChanges
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit 510afbc1403c9fd2b764b4f3a71dddabd696f052
Author: James Cherry <cherry@CerezoBook.local>
Date: Thu Jul 2 11:07:44 2026 -0700
bfs enqueueFanin/out
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit 9a5aa570e910c289b276a519bdf532dfa2e28c5f
Author: James Cherry <cherry@CerezoBook.local>
Date: Thu Jul 2 10:41:27 2026 -0700
Revert "bfs continueFrom/enqueueFanin/out"
This reverts commit d18498c947a7df2b615fafda38fbdbe8033eca9d.
commit 02a253ab252f6637cfea29bdd788cb25da16813d
Author: James Cherry <cherry@CerezoBook.local>
Date: Thu Jul 2 08:21:49 2026 -0700
Revert "Bfs rm search_pred"
This reverts commit d858b3380b5e1d81ff6162b6378672a6099a246f.
commit 0adf03613d91c5774545d12cba1dc52052ca732a
Author: James Cherry <cherry@CerezoBook.local>
Date: Thu Jul 2 08:08:04 2026 -0700
Genclks::ensureMaster
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit 089b373c548b77f9189a2617c3168867de620dfe
Author: James Cherry <cherry@CerezoBook.local>
Date: Wed Jul 1 17:50:43 2026 -0700
Search::ensureDownstreamClkPins() use dfs
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit 000ca16adb9bdcb92266e5f242629bc3e8612658
Author: James Cherry <cherry@CerezoBook.local>
Date: Wed Jul 1 10:03:57 2026 -0700
ApiChangeLog
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit d858b3380b5e1d81ff6162b6378672a6099a246f
Author: James Cherry <cherry@CerezoBook.local>
Date: Wed Jul 1 09:56:53 2026 -0700
Bfs rm search_pred
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit d18498c947a7df2b615fafda38fbdbe8033eca9d
Author: James Cherry <cherry@CerezoBook.local>
Date: Wed Jul 1 08:07:15 2026 -0700
bfs continueFrom/enqueueFanin/out
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit a8c55b12b3ad7a1041766775727ad758ae8c6d18
Author: James Cherry <cherry@CerezoBook.local>
Date: Tue Jun 30 10:07:46 2026 -0700
bfs continue
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit 8530dcd86b7ee736f1858143c3b2cee57cdbc991
Author: James Cherry <cherry@CerezoBook.local>
Date: Tue Jun 30 07:15:28 2026 -0700
Graph::visitFanin/out uninline edge iter
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit 1ba1f4576f4b72c64db742369a63dcf8726ba002
Author: James Cherry <cherry@CerezoBook.local>
Date: Mon Jun 29 21:09:17 2026 -0700
BfsIterator rm Iterator<Vector> subclass
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit b3ddd2580298958ad6da8225ecac0d255315504c
Author: James Cherry <cherry@CerezoBook.local>
Date: Mon Jun 29 20:15:23 2026 -0700
ClkNetwork::findClkPins use VertexQueue instead of bfs
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit 9e73154db48a7301be4039a25aec1fef589ef18a
Author: James Cherry <cherry@CerezoBook.local>
Date: Mon Jun 29 18:39:39 2026 -0700
Search::ensureDownstreamClkPins use VertexQueue
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit 9cd1b160e126ccacc47375ef508fdbb580bfa162
Author: James Cherry <cherry@CerezoBook.local>
Date: Mon Jun 29 11:18:03 2026 -0700
comment
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit 0baf3838e2b8faa5fea560b0c95431b277631fea
Author: James Cherry <cherry@CerezoBook.local>
Date: Mon Jun 29 10:57:39 2026 -0700
findClkArrivals use invalid for clk fringe
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit e82ccd10a5e4bd69e41ce889685d7a130ae79ed6
Author: James Cherry <cherry@CerezoBook.local>
Date: Sun Jun 28 20:36:48 2026 -0700
Search::findClkArrivals
Signed-off-by: James Cherry <cherry@CerezoBook.local>
commit cb66a72686c8728141c72ceb593b8a4b895ff696
Author: James Cherry <cherry@CerezoBook.local>
Date: Sun Jun 28 10:11:55 2026 -0700
rm Search::postponeClkFanouts
Signed-off-by: James Cherry <cherry@CerezoBook.local>
Signed-off-by: James Cherry <cherry@CerezoBook.local>
This commit is contained in:
parent
900116cf72
commit
2c866d5f2d
|
|
@ -395,7 +395,7 @@ GraphDelayCalc::seedRootSlew(Vertex *vertex,
|
|||
seedDrvrSlew(vertex, arc_delay_calc);
|
||||
else
|
||||
seedLoadSlew(vertex);
|
||||
iter_->enqueueAdjacentVertices(vertex);
|
||||
iter_->enqueueFanout(vertex);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -703,7 +703,7 @@ GraphDelayCalc::findVertexDelay(Vertex *vertex,
|
|||
// change when non-incremental to stride past annotations.
|
||||
if (!incremental_
|
||||
|| loadSlewsChanged(load_slews_prev, load_pin_index_map))
|
||||
iter_->enqueueAdjacentVertices(vertex);
|
||||
iter_->enqueueFanout(vertex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -711,7 +711,7 @@ GraphDelayCalc::findVertexDelay(Vertex *vertex,
|
|||
enqueueTimingChecksEdges(vertex);
|
||||
// Enqueue driver vertices from this input load.
|
||||
if (propagate)
|
||||
iter_->enqueueAdjacentVertices(vertex);
|
||||
iter_->enqueueFanout(vertex);
|
||||
}
|
||||
}
|
||||
// Bidirect port drivers are enqueued by their load vertex in
|
||||
|
|
|
|||
|
|
@ -581,9 +581,9 @@ Graph::visitFanouts(Vertex *vertex,
|
|||
const VertexFn &fn)
|
||||
{
|
||||
if (pred->searchFrom(vertex)) {
|
||||
for (Edge *edge = this->edge(vertex->out_edges_);
|
||||
edge;
|
||||
edge = this->edge(edge->vertex_out_next_)) {
|
||||
VertexOutEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *to_vertex = this->vertex(edge->to_);
|
||||
if (pred->searchThru(edge)
|
||||
&& pred->searchTo(to_vertex))
|
||||
|
|
@ -598,9 +598,9 @@ Graph::visitFanoutEdges(Vertex *vertex,
|
|||
const EdgeFn &fn)
|
||||
{
|
||||
if (pred->searchFrom(vertex)) {
|
||||
for (Edge *edge = this->edge(vertex->out_edges_);
|
||||
edge;
|
||||
edge = this->edge(edge->vertex_out_next_)) {
|
||||
VertexOutEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *to_vertex = this->vertex(edge->to_);
|
||||
if (pred->searchThru(edge)
|
||||
&& pred->searchTo(to_vertex))
|
||||
|
|
@ -615,9 +615,9 @@ Graph::visitFanins(Vertex *vertex,
|
|||
const VertexFn &fn)
|
||||
{
|
||||
if (pred->searchFrom(vertex)) {
|
||||
for (Edge *edge = this->edge(vertex->in_edges_);
|
||||
edge;
|
||||
edge = this->edge(edge->vertex_in_next_)) {
|
||||
VertexInEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *from_vertex = this->vertex(edge->from_);
|
||||
if (pred->searchThru(edge)
|
||||
&& pred->searchFrom(from_vertex))
|
||||
|
|
@ -632,9 +632,9 @@ Graph::visitFaninEdges(Vertex *vertex,
|
|||
const EdgeFn &fn)
|
||||
{
|
||||
if (pred->searchFrom(vertex)) {
|
||||
for (Edge *edge = this->edge(vertex->in_edges_);
|
||||
edge;
|
||||
edge = this->edge(edge->vertex_in_next_)) {
|
||||
VertexOutEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *from_vertex = this->vertex(edge->from_);
|
||||
if (pred->searchThru(edge)
|
||||
&& pred->searchFrom(from_vertex))
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -38,6 +39,8 @@ class SearchPred;
|
|||
class BfsFwdIterator;
|
||||
class BfsBkwdIterator;
|
||||
|
||||
using VertexFn = std::function<void(Vertex*)>;
|
||||
|
||||
// LevelQueue is a vector of vertex vectors indexed by logic level.
|
||||
using LevelQueue = std::vector<VertexSeq>;
|
||||
|
||||
|
|
@ -50,26 +53,23 @@ using LevelQueue = std::vector<VertexSeq>;
|
|||
// Vertices are marked as being in the queue by using a flag on
|
||||
// the vertex indexed by bfs_index. A unique flag is only needed
|
||||
// if the BFS in in use when other BFS's are simultaneously in use.
|
||||
class BfsIterator : public StaState,
|
||||
public Iterator<Vertex*>
|
||||
class BfsIterator : public StaState
|
||||
{
|
||||
public:
|
||||
// Make sure that the BFS queue is deep enough for the max logic level.
|
||||
void ensureSize();
|
||||
// Reset to virgin state.
|
||||
void clear();
|
||||
// Apply fn to each vertex and clear.
|
||||
void clear(const VertexFn &fn);
|
||||
[[nodiscard]] bool empty() const;
|
||||
// Enqueue a vertex to search from.
|
||||
void enqueue(Vertex *vertex);
|
||||
// Enqueue vertices adjacent to a vertex.
|
||||
void enqueueAdjacentVertices(Vertex *vertex);
|
||||
virtual void enqueueAdjacentVertices(Vertex *vertex) = 0;
|
||||
virtual void enqueueAdjacentVertices(Vertex *vertex,
|
||||
const Mode *mode);
|
||||
virtual void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred,
|
||||
const Mode *mode) = 0;
|
||||
virtual void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred) = 0;
|
||||
|
||||
[[nodiscard]] bool inQueue(Vertex *vertex);
|
||||
void checkInQueue(Vertex *vertex);
|
||||
// Notify iterator that vertex will be deleted.
|
||||
|
|
@ -77,10 +77,6 @@ public:
|
|||
void remove(Vertex *vertex);
|
||||
void reportEntries() const;
|
||||
|
||||
bool hasNext() override;
|
||||
bool hasNext(Level to_level);
|
||||
Vertex *next() override;
|
||||
|
||||
// Apply visitor to all vertices in the queue in level order.
|
||||
// Returns the number of vertices that are visited.
|
||||
virtual int visit(Level to_level,
|
||||
|
|
@ -91,6 +87,10 @@ public:
|
|||
int visitParallel(Level to_level,
|
||||
VertexVisitor *visitor);
|
||||
|
||||
bool hasNext();
|
||||
bool hasNext(Level to_level);
|
||||
Vertex *next();
|
||||
|
||||
protected:
|
||||
BfsIterator(BfsIndex bfs_index,
|
||||
Level level_min,
|
||||
|
|
@ -104,10 +104,10 @@ protected:
|
|||
virtual bool levelLessOrEqual(Level level1,
|
||||
Level level2) const = 0;
|
||||
virtual void incrLevel(Level &level) const = 0;
|
||||
void findNext(Level to_level);
|
||||
void deleteEntries();
|
||||
void checkLevel(Vertex *vertex,
|
||||
Level level);
|
||||
void findNext(Level to_level);
|
||||
|
||||
BfsIndex bfs_index_;
|
||||
Level level_min_;
|
||||
|
|
@ -131,12 +131,13 @@ public:
|
|||
SearchPred *search_pred,
|
||||
StaState *sta);
|
||||
~BfsFwdIterator() override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex) override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred) override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred,
|
||||
const Mode *mode) override;
|
||||
using BfsIterator::enqueueAdjacentVertices;
|
||||
void enqueueFanout(Vertex *vertex);
|
||||
void enqueueFanout(Vertex *vertex,
|
||||
const Mode *mode);
|
||||
|
||||
protected:
|
||||
bool levelLessOrEqual(Level level1,
|
||||
|
|
@ -153,14 +154,17 @@ public:
|
|||
SearchPred *search_pred,
|
||||
StaState *sta);
|
||||
~BfsBkwdIterator() override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex) override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred) override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred,
|
||||
const Mode *mode) override;
|
||||
using BfsIterator::enqueueAdjacentVertices;
|
||||
void enqueueFanin(Vertex *vertex);
|
||||
void enqueueFanin(Vertex *vertex,
|
||||
const Mode *mode);
|
||||
|
||||
protected:
|
||||
void enqueueFanin(Vertex *vertex,
|
||||
SearchPred *search_pred);
|
||||
bool levelLessOrEqual(Level level1,
|
||||
Level level2) const override;
|
||||
bool levelLess(Level level1,
|
||||
|
|
|
|||
|
|
@ -286,8 +286,6 @@ public:
|
|||
TagGroupBldr *tag_bldr);
|
||||
void postponeLatchDataOutputs(Vertex *vertex);
|
||||
void postponeArrivals(Vertex *vertex);
|
||||
void enqueuePendingClkFanouts();
|
||||
void postponeClkFanouts(Vertex *vertex);
|
||||
void seedRequired(Vertex *vertex);
|
||||
void seedRequiredEnqueueFanin(Vertex *vertex);
|
||||
void seedInputDelayArrival(const Pin *pin,
|
||||
|
|
@ -503,12 +501,12 @@ protected:
|
|||
bool is_segment_start,
|
||||
const MinMax *min_max,
|
||||
Scene *scene);
|
||||
void seedClkVertexArrivals();
|
||||
void findClkArrivals1();
|
||||
void enqueueClkRoots();
|
||||
void enqueueInvalidClks();
|
||||
|
||||
void findAllArrivals(bool thru_latches,
|
||||
bool clks_only);
|
||||
void findAllArrivals(bool thru_latches);
|
||||
void findArrivals1(Level level);
|
||||
void findArrivals2(Level level);
|
||||
Tag *mutateTag(Tag *from_tag,
|
||||
const Pin *from_pin,
|
||||
const RiseFall *from_rf,
|
||||
|
|
@ -646,12 +644,9 @@ protected:
|
|||
std::vector<TagIndex> tag_group_free_indices_;
|
||||
std::mutex tag_group_lock_;
|
||||
|
||||
// Latches data outputs to queue on the next search pass.
|
||||
VertexSet postponed_arrivals_;
|
||||
std::mutex postponed_arrivals_lock_;
|
||||
// Clock network endpoints where arrival search was suppended by findClkArrivals().
|
||||
VertexSet postponed_clk_endpoints_;
|
||||
std::mutex postponed_clk_endpoints_lock_;
|
||||
// Arrivals to queue on the next search pass.
|
||||
VertexSet pending_arrivals_;
|
||||
std::mutex pending_arrivals_lock_;
|
||||
|
||||
VertexSet endpoints_;
|
||||
bool endpoints_initialized_{false};
|
||||
|
|
|
|||
205
search/Bfs.cc
205
search/Bfs.cc
|
|
@ -70,13 +70,21 @@ BfsIterator::ensureSize()
|
|||
|
||||
void
|
||||
BfsIterator::clear()
|
||||
{
|
||||
clear([] (Vertex *) {});
|
||||
}
|
||||
|
||||
void
|
||||
BfsIterator::clear(const VertexFn &fn)
|
||||
{
|
||||
Level level = first_level_;
|
||||
while (levelLessOrEqual(level, last_level_)) {
|
||||
VertexSeq &level_vertices = queue_[level];
|
||||
for (Vertex *vertex : level_vertices) {
|
||||
if (vertex)
|
||||
if (vertex) {
|
||||
vertex->setBfsInQueue(bfs_index_, false);
|
||||
fn(vertex);
|
||||
}
|
||||
}
|
||||
level_vertices.clear();
|
||||
incrLevel(level);
|
||||
|
|
@ -115,19 +123,6 @@ BfsIterator::empty() const
|
|||
return levelLess(last_level_, first_level_);
|
||||
}
|
||||
|
||||
void
|
||||
BfsIterator::enqueueAdjacentVertices(Vertex *vertex)
|
||||
{
|
||||
enqueueAdjacentVertices(vertex, search_pred_);
|
||||
}
|
||||
|
||||
void
|
||||
BfsIterator::enqueueAdjacentVertices(Vertex *vertex,
|
||||
const Mode *mode)
|
||||
{
|
||||
enqueueAdjacentVertices(vertex, search_pred_, mode);
|
||||
}
|
||||
|
||||
int
|
||||
BfsIterator::visit(Level to_level,
|
||||
VertexVisitor *visitor)
|
||||
|
|
@ -217,50 +212,6 @@ BfsIterator::visitParallel(Level to_level,
|
|||
return visit_count;
|
||||
}
|
||||
|
||||
bool
|
||||
BfsIterator::hasNext()
|
||||
{
|
||||
return hasNext(last_level_);
|
||||
}
|
||||
|
||||
bool
|
||||
BfsIterator::hasNext(Level to_level)
|
||||
{
|
||||
findNext(to_level);
|
||||
return levelLessOrEqual(first_level_, last_level_)
|
||||
&& !queue_[first_level_].empty();
|
||||
}
|
||||
|
||||
Vertex *
|
||||
BfsIterator::next()
|
||||
{
|
||||
VertexSeq &level_vertices = queue_[first_level_];
|
||||
Vertex *vertex = level_vertices.back();
|
||||
level_vertices.pop_back();
|
||||
vertex->setBfsInQueue(bfs_index_, false);
|
||||
return vertex;
|
||||
}
|
||||
|
||||
void
|
||||
BfsIterator::findNext(Level to_level)
|
||||
{
|
||||
while (levelLessOrEqual(first_level_, last_level_)
|
||||
&& levelLessOrEqual(first_level_, to_level)) {
|
||||
VertexSeq &level_vertices = queue_[first_level_];
|
||||
// Skip null entries from deleted vertices.
|
||||
while (!level_vertices.empty()) {
|
||||
Vertex *vertex = level_vertices.back();
|
||||
if (vertex == nullptr)
|
||||
level_vertices.pop_back();
|
||||
else {
|
||||
checkLevel(vertex, first_level_);
|
||||
return;
|
||||
}
|
||||
}
|
||||
incrLevel(first_level_);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BfsIterator::enqueue(Vertex *vertex)
|
||||
{
|
||||
|
|
@ -340,6 +291,52 @@ BfsIterator::remove(Vertex *vertex)
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
bool
|
||||
BfsIterator::hasNext()
|
||||
{
|
||||
return hasNext(last_level_);
|
||||
}
|
||||
|
||||
bool
|
||||
BfsIterator::hasNext(Level to_level)
|
||||
{
|
||||
findNext(to_level);
|
||||
return levelLessOrEqual(first_level_, last_level_)
|
||||
&& !queue_[first_level_].empty();
|
||||
}
|
||||
|
||||
Vertex *
|
||||
BfsIterator::next()
|
||||
{
|
||||
VertexSeq &level_vertices = queue_[first_level_];
|
||||
Vertex *vertex = level_vertices.back();
|
||||
level_vertices.pop_back();
|
||||
vertex->setBfsInQueue(bfs_index_, false);
|
||||
return vertex;
|
||||
}
|
||||
|
||||
void
|
||||
BfsIterator::findNext(Level to_level)
|
||||
{
|
||||
while (levelLessOrEqual(first_level_, last_level_)
|
||||
&& levelLessOrEqual(first_level_, to_level)) {
|
||||
VertexSeq &level_vertices = queue_[first_level_];
|
||||
// Skip null entries from deleted vertices.
|
||||
while (!level_vertices.empty()) {
|
||||
Vertex *vertex = level_vertices.back();
|
||||
if (vertex == nullptr)
|
||||
level_vertices.pop_back();
|
||||
else {
|
||||
checkLevel(vertex, first_level_);
|
||||
return;
|
||||
}
|
||||
}
|
||||
incrLevel(first_level_);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
BfsFwdIterator::BfsFwdIterator(BfsIndex bfs_index,
|
||||
SearchPred *search_pred,
|
||||
StaState *sta) :
|
||||
|
|
@ -375,15 +372,46 @@ BfsFwdIterator::levelLess(Level level1,
|
|||
}
|
||||
|
||||
void
|
||||
BfsFwdIterator::enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred)
|
||||
BfsFwdIterator::enqueueFanout(Vertex *vertex)
|
||||
{
|
||||
if (search_pred->searchFrom(vertex)) {
|
||||
if (search_pred_->searchFrom(vertex)) {
|
||||
VertexOutEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *to_vertex = edge->to(graph_);
|
||||
if (search_pred->searchThru(edge) && search_pred->searchTo(to_vertex))
|
||||
if (search_pred_->searchThru(edge)
|
||||
&& search_pred_->searchTo(to_vertex))
|
||||
enqueue(to_vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BfsFwdIterator::enqueueFanout(Vertex *vertex,
|
||||
const Mode *mode)
|
||||
{
|
||||
if (search_pred_->searchFrom(vertex, mode)) {
|
||||
VertexOutEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *to_vertex = edge->to(graph_);
|
||||
if (search_pred_->searchThru(edge, mode)
|
||||
&& search_pred_->searchTo(to_vertex, mode))
|
||||
enqueue(to_vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BfsFwdIterator::enqueueAdjacentVertices(Vertex *vertex)
|
||||
{
|
||||
if (search_pred_->searchFrom(vertex)) {
|
||||
VertexOutEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *to_vertex = edge->to(graph_);
|
||||
if (search_pred_->searchThru(edge)
|
||||
&& search_pred_->searchTo(to_vertex))
|
||||
enqueue(to_vertex);
|
||||
}
|
||||
}
|
||||
|
|
@ -391,16 +419,15 @@ BfsFwdIterator::enqueueAdjacentVertices(Vertex *vertex,
|
|||
|
||||
void
|
||||
BfsFwdIterator::enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred,
|
||||
const Mode *mode)
|
||||
{
|
||||
if (search_pred->searchFrom(vertex, mode)) {
|
||||
if (search_pred_->searchFrom(vertex, mode)) {
|
||||
VertexOutEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *to_vertex = edge->to(graph_);
|
||||
if (search_pred->searchThru(edge, mode)
|
||||
&& search_pred->searchTo(to_vertex, mode))
|
||||
if (search_pred_->searchThru(edge, mode)
|
||||
&& search_pred_->searchTo(to_vertex, mode))
|
||||
enqueue(to_vertex);
|
||||
}
|
||||
}
|
||||
|
|
@ -443,15 +470,15 @@ BfsBkwdIterator::levelLess(Level level1,
|
|||
}
|
||||
|
||||
void
|
||||
BfsBkwdIterator::enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred)
|
||||
BfsBkwdIterator::enqueueAdjacentVertices(Vertex *vertex)
|
||||
{
|
||||
if (search_pred->searchTo(vertex)) {
|
||||
if (search_pred_->searchTo(vertex)) {
|
||||
VertexInEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *from_vertex = edge->from(graph_);
|
||||
if (search_pred->searchFrom(from_vertex) && search_pred->searchThru(edge))
|
||||
if (search_pred_->searchFrom(from_vertex)
|
||||
&& search_pred_->searchThru(edge))
|
||||
enqueue(from_vertex);
|
||||
}
|
||||
}
|
||||
|
|
@ -459,16 +486,46 @@ BfsBkwdIterator::enqueueAdjacentVertices(Vertex *vertex,
|
|||
|
||||
void
|
||||
BfsBkwdIterator::enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred,
|
||||
const Mode *mode)
|
||||
{
|
||||
if (search_pred->searchTo(vertex, mode)) {
|
||||
if (search_pred_->searchTo(vertex, mode)) {
|
||||
VertexInEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *from_vertex = edge->from(graph_);
|
||||
if (search_pred->searchFrom(from_vertex, mode)
|
||||
&& search_pred->searchThru(edge, mode))
|
||||
if (search_pred_->searchFrom(from_vertex, mode)
|
||||
&& search_pred_->searchThru(edge, mode))
|
||||
enqueue(from_vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BfsBkwdIterator::enqueueFanin(Vertex *vertex)
|
||||
{
|
||||
if (search_pred_->searchTo(vertex)) {
|
||||
VertexInEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *from_vertex = edge->from(graph_);
|
||||
if (search_pred_->searchFrom(from_vertex)
|
||||
&& search_pred_->searchThru(edge))
|
||||
enqueue(from_vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BfsBkwdIterator::enqueueFanin(Vertex *vertex,
|
||||
const Mode *mode)
|
||||
{
|
||||
if (search_pred_->searchTo(vertex, mode)) {
|
||||
VertexInEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *from_vertex = edge->from(graph_);
|
||||
if (search_pred_->searchFrom(from_vertex, mode)
|
||||
&& search_pred_->searchThru(edge, mode))
|
||||
enqueue(from_vertex);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@
|
|||
|
||||
#include "ClkNetwork.hh"
|
||||
|
||||
#include "Bfs.hh"
|
||||
#include <queue>
|
||||
|
||||
#include "Debug.hh"
|
||||
#include "Graph.hh"
|
||||
#include "Mode.hh"
|
||||
|
|
@ -127,7 +128,6 @@ ClkNetwork::findClkPins(bool ideal_only,
|
|||
{
|
||||
const Sdc *sdc = mode_->sdc();
|
||||
ClkSearchPred srch_pred(this);
|
||||
BfsFwdIterator bfs(BfsIndex::other, &srch_pred, this);
|
||||
for (Clock *clk : sdc->clocks()) {
|
||||
if (!ideal_only
|
||||
|| !clk->isPropagated()) {
|
||||
|
|
@ -136,25 +136,39 @@ ClkNetwork::findClkPins(bool ideal_only,
|
|||
clk_pins = new PinSet(network_);
|
||||
clk_pins_map_[clk] = clk_pins;
|
||||
}
|
||||
std::queue<Vertex *> queue;
|
||||
VertexSet visited = makeVertexSet(this);
|
||||
auto enqueue = [&queue, &visited] (Vertex *vertex) {
|
||||
if (vertex && !visited.contains(vertex)) {
|
||||
visited.insert(vertex);
|
||||
queue.push(vertex);
|
||||
}
|
||||
};
|
||||
for (const Pin *pin : clk->leafPins()) {
|
||||
if (!ideal_only
|
||||
|| !sdc->isPropagatedClock(pin)) {
|
||||
Vertex *vertex, *bidirect_drvr_vertex;
|
||||
graph_->pinVertices(pin, vertex, bidirect_drvr_vertex);
|
||||
bfs.enqueue(vertex);
|
||||
if (bidirect_drvr_vertex)
|
||||
bfs.enqueue(bidirect_drvr_vertex);
|
||||
enqueue(vertex);
|
||||
enqueue(bidirect_drvr_vertex);
|
||||
}
|
||||
}
|
||||
while (bfs.hasNext()) {
|
||||
Vertex *vertex = bfs.next();
|
||||
while (!queue.empty()) {
|
||||
Vertex *vertex = queue.front();
|
||||
queue.pop();
|
||||
const Pin *pin = vertex->pin();
|
||||
if (!ideal_only
|
||||
|| !sdc->isPropagatedClock(pin)) {
|
||||
clk_pins->insert(pin);
|
||||
ClockSet &pin_clks = pin_clks_map[pin];
|
||||
pin_clks.insert(clk);
|
||||
bfs.enqueueAdjacentVertices(vertex);
|
||||
graph_->visitFanouts(vertex, &srch_pred,
|
||||
[&queue, &visited] (Vertex *fanout) {
|
||||
if (!visited.contains(fanout)) {
|
||||
visited.insert(fanout);
|
||||
queue.push(fanout);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,7 +271,6 @@ Genclks::ensureMaster(Clock *gclk,
|
|||
// Search backward from generated clock source pin to a clock pin.
|
||||
GenClkMasterSearchPred srch_pred(this);
|
||||
VertexQueue master_queue;
|
||||
VertexSet visited = makeVertexSet(this);
|
||||
VertexSet src_vertices = makeVertexSet(this);
|
||||
gclk->srcPinVertices(src_vertices, network_, graph_);
|
||||
for (Vertex *vertex : src_vertices)
|
||||
|
|
@ -279,28 +278,25 @@ Genclks::ensureMaster(Clock *gclk,
|
|||
while (!master_queue.empty()) {
|
||||
Vertex *vertex = master_queue.front();
|
||||
master_queue.pop();
|
||||
if (!visited.contains(vertex)) {
|
||||
visited.insert(vertex);
|
||||
Pin *pin = vertex->pin();
|
||||
if (sdc->isLeafPinClock(pin)) {
|
||||
ClockSet *master_clks = sdc->findLeafPinClocks(pin);
|
||||
if (master_clks) {
|
||||
ClockSet::iterator master_iter = master_clks->begin();
|
||||
if (master_iter != master_clks->end()) {
|
||||
master_clk = *master_iter++;
|
||||
// Master source pin can actually be a clock source pin.
|
||||
if (master_clk != gclk) {
|
||||
gclk->setInferedMasterClk(master_clk);
|
||||
debugPrint(debug_, "genclk", 2, " {} master clk {}", gclk->name(),
|
||||
master_clk->name());
|
||||
master_clk_count++;
|
||||
break;
|
||||
}
|
||||
Pin *pin = vertex->pin();
|
||||
if (sdc->isLeafPinClock(pin)) {
|
||||
ClockSet *master_clks = sdc->findLeafPinClocks(pin);
|
||||
if (master_clks) {
|
||||
ClockSet::iterator master_iter = master_clks->begin();
|
||||
if (master_iter != master_clks->end()) {
|
||||
master_clk = *master_iter++;
|
||||
// Master source pin can actually be a clock source pin.
|
||||
if (master_clk != gclk) {
|
||||
gclk->setInferedMasterClk(master_clk);
|
||||
debugPrint(debug_, "genclk", 2, " {} master clk {}", gclk->name(),
|
||||
master_clk->name());
|
||||
master_clk_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enqueueFanin(vertex, master_queue, srch_pred);
|
||||
}
|
||||
enqueueFanin(vertex, master_queue, srch_pred);
|
||||
}
|
||||
}
|
||||
if (master_clk_count > 1)
|
||||
|
|
|
|||
217
search/Search.cc
217
search/Search.cc
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "Bfs.hh"
|
||||
#include "ClkInfo.hh"
|
||||
#include "ClkNetwork.hh"
|
||||
#include "Clock.hh"
|
||||
#include "ContainerHelpers.hh"
|
||||
#include "Crpr.hh"
|
||||
|
|
@ -263,8 +264,7 @@ Search::Search(StaState *sta) :
|
|||
tag_group_capacity_(tag_capacity_),
|
||||
tag_groups_(new TagGroup *[tag_group_capacity_]),
|
||||
tag_group_set_(new TagGroupSet(tag_group_capacity_)),
|
||||
postponed_arrivals_(makeVertexSet(this)),
|
||||
postponed_clk_endpoints_(makeVertexSet(this)),
|
||||
pending_arrivals_(makeVertexSet(this)),
|
||||
endpoints_(makeVertexSet(this)),
|
||||
invalid_endpoints_(makeVertexSet(this)),
|
||||
|
||||
|
|
@ -328,8 +328,7 @@ Search::clear()
|
|||
deletePathGroups();
|
||||
deletePaths();
|
||||
deleteTags();
|
||||
postponed_arrivals_.clear();
|
||||
postponed_clk_endpoints_.clear();
|
||||
pending_arrivals_.clear();
|
||||
deleteFilter();
|
||||
found_downstream_clk_pins_ = false;
|
||||
}
|
||||
|
|
@ -546,7 +545,7 @@ Search::findFilteredArrivals(ExceptionFrom *from,
|
|||
// These cases do not require filtered arrivals.
|
||||
// -from clocks
|
||||
// -to
|
||||
findAllArrivals(thru_latches, false);
|
||||
findAllArrivals(thru_latches);
|
||||
}
|
||||
|
||||
// From/thrus/to are used to make a filter exception. If the last
|
||||
|
|
@ -639,32 +638,36 @@ Search::deleteFilterClkInfos()
|
|||
void
|
||||
Search::findFilteredArrivals(bool thru_latches)
|
||||
{
|
||||
filtered_arrivals_.clear();
|
||||
findArrivalsSeed();
|
||||
seedFilterStarts();
|
||||
Level max_level = levelize_->maxLevel();
|
||||
// Search always_to_endpoint to search from exisiting arrivals at
|
||||
// fanin startpoints to reach -thru/-to endpoints.
|
||||
arrival_visitor_->init(true, false, eval_pred_);
|
||||
enqueuePendingClkFanouts();
|
||||
bool have_pending_latch_outputs = false;
|
||||
// Iterate until data arrivals at all latches stop changing.
|
||||
arrival_iter_->ensureSize();
|
||||
|
||||
filtered_arrivals_.clear();
|
||||
findArrivalsSeed();
|
||||
seedFilterStarts();
|
||||
|
||||
Level max_level = levelize_->maxLevel();
|
||||
bool have_pending_arrivals = false;
|
||||
for (int pass = 1;
|
||||
pass == 1 || (thru_latches && have_pending_latch_outputs);
|
||||
pass == 1 || (thru_latches && have_pending_arrivals);
|
||||
pass++) {
|
||||
debugPrint(debug_, "search", 1, "find arrivals pass {}", pass);
|
||||
|
||||
int arrival_count = arrival_iter_->visitParallel(max_level, arrival_visitor_);
|
||||
debugPrint(debug_, "search", 1, "found {} arrivals", arrival_count);
|
||||
|
||||
have_pending_latch_outputs = !postponed_arrivals_.empty();
|
||||
for (Vertex *latch_output : postponed_arrivals_)
|
||||
arrival_visitor_->visit(latch_output, true);
|
||||
postponed_arrivals_.clear();
|
||||
// Latch D->Q and disabled loop edges have level discontinuities so their
|
||||
// eval. For latches the data path crpr clk path may be evaled in another
|
||||
// thread at the same time the latch D->Q edge.
|
||||
// Disabled loop edges propagate pending loop paths here.
|
||||
have_pending_arrivals = !pending_arrivals_.empty();
|
||||
for (Vertex *vertex : pending_arrivals_)
|
||||
arrival_visitor_->visit(vertex, true);
|
||||
pending_arrivals_.clear();
|
||||
|
||||
deleteTagsPrev();
|
||||
}
|
||||
arrivals_exist_ = true;
|
||||
}
|
||||
|
||||
// Delete stale tag arrarys.
|
||||
|
|
@ -860,14 +863,13 @@ void
|
|||
Search::levelsChangedBefore()
|
||||
{
|
||||
if (arrivals_exist_) {
|
||||
while (arrival_iter_->hasNext()) {
|
||||
Vertex *vertex = arrival_iter_->next();
|
||||
arrival_iter_->clear([this] (Vertex *vertex) {
|
||||
arrivalInvalid(vertex);
|
||||
}
|
||||
while (required_iter_->hasNext()) {
|
||||
Vertex *vertex = required_iter_->next();
|
||||
});
|
||||
|
||||
required_iter_->clear([this] (Vertex *vertex) {
|
||||
requiredInvalid(vertex);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -939,11 +941,16 @@ Search::requiredInvalid(Vertex *vertex)
|
|||
void
|
||||
Search::findClkArrivals()
|
||||
{
|
||||
findAllArrivals(false, true);
|
||||
debugPrint(debug_, "search", 1, "find clk arrivals");
|
||||
arrival_visitor_->init(false, true, eval_pred_);
|
||||
arrival_iter_->ensureSize();
|
||||
enqueueClkRoots();
|
||||
enqueueInvalidClks();
|
||||
findArrivals2(levelize_->maxLevel());
|
||||
}
|
||||
|
||||
void
|
||||
Search::seedClkVertexArrivals()
|
||||
Search::enqueueClkRoots()
|
||||
{
|
||||
PinSet clk_pins(network_);
|
||||
findClkVertexPins(clk_pins);
|
||||
|
|
@ -954,6 +961,32 @@ Search::seedClkVertexArrivals()
|
|||
if (bidirect_drvr_vertex)
|
||||
arrival_iter_->enqueue(bidirect_drvr_vertex);
|
||||
}
|
||||
arrivals_exist_ = true;
|
||||
}
|
||||
|
||||
void
|
||||
Search::enqueueInvalidClks()
|
||||
{
|
||||
if (!invalid_arrivals_.empty()) {
|
||||
for (Mode *mode : modes_)
|
||||
mode->clkNetwork()->ensureClkNetwork();
|
||||
for (auto itr = invalid_arrivals_.begin(); itr != invalid_arrivals_.end();) {
|
||||
Vertex *vertex = *itr;
|
||||
bool is_clk = false;
|
||||
for (Mode *mode : modes_) {
|
||||
if (mode->clkNetwork()->isClock(vertex)) {
|
||||
is_clk = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_clk) {
|
||||
arrival_iter_->enqueue(vertex);
|
||||
itr = invalid_arrivals_.erase(itr);
|
||||
}
|
||||
else
|
||||
itr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Arrival
|
||||
|
|
@ -980,51 +1013,31 @@ Search::clockInsertion(const Clock *clk,
|
|||
void
|
||||
Search::findAllArrivals()
|
||||
{
|
||||
findAllArrivals(true, false);
|
||||
findAllArrivals(true);
|
||||
}
|
||||
|
||||
void
|
||||
Search::findAllArrivals(bool thru_latches,
|
||||
bool clks_only)
|
||||
Search::findAllArrivals(bool thru_latches)
|
||||
{
|
||||
if (!clks_only)
|
||||
enqueuePendingClkFanouts();
|
||||
arrival_visitor_->init(false, clks_only, eval_pred_);
|
||||
bool have_pending_latch_outputs = false;
|
||||
arrival_visitor_->init(false, false, eval_pred_);
|
||||
arrival_iter_->ensureSize();
|
||||
|
||||
bool have_pending_arrivals = false;
|
||||
// Iterate until data arrivals at all latches stop changing.
|
||||
for (int pass = 1;
|
||||
pass == 1 || (thru_latches && have_pending_latch_outputs);
|
||||
pass == 1 || (thru_latches && have_pending_arrivals);
|
||||
pass++) {
|
||||
debugPrint(debug_, "search", 1, "find arrivals pass {}", pass);
|
||||
|
||||
findArrivals1(levelize_->maxLevel());
|
||||
|
||||
have_pending_latch_outputs = !postponed_arrivals_.empty();
|
||||
for (Vertex *latch_output : postponed_arrivals_)
|
||||
arrival_visitor_->visit(latch_output, true);
|
||||
postponed_arrivals_.clear();
|
||||
have_pending_arrivals = !pending_arrivals_.empty();
|
||||
for (Vertex *vertex : pending_arrivals_)
|
||||
arrival_visitor_->visit(vertex, true);
|
||||
pending_arrivals_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Pick up where the search stopped at the clock network boundary.
|
||||
void
|
||||
Search::enqueuePendingClkFanouts()
|
||||
{
|
||||
for (Vertex *vertex : postponed_clk_endpoints_) {
|
||||
debugPrint(debug_, "search", 2, "enqueue clk fanout {}",
|
||||
vertex->to_string(this));
|
||||
arrival_iter_->enqueueAdjacentVertices(vertex, search_adj_);
|
||||
}
|
||||
postponed_clk_endpoints_.clear();
|
||||
}
|
||||
|
||||
void
|
||||
Search::postponeClkFanouts(Vertex *vertex)
|
||||
{
|
||||
LockGuard lock(postponed_clk_endpoints_lock_);
|
||||
postponed_clk_endpoints_.insert(vertex);
|
||||
}
|
||||
|
||||
void
|
||||
Search::findArrivals()
|
||||
{
|
||||
|
|
@ -1035,6 +1048,7 @@ void
|
|||
Search::findArrivals(Level level)
|
||||
{
|
||||
arrival_visitor_->init(false, false, eval_pred_);
|
||||
arrival_iter_->ensureSize();
|
||||
findArrivals1(level);
|
||||
}
|
||||
|
||||
|
|
@ -1043,13 +1057,19 @@ Search::findArrivals1(Level level)
|
|||
{
|
||||
debugPrint(debug_, "search", 1, "find arrivals to level {}", level);
|
||||
findArrivalsSeed();
|
||||
findArrivals2(level);
|
||||
}
|
||||
|
||||
// Caller seeds arrival_iter_.
|
||||
void
|
||||
Search::findArrivals2(Level level)
|
||||
{
|
||||
Stats stats(debug_, report_);
|
||||
int arrival_count = arrival_iter_->visitParallel(level, arrival_visitor_);
|
||||
deleteTagsPrev();
|
||||
if (arrival_count > 0)
|
||||
deleteUnusedTagGroups();
|
||||
stats.report("Find arrivals");
|
||||
arrivals_exist_ = true;
|
||||
debugPrint(debug_, "search", 1, "found {} arrivals", arrival_count);
|
||||
}
|
||||
|
||||
|
|
@ -1059,15 +1079,9 @@ Search::findArrivalsSeed()
|
|||
if (!arrivals_seeded_) {
|
||||
for (const Mode *mode : modes_)
|
||||
mode->genclks()->ensureInsertionDelays();
|
||||
arrival_iter_->clear();
|
||||
required_iter_->clear();
|
||||
seedArrivals();
|
||||
arrivals_seeded_ = true;
|
||||
}
|
||||
else {
|
||||
arrival_iter_->ensureSize();
|
||||
required_iter_->ensureSize();
|
||||
}
|
||||
seedInvalidArrivals();
|
||||
}
|
||||
|
||||
|
|
@ -1173,22 +1187,18 @@ ArrivalVisitor::visit(Vertex *vertex,
|
|||
search_->postponeLatchDataOutputs(vertex);
|
||||
|
||||
if ((always_to_endpoints_ || arrivals_changed)) {
|
||||
if (clks_only_ && vertex->isRegClk()) {
|
||||
debugPrint(debug_, "search", 3, "postponing clk fanout");
|
||||
search_->postponeClkFanouts(vertex);
|
||||
}
|
||||
else {
|
||||
graph_->visitFanoutEdges(vertex, search_adj_,
|
||||
[this] (Edge *edge,
|
||||
Vertex *fanout) {
|
||||
if (edge->isDisabledLoop()) {
|
||||
if (hasPendingLoopPaths(edge))
|
||||
search_->postponeArrivals(fanout);
|
||||
}
|
||||
else
|
||||
search_->arrivalIterator()->enqueue(fanout);
|
||||
});
|
||||
}
|
||||
graph_->visitFanoutEdges(vertex, search_adj_,
|
||||
[this, vertex] (Edge *edge,
|
||||
Vertex *fanout) {
|
||||
if (edge->isDisabledLoop()) {
|
||||
if (hasPendingLoopPaths(edge))
|
||||
search_->postponeArrivals(fanout);
|
||||
}
|
||||
else if (clks_only_ && vertex->isRegClk())
|
||||
search_->arrivalInvalid(fanout);
|
||||
else
|
||||
search_->arrivalIterator()->enqueue(fanout);
|
||||
});
|
||||
}
|
||||
if (arrivals_changed) {
|
||||
debugPrint(debug_, "search", 4, "arrivals changed");
|
||||
|
|
@ -1425,8 +1435,8 @@ Search::postponeLatchDataOutputs(Vertex *latch_data)
|
|||
Edge *edge = edge_iter.next();
|
||||
if (edge->role() == TimingRole::latchDtoQ()) {
|
||||
Vertex *out_vertex = edge->to(graph_);
|
||||
LockGuard lock(postponed_arrivals_lock_);
|
||||
postponed_arrivals_.insert(out_vertex);
|
||||
LockGuard lock(pending_arrivals_lock_);
|
||||
pending_arrivals_.insert(out_vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1434,8 +1444,8 @@ Search::postponeLatchDataOutputs(Vertex *latch_data)
|
|||
void
|
||||
Search::postponeArrivals(Vertex *vertex)
|
||||
{
|
||||
LockGuard lock(postponed_arrivals_lock_);
|
||||
postponed_arrivals_.insert(vertex);
|
||||
LockGuard lock(pending_arrivals_lock_);
|
||||
pending_arrivals_.insert(vertex);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1448,6 +1458,7 @@ Search::seedArrivals()
|
|||
|
||||
for (Vertex *vertex : vertices)
|
||||
arrival_iter_->enqueue(vertex);
|
||||
arrivals_exist_ = true;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3160,6 +3171,7 @@ void
|
|||
Search::seedRequireds()
|
||||
{
|
||||
ensureDownstreamClkPins();
|
||||
required_iter_->ensureSize();
|
||||
for (Vertex *vertex : endpoints())
|
||||
seedRequired(vertex);
|
||||
requireds_seeded_ = true;
|
||||
|
|
@ -3334,8 +3346,9 @@ Search::seedRequired(Vertex *vertex)
|
|||
required_cmp.requiredsInit(vertex, this);
|
||||
visit_path_ends_->visitPathEnds(vertex, &seeder);
|
||||
// Enqueue fanin vertices for back-propagating required times.
|
||||
required_iter_->ensureSize();
|
||||
if (required_cmp.requiredsSave(vertex, this))
|
||||
required_iter_->enqueueAdjacentVertices(vertex);
|
||||
required_iter_->enqueueFanin(vertex);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3347,7 +3360,7 @@ Search::seedRequiredEnqueueFanin(Vertex *vertex)
|
|||
visit_path_ends_->visitPathEnds(vertex, &seeder);
|
||||
// Enqueue fanin vertices for back-propagating required times.
|
||||
required_cmp.requiredsSave(vertex, this);
|
||||
required_iter_->enqueueAdjacentVertices(vertex);
|
||||
required_iter_->enqueueFanin(vertex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3455,7 +3468,7 @@ RequiredVisitor::visit(Vertex *vertex)
|
|||
search_->tnsInvalid(vertex);
|
||||
|
||||
if (changed)
|
||||
search_->requiredIterator()->enqueueAdjacentVertices(vertex);
|
||||
search_->requiredIterator()->enqueueFanin(vertex);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -3538,17 +3551,27 @@ void
|
|||
Search::ensureDownstreamClkPins()
|
||||
{
|
||||
if (!found_downstream_clk_pins_) {
|
||||
// Use backward BFS from register clk pins to mark upsteam pins
|
||||
// as having downstream clk pins.
|
||||
// Use backward DFS from register clk pins to mark upstream pins
|
||||
// as having downstream clk pins. hasDownstreamClkPin doubles as the
|
||||
// visited flag since its meaning is exactly "reached here".
|
||||
ClkTreeSearchPred pred(this);
|
||||
BfsBkwdIterator iter(BfsIndex::other, &pred, this);
|
||||
for (Vertex *vertex : graph_->regClkVertices())
|
||||
iter.enqueue(vertex);
|
||||
|
||||
while (iter.hasNext()) {
|
||||
Vertex *vertex = iter.next();
|
||||
vertex->setHasDownstreamClkPin(true);
|
||||
iter.enqueueAdjacentVertices(vertex);
|
||||
std::vector<Vertex*> stack;
|
||||
for (Vertex *vertex : graph_->regClkVertices()) {
|
||||
if (!vertex->hasDownstreamClkPin()) {
|
||||
vertex->setHasDownstreamClkPin(true);
|
||||
stack.push_back(vertex);
|
||||
}
|
||||
}
|
||||
while (!stack.empty()) {
|
||||
Vertex *vertex = stack.back();
|
||||
stack.pop_back();
|
||||
graph_->visitFanins(vertex, &pred,
|
||||
[&stack] (Vertex *fanin) {
|
||||
if (!fanin->hasDownstreamClkPin()) {
|
||||
fanin->setHasDownstreamClkPin(true);
|
||||
stack.push_back(fanin);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
found_downstream_clk_pins_ = true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue