Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions dcalc/GraphDelayCalc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,7 @@ DcalcPred::searchThru(Edge *edge,
|| edge->isDisabledLoop()
|| sdc->isDisabledConstraint(edge)
|| sdc->isDisabledCondDefault(edge)
|| (edge->isBidirectInstPath()
&& !variables->bidirectInstPathsEnabled()));
|| sta_->isDisabledBidirectInstPath(edge));
}

bool
Expand Down Expand Up @@ -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_) {
Expand Down
14 changes: 14 additions & 0 deletions graph/Graph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Comment on lines +253 to +259

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Potential null pointer dereference. If bidir_load or bidir_drvr is null (for example, if the pin is a power or ground pin, or if the vertices were not created), calling makeEdge will dereference a null pointer when calling id(from) or id(to). A null check should be added before creating the edge.

    if (network_->isTopInstance(inst)
        && network_->direction(pin)->isBidirect()) {
      Vertex *bidir_load, *bidir_drvr;
      pinVertices(pin, bidir_load, bidir_drvr);
      if (bidir_load && bidir_drvr) {
        Edge *edge = makeEdge(bidir_load, bidir_drvr, TimingArcSet::wireTimingArcSet());
        edge->setIsBidirectPortPath(true);
      }
    }

}
delete pin_iter;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down
1 change: 1 addition & 0 deletions graph/Graph.i
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions include/sta/Graph.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions include/sta/PortDelay.hh
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public:
const Pin *refPin() const { return ref_pin_; }
void setRefPin(const Pin *ref_pin);
const RiseFall *refTransition() const;
bool refPinEdgesExist() const { return ref_pin_edges_exist_; }
void setRefPinEdgesExist(bool exists);

protected:
PortDelay(const Pin *pin,
Expand All @@ -62,6 +64,7 @@ protected:
bool source_latency_included_{false};
bool network_latency_included_{false};
const Pin *ref_pin_{nullptr};
bool ref_pin_edges_exist_{false};
RiseFallMinMax delays_;
PinSet leaf_pins_;
};
Expand Down
7 changes: 4 additions & 3 deletions include/sta/Sdc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@ public:
const Clock *clk,
const RiseFall *clk_rf,
const MinMaxAll *min_max);
void ensureInputDelayRefPinEdges();
void setOutputDelay(const Pin *pin,
const RiseFallBoth *rf,
const Clock *clk,
Expand Down Expand Up @@ -806,7 +807,6 @@ public:
const MinMaxAll *min_max);

// STA interface.
InputDelaySet *refPinInputDelays(const Pin *ref_pin) const;
const LogicValueMap &logicValues() const { return logic_value_map_; }
const LogicValueMap &caseLogicValues() const { return case_value_map_; }
// Returns nullptr if set_operating_conditions has not been called.
Expand Down Expand Up @@ -1221,6 +1221,7 @@ protected:
InputDelay *except);
void deleteInputDelaysReferencing(const Clock *clk);
void deleteInputDelay(InputDelay *input_delay);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Declare a helper method to clean up virtual edges created for input delay reference pins when the input delays are deleted.

Suggested change
void deleteInputDelayRefPinEdges();

OutputDelay *findOutputDelay(const Pin *pin,
const ClockEdge *clk_edge);
OutputDelay *makeOutputDelay(const Pin *pin,
Expand All @@ -1229,6 +1230,7 @@ protected:
OutputDelay *except);
void deleteOutputDelaysReferencing(const Clock *clk);
void deleteOutputDelay(OutputDelay *output_delay);

void deleteClockInsertion(ClockInsertion *insertion);
void deleteClockInsertionsReferencing(Clock *clk);
void deleteInterClockUncertainty(InterClockUncertainty *uncertainties);
Expand Down Expand Up @@ -1334,15 +1336,14 @@ protected:

InputDelaySet input_delays_;
InputDelaysPinMap input_delay_pin_map_;
InputDelaysPinMap input_delay_ref_pin_map_;
bool have_input_delay_ref_pins_{false};
// Input delays on hierarchical pins are indexed by the load pins.
InputDelaysPinMap input_delay_leaf_pin_map_;
InputDelaysPinMap input_delay_internal_pin_map_;
int input_delay_index_{0};

OutputDelaySet output_delays_;
OutputDelaysPinMap output_delay_pin_map_;
OutputDelaysPinMap output_delay_ref_pin_map_;
// Output delays on hierarchical pins are indexed by the load pins.
OutputDelaysPinMap output_delay_leaf_pin_map_;

Expand Down
2 changes: 0 additions & 2 deletions include/sta/Search.hh
Original file line number Diff line number Diff line change
Expand Up @@ -800,8 +800,6 @@ public:

protected:
void init0();
void enqueueRefPinInputDelays(const Pin *ref_pin,
const Sdc *sdc);
void seedArrivals(Vertex *vertex);
void pruneCrprArrivals();
void constrainedRequiredsInvalid(Vertex *vertex,
Expand Down
4 changes: 1 addition & 3 deletions include/sta/Sta.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1044,6 +1042,7 @@ public:
int endpointViolationCount(const MinMax *min_max);
// Find all required times after updateTiming().
void findRequireds();
void findRequired(Vertex *vertex);
std::string reportDelayCalc(Edge *edge,
TimingArc *arc,
const Scene *scene,
Expand Down Expand Up @@ -1532,7 +1531,6 @@ protected:
const Mode *mode,
// Return value.
PinSet &pins);
void findRequired(Vertex *vertex);

void reportDelaysWrtClks(const Pin *pin,
const Scene *scene,
Expand Down
2 changes: 2 additions & 0 deletions include/sta/StaState.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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_; }
Expand Down
4 changes: 4 additions & 0 deletions include/sta/TimingArc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ public:
static int wireArcIndex(const RiseFall *rf);
static int wireArcCount() { return 2; }

// Psuedo definition for port ref_pin arcs.
static TimingArcSet *portRefPinTimingArcSet() { return port_refpin_timing_arc_set_; }

protected:
TimingArcSet(const TimingRole *role,
TimingArcAttrsPtr attrs);
Expand All @@ -230,6 +233,7 @@ protected:

static TimingArcAttrsPtr wire_timing_arc_attrs_;
static TimingArcSet *wire_timing_arc_set_;
static TimingArcSet *port_refpin_timing_arc_set_;
};

// A timing arc is a single from/to transition between two ports.
Expand Down
3 changes: 3 additions & 0 deletions include/sta/TimingRole.hh
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public:
static const TimingRole *nonSeqHold() { return &non_seq_hold_; }
static const TimingRole *clockTreePathMin() { return &clock_tree_path_min_; }
static const TimingRole *clockTreePathMax() { return &clock_tree_path_max_; }
static const TimingRole *portDelayRefPin() { return &port_delay_ref_pin_; }
const std::string &to_string() const { return name_; }
int index() const { return index_; }
bool isWire() const;
Expand Down Expand Up @@ -139,6 +140,8 @@ private:
static const TimingRole non_seq_hold_;
static const TimingRole clock_tree_path_min_;
static const TimingRole clock_tree_path_max_;
// Artificial timing from input/output_delay ref_pin to the input/output.
static const TimingRole port_delay_ref_pin_;
static TimingRoleMap timing_roles_;

friend class TimingRoleLess;
Expand Down
4 changes: 4 additions & 0 deletions liberty/TimingArc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ TimingArc::intrinsicDelay() const

TimingArcAttrsPtr TimingArcSet::wire_timing_arc_attrs_ = nullptr;
TimingArcSet *TimingArcSet::wire_timing_arc_set_ = nullptr;
TimingArcSet *TimingArcSet::port_refpin_timing_arc_set_ = nullptr;

TimingArcSet::TimingArcSet(LibertyCell *,
LibertyPort *from,
Expand Down Expand Up @@ -524,6 +525,9 @@ TimingArcSet::init()
Transition::rise(), nullptr);
new TimingArc(wire_timing_arc_set_, Transition::fall(),
Transition::fall(), nullptr);

port_refpin_timing_arc_set_ = new TimingArcSet(TimingRole::portDelayRefPin(),
wire_timing_arc_attrs_);
}

void
Expand Down
2 changes: 2 additions & 0 deletions liberty/TimingRole.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ const TimingRole TimingRole::clock_tree_path_min_("min clock tree path", false,
false, MinMax::min(), nullptr, 27);
const TimingRole TimingRole::clock_tree_path_max_("max clock tree path", false, false,
false, MinMax::max(), nullptr, 28);
const TimingRole TimingRole::port_delay_ref_pin_("port delay ref pin", false, false,
false, nullptr, nullptr, 29);

TimingRole::TimingRole(const char *name,
bool is_sdf_iopath,
Expand Down
10 changes: 10 additions & 0 deletions sdc/PortDelay.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ PortDelay::refTransition() const
return RiseFall::rise();
}

void
PortDelay::setRefPinEdgesExist(bool exists)
{
ref_pin_edges_exist_ = exists;
}

////////////////////////////////////////////////////////////////

InputDelay::InputDelay(const Pin *pin,
const ClockEdge *clk_edge,
int index,
Expand All @@ -97,6 +105,8 @@ InputDelay::InputDelay(const Pin *pin,
findLeafLoadPins(pin, network, &leaf_pins_);
}

////////////////////////////////////////////////////////////////

OutputDelay::OutputDelay(const Pin *pin,
const ClockEdge *clk_edge,
const Network *network) :
Expand Down
Loading