Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

oagFpgaMapperUtils.cpp

Go to the documentation of this file.
00001 
00002 #include "oagFpgaMapperUtils.h"
00003 #include "oagFpga.h"
00004 #include "oagFpgaAiModGraph.h"
00005 #include "oagFpgaManager.h"
00006 #include "oagFpgaSynthesis.h"
00007 #include "oagFpgaSimMod.h"
00008 #include "oagAiNode.h"
00009 #include "oagFpgaDebug.h"
00010 #include <map>
00011 #include <sstream>
00012 #include <algorithm>
00013 
00014 
00015 using namespace std;
00016 
00017 namespace oagFpga {
00018 
00019 // *****************************************************************************
00020 // Utils()
00021 //
00024 // *****************************************************************************
00025 MapperUtils::MapperUtils() {
00026     
00027     seqGate = NULL;
00028     seqInput = seqOutput = NULL;
00029     seqReset = seqPreset = seqClock = NULL;
00030 
00031     lutGate = NULL; lutOutput = NULL;
00032 }
00033 
00034 // *****************************************************************************
00035 // CreateSeq()
00036 //
00042 // *****************************************************************************
00043 oa::oaDesign *
00044 MapperUtils::createSeq(oa::oaLib* curLib, oa::oaView* curView) {
00045 
00046     oa::oaDesign       *design;
00047 
00048     try {
00049 
00050         // obtain the names of the library, view and cell
00051         const oa::oaNativeNS nativeNS;
00052         oa::oaScalarName    libName;
00053         curLib->getName(libName);
00054         oa::oaScalarName    viewName;
00055         curView->getName(viewName);
00056         oa::oaViewType     *viewType = oa::oaViewType::get(oa::oacNetlist);
00057         oa::oaScalarName    cellName(nativeNS, "SEQ");
00058 
00059         // find or create design
00060         if ((design = oa::oaDesign::find(libName, cellName, viewName))) {
00061             return design;
00062         } else {
00063             try {
00064                 design = oa::oaDesign::open(libName, cellName, viewName, 'a');
00065             } catch (oa::oaException &e) {
00066                 // create
00067                 design = oa::oaDesign::open(libName, cellName, viewName, viewType, 'w');
00068             }
00069         }
00070         assert(design);
00071 
00072         // creat the top module
00073         // get/create top module
00074         oa::oaModule *module = design->getTopModule();
00075         if (!module) {
00076             module = oa::oaModule::create(design, cellName);
00077             design->setTopModule(module);
00078         } else {
00079 
00080             // any existing structure needs to be discarded (if overwriteStructure)
00081             // destroy the existing design and create a new one
00082             design->purge();
00083             if (Synthesis::checkForExistenceOfDesign(libName, cellName, viewName)) {
00084                 oa::oaDesign::destroy(libName, cellName, viewName);
00085             }
00086             design = oa::oaDesign::open(libName, cellName, viewName, viewType, 'w');
00087             module = oa::oaModule::create(design, cellName); 
00088             design->setTopModule(module); 
00089 
00090         }
00091         assert(module);
00092 
00093         // create I/O terminals of the module
00094         oa::oaModScalarNet *net;
00095         net = oa::oaModScalarNet::create( module, 
00096             oa::oaScalarName(nativeNS, "D") );
00097         seqInput = oa::oaModScalarTerm::create( net, 
00098             oa::oaScalarName(nativeNS,"D"), oa::oacInputTermType);
00099         net = oa::oaModScalarNet::create( module, 
00100             oa::oaScalarName(nativeNS, "CLK") );
00101         seqClock = oa::oaModScalarTerm::create( net, 
00102             oa::oaScalarName(nativeNS,"CLK"), oa::oacInputTermType);
00103         net = oa::oaModScalarNet::create( module, 
00104             oa::oaScalarName(nativeNS, "PRESET") );
00105         seqPreset = oa::oaModScalarTerm::create( net, 
00106             oa::oaScalarName(nativeNS,"PRESET"), oa::oacInputTermType);
00107         net = oa::oaModScalarNet::create( module, 
00108             oa::oaScalarName(nativeNS, "RESET") );
00109         seqReset = oa::oaModScalarTerm::create( net, 
00110             oa::oaScalarName(nativeNS,"RESET"), oa::oacInputTermType);
00111         net = oa::oaModScalarNet::create( module, 
00112             oa::oaScalarName(nativeNS, "OUT") );
00113         seqOutput = oa::oaModScalarTerm::create( net, 
00114             oa::oaScalarName(nativeNS,"OUT"), oa::oacOutputTermType);
00115 
00116         // setup the trigger types of clock, reset, preset
00117         // FIXME: currently I assume that all triggers are positive...
00118         seqClockTrigger = POSEDGE;
00119         seqResetTrigger = POSEDGE;
00120         seqPresetTrigger = POSEDGE;
00121 
00122 
00123     }catch(oa::oaException &e) {
00124         std::cerr << "ERROR: " << e.getMsg() << std::endl;
00125         assert(0);
00126     }
00127 
00128     assert(design);
00129 
00130     return seqGate = design;
00131 }
00132 
00133 // *****************************************************************************
00134 // CreateLut()
00135 //
00141 // *****************************************************************************
00142 oa::oaDesign *
00143 MapperUtils::createLut(oa::oaLib* curLib, oa::oaView* curView, int K) {
00144         
00145     oa::oaDesign       *design;
00146 
00147     try {
00148 
00149         // obtain the names of the library, view and cell
00150         oa::oaScalarName    libName;
00151         curLib->getName(libName);
00152         oa::oaScalarName    viewName;
00153         curView->getName(viewName);
00154         oa::oaViewType     *viewType = oa::oaViewType::get(oa::oacNetlist);
00155         ostringstream       lutNameStrStream;
00156         lutNameStrStream << "LUT" << K;
00157         string              lutNameStr = lutNameStrStream.str();
00158         
00159         const oa::oaNativeNS nativeNS;
00160         oa::oaScalarName    cellName(nativeNS, lutNameStr.c_str());
00161 
00162         // find or create design
00163         if ((design = oa::oaDesign::find(libName, cellName, viewName))) {
00164             return design;
00165         } else {
00166             try {
00167                 design = oa::oaDesign::open(libName, cellName, viewName, 'a');
00168             } catch (oa::oaException &e) {
00169                 // create
00170                 design = oa::oaDesign::open(libName, cellName, viewName, viewType, 'w');
00171             }
00172         }
00173         assert(design);
00174 
00175         // creat the top module
00176         // get/create top module
00177         oa::oaModule *module = design->getTopModule();
00178         if (!module) {
00179             module = oa::oaModule::create(design, cellName);
00180             design->setTopModule(module);
00181         } else {
00182 
00183             // any existing structure needs to be discarded (if overwriteStructure)
00184             // destroy the existing design and create a new one
00185             design->purge();
00186             if (Synthesis::checkForExistenceOfDesign(libName, cellName, viewName)) {
00187                 oa::oaDesign::destroy(libName, cellName, viewName);
00188             }
00189             design = oa::oaDesign::open(libName, cellName, viewName, viewType, 'w');
00190             module = oa::oaModule::create(design, cellName); 
00191             design->setTopModule(module); 
00192 
00193         }
00194         assert(module);
00195 
00196         // create I/O terminals of the module
00197         oa::oaModScalarNet *net;
00198         for(int i=0;i<K;i++){
00199             ostringstream lutPinStrStream;
00200             lutPinStrStream << "IN" << i;
00201             string lutTermName = lutPinStrStream.str();
00202             net = oa::oaModScalarNet::create( module, 
00203                 oa::oaScalarName(nativeNS, lutTermName.c_str()) );
00204             lutInputs.push_back(oa::oaModScalarTerm::create( net, 
00205                 oa::oaScalarName(nativeNS, lutTermName.c_str()), oa::oacInputTermType));
00206         }
00207         net = oa::oaModScalarNet::create( module, 
00208             oa::oaScalarName(nativeNS, "OUT") );
00209         lutOutput = oa::oaModScalarTerm::create( net, 
00210             oa::oaScalarName(nativeNS,"OUT"), oa::oacOutputTermType);
00211 
00212     }catch(oa::oaException &e) {
00213         std::cerr << "ERROR: " << e.getMsg() << std::endl;
00214         assert(0);
00215     }
00216 
00217     assert(design);
00218 
00219     return lutGate = design;
00220 }
00221 
00222 // *****************************************************************************
00223 // removeAsyncResetsFromLogic()
00224 //
00249 // *****************************************************************************
00250 void
00251 MapperUtils::removeAsyncResetsFromLogic(oa::oaModule *module) {
00252   assert(module);
00253 
00254   // is this design already structural?
00255   if (!Manager::hasManager(module->getDesign())) {
00256     return;
00257   }
00258 
00259   // note that the resubstitute command does not affect anything in
00260   // the sequentialData structures.  it will only substitute
00261   // the values in the input logic
00262 
00263   // resubstitute 0 for all posedge resets
00264   for(set<oa::oaModBitNet *>::iterator it = posAsyncResets.begin();
00265       it != posAsyncResets.end(); it++) {
00266     AiModRef term = AiModGraph::getNetToAiConnection(*it);
00267     assert(!AiModGraph::isNull(term));
00268     AiModGraph::resubstitute(term, AiModGraph::constantZero(term.module));
00269   }
00270  
00271   // resubstitute 1 for all negedge resets
00272   for(set<oa::oaModBitNet *>::iterator it = negAsyncResets.begin();
00273       it != negAsyncResets.end(); it++) {
00274     AiModRef term = AiModGraph::getNetToAiConnection(*it);
00275     assert(!AiModGraph::isNull(term));
00276     AiModGraph::resubstitute(term, AiModGraph::constantOne(term.module));    
00277   }
00278 
00279 }
00280 
00281 
00282 // *****************************************************************************
00283 // identifyControls()
00284 //
00288 //
00289 // *****************************************************************************
00290 void
00291 MapperUtils::identifyControls(oa::oaModule *module) {
00292   list<AiModRef> seq;
00293   AiModGraph::getLocalStates(module, seq);    
00294   for(list<AiModRef>::iterator it = seq.begin(); it!=seq.end(); it++) {
00295     identifyControls(*it);
00296   }
00297 }
00298 
00299 
00300 // *****************************************************************************
00301 // identifyControls()
00302 //
00306 //
00307 // *****************************************************************************
00308 void
00309 MapperUtils::identifyControls(AiModRef seq) {
00310 
00311   oagAi::Node::SequentialData *data = AiModGraph::getSequentialData(seq);
00312   if (!data) {
00313     return;
00314   }
00315   
00316   oa::oaModule *module = seq.module;
00317   assert(module);
00318 
00319   // get the roots of the fan-in cone
00320   list<AiModRef> roots;
00321   AiModGraph::getFaninRoots(seq, roots);
00322 
00323   for(map<string, oagAi::Ref>::iterator sigIter = data->signals.begin();
00324       sigIter != data->signals.end(); sigIter++) {
00325 
00326     AiModRef ref(sigIter->second, module);
00327 
00328     // only can deal with TERMINALS
00329     if (!AiModGraph::isTerminal(ref)) {
00330       continue;
00331     }
00332 
00333     // follow strings of terminals to driver
00334     while (true) {
00335       AiModRef driver = AiModGraph::getTerminalDriver(ref);
00336       if (!AiModGraph::isTerminal(driver)) {
00337         break;
00338       }
00339       ref = driver;
00340     }
00341 
00342     // get the connected net
00343     oa::oaModNet *net = AiModGraph::getNetToAiConnection(ref);
00344     if (!net) {
00345       continue;
00346     }
00347     oa::oaModBitNet *bitNet = toBitNet(net);
00348 
00349     bool inFanin = false;
00350     inFanin |= find(roots.begin(), roots.end(), ref) != roots.end();
00351     inFanin |= find(roots.begin(), roots.end(), AiModGraph::notOf(ref)) != roots.end();
00352     
00353     bool posedge = (sigIter->first.find("posedge") != sigIter->first.npos);
00354     bool clocked_on = (sigIter->first == "clocked_on");
00355     bool negedge = (sigIter->first.find("negedge") != sigIter->first.npos);
00356     bool clear = (sigIter->first == "clear");
00357 
00358 #if defined(DEBUG)
00359     oa::oaString netString;
00360     bitNet->getName(oa::oaVerilogNS(), netString);
00361 #endif
00362 
00363     if (inFanin && posedge || clear) {
00364       DEBUG_PRINTLN(netString << " = pos-triggered reset");
00365       posAsyncResets.insert(bitNet);
00366     } else if (inFanin && negedge) {
00367       DEBUG_PRINTLN(netString << " = neg-triggered reset");
00368       negAsyncResets.insert(bitNet);
00369     } else if (!inFanin && posedge || clocked_on) {
00370       DEBUG_PRINTLN(netString << " = pos-triggered clock");
00371       posClocks.insert(bitNet);
00372     } else if (!inFanin && negedge) {
00373       DEBUG_PRINTLN(netString << " = neg-triggered clock");
00374       negClocks.insert(bitNet);
00375     }
00376   }
00377 }
00378 
00379 #ifdef CELL_MAPPING
00380 // *****************************************************************************
00381 // connectControl()
00382 //
00389 //
00390 // *****************************************************************************
00391 void
00392 MapperUtils::connectControl(oa::oaModTerm *term, oa::oaModInst *inst,
00393                       oa::oaModBitNet *net, bool inverted) {
00394   assert(term);
00395   assert(inst);
00396   assert(net);
00397 
00398   oa::oaModule *module = net->getModule();
00399   assert(module);
00400 
00401 #if defined(DEBUG)
00402   oa::oaString termString, netString, instString;
00403   term->getName(oa::oaVerilogNS(), termString);
00404   net->getName(oa::oaVerilogNS(), netString);
00405   inst->getName(oa::oaVerilogNS(), instString);
00406   DEBUG_PRINTLN("Connecting " << termString << " of " << instString << " -> " << netString);
00407 #endif
00408 
00409   if (oa::oaModInstTerm::find(inst, term)) {
00410     DEBUG_PRINTLN("Aborted.  Term is already connected");
00411     return;
00412   }
00413 
00414   if (inverted) {
00415     assert(notGate);
00416     // if not, insert an inverted on the input   
00417     oa::oaModScalarInst *notInst = oa::oaModScalarInst::create(module, notGate);
00418     oa::oaModInstTerm::create(net, notInst, notInput);
00419     oa::oaModScalarNet *localInvertedClockNet = oa::oaModScalarNet::create(module);
00420     oa::oaModInstTerm::create(localInvertedClockNet, notInst, notOutput);
00421     oa::oaModInstTerm::create(localInvertedClockNet, inst, term);
00422   } else {
00423     oa::oaModInstTerm::create(net, inst, term);
00424   }
00425   
00426 }
00427 
00428 
00429 // *****************************************************************************
00430 // connectSeqControls()
00431 //
00455 //
00456 // *****************************************************************************
00457 void
00458 MapperUtils::connectAllControls(AiModRef ref, oa::oaModInst *inst) {
00459     assert(inst);
00460 
00461     oagAi::Node::SequentialData *data = AiModGraph::getSequentialData(ref);   
00462     assert(data);
00463 
00464     // the node must be a BLACK_BOX abstraction level
00465     assert(data->abstractionLevel == oagAi::Node::SequentialData::BLACK_BOX);
00466 
00467     // scan through all posedge triggers 
00468     for(char p = '0'; p <= '9'; p++) {
00469       stringstream label;
00470       label << "trigger_" << p << "_posedge";
00471 
00472       if (data->signals.find(label.str()) != data->signals.end()) {
00473         DEBUG_PRINTLN("Trigger " << label.str() << " is present");
00474 
00475         // found a signal
00476         AiModRef ref(data->signals[label.str()], inst->getModule());
00477 
00478         // if this isn't a terminal... not so straightforward
00479         if (!AiModGraph::isTerminal(ref)) {
00480           continue;
00481         }
00482 
00483         // follow strings of terminals to driver
00484         while (true) {
00485           AiModRef driver = AiModGraph::getTerminalDriver(ref);
00486           if (!AiModGraph::isTerminal(driver)) {
00487             break;
00488           }
00489           ref = driver;
00490         }
00491 
00492         oa::oaModNet *net = AiModGraph::getNetToAiConnection(ref);
00493         if (!net) {
00494           continue;
00495         }
00496         oa::oaModBitNet *bitNet = toBitNet(net);
00497         if (seqClock && find(posClocks.begin(), posClocks.end(), bitNet) != posClocks.end()) {
00498           connectControl(seqClock, inst, bitNet, false);
00499         }
00500         if (seqClock && find(negClocks.begin(), negClocks.end(), bitNet) != negClocks.end()) {
00501           connectControl(seqClock, inst, bitNet, true);
00502         }
00503         if (seqReset && find(posAsyncResets.begin(), posAsyncResets.end(), bitNet) != posAsyncResets.end()) {
00504           connectControl(seqReset, inst, bitNet, false);
00505         }
00506         if (seqReset && find(negAsyncResets.begin(), negAsyncResets.end(), bitNet) != negAsyncResets.end()) {
00507           connectControl(seqReset, inst, bitNet, true);
00508         }
00509       }
00510     }
00511 
00512     // scan through all negedge triggers 
00513     for(char p = '0'; p <= '9'; p++) {
00514       stringstream label;
00515       label << "trigger_" << p << "_negedge";
00516 
00517       if (data->signals.find(label.str()) != data->signals.end()) {
00518         DEBUG_PRINTLN("Trigger " << label.str() << " is present");
00519 
00520         // found a signal
00521         AiModRef ref(data->signals[label.str()], inst->getModule());
00522 
00523         // if this isn't a terminal... not so straightforward
00524         if (!AiModGraph::isTerminal(ref)) {
00525           continue;
00526         }
00527 
00528         // follow strings of terminals to driver
00529         while (true) {
00530           AiModRef driver = AiModGraph::getTerminalDriver(ref);
00531           if (!AiModGraph::isTerminal(driver)) {
00532             break;
00533           }
00534           ref = driver;
00535         }
00536 
00537         oa::oaModNet *net = AiModGraph::getNetToAiConnection(ref);
00538         if (!net) {
00539           continue;
00540         }
00541         oa::oaModBitNet *bitNet = toBitNet(net);
00542         if (seqClock && find(posClocks.begin(), posClocks.end(), bitNet) != posClocks.end()) {
00543           connectControl(seqClock, inst, bitNet, true);
00544         }
00545         if (seqClock && find(negClocks.begin(), negClocks.end(), bitNet) != negClocks.end()) {
00546           connectControl(seqClock, inst, bitNet, false);
00547         }
00548         if (seqReset && find(posAsyncResets.begin(), posAsyncResets.end(), bitNet) != posAsyncResets.end()) {
00549           connectControl(seqReset, inst, bitNet, true);
00550         }
00551         if (seqReset && find(negAsyncResets.begin(), negAsyncResets.end(), bitNet) != negAsyncResets.end()) {
00552           connectControl(seqReset, inst, bitNet, false);
00553         }
00554       }
00555     }
00556 
00557     // check for "clocked_on"
00558     if (data->signals.find("clocked_on") != data->signals.end()) {
00559       DEBUG_PRINTLN("Trigger clocked_on is present");
00560       
00561       // found a signal
00562       AiModRef ref(data->signals["clocked_on"], inst->getModule());
00563       
00564       // if this isn't a terminal... not so straightforward
00565       if (AiModGraph::isTerminal(ref)) {
00566 
00567         // follow strings of terminals to driver
00568         while (true) {
00569           AiModRef driver = AiModGraph::getTerminalDriver(ref);
00570           if (!AiModGraph::isTerminal(driver)) {
00571             break;
00572           }
00573           ref = driver;
00574         }
00575 
00576         oa::oaModNet *net = AiModGraph::getNetToAiConnection(ref);
00577         if (net) {
00578           oa::oaModBitNet *bitNet = toBitNet(net);
00579           if (seqClock && find(posClocks.begin(), posClocks.end(), bitNet) != posClocks.end()) {
00580             connectControl(seqClock, inst, bitNet, false);
00581           }
00582           if (seqClock && find(negClocks.begin(), negClocks.end(), bitNet) != negClocks.end()) {
00583             connectControl(seqClock, inst, bitNet, true);
00584           }
00585         }
00586       }
00587     }
00588 
00589     // check for "clear"
00590     if (data->signals.find("clear") != data->signals.end()) {
00591         DEBUG_PRINTLN("Trigger clear is present");
00592         
00593         // found a signal
00594         AiModRef ref(data->signals["clear"], inst->getModule());
00595 
00596         // if this isn't a terminal... not so straightforward
00597         if (AiModGraph::isTerminal(ref)) {
00598 
00599           // follow strings of terminals to driver
00600           while (true) {
00601             AiModRef driver = AiModGraph::getTerminalDriver(ref);
00602             if (!AiModGraph::isTerminal(driver)) {
00603               break;
00604             }
00605             ref = driver;
00606           }
00607 
00608           oa::oaModNet *net = AiModGraph::getNetToAiConnection(ref);
00609           if (net) {
00610             oa::oaModBitNet *bitNet = toBitNet(net);
00611             if (seqReset && find(posAsyncResets.begin(), posAsyncResets.end(), bitNet) != posAsyncResets.end()) {
00612               connectControl(seqReset, inst, bitNet, false);
00613             }
00614             if (seqReset && find(negAsyncResets.begin(), negAsyncResets.end(), bitNet) != negAsyncResets.end()) {
00615               connectControl(seqReset, inst, bitNet, true);
00616             }
00617           }
00618         }
00619     }
00620 }
00621 #endif // #ifdef CELL_MAPPING
00622 
00623 // *****************************************************************************
00624 // mergeEquivalentNets()
00625 //
00629 //
00630 // *****************************************************************************
00631 void
00632 MapperUtils::mergeEquivalentNets(oa::oaModule *module) {
00633     assert(module);
00634 
00635     // merge all nets
00636     bool changed = true;
00637     while(changed) {
00638         changed = false;
00639 
00640         // make all bus net bits explicit
00641         oa::oaModNet *net;
00642         oa::oaIter<oa::oaModNet> netIter2(module->getNets(oacNetIterNotImplicit));
00643         while((net = netIter2.getNext())) {
00644             if(!net->isImplicit() && net->getNumBits() > 1) {
00645                 net->scalarize();
00646             }
00647         }
00648 
00649         oa::oaIter<oa::oaModNet> netIter(module->getNets(oacNetIterSingleBit));
00650         while(!changed && (net = netIter.getNext())) {
00651             oa::oaModBitNet *preferred = toBitNet(net)->getPreferredEquivalent();
00652 
00653             oa::oaModBitNet *equivNet;
00654             oa::oaIter<oa::oaModBitNet> equivIter(preferred->getEquivalentNets());      
00655             while((equivNet = equivIter.getNext())) {
00656 
00657                 // move instTerms
00658                 oa::oaModInstTerm *instTerm;
00659                 oa::oaIter<oa::oaModInstTerm> instTermIter(equivNet->getInstTerms(oacInstTermIterAll));      
00660                 while((instTerm = instTermIter.getNext())) {
00661                     if (instTerm->isImplicit()) {
00662                         instTerm->scalarize();
00663                     }
00664                     instTerm->addToNet(preferred);
00665                 }
00666                 
00667                 // move terms
00668                 oa::oaModTerm *term;
00669                 oa::oaIter<oa::oaModTerm> termIter(equivNet->getTerms(oacTermIterAll));
00670                 while((term = termIter.getNext())) {
00671                     if (term->isImplicit()) {
00672                         term->scalarize();
00673                     }
00674                     term->moveToNet(preferred);
00675                 }
00676                
00677                 // resubstitute graph
00678                 AiModRef target = AiModGraph::getNetToAiConnection(equivNet);
00679                 if (!AiModGraph::isNull(target)) {
00680                     AiModRef replacement = AiModGraph::prepareNetToAiConnection(preferred);
00681                     AiModGraph::resubstitute(target, replacement);
00682                     AiModGraph::removeNetToAiConnection(equivNet);
00683                 }
00684                 
00685                 // destroy net or at least break equivalence
00686                 equivNet->destroy();
00687                 changed = true;
00688             }
00689         }
00690     }   
00691 }
00692 
00693 
00694 // *****************************************************************************
00695 // printGateUsage()
00696 //
00700 //
00701 // *****************************************************************************
00702 void
00703 MapperUtils::printGateUsage(oa::oaModule *target) {  
00704   assert(target);
00705 
00706   const int NAME_COL_WIDTH = 15;
00707   const int COUNT_COL_WIDTH = 8;
00708 
00709   long total = 0;
00710   
00711   map<oa::oaModule *,int> histogram;
00712 
00713   oa::oaModInst *inst;
00714   oa::oaIter<oa::oaModInst> instIter(target->getInsts());
00715   while((inst = instIter.getNext())) {
00716     oa::oaModule *module = inst->getMasterModule();
00717     assert(module);
00718 
00719     // increment count
00720     if (histogram.find(module) == histogram.end()) {
00721       histogram[module] = 1;
00722     } else {
00723       histogram[module] = histogram[module] + 1;
00724     }
00725     total++;
00726   }
00727 
00728   // print statistics
00729   cout << "\tComponent gate usage" << endl;
00730   for(map<oa::oaModule *,int>::iterator cellIter = histogram.begin();
00731       cellIter != histogram.end(); cellIter++) {
00732     oa::oaString modString;
00733     cellIter->first->getName(oa::oaVerilogNS(), modString);
00734     cout << "\t\t";
00735     cout.width(NAME_COL_WIDTH);
00736     cout << modString;
00737     cout.width(COUNT_COL_WIDTH);
00738     cout << cellIter->second;
00739     cout << endl;
00740   }
00741 
00742   cout << "\t\t";
00743   cout.width(NAME_COL_WIDTH);
00744   cout << "TOTAL";
00745   cout.width(COUNT_COL_WIDTH);
00746   cout << total << endl;
00747 }
00748 
00749 
00750 // *****************************************************************************
00751 // removeDanglingNets()
00752 //
00758 //
00759 // *****************************************************************************
00760 void
00761 MapperUtils::removeDanglingNets(oa::oaModule *module) {
00762     const oa::oaVerilogNS verilogNS;
00763 
00764     // map all nets
00765     oa::oaModNet *net;
00766     oa::oaIter<oa::oaModNet> netIter(module->getNets(oacNetIterSingleBit));
00767     while((net = netIter.getNext())) {
00768       oa::oaModBitNet *bitNet = toBitNet(net);
00769       if (net->getInstTerms(oacInstTermIterAll).isEmpty() && 
00770           net->getTerms(oacTermIterAll).isEmpty()) {
00771 
00772 #if defined(DEBUG)
00773         oa::oaString netString;
00774         net->getName(verilogNS, netString);
00775         DEBUG_PRINTLN("Removing dangling net " << netString);
00776 #endif
00777 
00778         // resubstitute and remove node from graph
00779         AiModRef termRef = AiModGraph::getNetToAiConnection(bitNet);
00780         if(!AiModGraph::isNull(termRef)) {
00781           assert(AiModGraph::isTerminal(termRef));
00782           AiModRef driverRef = AiModGraph::getTerminalDriver(termRef); 
00783           AiModGraph::resubstitute(termRef, driverRef);
00784           
00785           // destroy connection
00786           AiModGraph::removeNetToAiConnection(bitNet);
00787         }
00788         
00789         // destroy net
00790         net->destroy();
00791       }
00792     }
00793 }
00794 
00795 
00796 }

Generated on Mon Jul 9 14:17:19 2007 for OA Gear Fpga by  doxygen 1.3.9.1