1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (c) 2019, Nefelus Inc
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 // list of conditions and the following disclaimer.
12 //
13 // * Redistributions in binary form must reproduce the above copyright notice,
14 // this list of conditions and the following disclaimer in the documentation
15 // and/or other materials provided with the distribution.
16 //
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32
33 #include "dbTechNonDefaultRule.h"
34
35 #include "db.h"
36 #include "dbBlock.h"
37 #include "dbDatabase.h"
38 #include "dbTable.h"
39 #include "dbTable.hpp"
40 #include "dbTech.h"
41 #include "dbTechLayer.h"
42 #include "dbTechLayerRule.h"
43 #include "dbTechSameNetRule.h"
44 #include "dbTechVia.h"
45
46 namespace odb {
47
48 template class dbTable<_dbTechNonDefaultRule>;
49
_dbTechNonDefaultRule(_dbDatabase *,const _dbTechNonDefaultRule & r)50 _dbTechNonDefaultRule::_dbTechNonDefaultRule(_dbDatabase*,
51 const _dbTechNonDefaultRule& r)
52 : _flags(r._flags),
53 _name(NULL),
54 _layer_rules(r._layer_rules),
55 _vias(r._vias),
56 _samenet_rules(r._samenet_rules),
57 _samenet_matrix(r._samenet_matrix),
58 _use_vias(r._use_vias),
59 _use_rules(r._use_rules),
60 _cut_layers(r._cut_layers),
61 _min_cuts(r._min_cuts)
62 {
63 if (r._name) {
64 _name = strdup(r._name);
65 ZALLOCATED(_name);
66 }
67 }
68
_dbTechNonDefaultRule(_dbDatabase *)69 _dbTechNonDefaultRule::_dbTechNonDefaultRule(_dbDatabase*)
70 {
71 _flags._spare_bits = 0;
72 _flags._hard_spacing = 0;
73 _flags._block_rule = 0;
74 _name = NULL;
75 }
76
~_dbTechNonDefaultRule()77 _dbTechNonDefaultRule::~_dbTechNonDefaultRule()
78 {
79 if (_name)
80 free((void*) _name);
81 }
82
operator <<(dbOStream & stream,const _dbTechNonDefaultRule & rule)83 dbOStream& operator<<(dbOStream& stream, const _dbTechNonDefaultRule& rule)
84 {
85 uint* bit_field = (uint*) &rule._flags;
86 stream << *bit_field;
87 stream << rule._name;
88 stream << rule._layer_rules;
89 stream << rule._vias;
90 stream << rule._samenet_rules;
91 stream << rule._samenet_matrix;
92 stream << rule._use_vias;
93 stream << rule._use_rules;
94 stream << rule._cut_layers;
95 stream << rule._min_cuts;
96 return stream;
97 }
98
operator >>(dbIStream & stream,_dbTechNonDefaultRule & rule)99 dbIStream& operator>>(dbIStream& stream, _dbTechNonDefaultRule& rule)
100 {
101 uint* bit_field = (uint*) &rule._flags;
102 stream >> *bit_field;
103 stream >> rule._name;
104 stream >> rule._layer_rules;
105 stream >> rule._vias;
106 stream >> rule._samenet_rules;
107 stream >> rule._samenet_matrix;
108 stream >> rule._use_vias;
109 stream >> rule._use_rules;
110 stream >> rule._cut_layers;
111 stream >> rule._min_cuts;
112
113 return stream;
114 }
115
operator ==(const _dbTechNonDefaultRule & rhs) const116 bool _dbTechNonDefaultRule::operator==(const _dbTechNonDefaultRule& rhs) const
117 {
118 if (_flags._hard_spacing != rhs._flags._hard_spacing)
119 return false;
120
121 if (_flags._block_rule != rhs._flags._block_rule)
122 return false;
123
124 if (_name && rhs._name) {
125 if (strcmp(_name, rhs._name) != 0)
126 return false;
127 } else if (_name || rhs._name)
128 return false;
129
130 if (_layer_rules != rhs._layer_rules)
131 return false;
132
133 if (_vias != rhs._vias)
134 return false;
135
136 if (_samenet_rules != rhs._samenet_rules)
137 return false;
138
139 if (_samenet_matrix != rhs._samenet_matrix)
140 return false;
141
142 if (_use_vias != rhs._use_vias)
143 return false;
144
145 if (_use_rules != rhs._use_rules)
146 return false;
147
148 if (_cut_layers != rhs._cut_layers)
149 return false;
150
151 if (_min_cuts != rhs._min_cuts)
152 return false;
153
154 return true;
155 }
156
differences(dbDiff & diff,const char * field,const _dbTechNonDefaultRule & rhs) const157 void _dbTechNonDefaultRule::differences(dbDiff& diff,
158 const char* field,
159 const _dbTechNonDefaultRule& rhs) const
160 {
161 DIFF_BEGIN
162 DIFF_FIELD(_flags._hard_spacing);
163 DIFF_FIELD(_flags._block_rule);
164 DIFF_FIELD(_name);
165 DIFF_VECTOR(_layer_rules);
166 DIFF_VECTOR(_vias);
167 DIFF_VECTOR(_samenet_rules);
168 DIFF_MATRIX(_samenet_matrix);
169 DIFF_VECTOR(_use_vias);
170 DIFF_VECTOR(_use_rules);
171 DIFF_VECTOR(_cut_layers);
172 DIFF_VECTOR(_min_cuts);
173 DIFF_END
174 }
175
out(dbDiff & diff,char side,const char * field) const176 void _dbTechNonDefaultRule::out(dbDiff& diff,
177 char side,
178 const char* field) const
179 {
180 DIFF_OUT_BEGIN
181 DIFF_OUT_FIELD(_flags._hard_spacing);
182 DIFF_OUT_FIELD(_flags._block_rule);
183 DIFF_OUT_FIELD(_name);
184 DIFF_OUT_VECTOR(_layer_rules);
185 DIFF_OUT_VECTOR(_vias);
186 DIFF_OUT_VECTOR(_samenet_rules);
187 DIFF_OUT_MATRIX(_samenet_matrix);
188 DIFF_OUT_VECTOR(_use_vias);
189 DIFF_OUT_VECTOR(_use_rules);
190 DIFF_OUT_VECTOR(_cut_layers);
191 DIFF_OUT_VECTOR(_min_cuts);
192 DIFF_END
193 }
194
getTech()195 _dbTech* _dbTechNonDefaultRule::getTech()
196 {
197 #if 0 // dead code generates warnings -cherry
198 if (_flags._block_rule == 0)
199 (_dbTech *) getOwner();
200 #endif
201
202 return (_dbTech*) getDb()->getTech();
203 }
204
getBlock()205 _dbBlock* _dbTechNonDefaultRule::getBlock()
206 {
207 assert(_flags._block_rule == 1);
208 return (_dbBlock*) getOwner();
209 }
210
operator <(const _dbTechNonDefaultRule & rhs) const211 bool _dbTechNonDefaultRule::operator<(const _dbTechNonDefaultRule& rhs) const
212 {
213 return strcmp(_name, rhs._name) < 0;
214 }
215
216 ////////////////////////////////////////////////////////////////////
217 //
218 // dbTechNonDefaultRule - Methods
219 //
220 ////////////////////////////////////////////////////////////////////
221
getName()222 std::string dbTechNonDefaultRule::getName()
223 {
224 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
225 return rule->_name;
226 }
227
getConstName()228 const char* dbTechNonDefaultRule::getConstName()
229 {
230 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
231 return rule->_name;
232 }
233
isBlockRule()234 bool dbTechNonDefaultRule::isBlockRule()
235 {
236 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
237 return rule->_flags._block_rule == 1;
238 }
239
getLayerRule(dbTechLayer * layer_)240 dbTechLayerRule* dbTechNonDefaultRule::getLayerRule(dbTechLayer* layer_)
241 {
242 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
243 _dbTechLayer* layer = (_dbTechLayer*) layer_;
244 dbId<_dbTechLayerRule> id = rule->_layer_rules[layer->_number];
245
246 if (id == 0)
247 return NULL;
248
249 if (rule->_flags._block_rule == 0) {
250 return (dbTechLayerRule*) rule->getTech()->_layer_rule_tbl->getPtr(id);
251 } else {
252 return (dbTechLayerRule*) rule->getBlock()->_layer_rule_tbl->getPtr(id);
253 }
254 }
255
getLayerRules(std::vector<dbTechLayerRule * > & layer_rules)256 void dbTechNonDefaultRule::getLayerRules(
257 std::vector<dbTechLayerRule*>& layer_rules)
258 {
259 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
260 dbTable<_dbTechLayerRule>* layer_rule_tbl = NULL;
261
262 if (rule->_flags._block_rule == 0) {
263 _dbTech* tech = rule->getTech();
264 layer_rule_tbl = tech->_layer_rule_tbl;
265 } else {
266 _dbBlock* block = rule->getBlock();
267 layer_rule_tbl = block->_layer_rule_tbl;
268 }
269
270 layer_rules.clear();
271
272 dbVector<dbId<_dbTechLayerRule>>::iterator itr;
273
274 for (itr = rule->_layer_rules.begin(); itr != rule->_layer_rules.end();
275 ++itr) {
276 dbId<_dbTechLayerRule> id = *itr;
277
278 if (id != 0)
279 layer_rules.push_back((dbTechLayerRule*) layer_rule_tbl->getPtr(id));
280 }
281 }
282
getVias(std::vector<dbTechVia * > & vias)283 void dbTechNonDefaultRule::getVias(std::vector<dbTechVia*>& vias)
284 {
285 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
286
287 if (rule->_flags._block_rule == 1) // not supported on block rules
288 return;
289
290 _dbTech* tech = rule->getTech();
291 vias.clear();
292
293 dbVector<dbId<_dbTechVia>>::iterator itr;
294
295 for (itr = rule->_vias.begin(); itr != rule->_vias.end(); ++itr) {
296 dbId<_dbTechVia> id = *itr;
297 vias.push_back((dbTechVia*) tech->_via_tbl->getPtr(id));
298 }
299 }
300
findSameNetRule(dbTechLayer * l1_,dbTechLayer * l2_)301 dbTechSameNetRule* dbTechNonDefaultRule::findSameNetRule(dbTechLayer* l1_,
302 dbTechLayer* l2_)
303 {
304 _dbTechNonDefaultRule* ndrule = (_dbTechNonDefaultRule*) this;
305
306 if (ndrule->_flags._block_rule == 1) // not supported on block rules
307 return NULL;
308
309 _dbTech* tech = ndrule->getTech();
310 _dbTechLayer* l1 = (_dbTechLayer*) l1_;
311 _dbTechLayer* l2 = (_dbTechLayer*) l2_;
312 dbId<_dbTechSameNetRule> rule
313 = ndrule->_samenet_matrix(l1->_number, l2->_number);
314
315 if (rule == 0)
316 return NULL;
317
318 return (dbTechSameNetRule*) tech->_samenet_rule_tbl->getPtr(rule);
319 }
320
getSameNetRules(std::vector<dbTechSameNetRule * > & rules)321 void dbTechNonDefaultRule::getSameNetRules(
322 std::vector<dbTechSameNetRule*>& rules)
323 {
324 _dbTechNonDefaultRule* ndrule = (_dbTechNonDefaultRule*) this;
325
326 if (ndrule->_flags._block_rule == 1) // not supported on block rules
327 return;
328
329 _dbTech* tech = ndrule->getTech();
330 rules.clear();
331 dbVector<dbId<_dbTechSameNetRule>>::iterator itr;
332
333 for (itr = ndrule->_samenet_rules.begin();
334 itr != ndrule->_samenet_rules.end();
335 ++itr) {
336 dbId<_dbTechSameNetRule> r = *itr;
337 rules.push_back((dbTechSameNetRule*) tech->_samenet_rule_tbl->getPtr(r));
338 }
339 }
340
getHardSpacing()341 bool dbTechNonDefaultRule::getHardSpacing()
342 {
343 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
344 return rule->_flags._hard_spacing == 1;
345 }
346
setHardSpacing(bool value)347 void dbTechNonDefaultRule::setHardSpacing(bool value)
348 {
349 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
350 rule->_flags._hard_spacing = value;
351 }
352
addUseVia(dbTechVia * via)353 void dbTechNonDefaultRule::addUseVia(dbTechVia* via)
354 {
355 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
356 rule->_use_vias.push_back(via->getId());
357 }
358
getUseVias(std::vector<dbTechVia * > & vias)359 void dbTechNonDefaultRule::getUseVias(std::vector<dbTechVia*>& vias)
360 {
361 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
362 _dbTech* tech = rule->getTech();
363
364 dbVector<dbId<_dbTechVia>>::iterator itr;
365
366 for (itr = rule->_use_vias.begin(); itr != rule->_use_vias.end(); ++itr) {
367 dbId<_dbTechVia> vid = *itr;
368 dbTechVia* via = dbTechVia::getTechVia((dbTech*) tech, vid);
369 vias.push_back(via);
370 }
371 }
372
addUseViaRule(dbTechViaGenerateRule * gen_rule)373 void dbTechNonDefaultRule::addUseViaRule(dbTechViaGenerateRule* gen_rule)
374 {
375 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
376 rule->_use_rules.push_back(gen_rule->getId());
377 }
378
getUseViaRules(std::vector<dbTechViaGenerateRule * > & rules)379 void dbTechNonDefaultRule::getUseViaRules(
380 std::vector<dbTechViaGenerateRule*>& rules)
381 {
382 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
383 _dbTech* tech = rule->getTech();
384
385 dbVector<dbId<_dbTechViaGenerateRule>>::iterator itr;
386
387 for (itr = rule->_use_rules.begin(); itr != rule->_use_rules.end(); ++itr) {
388 dbId<_dbTechViaGenerateRule> rid = *itr;
389 dbTechViaGenerateRule* rule
390 = dbTechViaGenerateRule::getTechViaGenerateRule((dbTech*) tech, rid);
391 rules.push_back(rule);
392 }
393 }
394
setMinCuts(dbTechLayer * cut_layer,int count)395 void dbTechNonDefaultRule::setMinCuts(dbTechLayer* cut_layer, int count)
396 {
397 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
398
399 uint id = cut_layer->getId();
400 dbVector<dbId<_dbTechLayer>>::iterator itr;
401 uint idx = 0;
402
403 for (itr = rule->_cut_layers.begin(); itr != rule->_cut_layers.end();
404 ++itr, ++idx) {
405 dbId<_dbTechLayer> lid = *itr;
406
407 if (lid == id) {
408 rule->_min_cuts[idx] = count;
409 return;
410 }
411 }
412
413 rule->_cut_layers.push_back(id);
414 rule->_min_cuts.push_back(count);
415 }
416
getMinCuts(dbTechLayer * cut_layer,int & count)417 bool dbTechNonDefaultRule::getMinCuts(dbTechLayer* cut_layer, int& count)
418 {
419 _dbTechNonDefaultRule* rule = (_dbTechNonDefaultRule*) this;
420
421 uint id = cut_layer->getId();
422 dbVector<dbId<_dbTechLayer>>::iterator itr;
423 uint idx = 0;
424
425 for (itr = rule->_cut_layers.begin(); itr != rule->_cut_layers.end();
426 ++itr, ++idx) {
427 dbId<_dbTechLayer> lid = *itr;
428
429 if (lid == id) {
430 count = rule->_min_cuts[idx];
431 return true;
432 }
433 }
434
435 return false;
436 }
437
create(dbTech * tech_,const char * name_)438 dbTechNonDefaultRule* dbTechNonDefaultRule::create(dbTech* tech_,
439 const char* name_)
440 {
441 if (tech_->findNonDefaultRule(name_))
442 return NULL;
443
444 _dbTech* tech = (_dbTech*) tech_;
445 _dbTechNonDefaultRule* rule = tech->_non_default_rule_tbl->create();
446 rule->_name = strdup(name_);
447 ZALLOCATED(rule->_name);
448 rule->_layer_rules.resize(tech->_layer_cnt);
449
450 int i;
451 for (i = 0; i < tech->_layer_cnt; ++i)
452 rule->_layer_rules.push_back(0);
453
454 return (dbTechNonDefaultRule*) rule;
455 }
456
create(dbBlock * block_,const char * name_)457 dbTechNonDefaultRule* dbTechNonDefaultRule::create(dbBlock* block_,
458 const char* name_)
459 {
460 if (block_->findNonDefaultRule(name_))
461 return NULL;
462
463 _dbBlock* block = (_dbBlock*) block_;
464 _dbTech* tech = (_dbTech*) block->getDb()->getTech();
465 _dbTechNonDefaultRule* rule = block->_non_default_rule_tbl->create();
466
467 rule->_name = strdup(name_);
468 ZALLOCATED(rule->_name);
469 rule->_flags._block_rule = 1;
470 rule->_layer_rules.resize(tech->_layer_cnt);
471
472 int i;
473 for (i = 0; i < tech->_layer_cnt; ++i)
474 rule->_layer_rules.push_back(0);
475
476 return (dbTechNonDefaultRule*) rule;
477 }
478
getTechNonDefaultRule(dbTech * tech_,uint dbid_)479 dbTechNonDefaultRule* dbTechNonDefaultRule::getTechNonDefaultRule(dbTech* tech_,
480 uint dbid_)
481 {
482 _dbTech* tech = (_dbTech*) tech_;
483 return (dbTechNonDefaultRule*) tech->_non_default_rule_tbl->getPtr(dbid_);
484 }
485
getTechNonDefaultRule(dbBlock * block_,uint dbid_)486 dbTechNonDefaultRule* dbTechNonDefaultRule::getTechNonDefaultRule(
487 dbBlock* block_,
488 uint dbid_)
489 {
490 _dbBlock* block = (_dbBlock*) block_;
491 return (dbTechNonDefaultRule*) block->_non_default_rule_tbl->getPtr(dbid_);
492 }
493
494 } // namespace odb
495