GraphDelayCalc::findVertexDelay incr
Signed-off-by: James Cherry <cherry@CerezoBook.local>
This commit is contained in:
parent
dbb19a2687
commit
affd539b3f
|
|
@ -698,19 +698,30 @@ GraphDelayCalc::findVertexDelay(Vertex *vertex,
|
||||||
load_slews_prev = loadSlews(load_pin_index_map);
|
load_slews_prev = loadSlews(load_pin_index_map);
|
||||||
findDriverDelays(vertex, arc_delay_calc, load_pin_index_map);
|
findDriverDelays(vertex, arc_delay_calc, load_pin_index_map);
|
||||||
if (network_->direction(pin)->isInternal())
|
if (network_->direction(pin)->isInternal())
|
||||||
enqueueTimingChecksEdges(vertex);
|
enqueueCheckEdges(vertex);
|
||||||
// Enqueue adjacent vertices even if the load slews did not
|
graph_->visitFanouts(vertex, search_non_latch_pred_,
|
||||||
// change when non-incremental to stride past annotations.
|
[this, &load_slews_prev, &load_pin_index_map]
|
||||||
if (!delays_exist_
|
(Vertex *fanout) {
|
||||||
|| loadSlewsChanged(load_slews_prev, load_pin_index_map))
|
// Enqueue adjacent vertices even if the load slew
|
||||||
iter_->enqueueFanout(vertex);
|
// did not change when non-incremental to stride
|
||||||
|
// past annotations.
|
||||||
|
if (!delays_exist_
|
||||||
|
|| loadSlewChanged(fanout, load_slews_prev,
|
||||||
|
load_pin_index_map)) {
|
||||||
|
iter_->enqueue(fanout);
|
||||||
|
fanout->setBfsPredecessorChanged(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else if (vertex->isLoad(network_)) {
|
else if (vertex->isLoad(network_)) {
|
||||||
// Load vertex.
|
// Load vertex.
|
||||||
// Includes top level bidirect load vertex with wire edge to bidirect driver.
|
// Includes top level bidirect load vertex with wire edge to bidirect driver.
|
||||||
enqueueTimingChecksEdges(vertex);
|
enqueueCheckEdges(vertex);
|
||||||
// Enqueue driver vertices from this input load.
|
graph_->visitFanouts(vertex, search_non_latch_pred_,
|
||||||
iter_->enqueueFanout(vertex);
|
[this] (Vertex *fanout) {
|
||||||
|
iter_->enqueue(fanout);
|
||||||
|
fanout->setBfsPredecessorChanged(true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -730,24 +741,25 @@ GraphDelayCalc::loadSlews(LoadPinIndexMap &load_pin_index_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GraphDelayCalc::loadSlewsChanged(DrvrLoadSlews &load_slews_prev,
|
GraphDelayCalc::loadSlewChanged(Vertex *load_vertex,
|
||||||
LoadPinIndexMap &load_pin_index_map)
|
DrvrLoadSlews &load_slews_prev,
|
||||||
|
LoadPinIndexMap &load_pin_index_map)
|
||||||
{
|
{
|
||||||
|
if (load_slews_prev.empty())
|
||||||
|
return true;
|
||||||
|
size_t index = load_pin_index_map[load_vertex->pin()];
|
||||||
|
SlewSeq &slews_prev = load_slews_prev[index];;
|
||||||
size_t slew_count = graph_->slewCount();
|
size_t slew_count = graph_->slewCount();
|
||||||
for (auto const [pin, index] : load_pin_index_map) {
|
for (size_t i = 0; i < slew_count; i++) {
|
||||||
Vertex *load_vertex = graph_->pinLoadVertex(pin);
|
const Slew slew = graph_->slew(load_vertex, i);
|
||||||
SlewSeq &slews_prev = load_slews_prev[index];;
|
if (!delayEqual(slew, slews_prev[i], this))
|
||||||
for (size_t i = 0; i < slew_count; i++) {
|
return true;
|
||||||
const Slew slew = graph_->slew(load_vertex, i);
|
|
||||||
if (!delayEqual(slew, slews_prev[i], this))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GraphDelayCalc::enqueueTimingChecksEdges(Vertex *vertex)
|
GraphDelayCalc::enqueueCheckEdges(Vertex *vertex)
|
||||||
{
|
{
|
||||||
if (vertex->hasChecks()) {
|
if (vertex->hasChecks()) {
|
||||||
VertexInEdgeIterator edge_iter(vertex, graph_);
|
VertexInEdgeIterator edge_iter(vertex, graph_);
|
||||||
|
|
@ -1173,10 +1185,10 @@ GraphDelayCalc::annotateDelaysSlews(Edge *edge,
|
||||||
dcalc_result.drvrSlew(), scene, min_max);
|
dcalc_result.drvrSlew(), scene, min_max);
|
||||||
if (!edge->role()->isLatchDtoQ()) {
|
if (!edge->role()->isLatchDtoQ()) {
|
||||||
Vertex *drvr_vertex = edge->to(graph_);
|
Vertex *drvr_vertex = edge->to(graph_);
|
||||||
delay_changed |= annotateLoadDelays(drvr_vertex, arc->toEdge()->asRiseFall(),
|
annotateLoadDelays(drvr_vertex, arc->toEdge()->asRiseFall(),
|
||||||
dcalc_result,
|
dcalc_result,
|
||||||
load_pin_index_map, delay_zero, true,
|
load_pin_index_map, delay_zero, true,
|
||||||
scene, min_max);
|
scene, min_max);
|
||||||
}
|
}
|
||||||
return delay_changed;
|
return delay_changed;
|
||||||
}
|
}
|
||||||
|
|
@ -1231,7 +1243,7 @@ GraphDelayCalc::annotateDelaySlew(Edge *edge,
|
||||||
// Annotate wire arc delays and load pin slews.
|
// Annotate wire arc delays and load pin slews.
|
||||||
// extra_delay is additional wire delay to add to delay returned
|
// extra_delay is additional wire delay to add to delay returned
|
||||||
// by the delay calculator.
|
// by the delay calculator.
|
||||||
bool
|
void
|
||||||
GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex,
|
GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex,
|
||||||
const RiseFall *drvr_rf,
|
const RiseFall *drvr_rf,
|
||||||
ArcDcalcResult &dcalc_result,
|
ArcDcalcResult &dcalc_result,
|
||||||
|
|
@ -1242,7 +1254,6 @@ GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex,
|
||||||
const MinMax *min_max)
|
const MinMax *min_max)
|
||||||
{
|
{
|
||||||
DcalcAPIndex ap_index = scene->dcalcAnalysisPtIndex(min_max);
|
DcalcAPIndex ap_index = scene->dcalcAnalysisPtIndex(min_max);
|
||||||
bool changed = false;
|
|
||||||
VertexOutEdgeIterator edge_iter(drvr_vertex, graph_);
|
VertexOutEdgeIterator edge_iter(drvr_vertex, graph_);
|
||||||
while (edge_iter.hasNext()) {
|
while (edge_iter.hasNext()) {
|
||||||
Edge *wire_edge = edge_iter.next();
|
Edge *wire_edge = edge_iter.next();
|
||||||
|
|
@ -1257,20 +1268,17 @@ GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex,
|
||||||
load_vertex->to_string(this),
|
load_vertex->to_string(this),
|
||||||
delayAsString(wire_delay, this),
|
delayAsString(wire_delay, this),
|
||||||
delayAsString(load_slew, this));
|
delayAsString(load_slew, this));
|
||||||
bool load_changed = false;
|
|
||||||
if (!load_vertex->slewAnnotated(drvr_rf, min_max)) {
|
if (!load_vertex->slewAnnotated(drvr_rf, min_max)) {
|
||||||
if (drvr_vertex->slewAnnotated(drvr_rf, min_max)) {
|
if (drvr_vertex->slewAnnotated(drvr_rf, min_max)) {
|
||||||
// Copy the driver slew to the load if it is annotated.
|
// Copy the driver slew to the load if it is annotated.
|
||||||
const Slew drvr_slew = graph_->slew(drvr_vertex, drvr_rf, ap_index);
|
const Slew drvr_slew = graph_->slew(drvr_vertex, drvr_rf, ap_index);
|
||||||
graph_->setSlew(load_vertex, drvr_rf, ap_index, drvr_slew);
|
graph_->setSlew(load_vertex, drvr_rf, ap_index, drvr_slew);
|
||||||
load_changed = true;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const Slew slew = graph_->slew(load_vertex, drvr_rf, ap_index);
|
const Slew slew = graph_->slew(load_vertex, drvr_rf, ap_index);
|
||||||
if (!merge
|
if (!merge
|
||||||
|| delayGreater(load_slew, slew, min_max, this)) {
|
|| delayGreater(load_slew, slew, min_max, this)) {
|
||||||
graph_->setSlew(load_vertex, drvr_rf, ap_index, load_slew);
|
graph_->setSlew(load_vertex, drvr_rf, ap_index, load_slew);
|
||||||
load_changed = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1283,15 +1291,12 @@ GraphDelayCalc::annotateLoadDelays(Vertex *drvr_vertex,
|
||||||
if (!merge
|
if (!merge
|
||||||
|| delayGreater(wire_delay_extra, delay, min_max, this)) {
|
|| delayGreater(wire_delay_extra, delay, min_max, this)) {
|
||||||
graph_->setWireArcDelay(wire_edge, drvr_rf, ap_index, wire_delay_extra);
|
graph_->setWireArcDelay(wire_edge, drvr_rf, ap_index, wire_delay_extra);
|
||||||
load_changed = true;
|
if (observer_)
|
||||||
|
observer_->delayChangedTo(load_vertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (load_changed && observer_)
|
|
||||||
observer_->delayChangedTo(load_vertex);
|
|
||||||
changed |= load_changed;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return changed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadPinIndexMap
|
LoadPinIndexMap
|
||||||
|
|
|
||||||
|
|
@ -1053,6 +1053,7 @@ Vertex::init(Pin *pin,
|
||||||
has_downstream_clk_pin_ = false;
|
has_downstream_clk_pin_ = false;
|
||||||
visited1_ = false;
|
visited1_ = false;
|
||||||
visited2_ = false;
|
visited2_ = false;
|
||||||
|
bfs_predecessor_changed_ = false;
|
||||||
has_sim_value_ = false;
|
has_sim_value_ = false;
|
||||||
level_ = 0;
|
level_ = 0;
|
||||||
slew_annotated_ = false;
|
slew_annotated_ = false;
|
||||||
|
|
@ -1281,6 +1282,12 @@ Vertex::setBfsInQueue(BfsIndex index,
|
||||||
bfs_in_queue_ &= ~(1 << static_cast<unsigned>(index));
|
bfs_in_queue_ &= ~(1 << static_cast<unsigned>(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Vertex::setBfsPredecessorChanged(bool changed)
|
||||||
|
{
|
||||||
|
bfs_predecessor_changed_ = changed;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Edge
|
// Edge
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,8 @@ public:
|
||||||
void setHasDownstreamClkPin(bool has_clk_pin);
|
void setHasDownstreamClkPin(bool has_clk_pin);
|
||||||
[[nodiscard]] bool bfsInQueue(BfsIndex index) const;
|
[[nodiscard]] bool bfsInQueue(BfsIndex index) const;
|
||||||
void setBfsInQueue(BfsIndex index, bool value);
|
void setBfsInQueue(BfsIndex index, bool value);
|
||||||
|
bool bfsPredecessorChanged() const { return bfs_predecessor_changed_; }
|
||||||
|
void setBfsPredecessorChanged(bool changed);
|
||||||
[[nodiscard]] bool isRegClk() const { return is_reg_clk_; }
|
[[nodiscard]] bool isRegClk() const { return is_reg_clk_; }
|
||||||
// Has sim value in some mode.
|
// Has sim value in some mode.
|
||||||
[[nodiscard]] bool hasSimValue() const { return has_sim_value_; }
|
[[nodiscard]] bool hasSimValue() const { return has_sim_value_; }
|
||||||
|
|
@ -336,6 +338,7 @@ protected:
|
||||||
unsigned int has_downstream_clk_pin_:1;
|
unsigned int has_downstream_clk_pin_:1;
|
||||||
unsigned int visited1_:1;
|
unsigned int visited1_:1;
|
||||||
unsigned int visited2_:1;
|
unsigned int visited2_:1;
|
||||||
|
unsigned int bfs_predecessor_changed_:1;
|
||||||
unsigned int has_sim_value_:1;
|
unsigned int has_sim_value_:1;
|
||||||
int level_:Graph::vertex_level_bits; // 24
|
int level_:Graph::vertex_level_bits; // 24
|
||||||
unsigned int slew_annotated_:slew_annotated_bits; // 4
|
unsigned int slew_annotated_:slew_annotated_bits; // 4
|
||||||
|
|
|
||||||
|
|
@ -234,9 +234,10 @@ protected:
|
||||||
void findVertexDelay(Vertex *vertex,
|
void findVertexDelay(Vertex *vertex,
|
||||||
ArcDelayCalc *arc_delay_calc);
|
ArcDelayCalc *arc_delay_calc);
|
||||||
DrvrLoadSlews loadSlews(LoadPinIndexMap &load_pin_index_map);
|
DrvrLoadSlews loadSlews(LoadPinIndexMap &load_pin_index_map);
|
||||||
bool loadSlewsChanged(DrvrLoadSlews &load_slews_prev,
|
void enqueueCheckEdges(Vertex *vertex);
|
||||||
LoadPinIndexMap &load_pin_index_map);
|
bool loadSlewChanged(Vertex *load_vertex,
|
||||||
void enqueueTimingChecksEdges(Vertex *vertex);
|
DrvrLoadSlews &load_slews_prev,
|
||||||
|
LoadPinIndexMap &load_pin_index_map);
|
||||||
bool annotateDelaysSlews(Edge *edge,
|
bool annotateDelaysSlews(Edge *edge,
|
||||||
const TimingArc *arc,
|
const TimingArc *arc,
|
||||||
ArcDcalcResult &dcalc_result,
|
ArcDcalcResult &dcalc_result,
|
||||||
|
|
@ -250,7 +251,7 @@ protected:
|
||||||
const Slew &gate_slew,
|
const Slew &gate_slew,
|
||||||
const Scene *scene,
|
const Scene *scene,
|
||||||
const MinMax *min_max);
|
const MinMax *min_max);
|
||||||
bool annotateLoadDelays(Vertex *drvr_vertex,
|
void annotateLoadDelays(Vertex *drvr_vertex,
|
||||||
const RiseFall *drvr_rf,
|
const RiseFall *drvr_rf,
|
||||||
ArcDcalcResult &dcalc_result,
|
ArcDcalcResult &dcalc_result,
|
||||||
LoadPinIndexMap &load_pin_index_map,
|
LoadPinIndexMap &load_pin_index_map,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue