sta_internal_bidirect_instance_paths_enabled use load->driver edges

Signed-off-by: James Cherry <cherry@CerezoBook.local>
This commit is contained in:
James Cherry 2026-06-15 17:02:58 -07:00
parent 376d86bbce
commit 0fe167a80d
11 changed files with 66 additions and 34 deletions

View File

@ -107,8 +107,7 @@ DcalcPred::searchThru(Edge *edge,
|| edge->isDisabledLoop()
|| sdc->isDisabledConstraint(edge)
|| sdc->isDisabledCondDefault(edge)
|| (edge->isBidirectInstPath()
&& !variables->bidirectInstPathsEnabled()));
|| sta_->isDisabledBidirectInstPath(edge));
}
bool
@ -1011,13 +1010,13 @@ GraphDelayCalc::findDriverEdgeDelays(Vertex *drvr_vertex,
if (search_pred_->searchFrom(from_vertex, mode)
&& search_pred_->searchThru(edge, mode)) {
for (const MinMax *min_max : MinMax::range()) {
for (const TimingArc *arc : arc_set->arcs()) {
delay_changed |= findDriverArcDelays(drvr_vertex, multi_drvr, edge, arc,
for (const TimingArc *arc : arc_set->arcs()) {
delay_changed |= findDriverArcDelays(drvr_vertex, multi_drvr, edge, arc,
scene, min_max, arc_delay_calc,
load_pin_index_map);
delay_exists[arc->toEdge()->asRiseFall()->index()] = true;
}
}
load_pin_index_map);
delay_exists[arc->toEdge()->asRiseFall()->index()] = true;
}
}
}
}
if (delay_changed && observer_) {

View File

@ -250,6 +250,13 @@ Graph::makeInstDrvrWireEdges(const Instance *inst,
if (network_->isDriver(pin)
&& !visited_drvrs.contains(pin))
makeWireEdgesFromPin(pin, visited_drvrs);
if (network_->isTopInstance(inst)
&& network_->direction(pin)->isBidirect()) {
Vertex *bidir_load, *bidir_drvr;
pinVertices(pin, bidir_load, bidir_drvr);
Edge *edge = makeEdge(bidir_load, bidir_drvr, TimingArcSet::wireTimingArcSet());
edge->setIsBidirectPortPath(true);
}
}
delete pin_iter;
}
@ -1211,6 +1218,7 @@ Edge::init(VertexId from,
vertex_out_prev_ = edge_id_null;
is_bidirect_inst_path_ = false;
is_bidirect_net_path_ = false;
is_bidirect_port_path_ = false;
arc_delays_ = nullptr;
arc_delay_annotated_is_bits_ = true;
@ -1368,6 +1376,12 @@ Edge::setIsBidirectNetPath(bool is_bidir)
is_bidirect_net_path_ = is_bidir;
}
void
Edge::setIsBidirectPortPath(bool is_bidir)
{
is_bidirect_port_path_ = is_bidir;
}
void
Edge::setHasSimSense(bool has_sense)
{

View File

@ -128,6 +128,7 @@ remove_delay_slew_annotations()
Pin *pin() { return self->pin(); }
bool is_bidirect_driver() { return self->isBidirectDriver(); }
int level() { return Sta::sta()->vertexLevel(self); }
bool is_root() { return self->isRoot(); }
int tag_group_index() { return self->tagGroupIndex(); }
float

View File

@ -364,6 +364,9 @@ public:
void setIsBidirectInstPath(bool is_bidir);
bool isBidirectNetPath() const { return is_bidirect_net_path_; }
void setIsBidirectNetPath(bool is_bidir);
bool isBidirectPortPath() const { return is_bidirect_port_path_; }
void setIsBidirectPortPath(bool is_bidir);
void removeDelayAnnotated();
[[nodiscard]] bool hasSimSense() const { return has_sim_sense_; }
void setHasSimSense(bool has_sense);
@ -403,6 +406,8 @@ protected:
bool delay_annotation_is_incremental_:1;
bool is_bidirect_inst_path_:1;
bool is_bidirect_net_path_:1;
// Bidirect load -> driver edge.
bool is_bidirect_port_path_:1;
bool is_disabled_loop_:1;
bool has_sim_sense_:1;
bool has_disabled_cond_:1;

View File

@ -567,8 +567,6 @@ public:
const Sdc *sdc);
// Edge is disabled to break combinational loops.
[[nodiscard]] bool isDisabledLoop(Edge *edge) const;
// Edge is disabled internal bidirect output path.
[[nodiscard]] bool isDisabledBidirectInstPath(Edge *edge) const;
// Edge is disabled bidirect net path.
[[nodiscard]] bool isDisabledBidirectNetPath(Edge *edge) const;
[[nodiscard]] bool isDisabledPresetClr(Edge *edge) const;

View File

@ -106,6 +106,8 @@ public:
const Variables *variables() const { return variables_; }
// Edge is default cond disabled by timing_disable_cond_default_arcs var.
[[nodiscard]] bool isDisabledCondDefault(const Edge *edge) const;
// Edge is disabled internal bidirect output path.
[[nodiscard]] bool isDisabledBidirectInstPath(Edge *edge) const;
const SceneSeq &scenes() { return scenes_; }
const SceneSeq &scenes() const { return scenes_; }

View File

@ -196,11 +196,13 @@ bool
Levelize::searchThru(Edge *edge)
{
const TimingRole *role = edge->role();
return !role->isTimingCheck() && role != TimingRole::latchDtoQ()
&& !edge->isDisabledLoop()
// Register/latch preset/clr edges are disabled by default.
&& !(role == TimingRole::regSetClr() && !variables_->presetClrArcsEnabled())
&& !(edge->isBidirectInstPath() && !variables_->bidirectInstPathsEnabled());
return !(role->isTimingCheck()
|| role == TimingRole::latchDtoQ()
|| edge->isDisabledLoop()
// Register/latch preset/clr edges are disabled by default.
|| (role == TimingRole::regSetClr()
&& !variables_->presetClrArcsEnabled())
|| isDisabledBidirectInstPath(edge));
}
bool

View File

@ -184,13 +184,14 @@ SearchAdj::searchThru(Edge *edge,
{
const TimingRole *role = edge->role();
const Variables *variables = sta_->variables();
return !role->isTimingCheck()
&& !role->isLatchDtoQ()
// Register/latch preset/clr edges are disabled by default.
&& !(role == TimingRole::regSetClr() && !variables->presetClrArcsEnabled())
&& !(edge->isBidirectInstPath() && !variables->bidirectInstPathsEnabled())
&& (!edge->isDisabledLoop()
|| (variables->dynamicLoopBreaking() && hasPendingLoopPaths(edge)));
return !(role->isTimingCheck()
|| role->isLatchDtoQ()
// Register/latch preset/clr edges are disabled by default.
|| (role == TimingRole::regSetClr()
&& !variables->presetClrArcsEnabled())
|| sta_->isDisabledBidirectInstPath(edge)
|| (edge->isDisabledLoop()
&& !(variables->dynamicLoopBreaking() && hasPendingLoopPaths(edge))));
}
bool
@ -3228,8 +3229,10 @@ Search::isEndpoint(Vertex *vertex,
const Pin *pin = vertex->pin();
const Sdc *sdc = mode->sdc();
return hasFanin(vertex, pred, graph_, mode)
&& ((vertex->hasChecks() && hasEnabledChecks(vertex, mode))
|| sdc->isConstrainedEnd(pin) || !hasFanout(vertex, pred, graph_, mode)
&& ((vertex->hasChecks()
&& hasEnabledChecks(vertex, mode))
|| sdc->isConstrainedEnd(pin)
|| !hasFanout(vertex, pred, graph_, mode)
|| sdc->isPathDelayInternalTo(pin)
// Unconstrained paths at register clk pins.
|| (unconstrained_paths_ && vertex->isRegClk())

View File

@ -184,6 +184,7 @@ ClkTreeSearchPred::searchThru(Edge *edge,
|| sdc->isDisabledConstraint(edge)
|| sdc->isDisabledCondDefault(edge)
|| edge->isBidirectInstPath()
|| edge->isBidirectPortPath()
|| edge->isDisabledLoop());
}

View File

@ -1702,8 +1702,10 @@ Sta::disabledEdges(const Mode *mode)
VertexOutEdgeIterator edge_iter(vertex, graph_);
while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next();
if (isDisabledConstant(edge, mode) || isDisabledCondDefault(edge)
|| isDisabledConstraint(edge, sdc) || edge->isDisabledLoop()
if (isDisabledConstant(edge, mode)
|| isDisabledCondDefault(edge)
|| isDisabledConstraint(edge, sdc)
|| edge->isDisabledLoop()
|| isDisabledPresetClr(edge))
disabled_edges.push_back(edge);
}
@ -1841,12 +1843,6 @@ Sta::exprConstantPins(FuncExpr *expr,
}
}
bool
Sta::isDisabledBidirectInstPath(Edge *edge) const
{
return !variables_->bidirectInstPathsEnabled() && edge->isBidirectInstPath();
}
bool
Sta::isDisabledPresetClr(Edge *edge) const
{
@ -5217,8 +5213,10 @@ FanInOutSrchPred::searchThru(Edge *edge,
const Sim *sim = mode->sim();
return searchThruRole(edge)
&& (thru_disabled_
|| !(sdc->isDisabledConstraint(edge) || sim->isDisabledCond(edge)
|| sta_->isDisabledCondDefault(edge)))
|| !(sdc->isDisabledConstraint(edge)
|| sim->isDisabledCond(edge)
|| sta_->isDisabledCondDefault(edge)
|| sta_->isDisabledBidirectInstPath(edge)))
&& (thru_constants_ || sim->simTimingSense(edge) != TimingSense::none);
}

View File

@ -31,6 +31,7 @@
#include "Graph.hh"
#include "Mode.hh"
#include "Network.hh"
#include "PortDirection.hh"
#include "Scene.hh"
#include "Sdc.hh"
#include "TimingArc.hh"
@ -124,6 +125,14 @@ StaState::isDisabledCondDefault(const Edge *edge) const
&& edge->timingArcSet()->isCondDefault();
}
bool
StaState::isDisabledBidirectInstPath(Edge *edge) const
{
return (edge->isBidirectInstPath()
|| edge->isBidirectPortPath())
&& !variables_->bidirectInstPathsEnabled();
}
////////////////////////////////////////////////////////////////
size_t