dcalc use load slew changes to stop propagation
Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
parent
49a931b0d1
commit
2d11aa9c5e
|
|
@ -579,13 +579,17 @@ GraphDelayCalc::findVertexDelay(Vertex *vertex,
|
|||
else {
|
||||
if (network_->isLeaf(pin)) {
|
||||
if (vertex->isDriver(network_)) {
|
||||
bool delay_changed = findDriverDelays(vertex, arc_delay_calc);
|
||||
LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(vertex);
|
||||
DrvrLoadSlews prev_load_slews = loadSlews(load_pin_index_map);
|
||||
findDriverDelays(vertex, arc_delay_calc, load_pin_index_map);
|
||||
if (propagate) {
|
||||
if (network_->direction(pin)->isInternal())
|
||||
enqueueTimingChecksEdges(vertex);
|
||||
// Enqueue adjacent vertices even if the delays did not
|
||||
bool load_slews_changed = loadSlewsChanged(prev_load_slews,
|
||||
load_pin_index_map);
|
||||
// Enqueue adjacent vertices even if the load slews did not
|
||||
// change when non-incremental to stride past annotations.
|
||||
if (delay_changed || !incremental_)
|
||||
if (load_slews_changed || !incremental_)
|
||||
iter_->enqueueAdjacentVertices(vertex);
|
||||
}
|
||||
}
|
||||
|
|
@ -605,6 +609,33 @@ GraphDelayCalc::findVertexDelay(Vertex *vertex,
|
|||
}
|
||||
}
|
||||
|
||||
DrvrLoadSlews
|
||||
GraphDelayCalc::loadSlews(LoadPinIndexMap &load_pin_index_map)
|
||||
{
|
||||
DrvrLoadSlews load_slews(load_pin_index_map.size());
|
||||
for (auto const [pin, index] : load_pin_index_map) {
|
||||
Vertex *load_vertex = graph_->pinLoadVertex(pin);
|
||||
load_slews[index] = graph_->slews(load_vertex);
|
||||
}
|
||||
return load_slews;
|
||||
}
|
||||
|
||||
bool
|
||||
GraphDelayCalc::loadSlewsChanged(DrvrLoadSlews &prev_load_slews,
|
||||
LoadPinIndexMap &load_pin_index_map)
|
||||
{
|
||||
for (auto const [pin, index] : load_pin_index_map) {
|
||||
Vertex *load_vertex = graph_->pinLoadVertex(pin);
|
||||
const SlewSeq load_slews = graph_->slews(load_vertex);
|
||||
const SlewSeq &prev_slews = prev_load_slews[index];
|
||||
for (size_t i = 0; i < load_slews.size(); i++) {
|
||||
if (!delayEqual(load_slews[i], prev_slews[i]))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
GraphDelayCalc::enqueueTimingChecksEdges(Vertex *vertex)
|
||||
{
|
||||
|
|
@ -639,21 +670,20 @@ GraphDelayCalc::enqueueTimingChecksEdges(Vertex *vertex)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
GraphDelayCalc::findDriverDelays(Vertex *drvr_vertex,
|
||||
ArcDelayCalc *arc_delay_calc)
|
||||
ArcDelayCalc *arc_delay_calc,
|
||||
LoadPinIndexMap &load_pin_index_map)
|
||||
{
|
||||
bool delay_changed = false;
|
||||
MultiDrvrNet *multi_drvr = findMultiDrvrNet(drvr_vertex);
|
||||
if (multi_drvr == nullptr
|
||||
|| (multi_drvr
|
||||
&& (!multi_drvr->parallelGates(network_)
|
||||
|| drvr_vertex == multi_drvr->dcalcDrvr()))) {
|
||||
initLoadSlews(drvr_vertex);
|
||||
delay_changed |= findDriverDelays1(drvr_vertex, multi_drvr, arc_delay_calc);
|
||||
findDriverDelays1(drvr_vertex, multi_drvr, arc_delay_calc, load_pin_index_map);
|
||||
}
|
||||
arc_delay_calc_->finishDrvrPin();
|
||||
return delay_changed;
|
||||
}
|
||||
|
||||
MultiDrvrNet *
|
||||
|
|
@ -782,7 +812,8 @@ GraphDelayCalc::initLoadSlews(Vertex *drvr_vertex)
|
|||
bool
|
||||
GraphDelayCalc::findDriverDelays1(Vertex *drvr_vertex,
|
||||
MultiDrvrNet *multi_drvr,
|
||||
ArcDelayCalc *arc_delay_calc)
|
||||
ArcDelayCalc *arc_delay_calc,
|
||||
LoadPinIndexMap &load_pin_index_map)
|
||||
{
|
||||
initSlew(drvr_vertex);
|
||||
if (multi_drvr
|
||||
|
|
@ -806,7 +837,8 @@ GraphDelayCalc::findDriverDelays1(Vertex *drvr_vertex,
|
|||
&& search_pred_->searchThru(edge)
|
||||
&& !edge->role()->isLatchDtoQ())
|
||||
delay_changed |= findDriverEdgeDelays(drvr_vertex, multi_drvr, edge,
|
||||
arc_delay_calc, delay_exists);
|
||||
arc_delay_calc, load_pin_index_map,
|
||||
delay_exists);
|
||||
}
|
||||
for (auto rf : RiseFall::range()) {
|
||||
if (!delay_exists[rf->index()])
|
||||
|
|
@ -841,10 +873,10 @@ GraphDelayCalc::findLatchEdgeDelays(Edge *edge)
|
|||
debugPrint(debug_, "delay_calc", 2, "find latch D->Q %s",
|
||||
sdc_network_->pathName(drvr_inst));
|
||||
array<bool, RiseFall::index_count> delay_exists = {false, false};
|
||||
bool delay_changed = findDriverEdgeDelays(drvr_vertex, nullptr, edge,
|
||||
arc_delay_calc_, delay_exists);
|
||||
if (delay_changed && observer_)
|
||||
observer_->delayChangedTo(drvr_vertex);
|
||||
LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(drvr_vertex);
|
||||
findDriverEdgeDelays(drvr_vertex, nullptr, edge,
|
||||
arc_delay_calc_, load_pin_index_map,
|
||||
delay_exists);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -852,17 +884,18 @@ GraphDelayCalc::findDriverEdgeDelays(Vertex *drvr_vertex,
|
|||
const MultiDrvrNet *multi_drvr,
|
||||
Edge *edge,
|
||||
ArcDelayCalc *arc_delay_calc,
|
||||
LoadPinIndexMap &load_pin_index_map,
|
||||
// Return value.
|
||||
array<bool, RiseFall::index_count> &delay_exists)
|
||||
{
|
||||
Vertex *from_vertex = edge->from(graph_);
|
||||
const TimingArcSet *arc_set = edge->timingArcSet();
|
||||
bool delay_changed = false;
|
||||
LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(drvr_vertex);
|
||||
for (auto dcalc_ap : corners_->dcalcAnalysisPts()) {
|
||||
for (const TimingArc *arc : arc_set->arcs()) {
|
||||
delay_changed |= findDriverArcDelays(drvr_vertex, multi_drvr, edge, arc,
|
||||
load_pin_index_map, dcalc_ap,
|
||||
arc_delay_calc);
|
||||
dcalc_ap, arc_delay_calc,
|
||||
load_pin_index_map);
|
||||
delay_exists[arc->toEdge()->asRiseFall()->index()] = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -873,6 +906,7 @@ GraphDelayCalc::findDriverEdgeDelays(Vertex *drvr_vertex,
|
|||
return delay_changed;
|
||||
}
|
||||
|
||||
// External API.
|
||||
void
|
||||
GraphDelayCalc::findDriverArcDelays(Vertex *drvr_vertex,
|
||||
Edge *edge,
|
||||
|
|
@ -882,9 +916,8 @@ GraphDelayCalc::findDriverArcDelays(Vertex *drvr_vertex,
|
|||
{
|
||||
MultiDrvrNet *multi_drvr = multiDrvrNet(drvr_vertex);
|
||||
LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(drvr_vertex);
|
||||
findDriverArcDelays(drvr_vertex, multi_drvr, edge, arc,
|
||||
load_pin_index_map, dcalc_ap,
|
||||
arc_delay_calc);
|
||||
findDriverArcDelays(drvr_vertex, multi_drvr, edge, arc, dcalc_ap,
|
||||
arc_delay_calc, load_pin_index_map);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -892,9 +925,9 @@ GraphDelayCalc::findDriverArcDelays(Vertex *drvr_vertex,
|
|||
const MultiDrvrNet *multi_drvr,
|
||||
Edge *edge,
|
||||
const TimingArc *arc,
|
||||
LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
ArcDelayCalc *arc_delay_calc)
|
||||
ArcDelayCalc *arc_delay_calc,
|
||||
LoadPinIndexMap &load_pin_index_map)
|
||||
{
|
||||
bool delay_changed = false;
|
||||
const RiseFall *from_rf = arc->fromEdge()->asRiseFall();
|
||||
|
|
|
|||
|
|
@ -741,6 +741,20 @@ Graph::setSlew(Vertex *vertex,
|
|||
}
|
||||
}
|
||||
|
||||
SlewSeq
|
||||
Graph::slews(Vertex *vertex)
|
||||
{
|
||||
SlewSeq slews;
|
||||
VertexId vertex_id = id(vertex);
|
||||
DcalcAPIndex rf_ap_count = slew_rf_count_ * ap_count_;
|
||||
for (DcalcAPIndex i = 0; i < rf_ap_count; i++) {
|
||||
DelayTable *table = slew_tables_[i];
|
||||
Slew &slew = table->ref(vertex_id);
|
||||
slews.push_back(slew);
|
||||
}
|
||||
return slews;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
Edge *
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ public:
|
|||
const RiseFall *rf,
|
||||
DcalcAPIndex ap_index,
|
||||
const Slew &slew);
|
||||
SlewSeq slews(Vertex *vertex);
|
||||
|
||||
// Edge functions.
|
||||
virtual Edge *edge(EdgeId edge_index) const;
|
||||
|
|
|
|||
|
|
@ -23,9 +23,12 @@
|
|||
#include "Vector.hh"
|
||||
#include "MinMax.hh"
|
||||
#include "Transition.hh"
|
||||
#include "Delay.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
using std::vector;
|
||||
|
||||
// Class declarations for pointer references.
|
||||
class Graph;
|
||||
class Vertex;
|
||||
|
|
@ -46,6 +49,7 @@ typedef int Level;
|
|||
typedef int DcalcAPIndex;
|
||||
typedef int TagGroupIndex;
|
||||
typedef Vector<GraphLoop*> GraphLoopSeq;
|
||||
typedef vector<Slew> SlewSeq;
|
||||
|
||||
static constexpr int level_max = std::numeric_limits<Level>::max();
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include "SearchClass.hh"
|
||||
#include "DcalcAnalysisPt.hh"
|
||||
#include "StaState.hh"
|
||||
#include "Delay.hh"
|
||||
#include "ArcDelayCalc.hh"
|
||||
|
||||
namespace sta {
|
||||
|
|
@ -41,6 +40,7 @@ class FindVertexDelays;
|
|||
class NetCaps;
|
||||
|
||||
typedef Map<const Vertex*, MultiDrvrNet*> MultiDrvrNetMap;
|
||||
typedef vector<SlewSeq> DrvrLoadSlews;
|
||||
|
||||
// This class traverses the graph calling the arc delay calculator and
|
||||
// annotating delays on graph edges.
|
||||
|
|
@ -163,8 +163,9 @@ protected:
|
|||
const TimingArc *arc,
|
||||
float from_slew,
|
||||
const DcalcAnalysisPt *dcalc_ap);
|
||||
bool findDriverDelays(Vertex *drvr_vertex,
|
||||
ArcDelayCalc *arc_delay_calc);
|
||||
void findDriverDelays(Vertex *drvr_vertex,
|
||||
ArcDelayCalc *arc_delay_calc,
|
||||
LoadPinIndexMap &load_pin_index_map);
|
||||
MultiDrvrNet *multiDrvrNet(const Vertex *drvr_vertex) const;
|
||||
MultiDrvrNet *findMultiDrvrNet(Vertex *drvr_pin);
|
||||
MultiDrvrNet *makeMultiDrvrNet(Vertex *drvr_vertex);
|
||||
|
|
@ -172,20 +173,23 @@ protected:
|
|||
Vertex *firstLoad(Vertex *drvr_vertex);
|
||||
bool findDriverDelays1(Vertex *drvr_vertex,
|
||||
MultiDrvrNet *multi_drvr,
|
||||
ArcDelayCalc *arc_delay_calc);
|
||||
ArcDelayCalc *arc_delay_calc,
|
||||
LoadPinIndexMap &load_pin_index_map);
|
||||
void initLoadSlews(Vertex *drvr_vertex);
|
||||
bool findDriverEdgeDelays(Vertex *drvr_vertex,
|
||||
const MultiDrvrNet *multi_drvr,
|
||||
Edge *edge,
|
||||
ArcDelayCalc *arc_delay_calc,
|
||||
const MultiDrvrNet *multi_drvr,
|
||||
Edge *edge,
|
||||
ArcDelayCalc *arc_delay_calc,
|
||||
LoadPinIndexMap &load_pin_index_map,
|
||||
// Return value.
|
||||
array<bool, RiseFall::index_count> &delay_exists);
|
||||
bool findDriverArcDelays(Vertex *drvr_vertex,
|
||||
const MultiDrvrNet *multi_drvr,
|
||||
Edge *edge,
|
||||
const TimingArc *arc,
|
||||
LoadPinIndexMap &load_pin_index_map,
|
||||
const DcalcAnalysisPt *dcalc_ap,
|
||||
ArcDelayCalc *arc_delay_calc);
|
||||
ArcDelayCalc *arc_delay_calc,
|
||||
LoadPinIndexMap &load_pin_index_map);
|
||||
ArcDcalcArgSeq makeArcDcalcArgs(Vertex *drvr_vertex,
|
||||
const MultiDrvrNet *multi_drvr,
|
||||
Edge *edge,
|
||||
|
|
@ -205,6 +209,9 @@ protected:
|
|||
void findVertexDelay(Vertex *vertex,
|
||||
ArcDelayCalc *arc_delay_calc,
|
||||
bool propagate);
|
||||
DrvrLoadSlews loadSlews(LoadPinIndexMap &load_pin_index_map);
|
||||
bool loadSlewsChanged(DrvrLoadSlews &prev_load_slews,
|
||||
LoadPinIndexMap &load_pin_index_map);
|
||||
void enqueueTimingChecksEdges(Vertex *vertex);
|
||||
bool annotateDelaysSlews(Edge *edge,
|
||||
const TimingArc *arc,
|
||||
|
|
|
|||
Loading…
Reference in New Issue