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
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
00031
00035
00036
00037
00038 void
00039 VerilogSynthesis::synthesize(VerilogDesign *vDesign) {
00040 assert(vDesign);
00041
00042
00043 nameSpace = new oa::oaVerilogNS();
00044
00045
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;
00051 synthesizeModule(vModule, emptyParameters);
00052 }
00053 }
00054
00055 delete nameSpace;
00056 }
00057
00058
00059
00060
00062
00068
00069
00070 string
00071 VerilogSynthesis::getParameterizedModuleName(VerilogDesign::Module *vModule,
00072 list<ConstantValue> ¶meters) {
00073 assert(vModule);
00074
00075 string parameterizedModuleName(vModule->name);
00076 ParameterValues localParameters;
00077 bool nonDefault = false;
00078
00079
00080 if (parameters.size() == 0)
00081 return parameterizedModuleName;
00082
00083
00084 list<ConstantValue>::iterator it1 = parameters.begin();
00085 list<VerilogDesign::Declaration*>::iterator it2 = vModule->parameters.begin();
00086 while(it2 != vModule->parameters.end()) {
00087
00088 ConstantValue c;
00089 evaluateConstantExpression(c, (*it2)->value, &localParameters );
00090
00091 if (it1 == parameters.end()) {
00092
00093 stringstream suffix;
00094 suffix << "_" << c.intValue;
00095 appendSuffix(parameterizedModuleName, suffix.str());
00096
00097 localParameters[(*it2)->name] = c;
00098 ++it2;
00099 } else {
00100
00101 if (it1->intValue != c.intValue) {
00102 nonDefault = true;
00103 }
00104
00105
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
00116 if (it1 != parameters.end()) {
00117 cerr << "WARNING: Too many parameters for module " << vModule->name <<
00118 ". Ignoring extra" << endl;
00119 }
00120
00121
00122 if (!nonDefault) {
00123 parameterizedModuleName = vModule->name;
00124 }
00125
00126
00127 return parameterizedModuleName;
00128 }
00129
00130
00131
00132
00133
00141
00142
00143
00144 void
00145 VerilogSynthesis::synthesizeModule(VerilogDesign::Module *vModule,
00146 list<ConstantValue> ¶meters) {
00147
00148 assert(vModule);
00149 assert(nameSpace);
00150 currentVmodule = vModule;
00151
00152
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
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
00175 if (it_par != parameters.end()) {
00176 cerr << "WARNING: Too many parameters for module " << vModule->name <<
00177 ". Ignoring extra" << endl;
00178 }
00179
00180
00181 string parameterizedModuleName = getParameterizedModuleName(vModule,
00182 parameters);
00183 DEBUG_PRINTLN("module " << parameterizedModuleName);
00184
00185 currentModule = createModule(parameterizedModuleName);
00186
00187 currentManager = NULL;
00188
00189
00190 synthesizeModuleNets();
00191 synthesizeModuleTerms();
00192 synthesizeModuleAssigns();
00193 synthesizeModuleInsts();
00194 synthesizeModuleFunc();
00195
00196
00197 if (currentManager) {
00198 ModGraph::connectEquivalentNetsInGraph(currentModule);
00199 #ifdef DEBUG
00200 currentManager->print(cout);
00201 #endif
00202 }
00203
00204
00205 currentVmodule = NULL;
00206 assert(currentParams);
00207 delete currentParams;
00208 currentParams = NULL;
00209
00210
00211 finishedModules.insert(parameterizedModuleName);
00212 DEBUG_PRINTLN("endmodule " << parameterizedModuleName);
00213 }
00214
00215
00216
00217
00222
00223 void
00224 VerilogSynthesis::synthesizeModuleNets() {
00225
00226
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
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
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
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
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
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
00372
00377
00378 void
00379 VerilogSynthesis::synthesizeModuleTerms() {
00380
00381
00382
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
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
00433
00442
00443 void
00444 VerilogSynthesis::synthesizeModuleAssigns() {
00445
00446
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
00466
00467
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
00486
00492
00493 void
00494 VerilogSynthesis::synthesizeModuleInsts() {
00495
00496
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
00506
00507
00508
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
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
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
00585 if(instVmodule) {
00586
00587 list<ConstantValue> instParameters;
00588 for(list<VerilogDesign::Expression*>::iterator paramIter =
00589 instantiation->parameters->begin(); paramIter !=
00590 instantiation->parameters->end(); ++ paramIter) {
00591
00592 ConstantValue c;
00593 evaluateConstantExpression(c, *paramIter, currentParams);
00594 instParameters.push_back(c);
00595 }
00596
00597
00598 string parameterizedInstName =
00599 getParameterizedModuleName(instVmodule, instParameters);
00600 DEBUG_PRINTLN("\t instance of Verilog module " <<
00601 parameterizedInstName << " named " << instantiation->name);
00602
00603
00604 master = findModule(parameterizedInstName);
00605 if(master == NULL) {
00606
00607
00608
00609 oa::oaModule *lastModule = currentModule;
00610 VerilogDesign::Module *lastVmodule = currentVmodule;
00611 Manager *lastManager = currentManager;
00612 ParameterValues *lastParams = currentParams;
00613
00614
00615 synthesizeModule(instVmodule, instParameters);
00616 master = currentModule;
00617
00618
00619 currentParams = lastParams;
00620 currentModule = lastModule;
00621 currentManager = lastManager;
00622 currentVmodule = lastVmodule;
00623 }
00624
00625 }
00626
00627
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
00635 cerr << "ERROR: No Verilog or pre-existing definition of \
00636 module " << instantiation->type << endl;
00637 QUIT_ON_ERROR;
00638 }
00639
00640
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
00650 oa::oaModInst *inst = instantiateModule(master->getDesign(),
00651 instantiation->name);
00652
00653
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
00661 MultiRefBus value;
00662 if (connection->value == NULL) {
00663
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
00678
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
00692
00693 oa::oaModBitNet *net;
00694
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
00701
00702
00703
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
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
00722
00723
00724 oa::oaModBusNet *bus = createBusNet(dummyName,
00725 value.size()-1,0);
00726
00727
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
00738 QUIT_ON_INTERNAL_ERROR;
00739 }
00740 ++bitIter; ++b;
00741 }
00742
00743
00744
00745
00746
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
00769
00775
00776 void
00777 VerilogSynthesis::synthesizeModuleFunc()
00778 {
00779
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
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
00816
00817
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
00829
00830
00831
00832
00833 MultiRef curClock;
00834 if(state.isRegister) {
00835
00836
00837
00838
00839
00840
00841
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
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
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
00900
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
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
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
00969
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
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011 } else {
01012 assignMultiRef(it->first, it->second);
01013 }
01014 }
01015 }
01016 }
01017
01018
01019
01020
01023
01024
01025 void
01026 VerilogSynthesis::synthesizeBlock(VerilogDesign::Statement *statement,
01027 ProceduralState &state,
01028 ParameterValues *parameters)
01029 {
01030
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
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
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
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
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
01144
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
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
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
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
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
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
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
01235
01236 }else if(state.isRegister) {
01237
01238
01239
01240 state.blockingAssignments[it->first] = mux(select,
01241 MultiRef(it->first), it->second);
01242 }else{
01243
01244
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
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
01268
01269 state.nonblockingAssignments[it->first] = mux(select,
01270 elseState.nonblockingAssignments[it->first],
01271 it->second);
01272 }else if(state.isRegister) {
01273
01274
01275
01276 state.nonblockingAssignments[it->first] = mux(select,
01277 MultiRef(it->first), it->second);
01278 }else{
01279
01280
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
01299
01300 }else if(state.isRegister) {
01301
01302
01303
01304 state.nonblockingAssignments[it->first] = mux(select,
01305 MultiRef(it->first), it->second);
01306 }else{
01307
01308
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
01324
01325
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
01338
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
01346
01347
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
01360
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
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
01386
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
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
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
01415 cerr << "ERROR: CASEX is unimplemented yet ... "
01416 << endl;
01417 QUIT_ON_ERROR;
01418 } else if (statement->type ==
01419 VerilogDesign::Statement::CASEZ) {
01420
01421 cerr << "ERROR: CASEZ is unimplemented yet ... "
01422 << endl;
01423 QUIT_ON_ERROR;
01424 }
01425
01426 }
01427
01428 }
01429
01430 }
01431
01432
01433
01434 DEBUG_PRINTLN("\t\t an easy case is identified");
01435
01436
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
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
01457
01458
01459
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
01471
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
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
01494 DEBUG_PRINTLN("\t\t case label conditions=" <<
01495 c->conditions->size());
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
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
01528 cerr << "ERROR: CASEX is unimplemented yet ... " << endl;
01529 QUIT_ON_ERROR;
01530 } else if (statement->type == VerilogDesign::Statement::CASEZ) {
01531
01532 cerr << "ERROR: CASEZ is unimplemented yet ... " << endl;
01533 QUIT_ON_ERROR;
01534 } else {
01535 caseMatchesCondition.push_back(caseConstantCondition);
01536 }
01537 }
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 }
01549
01550 if(action == NULL)
01551 cerr << "Error: action is not NULL\n";
01552
01553
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
01563
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
01577
01578 if(preActionAssignment == state.nonblockingAssignments.end() ||
01579 !(postActionAssignment->second ==
01580 preActionAssignment->second)) {
01581 modifiednonblockingAssignments.insert(postActionAssignment->first);
01582 }
01583 }
01584 }
01585
01586 }
01587
01588
01589
01590
01591
01592 int numSelectBits = condition.size();
01593
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
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
01616 for(int selectCur = 0; selectCur < selectMax; ++ selectCur)
01617 if(selectBitMap[selectCur] == false)
01618 defaultSelect.push_back(selectCur);
01619
01620
01621
01622
01623 for(set<oa::oaModBitNet*>::iterator bitIter =
01624 modifiedBlockingAssignments.begin(); bitIter !=
01625 modifiedBlockingAssignments.end(); ++ bitIter) {
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
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
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
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
01675 if(defaultAction != NULL) {
01676 if(defaultAction->blockingAssignments.find(*bitIter) ==
01677 defaultAction->blockingAssignments.end()) {
01678
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
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
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
01712
01713
01714
01715
01716
01717 oa::oaString str;
01718 (*bitIter)->getName(*nameSpace, str);
01719 cerr << "NOTE: Implicit latch on net " <<
01720 currentVmodule->name << "." << str << endl;
01721
01722
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
01730 MultiRef combinationalOutput = mux(condition, muxDataList);
01731
01732 MultiRefBus latchEnableBitMapList;
01733 back_insert_iterator<MultiRefBus > latchEnableBIIter(latchEnableBitMapList);
01734 copy(latchEnableBitMap.begin(), latchEnableBitMap.end(), latchEnableBIIter);
01735
01736 MultiRef latchEnableBit = mux(condition, latchEnableBitMapList);
01737
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
01748
01749
01750
01751
01752
01753
01754
01755
01756
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
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
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
01794 if(defaultAction != NULL) {
01795 if(defaultAction->nonblockingAssignments.find(*bitIter) ==
01796 defaultAction->nonblockingAssignments.end()) {
01797
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
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
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
01830
01831
01832
01833
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
01846 MultiRef combinationalOutput = mux(condition, muxDataList);
01847
01848 MultiRefBus latchEnableBitMapList;
01849 back_insert_iterator<MultiRefBus > latchEnableBIIter(latchEnableBitMapList);
01850 copy(latchEnableBitMap.begin(), latchEnableBitMap.end(), latchEnableBIIter);
01851
01852 MultiRef latchEnableBit = mux(condition, latchEnableBitMapList);
01853
01854 state.blockingAssignments[*bitIter] = latch(latchEnableBit,
01855 combinationalOutput);
01856
01857 }
01858 }
01859
01860
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
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
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
01895
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
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
01919 DEBUG_PRINTLN("\t\t case label conditions=" <<
01920 c->conditions->size());
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
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
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
01968 cerr << "ERROR: CASEX is unimplemented yet ... "
01969 << endl;
01970 QUIT_ON_ERROR;
01971 } else if (statement->type ==
01972 VerilogDesign::Statement::CASEZ) {
01973
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 }
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
01997
01998 defaultSelect = orOf(defaultSelect, select);
01999
02000 }
02001
02002
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
02015
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
02033
02034 if(preActionAssignment ==
02035 state.nonblockingAssignments.end() ||
02036 !(postActionAssignment->second ==
02037 preActionAssignment->second)) {
02038 modifiednonblockingAssignments.insert(postActionAssignment->first);
02039 }
02040
02041 }
02042 }
02043
02044 }
02045
02046
02047 defaultSelect = notOf(defaultSelect);
02048
02049
02050
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
02067 latchTerms.push_back(*selectsIter);
02068 }else {
02069
02070 muxTerms.push_back(andOf(*selectsIter,
02071 (*actionIter)->blockingAssignments[*bitIter]));
02072 }
02073
02074 ++ selectsIter; ++ actionIter;
02075 }
02076
02077
02078 if(defaultAction != NULL) {
02079 if(defaultAction->blockingAssignments.find(*bitIter) ==
02080 defaultAction->blockingAssignments.end()) {
02081
02082 latchTerms.push_back(defaultSelect);
02083 }else{
02084
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
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
02122 latchTerms.push_back(*selectsIter);
02123 }else {
02124
02125 muxTerms.push_back(andOf(*selectsIter,
02126 (*actionIter)->nonblockingAssignments[*bitIter]));
02127 }
02128
02129 ++ selectsIter; ++ actionIter;
02130 }
02131
02132
02133 if(defaultAction != NULL) {
02134 if(defaultAction->nonblockingAssignments.find(*bitIter) ==
02135 defaultAction->nonblockingAssignments.end()) {
02136
02137 latchTerms.push_back(defaultSelect);
02138 }else{
02139
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
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
02163 for(list<ProceduralState *>::iterator actionIter =
02164 caseActions.begin(); actionIter != caseActions.end(); ++
02165 actionIter) {
02166 delete (*actionIter);
02167 }
02168
02169 }
02170
02171
02172
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
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
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
02219
02220 DEBUG_PRINTLN("\t\t\t" << "LVAL_CONDITIONAL occurs!!");
02221 QUIT_ON_INTERNAL_ERROR;
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
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
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
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
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
02317
02318 DEBUG_PRINTLN("\t\t\t" << "LVAL_CONDITIONAL occurs!!");
02319 QUIT_ON_INTERNAL_ERROR;
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
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
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 }
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 }
02398
02399 case VerilogDesign::Statement::BLOCKING_ASSIGNMENT:
02400 {
02401 synthesizeBlockingassignment(statement, state, parameters);
02402 break;
02403 }
02404
02405 case VerilogDesign::Statement::NONBLOCKING_ASSIGNMENT:
02406 {
02407 synthesizeNonblockingassignment(statement, state, parameters);
02408 break;
02409 }
02410
02411 default:
02412 QUIT_ON_INTERNAL_ERROR;
02413 }
02414 }
02415
02416
02417
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
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
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
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
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
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
02738 else if (state && state->isFunction) {
02739 cerr << "ERROR: function is not supported so far" << endl;
02740 QUIT_ON_ERROR;
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786 break;
02787 }
02788
02789
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
02801
02802
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
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891 }
02892
02893
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
02910
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
02923
02924 cerr << "ERROR: Index of net" << expression->primary->name
02925 << " must be a constant" << endl;
02926 QUIT_ON_ERROR;
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
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
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
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
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
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
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
03099 else if (state && state->isFunction) {
03100
03101 cerr << "ERROR: Function calls are currently unimplemented" << endl;
03102 QUIT_ON_ERROR;
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149 break;
03150 }
03151
03152
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
03159
03160
03161
03162
03163
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
03171
03172
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
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266 }
03267
03268
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
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
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
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521
03522 } else {
03523 QUIT_ON_INTERNAL_ERROR;
03524 }
03525
03526 break;
03527 }
03528
03529 case VerilogDesign::Expression::BUNDLE:
03530
03531
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
03566
03567
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
03863
03864
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
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903
03904
03905
03906
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938
03939
03940
03941
03942
03943
03944
03945
03946
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
03958
03959
03960
03961
03962
03963
03964
03965
03966
03967
03968
03969
03970
03971
03972
03973
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985
03986
03987
03988
03989
03990
03991
03992
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008
04009
04010
04011
04012
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
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
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
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
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
04175
04179
04180
04181 VerilogSynthesis::LvalRef::LvalRef(oa::oaModBitNet* n) {
04182 type = VerilogSynthesis::LVAL_UNCONDITIONAL;
04183 unconditionalLval = n;
04184 }
04185
04186
04187
04188
04189
04194
04195
04196 VerilogSynthesis::LvalRef::LvalRef() {
04197 type = LVAL_CONDITIONAL;
04198 }
04199
04200
04201
04202
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
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 }