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