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

oagFpgaModuleCompiler.cpp

Go to the documentation of this file.
00001 #include "oaDesignDB.h"
00002 #include "oagFpgaManager.h"
00003 #include "oagFpgaModuleCompiler.h"
00004 #include "oagFpgaVerilogSynthesis.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 Manager                             *ModuleCompiler::currentManager = NULL;
00024 
00025 // *****************************************************************************
00026 // scalarNet2Ai()
00027 //
00029 //
00030 // *****************************************************************************
00031 void
00032 ModuleCompiler::scalarNet2Ai(oa::oaModBitNet* net) {
00033     assert(net);
00034 
00035     // create a terminal node if module has functional description
00036     if (currentManager != NULL) {
00037         currentManager->setNetToAiConnection(net, 
00038             currentManager->ai.newTerminal( currentManager->ai.getNull()) );
00039     }
00040 }
00041 
00042 
00043 // *****************************************************************************
00044 // busNet2Ai()
00045 //
00047 //
00048 // *****************************************************************************
00049 void
00050 ModuleCompiler::busNet2Ai(oa::oaModBusNet* bus) {
00051     assert(bus);
00052     
00053     // create terminal AI nodes if functional manager exists
00054     if (currentManager != NULL) {
00055         for(int b = 0; b<=abs(bus->getStop()-bus->getStart()); b++) {
00056             currentManager->setNetToAiConnection(bus->getBit(b), 
00057                 currentManager->ai.newTerminal(currentManager->ai.getNull()) );
00058         }
00059     }
00060 }
00061 
00062 // *****************************************************************************
00063 // compileOneModule()
00064 //
00066 //
00067 // *****************************************************************************
00068 void 
00069 ModuleCompiler::compileOneModule(oa::oaModule *module) {
00070 
00071     // Convert all nets within this module to AI nodes
00072     // for preparing the AI nodes lookup for nets during the synthesis 
00073     // of the RTL nodes
00074     oa::oaModBitNet *net;
00075     oa::oaIter<oa::oaModBitNet> netIter(module->getNets(oacNetIterSingleBit));
00076     while ((net = netIter.getNext())) {
00077         // do nothing for constant one and zero nets
00078         if(net->getNumBits() > 1) 
00079             continue;
00080         scalarNet2Ai(net);
00081     }
00082 }
00083 
00084 // *****************************************************************************
00085 // compileModules()
00086 //
00089 //
00090 // *****************************************************************************
00091 void
00092 ModuleCompiler::compileModules(oa::oaLib *lib, oa::oaView *view) {
00093     assert(lib);
00095     assert(view);
00096 
00097     oa::oaScalarName libName;
00098     lib->getName(libName);
00099     oa::oaScalarName viewName;
00100     view->getName(viewName);
00101 
00102     oa::oaCellView *cellView;
00103     oa::oaIter<oa::oaCellView> cellViewIter(view->getCellViews());
00104 
00105     // setup AI nodes for all nets within each modules
00106     while((cellView = cellViewIter.getNext())) {
00107         oa::oaScalarName cellName;
00108         cellView->getCell()->getName(cellName);
00109 
00110         // for each design in the library
00111         oa::oaDesign *design = oa::oaDesign::find(libName, cellName, viewName);
00112         if (design) { 
00113             // for each module ...
00114             oa::oaModule *module;
00115             oa::oaIter<oa::oaModule> moduleIter(design->getModules());
00116             currentManager = static_cast<Manager*>(managerAppDef->get(design));
00117             while(module = moduleIter.getNext()){
00118                 compileOneModule(module);
00119             }
00120             // compile all RTL nodes
00121             if(currentManager){
00122                 for(vector<RtlNode*>::iterator rtlNodeIter = 
00123                     currentManager->bbg.dataBBNodes.begin(); 
00124                     rtlNodeIter != currentManager->bbg.dataBBNodes.end();
00125                 ++ rtlNodeIter) {
00126                     compileBBNode((*rtlNodeIter)->self);
00127                 }
00128             }
00129 #ifdef DEBUG
00130             currentManager->ai.print();
00131 #endif
00132         }
00133     }
00134 }
00135 
00136 // *****************************************************************************
00137 // compileFunctionalOptBBNode()
00138 //
00140 //
00141 // *****************************************************************************
00142 void
00143 ModuleCompiler::compileFunctionalOptBBNode(RtlNode* bbNode) {
00144 
00145     assert(bbNode->funcType == RtlNode::OPERATOR);
00146 
00147     list<oagAi::Ref> op1, op2, op3, result;
00148     oagAi::Ref discard;
00149     result.clear();
00150     BBRef2AiRef(bbNode->optInfo->op1, op1);
00151     BBRef2AiRef(bbNode->optInfo->op2, op2);
00152     BBRef2AiRef(bbNode->optInfo->op3, op3);
00153     
00154     switch(bbNode->optType){
00155         case RtlNode::BUNDLE:
00156 
00157             cerr << "RTL node cannot be BUNDLE" << endl;
00158             QUIT_ON_INTERNAL_ERROR;
00159             break;
00160 
00161         case RtlNode::BITWISE_AND: {
00162 
00163             zeroExpand(op1, op2);
00164             assert(op1.size() == op2.size());
00165 
00166             list<oagAi::Ref>::iterator op1Iter = op1.begin(), op2Iter = op2.begin();
00167             while(op1Iter != op1.end() && op2Iter != op2.end()) {
00168                 result.push_back( andOf(*op1Iter, *op2Iter) );
00169                 ++op1Iter; ++op2Iter;
00170             }
00171 
00172             break;
00173         }
00174 
00175         case RtlNode::BITWISE_NOT: {
00176 
00177             list<oagAi::Ref>::iterator op1Iter = op1.begin();
00178             while(op1Iter != op1.end()) {
00179                 result.push_back( notOf(*op1Iter) );
00180                 ++op1Iter;
00181             }
00182 
00183             break;
00184                                             }
00185 
00186         case RtlNode::BITWISE_OR: {
00187 
00188             zeroExpand(op1, op2);
00189             assert(op1.size() == op2.size());
00190 
00191             list<oagAi::Ref>::iterator op1Iter = op1.begin(), op2Iter = op2.begin();
00192             while(op1Iter != op1.end() && op2Iter != op2.end()) {
00193                 result.push_back( orOf(*op1Iter, *op2Iter) );
00194                 ++op1Iter; ++op2Iter;
00195             }
00196 
00197             break;
00198                                            }
00199 
00200         case RtlNode::BITWISE_XOR:{
00201 
00202             zeroExpand(op1, op2);
00203             assert(op1.size() == op2.size());
00204 
00205             list<oagAi::Ref>::iterator op1Iter = op1.begin(), op2Iter = op2.begin();
00206             while(op1Iter != op1.end() && op2Iter != op2.end()) {
00207                 result.push_back( xorOf(*op1Iter, *op2Iter) );
00208                 ++op1Iter; ++op2Iter;
00209             }
00210 
00211             break;
00212                                            }
00213 
00214         case RtlNode::BITWISE_NOR: {
00215 
00216             zeroExpand(op1, op2);
00217             assert(op1.size() == op2.size());
00218 
00219             list<oagAi::Ref>::iterator op1Iter = op1.begin(), op2Iter = op2.begin();
00220             while(op1Iter != op1.end() && op2Iter != op2.end()) {
00221                 result.push_back( notOf(orOf(*op1Iter, *op2Iter)) );
00222                 ++op1Iter; ++op2Iter;
00223             }
00224 
00225             break;
00226                                             }
00227 
00228         case RtlNode::BITWISE_NAND: {
00229 
00230             zeroExpand(op1, op2);
00231             assert(op1.size() == op2.size());
00232 
00233             list<oagAi::Ref>::iterator op1Iter = op1.begin(), op2Iter = op2.begin();
00234             while(op1Iter != op1.end() && op2Iter != op2.end()) {
00235                 result.push_back( notOf(andOf(*op1Iter, *op2Iter)) );
00236                 ++op1Iter; ++op2Iter;
00237             }
00238 
00239             break;
00240                                              }
00241 
00242         case RtlNode::BITWISE_XNOR: {
00243 
00244             zeroExpand(op1, op2);
00245             assert(op1.size() == op2.size());
00246 
00247             list<oagAi::Ref>::iterator op1Iter = op1.begin(), op2Iter = op2.begin();
00248             while(op1Iter != op1.end() && op2Iter != op2.end()) {
00249                 result.push_back( notOf(xorOf(*op1Iter, *op2Iter)) );
00250                 ++op1Iter; ++op2Iter;
00251             }
00252 
00253             break;
00254                                              }
00255 
00256         case RtlNode::LOGICAL_AND:
00257 
00258             zeroExpand(op1, op2);
00259             assert(op1.size() == op2.size());
00260 
00261             result.push_back(andOf(reductionOr(op1), reductionOr(op2)));
00262             break;
00263 
00264         case RtlNode::LOGICAL_NOT:
00265 
00266             result.push_back(notOf(reductionOr(op1)));
00267             break;
00268 
00269         case RtlNode::LOGICAL_OR:
00270 
00271             result.push_back(orOf(reductionOr(op1), reductionOr(op2)));
00272             break;
00273 
00274         case RtlNode::REDUCTION_AND:
00275 
00276             result.push_back(reductionAnd(op1));
00277             break;
00278 
00279         case RtlNode::REDUCTION_OR:
00280 
00281             result.push_back(reductionOr(op1));
00282             break;
00283 
00284         case RtlNode::REDUCTION_XOR:
00285 
00286             result.push_back(reductionXor(op1));
00287             break;
00288 
00289         case RtlNode::REDUCTION_NAND: 
00290 
00291             result.push_back(notOf(reductionAnd(op1)));
00292             break;
00293 
00294         case RtlNode::REDUCTION_NOR: 
00295 
00296             result.push_back(notOf(reductionOr(op1)));
00297             break;
00298 
00299         case RtlNode::REDUCTION_XNOR:
00300 
00301             result.push_back(notOf(reductionXor(op1)));
00302             break;
00303 
00304         case RtlNode::LESS_THAN:
00305 
00306             zeroExpand(op1, op2);
00307             assert(op1.size() == op2.size());
00308 
00309             result.push_back(lessThan(op1, op2));
00310             break;
00311 
00312         case RtlNode::LESS_THAN_EQUAL:
00313 
00314             zeroExpand(op1, op2);
00315             assert(op1.size() == op2.size());
00316 
00317             result.push_back(notOf(lessThan(op2, op1)));
00318             break;
00319 
00320         case RtlNode::GREATER_THAN:
00321 
00322             zeroExpand(op1, op2);
00323             assert(op1.size() == op2.size());
00324 
00325             result.push_back(lessThan(op2, op1));
00326             break;
00327 
00328         case RtlNode::GREATER_THAN_EQUAL:
00329 
00330             zeroExpand(op1, op2);
00331             assert(op1.size() == op2.size());
00332 
00333             result.push_back(notOf(lessThan(op1, op2)));
00334             break;
00335 
00336         case RtlNode::EQUAL:
00337 
00338             zeroExpand(op1, op2);
00339             assert(op1.size() == op2.size());
00340 
00341             result.push_back(equalTo(op1, op2));
00342             break;
00343 
00344         case RtlNode::NOTEQUAL:
00345 
00346             zeroExpand(op1, op2);
00347             assert(op1.size() == op2.size());
00348 
00349             result.push_back(notOf(equalTo(op1, op2)));
00350             break;
00351 
00352         case RtlNode::IF_ELSE: {
00353 
00354             // a RTL node cannot be IF_ELSE after synthesis
00355             QUIT_ON_INTERNAL_ERROR;
00356 
00357             break;
00358                                         }
00359 
00360         case RtlNode::LEFT_SHIFT:
00361 
00362 /*
00363             if (VerilogSynthesis::isConstantExpression(expression->op2, parameters)) {
00364                 // shift signal a constant number of bits by connection
00365 
00366                 VerilogSynthesis::ConstantValue c;
00367                 VerilogSynthesis::evaluateConstantExpression(c, expression->op2, parameters);
00368                 if (c.intValue < 0) {
00369                     cerr << "ERROR: Constant shift length must be greater than zero" << endl;
00370                     QUIT_ON_ERROR;                
00371                 }
00372                 int size = op1.size();
00373                 if (c.intValue >= size) {
00374                     cerr << "WARNING: Shift length is greater than length of operand.  Result will be constant zero." << endl;   
00375                 }
00376 
00377                 list<oagAi::Ref>::reverse_iterator bitIter = op1.rbegin();
00378                 for(int i=0; i<size; i++) {
00379                     if(i<c.intValue) {
00380                         result.push_front(currentManager->ai.constantZero());
00381                     } else {
00382                         result.push_front(*bitIter);
00383                         ++bitIter;
00384                     }
00385                 }        
00386             } else {
00387                 // shift signal a variable number of bits by multiplexing
00388 
00389                 // the number of shift possibilities is the minimum of the bits to be shifted
00390                 // and the largest number that can be represented by the shift value
00391                 unsigned int size = min(op1.size(), static_cast<unsigned int>(1 << op2.size()));
00392                 list<oagAi::Ref> selects;
00393                 for(unsigned int i=0; i<size; ++i) {
00394                     list<oagAi::Ref> constantBits;
00395                     multiBitConstant(constantBits, i);
00396                     zeroExpand(constantBits, op2);
00397                     selects.push_back(equalTo(constantBits, op2));
00398                 }
00399 
00400                 // build a multiplexor for each bit    
00401                 for(list<oagAi::Ref>::iterator bitIter = op1.begin(); bitIter != op1.end(); ++bitIter) {
00402                     list<oagAi::Ref> muxTerms;            
00403 
00404                     // build term for each bit
00405                     list<oagAi::Ref>::iterator inputIter(bitIter);
00406                     list<oagAi::Ref>::iterator selectIter = selects.begin();
00407                     while(inputIter != op1.end() && selectIter != selects.end()) {
00408                         muxTerms.push_back(andOf(*selectIter, *inputIter));
00409                         ++selectIter;
00410                         if (inputIter == op1.begin()) {
00411                             inputIter = op1.end();
00412                         } else {
00413                             ++inputIter;
00414                         }
00415                     }
00416 
00417                     result.push_back(reductionOr(muxTerms));            
00418                 }
00419             }
00420 */
00421             break;
00422 
00423         case RtlNode::RIGHT_SHIFT:
00424 /*            
00425             if (VerilogSynthesis::isConstantExpression(expression->op2, parameters)) {
00426                 // shift signal a constant number of bits by connection
00427 
00428                 VerilogSynthesis::ConstantValue c;
00429                 VerilogSynthesis::evaluateConstantExpression(c, expression->op2, parameters);
00430                 if (c.intValue < 0) {
00431                     cerr << "ERROR: Constant shift length must be greater than zero" << endl;
00432                     QUIT_ON_ERROR;                
00433                 }
00434                 int size = op1.size();
00435                 if (c.intValue >= size) {
00436                     cerr << "WARNING: Shift length is greater than length of operand.  Result will be constant zero." << endl;   
00437                 }
00438 
00439                 list<oagAi::Ref>::iterator bitIter = op1.begin();
00440                 for(int i=0; i<size; i++) {
00441                     if(i<c.intValue) {
00442                         result.push_back(currentManager->ai.constantZero());
00443                     } else {
00444                         result.push_back(*bitIter);
00445                         ++bitIter;
00446                     }
00447                 }        
00448             } else {
00449                 // shift signal a variable number of bits by multiplexing
00450 
00451                 // the number of shift possibilities is the minimum of the bits to be shifted
00452                 // and the largest number that can be represented by the shift value
00453                 unsigned int size = min(op1.size(), static_cast<unsigned int>(1 << op2.size()));
00454                 list<oagAi::Ref> selects;
00455                 for(unsigned int i=0; i<size; i++) {
00456                     list<oagAi::Ref> constantBits;
00457                     multiBitConstant(constantBits, i);
00458                     zeroExpand(constantBits, op2);
00459                     selects.push_back(equalTo(constantBits, op2));
00460                 }
00461 
00462                 // build a multiplexor for each bit    
00463                 for(list<oagAi::Ref>::iterator bitIter = op1.begin(); bitIter != op1.end(); ++bitIter) {
00464                     list<oagAi::Ref> muxTerms;            
00465 
00466                     // build term for each bit
00467                     list<oagAi::Ref>::iterator inputIter(bitIter);
00468                     list<oagAi::Ref>::iterator selectIter = selects.begin();
00469                     while(inputIter != op1.end() && selectIter != selects.end()) {
00470                         muxTerms.push_back(andOf(*selectIter, *inputIter));
00471                         ++inputIter; ++selectIter;
00472                     }
00473 
00474                     result.push_back(reductionOr(muxTerms));            
00475                 }
00476             }
00477             */
00478             break;
00479 
00480         case RtlNode::ADD:
00481 
00482             zeroExpand(op1, op2);
00483             assert(op1.size() == op2.size());
00484 
00485             arithmeticAdd(result, op1, op2);
00486             break;
00487 
00488         case RtlNode::SUBTRACT:
00489 
00490             zeroExpand(op1, op2);
00491             assert(op1.size() == op2.size());
00492 
00493             arithmeticSubtract(result, discard, op1, op2);
00494             break;
00495 
00496         case RtlNode::NEGATE:
00497 
00498             zeroExpand(op1, op2);
00499             assert(op1.size() == op2.size());
00500 
00501             arithmeticSubtract(result, discard, op2, op1);
00502             break;
00503 
00504         case RtlNode::MULTIPLY:
00505 
00506             zeroExpand(op1, op2);
00507             assert(op1.size() == op2.size());
00508 
00509             arithmeticMultiply(result, op1, op2);
00510             break;
00511 
00512         case RtlNode::DIVIDE:
00513 
00514             zeroExpand(op1, op2);
00515             assert(op1.size() == op2.size());
00516 
00517             arithmeticDivide(result, op1, op2);
00518             break;
00519 
00520         case RtlNode::MODULO:
00521 
00522             zeroExpand(op1, op2);
00523             assert(op1.size() == op2.size());
00524 
00525             arithmeticModulo(result, op1, op2);
00526             break;
00527 
00528         default:
00529             cerr << "Invalid operator RTL node type " << bbNode->optType << endl;
00530             QUIT_ON_INTERNAL_ERROR;
00531             break;
00532     }
00533     // connecting the AI nodes and RTL nodes
00534     back_insert_iterator<vector<oagAi::Ref> > bii(bbNode->aiRef);
00535     copy(result.begin(), result.end(), bii);
00536 }
00537 
00538 // *****************************************************************************
00539 // compileFunctionalMuxBBNode()
00540 //
00542 //
00543 // *****************************************************************************
00544 void
00545 ModuleCompiler::compileFunctionalMuxBBNode(RtlNode* bbNode) {
00546     assert(bbNode->funcType == RtlNode::CONTROL);
00547     
00548     list<oagAi::Ref> aiIn;
00549     list<oagAi::Ref> aiSel;
00550     BBRef2AiRef(bbNode->muxInfo->in, aiIn);
00551     BBRef2AiRef(bbNode->muxInfo->sel, aiSel);
00552     bbNode->aiRef.push_back(mux(aiIn, aiSel));
00553 }
00554 
00555 // *****************************************************************************
00556 // compileFunctionalSeqBBNode()
00557 //
00559 //
00560 // *****************************************************************************
00561 void
00562 ModuleCompiler::compileFunctionalSeqBBNode(RtlNode* bbNode) {
00563     assert(bbNode->funcType == RtlNode::SEQ);
00564     
00565     oagAi::Ref aiD      = BBRef2AiRef(bbNode->seqInfo->D);
00566     oagAi::Ref aiClock  = BBRef2AiRef(bbNode->seqInfo->clock);
00567     oagAi::Ref aiAload  = BBRef2AiRef(bbNode->seqInfo->aLoad);
00568     // FIXME: AData is not annotated in this routine, 
00569     // double check the sequential element model.
00570     oagAi::Ref aiAdata  = BBRef2AiRef(bbNode->seqInfo->aData);
00571 
00572     if(bbNode->seqType == RtlNode::DFF){
00573         oagAi::Ref aiSeq = seq(aiD, "");
00574         bbNode->aiRef.push_back(aiSeq);
00575         // FIXME: "_posedge" is assumed for all asynchronous signals, 
00576         // which is not true. In fact, the information of clock trigger 
00577         // edge has been lost at this point.
00578         stringstream label;
00579         label << "trigger_" << aiClock << "_posedge";
00580         annotateAsynchronousSignal(aiSeq, label.str(), aiClock);
00581         label.clear();
00582         label << "trigger_" << aiAload << "_posedge";
00583         annotateAsynchronousSignal(aiSeq, label.str(), aiAload);
00584     } else {
00585         assert(bbNode->seqType == RtlNode::LATCH);
00586         bbNode->aiRef.push_back(latch(aiClock, aiD, ""));
00587     }
00588 }
00589 
00590 // *****************************************************************************
00591 // compileFunctionalBBNode()
00592 //
00595 //
00596 // *****************************************************************************
00597 void
00598 ModuleCompiler::compileFunctionalBBNode(BBRef e) {
00599     RtlNode* bbNode = currentManager->bbg.getNode(e);
00600     assert(bbNode);
00601 
00602     // don't re-compile a BBNode if it's been decomposed to AIG
00603     if(bbNode->aiRef.size() != 0)
00604         return;
00605 
00606     // Decompose a functional BB node to several AI nodes
00607     // the output AI nodes need to be pushed into "bbNode->aiRef". 
00608     switch(bbNode->funcType){
00609         case RtlNode::CONTROL:
00610             compileFunctionalMuxBBNode(bbNode);
00611             break;
00612         case RtlNode::OPERATOR:
00613             compileFunctionalOptBBNode(bbNode);
00614             break;
00615         case RtlNode::SEQ:
00616             compileFunctionalSeqBBNode(bbNode);
00617             break;
00618         default:
00619             QUIT_ON_INTERNAL_ERROR;
00620     }
00621 }
00622 
00623 // *****************************************************************************
00624 // compileBBNode()
00625 //
00627 //
00628 // *****************************************************************************
00629 void
00630 ModuleCompiler::compileBBNode(BBRef e) {
00631     RtlNode* bbNode = currentManager->bbg.getNode(e);
00632     assert(bbNode);
00633 
00634 #ifdef DEBUG
00635     static const oa::oaVerilogNS verilogNS;
00636 #endif
00637 
00638     // don't re-compile a BBNode if it's been decomposed to AIG
00639     if(bbNode->aiRef.size() != 0)
00640         return;
00641 
00642     if (currentManager->bbg.isNull(e)) {
00643         
00644         assert(0);
00645         // Null has been handled
00646     
00647     } else if (currentManager->bbg.isTerminal(e)) {
00648 
00649         // TERMINAL node, return the AI node associated with the corresponding net
00650         oa::oaModBitNet *net = currentManager->getNetToBBConnection(e);
00651         assert(net->getAppDefs().includes(AiRefAppDef));
00652         oagAi::Ref terminalAi = AiRefAppDef->get(net);
00653         bbNode->aiRef.push_back(terminalAi);
00654 
00655         // setup the terminal drivers for primary outputs
00656         BBRef BBTerminalDriver = currentManager->bbg.getTerminalDriver(e);
00657         if(!currentManager->bbg.isNull(BBTerminalDriver)) {
00658             // decompose the driver BB node to AI nodes
00659             compileBBNode(BBTerminalDriver);
00660             // get the proper bit for the AI node of the terminal driver
00661             vector<oagAi::Ref> &aiTerminalDriver = 
00662                 currentManager->bbg.getNode(BBTerminalDriver)->aiRef;
00663             int aiTerminalDriverBit = 
00664                 currentManager->bbg.getOutputBit(BBTerminalDriver);
00665 #ifdef DEBUG
00666             oa::oaString netName;
00667             net->getName(verilogNS, netName);
00668             cerr << "Terminal " << terminalAi << " i.e. net " << 
00669                 netName << ", its driver is " << aiTerminalDriver[aiTerminalDriverBit];          
00670             //for(vector<oagAi::Ref>::iterator aiTerminalDriverIter = aiTerminalDriver.begin();
00671             //    aiTerminalDriverIter != aiTerminalDriver.end(); ++ aiTerminalDriverIter){
00672             //        cerr << *aiTerminalDriverIter << ", " ;
00673             //}
00674             cerr << endl;
00675             cerr.flush();
00676 #endif
00677             currentManager->ai.setTerminalDriver(terminalAi, aiTerminalDriver[aiTerminalDriverBit]);
00678         }
00679 
00680     } else if (currentManager->bbg.isFunctional(e) ||
00681         currentManager->bbg.isSequential(e)) {
00682 
00683         // functional node,
00684         compileFunctionalBBNode(e);
00685 
00686     } else if (e == currentManager->bbg.constantZero()) {
00687 
00688         // constant zero is handled
00689         bbNode->aiRef.push_back(currentManager->ai.constantZero());
00690 
00691     } else if (e == currentManager->bbg.constantOne()) {
00692 
00693         // constant one is handled
00694         bbNode->aiRef.push_back(currentManager->ai.notOf(
00695             currentManager->ai.constantZero()));
00696     }
00697 
00698 }
00699 
00700 // *****************************************************************************
00701 // BBRef2AiRef()
00702 //
00704 //
00705 // *****************************************************************************
00706 oagAi::Ref
00707 ModuleCompiler::BBRef2AiRef(BBRef e) {
00708 
00709     vector<oagAi::Ref>& aiRef = currentManager->bbg.getNode(e)->aiRef;
00710 
00711     DEBUG_PRINTLN("BBRef2AiRef e = " << e << ", aiRef.size() = " << aiRef.size());
00712 
00713     // decompose the BBNode to AI nodes if it's not decomposed yet.
00714     if(aiRef.size() == 0){
00715         compileBBNode(e);
00716         aiRef = currentManager->bbg.getNode(e)->aiRef;
00717     }
00718     //assert(aiRef.size() == 1);
00719     int outBit = currentManager->bbg.getOutputBit(e);
00720     return aiRef[outBit];
00721 }
00722 
00723 // *****************************************************************************
00724 // BBRef2AiRef()
00725 //
00727 //
00728 // *****************************************************************************
00729 void
00730 ModuleCompiler::BBRef2AiRef(BBRef e, vector<oagAi::Ref>& aiRefs) {
00731 
00732     // decompose the BBNode to AI nodes if it's not decomposed yet.
00733     aiRefs = currentManager->bbg.getNode(e)->aiRef;
00734     if(aiRefs.size() == 0){
00735         compileBBNode(e);
00736         aiRefs = currentManager->bbg.getNode(e)->aiRef;
00737     }
00738 }
00739 
00740 // *****************************************************************************
00741 // BBRef2AiRef()
00742 //
00744 //
00745 // *****************************************************************************
00746 void
00747 ModuleCompiler::BBRef2AiRef(list<BBRef> &e, list<oagAi::Ref>& aiRefs) {
00748 
00749     aiRefs.clear();
00750     for(list<BBRef>::iterator bbIter = e.begin(); bbIter != e.end(); ++ bbIter){
00751         vector<oagAi::Ref>& tmpAiRefs = currentManager->bbg.getNode(*bbIter)->aiRef;
00752         // decompose the BBNode to AI nodes if it's not decomposed yet.
00753         if(tmpAiRefs.size() == 0){
00754             compileBBNode(*bbIter);
00755             tmpAiRefs = currentManager->bbg.getNode(*bbIter)->aiRef;
00756         }
00757         for(vector<oagAi::Ref>::iterator aiIter = tmpAiRefs.begin();
00758             aiIter != tmpAiRefs.end(); ++ aiIter) {
00759                 aiRefs.push_back(*aiIter);
00760         }
00761     }
00762 }
00763 
00764 // *****************************************************************************
00765 // zeroExpand()
00766 //
00770 //
00771 // *****************************************************************************
00772 void
00773 ModuleCompiler::zeroExpand(list<oagAi::Ref> &l1, list<oagAi::Ref> &l2) {
00774     assert(currentManager);
00775 
00776     if(l1.size() < l2.size()) {
00777         for(int i=l2.size()-l1.size(); i>0; i--) {
00778             l1.push_front( currentManager->ai.constantZero() );
00779         }
00780     } else if(l1.size() > l2.size()) {
00781         for(int i=l1.size()-l2.size(); i>0; i--) {
00782             l2.push_front( currentManager->ai.constantZero() );
00783         }
00784     }
00785 }
00786 
00787 // *****************************************************************************
00788 // notOf()
00789 //
00791 //
00792 // *****************************************************************************
00793  oagAi::Ref
00794 ModuleCompiler::notOf(oagAi::Ref e) {
00795     assert(currentManager);
00796         
00797     return currentManager->ai.notOf(e);
00798 }
00799 
00800 // *****************************************************************************
00801 // andOf()
00802 //
00806 //
00807 // *****************************************************************************
00808  oagAi::Ref
00809 ModuleCompiler::andOf(oagAi::Ref e1, oagAi::Ref e2) {
00810     assert(currentManager);
00811         
00812     return currentManager->ai.andOf(e1, e2);
00813 }
00814 
00815 // *****************************************************************************
00816 // orOf()
00817 //
00821 //
00822 // *****************************************************************************
00823  oagAi::Ref
00824 ModuleCompiler::orOf(oagAi::Ref e1Ai, oagAi::Ref e2Ai) {
00825     assert(currentManager);
00826 
00827     return currentManager->ai.notOf(currentManager->ai.andOf(
00828                        currentManager->ai.notOf(e1Ai), currentManager->ai.notOf(e2Ai)));
00829 }
00830 
00831 // *****************************************************************************
00832 // xorOf()
00833 //
00837 //
00838 // *****************************************************************************
00839  oagAi::Ref
00840 ModuleCompiler::xorOf(oagAi::Ref e1Ai, oagAi::Ref e2Ai) {
00841     assert(currentManager);
00842 
00843     oagAi::Ref t1 = currentManager->ai.andOf(currentManager->ai.notOf(e1Ai), e2Ai);
00844     oagAi::Ref t2 = currentManager->ai.andOf(currentManager->ai.notOf(e2Ai), e1Ai);
00845     return currentManager->ai.notOf(currentManager->ai.andOf(
00846                        currentManager->ai.notOf(t1), currentManager->ai.notOf(t2)));
00847 }
00848 
00849 // *****************************************************************************
00850 // reductionOr()
00851 //
00858 // *****************************************************************************
00859  oagAi::Ref
00860 ModuleCompiler::reductionOr(list<oagAi::Ref> &l) {
00861     assert(currentManager);
00862     assert(l.size() > 0);
00863 
00864     // synthesize a reduction-or into AIG 
00865     list<oagAi::Ref>::iterator it, completed;
00866     while(l.size() > 1) {
00867         it = l.begin();
00868         while(it != l.end()) {
00869             oagAi::Ref e1 = *it;
00870             completed = it++;
00871             l.erase(completed);
00872             if (it == l.end()) {
00873                 l.push_front(e1);
00874                 break;
00875             }
00876             l.push_front(orOf(e1, *it));
00877             completed = it++;
00878             l.erase(completed);
00879         }
00880     }
00881     
00882     return l.front();
00883 }
00884 
00885 // *****************************************************************************
00886 // reductionXor()
00887 //
00893 //
00894 // *****************************************************************************
00895  oagAi::Ref
00896 ModuleCompiler::reductionXor(list<oagAi::Ref> &l) {
00897     assert(currentManager);
00898     assert(l.size() > 0);
00899 
00900     // synthesize a reduction-xor into AIG 
00901     list<oagAi::Ref>::iterator it, completed;
00902     while(l.size() > 1) {
00903         it = l.begin();
00904         while(it != l.end()) {
00905             oagAi::Ref e1 = *it;
00906             completed = it++;
00907             l.erase(completed);
00908             if (it == l.end()) {
00909                 l.push_front(e1);
00910                 break;
00911             }
00912             l.push_front(xorOf(e1, *it));
00913             completed = it++;
00914             l.erase(completed);
00915         }
00916     }
00917     
00918     return l.front();
00919 }
00920 
00921 // *****************************************************************************
00922 // reductionAnd()
00923 //
00929 //
00930 // *****************************************************************************
00931  oagAi::Ref
00932 ModuleCompiler::reductionAnd(list<oagAi::Ref> &l) {
00933         
00934     // synthesize a reduction-xor into AIG 
00935     list<oagAi::Ref>::iterator it, completed;
00936     while(l.size() > 1) {
00937         it = l.begin();
00938         while(it != l.end()) {
00939             oagAi::Ref e1 = *it;
00940             completed = it++;
00941             l.erase(completed);
00942             if (it == l.end()) {
00943                 l.push_front(e1);
00944                 break;
00945             }
00946             l.push_front(andOf(e1, *it));
00947             completed = it++;
00948             l.erase(completed);
00949         }
00950     }
00951     
00952     return l.front();
00953 }
00954 
00955 // *****************************************************************************
00956 // lessThan()
00957 //
00962 //
00964 //
00965 // *****************************************************************************
00966  oagAi::Ref
00967 ModuleCompiler::lessThan(list<oagAi::Ref> &aiFanins1, list<oagAi::Ref> &aiFanins2) {
00968     assert(currentManager);
00969     assert(aiFanins1.size() == aiFanins2.size() && aiFanins1.size() > 0);
00970     
00971     oagAi::Ref last = currentManager->ai.constantZero();
00972 
00973     while(!aiFanins1.empty()) {
00974         // a'b + last(ab + a'b')
00975         last = orOf(andOf( notOf(aiFanins1.back()), aiFanins2.back()),
00976             andOf(last, notOf(xorOf(aiFanins1.back(), aiFanins2.back()))));
00977         aiFanins1.pop_back();
00978         aiFanins2.pop_back();
00979     }
00980     
00981     return last;
00982 }
00983 
00984 // *****************************************************************************
00985 // equalTo()
00986 //
00991 //
00993 //
00994 // *****************************************************************************
00995  oagAi::Ref
00996 ModuleCompiler::equalTo(list<oagAi::Ref> &l1, list<oagAi::Ref> &l2) {
00997     assert(currentManager);
00998     assert(l1.size() == l2.size() && l1.size() > 0);
00999 
01000     list<oagAi::Ref> l;
01001     list<oagAi::Ref>::iterator l1Iter = l1.begin(), 
01002         l2Iter = l2.begin();
01003     while(l1Iter != l1.end() && l2Iter != l2.end()) {
01004         l.push_back( notOf( xorOf(*l1Iter, *l2Iter)) );
01005         ++l1Iter; ++l2Iter;
01006     }
01007     
01008     return reductionAnd(l);
01009 }
01010 
01011 // *****************************************************************************
01012 // arithmeticAdd()
01013 //
01019 // *****************************************************************************
01020 void
01021 ModuleCompiler::arithmeticAdd(list<oagAi::Ref> &result, list<oagAi::Ref> &l1, 
01022                               list<oagAi::Ref> &l2) {
01023     assert(currentManager);
01024     assert(l1.size() == l2.size());
01025     result.clear();
01026     
01027     // this constructs a ripple-carry adder
01028     oagAi::Ref sum, carryOut, carryIn = currentManager->ai.constantZero();
01029     list<oagAi::Ref>::reverse_iterator   it1 = l1.rbegin();
01030     list<oagAi::Ref>::reverse_iterator   it2 = l2.rbegin();
01031     while(it1 != l1.rend() && it2 != l2.rend()) {
01032         fullAdder(sum, carryOut, *it1, *it2, carryIn);
01033         result.push_front(sum);
01034         carryIn = carryOut;
01035         it1++; it2++;
01036     }
01037     result.push_front(carryOut);
01038 
01039 }
01040 
01041 // *****************************************************************************
01042 // arithmeticSubtract()
01043 //
01048 //
01049 // *****************************************************************************
01050 void
01051 ModuleCompiler::arithmeticSubtract(list<oagAi::Ref> &result, oagAi::Ref &negFlag, 
01052                               list<oagAi::Ref> &l1, list<oagAi::Ref> &l2) {
01053     assert(currentManager);
01054     assert(l1.size() == l2.size());
01055     result.clear();
01056     
01057     // this constructs a ripple-carry subtractor
01058     oagAi::Ref sum, carryOut, carryIn = currentManager->ai.constantOne();
01059     list<oagAi::Ref>::reverse_iterator   it1 = l1.rbegin();
01060     list<oagAi::Ref>::reverse_iterator   it2 = l2.rbegin();
01061     while(it1 != l1.rend() && it2 != l2.rend()) {
01062         fullAdder(sum, carryOut, *it1, currentManager->ai.notOf(*it2), carryIn);
01063         result.push_front(sum);
01064         carryIn = carryOut;
01065         it1++; it2++;
01066     }
01067     
01068     negFlag = notOf(carryIn);
01069 }
01070 
01071 // *****************************************************************************
01072 // arithmeticMultiply()
01073 //
01078 //
01079 // *****************************************************************************
01080 void
01081 ModuleCompiler::arithmeticMultiply(list<oagAi::Ref> &result, 
01082                                    list<oagAi::Ref> &l1, list<oagAi::Ref> &l2) {
01083     assert(currentManager);    
01084     assert(l1.size() > 1 && l1.size() > 1);
01085 
01086     result.clear();
01087 
01088     list<oagAi::Ref> arrayRow;
01089     list<oagAi::Ref>::reverse_iterator colIter, rowIter = l2.rbegin();
01090     for(colIter = l1.rbegin(); colIter != l1.rend(); ++colIter) {
01091         arrayRow.push_front(currentManager->ai.andOf(*colIter, *rowIter));
01092     }
01093     arrayRow.push_front(currentManager->ai.constantZero());
01094     ++rowIter;
01095 
01096     while(rowIter != l2.rend()) {
01097         result.push_front(arrayRow.back());
01098         arrayRow.pop_back();
01099         list<oagAi::Ref> lastArrayRow(arrayRow);
01100         list<oagAi::Ref> andRow;
01101         for(colIter = l1.rbegin(); colIter != l1.rend(); ++colIter) {
01102             andRow.push_front(andOf(*colIter, *rowIter));
01103         }
01104         assert(andRow.size() == lastArrayRow.size());
01105         arrayRow.clear();
01106         arithmeticAdd(arrayRow, andRow, lastArrayRow);
01107         ++rowIter;
01108     }
01109 
01110     while(!arrayRow.empty()) {
01111         result.push_front(arrayRow.back());
01112         arrayRow.pop_back();
01113     }
01114 }
01115 
01116 // *****************************************************************************
01117 // arithmeticDivide()
01118 //
01123 //
01124 // *****************************************************************************
01125 void        
01126 ModuleCompiler::arithmeticDivide(list<oagAi::Ref> &result, list<oagAi::Ref> &l1, 
01127                                  list<oagAi::Ref> &l2) {
01128     assert(currentManager);
01129     result.clear();
01130     // l1 is the quotient
01131     // l2 is the divisor
01132 
01133     list<oagAi::Ref>           arrayRow;
01134     zeroExpand(arrayRow, l2);
01135     list<oagAi::Ref>::iterator quotientIter = l1.begin();
01136 
01137     while(quotientIter != l1.end()) {
01138         arrayRow.pop_front();
01139         arrayRow.push_back(*quotientIter);
01140         list<oagAi::Ref> lastArrayRow(arrayRow);
01141         list<oagAi::Ref> afterSubtract;
01142         oagAi::Ref    negFlag;
01143         arithmeticSubtract(afterSubtract, negFlag, lastArrayRow, l2);
01144         mux(arrayRow, negFlag, afterSubtract, lastArrayRow);
01145         result.push_back(currentManager->ai.notOf(negFlag));
01146         ++quotientIter;
01147     }
01148 }
01149 
01150 // *****************************************************************************
01151 // arithmeticModulo()
01152 //
01157 //
01158 // *****************************************************************************
01159 void
01160 ModuleCompiler::arithmeticModulo(list<oagAi::Ref> &result, 
01161                                  list<oagAi::Ref> &l1, list<oagAi::Ref> &l2) {
01162     assert(currentManager);
01163     result.clear();
01164     // l1 is the quotient
01165     // l2 is the divisor
01166 
01167     list<oagAi::Ref>           arrayRow;
01168     zeroExpand(arrayRow, l2);
01169     list<oagAi::Ref>::iterator quotientIter = l1.begin();
01170 
01171     while(quotientIter != l1.end()) {
01172         arrayRow.pop_front();
01173         arrayRow.push_back(*quotientIter);
01174         list<oagAi::Ref> lastArrayRow(arrayRow);
01175         list<oagAi::Ref> afterSubtract;
01176         oagAi::Ref    negFlag;
01177         arithmeticSubtract(afterSubtract, negFlag, lastArrayRow, l2);
01178         mux(arrayRow, negFlag, afterSubtract, lastArrayRow);
01179         ++quotientIter;
01180     }
01181     
01182     // the remainder is set of remaining values
01183     while(!arrayRow.empty()) {
01184         result.push_front(arrayRow.back());
01185         arrayRow.pop_back();
01186     }
01187 }
01188 
01189 
01190 // *****************************************************************************
01191 // latch()
01192 //
01201 //
01202 // *****************************************************************************
01203 oagAi::Ref
01204 ModuleCompiler::latch(oagAi::Ref enable, oagAi::Ref in, const string name) {
01205     oagAi::Ref seqRef = seq(in, name);
01206     annotateAsynchronousSignal(seqRef, string("enable"), enable);  
01207     return seqRef;
01208 }
01209 
01210 
01211 // *****************************************************************************
01212 // seq()
01213 //
01219 //
01220 // *****************************************************************************
01221 oagAi::Ref
01222 ModuleCompiler::seq(oagAi::Ref in, const string name) {
01223     assert(currentManager);
01224 
01225     // create a sequential node
01226     oagAi::Ref seqRef(currentManager->ai.newSequential(in));
01227 
01228     DEBUG_PRINTLN("\t\t\t created state bit")
01229 
01230     return seqRef;
01231 }
01232     
01233 // *****************************************************************************
01234 // mux()
01235 //
01237 //
01238 // *****************************************************************************
01239 oagAi::Ref
01240 ModuleCompiler::mux(oagAi::Ref select, oagAi::Ref in0, oagAi::Ref in1) {
01241     assert(currentManager);
01242     if (in0 == in1) {
01243         return in0;
01244     }
01245     return orOf(andOf(in1, select), andOf(in0, notOf(select)));
01246 }
01247 
01248 // *****************************************************************************
01249 // mux()
01250 //
01252 //
01253 // *****************************************************************************
01254 void
01255 ModuleCompiler::mux(list<oagAi::Ref> &result, oagAi::Ref select, 
01256                     list<oagAi::Ref> &in0, list<oagAi::Ref> &in1) {
01257     assert(in0.size() == in1.size());
01258     result.clear();
01259     
01260     list<oagAi::Ref>::iterator in0Iter = in0.begin(), in1Iter = in1.begin();
01261     while(in0Iter != in0.end() && in1Iter != in1.end()) {
01262         result.push_back(mux(select, *in0Iter, *in1Iter));
01263         ++in0Iter; ++in1Iter;
01264     }
01265 }
01266 
01267 // *****************************************************************************
01268 // mux()
01269 //
01271 //
01272 // *****************************************************************************
01273 oagAi::Ref
01274 ModuleCompiler::mux(list<oagAi::Ref> &select, list<oagAi::Ref> &in) {
01275     // out =    !s0*!s1*in0+
01276     //          !s0* s1*in1+
01277     //           s0*!s1*in2+
01278     //           s0* s1*in3
01279 
01280     int numBits = select.size();
01281     unsigned counter = 0;
01282     list<oagAi::Ref> minTerms;
01283     list<oagAi::Ref>::iterator inIter = in.begin();
01284     for(; inIter != in.end(); ++ inIter, ++ counter) {
01285             list<oagAi::Ref> cubeTerms;
01286             int curBit = 0;
01287             // calculate the selection bits phase
01288             for(list<oagAi::Ref>::iterator selIter = select.begin();
01289                 curBit < numBits; ++curBit, ++selIter){
01290                     assert(selIter != select.end());
01291                     int bitMask = 1 << curBit;
01292                     if(counter / bitMask) cubeTerms.push_back(notOf(*selIter));
01293                     else cubeTerms.push_back(*selIter);
01294             }
01295             cubeTerms.push_back(*inIter);
01296             minTerms.push_back(reductionAnd(cubeTerms));
01297     }
01298     return reductionOr(minTerms);
01299 }
01300 
01301 
01302 // *****************************************************************************
01303 // fullAdder()
01304 //
01308 //
01309 // *****************************************************************************
01310 void
01311 ModuleCompiler::fullAdder(oagAi::Ref &sum, oagAi::Ref &carryOut, 
01312                      oagAi::Ref e1, oagAi::Ref e2, oagAi::Ref carryIn) {
01313     assert(currentManager);
01314     oagAi::Ref intermediate = xorOf(e1, e2);
01315     sum = xorOf(carryIn, intermediate);
01316     carryOut = orOf(andOf(e1,e2), andOf(intermediate, carryIn));
01317 }
01318 
01319 
01320 // *****************************************************************************
01321 // multiBitConstant()
01322 //
01327 //
01328 // *****************************************************************************
01329 void
01330 ModuleCompiler::multiBitConstant(list<oagAi::Ref> &result, int value, int bits) {
01331     assert(currentManager);
01332     result.clear();
01333     for(int i=0; (bits == 0 ? value != 0 : i<bits); i++, value = value >> 1) {
01334         if (value % 2) {
01335             result.push_front(currentManager->ai.constantOne());
01336         } else {
01337             result.push_front(currentManager->ai.constantZero());
01338         }
01339     }
01340     if (result.empty()) {
01341         result.push_back(currentManager->ai.constantZero());
01342     }
01343 }
01344 
01345 // *****************************************************************************
01346 // annotateAsynchronousSignal()
01347 //
01353 //
01354 // *****************************************************************************
01355 void
01356 ModuleCompiler::annotateAsynchronousSignal(oagAi::Ref sequential, const string label, 
01357                                            oagAi::Ref signal) {
01358     assert(currentManager);
01359 
01360     // annotate the asynchronous input
01361     DEBUG_PRINTLN("\tannotating node " << sequential
01362                   << " with asychronous signal " << label
01363                   << " = " << signal);
01364     oagAi::Node::SequentialData *seqData = currentManager->ai.getSequentialData(sequential);
01365     assert(seqData);
01366     assert(seqData->abstractionLevel == oagAi::Node::SequentialData::BLACK_BOX);
01367     seqData->signals[label] = signal;
01368 }
01369 
01370 
01371 }

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