1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
|
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2019, Parallax Software, Inc.
//
// 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_PATHGROUP_H
#define STA_PATHGROUP_H
#include "DisallowCopyAssign.hh"
#include "Map.hh"
#include "Vector.hh"
#include "StaState.hh"
#include "SearchClass.hh"
namespace sta {
class MinMax;
class PathEndVisitor;
typedef PathEndSeq::Iterator PathGroupIterator;
typedef Map<const Clock*, PathGroup*> PathGroupClkMap;
typedef Map<const char*, PathGroup*, CharPtrLess> PathGroupNamedMap;
// A collection of PathEnds grouped and sorted for reporting.
class PathGroup
{
public:
virtual ~PathGroup();
// Path group that compares compare slacks.
static PathGroup *makePathGroupArrival(const char *name,
int group_count,
int endpoint_count,
bool unique_pins,
const MinMax *min_max,
const StaState *sta);
// Path group that compares arrival time, sorted by min_max.
static PathGroup *makePathGroupSlack(const char *name,
int group_count,
int endpoint_count,
bool unique_pins,
float min_slack,
float max_slack,
const StaState *sta);
const char *name() const { return name_; }
const MinMax *minMax() const { return min_max_;}
const PathEndSeq &pathEnds() const { return path_ends_; }
void insert(PathEnd *path_end);
// Push group_count into path_ends.
void pushEnds(PathEndSeq *path_ends);
// Predicates to determine if a PathEnd is worth saving.
virtual bool savable(PathEnd *path_end);
int maxPaths() const { return group_count_; }
PathGroupIterator *iterator();
// This does NOT delete the path ends.
void clear();
static int group_count_max;
protected:
PathGroup(const char *name,
int group_count,
int endpoint_count,
bool unique_pins,
float min_slack,
float max_slack,
bool cmp_slack,
const MinMax *min_max,
const StaState *sta);
void ensureSortedMaxPaths();
void prune();
void sort();
const char *name_;
int group_count_;
int endpoint_count_;
bool unique_pins_;
float slack_min_;
float slack_max_;
PathEndSeq path_ends_;
const MinMax *min_max_;
bool compare_slack_;
float threshold_;
std::mutex lock_;
const StaState *sta_;
private:
DISALLOW_COPY_AND_ASSIGN(PathGroup);
};
class PathGroups : public StaState
{
public:
PathGroups(int group_count,
int endpoint_count,
bool unique_pins,
float slack_min,
float slack_max,
PathGroupNameSet *group_names,
bool setup,
bool hold,
bool recovery,
bool removal,
bool clk_gating_setup,
bool clk_gating_hold,
bool unconstrained,
const StaState *sta);
~PathGroups();
// Use corner nullptr to make PathEnds for all corners.
// Returned PathEndSeq is owned by the caller.
// The PathEnds in the vector are owned by the PathGroups.
PathEndSeq *makePathEnds(ExceptionTo *to,
bool unconstrained_paths,
const Corner *corner,
const MinMaxAll *min_max,
bool sort_by_slack);
PathGroup *findPathGroup(const char *name,
const MinMax *min_max) const;
PathGroup *findPathGroup(const Clock *clock,
const MinMax *min_max) const;
PathGroup *pathGroup(const PathEnd *path_end) const;
static bool isGroupPathName(const char *group_name);
static const char *asyncPathGroupName() { return async_group_name_; }
protected:
void makeGroupPathEnds(ExceptionTo *to,
int group_count,
int endpoint_count,
bool unique_pins,
const Corner *corner,
const MinMaxAll *min_max);
void makeGroupPathEnds(ExceptionTo *to,
const Corner *corner,
const MinMaxAll *min_max,
PathEndVisitor *visitor);
void makeGroupPathEnds(VertexSet *endpoints,
const Corner *corner,
const MinMaxAll *min_max,
PathEndVisitor *visitor);
void enumPathEnds(PathGroup *group,
int group_count,
int endpoint_count,
bool unique_pins,
bool cmp_slack);
void pushGroupPathEnds(PathEndSeq *path_ends);
void pushUnconstrainedPathEnds(PathEndSeq *path_ends,
const MinMaxAll *min_max);
void makeGroups(int group_count,
int endpoint_count,
bool unique_pins,
float slack_min,
float slack_max,
PathGroupNameSet *group_names,
bool setup_hold,
bool async,
bool gated_clk,
bool unconstrained,
const MinMax *min_max);
bool reportGroup(const char *group_name,
PathGroupNameSet *group_names) const;
GroupPath *groupPathTo(const PathEnd *path_end) const;
int group_count_;
int endpoint_count_;
bool unique_pins_;
float slack_min_;
float slack_max_;
// Paths grouped by SDC group_path command.
// name -> PathGroup
PathGroupNamedMap named_map_[MinMax::index_count];
// clock -> PathGroup
PathGroupClkMap clk_map_[MinMax::index_count];
// Min/max path delays.
PathGroup *path_delay_[MinMax::index_count];
// Gated clock checks.
PathGroup *gated_clk_[MinMax::index_count];
// Asynchronous (recovery/removal) checks.
PathGroup *async_[MinMax::index_count];
// Unconstrained paths.
PathGroup *unconstrained_[MinMax::index_count];
static const char *path_delay_group_name_;
static const char *gated_clk_group_name_;
static const char *async_group_name_;
static const char *unconstrained_group_name_;
private:
DISALLOW_COPY_AND_ASSIGN(PathGroups);
};
} // namespace
#endif
|