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 "dbNet.h"
34 
35 #include <algorithm>
36 
37 #include "db.h"
38 #include "dbBTerm.h"
39 #include "dbBTermItr.h"
40 #include "dbBlock.h"
41 #include "dbBlockCallBackObj.h"
42 #include "dbCCSeg.h"
43 #include "dbCCSegItr.h"
44 #include "dbCapNode.h"
45 #include "dbCapNodeItr.h"
46 #include "dbCommon.h"
47 #include "dbDatabase.h"
48 #include "dbDiff.hpp"
49 #include "dbExtControl.h"
50 #include "dbGroup.h"
51 #include "dbITerm.h"
52 #include "dbITermItr.h"
53 #include "dbInst.h"
54 #include "dbJournal.h"
55 #include "dbMTerm.h"
56 #include "dbRSeg.h"
57 #include "dbRSegItr.h"
58 #include "dbSWire.h"
59 #include "dbSWireItr.h"
60 #include "dbSet.h"
61 #include "dbShape.h"
62 #include "dbTable.h"
63 #include "dbTable.hpp"
64 #include "dbTech.h"
65 #include "dbTechNonDefaultRule.h"
66 #include "dbWire.h"
67 #include "utl/Logger.h"
68 
69 namespace odb {
70 
71 template class dbTable<_dbNet>;
72 static void set_symmetric_diff(dbDiff& diff,
73                                std::vector<_dbBTerm*>& lhs,
74                                std::vector<_dbBTerm*>& rhs);
75 static void set_symmetric_diff(dbDiff& diff,
76                                std::vector<_dbITerm*>& lhs,
77                                std::vector<_dbITerm*>& rhs);
78 
_dbNet(_dbDatabase *,const _dbNet & n)79 _dbNet::_dbNet(_dbDatabase*, const _dbNet& n)
80     : _flags(n._flags),
81       _name(NULL),
82       _next_entry(n._next_entry),
83       _iterms(n._iterms),
84       _bterms(n._bterms),
85       _wire(n._wire),
86       _global_wire(n._global_wire),
87       _swires(n._swires),
88       _cap_nodes(n._cap_nodes),
89       _r_segs(n._r_segs),
90       _non_default_rule(n._non_default_rule),
91       _groups(n._groups),
92       _weight(n._weight),
93       _xtalk(n._xtalk),
94       _ccAdjustFactor(n._ccAdjustFactor),
95       _ccAdjustOrder(n._ccAdjustOrder)
96 
97 {
98   if (n._name) {
99     _name = strdup(n._name);
100     ZALLOCATED(_name);
101   }
102   _drivingIterm = -1;
103 }
104 
_dbNet(_dbDatabase *)105 _dbNet::_dbNet(_dbDatabase*)
106 {
107   _flags._sig_type = dbSigType::SIGNAL;
108   _flags._wire_type = dbWireType::ROUTED;
109   _flags._special = 0;
110   _flags._wild_connect = 0;
111   _flags._wire_ordered = 0;
112   _flags._buffered = 0;
113   _flags._disconnected = 0;
114   _flags._spef = 0;
115   _flags._select = 0;
116   _flags._mark = 0;
117   _flags._mark_1 = 0;
118   _flags._wire_altered = 0;
119   _flags._extracted = 0;
120   _flags._rc_graph = 0;
121   _flags._reduced = 0;
122   _flags._set_io = 0;
123   _flags._io = 0;
124   _flags._dont_touch = 0;
125   _flags._size_only = 0;
126   _flags._fixed_bump = 0;
127   _flags._source = dbSourceType::NONE;
128   _flags._rc_disconnected = 0;
129   _flags._block_rule = 0;
130   _name = 0;
131   _gndc_calibration_factor = 1.0;
132   _cc_calibration_factor = 1.0;
133   _weight = 1;
134   _xtalk = 0;
135   _ccAdjustFactor = -1;
136   _ccAdjustOrder = 0;
137   _drivingIterm = -1;
138 }
139 
~_dbNet()140 _dbNet::~_dbNet()
141 {
142   if (_name)
143     free((void*) _name);
144 }
145 
operator <<(dbOStream & stream,const _dbNet & net)146 dbOStream& operator<<(dbOStream& stream, const _dbNet& net)
147 {
148   uint* bit_field = (uint*) &net._flags;
149   stream << *bit_field;
150   stream << net._name;
151   stream << net._gndc_calibration_factor;
152   stream << net._cc_calibration_factor;
153   stream << net._next_entry;
154   stream << net._iterms;
155   stream << net._bterms;
156   stream << net._wire;
157   stream << net._global_wire;
158   stream << net._swires;
159   stream << net._cap_nodes;
160   stream << net._r_segs;
161   stream << net._non_default_rule;
162   stream << net._weight;
163   stream << net._xtalk;
164   stream << net._ccAdjustFactor;
165   stream << net._ccAdjustOrder;
166   stream << net._groups;
167   return stream;
168 }
169 
operator >>(dbIStream & stream,_dbNet & net)170 dbIStream& operator>>(dbIStream& stream, _dbNet& net)
171 {
172   uint* bit_field = (uint*) &net._flags;
173   stream >> *bit_field;
174   stream >> net._name;
175   stream >> net._gndc_calibration_factor;
176   stream >> net._cc_calibration_factor;
177   stream >> net._next_entry;
178   stream >> net._iterms;
179   stream >> net._bterms;
180   stream >> net._wire;
181   stream >> net._global_wire;
182   stream >> net._swires;
183   stream >> net._cap_nodes;
184   stream >> net._r_segs;
185   stream >> net._non_default_rule;
186   stream >> net._weight;
187   stream >> net._xtalk;
188   stream >> net._ccAdjustFactor;
189   stream >> net._ccAdjustOrder;
190   stream >> net._groups;
191 
192   return stream;
193 }
194 
operator <(const _dbNet & rhs) const195 bool _dbNet::operator<(const _dbNet& rhs) const
196 {
197   return strcmp(_name, rhs._name) < 0;
198 }
199 
operator ==(const _dbNet & rhs) const200 bool _dbNet::operator==(const _dbNet& rhs) const
201 {
202   if (_flags._sig_type != rhs._flags._sig_type)
203     return false;
204 
205   if (_flags._wire_type != rhs._flags._wire_type)
206     return false;
207 
208   if (_flags._special != rhs._flags._special)
209     return false;
210 
211   if (_flags._wild_connect != rhs._flags._wild_connect)
212     return false;
213 
214   if (_flags._wire_ordered != rhs._flags._wire_ordered)
215     return false;
216 
217   if (_flags._buffered != rhs._flags._buffered)
218     return false;
219 
220   if (_flags._disconnected != rhs._flags._disconnected)
221     return false;
222 
223   if (_flags._spef != rhs._flags._spef)
224     return false;
225 
226   if (_flags._select != rhs._flags._select)
227     return false;
228 
229   if (_flags._mark != rhs._flags._mark)
230     return false;
231 
232   if (_flags._mark_1 != rhs._flags._mark_1)
233     return false;
234 
235   if (_flags._wire_altered != rhs._flags._wire_altered)
236     return false;
237 
238   if (_flags._extracted != rhs._flags._extracted)
239     return false;
240 
241   if (_flags._rc_graph != rhs._flags._rc_graph)
242     return false;
243 
244   if (_flags._reduced != rhs._flags._reduced)
245     return false;
246 
247   if (_flags._set_io != rhs._flags._set_io)
248     return false;
249 
250   if (_flags._io != rhs._flags._io)
251     return false;
252 
253   if (_flags._dont_touch != rhs._flags._dont_touch)
254     return false;
255 
256   if (_flags._size_only != rhs._flags._size_only)
257     return false;
258 
259   if (_flags._fixed_bump != rhs._flags._fixed_bump)
260     return false;
261 
262   if (_flags._source != rhs._flags._source)
263     return false;
264 
265   if (_flags._rc_disconnected != rhs._flags._rc_disconnected)
266     return false;
267 
268   if (_flags._block_rule != rhs._flags._block_rule)
269     return false;
270 
271   if (_name && rhs._name) {
272     if (strcmp(_name, rhs._name) != 0)
273       return false;
274   } else if (_name || rhs._name)
275     return false;
276 
277   if (_gndc_calibration_factor != rhs._gndc_calibration_factor)
278     return false;
279   if (_cc_calibration_factor != rhs._cc_calibration_factor)
280     return false;
281 
282   if (_next_entry != rhs._next_entry)
283     return false;
284 
285   if (_iterms != rhs._iterms)
286     return false;
287 
288   if (_bterms != rhs._bterms)
289     return false;
290 
291   if (_wire != rhs._wire)
292     return false;
293 
294   if (_global_wire != rhs._global_wire)
295     return false;
296 
297   if (_swires != rhs._swires)
298     return false;
299 
300   if (_cap_nodes != rhs._cap_nodes)
301     return false;
302 
303   if (_r_segs != rhs._r_segs)
304     return false;
305 
306   if (_non_default_rule != rhs._non_default_rule)
307     return false;
308 
309   if (_weight != rhs._weight)
310     return false;
311 
312   if (_xtalk != rhs._xtalk)
313     return false;
314 
315   if (_ccAdjustFactor != rhs._ccAdjustFactor)
316     return false;
317 
318   if (_ccAdjustOrder != rhs._ccAdjustOrder)
319     return false;
320 
321   if (_groups != rhs._groups)
322     return false;
323 
324   return true;
325 }
326 
differences(dbDiff & diff,const char * field,const _dbNet & rhs) const327 void _dbNet::differences(dbDiff& diff,
328                          const char* field,
329                          const _dbNet& rhs) const
330 {
331   _dbBlock* lhs_block = (_dbBlock*) getOwner();
332   _dbBlock* rhs_block = (_dbBlock*) rhs.getOwner();
333 
334   DIFF_BEGIN
335   DIFF_FIELD(_name);
336   DIFF_FIELD(_flags._sig_type);
337   DIFF_FIELD(_flags._wire_type);
338   DIFF_FIELD(_flags._special);
339   DIFF_FIELD(_flags._wild_connect);
340   DIFF_FIELD(_flags._wire_ordered);
341   DIFF_FIELD(_flags._buffered);
342   DIFF_FIELD(_flags._disconnected);
343   DIFF_FIELD(_flags._spef);
344   DIFF_FIELD(_flags._select);
345   DIFF_FIELD(_flags._mark);
346   DIFF_FIELD(_flags._mark_1);
347   DIFF_FIELD(_flags._wire_altered);
348   DIFF_FIELD(_flags._extracted);
349   DIFF_FIELD(_flags._rc_graph);
350   DIFF_FIELD(_flags._reduced);
351   DIFF_FIELD(_flags._set_io);
352   DIFF_FIELD(_flags._io);
353   DIFF_FIELD(_flags._dont_touch);
354   DIFF_FIELD(_flags._size_only);
355   DIFF_FIELD(_flags._fixed_bump);
356   DIFF_FIELD(_flags._source);
357   DIFF_FIELD(_flags._rc_disconnected);
358   DIFF_FIELD(_flags._block_rule);
359   DIFF_FIELD_NO_DEEP(_gndc_calibration_factor);
360   DIFF_FIELD_NO_DEEP(_cc_calibration_factor);
361   DIFF_FIELD_NO_DEEP(_next_entry);
362 
363   if (!diff.deepDiff()) {
364     DIFF_FIELD(_bterms);
365   } else {
366     dbSet<_dbBTerm>::iterator itr;
367 
368     dbSet<_dbBTerm> lhs_set((dbObject*) this, lhs_block->_net_bterm_itr);
369     std::vector<_dbBTerm*> lhs_vec;
370 
371     for (itr = lhs_set.begin(); itr != lhs_set.end(); ++itr)
372       lhs_vec.push_back(*itr);
373 
374     dbSet<_dbBTerm> rhs_set((dbObject*) &rhs, rhs_block->_net_bterm_itr);
375     std::vector<_dbBTerm*> rhs_vec;
376 
377     for (itr = rhs_set.begin(); itr != rhs_set.end(); ++itr)
378       rhs_vec.push_back(*itr);
379 
380     set_symmetric_diff(diff, lhs_vec, rhs_vec);
381   }
382 
383   if (!diff.deepDiff()) {
384     DIFF_FIELD(_iterms);
385   } else {
386     dbSet<_dbITerm>::iterator itr;
387 
388     dbSet<_dbITerm> lhs_set((dbObject*) this, lhs_block->_net_iterm_itr);
389     std::vector<_dbITerm*> lhs_vec;
390 
391     for (itr = lhs_set.begin(); itr != lhs_set.end(); ++itr)
392       lhs_vec.push_back(*itr);
393 
394     dbSet<_dbITerm> rhs_set((dbObject*) &rhs, rhs_block->_net_iterm_itr);
395     std::vector<_dbITerm*> rhs_vec;
396 
397     for (itr = rhs_set.begin(); itr != rhs_set.end(); ++itr)
398       rhs_vec.push_back(*itr);
399 
400     set_symmetric_diff(diff, lhs_vec, rhs_vec);
401   }
402 
403   DIFF_OBJECT(_wire, lhs_block->_wire_tbl, rhs_block->_wire_tbl);
404   DIFF_OBJECT(_global_wire, lhs_block->_wire_tbl, rhs_block->_wire_tbl);
405   DIFF_SET(_swires, lhs_block->_swire_itr, rhs_block->_swire_itr);
406   DIFF_SET(_cap_nodes, lhs_block->_cap_node_itr, rhs_block->_cap_node_itr);
407   DIFF_SET(_r_segs, lhs_block->_r_seg_itr, rhs_block->_r_seg_itr);
408   DIFF_FIELD(_non_default_rule);
409   DIFF_FIELD(_weight);
410   DIFF_FIELD(_xtalk);
411   DIFF_FIELD(_ccAdjustFactor);
412   DIFF_FIELD(_ccAdjustOrder);
413   DIFF_VECTOR(_groups);
414   DIFF_END
415 }
416 
out(dbDiff & diff,char side,const char * field) const417 void _dbNet::out(dbDiff& diff, char side, const char* field) const
418 {
419   _dbBlock* block = (_dbBlock*) getOwner();
420 
421   DIFF_OUT_BEGIN
422   DIFF_OUT_FIELD(_name);
423   DIFF_OUT_FIELD(_flags._sig_type);
424   DIFF_OUT_FIELD(_flags._wire_type);
425   DIFF_OUT_FIELD(_flags._special);
426   DIFF_OUT_FIELD(_flags._wild_connect);
427   DIFF_OUT_FIELD(_flags._wire_ordered);
428   DIFF_OUT_FIELD(_flags._buffered);
429   DIFF_OUT_FIELD(_flags._disconnected);
430   DIFF_OUT_FIELD(_flags._spef);
431   DIFF_OUT_FIELD(_flags._select);
432   DIFF_OUT_FIELD(_flags._mark);
433   DIFF_OUT_FIELD(_flags._mark_1);
434   DIFF_OUT_FIELD(_flags._wire_altered);
435   DIFF_OUT_FIELD(_flags._extracted);
436   DIFF_OUT_FIELD(_flags._rc_graph);
437   DIFF_OUT_FIELD(_flags._reduced);
438   DIFF_OUT_FIELD(_flags._set_io);
439   DIFF_OUT_FIELD(_flags._io);
440   DIFF_OUT_FIELD(_flags._dont_touch);
441   DIFF_OUT_FIELD(_flags._size_only);
442   DIFF_OUT_FIELD(_flags._fixed_bump);
443   DIFF_OUT_FIELD(_flags._source);
444   DIFF_OUT_FIELD(_flags._rc_disconnected);
445   DIFF_OUT_FIELD(_flags._block_rule);
446   DIFF_OUT_FIELD_NO_DEEP(_gndc_calibration_factor);
447   DIFF_OUT_FIELD_NO_DEEP(_cc_calibration_factor);
448   DIFF_OUT_FIELD_NO_DEEP(_next_entry);
449 
450   if (!diff.deepDiff()) {
451     DIFF_OUT_FIELD(_bterms);
452   } else {
453     dbSet<_dbBTerm>::iterator itr;
454     dbSet<_dbBTerm> bterms((dbObject*) this, block->_net_bterm_itr);
455     diff.begin_object("%c _bterms\n", side);
456 
457     for (itr = bterms.begin(); itr != bterms.end(); ++itr)
458       diff.report("%c %s\n", side, (*itr)->_name);
459 
460     diff.end_object();
461   }
462 
463   if (!diff.deepDiff()) {
464     DIFF_OUT_FIELD(_iterms);
465   } else {
466     dbSet<_dbITerm>::iterator itr;
467     dbSet<_dbITerm> iterms((dbObject*) this, block->_net_iterm_itr);
468     diff.begin_object("%c _iterms\n", side);
469 
470     for (itr = iterms.begin(); itr != iterms.end(); ++itr) {
471       _dbITerm* it = *itr;
472       _dbInst* inst = it->getInst();
473       _dbMTerm* mt = it->getMTerm();
474       diff.report("%c (%s %s)\n", side, inst->_name, mt->_name);
475     }
476 
477     diff.end_object();
478   }
479 
480   DIFF_OUT_OBJECT(_wire, block->_wire_tbl);
481   DIFF_OUT_OBJECT(_global_wire, block->_wire_tbl);
482   DIFF_OUT_SET(_swires, block->_swire_itr);
483   DIFF_OUT_SET(_cap_nodes, block->_cap_node_itr);
484   DIFF_OUT_SET(_r_segs, block->_r_seg_itr);
485   DIFF_OUT_FIELD(_non_default_rule);
486   DIFF_OUT_FIELD(_weight);
487   DIFF_OUT_FIELD(_xtalk);
488   DIFF_OUT_FIELD(_ccAdjustFactor);
489   DIFF_OUT_FIELD(_ccAdjustOrder);
490   DIFF_OUT_VECTOR(_groups);
491   DIFF_END
492 }
493 
set_symmetric_diff(dbDiff & diff,std::vector<_dbBTerm * > & lhs,std::vector<_dbBTerm * > & rhs)494 void set_symmetric_diff(dbDiff& diff,
495                         std::vector<_dbBTerm*>& lhs,
496                         std::vector<_dbBTerm*>& rhs)
497 {
498   diff.begin_object("<> _bterms\n");
499 
500   std::sort(lhs.begin(), lhs.end(), dbDiffCmp<_dbBTerm>());
501   std::sort(rhs.begin(), rhs.end(), dbDiffCmp<_dbBTerm>());
502 
503   std::vector<_dbBTerm*>::iterator end;
504   std::vector<_dbBTerm*> symmetric_diff;
505 
506   symmetric_diff.resize(lhs.size() + rhs.size());
507 
508   end = std::set_symmetric_difference(lhs.begin(),
509                                       lhs.end(),
510                                       rhs.begin(),
511                                       rhs.end(),
512                                       symmetric_diff.begin(),
513                                       dbDiffCmp<_dbBTerm>());
514 
515   std::vector<_dbBTerm*>::iterator i1 = lhs.begin();
516   std::vector<_dbBTerm*>::iterator i2 = rhs.begin();
517   std::vector<_dbBTerm*>::iterator sd = symmetric_diff.begin();
518 
519   while ((i1 != lhs.end()) && (i2 != rhs.end())) {
520     _dbBTerm* o1 = *i1;
521     _dbBTerm* o2 = *i2;
522 
523     if (o1 == *sd) {
524       diff.report("%c %s\n", dbDiff::LEFT, o1->_name);
525       ++i1;
526       ++sd;
527     } else if (o2 == *sd) {
528       diff.report("%c %s\n", dbDiff::RIGHT, o2->_name);
529       ++i2;
530       ++sd;
531     } else  // equal keys
532     {
533       ++i1;
534       ++i2;
535     }
536   }
537 
538   for (; i1 != lhs.end(); ++i1) {
539     _dbBTerm* o1 = *i1;
540     diff.report("%c %s\n", dbDiff::LEFT, o1->_name);
541   }
542 
543   for (; i2 != rhs.end(); ++i2) {
544     _dbBTerm* o2 = *i2;
545     diff.report("%c %s\n", dbDiff::RIGHT, o2->_name);
546   }
547 
548   diff.end_object();
549 }
550 
set_symmetric_diff(dbDiff & diff,std::vector<_dbITerm * > & lhs,std::vector<_dbITerm * > & rhs)551 void set_symmetric_diff(dbDiff& diff,
552                         std::vector<_dbITerm*>& lhs,
553                         std::vector<_dbITerm*>& rhs)
554 {
555   diff.begin_object("<> _iterms\n");
556 
557   std::sort(lhs.begin(), lhs.end(), dbDiffCmp<_dbITerm>());
558   std::sort(rhs.begin(), rhs.end(), dbDiffCmp<_dbITerm>());
559 
560   std::vector<_dbITerm*>::iterator end;
561   std::vector<_dbITerm*> symmetric_diff;
562 
563   symmetric_diff.resize(lhs.size() + rhs.size());
564 
565   end = std::set_symmetric_difference(lhs.begin(),
566                                       lhs.end(),
567                                       rhs.begin(),
568                                       rhs.end(),
569                                       symmetric_diff.begin(),
570                                       dbDiffCmp<_dbITerm>());
571 
572   std::vector<_dbITerm*>::iterator i1 = lhs.begin();
573   std::vector<_dbITerm*>::iterator i2 = rhs.begin();
574   std::vector<_dbITerm*>::iterator sd = symmetric_diff.begin();
575 
576   while ((i1 != lhs.end()) && (i2 != rhs.end())) {
577     _dbITerm* o1 = *i1;
578     _dbITerm* o2 = *i2;
579 
580     if (o1 == *sd) {
581       _dbInst* inst = o1->getInst();
582       _dbMTerm* mterm = o1->getMTerm();
583       diff.report("%c (%s %s)\n", dbDiff::LEFT, inst->_name, mterm->_name);
584       ++i1;
585       ++sd;
586     } else if (o2 == *sd) {
587       _dbInst* inst = o2->getInst();
588       _dbMTerm* mterm = o2->getMTerm();
589       diff.report("%c (%s %s)\n", dbDiff::RIGHT, inst->_name, mterm->_name);
590       ++i2;
591       ++sd;
592     } else  // equal keys
593     {
594       ++i1;
595       ++i2;
596     }
597   }
598 
599   for (; i1 != lhs.end(); ++i1) {
600     _dbITerm* o1 = *i1;
601     _dbInst* inst = o1->getInst();
602     _dbMTerm* mterm = o1->getMTerm();
603     diff.report("%c (%s %s)\n", dbDiff::LEFT, inst->_name, mterm->_name);
604   }
605 
606   for (; i2 != rhs.end(); ++i2) {
607     _dbITerm* o2 = *i2;
608     _dbInst* inst = o2->getInst();
609     _dbMTerm* mterm = o2->getMTerm();
610     diff.report("%c (%s %s)\n", dbDiff::RIGHT, inst->_name, mterm->_name);
611   }
612 
613   diff.end_object();
614 }
615 
616 ////////////////////////////////////////////////////////////////////
617 //
618 // dbNet - Methods
619 //
620 ////////////////////////////////////////////////////////////////////
621 
getName()622 std::string dbNet::getName()
623 {
624   _dbNet* net = (_dbNet*) this;
625   return net->_name;
626 }
627 
getConstName()628 const char* dbNet::getConstName()
629 {
630   _dbNet* net = (_dbNet*) this;
631   return net->_name;
632 }
printNetName(FILE * fp,bool idFlag,bool newLine)633 void dbNet::printNetName(FILE* fp, bool idFlag, bool newLine)
634 {
635   if (idFlag)
636     fprintf(fp, " %d", getId());
637 
638   _dbNet* net = (_dbNet*) this;
639   fprintf(fp, " %s", net->_name);
640 
641   if (newLine)
642     fprintf(fp, "\n");
643 }
rename(const char * name)644 bool dbNet::rename(const char* name)
645 {
646   _dbNet* net = (_dbNet*) this;
647   _dbBlock* block = (_dbBlock*) net->getOwner();
648 
649   if (block->_net_hash.hasMember(name))
650     return false;
651 
652   block->_net_hash.remove(net);
653   free((void*) net->_name);
654   net->_name = strdup(name);
655   ZALLOCATED(net->_name);
656   block->_net_hash.insert(net);
657 
658   return true;
659 }
660 
isRCDisconnected()661 bool dbNet::isRCDisconnected()
662 {
663   _dbNet* net = (_dbNet*) this;
664   return net->_flags._rc_disconnected == 1;
665 }
666 
setRCDisconnected(bool value)667 void dbNet::setRCDisconnected(bool value)
668 {
669   _dbNet* net = (_dbNet*) this;
670   net->_flags._rc_disconnected = value;
671 }
672 
getWeight()673 int dbNet::getWeight()
674 {
675   _dbNet* net = (_dbNet*) this;
676   return net->_weight;
677 }
678 
setWeight(int weight)679 void dbNet::setWeight(int weight)
680 {
681   _dbNet* net = (_dbNet*) this;
682   net->_weight = weight;
683 }
684 
getSourceType()685 dbSourceType dbNet::getSourceType()
686 {
687   _dbNet* net = (_dbNet*) this;
688   dbSourceType t(net->_flags._source);
689   return t;
690 }
691 
setSourceType(dbSourceType type)692 void dbNet::setSourceType(dbSourceType type)
693 {
694   _dbNet* net = (_dbNet*) this;
695   net->_flags._source = type;
696 }
697 
getXTalkClass()698 int dbNet::getXTalkClass()
699 {
700   _dbNet* net = (_dbNet*) this;
701   return net->_xtalk;
702 }
703 
setXTalkClass(int value)704 void dbNet::setXTalkClass(int value)
705 {
706   _dbNet* net = (_dbNet*) this;
707   net->_xtalk = value;
708 }
709 
getCcAdjustFactor()710 float dbNet::getCcAdjustFactor()
711 {
712   _dbNet* net = (_dbNet*) this;
713   return net->_ccAdjustFactor;
714 }
715 
setCcAdjustFactor(float factor)716 void dbNet::setCcAdjustFactor(float factor)
717 {
718   _dbNet* net = (_dbNet*) this;
719   net->_ccAdjustFactor = factor;
720 }
721 
getCcAdjustOrder()722 uint dbNet::getCcAdjustOrder()
723 {
724   _dbNet* net = (_dbNet*) this;
725   return net->_ccAdjustOrder;
726 }
727 
setCcAdjustOrder(uint order)728 void dbNet::setCcAdjustOrder(uint order)
729 {
730   _dbNet* net = (_dbNet*) this;
731   net->_ccAdjustOrder = order;
732 }
733 
setDrivingITerm(int id)734 void dbNet::setDrivingITerm(int id)
735 {
736   _dbNet* net = (_dbNet*) this;
737   net->_drivingIterm = id;
738 }
getDrivingITerm()739 int dbNet::getDrivingITerm()
740 {
741   _dbNet* net = (_dbNet*) this;
742   return net->_drivingIterm;
743 }
hasFixedBump()744 bool dbNet::hasFixedBump()
745 {
746   _dbNet* net = (_dbNet*) this;
747   return net->_flags._fixed_bump == 1;
748 }
749 
setFixedBump(bool value)750 void dbNet::setFixedBump(bool value)
751 {
752   _dbNet* net = (_dbNet*) this;
753   net->_flags._fixed_bump = value;
754 }
755 
setWireType(dbWireType wire_type)756 void dbNet::setWireType(dbWireType wire_type)
757 {
758   _dbNet* net = (_dbNet*) this;
759   _dbBlock* block = (_dbBlock*) net->getOwner();
760   uint prev_flags = flagsToUInt(net);
761   net->_flags._wire_type = wire_type.getValue();
762 
763   if (block->_journal) {
764     debugPrint(getImpl()->getLogger(),
765                utl::ODB,
766                "DB_ECO",
767                1,
768                "ECO: net {}, setWireType: {}",
769                getId(),
770                wire_type.getValue());
771     block->_journal->updateField(
772         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
773   }
774 }
775 
getWireType()776 dbWireType dbNet::getWireType()
777 {
778   _dbNet* net = (_dbNet*) this;
779   return dbWireType(net->_flags._wire_type);
780 }
781 
getSigType()782 dbSigType dbNet::getSigType()
783 {
784   _dbNet* net = (_dbNet*) this;
785   return dbSigType(net->_flags._sig_type);
786 }
787 
setSigType(dbSigType sig_type)788 void dbNet::setSigType(dbSigType sig_type)
789 {
790   _dbNet* net = (_dbNet*) this;
791   _dbBlock* block = (_dbBlock*) net->getOwner();
792   uint prev_flags = flagsToUInt(net);
793   net->_flags._sig_type = sig_type.getValue();
794 
795   if (block->_journal) {
796     debugPrint(getImpl()->getLogger(),
797                utl::ODB,
798                "DB_ECO",
799                1,
800                "ECO: net {}, setSigType: {}",
801                getId(),
802                sig_type.getValue());
803     block->_journal->updateField(
804         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
805   }
806 }
807 
getGndcCalibFactor()808 float dbNet::getGndcCalibFactor()
809 {
810   _dbNet* net = (_dbNet*) this;
811   return net->_gndc_calibration_factor;
812 }
813 
setGndcCalibFactor(float gndcCalib)814 void dbNet::setGndcCalibFactor(float gndcCalib)
815 {
816   _dbNet* net = (_dbNet*) this;
817   net->_gndc_calibration_factor = gndcCalib;
818 }
819 
getRefCc()820 float dbNet::getRefCc()
821 {
822   _dbNet* net = (_dbNet*) this;
823   return net->_refCC;
824 }
825 
setRefCc(float cap)826 void dbNet::setRefCc(float cap)
827 {
828   _dbNet* net = (_dbNet*) this;
829   net->_refCC = cap;
830 }
831 
getCcCalibFactor()832 float dbNet::getCcCalibFactor()
833 {
834   _dbNet* net = (_dbNet*) this;
835   return net->_cc_calibration_factor;
836 }
837 
setCcCalibFactor(float ccCalib)838 void dbNet::setCcCalibFactor(float ccCalib)
839 {
840   _dbNet* net = (_dbNet*) this;
841   net->_cc_calibration_factor = ccCalib;
842 }
843 
getDbCc()844 float dbNet::getDbCc()
845 {
846   _dbNet* net = (_dbNet*) this;
847   return net->_dbCC;
848 }
849 
setDbCc(float cap)850 void dbNet::setDbCc(float cap)
851 {
852   _dbNet* net = (_dbNet*) this;
853   net->_dbCC = cap;
854 }
855 
addDbCc(float cap)856 void dbNet::addDbCc(float cap)
857 {
858   _dbNet* net = (_dbNet*) this;
859   net->_dbCC += cap;
860 }
861 
getCcMatchRatio()862 float dbNet::getCcMatchRatio()
863 {
864   _dbNet* net = (_dbNet*) this;
865   return net->_CcMatchRatio;
866 }
867 
setCcMatchRatio(float ratio)868 void dbNet::setCcMatchRatio(float ratio)
869 {
870   _dbNet* net = (_dbNet*) this;
871   net->_CcMatchRatio = ratio;
872 }
873 
calibrateCouplingCap(int corner)874 void dbNet::calibrateCouplingCap(int corner)
875 {
876   float srcnetCcCalibFactor = getCcCalibFactor();
877   float factor, tgtnetCcCalibFactor;
878   std::vector<dbCCSeg*> ccSet;
879   getSrcCCSegs(ccSet);
880   std::vector<dbCCSeg*>::iterator cc_itr;
881   dbCCSeg* cc;
882   for (cc_itr = ccSet.begin(); cc_itr != ccSet.end(); ++cc_itr) {
883     cc = *cc_itr;
884     tgtnetCcCalibFactor = cc->getTargetNet()->getCcCalibFactor();
885     factor = (srcnetCcCalibFactor + tgtnetCcCalibFactor) / 2;
886     if (factor == 1.0)
887       continue;
888     if (corner < 0)
889       cc->adjustCapacitance(factor);
890     else
891       cc->adjustCapacitance(factor, corner);
892   }
893 }
894 
calibrateCouplingCap()895 void dbNet::calibrateCouplingCap()
896 {
897   calibrateCouplingCap(-1);
898 }
899 
anchoredRSeg()900 bool dbNet::anchoredRSeg()
901 {
902   dbSet<dbRSeg> rSet = getRSegs();
903   dbSet<dbRSeg>::iterator rc_itr;
904   dbRSeg* rc = NULL;
905   for (rc_itr = rSet.begin(); rc_itr != rSet.end(); ++rc_itr) {
906     rc = *rc_itr;
907     if (rc->getShapeId() != 0)
908       return true;
909   }
910   return false;
911 }
getRSegCount()912 uint dbNet::getRSegCount()
913 {
914   dbSet<dbRSeg> rSet = getRSegs();
915   uint cnt = rSet.size();
916   return cnt;
917 }
918 
maxInternalCapNum()919 uint dbNet::maxInternalCapNum()
920 {
921   uint max_n = 0;
922   dbSet<dbCapNode> nodeSet = getCapNodes();
923   dbSet<dbCapNode>::iterator rc_itr;
924   dbCapNode* capn;
925   for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
926     capn = *rc_itr;
927     if (!capn->isInternal())
928       continue;
929 
930     uint n = capn->getNode();
931     if (max_n < n)
932       max_n = n;
933   }
934   return max_n;
935 }
collapseInternalCapNum(FILE * mapFile)936 void dbNet::collapseInternalCapNum(FILE* mapFile)
937 {
938   dbSet<dbCapNode> nodeSet = getCapNodes();
939   uint cnt = 1;
940   dbSet<dbCapNode>::iterator rc_itr;
941   dbCapNode* capn;
942   for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
943     cnt++;
944     capn = *rc_itr;
945     if (capn->isInternal()) {
946       if (mapFile)
947         fprintf(mapFile, "    %8d : %8d\n", capn->getNode(), cnt);
948       capn->setNode(cnt);
949     }
950   }
951 }
952 
getCapNodeCount()953 uint dbNet::getCapNodeCount()
954 {
955   dbSet<dbCapNode> nodeSet = getCapNodes();
956   uint cnt = nodeSet.size();
957   return cnt;
958 }
959 
getCcCount()960 uint dbNet::getCcCount()
961 {
962   dbSet<dbCapNode> nodeSet = getCapNodes();
963   dbSet<dbCapNode>::iterator rc_itr;
964   dbSet<dbCCSeg> ccSegs;
965   dbCapNode* node;
966   uint count = 0;
967   for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
968     node = *rc_itr;
969     ccSegs = node->getCCSegs();
970     count += ccSegs.size();
971   }
972   return count;
973 }
974 
groundCC(float gndFactor)975 bool dbNet::groundCC(float gndFactor)
976 {
977   dbSet<dbCapNode> nodeSet = getCapNodes();
978   dbSet<dbCapNode>::iterator rc_itr;
979   dbCapNode* node;
980   bool grounded = false;
981 
982   for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
983     node = *rc_itr;
984     grounded |= node->groundCC(gndFactor);
985   }
986   return grounded;
987 }
988 
adjustCC(uint adjOrder,float adjFactor,double ccThreshHold,std::vector<dbCCSeg * > & adjustedCC,std::vector<dbNet * > & halonets)989 bool dbNet::adjustCC(uint adjOrder,
990                      float adjFactor,
991                      double ccThreshHold,
992                      std::vector<dbCCSeg*>& adjustedCC,
993                      std::vector<dbNet*>& halonets)
994 {
995   if (((_dbNet*) this)->_ccAdjustFactor > 0) {
996     getImpl()->getLogger()->warn(
997         utl::ODB,
998         48,
999         "Net {} {} had been CC adjusted by {}. Please unadjust first.",
1000         getId(),
1001         getConstName(),
1002         ((_dbNet*) this)->_ccAdjustFactor);
1003     return false;
1004   }
1005   dbSet<dbCapNode> nodeSet = getCapNodes();
1006   dbSet<dbCapNode>::iterator rc_itr;
1007   dbCapNode* node;
1008   bool needAdjust = false;
1009   for (rc_itr = nodeSet.begin(); !needAdjust && rc_itr != nodeSet.end();
1010        ++rc_itr) {
1011     node = *rc_itr;
1012     if (node->needAdjustCC(ccThreshHold))
1013       needAdjust = true;
1014   }
1015   if (!needAdjust)
1016     return false;
1017 
1018   for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
1019     node = *rc_itr;
1020     node->adjustCC(adjOrder, adjFactor, adjustedCC, halonets);
1021   }
1022   ((_dbNet*) this)->_ccAdjustFactor = adjFactor;
1023   ((_dbNet*) this)->_ccAdjustOrder = adjOrder;
1024   return true;
1025 }
1026 
undoAdjustedCC(std::vector<dbCCSeg * > & adjustedCC,std::vector<dbNet * > & halonets)1027 void dbNet::undoAdjustedCC(std::vector<dbCCSeg*>& adjustedCC,
1028                            std::vector<dbNet*>& halonets)
1029 {
1030   if (((_dbNet*) this)->_ccAdjustFactor < 0)
1031     return;
1032   uint adjOrder = ((_dbNet*) this)->_ccAdjustOrder;
1033   float adjFactor = 1 / ((_dbNet*) this)->_ccAdjustFactor;
1034   dbSet<dbCapNode> nodeSet = getCapNodes();
1035   dbSet<dbCapNode>::iterator rc_itr;
1036   dbCapNode* node;
1037   for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
1038     node = *rc_itr;
1039     node->adjustCC(adjOrder, adjFactor, adjustedCC, halonets);
1040   }
1041   ((_dbNet*) this)->_ccAdjustFactor = -1;
1042   ((_dbNet*) this)->_ccAdjustOrder = 0;
1043 }
1044 
adjustNetGndCap(uint corner,float factor)1045 void dbNet::adjustNetGndCap(uint corner, float factor)
1046 {
1047   if (factor == 1.0)
1048     return;
1049   bool foreign = ((dbBlock*) getImpl()->getOwner())->getExtControl()->_foreign;
1050   if (foreign) {
1051     dbSet<dbCapNode> nodeSet = getCapNodes();
1052     dbSet<dbCapNode>::iterator rc_itr;
1053     dbCapNode* node;
1054     for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
1055       node = *rc_itr;
1056       node->adjustCapacitance(factor, corner);
1057     }
1058   } else {
1059     dbSet<dbRSeg> rSet = getRSegs();
1060     dbSet<dbRSeg>::iterator rc_itr;
1061     dbRSeg* rc;
1062     for (rc_itr = rSet.begin(); rc_itr != rSet.end(); ++rc_itr) {
1063       rc = *rc_itr;
1064       rc->adjustCapacitance(factor, corner);
1065     }
1066   }
1067 }
adjustNetGndCap(float factor)1068 void dbNet::adjustNetGndCap(float factor)
1069 {
1070   if (factor == 1.0)
1071     return;
1072   bool foreign = ((dbBlock*) getImpl()->getOwner())->getExtControl()->_foreign;
1073   if (foreign) {
1074     dbSet<dbCapNode> nodeSet = getCapNodes();
1075     dbSet<dbCapNode>::iterator rc_itr;
1076     dbCapNode* node;
1077     for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
1078       node = *rc_itr;
1079       node->adjustCapacitance(factor);
1080     }
1081   } else {
1082     dbSet<dbRSeg> rSet = getRSegs();
1083     dbSet<dbRSeg>::iterator rc_itr;
1084     dbRSeg* rc;
1085     for (rc_itr = rSet.begin(); rc_itr != rSet.end(); ++rc_itr) {
1086       rc = *rc_itr;
1087       rc->adjustCapacitance(factor);
1088     }
1089   }
1090 }
1091 
calibrateGndCap()1092 void dbNet::calibrateGndCap()
1093 {
1094   adjustNetGndCap(getGndcCalibFactor());
1095 }
1096 
calibrateCapacitance()1097 void dbNet::calibrateCapacitance()
1098 {
1099   calibrateGndCap();
1100   calibrateCouplingCap();
1101 }
adjustNetRes(float factor,uint corner)1102 void dbNet::adjustNetRes(float factor, uint corner)
1103 {
1104   if (factor == 1.0)
1105     return;
1106   dbSet<dbRSeg> rSet = getRSegs();
1107   dbSet<dbRSeg>::iterator rc_itr;
1108   dbRSeg* rc = NULL;
1109   for (rc_itr = rSet.begin(); rc_itr != rSet.end(); ++rc_itr) {
1110     rc = *rc_itr;
1111     rc->adjustResistance(factor, corner);
1112   }
1113 }
adjustNetRes(float factor)1114 void dbNet::adjustNetRes(float factor)
1115 {
1116   if (factor == 1.0)
1117     return;
1118   dbSet<dbRSeg> rSet = getRSegs();
1119   dbSet<dbRSeg>::iterator rc_itr;
1120   dbRSeg* rc = NULL;
1121   for (rc_itr = rSet.begin(); rc_itr != rSet.end(); ++rc_itr) {
1122     rc = *rc_itr;
1123     rc->adjustResistance(factor);
1124   }
1125 }
1126 
isSpef()1127 bool dbNet::isSpef()
1128 {
1129   _dbNet* net = (_dbNet*) this;
1130   return net->_flags._spef == 1;
1131 }
1132 
setSpef(bool value)1133 void dbNet::setSpef(bool value)
1134 {
1135   _dbNet* net = (_dbNet*) this;
1136   _dbBlock* block = (_dbBlock*) net->getOwner();
1137   uint prev_flags = flagsToUInt(net);
1138   net->_flags._spef = (value == true) ? 1 : 0;
1139 
1140   if (block->_journal) {
1141     debugPrint(getImpl()->getLogger(),
1142                utl::ODB,
1143                "DB_ECO",
1144                1,
1145                "ECO: net {}, setSpef: {}",
1146                getId(),
1147                value);
1148     block->_journal->updateField(
1149         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1150   }
1151 }
1152 
isSelect()1153 bool dbNet::isSelect()
1154 {
1155   _dbNet* net = (_dbNet*) this;
1156   return net->_flags._select == 1;
1157 }
1158 
setSelect(bool value)1159 void dbNet::setSelect(bool value)
1160 {
1161   _dbNet* net = (_dbNet*) this;
1162   _dbBlock* block = (_dbBlock*) net->getOwner();
1163   uint prev_flags = flagsToUInt(net);
1164   net->_flags._select = (value == true) ? 1 : 0;
1165 
1166   if (block->_journal) {
1167     debugPrint(getImpl()->getLogger(),
1168                utl::ODB,
1169                "DB_ECO",
1170                1,
1171                "ECO: net {}, setSelect: {}",
1172                getId(),
1173                value);
1174     block->_journal->updateField(
1175         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1176   }
1177 }
1178 
isEnclosed(Rect * bbox)1179 bool dbNet::isEnclosed(Rect* bbox)  // assuming no intersection
1180 {
1181   dbWire* wire = getWire();
1182   dbWirePathItr pitr;
1183   dbWirePath path;
1184   dbWirePathShape pathShape;
1185   pitr.begin(wire);
1186   uint cnt = 0;
1187   while (pitr.getNextPath(path)) {
1188     if (path.point.getX() > bbox->xMax() || path.point.getX() < bbox->xMin()
1189         || path.point.getY() > bbox->yMax() || path.point.getY() < bbox->yMin())
1190       return false;
1191     cnt++;
1192     if (cnt >= 4)
1193       return true;
1194     while (pitr.getNextShape(pathShape)) {
1195       if (pathShape.point.getX() > bbox->xMax()
1196           || pathShape.point.getX() < bbox->xMin()
1197           || pathShape.point.getY() > bbox->yMax()
1198           || pathShape.point.getY() < bbox->yMin())
1199         return false;
1200       cnt++;
1201       if (cnt >= 4)
1202         return true;
1203     }
1204   }
1205   return true;
1206 }
1207 
isMarked()1208 bool dbNet::isMarked()
1209 {
1210   _dbNet* net = (_dbNet*) this;
1211   return net->_flags._mark == 1;
1212 }
1213 
setMark(bool value)1214 void dbNet::setMark(bool value)
1215 {
1216   _dbNet* net = (_dbNet*) this;
1217   _dbBlock* block = (_dbBlock*) net->getOwner();
1218   uint prev_flags = flagsToUInt(net);
1219   net->_flags._mark = (value == true) ? 1 : 0;
1220 
1221   if (block->_journal) {
1222     debugPrint(getImpl()->getLogger(),
1223                utl::ODB,
1224                "DB_ECO",
1225                1,
1226                "ECO: net {}, setMark: {}",
1227                getId(),
1228                value);
1229     block->_journal->updateField(
1230         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1231   }
1232 }
1233 
isMark_1ed()1234 bool dbNet::isMark_1ed()
1235 {
1236   _dbNet* net = (_dbNet*) this;
1237   return net->_flags._mark_1 == 1;
1238 }
1239 
setMark_1(bool value)1240 void dbNet::setMark_1(bool value)
1241 {
1242   _dbNet* net = (_dbNet*) this;
1243   _dbBlock* block = (_dbBlock*) net->getOwner();
1244   uint prev_flags = flagsToUInt(net);
1245   net->_flags._mark_1 = (value == true) ? 1 : 0;
1246 
1247   if (block->_journal) {
1248     debugPrint(getImpl()->getLogger(),
1249                utl::ODB,
1250                "DB_ECO",
1251                1,
1252                "ECO: net {}, setMark_1: {}",
1253                getId(),
1254                value);
1255     block->_journal->updateField(
1256         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1257   }
1258 }
1259 
wireEqual(dbNet * target)1260 uint dbNet::wireEqual(dbNet* target)
1261 {
1262   dbWire* srcw = getWire();
1263   dbWire* tgtw = target->getWire();
1264   if (srcw == NULL && tgtw == NULL)
1265     return 0;
1266   if (srcw == NULL || tgtw == NULL)
1267     return 3;
1268   if (!isWireOrdered() || !target->isWireOrdered())
1269     return 4;
1270   return (srcw->equal(tgtw));
1271 }
1272 
wireMatch(dbNet * target)1273 void dbNet::wireMatch(dbNet* target)
1274 {
1275   dbWire* srcw = getWire();
1276   dbWire* tgtw = target->getWire();
1277   if (srcw == NULL && tgtw == NULL)
1278     return;
1279   if (srcw == NULL || tgtw == NULL)
1280     return;
1281   if (!isWireOrdered() || !target->isWireOrdered())
1282     return;
1283   /************************************************ dimitris_fix LOOK_AGAIN */
1284   // srcw->match(tgtw);
1285 }
1286 
donateWire(dbNet * tnet,dbRSeg ** new_rsegs)1287 void dbNet::donateWire(dbNet* tnet, dbRSeg** new_rsegs)
1288 {
1289   dbWire* wire = getWire();
1290 
1291   if (!wire || wire->length() == 0)
1292     return;
1293 
1294   dbWire* twire;
1295 
1296   if (tnet == this)  // discard iterm and bterm by donate
1297   {
1298     wire->detach();
1299     twire = dbWire::create(this);
1300     wire->donateWireSeg(twire, new_rsegs);
1301     dbWire::destroy(wire);
1302   } else {
1303     twire = tnet->getWire();
1304 
1305     if (!twire)
1306       twire = dbWire::create(tnet);
1307 
1308     wire->donateWireSeg(twire, new_rsegs);
1309   }
1310 }
1311 
printWire(int fid,int tid,char * type)1312 void dbNet::printWire(int fid, int tid, char* type)
1313 {
1314   FILE* fp;
1315   char fn[40];
1316   if (type) {
1317     sprintf(fn, "%s%d", type, getId());
1318     fp = fopen(fn, "w");
1319   } else
1320     fp = stdout;
1321   fprintf(fp, "dbWire of Net %d %s :\n", getId(), getConstName());
1322   if (getWire() && getWire()->length())
1323     getWire()->printWire(fp, fid, tid);
1324   if (fp != stdout)
1325     fclose(fp);
1326 }
1327 
printWire()1328 void dbNet::printWire()
1329 {
1330   printWire(0, 0, NULL);
1331 }
1332 
printWire(char * type)1333 void dbNet::printWire(char* type)
1334 {
1335   printWire(0, 0, type);
1336 }
1337 
isWireOrdered()1338 bool dbNet::isWireOrdered()
1339 {
1340   _dbNet* net = (_dbNet*) this;
1341   return net->_flags._wire_ordered == 1;
1342 }
1343 
setWireOrdered(bool value)1344 void dbNet::setWireOrdered(bool value)
1345 {
1346   _dbNet* net = (_dbNet*) this;
1347 
1348   _dbBlock* block = (_dbBlock*) net->getOwner();
1349   uint prev_flags = flagsToUInt(net);
1350 
1351   net->_flags._wire_ordered = (value == true) ? 1 : 0;
1352 
1353   if (block->_journal) {
1354     debugPrint(getImpl()->getLogger(),
1355                utl::ODB,
1356                "DB_ECO",
1357                1,
1358                "ECO: net {}, setWireOrdered: {}",
1359                getId(),
1360                value);
1361     block->_journal->updateField(
1362         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1363   }
1364 }
1365 
isBuffered()1366 bool dbNet::isBuffered()
1367 {
1368   _dbNet* net = (_dbNet*) this;
1369   return net->_flags._buffered == 1;
1370 }
1371 
setBuffered(bool value)1372 void dbNet::setBuffered(bool value)
1373 {
1374   _dbNet* net = (_dbNet*) this;
1375 
1376   _dbBlock* block = (_dbBlock*) net->getOwner();
1377   uint prev_flags = flagsToUInt(net);
1378 
1379   net->_flags._buffered = (value == true) ? 1 : 0;
1380 
1381   if (block->_journal) {
1382     debugPrint(getImpl()->getLogger(),
1383                utl::ODB,
1384                "DB_ECO",
1385                1,
1386                "ECO: net {}, setBuffered: {}",
1387                getId(),
1388                value);
1389     block->_journal->updateField(
1390         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1391   }
1392 }
1393 
isDisconnected()1394 bool dbNet::isDisconnected()
1395 {
1396   _dbNet* net = (_dbNet*) this;
1397   return net->_flags._disconnected == 1;
1398 }
1399 
setDisconnected(bool value)1400 void dbNet::setDisconnected(bool value)
1401 {
1402   _dbNet* net = (_dbNet*) this;
1403 
1404   _dbBlock* block = (_dbBlock*) net->getOwner();
1405   uint prev_flags = flagsToUInt(net);
1406   // dimitri_fix : LOOK_AGAIN for FULL_ECO mode uint prev_flags =
1407   // flagsToUInt(net);
1408 
1409   net->_flags._disconnected = (value == true) ? 1 : 0;
1410 
1411   if (block->_journal) {
1412     debugPrint(getImpl()->getLogger(),
1413                utl::ODB,
1414                "DB_ECO",
1415                1,
1416                "ECO: net {}, setDisconnected: {}",
1417                getId(),
1418                value);
1419     block->_journal->updateField(
1420         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1421   }
1422 }
1423 
setWireAltered(bool value)1424 void dbNet::setWireAltered(bool value)
1425 {
1426   _dbNet* net = (_dbNet*) this;
1427 
1428   _dbBlock* block = (_dbBlock*) net->getOwner();
1429   uint prev_flags = flagsToUInt(net);
1430   // dimitri_fix : LOOK_AGAIN for FULL_ECO mode uint prev_flags =
1431   // flagsToUInt(net);
1432 
1433   net->_flags._wire_altered = (value == true) ? 1 : 0;
1434   if (value)
1435     net->_flags._wire_ordered = 0;
1436 
1437   if (block->_journal) {
1438     debugPrint(getImpl()->getLogger(),
1439                utl::ODB,
1440                "DB_ECO",
1441                1,
1442                "ECO: net {}, setWireAltered: {}",
1443                getId(),
1444                value);
1445     block->_journal->updateField(
1446         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1447   }
1448 }
1449 
isWireAltered()1450 bool dbNet::isWireAltered()
1451 {
1452   _dbNet* net = (_dbNet*) this;
1453   return net->_flags._wire_altered == 1;
1454 }
1455 
setExtracted(bool value)1456 void dbNet::setExtracted(bool value)
1457 {
1458   _dbNet* net = (_dbNet*) this;
1459 
1460   _dbBlock* block = (_dbBlock*) net->getOwner();
1461   uint prev_flags = flagsToUInt(net);
1462   // dimitri_fix : LOOK_AGAIN for FULL_ECO mode uint prev_flags =
1463   // flagsToUInt(net);
1464 
1465   net->_flags._extracted = (value == true) ? 1 : 0;
1466 
1467   if (block->_journal) {
1468     debugPrint(getImpl()->getLogger(),
1469                utl::ODB,
1470                "DB_ECO",
1471                1,
1472                "ECO: net {}, setExtracted: {}",
1473                getId(),
1474                value);
1475     block->_journal->updateField(
1476         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1477   }
1478 }
1479 
isExtracted()1480 bool dbNet::isExtracted()
1481 {
1482   _dbNet* net = (_dbNet*) this;
1483   return net->_flags._extracted == 1;
1484 }
1485 
setRCgraph(bool value)1486 void dbNet::setRCgraph(bool value)
1487 {
1488   _dbNet* net = (_dbNet*) this;
1489 
1490   _dbBlock* block = (_dbBlock*) net->getOwner();
1491   uint prev_flags = flagsToUInt(net);
1492 
1493   net->_flags._rc_graph = (value == true) ? 1 : 0;
1494 
1495   if (block->_journal) {
1496     debugPrint(getImpl()->getLogger(),
1497                utl::ODB,
1498                "DB_ECO",
1499                1,
1500                "ECO: net {}, setRCgraph: {}",
1501                getId(),
1502                value);
1503     block->_journal->updateField(
1504         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1505   }
1506 }
1507 
isRCgraph()1508 bool dbNet::isRCgraph()
1509 {
1510   _dbNet* net = (_dbNet*) this;
1511   return net->_flags._rc_graph == 1;
1512 }
1513 
setReduced(bool value)1514 void dbNet::setReduced(bool value)
1515 {
1516   _dbNet* net = (_dbNet*) this;
1517   _dbBlock* block = (_dbBlock*) net->getOwner();
1518   uint prev_flags = flagsToUInt(net);
1519   net->_flags._reduced = (value == true) ? 1 : 0;
1520 
1521   if (block->_journal) {
1522     debugPrint(getImpl()->getLogger(),
1523                utl::ODB,
1524                "DB_ECO",
1525                1,
1526                "ECO: net {}, setReduced: {}",
1527                getId(),
1528                value);
1529     block->_journal->updateField(
1530         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1531   }
1532 }
1533 
isReduced()1534 bool dbNet::isReduced()
1535 {
1536   _dbNet* net = (_dbNet*) this;
1537   return net->_flags._reduced == 1;
1538 }
1539 
getBlock()1540 dbBlock* dbNet::getBlock()
1541 {
1542   return (dbBlock*) getImpl()->getOwner();
1543 }
1544 
getITerms()1545 dbSet<dbITerm> dbNet::getITerms()
1546 {
1547   _dbNet* net = (_dbNet*) this;
1548   _dbBlock* block = (_dbBlock*) net->getOwner();
1549   return dbSet<dbITerm>(net, block->_net_iterm_itr);
1550 }
1551 
get1stITerm()1552 dbITerm* dbNet::get1stITerm()
1553 {
1554   dbSet<dbITerm> iterms = getITerms();
1555   ;
1556   dbSet<dbITerm>::iterator iitr = iterms.begin();
1557   dbITerm* it = *iitr;
1558   return it;
1559 }
1560 
getBTerms()1561 dbSet<dbBTerm> dbNet::getBTerms()
1562 {
1563   _dbNet* net = (_dbNet*) this;
1564   _dbBlock* block = (_dbBlock*) net->getOwner();
1565   return dbSet<dbBTerm>(net, block->_net_bterm_itr);
1566 }
1567 
get1stBTerm()1568 dbBTerm* dbNet::get1stBTerm()
1569 {
1570   dbSet<dbBTerm> bterms = getBTerms();
1571   ;
1572   dbSet<dbBTerm>::iterator bitr = bterms.begin();
1573   dbBTerm* bt = *bitr;
1574   return bt;
1575 }
getFirstOutput()1576 dbITerm* dbNet::getFirstOutput()
1577 {
1578   if (getDrivingITerm() > 0)
1579     return dbITerm::getITerm((dbBlock*) getImpl()->getOwner(),
1580                              getDrivingITerm());
1581 
1582   dbSet<dbITerm> iterms = getITerms();
1583   dbSet<dbITerm>::iterator iitr;
1584 
1585   for (iitr = iterms.begin(); iitr != iterms.end(); ++iitr) {
1586     dbITerm* tr = *iitr;
1587 
1588     if ((tr->getSigType() == dbSigType::GROUND)
1589         || (tr->getSigType() == dbSigType::POWER))
1590       continue;
1591 
1592     if (tr->isClocked())
1593       continue;
1594 
1595     if (tr->getIoType() != dbIoType::OUTPUT)
1596       continue;
1597 
1598     return tr;
1599   }
1600   // warning(0, "instance %s has no output pin\n", getConstName());
1601   return NULL;
1602 }
get1stSignalInput(bool io)1603 dbITerm* dbNet::get1stSignalInput(bool io)
1604 {
1605   dbSet<dbITerm> iterms = getITerms();
1606   dbSet<dbITerm>::iterator iitr;
1607 
1608   for (iitr = iterms.begin(); iitr != iterms.end(); ++iitr) {
1609     dbITerm* tr = *iitr;
1610 
1611     if ((tr->getSigType() == dbSigType::GROUND)
1612         || (tr->getSigType() == dbSigType::POWER))
1613       continue;
1614 
1615     if (tr->getIoType() != dbIoType::INPUT)
1616       continue;
1617 
1618     if (io && (tr->getIoType() != dbIoType::INOUT))
1619       continue;
1620 
1621     return tr;
1622   }
1623   // warning(0, "instance %s has no output pin\n", getConstName());
1624   return NULL;
1625 }
1626 
getSWires()1627 dbSet<dbSWire> dbNet::getSWires()
1628 {
1629   _dbNet* net = (_dbNet*) this;
1630   _dbBlock* block = (_dbBlock*) net->getOwner();
1631   return dbSet<dbSWire>(net, block->_swire_itr);
1632 }
1633 dbSWire*  // Dimitris 9/11/07
getFirstSWire()1634 dbNet::getFirstSWire()
1635 {
1636   _dbNet* net = (_dbNet*) this;
1637   _dbBlock* block = (_dbBlock*) net->getOwner();
1638 
1639   if (net->_swires == 0)
1640     return NULL;
1641 
1642   return (dbSWire*) block->_swire_tbl->getPtr(net->_swires);
1643 }
1644 
getWire()1645 dbWire* dbNet::getWire()
1646 {
1647   _dbNet* net = (_dbNet*) this;
1648   _dbBlock* block = (_dbBlock*) net->getOwner();
1649 
1650   if (net->_wire == 0)
1651     return NULL;
1652 
1653   return (dbWire*) block->_wire_tbl->getPtr(net->_wire);
1654 }
1655 
getGlobalWire()1656 dbWire* dbNet::getGlobalWire()
1657 {
1658   _dbNet* net = (_dbNet*) this;
1659   _dbBlock* block = (_dbBlock*) net->getOwner();
1660 
1661   if (net->_global_wire == 0)
1662     return NULL;
1663 
1664   return (dbWire*) block->_wire_tbl->getPtr(net->_global_wire);
1665 }
1666 
setIOflag()1667 bool dbNet::setIOflag()
1668 {
1669   _dbNet* net = (_dbNet*) this;
1670   _dbBlock* block = (_dbBlock*) net->getOwner();
1671   uint prev_flags = flagsToUInt(net);
1672   net->_flags._set_io = 1;
1673   net->_flags._io = 0;
1674   dbSet<dbBTerm> bterms = getBTerms();
1675   uint n = bterms.size();
1676 
1677   if (n > 0) {
1678     net->_flags._io = 1;
1679 
1680     if (block->_journal) {
1681       debugPrint(getImpl()->getLogger(),
1682                  utl::ODB,
1683                  "DB_ECO",
1684                  1,
1685                  "ECO: net {}, setIOFlag",
1686                  getId());
1687       block->_journal->updateField(
1688           this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1689     }
1690 
1691     return true;
1692   }
1693 
1694   if (block->_journal) {
1695     debugPrint(getImpl()->getLogger(),
1696                utl::ODB,
1697                "DB_ECO",
1698                1,
1699                "ECO: net {}, setIOFlag",
1700                getId());
1701     block->_journal->updateField(
1702         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1703   }
1704 
1705   return false;
1706 }
isIO()1707 bool dbNet::isIO()
1708 {
1709   _dbNet* net = (_dbNet*) this;
1710 
1711   if (net->_flags._set_io > 0)
1712     return net->_flags._io == 1;
1713   else
1714     return setIOflag();
1715 }
1716 
setSizeOnly(bool v)1717 void dbNet::setSizeOnly(bool v)
1718 {
1719   _dbNet* net = (_dbNet*) this;
1720   net->_flags._size_only = v;
1721 }
1722 
isSizeOnly()1723 bool dbNet::isSizeOnly()
1724 {
1725   _dbNet* net = (_dbNet*) this;
1726   return net->_flags._size_only == 1;
1727 }
1728 
setDoNotTouch(bool v)1729 void dbNet::setDoNotTouch(bool v)
1730 {
1731   _dbNet* net = (_dbNet*) this;
1732   net->_flags._dont_touch = v;
1733 }
1734 
isDoNotTouch()1735 bool dbNet::isDoNotTouch()
1736 {
1737   _dbNet* net = (_dbNet*) this;
1738   return net->_flags._dont_touch == 1;
1739 }
1740 
isSpecial()1741 bool dbNet::isSpecial()
1742 {
1743   _dbNet* net = (_dbNet*) this;
1744   return net->_flags._special == 1;
1745 }
1746 
setSpecial()1747 void dbNet::setSpecial()
1748 {
1749   _dbNet* net = (_dbNet*) this;
1750 
1751   _dbBlock* block = (_dbBlock*) net->getOwner();
1752   uint prev_flags = flagsToUInt(net);
1753   // dimitri_fix : LOOK_AGAIN for FULL_ECO mode uint prev_flags =
1754   // flagsToUInt(net);
1755 
1756   net->_flags._special = 1;
1757 
1758   if (block->_journal) {
1759     debugPrint(getImpl()->getLogger(),
1760                utl::ODB,
1761                "DB_ECO",
1762                1,
1763                "ECO: net {}, setSpecial",
1764                getId());
1765     block->_journal->updateField(
1766         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1767   }
1768 }
1769 
clearSpecial()1770 void dbNet::clearSpecial()
1771 {
1772   _dbNet* net = (_dbNet*) this;
1773 
1774   _dbBlock* block = (_dbBlock*) net->getOwner();
1775   uint prev_flags = flagsToUInt(net);
1776   // dimitri_fix : LOOK_AGAIN for FULL_ECO mode uint prev_flags =
1777   // flagsToUInt(net);
1778 
1779   net->_flags._special = 0;
1780 
1781   if (block->_journal) {
1782     debugPrint(getImpl()->getLogger(),
1783                utl::ODB,
1784                "DB_ECO",
1785                1,
1786                "ECO: net {}, clearSpecial",
1787                getId());
1788     block->_journal->updateField(
1789         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1790   }
1791 }
1792 
isWildConnected()1793 bool dbNet::isWildConnected()
1794 {
1795   _dbNet* net = (_dbNet*) this;
1796   return net->_flags._wild_connect == 1;
1797 }
1798 
setWildConnected()1799 void dbNet::setWildConnected()
1800 {
1801   _dbNet* net = (_dbNet*) this;
1802 
1803   _dbBlock* block = (_dbBlock*) net->getOwner();
1804   uint prev_flags = flagsToUInt(net);
1805   // uint prev_flags = flagsToUInt(net);
1806 
1807   net->_flags._wild_connect = 1;
1808 
1809   if (block->_journal) {
1810     debugPrint(getImpl()->getLogger(),
1811                utl::ODB,
1812                "DB_ECO",
1813                1,
1814                "ECO: net {}, setWildConnected",
1815                getId());
1816     block->_journal->updateField(
1817         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1818   }
1819 }
1820 
clearWildConnected()1821 void dbNet::clearWildConnected()
1822 {
1823   _dbNet* net = (_dbNet*) this;
1824 
1825   _dbBlock* block = (_dbBlock*) net->getOwner();
1826   uint prev_flags = flagsToUInt(net);
1827   // uint prev_flags = flagsToUInt(net);
1828 
1829   net->_flags._wild_connect = 0;
1830 
1831   if (block->_journal) {
1832     debugPrint(getImpl()->getLogger(),
1833                utl::ODB,
1834                "DB_ECO",
1835                1,
1836                "ECO: net {}, clearWildConnected",
1837                getId());
1838     block->_journal->updateField(
1839         this, _dbNet::FLAGS, prev_flags, flagsToUInt(net));
1840   }
1841 }
1842 
printRSeg(char * type)1843 void dbNet::printRSeg(char* type)
1844 {
1845   FILE* fp;
1846   char fn[40];
1847   if (type) {
1848     sprintf(fn, "%s%d", type, getId());
1849     fp = fopen(fn, "w");
1850   } else
1851     fp = stdout;
1852   fprintf(fp, "dbRSeg of Net %d %s :\n", getId(), getConstName());
1853   dbSet<dbRSeg> rSet = getRSegs();
1854   dbSet<dbRSeg>::iterator rc_itr;
1855   dbRSeg* rseg;
1856   int cnt = 0;
1857   int rx, ry;
1858   for (rc_itr = rSet.begin(); rc_itr != rSet.end(); ++rc_itr) {
1859     rseg = *rc_itr;
1860     rseg->getCoords(rx, ry);
1861     fprintf(fp,
1862             "  %d  id= %d, src= %d, tgt= %d, R= %g, C= %g\n",
1863             cnt,
1864             rseg->getId(),
1865             rseg->getSourceNode(),
1866             rseg->getTargetNode(),
1867             rseg->getResistance(),
1868             rseg->getCapacitance());  // zzzz corner ?
1869     fprintf(fp, "      x= %d, y=%d\n", rx, ry);
1870     cnt++;
1871   }
1872   if (fp != stdout)
1873     fclose(fp);
1874 }
1875 
getRSegs()1876 dbSet<dbRSeg> dbNet::getRSegs()
1877 {
1878   _dbNet* net = (_dbNet*) this;
1879   _dbBlock* block = (_dbBlock*) net->getOwner();
1880   return dbSet<dbRSeg>(net, block->_r_seg_itr);
1881 }
1882 
reverseRSegs()1883 void dbNet::reverseRSegs()
1884 {
1885   dbSet<dbRSeg> rSet = getRSegs();
1886   rSet.reverse();
1887   _dbBlock* block = (_dbBlock*) getImpl()->getOwner();
1888   if (block->_journal) {
1889     debugPrint(getImpl()->getLogger(),
1890                utl::ODB,
1891                "DB_ECO",
1892                1,
1893                "ECO: dbNet {}, reverse rsegs sequence",
1894                getId());
1895     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
1896     block->_journal->pushParam(dbNetObj);
1897     block->_journal->pushParam(getId());
1898     block->_journal->pushParam(_dbNet::REVERSE_RSEG);
1899     block->_journal->endAction();
1900   }
1901 }
1902 
findRSeg(uint srcn,uint tgtn)1903 dbRSeg* dbNet::findRSeg(uint srcn, uint tgtn)
1904 {
1905   dbSet<dbRSeg> segs = getRSegs();
1906   dbSet<dbRSeg>::iterator sitr;
1907 
1908   dbRSeg* rseg;
1909   for (sitr = segs.begin(); sitr != segs.end(); sitr++) {
1910     rseg = *sitr;
1911     if (rseg->getSourceNode() == srcn && rseg->getTargetNode() == tgtn)
1912       return rseg;
1913   }
1914   return NULL;
1915 }
1916 
1917 int ttttsv = 0;
createZeroRc(bool foreign)1918 void dbNet::createZeroRc(bool foreign)
1919 {
1920   dbCapNode* cap1 = dbCapNode::create(this, 1, foreign);
1921   dbITerm* iterm = get1stITerm();
1922   cap1->setITermFlag();
1923   cap1->setNode(iterm->getId());
1924   dbCapNode* cap2 = dbCapNode::create(this, 2, foreign);
1925   cap2->setInternalFlag();
1926   if (ttttsv) {
1927     cap1->setCapacitance(0.0001, 0);
1928     cap2->setCapacitance(0.0001, 0);
1929   }
1930   dbRSeg* rseg1 = dbRSeg::create(
1931       this, 0 /*x*/, 0 /*y*/, 0 /*path_dir*/, !foreign /*allocate_cap*/);
1932   dbRSeg* rseg0 = dbRSeg::create(
1933       this, 0 /*x*/, 0 /*y*/, 0 /*path_dir*/, !foreign /*allocate_cap*/);
1934   rseg0->setSourceNode(0);
1935   rseg0->setTargetNode(cap1->getId());
1936   rseg1->setSourceNode(cap1->getId());
1937   rseg1->setTargetNode(cap2->getId());
1938   if (ttttsv)
1939     rseg1->setResistance(1.0, 0);
1940   // rseg1->setCapacitance(0.0001, 0);
1941 }
1942 
set1stRSegId(uint rid)1943 void dbNet::set1stRSegId(uint rid)
1944 {
1945   _dbNet* net = (_dbNet*) this;
1946   _dbBlock* block = (_dbBlock*) net->getOwner();
1947   uint pid = net->_r_segs;
1948   net->_r_segs = rid;
1949   if (block->_journal) {
1950     debugPrint(getImpl()->getLogger(),
1951                utl::ODB,
1952                "DB_ECO",
1953                1,
1954                "ECO: dbNet {}, set 1stRSegNode {}",
1955                getId(),
1956                rid);
1957     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
1958     block->_journal->pushParam(dbNetObj);
1959     block->_journal->pushParam(getId());
1960     block->_journal->pushParam(_dbNet::HEAD_RSEG);
1961     block->_journal->pushParam(pid);
1962     block->_journal->pushParam(rid);
1963     block->_journal->endAction();
1964   }
1965 }
1966 
get1stRSegId()1967 uint dbNet::get1stRSegId()
1968 {
1969   _dbNet* net = (_dbNet*) this;
1970   return net->_r_segs;
1971 }
1972 
getZeroRSeg()1973 dbRSeg* dbNet::getZeroRSeg()
1974 {
1975   _dbNet* net = (_dbNet*) this;
1976   if (net->_r_segs == 0)
1977     return NULL;
1978   dbRSeg* zrc = dbRSeg::getRSeg((dbBlock*) net->getOwner(), net->_r_segs);
1979   return zrc;
1980 }
1981 
findCapNode(uint nodeId)1982 dbCapNode* dbNet::findCapNode(uint nodeId)
1983 {
1984   dbSet<dbCapNode> capNodes = getCapNodes();
1985   dbSet<dbCapNode>::iterator itr;
1986 
1987   for (itr = capNodes.begin(); itr != capNodes.end(); ++itr) {
1988     dbCapNode* n = *itr;
1989 
1990     if (n->getNode() == nodeId)
1991       return n;
1992   }
1993 
1994   return NULL;
1995 }
1996 
printCapN(char * type)1997 void dbNet::printCapN(char* type)
1998 {
1999   FILE* fp;
2000   char fn[40];
2001   if (type) {
2002     sprintf(fn, "%s%d", type, getId());
2003     fp = fopen(fn, "w");
2004   } else
2005     fp = stdout;
2006   fprintf(fp, "dbCapNode of Net %d %s :\n", getId(), getConstName());
2007   dbSet<dbCapNode> capNodes = getCapNodes();
2008   dbSet<dbCapNode>::iterator citr;
2009 
2010   dbCapNode* capn;
2011   int cnt = 0;
2012   for (citr = capNodes.begin(); citr != capNodes.end(); ++citr) {
2013     capn = *citr;
2014     uint itermf = capn->isITerm() ? 1 : 0;
2015     uint btermf = capn->isBTerm() ? 1 : 0;
2016     uint interf = capn->isInternal() ? 1 : 0;
2017     uint branch = capn->isBranch() ? 1 : 0;
2018     uint foreign = capn->isForeign() ? 1 : 0;
2019     uint treenode = capn->isTreeNode() ? 1 : 0;
2020     // uint srcbterm = capn->isSourceNodeBterm() ? 1 : 0;
2021     fprintf(fp,
2022             "  %d  id= %d, node= %d, childCnt= %d, iterm= %d, bterm= %d, "
2023             "internal= %d, branch= %d, foreign= %d, treenode= %d\n",
2024             cnt,
2025             capn->getId(),
2026             capn->getNode(),
2027             capn->getChildrenCnt(),
2028             itermf,
2029             btermf,
2030             interf,
2031             branch,
2032             foreign,
2033             treenode);
2034     cnt++;
2035   }
2036   if (fp != stdout)
2037     fclose(fp);
2038 }
2039 
2040 // void dbNet::donateCornerRC(dbBlock *pblock, dbITerm *donorterm, dbITerm
2041 // *rcvterm, dbRSeg *& bridgeRseg, std::vector<dbCCSeg*> * gndcc, dbRSeg *&
2042 // rtrseg, dbCapNode *& lastrcapnd, dbRSeg *& 1stdrseg, dbRSeg *& dtrseg,
2043 // dbCapNode *& 1stdcapnd)
2044 
donateRC(dbITerm * donorterm,dbITerm * rcvterm,dbRSeg * & rtrseg,dbRSeg * & lastrrseg,dbCapNode * & lastrcapnd,uint & ricapndMax,dbRSeg * & fstdrseg,dbRSeg * & dtrseg,dbCapNode * & fstdcapnd,std::vector<dbCCSeg * > * gndcc,dbRSeg * & bridgeRseg)2045 void dbNet::donateRC(dbITerm* donorterm,
2046                      dbITerm* rcvterm,
2047                      dbRSeg*& rtrseg,
2048                      dbRSeg*& lastrrseg,
2049                      dbCapNode*& lastrcapnd,
2050                      uint& ricapndMax,
2051                      dbRSeg*& fstdrseg,
2052                      dbRSeg*& dtrseg,
2053                      dbCapNode*& fstdcapnd,
2054                      std::vector<dbCCSeg*>* gndcc,
2055                      dbRSeg*& bridgeRseg)
2056 {
2057   rtrseg = NULL;
2058   lastrcapnd = NULL;
2059   ricapndMax = 0;
2060   fstdrseg = NULL;
2061   dtrseg = NULL;
2062   fstdcapnd = NULL;
2063   bridgeRseg = NULL;
2064 
2065   dbBlock* block = (dbBlock*) getImpl()->getOwner();
2066   dbBlock* pblock = block;  // needed in case of independent spef corner
2067   dbNet* rcvnet = rcvterm->getNet();
2068 
2069   // donor rsegs
2070   dtrseg = NULL;
2071   dbRSeg* drseg = NULL;
2072   dbSet<dbRSeg> drSet = getRSegs();
2073   dbSet<dbRSeg>::iterator rc_itr;
2074   for (rc_itr = drSet.begin(); rc_itr != drSet.end(); ++rc_itr) {
2075     drseg = *rc_itr;
2076     if (!dtrseg
2077         && dbCapNode::getCapNode(block, drseg->getSourceNode())
2078                    ->getITerm(pblock)
2079                == donorterm) {
2080       dtrseg = drseg;
2081       break;
2082     }
2083   }
2084   if (!drseg)
2085     getImpl()->getLogger()->error(utl::ODB,
2086                                   49,
2087                                   "Donor net {} {} has no rc data",
2088                                   getId(),
2089                                   getConstName());
2090   if (!dtrseg)
2091     getImpl()->getLogger()->error(
2092         utl::ODB,
2093         50,
2094         "Donor net {} {} has no capnode attached to iterm {}/{}",
2095         getId(),
2096         getConstName(),
2097         donorterm->getInst()->getConstName(),
2098         donorterm->getMTerm()->getConstName());
2099   fstdrseg = getZeroRSeg();
2100 
2101   // receiver rsegs
2102   rtrseg = NULL;
2103   dbRSeg* rrseg = NULL;
2104   dbSet<dbRSeg> rSet = rcvnet->getRSegs();
2105   for (rc_itr = rSet.begin(); rc_itr != rSet.end(); ++rc_itr) {
2106     rrseg = *rc_itr;
2107     if (!rtrseg
2108         && dbCapNode::getCapNode(block, rrseg->getTargetNode())
2109                    ->getITerm(pblock)
2110                == rcvterm)
2111       rtrseg = rrseg;
2112     lastrrseg = rrseg;
2113   }
2114   if (!rtrseg)
2115     getImpl()->getLogger()->error(
2116         utl::ODB,
2117         51,
2118         "Receiver net {} {} has no capnode attached to iterm {}/{}",
2119         rcvnet->getId(),
2120         rcvnet->getConstName(),
2121         rcvterm->getInst()->getConstName(),
2122         rcvterm->getMTerm()->getConstName());
2123 
2124   // receiver capnodes
2125   dbCapNode* rcapnd = NULL;
2126   dbSet<dbCapNode> rnodeSet = rcvnet->getCapNodes();
2127   dbSet<dbCapNode>::iterator capn_itr;
2128   for (capn_itr = rnodeSet.begin(); capn_itr != rnodeSet.end(); ++capn_itr) {
2129     rcapnd = *capn_itr;
2130     if (rcapnd->isInternal()) {
2131       if (rcapnd->getNode() > ricapndMax)
2132         ricapndMax = rcapnd->getNode();
2133     }
2134   }
2135   ricapndMax += 3;
2136   lastrcapnd = rcapnd;
2137 
2138   uint rcvnid = rcvnet->getId();
2139 
2140   // donor capnodes
2141   dbCapNode* other = NULL;
2142   dbCapNode* capnd = NULL;
2143   uint cCnt = ((dbBlock*) getImpl()->getOwner())->getCornersPerBlock();
2144   dbSet<dbCapNode> nodeSet = getCapNodes();
2145   uint cid;
2146   for (capn_itr = nodeSet.begin(); capn_itr != nodeSet.end(); ++capn_itr) {
2147     capnd = *capn_itr;
2148     if (!fstdcapnd)
2149       fstdcapnd = capnd;
2150     dbSet<dbCCSeg> ccSegs = capnd->getCCSegs();
2151     dbCCSeg* ccSeg;
2152     dbSet<dbCCSeg>::iterator ccitr;
2153     for (ccitr = ccSegs.begin(); ccitr != ccSegs.end(); ccitr++) {
2154       ccSeg = *ccitr;
2155       other = ccSeg->getTheOtherCapn(capnd, cid);
2156       if (other->getNet() == rcvnet) {
2157         for (uint ii = 0; ii < cCnt; ii++) {
2158           capnd->addCapacitance(ccSeg->getCapacitance(ii), ii);
2159           other->addCapacitance(ccSeg->getCapacitance(ii), ii);
2160         }
2161         gndcc->push_back(ccSeg);
2162         dbCCSeg::disconnect(ccSeg);
2163       }
2164     }
2165     capnd->setNet(rcvnid);
2166     if (capnd->isInternal())
2167       capnd->setNode(capnd->getNode() + ricapndMax);
2168   }
2169 
2170   lastrcapnd->setNext(fstdcapnd->getId());
2171 
2172   dbCapNode* donorSrcCapNode
2173       = dbCapNode::getCapNode(block, dtrseg->getSourceNode());
2174   donorSrcCapNode->setInternalFlag();
2175   donorSrcCapNode->resetITermFlag();
2176   donorSrcCapNode->setNode(ricapndMax - 1);
2177   dbCapNode* rcvTgtCapNod
2178       = dbCapNode::getCapNode(block, rtrseg->getTargetNode());
2179   rcvTgtCapNod->setInternalFlag();
2180   rcvTgtCapNod->resetITermFlag();
2181   rcvTgtCapNod->setNode(ricapndMax - 2);
2182   bool foreign = block->getExtControl()->_foreign;
2183   dbRSeg* zrrseg = rcvnet->getZeroRSeg();
2184   bridgeRseg = dbRSeg::create(
2185       rcvnet, 0 /*x*/, 0 /*y*/, 0 /*pathDir*/, !foreign /*allocateCap*/);
2186   rcvnet->set1stRSegId(zrrseg->getId());
2187   bridgeRseg->setSourceNode(rcvTgtCapNod->getId());
2188   bridgeRseg->setTargetNode(donorSrcCapNode->getId());
2189   for (uint ii = 0; ii < cCnt; ii++) {
2190     bridgeRseg->setResistance(0, ii);
2191     if (!foreign)
2192       bridgeRseg->setCapacitance(0, ii);
2193   }
2194   lastrrseg->setNext(bridgeRseg->getId());
2195   bridgeRseg->setNext(dtrseg->getId());
2196 
2197   set1stRSegId(0);
2198   set1stCapNodeId(0);
2199 }
2200 
2201 // void dbNet::donateRC(dbITerm *rcvterm, dbNet *rcvnet)
2202 //{
2203 //    dbBlock *block = (dbBlock *)getOwner();
2204 //    donateCornerRC(block, rcvterm, rcvnet);
2205 //    if (!block->extCornersAreIndependent())
2206 //        return;
2207 //    dbBlock *extBlock;
2208 //    dbNet *dNet;
2209 //    dbNet *rNet;
2210 //    int numcorners = block->getCornerCount();
2211 //    for (int corner = 1; corner < numcorners; corner++) {
2212 //        extBlock = block->findExtCornerBlock(corner);
2213 //        dNet = dbNet::getNet(extBlock, getId());
2214 //        rNet = dbNet::getNet(extBlock, rcvnet->getId());
2215 //        dNet->donateCornerRC(block, rcvterm, rNet);
2216 //    }
2217 //}
2218 
unDonateRC(dbRSeg * rtrseg,dbRSeg * lastrrseg,dbITerm * it,dbCapNode * lastrcapnd,uint ricapndCnt,dbRSeg * dtrseg,dbRSeg * fstdrseg,dbCapNode * fstdcapnd,dbITerm * ot,std::vector<dbCCSeg * > * gndcc)2219 void dbNet::unDonateRC(dbRSeg* rtrseg,
2220                        dbRSeg* lastrrseg,
2221                        dbITerm* it,
2222                        dbCapNode* lastrcapnd,
2223                        uint ricapndCnt,
2224                        dbRSeg* dtrseg,
2225                        dbRSeg* fstdrseg,
2226                        dbCapNode* fstdcapnd,
2227                        dbITerm* ot,
2228                        std::vector<dbCCSeg*>* gndcc)
2229 {
2230   lastrrseg->setNext(0);
2231 
2232   rtrseg->getTargetCapNode()->resetInternalFlag();
2233   rtrseg->getTargetCapNode()->setITermFlag();
2234   rtrseg->getTargetCapNode()->setNode(it->getId());
2235   lastrcapnd->setNext(0);
2236 
2237   dtrseg->getSourceCapNode()->resetInternalFlag();
2238   dtrseg->getSourceCapNode()->setITermFlag();
2239   dtrseg->getSourceCapNode()->setNode(ot->getId());
2240 
2241   set1stRSegId(fstdrseg->getId());
2242   set1stCapNodeId(fstdcapnd->getId());
2243   uint donorNetId = getId();
2244   dbSet<dbCapNode> nodeSet = getCapNodes();
2245   dbSet<dbCapNode>::iterator capn_itr;
2246   dbCapNode* capnd;
2247   for (capn_itr = nodeSet.begin(); capn_itr != nodeSet.end(); ++capn_itr) {
2248     capnd = *capn_itr;
2249     capnd->setNet(donorNetId);
2250     if (capnd->isInternal())
2251       capnd->setNode(capnd->getNode() - ricapndCnt);
2252   }
2253   uint cCnt = ((dbBlock*) getImpl()->getOwner())->getCornersPerBlock();
2254   dbCCSeg* ccseg;
2255   dbCapNode* srcn;
2256   dbCapNode* tgtn;
2257   double cap;
2258   for (uint ii = 0; ii < gndcc->size(); ii++) {
2259     ccseg = (*gndcc)[ii];
2260     srcn = ccseg->getSourceCapNode();
2261     tgtn = ccseg->getTargetCapNode();
2262     for (uint jj = 0; jj < cCnt; jj++) {
2263       cap = ccseg->getCapacitance(jj);
2264       srcn->addCapacitance(-cap, jj);
2265       tgtn->addCapacitance(-cap, jj);
2266     }
2267     dbCCSeg::connect(ccseg);
2268   }
2269 }
2270 
printWnP(char * type)2271 void dbNet::printWnP(char* type)
2272 {
2273   char tag[20];
2274   sprintf(tag, "%s_w_", type);
2275   printWire(tag);
2276   sprintf(tag, "%s_r_", type);
2277   printRSeg(tag);
2278   sprintf(tag, "%s_c_", type);
2279   printCapN(tag);
2280 }
2281 
getCapNodes()2282 dbSet<dbCapNode> dbNet::getCapNodes()
2283 {
2284   _dbNet* net = (_dbNet*) this;
2285   _dbBlock* block = (_dbBlock*) net->getOwner();
2286   return dbSet<dbCapNode>(net, block->_cap_node_itr);
2287 }
2288 
setTermExtIds(int capId)2289 void dbNet::setTermExtIds(int capId)  // 1: capNodeId, 0: reset
2290 {
2291   dbSet<dbCapNode> nodeSet = getCapNodes();
2292   dbSet<dbCapNode>::iterator rc_itr;
2293   _dbBlock* block = (_dbBlock*) getImpl()->getOwner();
2294 
2295   if (block->_journal) {
2296     if (capId) {
2297       debugPrint(getImpl()->getLogger(),
2298                  utl::ODB,
2299                  "DB_ECO",
2300                  1,
2301                  "ECO: set net {} term extId",
2302                  getId());
2303     } else
2304       debugPrint(getImpl()->getLogger(),
2305                  utl::ODB,
2306                  "DB_ECO",
2307                  1,
2308                  "ECO: reset net {} term extId",
2309                  getId());
2310     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
2311     block->_journal->pushParam(dbNetObj);
2312     block->_journal->pushParam(getId());
2313     block->_journal->pushParam(_dbNet::TERM_EXTID);
2314     block->_journal->pushParam(capId);
2315     block->_journal->endAction();
2316   }
2317 
2318   for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
2319     dbCapNode* capNode = *rc_itr;
2320     if (capNode->isBTerm()) {
2321       uint nodeId = capNode->getNode();
2322       dbBTerm* bterm = dbBTerm::getBTerm((dbBlock*) block, nodeId);
2323       uint extId = capId ? capNode->getId() : 0;
2324       bterm->setExtId(extId);
2325       continue;
2326     }
2327 
2328     if (capNode->isITerm()) {
2329       uint nodeId = capNode->getNode();
2330       dbITerm* iterm = dbITerm::getITerm((dbBlock*) block, nodeId);
2331       uint extId = capId ? capNode->getId() : 0;
2332       iterm->setExtId(extId);
2333     }
2334   }
2335 }
set1stCapNodeId(uint cid)2336 void dbNet::set1stCapNodeId(uint cid)
2337 {
2338   _dbNet* net = (_dbNet*) this;
2339   _dbBlock* block = (_dbBlock*) net->getOwner();
2340   uint pid = net->_cap_nodes;
2341   net->_cap_nodes = cid;
2342   if (block->_journal) {
2343     debugPrint(getImpl()->getLogger(),
2344                utl::ODB,
2345                "DB_ECO",
2346                1,
2347                "ECO: dbNet {}, set 1stCapNode {}",
2348                getId(),
2349                cid);
2350     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
2351     block->_journal->pushParam(dbNetObj);
2352     block->_journal->pushParam(getId());
2353     block->_journal->pushParam(_dbNet::HEAD_CAPNODE);
2354     block->_journal->pushParam(pid);
2355     block->_journal->pushParam(cid);
2356     block->_journal->endAction();
2357   }
2358 }
2359 
get1stCapNodeId()2360 uint dbNet::get1stCapNodeId()
2361 {
2362   _dbNet* net = (_dbNet*) this;
2363   return net->_cap_nodes;
2364 }
2365 
reverseCCSegs()2366 void dbNet::reverseCCSegs()
2367 {
2368   dbSet<dbCapNode> nodes = getCapNodes();
2369   dbSet<dbCapNode>::iterator itr;
2370 
2371   for (itr = nodes.begin(); itr != nodes.end(); ++itr) {
2372     dbCapNode* node = *itr;
2373     node->getCCSegs().reverse();
2374   }
2375 }
2376 
getSrcCCSegs(std::vector<dbCCSeg * > & S)2377 void dbNet::getSrcCCSegs(std::vector<dbCCSeg*>& S)
2378 {
2379   dbSet<dbCapNode> nodes = getCapNodes();
2380   dbSet<dbCapNode>::iterator itr;
2381 
2382   for (itr = nodes.begin(); itr != nodes.end(); ++itr) {
2383     dbCapNode* node = *itr;
2384     uint cap_id = node->getImpl()->getOID();
2385     dbSet<dbCCSeg> segs = node->getCCSegs();
2386     dbSet<dbCCSeg>::iterator sitr;
2387 
2388     for (sitr = segs.begin(); sitr != segs.end(); ++sitr) {
2389       _dbCCSeg* seg = (_dbCCSeg*) *sitr;
2390       if (seg->_cap_node[0] == cap_id)
2391         S.push_back((dbCCSeg*) seg);
2392     }
2393   }
2394 }
2395 
getTgtCCSegs(std::vector<dbCCSeg * > & S)2396 void dbNet::getTgtCCSegs(std::vector<dbCCSeg*>& S)
2397 {
2398   dbSet<dbCapNode> nodes = getCapNodes();
2399   dbSet<dbCapNode>::iterator itr;
2400 
2401   for (itr = nodes.begin(); itr != nodes.end(); ++itr) {
2402     dbCapNode* node = *itr;
2403     uint cap_id = node->getImpl()->getOID();
2404     dbSet<dbCCSeg> segs = node->getCCSegs();
2405     dbSet<dbCCSeg>::iterator sitr;
2406 
2407     for (sitr = segs.begin(); sitr != segs.end(); ++sitr) {
2408       _dbCCSeg* seg = (_dbCCSeg*) *sitr;
2409       if (seg->_cap_node[1] == cap_id)
2410         S.push_back((dbCCSeg*) seg);
2411     }
2412   }
2413 }
2414 
2415 /*
2416 void
2417 dbNet::unlinkCapNodes()
2418 {
2419     _dbNet * net = (_dbNet *) this;
2420     net->_cap_nodes = 0;
2421 }
2422 */
2423 
destroyCapNodes(bool cleanExtid)2424 void dbNet::destroyCapNodes(bool cleanExtid)
2425 {
2426   dbBlock* block = (dbBlock*) getImpl()->getOwner();
2427   dbSet<dbCapNode> cap_nodes = getCapNodes();
2428   dbSet<dbCapNode>::iterator itr;
2429 
2430   for (itr = cap_nodes.begin(); itr != cap_nodes.end();) {
2431     dbCapNode* cn = *itr;
2432     uint oid = cn->getNode();
2433 
2434     if (cleanExtid) {
2435       if (cn->isITerm())
2436         (dbITerm::getITerm(block, oid))->setExtId(0);
2437 
2438       else if (cn->isBTerm())
2439         (dbBTerm::getBTerm(block, oid))->setExtId(0);
2440     }
2441 
2442     itr = dbCapNode::destroy(itr);
2443   }
2444 }
2445 
destroyRSegs()2446 void dbNet::destroyRSegs()
2447 {
2448   dbSet<dbRSeg> segs = getRSegs();
2449   dbSet<dbRSeg>::iterator sitr;
2450 
2451   for (sitr = segs.begin(); sitr != segs.end();)
2452     sitr = dbRSeg::destroy(sitr);
2453 
2454   dbRSeg* zrc = getZeroRSeg();
2455   if (zrc)
2456     dbRSeg::destroy(zrc);
2457 }
2458 
destroyCCSegs()2459 void dbNet::destroyCCSegs()
2460 {
2461   dbSet<dbCapNode> capNodes = getCapNodes();
2462   dbSet<dbCapNode>::iterator citr;
2463 
2464   for (citr = capNodes.begin(); citr != capNodes.end(); ++citr) {
2465     dbCapNode* n = *citr;
2466     dbSet<dbCCSeg> ccSegs = n->getCCSegs();
2467     dbSet<dbCCSeg>::iterator ccitr;
2468 
2469     for (ccitr = ccSegs.begin();
2470          ccitr != ccSegs.end();)  // ++ccitr here after destroy(cc) would crash
2471     {
2472       dbCCSeg* cc = *ccitr;
2473       ++ccitr;
2474       dbCCSeg::destroy(cc);
2475     }
2476   }
2477 }
2478 
getCouplingNets(uint corner,double ccThreshold,std::set<dbNet * > & cnets)2479 void dbNet::getCouplingNets(uint corner,
2480                             double ccThreshold,
2481                             std::set<dbNet*>& cnets)
2482 {
2483   dbSet<dbCapNode> capNodes = getCapNodes();
2484   dbSet<dbCapNode>::iterator citr;
2485   std::vector<dbNet*> inets;
2486   std::vector<double> netccap;
2487   dbNet* tnet;
2488   double cccap;
2489   uint ii;
2490 
2491   for (citr = capNodes.begin(); citr != capNodes.end(); ++citr) {
2492     dbCapNode* n = *citr;
2493     dbSet<dbCCSeg> ccSegs = n->getCCSegs();
2494     dbSet<dbCCSeg>::iterator ccitr;
2495 
2496     for (ccitr = ccSegs.begin(); ccitr != ccSegs.end(); ++ccitr) {
2497       dbCCSeg* cc = *ccitr;
2498       cccap = cc->getCapacitance(corner);
2499       tnet = cc->getSourceCapNode()->getNet();
2500       if (tnet == this)
2501         tnet = cc->getTargetCapNode()->getNet();
2502       if (tnet->isMarked()) {
2503         for (ii = 0; ii < inets.size(); ii++) {
2504           if (inets[ii] == tnet) {
2505             netccap[ii] += cccap;
2506             break;
2507           }
2508         }
2509         continue;
2510       }
2511       netccap.push_back(cccap);
2512       inets.push_back(tnet);
2513       tnet->setMark(true);
2514     }
2515   }
2516   for (ii = 0; ii < inets.size(); ii++) {
2517     if (netccap[ii] >= ccThreshold && cnets.find(inets[ii]) == cnets.end())
2518       cnets.insert(inets[ii]);
2519     inets[ii]->setMark(false);
2520   }
2521 }
2522 
getGndTotalCap(double * gndcap,double * totalcap,double mcf)2523 void dbNet::getGndTotalCap(double* gndcap, double* totalcap, double mcf)
2524 {
2525   dbSigType type = getSigType();
2526   if ((type == dbSigType::POWER) || (type == dbSigType::GROUND))
2527     return;
2528   dbSet<dbRSeg> rSet = getRSegs();
2529   if (rSet.begin() == rSet.end()) {
2530     getImpl()->getLogger()->warn(utl::ODB,
2531                                  52,
2532                                  "Net {}, {} has no extraction data",
2533                                  getId(),
2534                                  getConstName());
2535     return;
2536   }
2537   bool foreign = ((dbBlock*) getImpl()->getOwner())->getExtControl()->_foreign;
2538   bool first = true;
2539   if (foreign) {
2540     dbSet<dbCapNode> nodeSet = getCapNodes();
2541     dbSet<dbCapNode>::iterator rc_itr;
2542     dbCapNode* node;
2543     for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
2544       node = *rc_itr;
2545       if (first)
2546         node->getGndTotalCap(gndcap, totalcap, mcf);
2547       else
2548         node->addGndTotalCap(gndcap, totalcap, mcf);
2549       first = false;
2550     }
2551   } else {
2552     dbRSeg* rc;
2553     dbSet<dbRSeg>::iterator rc_itr;
2554     for (rc_itr = rSet.begin(); rc_itr != rSet.end(); ++rc_itr) {
2555       rc = *rc_itr;
2556       if (first)
2557         rc->getGndTotalCap(gndcap, totalcap, mcf);
2558       else
2559         rc->addGndTotalCap(gndcap, totalcap, mcf);
2560       first = false;
2561     }
2562   }
2563 }
2564 
preExttreeMergeRC(double max_cap,uint corner)2565 void dbNet::preExttreeMergeRC(double max_cap, uint corner)
2566 {
2567   dbBlock* block = (dbBlock*) (getImpl()->getOwner());
2568   double totalcap[ADS_MAX_CORNER];
2569   dbCapNode* tgtNode;
2570   std::vector<dbRSeg*> mrsegs;
2571   dbSigType type = getSigType();
2572   if ((type == dbSigType::POWER) || (type == dbSigType::GROUND))
2573     return;
2574   dbSet<dbRSeg> rSet = getRSegs();
2575   if (rSet.begin() == rSet.end()) {
2576     getImpl()->getLogger()->warn(utl::ODB,
2577                                  53,
2578                                  "Net {}, {} has no extraction data",
2579                                  getId(),
2580                                  getConstName());
2581     return;
2582   }
2583   dbRSeg* prc = getZeroRSeg();
2584   dbRSeg* rc;
2585   bool firstRC = true;
2586   uint cnt = 1;
2587   prc->getGndTotalCap(NULL, &totalcap[0], 1 /*mcf*/);
2588   dbSet<dbRSeg>::iterator rc_itr;
2589   for (rc_itr = rSet.begin(); rc_itr != rSet.end(); ++rc_itr) {
2590     rc = *rc_itr;
2591     mrsegs.push_back(rc);
2592     if (firstRC && cnt != 1)
2593       rc->getGndTotalCap(NULL, &totalcap[0], 1 /*mcf*/);
2594     else
2595       rc->addGndTotalCap(NULL, &totalcap[0], 1 /*mcf*/);
2596     cnt++;
2597     firstRC = false;
2598     tgtNode = dbCapNode::getCapNode(block, rc->getTargetNode());
2599     if (rc->getSourceNode() == rc->getTargetNode())
2600       continue;
2601     if (!tgtNode->isTreeNode() && totalcap[corner] <= max_cap
2602         && !tgtNode->isDangling())
2603       continue;
2604 #ifdef EXT
2605     prc->mergeRCs(mrsegs);
2606 #endif
2607     prc = rc;
2608     mrsegs.clear();
2609     firstRC = true;
2610   }
2611 }
2612 
destroyParasitics()2613 void dbNet::destroyParasitics()
2614 {
2615   dbBlock* block = (dbBlock*) getImpl()->getOwner();
2616   std::vector<dbNet*> nets;
2617   nets.push_back(this);
2618   block->destroyParasitics(nets);
2619 }
2620 
getTotalCouplingCap(uint corner)2621 double dbNet::getTotalCouplingCap(uint corner)
2622 {
2623   double cap = 0.0;
2624   dbSet<dbCapNode> capNodes = getCapNodes();
2625   dbSet<dbCapNode>::iterator citr;
2626 
2627   for (citr = capNodes.begin(); citr != capNodes.end(); ++citr) {
2628     dbCapNode* n = *citr;
2629     dbSet<dbCCSeg> ccSegs = n->getCCSegs();
2630     dbSet<dbCCSeg>::iterator ccitr;
2631 
2632     for (ccitr = ccSegs.begin(); ccitr != ccSegs.end(); ++ccitr) {
2633       dbCCSeg* cc = *ccitr;
2634       cap += cc->getCapacitance(corner);
2635     }
2636   }
2637 
2638   return cap;
2639 }
2640 
getTotalCapacitance(uint corner,bool cc)2641 double dbNet::getTotalCapacitance(uint corner, bool cc)
2642 {
2643   double cap = 0.0;
2644   double cap1 = 0.0;
2645   bool foreign = ((dbBlock*) getImpl()->getOwner())->getExtControl()->_foreign;
2646 
2647   if (foreign) {
2648     dbSet<dbCapNode> nodeSet = getCapNodes();
2649     dbSet<dbCapNode>::iterator rc_itr;
2650     dbCapNode* node;
2651     for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
2652       node = *rc_itr;
2653       cap1 = node->getCapacitance(corner);
2654       cap += cap1;
2655     }
2656   } else {
2657     dbSet<dbRSeg> rSet = getRSegs();
2658     dbSet<dbRSeg>::iterator rc_itr;
2659     dbRSeg* rc;
2660     for (rc_itr = rSet.begin(); rc_itr != rSet.end(); ++rc_itr) {
2661       rc = *rc_itr;
2662       cap1 = rc->getCapacitance(corner);
2663       cap += cap1;
2664     }
2665   }
2666   if (cc)
2667     cap += getTotalCouplingCap(corner);
2668   return cap;
2669 }
2670 
getTotalResistance(uint corner)2671 double dbNet::getTotalResistance(uint corner)
2672 {
2673   dbSet<dbRSeg> rSet = this->getRSegs();
2674   dbSet<dbRSeg>::iterator rc_itr;
2675 
2676   double cap = 0.0;
2677 
2678   for (rc_itr = rSet.begin(); rc_itr != rSet.end(); ++rc_itr) {
2679     dbRSeg* rc = *rc_itr;
2680 
2681     cap += rc->getResistance(corner);
2682   }
2683   return cap;
2684 }
2685 
setNonDefaultRule(dbTechNonDefaultRule * rule)2686 void dbNet::setNonDefaultRule(dbTechNonDefaultRule* rule)
2687 {
2688   _dbNet* net = (_dbNet*) this;
2689   _dbBlock* block = (_dbBlock*) net->getOwner();
2690   uint prev_rule = net->_non_default_rule;
2691   bool prev_block_rule = net->_flags._block_rule;
2692 
2693   if (rule == NULL) {
2694     net->_non_default_rule = 0U;
2695     net->_flags._block_rule = 0;
2696   } else {
2697     net->_non_default_rule = rule->getImpl()->getOID();
2698     net->_flags._block_rule = rule->isBlockRule();
2699   }
2700 
2701   if (block->_journal) {
2702     debugPrint(getImpl()->getLogger(),
2703                utl::ODB,
2704                "DB_ECO",
2705                1,
2706                "ECO: net {}, setNonDefaultRule: ",
2707                getId(),
2708                (rule) ? rule->getImpl()->getOID() : 0);
2709     // block->_journal->updateField(this, _dbNet::NON_DEFAULT_RULE, prev_rule,
2710     // net->_non_default_rule );
2711     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
2712     block->_journal->pushParam(rule->getObjectType());
2713     block->_journal->pushParam(rule->getId());
2714     block->_journal->pushParam(_dbNet::NON_DEFAULT_RULE);
2715     block->_journal->pushParam(prev_rule);
2716     block->_journal->pushParam((uint) net->_non_default_rule);
2717     block->_journal->pushParam(prev_block_rule);
2718     block->_journal->pushParam((bool) net->_flags._block_rule);
2719     block->_journal->endAction();
2720   }
2721 }
2722 
getNonDefaultRule()2723 dbTechNonDefaultRule* dbNet::getNonDefaultRule()
2724 {
2725   _dbNet* net = (_dbNet*) this;
2726 
2727   if (net->_non_default_rule == 0)
2728     return NULL;
2729 
2730   dbDatabase* db = (dbDatabase*) net->getDatabase();
2731 
2732   if (net->_flags._block_rule) {
2733     _dbBlock* block = (_dbBlock*) net->getOwner();
2734     return (dbTechNonDefaultRule*) block->_non_default_rule_tbl->getPtr(
2735         net->_non_default_rule);
2736   }
2737 
2738   _dbTech* tech = (_dbTech*) db->getTech();
2739   return (dbTechNonDefaultRule*) tech->_non_default_rule_tbl->getPtr(
2740       net->_non_default_rule);
2741 }
2742 
getSignalWireCount(uint & wireCnt,uint & viaCnt)2743 void dbNet::getSignalWireCount(uint& wireCnt, uint& viaCnt)
2744 {
2745   dbWirePath path;
2746   dbWirePathShape pshape;
2747   dbWire* wire = getWire();
2748   if (wire == NULL)
2749     return;
2750   dbWirePathItr pitr;
2751   for (pitr.begin(wire); pitr.getNextPath(path);) {
2752     while (pitr.getNextShape(pshape)) {
2753       if (pshape.shape.isVia())
2754         viaCnt++;
2755       else
2756         wireCnt++;
2757     }
2758   }
2759 }
getNetStats(uint & wireCnt,uint & viaCnt,uint & len,uint & layerCnt,uint * levelTable)2760 void dbNet::getNetStats(uint& wireCnt,
2761                         uint& viaCnt,
2762                         uint& len,
2763                         uint& layerCnt,
2764                         uint* levelTable)
2765 {
2766   len = 0;
2767   wireCnt = 0;
2768   viaCnt = 0;
2769   layerCnt = 0;
2770   dbWirePath path;
2771   dbWirePathShape pshape;
2772   dbWire* wire = getWire();
2773   if (wire == NULL)
2774     return;
2775   dbWirePathItr pitr;
2776   for (pitr.begin(wire); pitr.getNextPath(path);) {
2777     while (pitr.getNextShape(pshape)) {
2778       if (pshape.shape.isVia()) {
2779         viaCnt++;
2780         continue;
2781       }
2782       wireCnt++;
2783 
2784       uint level = pshape.shape.getTechLayer()->getRoutingLevel();
2785       if (levelTable)
2786         levelTable[level]++;
2787       len += MAX(pshape.shape.xMax() - pshape.shape.xMin(),
2788                  pshape.shape.yMax() - pshape.shape.yMin());
2789     }
2790   }
2791 }
getPowerWireCount(uint & wireCnt,uint & viaCnt)2792 void dbNet::getPowerWireCount(uint& wireCnt, uint& viaCnt)
2793 {
2794   dbSet<dbSWire> swires = getSWires();
2795   dbSet<dbSWire>::iterator itr;
2796   for (itr = swires.begin(); itr != swires.end(); ++itr) {
2797     dbSWire* swire = *itr;
2798     dbSet<dbSBox> wires = swire->getWires();
2799     dbSet<dbSBox>::iterator box_itr;
2800     for (box_itr = wires.begin(); box_itr != wires.end(); ++box_itr) {
2801       dbSBox* s = *box_itr;
2802       if (s->isVia())
2803         viaCnt++;
2804       else
2805         wireCnt++;
2806     }
2807   }
2808 }
2809 
getWireCount(uint & wireCnt,uint & viaCnt)2810 void dbNet::getWireCount(uint& wireCnt, uint& viaCnt)
2811 {
2812   if (getSigType() == dbSigType::POWER || getSigType() == dbSigType::GROUND)
2813     getPowerWireCount(wireCnt, viaCnt);
2814   else
2815     getSignalWireCount(wireCnt, viaCnt);
2816 }
2817 
getITermCount()2818 uint dbNet::getITermCount()
2819 {
2820   uint itc = 0;
2821   dbSet<dbITerm> iterms = getITerms();
2822   dbSet<dbITerm>::iterator iterm_itr;
2823   for (iterm_itr = iterms.begin(); iterm_itr != iterms.end(); ++iterm_itr)
2824     itc++;
2825   return itc;
2826 }
2827 
getBTermCount()2828 uint dbNet::getBTermCount()
2829 {
2830   uint btc = 0;
2831   dbSet<dbBTerm> bterms = getBTerms();
2832   dbSet<dbBTerm>::iterator bterm_itr;
2833   for (bterm_itr = bterms.begin(); bterm_itr != bterms.end(); ++bterm_itr)
2834     btc++;
2835   return btc;
2836 }
2837 
getTermCount()2838 uint dbNet::getTermCount()
2839 {
2840   uint itc = getITermCount();
2841   uint btc = getBTermCount();
2842   return itc + btc;
2843 }
2844 
destroySWires()2845 void dbNet::destroySWires()
2846 {
2847   _dbNet* net = (_dbNet*) this;
2848 
2849   dbSet<dbSWire> swires = getSWires();
2850   ;
2851   dbSet<dbSWire>::iterator sitr;
2852 
2853   for (sitr = swires.begin(); sitr != swires.end();)
2854     sitr = dbSWire::destroy(sitr);
2855 
2856   net->_swires = 0;
2857 }
2858 
create(dbBlock * block_,const char * name_,bool skipExistingCheck)2859 dbNet* dbNet::create(dbBlock* block_, const char* name_, bool skipExistingCheck)
2860 {
2861   _dbBlock* block = (_dbBlock*) block_;
2862 
2863   if (!skipExistingCheck && block->_net_hash.hasMember(name_))
2864     return NULL;
2865 
2866   if (block->_journal) {
2867     debugPrint(block->getImpl()->getLogger(),
2868                utl::ODB,
2869                "DB_ECO",
2870                1,
2871                "ECO: create net, name {}",
2872                name_);
2873     block->_journal->beginAction(dbJournal::CREATE_OBJECT);
2874     block->_journal->pushParam(dbNetObj);
2875     block->_journal->pushParam(name_);
2876     block->_journal->endAction();
2877   }
2878 
2879   _dbNet* net = block->_net_tbl->create();
2880   net->_name = strdup(name_);
2881   ZALLOCATED(net->_name);
2882   block->_net_hash.insert(net);
2883 
2884   std::list<dbBlockCallBackObj*>::iterator cbitr;
2885   for (cbitr = block->_callbacks.begin(); cbitr != block->_callbacks.end();
2886        ++cbitr)
2887     (**cbitr)().inDbNetCreate((dbNet*) net);  // client ECO optimization - payam
2888 
2889   return (dbNet*) net;
2890 }
2891 
destroy(dbNet * net_)2892 void dbNet::destroy(dbNet* net_)
2893 {
2894   _dbNet* net = (_dbNet*) net_;
2895   _dbBlock* block = (_dbBlock*) net->getOwner();
2896 
2897   dbSet<dbITerm> iterms = net_->getITerms();
2898   dbSet<dbITerm>::iterator iitr;
2899 
2900   for (iitr = iterms.begin(); iitr != iterms.end();)
2901     iitr = dbITerm::disconnect(iitr);
2902 
2903   dbSet<dbBTerm> bterms = net_->getBTerms();
2904 
2905   dbSet<dbBTerm>::iterator bitr;
2906 
2907   for (bitr = bterms.begin(); bitr != bterms.end();)
2908     bitr = dbBTerm::destroy(bitr);
2909 
2910   dbSet<dbSWire> swires = net_->getSWires();
2911   ;
2912   dbSet<dbSWire>::iterator sitr;
2913 
2914   for (sitr = swires.begin(); sitr != swires.end();)
2915     sitr = dbSWire::destroy(sitr);
2916 
2917   if (net->_wire != 0) {
2918     dbWire* wire = (dbWire*) block->_wire_tbl->getPtr(net->_wire);
2919     dbWire::destroy(wire);
2920   }
2921 
2922   for (dbId<_dbGroup> _group_id : net->_groups) {
2923     dbGroup* group = (dbGroup*) block->_group_tbl->getPtr(_group_id);
2924     group->removeNet(net_);
2925   }
2926 
2927   if (block->_journal) {
2928     debugPrint(block->getImpl()->getLogger(),
2929                utl::ODB,
2930                "DB_ECO",
2931                1,
2932                "ECO: destroy net, id: {}",
2933                net->getId());
2934     block->_journal->beginAction(dbJournal::DELETE_OBJECT);
2935     block->_journal->pushParam(dbNetObj);
2936     block->_journal->pushParam(net->getId());
2937     block->_journal->endAction();
2938   }
2939 
2940   // Bugzilla #7: The notification of the the net destruction must
2941   // be done after pin manipulation is completed. The notification is
2942   // now after the pin disconnection - payam 01/10/2006
2943   std::list<dbBlockCallBackObj*>::iterator cbitr;
2944   for (cbitr = block->_callbacks.begin(); cbitr != block->_callbacks.end();
2945        ++cbitr)
2946     (**cbitr)().inDbNetDestroy(net_);  // client ECO optimization - payam
2947 
2948   dbProperty::destroyProperties(net);
2949   block->_net_hash.remove(net);
2950   block->_net_tbl->destroy(net);
2951 }
2952 
destroy(dbSet<dbNet>::iterator & itr)2953 dbSet<dbNet>::iterator dbNet::destroy(dbSet<dbNet>::iterator& itr)
2954 {
2955   dbNet* bt = *itr;
2956   dbSet<dbNet>::iterator next = ++itr;
2957   destroy(bt);
2958   return next;
2959 }
2960 
getNet(dbBlock * block_,uint dbid_)2961 dbNet* dbNet::getNet(dbBlock* block_, uint dbid_)
2962 {
2963   _dbBlock* block = (_dbBlock*) block_;
2964   return (dbNet*) block->_net_tbl->getPtr(dbid_);
2965 }
2966 
getValidNet(dbBlock * block_,uint dbid_)2967 dbNet* dbNet::getValidNet(dbBlock* block_, uint dbid_)
2968 {
2969   _dbBlock* block = (_dbBlock*) block_;
2970   if (!block->_net_tbl->validId(dbid_))
2971     return NULL;
2972   return (dbNet*) block->_net_tbl->getPtr(dbid_);
2973 }
2974 
markNets(std::vector<dbNet * > & nets,dbBlock * block,bool mk)2975 void dbNet::markNets(std::vector<dbNet*>& nets, dbBlock* block, bool mk)
2976 {
2977   uint j;
2978   dbNet* net;
2979   if (nets.size() == 0) {
2980     dbSet<dbNet> bnets = block->getNets();
2981     dbSet<dbNet>::iterator nitr;
2982     for (nitr = bnets.begin(); nitr != bnets.end(); ++nitr) {
2983       net = (dbNet*) *nitr;
2984       net->setMark(mk);
2985     }
2986   } else {
2987     for (j = 0; j < nets.size(); j++) {
2988       net = nets[j];
2989       net->setMark(mk);
2990     }
2991   }
2992 }
setLevelAtFanout(uint level,bool fromPI,std::vector<dbInst * > & instVector)2993 uint dbNet::setLevelAtFanout(uint level,
2994                              bool fromPI,
2995                              std::vector<dbInst*>& instVector)
2996 {
2997   uint cnt = 0;
2998   dbSet<dbITerm> iterms = getITerms();
2999   dbSet<dbITerm>::iterator iitr;
3000   for (iitr = iterms.begin(); iitr != iterms.end(); ++iitr) {
3001     dbITerm* iterm = *iitr;
3002     if (!((iterm->getIoType() == dbIoType::INPUT)
3003           || (iterm->getIoType() == dbIoType::INOUT)))
3004       continue;
3005 
3006     dbInst* inst = iterm->getInst();
3007     // if (strcmp("INV_26", inst->getConstName())==0)
3008     //	notice(0, "inst %d %s\n", inst->getId(), inst->getConstName());
3009 
3010     if (inst->getMaster()->isSequential())
3011       continue;
3012     if (inst->getLevel() != 0)
3013       continue;
3014     if (inst->getMaster()->getType() != dbMasterType::CORE)
3015       continue;
3016     inst->setLevel(level, fromPI);
3017     instVector.push_back(inst);
3018     cnt++;
3019   }
3020   return cnt;
3021 }
3022 
3023 #if 0
3024 //
3025 // Helper fn: given a net create two terms at endpoints (x1,y1) and (x2,y2)
3026 // Return true iff successful.
3027 //
3028 std::pair<dbBTerm *,dbBTerm *>
3029 dbNet::createTerms4SingleNet(int x1, int y1, int x2, int y2, dbTechLayer *inly)
3030 {
3031   int fwidth = MIN(x2 - x1, y2 - y1);
3032   uint hwidth = fwidth/2;
3033 
3034   std::pair<dbBTerm *,dbBTerm *> retpr;
3035   retpr.first  = NULL;
3036   retpr.second = NULL;
3037 
3038   std::string term_str(this->getName());
3039   term_str = term_str + "_BL";
3040   dbBTerm *blterm = dbBTerm::create(this, term_str.c_str());
3041 
3042   if (!blterm)
3043     return retpr;
3044 
3045   term_str = this->getName();
3046   term_str = term_str + "_BU";
3047   dbBTerm *buterm = dbBTerm::create(this, term_str.c_str());
3048 
3049   if (!buterm)
3050   {
3051       dbBTerm::destroy(blterm);
3052       return retpr;
3053   }
3054 
3055   // TWG: Added bpins
3056   dbBPin * blpin = dbBPin::create(blterm);
3057   dbBPin * bupin = dbBPin::create(buterm);
3058 
3059   if ((x2 - x1) == fwidth)
3060   {
3061       int x = x1+hwidth;
3062 	  /*
3063 	  if ((y2-y1)==fwidth) {
3064 		  dbBox::create(blpin, inly, -hwidth+x, y1, hwidth+x, hwidth+y1);
3065 		  dbBox::create(bupin, inly, -hwidth+x, y2, hwidth+x, hwidth+y2);
3066 	  }
3067 	  else {
3068 		  dbBox::create(blpin, inly, -hwidth+x, -hwidth+y1, hwidth+x, hwidth+y1);
3069 		  dbBox::create(bupin, inly, -hwidth+x, -hwidth+y2, hwidth+x, hwidth+y2);
3070 	  }
3071 	  */
3072       dbBox::create(blpin, inly, -hwidth+x, -hwidth+y1, hwidth+x, hwidth+y1);
3073       dbBox::create(bupin, inly, -hwidth+x, -hwidth+y2, hwidth+x, hwidth+y2);
3074   }
3075   else
3076   {
3077       int y = y1+hwidth;
3078       dbBox::create(blpin, inly, -hwidth+x1, -hwidth+y, hwidth+x1, hwidth+y);
3079       dbBox::create(bupin, inly, -hwidth+x2, -hwidth+y, hwidth+x2, hwidth+y);
3080   }
3081 
3082   blterm->setSigType(dbSigType::SIGNAL);
3083   buterm->setSigType(dbSigType::SIGNAL);
3084   blterm->setIoType(dbIoType::INPUT);
3085   buterm->setIoType(dbIoType::OUTPUT);
3086   blpin->setPlacementStatus(dbPlacementStatus::PLACED);
3087   bupin->setPlacementStatus(dbPlacementStatus::PLACED);
3088 
3089   retpr.first = blterm;
3090   retpr.second = buterm;
3091   return retpr;
3092 }
3093 
3094 #endif
3095 }  // namespace odb
3096