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