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 "DisabledPorts.hh"
18
19 #include <algorithm>
20
21 #include "StringUtil.hh"
22 #include "TimingRole.hh"
23 #include "Liberty.hh"
24 #include "Network.hh"
25
26 namespace sta {
27
DisabledPorts()28 DisabledPorts::DisabledPorts() :
29 all_(false),
30 from_(nullptr),
31 to_(nullptr),
32 from_to_(nullptr)
33 {
34 }
35
~DisabledPorts()36 DisabledPorts::~DisabledPorts()
37 {
38 delete from_;
39 delete to_;
40 if (from_to_) {
41 from_to_->deleteContents();
42 delete from_to_;
43 }
44 }
45
46 void
setDisabledAll()47 DisabledPorts::setDisabledAll()
48 {
49 all_ = true;
50 }
51
52 void
removeDisabledAll()53 DisabledPorts::removeDisabledAll()
54 {
55 all_ = false;
56 }
57
58 void
setDisabledFrom(LibertyPort * port)59 DisabledPorts::setDisabledFrom(LibertyPort *port)
60 {
61 if (from_ == nullptr)
62 from_ = new LibertyPortSet;
63 from_->insert(port);
64 }
65
66 void
removeDisabledFrom(LibertyPort * port)67 DisabledPorts::removeDisabledFrom(LibertyPort *port)
68 {
69 if (from_)
70 from_->erase(port);
71 }
72
73 void
setDisabledTo(LibertyPort * port)74 DisabledPorts::setDisabledTo(LibertyPort *port)
75 {
76 if (to_ == nullptr)
77 to_ = new LibertyPortSet;
78 to_->insert(port);
79 }
80
81 void
removeDisabledTo(LibertyPort * port)82 DisabledPorts::removeDisabledTo(LibertyPort *port)
83 {
84 if (to_)
85 to_->erase(port);
86 }
87
88 void
setDisabledFromTo(LibertyPort * from,LibertyPort * to)89 DisabledPorts::setDisabledFromTo(LibertyPort *from, LibertyPort *to)
90 {
91 if (from_to_ == nullptr)
92 from_to_ = new LibertyPortPairSet;
93 LibertyPortPair pair(from, to);
94 if (!from_to_->hasKey(&pair)) {
95 LibertyPortPair *pair = new LibertyPortPair(from, to);
96 from_to_->insert(pair);
97 }
98 }
99
100 void
removeDisabledFromTo(LibertyPort * from,LibertyPort * to)101 DisabledPorts::removeDisabledFromTo(LibertyPort *from, LibertyPort *to)
102 {
103 if (from_to_) {
104 LibertyPortPair probe(from, to);
105 LibertyPortPair *pair = from_to_->findKey(&probe);
106 if (pair) {
107 from_to_->erase(pair);
108 delete pair;
109 }
110 }
111 }
112
113 bool
isDisabled(LibertyPort * from,LibertyPort * to,const TimingRole * role)114 DisabledPorts::isDisabled(LibertyPort *from, LibertyPort *to,
115 const TimingRole *role)
116 {
117 LibertyPortPair pair(from, to);
118 // set_disable_timing instance does not disable timing checks.
119 return (all_ && !role->isTimingCheck())
120 || (from_ && from_->hasKey(from))
121 || (to_ && to_->hasKey(to))
122 || (from_to_ && from_to_->hasKey(&pair));
123 }
124
125 ////////////////////////////////////////////////////////////////
126
DisabledCellPorts(LibertyCell * cell)127 DisabledCellPorts::DisabledCellPorts(LibertyCell *cell) :
128 DisabledPorts(),
129 cell_(cell),
130 arc_sets_(nullptr)
131 {
132 }
133
134
~DisabledCellPorts()135 DisabledCellPorts::~DisabledCellPorts()
136 {
137 delete arc_sets_;
138 }
139
140 void
setDisabled(TimingArcSet * arc_set)141 DisabledCellPorts::setDisabled(TimingArcSet *arc_set)
142 {
143 if (arc_sets_ == nullptr)
144 arc_sets_ = new TimingArcSetSet;
145 arc_sets_->insert(arc_set);
146 }
147
148 void
removeDisabled(TimingArcSet * arc_set)149 DisabledCellPorts::removeDisabled(TimingArcSet *arc_set)
150 {
151 if (arc_sets_)
152 arc_sets_->erase(arc_set);
153 }
154
155 bool
isDisabled(TimingArcSet * arc_set) const156 DisabledCellPorts::isDisabled(TimingArcSet *arc_set) const
157 {
158 return arc_sets_
159 && arc_sets_->hasKey(arc_set);
160 }
161
162 class DisabledCellPortsLess
163 {
164 public:
165 DisabledCellPortsLess();
166 bool operator()(const DisabledCellPorts *disable1,
167 const DisabledCellPorts *disable2);
168 };
169
DisabledCellPortsLess()170 DisabledCellPortsLess::DisabledCellPortsLess()
171 {
172 }
173
174 bool
operator ()(const DisabledCellPorts * disable1,const DisabledCellPorts * disable2)175 DisabledCellPortsLess::operator()(const DisabledCellPorts *disable1,
176 const DisabledCellPorts *disable2)
177 {
178 return stringLess(disable1->cell()->name(),
179 disable2->cell()->name());
180 }
181
182 void
sortDisabledCellPortsMap(DisabledCellPortsMap * cell_map,DisabledCellPortsSeq & disables)183 sortDisabledCellPortsMap(DisabledCellPortsMap *cell_map,
184 DisabledCellPortsSeq &disables)
185 {
186 DisabledCellPortsMap::Iterator disabled_iter(cell_map);
187 while (disabled_iter.hasNext())
188 disables.push_back(disabled_iter.next());
189 sort(disables, DisabledCellPortsLess());
190 }
191
192 ////////////////////////////////////////////////////////////////
193
DisabledInstancePorts(Instance * inst)194 DisabledInstancePorts::DisabledInstancePorts(Instance *inst) :
195 DisabledPorts(),
196 inst_(inst)
197 {
198 }
199
200 class DisabledInstPortsLess
201 {
202 public:
203 explicit DisabledInstPortsLess(Network *network);
204 bool operator()(const DisabledInstancePorts *disable1,
205 const DisabledInstancePorts *disable2);
206
207 private:
208 Network *network_;
209 };
210
DisabledInstPortsLess(Network * network)211 DisabledInstPortsLess::DisabledInstPortsLess(Network *network) :
212 network_(network)
213 {
214 }
215
216 bool
operator ()(const DisabledInstancePorts * disable1,const DisabledInstancePorts * disable2)217 DisabledInstPortsLess::operator()(const DisabledInstancePorts *disable1,
218 const DisabledInstancePorts *disable2)
219 {
220 return stringLess(network_->pathName(disable1->instance()),
221 network_->pathName(disable2->instance()));
222 }
223
224 void
sortDisabledInstancePortsMap(DisabledInstancePortsMap * inst_map,Network * network,DisabledInstancePortsSeq & disables)225 sortDisabledInstancePortsMap(DisabledInstancePortsMap *inst_map,
226 Network *network,
227 DisabledInstancePortsSeq &disables)
228 {
229 DisabledInstancePortsMap::Iterator disabled_iter(inst_map);
230 while (disabled_iter.hasNext())
231 disables.push_back(disabled_iter.next());
232 sort(disables, DisabledInstPortsLess(network));
233 }
234
235 ////////////////////////////////////////////////////////////////
236
237 class LibertyPortPairNameLess
238 {
239 public:
240 bool operator()(const LibertyPortPair *pair1,
241 const LibertyPortPair *pair2);
242 };
243
244 bool
operator ()(const LibertyPortPair * pair1,const LibertyPortPair * pair2)245 LibertyPortPairNameLess::operator()(const LibertyPortPair *pair1,
246 const LibertyPortPair *pair2)
247 {
248 const char *from1 = pair1->first->name();
249 const char *from2 = pair2->first->name();
250 const char *to1 = pair1->second->name();
251 const char *to2 = pair2->second->name();
252 return stringLess(from1, from2)
253 || (stringEq(from1, from2) && stringLess(to1, to2));
254 }
255
256 void
sortLibertyPortPairSet(LibertyPortPairSet * sets,LibertyPortPairSeq & pairs)257 sortLibertyPortPairSet(LibertyPortPairSet *sets,
258 LibertyPortPairSeq &pairs)
259 {
260 LibertyPortPairSet::Iterator pair_iter(sets);
261 while (pair_iter.hasNext())
262 pairs.push_back(pair_iter.next());
263 sort(pairs, LibertyPortPairNameLess());
264 }
265
266 }
267