2018-09-28 17:54:21 +02:00
|
|
|
// OpenSTA, Static Timing Analyzer
|
2019-01-01 21:26:11 +01:00
|
|
|
// Copyright (c) 2019, Parallax Software, Inc.
|
2018-09-28 17:54:21 +02:00
|
|
|
//
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
#ifndef STA_GRAPH_H
|
|
|
|
|
#define STA_GRAPH_H
|
|
|
|
|
|
|
|
|
|
#include "DisallowCopyAssign.hh"
|
|
|
|
|
#include "Iterator.hh"
|
|
|
|
|
#include "Map.hh"
|
|
|
|
|
#include "Vector.hh"
|
|
|
|
|
#include "Pool.hh"
|
|
|
|
|
#include "StaState.hh"
|
|
|
|
|
#include "LibertyClass.hh"
|
|
|
|
|
#include "NetworkClass.hh"
|
|
|
|
|
#include "Delay.hh"
|
|
|
|
|
#include "GraphClass.hh"
|
|
|
|
|
|
|
|
|
|
namespace sta {
|
|
|
|
|
|
|
|
|
|
class MinMax;
|
|
|
|
|
class Sdc;
|
|
|
|
|
class PathVertexRep;
|
|
|
|
|
|
|
|
|
|
enum VertexColor {
|
|
|
|
|
vertex_color_white,
|
|
|
|
|
vertex_color_gray,
|
|
|
|
|
vertex_color_black
|
|
|
|
|
};
|
|
|
|
|
|
2018-11-26 18:15:52 +01:00
|
|
|
typedef Pool<Delay> DelayPool;
|
2018-09-28 17:54:21 +02:00
|
|
|
typedef Pool<Vertex> VertexPool;
|
|
|
|
|
typedef Pool<Edge> EdgePool;
|
|
|
|
|
typedef Map<const Pin*, Vertex*> PinVertexMap;
|
|
|
|
|
typedef Iterator<Edge*> VertexEdgeIterator;
|
|
|
|
|
typedef Map<const Pin*, float*> WidthCheckAnnotations;
|
|
|
|
|
typedef Map<const Pin*, float*> PeriodCheckAnnotations;
|
|
|
|
|
typedef Vector<DelayPool*> DelayPoolSeq;
|
|
|
|
|
|
|
|
|
|
// The graph acts as a BUILDER for the graph vertices and edges.
|
|
|
|
|
class Graph : public StaState
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
// slew_tr_count is
|
|
|
|
|
// 0 no slews
|
|
|
|
|
// 1 one slew for rise/fall
|
|
|
|
|
// 2 rise/fall slews
|
|
|
|
|
// ap_count is the dcalc analysis point count.
|
|
|
|
|
Graph(StaState *sta,
|
|
|
|
|
int slew_tr_count,
|
|
|
|
|
bool have_arc_delays,
|
|
|
|
|
DcalcAPIndex ap_count);
|
|
|
|
|
void makeGraph();
|
|
|
|
|
virtual ~Graph();
|
|
|
|
|
|
|
|
|
|
// Number of arc delays and slews from sdf or delay calculation.
|
|
|
|
|
virtual void setDelayCount(DcalcAPIndex ap_count);
|
|
|
|
|
|
|
|
|
|
// Vertex functions.
|
|
|
|
|
// Bidirect pins have two vertices.
|
|
|
|
|
virtual Vertex *vertex(VertexIndex vertex_index) const;
|
|
|
|
|
VertexIndex index(const Vertex *vertex) const;
|
|
|
|
|
void makePinVertices(Pin *pin);
|
|
|
|
|
void makePinVertices(Pin *pin,
|
|
|
|
|
Vertex *&vertex,
|
|
|
|
|
Vertex *&bidir_drvr_vertex);
|
|
|
|
|
// Both vertices for bidirects.
|
|
|
|
|
void pinVertices(const Pin *pin,
|
|
|
|
|
// Return values.
|
|
|
|
|
Vertex *&vertex,
|
|
|
|
|
Vertex *&bidirect_drvr_vertex) const;
|
|
|
|
|
// Driver vertex for bidirects.
|
|
|
|
|
Vertex *pinDrvrVertex(const Pin *pin) const;
|
|
|
|
|
// Load vertex for bidirects.
|
|
|
|
|
Vertex *pinLoadVertex(const Pin *pin) const;
|
|
|
|
|
virtual void deleteVertex(Vertex *vertex);
|
|
|
|
|
bool hasFaninOne(Vertex *vertex) const;
|
|
|
|
|
VertexIndex vertexCount() { return vertex_count_; }
|
|
|
|
|
// Slews are reported slews in seconds.
|
|
|
|
|
// Reported slew are the same as those in the liberty tables.
|
|
|
|
|
// reported_slews = measured_slews / slew_derate_from_library
|
|
|
|
|
// Measured slews are between slew_lower_threshold and slew_upper_threshold.
|
|
|
|
|
virtual const Slew &slew(const Vertex *vertex,
|
|
|
|
|
const TransRiseFall *tr,
|
|
|
|
|
DcalcAPIndex ap_index);
|
|
|
|
|
virtual void setSlew(Vertex *vertex,
|
|
|
|
|
const TransRiseFall *tr,
|
|
|
|
|
DcalcAPIndex ap_index,
|
|
|
|
|
const Slew &slew);
|
|
|
|
|
|
|
|
|
|
// Edge functions.
|
|
|
|
|
virtual Edge *edge(EdgeIndex edge_index) const;
|
|
|
|
|
EdgeIndex index(const Edge *edge) const;
|
|
|
|
|
virtual Edge *makeEdge(Vertex *from,
|
|
|
|
|
Vertex *to,
|
|
|
|
|
TimingArcSet *arc_set);
|
|
|
|
|
virtual void makeWireEdge(Pin *from_pin,
|
|
|
|
|
Pin *to_pin);
|
|
|
|
|
void makePinInstanceEdges(Pin *pin);
|
|
|
|
|
void makeInstanceEdges(const Instance *inst);
|
|
|
|
|
void makeWireEdgesToPin(Pin *to_pin);
|
|
|
|
|
void makeWireEdgesThruPin(Pin *hpin);
|
|
|
|
|
virtual void makeWireEdgesFromPin(Pin *drvr_pin);
|
|
|
|
|
virtual void deleteEdge(Edge *edge);
|
|
|
|
|
virtual ArcDelay arcDelay(const Edge *edge,
|
|
|
|
|
const TimingArc *arc,
|
|
|
|
|
DcalcAPIndex ap_index) const;
|
|
|
|
|
virtual void setArcDelay(Edge *edge,
|
|
|
|
|
const TimingArc *arc,
|
|
|
|
|
DcalcAPIndex ap_index,
|
|
|
|
|
ArcDelay delay);
|
|
|
|
|
// Alias for arcDelays using library wire arcs.
|
|
|
|
|
virtual const ArcDelay &wireArcDelay(const Edge *edge,
|
|
|
|
|
const TransRiseFall *tr,
|
|
|
|
|
DcalcAPIndex ap_index);
|
|
|
|
|
virtual void setWireArcDelay(Edge *edge,
|
|
|
|
|
const TransRiseFall *tr,
|
|
|
|
|
DcalcAPIndex ap_index,
|
|
|
|
|
const ArcDelay &delay);
|
2018-11-09 19:04:16 +01:00
|
|
|
// Is timing arc delay annotated.
|
|
|
|
|
bool arcDelayAnnotated(Edge *edge,
|
|
|
|
|
TimingArc *arc,
|
|
|
|
|
DcalcAPIndex ap_index) const;
|
|
|
|
|
void setArcDelayAnnotated(Edge *edge,
|
|
|
|
|
TimingArc *arc,
|
|
|
|
|
DcalcAPIndex ap_index,
|
|
|
|
|
bool annotated);
|
|
|
|
|
bool wireDelayAnnotated(Edge *edge,
|
|
|
|
|
const TransRiseFall *tr,
|
|
|
|
|
DcalcAPIndex ap_index) const;
|
|
|
|
|
void setWireDelayAnnotated(Edge *edge,
|
|
|
|
|
const TransRiseFall *tr,
|
|
|
|
|
DcalcAPIndex ap_index,
|
|
|
|
|
bool annotated);
|
|
|
|
|
// True if any edge arc is annotated.
|
|
|
|
|
bool delayAnnotated(Edge *edge);
|
2018-09-28 17:54:21 +02:00
|
|
|
EdgeIndex edgeCount() { return edge_count_; }
|
|
|
|
|
virtual ArcIndex arcCount() { return arc_count_; }
|
|
|
|
|
|
|
|
|
|
// Sdf width check annotation.
|
|
|
|
|
void widthCheckAnnotation(const Pin *pin,
|
|
|
|
|
const TransRiseFall *tr,
|
|
|
|
|
DcalcAPIndex ap_index,
|
|
|
|
|
// Return values.
|
|
|
|
|
float &width,
|
|
|
|
|
bool &exists);
|
|
|
|
|
void setWidthCheckAnnotation(const Pin *pin,
|
|
|
|
|
const TransRiseFall *tr,
|
|
|
|
|
DcalcAPIndex ap_index,
|
|
|
|
|
float width);
|
|
|
|
|
|
|
|
|
|
// Sdf period check annotation.
|
|
|
|
|
void periodCheckAnnotation(const Pin *pin,
|
|
|
|
|
DcalcAPIndex ap_index,
|
|
|
|
|
// Return values.
|
|
|
|
|
float &period,
|
|
|
|
|
bool &exists);
|
|
|
|
|
void setPeriodCheckAnnotation(const Pin *pin,
|
|
|
|
|
DcalcAPIndex ap_index,
|
|
|
|
|
float period);
|
|
|
|
|
// Remove all delay and slew annotations.
|
|
|
|
|
void removeDelaySlewAnnotations();
|
|
|
|
|
VertexSet *regClkVertices() { return ®_clk_vertices_; }
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
void makeVerticesAndEdges();
|
|
|
|
|
void vertexAndEdgeCounts(// Return values.
|
|
|
|
|
VertexIndex &vertex_count,
|
|
|
|
|
EdgeIndex &edge_count,
|
|
|
|
|
ArcIndex &arc_count);
|
|
|
|
|
virtual void vertexAndEdgeCounts(const Instance *inst,
|
|
|
|
|
PinSet &visited_drvrs,
|
|
|
|
|
// Return values.
|
|
|
|
|
VertexIndex &vertex_count,
|
|
|
|
|
EdgeIndex &edge_count,
|
|
|
|
|
ArcIndex &arc_count);
|
|
|
|
|
virtual void drvrPinEdgeCounts(Pin *pin,
|
|
|
|
|
PinSet &visited_drvrs,
|
|
|
|
|
// Return values.
|
|
|
|
|
EdgeIndex &edge_count,
|
|
|
|
|
ArcIndex &arc_count);
|
|
|
|
|
Vertex *makeVertex(Pin *pin,
|
|
|
|
|
bool is_bidirect_drvr,
|
|
|
|
|
bool is_reg_clk);
|
|
|
|
|
virtual void makeEdgeArcDelays(Edge *edge);
|
|
|
|
|
void makePinVertices(const Instance *inst);
|
|
|
|
|
void makeWireEdgesFromPin(Pin *drvr_pin,
|
|
|
|
|
PinSet &visited_drvrs);
|
|
|
|
|
void makeWireEdges();
|
|
|
|
|
virtual void makeInstDrvrWireEdges(Instance *inst,
|
|
|
|
|
PinSet &visited_drvrs);
|
|
|
|
|
virtual void makePortInstanceEdges(const Instance *inst,
|
|
|
|
|
LibertyCell *cell,
|
|
|
|
|
LibertyPort *from_to_port);
|
|
|
|
|
void removeWidthCheckAnnotations();
|
|
|
|
|
void removePeriodCheckAnnotations();
|
|
|
|
|
void makeSlewPools(VertexIndex vertex_count,
|
|
|
|
|
DcalcAPIndex count);
|
|
|
|
|
void deleteSlewPools();
|
|
|
|
|
void makeVertexSlews();
|
|
|
|
|
void deleteVertexSlews(Vertex *vertex);
|
|
|
|
|
void makeArcDelayPools(ArcIndex arc_count,
|
|
|
|
|
DcalcAPIndex ap_count);
|
|
|
|
|
void deleteArcDelayPools();
|
|
|
|
|
virtual void deleteEdgeArcDelays(Edge *edge);
|
|
|
|
|
void deleteInEdge(Vertex *vertex,
|
|
|
|
|
Edge *edge);
|
|
|
|
|
void deleteOutEdge(Vertex *vertex,
|
|
|
|
|
Edge *edge);
|
|
|
|
|
void removeDelays();
|
|
|
|
|
float *makeFloats(ObjectIndex count);
|
|
|
|
|
void deleteFloats(float *floats,
|
|
|
|
|
ObjectIndex count);
|
2018-11-09 19:04:16 +01:00
|
|
|
void removeDelayAnnotated(Edge *edge);
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
VertexPool *vertices_;
|
|
|
|
|
EdgePool *edges_;
|
|
|
|
|
// Bidirect pins are split into two vertices:
|
|
|
|
|
// load/sink (top level output, instance pin input) vertex in pin_vertex_map
|
|
|
|
|
// driver/source (top level input, instance pin output) vertex
|
|
|
|
|
// in pin_bidirect_drvr_vertex_map
|
|
|
|
|
PinVertexMap pin_bidirect_drvr_vertex_map_;
|
|
|
|
|
VertexIndex vertex_count_;
|
|
|
|
|
EdgeIndex edge_count_;
|
|
|
|
|
ArcIndex arc_count_;
|
2018-11-09 19:04:16 +01:00
|
|
|
Vector<bool> arc_delay_annotated_;
|
2018-09-28 17:54:21 +02:00
|
|
|
int slew_tr_count_;
|
|
|
|
|
bool have_arc_delays_;
|
|
|
|
|
DcalcAPIndex ap_count_;
|
|
|
|
|
DelayPoolSeq slew_pools_; // [ap_index][tr_index][vertex_index]
|
|
|
|
|
VertexIndex slew_count_;
|
|
|
|
|
DelayPoolSeq arc_delays_; // [ap_index][edge_arc_index]
|
|
|
|
|
Pool<float> *float_pool_;
|
|
|
|
|
// Sdf width check annotations.
|
|
|
|
|
WidthCheckAnnotations *width_check_annotations_;
|
|
|
|
|
// Sdf period check annotations.
|
|
|
|
|
PeriodCheckAnnotations *period_check_annotations_;
|
|
|
|
|
// Register/latch clock vertices to search from.
|
|
|
|
|
VertexSet reg_clk_vertices_;
|
|
|
|
|
friend class Vertex;
|
|
|
|
|
friend class VertexIterator;
|
|
|
|
|
friend class VertexInEdgeIterator;
|
|
|
|
|
friend class VertexOutEdgeIterator;
|
|
|
|
|
friend class MakeEdgesThruHierPin;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(Graph);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Each Vertex corresponds to one network pin.
|
|
|
|
|
class Vertex
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
Vertex();
|
|
|
|
|
Pin *pin() const { return pin_; }
|
|
|
|
|
// Pin path with load/driver suffix for bidirects.
|
|
|
|
|
const char *name(const Network *network) const;
|
|
|
|
|
bool isBidirectDriver() const { return is_bidirect_drvr_; }
|
|
|
|
|
Level level() const { return level_; }
|
|
|
|
|
void setLevel(Level level);
|
|
|
|
|
bool isRoot() const{ return level_ == 0; }
|
|
|
|
|
VertexColor color() const { return (VertexColor) color_; }
|
|
|
|
|
void setColor(VertexColor color);
|
|
|
|
|
Arrival *arrivals() const { return arrivals_; }
|
|
|
|
|
void setArrivals(Arrival *arrivals);
|
|
|
|
|
PathVertexRep *prevPaths() const { return prev_paths_; }
|
|
|
|
|
void setPrevPaths(PathVertexRep *prev_paths);
|
|
|
|
|
// Requireds optionally follow arrivals in the same array.
|
|
|
|
|
bool hasRequireds() const { return has_requireds_; }
|
|
|
|
|
void setHasRequireds(bool has_req);
|
|
|
|
|
TagGroupIndex tagGroupIndex() const;
|
|
|
|
|
void setTagGroupIndex(TagGroupIndex tag_index);
|
|
|
|
|
// Slew is annotated by sdc set_annotated_transition cmd.
|
|
|
|
|
bool slewAnnotated(const TransRiseFall *tr,
|
|
|
|
|
DcalcAPIndex ap_index) const;
|
|
|
|
|
// True if any rise/fall analysis pt slew is annotated.
|
|
|
|
|
bool slewAnnotated() const;
|
|
|
|
|
void setSlewAnnotated(bool annotated,
|
|
|
|
|
const TransRiseFall *tr,
|
|
|
|
|
DcalcAPIndex ap_index);
|
|
|
|
|
void removeSlewAnnotated();
|
|
|
|
|
// Constant zero/one from simulation.
|
|
|
|
|
bool isConstant() const;
|
|
|
|
|
LogicValue simValue() const;
|
|
|
|
|
void setSimValue(LogicValue value);
|
|
|
|
|
bool isDisabledConstraint() const { return is_disabled_constraint_; }
|
|
|
|
|
void setIsDisabledConstraint(bool disabled);
|
|
|
|
|
// True when vertex has timing check edges that constrain it.
|
|
|
|
|
bool hasChecks() const { return has_checks_; }
|
|
|
|
|
void setHasChecks(bool has_checks);
|
|
|
|
|
bool isCheckClk() const { return is_check_clk_; }
|
|
|
|
|
void setIsCheckClk(bool is_check_clk);
|
|
|
|
|
bool isGatedClkEnable() const { return is_gated_clk_enable_; }
|
|
|
|
|
void setIsGatedClkEnable(bool enable);
|
|
|
|
|
bool hasDownstreamClkPin() const { return has_downstream_clk_pin_; }
|
|
|
|
|
void setHasDownstreamClkPin(bool has_clk_pin);
|
|
|
|
|
// Vertices are constrained if they have one or more of the
|
|
|
|
|
// following timing constraints:
|
|
|
|
|
// output delay constraints
|
|
|
|
|
// data check constraints
|
|
|
|
|
// path delay constraints
|
|
|
|
|
bool isConstrained() const { return is_constrained_; }
|
|
|
|
|
void setIsConstrained(bool constrained);
|
|
|
|
|
bool bfsInQueue(BfsIndex index) const;
|
|
|
|
|
void setBfsInQueue(BfsIndex index, bool value);
|
|
|
|
|
bool isRegClk() const { return is_reg_clk_; }
|
|
|
|
|
static int transitionCount() { return 2; } // rise/fall
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
void init(Pin *pin,
|
|
|
|
|
bool is_bidirect_drvr,
|
|
|
|
|
bool is_reg_clk);
|
|
|
|
|
|
|
|
|
|
Pin *pin_;
|
|
|
|
|
Arrival *arrivals_;
|
|
|
|
|
PathVertexRep *prev_paths_;
|
|
|
|
|
EdgeIndex in_edges_; // Edges to this vertex.
|
|
|
|
|
EdgeIndex out_edges_; // Edges from this vertex.
|
|
|
|
|
unsigned int tag_group_index_:tag_group_index_bits;
|
|
|
|
|
bool has_requireds_:1;
|
|
|
|
|
unsigned int slew_annotated_:4;
|
|
|
|
|
// Bidirect pins have two vertices.
|
|
|
|
|
// This flag distinguishes the driver and load vertices.
|
|
|
|
|
bool is_bidirect_drvr_:1;
|
|
|
|
|
bool is_reg_clk_:1;
|
|
|
|
|
unsigned int sim_value_:3; // LogicValue
|
|
|
|
|
bool is_disabled_constraint_:1;
|
|
|
|
|
bool is_gated_clk_enable_:1;
|
|
|
|
|
// Constrained by timing check edge.
|
|
|
|
|
bool has_checks_:1;
|
|
|
|
|
// Is the clock for a timing check.
|
|
|
|
|
bool is_check_clk_:1;
|
|
|
|
|
bool is_constrained_:1;
|
|
|
|
|
bool has_downstream_clk_pin_:1;
|
|
|
|
|
// Levelization search state.
|
|
|
|
|
unsigned int color_:2;
|
|
|
|
|
unsigned int level_:16;
|
|
|
|
|
// Each bit corresponds to a different BFS queue.
|
|
|
|
|
unsigned int bfs_in_queue_:bfs_index_bits;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(Vertex);
|
|
|
|
|
|
|
|
|
|
friend class Graph;
|
|
|
|
|
friend class Edge;
|
|
|
|
|
friend class VertexInEdgeIterator;
|
|
|
|
|
friend class VertexOutEdgeIterator;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// There is one Edge between each pair of pins that has a timing
|
|
|
|
|
// path between them.
|
|
|
|
|
class Edge
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
Edge();
|
|
|
|
|
Vertex *to(const Graph *graph) const { return graph->vertex(to_); }
|
|
|
|
|
Vertex *from(const Graph *graph) const { return graph->vertex(from_); }
|
|
|
|
|
TimingRole *role() const;
|
|
|
|
|
bool isWire() const;
|
|
|
|
|
TimingSense sense() const;
|
|
|
|
|
TimingArcSet *timingArcSet() const { return arc_set_; }
|
|
|
|
|
void setTimingArcSet(TimingArcSet *set);
|
|
|
|
|
ArcIndex arcDelays() const { return arc_delays_; }
|
|
|
|
|
void setArcDelays(ArcIndex arc_delays);
|
|
|
|
|
bool delayAnnotationIsIncremental() const;
|
|
|
|
|
void setDelayAnnotationIsIncremental(bool is_incr);
|
|
|
|
|
// Edge is disabled by set_disable_timing constraint.
|
|
|
|
|
bool isDisabledConstraint() const;
|
|
|
|
|
void setIsDisabledConstraint(bool disabled);
|
|
|
|
|
// Timing sense for the to_pin function after simplifying the
|
|
|
|
|
// function based constants on the instance pins.
|
|
|
|
|
TimingSense simTimingSense() const;
|
|
|
|
|
void setSimTimingSense(TimingSense sense);
|
|
|
|
|
// Edge is disabled by constants in condition (when) function.
|
|
|
|
|
bool isDisabledCond() const { return is_disabled_cond_; }
|
|
|
|
|
void setIsDisabledCond(bool disabled);
|
|
|
|
|
// Edge is disabled to break combinational loops.
|
|
|
|
|
bool isDisabledLoop() const { return is_disabled_loop_; }
|
|
|
|
|
void setIsDisabledLoop(bool disabled);
|
|
|
|
|
// Edge is disabled to prevent converging clocks from merging (Xilinx).
|
|
|
|
|
bool isBidirectInstPath() const { return is_bidirect_inst_path_; }
|
|
|
|
|
void setIsBidirectInstPath(bool is_bidir);
|
|
|
|
|
bool isBidirectNetPath() const { return is_bidirect_net_path_; }
|
|
|
|
|
void setIsBidirectNetPath(bool is_bidir);
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
void init(VertexIndex from,
|
|
|
|
|
VertexIndex to,
|
|
|
|
|
TimingArcSet *arc_set);
|
|
|
|
|
|
|
|
|
|
TimingArcSet *arc_set_;
|
|
|
|
|
VertexIndex from_;
|
|
|
|
|
VertexIndex to_;
|
|
|
|
|
VertexIndex vertex_in_link_; // Vertex in edges list.
|
|
|
|
|
VertexIndex vertex_out_next_; // Vertex out edges doubly linked list.
|
|
|
|
|
VertexIndex vertex_out_prev_;
|
|
|
|
|
ArcIndex arc_delays_;
|
|
|
|
|
unsigned int delay_annotation_is_incremental_:1;
|
|
|
|
|
unsigned int is_bidirect_inst_path_:1;
|
|
|
|
|
unsigned int is_bidirect_net_path_:1;
|
|
|
|
|
// Timing sense from function and constants on edge instance.
|
|
|
|
|
unsigned int sim_timing_sense_:timing_sense_bit_count;
|
|
|
|
|
unsigned int is_disabled_constraint_:1;
|
|
|
|
|
unsigned int is_disabled_cond_:1;
|
|
|
|
|
unsigned int is_disabled_loop_:1;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(Edge);
|
|
|
|
|
|
|
|
|
|
friend class Graph;
|
|
|
|
|
friend class GraphDelays1;
|
|
|
|
|
friend class GraphSlewsDelays1;
|
|
|
|
|
friend class GraphSlewsDelays2;
|
|
|
|
|
friend class Vertex;
|
|
|
|
|
friend class VertexInEdgeIterator;
|
|
|
|
|
friend class VertexOutEdgeIterator;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Iterate over all graph vertices.
|
|
|
|
|
class VertexIterator : public Iterator<Vertex*>
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit VertexIterator(Graph *graph);
|
|
|
|
|
virtual bool hasNext() { return vertex_ || bidir_vertex_; }
|
|
|
|
|
virtual Vertex *next();
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(VertexIterator);
|
|
|
|
|
bool findNextPin();
|
|
|
|
|
void findNext();
|
|
|
|
|
|
|
|
|
|
Graph *graph_;
|
|
|
|
|
Network *network_;
|
|
|
|
|
Instance *top_inst_;
|
|
|
|
|
LeafInstanceIterator *inst_iter_;
|
|
|
|
|
InstancePinIterator *pin_iter_;
|
|
|
|
|
Vertex *vertex_;
|
|
|
|
|
Vertex *bidir_vertex_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class VertexInEdgeIterator : public VertexEdgeIterator
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
VertexInEdgeIterator(Vertex *vertex,
|
|
|
|
|
const Graph *graph);
|
|
|
|
|
VertexInEdgeIterator(VertexIndex vertex_index,
|
|
|
|
|
const Graph *graph);
|
|
|
|
|
bool hasNext() { return (next_ != NULL); }
|
|
|
|
|
Edge *next();
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(VertexInEdgeIterator);
|
|
|
|
|
|
|
|
|
|
Edge *next_;
|
|
|
|
|
const Graph *graph_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class VertexOutEdgeIterator : public VertexEdgeIterator
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
VertexOutEdgeIterator(Vertex *vertex,
|
|
|
|
|
const Graph *graph);
|
|
|
|
|
bool hasNext() { return (next_ != NULL); }
|
|
|
|
|
Edge *next();
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(VertexOutEdgeIterator);
|
|
|
|
|
|
|
|
|
|
Edge *next_;
|
|
|
|
|
const Graph *graph_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Iterate over the edges through a hierarchical pin.
|
|
|
|
|
class EdgesThruHierPinIterator : public Iterator<Edge*>
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
EdgesThruHierPinIterator(const Pin *hpin,
|
|
|
|
|
Network *network,
|
|
|
|
|
Graph *graph);
|
|
|
|
|
virtual bool hasNext() { return edge_iter_.hasNext(); }
|
|
|
|
|
virtual Edge *next() { return edge_iter_.next(); }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(EdgesThruHierPinIterator);
|
|
|
|
|
|
|
|
|
|
EdgeSet edges_;
|
|
|
|
|
EdgeSet::Iterator edge_iter_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
#endif
|