00001 00002 #include "oagFpga.h" 00003 #include "oagFpgaManager.h" 00004 #include "oagAiGraph.h" 00005 #include <list> 00006 #include <map> 00007 #include <assert.h> 00008 #include <iostream> 00009 00010 #include "oagFpgaDebug.h" 00011 00012 namespace oagFpga { 00013 00014 00015 // ***************************************************************************** 00016 // Class static variable definitions. 00017 // ***************************************************************************** 00018 00019 #if defined(CACHE_LAST_MANAGER_LOOKUP) 00020 oa::oaDesign *Manager::lastManagerDesign; 00021 Manager *Manager::lastManagerObject; 00022 #endif 00023 00024 00025 // ***************************************************************************** 00026 // Manager() constructor 00039 // 00040 // ***************************************************************************** 00041 Manager::Manager(oa::oaDesign *design) { 00042 00043 // does this design already have a Manager associated with it? 00044 if(hasManager(design)) { 00045 cerr << "ERROR: Manager for design already exists" << endl; 00046 QUIT_ON_ERROR; 00047 } 00048 00049 // initialize variables and caches 00050 this->design = design; 00051 //preflattenedCache.clear(); 00052 00053 // associate this manager with the design by setting an AppDef 00054 managerAppDef->set(design, this); 00055 00056 // design must have a top module 00057 oa::oaModule *module; 00058 if (!(module = design->getTopModule())) { 00059 module = oa::oaModule::create(design); 00060 design->setTopModule(module); 00061 } 00062 00063 } 00064 00065 00066 // ***************************************************************************** 00067 // create() 00068 // 00070 // 00071 // ***************************************************************************** 00072 Manager * 00073 Manager::create(oa::oaDesign *design) { 00074 00075 if (hasManager(design)) { 00076 return static_cast<Manager*>(managerAppDef->get(design)); 00077 } 00078 00079 // there is no Manager yet associated with this design 00080 Manager *manager = new Manager(design); 00081 00082 // create a terminal BB node for each net in each module 00083 oa::oaModule *module; 00084 oa::oaIter<oa::oaModule> modIter(design->getModules()); 00085 while((module = modIter.getNext())) { 00086 oa::oaModBitNet *net; 00087 oa::oaIter<oa::oaModBitNet> netIter(module->getNets(oacNetIterAll)); 00088 while((net = netIter.getNext())) { 00089 if(net->getNumBits() > 1) { 00090 // YH: I don't understand why we don't create terminal BB for 00091 // multiBit-net 00092 // Guess: in oa::oaModBusNet::create routine, it will automatically 00093 // create multiple scalarNet in the same time when a bus net is created. 00094 #ifdef DEBUG 00095 oa::oaString str; 00096 net->getName(oa::oaVerilogNS(), str); 00097 DEBUG_PRINTLN("In create manager, busnet: " << str); 00098 #endif 00099 continue; 00100 } 00101 #ifdef DEBUG 00102 oa::oaString str; 00103 net->getName(oa::oaVerilogNS(), str); 00104 DEBUG_PRINTLN("In create manager, scalar net: " << str); 00105 #endif 00106 00107 // clear an existing AppDef, if it exists 00108 bbRefAppDef->destroy(net); 00109 AiRefAppDef->destroy(net); 00110 00111 // create a terminal to connect the net to the RTL graph 00112 manager->prepareNetToBBConnection(net); 00113 00114 // create a terminal to connect the net to the AI graph 00115 manager->prepareNetToAiConnection(net); 00116 } 00117 00118 // tie the 0 and 1 nets appropriately 00119 oa::oaNativeNS nativeNS; 00120 oa::oaModScalarNet *logicConstantNet; 00121 logicConstantNet = oa::oaModScalarNet::find(module, oa::oaScalarName(nativeNS, "tie0")); 00122 00123 if (logicConstantNet) { 00124 manager->bbg.setTerminalDriver(bbRefAppDef->get(logicConstantNet), 00125 manager->bbg.constantZero()); 00126 manager->ai.setTerminalDriver(AiRefAppDef->get(logicConstantNet), 00127 manager->ai.constantZero()); 00128 } 00129 00130 logicConstantNet = oa::oaModScalarNet::find(module, oa::oaScalarName(nativeNS, "tie1")); 00131 00132 if (logicConstantNet) { 00133 manager->bbg.setTerminalDriver(bbRefAppDef->get(logicConstantNet), 00134 manager->bbg.constantOne()); 00135 manager->ai.setTerminalDriver(AiRefAppDef->get(logicConstantNet), 00136 manager->ai.constantOne()); 00137 } 00138 } 00139 00140 return manager; 00141 } 00142 00143 00144 // ***************************************************************************** 00145 // destory() 00146 // 00148 // 00149 // ***************************************************************************** 00150 void 00151 Manager::destroy(oa::oaDesign *design) { 00152 // is there a Manager? 00153 if (!hasManager(design)) { 00154 return; 00155 } 00156 00157 // remove links from nets to AI graph 00158 oa::oaModule *module; 00159 oa::oaIter<oa::oaModule> modIter(design->getModules()); 00160 while((module = modIter.getNext())) { 00161 oa::oaModBitNet *net; 00162 oa::oaIter<oa::oaModBitNet> netIter(module->getNets(oacNetIterAll)); 00163 while((net = netIter.getNext())) { 00164 if(net->getNumBits() > 1) { 00165 continue; 00166 } 00167 00168 // clear an existing AppDef, if it exists 00169 bbRefAppDef->destroy(net); 00170 AiRefAppDef->destroy(net); 00171 } 00172 } 00173 00174 // delete manager object 00175 delete static_cast<Manager*>(managerAppDef->get(design)); 00176 managerAppDef->destroy(design); 00177 } 00178 00179 00180 // ***************************************************************************** 00181 // ~Manager() destructor 00186 // 00187 // ***************************************************************************** 00188 Manager::~Manager() { 00189 } 00190 00191 00192 // ***************************************************************************** 00193 // prepareNetToBBConnection() 00194 // 00204 // 00205 // ***************************************************************************** 00206 BBRef 00207 Manager::prepareNetToBBConnection(oa::oaModBitNet *net) { 00208 assert(net); 00209 00210 // is there already an terminal node associated with this net? 00211 if (net->getAppDefs().includes(bbRefAppDef)) { 00212 BBRef terminal = bbRefAppDef->get(net); 00213 assert(bbg.isTerminal(terminal)); 00214 return terminal; 00215 } 00216 00217 // create a new terminal node 00218 BBRef terminal = bbg.newTerminal(bbg.getNull()); 00219 //bbg.incrementExternalReferences(terminal); 00220 setNetToBBConnection(net, terminal); 00221 return terminal; 00222 } 00223 00224 // ***************************************************************************** 00225 // prepareNetToAiConnection() 00226 // 00236 // 00237 // ***************************************************************************** 00238 BBRef 00239 Manager::prepareNetToAiConnection(oa::oaModBitNet *net) { 00240 assert(net); 00241 00242 // is there already an terminal node associated with this net? 00243 if (net->getAppDefs().includes(AiRefAppDef)) { 00244 oagAi::Ref terminal = AiRefAppDef->get(net); 00245 assert(ai.isTerminal(terminal)); 00246 return terminal; 00247 } 00248 00249 // create a new terminal node 00250 oagAi::Ref terminal = ai.newTerminal(ai.getNull()); 00251 //bbg.incrementExternalReferences(terminal); 00252 setNetToAiConnection(net, terminal); 00253 return terminal; 00254 } 00255 00256 // ***************************************************************************** 00257 // getSerializedSize() 00258 // 00262 // 00263 // ***************************************************************************** 00264 int 00265 Manager::getSerializedSize(oa::oaDesign *design) { 00266 assert(design); 00267 00268 // YH: getSerializedSize() need to be rewrite 00269 00270 /* 00271 if (!Manager::hasManager(design)) { 00272 return 0; 00273 } 00274 00275 Manager *manager = Manager::get(design); 00276 00277 int bytes = 0; 00278 00279 long numNodes = manager->ai.getNumNodes() - manager->ai.NODES_TO_IGNORE; 00280 bytes += sizeof(numNodes); 00281 00282 while(--numNodes >= 0) { 00283 oagAi::Node *node = manager->ai.getNode((numNodes+manager->ai.NODES_TO_IGNORE)*2); 00284 bytes += node->getSerializedSize(); 00285 } 00286 00287 return bytes; 00288 */ 00289 } 00290 00291 00292 // ***************************************************************************** 00293 // serialize() 00294 // 00299 // 00300 // ***************************************************************************** 00301 void 00302 Manager::serialize(void* buf, oa::oaDesign *design) { 00303 assert(buf); 00304 assert(design); 00305 assert(design->getTopModule()); 00306 00307 oa::oaString moduleNameString; 00308 design->getTopModule()->getName(oa::oaVerilogNS(), moduleNameString); 00309 DEBUG_PRINTLN("serializing " << moduleNameString) 00310 00311 // is there any functional information to serialize? 00312 if (!Manager::hasManager(design)) { 00313 return; 00314 } 00315 00316 Manager *manager = Manager::get(design); 00317 00318 void *ptr = buf; 00319 00320 // YH: serialize() need to be rewrite 00321 00322 /* 00323 long numNodes = manager->ai.getNumNodes() - manager->ai.NODES_TO_IGNORE; 00324 memcpy(ptr, &numNodes, sizeof(numNodes)); 00325 char *char_ptr = static_cast<char*>(ptr); 00326 char_ptr += sizeof(numNodes); 00327 ptr = char_ptr; 00328 DEBUG_PRINTLN("\twriting " << numNodes << " AI nodes") 00329 00330 oagAi::Ref currentRef = manager->ai.NODES_TO_IGNORE*2; 00331 while(--numNodes >= 0) { 00332 oagAi::Node *node = manager->ai.getNode(currentRef); 00333 node->serialize(ptr); 00334 char *char_ptr = static_cast<char*>(ptr); 00335 char_ptr += node->getSerializedSize(); 00336 ptr = char_ptr; 00337 currentRef += 2; 00338 } 00339 00340 */ 00341 #ifdef DEBUG 00342 long bytes = reinterpret_cast<long>(ptr)-reinterpret_cast<long>(buf); 00343 DEBUG_PRINTLN("\twrote " << bytes << " bytes"); 00344 #endif 00345 } 00346 00347 00348 // ***************************************************************************** 00349 // unserialize() 00350 // 00356 // 00357 // ***************************************************************************** 00358 int 00359 Manager::unserialize(void *buf, oa::oaDesign *design) { 00360 assert(design); 00361 assert(design->getTopModule()); 00362 00363 oa::oaString moduleNameString; 00364 design->getTopModule()->getName(oa::oaVerilogNS(), moduleNameString); 00365 DEBUG_PRINTLN("unserializing " << moduleNameString) 00366 00367 if (Manager::hasManager(design)) { 00368 QUIT_ON_INTERNAL_ERROR; 00369 } 00370 Manager *manager = new Manager(design); 00371 void *ptr = buf; 00372 00373 // YH: unserialize() need to be rewrite 00374 00375 /* 00376 long numNodes; 00377 memcpy(&numNodes, ptr, sizeof(numNodes)); 00378 char *char_ptr = static_cast<char*>(ptr); 00379 char_ptr += sizeof(numNodes); 00380 ptr = char_ptr; 00381 DEBUG_PRINTLN("\treading " << numNodes << " AI nodes") 00382 00383 // recreate all nodes 00384 assert(manager->ai.getNumNodes() == manager->ai.NODES_TO_IGNORE); 00385 while(--numNodes >= 0) { 00386 oagAi::Node *node = manager->ai.newNode(); 00387 char *char_ptr = static_cast<char*>(ptr); 00388 char_ptr += node->unserialize(ptr); 00389 ptr = char_ptr; 00390 } 00391 // rebuild all non-persistent data 00392 oagAi::Ref currentRef = manager->ai.NODES_TO_IGNORE*2; 00393 oagAi::Ref lastRef = (manager->ai.getNumNodes()-1)*2; 00394 while(currentRef <= lastRef) { 00395 switch(manager->ai.getNodeType(currentRef)) { 00396 case oagAi::Node::TERMINAL: { 00397 // update fan-outs and reference counts 00398 manager->ai.addToFanout(manager->ai.getTerminalDriver(currentRef), currentRef); 00399 break; 00400 } 00401 case oagAi::Node::SEQUENTIAL: { 00402 // update fan-outs and reference counts 00403 manager->ai.addToFanout(manager->ai.getNextState(currentRef), currentRef); 00404 manager->ai.seqNodes++; 00405 break; 00406 } 00407 case oagAi::Node::AND: { 00408 // update fan-outs and reference counts 00409 manager->ai.addToFanout(manager->ai.getAndLeft(currentRef), currentRef); 00410 manager->ai.addToFanout(manager->ai.getAndRight(currentRef), currentRef); 00411 00412 // add node to structural hash table 00413 int hash_key = manager->ai.getStructuralHashKey(manager->ai.getAndLeft(currentRef),manager->ai.getAndLeft(currentRef)); 00414 manager->ai.getNode(currentRef)->next = manager->ai.structuralHash[hash_key]; 00415 manager->ai.structuralHash[hash_key] = currentRef; 00416 00417 manager->ai.andNodes++; 00418 break; 00419 } 00420 default: 00421 break; 00422 } 00423 currentRef += 2; 00424 } 00425 00426 DEBUG_PRINTLN("\t\tfinal num nodes = " << manager->ai.getNumNodes()) 00427 DEBUG_PRINTLN("\t\t\tlastPage = " << manager->ai.lastPage << " lastIndex = " << manager->ai.lastIndex) 00428 00429 // 1. increment refcounts of nodes that are attached to nets 00430 // 2. set external_terminal_connection pointers to nets 00431 00432 oa::oaModule *module; 00433 oa::oaIter<oa::oaModule> modIter(design->getModules()); 00434 while((module = modIter.getNext())) { 00435 oa::oaModNet *net; 00436 oa::oaIter<oa::oaModNet> netIter(module->getNets(oacNetIterSingleBit)); 00437 while((net = netIter.getNext())) { 00438 oa::oaModBitNet *bit = toBitNet(net); 00439 if (!manager->ai.isNull(currentRef = manager->getNetToAiConnection(bit))) { 00440 manager->ai.incrementExternalReferences(currentRef); 00441 manager->ai.setExternalTerminalConnection(currentRef, reinterpret_cast<void *>(bit)); 00442 } 00443 } 00444 } 00445 */ 00446 00447 long bytes = reinterpret_cast<long>(ptr)-reinterpret_cast<long>(buf); 00448 DEBUG_PRINTLN("\tread " << bytes << " bytes"); 00449 return bytes; 00450 } 00451 00452 // ***************************************************************************** 00453 // removeNetToAiConnection() 00454 // 00458 // 00459 // ***************************************************************************** 00460 void 00461 Manager::removeNetToAiConnection(oa::oaModBitNet *net) { 00462 assert(net); 00463 00464 // remove the pointer from the node to the net 00465 if (net->getAppDefs().includes(AiRefAppDef)) { 00466 oagAi::Ref ref = AiRefAppDef->get(net); 00467 assert(!ai.isNull(ref)); 00468 ai.setExternalTerminalConnection(ref, NULL); 00469 } 00470 00471 // remove the pointer from the net to the node 00472 AiRefAppDef->destroy(net); 00473 } 00474 00475 // ***************************************************************************** 00476 // setNetToBBConnection() 00477 // 00482 // 00483 // ***************************************************************************** 00484 // YH: 05/09/2007, TODO update this routine to black box port 00485 // YH: 05/10/2007, DONE! 00486 void 00487 Manager::setNetToBBConnection(oa::oaModBitNet *net, BBRef bbRef) { 00488 00489 if(bbg.getNodeType(bbRef) != RtlNode::TERMINAL) { 00490 cerr << "ERROR: Nets can only be connected to TERMINAL nodes:"; 00491 QUIT_ON_ERROR; 00492 } 00493 00494 #ifdef DEBUG 00495 oa::oaString str; 00496 net->getName(oa::oaVerilogNS(), str); 00497 DEBUG_PRINTLN("setNetToBBConnection: " << str); 00498 #endif 00499 00500 bbRefAppDef->set(net, bbRef); 00501 bbg.setExternalTerminalConnection(bbRef, reinterpret_cast<void*>(net)); 00502 } 00503 00504 // ***************************************************************************** 00505 // setNetToAiConnection() 00506 // 00511 // 00512 // ***************************************************************************** 00513 void 00514 Manager::setNetToAiConnection(oa::oaModBitNet *net, oagAi::Ref ref) { 00515 if(ai.getNodeType(ref) != oagAi::Node::TERMINAL) { 00516 cerr << "ERROR: Nets can only be connected to TERMINAL nodes:"; 00517 ai.print(ref); 00518 QUIT_ON_ERROR; 00519 } else if (ai.isInverted(ref)) { 00520 cerr << "ERROR: Nets can only be connected to non-inverted references: "; 00521 ai.print(ref); 00522 QUIT_ON_ERROR; 00523 } 00524 00525 oa::oaString str; 00526 net->getName(oa::oaVerilogNS(), str); 00527 AiRefAppDef->set(net, ref); 00528 ai.setExternalTerminalConnection(ref, reinterpret_cast<void*>(net)); 00529 } 00530 00531 00532 // ***************************************************************************** 00533 // getNetToBBConnection() 00534 // 00541 // 00542 // ***************************************************************************** 00543 oa::oaModBitNet * 00544 Manager::getNetToBBConnection(BBRef ref) { 00545 assert(bbg.getNodeType(ref) == RtlNode::TERMINAL); 00546 00547 // is the pointer to the connected net stored in the terminal node? 00548 void *external_terminal_connection = bbg.getExternalTerminalConnection(ref); 00549 oa::oaModBitNet *bit; 00550 if (external_terminal_connection) { 00551 bit = reinterpret_cast<oa::oaModBitNet*>(external_terminal_connection); 00552 assert(getNetToBBConnection(bit) == ref); 00553 return bit; 00554 } 00555 00556 return NULL; 00557 } 00558 00559 // ***************************************************************************** 00560 // getNetToAiConnection() 00561 // 00568 // 00569 // ***************************************************************************** 00570 oa::oaModBitNet * 00571 Manager::getNetToAiConnection(oagAi::Ref ref) { 00572 assert(ai.getNodeType(ref) == oagAi::Node::TERMINAL); 00573 00574 // is the pointer to the connected net stored in the terminal node? 00575 void *external_terminal_connection = ai.getExternalTerminalConnection(ref); 00576 oa::oaModBitNet *bit; 00577 if (external_terminal_connection) { 00578 bit = reinterpret_cast<oa::oaModBitNet*>(external_terminal_connection); 00579 assert(getNetToAiConnection(bit) == ref); 00580 return bit; 00581 } 00582 00583 return NULL; 00584 } 00585 00586 // ***************************************************************************** 00587 // isStructural() 00588 // 00596 // 00597 // ***************************************************************************** 00598 bool 00599 Manager::isStructural() { 00600 assert(design); 00601 assert(design->getTopModule()); 00602 00603 // if there are any black box nodes in the graph, the design 00604 // is not structural 00605 if (bbg.getBBNodeNum() > 0) { 00606 return false; 00607 } 00608 00609 return true; 00610 } 00611 00612 // ***************************************************************************** 00613 // getNetToBBConnection() 00614 // 00622 // 00623 // ***************************************************************************** 00624 BBRef 00625 Manager::getNetToBBConnection(oa::oaModBitNet *net) { 00626 00627 BBRef ref = bbg.getNull(); 00628 00629 // examine each one of the functionally equivalent nets 00630 if (net->getAppDefs().includes(bbRefAppDef)) { 00631 ref = bbRefAppDef->get(net); 00632 assert(!bbg.isNull(ref)); 00633 assert(bbg.isTerminal(ref)); 00634 return ref; 00635 } 00636 00637 return bbg.getNull(); 00638 00639 } 00640 00641 // ***************************************************************************** 00642 // getNetToAiConnection() 00643 // 00651 // 00652 // ***************************************************************************** 00653 oagAi::Ref 00654 Manager::getNetToAiConnection(oa::oaModBitNet *net) { 00655 00656 oagAi::Ref ref = ai.getNull(); 00657 00658 // examine each one of the functionally equivalent nets 00659 if (net->getAppDefs().includes(AiRefAppDef)) { 00660 ref = AiRefAppDef->get(net); 00661 assert(!ai.isNull(ref)); 00662 assert(ai.isTerminal(ref)); 00663 return ref; 00664 } 00665 00666 return ai.getNull(); 00667 00668 } 00669 00670 /* 00671 00672 // ***************************************************************************** 00673 // getLocalAIsize() 00674 // 00678 // 00679 // ***************************************************************************** 00680 int 00681 Manager::getLocalAIsize() { 00682 return ai.getNumNodes(); 00683 } 00684 00685 00686 // ***************************************************************************** 00687 // getHierarchicalAIsize() 00688 // 00695 // 00696 // ***************************************************************************** 00697 int 00698 Manager::getHierarchicalAIsize() { 00699 assert(design); 00700 00701 return getHierarchicalAIsize(design); 00702 } 00703 00704 00705 // ***************************************************************************** 00706 // getHierarchicalAIsize() 00707 // 00715 // 00716 // ***************************************************************************** 00717 int 00718 Manager::getHierarchicalAIsize(oa::oaDesign *design) { 00719 assert(design); 00720 assert(design->getTopOccurrence()); 00721 00722 int num = 0; 00723 00724 // if this design is not entirely structural, add the number of nodes here 00725 if (Manager::hasManager(design)) { 00726 num += Manager::get(design)->ai.getNumNodes(); 00727 } 00728 00729 // traverse the ModuleInst hierarchy, and recurse on any DesignInsts 00730 list<oa::oaModule*> toBeVisited; 00731 toBeVisited.push_back(design->getTopModule()); 00732 00733 while(!toBeVisited.empty()) { 00734 oa::oaModule *module = toBeVisited.front(); 00735 toBeVisited.pop_front(); 00736 00737 oa::oaModInst *inst; 00738 oa::oaIter<oa::oaModInst> instIter(module->getInsts()); 00739 while((inst = instIter.getNext())) { 00740 assert(inst); 00741 00742 oa::oaModule *subMod = inst->getMasterModule(); 00743 if (!subMod) { 00744 assert(inst->isModDesignInst()); 00745 oa::oaModDesignInst *designInst = static_cast<oa::oaModDesignInst *>(inst); 00746 oa::oaString libNameString, cellNameString, viewNameString; 00747 designInst->getLibName(oa::oaNativeNS(), libNameString); 00748 designInst->getCellName(oa::oaNativeNS(), cellNameString); 00749 designInst->getViewName(oa::oaNativeNS(), viewNameString); 00750 cerr << "ERROR: Can not bind to " << libNameString << "/" << cellNameString << "/" << viewNameString << endl; 00751 QUIT_ON_ERROR; 00752 } 00753 00754 if (inst->isModDesignInst()) { 00755 num += getHierarchicalAIsize(subMod->getDesign()); 00756 } else if (inst->isModModuleInst()) { 00757 toBeVisited.push_front(subMod); 00758 } else { 00759 QUIT_ON_INTERNAL_ERROR; 00760 } 00761 } 00762 } 00763 00764 return num; 00765 } 00766 00767 00768 // ***************************************************************************** 00769 // getLocalAndAIsize() 00770 // 00774 // 00775 // ***************************************************************************** 00776 int 00777 Manager::getLocalAndAIsize() { 00778 return ai.getNumAndNodes(); 00779 } 00780 00781 00782 // ***************************************************************************** 00783 // getHierarchicalAndAIsize() 00784 // 00791 // 00792 // ***************************************************************************** 00793 int 00794 Manager::getHierarchicalAndAIsize() { 00795 assert(design); 00796 00797 return getHierarchicalAndAIsize(design); 00798 } 00799 00800 00801 // ***************************************************************************** 00802 // getHierarchicalAndAIsize() 00803 // 00811 // 00812 // ***************************************************************************** 00813 int 00814 Manager::getHierarchicalAndAIsize(oa::oaDesign *design) { 00815 assert(design); 00816 assert(design->getTopOccurrence()); 00817 00818 int num = 0; 00819 00820 // if this design is not entirely structural, add the number of AND nodes here 00821 if (Manager::hasManager(design)) { 00822 num += Manager::get(design)->ai.getNumAndNodes(); 00823 } 00824 00825 // traverse the ModuleInst hierarchy, and recurse on any DesignInsts 00826 list<oa::oaModule*> toBeVisited; 00827 toBeVisited.push_back(design->getTopModule()); 00828 00829 while(!toBeVisited.empty()) { 00830 oa::oaModule *module = toBeVisited.front(); 00831 toBeVisited.pop_front(); 00832 00833 oa::oaModInst *inst; 00834 oa::oaIter<oa::oaModInst> instIter(module->getInsts()); 00835 while((inst = instIter.getNext())) { 00836 assert(inst); 00837 00838 oa::oaModule *subMod = inst->getMasterModule(); 00839 if (!subMod) { 00840 assert(inst->isModDesignInst()); 00841 oa::oaModDesignInst *designInst = static_cast<oa::oaModDesignInst *>(inst); 00842 oa::oaString libNameString, cellNameString, viewNameString; 00843 designInst->getLibName(oa::oaNativeNS(), libNameString); 00844 designInst->getCellName(oa::oaNativeNS(), cellNameString); 00845 designInst->getViewName(oa::oaNativeNS(), viewNameString); 00846 cerr << "ERROR: Can not bind to " << libNameString << "/" << cellNameString << "/" << viewNameString << endl; 00847 QUIT_ON_ERROR; 00848 } 00849 00850 if (inst->isModDesignInst()) { 00851 num += getHierarchicalAndAIsize(subMod->getDesign()); 00852 } else if (inst->isModModuleInst()) { 00853 toBeVisited.push_front(subMod); 00854 } else { 00855 QUIT_ON_INTERNAL_ERROR; 00856 } 00857 } 00858 } 00859 00860 return num; 00861 } 00862 00863 // ***************************************************************************** 00864 // getLocalSeqNodeCount() 00865 // 00871 // 00872 // ***************************************************************************** 00873 int 00874 Manager::getLocalSeqNodeCount() { 00875 return ai.getNumSeqNodes(); 00876 } 00877 00878 00879 // ***************************************************************************** 00880 // getHierarchicalSeqNodeCount() 00881 // 00888 // 00889 // ***************************************************************************** 00890 int 00891 Manager::getHierarchicalSeqNodeCount() { 00892 assert(design); 00893 00894 return getHierarchicalSeqNodeCount(design); 00895 } 00896 00897 00898 // ***************************************************************************** 00899 // getHierarchicalSeqNodeCount 00900 // 00908 // 00909 // ***************************************************************************** 00910 int 00911 Manager::getHierarchicalSeqNodeCount(oa::oaDesign *design) { 00912 assert(design); 00913 assert(design->getTopOccurrence()); 00914 00915 int num = 0; 00916 00917 // if this design is not entirely structural, add the number of AND nodes here 00918 if (Manager::hasManager(design)) { 00919 num += Manager::get(design)->ai.getNumSeqNodes(); 00920 } 00921 00922 // traverse the ModuleInst hierarchy, and recurse on any DesignInsts 00923 list<oa::oaModule*> toBeVisited; 00924 toBeVisited.push_back(design->getTopModule()); 00925 00926 while(!toBeVisited.empty()) { 00927 oa::oaModule *module = toBeVisited.front(); 00928 toBeVisited.pop_front(); 00929 00930 oa::oaModInst *inst; 00931 oa::oaIter<oa::oaModInst> instIter(module->getInsts()); 00932 while((inst = instIter.getNext())) { 00933 assert(inst); 00934 00935 oa::oaModule *subMod = inst->getMasterModule(); 00936 if (!subMod) { 00937 assert(inst->isModDesignInst()); 00938 oa::oaModDesignInst *designInst = static_cast<oa::oaModDesignInst *>(inst); 00939 oa::oaString libNameString, cellNameString, viewNameString; 00940 designInst->getLibName(oa::oaNativeNS(), libNameString); 00941 designInst->getCellName(oa::oaNativeNS(), cellNameString); 00942 designInst->getViewName(oa::oaNativeNS(), viewNameString); 00943 cerr << "ERROR: Can not bind to " << libNameString << "/" << cellNameString << "/" << viewNameString << endl; 00944 QUIT_ON_ERROR; 00945 } 00946 00947 if (inst->isModDesignInst()) { 00948 num += getHierarchicalSeqNodeCount(subMod->getDesign()); 00949 } else if (inst->isModModuleInst()) { 00950 toBeVisited.push_front(subMod); 00951 } else { 00952 QUIT_ON_INTERNAL_ERROR; 00953 } 00954 } 00955 } 00956 00957 return num; 00958 } 00959 00960 00961 // ***************************************************************************** 00962 // getNumTotalInstances() 00963 // 00967 // 00968 // ***************************************************************************** 00969 int 00970 Manager::getNumTotalInstances() { 00971 assert(design); 00972 00973 return getNumTotalInstances(design) + 1; 00974 } 00975 00976 00977 // ***************************************************************************** 00978 // getNumTotalInstances() 00979 // 00983 // 00984 // ***************************************************************************** 00985 int 00986 Manager::getNumTotalInstances(oa::oaDesign *design) { 00987 assert(design); 00988 assert(design->getTopOccurrence()); 00989 00990 int num = 0; 00991 00992 // add the number of instances inside this instance 00993 num += design->getTopOccurrence()->getInsts().getCount(); 00994 00995 // add the number of instances inside each instance 00996 oa::oaOccInst *inst; 00997 oa::oaIter<oa::oaOccInst> instIter(design->getTopOccurrence()->getInsts()); 00998 while((inst = instIter.getNext())) { 00999 assert(inst->getMasterOccurrence()); 01000 assert(inst->getMasterOccurrence()->getModule()); 01001 num += getNumTotalInstances(inst->getMasterOccurrence()->getModule()->getDesign()); 01002 } 01003 01004 return num; 01005 } 01006 01007 01008 // ***************************************************************************** 01009 // getNumLeafInstances() 01010 // 01014 // 01015 // ***************************************************************************** 01016 int 01017 Manager::getNumLeafInstances() { 01018 assert(design); 01019 01020 return getNumLeafInstances(design); 01021 } 01022 01023 01024 // ***************************************************************************** 01025 // getNumLeafInstances() 01026 // 01030 // 01031 // ***************************************************************************** 01032 int 01033 Manager::getNumLeafInstances(oa::oaDesign *design) { 01034 assert(design); 01035 assert(design->getTopOccurrence()); 01036 01037 int num = 0; 01038 01039 // add the number of leaves in each instance 01040 oa::oaOccInst *inst; 01041 oa::oaIter<oa::oaOccInst> instIter(design->getTopOccurrence()->getInsts()); 01042 while((inst = instIter.getNext())) { 01043 assert(inst->getMasterOccurrence()); 01044 assert(inst->getMasterOccurrence()->getModule()); 01045 num += getNumLeafInstances(inst->getMasterOccurrence()->getModule()->getDesign()); 01046 } 01047 01048 if (num != 0) { 01049 // non-leaf 01050 return num; 01051 } else { 01052 // leaf 01053 return 1; 01054 } 01055 } 01056 01057 */ 01058 01059 01060 // ***************************************************************************** 01061 // print() 01062 // 01068 // 01069 // ***************************************************************************** 01070 01071 01072 void 01073 Manager::print(ostream& os) { 01074 01075 const oa::oaVerilogNS verilogNS; 01076 01077 oa::oaModule *module; 01078 oa::oaIter<oa::oaModule> modIter(design->getModules()); 01079 while((module = modIter.getNext())) { 01080 01081 oa::oaModNet *net; 01082 oa::oaIter<oa::oaModNet> netIter(module->getNets(oacNetIterSingleBit)); 01083 while((net = netIter.getNext())) { 01084 oa::oaString netNameString; 01085 net->getName(verilogNS, netNameString); 01086 01087 BBRef ref = getNetToBBConnection(toBitNet(net)); 01088 if (!bbg.isNull(ref)) { 01089 os << "net \"" << netNameString << "\" -> " << ref << endl; 01090 } else { 01091 os << "net \"" << netNameString << "\" is not connected to a graph node" << endl; 01092 } 01093 } 01094 } 01095 01096 bbg.print(os); 01097 } 01098 01099 } 01100 01101