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

oagFpgaSynthesis.cpp

Go to the documentation of this file.
00001 
00002 #include "oaDesignDB.h"
00003 #include "oagFpgaManager.h"
00004 #include "oagFpgaSynthesis.h"
00005 #include <list>
00006 #include <set>
00007 
00008 //#define DEBUG
00009 
00010 #include "oagFpgaDebug.h"
00011 
00012 #define sign(a)  ( (a)==0?0: ((a)<0?-1:1) )
00013 #define abs(a)   ( (a)>=0?(a):-(a) )
00014 #define max(a,b) ( (a)>(b)?(a):(b) )
00015 #define min(a,b) ( (a)>(b)?(b):(a) )
00016 
00017 namespace oagFpga {
00018 
00019 // *****************************************************************************
00020 // Class static variable definitions.
00021 // *****************************************************************************
00022 
00023 oa::oaNameSpace                     *Synthesis::nameSpace = NULL;
00024 oa::oaLib                           *Synthesis::currentLibrary = NULL;
00025 oa::oaView                          *Synthesis::currentView = NULL;
00026 Manager                             *Synthesis::currentManager = NULL;
00027 oa::oaModule                        *Synthesis::currentModule = NULL;
00028 bool                                 Synthesis::overwriteStructure = true;
00029 
00030 list<oa::oaLib*>                     Synthesis::leafLibs;
00031 list<oa::oaScalarName>               Synthesis::leafViews;
00032 
00033 
00034 // ***************************************************************************** 
00035 // setOverwriteStructure() 
00036 // 
00055 // ***************************************************************************** 
00056 void
00057 Synthesis::setOverwriteStructure(bool overwrite) {
00058     overwriteStructure = overwrite;
00059 }
00060 
00061 
00062 // *****************************************************************************
00063 // zeroExpand()
00064 //
00068 //
00069 // *****************************************************************************
00070 void 
00071 Synthesis::zeroExpand(MultiRefBus &l1, MultiRefBus &l2) {
00072     if(l1.size() < l2.size()) {
00073         for(int i=l2.size()-l1.size(); i>0; i--) {
00074             l1.push_front( constantZero() );
00075         }
00076     } else if(l1.size() > l2.size()) {
00077         for(int i=l1.size()-l2.size(); i>0; i--) {
00078             l2.push_front( constantZero() );
00079         }
00080     }
00081 }
00082 
00083 
00092 
00093 bool
00094 Synthesis::checkForExistenceOfDesign(oa::oaScalarName libName,
00095                                      oa::oaScalarName cellName,
00096                                      oa::oaScalarName viewName)
00097 {
00098     try {
00099         oa::oaDesign *design;
00100         design = oa::oaDesign::open(libName, cellName, viewName, 'a');
00101         design->close();
00102         return true;
00103     } catch (oa::oaException &e) {
00104         return false;
00105     }
00106 }
00107 
00108 
00109 // *****************************************************************************
00110 // findModule()
00111 //
00123 //
00124 // *****************************************************************************
00125 oa::oaModule*           
00126 Synthesis::findModule(const string identifier) {
00127     assert(nameSpace);
00128 
00129     DEBUG_PRINTLN("find module " << identifier);
00130 
00131     if (!currentLibrary || !currentView) {
00132       cerr << "ERROR: The design library and view both must first be set" << endl;
00133       QUIT_ON_ERROR;
00134     }
00135 
00136     oa::oaScalarName    cellName(*nameSpace, identifier.c_str());
00137 
00138     // 1. a module in the current design (if it exists)
00139     if (currentModule) {
00140         oa::oaModule *module = oa::oaModule::find(currentModule->getDesign(), cellName);
00141         if (module) {
00142             return module;
00143         }
00144     }
00145 
00146     // 2. search current design library
00147     oa::oaNativeNS      nativeNS;
00148     oa::oaScalarName    libName;
00149     currentLibrary->getName(libName);
00150     oa::oaScalarName    viewName;
00151     currentView->getName(viewName);
00152 
00153     oa::oaDesign *design;
00154     
00155     // find or open design
00156     if ((design = oa::oaDesign::find(libName, cellName, viewName))) {
00157         return design->getTopModule();
00158     } else {
00159         try {
00160             design = oa::oaDesign::open(libName, cellName, viewName, 'a');
00161             assert(design);
00162             oa::oaModule *module = design->getTopModule();
00163             return module;
00164         } catch (oa::oaException &e) {
00165         }
00166     }
00167 
00168     // 3. search leaf libraries
00169     for(list<oa::oaLib*>::iterator libIter=leafLibs.begin();
00170         libIter!=leafLibs.end(); libIter++) {
00171       oa::oaLib *leafLib = *libIter;
00172       oa::oaScalarName leafLibName;
00173       leafLib->getName(leafLibName);
00174 
00175       // search each view
00176       for(list<oa::oaScalarName>::iterator viewIter=leafViews.begin();
00177           viewIter!=leafViews.end(); viewIter++) {
00178 
00179         if ((design = oa::oaDesign::find(leafLibName, cellName, *viewIter))) {
00180             return design->getTopModule();
00181         }
00182 
00183         try {
00184             design = oa::oaDesign::open(leafLibName, cellName, *viewIter, 'r');
00185             assert(design);
00186             oa::oaModule *module = design->getTopModule();
00187             return module;
00188         } catch (oa::oaException &e) {
00189             // design didn't exist
00190         }
00191       }
00192 
00193       cout << endl;
00194     }
00195     
00196     return NULL;
00197 }
00198 
00199 
00200 // *****************************************************************************
00201 // createModule()
00202 //
00220 //
00221 // *****************************************************************************
00222 oa::oaModule*           
00223 Synthesis::createModule(const string identifier) {
00224     assert(nameSpace);
00225 
00226     DEBUG_PRINTLN("create module " << identifier);
00227 
00228     if (!currentLibrary || !currentView) {
00229       cerr << "ERROR: The design library and view both must first be set" << endl;
00230       QUIT_ON_ERROR;
00231     }
00232 
00233     oa::oaScalarName    cellName(*nameSpace, identifier.c_str());
00234 
00235     // open design
00236     oa::oaNativeNS      nativeNS;
00237     oa::oaScalarName    libName;
00238     currentLibrary->getName(libName);
00239     oa::oaScalarName    viewName;
00240     currentView->getName(viewName);
00241     oa::oaViewType     *viewType = oa::oaViewType::get(oa::oacNetlist);
00242     oa::oaDesign       *design;
00243     
00244     // find or create design
00245     if ((design = oa::oaDesign::find(libName, cellName, viewName))) {
00246         return design->getTopModule();
00247     } else {
00248         try {
00249             design = oa::oaDesign::open(libName, cellName, viewName, 'a');
00250         } catch (oa::oaException &e) {
00251             // create
00252             design = oa::oaDesign::open(libName, cellName, viewName, viewType, 'w');
00253         }
00254     }
00255     if (!design) {
00256       cerr << "ERROR: Could not find/open design: " << identifier << endl;
00257       QUIT_ON_ERROR;
00258     }
00259         
00260     // get/create top module
00261     oa::oaModule *module = design->getTopModule();
00262     if (!module) {
00263         module = oa::oaModule::create(design, cellName);
00264         design->setTopModule(module);
00265     } else {
00266 
00267         // any existing structure needs to be discarded (if overwriteStructure)
00268         if (overwriteStructure) {
00269             // destroy the existing design and create a new one
00270             design->purge();
00271             if (checkForExistenceOfDesign(libName, cellName, viewName)) {
00272                 oa::oaDesign::destroy(libName, cellName, viewName);
00273             }
00274             design = oa::oaDesign::open(libName, cellName, viewName, viewType, 'w');
00275             module = oa::oaModule::create(design, cellName); 
00276             design->setTopModule(module); 
00277         }
00278 
00279         // any existing functional information needs to be discarded
00280 
00281         // clear existing manager
00282         if (oagFpga::Manager::hasManager(design)) {
00283             oagFpga::Manager *manager = oagFpga::Manager::get(design);
00284             assert(manager);
00285             delete manager;
00286             managerAppDef->destroy(design);
00287         }
00288 
00289         // clear connections from nets to nodes
00290         oa::oaModNet *net;
00291         oa::oaIter<oa::oaModNet> netIter(module->getNets(oacNetIterSingleBit));
00292         while ((net = netIter.getNext())) {
00293             bbRefAppDef->destroy(net);
00294         }
00295     }
00296     assert(module);
00297 
00298     // create global "tie0" and "tie1" nets if they don't exist
00299     oa::oaScalarName tie0Name(nativeNS, "tie0");
00300     if (oa::oaModScalarNet::find(module, tie0Name) == NULL) {
00301         oa::oaModScalarNet::create(module, tie0Name, oa::oacTieLoSigType, false);
00302     }
00303     oa::oaScalarName tie1Name(nativeNS, "tie1");
00304     if (oa::oaModScalarNet::find(module, tie1Name) == NULL) {
00305         oa::oaModScalarNet::create(module, tie1Name, oa::oacTieHiSigType, false);
00306     }
00307 
00308     return module;
00309 }
00310 
00311 
00312 // *****************************************************************************
00313 // instantiateModule()
00314 //
00321 // *****************************************************************************
00322 oa::oaModInst*          
00323 Synthesis::instantiateModule(oa::oaDesign *master, const string name) {
00324     assert(nameSpace);
00325     assert(currentModule);
00326     assert(master);
00327 
00328     // find or create design
00329     oa::oaModInst *inst;
00330     if (name.empty()) {
00331         inst = oa::oaModScalarInst::create(currentModule, master);
00332     } else {
00333         inst = oa::oaModScalarInst::create(currentModule, master, 
00334                                            oa::oaScalarName(*nameSpace,name.c_str()));
00335     }
00336 
00337     return inst;
00338 }
00339     
00340 
00341 // *****************************************************************************
00342 // createScalarNet()
00343 //
00345 //
00346 // *****************************************************************************
00347 oa::oaModScalarNet*
00348 Synthesis::createScalarNet(const string identifier) {
00349     assert(nameSpace);
00350     assert(currentModule);
00351 
00352     // does this net exist?
00353     oa::oaScalarName netName(*nameSpace, oa::oaString(identifier.c_str()));
00354     oa::oaModScalarNet *net = oa::oaModScalarNet::find(currentModule, netName);
00355     if (!net) {
00356         // create the net
00357         net = oa::oaModScalarNet::create(currentModule, netName);
00358     }
00359 
00360     // create a terminal node if module has functional description
00361     if (currentManager != NULL) {
00362         currentManager->setNetToBBConnection(net, 
00363             currentManager->bbg.newTerminal( currentManager->bbg.getNull()) );
00364     }
00365 
00366     return net;
00367 }
00368 
00369 
00370 // *****************************************************************************
00371 // createBusNet()
00372 //
00374 //
00375 // *****************************************************************************
00376 oa::oaModBusNet*
00377 Synthesis::createBusNet(const string identifier, int start, int stop) {
00378     assert(nameSpace);
00379     assert(currentModule);
00380     
00381     oa::oaScalarName netName(*nameSpace, oa::oaString(identifier.c_str()));
00382     
00383     // does a bus net of this name already exist?
00384     oa::oaModBusNet *bus = oa::oaModBusNet::find(currentModule, netName, start, stop, 1);
00385     if (bus) {
00386         cerr << "ERROR: net " << identifier << " defined twice" << endl;
00387         QUIT_ON_ERROR;
00388     }
00389     
00390     // create the net
00391     bus = oa::oaModBusNet::create(currentModule, netName, start, stop, 1);
00392 
00393 #ifdef DEBUG
00394     oa::oaString modName;
00395     currentModule->getName(oa::oaVerilogNS(), modName);
00396 
00397     oa::oaString str;
00398     bus->getName(oa::oaVerilogNS(), str);
00399     DEBUG_PRINTLN("BusNet created: " << str);
00400     DEBUG_PRINTLN("currentManager = " << currentManager);
00401 #endif
00402 
00403     // create terminal BB nodes if functional manager exists
00404     if (currentManager != NULL) {
00405 #ifdef DEBUG
00406         DEBUG_PRINTLN("createBusNet, create terminal BB nodes");
00407 #endif
00408         for(int b = 0; b<=abs(stop-start); b++) {
00409             currentManager->setNetToBBConnection(bus->getBit(b), 
00410                 currentManager->bbg.newTerminal(currentManager->bbg.getNull()) );
00411         }
00412     }
00413 
00414     return bus;
00415 }
00416 
00417 
00418 // *****************************************************************************
00419 // createTerm()
00420 //
00422 //
00423 // *****************************************************************************
00424 oa::oaModTerm*
00425 Synthesis::createTerm(oa::oaModNet *net, const string identifier, 
00426         oa::oaTermType type, unsigned int portPosition) {
00427     assert(nameSpace);
00428     assert(net);
00429     
00430     if (type == oa::oacInputOutputTermType) {
00431        cerr << "WARNING: Functionality not supported for inout ports" << endl;
00432     }
00433     
00434     oa::oaModTerm *term;
00435 
00436     oa::oaModule *module = net->getModule();
00437     oa::oaUInt4 numBits = net->getNumBits();
00438     oa::oaModTerm *newTerm = 0;
00439     
00440     // create term
00441     if (numBits == 1) {
00442         oa::oaScalarName sName(*nameSpace, identifier.c_str());
00443         term = oa::oaModTerm::find(module, sName);
00444         if (!term) {
00445             newTerm = oa::oaModTerm::create(net, sName, type);
00446         }
00447     } else {
00448         oa::oaVectorName vName(*nameSpace, identifier.c_str(), 0, numBits - 1);
00449         term = oa::oaModTerm::find(module, vName);
00450         if (!term) {
00451             newTerm = oa::oaModTerm::create(net, vName, type);
00452         }
00453     }
00454 
00455     if (term) {
00456         // FIXME perhaps we should do more checking here to make sure the
00457         // term has the right direction, bus width, position, etc.
00458         return term;
00459     }
00460 
00461     // set port position if given
00462     if (portPosition != oacNullIndex) {
00463         newTerm->setPosition(portPosition);
00464     }
00465     return newTerm;
00466 }   
00467 
00468 
00469 // *****************************************************************************
00470 // findBusNet()
00471 //
00474 //
00475 // *****************************************************************************
00476 oa::oaModBusNet*
00477 Synthesis::findBusNet(const string identifier) {
00478     assert(currentModule);
00479     assert(nameSpace);
00480 
00481     oa::oaScalarName baseName(*nameSpace,identifier.c_str());
00482 
00483     oa::oaModBusNetDef *busNetDef = oa::oaModBusNetDef::find(currentModule, baseName);
00484     if (busNetDef) {
00485         oa::oaIter<oa::oaModBusNet> busIter(busNetDef->getBusNets());
00486         oa::oaModBusNet *busNet = busIter.getNext();
00487         if (busNet) {
00488             return busNet;
00489         }
00490     }
00491 
00492     return NULL;
00493 }
00494 
00495 
00496 // *****************************************************************************
00497 // findBusNetBit()
00498 //
00500 //
00501 // *****************************************************************************
00502 oa::oaModBusNetBit*
00503 Synthesis::findBusNetBit(const string identifier, const int bit) {
00504     assert(nameSpace);
00505     assert(currentModule);
00506 
00507     // create the net
00508     oa::oaScalarName netName(*nameSpace, identifier.c_str());
00509     return oa::oaModBusNetBit::find(currentModule, netName, bit);
00510 }
00511 
00512 
00513 // *****************************************************************************
00514 // findScalarNet()
00515 //
00517 //
00518 // *****************************************************************************
00519 oa::oaModScalarNet*
00520 Synthesis::findScalarNet(const string identifier) {
00521     assert(nameSpace);
00522     assert(currentModule);
00523 
00524     // create the net
00525     oa::oaScalarName netName(*nameSpace, identifier.c_str());
00526     return oa::oaModScalarNet::find(currentModule, netName);
00527 }
00528 
00529 
00530 // *****************************************************************************
00531 // findNet()
00532 //
00534 //
00535 // *****************************************************************************
00536 oa::oaModNet*
00537 Synthesis::findNet(const string identifier) {
00538   oa::oaModNet *net;
00539   net = findScalarNet(identifier);
00540   if (!net)
00541     net = findBusNet(identifier);  
00542   return net;
00543 }
00544 
00545 
00546 // *****************************************************************************
00547 // assignMultiRef()
00548 //
00554 //
00555 // *****************************************************************************
00556 void
00557 Synthesis::assignMultiRef(oa::oaModBitNet *net, const MultiRef e) {
00558     assert(nameSpace);
00559     assert(net);
00560     
00561     oa::oaString str;
00562     net->getName(*nameSpace, str);
00563     
00564     // has this net already been assigned?
00565     // (a terminal node's driver should be NULL_BBREF it's unassigned)
00566     if (currentManager && net->getAppDefs().includes(bbRefAppDef)) {
00567         BBRef node = bbRefAppDef->get(net);
00568         if (!currentManager->bbg.isNull(currentManager->bbg.getTerminalDriver(node))) {
00569             cerr << "ERROR: net " << str << " is being assigned more than once" << endl;
00570             QUIT_ON_ERROR;
00571         }
00572     }
00573     
00574     if (e.type == BBREF) {
00575         assert(currentManager);
00576         // if we're being asked to assign an BBREF, 
00577         // we know this module must already be functional
00578         assert( net->getAppDefs().includes(bbRefAppDef) );
00579     
00580         BBRef node = bbRefAppDef->get(net);
00581         
00582         // repoint the node to the MultiRef
00583         currentManager->bbg.setTerminalDriver(node, e.bb);
00584         DEBUG_PRINTLN("\t\t . " << node << "," << str << " (functional) = " << e.bb)
00585     } else {
00586 
00587         net->makeEquivalent(e.net);
00588 
00589         DEBUG_PRINTLN("\t\t . " << str << " (structural)")
00590     }
00591 }
00592 
00593 
00594 // *****************************************************************************
00595 // notOf()
00596 //
00598 //
00599 // *****************************************************************************
00600 MultiRef
00601 Synthesis::notOf(MultiRef e) {
00602     assert(currentModule);
00603 
00604     // have we created a functional manager for this design yet?
00605     if (currentManager == NULL) {
00606         currentManager = Manager::get(currentModule->getDesign());
00607     }
00608 
00609     // if this MultiRef is a net, convert it to a BBRef
00610     if (e.type == NET) {
00611         // there must already be an existing BBRef
00612         oa::oaModBitNet *net = e.net;
00613         assert(net);
00614         assert(net->getAppDefs().includes(bbRefAppDef));
00615         e.bb = bbRefAppDef->get(net);
00616         e.type = BBREF;
00617     }
00618 
00619     assert(e.type == BBREF);
00620     return MultiRef(currentManager->bbg.unaryOpt(RtlNode::BITWISE_NOT, e.bb));
00621 }
00622 
00623 // *****************************************************************************
00624 // binaryOpt()
00625 //
00629 //
00630 // *****************************************************************************
00631 MultiRef
00632 Synthesis::binaryOpt(RtlNode::OptType optType, MultiRef e1, MultiRef e2) {
00633     assert(currentModule);
00634 
00635     // have we created a functional manager for this design yet?
00636     if (currentManager == NULL) {
00637         currentManager = Manager::get(currentModule->getDesign());
00638     }
00639 
00640     // if this either MultiRef is a net, convert it to a BBRef
00641     if (e1.type == NET) {
00642         // there must already be an existing BBRef
00643         oa::oaModBitNet *net = e1.net;
00644         assert(net);
00645         assert(net->getAppDefs().includes(bbRefAppDef));
00646         e1.bb = bbRefAppDef->get(net);
00647         e1.type = BBREF;
00648     }
00649     if (e2.type == NET) {
00650         // there must already be an existing BBRef
00651         oa::oaModBitNet *net = e2.net;
00652         assert(net);
00653         assert(net->getAppDefs().includes(bbRefAppDef));
00654         e2.bb = bbRefAppDef->get(net);
00655         e2.type = BBREF;
00656     }
00657     
00658     assert(e1.type == BBREF);
00659     assert(e2.type == BBREF);
00660 
00661     return MultiRef(currentManager->bbg.binaryOpt(optType, e1.bb, e2.bb));
00662 }
00663 
00664 // *****************************************************************************
00665 // andOf()
00666 //
00670 //
00671 // *****************************************************************************
00672 MultiRef
00673 Synthesis::andOf(MultiRef e1, MultiRef e2) {
00674     return binaryOpt(RtlNode::BITWISE_AND, e1, e2);
00675 }
00676 
00677 
00678 // *****************************************************************************
00679 // orOf()
00680 //
00684 //
00685 // *****************************************************************************
00686 MultiRef
00687 Synthesis::orOf(MultiRef e1, MultiRef e2) {
00688     return binaryOpt(RtlNode::BITWISE_OR, e1, e2);
00689 }
00690 
00691 
00692 // *****************************************************************************
00693 // xorOf()
00694 //
00698 //
00699 // *****************************************************************************
00700 MultiRef
00701 Synthesis::xorOf(MultiRef e1, MultiRef e2) {
00702     return binaryOpt(RtlNode::BITWISE_XOR, e1, e2);
00703 }
00704 
00705 // *****************************************************************************
00706 // norOf()
00707 //
00711 //
00712 // *****************************************************************************
00713 MultiRef
00714 Synthesis::norOf(MultiRef e1, MultiRef e2) {
00715     return binaryOpt(RtlNode::BITWISE_NOR, e1, e2);
00716 }
00717 
00718 // *****************************************************************************
00719 // nandOf()
00720 //
00724 //
00725 // *****************************************************************************
00726 MultiRef
00727 Synthesis::nandOf(MultiRef e1, MultiRef e2) {
00728     return binaryOpt(RtlNode::BITWISE_NAND, e1, e2);
00729 }
00730 
00731 // *****************************************************************************
00732 // xnorOf()
00733 //
00737 //
00738 // *****************************************************************************
00739 MultiRef
00740 Synthesis::xnorOf(MultiRef e1, MultiRef e2) {
00741     return binaryOpt(RtlNode::BITWISE_XNOR, e1, e2);
00742 }
00743 
00744 // *****************************************************************************
00745 // connectPort()
00746 //
00751 //
00752 // *****************************************************************************
00753 void
00754 Synthesis::connectPort(oa::oaModInst *inst, oa::oaModNet *net, 
00755                        unsigned int portPosition) {
00756     oa::oaModInstTerm::create(net, inst, portPosition);
00757 
00758     // check that port widths match
00759     oa::oaModule *module = inst->getMasterModule();
00760     assert(module);
00761     oa::oaModTerm *term = oa::oaModTerm::find(module, portPosition);
00762     assert(term);
00763     if(term->getNumBits() != net->getNumBits()) {
00764         cout << "ERROR: Port connection width mismatch" << endl;
00765         QUIT_ON_ERROR;
00766     }
00767 }
00768 
00769 
00770 // *****************************************************************************
00771 // connectPort()
00772 //
00777 //
00778 // *****************************************************************************
00779 void 
00780 Synthesis::connectPort(oa::oaModInst *inst, oa::oaModNet *net, 
00781                        const string portString) {
00782     assert(nameSpace);
00783     
00784     oa::oaName netName, termName;
00785     net->getName(netName);
00786     if (net->getNumBits() == 1) {
00787         termName = oa::oaScalarName(*nameSpace, portString.c_str());
00788         oa::oaModInstTerm::create(net, inst, termName);
00789   
00790     } else if (netName.getType() == oa::oacVectorNameType) {
00791         termName = oa::oaVectorName(*nameSpace, portString.c_str(), 0,net->getNumBits()-1);
00792         oa::oaModInstTerm::create(net, inst, termName);
00793     } else {
00794         QUIT_ON_INTERNAL_ERROR;
00795     }
00796     
00797     // check that port widths match
00798     oa::oaModule *module = inst->getMasterModule();
00799     assert(module);
00800     oa::oaModTerm *term = oa::oaModTerm::find(module, termName);
00801     assert(term);
00802     if(term->getNumBits() != net->getNumBits()) {
00803         cout << "ERROR: Port connection width mismatch" << endl;
00804         QUIT_ON_ERROR;
00805     }
00806 }
00807 
00808 // *****************************************************************************
00809 // unaryBusOpt()
00810 //
00813 // *****************************************************************************
00814 
00815 MultiRef
00816 Synthesis::unaryBusOpt(RtlNode::OptType optType, MultiRefBus &l) {
00817     assert(currentModule);
00818     assert(l.size() > 0);
00819     
00820     // have we created a functional manager for this design yet?
00821     if (currentManager == NULL) {
00822         currentManager = Manager::get(currentModule->getDesign());
00823     }
00824     
00825     MultiRefBus::iterator multiRefIter;
00826     vector<BBRef> driverBBRefs;
00827     for(multiRefIter = l.begin(); multiRefIter != l.end(); ++ multiRefIter){
00828 
00829         MultiRef multiRef = *multiRefIter;
00830 
00831         if(multiRef.type == NET){
00832             // there must already be an existing BBRef
00833             oa::oaModBitNet *net = multiRef.net;
00834             assert(net);
00835             assert(net->getAppDefs().includes(bbRefAppDef));
00836             multiRef.bb = bbRefAppDef->get(net);
00837             multiRef.type = BBREF;
00838         }
00839 
00840         assert(multiRef.type == BBREF);
00841  
00842         // setup one input of this reduction operator
00843         driverBBRefs.push_back(multiRef.bb);
00844     }
00845     return MultiRef(currentManager->bbg.unaryBusOpt(optType, driverBBRefs));
00846 }
00847 
00848 
00849 // *****************************************************************************
00850 // reductionOr()
00851 //
00855 // *****************************************************************************
00856 MultiRef
00857 Synthesis::reductionOr(MultiRefBus &l) {
00858     if(l.size() == 1) return *l.begin();
00859     return unaryBusOpt(RtlNode::REDUCTION_OR, l);
00860 }
00861 
00862 
00863 // *****************************************************************************
00864 // reductionXor()
00865 //
00868 // *****************************************************************************
00869 MultiRef
00870 Synthesis::reductionXor(MultiRefBus &l) {
00871     assert(l.size() > 1);
00872     return unaryBusOpt(RtlNode::REDUCTION_XOR, l);
00873 }
00874 
00875 // *****************************************************************************
00876 // reductionAnd()
00877 //
00880 // *****************************************************************************
00881 MultiRef
00882 Synthesis::reductionAnd(MultiRefBus &l) {
00883     if(l.size() == 1) return *l.begin();
00884     return unaryBusOpt(RtlNode::REDUCTION_AND, l);
00885 }
00886 
00887 // *****************************************************************************
00888 // reductionNand()
00889 //
00892 // *****************************************************************************
00893 MultiRef
00894 Synthesis::reductionNand(MultiRefBus &l) {
00895     return unaryBusOpt(RtlNode::REDUCTION_NAND, l);
00896 }
00897 
00898 // *****************************************************************************
00899 // reductionNor()
00900 //
00903 // *****************************************************************************
00904 MultiRef
00905 Synthesis::reductionNor(MultiRefBus &l) {
00906     return unaryBusOpt(RtlNode::REDUCTION_NOR, l);
00907 }
00908 
00909 // *****************************************************************************
00910 // reductionXnor()
00911 //
00914 // *****************************************************************************
00915 MultiRef
00916 Synthesis::reductionXnor(MultiRefBus &l) {
00917     return unaryBusOpt(RtlNode::REDUCTION_XNOR, l);
00918 }
00919 
00920 // *****************************************************************************
00921 // logicNOT()
00922 //
00926 //
00927 // *****************************************************************************
00928 MultiRef
00929 Synthesis::logicNot(MultiRefBus &l) {
00930     return unaryBusOpt(RtlNode::LOGICAL_NOT,l); 
00931 }
00932 // *****************************************************************************
00933 // constantZero()
00934 //
00940 //
00941 // *****************************************************************************
00942 MultiRef
00943 Synthesis::constantZero() {
00944     oa::oaNativeNS      nativeNS;
00945     oa::oaScalarName    name(nativeNS, "tie0");
00946     MultiRef e(oa::oaModScalarNet::find(currentModule, name));
00947     return e;
00948 }
00949 
00950 
00951 // *****************************************************************************
00952 // constantOne()
00953 //
00954 //
00960 //
00961 // *****************************************************************************
00962 MultiRef
00963 Synthesis::constantOne() {
00964     oa::oaNativeNS      nativeNS;
00965     oa::oaScalarName    name(nativeNS, "tie1");
00966     MultiRef e(oa::oaModScalarNet::find(currentModule, name));
00967     return e;
00968 }
00969 
00970 // *****************************************************************************
00971 // binaryBusOpt()
00972 //
00976 //
00977 // *****************************************************************************
00978 MultiRef
00979 Synthesis::binaryBusOpt(RtlNode::OptType optType, MultiRefBus &l1, MultiRefBus &l2) {
00980     assert(l1.size() == l2.size() && l1.size() > 0);
00981 
00982      // have we created a functional manager for this design yet?
00983     if (currentManager == NULL) {
00984         currentManager = Manager::get(currentModule->getDesign());
00985     }
00986     
00987     MultiRefBus::iterator multiRefIter;
00988     vector<BBRef> driverBBRefs1;
00989     for(multiRefIter = l1.begin(); multiRefIter != l1.end(); ++ multiRefIter){
00990 
00991         MultiRef multiRef = *multiRefIter;
00992 
00993         if(multiRef.type == NET){
00994             // there must already be an existing BBRef
00995             oa::oaModBitNet *net = multiRef.net;
00996             assert(net);
00997             assert(net->getAppDefs().includes(bbRefAppDef));
00998             multiRef.bb = bbRefAppDef->get(net);
00999             multiRef.type = BBREF;
01000         }
01001 
01002         assert(multiRef.type == BBREF);
01003  
01004         // setup one input of this reduction operator
01005         driverBBRefs1.push_back(multiRef.bb);
01006     }
01007     vector<BBRef> driverBBRefs2;
01008     for(multiRefIter = l2.begin(); multiRefIter != l2.end(); ++ multiRefIter){
01009 
01010         MultiRef multiRef = *multiRefIter;
01011 
01012         if(multiRef.type == NET){
01013             // there must already be an existing BBRef
01014             oa::oaModBitNet *net = multiRef.net;
01015             assert(net);
01016             assert(net->getAppDefs().includes(bbRefAppDef));
01017             multiRef.bb = bbRefAppDef->get(net);
01018             multiRef.type = BBREF;
01019         }
01020 
01021         assert(multiRef.type == BBREF);
01022  
01023         // setup one input of this reduction operator
01024         driverBBRefs2.push_back(multiRef.bb);
01025     }
01026     return MultiRef(currentManager->bbg.binaryBusOpt(optType,
01027                 driverBBRefs1, driverBBRefs2));
01028 
01029 }
01030 
01031 
01032 // *****************************************************************************
01033 // lessThan()
01034 //
01039 //
01040 // *****************************************************************************
01041 MultiRef
01042 Synthesis::lessThan(MultiRefBus &l1, MultiRefBus &l2) {
01043     return binaryBusOpt(RtlNode::LESS_THAN, l1, l2);
01044 
01045 }
01046 
01047 
01048 // *****************************************************************************
01049 // equalTo()
01050 //
01055 //
01056 // *****************************************************************************
01057 MultiRef
01058 Synthesis::equalTo(MultiRefBus &l1, MultiRefBus &l2) {
01059     return binaryBusOpt(RtlNode::EQUAL,l1, l2); 
01060 }
01061 
01062 // *****************************************************************************
01063 // lessThan()
01064 //
01069 //
01070 // *****************************************************************************
01071 MultiRef
01072 Synthesis::lessThanEqual(MultiRefBus &l1, MultiRefBus &l2) {
01073     return binaryBusOpt(RtlNode::LESS_THAN_EQUAL, l1, l2);
01074 
01075 }
01076 
01077 // *****************************************************************************
01078 // greaterThan()
01079 //
01084 //
01085 // *****************************************************************************
01086 MultiRef
01087 Synthesis::greaterThan(MultiRefBus &l1, MultiRefBus &l2) {
01088     return binaryBusOpt(RtlNode::GREATER_THAN, l1, l2);
01089 
01090 }
01091 
01092 // *****************************************************************************
01093 // greaterThanEqual()
01094 //
01099 //
01100 // *****************************************************************************
01101 MultiRef
01102 Synthesis::greaterThanEqual(MultiRefBus &l1, MultiRefBus &l2) {
01103     return binaryBusOpt(RtlNode::GREATER_THAN_EQUAL, l1, l2);
01104 
01105 }
01106 
01107 // *****************************************************************************
01108 // notEuqalTo()
01109 //
01114 //
01115 // *****************************************************************************
01116 MultiRef
01117 Synthesis::notEqualTo(MultiRefBus &l1, MultiRefBus &l2) {
01118     return binaryBusOpt(RtlNode::NOTEQUAL, l1, l2);
01119 
01120 }
01121 
01122 // *****************************************************************************
01123 // logicAnd()
01124 //
01129 //
01130 // *****************************************************************************
01131 MultiRef
01132 Synthesis::logicAnd(MultiRefBus &l1, MultiRefBus &l2) {
01133     return binaryBusOpt(RtlNode::LOGICAL_AND,l1, l2); 
01134 }
01135 
01136 // *****************************************************************************
01137 // logicOr()
01138 //
01143 //
01144 // *****************************************************************************
01145 MultiRef
01146 Synthesis::logicOr(MultiRefBus &l1, MultiRefBus &l2) {
01147     return binaryBusOpt(RtlNode::LOGICAL_OR,l1, l2); 
01148 }
01149 
01150 // *****************************************************************************
01151 // unaryBusInputOutputOpt()
01152 //
01159 // *****************************************************************************
01160 void
01161 Synthesis::unaryBusInputOutputOpt(RtlNode::OptType optType, int numOutBits,
01162         MultiRefBus &result, MultiRefBus &l) {
01163 
01164     result.clear();
01165 
01166     // have we created a functional manager for this design yet?
01167     if (currentManager == NULL) {
01168         currentManager = Manager::get(currentModule->getDesign());
01169     }
01170     
01171     MultiRefBus::iterator multiRefIter;
01172     vector<BBRef> driverBBRefs;
01173     for(multiRefIter = l.begin(); multiRefIter != l.end(); ++ multiRefIter){
01174 
01175         MultiRef multiRef = *multiRefIter;
01176 
01177         if(multiRef.type == NET){
01178             // there must already be an existing BBRef
01179             oa::oaModBitNet *net = multiRef.net;
01180             assert(net);
01181             assert(net->getAppDefs().includes(bbRefAppDef));
01182             multiRef.bb = bbRefAppDef->get(net);
01183             multiRef.type = BBREF;
01184         }
01185 
01186         assert(multiRef.type == BBREF);
01187  
01188         // setup one input of this operator
01189         driverBBRefs.push_back(multiRef.bb);
01190     }
01191 
01192     // create a BB node
01193     vector<BBRef> outputBBRefs;
01194     currentManager->bbg.unaryBusInputOutputOpt(optType, numOutBits,
01195             driverBBRefs, outputBBRefs);
01196 
01197     // setup outputs (result)
01198     vector<BBRef>::iterator bbRefIter;
01199     for(bbRefIter = outputBBRefs.begin(); bbRefIter != outputBBRefs.end();
01200             ++ bbRefIter) {
01201         result.push_front(MultiRef(*bbRefIter));
01202     }
01203 
01204 }
01205 
01206 // *****************************************************************************
01207 // binaryBusInputOutputOpt()
01208 //
01216 // *****************************************************************************
01217 void
01218 Synthesis::binaryBusInputOutputOpt(RtlNode::OptType optType, int numOutBits,
01219         MultiRefBus &result, MultiRefBus &l1, MultiRefBus &l2) {
01220 
01221     result.clear();
01222 
01223     // have we created a functional manager for this design yet?
01224     if (currentManager == NULL) {
01225         currentManager = Manager::get(currentModule->getDesign());
01226     }
01227     
01228     MultiRefBus::iterator multiRefIter;
01229     vector<BBRef> driverBBRefs1;
01230     for(multiRefIter = l1.begin(); multiRefIter != l1.end(); ++ multiRefIter){
01231 
01232         MultiRef multiRef = *multiRefIter;
01233 
01234         if(multiRef.type == NET){
01235             // there must already be an existing BBRef
01236             oa::oaModBitNet *net = multiRef.net;
01237             assert(net);
01238 
01239 #ifdef DEBUG
01240             oa::oaString str;
01241             net->getName(oa::oaVerilogNS(), str);
01242             DEBUG_PRINTLN("binaryBusInputOutputOpt: " << str);
01243 #endif
01244             assert(net->getAppDefs().includes(bbRefAppDef));
01245             multiRef.bb = bbRefAppDef->get(net);
01246             multiRef.type = BBREF;
01247         }
01248 
01249         assert(multiRef.type == BBREF);
01250  
01251         // setup one input of this operator
01252         driverBBRefs1.push_back(multiRef.bb);
01253     }
01254     vector<BBRef> driverBBRefs2;
01255     for(multiRefIter = l2.begin(); multiRefIter != l2.end(); ++ multiRefIter){
01256 
01257         MultiRef multiRef = *multiRefIter;
01258 
01259         if(multiRef.type == NET){
01260             // there must already be an existing BBRef
01261             oa::oaModBitNet *net = multiRef.net;
01262             assert(net);
01263             assert(net->getAppDefs().includes(bbRefAppDef));
01264             multiRef.bb = bbRefAppDef->get(net);
01265             multiRef.type = BBREF;
01266         }
01267 
01268         assert(multiRef.type == BBREF);
01269  
01270         // setup one input of this operator
01271         driverBBRefs2.push_back(multiRef.bb);
01272     }
01273 
01274     // create a BB node
01275     vector<BBRef> outputBBRefs;
01276     currentManager->bbg.binaryBusInputOutputOpt(optType, numOutBits,
01277             driverBBRefs1, driverBBRefs2, outputBBRefs);
01278 
01279     // setup outputs (result)
01280     vector<BBRef>::iterator bbRefIter;
01281     for(bbRefIter = outputBBRefs.begin(); bbRefIter != outputBBRefs.end();
01282             ++ bbRefIter) {
01283         result.push_front(MultiRef(*bbRefIter));
01284     }
01285 
01286 }
01287 
01288 // *****************************************************************************
01289 // arithmeticAdd()
01290 //
01296 // *****************************************************************************
01297 void
01298 Synthesis::arithmeticAdd(MultiRefBus &result, MultiRefBus &l1, MultiRefBus &l2) {
01299     assert(l1.size() == l2.size());
01300     //binaryBusInputOutputOpt(RtlNode::ADD, l1.size(), result, l1, l2);
01301     binaryBusInputOutputOpt(RtlNode::ADD, l1.size()+1, result, l1, l2);
01302 }
01303 
01304 
01305 // *****************************************************************************
01306 // arithmeticSubtract()
01307 //
01312 //
01313 // *****************************************************************************
01314 void
01315 Synthesis::arithmeticSubtract(MultiRefBus &result, MultiRefBus &l1, MultiRefBus &l2) {
01316     assert(l1.size() == l2.size());
01317     binaryBusInputOutputOpt(RtlNode::SUBTRACT, l1.size(), result, l1, l2);
01318 }
01319 
01320 
01321 // *****************************************************************************
01322 // arithmeticMultiply()
01323 //
01328 //
01329 // *****************************************************************************
01330 void
01331 Synthesis::arithmeticMultiply(MultiRefBus &result, MultiRefBus &l1, MultiRefBus &l2) {
01332     binaryBusInputOutputOpt(RtlNode::MULTIPLY, l1.size()+l2.size(), result, l1, l2);
01333 }
01334 
01335 
01336 // *****************************************************************************
01337 // arithmeticDivide()
01338 //
01343 //
01344 // *****************************************************************************
01345 void        
01346 Synthesis::arithmeticDivide(MultiRefBus &result, MultiRefBus &l1, MultiRefBus &l2) {
01347     binaryBusInputOutputOpt(RtlNode::DIVIDE, l1.size(), result, l1, l2);
01348 }
01349 
01350 
01351 // *****************************************************************************
01352 // arithmeticDivide()
01353 //
01358 //
01359 // *****************************************************************************
01360 void
01361 Synthesis::arithmeticModulo(MultiRefBus &result, MultiRefBus &l1, MultiRefBus &l2) {
01362     binaryBusInputOutputOpt(RtlNode::MODULO, l2.size(), result, l1, l2);
01363 }
01364 
01365 // *****************************************************************************
01366 // leftShift()
01367 //
01373 // *****************************************************************************
01374 void
01375 Synthesis::leftShift(MultiRefBus &result, MultiRefBus &l1, MultiRefBus &l2) {
01376     binaryBusInputOutputOpt(RtlNode::LEFT_SHIFT, l2.size(), result, l1, l2);
01377 }
01378 
01379 // *****************************************************************************
01380 // latch()
01381 //
01390 //
01391 // *****************************************************************************
01392 MultiRef
01393 Synthesis::latch(MultiRef enable, MultiRef in, const string name) {
01394     assert(nameSpace);
01395     assert(currentModule);
01396     static_cast<void>(name);
01397 
01398     // have we created a functional manager for this design yet?
01399     if (currentManager == NULL) {
01400         currentManager = Manager::get(currentModule->getDesign());
01401     }
01402 
01403     // if this MultiRef is a net, convert it to a BBRef
01404     if (in.type == NET) {
01405         // there must already be an existing BBRef
01406         oa::oaModBitNet *net = in.net;
01407         assert(net);
01408         assert(net->getAppDefs().includes(bbRefAppDef));
01409         in.bb = bbRefAppDef->get(net);
01410         in.type = BBREF;
01411     }
01412 
01413     return MultiRef(currentManager->bbg.bitSeq(RtlNode::LATCH, in.bb, enable.bb,
01414                 currentManager->bbg.getNull(),
01415                 currentManager->bbg.getNull()));
01416 }
01417 
01418 // *****************************************************************************
01419 // seq()
01420 //
01426 //
01427 // *****************************************************************************
01428 MultiRef
01429 Synthesis::seq(MultiRef in, MultiRef clock, const string name) {
01430     assert(nameSpace);
01431     assert(currentModule);
01432     static_cast<void>(name);
01433 
01434     // have we created a functional manager for this design yet?
01435     if (currentManager == NULL) {
01436         currentManager = Manager::get(currentModule->getDesign());
01437     }
01438 
01439     // if in is a net, convert it to a BBRef
01440     if (in.type == NET) {
01441         // there must already be an existing BBRef
01442         oa::oaModBitNet *net = in.net;
01443         assert(net);
01444         assert(net->getAppDefs().includes(bbRefAppDef));
01445         in.bb = bbRefAppDef->get(net);
01446         in.type = BBREF;
01447     }
01448     if (clock.type == NET) {
01449         // there must already be an existing BBRef
01450         oa::oaModBitNet *net = clock.net;
01451         assert(net);
01452         assert(net->getAppDefs().includes(bbRefAppDef));
01453         clock.bb = bbRefAppDef->get(net);
01454         clock.type = BBREF;
01455     }
01456 
01457     DEBUG_PRINTLN("\t\t\t created state bit")
01458 
01459     return MultiRef(currentManager->bbg.bitSeq(RtlNode::DFF, in.bb, clock.bb,
01460                 currentManager->bbg.getNull(), 
01461                 currentManager->bbg.getNull()));
01462 }
01463 
01464 
01465 // *****************************************************************************
01466 // seq()
01467 //
01477 //
01478 // *****************************************************************************
01479 MultiRef
01480 Synthesis::seq(MultiRef in, MultiRef clock, MultiRef aLoad, MultiRef aData, 
01481         const string name) {
01482     assert(nameSpace);
01483     assert(currentModule);
01484     static_cast<void>(name);
01485 
01486     // have we created a functional manager for this design yet?
01487     if (currentManager == NULL) {
01488         currentManager = Manager::get(currentModule->getDesign());
01489     }
01490 
01491     // if in is a net, convert it to a BBRef
01492     if (in.type == NET) {
01493         // there must already be an existing BBRef
01494         oa::oaModBitNet *net = in.net;
01495         assert(net);
01496         assert(net->getAppDefs().includes(bbRefAppDef));
01497         in.bb = bbRefAppDef->get(net);
01498         in.type = BBREF;
01499     }
01500     // if clock is a net, convert it to a BBRef
01501     if (clock.type == NET) {
01502         // there must already be an existing BBRef
01503         oa::oaModBitNet *net = clock.net;
01504         assert(net);
01505         assert(net->getAppDefs().includes(bbRefAppDef));
01506         clock.bb = bbRefAppDef->get(net);
01507         clock.type = BBREF;
01508     }
01509     // if aLoad is a net, convert it to a BBRef
01510     if (aLoad.type == NET) {
01511         // there must already be an existing BBRef
01512         oa::oaModBitNet *net = aLoad.net;
01513         assert(net);
01514         assert(net->getAppDefs().includes(bbRefAppDef));
01515         aLoad.bb = bbRefAppDef->get(net);
01516         aLoad.type = BBREF;
01517     }
01518     // if aData is a net, convert it to a BBRef
01519     if (aData.type == NET) {
01520         // there must already be an existing BBRef
01521         oa::oaModBitNet *net = aData.net;
01522         assert(net);
01523         assert(net->getAppDefs().includes(bbRefAppDef));
01524         aData.bb = bbRefAppDef->get(net);
01525         aData.type = BBREF;
01526     }
01527 
01528     DEBUG_PRINTLN("\t\t\t created state bit")
01529 
01530     return MultiRef(currentManager->bbg.bitSeq(RtlNode::DFF, in.bb, clock.bb,
01531                 aLoad.bb, aData.bb));
01532 }
01533 
01534 
01535 /*
01536 // *****************************************************************************
01537 // annotateAsynchronousSignal()
01538 //
01544 //
01545 // *****************************************************************************
01546 void
01547 Synthesis::annotateAsynchronousSignal(oagAi::Ref sequential, const string label, MultiRef signal) {
01548     assert(currentManager);
01549 
01550     // TODO: check back to see whether we need this
01551 
01552     // if the MultiRef is a net, convert it to an oagAi::Ref
01553     if (signal.type == NET) {
01554         // there must already be an existing oagAi::Ref
01555         oa::oaModBitNet *net = signal.net;
01556         assert(net);
01557         assert(net->getAppDefs().includes(AiRefAppDef));
01558         signal.ai = AiRefAppDef->get(net);
01559         signal.type = AIREF;
01560     }
01561     
01562     // annotate the asynchronous input
01563     DEBUG_PRINTLN("\tannotating node " << sequential 
01564                   << " with asychronous signal " << label 
01565                   << " = " << signal.ai);
01566     oagAi::Node::SequentialData *seqData = currentManager->ai.getSequentialData(sequential);
01567     assert(seqData);
01568     assert(seqData->abstractionLevel == oagAi::Node::SequentialData::BLACK_BOX);
01569     seqData->signals[label] = signal.ai;
01570 }
01571 */
01572     
01573 // *****************************************************************************
01574 // mux()
01575 //
01577 //
01578 // *****************************************************************************
01579 MultiRef
01580 Synthesis::mux(MultiRef sel, MultiRef in0, MultiRef in1) {
01581 
01582     if (in0 == in1) {
01583         return in0;
01584     }
01585 
01586     // have we created a functional manager for this design yet?
01587     if (currentManager == NULL) {
01588         currentManager = Manager::get(currentModule->getDesign());
01589     }
01590 
01591     // if in0 is a net, convert it to a BBRef
01592     if (in0.type == NET) {
01593         // there must already be an existing BBRef
01594         oa::oaModBitNet *net = in0.net;
01595         assert(net);
01596         assert(net->getAppDefs().includes(bbRefAppDef));
01597         in0.bb = bbRefAppDef->get(net);
01598         in0.type = BBREF;
01599     }
01600     // if in1 is a net, convert it to a BBRef
01601     if (in1.type == NET) {
01602         // there must already be an existing BBRef
01603         oa::oaModBitNet *net = in1.net;
01604         assert(net);
01605         assert(net->getAppDefs().includes(bbRefAppDef));
01606         in1.bb = bbRefAppDef->get(net);
01607         in1.type = BBREF;
01608     }
01609     // if sel is a net, convert it to a BBRef
01610     if (sel.type == NET) {
01611         // there must already be an existing BBRef
01612         oa::oaModBitNet *net = sel.net;
01613         assert(net);
01614         assert(net->getAppDefs().includes(bbRefAppDef));
01615         sel.bb = bbRefAppDef->get(net);
01616         sel.type = BBREF;
01617     }
01618 
01619     return MultiRef(currentManager->bbg.bitMux(in0.bb, in1.bb, sel.bb));
01620 }
01621 
01622 // *****************************************************************************
01623 // mux()
01624 //
01626 //
01627 // *****************************************************************************
01628 MultiRef
01629 Synthesis::mux(MultiRefBus& select, MultiRefBus &in0) {
01630 
01631     // have we created a functional manager for this design yet?
01632     if (currentManager == NULL) {
01633         currentManager = Manager::get(currentModule->getDesign());
01634     }
01635     
01636     MultiRefBus::iterator multiRefIter;
01637     vector<BBRef> driverBBRefs1;
01638     for(multiRefIter = in0.begin(); multiRefIter != in0.end(); ++ multiRefIter){
01639 
01640         MultiRef multiRef = *multiRefIter;
01641 
01642         if(multiRef.type == NET){
01643             // there must already be an existing BBRef
01644             oa::oaModBitNet *net = multiRef.net;
01645             assert(net);
01646             assert(net->getAppDefs().includes(bbRefAppDef));
01647             multiRef.bb = bbRefAppDef->get(net);
01648             multiRef.type = BBREF;
01649         }
01650 
01651         assert(multiRef.type == BBREF);
01652  
01653         // setup one input of this operator
01654         driverBBRefs1.push_back(multiRef.bb);
01655     }
01656     vector<BBRef> driverBBRefsSel;
01657     for(multiRefIter = select.begin(); multiRefIter != select.end(); ++ multiRefIter){
01658 
01659         MultiRef multiRef = *multiRefIter;
01660 
01661         if(multiRef.type == NET){
01662             // there must already be an existing BBRef
01663             oa::oaModBitNet *net = multiRef.net;
01664             assert(net);
01665             assert(net->getAppDefs().includes(bbRefAppDef));
01666             multiRef.bb = bbRefAppDef->get(net);
01667             multiRef.type = BBREF;
01668         }
01669 
01670         assert(multiRef.type == BBREF);
01671  
01672         // setup one input of this operator
01673         driverBBRefsSel.push_back(multiRef.bb);
01674     }
01675 
01676     // create a BB node
01677     return MultiRef(currentManager->bbg.busMux(driverBBRefs1, driverBBRefsSel));
01678 
01679 }
01680 
01681 
01682 
01683 // *****************************************************************************
01684 // mux()
01685 //
01687 //
01688 // *****************************************************************************
01689 void
01690 Synthesis::mux(MultiRefBus &result, MultiRefBus& select, 
01691         MultiRefBus &in0, MultiRefBus &in1) {
01692     assert(in0.size() == in1.size());
01693     result.clear();
01694 
01695     // have we created a functional manager for this design yet?
01696     if (currentManager == NULL) {
01697         currentManager = Manager::get(currentModule->getDesign());
01698     }
01699     
01700     MultiRefBus::iterator multiRefIter;
01701     vector<BBRef> driverBBRefs1;
01702     for(multiRefIter = in0.begin(); multiRefIter != in0.end(); ++ multiRefIter){
01703 
01704         MultiRef multiRef = *multiRefIter;
01705 
01706         if(multiRef.type == NET){
01707             // there must already be an existing BBRef
01708             oa::oaModBitNet *net = multiRef.net;
01709             assert(net);
01710             assert(net->getAppDefs().includes(bbRefAppDef));
01711             multiRef.bb = bbRefAppDef->get(net);
01712             multiRef.type = BBREF;
01713         }
01714 
01715         assert(multiRef.type == BBREF);
01716  
01717         // setup one input of this operator
01718         driverBBRefs1.push_back(multiRef.bb);
01719     }
01720     vector<BBRef> driverBBRefs2;
01721     for(multiRefIter = in1.begin(); multiRefIter != in1.end(); ++ multiRefIter){
01722 
01723         MultiRef multiRef = *multiRefIter;
01724 
01725         if(multiRef.type == NET){
01726             // there must already be an existing BBRef
01727             oa::oaModBitNet *net = multiRef.net;
01728             assert(net);
01729             assert(net->getAppDefs().includes(bbRefAppDef));
01730             multiRef.bb = bbRefAppDef->get(net);
01731             multiRef.type = BBREF;
01732         }
01733 
01734         assert(multiRef.type == BBREF);
01735  
01736         // setup one input of this operator
01737         driverBBRefs2.push_back(multiRef.bb);
01738     }
01739     vector<BBRef> driverBBRefsSel;
01740     for(multiRefIter = select.begin(); multiRefIter != select.end(); ++ multiRefIter){
01741 
01742         MultiRef multiRef = *multiRefIter;
01743 
01744         if(multiRef.type == NET){
01745             // there must already be an existing BBRef
01746             oa::oaModBitNet *net = multiRef.net;
01747             assert(net);
01748             assert(net->getAppDefs().includes(bbRefAppDef));
01749             multiRef.bb = bbRefAppDef->get(net);
01750             multiRef.type = BBREF;
01751         }
01752 
01753         assert(multiRef.type == BBREF);
01754  
01755         // setup one input of this operator
01756         driverBBRefsSel.push_back(multiRef.bb);
01757     }
01758 
01759     // create a BB node
01760     vector<BBRef> outputBBRefs;
01761     currentManager->bbg.busMux(driverBBRefs1, driverBBRefs2, driverBBRefsSel,
01762             outputBBRefs);
01763 
01764     // setup outputs (result)
01765     vector<BBRef>::iterator bbRefIter;
01766     for(bbRefIter = outputBBRefs.begin(); bbRefIter != outputBBRefs.end();
01767             ++ bbRefIter) {
01768         result.push_front(MultiRef(*bbRefIter));
01769     }
01770 
01771 }
01772 
01773 
01774 /*
01775 // *****************************************************************************
01776 // fullAdder()
01777 //
01781 //
01782 // *****************************************************************************
01783 void
01784 Synthesis::fullAdder(MultiRef &sum, MultiRef &carryOut, 
01785                      MultiRef e1, MultiRef e2, MultiRef carryIn) {
01786     // YH: fullAdder() needs to be updated
01787     MultiRef intermediate = xorOf(e1, e2);
01788     sum = xorOf(carryIn, intermediate);
01789     carryOut = orOf(andOf(e1,e2), andOf(intermediate, carryIn));
01790 }*/
01791 
01792 
01793 // *****************************************************************************
01794 // multiBitConstant()
01795 //
01800 //
01801 // *****************************************************************************
01802 void
01803 Synthesis::multiBitConstant(MultiRefBus &result, int value, int bits) {
01804     result.clear();
01805     for(int i=0; (bits == 0 ? value != 0 : i<bits); i++, value = value >> 1) {
01806         if (value % 2) {
01807             result.push_front(constantOne());
01808         } else {
01809             result.push_front(constantZero());
01810         }
01811     }
01812     if (result.empty()) {
01813         result.push_back(constantZero());
01814     }
01815 }
01816 
01817 }

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