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

oagFpgaVerilogSynthesis.cpp

Go to the documentation of this file.
00001 #include "oaDesignDB.h"
00002 #include "oagFpgaManager.h"
00003 #include "oagFpgaModGraph.h"
00004 #include "oagFpgaVerilogSynthesis.h"
00005 #include <list>
00006 #include <set>
00007 #include <string>                                   
00008 #include <sstream>
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 VerilogDesign::Module                       *VerilogSynthesis::currentVmodule;
00024 VerilogSynthesis::ParameterValues        *VerilogSynthesis::currentParams;
00025 set<string>                                 VerilogSynthesis::finishedModules;
00026 map<string, VerilogSynthesis::Bounds>    VerilogSynthesis::twoDimRegisters;
00027 
00028 
00029 // *****************************************************************************
00030 // synthesize()
00031 //
00035 //
00036 // *****************************************************************************
00037 
00038 void        
00039 VerilogSynthesis::synthesize(VerilogDesign *vDesign) {
00040     assert(vDesign);
00041 
00042     // creat a namespace object that will be used through the synthesis
00043     nameSpace = new oa::oaVerilogNS();
00044 
00045     // synthesis the unparameterized versions of all modules in the design
00046     for(list<VerilogDesign::Module*>::iterator modIter = vDesign->modules.begin(); 
00047             modIter != vDesign->modules.end(); ++modIter) {
00048         VerilogDesign::Module *vModule = *modIter;
00049         if(finishedModules.find(vModule->name) == finishedModules.end()) {
00050             list<ConstantValue> emptyParameters; // i.e.  unparameterized
00051             synthesizeModule(vModule, emptyParameters);
00052         }
00053     }
00054 
00055     delete nameSpace;
00056 }
00057 
00058 // *****************************************************************************
00059 // getParameterizedModuleName()
00060 //
00062 //
00068 //
00069 // *****************************************************************************
00070 string
00071 VerilogSynthesis::getParameterizedModuleName(VerilogDesign::Module *vModule, 
00072                                              list<ConstantValue> &parameters) {
00073     assert(vModule);
00074 
00075     string              parameterizedModuleName(vModule->name);
00076     ParameterValues     localParameters;
00077     bool                nonDefault = false;
00078 
00079     // if no parameters, then all values must be default
00080     if (parameters.size() == 0)
00081         return parameterizedModuleName;
00082 
00083     // scan the parameters by position
00084     list<ConstantValue>::iterator it1 = parameters.begin();
00085     list<VerilogDesign::Declaration*>::iterator it2 = vModule->parameters.begin();
00086     while(it2 != vModule->parameters.end()) {
00087         // compute the default value
00088         ConstantValue c;
00089         evaluateConstantExpression(c, (*it2)->value, &localParameters );
00090     
00091         if (it1 == parameters.end()) {
00092             // append the default value to the module name
00093             stringstream suffix;
00094             suffix << "_" << c.intValue;
00095             appendSuffix(parameterizedModuleName, suffix.str());
00096 
00097             localParameters[(*it2)->name] = c;
00098             ++it2;
00099         } else {
00100             // test if we have differed from the default settings
00101             if (it1->intValue != c.intValue) {
00102                 nonDefault = true;
00103             }
00104        
00105             // append this parameter value to the module name
00106             stringstream suffix;
00107             suffix << "_" << it1->intValue;
00108             appendSuffix(parameterizedModuleName, suffix.str());
00109 
00110             localParameters[(*it2)->name] = *it1;
00111             ++it1; ++it2;
00112         }
00113     }
00114     
00115     // are there too many parameters?
00116     if (it1 != parameters.end()) {
00117         cerr << "WARNING: Too many parameters for module " << vModule->name << 
00118             ".  Ignoring extra" << endl;
00119     }
00120     
00121     // if no parameter still match default, no suffix is necessary
00122     if (!nonDefault) {
00123         parameterizedModuleName = vModule->name;
00124     }
00125 
00126    
00127     return parameterizedModuleName;
00128 }
00129 
00130 
00131 // *****************************************************************************
00132 // synthesizeModule()
00133 //
00141 //
00142 // *****************************************************************************
00143 
00144 void
00145 VerilogSynthesis::synthesizeModule(VerilogDesign::Module *vModule,
00146         list<ConstantValue> &parameters) {
00147 
00148     assert(vModule);
00149     assert(nameSpace);
00150     currentVmodule = vModule;
00151 
00152     // set up the local parameter value lookup table
00153     currentParams = new ParameterValues;
00154     assert(currentParams);
00155     list<ConstantValue>::iterator it_par = parameters.begin();
00156     list<VerilogDesign::Declaration*>::iterator it_dec =
00157         vModule->parameters.begin();
00158 
00159     while(it_dec != vModule->parameters.end()){
00160         // compute the default value
00161         ConstantValue c;
00162 
00163         evaluateConstantExpression(c, (*it_dec)->value, currentParams);
00164 
00165         if (it_par == parameters.end()) {
00166             (*currentParams)[(*it_dec)->name] = c;
00167             ++it_dec;
00168         } else {
00169             (*currentParams)[(*it_dec)->name] = *it_par;
00170             ++it_dec; ++it_par;
00171         }
00172     }
00173 
00174     // are there too many parameters?
00175     if (it_par != parameters.end()) {
00176         cerr << "WARNING: Too many parameters for module " << vModule->name <<
00177             ".  Ignoring extra" << endl;
00178     }
00179 
00180     // create the module
00181     string parameterizedModuleName = getParameterizedModuleName(vModule,
00182             parameters);
00183     DEBUG_PRINTLN("module " << parameterizedModuleName);
00184 
00185     currentModule = createModule(parameterizedModuleName);
00186 
00187     currentManager = NULL;
00188 
00189     // synthesis
00190     synthesizeModuleNets();
00191     synthesizeModuleTerms();
00192     synthesizeModuleAssigns();
00193     synthesizeModuleInsts();
00194     synthesizeModuleFunc();
00195 
00196     // if not structural, reflect structural equivalences in graph
00197     if (currentManager) {
00198         ModGraph::connectEquivalentNetsInGraph(currentModule);
00199  #ifdef DEBUG
00200         currentManager->print(cout);
00201 #endif
00202    }
00203 
00204     // clean up
00205     currentVmodule = NULL;
00206     assert(currentParams);
00207     delete currentParams;
00208     currentParams = NULL;
00209 
00210     // store the completed module
00211     finishedModules.insert(parameterizedModuleName);
00212     DEBUG_PRINTLN("endmodule " << parameterizedModuleName);
00213 }
00214 
00215 // *****************************************************************************
00216 // synthesizeModuleNets()
00217 //
00222 // *****************************************************************************
00223 void
00224 VerilogSynthesis::synthesizeModuleNets() {
00225 
00226     // create a net for each declaration
00227 
00228     for(list<VerilogDesign::Declaration*>::iterator decIter =
00229             currentVmodule->declarations.begin(); decIter !=
00230             currentVmodule->declarations.end(); ++ decIter) {
00231         VerilogDesign::Declaration *vDeclaration = *decIter;
00232         oa::oaModNet *net = NULL;
00233         list<oa::oaModBitNet*> bits;
00234 
00235         ConstantValue start, stop;
00236         if(vDeclaration->start == NULL) {
00237             if(vDeclaration->start2D == NULL) {
00238                 if(!(net = findScalarNet(vDeclaration->name))) {
00239                     net = createScalarNet(vDeclaration->name);
00240                 }
00241                 DEBUG_PRINT("\t 1-D scalarNet " << vDeclaration->name);
00242             }else{
00243                 ConstantValue start2D, stop2D;
00244                 evaluateConstantExpression(start2D, vDeclaration->start2D,
00245                         currentParams);
00246                 evaluateConstantExpression(stop2D, vDeclaration->stop2D,
00247                         currentParams);
00248                 Bounds bounds;
00249                 bounds.upper = max(start2D.intValue, stop2D.intValue);
00250                 bounds.lower = min(start2D.intValue, stop2D.intValue);
00251                 twoDimRegisters[vDeclaration->name] = bounds;
00252                 for(int i=bounds.lower; i<=bounds.upper; i++) {
00253                     string vectorName(vDeclaration->name);
00254                     stringstream suffix;
00255                     suffix << "_" << i << "_";
00256                     appendSuffix(vectorName, suffix.str());
00257                     if(!(net = findScalarNet(vectorName))){
00258                         net = createScalarNet(vectorName);
00259                     }
00260                 }
00261                 DEBUG_PRINT("\t 2-D scalarNet " << vDeclaration->name << "<" <<
00262                         start2D.intValue << ":" << stop2D.intValue << ">");
00263             }
00264         } else {
00265             evaluateConstantExpression(start, vDeclaration->start, currentParams);
00266             evaluateConstantExpression(stop, vDeclaration->stop, currentParams);
00267             // YH: 05/14/2007, 12:51pm
00268             if(vDeclaration->start2D == NULL) {
00269                 if(!(net = findBusNet(vDeclaration->name))){
00270                     net = createBusNet(vDeclaration->name, start.intValue,
00271                             stop.intValue);
00272                 }
00273                 DEBUG_PRINT("\t 1-D busNet " << vDeclaration->name << "[" <<
00274                         start.intValue  << ":" << stop.intValue << "]");
00275             } else {
00276                 // assume that multi-dimensional nets are supply lines
00277                 if (vDeclaration->type == VerilogDesign::Declaration::SUPPLY0 ||
00278                     vDeclaration->type == VerilogDesign::Declaration::SUPPLY1) {
00279                     cerr << "ERROR: Two dimensional supply nets are not \
00280                         supported" << endl;
00281                     QUIT_ON_ERROR;
00282                 } 
00283                 ConstantValue start2D, stop2D;
00284                 evaluateConstantExpression(start2D, vDeclaration->start2D,
00285                         currentParams);
00286                 evaluateConstantExpression(stop2D, vDeclaration->stop2D,
00287                         currentParams);
00288                 Bounds bounds;
00289                 bounds.upper = max(start2D.intValue, stop2D.intValue);
00290                 bounds.upper = min(start2D.intValue, stop2D.intValue);
00291                 twoDimRegisters[vDeclaration->name] = bounds;
00292                 for(int i=bounds.lower; i<bounds.upper; i++){
00293                     // // construct suffix to identify net in 2-d vector
00294                     string vectorName(vDeclaration->name);
00295                     stringstream suffix;
00296                     suffix << "_" << i << "_";
00297                     appendSuffix(vectorName, suffix.str());
00298                     if(!(net = findScalarNet(vectorName))){
00299                         net = createBusNet(vectorName, start.intValue,
00300                                 stop.intValue);
00301                     }
00302                 }
00303                 DEBUG_PRINT("\t 2-D busNet " << vDeclaration->name << "[" <<
00304                         start.intValue << ":" << stop.intValue << "]" << "<"
00305                         << start2D.intValue << ":" << stop2D.intValue << ">");
00306             }
00307         }
00308 
00309         switch(vDeclaration->type) {
00310             case VerilogDesign::Declaration::INPUT:
00311                 DEBUG_PRINTMORE(" (input)" << endl);
00312                 break;
00313             case VerilogDesign::Declaration::OUTPUT:
00314                 DEBUG_PRINTMORE(" (output)" << endl);
00315                 break;
00316             case VerilogDesign::Declaration::WIRE:
00317                 DEBUG_PRINTMORE(" (wire)" << endl);
00318                 break;
00319             case VerilogDesign::Declaration::SUPPLY0: 
00320             {
00321                 DEBUG_PRINTMORE(" (supply0)" << endl);
00322                 // tie to supply
00323                 oa::oaModScalarNet *supplyNet = 
00324                     oa::oaModScalarNet::find(currentModule, 
00325                             oa::oaScalarName(oa::oaNativeNS(), "tie0"));
00326                 for(list<oa::oaModBitNet*>::iterator bitIter = bits.begin();
00327                         bitIter != bits.end(); bitIter++) {
00328                     (*bitIter)->makeEquivalent(supplyNet);
00329                 }
00330                 break;
00331             }
00332             case VerilogDesign::Declaration::SUPPLY1: 
00333             {
00334                 DEBUG_PRINTMORE(" (supply1)" << endl);
00335                 // tie to supply
00336                 oa::oaModScalarNet *supplyNet = 
00337                     oa::oaModScalarNet::find(currentModule, 
00338                             oa::oaScalarName(oa::oaNativeNS(), "tie1"));
00339                 for(list<oa::oaModBitNet*>::iterator bitIter = bits.begin();
00340                         bitIter != bits.end(); bitIter++) {
00341                     (*bitIter)->makeEquivalent(supplyNet);
00342                 }
00343                 break;
00344             }
00345             case VerilogDesign::Declaration::INOUT:
00346                 DEBUG_PRINTMORE(" (inout)" << endl);
00347                 break;
00348             case VerilogDesign::Declaration::REG:
00349                 DEBUG_PRINTMORE(" (reg)" << endl);
00350                 break;
00351             default:
00352                 QUIT_ON_INTERNAL_ERROR;
00353                 break;
00354         }
00355     }
00356 
00357 #ifdef DEBUG
00358     DEBUG_PRINTLN(twoDimRegisters.size() << " 2-D nets are detected:");
00359     for(map<string, VerilogSynthesis::Bounds>::iterator mapIter =
00360             twoDimRegisters.begin(); mapIter != twoDimRegisters.end(); ++
00361             mapIter) {
00362         string netName = mapIter->first;
00363         Bounds netBound = mapIter->second;
00364         cerr << "net: " << netName << " [ " << netBound.upper << ":" <<
00365             netBound.lower << "]" << endl;
00366     }
00367 #endif
00368 }
00369 
00370 // *****************************************************************************
00371 // synthesizeModuleTerms()
00372 //
00377 // *****************************************************************************
00378 void
00379 VerilogSynthesis::synthesizeModuleTerms() {
00380 
00381     // create a term for each port (and check that it has been declared inside
00382     // the module)
00383 
00384     int position = 0;
00385     for(list<VerilogDesign::Port*>::iterator portIter =
00386             currentVmodule->ports->begin(); portIter !=
00387             currentVmodule->ports->end(); ++ portIter, ++ position) {
00388         VerilogDesign::Port *vPort = *portIter;
00389         DEBUG_PRINTLN("\t port " << position << " " << vPort->externalName);
00390 
00391         // search for a corresponding declaration
00392         bool foundCorrespondingDeclaration = false;
00393         VerilogDesign::Declaration *vDeclaration = NULL;
00394         for(list<VerilogDesign::Declaration*>::iterator decIter =
00395                 currentVmodule->declarations.begin(); decIter !=
00396                 currentVmodule->declarations.end(); ++ decIter) {
00397             vDeclaration = *decIter;
00398             if(vDeclaration->name == vPort->internalName) {
00399                 foundCorrespondingDeclaration = true;
00400                 break;
00401             }
00402         }
00403         if(!foundCorrespondingDeclaration) {
00404             cerr << "ERROR: Port " << vPort->internalName << " not declared in \
00405                 module body" << endl;
00406             QUIT_ON_ERROR;
00407         }
00408         oa::oaModNet *net = findNet(vPort->internalName);
00409         assert(net);
00410 
00411         assert(vDeclaration);
00412         switch(vDeclaration->type) {
00413             case VerilogDesign::Declaration::INPUT:
00414                 createTerm(net, vPort->externalName.c_str(),
00415                         oa::oacInputTermType, position);
00416                 break;
00417             case VerilogDesign::Declaration::OUTPUT:
00418                 createTerm(net, vPort->externalName.c_str(),
00419                         oa::oacOutputTermType, position);
00420                 break;
00421             case VerilogDesign::Declaration::INOUT:
00422                 createTerm(net, vPort->externalName.c_str(),
00423                         oa::oacInputOutputTermType, position);
00424                 break;
00425             default:
00426                 QUIT_ON_INTERNAL_ERROR;
00427         }
00428     }
00429 }
00430 
00431 // *****************************************************************************
00432 // synthesizeModuleAssigns()
00433 //
00442 // *****************************************************************************
00443 void
00444 VerilogSynthesis::synthesizeModuleAssigns() {
00445 
00446     // continuous assignments
00447 
00448     for(list<VerilogDesign::Assignment*>::iterator assignIter =
00449             currentVmodule->assignments->begin();
00450             assignIter != currentVmodule->assignments->end(); ++ assignIter) {
00451 
00452         VerilogDesign::Assignment *assignment = *assignIter;
00453 
00454         LvalRefBus lval;
00455         MultiRefBus value;
00456         evaluateLval(lval, assignment->lval, NULL, currentParams);
00457         evaluateExpression(value, assignment->value, NULL, currentParams);
00458         DEBUG_PRINTLN("\t assign [" << lval.size() << "] = [" << value.size() <<
00459                 "]");
00460 
00461         LvalRefBus::reverse_iterator leftIter = lval.rbegin();
00462         MultiRefBus::reverse_iterator rightIter = value.rbegin();
00463         while(leftIter != lval.rend()){
00464             
00465             // YH: evaluateLval() could generate non-empty conditionalLval due
00466             // to non-constant bit index, but here why we don't allow such a
00467             // case??
00468             assert((*leftIter)->conditionalLval.empty());
00469 
00470             oa::oaModBitNet *net = (*leftIter)->unconditionalLval;
00471             assert(net);
00472 
00473             if(rightIter == value.rend()) {
00474                 assignMultiRef(net, constantZero());
00475             }else{
00476                 assignMultiRef(net, *rightIter);
00477                 ++ rightIter;
00478             }
00479             ++ leftIter;
00480         }
00481     }
00482 }
00483 
00484 // *****************************************************************************
00485 // synthesizeModuleInsts()
00486 //
00492 // *****************************************************************************
00493 void
00494 VerilogSynthesis::synthesizeModuleInsts() {
00495 
00496     // instantiations
00497 
00498     for(list<VerilogDesign::Instantiation*>::iterator instIter =
00499             currentVmodule->instantiations->begin(); instIter !=
00500             currentVmodule->instantiations->end(); ++ instIter) {
00501 
00502         VerilogDesign::Instantiation * instantiation = *instIter;
00503         oa::oaModule *master = NULL;
00504 
00505         // is this an instantiation of a primitive, a Verilog module, or an
00506         // external pre-existing cell?
00507 
00508         // a primitive?
00509         if(instantiation->primitive !=
00510                 VerilogDesign::Instantiation::ISNT_PRIMITIVE) {
00511             MultiRefBus rvals;
00512             MultiRef rval;
00513             assert(instantiation->connections->back()->name == "in");
00514             evaluateExpression(rvals, instantiation->connections->back()->value,
00515                     NULL, currentParams);
00516             switch(instantiation->primitive){
00517                 case VerilogDesign::Instantiation::AND:
00518                     rval = reductionAnd(rvals);
00519                     break;
00520                 case VerilogDesign::Instantiation::NAND:
00521                     rval = reductionNand(rvals);
00522                     break;
00523                 case VerilogDesign::Instantiation::OR:
00524                     rval = reductionOr(rvals);
00525                     break;
00526                 case VerilogDesign::Instantiation::NOR:
00527                     rval = reductionNor(rvals);
00528                     break;
00529                 case VerilogDesign::Instantiation::XOR:
00530                     rval = reductionXor(rvals);
00531                     break;
00532                 case VerilogDesign::Instantiation::XNOR:
00533                     rval = reductionXnor(rvals);
00534                     break;
00535                 case VerilogDesign::Instantiation::NOT:
00536                     assert(rvals.size() == 1);
00537                     rval = notOf(rvals.front());
00538                     break;
00539                 case VerilogDesign::Instantiation::BUF:
00540                     assert(rvals.size() == 1);
00541                     rval = rvals.front();
00542                     break;
00543                 case VerilogDesign::Instantiation::ISNT_PRIMITIVE:
00544                     // should never reach here!!
00545                     assert(0);
00546                     break;
00547                 default:
00548                     QUIT_ON_INTERNAL_ERROR
00549             }
00550 
00551             LvalRefBus lvals;
00552             assert(instantiation->connections->front()->name == "out");
00553             evaluateLval(lvals, instantiation->connections->front()->value,
00554                     NULL, currentParams);
00555 
00556             DEBUG_PRINTLN("\t primitive [" << lvals.size() << "] = [" <<
00557                     rvals.size() << "]");
00558             LvalRefBus::iterator leftIter = lvals.begin();
00559             while(leftIter != lvals.end()) {
00560                 assert((*leftIter)->conditionalLval.empty());
00561                 oa::oaModBitNet *net = (*leftIter)->unconditionalLval;
00562                 assert(net);
00563 
00564                 assignMultiRef(net, rval);
00565                 ++ leftIter;
00566             }
00567 
00568             continue;
00569         }
00570 
00571         assert(instantiation->parameters);
00572 
00573         // find the Verilog definition of this module
00574         VerilogDesign::Module *instVmodule = NULL;
00575         for(list<VerilogDesign::Module*>::iterator modIter =
00576                 currentVmodule->design->modules.begin(); modIter !=
00577                 currentVmodule->design->modules.end(); ++ modIter) {
00578             if((*modIter)->name == instantiation->type){
00579                 instVmodule = *modIter;
00580                 break;
00581             }
00582         }
00583 
00584         // an instantiation of a Verilog module
00585         if(instVmodule) {
00586             // decode parameters
00587             list<ConstantValue> instParameters;
00588             for(list<VerilogDesign::Expression*>::iterator paramIter =
00589                     instantiation->parameters->begin(); paramIter !=
00590                     instantiation->parameters->end(); ++ paramIter) {
00591                 // evaluate value of constant expression
00592                 ConstantValue c;
00593                 evaluateConstantExpression(c, *paramIter, currentParams);
00594                 instParameters.push_back(c);
00595             }
00596 
00597             // get module name
00598             string parameterizedInstName =
00599                 getParameterizedModuleName(instVmodule, instParameters);
00600             DEBUG_PRINTLN("\t instance of Verilog module " <<
00601                     parameterizedInstName << " named " << instantiation->name);
00602 
00603             // has this module already been synthesized?
00604             master = findModule(parameterizedInstName);
00605             if(master == NULL) {
00606                 // not yet, then synthesize this module
00607 
00608                 // bakup the global intermediate variables
00609                 oa::oaModule *lastModule = currentModule;
00610                 VerilogDesign::Module *lastVmodule = currentVmodule;
00611                 Manager *lastManager = currentManager;
00612                 ParameterValues *lastParams = currentParams;
00613 
00614                 // perform synthesis
00615                 synthesizeModule(instVmodule, instParameters);
00616                 master = currentModule;
00617 
00618                 // set back the global intermediate variables
00619                 currentParams = lastParams;
00620                 currentModule = lastModule;
00621                 currentManager = lastManager;
00622                 currentVmodule = lastVmodule;
00623             }
00624 
00625         }
00626 
00627         // an instantiation of a leaf library cell
00628         else {
00629             DEBUG_PRINTLN("\t instance of leaf cell " << instantiation->type
00630                     << " named " << instantiation->name);
00631 
00632             master = findModule(instantiation->type);
00633             if(master == NULL) {
00634                 // can't find this cell
00635                 cerr << "ERROR: No Verilog or pre-existing definition of \
00636                     module " << instantiation->type << endl;
00637                 QUIT_ON_ERROR;
00638             }
00639 
00640             // can't parameterize an external cell
00641             if(!instantiation->parameters->empty()) {
00642                 cerr << "ERROR: The non-Verilog module " << instantiation->type
00643                      << " can not be parameterized" << endl;
00644                 QUIT_ON_ERROR;
00645             }
00646 
00647         }
00648 
00649         // create instance and add it to OA database
00650         oa::oaModInst *inst = instantiateModule(master->getDesign(),
00651                 instantiation->name);
00652 
00653         // connect ports
00654         for(list<VerilogDesign::PortConnection*>::iterator conIter =
00655                 instantiation->connections->begin(); conIter !=
00656                 instantiation->connections->end(); ++ conIter) {
00657 
00658             VerilogDesign::PortConnection *connection = *conIter;
00659 
00660             // evaluate the expression to be connected
00661             MultiRefBus value;
00662             if (connection->value == NULL) {
00663                 // if the port is unconnected, ignore
00664                 if(connection->name.empty()){
00665                     DEBUG_PRINTLN("\t\t " << connection->position << " <- \
00666                             floating")
00667                 }else{
00668                     DEBUG_PRINTLN("\t\t " << connection->name << " <- \
00669                             floating");
00670                 }
00671                 continue;
00672             } else {
00673                 evaluateExpression(value, connection->value, NULL,
00674                         currentParams);
00675             }
00676 
00677             // construct dummy net name
00678             // YH: end of 05/07/2007, 10:02pm
00679             string dummyName(instantiation->name);
00680             if(connection->name.empty()){
00681                 stringstream suffix;
00682                 suffix << "_" << connection->position << "_connection_";
00683                 appendSuffix(dummyName, suffix.str());
00684             }else{
00685                 stringstream suffix;
00686                 suffix << "_" << connection->name << "_connection_";
00687                 appendSuffix(dummyName, suffix.str());
00688             }
00689 
00690             if(value.size() == 1){
00691                 // single-bit connection
00692 
00693                 oa::oaModBitNet *net;
00694                 // if this is an BBRef, create a dummy net
00695                 if(value.front().type == BBREF) {
00696                     net = createScalarNet(dummyName);
00697                     net->makeEquivalent(value.front().net);
00698                 }else if(value.front().type == NET) {
00699                     assert(value.front().net);
00700                     // if this is an implicit net (i.e. a vector bit),
00701                     // a dummy explicit net needs to be created for the
00702                     // connection
00703                     // YH: how can this kind of implicit net be generated??
00704                     if (value.front().net->isImplicit()){
00705                         net = createScalarNet(dummyName);
00706                         net->makeEquivalent(value.front().net);
00707                     }else{
00708                         net = value.front().net;
00709                     }
00710                 } else{
00711                     // a net of NEITHER type
00712                     QUIT_ON_INTERNAL_ERROR;
00713                 }
00714 
00715                 if(connection->name.empty()) {
00716                     connectPort(inst, net, connection->position);
00717                 }else{
00718                     connectPort(inst, net, connection->name);
00719                 }
00720             }else{
00721                 // bus connection
00722 
00723                 // 1. make a dummy bus net of the appropriate width
00724                 oa::oaModBusNet *bus = createBusNet(dummyName,
00725                         value.size()-1,0);
00726 
00727                 // 2. assign bus net bits to be equivalent to supplied nets
00728                 MultiRefBus::iterator bitIter = value.begin();
00729                 int b = 0;
00730                 while(bitIter != value.end()) {
00731                     MultiRef m = *bitIter;
00732                     if(m.type == BBREF) {
00733                         assignMultiRef(bus->getBit(b), m);
00734                     }else if (m.type == NET) {
00735                         m.net->makeEquivalent(bus->getBit(b));
00736                     }else{
00737                         // a net of NEITHER type
00738                         QUIT_ON_INTERNAL_ERROR;
00739                     }
00740                     ++bitIter; ++b;
00741                 }
00742 
00743                 // 3. connect bus net to InstTerm
00744                 // YH: pay attention the differenct handler for the following
00745                 // two kinds of port connections,
00746                 // I'm not quite clear about why we need such difference
00747                 if(connection->name.empty()){
00748                     connectPort(inst, bus, connection->position);
00749                 }else{
00750                     connectPort(inst, bus, connection->name);
00751                 }
00752             }
00753 
00754             if(connection->name.empty()){
00755                 DEBUG_PRINTLN("\t\t " << connection->position << " <- [" <<
00756                         value.size() << "]");
00757             } else {
00758                 DEBUG_PRINTLN("\t\t " << connection->name << " <- [" << 
00759                         value.size() << "]");
00760             }
00761 
00762         }
00763 
00764     }
00765 }
00766 
00767 // *****************************************************************************
00768 // synthesizeModuleFunc()
00769 //
00775 // *****************************************************************************
00776 void
00777 VerilogSynthesis::synthesizeModuleFunc() 
00778 {
00779     // synthesize always blocks
00780 
00781     for(list<VerilogDesign::AlwaysBlock*>::iterator alwaysIter =
00782             currentVmodule->alwaysBlocks->begin(); alwaysIter !=
00783             currentVmodule->alwaysBlocks->end(); ++ alwaysIter) {
00784 
00785         VerilogDesign::AlwaysBlock *always = *alwaysIter;
00786         DEBUG_PRINTLN("\t always block");
00787         ProceduralState state;
00788 
00789         // categorize triggers
00790         for(list<VerilogDesign::Trigger*>::iterator triggerIter =
00791                 always->triggers->begin(); triggerIter !=
00792                 always->triggers->end(); ++ triggerIter) {
00793             
00794             VerilogDesign::Trigger *trigger = *triggerIter;
00795             MultiRefBus t;
00796             evaluateExpression(t, trigger->net, NULL, currentParams);
00797             for(MultiRefBus::iterator bitIter = t.begin(); bitIter != t.end();
00798                     ++ bitIter) {
00799                 assert(bitIter->type == NET);
00800                 if(trigger->type == VerilogDesign::Trigger::POSEDGE) {
00801                     state.posTriggers.insert(bitIter->net);
00802                 }else if(trigger->type == VerilogDesign::Trigger::NEGEDGE) {
00803                     state.negTriggers.insert(bitIter->net);
00804                 }else{
00805                     state.normalTriggers.insert(bitIter->net);
00806                 }
00807             }
00808         }
00809 
00810         if(state.posTriggers.empty() && state.negTriggers.empty()) {
00811             DEBUG_PRINTLN("\t\t combinational/latch");
00812             state.isRegister = false;
00813         }else{
00814             if(state.normalTriggers.size() > 0){
00815                 // something like the following is not allowed (according to
00816                 // Quartus II Web Edition 7.1)
00817                 // ``always @(posedge C or tmp)''
00818                 DEBUG_PRINTLN("Error: Mixed single- double-edge expressions are\
00819                         not supported!");
00820                 QUIT_ON_INTERNAL_ERROR;
00821             }
00822             DEBUG_PRINTLN("\t\t register");
00823             state.isRegister = true;
00824         }
00825 
00826         synthesizeBehavioral(always->action, state, currentParams);
00827 
00828         // UNIMPLEMENTED
00829         // 1. verify that always trigger are complete 
00830         // 2. verify that triggers don't include lvals
00831         // YH: TODO
00832 
00833         MultiRef curClock;
00834         if(state.isRegister) {
00835 
00836             // Identify the clock signal and 
00837             // verify that clock signal exists for a sequential always block.
00838             // A clock signal is the one that is NOT a ALOAD signal for any
00839             // variables within this block
00840 
00841             // Firstly get those triggers that are not referred in the always block
00842             set<oa::oaModBitNet*> edgeTriggers;
00843             set_union(state.posTriggers.begin(), state.posTriggers.end(),
00844                     state.negTriggers.begin(), state.negTriggers.end(),
00845                     inserter(edgeTriggers, edgeTriggers.begin()));
00846             set<oa::oaModBitNet*> clockTriggers;
00847             set_difference(edgeTriggers.begin(), edgeTriggers.end(),
00848                     state.nonClockTriggers.begin(), state.nonClockTriggers.end(),
00849                     inserter(clockTriggers, clockTriggers.begin()));
00850 
00851             // Then check the number of clock triggers
00852             if(clockTriggers.size() == 0){
00853                 DEBUG_PRINTLN("ERROR: Cannot find a clock net in a synchronous\
00854                         always block");
00855                 QUIT_ON_INTERNAL_ERROR;
00856             }else if(clockTriggers.size() > 1) {
00857                 cerr << "The following clock nets are detected: ";
00858                 for(set<oa::oaModBitNet*>::iterator netIter =
00859                         clockTriggers.begin(); netIter !=
00860                         clockTriggers.end(); ++
00861                         netIter){
00862                     cerr << printBitNetName(*netIter) << ",";
00863                 }
00864                 cerr << endl;
00865                 DEBUG_PRINTLN("ERROR: more than one nets defined in the trigger \
00866                         list of a synchronous always block, while not used as \
00867                         asynchronous signals"); 
00868                     QUIT_ON_INTERNAL_ERROR;
00869             }
00870             assert(clockTriggers.size() == 1);
00871             curClock = MultiRef(*clockTriggers.begin());
00872         }
00873 
00874         // set the functionality for all of the modified nets
00875         DEBUG_PRINTLN("\t nets assigned: ");
00876         for(map<oa::oaModBitNet*, MultiRef>::iterator it =
00877                 state.blockingAssignments.begin(); it !=
00878                 state.blockingAssignments.end(); it++) {
00879 
00880             if(state.isRegister) {
00881                 stringstream str;
00882                 oa::oaName name;
00883                 it->first->getName(name);
00884                 if(name.getVectorBit()){
00885                     oa::oaString baseName;
00886                     name.getVectorBit()->getBaseName(baseName);
00887                     str << baseName << "_" << name.getVectorBit()->getIndex();
00888                 } else {
00889                     oa::oaString scalarName;
00890                     assert(name.getScalar());
00891                     name.getScalar()->get(scalarName);
00892                     str << scalarName;
00893                 }
00894                 cerr << "WARNING: Blocking assignment in register " << str <<
00895                     endl;
00896                 MultiRef seqRef;
00897                 if(state.aData.find(it->first) != state.aData.end()){
00898                     assert(state.aLoad.find(it->first) != state.aLoad.end());
00899                     // Annotate clock signal and the asynchronous 
00900                     // load and data (aLoad/aData) on the DFF
00901                     seqRef = seq(it->second, curClock, state.aLoad[it->first],
00902                             state.aData[it->first], str.str());
00903                 }else{
00904                     cerr << "WARNING: Initial state of register " << str.str() 
00905                         << " is not clear, using signal bb_" << curClock.bb 
00906                         << " as the clock for it" << endl;
00907                     seqRef = seq(it->second, curClock, str.str());
00908                 }
00909                 assignMultiRef(it->first, seqRef);
00910 
00911                 /*
00912                 // append all of the negedge triggers as "trigger_XXX_negedge"
00913                 // and posedge as "trigger_XXX_posedge"
00914                 // the tech mapper will need to distinguish clocks from
00915                 // reset/preset
00916                 int triggerID = 0;
00917                 assert(seqRef.type == BBREF);
00918                 for(set<oa::oaModBitNet*>::iterator trigIter =
00919                             state.posTriggers.begin(); trigIter != state.posTriggers.end();
00920                             trigIter++, triggerID++) {
00921                     oa::oaModBitNet *trigNet = *trigIter;
00922                     stringstream label;
00923                     label << "trigger_" << triggerID << "_posedge";
00924                     // YH: come back!!
00925                     // routine annotateAsynchronousSignal() needs to be
00926                     // changed!!
00927                     // annotateAsynchronousSignal(seqRef.ai, label.str(),
00928                     //         MultiRef(trigNet));
00929                 }
00930                 for(set<oa::oaModBitNet *>::iterator trigIter =
00931                         state.negTriggers.begin(); trigIter != state.negTriggers.end();
00932                         trigIter++, triggerID++) {
00933                     oa::oaModBitNet *trigNet = *trigIter;
00934                     stringstream label;
00935                     label << "trigger_" << triggerID << "_negedge";
00936                     // YH: come back!!
00937                     // routine annotateAsynchronousSignal() needs to be
00938                     // changed!!
00939                     // annotateAsynchronousSignal(seqRef.ai, label.str(),
00940                     //         MultiRef(trigNet));
00941                 }*/
00942             } else {
00943                 assignMultiRef(it->first, it->second);
00944             }
00945         }
00946 
00947         for(map<oa::oaModBitNet*, MultiRef>::iterator it =
00948                 state.nonblockingAssignments.begin(); it !=
00949                 state.nonblockingAssignments.end(); it ++){
00950             if (state.isRegister) {
00951                 stringstream str;
00952                 oa::oaName name;
00953                 it->first->getName(name);
00954                 if(name.getVectorBit()) {
00955                     oa::oaString baseName;
00956                     name.getVectorBit()->getBaseName(baseName);
00957                     str << baseName << "_" << name.getVectorBit()->getIndex();
00958                 }else{
00959                     assert(name.getScalar());
00960                     oa::oaString scalarName;
00961                     name.getScalar()->get(scalarName);
00962                     str << scalarName;
00963                 }
00964 
00965                 MultiRef seqRef;
00966                 if(state.aData.find(it->first) != state.aData.end()){
00967                     assert(state.aLoad.find(it->first) != state.aLoad.end());
00968                     // Annotate clock signal and the asynchronous 
00969                     // load and data (aLoad/aData) on the DFF
00970                     seqRef = seq(it->second, curClock, state.aLoad[it->first],
00971                             state.aData[it->first], str.str());
00972                 }else{
00973                     cerr << "WARNING: Initial state of register " << str.str()
00974                         << " is not clear, using signal bb_" << curClock.bb 
00975                         << " as the clock for it" << endl;
00976                     seqRef = seq(it->second, curClock, str.str());
00977                 }
00978                 assignMultiRef(it->first, seqRef);
00979 
00980                 /*
00981                 // append all of the negedge triggers as "trigger_XXX_negedge"
00982                 // and posedge as "trigger_XXX_posedge"
00983                 // the tech mapper will need to distinguish clocks from
00984                 // reset/preset
00985                 int triggerID = 0;
00986                 assert(seqRef.type == BBREF);
00987                 for(set<oa::oaModBitNet*>::iterator trigIter =
00988                             state.posTriggers.begin(); trigIter != state.posTriggers.end();
00989                             trigIter++, triggerID++) {
00990                     oa::oaModBitNet *trigNet = *trigIter;
00991                     stringstream label;
00992                     label << "trigger_" << triggerID << "_posedge";
00993                     // YH: come back!!
00994                     // routine annotateAsynchronousSignal() needs to be
00995                     // changed!!
00996                     // annotateAsynchronousSignal(seqRef.ai, label.str(),
00997                     //         MultiRef(trigNet));
00998                 }
00999                 for(set<oa::oaModBitNet *>::iterator trigIter =
01000                         state.negTriggers.begin(); trigIter != state.negTriggers.end();
01001                         trigIter++, triggerID++) {
01002                     oa::oaModBitNet *trigNet = *trigIter;
01003                     stringstream label;
01004                     label << "trigger_" << triggerID << "_negedge";
01005                     // YH: come back!!
01006                     // routine annotateAsynchronousSignal() needs to be
01007                     // changed!!
01008                     // annotateAsynchronousSignal(seqRef.ai, label.str(),
01009                     //         MultiRef(trigNet));
01010                 }*/
01011             } else {
01012                 assignMultiRef(it->first, it->second);
01013             }
01014         }
01015     }
01016 }
01017 
01018 // *****************************************************************************
01019 // synthesizeBlock()
01020 //
01023 //
01024 // *****************************************************************************
01025 void
01026 VerilogSynthesis::synthesizeBlock(VerilogDesign::Statement *statement,
01027                                             ProceduralState &state,
01028                                             ParameterValues *parameters)
01029 {
01030     // there may be local variables defined for this block
01031     if(statement->begin_end.declarations != NULL)
01032         for(list<VerilogDesign::Declaration*>::iterator declIter =
01033                 statement->begin_end.declarations->begin(); declIter !=
01034                 statement->begin_end.declarations->end(); declIter++) {
01035 
01036             VerilogDesign::Declaration *vDeclaration = *declIter;
01037             // UNIMPLEMENTED: prefix register name with block name
01038 
01039             ConstantValue start, stop;
01040             if(vDeclaration->start == NULL) {
01041                 if(vDeclaration->start2D == NULL) {
01042                     if(!(findScalarNet(vDeclaration->name))) {
01043                         createScalarNet(vDeclaration->name);
01044                     }
01045                     DEBUG_PRINT("\t net " << vDeclaration->name);
01046                 } else {
01047                     ConstantValue start2D, stop2D;
01048                     evaluateConstantExpression(start2D,
01049                             vDeclaration->start2D, parameters);
01050                     evaluateConstantExpression(stop2D, vDeclaration->stop2D,
01051                             parameters);
01052                     Bounds bounds;
01053                     bounds.upper = max(start2D.intValue, stop2D.intValue);
01054                     bounds.lower = min(start2D.intValue, stop2D.intValue);
01055                     twoDimRegisters[vDeclaration->name] = bounds;
01056                     for(int i=bounds.lower; i<=bounds.upper; i++) {
01057                         // construct suffix to identify net in 2-d vector
01058                         string vectorName(vDeclaration->name);
01059                         stringstream suffix;
01060                         suffix << "_" << i << "_";
01061                         appendSuffix(vectorName, suffix.str());
01062                         if(!(findScalarNet(vectorName))){
01063                             createScalarNet(vectorName);
01064                         }
01065                     }
01066                     DEBUG_PRINT("\t net " << vDeclaration->name << "<"
01067                             << start2D.intValue << ":" << stop2D.intValue
01068                             << ">");
01069                 }
01070             } else {
01071                 evaluateConstantExpression(start, vDeclaration->start, 
01072                         parameters); 
01073                 evaluateConstantExpression(stop, vDeclaration->stop, 
01074                         parameters);
01075                 if (vDeclaration->start2D == NULL) {
01076                     if (!(findBusNet(vDeclaration->name))) {
01077                         createBusNet(vDeclaration->name, start.intValue, 
01078                                 stop.intValue);
01079                     }
01080                     DEBUG_PRINT("\t net " << vDeclaration->name << "[" 
01081                             << start.intValue << ":" << stop.intValue << "]");
01082                 } else {
01083                     ConstantValue start2D, stop2D;
01084                     evaluateConstantExpression(start2D, vDeclaration->start2D,
01085                             parameters); 
01086                     evaluateConstantExpression(stop2D, vDeclaration->stop2D, 
01087                             parameters);
01088                     Bounds bounds;
01089                     bounds.upper = max(start2D.intValue, stop2D.intValue); 
01090                     bounds.lower = min(start2D.intValue, stop2D.intValue);
01091                     twoDimRegisters[vDeclaration->name] = bounds;
01092                     for(int i=bounds.lower; i<=bounds.upper; i++) {
01093                         // construct suffix to identify net in 2-d vector 
01094                         string vectorName(vDeclaration->name);
01095                         stringstream suffix;
01096                         suffix << "_" << i << "_";
01097                         appendSuffix(vectorName, suffix.str());
01098                         if (!(findBusNet(vectorName))) {  
01099                             createBusNet(vectorName, start.intValue, 
01100                                     stop.intValue);
01101                         }
01102                     }
01103                     DEBUG_PRINT("\t net " << vDeclaration->name << "[" 
01104                             << start.intValue << ":" << stop.intValue << "]" 
01105                             << "<" << start2D.intValue << ":" 
01106                             << stop2D.intValue << ">");
01107                 }
01108             }
01109 
01110             switch(vDeclaration->type) {
01111                 case VerilogDesign::Declaration::REG:
01112                     DEBUG_PRINTMORE(" (reg)" << endl);
01113                     break;
01114                 default:
01115                     QUIT_ON_INTERNAL_ERROR;
01116                     break;
01117             }
01118         }
01119 
01120     DEBUG_PRINTLN("\t\t block");
01121     for(list<VerilogDesign::Statement*>::iterator stateIter =
01122             statement->begin_end.block->begin(); stateIter !=
01123             statement->begin_end.block->end(); ++ stateIter) {
01124         synthesizeBehavioral(*stateIter, state, parameters);
01125     }
01126 }
01127 
01128 // *****************************************************************************
01129 // synthesizeIf()
01130 //
01132 //
01133 // *****************************************************************************
01134 void
01135 VerilogSynthesis::synthesizeIf(VerilogDesign::Statement *statement,
01136                                                ProceduralState &state,
01137                                                ParameterValues *parameters)
01138 {
01139             DEBUG_PRINTLN("\t\t if");
01140 
01141             MultiRefBus condition;
01142             assert(statement->ifc.condition);
01143             // Synthesize the condition expression and 
01144             // check if there is asynchronous signals in condition expression
01145             bool hasAsynchronousSignal = 
01146                 evaluateExpression(condition, statement->ifc.condition, &state,
01147                     parameters);
01148 
01149             MultiRef select(reductionOr(condition));
01150 
01151             if(hasAsynchronousSignal){
01152                 state.pStateType = ProceduralState::PSTATE_ASYNC;
01153                 state.curTrigger = select;
01154             }else{
01155                 state.pStateType = ProceduralState::PSTATE_SYNC;
01156             }
01157 
01158             // The default shallow copy constructor of "ProceduralState" applies
01159             // here. Basically, it copies each field of ProceduralState.
01160             // Importantly, blockingAssignments/nonblockingAssignments of the
01161             // upper level scope is copied to ifState and elseState, thereby the
01162             // following case can be handled without inferring a latch by
01163             // mistake. In fact, a combinational MUX will be inferred.
01164             // 
01165             //          always @(ld or d or q_old)
01166             //              begin
01167             //                  q = q_old;
01168             //                  if (ld)
01169             //                      q = d;
01170             //              end
01171             ProceduralState ifState(state), elseState(state);
01172 
01173             assert(statement->ifc.ifTrue);
01174             synthesizeBehavioral(statement->ifc.ifTrue, ifState, parameters);
01175             if(statement->ifc.ifFalse) {
01176                 synthesizeBehavioral(statement->ifc.ifFalse, elseState,
01177                         parameters);
01178             }
01179 
01180             if(state.pStateType == ProceduralState::PSTATE_SYNC){
01181 
01182                 // construct mux for all variables w/ blocking assignments
01183                 for(map<oa::oaModBitNet*, MultiRef>::iterator it =
01184                         ifState.blockingAssignments.begin(); it !=
01185                         ifState.blockingAssignments.end(); ++ it) {
01186 
01187                     oa::oaString str;
01188                     it->first->getName(*nameSpace, str);
01189 
01190                     if(elseState.blockingAssignments.find(it->first) !=
01191                             elseState.blockingAssignments.end()) {
01192 
01193                         // combinational
01194 
01195                         state.blockingAssignments[it->first] = mux(select,
01196                                 elseState.blockingAssignments[it->first],
01197                                 it->second);
01198 
01199                         oa::oaString str;
01200                         it->first->getName(*nameSpace, str);
01201                         DEBUG_PRINTLN("Combinational mux " <<
01202                                 currentVmodule->name << "." << str << endl);
01203                     }else if(state.isRegister) {
01204 
01205                         // mux previous state
01206 
01207                         state.blockingAssignments[it->first] = mux(select,
01208                                 MultiRef(it->first), it->second);
01209 
01210                         oa::oaString str;
01211                         it->first->getName(*nameSpace, str);
01212                         DEBUG_PRINTLN("Mux the previous state " <<
01213                                 currentVmodule->name << "." << str << endl);
01214                     }else{
01215 
01216                         // implict latch... transparent when condition
01217 
01218                         state.blockingAssignments[it->first] = latch(select,
01219                                 it->second);
01220 
01221                         oa::oaString str;
01222                         it->first->getName(*nameSpace, str);
01223                         DEBUG_PRINTLN("NOTE: Implicit latch on net " <<
01224                                 currentVmodule->name << "." << str << endl);
01225                     }
01226                 }
01227                 for(map<oa::oaModBitNet*, MultiRef>::iterator it =
01228                         elseState.blockingAssignments.begin(); it !=
01229                         elseState.blockingAssignments.end(); ++ it) {
01230 
01231                     if(ifState.blockingAssignments.find(it->first) !=
01232                             ifState.blockingAssignments.end()) {
01233 
01234                         // combinational, a mux has been assigned in ifState
01235 
01236                     }else if(state.isRegister) {
01237 
01238                         // mux previous state
01239 
01240                         state.blockingAssignments[it->first] = mux(select,
01241                                 MultiRef(it->first), it->second);
01242                     }else{
01243 
01244                         // implict latch... transparent when !select
01245 
01246                         state.blockingAssignments[it->first] = latch(notOf(select),
01247                                 it->second);
01248 
01249                         oa::oaString str;
01250                         it->first->getName(*nameSpace, str);
01251                         cerr << "NOTE: Implicit latch on net " <<
01252                             currentVmodule->name << "." << str << endl;
01253                     }
01254                 }
01255 
01256                 // construct mux for all variables w/ nonblocking assignments
01257                 for(map<oa::oaModBitNet*, MultiRef>::iterator it =
01258                         ifState.nonblockingAssignments.begin(); it !=
01259                         ifState.nonblockingAssignments.end(); ++ it) {
01260 
01261                     oa::oaString str;
01262                     it->first->getName(*nameSpace, str);
01263 
01264                     if(elseState.nonblockingAssignments.find(it->first) !=
01265                             elseState.nonblockingAssignments.end()) {
01266 
01267                         // combinational
01268 
01269                         state.nonblockingAssignments[it->first] = mux(select,
01270                                 elseState.nonblockingAssignments[it->first],
01271                                 it->second);
01272                     }else if(state.isRegister) {
01273 
01274                         // mux previous state
01275 
01276                         state.nonblockingAssignments[it->first] = mux(select,
01277                                 MultiRef(it->first), it->second);
01278                     }else{
01279 
01280                         // implict latch... transparent when condition
01281 
01282                         state.nonblockingAssignments[it->first] = latch(select,
01283                                 it->second);
01284 
01285                         oa::oaString str;
01286                         it->first->getName(*nameSpace, str);
01287                         cerr << "NOTE: Implicit latch on net " <<
01288                             currentVmodule->name << "." << str << endl;
01289                     }
01290                 }
01291                 for(map<oa::oaModBitNet*, MultiRef>::iterator it =
01292                         elseState.nonblockingAssignments.begin(); it !=
01293                         elseState.nonblockingAssignments.end(); ++ it) {
01294 
01295                     if(ifState.nonblockingAssignments.find(it->first) !=
01296                             ifState.nonblockingAssignments.end()) {
01297 
01298                         // combinational, a mux has been assigned in ifState
01299 
01300                     }else if(state.isRegister) {
01301 
01302                         // mux previous state
01303 
01304                         state.nonblockingAssignments[it->first] = mux(select,
01305                                 MultiRef(it->first), it->second);
01306                     }else{
01307 
01308                         // implict latch... transparent when !select
01309 
01310                         state.nonblockingAssignments[it->first] = latch(notOf(select),
01311                                 it->second);
01312 
01313                         oa::oaString str;
01314                         it->first->getName(*nameSpace, str);
01315                         cerr << "NOTE: Implicit latch on net " <<
01316                             currentVmodule->name << "." << str << endl;
01317                     }
01318                 }
01319             }else{
01320                 assert(state.pStateType == ProceduralState::PSTATE_ASYNC);
01321                 assert(state.curTrigger.type != NEITHER);
01322 
01323                 // store the r-value and the trigger
01324                 // of the asynchronous assignment
01325                 // for all variables w/ blocking assignments
01326                 for(map<oa::oaModBitNet*, MultiRef>::iterator it =
01327                         ifState.blockingAssignments.begin(); it !=
01328                         ifState.blockingAssignments.end(); ++ it) {
01329 
01330                     state.aData[it->first] = it->second;
01331                     state.aLoad[it->first] = state.curTrigger;
01332                     oa::oaString str;
01333                     it->first->getName(*nameSpace, str);
01334                     DEBUG_PRINTLN("Annoate asynchronous signal for " <<
01335                             currentVmodule->name << "." << str << endl);
01336                 }
01337                 // copy the blocking assignments in the deeper scope (i.e.,
01338                 // block within the ELSE scope)
01339                 for(map<oa::oaModBitNet*, MultiRef>::iterator it =
01340                         elseState.blockingAssignments.begin(); it !=
01341                         elseState.blockingAssignments.end(); ++ it) {
01342                     state.blockingAssignments[it->first] = it->second;
01343                 }
01344 
01345                 // store the r-value and the trigger 
01346                 // of the asynchronous assignment 
01347                 // for all variables w/ nonblocking assignments
01348                 for(map<oa::oaModBitNet*, MultiRef>::iterator it =
01349                         ifState.nonblockingAssignments.begin(); it !=
01350                         ifState.nonblockingAssignments.end(); ++ it) {
01351 
01352                     state.aData[it->first] = it->second;
01353                     state.aLoad[it->first] = state.curTrigger;
01354                     oa::oaString str;
01355                     it->first->getName(*nameSpace, str);
01356                     DEBUG_PRINTLN("Annoate asynchronous signal for " <<
01357                             currentVmodule->name << "." << str << endl);
01358                 }
01359                 // copy the nonblocking assignments in the deeper scope (i.e.,
01360                 // block within the ELSE scope)
01361                 for(map<oa::oaModBitNet*, MultiRef>::iterator it =
01362                         elseState.nonblockingAssignments.begin(); it !=
01363                         elseState.nonblockingAssignments.end(); ++ it) {
01364                     state.nonblockingAssignments[it->first] = it->second;
01365                 }
01366 
01367             }
01368 }
01369 
01370 // *****************************************************************************
01371 // synthesizeCaseEasy()
01372 //
01375 //
01376 // *****************************************************************************
01377 bool
01378 VerilogSynthesis::synthesizeCaseEasy(VerilogDesign::Statement *statement,
01379                                                ProceduralState &state,
01380                                                ParameterValues *parameters)
01381 {
01382     bool                    allConstCondition = true;
01383     vector<ConstantValue>   constConditionVal;
01384 
01385     // go through all branch conditions to check if they are all constant, and
01386     // collect those conditions
01387     for(list<VerilogDesign::Case*>::iterator caseIter =
01388             statement->ifc.cases->begin(); caseIter !=
01389             statement->ifc.cases->end(); ++ caseIter) {
01390 
01391         VerilogDesign::Case *c = *caseIter;
01392         assert(c);
01393 
01394         if(!c->isDefault) {
01395             // not a default case
01396             DEBUG_PRINTLN("\t\t case label conditions=" <<
01397                     c->conditions->size());
01398 
01399             for(list<VerilogDesign::Expression*>::iterator condIter =
01400                     c->conditions->begin(); condIter !=
01401                     c->conditions->end(); ++ condIter) {
01402 
01403                 VerilogDesign::Expression *condExpr = *condIter;
01404                 if(!isConstantExpression(condExpr, parameters)) return false;
01405 
01406                 // calculate and store the current case branch condition
01407                 ConstantValue caseConstant, conditionConstant;
01408                 evaluateConstantExpression(caseConstant, condExpr,
01409                         parameters);
01410                 constConditionVal.push_back(caseConstant);
01411 
01412                 if (statement->type ==
01413                         VerilogDesign::Statement::CASEX) {
01414                     // YH: UNIMPLEMENTED yet
01415                     cerr << "ERROR: CASEX is unimplemented yet ... " 
01416                         << endl;
01417                     QUIT_ON_ERROR;
01418                 } else if (statement->type ==
01419                         VerilogDesign::Statement::CASEZ) {
01420                     // YH: UNIMPLEMENTED yet
01421                     cerr << "ERROR: CASEZ is unimplemented yet ... " 
01422                         << endl;
01423                     QUIT_ON_ERROR;
01424                 } 
01425 
01426             } // end of loop for all conditions of the current CASE
01427 
01428         } // end if (not a default case)
01429 
01430     } // end of loop for each CASE
01431 
01432     // at this point, all branch conditions are constant
01433 
01434     DEBUG_PRINTLN("\t\t an easy case is identified");
01435 
01436     // TODO: handle the scenario when the CASE condition is constant
01437     if(isConstantExpression(statement->ifc.condition,
01438                             parameters)) {
01439         cerr << "ERROR: the constant case condition is unimplemented yet ... "
01440             << endl;
01441         QUIT_ON_ERROR;
01442 #if 0
01443         // both case condition and case branch are constant
01444         ConstantValue conditionConstant;
01445         evaluateConstantExpression(conditionConstant,
01446                 statement->ifc.condition, parameters);
01447         vector<ConstantValue>::iterator constIter;   
01448         for(constIter = constConditionVal.begin(); constIter !=
01449                 constConditionVal.end(); ++ constIter){
01450             assert(constIter->bitWidth == conditionConstant.bitWidth);
01451             if(constIter->intValue == conditionConstant.intValue) 
01452         }
01453 #endif
01454     }
01455 
01456     // begin to synthesize this CASE statement
01457     // 06/12/07, 11:23AM
01458 
01459     // 1. compute condition
01460     MultiRefBus condition;
01461     evaluateExpression(condition, statement->ifc.condition, &state,
01462             parameters);
01463     list<ProceduralState*>  caseActions;
01464     vector<vector<ConstantValue> > caseSelects;
01465     set<oa::oaModBitNet*>   modifiedBlockingAssignments,
01466         modifiednonblockingAssignments;
01467     ProceduralState         *defaultAction = NULL;
01468     vector<int> defaultSelect;
01469 
01470     // 2. compute the procedural state for each case
01471     // 3. compute the select lines for each case
01472     for(list<VerilogDesign::Case*>::iterator caseIter =
01473             statement->ifc.cases->begin(); caseIter !=
01474             statement->ifc.cases->end(); ++ caseIter) {
01475 
01476         VerilogDesign::Case *c = *caseIter;
01477         assert(c);
01478 
01479         ProceduralState *action = NULL;
01480         if(c->isDefault) {
01481             // this is the default case
01482             DEBUG_PRINTLN("\t\t default case");
01483 
01484             if(defaultAction != NULL) {
01485                 cerr << "ERROR: Multiple default cases" << endl;
01486                 QUIT_ON_ERROR;
01487             }
01488 
01489             action = new ProceduralState(state);
01490             synthesizeBehavioral(c->action, *action, parameters);
01491             defaultAction = action;
01492         } else {
01493             // not a default case
01494             DEBUG_PRINTLN("\t\t case label conditions=" <<
01495                     c->conditions->size());
01496 
01497             // For each CASE, there could be multiple conditions.
01498             // The selective bit (select) which satisfies this CASE
01499             // should satisfy any of those conditions.
01500             // 
01501             // E.g., 
01502             // case A:
01503             // case B:
01504             // case C:
01505             //      action() {/* action for A or B or C */}
01506             //      break;
01507             // Therefore, select = A or B or C
01508 
01509             // collect all CASE branch conditions for the current CASE statement
01510             vector<ConstantValue> caseMatchesCondition;
01511 
01512             for(list<VerilogDesign::Expression*>::iterator condIter =
01513                     c->conditions->begin(); condIter !=
01514                     c->conditions->end(); ++ condIter) {
01515 
01516                 MultiRefBus caseCondition;
01517                 VerilogDesign::Expression *condExpr = *condIter;
01518                 evaluateExpression(caseCondition, condExpr, &state,
01519                         parameters);
01520                 zeroExpand(condition, caseCondition);
01521 
01522                 ConstantValue caseConstantCondition;
01523                 evaluateConstantExpression(caseConstantCondition, condExpr,
01524                         parameters);
01525 
01526                 if (statement->type == VerilogDesign::Statement::CASEX) {
01527                     // YH: UNIMPLEMENTED yet
01528                     cerr << "ERROR: CASEX is unimplemented yet ... " << endl;
01529                     QUIT_ON_ERROR;
01530                 } else if (statement->type == VerilogDesign::Statement::CASEZ) {
01531                     // YH: UNIMPLEMENTED yet
01532                     cerr << "ERROR: CASEZ is unimplemented yet ... " << endl;
01533                     QUIT_ON_ERROR;
01534                 } else {
01535                     caseMatchesCondition.push_back(caseConstantCondition);
01536                 }
01537             } // end of loop for all conditions of the current CASE
01538 
01539             caseSelects.push_back(caseMatchesCondition);
01540 
01541             assert(action == NULL);
01542             if (action == NULL) {
01543                 action = new ProceduralState(state);
01544                 synthesizeBehavioral(c->action, *action, parameters);
01545             }
01546             caseActions.push_back(action);
01547 
01548         } // end of else (not a default case)
01549 
01550         if(action == NULL)
01551             cerr << "Error: action is not NULL\n";
01552 
01553         // identify the nets that have been modified
01554         assert(action != NULL);
01555         if(action != NULL) {
01556             for(map<oa::oaModBitNet*, MultiRef>::iterator postActionAssignment =
01557                     action->blockingAssignments.begin(); postActionAssignment !=
01558                     action->blockingAssignments.end(); ++postActionAssignment) {
01559 
01560                 map<oa::oaModBitNet*, MultiRef>::iterator preActionAssignment =
01561                     state.blockingAssignments.find(postActionAssignment->first); 
01562                 // either the net hadn't been assigned before, or it was
01563                 // assigned to something different?
01564                 if(preActionAssignment == state.blockingAssignments.end() ||
01565                         !(postActionAssignment->second ==
01566                             preActionAssignment->second)) {
01567                     modifiedBlockingAssignments.insert(postActionAssignment->first);
01568                 }
01569             }
01570             for(map<oa::oaModBitNet*, MultiRef>::iterator
01571                     postActionAssignment = action->nonblockingAssignments.begin();
01572                     postActionAssignment != action->nonblockingAssignments.end(); ++
01573                     postActionAssignment) {
01574                 map<oa::oaModBitNet*, MultiRef>::iterator preActionAssignment =
01575                     state.nonblockingAssignments.find(postActionAssignment->first);
01576                 // either the net hadn't been assigned before, or it was
01577                 // assigned to something different?
01578                 if(preActionAssignment == state.nonblockingAssignments.end() ||
01579                         !(postActionAssignment->second ==
01580                             preActionAssignment->second)) {
01581                     modifiednonblockingAssignments.insert(postActionAssignment->first);
01582                 }
01583             }
01584         }
01585 
01586     } // end of loop for each CASE
01587 
01588     // 3.1. calculate the defaultSelect bit by performing complement
01589 
01590     // 3.1.1. generate possible selection values based on the select bits width
01591 
01592     int numSelectBits = condition.size();
01593     // NOTE: "unsigned int" is assumed here!
01594     if(numSelectBits > 30){
01595         cerr << "The number of selection bits of a CASE statement cannot exceed 31 bits" 
01596             << endl;
01597         QUIT_ON_ERROR;
01598     }
01599     int selectMax = 1 << numSelectBits;
01600     vector<bool> selectBitMap(selectMax);
01601     for(int selectCur = 0; selectCur < selectMax; ++ selectCur)
01602         selectBitMap[selectCur] = false;
01603 
01604     // 3.1.2. setup the selection values covered by CASE branch conditions
01605     for(vector<vector<ConstantValue> >::iterator caseConditionIter =
01606             caseSelects.begin(); caseConditionIter != caseSelects.end();
01607             ++ caseConditionIter){
01608         for(vector<ConstantValue>::iterator oneCaseConditionIter =
01609                 caseConditionIter->begin(); oneCaseConditionIter !=
01610                 caseConditionIter->end(); ++ oneCaseConditionIter){
01611             selectBitMap[oneCaseConditionIter->intValue] = true;
01612         }
01613     }
01614 
01615     // 3.1.3. obtain default selection values
01616     for(int selectCur = 0; selectCur < selectMax; ++ selectCur)
01617         if(selectBitMap[selectCur] == false)
01618             defaultSelect.push_back(selectCur);
01619 
01620     // 4. for each set variable, build n-way mux.
01621     // 5. also compute the case where the value is nextState
01622 
01623     for(set<oa::oaModBitNet*>::iterator bitIter =
01624             modifiedBlockingAssignments.begin(); bitIter !=
01625             modifiedBlockingAssignments.end(); ++ bitIter) {
01626 
01627 
01628         // The structure of the CASE statement is as follows.
01629         // 
01630         // For each modified blocking assignment, the DATA input of the MUX is
01631         // feed by blocking/nonblocing assignment, the SELECT input of the MUX
01632         // is feed by the selection bits.
01633         //
01634         // In case that a signal is not assigned in certain CASE branch
01635         // condition, a latch is inferred. The enable signal of that latch is
01636         // the OR of all CASE branch conditions where the signal is not
01637         // assigned.
01638 
01639         vector<MultiRef>        muxData(selectMax);
01640         vector<bool>            muxDataValid(selectMax);
01641         vector<int>             latchEnableTerms;
01642 
01643         vector<vector<ConstantValue> >::iterator selectsIter = caseSelects.begin();
01644         list<ProceduralState*>::iterator actionIter = caseActions.begin();
01645         assert(caseSelects.size() == caseActions.size());
01646 
01647         while(selectsIter != caseSelects.end() && actionIter !=
01648                 caseActions.end()) {
01649 
01650             if((*actionIter)->blockingAssignments.find(*bitIter) ==
01651                     (*actionIter)->blockingAssignments.end()){
01652                 // implicit latch
01653                 for(vector<ConstantValue>::iterator constIter =
01654                         selectsIter->begin(); constIter != selectsIter->end();
01655                         ++ constIter){
01656                     latchEnableTerms.push_back(constIter->intValue);
01657                     muxDataValid[constIter->intValue] = false;
01658                 }
01659             }else {
01660                 // mux input terms for the current CASE branch
01661                 for(vector<ConstantValue>::iterator constIter =
01662                         selectsIter->begin(); constIter != selectsIter->end();
01663                         ++ constIter){
01664                     int curSelection = constIter->intValue;
01665                     muxData[curSelection] =
01666                         (*actionIter)->blockingAssignments[*bitIter];
01667                     muxDataValid[curSelection] = true;
01668                 }
01669             }
01670 
01671             ++ selectsIter; ++ actionIter;
01672         }
01673 
01674         // handle default case, if it exists
01675         if(defaultAction != NULL) {
01676             if(defaultAction->blockingAssignments.find(*bitIter) ==
01677                     defaultAction->blockingAssignments.end()) {
01678                 // implicit latch
01679                 for(vector<int>::iterator constIter =
01680                         defaultSelect.begin(); constIter != defaultSelect.end();
01681                         ++ constIter){
01682                     latchEnableTerms.push_back(*constIter);
01683                     muxDataValid[*constIter] = false;
01684                 }
01685             }else{
01686                 // mux term
01687                 for(vector<int>::iterator constIter =
01688                         defaultSelect.begin(); constIter != defaultSelect.end();
01689                         ++ constIter){
01690                     muxData[*constIter] =
01691                         defaultAction->blockingAssignments[*bitIter];
01692                     muxDataValid[*constIter] = true;
01693                 }
01694             }
01695         }
01696 
01697         MultiRefBus muxDataList;
01698         for(int i=0;i<selectMax;i++){
01699             if(muxDataValid[i]) muxDataList.push_back(muxData[i]);
01700         }
01701 
01702         if(latchEnableTerms.empty()){
01703             assert(muxData.size() == muxDataList.size());
01704             // a single MUX is ok to implement this assignment in this CASE statement
01705             oa::oaString str;
01706             (*bitIter)->getName(*nameSpace, str);
01707             DEBUG_PRINTLN("\t\t\t "<< str << " = case_mux" );
01708             state.blockingAssignments[*bitIter] = mux(condition, muxDataList);
01709         }else{
01710 
01711             // In case there is a latch, the latch's enable is feed by a mux
01712             // whose input data and selection bits are from a pre-calculated
01713             // table and the condition of the CASE statement, respectively.
01714             // The latch's data signal is feed by the mux inferred by the CASE
01715             // statement.
01716 
01717             oa::oaString str;
01718             (*bitIter)->getName(*nameSpace, str);
01719             cerr << "NOTE: Implicit latch on net " <<
01720                 currentVmodule->name << "." << str << endl;
01721 
01722             // setup latch enable bits
01723             vector<MultiRef> latchEnableBitMap(selectMax);
01724             for(int i=0;i<selectMax;i++)
01725                 latchEnableBitMap[i] = constantOne();
01726             for(vector<int>::iterator latchTermIter = latchEnableTerms.begin();
01727                     latchTermIter != latchEnableTerms.end(); ++ latchTermIter)
01728                 latchEnableBitMap[*latchTermIter] = constantZero();
01729             // create a MUX for the assignment in the CASE branch condition
01730             MultiRef combinationalOutput = mux(condition, muxDataList);
01731             // conver the vector the MultiRefBus
01732             MultiRefBus latchEnableBitMapList;
01733             back_insert_iterator<MultiRefBus > latchEnableBIIter(latchEnableBitMapList);
01734             copy(latchEnableBitMap.begin(), latchEnableBitMap.end(), latchEnableBIIter);
01735             // create a MUX for generating enable bit of the latch
01736             MultiRef latchEnableBit = mux(condition, latchEnableBitMapList);
01737             // create the latch
01738             state.blockingAssignments[*bitIter] = latch(latchEnableBit, 
01739                     combinationalOutput);
01740         }
01741     }
01742 
01743     for(set<oa::oaModBitNet*>::iterator bitIter =
01744             modifiednonblockingAssignments.begin(); bitIter !=
01745             modifiednonblockingAssignments.end(); ++ bitIter) {
01746 
01747         // The structure of the CASE statement is as follows.
01748         // 
01749         // For each modified blocking assignment, the DATA input of the MUX is
01750         // feed by blocking/nonblocing assignment, the SELECT input of the MUX
01751         // is feed by the selection bits.
01752         //
01753         // In case that a signal is not assigned in certain CASE branch
01754         // condition, a latch is inferred. The enable signal of that latch is
01755         // the OR of all CASE branch conditions where the signal is not
01756         // assigned.
01757 
01758         vector<MultiRef>        muxData(selectMax);
01759         vector<bool>            muxDataValid(selectMax);
01760         vector<int>             latchEnableTerms;
01761 
01762         vector<vector<ConstantValue> >::iterator selectsIter = caseSelects.begin();
01763         list<ProceduralState*>::iterator actionIter = caseActions.begin();
01764         assert(caseSelects.size() == caseActions.size());
01765 
01766         while(selectsIter != caseSelects.end() && actionIter !=
01767                 caseActions.end()) {
01768 
01769             if((*actionIter)->nonblockingAssignments.find(*bitIter) ==
01770                     (*actionIter)->nonblockingAssignments.end()){
01771                 // implicit latch
01772                 for(vector<ConstantValue>::iterator constIter =
01773                         selectsIter->begin(); constIter != selectsIter->end();
01774                         ++ constIter){
01775                     latchEnableTerms.push_back(constIter->intValue);
01776                     muxDataValid[constIter->intValue] = false;
01777                 }
01778             }else {
01779                 // mux input terms for the current CASE branch
01780                 for(vector<ConstantValue>::iterator constIter =
01781                         selectsIter->begin(); constIter != selectsIter->end();
01782                         ++ constIter){
01783                     int curSelection = constIter->intValue;
01784                     muxData[curSelection] =
01785                         (*actionIter)->nonblockingAssignments[*bitIter];
01786                     muxDataValid[curSelection] = true;
01787                 }
01788             }
01789 
01790             ++ selectsIter; ++ actionIter;
01791         }
01792 
01793         // handle default case, if it exists
01794         if(defaultAction != NULL) {
01795             if(defaultAction->nonblockingAssignments.find(*bitIter) ==
01796                     defaultAction->nonblockingAssignments.end()) {
01797                 // implicit latch
01798                 for(vector<int>::iterator constIter =
01799                         defaultSelect.begin(); constIter != defaultSelect.end();
01800                         ++ constIter){
01801                     latchEnableTerms.push_back(*constIter);
01802                     muxDataValid[*constIter] = false;
01803                 }
01804             }else{
01805                 // mux term
01806                 for(vector<int>::iterator constIter =
01807                         defaultSelect.begin(); constIter != defaultSelect.end();
01808                         ++ constIter){
01809                     muxData[*constIter] =
01810                         defaultAction->nonblockingAssignments[*bitIter];
01811                     muxDataValid[*constIter] = true;
01812                 }
01813             }
01814         }
01815 
01816         MultiRefBus muxDataList;
01817         for(int i=0;i<selectMax;i++){
01818             if(muxDataValid[i]) muxDataList.push_back(muxData[i]);
01819         }
01820 
01821         if(latchEnableTerms.empty()){
01822             // a single MUX is ok to implement this assignment in this CASE statement
01823             oa::oaString str;
01824             (*bitIter)->getName(*nameSpace, str);
01825             DEBUG_PRINTLN("\t\t\t "<< str << " = case_mux" );
01826             state.nonblockingAssignments[*bitIter] = mux(condition, muxDataList);
01827         }else{
01828 
01829             // In case there is a latch, the latch's enable is feed by a mux
01830             // whose input data and selection bits are from a pre-calculated
01831             // table and the condition of the CASE statement, respectively.
01832             // The latch's data signal is feed by the mux inferred by the CASE
01833             // statement.
01834 
01835             oa::oaString str;
01836             (*bitIter)->getName(*nameSpace, str);
01837             cerr << "NOTE: Implicit latch on net " <<
01838                 currentVmodule->name << "." << str << endl;
01839             vector<MultiRef> latchEnableBitMap(selectMax);
01840             for(int i=0;i<selectMax;i++)
01841                 latchEnableBitMap[i] = constantOne();
01842             for(vector<int>::iterator latchTermIter = latchEnableTerms.begin();
01843                     latchTermIter != latchEnableTerms.end(); ++ latchTermIter)
01844                 latchEnableBitMap[*latchTermIter] = constantZero();
01845             // create a MUX for the assignment in the CASE branch condition
01846             MultiRef combinationalOutput = mux(condition, muxDataList);
01847             // conver the vector the MultiRefBus
01848             MultiRefBus latchEnableBitMapList;
01849             back_insert_iterator<MultiRefBus > latchEnableBIIter(latchEnableBitMapList);
01850             copy(latchEnableBitMap.begin(), latchEnableBitMap.end(), latchEnableBIIter);
01851             // create a MUX for generating enable bit of the latch
01852             MultiRef latchEnableBit = mux(condition, latchEnableBitMapList);
01853             // create the latch
01854             state.blockingAssignments[*bitIter] = latch(latchEnableBit, 
01855                     combinationalOutput);
01856  
01857         }
01858     }
01859 
01860     // free memory
01861     for(list<ProceduralState *>::iterator actionIter =
01862             caseActions.begin(); actionIter != caseActions.end(); ++
01863             actionIter) {
01864         delete (*actionIter);
01865     }
01866 
01867     return true;
01868 }
01869 
01870 // *****************************************************************************
01871 // synthesizeCase()
01872 //
01874 //
01875 // *****************************************************************************
01876 void
01877 VerilogSynthesis::synthesizeCase(VerilogDesign::Statement *statement,
01878                                                ProceduralState &state,
01879                                                ParameterValues *parameters)
01880 {
01881     DEBUG_PRINTLN("\t\t case");
01882 
01883     // 1. compute condition
01884     MultiRefBus condition;
01885     evaluateExpression(condition, statement->ifc.condition, &state,
01886             parameters);
01887     list<ProceduralState*>  caseActions;
01888     MultiRefBus             caseSelects;
01889     set<oa::oaModBitNet*>   modifiedBlockingAssignments,
01890         modifiednonblockingAssignments;
01891     ProceduralState         *defaultAction = NULL;
01892     MultiRef                defaultSelect = constantZero();
01893 
01894     // 2. compute the procedural state for each case
01895     // 3. compute the select lines for each case
01896     for(list<VerilogDesign::Case*>::iterator caseIter =
01897             statement->ifc.cases->begin(); caseIter !=
01898             statement->ifc.cases->end(); ++ caseIter) {
01899 
01900         VerilogDesign::Case *c = *caseIter;
01901         assert(c);
01902 
01903         ProceduralState *action = NULL;
01904 
01905         if(c->isDefault) {
01906             // this is the default case
01907             DEBUG_PRINTLN("\t\t default case");
01908 
01909             if(defaultAction != NULL) {
01910                 cerr << "ERROR: Multiple default cases" << endl;
01911                 QUIT_ON_ERROR;
01912             }
01913 
01914             action = new ProceduralState(state);
01915             synthesizeBehavioral(c->action, *action, parameters);
01916             defaultAction = action;
01917         } else {
01918             // not a default case
01919             DEBUG_PRINTLN("\t\t case label conditions=" <<
01920                     c->conditions->size());
01921 
01922             // For each CASE, there could be multiple conditions.
01923             // The selective bit (select) which satisfies this CASE
01924             // should satisfy any of those conditions.
01925             // 
01926             // E.g., 
01927             // case A:
01928             // case B:
01929             // case C:
01930             //      action() {/* action for A or B or C */}
01931             //      break;
01932             // Therefore, select = A or B or C
01933 
01934             MultiRef select = constantZero();
01935             bool onePossiblyTrueCase = false;
01936             for(list<VerilogDesign::Expression*>::iterator condIter =
01937                     c->conditions->begin(); condIter !=
01938                     c->conditions->end(); ++ condIter) {
01939 
01940                 MultiRefBus caseCondition;
01941                 VerilogDesign::Expression *condExpr = *condIter;
01942                 evaluateExpression(caseCondition, condExpr, &state,
01943                         parameters);
01944                 zeroExpand(condition, caseCondition);
01945                 MultiRef caseMatchesCondition;
01946 
01947                 if(isConstantExpression(condExpr, parameters) &&
01948                         isConstantExpression(statement->ifc.condition,
01949                             parameters)) {
01950                     // both case condition and case branch are constant
01951                     ConstantValue caseConstant, conditionConstant;
01952                     evaluateConstantExpression(caseConstant, condExpr,
01953                             parameters);
01954                     evaluateConstantExpression(conditionConstant,
01955                             statement->ifc.condition, parameters);
01956                     if(caseConstant.intValue ==
01957                             conditionConstant.intValue) {
01958                         caseMatchesCondition = constantOne();
01959                         DEBUG_PRINTLN("\t\t\t\t case always true");
01960                         onePossiblyTrueCase = true;
01961                     } else {
01962                         caseMatchesCondition = constantZero();
01963                         DEBUG_PRINTLN("\t\t\t\t case always false"); 
01964                     }
01965                 } else if (statement->type ==
01966                         VerilogDesign::Statement::CASEX) {
01967                     // YH: UNIMPLEMENTED yet
01968                     cerr << "ERROR: CASEX is unimplemented yet ... " 
01969                         << endl;
01970                     QUIT_ON_ERROR;
01971                 } else if (statement->type ==
01972                         VerilogDesign::Statement::CASEZ) {
01973                     // YH: UNIMPLEMENTED yet
01974                     cerr << "ERROR: CASEZ is unimplemented yet ... " 
01975                         << endl;
01976                     QUIT_ON_ERROR;
01977                 } else {
01978                     onePossiblyTrueCase = true;
01979                     caseMatchesCondition = equalTo(caseCondition,
01980                             condition);
01981                 }
01982 
01983                 select = orOf(select, caseMatchesCondition);
01984 
01985             } // end of loop for all conditions of the current CASE
01986 
01987             if (onePossiblyTrueCase) {
01988                 caseSelects.push_back(select);
01989                 if (action == NULL) {
01990                     action = new ProceduralState(state);
01991                     synthesizeBehavioral(c->action, *action,
01992                             parameters);
01993                 }
01994                 caseActions.push_back(action);
01995             }
01996             // collect the complement of the defaultSelect bit, 
01997             // i.e., defaultSelect = !(case1 or case2 or case3 or ...)
01998             defaultSelect = orOf(defaultSelect, select);
01999 
02000         } // end of else (not a default case)
02001 
02002         // identify the nets that have been modified
02003         if(action != NULL) {
02004             for(map<oa::oaModBitNet*, MultiRef>::iterator
02005                     postActionAssignment =
02006                     action->blockingAssignments.begin();
02007                     postActionAssignment !=
02008                     action->blockingAssignments.end();
02009                     ++postActionAssignment) {
02010 
02011                 map<oa::oaModBitNet*, MultiRef>::iterator
02012                     preActionAssignment =
02013                     state.blockingAssignments.find(postActionAssignment->first); 
02014                 // either the net hadn't been assigned before, or it was
02015                 // assigned to something different?
02016                 if(preActionAssignment ==
02017                         state.blockingAssignments.end() ||
02018                         !(postActionAssignment->second ==
02019                             preActionAssignment->second)) {
02020                     modifiedBlockingAssignments.insert(postActionAssignment->first);
02021                 }
02022             }
02023             for(map<oa::oaModBitNet*, MultiRef>::iterator
02024                     postActionAssignment =
02025                     action->nonblockingAssignments.begin();
02026                     postActionAssignment !=
02027                     action->nonblockingAssignments.end(); ++
02028                     postActionAssignment) {
02029                 map<oa::oaModBitNet*, MultiRef>::iterator
02030                     preActionAssignment =
02031                     state.nonblockingAssignments.find(postActionAssignment->first);
02032                 // either the net hadn't been assigned before, or it was
02033                 // assigned to something different?
02034                 if(preActionAssignment ==
02035                         state.nonblockingAssignments.end() ||
02036                         !(postActionAssignment->second ==
02037                             preActionAssignment->second)) {
02038                     modifiednonblockingAssignments.insert(postActionAssignment->first);
02039                 }
02040 
02041             }
02042         }
02043 
02044     } // end of loop for each CASE
02045 
02046     // calculate the real defaultSelect bit by performing complement
02047     defaultSelect = notOf(defaultSelect);
02048 
02049     // 4. for each set variable, build n-way mux.
02050     // 5. also compute the case where the value is nextState
02051 
02052     for(set<oa::oaModBitNet*>::iterator bitIter =
02053             modifiedBlockingAssignments.begin(); bitIter !=
02054             modifiedBlockingAssignments.end(); ++ bitIter) {
02055         MultiRefBus                 muxTerms;
02056         MultiRefBus                 latchTerms;
02057 
02058         MultiRefBus::iterator       selectsIter = caseSelects.begin();
02059         list<ProceduralState*>::iterator actionIter = 
02060             caseActions.begin();
02061 
02062         while(selectsIter != caseSelects.end() && actionIter !=
02063                 caseActions.end()) {
02064             if((*actionIter)->blockingAssignments.find(*bitIter) ==
02065                     (*actionIter)->blockingAssignments.end()){
02066                 // implicit latch
02067                 latchTerms.push_back(*selectsIter);
02068             }else {
02069                 // mux term
02070                 muxTerms.push_back(andOf(*selectsIter,
02071                             (*actionIter)->blockingAssignments[*bitIter]));
02072             }
02073 
02074             ++ selectsIter; ++ actionIter;
02075         }
02076 
02077         // handle default case, if it exists
02078         if(defaultAction != NULL) {
02079             if(defaultAction->blockingAssignments.find(*bitIter) ==
02080                     defaultAction->blockingAssignments.end()) {
02081                 // implicit latch
02082                 latchTerms.push_back(defaultSelect);
02083             }else{
02084                 // mux term
02085                 muxTerms.push_back(andOf(defaultSelect,
02086                             defaultAction->blockingAssignments[*bitIter]));
02087             }
02088         }
02089 
02090         if(latchTerms.empty()){
02091             oa::oaString str;
02092             (*bitIter)->getName(*nameSpace, str);
02093             DEBUG_PRINTLN("\t\t\t "<< str << " = case_mux" );
02094 
02095             state.blockingAssignments[*bitIter] = reductionOr(muxTerms);
02096         }else{
02097             // 05/08/2007 04:49pm
02098             oa::oaString str;
02099             (*bitIter)->getName(*nameSpace, str);
02100             cerr << "NOTE: Implicit latch on net " <<
02101                 currentVmodule->name << "." << str << endl;
02102             state.blockingAssignments[*bitIter] =
02103                 latch(reductionOr(latchTerms), reductionOr(muxTerms));
02104         }
02105     }
02106 
02107     for(set<oa::oaModBitNet*>::iterator bitIter =
02108             modifiednonblockingAssignments.begin(); bitIter !=
02109             modifiednonblockingAssignments.end(); ++ bitIter) {
02110         MultiRefBus                 muxTerms;
02111         MultiRefBus                 latchTerms;
02112 
02113         MultiRefBus::iterator       selectsIter = caseSelects.begin();
02114         list<ProceduralState*>::iterator actionIter = 
02115             caseActions.begin();
02116 
02117         while(selectsIter != caseSelects.end() && actionIter !=
02118                 caseActions.end()) {
02119             if((*actionIter)->nonblockingAssignments.find(*bitIter) ==
02120                     (*actionIter)->nonblockingAssignments.end()){
02121                 // implicit latch
02122                 latchTerms.push_back(*selectsIter);
02123             }else {
02124                 // mux term
02125                 muxTerms.push_back(andOf(*selectsIter,
02126                             (*actionIter)->nonblockingAssignments[*bitIter]));
02127             }
02128 
02129             ++ selectsIter; ++ actionIter;
02130         }
02131 
02132         // handle default case, if it exists
02133         if(defaultAction != NULL) {
02134             if(defaultAction->nonblockingAssignments.find(*bitIter) ==
02135                     defaultAction->nonblockingAssignments.end()) {
02136                 // implicit latch
02137                 latchTerms.push_back(defaultSelect);
02138             }else{
02139                 // mux term
02140                 muxTerms.push_back(andOf(defaultSelect,
02141                             defaultAction->nonblockingAssignments[*bitIter]));
02142             }
02143         }
02144 
02145         if(latchTerms.empty()){
02146             oa::oaString str;
02147             (*bitIter)->getName(*nameSpace, str);
02148             DEBUG_PRINTLN("\t\t\t "<< str << " = case_mux" );
02149 
02150             state.nonblockingAssignments[*bitIter] = reductionOr(muxTerms);
02151         }else{
02152             // 05/08/2007 04:49pm
02153             oa::oaString str;
02154             (*bitIter)->getName(*nameSpace, str);
02155             cerr << "NOTE: Implicit latch on net " <<
02156                 currentVmodule->name << "." << str << endl;
02157             state.nonblockingAssignments[*bitIter] =
02158                 latch(reductionOr(latchTerms), reductionOr(muxTerms));
02159         }
02160     }
02161 
02162     // free memory
02163     for(list<ProceduralState *>::iterator actionIter =
02164             caseActions.begin(); actionIter != caseActions.end(); ++
02165             actionIter) {
02166         delete (*actionIter);
02167     }
02168 
02169 }
02170 
02171 // *****************************************************************************
02172 // synthesizeBlockingassignment()
02173 //
02175 //
02176 // *****************************************************************************
02177 void
02178 VerilogSynthesis::synthesizeBlockingassignment(VerilogDesign::Statement *statement,
02179                                                ProceduralState &state,
02180                                                ParameterValues *parameters)
02181 {
02182     LvalRefBus lval;
02183     MultiRefBus rval;
02184     evaluateLval(lval, statement->assign.lval, &state, parameters);
02185     evaluateExpression(rval, statement->assign.rval, &state,
02186             parameters);
02187 
02188     // YH: why use reverse order for the assignment??
02189     LvalRefBus::reverse_iterator leftIter = lval.rbegin();
02190     MultiRefBus::reverse_iterator rightIter = rval.rbegin();
02191     while(leftIter != lval.rend()){
02192         MultiRef value;
02193         if(rightIter == rval.rend()) {
02194             value = constantZero();
02195         }else{
02196             value = *rightIter;
02197             ++ rightIter;
02198         }
02199 
02200         if ((*leftIter)->type == VerilogSynthesis::LVAL_UNCONDITIONAL) {
02201             // unconditional assignment
02202 
02203             oa::oaModBitNet *net = (*leftIter)->unconditionalLval;
02204             state.blockingAssignments[net] = value;
02205 
02206             oa::oaString str, str2;
02207             net->getName(*nameSpace, str);
02208 
02209             if(state.blockingAssignments[net].type == NET) {
02210                 oa::oaString str;
02211                 state.blockingAssignments[net].net->getName(*nameSpace,
02212                         str2);
02213                 DEBUG_PRINTLN("\t\t\t " << str << " = " << str2);
02214             }else{
02215                 DEBUG_PRINTLN("\t\t\t " << str << " = (func)");
02216             }
02217         } else if ((*leftIter)->type == LVAL_CONDITIONAL) {
02218             // conditional assignment
02219 
02220             DEBUG_PRINTLN("\t\t\t" << "LVAL_CONDITIONAL occurs!!");
02221             QUIT_ON_INTERNAL_ERROR;
02222 
02223             /*
02224             for(list<ConditionalLvalRef>::iterator condIter =
02225                     (*leftIter)->conditionalLval.begin(); condIter !=
02226                     (*leftIter)->conditionalLval.end(); ++ condIter){
02227                 if(state.blockingAssignments.find(condIter->lval) !=
02228                         state.blockingAssignments.end()) {
02229 
02230                     // YH: can't quite understand what's the case here
02231                     // for left-hand assignment??
02232                     // combinational
02233                     state.blockingAssignments[condIter->lval] =
02234                         mux(condIter->condition,
02235                                 state.blockingAssignments[condIter->lval],
02236                                value);
02237 
02238                }else if (state.isRegister){
02239                    // mux previous state
02240                    state.blockingAssignments[condIter->lval] =
02241                        mux(condIter->condition,
02242                                MultiRef(condIter->lval), value);
02243                }else{
02244                    // implicit latch... transparent when condition
02245                    state.blockingAssignments[condIter->lval] =
02246                        latch(condIter->condition, value);
02247                    oa::oaString str;
02248                    condIter->lval->getName(*nameSpace, str);
02249                    cerr << "NOTE: Implicit latch on net " <<
02250                        currentVmodule->name << "." << str << endl;
02251                }
02252                }
02253              */
02254             DEBUG_PRINTLN("\t\t\t (mux) <= (func)");
02255         } else if ((*leftIter)->type == LVAL_FUNCTION) {
02256             assert(state.isFunction);
02257             state.functionAssignments[(*leftIter)->functionLvalName][(*leftIter)->functionLvalBit]
02258                 = value;
02259             DEBUG_PRINTLN("\t\t\t " << (*leftIter)->functionLvalName 
02260                     << " <= (func)");
02261         } else {
02262             QUIT_ON_INTERNAL_ERROR;
02263         }
02264 
02265         ++ leftIter;
02266     }
02267 
02268 }
02269 
02270 // *****************************************************************************
02271 // synthesizeNonblockingassignment()
02272 //
02274 //
02275 // *****************************************************************************
02276 void
02277 VerilogSynthesis::synthesizeNonblockingassignment(VerilogDesign::Statement *statement,
02278                                                ProceduralState &state,
02279                                                ParameterValues *parameters)
02280 {
02281     LvalRefBus lval;
02282     MultiRefBus rval;
02283     evaluateLval(lval, statement->assign.lval, &state, parameters);
02284     evaluateExpression(rval, statement->assign.rval, &state,
02285             parameters);
02286 
02287     // YH: why use reverse order for the assignment??
02288     LvalRefBus::reverse_iterator leftIter = lval.rbegin();
02289     MultiRefBus::reverse_iterator rightIter = rval.rbegin();
02290     while(leftIter != lval.rend()){
02291         MultiRef value;
02292         if(rightIter == rval.rend()) {
02293             value = constantZero();
02294         }else{
02295             value = *rightIter;
02296             ++ rightIter;
02297         }
02298 
02299         if ((*leftIter)->type == VerilogSynthesis::LVAL_UNCONDITIONAL) {
02300             // unconditional assignment
02301 
02302             oa::oaModBitNet *net = (*leftIter)->unconditionalLval;
02303             state.nonblockingAssignments[net] = value;
02304 
02305             oa::oaString str;
02306             net->getName(*nameSpace, str);
02307             if(state.nonblockingAssignments[net].type == NET) {
02308                 oa::oaString str, str2;
02309                 state.nonblockingAssignments[net].net->getName(*nameSpace,
02310                         str2);
02311                 DEBUG_PRINTLN("\t\t\t " << str << " = " << str2);
02312             }else{
02313                 DEBUG_PRINTLN("\t\t\t " << str << " = (func)");
02314             }
02315         } else if ((*leftIter)->type == LVAL_CONDITIONAL) {
02316             // conditional assignment
02317 
02318             DEBUG_PRINTLN("\t\t\t" << "LVAL_CONDITIONAL occurs!!");
02319             QUIT_ON_INTERNAL_ERROR;
02320 
02321             /*
02322             for(list<ConditionalLvalRef>::iterator condIter =
02323                     (*leftIter)->conditionalLval.begin(); condIter !=
02324                     (*leftIter)->conditionalLval.end(); ++ condIter){
02325                 if(state.nonblockingAssignments.find(condIter->lval) !=
02326                         state.nonblockingAssignments.end()) {
02327                     // combinational
02328                     state.nonblockingAssignments[condIter->lval] =
02329                         mux(condIter->condition,
02330                                 state.nonblockingAssignments[condIter->lval],
02331                                 value);
02332                 }else if (state.isRegister){
02333                     // mux previous state
02334                     state.nonblockingAssignments[condIter->lval] =
02335                         mux(condIter->condition,
02336                                 MultiRef(condIter->lval), value);
02337                 }else{
02338                     // implicit latch... transparent when condition
02339                     state.nonblockingAssignments[condIter->lval] =
02340                         latch(condIter->condition, value);
02341                     oa::oaString str;
02342                     condIter->lval->getName(*nameSpace, str);
02343                     cerr << "NOTE: Implicit latch on net " <<
02344                         currentVmodule->name << "." << str << endl;
02345                 }
02346             }
02347             DEBUG_PRINTLN("\t\t\t (mux) <= (func)");
02348              */
02349         } else if ((*leftIter)->type == LVAL_FUNCTION) {
02350             cerr << "ERROR: Non-blocking assignments are not supported \
02351                 inside functions" << endl;
02352             QUIT_ON_ERROR;
02353         } else {
02354             QUIT_ON_INTERNAL_ERROR;
02355         }
02356         ++ leftIter;
02357     }
02358 
02359 }
02360 
02361 // *****************************************************************************
02362 // synthesizeBehavioral()
02363 //
02365 //
02366 // *****************************************************************************
02367 void
02368 VerilogSynthesis::synthesizeBehavioral(VerilogDesign::Statement *statement,
02369                                                ProceduralState &state,
02370                                                ParameterValues *parameters)
02371 {
02372     assert(nameSpace);
02373     assert(statement);
02374 
02375     switch(statement->type) {
02376 
02377         case VerilogDesign::Statement::NOP: 
02378             break;
02379 
02380         case VerilogDesign::Statement::BLOCK:
02381             synthesizeBlock(statement, state, parameters);
02382             break;
02383 
02384         case VerilogDesign::Statement::IF: 
02385         {
02386             synthesizeIf(statement, state, parameters);
02387             break;
02388         } // end of case VerilogDesign::Statement::IF
02389 
02390         case VerilogDesign::Statement::CASEZ:
02391         case VerilogDesign::Statement::CASEX:
02392         case VerilogDesign::Statement::CASE: 
02393         {
02394             if(!synthesizeCaseEasy(statement, state, parameters))
02395                 synthesizeCase(statement, state, parameters);
02396             break;
02397         } // end of case VerilogDesign::Statement::CASE
02398 
02399         case VerilogDesign::Statement::BLOCKING_ASSIGNMENT: 
02400         {
02401             synthesizeBlockingassignment(statement, state, parameters);            
02402             break;
02403         } // end of case VerilogDesign::Statement::BLOCKING_ASSIGNMENT
02404 
02405         case VerilogDesign::Statement::NONBLOCKING_ASSIGNMENT: 
02406         {
02407             synthesizeNonblockingassignment(statement, state, parameters);
02408             break;
02409         } // end of case VerilogDesign::Statement::BLOCKING_ASSIGNMENT
02410 
02411         default:
02412             QUIT_ON_INTERNAL_ERROR;
02413     }
02414 }
02415 
02416 // *****************************************************************************
02417 // evaluateConstantExpression()
02418 //
02420 //
02422 //
02423 // *****************************************************************************
02424 void
02425 VerilogSynthesis::evaluateConstantExpression(ConstantValue &result,
02426         VerilogDesign::Expression *expression,
02427         ParameterValues *parameters) 
02428 {
02429     assert(expression);
02430 
02431     ConstantValue c1, c2, c3;
02432     switch(expression->type) {
02433     
02434       case VerilogDesign::Expression::PRIMARY:
02435       
02436         if (expression->primary->type == VerilogDesign::Primary::CONST) {
02437             result.intValue = expression->primary->number.intValue;
02438             result.bitWidth = expression->primary->number.bitWidth;
02439         } else if (expression->primary->type == VerilogDesign::Primary::NET) {
02440             ParameterValues::iterator it;
02441             if ((it = parameters->find(expression->primary->name)) == parameters->end()) {
02442                 cerr << "ERROR: Unknown parameter " << expression->primary->name << endl;
02443                 QUIT_ON_ERROR;
02444             }
02445             result = it->second;
02446         } else if (expression->primary->type == VerilogDesign::Primary::FUNCTION_CALL) {
02447             cerr << "ERROR: Function calls are not supported in constant expressions" 
02448                 << endl;
02449             QUIT_ON_ERROR;
02450         } else {
02451             QUIT_ON_INTERNAL_ERROR;
02452         }
02453       break;
02454       
02455       case VerilogDesign::Expression::BUNDLE:
02456 
02457         // bundle may be replicated
02458         ConstantValue replication;
02459         
02460         if (expression->bundle->replication == NULL) {
02461             replication.intValue = 1;
02462         } else {
02463             evaluateConstantExpression(replication, expression->bundle->replication, 
02464                     parameters);
02465     
02466             if (replication.intValue != 1) {
02467                 cerr << "ERROR: Bundle replication not supported \
02468                     in constant expressions" << endl;
02469                 QUIT_ON_ERROR;
02470             }
02471         }
02472 
02473         result.intValue = 0;
02474         result.bitWidth = 0;
02475         for(list<VerilogDesign::Expression*>::iterator 
02476                 exprIter = expression->bundle->members->begin();
02477                 exprIter != expression->bundle->members->end(); 
02478                 ++exprIter) {
02479             ConstantValue partial;
02480             evaluateConstantExpression(partial, *exprIter, parameters);
02481             result.intValue = (result.intValue << partial.bitWidth) + partial.intValue;
02482             result.bitWidth += partial.bitWidth;
02483         }
02484             
02485         DEBUG_PRINTLN("\t\t bundle [" << result.bitWidth << 
02486                 "] replication= " << replication.intValue);
02487         break;
02488         
02489       case VerilogDesign::Expression::ADD:
02490         evaluateConstantExpression(c1, expression->op1, parameters);
02491         evaluateConstantExpression(c2, expression->op2, parameters);
02492         result.intValue = c1.intValue + c2.intValue;
02493         result.bitWidth = max(c1.bitWidth, c2.bitWidth)+1;
02494       break;
02495       case VerilogDesign::Expression::SUBTRACT:
02496         evaluateConstantExpression(c1, expression->op1, parameters);
02497         evaluateConstantExpression(c2, expression->op2, parameters);
02498         result.intValue = c1.intValue - c2.intValue;
02499         result.bitWidth = max(c1.bitWidth, c2.bitWidth);
02500       break;
02501       case VerilogDesign::Expression::MULTIPLY:
02502         evaluateConstantExpression(c1, expression->op1, parameters);
02503         evaluateConstantExpression(c2, expression->op2, parameters);
02504         result.intValue = c1.intValue * c2.intValue;
02505         result.bitWidth = c1.bitWidth+c2.bitWidth;
02506       break;
02507       case VerilogDesign::Expression::DIVIDE:
02508         evaluateConstantExpression(c1, expression->op1, parameters);
02509         evaluateConstantExpression(c2, expression->op2, parameters);
02510         result.intValue = c1.intValue / c2.intValue;
02511         result.bitWidth = c1.bitWidth;
02512       break;
02513       case VerilogDesign::Expression::MODULO:
02514         evaluateConstantExpression(c1, expression->op1, parameters);
02515         evaluateConstantExpression(c2, expression->op2, parameters);
02516         result.intValue = c1.intValue % c2.intValue;
02517         result.bitWidth = c2.bitWidth;
02518       break;
02519       case VerilogDesign::Expression::BITWISE_AND:
02520         evaluateConstantExpression(c1, expression->op1, parameters);
02521         evaluateConstantExpression(c2, expression->op2, parameters);
02522         result.intValue = c1.intValue & c2.intValue;
02523         result.bitWidth = max(c1.bitWidth, c2.bitWidth);
02524       break;
02525       case VerilogDesign::Expression::BITWISE_NOT:
02526         evaluateConstantExpression(c1, expression->op1, parameters);
02527         result.intValue = (~c1.intValue);
02528         result.bitWidth = c1.bitWidth;
02529       break;
02530       case VerilogDesign::Expression::BITWISE_OR:
02531         evaluateConstantExpression(c1, expression->op1, parameters);
02532         evaluateConstantExpression(c2, expression->op2, parameters);
02533         result.intValue = c1.intValue | c2.intValue;
02534         result.bitWidth = max(c1.bitWidth, c2.bitWidth);
02535       break;
02536       case VerilogDesign::Expression::BITWISE_XOR:
02537         evaluateConstantExpression(c1, expression->op1, parameters);
02538         evaluateConstantExpression(c2, expression->op2, parameters);
02539         result.intValue = c1.intValue ^ c2.intValue;
02540         result.bitWidth = max(c1.bitWidth, c2.bitWidth);
02541       break;
02542       case VerilogDesign::Expression::LEFT_SHIFT:
02543         evaluateConstantExpression(c1, expression->op1, parameters);
02544         evaluateConstantExpression(c2, expression->op2, parameters);
02545         result.intValue = c1.intValue << c2.intValue;
02546         result.bitWidth = c1.bitWidth + c2.intValue;
02547       break;
02548       case VerilogDesign::Expression::RIGHT_SHIFT:
02549         evaluateConstantExpression(c1, expression->op1, parameters);
02550         evaluateConstantExpression(c2, expression->op2, parameters);
02551         result.intValue = c1.intValue >> c2.intValue;
02552         result.bitWidth = c1.bitWidth;
02553       break;
02554       case VerilogDesign::Expression::GREATER_THAN:
02555         evaluateConstantExpression(c1, expression->op1, parameters);
02556         evaluateConstantExpression(c2, expression->op2, parameters);
02557         result.intValue = (c1.intValue > c2.intValue ? 1 : 0);
02558         result.bitWidth = 1;
02559       break;
02560       case VerilogDesign::Expression::LESS_THAN:
02561         evaluateConstantExpression(c1, expression->op1, parameters);
02562         evaluateConstantExpression(c2, expression->op2, parameters);
02563         result.intValue = (c1.intValue < c2.intValue ? 1 : 0);
02564         result.bitWidth = 1;
02565       break;
02566       case VerilogDesign::Expression::GREATER_THAN_EQUAL:
02567         evaluateConstantExpression(c1, expression->op1, parameters);
02568         evaluateConstantExpression(c2, expression->op2, parameters);
02569         result.intValue = (c1.intValue >= c2.intValue ? 1 : 0);
02570         result.bitWidth = 1;
02571       break;
02572       case VerilogDesign::Expression::LESS_THAN_EQUAL:
02573         evaluateConstantExpression(c1, expression->op1, parameters);
02574         evaluateConstantExpression(c2, expression->op2, parameters);
02575         result.intValue = (c1.intValue <= c2.intValue ? 1 : 0);
02576         result.bitWidth = 1;
02577       break;
02578       case VerilogDesign::Expression::EQUAL:
02579         evaluateConstantExpression(c1, expression->op1, parameters);
02580         evaluateConstantExpression(c2, expression->op2, parameters);
02581         result.intValue = (c1.intValue == c2.intValue ? 1 : 0);
02582         result.bitWidth = 1;
02583       break;
02584       case VerilogDesign::Expression::NOTEQUAL:
02585         evaluateConstantExpression(c1, expression->op1, parameters);
02586         evaluateConstantExpression(c2, expression->op2, parameters);
02587         result.intValue = (c1.intValue != c2.intValue ? 1 : 0);
02588         result.bitWidth = 1;
02589       break;
02590       case VerilogDesign::Expression::LOGICAL_AND:
02591         evaluateConstantExpression(c1, expression->op1, parameters);
02592         evaluateConstantExpression(c2, expression->op2, parameters);
02593         result.intValue = (c1.intValue != 0 && c2.intValue != 0 ? 1 : 0);
02594         result.bitWidth = 1;
02595       break;
02596       case VerilogDesign::Expression::LOGICAL_OR:
02597         evaluateConstantExpression(c1, expression->op1, parameters);
02598         evaluateConstantExpression(c2, expression->op2, parameters);
02599         result.intValue = (c1.intValue != 0 || c2.intValue != 0 ? 1 : 0);
02600         result.bitWidth = 1;
02601       break;
02602       case VerilogDesign::Expression::LOGICAL_NOT:
02603         evaluateConstantExpression(c1, expression->op1, parameters);
02604         evaluateConstantExpression(c2, expression->op2, parameters);
02605         result.intValue = (c1.intValue == 0 ? 1 : 0);
02606         result.bitWidth = 1;
02607       break;
02608       case VerilogDesign::Expression::IF_ELSE:
02609         evaluateConstantExpression(c1, expression->op1, parameters);
02610         evaluateConstantExpression(c2, expression->op2, parameters);
02611         evaluateConstantExpression(c3, expression->op3, parameters);
02612         if (c1.intValue != 0) {
02613             result.intValue = c2.intValue;
02614             result.bitWidth = c2.bitWidth;
02615         } else {
02616             result.intValue = c3.intValue;
02617             result.bitWidth = c3.bitWidth;
02618         }
02619       break;
02620       default:
02621         cerr << "ERROR: Invalid operator in constant expression: " << 
02622             expression->type << endl;
02623         break;
02624     }
02625 
02626 }
02627 
02628 // *****************************************************************************
02629 // isConstantExpression()
02630 //
02638 //
02639 // *****************************************************************************
02640 bool
02641 VerilogSynthesis::isConstantExpression(VerilogDesign::Expression *expression,
02642                                                ParameterValues *parameters) 
02643 {
02644     assert(expression);
02645     switch(expression->type) {
02646     
02647       case VerilogDesign::Expression::PRIMARY:
02648         if (expression->primary->type == VerilogDesign::Primary::CONST) {
02649             return true;
02650         } if (expression->primary->type == VerilogDesign::Primary::NET) {
02651             ParameterValues::iterator it;
02652             if ((it = parameters->find(expression->primary->name)) == 
02653                     parameters->end()) {
02654                 return false;
02655             }
02656             return true;
02657         } else {
02658             return false;
02659         }
02660       case VerilogDesign::Expression::BUNDLE:
02661         for(list<VerilogDesign::Expression*>::iterator 
02662                 exprIter = expression->bundle->members->begin();
02663                 exprIter != expression->bundle->members->end(); 
02664                 ++exprIter) {
02665             if (!isConstantExpression(*exprIter, parameters)) {
02666                 return false;
02667             }
02668         }
02669         return true;
02670       case VerilogDesign::Expression::BITWISE_NOT:
02671       case VerilogDesign::Expression::LOGICAL_NOT:
02672         return isConstantExpression(expression->op1, parameters);
02673       case VerilogDesign::Expression::ADD:
02674       case VerilogDesign::Expression::SUBTRACT:
02675       case VerilogDesign::Expression::MULTIPLY:
02676       case VerilogDesign::Expression::DIVIDE:
02677       case VerilogDesign::Expression::MODULO:
02678       case VerilogDesign::Expression::BITWISE_AND:
02679       case VerilogDesign::Expression::BITWISE_OR:
02680       case VerilogDesign::Expression::BITWISE_XOR:
02681       case VerilogDesign::Expression::LEFT_SHIFT:
02682       case VerilogDesign::Expression::RIGHT_SHIFT:
02683       case VerilogDesign::Expression::LESS_THAN:
02684       case VerilogDesign::Expression::GREATER_THAN:
02685       case VerilogDesign::Expression::LESS_THAN_EQUAL:
02686       case VerilogDesign::Expression::GREATER_THAN_EQUAL:
02687       case VerilogDesign::Expression::LOGICAL_AND:
02688       case VerilogDesign::Expression::LOGICAL_OR:
02689       case VerilogDesign::Expression::EQUAL:
02690       case VerilogDesign::Expression::NOTEQUAL:
02691         return isConstantExpression(expression->op1, parameters) && 
02692                isConstantExpression(expression->op2, parameters);
02693       case VerilogDesign::Expression::IF_ELSE:
02694         return isConstantExpression(expression->op1, parameters) && 
02695                isConstantExpression(expression->op2, parameters) && 
02696                isConstantExpression(expression->op3, parameters);
02697       default:
02698         return false;
02699     }
02700 
02701 }
02702 
02703 // *****************************************************************************
02704 // evaluateLval()
02705 //
02707 //
02708 // *****************************************************************************
02709 void
02710 VerilogSynthesis::evaluateLval(LvalRefBus &result, 
02711         VerilogDesign::Expression *expression, 
02712         ProceduralState *state, 
02713         ParameterValues *parameters) 
02714 {
02715     assert(expression);
02716     result.clear();
02717 
02718     MultiRefBus op1, op3;
02719     switch(expression->type) {
02720     
02721       case VerilogDesign::Expression::PRIMARY: {
02722         
02723         // is this a numerical constant?
02724         if (expression->primary->type == VerilogDesign::Primary::CONST) {
02725                 cerr << "ERROR: Lval can not be a constant" << endl;
02726                 QUIT_ON_ERROR;
02727 
02728         } else if (expression->primary->type == VerilogDesign::Primary::NET) {
02729         
02730             // is this a parameter?
02731             ParameterValues::iterator it;
02732             if ((it = parameters->find(expression->primary->name)) != parameters->end()) {
02733                 cerr << "ERROR: Lval can not be a parameter" << endl;
02734                 QUIT_ON_ERROR;
02735             }
02736 
02737             // is this in the context of a function?
02738             else if (state && state->isFunction) {
02739                 cerr << "ERROR: function is not supported so far" << endl;
02740                 QUIT_ON_ERROR;
02741                 /*
02742                 
02743                 // YH: TODO: look back to handle function synthesis
02744 
02745                 map<string, FunctionVariableAssignment>::iterator it = 
02746                   state->functionAssignments.find(expression->primary->name);
02747                 if (it == state->functionAssignments.end()) {
02748                     cerr << "ERROR: Unknown net: " << expression->primary->name << endl;
02749                     QUIT_ON_ERROR;
02750                 }
02751                 
02752                 FunctionVariableAssignment bitAssignments = it->second;
02753                 if (expression->primary->range.start == NULL) {
02754                     for(int b=bitAssignments.start; 
02755                         (bitAssignments.start<bitAssignments.stop ? b<=bitAssignments.stop : b>=bitAssignments.stop); 
02756                         b+=(bitAssignments.start<bitAssignments.stop?1:-1)) {
02757                         result.push_back(new LvalRef(expression->primary->name, b));
02758                     }
02759                 } else {
02760                     
02761                     if (!isConstantExpression(expression->primary->range.start, parameters) 
02762                         || !isConstantExpression(expression->primary->range.stop, parameters)) {
02763                         cerr << "ERROR: Range expressions must be constant" << endl;
02764                         QUIT_ON_ERROR;
02765                     }
02766                     
02767                     ConstantValue start, stop;
02768                     evaluateConstantExpression(start, expression->primary->range.start, parameters);
02769                     evaluateConstantExpression(stop, expression->primary->range.stop, parameters);
02770                     for(int b=start.intValue; 
02771                         (start.intValue<stop.intValue?b<=stop.intValue:b>=stop.intValue); 
02772                         b+=(start.intValue<stop.intValue?1:-1)) {
02773                         if (b > bitAssignments.start && b > bitAssignments.stop ||
02774                             b < bitAssignments.start && b < bitAssignments.stop) {
02775                             cerr << "ERROR: Bus index " << expression->primary->name << "[" 
02776                                  << b << "] is out of range.  Range is [" << bitAssignments.start 
02777                                  << ":" << bitAssignments.stop << "]" << endl;
02778                             QUIT_ON_ERROR;
02779                         }
02780                         result.push_back(new LvalRef(expression->primary->name, b));
02781                     }
02782                 }
02783                 DEBUG_PRINTLN("\t\t\t\t lval " << expression->primary->name);
02784                 */
02785                 
02786                 break;
02787             }
02788         
02789             // is this a 2D net?
02790             else if (twoDimRegisters.find(expression->primary->name) != 
02791                     twoDimRegisters.end()) {
02792                 if (expression->primary->range.start == NULL || 
02793                     expression->primary->range.start != expression->primary->range.stop) {
02794                     cerr << "ERROR: Net " << expression->primary->name 
02795                          << " is two-dimensional.  Index required" << endl;
02796                     QUIT_ON_ERROR;
02797                 }
02798                 Bounds bounds(twoDimRegisters[expression->primary->name]);
02799                 if (isConstantExpression(expression->primary->range.start, parameters)) {
02800                     // attach wires to appropriate net
02801 
02802                     // construct suffix to identify net in 2-d vector 
02803                     ConstantValue c;
02804                     evaluateConstantExpression(c, expression->primary->range.start, 
02805                             parameters);
02806                     if (c.intValue < bounds.lower || c.intValue > bounds.upper) {
02807                         cerr << "ERROR: Net vector index out of bounds" << endl;
02808                         QUIT_ON_ERROR;
02809                     }
02810 
02811                     string vectorName(expression->primary->name);
02812                     stringstream suffix;
02813                     suffix << "_" << c.intValue << "_";
02814                     appendSuffix(vectorName, suffix.str());
02815 
02816                     oa::oaModScalarNet *scalarNet;
02817                     oa::oaModBusNet *busNet;
02818                     if ((scalarNet = findScalarNet(vectorName))) {
02819                         result.push_back(new LvalRef(scalarNet));
02820                     } else if ((busNet = findBusNet(vectorName))) {
02821                         int start = busNet->getStart();
02822                         int stop = busNet->getStop();
02823                         for(int b=start; (start<stop?b<=stop:b>=stop); 
02824                                 b+=(start<stop?1:-1)) {
02825                             oa::oaModBusNetBit *bitNet = findBusNetBit(vectorName, b);
02826                             assert(bitNet);
02827                             result.push_back(new LvalRef(bitNet));
02828                         }
02829                     } else {
02830                         QUIT_ON_INTERNAL_ERROR;
02831                     }
02832                     
02833                     DEBUG_PRINTLN("\t\t\t\t lval <" << c.intValue << ">: " << expression->primary->name);        
02834                 } else {
02835 
02836                     cerr << "ERROR: Index of net" << expression->primary->name 
02837                         << " must be a constant" << endl;
02838                     QUIT_ON_ERROR;
02839 
02840                     /*
02841                     // YH: TODO look back to handle the case that net index is
02842                     // not a constant
02843                     // A[B] <= 2; where B is not a constant
02844 
02845                     // build mux
02846 
02847                     evaluateExpression(op1, expression->primary->range.start, state, parameters); 
02848                     int low = bounds.lower;
02849                     int high = min(bounds.upper, 1<<op1.size());
02850                     bool firstConditional = true;
02851                     for(int i=low; i<=high; i++) {
02852                         MultiRefBus constantBits;
02853                         multiBitConstant(constantBits, i);
02854                         zeroExpand(constantBits, op1);
02855                         MultiRef select(equalTo(constantBits, op1));
02856                         
02857                         // construct suffix to identify net in 2-d vector 
02858                         string vectorName(expression->primary->name);
02859                         stringstream suffix;
02860                         suffix << "_" << i << "_";
02861                         appendSuffix(vectorName, suffix.str());
02862                         
02863                         oa::oaModScalarNet *scalarNet;
02864                         oa::oaModBusNet *busNet;
02865                         if ((scalarNet = findScalarNet(vectorName))) {
02866                             if (firstConditional) {
02867                                 result.push_back(new LvalRef);
02868                             }
02869                             result.front()->addConditional(scalarNet, select);                     
02870                         } else if ((busNet = findBusNet(vectorName))) {
02871                             int start = busNet->getStart(), stop = busNet->getStop();
02872                             if (firstConditional) {
02873                                 for(int b=start; (start<stop?b<=stop:b>=stop); b+=(start<stop?1:-1)) {
02874                                     result.push_back(new LvalRef);
02875                                 }
02876                             }                            
02877                             LvalRefBus::iterator bitIter = result.begin();
02878                             for(int b=0; b<=abs(start-stop) && bitIter != result.end(); ++b, ++bitIter) {
02879                                 oa::oaModBitNet *bitNet = busNet->getBit(b);
02880                                 assert(bitNet);
02881                                 (*bitIter)->addConditional(bitNet, select);
02882                             }
02883                         } else {
02884                             QUIT_ON_INTERNAL_ERROR;
02885                         }
02886                         firstConditional = false;
02887                     }
02888             
02889                     DEBUG_PRINTLN("\t\t\t\t lval <mux>: " << expression->primary->name);
02890                     */
02891                 }
02892                 
02893             // is this a net?
02894             } else if (expression->primary->range.start == NULL) {
02895                 oa::oaModScalarNet *scalarNet;
02896                 oa::oaModBusNet *busNet;
02897                 if ((scalarNet = findScalarNet(expression->primary->name))) {
02898                     result.push_back(new LvalRef(scalarNet));
02899                 } else if ((busNet = findBusNet(expression->primary->name))) {
02900                     int start = busNet->getStart();
02901                     int stop = busNet->getStop();
02902                     for(int b=start; (start<stop?b<=stop:b>=stop); b+=(start<stop?1:-1)) {
02903                         oa::oaModBusNetBit *bitNet = 
02904                             findBusNetBit(expression->primary->name, b);
02905                         assert(bitNet);
02906                         result.push_back(new LvalRef(bitNet));
02907                     }
02908                 } else {
02909                     // this l-value is never declared before being referred,
02910                     // which cause an implicit net 
02911                     if (IMPLICIT_NET_WARNINGS) {
02912                         cerr << "NOTE: Implicit net " << expression->primary->name 
02913                             << ".  Assuming scalar wire" << endl;
02914                     }
02915                     result.push_back(
02916                             new LvalRef(createScalarNet(expression->primary->name)));
02917                 }
02918                 DEBUG_PRINTLN("\t\t\t\t lval: " << expression->primary->name);
02919             } else if (expression->primary->range.start == expression->primary->range.stop 
02920                     && 
02921                     !isConstantExpression(expression->primary->range.start, parameters)) {
02922                 // bit index is not known at compile time.  build a multiplexor
02923 
02924                 cerr << "ERROR: Index of net" << expression->primary->name 
02925                     << " must be a constant" << endl;
02926                 QUIT_ON_ERROR;
02927 
02928                 /*
02929 
02930                 // YH: TODO look back to handle the case that net index is
02931 
02932                 oa::oaModBusNet *busNet = findBusNet(expression->primary->name);
02933                 if (busNet == NULL) {
02934                     cerr << "ERROR: Unknown net " << expression->primary->name 
02935                         << ".  Busses can not be implicit" << endl;
02936                     QUIT_ON_ERROR;
02937                 }
02938                 evaluateExpression(op1, expression->primary->range.start, 
02939                         state, parameters);
02940                 
02941                 result.push_back(new LvalRef);
02942                 int start = busNet->getStart(), stop = busNet->getStop();
02943                 for(int i=0; i<=abs(stop-start); i++) {
02944                     // only need to mux bits that are indexable by select
02945                     if (i*sign(stop-start)+start < (1 << op1.size())) {
02946                         MultiRefBus constantBits;
02947                         multiBitConstant(constantBits, i*sign(stop-start)+start);
02948                         zeroExpand(constantBits, op1);
02949                         oa::oaModBitNet *bitNet = busNet->getBit(i);
02950                         assert(bitNet);
02951                         result.back()->addConditional(bitNet, equalTo(constantBits, op1));
02952                     }
02953                 } 
02954                 DEBUG_PRINTLN("\t\t\t\t lval [mux]: " << expression->primary->name);
02955                 */
02956             } else {
02957             
02958                 if (!isConstantExpression(expression->primary->range.start, parameters) || 
02959                     !isConstantExpression(expression->primary->range.stop, parameters)) {
02960                     cerr << "ERROR: Range expressions must be constant" << endl;
02961                     QUIT_ON_ERROR;
02962                 }
02963                     
02964                 ConstantValue start, stop;
02965                 evaluateConstantExpression(start, expression->primary->range.start, 
02966                         parameters);
02967                 evaluateConstantExpression(stop, expression->primary->range.stop, 
02968                         parameters);
02969                 for(int b=start.intValue; 
02970                     (start.intValue<stop.intValue ? b<=stop.intValue : b>=stop.intValue); 
02971                     b+=(start.intValue<stop.intValue?1:-1)) {
02972                     oa::oaModBusNetBit *bitNet = 
02973                         findBusNetBit(expression->primary->name, b);
02974                     if (!bitNet) {
02975                         cerr << "ERROR: Bus index " << expression->primary->name 
02976                             << "[" << b 
02977                             << "] does not exist or is out of range" << endl;
02978                         QUIT_ON_ERROR;
02979                     }
02980                 
02981                     result.push_back(new LvalRef(bitNet));
02982                 }
02983                 DEBUG_PRINTLN("\t\t\t\t lval [" << start.intValue << ":" 
02984                               << stop.intValue << "]: " << expression->primary->name);
02985             }
02986 
02987         } else if (expression->primary->type == VerilogDesign::Primary::FUNCTION_CALL) {
02988             cerr << "ERROR: Lval can not be a function call" << endl;
02989             QUIT_ON_ERROR;
02990         } else {
02991             QUIT_ON_INTERNAL_ERROR;
02992         }
02993 
02994         break;
02995       }
02996       
02997       case VerilogDesign::Expression::BUNDLE:
02998 
02999         // bundle may be replicated
03000         ConstantValue replication;
03001         if (expression->bundle->replication == NULL) {
03002             replication.intValue = 1;
03003         } else {
03004             evaluateConstantExpression(replication, 
03005                     expression->bundle->replication, parameters);
03006         }
03007 
03008         for(int i=0; i<replication.intValue; i++)
03009             for(list<VerilogDesign::Expression*>::iterator 
03010                     exprIter = expression->bundle->members->begin();
03011                     exprIter != expression->bundle->members->end(); 
03012                     ++exprIter) {
03013                 LvalRefBus partial;
03014                 evaluateLval(partial, *exprIter, state, parameters);
03015                 result.splice(result.end(), partial);
03016             }
03017             
03018         DEBUG_PRINTLN("\t\t\t\t lval bundle [" << result.size() << "] replication= " << replication.intValue);
03019         break;
03020 
03021       default:
03022 
03023         QUIT_ON_INTERNAL_ERROR;
03024       }
03025 }
03026 
03027 // *****************************************************************************
03028 // isAsynchronousSignal()
03029 //
03032 // *****************************************************************************
03033 bool
03034 VerilogSynthesis::isAsynchronousSignal(oa::oaModBitNet* net, ProceduralState*
03035         state)
03036 {
03037     if(!state) return false;
03038     if(state->posTriggers.find(net) != state->posTriggers.end()) {
03039         state->nonClockTriggers.insert(net);
03040         return true;
03041     }
03042     if(state->negTriggers.find(net) != state->negTriggers.end()) {
03043         state->nonClockTriggers.insert(net);
03044         return true;
03045     }
03046     return false;
03047 }
03048 
03049 // *****************************************************************************
03050 // evaluateExpression()
03051 //
03056 //
03057 // *****************************************************************************
03058 bool
03059 VerilogSynthesis::evaluateExpression(MultiRefBus &result,
03060         VerilogDesign::Expression *expression,
03061         ProceduralState *state,
03062         ParameterValues *parameters) 
03063 {
03064     assert(expression);
03065     assert(parameters);
03066 
03067     result.clear();
03068 
03069     bool hasAsynchronousSignal = false;
03070     
03071     MultiRefBus op1, op2, op3;
03072     switch(expression->type) {
03073     
03074       case VerilogDesign::Expression::PRIMARY: {
03075         assert(expression->primary);
03076 
03077         // is this a numerical constant?
03078         if (expression->primary->type == VerilogDesign::Primary::CONST) {
03079             if (expression->primary->number.negative) {
03080                 cerr << "ERROR: Negative numbers are currently unimplemented" << endl;
03081                 QUIT_ON_ERROR;
03082             }
03083             multiBitConstant(result, expression->primary->number.intValue, 
03084                     expression->primary->number.bitWidth);
03085             DEBUG_PRINTLN("\t\t\t\t const [" << result.size() << "]");
03086             break;
03087 
03088         } else if (expression->primary->type == VerilogDesign::Primary::NET) {
03089         
03090             // is this a parameter?
03091             ParameterValues::iterator it;
03092             if ((it = parameters->find(expression->primary->name)) != parameters->end()) {
03093                 multiBitConstant(result, it->second.intValue, it->second.bitWidth);
03094                 DEBUG_PRINTLN("\t\t\t\t param [" << result.size() << "]");
03095                 break;
03096             }
03097 
03098             // is this in the context of a function?
03099             else if (state && state->isFunction) {
03100 
03101                 cerr << "ERROR: Function calls are currently unimplemented" << endl;
03102                 QUIT_ON_ERROR;
03103 
03104                 /*
03105 
03106                 // YH: TODO: look back to handle function
03107 
03108                 map<string, FunctionVariableAssignment>::iterator it = 
03109                     state->functionAssignments.find(expression->primary->name);
03110                 if (it == state->functionAssignments.end()) {
03111                     cerr << "ERROR: Unknown net: " << expression->primary->name << endl;
03112                     QUIT_ON_ERROR;
03113                 }
03114                 
03115                 FunctionVariableAssignment bitAssignments = it->second;
03116                 if (expression->primary->range.start == NULL) {
03117                     for(int b=bitAssignments.start; 
03118                         bitAssignments.start<bitAssignments.stop?b<=bitAssignments.stop:b>=bitAssignments.stop; 
03119                         b+=(bitAssignments.start<bitAssignments.stop?1:-1)) {
03120                         result.push_back(bitAssignments[b]);
03121                     }
03122                 } else {
03123                     
03124                     if (!isConstantExpression(expression->primary->range.start, parameters) || 
03125                         !isConstantExpression(expression->primary->range.stop, parameters)) {
03126                         cerr << "ERROR: Range expressions must be constant" << endl;
03127                         QUIT_ON_ERROR;
03128                     }
03129                     
03130                     ConstantValue start, stop;
03131                     evaluateConstantExpression(start, expression->primary->range.start, parameters);
03132                     evaluateConstantExpression(stop, expression->primary->range.stop, parameters);
03133                     for(int b=start.intValue; (start.intValue<stop.intValue?b<=stop.intValue:b>=stop.intValue); 
03134                         b+=(start.intValue<stop.intValue?1:-1)) {
03135                         if (b > bitAssignments.start && b > bitAssignments.stop || 
03136                             b < bitAssignments.start && b < bitAssignments.stop) {
03137                             cerr << "ERROR: Bus index " << expression->primary->name 
03138                                  << "[" << b << "] is out of range.  Range is [" 
03139                                  << bitAssignments.start << ":" << bitAssignments.stop << "]" 
03140                                  << endl;
03141                             QUIT_ON_ERROR;
03142                         }
03143                         result.push_back(bitAssignments[b]);
03144                     }
03145                 }
03146                 DEBUG_PRINTLN("\t\t\t\t funcval " << expression->primary->name);
03147                 
03148                 */
03149                 break;
03150             }
03151             
03152             // is this a 2D net?
03153             else if (twoDimRegisters.find(expression->primary->name) 
03154                     != twoDimRegisters.end()) 
03155             {
03156                 if (expression->primary->range.start == NULL || 
03157                     expression->primary->range.start != expression->primary->range.stop) {
03158                     // YH NOTE: here "expression->primary->range.start" is in fact
03159                     // the high dimension of a 2D net, which is declared as
03160                     // "reg [start:stop] net1 [start2D:stop2D]"
03161                     // and is referred as
03162                     // "net1[start:stop]", therefore, here "start" is "start2D"
03163                     // in its declaration.
03164                     cerr << "ERROR: Net " << expression->primary->name << 
03165                         " is two-dimensional.  Index required" << endl;
03166                     QUIT_ON_ERROR;
03167                 }
03168                 Bounds bounds(twoDimRegisters[expression->primary->name]);
03169                 if (isConstantExpression(expression->primary->range.start, parameters)) {
03170                     // attach wires to appropriate net
03171 
03172                     // construct suffix to identify net in 2-d vector 
03173                     ConstantValue c;
03174                     evaluateConstantExpression(c, expression->primary->range.start, 
03175                             parameters);
03176                     if (c.intValue < bounds.lower || c.intValue > bounds.upper) {
03177                         cerr << "ERROR: Net vector index out of bounds" << endl;
03178                         QUIT_ON_ERROR;
03179                     }
03180                     string vectorName(expression->primary->name);
03181                     stringstream suffix;
03182                     suffix << "_" << c.intValue << "_";
03183                     appendSuffix(vectorName, suffix.str());
03184 
03185                     oa::oaModScalarNet *scalarNet;
03186                     oa::oaModBusNet *busNet;
03187                     if ((scalarNet = findScalarNet(vectorName))) {
03188                         result.push_back(getContextualValue(scalarNet, state));
03189                         hasAsynchronousSignal = hasAsynchronousSignal 
03190                             || isAsynchronousSignal(scalarNet, state);
03191                     } else if ((busNet = findBusNet(vectorName))) {
03192                         int start = busNet->getStart();
03193                         int stop = busNet->getStop();
03194                         for(int b=start; (start<stop?b<=stop:b>=stop); b+=(start<stop?1:-1)) {
03195                             oa::oaModBusNetBit *bitNet = findBusNetBit(vectorName, b);
03196                             assert(bitNet);
03197                             result.push_back(getContextualValue(bitNet, state));
03198                             hasAsynchronousSignal = hasAsynchronousSignal ||
03199                                 isAsynchronousSignal(bitNet, state);
03200                         }
03201                     } else {
03202                         QUIT_ON_INTERNAL_ERROR;
03203                     }
03204                     
03205                     DEBUG_PRINTLN("\t\t\t\t net <" << c.intValue << ">: " << expression->primary->name);
03206 
03207                 } else {
03208 
03209                     cerr << "ERROR: Net " << expression->primary->name <<
03210                         " , bit index is not a constant" << endl;
03211                     QUIT_ON_ERROR;
03212 
03213 
03214                     // YH TODO: look back to handle the case that bit index is
03215                     // not a constant
03216 
03217                     /*
03218 
03219                     // build mux
03220 
03221                     evaluateExpression(op1, expression->primary->range.start, state, parameters);
03222                     int low = bounds.lower;
03223                     int high = min(bounds.upper, 1<<op1.size());
03224                     MultiRefBus *muxTerms = new MultiRefBus[high-low+1];
03225                     for(int i=low; i<=high; i++) {
03226                         MultiRefBus constantBits;
03227                         multiBitConstant(constantBits, i);
03228                         zeroExpand(constantBits, op1);
03229                         MultiRef select(equalTo(constantBits, op1));
03230                         
03231                         // construct suffix to identify net in 2-d vector 
03232                         string vectorName(expression->primary->name);
03233                         stringstream suffix;
03234                         suffix << "_" << i << "_";
03235                         appendSuffix(vectorName, suffix.str());
03236                         
03237                         oa::oaModScalarNet *scalarNet;
03238                         oa::oaModBusNet *busNet;
03239                         if ((scalarNet = findScalarNet(vectorName))) {
03240                             muxTerms[i-low].push_back(andOf(getContextualValue(scalarNet, state), select));                     
03241                         } else if ((busNet = findBusNet(vectorName))) {
03242                             int start = busNet->getStart(), stop = busNet->getStop();
03243                             for(int b=0; b<=abs(stop-start); b++) {
03244                                 oa::oaModBitNet *bitNet = busNet->getBit(b);
03245                                 assert(bitNet);
03246                                 muxTerms[i-low].push_back(andOf(getContextualValue(bitNet, state), select));
03247                             }
03248                         } else {
03249                             QUIT_ON_INTERNAL_ERROR;
03250                         }
03251                     }
03252 
03253                     while(!muxTerms[0].empty()) {
03254                         MultiRefBus terms;
03255                         for(int i=low; i<=high; i++) {
03256                             terms.push_back(muxTerms[i-low].front());
03257                             muxTerms[i-low].pop_front();
03258                         }
03259                         result.push_back(reductionOr(terms));
03260                     }
03261             
03262                     DEBUG_PRINTLN("\t\t\t\t net <mux>: " << expression->primary->name);
03263                     delete [] muxTerms;
03264 
03265                     */
03266                 }
03267                 
03268             // is this a 1-D net?
03269             } else if (expression->primary->range.start == NULL) {
03270                 oa::oaModScalarNet *scalarNet;
03271                 oa::oaModBusNet *busNet;
03272                 if ((scalarNet = findScalarNet(expression->primary->name))) {
03273                     result.push_back(getContextualValue(scalarNet, state));
03274                         hasAsynchronousSignal = hasAsynchronousSignal || 
03275                             isAsynchronousSignal(scalarNet, state);
03276                 } else if ((busNet = findBusNet(expression->primary->name))) {
03277                     int start = busNet->getStart();
03278                     int stop = busNet->getStop();
03279                     for(int b=start; (start<stop?b<=stop:b>=stop); b+=(start<stop?1:-1)) {
03280                         oa::oaModBusNetBit *bitNet = 
03281                             findBusNetBit(expression->primary->name, b);
03282                         assert(bitNet);
03283                         result.push_back(getContextualValue(bitNet, state));
03284                         hasAsynchronousSignal = hasAsynchronousSignal || 
03285                             isAsynchronousSignal(bitNet, state);
03286                     }
03287                 } else {
03288                     if (IMPLICIT_NET_WARNINGS) {
03289                         cerr << "NOTE: Implicit net " << expression->primary->name 
03290                              << ".  Assuming scalar wire" << endl;
03291                     }
03292                     result.push_back(MultiRef(createScalarNet(expression->primary->name)));
03293                 }
03294                 DEBUG_PRINTLN("\t\t\t\t net: " << expression->primary->name);
03295             } else if (expression->primary->range.start == 
03296                     expression->primary->range.stop && 
03297                     !isConstantExpression(expression->primary->range.start, parameters)) {
03298 
03299                 cerr << "ERROR: Net " << expression->primary->name <<
03300                     " , bit index is not a constant" << endl;
03301                 QUIT_ON_ERROR;
03302 
03303 
03304                 // YH TODO: look back to handle the case that bit index is
03305                 // not a constant
03306 
03307                 /*
03308 
03309                 // bit index is not known at compile time.  build a multiplexor
03310                 oa::oaModBusNet *busNet = findBusNet(expression->primary->name);
03311                 if (busNet == NULL) {
03312                     cerr << "ERROR: Unknown net " << expression->primary->name 
03313                          << ".  Busses can not be implicit" << endl;
03314                     QUIT_ON_ERROR;
03315                 }
03316                 evaluateExpression(op1, expression->primary->range.start, state, parameters);
03317                 
03318                 MultiRefBus muxTerms;
03319                 int start = busNet->getStart(), stop = busNet->getStop();
03320                 for(int i=0; i<=abs(stop-start); i++) {
03321                     // only need to mux bits that are indexable by select
03322                     if (i*sign(stop-start)+start < (1 << op1.size())) {
03323                         MultiRefBus constantBits;
03324                         multiBitConstant(constantBits, i*sign(stop-start)+start);
03325                         zeroExpand(constantBits, op1);
03326                         oa::oaModBitNet *bitNet = busNet->getBit(i);
03327                         assert(bitNet);
03328                         muxTerms.push_back(andOf(MultiRef(bitNet), equalTo(constantBits, op1)));
03329                     } 
03330                 }
03331                 result.push_back(reductionOr(muxTerms));
03332                 DEBUG_PRINTLN("\t\t\t\t net [mux]: " << expression->primary->name);
03333                 */
03334             } else {
03335             
03336                 if (!isConstantExpression(expression->primary->range.start, parameters) || 
03337                     !isConstantExpression(expression->primary->range.stop, parameters)) {
03338                     cerr << "ERROR: Range expressions must be constant" << endl;
03339                     QUIT_ON_ERROR;
03340                 }
03341             
03342                 ConstantValue start, stop;
03343                 evaluateConstantExpression(start, expression->primary->range.start, 
03344                         parameters);
03345                 evaluateConstantExpression(stop, expression->primary->range.stop, 
03346                         parameters);
03347                 for(int b=start.intValue; 
03348                         (start.intValue<stop.intValue?b<=stop.intValue:b>=stop.intValue); 
03349                         b+=(start.intValue<stop.intValue?1:-1)) {
03350                     oa::oaModBusNetBit *bitNet = 
03351                         findBusNetBit(expression->primary->name, b);
03352                     if (!bitNet) {
03353                         cerr << "ERROR: Bus net bit " << 
03354                             expression->primary->name << "[" << b 
03355                             << "] does not exist or is out of range" << endl;
03356                         QUIT_ON_ERROR;
03357                     }
03358                 
03359                     result.push_back(MultiRef(bitNet));
03360                     hasAsynchronousSignal = hasAsynchronousSignal || 
03361                         isAsynchronousSignal(bitNet, state);
03362                 }
03363                 DEBUG_PRINTLN("\t\t\t\t net [" << start.intValue << ":" << stop.intValue 
03364                               << "]: " << expression->primary->name);
03365             }
03366 
03367         } else if (expression->primary->type == VerilogDesign::Primary::FUNCTION_CALL) {
03368             assert(currentVmodule);
03369 
03370             cerr << "ERROR: Function calls are currently unimplemented" << endl;
03371             QUIT_ON_ERROR;
03372 
03373             /*
03374 
03375             // YH: TODO: look back to handle function
03376 
03377 
03378             // find the function defintion of this name
03379             VerilogDesign::Function *definition = NULL;
03380             VerilogDesign::Primary *invocation = expression->primary;
03381             for(list<VerilogDesign::Function*>::iterator fIter = 
03382                     currentVmodule->functions->begin();
03383                     fIter != currentVmodule->functions->end();
03384                     ++fIter) {
03385                 if (invocation->name == (*fIter)->name) {
03386                     definition = *fIter;
03387                     break;
03388                 }
03389             }
03390             if (definition == NULL) {
03391                 cerr << "ERROR: Unknown function: " << invocation->name << endl;
03392                 QUIT_ON_ERROR;            
03393             }
03394 
03395             DEBUG_PRINTLN("\t\t\t\t function call " << invocation->name << "()");
03396 
03397             // create a ProceduralState.  Because of the independent scope of the
03398             // function call, no procedural states are inhereted from the current one
03399             ProceduralState functionState;
03400             ParameterValues functionParameters(*parameters);
03401             functionState.isFunction = true;
03402             
03403             // declare the function variable for the output
03404             ConstantValue start, stop;
03405             if (definition->start) {
03406                 // bus variable
03407                 evaluateConstantExpression(start, definition->start, parameters);
03408                 evaluateConstantExpression(stop, definition->stop, parameters);
03409                 FunctionVariableAssignment bitAssignments(start.intValue, stop.intValue);
03410                 for(int b=start.intValue; (start.intValue<stop.intValue ? b<=stop.intValue : b>=stop.intValue); 
03411                     b+=(start.intValue<stop.intValue?1:-1)) {
03412                     bitAssignments[b] = constantZero();
03413                 }
03414                 functionState.functionAssignments[definition->name] = bitAssignments;
03415             } else {
03416                 // scalar variable
03417                 FunctionVariableAssignment bitAssignments;
03418                 bitAssignments[0] = constantZero();
03419                 functionState.functionAssignments[definition->name] = bitAssignments;
03420             }
03421 
03422             // declare the function variable for the other declarations
03423             // and assign the state of the inputs to be that of the arguments passed
03424             list<VerilogDesign::Expression *>::iterator argIter = invocation->arguments->begin();
03425             list<VerilogDesign::Declaration *>::iterator declIter = definition->declarations->begin();
03426             while (declIter != definition->declarations->end()) {
03427                 VerilogDesign::Declaration *declaration = *declIter;
03428                 
03429                 // an input declaration
03430                 if (declaration->type == VerilogDesign::Declaration::INPUT) {
03431                     if (declaration->start2D!=NULL) {
03432                         cerr << "ERROR: Two dimensional nets are not supported inside functions" << endl;
03433                         QUIT_ON_ERROR;
03434                     }
03435                     
03436                     // evaluate the matching argument
03437                     if (argIter == invocation->arguments->end()) {
03438                         cerr << "ERROR: Too few arguments to function call" << endl;
03439                         QUIT_ON_ERROR;
03440                     }
03441                     MultiRefBus argResult;
03442                     evaluateExpression(argResult, *argIter, state, parameters);
03443                     ++argIter;
03444 
03445                     DEBUG_PRINTLN("\t\t\t\t\t input " << declaration->name);
03446                     if (!declaration->start) {
03447                         // scalar variable
03448                         FunctionVariableAssignment bitAssignments;
03449                         bitAssignments[0] = argResult.back();
03450                         functionState.functionAssignments[declaration->name] = bitAssignments;
03451                     } else {
03452                         // bus variable
03453                         ConstantValue start, stop;
03454                         evaluateConstantExpression(start, declaration->start, parameters);
03455                         evaluateConstantExpression(stop, declaration->stop, parameters);
03456                         FunctionVariableAssignment bitAssignments(start.intValue, stop.intValue);
03457                         MultiRefBus::reverse_iterator argResultIter = argResult.rbegin();
03458                         for(int b=stop.intValue; (start.intValue<stop.intValue?b>=start.intValue:b<=start.intValue); 
03459                             b+=(start.intValue<stop.intValue?-1:1)) {
03460                             if (argResultIter == argResult.rend()) {
03461                                 bitAssignments[b] = constantZero();
03462                             } else {
03463                                 bitAssignments[b] = *argResultIter;
03464                             }
03465                             ++argResultIter;
03466                         }
03467                         functionState.functionAssignments[declaration->name] = bitAssignments;
03468                     }
03469 
03470                 // a reg declaration                    
03471                 } else if (declaration->type == VerilogDesign::Declaration::REG) {
03472                     if (declaration->start2D!=NULL) {
03473                         cerr << "ERROR: Two dimensional nets are not supported inside functions" << endl;
03474                         QUIT_ON_ERROR;
03475                     }
03476                     
03477                     DEBUG_PRINTLN("\t\t\t\t\t reg " << declaration->name);
03478                     if (!declaration->start) {
03479                         // scalar variable
03480                         FunctionVariableAssignment bitAssignments;
03481                         bitAssignments[0] = constantZero();
03482                         functionState.functionAssignments[declaration->name] = bitAssignments;
03483                     } else {
03484                         // bus variable
03485                         ConstantValue start, stop;
03486                         evaluateConstantExpression(start, declaration->start, parameters);
03487                         evaluateConstantExpression(stop, declaration->stop, parameters);
03488                         FunctionVariableAssignment bitAssignments(start.intValue, stop.intValue);
03489                         for(int b=start.intValue; 
03490                             (start.intValue<stop.intValue?b<=stop.intValue:b>=stop.intValue); 
03491                             b+=(start.intValue<stop.intValue?1:-1)) {
03492                             bitAssignments[b] = constantZero();
03493                         }
03494                         functionState.functionAssignments[declaration->name] = bitAssignments;
03495                     }
03496                     
03497                 // UNIMPLEMENTED: allow parameters inside functions
03498                 } else {
03499                     cerr << "ERROR: Invalid declaration for function.  Only input and reg declarations are allowed" << endl;
03500                     QUIT_ON_ERROR;
03501                 }
03502                 ++declIter;            
03503             }
03504 
03505             // left over arguments?
03506             if (argIter != invocation->arguments->end()) {
03507                 cerr << "ERROR: Too many arguments to function call" << endl;
03508                 QUIT_ON_ERROR;
03509             }
03510 
03511             // evaluate function
03512             synthesizeBehavioral(definition->action, functionState, &functionParameters);
03513             
03514             // return the final state of the bits w/ same name as function
03515             FunctionVariableAssignment resultAssignment(functionState.functionAssignments[expression->primary->name]);
03516             for(int b=resultAssignment.start; 
03517                 (resultAssignment.start<resultAssignment.stop ? b<=resultAssignment.stop : b>=resultAssignment.stop); 
03518                 b+=(resultAssignment.start<resultAssignment.stop?1:-1)) {
03519                 result.push_back(resultAssignment[b]);
03520             }
03521             */
03522         } else {
03523             QUIT_ON_INTERNAL_ERROR;
03524         }
03525 
03526         break;
03527       }
03528       
03529       case VerilogDesign::Expression::BUNDLE:
03530 
03531         // bundle may be replicated
03532         ConstantValue replication;
03533         if (expression->bundle->replication == NULL) {
03534             replication.intValue = 1;
03535         } else {
03536             evaluateConstantExpression(replication, 
03537                     expression->bundle->replication, parameters);
03538         }
03539 
03540         for(int i=0; i<replication.intValue; i++)
03541             for(list<VerilogDesign::Expression*>::iterator exprIter = 
03542                     expression->bundle->members->begin();
03543                     exprIter != expression->bundle->members->end(); 
03544                     ++exprIter) {
03545                 MultiRefBus partial;
03546                 evaluateExpression(partial, *exprIter, state, parameters);
03547                 result.splice(result.end(), partial);
03548             }
03549             
03550         DEBUG_PRINTLN("\t\t bundle [" << result.size() << 
03551                 "] replication= " << replication.intValue);
03552         break;
03553         
03554       case VerilogDesign::Expression::BITWISE_AND: {
03555 
03556         bool hasAsynchronousSignal1 = 
03557             evaluateExpression(op1, expression->op1, state, parameters);
03558         bool hasAsynchronousSignal2 = 
03559             evaluateExpression(op2, expression->op2, state, parameters);
03560         hasAsynchronousSignal = 
03561             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03562         zeroExpand(op1, op2);
03563         assert(op1.size() == op2.size());
03564 
03565         // YH TODO: currently I build N BB nodes for an N-bit operator. An
03566         // alternative is to build a 2N-input/N-output big BB node, which may or
03567         // may not improve the effectiveness of device inference
03568 
03569         MultiRefBus::iterator op1Iter = op1.begin(), op2Iter = op2.begin();
03570         while(op1Iter != op1.end() && op2Iter != op2.end()) {
03571             result.push_back( andOf(*op1Iter, *op2Iter) );
03572             ++op1Iter; ++op2Iter;
03573         }
03574         
03575         break;
03576         }
03577         
03578       case VerilogDesign::Expression::BITWISE_NOT: {
03579 
03580         hasAsynchronousSignal = hasAsynchronousSignal ||
03581             evaluateExpression(op1, expression->op1, state, parameters);
03582 
03583         MultiRefBus::iterator op1Iter = op1.begin();
03584         while(op1Iter != op1.end()) {
03585             result.push_back( notOf(*op1Iter) );
03586             ++op1Iter;
03587         }
03588         
03589         break;
03590         }
03591 
03592       case VerilogDesign::Expression::BITWISE_OR: {
03593 
03594         bool hasAsynchronousSignal1 = 
03595             evaluateExpression(op1, expression->op1, state, parameters);
03596         bool hasAsynchronousSignal2 = 
03597             evaluateExpression(op2, expression->op2, state, parameters);
03598         hasAsynchronousSignal = 
03599             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03600  
03601         zeroExpand(op1, op2);
03602         assert(op1.size() == op2.size());
03603         MultiRefBus::iterator op1Iter = op1.begin(), op2Iter = op2.begin();
03604         while(op1Iter != op1.end() && op2Iter != op2.end()) {
03605             result.push_back( orOf(*op1Iter, *op2Iter) );
03606             ++op1Iter; ++op2Iter;
03607         }
03608         
03609         break;
03610         }
03611 
03612       case VerilogDesign::Expression::BITWISE_XOR:{
03613 
03614         bool hasAsynchronousSignal1 = 
03615             evaluateExpression(op1, expression->op1, state, parameters);
03616         bool hasAsynchronousSignal2 = 
03617             evaluateExpression(op2, expression->op2, state, parameters);
03618         hasAsynchronousSignal = 
03619             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03620 
03621         zeroExpand(op1, op2);
03622         assert(op1.size() == op2.size());
03623         MultiRefBus::iterator op1Iter = op1.begin(), op2Iter = op2.begin();
03624         while(op1Iter != op1.end() && op2Iter != op2.end()) {
03625             result.push_back( xorOf(*op1Iter, *op2Iter) );
03626             ++op1Iter; ++op2Iter;
03627         }
03628         
03629         break;
03630         }
03631 
03632       case VerilogDesign::Expression::BITWISE_NOR: {
03633 
03634         bool hasAsynchronousSignal1 = 
03635             evaluateExpression(op1, expression->op1, state, parameters);
03636         bool hasAsynchronousSignal2 = 
03637             evaluateExpression(op2, expression->op2, state, parameters);
03638         hasAsynchronousSignal = 
03639             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03640 
03641         zeroExpand(op1, op2);
03642         assert(op1.size() == op2.size());
03643         MultiRefBus::iterator op1Iter = op1.begin(), op2Iter = op2.begin();
03644         while(op1Iter != op1.end() && op2Iter != op2.end()) {
03645             result.push_back( norOf(*op1Iter, *op2Iter) ) ;
03646             ++op1Iter; ++op2Iter;
03647         }
03648         
03649         break;
03650         }
03651 
03652       case VerilogDesign::Expression::BITWISE_NAND: {
03653 
03654         bool hasAsynchronousSignal1 = 
03655             evaluateExpression(op1, expression->op1, state, parameters);
03656         bool hasAsynchronousSignal2 = 
03657             evaluateExpression(op2, expression->op2, state, parameters);
03658         hasAsynchronousSignal = 
03659             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03660 
03661         zeroExpand(op1, op2);
03662         assert(op1.size() == op2.size());
03663         MultiRefBus::iterator op1Iter = op1.begin(), op2Iter = op2.begin();
03664         while(op1Iter != op1.end() && op2Iter != op2.end()) {
03665             result.push_back( nandOf(*op1Iter, *op2Iter) );
03666             ++op1Iter; ++op2Iter;
03667         }
03668         
03669         break;
03670         }
03671         
03672       case VerilogDesign::Expression::BITWISE_XNOR: {
03673 
03674         bool hasAsynchronousSignal1 = 
03675             evaluateExpression(op1, expression->op1, state, parameters);
03676         bool hasAsynchronousSignal2 = 
03677             evaluateExpression(op2, expression->op2, state, parameters);
03678         hasAsynchronousSignal = 
03679             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03680 
03681         zeroExpand(op1, op2);
03682         assert(op1.size() == op2.size());
03683         MultiRefBus::iterator op1Iter = op1.begin(), op2Iter = op2.begin();
03684         while(op1Iter != op1.end() && op2Iter != op2.end()) {
03685             result.push_back( xnorOf(*op1Iter, *op2Iter) );
03686             ++op1Iter; ++op2Iter;
03687         }
03688         
03689         break;
03690         }
03691         
03692       case VerilogDesign::Expression::LOGICAL_AND: {
03693 
03694         bool hasAsynchronousSignal1 = 
03695             evaluateExpression(op1, expression->op1, state, parameters);
03696         bool hasAsynchronousSignal2 = 
03697             evaluateExpression(op2, expression->op2, state, parameters);
03698         hasAsynchronousSignal = 
03699             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03700 
03701         result.push_back(logicAnd(op1, op2));
03702         break;
03703       }
03704         
03705       case VerilogDesign::Expression::LOGICAL_NOT:
03706 
03707         hasAsynchronousSignal = hasAsynchronousSignal ||
03708             evaluateExpression(op1, expression->op1, state, parameters);
03709         result.push_back(logicNot(op1));
03710         break;
03711         
03712       case VerilogDesign::Expression::LOGICAL_OR: {
03713 
03714         bool hasAsynchronousSignal1 = 
03715             evaluateExpression(op1, expression->op1, state, parameters);
03716         bool hasAsynchronousSignal2 = 
03717             evaluateExpression(op2, expression->op2, state, parameters);
03718         hasAsynchronousSignal = 
03719             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03720         result.push_back(logicOr(op1, op2));
03721         break;
03722       }
03723         
03724       case VerilogDesign::Expression::REDUCTION_AND:
03725         
03726         hasAsynchronousSignal = hasAsynchronousSignal ||
03727             evaluateExpression(op1, expression->op1, state, parameters);
03728         result.push_back(reductionAnd(op1));
03729         break;
03730         
03731       case VerilogDesign::Expression::REDUCTION_OR:
03732 
03733         hasAsynchronousSignal = hasAsynchronousSignal ||
03734             evaluateExpression(op1, expression->op1, state, parameters);
03735         result.push_back(reductionOr(op1));
03736         break;
03737 
03738       case VerilogDesign::Expression::REDUCTION_XOR:
03739       
03740         hasAsynchronousSignal = hasAsynchronousSignal ||
03741             evaluateExpression(op1, expression->op1, state, parameters);
03742         result.push_back(reductionXor(op1));
03743         break;
03744         
03745       case VerilogDesign::Expression::REDUCTION_NAND: 
03746 
03747         hasAsynchronousSignal = hasAsynchronousSignal ||
03748             evaluateExpression(op1, expression->op1, state, parameters);
03749         result.push_back(reductionNand(op1));
03750         break;
03751         
03752       case VerilogDesign::Expression::REDUCTION_NOR: 
03753 
03754         hasAsynchronousSignal = hasAsynchronousSignal ||
03755             evaluateExpression(op1, expression->op1, state, parameters);
03756         result.push_back(reductionNor(op1));
03757         break;
03758         
03759       case VerilogDesign::Expression::REDUCTION_XNOR:
03760 
03761         hasAsynchronousSignal = hasAsynchronousSignal ||
03762             evaluateExpression(op1, expression->op1, state, parameters);
03763         result.push_back(reductionXnor(op1));
03764         break;
03765         
03766       case VerilogDesign::Expression::LESS_THAN: {
03767 
03768         bool hasAsynchronousSignal1 = 
03769             evaluateExpression(op1, expression->op1, state, parameters);
03770         bool hasAsynchronousSignal2 = 
03771             evaluateExpression(op2, expression->op2, state, parameters);
03772         hasAsynchronousSignal = 
03773             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03774         zeroExpand(op1, op2);
03775         assert(op1.size() == op2.size());
03776         result.push_back(lessThan(op1, op2));
03777         break;
03778       }
03779         
03780       case VerilogDesign::Expression::LESS_THAN_EQUAL: {
03781 
03782         bool hasAsynchronousSignal1 = 
03783             evaluateExpression(op1, expression->op1, state, parameters);
03784         bool hasAsynchronousSignal2 = 
03785             evaluateExpression(op2, expression->op2, state, parameters);
03786         hasAsynchronousSignal = 
03787             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03788         zeroExpand(op1, op2);
03789         assert(op1.size() == op2.size());
03790         result.push_back(lessThanEqual(op2, op1));
03791         break;
03792       }
03793         
03794       case VerilogDesign::Expression::GREATER_THAN: {
03795 
03796         bool hasAsynchronousSignal1 = 
03797             evaluateExpression(op1, expression->op1, state, parameters);
03798         bool hasAsynchronousSignal2 = 
03799             evaluateExpression(op2, expression->op2, state, parameters);
03800         hasAsynchronousSignal = 
03801             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03802         zeroExpand(op1, op2);
03803         assert(op1.size() == op2.size());
03804         result.push_back(greaterThan(op2, op1));
03805         break;
03806       }
03807 
03808       case VerilogDesign::Expression::GREATER_THAN_EQUAL: {
03809 
03810         bool hasAsynchronousSignal1 = 
03811             evaluateExpression(op1, expression->op1, state, parameters);
03812         bool hasAsynchronousSignal2 = 
03813             evaluateExpression(op2, expression->op2, state, parameters);
03814         hasAsynchronousSignal = 
03815             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03816         zeroExpand(op1, op2);
03817         assert(op1.size() == op2.size());
03818         result.push_back(greaterThanEqual(op1, op2));
03819         break;
03820       }
03821         
03822       case VerilogDesign::Expression::EQUAL: {
03823 
03824         bool hasAsynchronousSignal1 =                                          
03825             evaluateExpression(op1, expression->op1, state, parameters);       
03826         bool hasAsynchronousSignal2 =                                          
03827             evaluateExpression(op2, expression->op2, state, parameters);       
03828         hasAsynchronousSignal =                                                
03829             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03830         zeroExpand(op1, op2);
03831         assert(op1.size() == op2.size());
03832         result.push_back(equalTo(op1, op2));
03833         break;
03834       }
03835         
03836       case VerilogDesign::Expression::NOTEQUAL: {
03837 
03838         bool hasAsynchronousSignal1 =                                          
03839             evaluateExpression(op1, expression->op1, state, parameters);       
03840         bool hasAsynchronousSignal2 =                                          
03841             evaluateExpression(op2, expression->op2, state, parameters);       
03842         hasAsynchronousSignal =                                                
03843             hasAsynchronousSignal1 || hasAsynchronousSignal2;
03844         zeroExpand(op1, op2);
03845         assert(op1.size() == op2.size());
03846         result.push_back(notEqualTo(op1, op2));
03847         break;
03848       }
03849         
03850       case VerilogDesign::Expression::IF_ELSE: {
03851 
03852         bool hasAsynchronousSignal1 =                                          
03853             evaluateExpression(op1, expression->op1, state, parameters);       
03854         bool hasAsynchronousSignal2 =                                          
03855             evaluateExpression(op2, expression->op2, state, parameters);       
03856         bool hasAsynchronousSignal3 =                                          
03857             evaluateExpression(op3, expression->op3, state, parameters);       
03858         hasAsynchronousSignal =                                                
03859             hasAsynchronousSignal1 || hasAsynchronousSignal2 || 
03860                 hasAsynchronousSignal3;
03861 
03862         // YH TODO: An alternative to implement IF_ELSE is to use a big MUX
03863         // which select op2 and op3 by op1, so that bus net can be
03864         // handled/inferred as a whole
03865 
03866         MultiRef condition = reductionOr(op1);
03867 
03868         zeroExpand(op2, op3);
03869         assert(op2.size() == op3.size());
03870         MultiRefBus::iterator op2Iter = op2.begin(), op3Iter = op3.begin();
03871         while(op2Iter != op2.end() && op3Iter != op3.end()) {
03872             result.push_back( mux(condition, *op2Iter, *op3Iter) );
03873             ++op2Iter; ++op3Iter;
03874         }
03875         
03876         break;
03877         }
03878 
03879       case VerilogDesign::Expression::LEFT_SHIFT:
03880 
03881         cerr << "ERROR: shifting signal is currently unimplemented" << endl;
03882         QUIT_ON_ERROR;
03883 
03884         // YH TODO: lookup back to handle shift
03885 
03886         /*
03887 
03888         evaluateExpression(op1, expression->op1, state, parameters);
03889         
03890         if (isConstantExpression(expression->op2, parameters)) {
03891             // shift signal a constant number of bits by connection
03892             
03893             ConstantValue c;
03894             evaluateConstantExpression(c, expression->op2, parameters);
03895             if (c.intValue < 0) {
03896                 cerr << "ERROR: Constant shift length must be greater than zero" << endl;
03897                 QUIT_ON_ERROR;                
03898             }
03899             int size = op1.size();
03900             if (c.intValue >= size) {
03901                 cerr << "WARNING: Shift length is greater than length of \
03902                     operand. Result will be constant zero." << endl;   
03903             }
03904         
03905             MultiRefBus::reverse_iterator bitIter = op1.rbegin();
03906             for(int i=0; i<size; i++) {
03907                 if(i<c.intValue) {
03908                     result.push_front(constantZero());
03909                 } else {
03910                     result.push_front(*bitIter);
03911                     ++bitIter;
03912                 }
03913             }        
03914         } else {
03915             // shift signal a variable number of bits by multiplexing
03916 
03917             evaluateExpression(op2, expression->op2, state, parameters);
03918             // the number of shift possibilities is the minimum of the bits to be shifted
03919             // and the largest number that can be represented by the shift value
03920             unsigned int size = min(op1.size(), static_cast<unsigned int>(1 << op2.size()));
03921             MultiRefBus selects;
03922             for(unsigned int i=0; i<size; ++i) {
03923                 MultiRefBus constantBits;
03924                 multiBitConstant(constantBits, i);
03925                 zeroExpand(constantBits, op2);
03926                 selects.push_back(equalTo(constantBits, op2));
03927             }
03928 
03929             // build a multiplexor for each bit    
03930             for(MultiRefBus::iterator bitIter = op1.begin(); bitIter != op1.end(); ++bitIter) {
03931                 MultiRefBus muxTerms;            
03932 
03933                 // build term for each bit
03934                 MultiRefBus::iterator inputIter(bitIter);
03935                 MultiRefBus::iterator selectIter = selects.begin();
03936                 while(inputIter != op1.end() && selectIter != selects.end()) {
03937                     muxTerms.push_back(andOf(*selectIter, *inputIter));
03938                     ++selectIter;
03939                     if (inputIter == op1.begin()) {
03940                         inputIter = op1.end();
03941                     } else {
03942                         ++inputIter;
03943                     }
03944                 }
03945 
03946                 result.push_back(reductionOr(muxTerms));            
03947             }
03948         }
03949         */
03950         break;
03951       
03952       case VerilogDesign::Expression::RIGHT_SHIFT:
03953 
03954         cerr << "ERROR: shifting signal is currently unimplemented" << endl;
03955         QUIT_ON_ERROR;
03956 
03957         // YH TODO: lookup back to handle shift
03958 
03959         /*
03960         evaluateExpression(op1, expression->op1, state, parameters);
03961         
03962         if (isConstantExpression(expression->op2, parameters)) {
03963             // shift signal a constant number of bits by connection
03964             
03965             ConstantValue c;
03966             evaluateConstantExpression(c, expression->op2, parameters);
03967             if (c.intValue < 0) {
03968                 cerr << "ERROR: Constant shift length must be greater than zero" << endl;
03969                 QUIT_ON_ERROR;                
03970             }
03971             int size = op1.size();
03972             if (c.intValue >= size) {
03973                 cerr << "WARNING: Shift length is greater than length of operand.  Result will be constant zero." << endl;   
03974             }
03975         
03976             MultiRefBus::iterator bitIter = op1.begin();
03977             for(int i=0; i<size; i++) {
03978                 if(i<c.intValue) {
03979                     result.push_back(constantZero());
03980                 } else {
03981                     result.push_back(*bitIter);
03982                     ++bitIter;
03983                 }
03984             }        
03985         } else {
03986             // shift signal a variable number of bits by multiplexing
03987            
03988             evaluateExpression(op2, expression->op2, state, parameters);
03989             // the number of shift possibilities is the minimum of the bits to be shifted
03990             // and the largest number that can be represented by the shift value
03991             unsigned int size = min(op1.size(), static_cast<unsigned int>(1 << op2.size()));
03992             MultiRefBus selects;
03993             for(unsigned int i=0; i<size; i++) {
03994                 MultiRefBus constantBits;
03995                 multiBitConstant(constantBits, i);
03996                 zeroExpand(constantBits, op2);
03997                 selects.push_back(equalTo(constantBits, op2));
03998             }
03999 
04000             // build a multiplexor for each bit    
04001             for(MultiRefBus::iterator bitIter = op1.begin(); bitIter != op1.end(); ++bitIter) {
04002                 MultiRefBus muxTerms;            
04003 
04004                 // build term for each bit
04005                 MultiRefBus::iterator inputIter(bitIter);
04006                 MultiRefBus::iterator selectIter = selects.begin();
04007                 while(inputIter != op1.end() && selectIter != selects.end()) {
04008                     muxTerms.push_back(andOf(*selectIter, *inputIter));
04009                     ++inputIter; ++selectIter;
04010                 }
04011 
04012                 result.push_back(reductionOr(muxTerms));            
04013             }
04014         }
04015         */
04016         break;
04017         
04018       case VerilogDesign::Expression::ADD: {
04019       
04020         bool hasAsynchronousSignal1 =                                          
04021             evaluateExpression(op1, expression->op1, state, parameters);       
04022         bool hasAsynchronousSignal2 =                                          
04023             evaluateExpression(op2, expression->op2, state, parameters);       
04024         hasAsynchronousSignal =                                                
04025             hasAsynchronousSignal1 || hasAsynchronousSignal2;
04026 
04027         zeroExpand(op1, op2);
04028         assert(op1.size() == op2.size());
04029         arithmeticAdd(result, op1, op2);
04030         break;
04031       }
04032         
04033       case VerilogDesign::Expression::SUBTRACT:{
04034 
04035         bool hasAsynchronousSignal1 =                                          
04036             evaluateExpression(op1, expression->op1, state, parameters);       
04037         bool hasAsynchronousSignal2 =                                          
04038             evaluateExpression(op2, expression->op2, state, parameters);       
04039         hasAsynchronousSignal =                                                
04040             hasAsynchronousSignal1 || hasAsynchronousSignal2;
04041 
04042         zeroExpand(op1, op2);
04043         assert(op1.size() == op2.size());
04044         arithmeticSubtract(result, op1, op2);
04045         break;
04046       }
04047         
04048       case VerilogDesign::Expression::NEGATE: {
04049       
04050         // -op1 = op2 - op1, op2 = 0
04051         bool hasAsynchronousSignal1 =                                          
04052             evaluateExpression(op1, expression->op1, state, parameters);       
04053         hasAsynchronousSignal =                                                
04054             hasAsynchronousSignal1 || hasAsynchronousSignal;
04055 
04056         op2.clear();
04057         zeroExpand(op1, op2);
04058         assert(op1.size() == op2.size());
04059         arithmeticSubtract(result, op2, op1);
04060         break;
04061       }
04062         
04063       case VerilogDesign::Expression::MULTIPLY: {
04064       
04065         bool hasAsynchronousSignal1 =                                          
04066             evaluateExpression(op1, expression->op1, state, parameters);       
04067         bool hasAsynchronousSignal2 =                                          
04068             evaluateExpression(op2, expression->op2, state, parameters);       
04069         hasAsynchronousSignal =                                                
04070             hasAsynchronousSignal1 || hasAsynchronousSignal2;
04071 
04072         arithmeticMultiply(result, op1, op2);
04073         break;
04074       }
04075         
04076       case VerilogDesign::Expression::DIVIDE: {
04077 
04078         bool hasAsynchronousSignal1 =                                          
04079             evaluateExpression(op1, expression->op1, state, parameters);       
04080         bool hasAsynchronousSignal2 =                                          
04081             evaluateExpression(op2, expression->op2, state, parameters);       
04082         hasAsynchronousSignal =                                                
04083             hasAsynchronousSignal1 || hasAsynchronousSignal2;
04084 
04085         zeroExpand(op1, op2);
04086         assert(op1.size() == op2.size());
04087         arithmeticDivide(result, op1, op2);
04088         break;
04089       }
04090         
04091       case VerilogDesign::Expression::MODULO: {
04092 
04093         bool hasAsynchronousSignal1 =                                          
04094             evaluateExpression(op1, expression->op1, state, parameters);       
04095         bool hasAsynchronousSignal2 =                                          
04096             evaluateExpression(op2, expression->op2, state, parameters);       
04097         hasAsynchronousSignal =                                                
04098             hasAsynchronousSignal1 || hasAsynchronousSignal2;
04099 
04100         zeroExpand(op1, op2);
04101         assert(op1.size() == op2.size());
04102         arithmeticModulo(result, op1, op2);
04103         break;
04104       }
04105 
04106       default:
04107         QUIT_ON_INTERNAL_ERROR;
04108         break;
04109     }
04110 
04111     for(MultiRefBus::iterator it = result.begin(); it != result.end(); it++)
04112         assert(it->type != NEITHER);   
04113 
04114     return hasAsynchronousSignal;
04115 }
04116 
04117 // *****************************************************************************
04118 // getContextualValue()
04119 //
04122 //
04123 // *****************************************************************************
04124 MultiRef
04125 VerilogSynthesis::getContextualValue(oa::oaModBitNet *net, ProceduralState
04126         *state) {
04127     map<oa::oaModBitNet*, MultiRef>::iterator it;
04128     if (state && (it = state->blockingAssignments.find(net)) !=
04129             state->blockingAssignments.end() ) {
04130         return it->second;
04131     } else {
04132         return MultiRef(net);
04133     }
04134 }
04135 
04136 // *****************************************************************************
04137 // appendSuffix()
04138 //
04145 //
04146 // *****************************************************************************
04147 void
04148 VerilogSynthesis::appendSuffix(string &root, const string suffix) {
04149     if (root[root.length()-1] == ' ') {
04150         root.erase(root.length());
04151         root += suffix + " ";
04152     } else {
04153         root += suffix;
04154     }
04155 }
04156 
04157 // *****************************************************************************
04158 // LvalRef constructors
04159 //
04164 //
04165 // *****************************************************************************
04166 VerilogSynthesis::LvalRef::LvalRef(string c, int b) {
04167     type = LVAL_FUNCTION;
04168     functionLvalName = c;
04169     functionLvalBit = b;
04170 }
04171 
04172 
04173 // *****************************************************************************
04174 // LvalRef constructors
04175 //
04179 //
04180 // *****************************************************************************
04181 VerilogSynthesis::LvalRef::LvalRef(oa::oaModBitNet* n) {
04182     type = VerilogSynthesis::LVAL_UNCONDITIONAL;
04183     unconditionalLval = n;
04184 }
04185 
04186 
04187 // *****************************************************************************
04188 // LvalRef constructors
04189 //
04194 //
04195 // *****************************************************************************
04196 VerilogSynthesis::LvalRef::LvalRef() {
04197     type = LVAL_CONDITIONAL;
04198 }
04199 
04200 
04201 // *****************************************************************************
04202 // LvalRef::addConditional
04203 //
04208 //
04209 // *****************************************************************************
04210 void
04211 VerilogSynthesis::LvalRef::addConditional(oa::oaModBitNet *n, MultiRef c) {
04212     assert(type == LVAL_CONDITIONAL);
04213     conditionalLval.push_back(ConditionalLvalRef(n,c));
04214 }
04215 
04216 // *****************************************************************************
04217 // printBitNetName()
04218 //
04219 // *****************************************************************************
04220 
04221 string
04222 VerilogSynthesis::printBitNetName(oa::oaModBitNet *n) {
04223     stringstream str;
04224     oa::oaName name;
04225     n->getName(name);
04226     if(name.getVectorBit()){
04227         oa::oaString baseName;
04228         name.getVectorBit()->getBaseName(baseName);
04229         str << baseName << "_" << name.getVectorBit()->getIndex();
04230     } else {
04231         oa::oaString scalarName;
04232         assert(name.getScalar());
04233         name.getScalar()->get(scalarName);
04234         str << scalarName;
04235     }
04236     return str.str();
04237 }
04238 
04239 }

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