mirror of
https://github.com/The-OpenROAD-Project/OpenSTA.git
synced 2026-09-01 10:27:10 +02:00
Merge remote-tracking branch 'upstream/master' into sta_latest_0710
This commit is contained in:
+23
-19
@@ -24,6 +24,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
@@ -38,6 +39,8 @@ class SearchPred;
|
||||
class BfsFwdIterator;
|
||||
class BfsBkwdIterator;
|
||||
|
||||
using VertexFn = std::function<void(Vertex*)>;
|
||||
|
||||
// LevelQueue is a vector of vertex vectors indexed by logic level.
|
||||
using LevelQueue = std::vector<VertexSeq>;
|
||||
|
||||
@@ -50,26 +53,23 @@ using LevelQueue = std::vector<VertexSeq>;
|
||||
// Vertices are marked as being in the queue by using a flag on
|
||||
// the vertex indexed by bfs_index. A unique flag is only needed
|
||||
// if the BFS in in use when other BFS's are simultaneously in use.
|
||||
class BfsIterator : public StaState,
|
||||
public Iterator<Vertex*>
|
||||
class BfsIterator : public StaState
|
||||
{
|
||||
public:
|
||||
// Make sure that the BFS queue is deep enough for the max logic level.
|
||||
void ensureSize();
|
||||
// Reset to virgin state.
|
||||
void clear();
|
||||
// Apply fn to each vertex and clear.
|
||||
void clear(const VertexFn &fn);
|
||||
[[nodiscard]] bool empty() const;
|
||||
// Enqueue a vertex to search from.
|
||||
void enqueue(Vertex *vertex);
|
||||
// Enqueue vertices adjacent to a vertex.
|
||||
void enqueueAdjacentVertices(Vertex *vertex);
|
||||
virtual void enqueueAdjacentVertices(Vertex *vertex) = 0;
|
||||
virtual void enqueueAdjacentVertices(Vertex *vertex,
|
||||
const Mode *mode);
|
||||
virtual void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred,
|
||||
const Mode *mode) = 0;
|
||||
virtual void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred) = 0;
|
||||
|
||||
[[nodiscard]] bool inQueue(Vertex *vertex);
|
||||
void checkInQueue(Vertex *vertex);
|
||||
// Notify iterator that vertex will be deleted.
|
||||
@@ -77,10 +77,6 @@ public:
|
||||
void remove(Vertex *vertex);
|
||||
void reportEntries() const;
|
||||
|
||||
bool hasNext() override;
|
||||
bool hasNext(Level to_level);
|
||||
Vertex *next() override;
|
||||
|
||||
// Apply visitor to all vertices in the queue in level order.
|
||||
// Returns the number of vertices that are visited.
|
||||
virtual int visit(Level to_level,
|
||||
@@ -91,6 +87,10 @@ public:
|
||||
int visitParallel(Level to_level,
|
||||
VertexVisitor *visitor);
|
||||
|
||||
bool hasNext();
|
||||
bool hasNext(Level to_level);
|
||||
Vertex *next();
|
||||
|
||||
protected:
|
||||
BfsIterator(BfsIndex bfs_index,
|
||||
Level level_min,
|
||||
@@ -104,10 +104,10 @@ protected:
|
||||
virtual bool levelLessOrEqual(Level level1,
|
||||
Level level2) const = 0;
|
||||
virtual void incrLevel(Level &level) const = 0;
|
||||
void findNext(Level to_level);
|
||||
void deleteEntries();
|
||||
void checkLevel(Vertex *vertex,
|
||||
Level level);
|
||||
void findNext(Level to_level);
|
||||
|
||||
BfsIndex bfs_index_;
|
||||
Level level_min_;
|
||||
@@ -131,12 +131,13 @@ public:
|
||||
SearchPred *search_pred,
|
||||
StaState *sta);
|
||||
~BfsFwdIterator() override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex) override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred) override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred,
|
||||
const Mode *mode) override;
|
||||
using BfsIterator::enqueueAdjacentVertices;
|
||||
void enqueueFanout(Vertex *vertex);
|
||||
void enqueueFanout(Vertex *vertex,
|
||||
const Mode *mode);
|
||||
|
||||
protected:
|
||||
bool levelLessOrEqual(Level level1,
|
||||
@@ -153,14 +154,17 @@ public:
|
||||
SearchPred *search_pred,
|
||||
StaState *sta);
|
||||
~BfsBkwdIterator() override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex) override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred) override;
|
||||
void enqueueAdjacentVertices(Vertex *vertex,
|
||||
SearchPred *search_pred,
|
||||
const Mode *mode) override;
|
||||
using BfsIterator::enqueueAdjacentVertices;
|
||||
void enqueueFanin(Vertex *vertex);
|
||||
void enqueueFanin(Vertex *vertex,
|
||||
const Mode *mode);
|
||||
|
||||
protected:
|
||||
void enqueueFanin(Vertex *vertex,
|
||||
SearchPred *search_pred);
|
||||
bool levelLessOrEqual(Level level1,
|
||||
Level level2) const override;
|
||||
bool levelLess(Level level1,
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "GraphClass.hh"
|
||||
#include "NetworkClass.hh"
|
||||
#include "Scene.hh"
|
||||
#include "SdcClass.hh"
|
||||
#include "SearchClass.hh"
|
||||
#include "StringUtil.hh"
|
||||
@@ -64,6 +65,16 @@ filterClocks(std::string_view filter_expression,
|
||||
ClockSeq *clks,
|
||||
Sta *sta);
|
||||
|
||||
SceneSeq
|
||||
filterScenes(std::string_view filter_expression,
|
||||
SceneSeq *scenes,
|
||||
Sta *sta);
|
||||
|
||||
ModeSeq
|
||||
filterModes(std::string_view filter_expression,
|
||||
ModeSeq *modes,
|
||||
Sta *sta);
|
||||
|
||||
LibertyCellSeq
|
||||
filterLibCells(std::string_view filter_expression,
|
||||
LibertyCellSeq *cells,
|
||||
|
||||
+148
-103
@@ -28,6 +28,7 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include "LibertyClass.hh"
|
||||
#include "NetworkClass.hh"
|
||||
@@ -61,109 +62,6 @@ private:
|
||||
std::map<std::string, PropertyHandler, std::less<>> registry_;
|
||||
};
|
||||
|
||||
class Properties
|
||||
{
|
||||
public:
|
||||
Properties(Sta *sta);
|
||||
|
||||
PropertyValue getProperty(const Library *lib,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const LibertyLibrary *lib,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Cell *cell,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const LibertyCell *cell,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Port *port,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const LibertyPort *port,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Instance *inst,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Pin *pin,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Net *net,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(Edge *edge,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Clock *clk,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Scene *scene,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Mode *mode,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(PathEnd *end,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(Path *path,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(TimingArcSet *arc_set,
|
||||
std::string_view property);
|
||||
|
||||
// Define handler for external property.
|
||||
// properties->defineProperty("foo",
|
||||
// [] (const Instance *, Sta *) -> PropertyValue {
|
||||
// return PropertyValue("bar");
|
||||
// });
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Library *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const LibertyLibrary *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Cell *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const LibertyCell *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Port *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const LibertyPort *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Instance *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Pin *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Net *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Clock *>::PropertyHandler &handler);
|
||||
|
||||
protected:
|
||||
PropertyValue portSlew(const Port *port,
|
||||
const RiseFallBoth *rf,
|
||||
const MinMax *min_max);
|
||||
PropertyValue portSlack(const Port *port,
|
||||
const RiseFallBoth *rf,
|
||||
const MinMax *min_max);
|
||||
PropertyValue pinArrival(const Pin *pin,
|
||||
const RiseFallBoth *rf,
|
||||
const MinMax *min_max);
|
||||
|
||||
PropertyValue pinSlack(const Pin *pin,
|
||||
const RiseFallBoth *rf,
|
||||
const MinMax *min_max);
|
||||
PropertyValue pinSlew(const Pin *pin,
|
||||
const RiseFallBoth *rf,
|
||||
const MinMax *min_max);
|
||||
|
||||
PropertyValue delayPropertyValue(Delay delay);
|
||||
PropertyValue resistancePropertyValue(float res);
|
||||
PropertyValue capacitancePropertyValue(float cap);
|
||||
PropertyValue edgeDelay(Edge *edge,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max);
|
||||
|
||||
PropertyRegistry<const Library*> registry_library_;
|
||||
PropertyRegistry<const LibertyLibrary*> registry_liberty_library_;
|
||||
PropertyRegistry<const Cell*> registry_cell_;
|
||||
PropertyRegistry<const LibertyCell*> registry_liberty_cell_;
|
||||
PropertyRegistry<const Port*> registry_port_;
|
||||
PropertyRegistry<const LibertyPort*> registry_liberty_port_;
|
||||
PropertyRegistry<const Instance*> registry_instance_;
|
||||
PropertyRegistry<const Pin*> registry_pin_;
|
||||
PropertyRegistry<const Net*> registry_net_;
|
||||
PropertyRegistry<const Clock*> registry_clock_;
|
||||
|
||||
Sta *sta_;
|
||||
};
|
||||
|
||||
// Adding a new property type
|
||||
// value union (string values use std::string* so the union stays trivial)
|
||||
// enum Type
|
||||
@@ -262,4 +160,151 @@ private:
|
||||
const Unit *unit_;
|
||||
};
|
||||
|
||||
// Key for user-defined property values: the object instance and the
|
||||
// property name.
|
||||
class PropertyKey
|
||||
{
|
||||
public:
|
||||
PropertyKey(const void *object,
|
||||
std::string_view property);
|
||||
bool operator<(const PropertyKey &key) const;
|
||||
|
||||
private:
|
||||
const void *object_;
|
||||
std::string property_;
|
||||
};
|
||||
|
||||
class Properties
|
||||
{
|
||||
public:
|
||||
Properties(Sta *sta);
|
||||
|
||||
PropertyValue getProperty(const Library *lib,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const LibertyLibrary *lib,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Cell *cell,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const LibertyCell *cell,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Port *port,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const LibertyPort *port,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Instance *inst,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Pin *pin,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Net *net,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(Edge *edge,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Clock *clk,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Scene *scene,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(const Mode *mode,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(PathEnd *end,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(Path *path,
|
||||
std::string_view property);
|
||||
PropertyValue getProperty(TimingArcSet *arc_set,
|
||||
std::string_view property);
|
||||
|
||||
// Define handler for external property.
|
||||
// properties->defineProperty("foo",
|
||||
// [] (const Instance *, Sta *) -> PropertyValue {
|
||||
// return PropertyValue("bar");
|
||||
// });
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Library *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const LibertyLibrary *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Cell *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const LibertyCell *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Port *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const LibertyPort *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Instance *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Pin *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Net *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Clock *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Scene *>::PropertyHandler &handler);
|
||||
void defineProperty(std::string_view property,
|
||||
const PropertyRegistry<const Mode *>::PropertyHandler &handler);
|
||||
|
||||
// User-defined, per-object mutable properties. defineProperty registers
|
||||
// a property of the given value type ("bool", "float" or "string");
|
||||
// setProperty sets the value on one object. Objects the property was never
|
||||
// set on read back as an empty (none) value. The property is read through
|
||||
// the same registry path as every other property so get_property /
|
||||
// get_* -filter work unchanged.
|
||||
template<class TYPE>
|
||||
void defineProperty(std::string_view object_type,
|
||||
std::string_view property,
|
||||
std::string_view value_type);
|
||||
void setProperty(const void *object,
|
||||
std::string_view object_type,
|
||||
std::string_view property,
|
||||
std::string_view value);
|
||||
|
||||
protected:
|
||||
PropertyValue portSlew(const Port *port,
|
||||
const RiseFallBoth *rf,
|
||||
const MinMax *min_max);
|
||||
PropertyValue portSlack(const Port *port,
|
||||
const RiseFallBoth *rf,
|
||||
const MinMax *min_max);
|
||||
PropertyValue pinArrival(const Pin *pin,
|
||||
const RiseFallBoth *rf,
|
||||
const MinMax *min_max);
|
||||
|
||||
PropertyValue pinSlack(const Pin *pin,
|
||||
const RiseFallBoth *rf,
|
||||
const MinMax *min_max);
|
||||
PropertyValue pinSlew(const Pin *pin,
|
||||
const RiseFallBoth *rf,
|
||||
const MinMax *min_max);
|
||||
|
||||
PropertyValue delayPropertyValue(Delay delay);
|
||||
PropertyValue resistancePropertyValue(float res);
|
||||
PropertyValue capacitancePropertyValue(float cap);
|
||||
PropertyValue edgeDelay(Edge *edge,
|
||||
const RiseFall *rf,
|
||||
const MinMax *min_max);
|
||||
PropertyValue::Type propertyType(std::string_view type);
|
||||
PropertyValue coercePropertyValue(PropertyValue::Type type,
|
||||
std::string_view value);
|
||||
|
||||
PropertyRegistry<const Library*> registry_library_;
|
||||
PropertyRegistry<const LibertyLibrary*> registry_liberty_library_;
|
||||
PropertyRegistry<const Cell*> registry_cell_;
|
||||
PropertyRegistry<const LibertyCell*> registry_liberty_cell_;
|
||||
PropertyRegistry<const Port*> registry_port_;
|
||||
PropertyRegistry<const LibertyPort*> registry_liberty_port_;
|
||||
PropertyRegistry<const Instance*> registry_instance_;
|
||||
PropertyRegistry<const Pin*> registry_pin_;
|
||||
PropertyRegistry<const Net*> registry_net_;
|
||||
PropertyRegistry<const Clock*> registry_clock_;
|
||||
PropertyRegistry<const Scene*> registry_scene_;
|
||||
PropertyRegistry<const Mode*> registry_mode_;
|
||||
|
||||
// Value types of user-defined properties keyed by object type name and
|
||||
// property name.
|
||||
std::map<std::pair<std::string, std::string>, PropertyValue::Type> prop_types_;
|
||||
// User-defined property values.
|
||||
std::map<PropertyKey, PropertyValue> prop_values_;
|
||||
|
||||
Sta *sta_;
|
||||
};
|
||||
|
||||
} // namespace sta
|
||||
|
||||
+7
-12
@@ -286,8 +286,6 @@ public:
|
||||
TagGroupBldr *tag_bldr);
|
||||
void postponeLatchDataOutputs(Vertex *vertex);
|
||||
void postponeArrivals(Vertex *vertex);
|
||||
void enqueuePendingClkFanouts();
|
||||
void postponeClkFanouts(Vertex *vertex);
|
||||
void seedRequired(Vertex *vertex);
|
||||
void seedRequiredEnqueueFanin(Vertex *vertex);
|
||||
void seedInputDelayArrival(const Pin *pin,
|
||||
@@ -503,12 +501,12 @@ protected:
|
||||
bool is_segment_start,
|
||||
const MinMax *min_max,
|
||||
Scene *scene);
|
||||
void seedClkVertexArrivals();
|
||||
void findClkArrivals1();
|
||||
void enqueueClkRoots();
|
||||
void enqueueInvalidClks();
|
||||
|
||||
void findAllArrivals(bool thru_latches,
|
||||
bool clks_only);
|
||||
void findAllArrivals(bool thru_latches);
|
||||
void findArrivals1(Level level);
|
||||
void findArrivals2(Level level);
|
||||
Tag *mutateTag(Tag *from_tag,
|
||||
const Pin *from_pin,
|
||||
const RiseFall *from_rf,
|
||||
@@ -646,12 +644,9 @@ protected:
|
||||
std::vector<TagIndex> tag_group_free_indices_;
|
||||
std::mutex tag_group_lock_;
|
||||
|
||||
// Latches data outputs to queue on the next search pass.
|
||||
VertexSet postponed_arrivals_;
|
||||
std::mutex postponed_arrivals_lock_;
|
||||
// Clock network endpoints where arrival search was suppended by findClkArrivals().
|
||||
VertexSet postponed_clk_endpoints_;
|
||||
std::mutex postponed_clk_endpoints_lock_;
|
||||
// Arrivals to queue on the next search pass.
|
||||
VertexSet pending_arrivals_;
|
||||
std::mutex pending_arrivals_lock_;
|
||||
|
||||
VertexSet endpoints_;
|
||||
bool endpoints_initialized_{false};
|
||||
|
||||
@@ -947,6 +947,11 @@ public:
|
||||
// from/thrus/to are owned and deleted by Search.
|
||||
// PathEnds in the returned PathEndSeq are owned by Search PathGroups
|
||||
// and deleted on next call.
|
||||
//
|
||||
// IMPORTANT: THIS IS NOT THE DROID YOU ARE LOOKING FOR.
|
||||
// This function is specifically designed to support the many options
|
||||
// and results of timing reports. It is NOT a good option to find paths
|
||||
// for optimization.
|
||||
PathEndSeq findPathEnds(ExceptionFrom *from,
|
||||
ExceptionThruSeq *thrus,
|
||||
ExceptionTo *to,
|
||||
|
||||
Reference in New Issue
Block a user