1 // OpenSTA, Static Timing Analyzer 2 // Copyright (c) 2020, 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 #pragma once 18 19 #include <array> 20 #include <vector> 21 #include "DisallowCopyAssign.hh" 22 #include "Iterator.hh" 23 #include "Map.hh" 24 #include "StringUtil.hh" 25 26 namespace sta { 27 28 class Transition; 29 class RiseFall; 30 class RiseFallBoth; 31 32 typedef Map<const char*, Transition*, CharPtrLess> TransitionMap; 33 34 // Rise/fall transition. 35 class RiseFall 36 { 37 public: 38 // Singleton accessors. rise()39 static RiseFall *rise() { return &rise_; } fall()40 static RiseFall *fall() { return &fall_; } riseIndex()41 static int riseIndex() { return rise_.sdf_triple_index_; } fallIndex()42 static int fallIndex() { return fall_.sdf_triple_index_; } asString() const43 const char *asString() const { return short_name_; } name() const44 const char *name() const { return name_; } shortName() const45 const char *shortName() const { return short_name_; } 46 void setShortName(const char *short_name); index() const47 int index() const { return sdf_triple_index_; } 48 RiseFallBoth *asRiseFallBoth(); 49 const RiseFallBoth *asRiseFallBoth() const; 50 Transition *asTransition() const; 51 // Find transition corresponding to tr_str. 52 static RiseFall *find(const char *tr_str); 53 // Find transition from index. 54 static RiseFall *find(int index); 55 RiseFall *opposite() const; 56 57 // for range support. 58 // for (auto tr : RiseFall::range()) {} range()59 static const std::array<RiseFall*, 2> &range() { return range_; } 60 // for (auto tr_index : RiseFall::rangeIndex()) {} rangeIndex()61 static const std::array<int, 2> &rangeIndex() { return range_index_; } 62 static const int index_count = 2; 63 static const int index_max = (index_count - 1); 64 static const int index_bit_count = 1; 65 66 protected: 67 RiseFall(const char *name, 68 const char *short_name, 69 int sdf_triple_index); 70 ~RiseFall(); 71 72 const char *name_; 73 const char *short_name_; 74 const int sdf_triple_index_; 75 76 static RiseFall rise_; 77 static RiseFall fall_; 78 static const std::array<RiseFall*, 2> range_; 79 static const std::array<int, 2> range_index_; 80 81 private: 82 DISALLOW_COPY_AND_ASSIGN(RiseFall); 83 }; 84 85 // Rise/fall/risefall transition. 86 class RiseFallBoth 87 { 88 public: 89 // Singleton accessors. rise()90 static RiseFallBoth *rise() { return &rise_; } fall()91 static RiseFallBoth *fall() { return &fall_; } riseFall()92 static RiseFallBoth *riseFall() { return &rise_fall_; } asString() const93 const char *asString() const { return short_name_; } name() const94 const char *name() const { return name_; } shortName() const95 const char *shortName() const { return short_name_; } 96 void setShortName(const char *short_name); index() const97 int index() const { return sdf_triple_index_; } 98 bool matches(const RiseFall *rf) const; 99 bool matches(const Transition *tr) const; asRiseFall() const100 RiseFall *asRiseFall() const { return as_rise_fall_; } 101 // Find transition corresponding to string. 102 static RiseFallBoth *find(const char *tr_str); 103 // for (auto tr : min_max->range()) {} range() const104 const std::vector<RiseFall*> &range() const { return range_; } 105 // for (auto tr_index : min_max->rangeIndex()) {} rangeIndex() const106 const std::vector<int> &rangeIndex() const { return range_index_; } 107 108 static const int index_count = 3; 109 static const int index_max = (index_count - 1); 110 static const int index_bit_count = 2; 111 112 protected: 113 RiseFallBoth(const char *name, 114 const char *short_name, 115 int sdf_triple_index, 116 RiseFall *as_rise_fall, 117 std::vector<RiseFall*> range, 118 std::vector<int> range_index); 119 ~RiseFallBoth(); 120 121 const char *name_; 122 const char *short_name_; 123 const int sdf_triple_index_; 124 RiseFall *as_rise_fall_; 125 const std::vector<RiseFall*> range_; 126 const std::vector<int> range_index_; 127 128 static RiseFallBoth rise_; 129 static RiseFallBoth fall_; 130 static RiseFallBoth rise_fall_; 131 132 private: 133 DISALLOW_COPY_AND_ASSIGN(RiseFallBoth); 134 }; 135 136 // General SDF transition. 137 class Transition 138 { 139 public: 140 // Singleton accessors. rise()141 static Transition *rise() { return &rise_; } fall()142 static Transition *fall() { return &fall_; } tr0Z()143 static Transition *tr0Z() { return &tr_0Z_; } trZ1()144 static Transition *trZ1() { return &tr_Z1_; } tr1Z()145 static Transition *tr1Z() { return &tr_1Z_; } trZ0()146 static Transition *trZ0() { return &tr_Z0_; } tr0X()147 static Transition *tr0X() { return &tr_0X_; } trX1()148 static Transition *trX1() { return &tr_X1_; } tr1X()149 static Transition *tr1X() { return &tr_1X_; } trX0()150 static Transition *trX0() { return &tr_X0_; } trXZ()151 static Transition *trXZ() { return &tr_XZ_; } trZX()152 static Transition *trZX() { return &tr_ZX_; } 153 void setName(const char *name); 154 // Matches rise and fall. riseFall()155 static Transition *riseFall() { return &rise_fall_; } asString() const156 const char *asString() const { return name_; } 157 // As initial/final value pair. asInitFinalString() const158 const char *asInitFinalString() const { return init_final_; } sdfTripleIndex() const159 int sdfTripleIndex() const { return sdf_triple_index_; } index() const160 int index() const { return sdf_triple_index_; } asRiseFall() const161 RiseFall *asRiseFall() const { return as_rise_fall_; } 162 const RiseFallBoth *asRiseFallBoth() const; 163 bool matches(const Transition *tr) const; 164 // Find transition corresponding to string. 165 static Transition *find(const char *tr_str); maxIndex()166 static int maxIndex() { return max_index_; } 167 168 private: 169 Transition(const char *name, 170 const char *init_final, 171 RiseFall *as_rise_fall, 172 int sdf_triple_index); 173 ~Transition(); 174 175 const char *name_; 176 const char *init_final_; 177 RiseFall *as_rise_fall_; 178 const int sdf_triple_index_; 179 180 static Transition rise_; 181 static Transition fall_; 182 static Transition tr_0Z_; 183 static Transition tr_Z1_; 184 static Transition tr_1Z_; 185 static Transition tr_Z0_; 186 static Transition tr_0X_; 187 static Transition tr_X1_; 188 static Transition tr_1X_; 189 static Transition tr_X0_; 190 static Transition tr_XZ_; 191 static Transition tr_ZX_; 192 static Transition rise_fall_; 193 static const int index_count = 13; 194 static const int index_max = (index_count - 1); 195 static const int index_bit_count = 4; 196 197 static TransitionMap transition_map_; 198 static int max_index_; 199 200 private: 201 DISALLOW_COPY_AND_ASSIGN(Transition); 202 }; 203 204 // Obsolete. Use range iteration instead. 205 // for (RiseFall *rf : RiseFall::range()) {} 206 class RiseFallIterator : public Iterator<RiseFall*> 207 { 208 public: RiseFallIterator()209 RiseFallIterator() : index_(0), index_max_(RiseFall::index_max) {} 210 explicit RiseFallIterator(const RiseFallBoth *rf); 211 void init(); 212 virtual bool hasNext(); 213 virtual RiseFall *next(); 214 215 private: 216 DISALLOW_COPY_AND_ASSIGN(RiseFallIterator); 217 218 int index_; 219 int index_max_; 220 }; 221 222 } // namespace 223