1 // OpenSTA, Static Timing Analyzer
2 // Copyright (c) 2021, Parallax Software, Inc.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <https://www.gnu.org/licenses/>.
16
17 #include "MinMax.hh"
18
19 #include <algorithm>
20
21 #include "StringUtil.hh"
22
23 namespace sta {
24
25 const float INF = 1E+30F;
26
27 static bool
compareMin(float value1,float value2)28 compareMin(float value1,
29 float value2)
30 {
31 return value1 < value2;
32 }
33
34 static bool
compareMax(float value1,float value2)35 compareMax(float value1,
36 float value2)
37 {
38 return value1 > value2;
39 }
40
41 ////////////////////////////////////////////////////////////////
42
43 MinMax MinMax::min_("min", 0, INF, compareMin);
44 MinMax MinMax::max_("max", 1, -INF, compareMax);
45 const std::array<MinMax*, 2> MinMax::range_{&min_, &max_};
46 const std::array<int, 2> MinMax::range_index_{min_.index(), max_.index()};
47
MinMax(const char * name,int index,float init_value,bool (* compare)(float value1,float value2))48 MinMax::MinMax(const char *name,
49 int index,
50 float init_value,
51 bool (*compare)(float value1, float value2)) :
52 name_(name),
53 index_(index),
54 init_value_(init_value),
55 compare_(compare)
56 {
57 }
58
59 MinMaxAll *
asMinMaxAll() const60 MinMax::asMinMaxAll() const
61 {
62 if (this == &min_)
63 return MinMaxAll::min();
64 else
65 return MinMaxAll::max();
66 }
67
68 MinMax *
opposite() const69 MinMax::opposite() const
70 {
71 if (this == &max_)
72 return &min_;
73 else
74 return &max_;
75 }
76
77 MinMax *
find(const char * min_max)78 MinMax::find(const char *min_max)
79 {
80 if (stringEq(min_max, "min")
81 || stringEq(min_max, "early"))
82 return &min_;
83 else if (stringEq(min_max, "max")
84 || stringEq(min_max, "late"))
85 return &max_;
86 else
87 return nullptr;
88 }
89
90 MinMax *
find(int index)91 MinMax::find(int index)
92 {
93 if (index == min_.index())
94 return &min_;
95 else if (index == max_.index())
96 return &max_;
97 else
98 return nullptr;
99 }
100
101 bool
compare(float value1,float value2) const102 MinMax::compare(float value1,
103 float value2) const
104 {
105 return compare_(value1, value2);
106 }
107
108 float
minMax(float value1,float value2) const109 MinMax::minMax(float value1,
110 float value2) const
111 {
112 if (compare_(value1, value2))
113 return value1;
114 else
115 return value2;
116 }
117
118 ////////////////////////////////////////////////////////////////
119
120 MinMaxAll MinMaxAll::min_("min", 0, {MinMax::min()}, {MinMax::min()->index()});
121 MinMaxAll MinMaxAll::max_("max", 1, {MinMax::max()}, {MinMax::max()->index()});
122 MinMaxAll MinMaxAll::all_("all", 2, {MinMax::min(), MinMax::max()},
123 {MinMax::min()->index(), MinMax::max()->index()});
124
MinMaxAll(const char * name,int index,std::vector<MinMax * > range,std::vector<int> range_index)125 MinMaxAll::MinMaxAll(const char *name,
126 int index,
127 std::vector<MinMax*> range,
128 std::vector<int> range_index) :
129 name_(name),
130 index_(index),
131 range_(range),
132 range_index_(range_index)
133 {
134 }
135
136 MinMax *
asMinMax() const137 MinMaxAll::asMinMax() const
138 {
139 if (this == &min_)
140 return MinMax::min();
141 else
142 return MinMax::max();
143 }
144
145 bool
matches(const MinMax * min_max) const146 MinMaxAll::matches(const MinMax *min_max) const
147 {
148 return this == &all_ || asMinMax() == min_max;
149 }
150
151 bool
matches(const MinMaxAll * min_max) const152 MinMaxAll::matches(const MinMaxAll *min_max) const
153 {
154 return this == &all_ || this == min_max;
155 }
156
157 MinMaxAll *
find(const char * min_max)158 MinMaxAll::find(const char *min_max)
159 {
160 if (stringEq(min_max, "min")
161 || stringEq(min_max, "early"))
162 return &min_;
163 else if (stringEq(min_max, "max")
164 || stringEq(min_max, "late"))
165 return &max_;
166 else if (stringEq(min_max, "all")
167 || stringEq(min_max, "min_max")
168 || stringEq(min_max, "minmax"))
169 return &all_;
170 else
171 return nullptr;
172 }
173
174 ////////////////////////////////////////////////////////////////
175
MinMaxIterator(const MinMaxAll * min_max)176 MinMaxIterator::MinMaxIterator(const MinMaxAll *min_max)
177 {
178 if (min_max == MinMaxAll::all()) {
179 index_ = 0;
180 index_max_ = MinMax::index_max;
181 }
182 else {
183 index_ = min_max->asMinMax()->index();
184 index_max_ = index_;
185 }
186 }
187
188 } // namespace
189