incremental levelizaation
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
3620d7a259
commit
3d3b16334e
|
|
@ -297,7 +297,7 @@ GraphDelayCalc::seedInvalidDelays()
|
|||
void
|
||||
GraphDelayCalc::seedRootSlews()
|
||||
{
|
||||
for (Vertex *vertex : *levelize_->roots())
|
||||
for (Vertex *vertex : levelize_->roots())
|
||||
seedRootSlew(vertex, arc_delay_calc_);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -737,7 +737,7 @@ Power::ensureActivities()
|
|||
void
|
||||
Power::seedActivities(BfsFwdIterator &bfs)
|
||||
{
|
||||
for (Vertex *vertex : *levelize_->roots()) {
|
||||
for (Vertex *vertex : levelize_->roots()) {
|
||||
const Pin *pin = vertex->pin();
|
||||
// Clock activities are baked in.
|
||||
if (!sdc_->isLeafPinClock(pin)
|
||||
|
|
|
|||
|
|
@ -51,16 +51,15 @@ Levelize::Levelize(StaState *sta) :
|
|||
levels_valid_(false),
|
||||
max_level_(0),
|
||||
level_space_(10),
|
||||
roots_(new VertexSet(graph_)),
|
||||
relevelize_from_(new VertexSet(graph_)),
|
||||
max_incremental_level_(100),
|
||||
roots_(graph_),
|
||||
relevelize_from_(graph_),
|
||||
observer_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Levelize::~Levelize()
|
||||
{
|
||||
delete roots_;
|
||||
delete relevelize_from_;
|
||||
delete observer_;
|
||||
loops_.deleteContents();
|
||||
}
|
||||
|
|
@ -83,8 +82,8 @@ Levelize::clear()
|
|||
{
|
||||
levelized_ = false;
|
||||
levels_valid_ = false;
|
||||
roots_->clear();
|
||||
relevelize_from_->clear();
|
||||
roots_.clear();
|
||||
relevelize_from_.clear();
|
||||
clearLoopEdges();
|
||||
loops_.deleteContentsClear();
|
||||
loop_edges_.clear();
|
||||
|
|
@ -106,7 +105,8 @@ void
|
|||
Levelize::ensureLevelized()
|
||||
{
|
||||
if (!levels_valid_) {
|
||||
if (levelized_)
|
||||
if (levelized_
|
||||
&& relevelize_from_.size() < max_incremental_level_)
|
||||
relevelize();
|
||||
else
|
||||
levelize();
|
||||
|
|
@ -151,6 +151,7 @@ Levelize::levelize()
|
|||
vertex->setVisited(false);
|
||||
vertex->setOnPath(false);
|
||||
}
|
||||
relevelize_from_.clear();
|
||||
levelized_ = true;
|
||||
levels_valid_ = true;
|
||||
stats.report("Levelize");
|
||||
|
|
@ -159,7 +160,7 @@ Levelize::levelize()
|
|||
void
|
||||
Levelize::findRoots()
|
||||
{
|
||||
roots_->clear();
|
||||
roots_.clear();
|
||||
VertexIterator vertex_iter(graph_);
|
||||
while (vertex_iter.hasNext()) {
|
||||
Vertex *vertex = vertex_iter.next();
|
||||
|
|
@ -167,17 +168,17 @@ Levelize::findRoots()
|
|||
debugPrint(debug_, "levelize", 2, "root %s%s",
|
||||
vertex->to_string(this).c_str(),
|
||||
hasFanout(vertex) ? " fanout" : "");
|
||||
roots_->insert(vertex);
|
||||
roots_.insert(vertex);
|
||||
}
|
||||
}
|
||||
if (debug_->check("levelize", 1)) {
|
||||
size_t fanout_roots = 0;
|
||||
for (Vertex *root : *roots_) {
|
||||
for (Vertex *root : roots_) {
|
||||
if (hasFanout(root))
|
||||
fanout_roots++;
|
||||
}
|
||||
debugPrint(debug_, "levelize", 1, "Found %zu roots %zu with fanout",
|
||||
roots_->size(),
|
||||
roots_.size(),
|
||||
fanout_roots);
|
||||
}
|
||||
}
|
||||
|
|
@ -251,7 +252,7 @@ VertexSeq
|
|||
Levelize::sortedRootsWithFanout()
|
||||
{
|
||||
VertexSeq roots;
|
||||
for (Vertex *root : *roots_) {
|
||||
for (Vertex *root : roots_) {
|
||||
if (hasFanout(root))
|
||||
roots.push_back(root);
|
||||
}
|
||||
|
|
@ -322,7 +323,7 @@ Levelize::findCycleBackEdges()
|
|||
stack.emplace(vertex, new VertexOutEdgeIterator(vertex, graph_));
|
||||
EdgeSet back_edges = findBackEdges(path, stack);
|
||||
for (Edge *back_edge : back_edges)
|
||||
roots_->insert(back_edge->from(graph_));
|
||||
roots_.insert(back_edge->from(graph_));
|
||||
back_edge_count += back_edges.size();
|
||||
}
|
||||
}
|
||||
|
|
@ -378,7 +379,7 @@ Levelize::findTopologicalOrder()
|
|||
}
|
||||
|
||||
std::deque<Vertex*> queue;
|
||||
for (Vertex *root : *roots_)
|
||||
for (Vertex *root : roots_)
|
||||
queue.push_back(root);
|
||||
|
||||
VertexSeq topo_order;
|
||||
|
|
@ -501,10 +502,11 @@ Levelize::reportPath(EdgeSeq &path) const
|
|||
void
|
||||
Levelize::assignLevels(VertexSeq &topo_sorted)
|
||||
{
|
||||
for (Vertex *root : *roots_)
|
||||
for (Vertex *root : roots_)
|
||||
setLevel(root, 0);
|
||||
for (Vertex *vertex : topo_sorted) {
|
||||
if (vertex->level() != -1) {
|
||||
if (vertex->level() != -1
|
||||
&& search_pred_.searchFrom(vertex)) {
|
||||
VertexOutEdgeIterator edge_iter(vertex, graph_);
|
||||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
|
|
@ -557,7 +559,7 @@ Levelize::setLevel(Vertex *vertex,
|
|||
vertex->setLevel(level);
|
||||
max_level_ = max(level, max_level_);
|
||||
if (level >= Graph::vertex_level_max)
|
||||
criticalError(616, "maximum logic level exceeded");
|
||||
report_->critical(616, "maximum logic level exceeded");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -580,9 +582,9 @@ Levelize::invalidFrom(Vertex *vertex)
|
|||
while (edge_iter.hasNext()) {
|
||||
Edge *edge = edge_iter.next();
|
||||
Vertex *from_vertex = edge->from(graph_);
|
||||
relevelize_from_->insert(from_vertex);
|
||||
relevelize_from_.insert(from_vertex);
|
||||
}
|
||||
relevelize_from_->insert(vertex);
|
||||
relevelize_from_.insert(vertex);
|
||||
levels_valid_ = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -591,8 +593,8 @@ void
|
|||
Levelize::deleteVertexBefore(Vertex *vertex)
|
||||
{
|
||||
if (levelized_) {
|
||||
roots_->erase(vertex);
|
||||
relevelize_from_->erase(vertex);
|
||||
roots_.erase(vertex);
|
||||
relevelize_from_.erase(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -600,9 +602,9 @@ void
|
|||
Levelize::relevelizeFrom(Vertex *vertex)
|
||||
{
|
||||
if (levelized_) {
|
||||
debugPrint(debug_, "levelize", 1, "invalid relevelize from %s",
|
||||
debugPrint(debug_, "levelize", 1, "relevelize from %s",
|
||||
vertex->to_string(this).c_str());
|
||||
relevelize_from_->insert(vertex);
|
||||
relevelize_from_.insert(vertex);
|
||||
levels_valid_ = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -633,23 +635,22 @@ Levelize::deleteEdgeBefore(Edge *edge)
|
|||
void
|
||||
Levelize::relevelize()
|
||||
{
|
||||
for (Vertex *vertex : *relevelize_from_) {
|
||||
for (Vertex *vertex : relevelize_from_) {
|
||||
debugPrint(debug_, "levelize", 1, "relevelize from %s",
|
||||
vertex->to_string(this).c_str());
|
||||
if (search_pred_.searchFrom(vertex)) {
|
||||
if (isRoot(vertex)) {
|
||||
setLevelIncr(vertex, 0);
|
||||
roots_->insert(vertex);
|
||||
}
|
||||
VertexSet visited(graph_);
|
||||
if (isRoot(vertex))
|
||||
roots_.insert(vertex);
|
||||
VertexSet path_vertices(graph_);
|
||||
EdgeSeq path;
|
||||
visit(vertex, nullptr, vertex->level(), 1, visited, path_vertices, path);
|
||||
visit(vertex, nullptr, vertex->level(), 1, path_vertices, path);
|
||||
}
|
||||
}
|
||||
ensureLatchLevels();
|
||||
levels_valid_ = true;
|
||||
relevelize_from_->clear();
|
||||
relevelize_from_.clear();
|
||||
|
||||
checkLevels();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -657,14 +658,11 @@ Levelize::visit(Vertex *vertex,
|
|||
Edge *from,
|
||||
Level level,
|
||||
Level level_space,
|
||||
VertexSet &visited,
|
||||
VertexSet &path_vertices,
|
||||
EdgeSeq &path)
|
||||
{
|
||||
Pin *from_pin = vertex->pin();
|
||||
setLevelIncr(vertex, level);
|
||||
level += level_space;
|
||||
visited.insert(vertex);
|
||||
path_vertices.insert(vertex);
|
||||
if (from)
|
||||
path.push_back(from);
|
||||
|
|
@ -679,9 +677,9 @@ Levelize::visit(Vertex *vertex,
|
|||
if (path_vertices.find(to_vertex) != path_vertices.end())
|
||||
// Back edges form feedback loops.
|
||||
recordLoop(edge, path);
|
||||
else if (visited.find(to_vertex) == visited.end()
|
||||
&& to_vertex->level() < level)
|
||||
visit(to_vertex, edge, level, level_space, visited, path_vertices, path);
|
||||
else if (to_vertex->level() <= level)
|
||||
visit(to_vertex, edge, level+level_space, level_space,
|
||||
path_vertices, path);
|
||||
}
|
||||
if (edge->role() == TimingRole::latchDtoQ())
|
||||
latch_d_to_q_edges_.insert(edge);
|
||||
|
|
@ -691,9 +689,9 @@ Levelize::visit(Vertex *vertex,
|
|||
&& !vertex->isBidirectDriver()) {
|
||||
Vertex *to_vertex = graph_->pinDrvrVertex(from_pin);
|
||||
if (search_pred_.searchTo(to_vertex)
|
||||
&& (visited.find(to_vertex) == visited.end()
|
||||
|| to_vertex->level() < level))
|
||||
visit(to_vertex, nullptr, level, level_space, visited, path_vertices, path);
|
||||
&& (to_vertex->level() <= level))
|
||||
visit(to_vertex, nullptr, level+level_space, level_space,
|
||||
path_vertices, path);
|
||||
}
|
||||
}
|
||||
path_vertices.erase(vertex);
|
||||
|
|
@ -724,6 +722,34 @@ Levelize::setLevelIncr(Vertex *vertex,
|
|||
criticalError(617, "maximum logic level exceeded");
|
||||
}
|
||||
|
||||
void
|
||||
Levelize::checkLevels()
|
||||
{
|
||||
VertexIterator vertex_iter(graph_);
|
||||
while (vertex_iter.hasNext()) {
|
||||
Vertex *vertex = vertex_iter.next();
|
||||
if (search_pred_.searchTo(vertex)) {
|
||||
Level level = vertex->level();
|
||||
VertexInEdgeIterator edge_iter1(vertex, graph_);
|
||||
while (edge_iter1.hasNext()) {
|
||||
Edge *edge = edge_iter1.next();
|
||||
Vertex *from_vertex = edge->from(graph_);
|
||||
Level from_level = from_vertex->level();
|
||||
if (search_pred_.searchFrom(from_vertex)
|
||||
&& search_pred_.searchThru(edge)
|
||||
&& from_level >= level
|
||||
// Loops with no entry edges are all level zero.
|
||||
&& !(from_level == 0 && level == 0))
|
||||
report_->warn(617, "level check failed %s %d -> %s %d",
|
||||
from_vertex->name(network_),
|
||||
from_vertex->level(),
|
||||
vertex->name(network_),
|
||||
level);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
GraphLoop::GraphLoop(EdgeSeq *edges) :
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "NetworkClass.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "GraphClass.hh"
|
||||
#include "Graph.hh"
|
||||
#include "SearchPred.hh"
|
||||
#include "StaState.hh"
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ public:
|
|||
void deleteEdgeBefore(Edge *edge);
|
||||
int maxLevel() const { return max_level_; }
|
||||
// Vertices with no fanin edges.
|
||||
VertexSet *roots() { return roots_; }
|
||||
VertexSet &roots() { return roots_; }
|
||||
bool isRoot(Vertex *vertex);
|
||||
bool hasFanout(Vertex *vertex);
|
||||
// Reset to virgin state.
|
||||
|
|
@ -69,6 +69,7 @@ public:
|
|||
GraphLoopSeq &loops() { return loops_; }
|
||||
// Set the observer for level changes.
|
||||
void setObserver(LevelizeObserver *observer);
|
||||
void checkLevels();
|
||||
|
||||
protected:
|
||||
void levelize();
|
||||
|
|
@ -91,7 +92,6 @@ protected:
|
|||
Edge *from,
|
||||
Level level,
|
||||
Level level_space,
|
||||
VertexSet &visited,
|
||||
VertexSet &path_vertices,
|
||||
EdgeSeq &path);
|
||||
void setLevel(Vertex *vertex,
|
||||
|
|
@ -107,8 +107,9 @@ protected:
|
|||
bool levels_valid_;
|
||||
Level max_level_;
|
||||
Level level_space_;
|
||||
VertexSet *roots_;
|
||||
VertexSet *relevelize_from_;
|
||||
size_t max_incremental_level_;
|
||||
VertexSet roots_;
|
||||
VertexSet relevelize_from_;
|
||||
GraphLoopSeq loops_;
|
||||
EdgeSet loop_edges_;
|
||||
EdgeSet disabled_loop_edges_;
|
||||
|
|
|
|||
|
|
@ -1671,7 +1671,7 @@ Search::makeUnclkedPaths(Vertex *vertex,
|
|||
void
|
||||
Search::findRootVertices(VertexSet &vertices)
|
||||
{
|
||||
for (Vertex *vertex : *levelize_->roots()) {
|
||||
for (Vertex *vertex : levelize_->roots()) {
|
||||
const Pin *pin = vertex->pin();
|
||||
if (!sdc_->isLeafPinClock(pin)
|
||||
&& !sdc_->hasInputDelay(pin)
|
||||
|
|
|
|||
|
|
@ -4407,7 +4407,7 @@ Sta::connectDrvrPinAfter(Vertex *vertex)
|
|||
graph_delay_calc_->delayInvalid(vertex);
|
||||
search_->requiredInvalid(vertex);
|
||||
search_->endpointInvalid(vertex);
|
||||
levelize_->invalidFrom(vertex);
|
||||
levelize_->relevelizeFrom(vertex);
|
||||
clk_network_->connectPinAfter(pin);
|
||||
}
|
||||
|
||||
|
|
@ -4422,11 +4422,11 @@ Sta::connectLoadPinAfter(Vertex *vertex)
|
|||
graph_delay_calc_->delayInvalid(from_vertex);
|
||||
search_->requiredInvalid(from_vertex);
|
||||
sdc_->clkHpinDisablesChanged(from_vertex->pin());
|
||||
levelize_->relevelizeFrom(from_vertex);
|
||||
}
|
||||
Pin *pin = vertex->pin();
|
||||
sdc_->clkHpinDisablesChanged(pin);
|
||||
graph_delay_calc_->delayInvalid(vertex);
|
||||
levelize_->invalidFrom(vertex);
|
||||
search_->arrivalInvalid(vertex);
|
||||
search_->endpointInvalid(vertex);
|
||||
clk_network_->connectPinAfter(pin);
|
||||
|
|
@ -4584,6 +4584,7 @@ Sta::deletePinBefore(const Pin *pin)
|
|||
}
|
||||
levelize_->deleteEdgeBefore(edge);
|
||||
}
|
||||
// Deletes edges to/from vertex also.
|
||||
graph_->deleteVertex(vertex);
|
||||
}
|
||||
}
|
||||
|
|
@ -4606,6 +4607,7 @@ Sta::deletePinBefore(const Pin *pin)
|
|||
}
|
||||
levelize_->deleteEdgeBefore(edge);
|
||||
}
|
||||
// Deletes edges to/from vertex also.
|
||||
graph_->deleteVertex(vertex);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue