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 <dbExtControl.h>
34 #include <math.h>
35
36 #include <algorithm>
37
38 #include "parse.h"
39 #include "rcx/extRCap.h"
40 #include "rcx/extSpef.h"
41 #include "utl/Logger.h"
42
43 //#ifdef _WIN32
44 #define ATH__fprintf fprintf
45 #define ATH__fopen fopen
46 #define ATH__fclose fclose
47 //#endif
48
49 namespace rcx {
50
51 using utl::RCX;
52
writeHierInstNameMap()53 uint extSpef::writeHierInstNameMap() {
54 odb::dbSet<odb::dbInst> insts = _block->getInsts();
55 odb::dbSet<odb::dbInst>::iterator itr;
56
57 uint instCnt = 0;
58 for (itr = insts.begin(); itr != insts.end(); ++itr) {
59 odb::dbInst* inst = *itr;
60 odb::dbBlock* child = inst->getChild();
61
62 if (child == NULL)
63 continue;
64
65 odb::dbIntProperty::create(child, "_instSpefMapBase", _baseNameMap);
66 int baseMapId = extSpef::getIntProperty(child, "_instSpefMapBase");
67 debugPrint(logger_, RCX, "hierspef", 1,
68 "[HEXT:S]"
69 "\ninstMapBase {} : {} {}",
70 baseMapId, child->getConstName(), inst->getConstName());
71
72 uint mapId = 0;
73 odb::dbSet<odb::dbInst> binsts = child->getInsts();
74 odb::dbSet<odb::dbInst>::iterator bitr;
75 for (bitr = binsts.begin(); bitr != binsts.end(); ++bitr) {
76 odb::dbInst* ii = *bitr;
77
78 mapId = _baseNameMap + ii->getId();
79
80 char* nname = (char*)ii->getConstName();
81 char* nname1 = tinkerSpefName(nname);
82 ATH__fprintf(_outFP, "*%d %s/%s\n", mapId, inst->getConstName(), nname1);
83 debugPrint(logger_, RCX, "hierspef", 1, "[HEXT:S]", "\t{} {}/{}", mapId,
84 inst->getConstName(), nname1);
85
86 instCnt++;
87 }
88 _baseNameMap = mapId;
89 debugPrint(logger_, RCX, "hierspef", 1,
90 "[HEXT:S]"
91 "END_MAP {} inames : {}\n",
92 instCnt, child->getConstName());
93 }
94 return instCnt;
95 }
getIntProperty(odb::dbBlock * block,const char * name)96 int extSpef::getIntProperty(odb::dbBlock* block, const char* name) {
97 odb::dbProperty* p = odb::dbProperty::find(block, name);
98
99 if (p == NULL)
100 return 0;
101
102 odb::dbIntProperty* ip = (odb::dbIntProperty*)p;
103 return ip->getValue();
104 }
105
writeHierNetNameMap()106 uint extSpef::writeHierNetNameMap() {
107 odb::dbSet<odb::dbInst> insts = _block->getInsts();
108 odb::dbSet<odb::dbInst>::iterator itr;
109
110 uint netCnt = 0;
111 for (itr = insts.begin(); itr != insts.end(); ++itr) {
112 odb::dbInst* inst = *itr;
113 odb::dbBlock* child = inst->getChild();
114
115 if (child == NULL)
116 continue;
117
118 odb::dbIntProperty::create(child, "_netSpefMapBase", _baseNameMap);
119 int baseMapId = extSpef::getIntProperty(child, "_netSpefMapBase");
120
121 debugPrint(logger_, RCX, "hierspef", 1,
122 "[HEXT:S]"
123 "\nnetMapBase {} : {} {}",
124 baseMapId, child->getConstName(), inst->getConstName());
125
126 uint mapId = 0;
127 odb::dbSet<odb::dbNet> nets = child->getNets();
128 odb::dbSet<odb::dbNet>::iterator bitr;
129 for (bitr = nets.begin(); bitr != nets.end(); ++bitr) {
130 odb::dbNet* ii = *bitr;
131
132 if (ii->getBTermCount() > 0)
133 continue;
134
135 mapId = _baseNameMap + ii->getId();
136
137 char* nname = (char*)ii->getConstName();
138 char* nname1 = tinkerSpefName(nname);
139 ATH__fprintf(_outFP, "*%d %s/%s\n", mapId, inst->getConstName(), nname1);
140 debugPrint(logger_, RCX, "hierspef", 1, "[HEXT:S]", "\t{} {}/{}", mapId,
141 inst->getConstName(), nname1);
142 netCnt++;
143 }
144 _baseNameMap = mapId;
145 debugPrint(logger_, RCX, "hierspef", 1,
146 "[HEXT:S]"
147 "\tNET_MAP_END ({} internal nets) : {}\n",
148 netCnt, child->getConstName());
149 }
150 // OPTIMIZE this ; have to do due to 1st "null" rseg;
151 // if not, appending rsegs creates a havoc!
152
153 odb::dbSet<odb::dbNet> topnets = _block->getNets();
154 odb::dbSet<odb::dbNet>::iterator bitr;
155 for (bitr = topnets.begin(); bitr != topnets.end(); ++bitr) {
156 odb::dbNet* ii = *bitr;
157
158 // extMain::printRSegs(ii);
159 odb::dbSet<odb::dbRSeg> rSet = ii->getRSegs();
160 rSet.reverse();
161 // extMain::printRSegs(ii);
162 }
163 return netCnt;
164 }
markCCsegs(odb::dbBlock * blk,bool flag)165 uint extMain::markCCsegs(odb::dbBlock* blk, bool flag) {
166 odb::dbSet<odb::dbCCSeg> ccs = blk->getCCSegs();
167 odb::dbSet<odb::dbCCSeg>::iterator ccitr;
168 for (ccitr = ccs.begin(); ccitr != ccs.end(); ++ccitr) {
169 odb::dbCCSeg* cc = *ccitr;
170 cc->setMark(flag);
171 }
172 return ccs.size();
173 }
174
addRCtoTop(odb::dbBlock * blk,bool write_spef)175 uint extMain::addRCtoTop(odb::dbBlock* blk, bool write_spef) {
176 logger_->info(RCX, 232, "Merging Parasitics for Block {} : {} Into parent {}",
177 blk->getConstName(), blk->getParentInst()->getConstName(),
178 _block->getConstName());
179
180 // blk->getParent()->getConstName()
181
182 int netBaseMapId = extSpef::getIntProperty(blk, "_netSpefMapBase");
183 int instBaseMapId = extSpef::getIntProperty(blk, "_instSpefMapBase");
184 _spef->setHierBaseNameMap(instBaseMapId, netBaseMapId);
185
186 debugPrint(logger_, RCX, "hierspef", 1, "[HEXT:F]",
187 "\n\t_netSpefMapBase= {} _instSpefMapBase= {}", netBaseMapId,
188 instBaseMapId);
189
190 odb::dbSet<odb::dbCapNode> allcapnodes = blk->getCapNodes();
191 uint blockCapSize = allcapnodes.size();
192
193 uint* capNodeMap = new uint[2 * blockCapSize + 1];
194
195 bool foreign = false;
196 uint spefCnt = 0;
197 uint flatCnt = 0;
198 uint gCnt = 0;
199 uint rCnt = 0;
200 uint ccCnt = 0;
201 double resBound = 0.0;
202 uint dbg = 0;
203
204 odb::dbNet* topDummyNodeNet = _block->findNet("dummy_sub_block_cap_nodes");
205 if (topDummyNodeNet == NULL)
206 topDummyNodeNet = odb::dbNet::create(_block, "dummy_sub_block_cap_nodes");
207
208 odb::dbSet<odb::dbNet> nets = blk->getNets();
209 odb::dbSet<odb::dbNet>::iterator bitr;
210 for (bitr = nets.begin(); bitr != nets.end(); ++bitr) {
211 odb::dbNet* net = *bitr;
212
213 if (!net->setIOflag())
214 continue;
215
216 odb::dbBTerm* bterm = net->get1stBTerm();
217 odb::dbITerm* iterm = bterm->getITerm();
218 odb::dbNet* parentNet = iterm->getNet();
219 if (parentNet == NULL) {
220 logger_->warn(RCX, 408, "Null parent[{}] net : {}", net->getBTermCount(),
221 net->getConstName());
222 continue;
223 }
224
225 gCnt += createCapNodes(net, parentNet, capNodeMap, instBaseMapId);
226 rCnt += createRSegs(net, parentNet, capNodeMap);
227 flatCnt++;
228 }
229 markCCsegs(blk, false);
230 for (bitr = nets.begin(); bitr != nets.end(); ++bitr) {
231 odb::dbNet* net = *bitr;
232 if (!net->isIO())
233 continue;
234
235 odb::dbBTerm* bterm = net->get1stBTerm();
236 odb::dbITerm* iterm = bterm->getITerm();
237 odb::dbNet* parentNet = iterm->getNet();
238 if (parentNet == NULL) {
239 logger_->warn(RCX, 233, "Null parent[{}] net : {}", net->getBTermCount(),
240 net->getConstName());
241 continue;
242 }
243
244 ccCnt += createCCsegs(net, parentNet, topDummyNodeNet, capNodeMap,
245 instBaseMapId);
246 }
247 markCCsegs(blk, false);
248
249 _spef->setBlock(blk);
250 for (bitr = nets.begin(); bitr != nets.end(); ++bitr) {
251 odb::dbNet* net = *bitr;
252 if (net->isIO())
253 continue;
254
255 // extMain::printRSegs(net);
256 if (write_spef)
257 spefCnt += _spef->writeHierNet(net, resBound, dbg);
258 }
259 _spef->setBlock(_block);
260 logger_->info(RCX, 235,
261 "{} internal {} IO nets {} gCaps {} rSegs {} ccCaps : {}",
262 spefCnt, flatCnt, gCnt, rCnt, ccCnt, blk->getConstName());
263
264 delete[] capNodeMap;
265 return flatCnt + spefCnt;
266 }
adjustParentNode(odb::dbNet * net,odb::dbITerm * from_child_iterm,uint node_num)267 uint extMain::adjustParentNode(odb::dbNet* net, odb::dbITerm* from_child_iterm,
268 uint node_num) {
269 odb::dbSet<odb::dbCapNode> capNodes = net->getCapNodes();
270 odb::dbSet<odb::dbCapNode>::iterator cap_node_itr = capNodes.begin();
271 for (; cap_node_itr != capNodes.end(); ++cap_node_itr) {
272 odb::dbCapNode* node = *cap_node_itr;
273 if (!node->isITerm())
274 continue;
275 odb::dbITerm* iterm = node->getITerm();
276 if (iterm != from_child_iterm)
277 continue;
278
279 node->resetITermFlag();
280 node->setInternalFlag();
281
282 node->setNode(node_num);
283
284 return node->getId();
285 }
286 return 0;
287 }
288
createParentCapNode(odb::dbCapNode * node,odb::dbNet * parentNet,uint nodeNum,uint * capNodeMap,uint baseNum)289 bool extMain::createParentCapNode(odb::dbCapNode* node, odb::dbNet* parentNet,
290 uint nodeNum, uint* capNodeMap,
291 uint baseNum) {
292 bool foreign = false;
293 char buf[1024];
294
295 odb::dbCapNode* cap = NULL;
296 if (!node->isBTerm()) { //
297 cap = odb::dbCapNode::create(parentNet, nodeNum, foreign);
298 capNodeMap[node->getId()] = cap->getId();
299 }
300 if (node->isInternal()) { //
301 cap->setInternalFlag();
302
303 debugPrint(logger_, RCX, "hierspef", 1,
304 "[HEXT:C]"
305 "\t\tG intrn {} --> {}",
306 node->getId(), capNodeMap[node->getId()]);
307 } else if (node->isITerm()) { //
308 odb::dbITerm* iterm = node->getITerm();
309 odb::dbInst* inst = iterm->getInst();
310 uint instId = inst->getId();
311 sprintf(buf, "*%d%s%s", baseNum + instId, _spef->getDelimeter(),
312 iterm->getMTerm()->getConstName());
313
314 odb::dbStringProperty::create(cap, "_inode", buf);
315 cap->setNode(baseNum + instId); // so there is some value
316 cap->setNameFlag();
317
318 debugPrint(logger_, RCX, "hierspef", 1,
319 "[HEXT:C]"
320 "\t\tG ITerm {} --> {} : {}",
321 node->getId(), capNodeMap[node->getId()], buf);
322 } else if (node->isBTerm()) { //
323
324 odb::dbBTerm* bterm = node->getBTerm();
325 odb::dbITerm* iterm = bterm->getITerm();
326 uint parentId = adjustParentNode(parentNet, iterm, nodeNum);
327 capNodeMap[node->getId()] = parentId;
328
329 debugPrint(logger_, RCX, "hierspef", 1,
330 "[HEXT:C]"
331 "\t\tG BTerm {} --> {} : {}",
332 node->getId(), parentId, nodeNum);
333 }
334 return true;
335 }
createTop1stRseg(odb::dbNet * net,odb::dbNet * parentNet)336 void extMain::createTop1stRseg(odb::dbNet* net, odb::dbNet* parentNet) {
337 if (parentNet->getWire() != NULL)
338 return;
339
340 odb::dbBTerm* bterm = net->get1stBTerm();
341 odb::dbITerm* iterm = bterm->getITerm();
342
343 odb::dbCapNode* cap =
344 odb::dbCapNode::create(parentNet, 0, /*_foreign*/ false);
345 cap->setNode(iterm->getId());
346 cap->setITermFlag();
347 odb::dbRSeg* rc = odb::dbRSeg::create(parentNet, 0, 0, 0, true);
348 rc->setTargetNode(cap->getId());
349 }
createCapNodes(odb::dbNet * net,odb::dbNet * parentNet,uint * capNodeMap,uint baseNum)350 uint extMain::createCapNodes(odb::dbNet* net, odb::dbNet* parentNet,
351 uint* capNodeMap, uint baseNum) {
352 createTop1stRseg(net, parentNet);
353
354 // have to improve for performance
355 uint maxCap = parentNet->maxInternalCapNum() + 1;
356 debugPrint(logger_, RCX, "hierspef", 1,
357 "[HEXT:C]"
358 "\n\tCapNodes: maxCap={} : {} {}",
359 maxCap, net->getConstName(), parentNet->getConstName());
360
361 uint gCnt = 0;
362 bool foreign = false;
363 char buf[1024];
364 odb::dbSet<odb::dbCapNode> capNodes = net->getCapNodes();
365 odb::dbSet<odb::dbCapNode>::iterator cap_node_itr = capNodes.begin();
366 for (; cap_node_itr != capNodes.end(); ++cap_node_itr) {
367 odb::dbCapNode* node = *cap_node_itr;
368
369 uint nodeNum = maxCap++;
370
371 gCnt += createParentCapNode(node, parentNet, nodeNum, capNodeMap, baseNum);
372 }
373 return gCnt;
374 }
printRSegs(odb::dbNet * net,Logger * logger)375 uint extMain::printRSegs(odb::dbNet* net, Logger* logger) {
376 logger->info(RCX, 236, "\t\t\tprintRSegs: {}", net->getConstName());
377 odb::dbSet<odb::dbRSeg> rsegs = net->getRSegs();
378 uint rsize = rsegs.size();
379
380 uint rCnt = 0;
381 odb::dbSet<odb::dbRSeg>::iterator rseg_itr = rsegs.begin();
382 for (; rseg_itr != rsegs.end(); ++rseg_itr) {
383 odb::dbRSeg* rseg = *rseg_itr;
384
385 logger->info(RCX, 234, "\t\t\t\t\trsegId: {} -- {} {}", rseg->getId(),
386 rseg->getSourceNode(), rseg->getTargetNode());
387 rCnt++;
388 }
389 return rCnt;
390 }
createRSegs(odb::dbNet * net,odb::dbNet * parentNet,uint * capNodeMap)391 uint extMain::createRSegs(odb::dbNet* net, odb::dbNet* parentNet,
392 uint* capNodeMap) {
393 debugPrint(logger_, RCX, "hierspef", 1,
394 "[HEXT:R]"
395 "\n\tRSegs: {} {}",
396 net->getConstName(), parentNet->getConstName());
397
398 // extMain::printRSegs(parentNet);
399
400 odb::dbSet<odb::dbRSeg> rsegs = net->getRSegs();
401 uint rsize = rsegs.size();
402
403 uint rCnt = 0;
404 odb::dbSet<odb::dbRSeg>::iterator rseg_itr = rsegs.begin();
405 for (; rseg_itr != rsegs.end(); ++rseg_itr) {
406 odb::dbRSeg* rseg = *rseg_itr;
407
408 int x, y;
409 rseg->getCoords(x, y);
410 uint pathDir = rseg->pathLowToHigh() ? 0 : 1;
411 odb::dbRSeg* rc = odb::dbRSeg::create(parentNet, x, y, pathDir, true);
412
413 uint tgtId = rseg->getTargetNode();
414 uint srcId = rseg->getSourceNode();
415
416 rc->setSourceNode(capNodeMap[srcId]);
417 rc->setTargetNode(capNodeMap[tgtId]);
418
419 for (uint corner = 0; corner < _block->getCornerCount(); corner++) {
420 double res = rseg->getResistance(corner);
421 double cap = rseg->getCapacitance(corner);
422
423 rc->setResistance(res, corner);
424 rc->setCapacitance(cap, corner);
425 debugPrint(logger_, RCX, "hierspef", 1,
426 "[HEXT:R]"
427 "\t\tsrc:{}->{} - tgt:{}->{} - {} {}",
428 srcId, capNodeMap[srcId], tgtId, capNodeMap[tgtId], res, cap);
429 }
430 rCnt++;
431 }
432 // extMain::printRSegs(parentNet);
433 /*
434 if (rCnt>0) {
435 odb::dbSet<odb::dbRSeg> rSet= parentNet->getRSegs();
436 //rSet.reverse();
437 }
438 */
439 return rCnt;
440 }
adjustChildNode(odb::dbCapNode * childNode,odb::dbNet * parentNet,uint * capNodeMap)441 void extMain::adjustChildNode(odb::dbCapNode* childNode, odb::dbNet* parentNet,
442 uint* capNodeMap) {
443 char buf[1024];
444 uint parentId = capNodeMap[childNode->getId()];
445 odb::dbCapNode* parentNode = odb::dbCapNode::getCapNode(_block, parentId);
446
447 if (childNode->isInternal() || childNode->isBTerm()) { //
448 childNode->resetInternalFlag();
449 childNode->resetBTermFlag();
450
451 // spefParentNameId == parent netId (just lucky!!)
452 sprintf(buf, "*%d%s%d", parentNet->getId(), _spef->getDelimeter(),
453 parentNode->getNode());
454
455 odb::dbStringProperty::create(childNode, "_inode", buf);
456
457 debugPrint(logger_, RCX, "hierspef", 1,
458 "[HEXT:CC]"
459 "\t\tCC intNode {} --> {} : {}",
460 childNode->getId(), parentId, buf);
461 } else if (childNode->isITerm()) { //
462 childNode->resetITermFlag();
463
464 odb::dbStringProperty* p =
465 odb::dbStringProperty::find(parentNode, "_inode");
466 odb::dbStringProperty::create(childNode, "_inode", p->getValue().c_str());
467
468 debugPrint(logger_, RCX, "hierspef", 1,
469 "[HEXT:CC]"
470 "\t\tCC ITermNode {} --> {} : {}",
471 childNode->getId(), parentId, p->getValue().c_str());
472 }
473 childNode->setNameFlag();
474 }
475
createCCsegs(odb::dbNet * net,odb::dbNet * parentNet,odb::dbNet * topDummyNet,uint * capNodeMap,uint baseNum)476 uint extMain::createCCsegs(odb::dbNet* net, odb::dbNet* parentNet,
477 odb::dbNet* topDummyNet, uint* capNodeMap,
478 uint baseNum) {
479 // IO nets
480
481 // have to improve for performance
482 uint maxCap = parentNet->maxInternalCapNum() + 1;
483
484 debugPrint(logger_, RCX, "hierspef", 1,
485 "[HEXT:CC]"
486 "\tCCsegs: maxCap[{}] {} {}",
487 maxCap, net->getConstName(), parentNet->getConstName());
488
489 odb::dbBlock* pblock = parentNet->getBlock();
490 uint ccCnt = 0;
491
492 odb::dbSet<odb::dbCapNode> nodeSet = net->getCapNodes();
493 odb::dbSet<odb::dbCapNode>::iterator rc_itr;
494 for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
495 odb::dbCapNode* srcCapNode = *rc_itr;
496
497 odb::dbSet<odb::dbCCSeg> ccsegs = srcCapNode->getCCSegs();
498 odb::dbSet<odb::dbCCSeg>::iterator ccseg_itr = ccsegs.begin();
499 for (; ccseg_itr != ccsegs.end(); ++ccseg_itr) {
500 odb::dbCCSeg* cc = *ccseg_itr;
501
502 if (cc->isMarked())
503 continue;
504
505 odb::dbCapNode* dstCapNode = cc->getTargetCapNode();
506 if (cc->getSourceCapNode() != srcCapNode) {
507 dstCapNode = cc->getSourceCapNode();
508 }
509 if (!dstCapNode->getNet()->isIO()) {
510 uint nodeNum = maxCap++;
511 createParentCapNode(dstCapNode, topDummyNet, nodeNum, capNodeMap,
512 baseNum);
513 adjustChildNode(srcCapNode, parentNet, capNodeMap);
514 }
515 uint tId = dstCapNode->getId();
516 uint sId = srcCapNode->getId();
517 uint tgtId = capNodeMap[tId];
518 uint srcId = capNodeMap[sId];
519
520 odb::dbCapNode* map_tgt = odb::dbCapNode::getCapNode(pblock, tgtId);
521 odb::dbCapNode* map_src = odb::dbCapNode::getCapNode(pblock, srcId);
522
523 odb::dbCCSeg* ccap = odb::dbCCSeg::create(map_src, map_tgt, false);
524
525 for (uint corner = 0; corner < _block->getCornerCount(); corner++) {
526 double cap = cc->getCapacitance(corner);
527 ccap->setCapacitance(cap, corner);
528
529 debugPrint(logger_, RCX, "hierspef", 1,
530 "[HEXT:C]"
531 "\t\tCC src:{}->{} tgt:{}->{} CC {:g}\n",
532 sId, srcId, tId, tgtId, cap);
533 }
534 cc->setMark(true);
535 }
536 }
537 return maxCap;
538 }
539 /*
540 uint extMain::adjustCCsegs(odb::dbNet *net, uint baseNum)
541 {
542 //Internal nets
543
544 // have to improve for performance
545 uint maxCap= parentNet->maxInternalCapNum()+1;
546
547 debugPrint(logger_, RCX, "hierspef", 1,
548 "[HEXT:F]"
549 "\tCCsegs: maxCap[{}] {} {}\n", maxCap,
550 net->getConstName(), parentNet->getConstName());
551
552 odb::dbBlock *pblock= parentNet->getBlock();
553 uint ccCnt= 0;
554
555 odb::dbSet<odb::dbCapNode> nodeSet = net->getCapNodes();
556 odb::dbSet<odb::dbCapNode>::iterator rc_itr;
557 for( rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr ) {
558 odb::dbCapNode *srcCapNode = *rc_itr;
559
560 odb::dbSet<odb::dbCCSeg> ccsegs= srcCapNode->getCCSegs();
561 odb::dbSet<odb::dbCCSeg>::iterator ccseg_itr= ccsegs.begin();
562 for( ; ccseg_itr != ccsegs.end(); ++ccseg_itr ) {
563 odb::dbCCSeg *cc= *ccseg_itr;
564
565 if (cc->isMarked())
566 continue;
567
568 adjustChildNode(srcCapNode, parentNet,
569 capNodeMap); cc->setMark(true);
570 }
571 }
572 return maxCap;
573 }
574 */
writeDnetHier(uint mapId,double * totCap)575 void extSpef::writeDnetHier(uint mapId, double* totCap) {
576 if (_writeNameMap)
577 ATH__fprintf(_outFP, "\n*D_NET *%d ", mapId);
578 // else
579 // ATH__fprintf(_outFP, "\n*D_NET %s ", tinkerSpefName((char
580 // *)_d_net->getConstName()));
581 writeRCvalue(totCap, _cap_unit);
582 ATH__fprintf(_outFP, "\n");
583 }
584
writeHierNet(odb::dbNet * net,double resBound,uint dbg)585 bool extSpef::writeHierNet(odb::dbNet* net, double resBound, uint dbg) {
586 _block = net->getBlock();
587 _d_net = net;
588 uint netId = net->getId();
589 _cornerBlock = net->getBlock();
590
591 _cornersPerBlock = _cornerCnt;
592
593 // if (_cornerBlock && _cornerBlock!=_block)
594 // net= odb::dbNet::getNet(_cornerBlock, netId);
595
596 uint minNode;
597 uint capNodeCnt = getMinCapNode(net, &minNode);
598 if (capNodeCnt == 0) {
599 logger_->warn(RCX, 237, "No cap nodes net: {}", net->getConstName());
600 return false;
601 }
602 odb::dbSet<odb::dbRSeg> rcSet = net->getRSegs();
603
604 _cCnt = 1;
605 // must set at calling _symmetricCCcaps= true; //TODO non symmetric case??
606 // must set at calling _preserveCapValues= false // true only for reading in
607 // SPEF
608
609 double totCap[5];
610 resetCap(totCap);
611 if (_symmetricCCcaps)
612 addCouplingCaps(net, totCap);
613
614 _firstCapNode = minNode - 1;
615
616 reinitCapTable(_nodeCapTable, capNodeCnt + 2);
617
618 if (_singleP)
619 computeCapsAdd2Target(rcSet, totCap);
620 else
621 computeCaps(rcSet, totCap);
622
623 debugPrint(logger_, RCX, "hierspef", 1,
624 "[HEXT:S]"
625 "\tDNET *{}-{} {:g} {}\n",
626 _childBlockNetBaseMap + netId, netId, totCap[0],
627 net->getConstName());
628
629 // netId= _childBlockNetBaseMap+netId;
630 writeDnetHier(_childBlockNetBaseMap + netId, totCap);
631
632 if (_wConn) {
633 writeKeyword("*CONN");
634 writePorts(net);
635 writeITerms(net);
636 }
637 if (_writingNodeCoords == C_STARRC)
638 writeNodeCoords(netId, rcSet);
639
640 if (_wCap || _wOnlyCCcap)
641 writeKeyword("*CAP");
642
643 if (_wCap && !_wOnlyCCcap) {
644 writeCapPorts(net);
645 writeCapITerms(net);
646 writeNodeCaps(net, _childBlockNetBaseMap + netId);
647 }
648
649 if (_wCap || _wOnlyCCcap)
650 writeSrcCouplingCaps(net);
651
652 if (_symmetricCCcaps && (_wCap || _wOnlyCCcap))
653 writeTgtCouplingCaps(net);
654
655 if (_wRes) {
656 writeRes(netId, rcSet);
657 }
658 writeKeyword("*END");
659
660 odb::dbSet<odb::dbCapNode> nodeSet = net->getCapNodes();
661 odb::dbSet<odb::dbCapNode>::iterator rc_itr;
662 for (rc_itr = nodeSet.begin(); rc_itr != nodeSet.end(); ++rc_itr) {
663 odb::dbCapNode* node = *rc_itr;
664 node->setSortIndex(0);
665 }
666 return true;
667 }
setHierBaseNameMap(uint instBase,uint netBase)668 void extSpef::setHierBaseNameMap(uint instBase, uint netBase) {
669 _childBlockNetBaseMap = netBase;
670 _childBlockInstBaseMap = instBase;
671 }
672
673 } // namespace rcx
674