00001
00002 #include "oaDesignDB.h"
00003 #include "oagFpgaManager.h"
00004 #include "oagFpgaSynthesis.h"
00005 #include <list>
00006 #include <set>
00007
00008
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
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
00036
00055
00056 void
00057 Synthesis::setOverwriteStructure(bool overwrite) {
00058 overwriteStructure = overwrite;
00059 }
00060
00061
00062
00063
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
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
00139 if (currentModule) {
00140 oa::oaModule *module = oa::oaModule::find(currentModule->getDesign(), cellName);
00141 if (module) {
00142 return module;
00143 }
00144 }
00145
00146
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
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
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
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
00190 }
00191 }
00192
00193 cout << endl;
00194 }
00195
00196 return NULL;
00197 }
00198
00199
00200
00201
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
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
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
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
00261 oa::oaModule *module = design->getTopModule();
00262 if (!module) {
00263 module = oa::oaModule::create(design, cellName);
00264 design->setTopModule(module);
00265 } else {
00266
00267
00268 if (overwriteStructure) {
00269
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
00280
00281
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
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
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
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
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
00343
00345
00346
00347 oa::oaModScalarNet*
00348 Synthesis::createScalarNet(const string identifier) {
00349 assert(nameSpace);
00350 assert(currentModule);
00351
00352
00353 oa::oaScalarName netName(*nameSpace, oa::oaString(identifier.c_str()));
00354 oa::oaModScalarNet *net = oa::oaModScalarNet::find(currentModule, netName);
00355 if (!net) {
00356
00357 net = oa::oaModScalarNet::create(currentModule, netName);
00358 }
00359
00360
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
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
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
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
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
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
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
00457
00458 return term;
00459 }
00460
00461
00462 if (portPosition != oacNullIndex) {
00463 newTerm->setPosition(portPosition);
00464 }
00465 return newTerm;
00466 }
00467
00468
00469
00470
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
00498
00500
00501
00502 oa::oaModBusNetBit*
00503 Synthesis::findBusNetBit(const string identifier, const int bit) {
00504 assert(nameSpace);
00505 assert(currentModule);
00506
00507
00508 oa::oaScalarName netName(*nameSpace, identifier.c_str());
00509 return oa::oaModBusNetBit::find(currentModule, netName, bit);
00510 }
00511
00512
00513
00514
00515
00517
00518
00519 oa::oaModScalarNet*
00520 Synthesis::findScalarNet(const string identifier) {
00521 assert(nameSpace);
00522 assert(currentModule);
00523
00524
00525 oa::oaScalarName netName(*nameSpace, identifier.c_str());
00526 return oa::oaModScalarNet::find(currentModule, netName);
00527 }
00528
00529
00530
00531
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
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
00565
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
00577
00578 assert( net->getAppDefs().includes(bbRefAppDef) );
00579
00580 BBRef node = bbRefAppDef->get(net);
00581
00582
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
00596
00598
00599
00600 MultiRef
00601 Synthesis::notOf(MultiRef e) {
00602 assert(currentModule);
00603
00604
00605 if (currentManager == NULL) {
00606 currentManager = Manager::get(currentModule->getDesign());
00607 }
00608
00609
00610 if (e.type == NET) {
00611
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
00625
00629
00630
00631 MultiRef
00632 Synthesis::binaryOpt(RtlNode::OptType optType, MultiRef e1, MultiRef e2) {
00633 assert(currentModule);
00634
00635
00636 if (currentManager == NULL) {
00637 currentManager = Manager::get(currentModule->getDesign());
00638 }
00639
00640
00641 if (e1.type == NET) {
00642
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
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
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
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
00694
00698
00699
00700 MultiRef
00701 Synthesis::xorOf(MultiRef e1, MultiRef e2) {
00702 return binaryOpt(RtlNode::BITWISE_XOR, e1, e2);
00703 }
00704
00705
00706
00707
00711
00712
00713 MultiRef
00714 Synthesis::norOf(MultiRef e1, MultiRef e2) {
00715 return binaryOpt(RtlNode::BITWISE_NOR, e1, e2);
00716 }
00717
00718
00719
00720
00724
00725
00726 MultiRef
00727 Synthesis::nandOf(MultiRef e1, MultiRef e2) {
00728 return binaryOpt(RtlNode::BITWISE_NAND, e1, e2);
00729 }
00730
00731
00732
00733
00737
00738
00739 MultiRef
00740 Synthesis::xnorOf(MultiRef e1, MultiRef e2) {
00741 return binaryOpt(RtlNode::BITWISE_XNOR, e1, e2);
00742 }
00743
00744
00745
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
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
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
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
00810
00813
00814
00815 MultiRef
00816 Synthesis::unaryBusOpt(RtlNode::OptType optType, MultiRefBus &l) {
00817 assert(currentModule);
00818 assert(l.size() > 0);
00819
00820
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
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
00843 driverBBRefs.push_back(multiRef.bb);
00844 }
00845 return MultiRef(currentManager->bbg.unaryBusOpt(optType, driverBBRefs));
00846 }
00847
00848
00849
00850
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
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
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
00889
00892
00893 MultiRef
00894 Synthesis::reductionNand(MultiRefBus &l) {
00895 return unaryBusOpt(RtlNode::REDUCTION_NAND, l);
00896 }
00897
00898
00899
00900
00903
00904 MultiRef
00905 Synthesis::reductionNor(MultiRefBus &l) {
00906 return unaryBusOpt(RtlNode::REDUCTION_NOR, l);
00907 }
00908
00909
00910
00911
00914
00915 MultiRef
00916 Synthesis::reductionXnor(MultiRefBus &l) {
00917 return unaryBusOpt(RtlNode::REDUCTION_XNOR, l);
00918 }
00919
00920
00921
00922
00926
00927
00928 MultiRef
00929 Synthesis::logicNot(MultiRefBus &l) {
00930 return unaryBusOpt(RtlNode::LOGICAL_NOT,l);
00931 }
00932
00933
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
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
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
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
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
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
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
01024 driverBBRefs2.push_back(multiRef.bb);
01025 }
01026 return MultiRef(currentManager->bbg.binaryBusOpt(optType,
01027 driverBBRefs1, driverBBRefs2));
01028
01029 }
01030
01031
01032
01033
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
01050
01055
01056
01057 MultiRef
01058 Synthesis::equalTo(MultiRefBus &l1, MultiRefBus &l2) {
01059 return binaryBusOpt(RtlNode::EQUAL,l1, l2);
01060 }
01061
01062
01063
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
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
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
01109
01114
01115
01116 MultiRef
01117 Synthesis::notEqualTo(MultiRefBus &l1, MultiRefBus &l2) {
01118 return binaryBusOpt(RtlNode::NOTEQUAL, l1, l2);
01119
01120 }
01121
01122
01123
01124
01129
01130
01131 MultiRef
01132 Synthesis::logicAnd(MultiRefBus &l1, MultiRefBus &l2) {
01133 return binaryBusOpt(RtlNode::LOGICAL_AND,l1, l2);
01134 }
01135
01136
01137
01138
01143
01144
01145 MultiRef
01146 Synthesis::logicOr(MultiRefBus &l1, MultiRefBus &l2) {
01147 return binaryBusOpt(RtlNode::LOGICAL_OR,l1, l2);
01148 }
01149
01150
01151
01152
01159
01160 void
01161 Synthesis::unaryBusInputOutputOpt(RtlNode::OptType optType, int numOutBits,
01162 MultiRefBus &result, MultiRefBus &l) {
01163
01164 result.clear();
01165
01166
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
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
01189 driverBBRefs.push_back(multiRef.bb);
01190 }
01191
01192
01193 vector<BBRef> outputBBRefs;
01194 currentManager->bbg.unaryBusInputOutputOpt(optType, numOutBits,
01195 driverBBRefs, outputBBRefs);
01196
01197
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
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
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
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
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
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
01271 driverBBRefs2.push_back(multiRef.bb);
01272 }
01273
01274
01275 vector<BBRef> outputBBRefs;
01276 currentManager->bbg.binaryBusInputOutputOpt(optType, numOutBits,
01277 driverBBRefs1, driverBBRefs2, outputBBRefs);
01278
01279
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
01290
01296
01297 void
01298 Synthesis::arithmeticAdd(MultiRefBus &result, MultiRefBus &l1, MultiRefBus &l2) {
01299 assert(l1.size() == l2.size());
01300
01301 binaryBusInputOutputOpt(RtlNode::ADD, l1.size()+1, result, l1, l2);
01302 }
01303
01304
01305
01306
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
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
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
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
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
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
01399 if (currentManager == NULL) {
01400 currentManager = Manager::get(currentModule->getDesign());
01401 }
01402
01403
01404 if (in.type == NET) {
01405
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
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
01435 if (currentManager == NULL) {
01436 currentManager = Manager::get(currentModule->getDesign());
01437 }
01438
01439
01440 if (in.type == NET) {
01441
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
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
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
01487 if (currentManager == NULL) {
01488 currentManager = Manager::get(currentModule->getDesign());
01489 }
01490
01491
01492 if (in.type == NET) {
01493
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
01501 if (clock.type == NET) {
01502
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
01510 if (aLoad.type == NET) {
01511
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
01519 if (aData.type == NET) {
01520
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
01538
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
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
01587 if (currentManager == NULL) {
01588 currentManager = Manager::get(currentModule->getDesign());
01589 }
01590
01591
01592 if (in0.type == NET) {
01593
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
01601 if (in1.type == NET) {
01602
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
01610 if (sel.type == NET) {
01611
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
01624
01626
01627
01628 MultiRef
01629 Synthesis::mux(MultiRefBus& select, MultiRefBus &in0) {
01630
01631
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
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
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
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
01673 driverBBRefsSel.push_back(multiRef.bb);
01674 }
01675
01676
01677 return MultiRef(currentManager->bbg.busMux(driverBBRefs1, driverBBRefsSel));
01678
01679 }
01680
01681
01682
01683
01684
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
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
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
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
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
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
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
01756 driverBBRefsSel.push_back(multiRef.bb);
01757 }
01758
01759
01760 vector<BBRef> outputBBRefs;
01761 currentManager->bbg.busMux(driverBBRefs1, driverBBRefs2, driverBBRefsSel,
01762 outputBBRefs);
01763
01764
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
01777
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
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 }