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 "dbBlock.h"
34 
35 #include <errno.h>
36 #include <unistd.h>
37 
38 #include <memory>
39 #include <string>
40 
41 #include "ZComponents.h"
42 #include "db.h"
43 #include "dbArrayTable.h"
44 #include "dbArrayTable.hpp"
45 #include "dbBPin.h"
46 #include "dbBPinItr.h"
47 #include "dbBTerm.h"
48 #include "dbBTermItr.h"
49 #include "dbBlockCallBackObj.h"
50 #include "dbBlockItr.h"
51 #include "dbBlockage.h"
52 #include "dbBox.h"
53 #include "dbBoxItr.h"
54 #include "dbCCSeg.h"
55 #include "dbCCSegItr.h"
56 #include "dbCapNode.h"
57 #include "dbCapNodeItr.h"
58 #include "dbChip.h"
59 #include "dbDatabase.h"
60 #include "dbDiff.h"
61 #include "dbDiff.hpp"
62 #include "dbExtControl.h"
63 #include "dbFill.h"
64 #include "dbGCellGrid.h"
65 #include "dbGroup.h"
66 #include "dbGroupGroundNetItr.h"
67 #include "dbGroupInstItr.h"
68 #include "dbGroupItr.h"
69 #include "dbGroupModInstItr.h"
70 #include "dbGroupPowerNetItr.h"
71 #include "dbHashTable.hpp"
72 #include "dbHier.h"
73 #include "dbITerm.h"
74 #include "dbITermItr.h"
75 #include "dbInst.h"
76 #include "dbInstHdr.h"
77 #include "dbIntHashTable.hpp"
78 #include "dbJournal.h"
79 #include "dbModInst.h"
80 #include "dbModule.h"
81 #include "dbModuleInstItr.h"
82 #include "dbModuleModInstItr.h"
83 #include "dbNameCache.h"
84 #include "dbNet.h"
85 #include "dbObstruction.h"
86 #include "dbProperty.h"
87 #include "dbPropertyItr.h"
88 #include "dbRSeg.h"
89 #include "dbRSegItr.h"
90 #include "dbRegion.h"
91 #include "dbRegionInstItr.h"
92 #include "dbRegionItr.h"
93 #include "dbRow.h"
94 #include "dbSBox.h"
95 #include "dbSBoxItr.h"
96 #include "dbSWire.h"
97 #include "dbSWireItr.h"
98 #include "dbSearch.h"
99 #include "dbShape.h"
100 #include "dbTable.h"
101 #include "dbTable.hpp"
102 #include "dbTech.h"
103 #include "dbTechLayerRule.h"
104 #include "dbTechNonDefaultRule.h"
105 #include "dbTrackGrid.h"
106 #include "dbVia.h"
107 #include "dbWire.h"
108 #include "defout.h"
109 #include "lefout.h"
110 #include "parse.h"
111 #include "utl/Logger.h"
112 
113 namespace odb {
114 
115 struct OldTransform
116 {
117   int _orient;
118   int _originX;
119   int _originY;
120   int _sizeX;
121   int _sizeY;
122 };
123 
operator >>(dbIStream & stream,OldTransform & t)124 dbIStream& operator>>(dbIStream& stream, OldTransform& t)
125 {
126   stream >> t._orient;
127   stream >> t._originX;
128   stream >> t._originY;
129   stream >> t._sizeX;
130   stream >> t._sizeY;
131   return stream;
132 }
133 
134 static void unlink_child_from_parent(_dbBlock* child, _dbBlock* parent);
135 
136 // TODO: Bounding box updates...
137 template class dbTable<_dbBlock>;
138 
139 template class dbHashTable<_dbNet>;
140 template class dbHashTable<_dbInst>;
141 template class dbIntHashTable<_dbInstHdr>;
142 template class dbHashTable<_dbBTerm>;
143 
_dbBlock(_dbDatabase * db)144 _dbBlock::_dbBlock(_dbDatabase* db)
145 {
146   _flags._valid_bbox = 0;
147   _flags._buffer_altered = 1;
148   _flags._active_pins = 0;
149   _flags._skip_hier_stream = 0;
150   _flags._mme = 0;
151   _flags._spare_bits_27 = 0;
152   _def_units = 100;
153   _dbu_per_micron = 1000;
154   _hier_delimeter = 0;
155   _left_bus_delimeter = 0;
156   _right_bus_delimeter = 0;
157   _num_ext_corners = 0;
158   _corners_per_block = 0;
159   _corner_name_list = 0;
160   _name = 0;
161   _maxCapNodeId = 0;
162   _maxRSegId = 0;
163   _maxCCSegId = 0;
164   _minExtModelIndex = -1;
165   _maxExtModelIndex = -1;
166 
167   _bterm_tbl = new dbTable<_dbBTerm>(
168       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbBTermObj);
169   ZALLOCATED(_bterm_tbl);
170 
171   _iterm_tbl = new dbTable<_dbITerm>(
172       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbITermObj, 1024, 10);
173   ZALLOCATED(_iterm_tbl);
174 
175   _net_tbl = new dbTable<_dbNet>(
176       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbNetObj);
177   ZALLOCATED(_net_tbl);
178 
179   _inst_hdr_tbl = new dbTable<_dbInstHdr>(
180       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbInstHdrObj);
181   ZALLOCATED(_inst_hdr_tbl);
182 
183   _inst_tbl = new dbTable<_dbInst>(
184       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbInstObj);
185   ZALLOCATED(_inst_tbl);
186 
187   _module_tbl = new dbTable<_dbModule>(
188       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbModuleObj);
189   ZALLOCATED(_module_tbl);
190 
191   _modinst_tbl = new dbTable<_dbModInst>(
192       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbModInstObj);
193   ZALLOCATED(_modinst_tbl);
194 
195   _group_tbl = new dbTable<_dbGroup>(
196       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbGroupObj);
197   ZALLOCATED(_group_tbl);
198 
199   _box_tbl = new dbTable<_dbBox>(
200       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbBoxObj, 1024, 10);
201   ZALLOCATED(_box_tbl);
202 
203   _via_tbl = new dbTable<_dbVia>(
204       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbViaObj, 1024, 10);
205   ZALLOCATED(_via_tbl);
206 
207   _gcell_grid_tbl = new dbTable<_dbGCellGrid>(
208       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbGCellGridObj);
209   ZALLOCATED(_gcell_grid_tbl);
210 
211   _track_grid_tbl = new dbTable<_dbTrackGrid>(
212       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbTrackGridObj);
213   ZALLOCATED(_track_grid_tbl);
214 
215   _obstruction_tbl = new dbTable<_dbObstruction>(
216       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbObstructionObj);
217   ZALLOCATED(_obstruction_tbl);
218 
219   _blockage_tbl = new dbTable<_dbBlockage>(
220       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbBlockageObj);
221   ZALLOCATED(_blockage_tbl);
222 
223   _wire_tbl = new dbTable<_dbWire>(
224       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbWireObj);
225   ZALLOCATED(_wire_tbl);
226 
227   _swire_tbl = new dbTable<_dbSWire>(
228       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbSWireObj);
229   ZALLOCATED(_swire_tbl);
230 
231   _sbox_tbl = new dbTable<_dbSBox>(
232       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbSBoxObj);
233   ZALLOCATED(_sbox_tbl);
234 
235   _row_tbl = new dbTable<_dbRow>(
236       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbRowObj);
237   ZALLOCATED(_row_tbl);
238 
239   _fill_tbl = new dbTable<_dbFill>(
240       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbFillObj);
241   ZALLOCATED(_fill_tbl);
242 
243   _region_tbl = new dbTable<_dbRegion>(
244       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbRegionObj, 32, 5);
245   ZALLOCATED(_region_tbl);
246 
247   _hier_tbl = new dbTable<_dbHier>(
248       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbHierObj, 16, 4);
249   ZALLOCATED(_hier_tbl);
250 
251   _bpin_tbl = new dbTable<_dbBPin>(
252       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbBPinObj);
253   ZALLOCATED(_bpin_tbl);
254 
255   _non_default_rule_tbl = new dbTable<_dbTechNonDefaultRule>(
256       db,
257       this,
258       (GetObjTbl_t) &_dbBlock::getObjectTable,
259       dbTechNonDefaultRuleObj,
260       16,
261       4);
262   ZALLOCATED(_non_default_rule_tbl);
263 
264   _layer_rule_tbl
265       = new dbTable<_dbTechLayerRule>(db,
266                                       this,
267                                       (GetObjTbl_t) &_dbBlock::getObjectTable,
268                                       dbTechLayerRuleObj,
269                                       16,
270                                       4);
271   ZALLOCATED(_layer_rule_tbl);
272 
273   _prop_tbl = new dbTable<_dbProperty>(
274       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbPropertyObj);
275   ZALLOCATED(_prop_tbl);
276 
277   _name_cache
278       = new _dbNameCache(db, this, (GetObjTbl_t) &_dbBlock::getObjectTable);
279   ZALLOCATED(_name_cache);
280 
281   _r_val_tbl = new dbPagedVector<float, 4096, 12>();
282   ZALLOCATED(_r_val_tbl);
283   _r_val_tbl->push_back(0.0);
284 
285   _c_val_tbl = new dbPagedVector<float, 4096, 12>();
286   ZALLOCATED(_c_val_tbl);
287   _c_val_tbl->push_back(0.0);
288 
289   _cc_val_tbl = new dbPagedVector<float, 4096, 12>();
290   ZALLOCATED(_cc_val_tbl);
291   _cc_val_tbl->push_back(0.0);
292 
293   _cap_node_tbl
294       = new dbTable<_dbCapNode>(db,
295                                 this,
296                                 (GetObjTbl_t) &_dbBlock::getObjectTable,
297                                 dbCapNodeObj,
298                                 4096,
299                                 12);
300   ZALLOCATED(_cap_node_tbl);
301 
302   // We need to allocate the first cap-node (id == 1) to resolve a problem with
303   // the extraction code (Hopefully this is temporary)
304   _cap_node_tbl->create();
305 
306   _r_seg_tbl = new dbTable<_dbRSeg>(
307       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbRSegObj, 4096, 12);
308   ZALLOCATED(_r_seg_tbl);
309 
310   _cc_seg_tbl = new dbTable<_dbCCSeg>(
311       db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbCCSegObj, 4096, 12);
312   ZALLOCATED(_cc_seg_tbl);
313 
314   _extControl = new dbExtControl();
315   ZALLOCATED(_extControl);
316 
317   _net_hash.setTable(_net_tbl);
318   _inst_hash.setTable(_inst_tbl);
319   _module_hash.setTable(_module_tbl);
320   _modinst_hash.setTable(_modinst_tbl);
321   _group_hash.setTable(_group_tbl);
322   _inst_hdr_hash.setTable(_inst_hdr_tbl);
323   _bterm_hash.setTable(_bterm_tbl);
324 
325   _net_bterm_itr = new dbNetBTermItr(_bterm_tbl);
326   ZALLOCATED(_net_bterm_itr);
327 
328   _net_iterm_itr = new dbNetITermItr(_iterm_tbl);
329   ZALLOCATED(_net_iterm_itr);
330 
331   _inst_iterm_itr = new dbInstITermItr(_iterm_tbl);
332   ZALLOCATED(_inst_iterm_itr);
333 
334   _box_itr = new dbBoxItr(_box_tbl);
335   ZALLOCATED(_box_itr);
336 
337   _swire_itr = new dbSWireItr(_swire_tbl);
338   ZALLOCATED(_swire_itr);
339 
340   _sbox_itr = new dbSBoxItr(_sbox_tbl);
341   ZALLOCATED(_sbox_itr);
342 
343   _cap_node_itr = new dbCapNodeItr(_cap_node_tbl);
344   ZALLOCATED(_cap_node_itr);
345 
346   _r_seg_itr = new dbRSegItr(_r_seg_tbl);
347   ZALLOCATED(_r_seg_itr);
348 
349   _cc_seg_itr = new dbCCSegItr(_cc_seg_tbl);
350   ZALLOCATED(_cc_seg_itr);
351 
352   _region_inst_itr = new dbRegionInstItr(_inst_tbl);
353   ZALLOCATED(_region_inst_itr);
354 
355   _module_inst_itr = new dbModuleInstItr(_inst_tbl);
356   ZALLOCATED(_module_inst_itr);
357 
358   _module_modinst_itr = new dbModuleModInstItr(_modinst_tbl);
359   ZALLOCATED(_module_modinst_itr);
360 
361   _group_itr = new dbGroupItr(_group_tbl);
362   ZALLOCATED(_group_itr);
363 
364   _group_inst_itr = new dbGroupInstItr(_inst_tbl);
365   ZALLOCATED(_group_inst_itr);
366 
367   _group_modinst_itr = new dbGroupModInstItr(_modinst_tbl);
368   ZALLOCATED(_group_modinst_itr);
369 
370   _group_power_net_itr = new dbGroupPowerNetItr(_net_tbl);
371   ZALLOCATED(_group_power_net_itr);
372 
373   _group_ground_net_itr = new dbGroupGroundNetItr(_net_tbl);
374   ZALLOCATED(_group_ground_net_itr);
375 
376   _bpin_itr = new dbBPinItr(_bpin_tbl);
377   ZALLOCATED(_bpin_itr);
378 
379   _region_itr = new dbRegionItr(_region_tbl);
380   ZALLOCATED(_region_itr);
381 
382   _prop_itr = new dbPropertyItr(_prop_tbl);
383   ZALLOCATED(_prop_itr);
384 
385   _num_ext_dbs = 1;
386   _searchDb = NULL;
387   _extmi = NULL;
388   _ptFile = NULL;
389   _journal = NULL;
390   _journal_pending = NULL;
391 
392   _bterm_pins = nullptr;
393 }
394 
_dbBlock(_dbDatabase * db,const _dbBlock & block)395 _dbBlock::_dbBlock(_dbDatabase* db, const _dbBlock& block)
396     : _flags(block._flags),
397       _def_units(block._def_units),
398       _dbu_per_micron(block._dbu_per_micron),
399       _hier_delimeter(block._hier_delimeter),
400       _left_bus_delimeter(block._left_bus_delimeter),
401       _right_bus_delimeter(block._right_bus_delimeter),
402       _num_ext_corners(block._num_ext_corners),
403       _corners_per_block(block._corners_per_block),
404       _corner_name_list(block._corner_name_list),
405       _name(NULL),
406       _die_area(block._die_area),
407       _chip(block._chip),
408       _bbox(block._bbox),
409       _parent(block._parent),
410       _next_block(block._next_block),
411       _gcell_grid(block._gcell_grid),
412       _parent_block(block._parent_block),
413       _parent_inst(block._parent_inst),
414       _top_module(block._top_module),
415       _net_hash(block._net_hash),
416       _inst_hash(block._inst_hash),
417       _module_hash(block._module_hash),
418       _modinst_hash(block._modinst_hash),
419       _group_hash(block._group_hash),
420       _inst_hdr_hash(block._inst_hdr_hash),
421       _bterm_hash(block._bterm_hash),
422       _maxCapNodeId(block._maxCapNodeId),
423       _maxRSegId(block._maxRSegId),
424       _maxCCSegId(block._maxCCSegId),
425       _minExtModelIndex(block._minExtModelIndex),
426       _maxExtModelIndex(block._maxExtModelIndex),
427       _children(block._children),
428       _currentCcAdjOrder(block._currentCcAdjOrder)
429 {
430   if (block._name) {
431     _name = strdup(block._name);
432     ZALLOCATED(_name);
433   }
434 
435   _bterm_tbl = new dbTable<_dbBTerm>(db, this, *block._bterm_tbl);
436   ZALLOCATED(_bterm_tbl);
437 
438   _iterm_tbl = new dbTable<_dbITerm>(db, this, *block._iterm_tbl);
439   ZALLOCATED(_iterm_tbl);
440 
441   _net_tbl = new dbTable<_dbNet>(db, this, *block._net_tbl);
442   ZALLOCATED(_net_tbl);
443 
444   _inst_hdr_tbl = new dbTable<_dbInstHdr>(db, this, *block._inst_hdr_tbl);
445   ZALLOCATED(_inst_hdr_tbl);
446 
447   _inst_tbl = new dbTable<_dbInst>(db, this, *block._inst_tbl);
448   ZALLOCATED(_inst_tbl);
449 
450   _module_tbl = new dbTable<_dbModule>(db, this, *block._module_tbl);
451   ZALLOCATED(_module_tbl);
452 
453   _modinst_tbl = new dbTable<_dbModInst>(db, this, *block._modinst_tbl);
454   ZALLOCATED(_modinst_tbl);
455 
456   _group_tbl = new dbTable<_dbGroup>(db, this, *block._group_tbl);
457   ZALLOCATED(_group_tbl);
458 
459   _box_tbl = new dbTable<_dbBox>(db, this, *block._box_tbl);
460   ZALLOCATED(_box_tbl);
461 
462   _via_tbl = new dbTable<_dbVia>(db, this, *block._via_tbl);
463   ZALLOCATED(_via_tbl);
464 
465   _gcell_grid_tbl = new dbTable<_dbGCellGrid>(db, this, *block._gcell_grid_tbl);
466   ZALLOCATED(_gcell_grid_tbl);
467 
468   _track_grid_tbl = new dbTable<_dbTrackGrid>(db, this, *block._track_grid_tbl);
469   ZALLOCATED(_track_grid_tbl);
470 
471   _obstruction_tbl
472       = new dbTable<_dbObstruction>(db, this, *block._obstruction_tbl);
473   ZALLOCATED(_obstruction_tbl);
474 
475   _blockage_tbl = new dbTable<_dbBlockage>(db, this, *block._blockage_tbl);
476   ZALLOCATED(_blockage_tbl);
477 
478   _wire_tbl = new dbTable<_dbWire>(db, this, *block._wire_tbl);
479   ZALLOCATED(_wire_tbl);
480 
481   _swire_tbl = new dbTable<_dbSWire>(db, this, *block._swire_tbl);
482   ZALLOCATED(_swire_tbl);
483 
484   _sbox_tbl = new dbTable<_dbSBox>(db, this, *block._sbox_tbl);
485   ZALLOCATED(_sbox_tbl);
486 
487   _row_tbl = new dbTable<_dbRow>(db, this, *block._row_tbl);
488   ZALLOCATED(_row_tbl);
489 
490   _fill_tbl = new dbTable<_dbFill>(db, this, *block._fill_tbl);
491   ZALLOCATED(_fill_tbl);
492 
493   _region_tbl = new dbTable<_dbRegion>(db, this, *block._region_tbl);
494   ZALLOCATED(_region_tbl);
495 
496   _hier_tbl = new dbTable<_dbHier>(db, this, *block._hier_tbl);
497   ZALLOCATED(_hier_tbl);
498 
499   _bpin_tbl = new dbTable<_dbBPin>(db, this, *block._bpin_tbl);
500   ZALLOCATED(_bpin_tbl);
501 
502   _non_default_rule_tbl = new dbTable<_dbTechNonDefaultRule>(
503       db, this, *block._non_default_rule_tbl);
504   ZALLOCATED(_non_default_rule_tbl);
505 
506   _layer_rule_tbl
507       = new dbTable<_dbTechLayerRule>(db, this, *block._layer_rule_tbl);
508   ZALLOCATED(_layer_rule_tbl);
509 
510   _prop_tbl = new dbTable<_dbProperty>(db, this, *block._prop_tbl);
511   ZALLOCATED(_prop_tbl);
512 
513   _name_cache = new _dbNameCache(db, this, *block._name_cache);
514   ZALLOCATED(_name_cache);
515 
516   _r_val_tbl = new dbPagedVector<float, 4096, 12>(*block._r_val_tbl);
517   ZALLOCATED(_r_val_tbl);
518 
519   _c_val_tbl = new dbPagedVector<float, 4096, 12>(*block._c_val_tbl);
520   ZALLOCATED(_c_val_tbl);
521 
522   _cc_val_tbl = new dbPagedVector<float, 4096, 12>(*block._cc_val_tbl);
523   ZALLOCATED(_cc_val_tbl);
524 
525   _cap_node_tbl = new dbTable<_dbCapNode>(db, this, *block._cap_node_tbl);
526   ZALLOCATED(_cap_node_tbl);
527 
528   _r_seg_tbl = new dbTable<_dbRSeg>(db, this, *block._r_seg_tbl);
529   ZALLOCATED(_r_seg_tbl);
530 
531   _cc_seg_tbl = new dbTable<_dbCCSeg>(db, this, *block._cc_seg_tbl);
532   ZALLOCATED(_cc_seg_tbl);
533 
534   _extControl = new dbExtControl();
535   ZALLOCATED(_extControl);
536 
537   _net_hash.setTable(_net_tbl);
538   _inst_hash.setTable(_inst_tbl);
539   _module_hash.setTable(_module_tbl);
540   _modinst_hash.setTable(_modinst_tbl);
541   _group_hash.setTable(_group_tbl);
542   _inst_hdr_hash.setTable(_inst_hdr_tbl);
543   _bterm_hash.setTable(_bterm_tbl);
544 
545   _net_bterm_itr = new dbNetBTermItr(_bterm_tbl);
546   ZALLOCATED(_net_bterm_itr);
547 
548   _net_iterm_itr = new dbNetITermItr(_iterm_tbl);
549   ZALLOCATED(_net_iterm_itr);
550 
551   _inst_iterm_itr = new dbInstITermItr(_iterm_tbl);
552   ZALLOCATED(_inst_iterm_itr);
553 
554   _box_itr = new dbBoxItr(_box_tbl);
555   ZALLOCATED(_box_itr);
556 
557   _swire_itr = new dbSWireItr(_swire_tbl);
558   ZALLOCATED(_swire_itr);
559 
560   _sbox_itr = new dbSBoxItr(_sbox_tbl);
561   ZALLOCATED(_sbox_itr);
562 
563   _cap_node_itr = new dbCapNodeItr(_cap_node_tbl);
564   ZALLOCATED(_cap_node_itr);
565 
566   _r_seg_itr = new dbRSegItr(_r_seg_tbl);
567   ZALLOCATED(_r_seg_itr);
568 
569   _cc_seg_itr = new dbCCSegItr(_cc_seg_tbl);
570   ZALLOCATED(_cc_seg_itr);
571 
572   _region_inst_itr = new dbRegionInstItr(_inst_tbl);
573   ZALLOCATED(_region_inst_itr);
574 
575   _module_inst_itr = new dbModuleInstItr(_inst_tbl);
576   ZALLOCATED(_module_inst_itr);
577 
578   _module_modinst_itr = new dbModuleModInstItr(_modinst_tbl);
579   ZALLOCATED(_module_modinst_itr);
580 
581   _group_itr = new dbGroupItr(_group_tbl);
582   ZALLOCATED(_group_itr);
583 
584   _group_inst_itr = new dbGroupInstItr(_inst_tbl);
585   ZALLOCATED(_group_inst_itr);
586 
587   _group_modinst_itr = new dbGroupModInstItr(_modinst_tbl);
588   ZALLOCATED(_group_modinst_itr);
589 
590   _group_power_net_itr = new dbGroupPowerNetItr(_net_tbl);
591   ZALLOCATED(_group_power_net_itr);
592 
593   _group_ground_net_itr = new dbGroupGroundNetItr(_net_tbl);
594   ZALLOCATED(_group_ground_net_itr);
595 
596   _bpin_itr = new dbBPinItr(_bpin_tbl);
597   ZALLOCATED(_bpin_itr);
598 
599   _region_itr = new dbRegionItr(_region_tbl);
600   ZALLOCATED(_region_itr);
601 
602   _prop_itr = new dbPropertyItr(_prop_tbl);
603   ZALLOCATED(_prop_itr);
604 
605   // ??? Initialize search-db on copy?
606   _searchDb = NULL;
607 
608   // ??? callbacks
609   // _callbacks = ???
610 
611   // ??? _ext?
612   _extmi = block._extmi;
613   _journal = NULL;
614   _journal_pending = NULL;
615 }
616 
~_dbBlock()617 _dbBlock::~_dbBlock()
618 {
619   if (_name)
620     free((void*) _name);
621 
622   delete _bterm_tbl;
623   delete _iterm_tbl;
624   delete _net_tbl;
625   delete _inst_hdr_tbl;
626   delete _inst_tbl;
627   delete _module_tbl;
628   delete _modinst_tbl;
629   delete _group_tbl;
630   delete _box_tbl;
631   delete _via_tbl;
632   delete _gcell_grid_tbl;
633   delete _track_grid_tbl;
634   delete _obstruction_tbl;
635   delete _blockage_tbl;
636   delete _wire_tbl;
637   delete _swire_tbl;
638   delete _sbox_tbl;
639   delete _row_tbl;
640   delete _fill_tbl;
641   delete _region_tbl;
642   delete _hier_tbl;
643   delete _bpin_tbl;
644   delete _non_default_rule_tbl;
645   delete _layer_rule_tbl;
646   delete _prop_tbl;
647   delete _name_cache;
648   delete _r_val_tbl;
649   delete _c_val_tbl;
650   delete _cc_val_tbl;
651   delete _cap_node_tbl;
652   delete _r_seg_tbl;
653   delete _cc_seg_tbl;
654   delete _extControl;
655   delete _net_bterm_itr;
656   delete _net_iterm_itr;
657   delete _inst_iterm_itr;
658   delete _box_itr;
659   delete _swire_itr;
660   delete _sbox_itr;
661   delete _cap_node_itr;
662   delete _r_seg_itr;
663   delete _cc_seg_itr;
664   delete _region_inst_itr;
665   delete _module_inst_itr;
666   delete _module_modinst_itr;
667   delete _group_itr;
668   delete _group_inst_itr;
669   delete _group_modinst_itr;
670   delete _group_power_net_itr;
671   delete _group_ground_net_itr;
672   delete _bpin_itr;
673   delete _region_itr;
674   delete _prop_itr;
675 
676   std::list<dbBlockCallBackObj*>::iterator _cbitr;
677   while (_callbacks.begin() != _callbacks.end()) {
678     _cbitr = _callbacks.begin();
679     (*_cbitr)->removeOwner();
680   }
681 #ifdef ZUI
682   if (_searchDb)
683     delete _searchDb;
684 #endif
685   if (_journal)
686     delete _journal;
687 
688   if (_journal_pending)
689     delete _journal_pending;
690 }
691 
clear()692 void dbBlock::clear()
693 {
694   _dbBlock* block = (_dbBlock*) this;
695   _dbDatabase* db = block->getDatabase();
696   _dbBlock* parent = (_dbBlock*) getParent();
697   _dbChip* chip = (_dbChip*) getChip();
698 
699   // save a copy of the name
700   char* name = strdup(block->_name);
701   ZALLOCATED(name);
702 
703   // save a copy of the delimeter
704   char delimeter = block->_hier_delimeter;
705 
706   std::list<dbBlockCallBackObj*> callbacks;
707 
708   // save callbacks
709   callbacks.swap(block->_callbacks);
710 
711   // unlink the child from the parent
712   if (parent)
713     unlink_child_from_parent(block, parent);
714 
715   // destroy the block contents
716   block->~_dbBlock();
717 
718   // call in-place new to create new block
719   new (block) _dbBlock(db);
720 
721   // nitialize the
722   block->initialize(chip, parent, name, delimeter);
723 
724   // restore callbacks
725   block->_callbacks.swap(callbacks);
726 
727   free((void*) name);
728 
729   if (block->_journal) {
730     delete block->_journal;
731     block->_journal = NULL;
732   }
733 
734   if (block->_journal_pending) {
735     delete block->_journal_pending;
736     block->_journal_pending = NULL;
737   }
738 }
739 
initialize(_dbChip * chip,_dbBlock * parent,const char * name,char delimeter)740 void _dbBlock::initialize(_dbChip* chip,
741                           _dbBlock* parent,
742                           const char* name,
743                           char delimeter)
744 {
745   _name = strdup(name);
746   ZALLOCATED(name);
747 
748   _dbBox* box = _box_tbl->create();
749   box->_flags._owner_type = dbBoxOwner::BLOCK;
750   box->_owner = getOID();
751   box->_shape._rect.reset(INT_MAX, INT_MAX, INT_MIN, INT_MIN);
752   _bbox = box->getOID();
753   _chip = chip->getOID();
754   _hier_delimeter = delimeter;
755   // create top module
756   _dbModule* _top = (_dbModule*) dbModule::create(
757       (dbBlock*) this, (std::string(name) + "_top_module").c_str());
758   _top_module = _top->getOID();
759   if (parent) {
760     _def_units = parent->_def_units;
761     _dbu_per_micron = parent->_dbu_per_micron;
762     _parent = parent->getOID();
763     parent->_children.push_back(getOID());
764     _num_ext_corners = parent->_num_ext_corners;
765     _corners_per_block = parent->_corners_per_block;
766   }
767 }
768 
getObjectTable(dbObjectType type)769 dbObjectTable* _dbBlock::getObjectTable(dbObjectType type)
770 {
771   switch (type) {
772     case dbInstHdrObj:
773       return _inst_hdr_tbl;
774 
775     case dbInstObj:
776       return _inst_tbl;
777 
778     case dbModuleObj:
779       return _module_tbl;
780 
781     case dbModInstObj:
782       return _modinst_tbl;
783 
784     case dbGroupObj:
785       return _group_tbl;
786 
787     case dbNetObj:
788       return _net_tbl;
789 
790     case dbBTermObj:
791       return _bterm_tbl;
792 
793     case dbITermObj:
794       return _iterm_tbl;
795 
796     case dbBoxObj:
797       return _box_tbl;
798 
799     case dbViaObj:
800       return _via_tbl;
801 
802     case dbGCellGridObj:
803       return _gcell_grid_tbl;
804 
805     case dbTrackGridObj:
806       return _track_grid_tbl;
807 
808     case dbObstructionObj:
809       return _obstruction_tbl;
810 
811     case dbBlockageObj:
812       return _blockage_tbl;
813 
814     case dbWireObj:
815       return _wire_tbl;
816 
817     case dbSWireObj:
818       return _swire_tbl;
819 
820     case dbSBoxObj:
821       return _sbox_tbl;
822 
823     case dbCapNodeObj:
824       return _cap_node_tbl;
825 
826     case dbRSegObj:
827       return _r_seg_tbl;
828 
829     case dbCCSegObj:
830       return _cc_seg_tbl;
831 
832     case dbRowObj:
833       return _row_tbl;
834 
835     case dbFillObj:
836       return _fill_tbl;
837 
838     case dbRegionObj:
839       return _region_tbl;
840 
841     case dbHierObj:
842       return _hier_tbl;
843 
844     case dbBPinObj:
845       return _bpin_tbl;
846 
847     case dbTechNonDefaultRuleObj:
848       return _non_default_rule_tbl;
849 
850     case dbTechLayerRuleObj:
851       return _layer_rule_tbl;
852 
853     case dbPropertyObj:
854       return _prop_tbl;
855     default:
856       break;
857   }
858 
859   return getTable()->getObjectTable(type);
860 }
861 
operator <<(dbOStream & stream,const _dbBlock & block)862 dbOStream& operator<<(dbOStream& stream, const _dbBlock& block)
863 {
864   std::list<dbBlockCallBackObj*>::const_iterator cbitr;
865   for (cbitr = block._callbacks.begin(); cbitr != block._callbacks.end();
866        ++cbitr)
867     (**cbitr)().inDbBlockStreamOutBefore(
868         (dbBlock*) &block);  // client ECO initialization  - payam
869 
870   stream << block._def_units;
871   stream << block._dbu_per_micron;
872   stream << block._hier_delimeter;
873   stream << block._left_bus_delimeter;
874   stream << block._right_bus_delimeter;
875   stream << block._num_ext_corners;
876   stream << block._corners_per_block;
877   stream << block._corner_name_list;
878   stream << block._name;
879   stream << block._die_area;
880   stream << block._chip;
881   stream << block._bbox;
882   stream << block._parent;
883   stream << block._next_block;
884   stream << block._gcell_grid;
885   if (block._flags._skip_hier_stream) {
886     stream << 0;
887     stream << 0;
888   } else {
889     stream << block._parent_block;
890     stream << block._parent_inst;
891   }
892   stream << block._top_module;
893   stream << block._net_hash;
894   stream << block._inst_hash;
895   stream << block._module_hash;
896   stream << block._modinst_hash;
897   stream << block._group_hash;
898   stream << block._inst_hdr_hash;
899   stream << block._bterm_hash;
900   stream << block._maxCapNodeId;
901   stream << block._maxRSegId;
902   stream << block._maxCCSegId;
903   stream << block._minExtModelIndex;
904   stream << block._maxExtModelIndex;
905   if (block._flags._skip_hier_stream) {
906     block.getImpl()->getLogger()->info(
907         utl::ODB, 4, "Hierarchical block information is lost");
908     stream << 0;
909   } else
910     stream << block._children;
911 
912   stream << block._currentCcAdjOrder;
913   stream << *block._bterm_tbl;
914   stream << *block._iterm_tbl;
915   stream << *block._net_tbl;
916   stream << *block._inst_hdr_tbl;
917   stream << *block._inst_tbl;
918   stream << *block._module_tbl;
919   stream << *block._modinst_tbl;
920   stream << *block._group_tbl;
921   stream << *block._box_tbl;
922   stream << *block._via_tbl;
923   stream << *block._gcell_grid_tbl;
924   stream << *block._track_grid_tbl;
925   stream << *block._obstruction_tbl;
926   stream << *block._blockage_tbl;
927   stream << *block._wire_tbl;
928   stream << *block._swire_tbl;
929   stream << *block._sbox_tbl;
930   stream << *block._row_tbl;
931   stream << *block._fill_tbl;
932   stream << *block._region_tbl;
933   stream << *block._hier_tbl;
934   stream << *block._bpin_tbl;
935   stream << *block._non_default_rule_tbl;
936   stream << *block._layer_rule_tbl;
937   stream << *block._prop_tbl;
938   stream << *block._name_cache;
939   stream << *block._r_val_tbl;
940   stream << *block._c_val_tbl;
941   stream << *block._cc_val_tbl;
942   stream << *block._cap_node_tbl;  // DKF - 2/21/05
943   stream << *block._r_seg_tbl;     // DKF - 2/21/05
944   stream << *block._cc_seg_tbl;
945   stream << *block._extControl;
946 
947   //---------------------------------------------------------- stream out
948   // properties
949   // TOM
950   dbObjectTable* table = block.getTable();
951   dbId<_dbProperty> propList = table->getPropList(block.getOID());
952 
953   stream << propList;
954   // TOM
955   //----------------------------------------------------------
956 
957   for (cbitr = block._callbacks.begin(); cbitr != block._callbacks.end();
958        ++cbitr)
959     (*cbitr)->inDbBlockStreamOutAfter((dbBlock*) &block);
960   return stream;
961 }
962 
operator >>(dbIStream & stream,_dbBlock & block)963 dbIStream& operator>>(dbIStream& stream, _dbBlock& block)
964 {
965   stream >> block._def_units;
966   stream >> block._dbu_per_micron;
967   stream >> block._hier_delimeter;
968   stream >> block._left_bus_delimeter;
969   stream >> block._right_bus_delimeter;
970   stream >> block._num_ext_corners;
971   stream >> block._corners_per_block;
972   stream >> block._corner_name_list;
973   stream >> block._name;
974   stream >> block._die_area;
975   stream >> block._chip;
976   stream >> block._bbox;
977   stream >> block._parent;
978   stream >> block._next_block;
979   stream >> block._gcell_grid;
980   stream >> block._parent_block;
981   stream >> block._parent_inst;
982   stream >> block._top_module;
983   stream >> block._net_hash;
984   stream >> block._inst_hash;
985   stream >> block._module_hash;
986   stream >> block._modinst_hash;
987   stream >> block._group_hash;
988   stream >> block._inst_hdr_hash;
989   stream >> block._bterm_hash;
990   stream >> block._maxCapNodeId;
991   stream >> block._maxRSegId;
992   stream >> block._maxCCSegId;
993   stream >> block._minExtModelIndex;
994   stream >> block._maxExtModelIndex;
995   stream >> block._children;
996   stream >> block._currentCcAdjOrder;
997   stream >> *block._bterm_tbl;
998   stream >> *block._iterm_tbl;
999   stream >> *block._net_tbl;
1000   stream >> *block._inst_hdr_tbl;
1001   stream >> *block._inst_tbl;
1002   stream >> *block._module_tbl;
1003   stream >> *block._modinst_tbl;
1004   stream >> *block._group_tbl;
1005   stream >> *block._box_tbl;
1006   stream >> *block._via_tbl;
1007   stream >> *block._gcell_grid_tbl;
1008   stream >> *block._track_grid_tbl;
1009   stream >> *block._obstruction_tbl;
1010   stream >> *block._blockage_tbl;
1011   stream >> *block._wire_tbl;
1012   stream >> *block._swire_tbl;
1013   stream >> *block._sbox_tbl;
1014   stream >> *block._row_tbl;
1015   stream >> *block._fill_tbl;
1016   stream >> *block._region_tbl;
1017   stream >> *block._hier_tbl;
1018   stream >> *block._bpin_tbl;
1019   stream >> *block._non_default_rule_tbl;
1020   stream >> *block._layer_rule_tbl;
1021   stream >> *block._prop_tbl;
1022   stream >> *block._name_cache;
1023   stream >> *block._r_val_tbl;
1024   stream >> *block._c_val_tbl;
1025   stream >> *block._cc_val_tbl;
1026   stream >> *block._cap_node_tbl;  // DKF
1027   stream >> *block._r_seg_tbl;     // DKF
1028   stream >> *block._cc_seg_tbl;
1029   stream >> *block._extControl;
1030 
1031   //---------------------------------------------------------- stream in
1032   // properties
1033   // TOM
1034   dbObjectTable* table = block.getTable();
1035   dbId<_dbProperty> oldList = table->getPropList(block.getOID());
1036   dbId<_dbProperty> propList;
1037   stream >> propList;
1038 
1039   if (propList != 0)
1040     table->setPropList(block.getOID(), propList);
1041   else if (oldList != 0)
1042     table->setPropList(block.getOID(), 0);
1043   // TOM
1044   //-------------------------------------------------------------------------------
1045 
1046   return stream;
1047 }
1048 
add_rect(const Rect & rect)1049 void _dbBlock::add_rect(const Rect& rect)
1050 {
1051   _dbBox* box = _box_tbl->getPtr(_bbox);
1052 
1053   if (_flags._valid_bbox)
1054     box->_shape._rect.merge(rect);
1055 }
add_geom_shape(GeomShape * shape)1056 void _dbBlock::add_geom_shape(GeomShape* shape)
1057 {
1058   _dbBox* box = _box_tbl->getPtr(_bbox);
1059 
1060   if (_flags._valid_bbox)
1061     box->_shape._rect.merge(shape);
1062 }
1063 
remove_rect(const Rect & rect)1064 void _dbBlock::remove_rect(const Rect& rect)
1065 {
1066   _dbBox* box = _box_tbl->getPtr(_bbox);
1067 
1068   if (_flags._valid_bbox)
1069     _flags._valid_bbox = box->_shape._rect.inside(rect);
1070 }
1071 
operator ==(const _dbBlock & rhs) const1072 bool _dbBlock::operator==(const _dbBlock& rhs) const
1073 {
1074   if (_flags._valid_bbox != rhs._flags._valid_bbox)
1075     return false;
1076 
1077   if (_def_units != rhs._def_units)
1078     return false;
1079 
1080   if (_dbu_per_micron != rhs._dbu_per_micron)
1081     return false;
1082 
1083   if (_hier_delimeter != rhs._hier_delimeter)
1084     return false;
1085 
1086   if (_left_bus_delimeter != rhs._left_bus_delimeter)
1087     return false;
1088 
1089   if (_right_bus_delimeter != rhs._right_bus_delimeter)
1090     return false;
1091 
1092   if (_num_ext_corners != rhs._num_ext_corners)
1093     return false;
1094 
1095   if (_corners_per_block != rhs._corners_per_block)
1096     return false;
1097   if (_corner_name_list && rhs._corner_name_list) {
1098     if (strcmp(_corner_name_list, rhs._corner_name_list) != 0)
1099       return false;
1100   } else if (_corner_name_list || rhs._corner_name_list)
1101     return false;
1102 
1103   if (_name && rhs._name) {
1104     if (strcmp(_name, rhs._name) != 0)
1105       return false;
1106   } else if (_name || rhs._name)
1107     return false;
1108 
1109   if (_die_area != rhs._die_area)
1110     return false;
1111 
1112   if (_chip != rhs._chip)
1113     return false;
1114 
1115   if (_bbox != rhs._bbox)
1116     return false;
1117 
1118   if (_parent != rhs._parent)
1119     return false;
1120 
1121   if (_next_block != rhs._next_block)
1122     return false;
1123 
1124   if (_gcell_grid != rhs._gcell_grid)
1125     return false;
1126 
1127   if (_parent_block != rhs._parent_block)
1128     return false;
1129 
1130   if (_parent_inst != rhs._parent_inst)
1131     return false;
1132 
1133   if (_top_module != rhs._top_module)
1134     return false;
1135 
1136   if (_net_hash != rhs._net_hash)
1137     return false;
1138 
1139   if (_inst_hash != rhs._inst_hash)
1140     return false;
1141 
1142   if (_module_hash != rhs._module_hash)
1143     return false;
1144 
1145   if (_modinst_hash != rhs._modinst_hash)
1146     return false;
1147 
1148   if (_group_hash != rhs._group_hash)
1149     return false;
1150 
1151   if (_inst_hdr_hash != rhs._inst_hdr_hash)
1152     return false;
1153 
1154   if (_bterm_hash != rhs._bterm_hash)
1155     return false;
1156 
1157   if (_maxCapNodeId != rhs._maxCapNodeId)
1158     return false;
1159 
1160   if (_maxRSegId != rhs._maxRSegId)
1161     return false;
1162 
1163   if (_maxCCSegId != rhs._maxCCSegId)
1164     return false;
1165 
1166   if (_minExtModelIndex != rhs._minExtModelIndex)
1167     return false;
1168 
1169   if (_maxExtModelIndex != rhs._maxExtModelIndex)
1170     return false;
1171 
1172   if (_children != rhs._children)
1173     return false;
1174 
1175   if (_currentCcAdjOrder != rhs._currentCcAdjOrder)
1176     return false;
1177 
1178   if (*_bterm_tbl != *rhs._bterm_tbl)
1179     return false;
1180 
1181   if (*_iterm_tbl != *rhs._iterm_tbl)
1182     return false;
1183 
1184   if (*_net_tbl != *rhs._net_tbl)
1185     return false;
1186 
1187   if (*_inst_hdr_tbl != *rhs._inst_hdr_tbl)
1188     return false;
1189 
1190   if (*_inst_tbl != *rhs._inst_tbl)
1191     return false;
1192 
1193   if (*_module_tbl != *rhs._module_tbl)
1194     return false;
1195 
1196   if (*_modinst_tbl != *rhs._modinst_tbl)
1197     return false;
1198 
1199   if (*_group_tbl != *rhs._group_tbl)
1200     return false;
1201 
1202   if (*_box_tbl != *rhs._box_tbl)
1203     return false;
1204 
1205   if (*_via_tbl != *rhs._via_tbl)
1206     return false;
1207 
1208   if (*_gcell_grid_tbl != *rhs._gcell_grid_tbl)
1209     return false;
1210 
1211   if (*_track_grid_tbl != *rhs._track_grid_tbl)
1212     return false;
1213 
1214   if (*_obstruction_tbl != *rhs._obstruction_tbl)
1215     return false;
1216 
1217   if (*_blockage_tbl != *rhs._blockage_tbl)
1218     return false;
1219 
1220   if (*_wire_tbl != *rhs._wire_tbl)
1221     return false;
1222 
1223   if (*_swire_tbl != *rhs._swire_tbl)
1224     return false;
1225 
1226   if (*_sbox_tbl != *rhs._sbox_tbl)
1227     return false;
1228 
1229   if (*_row_tbl != *rhs._row_tbl)
1230     return false;
1231 
1232   if (*_fill_tbl != *rhs._fill_tbl)
1233     return false;
1234 
1235   if (*_region_tbl != *rhs._region_tbl)
1236     return false;
1237 
1238   if (*_hier_tbl != *rhs._hier_tbl)
1239     return false;
1240 
1241   if (*_bpin_tbl != *rhs._bpin_tbl)
1242     return false;
1243 
1244   if (*_non_default_rule_tbl != *rhs._non_default_rule_tbl)
1245     return false;
1246 
1247   if (*_layer_rule_tbl != *rhs._layer_rule_tbl)
1248     return false;
1249 
1250   if (*_prop_tbl != *rhs._prop_tbl)
1251     return false;
1252 
1253   if (*_name_cache != *rhs._name_cache)
1254     return false;
1255 
1256   if (*_r_val_tbl != *rhs._r_val_tbl)
1257     return false;
1258 
1259   if (*_c_val_tbl != *rhs._c_val_tbl)
1260     return false;
1261 
1262   if (*_cc_val_tbl != *rhs._cc_val_tbl)
1263     return false;
1264 
1265   if (*_cap_node_tbl != *rhs._cap_node_tbl)
1266     return false;
1267 
1268   if (*_r_seg_tbl != *rhs._r_seg_tbl)
1269     return false;
1270 
1271   if (*_cc_seg_tbl != *rhs._cc_seg_tbl)
1272     return false;
1273 
1274   return true;
1275 }
1276 
differences(dbDiff & diff,const char * field,const _dbBlock & rhs) const1277 void _dbBlock::differences(dbDiff& diff,
1278                            const char* field,
1279                            const _dbBlock& rhs) const
1280 {
1281   DIFF_BEGIN
1282   DIFF_FIELD(_flags._valid_bbox);
1283   DIFF_FIELD(_def_units);
1284   DIFF_FIELD(_dbu_per_micron);
1285   DIFF_FIELD(_hier_delimeter);
1286   DIFF_FIELD(_left_bus_delimeter);
1287   DIFF_FIELD(_right_bus_delimeter);
1288   DIFF_FIELD(_num_ext_corners);
1289   DIFF_FIELD(_corners_per_block);
1290   DIFF_FIELD(_name);
1291   DIFF_FIELD(_corner_name_list);
1292   DIFF_FIELD(_die_area);
1293   DIFF_FIELD(_chip);
1294   DIFF_FIELD(_bbox);
1295   DIFF_FIELD(_parent);
1296   DIFF_FIELD(_next_block);
1297   DIFF_OBJECT(_gcell_grid, _gcell_grid_tbl, rhs._gcell_grid_tbl);
1298   DIFF_FIELD(_parent_block);
1299   DIFF_FIELD(_parent_inst);
1300   DIFF_FIELD(_top_module);
1301 
1302   if (!diff.deepDiff()) {
1303     DIFF_HASH_TABLE(_net_hash);
1304     DIFF_HASH_TABLE(_inst_hash);
1305     DIFF_HASH_TABLE(_module_hash);
1306     DIFF_HASH_TABLE(_modinst_hash);
1307     DIFF_HASH_TABLE(_group_hash);
1308     DIFF_HASH_TABLE(_inst_hdr_hash);
1309     DIFF_HASH_TABLE(_bterm_hash);
1310   }
1311 
1312   DIFF_FIELD(_maxCapNodeId);
1313   DIFF_FIELD(_maxRSegId);
1314   DIFF_FIELD(_maxCCSegId);
1315   DIFF_FIELD(_minExtModelIndex);
1316   DIFF_FIELD(_maxExtModelIndex);
1317   DIFF_VECTOR(_children);
1318   DIFF_FIELD(_currentCcAdjOrder);
1319   DIFF_TABLE(_bterm_tbl);
1320   DIFF_TABLE_NO_DEEP(_iterm_tbl);
1321   DIFF_TABLE(_net_tbl);
1322   DIFF_TABLE_NO_DEEP(_inst_hdr_tbl);
1323   DIFF_TABLE(_inst_tbl);
1324   DIFF_TABLE(_module_tbl);
1325   DIFF_TABLE(_modinst_tbl);
1326   DIFF_TABLE(_group_tbl);
1327   DIFF_TABLE_NO_DEEP(_box_tbl);
1328   DIFF_TABLE(_via_tbl);
1329   DIFF_TABLE_NO_DEEP(_gcell_grid_tbl);
1330   DIFF_TABLE(_track_grid_tbl);
1331   DIFF_TABLE(_obstruction_tbl);
1332   DIFF_TABLE(_blockage_tbl);
1333   DIFF_TABLE_NO_DEEP(_wire_tbl);
1334   DIFF_TABLE_NO_DEEP(_swire_tbl);
1335   DIFF_TABLE_NO_DEEP(_sbox_tbl);
1336   DIFF_TABLE(_row_tbl);
1337   DIFF_TABLE(_fill_tbl);
1338   DIFF_TABLE(_region_tbl);
1339   DIFF_TABLE_NO_DEEP(_hier_tbl);
1340   DIFF_TABLE_NO_DEEP(_bpin_tbl);
1341   DIFF_TABLE(_non_default_rule_tbl);
1342   DIFF_TABLE(_layer_rule_tbl);
1343   DIFF_TABLE_NO_DEEP(_prop_tbl);
1344   DIFF_NAME_CACHE(_name_cache);
1345 
1346   if (*_r_val_tbl != *rhs._r_val_tbl)
1347     _r_val_tbl->differences(diff, "_r_val_tbl", *rhs._r_val_tbl);
1348 
1349   if (*_c_val_tbl != *rhs._c_val_tbl)
1350     _c_val_tbl->differences(diff, "_c_val_tbl", *rhs._c_val_tbl);
1351 
1352   if (*_cc_val_tbl != *rhs._cc_val_tbl)
1353     _cc_val_tbl->differences(diff, "_c_val_tbl", *rhs._cc_val_tbl);
1354 
1355   DIFF_TABLE_NO_DEEP(_cap_node_tbl);
1356   DIFF_TABLE_NO_DEEP(_r_seg_tbl);
1357   DIFF_TABLE_NO_DEEP(_cc_seg_tbl);
1358   DIFF_END
1359 }
1360 
out(dbDiff & diff,char side,const char * field) const1361 void _dbBlock::out(dbDiff& diff, char side, const char* field) const
1362 {
1363   DIFF_OUT_BEGIN
1364   DIFF_OUT_FIELD(_flags._valid_bbox);
1365   DIFF_OUT_FIELD(_def_units);
1366   DIFF_OUT_FIELD(_dbu_per_micron);
1367   DIFF_OUT_FIELD(_hier_delimeter);
1368   DIFF_OUT_FIELD(_left_bus_delimeter);
1369   DIFF_OUT_FIELD(_right_bus_delimeter);
1370   DIFF_OUT_FIELD(_num_ext_corners);
1371   DIFF_OUT_FIELD(_corners_per_block);
1372   DIFF_OUT_FIELD(_name);
1373   DIFF_OUT_FIELD(_corner_name_list);
1374   DIFF_OUT_FIELD(_die_area);
1375   DIFF_OUT_FIELD(_chip);
1376   DIFF_OUT_FIELD(_bbox);
1377   DIFF_OUT_FIELD(_parent);
1378   DIFF_OUT_FIELD(_next_block);
1379   DIFF_OUT_OBJECT(_gcell_grid, _gcell_grid_tbl);
1380   DIFF_OUT_FIELD(_parent_block);
1381   DIFF_OUT_FIELD(_parent_inst);
1382   DIFF_OUT_FIELD(_top_module);
1383 
1384   if (!diff.deepDiff()) {
1385     DIFF_OUT_HASH_TABLE(_net_hash);
1386     DIFF_OUT_HASH_TABLE(_inst_hash);
1387     DIFF_OUT_HASH_TABLE(_module_hash);
1388     DIFF_OUT_HASH_TABLE(_modinst_hash);
1389     DIFF_OUT_HASH_TABLE(_group_hash);
1390     DIFF_OUT_HASH_TABLE(_inst_hdr_hash);
1391     DIFF_OUT_HASH_TABLE(_bterm_hash);
1392   }
1393 
1394   DIFF_OUT_FIELD(_maxCapNodeId);
1395   DIFF_OUT_FIELD(_maxRSegId);
1396   DIFF_OUT_FIELD(_maxCCSegId);
1397   DIFF_OUT_FIELD(_minExtModelIndex);
1398   DIFF_OUT_FIELD(_maxExtModelIndex);
1399   DIFF_OUT_VECTOR(_children);
1400   DIFF_OUT_FIELD(_currentCcAdjOrder);
1401   DIFF_OUT_TABLE(_bterm_tbl);
1402   DIFF_OUT_TABLE_NO_DEEP(_iterm_tbl);
1403   DIFF_OUT_TABLE(_net_tbl);
1404   DIFF_OUT_TABLE_NO_DEEP(_inst_hdr_tbl);
1405   DIFF_OUT_TABLE(_inst_tbl);
1406   DIFF_OUT_TABLE(_module_tbl);
1407   DIFF_OUT_TABLE(_modinst_tbl);
1408   DIFF_OUT_TABLE(_group_tbl);
1409   DIFF_OUT_TABLE_NO_DEEP(_box_tbl);
1410   DIFF_OUT_TABLE(_via_tbl);
1411   DIFF_OUT_TABLE_NO_DEEP(_gcell_grid_tbl);
1412   DIFF_OUT_TABLE(_track_grid_tbl);
1413   DIFF_OUT_TABLE(_obstruction_tbl);
1414   DIFF_OUT_TABLE(_blockage_tbl);
1415   DIFF_OUT_TABLE_NO_DEEP(_wire_tbl);
1416   DIFF_OUT_TABLE_NO_DEEP(_swire_tbl);
1417   DIFF_OUT_TABLE_NO_DEEP(_sbox_tbl);
1418   DIFF_OUT_TABLE(_row_tbl);
1419   DIFF_OUT_TABLE(_fill_tbl);
1420   DIFF_OUT_TABLE(_region_tbl);
1421   DIFF_OUT_TABLE_NO_DEEP(_hier_tbl);
1422   DIFF_OUT_TABLE_NO_DEEP(_bpin_tbl);
1423   DIFF_OUT_TABLE(_non_default_rule_tbl);
1424   DIFF_OUT_TABLE(_layer_rule_tbl);
1425   DIFF_OUT_TABLE_NO_DEEP(_prop_tbl);
1426   DIFF_OUT_NAME_CACHE(_name_cache);
1427 
1428   _r_val_tbl->out(diff, side, "_r_val_tbl");
1429   _c_val_tbl->out(diff, side, "_c_val_tbl");
1430   _cc_val_tbl->out(diff, side, "_c_val_tbl");
1431 
1432   DIFF_OUT_TABLE_NO_DEEP(_cap_node_tbl);
1433   DIFF_OUT_TABLE_NO_DEEP(_r_seg_tbl);
1434   DIFF_OUT_TABLE_NO_DEEP(_cc_seg_tbl);
1435   DIFF_END
1436 }
1437 
1438 ////////////////////////////////////////////////////////////////////
1439 //
1440 // dbBlock - Methods
1441 //
1442 ////////////////////////////////////////////////////////////////////
1443 
getName()1444 std::string dbBlock::getName()
1445 {
1446   _dbBlock* block = (_dbBlock*) this;
1447   return block->_name;
1448 }
1449 
getConstName()1450 const char* dbBlock::getConstName()
1451 {
1452   _dbBlock* block = (_dbBlock*) this;
1453   return block->_name;
1454 }
1455 
getBBox()1456 dbBox* dbBlock::getBBox()
1457 {
1458   _dbBlock* block = (_dbBlock*) this;
1459 
1460   if (block->_flags._valid_bbox == 0)
1461     ComputeBBox();
1462 
1463   _dbBox* bbox = block->_box_tbl->getPtr(block->_bbox);
1464   return (dbBox*) bbox;
1465 }
1466 
ComputeBBox()1467 void dbBlock::ComputeBBox()
1468 {
1469   _dbBlock* block = (_dbBlock*) this;
1470   _dbBox* bbox = block->_box_tbl->getPtr(block->_bbox);
1471   bbox->_shape._rect.reset(INT_MAX, INT_MAX, INT_MIN, INT_MIN);
1472 
1473   dbSet<dbInst> insts = getInsts();
1474   dbSet<dbInst>::iterator iitr;
1475 
1476   for (iitr = insts.begin(); iitr != insts.end(); ++iitr) {
1477     dbInst* inst = *iitr;
1478     if (inst->isPlaced()) {
1479       _dbBox* box = (_dbBox*) inst->getBBox();
1480       bbox->_shape._rect.merge(box->_shape._rect);
1481     }
1482   }
1483 
1484   dbSet<dbBTerm> bterms = getBTerms();
1485   dbSet<dbBTerm>::iterator bitr;
1486 
1487   for (bitr = bterms.begin(); bitr != bterms.end(); ++bitr) {
1488     dbBTerm* bterm = *bitr;
1489     dbSet<dbBPin> bpins = bterm->getBPins();
1490     dbSet<dbBPin>::iterator pitr;
1491 
1492     for (pitr = bpins.begin(); pitr != bpins.end(); ++pitr) {
1493       dbBPin* bp = *pitr;
1494       if (bp->getPlacementStatus().isPlaced()) {
1495         for (dbBox* box : bp->getBoxes()) {
1496           Rect r;
1497           box->getBox(r);
1498           bbox->_shape._rect.merge(r);
1499         }
1500       }
1501     }
1502   }
1503 
1504   dbSet<dbObstruction> obstructions = getObstructions();
1505   dbSet<dbObstruction>::iterator oitr;
1506 
1507   for (oitr = obstructions.begin(); oitr != obstructions.end(); ++oitr) {
1508     dbObstruction* obs = *oitr;
1509     _dbBox* box = (_dbBox*) obs->getBBox();
1510     bbox->_shape._rect.merge(box->_shape._rect);
1511   }
1512 
1513   dbSet<dbSBox> sboxes(block, block->_sbox_tbl);
1514   dbSet<dbSBox>::iterator sitr;
1515 
1516   for (sitr = sboxes.begin(); sitr != sboxes.end(); ++sitr) {
1517     dbSBox* box = (dbSBox*) *sitr;
1518     bbox->_shape._rect.merge(box->getGeomShape());
1519   }
1520 
1521   dbSet<dbWire> wires(block, block->_wire_tbl);
1522   dbSet<dbWire>::iterator witr;
1523 
1524   for (witr = wires.begin(); witr != wires.end(); ++witr) {
1525     dbWire* wire = *witr;
1526     Rect r;
1527     if (wire->getBBox(r)) {
1528       bbox->_shape._rect.merge(r);
1529     }
1530   }
1531 
1532   if (bbox->_shape._rect.xMin() == INT_MAX) {  // empty block
1533     bbox->_shape._rect.reset(0, 0, 0, 0);
1534   }
1535 
1536   block->_flags._valid_bbox = 1;
1537 }
1538 
getDataBase()1539 dbDatabase* dbBlock::getDataBase()
1540 {
1541   dbDatabase* db = (dbDatabase*) getImpl()->getDatabase();
1542   return db;
1543 }
1544 
getChip()1545 dbChip* dbBlock::getChip()
1546 {
1547   _dbBlock* block = (_dbBlock*) this;
1548   _dbDatabase* db = block->getDatabase();
1549   _dbChip* chip = db->_chip_tbl->getPtr(block->_chip);
1550   return (dbChip*) chip;
1551 }
1552 
getParent()1553 dbBlock* dbBlock::getParent()
1554 {
1555   _dbBlock* block = (_dbBlock*) this;
1556   _dbDatabase* db = block->getDatabase();
1557   _dbChip* chip = db->_chip_tbl->getPtr(block->_chip);
1558   _dbBlock* parent = chip->_block_tbl->getPtr(block->_parent);
1559   return (dbBlock*) parent;
1560 }
1561 
getParentInst()1562 dbInst* dbBlock::getParentInst()
1563 {
1564   _dbBlock* block = (_dbBlock*) this;
1565 
1566   if (block->_parent_block == 0)
1567     return NULL;
1568 
1569   _dbChip* chip = (_dbChip*) block->getOwner();
1570   _dbBlock* parent_block = chip->_block_tbl->getPtr(block->_parent_block);
1571   _dbInst* parent_inst = parent_block->_inst_tbl->getPtr(block->_parent_inst);
1572   return (dbInst*) parent_inst;
1573 }
1574 
getTopModule()1575 dbModule* dbBlock::getTopModule()
1576 {
1577   _dbBlock* block = (_dbBlock*) this;
1578   return (dbModule*) block->_module_tbl->getPtr(block->_top_module);
1579 }
1580 
getChildren()1581 dbSet<dbBlock> dbBlock::getChildren()
1582 {
1583   _dbBlock* block = (_dbBlock*) this;
1584   _dbDatabase* db = getImpl()->getDatabase();
1585   _dbChip* chip = db->_chip_tbl->getPtr(block->_chip);
1586   return dbSet<dbBlock>(block, chip->_block_itr);
1587 }
1588 
findChild(const char * name_)1589 dbBlock* dbBlock::findChild(const char* name_)
1590 {
1591   dbSet<dbBlock> children = getChildren();
1592   dbSet<dbBlock>::iterator itr;
1593 
1594   for (itr = children.begin(); itr != children.end(); ++itr) {
1595     _dbBlock* child = (_dbBlock*) *itr;
1596     if (strcmp(child->_name, name_) == 0)
1597       return (dbBlock*) child;
1598   }
1599 
1600   return NULL;
1601 }
1602 
getBTerms()1603 dbSet<dbBTerm> dbBlock::getBTerms()
1604 {
1605   _dbBlock* block = (_dbBlock*) this;
1606   return dbSet<dbBTerm>(block, block->_bterm_tbl);
1607 }
1608 
findBTerm(const char * name)1609 dbBTerm* dbBlock::findBTerm(const char* name)
1610 {
1611   _dbBlock* block = (_dbBlock*) this;
1612   return (dbBTerm*) block->_bterm_hash.find(name);
1613 }
1614 
getITerms()1615 dbSet<dbITerm> dbBlock::getITerms()
1616 {
1617   _dbBlock* block = (_dbBlock*) this;
1618   return dbSet<dbITerm>(block, block->_iterm_tbl);
1619 }
1620 
getInsts()1621 dbSet<dbInst> dbBlock::getInsts()
1622 {
1623   _dbBlock* block = (_dbBlock*) this;
1624   return dbSet<dbInst>(block, block->_inst_tbl);
1625 }
1626 
getModules()1627 dbSet<dbModule> dbBlock::getModules()
1628 {
1629   _dbBlock* block = (_dbBlock*) this;
1630   return dbSet<dbModule>(block, block->_module_tbl);
1631 }
1632 
getModInsts()1633 dbSet<dbModInst> dbBlock::getModInsts()
1634 {
1635   _dbBlock* block = (_dbBlock*) this;
1636   return dbSet<dbModInst>(block, block->_modinst_tbl);
1637 }
1638 
getGroups()1639 dbSet<dbGroup> dbBlock::getGroups()
1640 {
1641   _dbBlock* block = (_dbBlock*) this;
1642   return dbSet<dbGroup>(block, block->_group_tbl);
1643 }
1644 
findInst(const char * name)1645 dbInst* dbBlock::findInst(const char* name)
1646 {
1647   _dbBlock* block = (_dbBlock*) this;
1648   return (dbInst*) block->_inst_hash.find(name);
1649 }
1650 
findModule(const char * name)1651 dbModule* dbBlock::findModule(const char* name)
1652 {
1653   _dbBlock* block = (_dbBlock*) this;
1654   return (dbModule*) block->_module_hash.find(name);
1655 }
1656 
findModInst(const char * path)1657 dbModInst* dbBlock::findModInst(const char* path)
1658 {
1659   char* _path = strdup(path);
1660   dbModule* cur_mod = getTopModule();
1661   dbModInst* cur_inst = nullptr;
1662   char* token = strtok(_path, "/");
1663   while (token != NULL) {
1664     cur_inst = cur_mod->findModInst(token);
1665     if (cur_inst == nullptr)
1666       return nullptr;
1667     cur_mod = cur_inst->getMaster();
1668     token = strtok(NULL, "/");
1669   }
1670   return cur_inst;
1671 }
1672 
findGroup(const char * name)1673 dbGroup* dbBlock::findGroup(const char* name)
1674 {
1675   _dbBlock* block = (_dbBlock*) this;
1676   return (dbGroup*) block->_group_hash.find(name);
1677 }
1678 
findITerm(const char * name)1679 dbITerm* dbBlock::findITerm(const char* name)
1680 {
1681   _dbBlock* block = (_dbBlock*) this;
1682 
1683   std::string s(name);
1684 
1685   std::string::size_type idx = s.rfind(block->_hier_delimeter);
1686 
1687   if (idx == std::string::npos)  // no delimeter
1688     return NULL;
1689 
1690   std::string instName = s.substr(0, idx);
1691   std::string termName = s.substr(idx + 1, s.size());
1692 
1693   dbInst* inst = findInst(instName.c_str());
1694 
1695   if (inst == NULL)
1696     return NULL;
1697 
1698   return inst->findITerm(termName.c_str());
1699 }
1700 
getObstructions()1701 dbSet<dbObstruction> dbBlock::getObstructions()
1702 {
1703   _dbBlock* block = (_dbBlock*) this;
1704   return dbSet<dbObstruction>(block, block->_obstruction_tbl);
1705 }
1706 
getBlockages()1707 dbSet<dbBlockage> dbBlock::getBlockages()
1708 {
1709   _dbBlock* block = (_dbBlock*) this;
1710   return dbSet<dbBlockage>(block, block->_blockage_tbl);
1711 }
1712 
getNets()1713 dbSet<dbNet> dbBlock::getNets()
1714 {
1715   _dbBlock* block = (_dbBlock*) this;
1716   return dbSet<dbNet>(block, block->_net_tbl);
1717 }
1718 
getCapNodes()1719 dbSet<dbCapNode> dbBlock::getCapNodes()
1720 {
1721   _dbBlock* block = (_dbBlock*) this;
1722   return dbSet<dbCapNode>(block, block->_cap_node_tbl);
1723 }
1724 
findNet(const char * name)1725 dbNet* dbBlock::findNet(const char* name)
1726 {
1727   _dbBlock* block = (_dbBlock*) this;
1728   return (dbNet*) block->_net_hash.find(name);
1729 }
1730 
findSomeMaster(const char * names,std::vector<dbMaster * > & masters)1731 bool dbBlock::findSomeMaster(const char* names, std::vector<dbMaster*>& masters)
1732 {
1733   if (!names || names[0] == '\0')
1734     return false;
1735 
1736   dbLib* lib = getChip()->getDb()->findLib("lib");
1737   dbMaster* master;
1738   auto parser = std::make_unique<Ath__parser>();
1739   parser->mkWords(names, NULL);
1740   // uint noid;
1741   char* masterName;
1742   for (int ii = 0; ii < parser->getWordCnt(); ii++) {
1743     masterName = parser->get(ii);
1744     master = lib->findMaster(masterName);
1745     /*
1746     if (!master)
1747     {
1748 
1749         //noid = masterName[0]=='N' ? atoi(&masterName[1]) :
1750     atoi(&masterName[0]); master = dbNet::getValidNet(this, noid);
1751     }
1752     */
1753     if (master)
1754       masters.push_back(master);
1755     else
1756       getImpl()->getLogger()->warn(
1757           utl::ODB, 5, "Can not find master {}", masterName);
1758   }
1759   return masters.size() ? true : false;
1760 }
findSomeNet(const char * names,std::vector<dbNet * > & nets)1761 bool dbBlock::findSomeNet(const char* names, std::vector<dbNet*>& nets)
1762 {
1763   if (!names || names[0] == '\0')
1764     return false;
1765   _dbBlock* block = (_dbBlock*) this;
1766   dbNet* net;
1767   auto parser = std::make_unique<Ath__parser>();
1768   parser->mkWords(names, NULL);
1769   uint noid;
1770   char* netName;
1771   for (int ii = 0; ii < parser->getWordCnt(); ii++) {
1772     netName = parser->get(ii);
1773     net = (dbNet*) block->_net_hash.find(netName);
1774     if (!net) {
1775       noid = netName[0] == 'N' ? atoi(&netName[1]) : atoi(&netName[0]);
1776       net = dbNet::getValidNet(this, noid);
1777     }
1778     if (net)
1779       nets.push_back(net);
1780     else
1781       getImpl()->getLogger()->warn(utl::ODB, 6, "Can not find net {}", netName);
1782   }
1783   return nets.size() ? true : false;
1784 }
1785 
findSomeInst(const char * names,std::vector<dbInst * > & insts)1786 bool dbBlock::findSomeInst(const char* names, std::vector<dbInst*>& insts)
1787 {
1788   if (!names || names[0] == '\0')
1789     return false;
1790   _dbBlock* block = (_dbBlock*) this;
1791   dbInst* inst;
1792   auto parser = std::make_unique<Ath__parser>();
1793   parser->mkWords(names, NULL);
1794   uint ioid;
1795   char* instName;
1796   for (int ii = 0; ii < parser->getWordCnt(); ii++) {
1797     instName = parser->get(ii);
1798     inst = (dbInst*) block->_inst_hash.find(instName);
1799     if (!inst) {
1800       ioid = instName[0] == 'I' ? atoi(&instName[1]) : atoi(&instName[0]);
1801       inst = dbInst::getValidInst(this, ioid);
1802     }
1803     if (inst)
1804       insts.push_back(inst);
1805     else
1806       getImpl()->getLogger()->warn(
1807           utl::ODB, 7, "Can not find inst {}", instName);
1808   }
1809   return insts.size() ? true : false;
1810 }
1811 
findVia(const char * name)1812 dbVia* dbBlock::findVia(const char* name)
1813 {
1814   dbSet<dbVia> vias = getVias();
1815   dbSet<dbVia>::iterator itr;
1816 
1817   for (itr = vias.begin(); itr != vias.end(); ++itr) {
1818     _dbVia* via = (_dbVia*) *itr;
1819 
1820     if (strcmp(via->_name, name) == 0)
1821       return (dbVia*) via;
1822   }
1823 
1824   return NULL;
1825 }
1826 
getVias()1827 dbSet<dbVia> dbBlock::getVias()
1828 {
1829   _dbBlock* block = (_dbBlock*) this;
1830   return dbSet<dbVia>(block, block->_via_tbl);
1831 }
1832 
getRows()1833 dbSet<dbRow> dbBlock::getRows()
1834 {
1835   _dbBlock* block = (_dbBlock*) this;
1836   return dbSet<dbRow>(block, block->_row_tbl);
1837 }
1838 
getFills()1839 dbSet<dbFill> dbBlock::getFills()
1840 {
1841   _dbBlock* block = (_dbBlock*) this;
1842   return dbSet<dbFill>(block, block->_fill_tbl);
1843 }
1844 
getGCellGrid()1845 dbGCellGrid* dbBlock::getGCellGrid()
1846 {
1847   _dbBlock* block = (_dbBlock*) this;
1848 
1849   if (block->_gcell_grid == 0)
1850     return NULL;
1851 
1852   return (dbGCellGrid*) block->_gcell_grid_tbl->getPtr(block->_gcell_grid);
1853 }
1854 
getRegions()1855 dbSet<dbRegion> dbBlock::getRegions()
1856 {
1857   _dbBlock* block = (_dbBlock*) this;
1858   return dbSet<dbRegion>(block, block->_region_tbl);
1859 }
1860 
findRegion(const char * name)1861 dbRegion* dbBlock::findRegion(const char* name)
1862 {
1863   dbSet<dbRegion> regions = getRegions();
1864   dbSet<dbRegion>::iterator itr;
1865 
1866   for (itr = regions.begin(); itr != regions.end(); ++itr) {
1867     _dbRegion* r = (_dbRegion*) *itr;
1868 
1869     if (strcmp(r->_name, name) == 0)
1870       return (dbRegion*) r;
1871   }
1872 
1873   return NULL;
1874 }
1875 
getDefUnits()1876 int dbBlock::getDefUnits()
1877 {
1878   _dbBlock* block = (_dbBlock*) this;
1879   return block->_def_units;
1880 }
1881 
setDefUnits(int units)1882 void dbBlock::setDefUnits(int units)
1883 {
1884   _dbBlock* block = (_dbBlock*) this;
1885   block->_def_units = units;
1886 }
1887 
getDbUnitsPerMicron()1888 int dbBlock::getDbUnitsPerMicron()
1889 {
1890   _dbBlock* block = (_dbBlock*) this;
1891   return block->_dbu_per_micron;
1892 }
1893 
getHierarchyDelimeter()1894 char dbBlock::getHierarchyDelimeter()
1895 {
1896   _dbBlock* block = (_dbBlock*) this;
1897   return block->_hier_delimeter;
1898 }
1899 
setBusDelimeters(char left,char right)1900 void dbBlock::setBusDelimeters(char left, char right)
1901 {
1902   _dbBlock* block = (_dbBlock*) this;
1903   block->_left_bus_delimeter = left;
1904   block->_right_bus_delimeter = right;
1905 }
1906 
getBusDelimeters(char & left,char & right)1907 void dbBlock::getBusDelimeters(char& left, char& right)
1908 {
1909   _dbBlock* block = (_dbBlock*) this;
1910   left = block->_left_bus_delimeter;
1911   right = block->_right_bus_delimeter;
1912 }
1913 
getTrackGrids()1914 dbSet<dbTrackGrid> dbBlock::getTrackGrids()
1915 {
1916   _dbBlock* block = (_dbBlock*) this;
1917   dbSet<dbTrackGrid> tracks(block, block->_track_grid_tbl);
1918   return tracks;
1919 }
1920 
findTrackGrid(dbTechLayer * layer)1921 dbTrackGrid* dbBlock::findTrackGrid(dbTechLayer* layer)
1922 {
1923   dbSet<dbTrackGrid> tracks = getTrackGrids();
1924   dbSet<dbTrackGrid>::iterator itr;
1925 
1926   for (itr = tracks.begin(); itr != tracks.end(); ++itr) {
1927     dbTrackGrid* g = *itr;
1928 
1929     if (g->getTechLayer() == layer)
1930       return g;
1931   }
1932 
1933   return NULL;
1934 }
1935 
getMasters(std::vector<dbMaster * > & masters)1936 void dbBlock::getMasters(std::vector<dbMaster*>& masters)
1937 {
1938   _dbBlock* block = (_dbBlock*) this;
1939   dbSet<dbInstHdr> inst_hdrs(block, block->_inst_hdr_tbl);
1940   dbSet<dbInstHdr>::iterator itr;
1941 
1942   for (itr = inst_hdrs.begin(); itr != inst_hdrs.end(); ++itr) {
1943     dbInstHdr* hdr = *itr;
1944     masters.push_back(hdr->getMaster());
1945   }
1946 }
1947 
setDieArea(const Rect & new_area)1948 void dbBlock::setDieArea(const Rect& new_area)
1949 {
1950   _dbBlock* block = (_dbBlock*) this;
1951   block->_die_area = new_area;
1952   for (auto callback : block->_callbacks) {
1953     callback->inDbBlockSetDieArea(this);
1954   }
1955 }
1956 
getDieArea(Rect & r)1957 void dbBlock::getDieArea(Rect& r)
1958 {
1959   _dbBlock* block = (_dbBlock*) this;
1960   r = block->_die_area;
1961 }
1962 
getCoreArea(Rect & rect)1963 void dbBlock::getCoreArea(Rect& rect)
1964 {
1965   auto rows = getRows();
1966   if (rows.size() > 0) {
1967     rect.mergeInit();
1968 
1969     for (dbRow* row : rows) {
1970       Rect rowRect;
1971       row->getBBox(rowRect);
1972       rect.merge(rowRect);
1973     }
1974   } else {
1975     // Default to die area if there aren't any rows.
1976     getDieArea(rect);
1977   }
1978 }
1979 
getPtFile()1980 FILE* dbBlock::getPtFile()
1981 {
1982   _dbBlock* block = (_dbBlock*) this;
1983   return block->_ptFile;
1984 }
1985 
setPtFile(FILE * ptf)1986 void dbBlock::setPtFile(FILE* ptf)
1987 {
1988   _dbBlock* block = (_dbBlock*) this;
1989   block->_ptFile = ptf;
1990 }
1991 
setExtmi(void * ext)1992 void dbBlock::setExtmi(void* ext)
1993 {
1994   _dbBlock* block = (_dbBlock*) this;
1995   block->_extmi = ext;
1996 }
1997 
getExtmi()1998 void* dbBlock::getExtmi()
1999 {
2000   _dbBlock* block = (_dbBlock*) this;
2001   return (block->_extmi);
2002 }
2003 
getExtControl()2004 dbExtControl* dbBlock::getExtControl()
2005 {
2006   _dbBlock* block = (_dbBlock*) this;
2007   return (block->_extControl);
2008 }
2009 
getExtCornerNames(std::list<std::string> & ecl)2010 void dbBlock::getExtCornerNames(std::list<std::string>& ecl)
2011 {
2012   _dbBlock* block = (_dbBlock*) this;
2013   if (block->_corner_name_list)
2014     ecl.push_back(block->_corner_name_list);
2015   else
2016     ecl.push_back("");
2017 }
2018 
getCCSegs()2019 dbSet<dbCCSeg> dbBlock::getCCSegs()
2020 {
2021   _dbBlock* block = (_dbBlock*) this;
2022   return dbSet<dbCCSeg>(block, block->_cc_seg_tbl);
2023 }
2024 
getRSegs()2025 dbSet<dbRSeg> dbBlock::getRSegs()
2026 {
2027   _dbBlock* block = (_dbBlock*) this;
2028   return dbSet<dbRSeg>(block, block->_r_seg_tbl);
2029 }
2030 
findNonDefaultRule(const char * name)2031 dbTechNonDefaultRule* dbBlock::findNonDefaultRule(const char* name)
2032 {
2033   //_dbBlock * block = (_dbBlock *) this;
2034   //_dbTech * tech = (_dbTech *) getDb()->getTech();
2035 
2036   dbSet<dbTechNonDefaultRule> rules = getNonDefaultRules();
2037   dbSet<dbTechNonDefaultRule>::iterator itr;
2038 
2039   for (itr = rules.begin(); itr != rules.end(); ++itr) {
2040     _dbTechNonDefaultRule* r = (_dbTechNonDefaultRule*) *itr;
2041 
2042     if (strcmp(r->_name, name) == 0)
2043       return (dbTechNonDefaultRule*) r;
2044   }
2045 
2046   return NULL;
2047 }
2048 
getNonDefaultRules()2049 dbSet<dbTechNonDefaultRule> dbBlock::getNonDefaultRules()
2050 {
2051   _dbBlock* block = (_dbBlock*) this;
2052   return dbSet<dbTechNonDefaultRule>(block, block->_non_default_rule_tbl);
2053 }
2054 
copyExtDb(uint fr,uint to,uint extDbCnt,double resFactor,double ccFactor,double gndcFactor)2055 void dbBlock::copyExtDb(uint fr,
2056                         uint to,
2057                         uint extDbCnt,
2058                         double resFactor,
2059                         double ccFactor,
2060                         double gndcFactor)
2061 {
2062   _dbBlock* block = (_dbBlock*) this;
2063   uint j;
2064   if (resFactor != 1.0) {
2065     for (j = 1; j < block->_r_val_tbl->size(); j += extDbCnt)
2066       (*block->_r_val_tbl)[j + to] = (*block->_r_val_tbl)[j + fr] * resFactor;
2067   } else {
2068     for (j = 1; j < block->_r_val_tbl->size(); j += extDbCnt)
2069       (*block->_r_val_tbl)[j + to] = (*block->_r_val_tbl)[j + fr];
2070   }
2071   if (ccFactor != 1.0) {
2072     for (j = 1; j < block->_cc_val_tbl->size(); j += extDbCnt)
2073       (*block->_cc_val_tbl)[j + to] = (*block->_cc_val_tbl)[j + fr] * ccFactor;
2074   } else {
2075     for (j = 1; j < block->_cc_val_tbl->size(); j += extDbCnt)
2076       (*block->_cc_val_tbl)[j + to] = (*block->_cc_val_tbl)[j + fr];
2077   }
2078   if (gndcFactor != 1.0) {
2079     for (j = 1; j < block->_c_val_tbl->size(); j += extDbCnt)
2080       (*block->_c_val_tbl)[j + to] = (*block->_c_val_tbl)[j + fr] * gndcFactor;
2081   } else {
2082     for (j = 1; j < block->_c_val_tbl->size(); j += extDbCnt)
2083       (*block->_c_val_tbl)[j + to] = (*block->_c_val_tbl)[j + fr];
2084   }
2085 }
2086 
adjustCC(float adjFactor,double ccThreshHold,std::vector<dbNet * > & nets,std::vector<dbNet * > & halonets)2087 bool dbBlock::adjustCC(float adjFactor,
2088                        double ccThreshHold,
2089                        std::vector<dbNet*>& nets,
2090                        std::vector<dbNet*>& halonets)
2091 {
2092   bool adjusted = false;
2093   dbNet* net;
2094   std::vector<dbCCSeg*> adjustedCC;
2095   std::vector<dbNet*>::iterator itr;
2096   uint adjustOrder = ((_dbBlock*) this)->_currentCcAdjOrder + 1;
2097   for (itr = nets.begin(); itr != nets.end(); ++itr) {
2098     net = *itr;
2099     adjusted |= net->adjustCC(
2100         adjustOrder, adjFactor, ccThreshHold, adjustedCC, halonets);
2101   }
2102   std::vector<dbCCSeg*>::iterator ccitr;
2103   dbCCSeg* ccs;
2104   for (ccitr = adjustedCC.begin(); ccitr != adjustedCC.end(); ++ccitr) {
2105     ccs = *ccitr;
2106     ccs->setMark(false);
2107   }
2108   if (adjusted)
2109     ((_dbBlock*) this)->_currentCcAdjOrder = adjustOrder;
2110   return adjusted;
2111 }
2112 
groundCC(float gndFactor)2113 bool dbBlock::groundCC(float gndFactor)
2114 {
2115   if (gndFactor == 0.0)
2116     return false;
2117   bool grounded = false;
2118   dbNet* net;
2119   dbSet<dbNet> nets = getNets();
2120   dbSet<dbNet>::iterator nitr;
2121   for (nitr = nets.begin(); nitr != nets.end(); ++nitr) {
2122     net = *nitr;
2123     grounded |= net->groundCC(gndFactor);
2124   }
2125   for (nitr = nets.begin(); nitr != nets.end(); ++nitr) {
2126     net = *nitr;
2127     dbNet* net = *nitr;
2128     net->destroyCCSegs();
2129   }
2130   return grounded;
2131 }
2132 
undoAdjustedCC(std::vector<dbNet * > & nets,std::vector<dbNet * > & halonets)2133 void dbBlock::undoAdjustedCC(std::vector<dbNet*>& nets,
2134                              std::vector<dbNet*>& halonets)
2135 {
2136   dbNet* net;
2137   std::vector<dbCCSeg*> adjustedCC;
2138   std::vector<dbNet*>::iterator itr;
2139   for (itr = nets.begin(); itr != nets.end(); ++itr) {
2140     net = *itr;
2141     net->undoAdjustedCC(adjustedCC, halonets);
2142   }
2143   std::vector<dbCCSeg*>::iterator ccitr;
2144   dbCCSeg* ccs;
2145   for (ccitr = adjustedCC.begin(); ccitr != adjustedCC.end(); ++ccitr) {
2146     ccs = *ccitr;
2147     ccs->setMark(false);
2148   }
2149 }
2150 
adjustRC(double resFactor,double ccFactor,double gndcFactor)2151 void dbBlock::adjustRC(double resFactor, double ccFactor, double gndcFactor)
2152 {
2153   _dbBlock* block = (_dbBlock*) this;
2154   uint j;
2155   if (resFactor != 1.0) {
2156     for (j = 1; j < block->_r_val_tbl->size(); j++)
2157       (*block->_r_val_tbl)[j] *= resFactor;
2158   }
2159   if (ccFactor != 1.0) {
2160     for (j = 1; j < block->_cc_val_tbl->size(); j++)
2161       (*block->_cc_val_tbl)[j] *= ccFactor;
2162   }
2163   if (gndcFactor != 1.0) {
2164     for (j = 1; j < block->_c_val_tbl->size(); j++)
2165       (*block->_c_val_tbl)[j] *= gndcFactor;
2166   }
2167 }
2168 
getExtCount(int & numOfNet,int & numOfRSeg,int & numOfCapNode,int & numOfCCSeg)2169 void dbBlock::getExtCount(int& numOfNet,
2170                           int& numOfRSeg,
2171                           int& numOfCapNode,
2172                           int& numOfCCSeg)
2173 {
2174   _dbBlock* block = (_dbBlock*) this;
2175   numOfNet = block->_net_tbl->size();
2176   numOfRSeg = block->_r_seg_tbl->size();
2177   numOfCapNode = block->_cap_node_tbl->size();
2178   numOfCCSeg = block->_cc_seg_tbl->size();
2179 }
2180 /*
2181 void dbBlock::setMinExtMOdel(int n)
2182 {
2183     _dbBlock * block = (_dbBlock *) this;
2184     block->_min_ext_model= n;
2185 }
2186 void dbBlock::setMaxExtMOdel(int n)
2187 {
2188     _dbBlock * block = (_dbBlock *) this;
2189     block->_max_ext_model= n;
2190 }
2191 int dbBlock::getMaxExtMOdel()
2192 {
2193     _dbBlock * block = (_dbBlock *) this;
2194     return block->_max_ext_model;
2195 }
2196 int dbBlock::getMinExtMOdel()
2197 {
2198     _dbBlock * block = (_dbBlock *) this;
2199     return block->_min_ext_model;
2200 }
2201 */
getCornerCount()2202 int dbBlock::getCornerCount()
2203 {
2204   _dbBlock* block = (_dbBlock*) this;
2205   return block->_num_ext_corners;
2206 }
2207 
getCornersPerBlock()2208 int dbBlock::getCornersPerBlock()
2209 {
2210   _dbBlock* block = (_dbBlock*) this;
2211   return block->_corners_per_block;
2212 }
2213 
extCornersAreIndependent()2214 bool dbBlock::extCornersAreIndependent()
2215 {
2216   bool independent = getExtControl()->_independentExtCorners;
2217   return independent;
2218 }
2219 
getExtDbCount()2220 int dbBlock::getExtDbCount()
2221 {
2222   _dbBlock* block = (_dbBlock*) this;
2223   return block->_num_ext_dbs;
2224 }
2225 
initParasiticsValueTables()2226 void dbBlock::initParasiticsValueTables()
2227 {
2228   _dbBlock* block = (_dbBlock*) this;
2229   if ((block->_r_seg_tbl->size() > 0) || (block->_cap_node_tbl->size() > 0)
2230       || (block->_cc_seg_tbl->size() > 0)) {
2231     dbSet<dbNet> nets = getNets();
2232     dbSet<dbNet>::iterator nitr;
2233 
2234     for (nitr = nets.begin(); nitr != nets.end(); ++nitr) {
2235       _dbNet* n = (_dbNet*) *nitr;
2236       n->_cap_nodes = 0;  // DKF
2237       n->_r_segs = 0;     // DKF
2238     }
2239   }
2240 
2241   int ttttClear = 1;
2242   _dbDatabase* db = block->_cap_node_tbl->_db;
2243   if (ttttClear)
2244     block->_cap_node_tbl->clear();
2245   else {
2246     delete block->_cap_node_tbl;
2247     block->_cap_node_tbl
2248         = new dbTable<_dbCapNode>(db,
2249                                   block,
2250                                   (GetObjTbl_t) &_dbBlock::getObjectTable,
2251                                   dbCapNodeObj,
2252                                   4096,
2253                                   12);
2254     ZALLOCATED(block->_cap_node_tbl);
2255   }
2256   block->_maxCapNodeId = 0;
2257 
2258   if (ttttClear)
2259     block->_r_seg_tbl->clear();
2260   else {
2261     delete block->_r_seg_tbl;
2262     block->_r_seg_tbl
2263         = new dbTable<_dbRSeg>(db,
2264                                block,
2265                                (GetObjTbl_t) &_dbBlock::getObjectTable,
2266                                dbRSegObj,
2267                                4096,
2268                                12);
2269     ZALLOCATED(block->_r_seg_tbl);
2270   }
2271   block->_maxRSegId = 0;
2272 
2273   if (ttttClear)
2274     block->_cc_seg_tbl->clear();
2275   else {
2276     delete block->_cc_seg_tbl;
2277     block->_cc_seg_tbl
2278         = new dbTable<_dbCCSeg>(db,
2279                                 block,
2280                                 (GetObjTbl_t) &_dbBlock::getObjectTable,
2281                                 dbCCSegObj,
2282                                 4096,
2283                                 12);
2284     ZALLOCATED(block->_cc_seg_tbl);
2285   }
2286   block->_maxCCSegId = 0;
2287 
2288   if (ttttClear)
2289     block->_cc_val_tbl->clear();
2290   else {
2291     delete block->_cc_val_tbl;
2292     block->_cc_val_tbl = new dbPagedVector<float, 4096, 12>();
2293     ZALLOCATED(block->_cc_val_tbl);
2294   }
2295   block->_cc_val_tbl->push_back(0.0);
2296 
2297   if (ttttClear)
2298     block->_r_val_tbl->clear();
2299   else {
2300     delete block->_r_val_tbl;
2301     block->_r_val_tbl = new dbPagedVector<float, 4096, 12>();
2302     ZALLOCATED(block->_r_val_tbl);
2303   }
2304   block->_r_val_tbl->push_back(0.0);
2305 
2306   if (ttttClear)
2307     block->_c_val_tbl->clear();
2308   else {
2309     delete block->_c_val_tbl;
2310     block->_c_val_tbl = new dbPagedVector<float, 4096, 12>();
2311     ZALLOCATED(block->_c_val_tbl);
2312   }
2313   block->_c_val_tbl->push_back(0.0);
2314 }
2315 
setCornersPerBlock(int cornersPerBlock)2316 void dbBlock::setCornersPerBlock(int cornersPerBlock)
2317 {
2318   initParasiticsValueTables();
2319   _dbBlock* block = (_dbBlock*) this;
2320   block->_corners_per_block = cornersPerBlock;
2321 }
2322 
setCornerCount(int cornersStoredCnt,int extDbCnt,const char * name_list)2323 void dbBlock::setCornerCount(int cornersStoredCnt,
2324                              int extDbCnt,
2325                              const char* name_list)
2326 {
2327   ZASSERT((cornersStoredCnt > 0) && (cornersStoredCnt <= 256));
2328   _dbBlock* block = (_dbBlock*) this;
2329 
2330   // TODO: Should this change be logged in the journal?
2331   //       Yes !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2332   if (block->_journal) {
2333     debugPrint(getImpl()->getLogger(),
2334                utl::ODB,
2335                "DB_ECO",
2336                1,
2337                "ECO: dbBlock {}, setCornerCount cornerCnt {}, extDbCnt {}, "
2338                "name_list {}",
2339                block->getId(),
2340                cornersStoredCnt,
2341                extDbCnt,
2342                name_list);
2343     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
2344     block->_journal->pushParam(dbBlockObj);
2345     block->_journal->pushParam(block->getId());
2346     block->_journal->pushParam(_dbBlock::CORNERCOUNT);
2347     block->_journal->pushParam(cornersStoredCnt);
2348     block->_journal->pushParam(extDbCnt);
2349     block->_journal->pushParam(name_list);
2350     block->_journal->endAction();
2351   }
2352   initParasiticsValueTables();
2353 
2354   block->_num_ext_corners = cornersStoredCnt;
2355   block->_corners_per_block = cornersStoredCnt;
2356   block->_num_ext_dbs = extDbCnt;
2357   if (name_list != NULL) {
2358     if (block->_corner_name_list)
2359       free(block->_corner_name_list);
2360     block->_corner_name_list = strdup((char*) name_list);
2361   }
2362 }
getExtCornerBlock(uint corner)2363 dbBlock* dbBlock::getExtCornerBlock(uint corner)
2364 {
2365   dbBlock* block = findExtCornerBlock(corner);
2366   if (!block)
2367     block = this;
2368   return block;
2369 }
2370 
findExtCornerBlock(uint corner)2371 dbBlock* dbBlock::findExtCornerBlock(uint corner)
2372 {
2373   char cornerName[64];
2374   sprintf(cornerName, "extCornerBlock__%d", corner);
2375   return findChild(cornerName);
2376 }
2377 
createExtCornerBlock(uint corner)2378 dbBlock* dbBlock::createExtCornerBlock(uint corner)
2379 {
2380   char cornerName[64];
2381   sprintf(cornerName, "extCornerBlock__%d", corner);
2382   dbBlock* extBlk = dbBlock::create(this, cornerName, '/');
2383   assert(extBlk);
2384   dbSet<dbNet> nets = getNets();
2385   dbSet<dbNet>::iterator nitr;
2386   dbNet* net;
2387   char name[64];
2388   for (nitr = nets.begin(); nitr != nets.end(); ++nitr) {
2389     net = *nitr;
2390     sprintf(name, "%d", net->getId());
2391     dbNet* xnet = dbNet::create(extBlk, name, true);
2392     if (xnet == NULL) {
2393       getImpl()->getLogger()->error(
2394           utl::ODB, 8, "Cannot duplicate net {}", net->getConstName());
2395     }
2396     if (xnet->getId() != net->getId())
2397       getImpl()->getLogger()->warn(utl::ODB,
2398                                    9,
2399                                    "id mismatch ({},{}) for net {}",
2400                                    xnet->getId(),
2401                                    net->getId(),
2402                                    net->getConstName());
2403     dbSigType ty = net->getSigType();
2404     if ((ty == dbSigType::POWER) && (ty == dbSigType::GROUND))
2405       xnet->setSpecial();
2406 
2407     xnet->setSigType(ty);
2408   }
2409   extBlk->setCornersPerBlock(1);
2410   return extBlk;
2411 }
2412 
getCornerNameList()2413 char* dbBlock::getCornerNameList()
2414 {
2415   _dbBlock* block = (_dbBlock*) this;
2416 
2417   return block->_corner_name_list;
2418 }
setCornerNameList(char * name_list)2419 void dbBlock::setCornerNameList(char* name_list)
2420 {
2421   _dbBlock* block = (_dbBlock*) this;
2422 
2423   if (block->_corner_name_list != NULL)
2424     free(block->_corner_name_list);
2425 
2426   block->_corner_name_list = strdup(name_list);
2427 }
getExtCornerName(int corner,char * cName)2428 void dbBlock::getExtCornerName(int corner, char* cName)
2429 {
2430   cName[0] = '\0';
2431   _dbBlock* block = (_dbBlock*) this;
2432   if (block->_num_ext_corners == 0)
2433     return;
2434   ZASSERT((corner >= 0) && (corner < block->_num_ext_corners));
2435 
2436   if (block->_corner_name_list == NULL)
2437     return;
2438 
2439   char buff[1024];
2440   strcpy(buff, block->_corner_name_list);
2441 
2442   int ii = 0;
2443   char* word = strtok(buff, " ");
2444   while (word != NULL) {
2445     if (ii == corner) {
2446       strcpy(cName, word);
2447       return;
2448     }
2449 
2450     word = strtok(NULL, " ");
2451     ii++;
2452   }
2453   return;
2454 }
getExtCornerIndex(const char * cornerName)2455 int dbBlock::getExtCornerIndex(const char* cornerName)
2456 {
2457   _dbBlock* block = (_dbBlock*) this;
2458 
2459   if (block->_corner_name_list == NULL)
2460     return -1;
2461 
2462   char buff[1024];
2463   strcpy(buff, block->_corner_name_list);
2464 
2465   uint ii = 0;
2466   char* word = strtok(buff, " ");
2467   while (word != NULL) {
2468     if (strcmp(cornerName, word) == 0)
2469       return ii;
2470 
2471     word = strtok(NULL, " ");
2472     ii++;
2473   }
2474   return -1;
2475 }
setCornerCount(int cnt)2476 void dbBlock::setCornerCount(int cnt)
2477 {
2478   setCornerCount(cnt, cnt, NULL);
2479 }
2480 
copyViaTable(dbBlock * dst_,dbBlock * src_)2481 void dbBlock::copyViaTable(dbBlock* dst_, dbBlock* src_)
2482 {
2483   _dbBlock* dst = (_dbBlock*) dst_;
2484   _dbBlock* src = (_dbBlock*) src_;
2485   delete dst->_via_tbl;
2486   dst->_via_tbl = new dbTable<_dbVia>(dst->getDatabase(), dst, *src->_via_tbl);
2487   ZALLOCATED(dst->_via_tbl);
2488 }
2489 
create(dbChip * chip_,const char * name_,char hier_delimeter_)2490 dbBlock* dbBlock::create(dbChip* chip_, const char* name_, char hier_delimeter_)
2491 {
2492   _dbChip* chip = (_dbChip*) chip_;
2493 
2494   if (chip->_top != 0)
2495     return NULL;
2496 
2497   _dbBlock* top = chip->_block_tbl->create();
2498   top->initialize(chip, NULL, name_, hier_delimeter_);
2499   chip->_top = top->getOID();
2500   _dbTech* tech = (_dbTech*) chip->getDb()->getTech();
2501   top->_dbu_per_micron = tech->_dbu_per_micron;
2502   return (dbBlock*) top;
2503 }
2504 
create(dbBlock * parent_,const char * name_,char hier_delimeter)2505 dbBlock* dbBlock::create(dbBlock* parent_,
2506                          const char* name_,
2507                          char hier_delimeter)
2508 {
2509   if (parent_->findChild(name_))
2510     return NULL;
2511 
2512   _dbBlock* parent = (_dbBlock*) parent_;
2513   _dbChip* chip = (_dbChip*) parent->getOwner();
2514   _dbBlock* child = chip->_block_tbl->create();
2515   child->initialize(chip, parent, name_, hier_delimeter);
2516   _dbTech* tech = (_dbTech*) parent->getDb()->getTech();
2517   child->_dbu_per_micron = tech->_dbu_per_micron;
2518   return (dbBlock*) child;
2519 }
2520 
duplicate(dbBlock * child_,const char * name_)2521 dbBlock* dbBlock::duplicate(dbBlock* child_, const char* name_)
2522 {
2523   _dbBlock* child = (_dbBlock*) child_;
2524 
2525   // must be a child block
2526   if (child->_parent == 0)
2527     return NULL;
2528 
2529   _dbBlock* parent = (_dbBlock*) child_->getParent();
2530   _dbChip* chip = (_dbChip*) child->getOwner();
2531 
2532   // make a copy
2533   _dbBlock* dup = chip->_block_tbl->duplicate(child);
2534 
2535   // link child-to-parent
2536   parent->_children.push_back(dup->getOID());
2537   dup->_parent = parent->getOID();
2538 
2539   if (name_ && dup->_name) {
2540     free((void*) dup->_name);
2541     dup->_name = strdup(name_);
2542     ZALLOCATED(dup->_name);
2543   }
2544 
2545   return (dbBlock*) dup;
2546 }
2547 
getBlock(dbChip * chip_,uint dbid_)2548 dbBlock* dbBlock::getBlock(dbChip* chip_, uint dbid_)
2549 {
2550   _dbChip* chip = (_dbChip*) chip_;
2551   return (dbBlock*) chip->_block_tbl->getPtr(dbid_);
2552 }
2553 
getBlock(dbBlock * block_,uint dbid_)2554 dbBlock* dbBlock::getBlock(dbBlock* block_, uint dbid_)
2555 {
2556   _dbChip* chip = (_dbChip*) block_->getImpl()->getOwner();
2557   return (dbBlock*) chip->_block_tbl->getPtr(dbid_);
2558 }
2559 
destroy(dbBlock * block_)2560 void dbBlock::destroy(dbBlock* block_)
2561 {
2562   _dbBlock* block = (_dbBlock*) block_;
2563   _dbChip* chip = (_dbChip*) block->getOwner();
2564   // delete the children of this block
2565   for (dbId<_dbBlock> child_id : block->_children) {
2566     _dbBlock* child = chip->_block_tbl->getPtr(child_id);
2567     destroy((dbBlock*) child);
2568   }
2569   // Deleting top block
2570   if (block->_parent == 0)
2571     chip->_top = 0;
2572   else {
2573     // unlink this block from the parent
2574     _dbBlock* parent = chip->_block_tbl->getPtr(block->_parent);
2575     unlink_child_from_parent(block, parent);
2576   }
2577 
2578   dbProperty::destroyProperties(block);
2579   chip->_block_tbl->destroy(block);
2580 }
2581 
unlink_child_from_parent(_dbBlock * child,_dbBlock * parent)2582 void unlink_child_from_parent(_dbBlock* child, _dbBlock* parent)
2583 {
2584   uint id = child->getOID();
2585 
2586   dbVector<dbId<_dbBlock>>::iterator citr;
2587 
2588   for (citr = parent->_children.begin(); citr != parent->_children.end();
2589        ++citr) {
2590     if (*citr == id) {
2591       parent->_children.erase(citr);
2592       break;
2593     }
2594   }
2595 }
2596 
destroy(dbSet<dbBlock>::iterator & itr)2597 dbSet<dbBlock>::iterator dbBlock::destroy(dbSet<dbBlock>::iterator& itr)
2598 {
2599   dbBlock* bt = *itr;
2600   dbSet<dbBlock>::iterator next = ++itr;
2601   destroy(bt);
2602   return next;
2603 }
set_skip_hier_stream(bool value)2604 void dbBlock::set_skip_hier_stream(bool value)
2605 {
2606   _dbBlock* block = (_dbBlock*) this;
2607   block->_flags._skip_hier_stream = value ? 1 : 0;
2608 }
isBufferAltered()2609 bool dbBlock::isBufferAltered()
2610 {
2611   _dbBlock* block = (_dbBlock*) this;
2612   return block->_flags._buffer_altered == 1;
2613 }
setBufferAltered(bool value)2614 void dbBlock::setBufferAltered(bool value)
2615 {
2616   _dbBlock* block = (_dbBlock*) this;
2617   block->_flags._buffer_altered = value ? 1 : 0;
2618 }
2619 
getSearchDb()2620 dbBlockSearch* dbBlock::getSearchDb()
2621 {
2622   _dbBlock* block = (_dbBlock*) this;
2623   return block->_searchDb;
2624 }
2625 
2626 #ifdef ZUI
getSignalNetSdb(ZContext & context,dbTech * tech)2627 ZPtr<ISdb> dbBlock::getSignalNetSdb(ZContext& context, dbTech* tech)
2628 {
2629   _dbBlock* block = (_dbBlock*) this;
2630   if (block->_searchDb == NULL)
2631     block->_searchDb = new dbBlockSearch(this, tech);
2632   if (block->_searchDb == NULL)
2633     return NULL;
2634   return block->_searchDb->getSignalNetSdb(context);
2635 }
getSearchDb()2636 dbBlockSearch* dbBlock::getSearchDb()
2637 {
2638   _dbBlock* block = (_dbBlock*) this;
2639   return block->_searchDb;
2640 }
getNetSdb(ZContext & context,dbTech * tech)2641 ZPtr<ISdb> dbBlock::getNetSdb(ZContext& context, dbTech* tech)
2642 {
2643   _dbBlock* block = (_dbBlock*) this;
2644   if (block->_searchDb == NULL)
2645     block->_searchDb = new dbBlockSearch(this, tech);
2646   if (block->_searchDb == NULL)
2647     return NULL;
2648   return block->_searchDb->getNetSdb(context);
2649 }
getNetSdb()2650 ZPtr<ISdb> dbBlock::getNetSdb()
2651 {
2652   _dbBlock* block = (_dbBlock*) this;
2653   if (block->_searchDb == NULL)
2654     return NULL;
2655   return block->_searchDb->getNetSdb();
2656 }
resetNetSdb()2657 void dbBlock::resetNetSdb()
2658 {
2659   _dbBlock* block = (_dbBlock*) this;
2660   if (block->_searchDb == NULL)
2661     return;
2662   block->_searchDb->resetNetSdb();
2663 }
removeSdb(std::vector<dbNet * > & nets)2664 void dbBlock::removeSdb(std::vector<dbNet*>& nets)
2665 {
2666   ZPtr<ISdb> netSdb = getNetSdb();
2667   if (netSdb == NULL || netSdb->getSearchPtr() == NULL)
2668     return;
2669   dbNet::markNets(nets, this, true);
2670   netSdb->removeMarkedNetWires();
2671   dbNet::markNets(nets, this, false);
2672 }
2673 
initSearchBlock(dbTech * tech,bool nets,bool insts,ZContext & context,bool skipViaCuts)2674 dbBlockSearch* dbBlock::initSearchBlock(dbTech* tech,
2675                                         bool nets,
2676                                         bool insts,
2677                                         ZContext& context,
2678                                         bool skipViaCuts)
2679 {
2680   _dbBlock* block = (_dbBlock*) this;
2681 
2682   /* TODO: TEMPORARY FIX
2683       if (block->_searchDb!=NULL)
2684               delete block->_searchDb;
2685   */
2686 
2687   block->_searchDb = new dbBlockSearch(this, tech);
2688 
2689   if (skipViaCuts)
2690     block->_searchDb->setViaCutsFlag(skipViaCuts);
2691   block->_searchDb->makeSearchDB(nets, insts, context);
2692 
2693   return block->_searchDb;
2694 }
2695 
getInsts(int x1,int y1,int x2,int y2,std::vector<dbInst * > & result)2696 uint dbBlock::getInsts(int x1,
2697                        int y1,
2698                        int x2,
2699                        int y2,
2700                        std::vector<dbInst*>& result)
2701 {
2702   _dbBlock* block = (_dbBlock*) this;
2703   return block->_searchDb->getInstBoxes(x1, y1, x2, y2, result);
2704 }
2705 #endif
updateNetFlags(std::vector<dbNet * > & result)2706 void dbBlock::updateNetFlags(std::vector<dbNet*>& result)
2707 {
2708   _dbBlock* block = (_dbBlock*) this;
2709   dbSet<dbNet> nets = getNets();
2710   dbSet<dbNet>::iterator nitr;
2711 
2712   for (nitr = nets.begin(); nitr != nets.end(); ++nitr) {
2713     dbNet* net = *nitr;
2714 
2715     _dbNet* n = (_dbNet*) *nitr;
2716 
2717     if (n->_flags._wire_altered != 1)
2718       continue;
2719 
2720     n->_flags._reduced = 0;
2721     n->_flags._extracted = 0;
2722     n->_flags._rc_graph = 0;
2723     n->_flags._wire_ordered = 0;
2724 
2725     if (block->_journal) {
2726       // assert(0);
2727     }
2728 
2729     result.push_back(net);
2730   }
2731 }
2732 
getWireUpdatedNets(std::vector<dbNet * > & result,Rect * ibox)2733 void dbBlock::getWireUpdatedNets(std::vector<dbNet*>& result, Rect* ibox)
2734 {
2735   dbSet<dbNet> nets = getNets();
2736   dbSet<dbNet>::iterator nitr;
2737 
2738   int tot = 0;
2739   int upd = 0;
2740   int enc = 0;
2741   for (nitr = nets.begin(); nitr != nets.end(); ++nitr) {
2742     tot++;
2743     dbNet* net = *nitr;
2744 
2745     _dbNet* n = (_dbNet*) *nitr;
2746 
2747     if (n->_flags._wire_altered != 1)
2748       continue;
2749     upd++;
2750     if (ibox && !net->isEnclosed(ibox))
2751       continue;
2752     enc++;
2753 
2754     result.push_back(net);
2755   }
2756   getImpl()->getLogger()->info(
2757       utl::ODB, 10, "tot = {}, upd = {}, enc = {}", tot, upd, enc);
2758 }
2759 
destroyCCs(std::vector<dbNet * > & nets)2760 void dbBlock::destroyCCs(std::vector<dbNet*>& nets)
2761 {
2762   std::vector<dbNet*>::iterator itr;
2763 
2764   for (itr = nets.begin(); itr != nets.end(); ++itr) {
2765     dbNet* net = *itr;
2766     net->destroyCCSegs();
2767   }
2768 }
2769 
destroyRSegs(std::vector<dbNet * > & nets)2770 void dbBlock::destroyRSegs(std::vector<dbNet*>& nets)
2771 {
2772   std::vector<dbNet*>::iterator itr;
2773 
2774   for (itr = nets.begin(); itr != nets.end(); ++itr) {
2775     dbNet* net = *itr;
2776     net->destroyRSegs();
2777   }
2778 }
2779 
destroyCNs(std::vector<dbNet * > & nets,bool cleanExtid)2780 void dbBlock::destroyCNs(std::vector<dbNet*>& nets, bool cleanExtid)
2781 {
2782   std::vector<dbNet*>::iterator itr;
2783 
2784   for (itr = nets.begin(); itr != nets.end(); ++itr) {
2785     dbNet* net = *itr;
2786     net->destroyCapNodes(cleanExtid);
2787   }
2788 }
2789 
destroyCornerParasitics(std::vector<dbNet * > & nets)2790 void dbBlock::destroyCornerParasitics(std::vector<dbNet*>& nets)
2791 {
2792   std::vector<dbNet*> cnets;
2793   uint jj;
2794   for (jj = 0; jj < nets.size(); jj++) {
2795     dbNet* net = dbNet::getNet(this, nets[jj]->getId());
2796     cnets.push_back(net);
2797   }
2798 #ifdef ZUI
2799   removeSdb(cnets);
2800 #endif
2801   destroyCCs(cnets);
2802   destroyRSegs(cnets);
2803   destroyCNs(cnets, true);
2804 }
2805 
destroyParasitics(std::vector<dbNet * > & nets)2806 void dbBlock::destroyParasitics(std::vector<dbNet*>& nets)
2807 {
2808   destroyCornerParasitics(nets);
2809   if (!extCornersAreIndependent())
2810     return;
2811   int numcorners = getCornerCount();
2812   dbBlock* extBlock;
2813   for (int corner = 1; corner < numcorners; corner++) {
2814     extBlock = findExtCornerBlock(corner);
2815     extBlock->destroyCornerParasitics(nets);
2816   }
2817 }
2818 
getCcHaloNets(std::vector<dbNet * > & changedNets,std::vector<dbNet * > & ccHaloNets)2819 void dbBlock::getCcHaloNets(std::vector<dbNet*>& changedNets,
2820                             std::vector<dbNet*>& ccHaloNets)
2821 {
2822   uint jj;
2823   dbNet* ccNet;
2824   for (jj = 0; jj < changedNets.size(); jj++)
2825     changedNets[jj]->setMark(true);
2826   for (jj = 0; jj < changedNets.size(); jj++) {
2827     dbSet<dbCapNode> capNodes = changedNets[jj]->getCapNodes();
2828     dbSet<dbCapNode>::iterator citr;
2829     for (citr = capNodes.begin(); citr != capNodes.end(); ++citr) {
2830       dbCapNode* capn = *citr;
2831       dbSet<dbCCSeg> ccSegs = capn->getCCSegs();
2832       dbSet<dbCCSeg>::iterator ccitr;
2833       for (ccitr = ccSegs.begin(); ccitr != ccSegs.end();) {
2834         dbCCSeg* cc = *ccitr;
2835         ++ccitr;
2836         dbCapNode* tcap = cc->getSourceCapNode();
2837         if (tcap != capn)
2838           ccNet = tcap->getNet();
2839         else
2840           ccNet = cc->getTargetCapNode()->getNet();
2841         if (ccNet->isMarked())
2842           continue;
2843         ccNet->setMark(true);
2844         ccHaloNets.push_back(ccNet);
2845       }
2846     }
2847   }
2848   for (jj = 0; jj < changedNets.size(); jj++)
2849     changedNets[jj]->setMark(false);
2850   for (jj = 0; jj < ccHaloNets.size(); jj++)
2851     ccHaloNets[jj]->setMark(false);
2852 }
2853 
restoreOldCornerParasitics(dbBlock * pblock,std::vector<dbNet * > & nets,bool coupled_rc,std::vector<dbNet * > & ccHaloNets,std::vector<uint> & capnn,std::vector<uint> & rsegn)2854 void dbBlock::restoreOldCornerParasitics(dbBlock* pblock,
2855                                          std::vector<dbNet*>& nets,
2856                                          bool coupled_rc,
2857                                          std::vector<dbNet*>& ccHaloNets,
2858                                          std::vector<uint>& capnn,
2859                                          std::vector<uint>& rsegn)
2860 {
2861   // destroyParasitics(nets);  ** discard new parasitics
2862   uint jj;
2863   dbNet* net;
2864   dbCCSeg* ccSeg;
2865   dbCapNode* capnd;
2866   dbCapNode* otherCapnode;
2867   dbNet* otherNet;
2868   uint otherid;
2869   std::vector<dbNet*>::iterator itr;
2870 
2871   for (jj = 0; jj < nets.size(); jj++) {
2872     net = dbNet::getNet(this, nets[jj]->getId());
2873     net->set1stCapNodeId(capnn[jj]);
2874     // have extId of terms becoming per corner ??
2875     if (pblock == this)
2876       net->setTermExtIds(1);
2877     net->set1stRSegId(rsegn[jj]);
2878   }
2879   for (itr = nets.begin(); itr != nets.end(); ++itr)
2880     (*itr)->setMark(true);
2881   for (itr = ccHaloNets.begin(); itr != ccHaloNets.end(); ++itr)
2882     (*itr)->setMark_1(true);
2883   for (itr = nets.begin(); itr != nets.end(); ++itr) {
2884     net = dbNet::getNet(this, (*itr)->getId());
2885     dbSet<dbCapNode> nodeSet = net->getCapNodes();
2886     dbSet<dbCapNode>::iterator rc_itr;
2887     for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
2888       capnd = *rc_itr;
2889       dbSet<dbCCSeg> ccSegs = capnd->getCCSegs();
2890       dbSet<dbCCSeg>::iterator ccitr;
2891       for (ccitr = ccSegs.begin(); ccitr != ccSegs.end(); ccitr++) {
2892         ccSeg = *ccitr;
2893         otherCapnode = ccSeg->getTheOtherCapn(capnd, otherid);
2894         otherNet = dbNet::getNet(pblock, otherCapnode->getNet()->getId());
2895         if (otherNet->isMarked())
2896           continue;
2897         if (otherNet->isMark_1ed() || !coupled_rc)  // link_cc_seg
2898           ccSeg->Link_cc_seg(otherCapnode, otherid);
2899         else {
2900           getImpl()->getLogger()->warn(
2901               utl::ODB,
2902               11,
2903               "net {} {} capNode {} ccseg {} has otherCapNode {} not from "
2904               "changed or halo nets",
2905               net->getId(),
2906               (char*) net->getConstName(),
2907               capnd->getId(),
2908               ccSeg->getId(),
2909               otherCapnode->getId());
2910           getImpl()->getLogger()->error(
2911               utl::ODB,
2912               12,
2913               "   the other capNode is from net {} {}",
2914               otherNet->getId(),
2915               otherNet->getConstName());
2916         }
2917       }
2918     }
2919   }
2920   for (itr = nets.begin(); itr != nets.end(); ++itr)
2921     (*itr)->setMark(false);
2922   for (itr = ccHaloNets.begin(); itr != ccHaloNets.end(); ++itr)
2923     (*itr)->setMark_1(false);
2924 }
2925 
restoreOldParasitics(std::vector<dbNet * > & nets,bool coupled_rc,std::vector<dbNet * > & ccHaloNets,std::vector<uint> * capnn,std::vector<uint> * rsegn)2926 void dbBlock::restoreOldParasitics(std::vector<dbNet*>& nets,
2927                                    bool coupled_rc,
2928                                    std::vector<dbNet*>& ccHaloNets,
2929                                    std::vector<uint>* capnn,
2930                                    std::vector<uint>* rsegn)
2931 {
2932   restoreOldCornerParasitics(
2933       this, nets, coupled_rc, ccHaloNets, capnn[0], rsegn[0]);
2934   if (!extCornersAreIndependent())
2935     return;
2936   int numcorners = getCornerCount();
2937   dbBlock* extBlock;
2938   for (int corner = 1; corner < numcorners; corner++) {
2939     extBlock = findExtCornerBlock(corner);
2940     extBlock->restoreOldCornerParasitics(
2941         this, nets, coupled_rc, ccHaloNets, capnn[corner], rsegn[corner]);
2942   }
2943 }
2944 
destroyOldCornerParasitics(std::vector<dbNet * > & nets,std::vector<uint> & capnn,std::vector<uint> & rsegn)2945 void dbBlock::destroyOldCornerParasitics(std::vector<dbNet*>& nets,
2946                                          std::vector<uint>& capnn,
2947                                          std::vector<uint>& rsegn)
2948 {
2949   std::vector<dbNet*> cnets;
2950   std::vector<uint> ncapnn;
2951   std::vector<uint> nrsegn;
2952   uint jj;
2953   for (jj = 0; jj < nets.size(); jj++) {
2954     dbNet* net = dbNet::getNet(this, nets[jj]->getId());
2955     cnets.push_back(net);
2956     ncapnn.push_back(net->get1stCapNodeId());
2957     net->set1stCapNodeId(capnn[jj]);
2958     nrsegn.push_back(net->get1stRSegId());
2959     net->set1stRSegId(rsegn[jj]);
2960   }
2961   // destroyParasitics(nets);
2962   destroyCCs(cnets);
2963   destroyRSegs(cnets);
2964   destroyCNs(cnets, false);  // don't touch ext_id's of terms
2965   for (jj = 0; jj < cnets.size(); jj++) {
2966     dbNet* net = cnets[jj];
2967     net->set1stCapNodeId(ncapnn[jj]);
2968     net->set1stRSegId(nrsegn[jj]);
2969   }
2970 }
2971 
destroyOldParasitics(std::vector<dbNet * > & nets,std::vector<uint> * capnn,std::vector<uint> * rsegn)2972 void dbBlock::destroyOldParasitics(std::vector<dbNet*>& nets,
2973                                    std::vector<uint>* capnn,
2974                                    std::vector<uint>* rsegn)
2975 {
2976   destroyOldCornerParasitics(nets, capnn[0], rsegn[0]);
2977   if (!extCornersAreIndependent())
2978     return;
2979   int numcorners = getCornerCount();
2980   dbBlock* extBlock;
2981   for (int corner = 1; corner < numcorners; corner++) {
2982     extBlock = findExtCornerBlock(corner);
2983     extBlock->destroyOldCornerParasitics(nets, capnn[corner], rsegn[corner]);
2984   }
2985 }
2986 
replaceOldParasitics(std::vector<dbNet * > & nets,std::vector<uint> & capnn,std::vector<uint> & rsegn)2987 void dbBlock::replaceOldParasitics(std::vector<dbNet*>& nets,
2988                                    std::vector<uint>& capnn,
2989                                    std::vector<uint>& rsegn)
2990 {
2991   dbNet* net;
2992   _dbBlock* block = (_dbBlock*) this;
2993 
2994   uint jj;
2995 
2996   dbJournal* tmpj = block->_journal;
2997   block->_journal = NULL;
2998   for (jj = 0; jj < nets.size(); jj++) {
2999     net = nets[jj];
3000     capnn.push_back(net->get1stCapNodeId());
3001     net->set1stCapNodeId(0);
3002     rsegn.push_back(net->get1stRSegId());
3003     net->set1stRSegId(0);
3004     net->createZeroRc(getExtControl()->_foreign);
3005   }
3006   block->_journal = tmpj;
3007 }
3008 
restoreOldParasitics(std::vector<dbNet * > & nets,std::vector<uint> & capnn,std::vector<uint> & rsegn)3009 void dbBlock::restoreOldParasitics(std::vector<dbNet*>& nets,
3010                                    std::vector<uint>& capnn,
3011                                    std::vector<uint>& rsegn)
3012 {
3013   uint jj;
3014   dbNet* net;
3015   _dbBlock* block = (_dbBlock*) this;
3016 
3017   dbJournal* tmpj = block->_journal;
3018   block->_journal = NULL;
3019   destroyParasitics(nets);
3020   for (jj = 0; jj < nets.size(); jj++) {
3021     net = nets[jj];
3022     net->set1stCapNodeId(capnn[jj]);
3023     net->set1stRSegId(rsegn[jj]);
3024   }
3025   block->_journal = tmpj;
3026 }
3027 
keepOldCornerParasitics(dbBlock * pblock,std::vector<dbNet * > & nets,bool coupled_rc,std::vector<dbNet * > & ccHaloNets,std::vector<uint> & capnn,std::vector<uint> & rsegn)3028 void dbBlock::keepOldCornerParasitics(dbBlock* pblock,
3029                                       std::vector<dbNet*>& nets,
3030                                       bool coupled_rc,
3031                                       std::vector<dbNet*>& ccHaloNets,
3032                                       std::vector<uint>& capnn,
3033                                       std::vector<uint>& rsegn)
3034 {
3035   dbNet* net;
3036   dbNet* onet;
3037   dbCapNode* capnd;
3038   dbCapNode* other;
3039   dbCCSeg* ccSeg;
3040   uint cid;
3041 
3042   std::vector<dbNet*>::iterator itr;
3043 
3044   for (itr = nets.begin(); itr != nets.end(); ++itr)
3045     (*itr)->setMark(true);
3046   for (itr = ccHaloNets.begin(); itr != ccHaloNets.end(); ++itr)
3047     (*itr)->setMark_1(true);
3048   for (itr = nets.begin(); itr != nets.end(); ++itr) {
3049     net = dbNet::getNet(this, (*itr)->getId());
3050     dbSet<dbCapNode> nodeSet = net->getCapNodes();
3051     dbSet<dbCapNode>::iterator rc_itr;
3052     for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
3053       capnd = *rc_itr;
3054       dbSet<dbCCSeg> ccSegs = capnd->getCCSegs();
3055       dbSet<dbCCSeg>::iterator ccitr;
3056       for (ccitr = ccSegs.begin(); ccitr != ccSegs.end(); ccitr++) {
3057         ccSeg = *ccitr;
3058         other = ccSeg->getTheOtherCapn(capnd, cid);
3059         onet = dbNet::getNet(pblock, other->getNet()->getId());
3060         if (onet->isMarked())
3061           continue;
3062         if (onet->isMark_1ed() || !coupled_rc)
3063           ccSeg->unLink_cc_seg(other);
3064         else
3065           getImpl()->getLogger()->error(
3066               utl::ODB,
3067               13,
3068               "ccseg {} has other capn {} not from changed or halo nets",
3069               ccSeg->getId(),
3070               other->getId());
3071       }
3072     }
3073   }
3074   for (itr = nets.begin(); itr != nets.end(); ++itr)
3075     (*itr)->setMark(false);
3076   for (itr = ccHaloNets.begin(); itr != ccHaloNets.end(); ++itr)
3077     (*itr)->setMark_1(false);
3078   for (itr = nets.begin(); itr != nets.end(); ++itr) {
3079     net = dbNet::getNet(this, (*itr)->getId());
3080     // have extId of terms becoming per corner ??
3081     if (pblock == this)
3082       net->setTermExtIds(0);
3083     capnn.push_back(net->get1stCapNodeId());
3084     net->set1stCapNodeId(0);
3085     rsegn.push_back(net->get1stRSegId());
3086     net->set1stRSegId(0);
3087   }
3088 }
3089 
keepOldParasitics(std::vector<dbNet * > & nets,bool coupled_rc,std::vector<dbNet * > & ccHaloNets,std::vector<uint> * capnn,std::vector<uint> * rsegn)3090 void dbBlock::keepOldParasitics(std::vector<dbNet*>& nets,
3091                                 bool coupled_rc,
3092                                 std::vector<dbNet*>& ccHaloNets,
3093                                 std::vector<uint>* capnn,
3094                                 std::vector<uint>* rsegn)
3095 {
3096   keepOldCornerParasitics(
3097       this, nets, coupled_rc, ccHaloNets, capnn[0], rsegn[0]);
3098   if (!extCornersAreIndependent())
3099     return;
3100   int numcorners = getCornerCount();
3101   dbBlock* extBlock;
3102   for (int corner = 1; corner < numcorners; corner++) {
3103     extBlock = findExtCornerBlock(corner);
3104     extBlock->keepOldCornerParasitics(
3105         this, nets, coupled_rc, ccHaloNets, capnn[corner], rsegn[corner]);
3106   }
3107 }
3108 
3109 #if 0
3110 //
3111 // Utility to create a net comprising a single SWire and two BTerms
3112 // Returns pointer to net (NULL iff not successful)
3113 //
3114 dbNet *
3115 dbBlock::createNetSingleSWire(const char *innm, int x1, int y1, int x2, int y2, uint rlevel)
3116 {
3117   if (!innm)
3118     return NULL;
3119 
3120   dbTech *intech = ((dbDatabase *) (getChip())->getOwner())->getTech();
3121   dbTechLayer *inly = NULL;
3122   if (!intech || ((inly = intech->findRoutingLayer(rlevel)) == NULL))
3123     return NULL;
3124 
3125   if (x2 < x1)
3126     std::swap(x1,x2);
3127   if (y2 < y1)
3128     std::swap(y1, y2);
3129 
3130   dbNet *nwnet = dbNet::create(this,innm);
3131   if (!nwnet)
3132     return NULL;
3133 
3134   nwnet->setSigType(dbSigType::SIGNAL);
3135 
3136   dbSWire *nwsw = dbSWire::create(nwnet, dbWireType::ROUTED);
3137   if (!nwsw)
3138     return NULL;
3139   dbSBox  *nwsbx = dbSBox::create(nwsw, inly, x1, y1, x2, y2, dbWireShapeType::NONE);
3140   if (!nwsbx)
3141     return NULL;
3142 
3143   std::pair<dbBTerm *, dbBTerm *> cktrms = nwnet->createTerms4SingleNet(x1, y1, x2, y2, inly);
3144   if ((cktrms.first == NULL) || (cktrms.second == NULL))
3145     return NULL;
3146 
3147   return nwnet;
3148 }
3149 
3150 //
3151 // Utility to create a net comprising a single Wire and two BTerms
3152 // Requires creating a suitable non-default rule for the wire if none exists.
3153 // Returns pointer to net (NULL iff not successful)
3154 //
3155 dbNet *
3156 dbBlock::createNetSingleWire(const char *innm, int x1, int y1, int x2, int y2, uint rlevel, bool skipBterms, dbTechLayerDir indir)
3157 {
3158         static int opendx = -1;
3159 
3160 	if (!innm)
3161 		return NULL;
3162 
3163 	dbTech *intech = ((dbDatabase *) (getChip())->getOwner())->getTech();
3164 	dbTechLayer *inly = NULL;
3165 	if (!intech || ((inly = intech->findRoutingLayer(rlevel)) == NULL))
3166 		return NULL;
3167 
3168 	if (x2 < x1)
3169 		std::swap(x1,x2);
3170 	if (y2 < y1)
3171 		std::swap(y1, y2);
3172 
3173 	dbNet *nwnet = dbNet::create(this,innm);
3174 	if (!nwnet)
3175 		return NULL;
3176 
3177 	nwnet->setSigType(dbSigType::SIGNAL);
3178 
3179 	std::pair<dbBTerm *, dbBTerm *> blutrms;
3180 	if (! skipBterms ) {
3181 		blutrms = nwnet->createTerms4SingleNet(x1, y1, x2, y2, inly);
3182 
3183 		if ((blutrms.first == NULL) || (blutrms.second == NULL))
3184 			return NULL;
3185 	}
3186 
3187 	dbWireEncoder ncdr;
3188 	ncdr.begin(dbWire::create(nwnet));
3189 
3190 	int fwidth;
3191 	if (indir == dbTechLayerDir::NONE)
3192 	  fwidth = MIN(x2 - x1, y2 - y1);
3193 	else
3194 	  fwidth = (indir == dbTechLayerDir::VERTICAL) ? x2 - x1 : y2 - y1;
3195 
3196 	uint hwidth = fwidth/2;
3197 
3198 	if (inly->getWidth()==fwidth) {
3199 		ncdr.newPath(inly, dbWireType::ROUTED);
3200 	}
3201 	else {
3202 		dbSet<dbTechNonDefaultRule> nd_rules = intech->getNonDefaultRules();
3203 		dbSet<dbTechNonDefaultRule>::iterator nditr;
3204 		dbTechLayerRule *tst_rule;
3205 		dbTechNonDefaultRule  *wdth_rule = NULL;
3206 		for (nditr = nd_rules.begin(); nditr != nd_rules.end(); ++nditr)
3207 		{
3208 			tst_rule = (*nditr)->getLayerRule(inly);
3209 			if (tst_rule && (tst_rule->getWidth() == fwidth))
3210 			{
3211 				wdth_rule = (*nditr);
3212 				break;
3213 			}
3214 		}
3215 
3216 		char  rule_name[14];
3217 		dbTechLayer *curly;
3218 		if (!wdth_rule)
3219 		{
3220 			// Find first open slot, opendx static so only search once
3221 			if (opendx == -1)
3222 			{
3223 				for (opendx = 1; opendx <= 300000; ++opendx)
3224 				{
3225 					snprintf(rule_name, 14, "ADS_ND_%d", opendx);
3226 					if ((wdth_rule = dbTechNonDefaultRule::create(intech, rule_name)) != NULL)
3227 						break;
3228 				}
3229 			}
3230 			else
3231 			{
3232 				snprintf(rule_name, 14, "ADS_ND_%d", ++opendx);
3233 				assert(wdth_rule = dbTechNonDefaultRule::create(intech, rule_name));
3234 			}
3235 
3236 			if (!wdth_rule)
3237 			{
3238 
3239 				getImpl()->getLogger()->warn(utl::ODB, 14, "Failed to generate non-default rule for single wire net {}", innm);
3240 				return NULL;
3241 			}
3242 
3243 			dbTechLayerRule *curly_rule;
3244 			int i;
3245 			for (i = 1; i <= 12; i++)   // Twelve routing layers??
3246 			{
3247 				if ((curly = intech->findRoutingLayer(i)) != NULL)
3248 				{
3249 					curly_rule = dbTechLayerRule::create(wdth_rule, curly);
3250 					curly_rule->setWidth(MAX(fwidth,curly->getWidth()));
3251 					curly_rule->setSpacing(curly->getSpacing());
3252 				}
3253 			}
3254 
3255 			dbTechVia  *curly_via;
3256 			dbSet<dbTechVia> all_vias = intech->getVias();
3257 			dbSet<dbTechVia>::iterator viter;
3258 			std::string  nd_via_name("");
3259 			for (viter = all_vias.begin(); viter != all_vias.end(); ++viter)
3260 			{
3261 				if (((*viter)->getNonDefaultRule() == NULL) && ((*viter)->isDefault()))
3262 				{
3263 					nd_via_name = std::string(rule_name) + std::string("_") + std::string((*viter)->getName().c_str());
3264 					curly_via = dbTechVia::clone(wdth_rule, (*viter), nd_via_name.c_str());
3265 				}
3266 			}
3267 		}
3268 
3269 		ncdr.newPath(inly, dbWireType::ROUTED, wdth_rule->getLayerRule(inly));
3270 	}
3271 	if (((x2-x1) == fwidth) || (indir == dbTechLayerDir::VERTICAL)) {
3272 		if ((y2-y1) == fwidth)
3273 			ncdr.addPoint(x1+hwidth, y1+hwidth);
3274 		else
3275 			ncdr.addPoint(x1+hwidth, y1, 0);
3276 		//ncdr.addPoint(x1+hwidth, y2);
3277 	}
3278 	else
3279 		ncdr.addPoint(x1, y1+hwidth, 0);
3280 
3281 	if (! skipBterms )
3282 		ncdr.addBTerm(blutrms.first);
3283 
3284 	if (((x2-x1) == fwidth) || (indir == dbTechLayerDir::VERTICAL)) {
3285 		if ((y2-y1) == fwidth)
3286 			ncdr.addPoint(x1+hwidth, y2-hwidth+1);
3287 		else
3288 			ncdr.addPoint(x1+hwidth, y2, 0);
3289 		//ncdr.addPoint(x1+hwidth, y2);
3290 	}
3291 	else
3292 		ncdr.addPoint(x2, y1+hwidth, 0);
3293 
3294 	if (! skipBterms )
3295 		ncdr.addBTerm(blutrms.second);
3296 
3297 	ncdr.end();
3298 
3299 	return nwnet;
3300 }
3301 #endif
3302 
3303 //
3304 // Utility to save_lef
3305 //
3306 
saveLef(char * filename)3307 void dbBlock::saveLef(char* filename)
3308 {
3309   lefout writer;
3310   dbLib* lib = getChip()->getDb()->findLib("lib");
3311   if (lib == NULL) {
3312     getImpl()->getLogger()->warn(utl::ODB, 15, "Library lib does not exist");
3313     return;
3314   }
3315   if (!writer.writeTechAndLib(lib, filename)) {
3316     getImpl()->getLogger()->warn(
3317         utl::ODB, 16, "Failed to write lef file {}", filename);
3318   }
3319 }
3320 
3321 //
3322 // Utility to save_def
3323 //
3324 
saveDef(char * filename,char * nets)3325 void dbBlock::saveDef(char* filename, char* nets)
3326 {
3327   std::vector<dbNet*> inets;
3328   findSomeNet(nets, inets);
3329   defout writer(getImpl()->getLogger());
3330   dbNet* net;
3331   uint jj;
3332   for (jj = 0; jj < inets.size(); jj++) {
3333     net = inets[jj];
3334     writer.selectNet(net);
3335   }
3336   if (!writer.writeBlock(this, filename))
3337     getImpl()->getLogger()->warn(
3338         utl::ODB, 17, "Failed to write def file {}", filename);
3339 }
3340 
3341 //
3342 // Utility to write db file
3343 //
3344 
writeDb(char * filename,int allNode)3345 void dbBlock::writeDb(char* filename, int allNode)
3346 {
3347   _dbBlock* block = (_dbBlock*) this;
3348   char dbname[max_name_length];
3349   if (allNode) {
3350     if (block->_journal)
3351       sprintf(dbname, "%s.main.%d.db", filename, getpid());
3352     else
3353       sprintf(dbname, "%s.remote.%d.db", filename, getpid());
3354   } else
3355     sprintf(dbname, "%s.db", filename);
3356   FILE* file = fopen(dbname, "wb");
3357   if (!file) {
3358     getImpl()->getLogger()->warn(
3359         utl::ODB, 19, "Can not open file {} to write!", dbname);
3360     return;
3361   }
3362   int io_bufsize = 65536;
3363   char* buffer = (char*) malloc(io_bufsize);
3364   if (buffer == NULL) {
3365     getImpl()->getLogger()->warn(
3366         utl::ODB, 20, "Memory allocation failed for io buffer");
3367     fclose(file);
3368     return;
3369   }
3370   setvbuf(file, buffer, _IOFBF, io_bufsize);
3371   getDataBase()->write(file);
3372   free((void*) buffer);
3373   fclose(file);
3374   if (block->_journal) {
3375     debugPrint(getImpl()->getLogger(),
3376                utl::ODB,
3377                "DB_ECO",
3378                1,
3379                "ECO: dbBlock {}, writeDb",
3380                block->getId());
3381     block->_journal->beginAction(dbJournal::UPDATE_FIELD);
3382     block->_journal->pushParam(dbBlockObj);
3383     block->_journal->pushParam(block->getId());
3384     block->_journal->pushParam(_dbBlock::WRITEDB);
3385     block->_journal->pushParam(filename);
3386     block->_journal->pushParam(allNode);
3387     block->_journal->endAction();
3388   }
3389 }
3390 
differences(dbBlock * block1,dbBlock * block2,FILE * out,int indent)3391 bool dbBlock::differences(dbBlock* block1,
3392                           dbBlock* block2,
3393                           FILE* out,
3394                           int indent)
3395 {
3396   _dbBlock* b1 = (_dbBlock*) block1;
3397   _dbBlock* b2 = (_dbBlock*) block2;
3398 
3399   dbDiff diff(out);
3400   diff.setDeepDiff(true);
3401   diff.setIndentPerLevel(indent);
3402   b1->differences(diff, NULL, *b2);
3403   return diff.hasDifferences();
3404 }
3405 
levelize(std::vector<dbInst * > & startingInsts,std::vector<dbInst * > & instsToBeLeveled)3406 uint dbBlock::levelize(std::vector<dbInst*>& startingInsts,
3407                        std::vector<dbInst*>& instsToBeLeveled)
3408 {
3409   if (startingInsts.size() <= 0)
3410     return 0;
3411 
3412   std::vector<dbInst*>::iterator itr;
3413   for (itr = startingInsts.begin(); itr != startingInsts.end(); ++itr) {
3414     dbInst* inst = *itr;
3415     int l = inst->getLevel();
3416     if (l == 0)
3417       continue;
3418     uint level = 0;
3419     if (l < 0)
3420       level = -l;
3421     else
3422       level = l;
3423     dbSet<dbITerm> iterms = inst->getITerms();
3424     dbSet<dbITerm>::iterator iitr;
3425     for (iitr = iterms.begin(); iitr != iterms.end(); ++iitr) {
3426       dbITerm* iterm = *iitr;
3427       if ((iterm->getSigType() == dbSigType::GROUND)
3428           || (iterm->getSigType() == dbSigType::POWER))
3429         continue;
3430 
3431       if ((iterm->getIoType() == dbIoType::INPUT)
3432           || (iterm->getIoType() == dbIoType::INOUT))
3433         continue;
3434 
3435       dbNet* net = iterm->getNet();
3436       if (net != NULL) {
3437         net->setLevelAtFanout(level + 1, false, instsToBeLeveled);
3438       }
3439     }
3440   }
3441   return instsToBeLeveled.size();
3442 }
levelizeFromPrimaryInputs()3443 uint dbBlock::levelizeFromPrimaryInputs()
3444 {
3445   dbSet<dbBTerm> bterms = getBTerms();
3446   dbSet<dbBTerm>::iterator bitr;
3447 
3448   std::vector<dbInst*> instsToBeLeveled;
3449 
3450   uint level = 1;
3451   for (bitr = bterms.begin(); bitr != bterms.end(); ++bitr) {
3452     dbBTerm* bterm = *bitr;
3453 
3454     dbNet* net = bterm->getNet();
3455 
3456     if (net != NULL) {
3457       if ((net->getSigType() == dbSigType::GROUND)
3458           || (net->getSigType() == dbSigType::POWER))
3459         continue;
3460 
3461       net->setLevelAtFanout(level, true, instsToBeLeveled);
3462     }
3463   }
3464   if (instsToBeLeveled.size() <= 0)
3465     return 0;
3466 
3467   while (1) {
3468     std::vector<dbInst*> startingInsts = instsToBeLeveled;
3469     instsToBeLeveled.clear();
3470 
3471     uint cnt = levelize(startingInsts, instsToBeLeveled);
3472     if (cnt == 0)
3473       break;
3474   }
3475   return 0;
3476 }
levelizeFromSequential()3477 uint dbBlock::levelizeFromSequential()
3478 {
3479   std::vector<dbInst*> instsToBeLeveled;
3480 
3481   dbSet<dbInst> insts = getInsts();
3482   dbSet<dbInst>::iterator iitr;
3483 
3484   for (iitr = insts.begin(); iitr != insts.end(); ++iitr) {
3485     dbInst* inst = *iitr;
3486     if (!inst->getMaster()->isSequential())
3487       continue;
3488     inst->setLevel(1, false);
3489     instsToBeLeveled.push_back(inst);
3490   }
3491   if (instsToBeLeveled.size() <= 0)
3492     return 0;
3493 
3494   while (1) {
3495     std::vector<dbInst*> startingInsts = instsToBeLeveled;
3496     instsToBeLeveled.clear();
3497 
3498     uint cnt = levelize(startingInsts, instsToBeLeveled);
3499     if (cnt == 0)
3500       break;
3501   }
3502   return 0;
3503 }
markBackwardsUser2(dbInst * firstInst,bool mark,std::vector<dbInst * > & resultTable)3504 int dbBlock::markBackwardsUser2(dbInst* firstInst,
3505                                 bool mark,
3506                                 std::vector<dbInst*>& resultTable)
3507 {
3508   std::vector<dbInst*> instsToBeMarked;
3509 
3510   if (firstInst == NULL) {
3511     dbSet<dbInst> insts = getInsts();
3512     dbSet<dbInst>::iterator iitr;
3513 
3514     for (iitr = insts.begin(); iitr != insts.end(); ++iitr) {
3515       dbInst* inst = *iitr;
3516       if (!inst->getMaster()->isSequential())
3517         continue;
3518 
3519       instsToBeMarked.push_back(inst);
3520     }
3521   } else {
3522     instsToBeMarked.push_back(firstInst);
3523   }
3524   if (instsToBeMarked.size() <= 0)
3525     return 0;
3526 
3527   while (1) {
3528     std::vector<dbInst*> startingInsts = instsToBeMarked;
3529     instsToBeMarked.clear();
3530 
3531     int cnt
3532         = markBackwardsUser2(startingInsts, instsToBeMarked, mark, resultTable);
3533     if (cnt == 0)
3534       break;
3535     if (!mark && (cnt < 0))
3536       return -1;
3537   }
3538   return 0;
3539 }
3540 /*
3541 int dbBlock::markBackwardsUser2(std::vector<dbInst *> & startingInsts,
3542 std::vector<dbInst *> & instsToMark, bool mark, std::vector<dbInst *> &
3543 resultTable)
3544 {
3545         if (startingInsts.size()<=0)
3546                 return 0;
3547 
3548         std::vector<dbInst *>::iterator itr;
3549         for (itr= startingInsts.begin(); itr != startingInsts.end(); ++itr)
3550         {
3551                 dbInst *inst= *itr;
3552                 if (mark) {
3553                         inst->setUserFlag2();
3554                         //resultTable.push_back(inst);
3555                 }
3556                 else if (inst->getUserFlag2())
3557                         return -1;
3558 
3559                 dbSet<dbITerm> iterms= inst->getITerms();
3560                 dbSet<dbITerm>::iterator iitr;
3561                 for (iitr= iterms.begin(); iitr != iterms.end(); ++iitr)
3562                 {
3563                         dbITerm *iterm= *iitr;
3564                         if ((iterm->getSigType() == dbSigType::GROUND)||
3565 (iterm->getSigType() == dbSigType::POWER)) continue; if
3566 (!iterm->isInputSignal()) continue; if (iterm->isClocked()) continue;
3567 
3568                         dbNet *inputNet= iterm->getNet();
3569 
3570                         if (inputNet==NULL)
3571                                 continue;
3572 
3573                         if ((inputNet->getSigType()==dbSigType::GROUND)||
3574 (inputNet->getSigType()==dbSigType::POWER)) continue;
3575 
3576                         dbITerm* out= inputNet->getFirstOutput();
3577 
3578                         if (out==NULL)
3579                                 continue;
3580 
3581                         dbInst *faninInst= out->getInst();
3582                         if
3583 (faninInst->getMaster()->getType()!=dbMasterType::CORE) continue;
3584 
3585                         if (mark) {
3586                                 if (! faninInst->getUserFlag2()) {
3587                                         faninInst->setUserFlag2();
3588                                         resultTable.push_back(faninInst);
3589                                 }
3590                         }
3591                         else if (faninInst->getUserFlag2())
3592                                 return -1;
3593 
3594                         if (! faninInst->getMaster()->isSequential())
3595                                 instsToMark.push_back(faninInst);
3596                 }
3597         }
3598         return instsToMark.size();
3599 }
3600 */
3601 #define FAST_INST_TERMS
markBackwardsUser2(std::vector<dbInst * > & startingInsts,std::vector<dbInst * > & instsToMark,bool mark,std::vector<dbInst * > & resultTable)3602 int dbBlock::markBackwardsUser2(std::vector<dbInst*>& startingInsts,
3603                                 std::vector<dbInst*>& instsToMark,
3604                                 bool mark,
3605                                 std::vector<dbInst*>& resultTable)
3606 {
3607   if (startingInsts.size() <= 0)
3608     return 0;
3609 
3610   // notice(0, ">>> markBackwardsUser2:%d startingInsts    %d resultTable\n",
3611   // startingInsts.size(), resultTable.size());
3612   std::vector<dbInst*>::iterator itr;
3613   for (itr = startingInsts.begin(); itr != startingInsts.end(); ++itr) {
3614     dbInst* inst = *itr;
3615 
3616     if (inst->getMaster()->isSequential())
3617       continue;
3618 
3619     if (mark) {
3620       ;  // inst->setUserFlag2();
3621       // resultTable.push_back(inst);
3622     } else if (inst->getUserFlag2())
3623       return -1;
3624 
3625 #ifdef FAST_INST_TERMS
3626     dbMaster* master = inst->getMaster();
3627     for (uint ii = 0; ii < (uint) master->getMTermCount(); ii++) {
3628       dbITerm* iterm = inst->getITerm(ii);
3629 #else
3630     dbSet<dbITerm> iterms = inst->getITerms();
3631     dbSet<dbITerm>::iterator iitr;
3632     for (iitr = iterms.begin(); iitr != iterms.end(); ++iitr) {
3633       dbITerm* iterm = *iitr;
3634 #endif
3635       if (!iterm->isInputSignal())
3636         continue;
3637       if (iterm->isClocked())
3638         continue;
3639 
3640       dbNet* inputNet = iterm->getNet();
3641 
3642       if (inputNet == NULL)
3643         continue;
3644 
3645       if ((inputNet->getSigType() == dbSigType::GROUND)
3646           || (inputNet->getSigType() == dbSigType::POWER))
3647         continue;
3648 
3649       dbITerm* out = inputNet->getFirstOutput();
3650 
3651       if (out == NULL)
3652         continue;
3653 
3654       dbInst* faninInst = out->getInst();
3655       if (faninInst->getMaster()->getType() != dbMasterType::CORE) {
3656         faninInst->setUserFlag2();
3657         continue;
3658       }
3659 
3660       if (mark) {
3661         if (!faninInst->getUserFlag2()) {
3662           faninInst->setUserFlag2();
3663           resultTable.push_back(faninInst);
3664           if (!faninInst->getMaster()->isSequential())
3665             instsToMark.push_back(faninInst);
3666         }
3667       } else if (faninInst->getUserFlag2()) {
3668         // notice(0, "<<< -1: markBackwardsUser2:     %d startingInsts    %d
3669         // resultTable   %d instsToMark\n", 	startingInsts.size(),
3670         // resultTable.size(), instsToMark.size());
3671         return -1;
3672       }
3673 
3674       // if (! faninInst->getMaster()->isSequential() && !
3675       // faninInst->getUserFlag2()) 	instsToMark.push_back(faninInst);
3676     }
3677   }
3678   // notice(0, "<<< -1: markBackwardsUser2:     %d startingInsts    %d
3679   // resultTable   %d instsToMark\n", 	startingInsts.size(),
3680   // resultTable.size(),
3681   // instsToMark.size());
3682   return instsToMark.size();
3683 }
3684 
3685 int dbBlock::markBackwardsUser2(dbNet* net,
3686                                 bool mark,
3687                                 std::vector<dbInst*>& resultTable)
3688 {
3689   std::vector<dbInst*> instsToBeMarked;
3690 
3691   int n = markBackwardsUser2(net, instsToBeMarked, mark, resultTable);
3692 
3693   if (n == 0)
3694     return 0;
3695   if (!mark && (n < 0))
3696     return -1;
3697 
3698   while (1) {
3699     std::vector<dbInst*> startingInsts = instsToBeMarked;
3700     instsToBeMarked.clear();
3701 
3702     int cnt
3703         = markBackwardsUser2(startingInsts, instsToBeMarked, mark, resultTable);
3704     if (cnt == 0)
3705       break;
3706     if (!mark && (cnt < 0))
3707       return -1;
3708   }
3709   return 0;
3710 }
3711 
3712 int dbBlock::markBackwardsUser2(dbNet* net,
3713                                 std::vector<dbInst*>& instsToMark,
3714                                 bool mark,
3715                                 std::vector<dbInst*>& resultTable)
3716 {
3717   if (net == NULL)
3718     return 0;
3719 
3720   dbITerm* out = net->getFirstOutput();
3721   if (out == NULL)
3722     return 0;
3723 
3724   dbInst* faninInst = out->getInst();
3725   if (mark) {
3726     if (!faninInst->getUserFlag2()) {
3727       faninInst->setUserFlag2();
3728       resultTable.push_back(faninInst);
3729     }
3730   } else if (faninInst->getUserFlag2())
3731     return -1;
3732 
3733   if (!faninInst->getMaster()->isSequential())
3734     instsToMark.push_back(faninInst);
3735 
3736   return instsToMark.size();
3737 }
3738 
3739 void dbBlock::markClockIterms()
3740 {
3741   std::vector<dbMaster*> masters;
3742   getMasters(masters);
3743   std::vector<dbMaster*>::iterator mtr;
3744   for (mtr = masters.begin(); mtr != masters.end(); ++mtr) {
3745     dbMaster* master = *mtr;
3746     if (master->getType() != dbMasterType::CORE)
3747       continue;
3748 
3749     bool clocked = false;
3750     int order_id = -1;
3751     master->setClockedIndex(-1);
3752     dbSet<dbMTerm> mterms = master->getMTerms();
3753     dbSet<dbMTerm>::iterator mitr;
3754     for (mitr = mterms.begin(); mitr != mterms.end(); ++mitr) {
3755       dbMTerm* mterm = *mitr;
3756       if (mterm->getSigType() == dbSigType::CLOCK) {
3757         clocked = true;
3758         order_id = mterm->getIndex();
3759         break;
3760       }
3761     }
3762     if (clocked) {
3763       master->setSequential(1);
3764       master->setClockedIndex(order_id);
3765     }
3766   }
3767   dbSet<dbInst> insts = getInsts();
3768   dbSet<dbInst>::iterator itr;
3769   for (itr = insts.begin(); itr != insts.end(); ++itr) {
3770     dbInst* inst = *itr;
3771     if (!inst->getMaster()->isSequential())
3772       continue;
3773 
3774     dbSet<dbITerm> iterms = inst->getITerms();
3775     dbSet<dbITerm>::iterator iitr;
3776     for (iitr = iterms.begin(); iitr != iterms.end(); ++iitr) {
3777       dbITerm* iterm = *iitr;
3778 
3779       if (iterm->getMTerm()->getSigType() == dbSigType::CLOCK) {
3780         iterm->setClocked(1);
3781         continue;
3782       }
3783     }
3784   }
3785 }
3786 void dbBlock::clearUserInstFlags()
3787 {
3788   dbSet<dbInst> insts = getInsts();
3789   dbSet<dbInst>::iterator itr;
3790   for (itr = insts.begin(); itr != insts.end(); ++itr) {
3791     dbInst* inst = *itr;
3792 
3793     inst->clearUserFlag2();
3794     inst->clearUserFlag1();
3795     inst->clearUserFlag3();
3796   }
3797 }
3798 void dbBlock::setDrivingItermsforNets()
3799 {
3800   dbSet<dbNet> nets = getNets();
3801   dbSet<dbNet>::iterator nitr;
3802 
3803   for (nitr = nets.begin(); nitr != nets.end(); ++nitr) {
3804     dbNet* net = *nitr;
3805     if ((net->getSigType() == dbSigType::GROUND)
3806         || (net->getSigType() == dbSigType::POWER))
3807       continue;
3808 
3809     net->setDrivingITerm(0);
3810     dbSet<dbITerm> iterms = net->getITerms();
3811     dbSet<dbITerm>::iterator iitr;
3812 
3813     for (iitr = iterms.begin(); iitr != iterms.end(); ++iitr) {
3814       dbITerm* tr = *iitr;
3815 
3816       if (tr->getIoType() == dbIoType::OUTPUT) {
3817         net->setDrivingITerm(tr->getId());
3818         break;
3819       }
3820     }
3821   }
3822 }
3823 
3824 void dbBlock::preExttreeMergeRC(double max_cap, uint corner)
3825 {
3826   if (!getExtControl()->_exttreePreMerg)
3827     return;
3828   if (max_cap == 0.0)
3829     max_cap = 10.0;
3830   if (getExtControl()->_exttreeMaxcap >= max_cap)
3831     return;
3832   getExtControl()->_exttreeMaxcap = max_cap;
3833   dbSet<dbNet> bnets = getNets();
3834   dbSet<dbNet>::iterator net_itr;
3835   dbNet* net;
3836   for (net_itr = bnets.begin(); net_itr != bnets.end(); ++net_itr) {
3837     net = *net_itr;
3838     net->preExttreeMergeRC(max_cap, corner);
3839   }
3840 }
3841 
3842 }  // namespace odb
3843