Skip to content

Commit

Permalink
Merge branch 'parallaxsw:master' into sidebranch
Browse files Browse the repository at this point in the history
  • Loading branch information
akashlevy authored Dec 17, 2024
2 parents 0c5ae37 + fded1f2 commit 1d6b251
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 75 deletions.
77 changes: 58 additions & 19 deletions dcalc/GraphDelayCalc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand All @@ -605,6 +609,37 @@ 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++) {
const Slew &slew = delayAsFloat(load_slews[i]);
const Slew &prev_slew = delayAsFloat(prev_slews[i]);
if ((prev_slew == 0.0 && slew != 0.0)
|| (prev_slew != 0.0
&& abs((slew - prev_slew) / prev_slew) > incremental_delay_tolerance_))
return true;
}
}
return false;
}

void
GraphDelayCalc::enqueueTimingChecksEdges(Vertex *vertex)
{
Expand Down Expand Up @@ -639,21 +674,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 *
Expand Down Expand Up @@ -782,7 +816,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
Expand All @@ -806,7 +841,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()])
Expand Down Expand Up @@ -841,8 +877,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};
LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(drvr_vertex);
bool delay_changed = findDriverEdgeDelays(drvr_vertex, nullptr, edge,
arc_delay_calc_, delay_exists);
arc_delay_calc_, load_pin_index_map,
delay_exists);
if (delay_changed && observer_)
observer_->delayChangedTo(drvr_vertex);
}
Expand All @@ -852,17 +890,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;
}
}
Expand All @@ -873,6 +912,7 @@ GraphDelayCalc::findDriverEdgeDelays(Vertex *drvr_vertex,
return delay_changed;
}

// External API.
void
GraphDelayCalc::findDriverArcDelays(Vertex *drvr_vertex,
Edge *edge,
Expand All @@ -882,19 +922,18 @@ 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
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();
Expand Down
14 changes: 14 additions & 0 deletions graph/Graph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand Down
1 change: 1 addition & 0 deletions include/sta/Graph.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions include/sta/GraphClass.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();

Expand Down
25 changes: 16 additions & 9 deletions include/sta/GraphDelayCalc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include "SearchClass.hh"
#include "DcalcAnalysisPt.hh"
#include "StaState.hh"
#include "Delay.hh"
#include "ArcDelayCalc.hh"

namespace sta {
Expand All @@ -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.
Expand Down Expand Up @@ -163,29 +163,33 @@ 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);
bool hasMultiDrvrs(Vertex *drvr_vertex);
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,
Expand All @@ -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,
Expand Down
37 changes: 19 additions & 18 deletions include/sta/Search.hh
Original file line number Diff line number Diff line change
Expand Up @@ -238,25 +238,26 @@ public:
const RiseFall *to_rf,
const MinMax *min_max,
const PathAnalysisPt *path_ap);
virtual Tag *thruTag(Tag *from_tag,
Edge *edge,
const RiseFall *to_rf,
const MinMax *min_max,
const PathAnalysisPt *path_ap);
virtual Tag *thruClkTag(PathVertex *from_path,
Tag *from_tag,
bool to_propagates_clk,
Edge *edge,
const RiseFall *to_rf,
const MinMax *min_max,
const PathAnalysisPt *path_ap);
Tag *thruTag(Tag *from_tag,
Edge *edge,
const RiseFall *to_rf,
const MinMax *min_max,
const PathAnalysisPt *path_ap);
Tag *thruClkTag(PathVertex *from_path,
Tag *from_tag,
bool to_propagates_clk,
Edge *edge,
const RiseFall *to_rf,
const MinMax *min_max,
const PathAnalysisPt *path_ap);
ClkInfo *thruClkInfo(PathVertex *from_path,
ClkInfo *from_tag_clk,
Edge *edge,
Vertex *to_vertex,
const Pin *to_pin,
const MinMax *min_max,
const PathAnalysisPt *path_ap);
ClkInfo *from_clk_info,
bool from_is_clk,
Edge *edge,
const Pin *to_pin,
bool to_is_clk,
const MinMax *min_max,
const PathAnalysisPt *path_ap);
ClkInfo *clkInfoWithCrprClkPath(ClkInfo *from_clk_info,
PathVertex *from_path,
const PathAnalysisPt *path_ap);
Expand Down
4 changes: 2 additions & 2 deletions search/ClkInfo.hh
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public:
const Arrival &insertion() const { return insertion_; }
ClockUncertainties *uncertainties() const { return uncertainties_; }
PathAPIndex pathAPIndex() const { return path_ap_index_; }
// Clock path for the last driver in the clock network used for
// crpr resolution.
// Clock path used for crpr resolution.
// Null for clocks because the path cannot point to itself.
PathVertexRep &crprClkPath() { return crpr_clk_path_; }
const PathVertexRep &crprClkPath() const { return crpr_clk_path_; }
VertexId crprClkVertexId() const;
Expand Down
Loading

0 comments on commit 1d6b251

Please sign in to comment.