00001 #include "oagFpgaRtlGraph.h"
00002 #include "oagFpgaDebug.h"
00003
00004 using namespace std;
00005
00006 namespace oagFpga {
00007
00008
00009
00010 const char* RtlNode::funcTypeName [] = {"NULL_FUNC", "TERMINAL", "CONTROL",
00011 "OPERATOR", "SEQ", "CONSTANT0", "CONSTANT1"};
00012 const char* RtlNode::optTypeName [] = {
00013 "UNKNOWN", "PRIMARY", "BUNDLE", "BITWISE_AND", "BITWISE_NAND", "BITWISE_OR", "BITWISE_NOR",
00014 "BITWISE_XOR", "BITWISE_XNOR", "BITWISE_NOT", "LOGICAL_AND", "LOGICAL_NOT", "LOGICAL_OR",
00015 "REDUCTION_AND", "REDUCTION_OR", "REDUCTION_XOR", "REDUCTION_NAND", "REDUCTION_NOR",
00016 "REDUCTION_XNOR", "LESS_THAN", "LESS_THAN_EQUAL", "GREATER_THAN", "GREATER_THAN_EQUAL",
00017 "EQUAL", "NOTEQUAL", "IF_ELSE", "LEFT_SHIFT", "RIGHT_SHIFT", "ADD", "SUBTRACT", "MULTIPLY",
00018 "DIVIDE", "MODULO", "NEGATE"
00019 };
00020 const char* RtlNode::seqTypeName [] = {
00021 "DFF", "LATCH"
00022 };
00023
00024
00025
00026
00029
00030
00031 BBRef
00032 RtlGraph::unaryOpt(RtlNode::OptType ot, BBRef driver) {
00033
00034
00035 RtlNode* node = newNode();
00036 node->funcType = RtlNode::OPERATOR;
00037 node->optType = ot;
00038 addNode(node);
00039 node->optInfo = new RtlNode::RtlOptNodeInfo();
00040
00041
00042 node->fanin.push_back(driver);
00043 getNode(driver)->fanout.push_back(node->self);
00044
00045
00046 node->optInfo->op1.push_back(driver);
00047
00048 return node->self;
00049 }
00050
00051
00052
00053
00056
00057
00058 BBRef
00059 RtlGraph::binaryOpt(RtlNode::OptType ot, BBRef in1, BBRef in2) {
00060
00061
00062 RtlNode* node = newNode();
00063 node->funcType = RtlNode::OPERATOR;
00064 node->optType = ot;
00065 addNode(node);
00066 node->optInfo = new RtlNode::RtlOptNodeInfo();
00067
00068
00069 node->fanin.push_back(in1);
00070 node->fanin.push_back(in2);
00071 getNode(in1)->fanout.push_back(node->self);
00072 getNode(in2)->fanout.push_back(node->self);
00073
00074
00075 node->optInfo->op1.push_back(in1);
00076 node->optInfo->op1.push_back(in2);
00077
00078 return node->self;
00079 }
00080
00081
00082
00083
00086
00087
00088 BBRef
00089 RtlGraph::unaryBusOpt(RtlNode::OptType ot, vector<BBRef>& ins) {
00090
00091
00092 RtlNode* node = newNode();
00093 node->funcType = RtlNode::OPERATOR;
00094 node->optType = ot;
00095 addNode(node);
00096 node->optInfo = new RtlNode::RtlOptNodeInfo();
00097
00098
00099 for(vector<BBRef>::iterator bbRefIter = ins.begin(); bbRefIter != ins.end();
00100 ++ bbRefIter) {
00101 BBRef ref = *bbRefIter;
00102 node->fanin.push_back(ref);
00103 getNode(ref)->fanout.push_back(node->self);
00104
00105
00106 node->optInfo->op1.push_back(ref);
00107 }
00108
00109 return node->self;
00110 }
00111
00112
00113
00114
00117
00118
00119 BBRef
00120 RtlGraph::binaryBusOpt(RtlNode::OptType ot, vector<BBRef>& in1,
00121 vector<BBRef>& in2) {
00122
00123 assert(in1.size() == in2.size());
00124
00125
00126 RtlNode* node = newNode();
00127 node->funcType = RtlNode::OPERATOR;
00128 node->optType = ot;
00129 addNode(node);
00130 node->optInfo = new RtlNode::RtlOptNodeInfo();
00131
00132
00133 for(vector<BBRef>::iterator bbRefIter = in1.begin(); bbRefIter != in1.end();
00134 ++ bbRefIter) {
00135 BBRef ref = *bbRefIter;
00136 node->fanin.push_back(ref);
00137 getNode(ref)->fanout.push_back(node->self);
00138
00139 node->optInfo->op1.push_back(ref);
00140 }
00141 for(vector<BBRef>::iterator bbRefIter = in2.begin(); bbRefIter != in2.end();
00142 ++ bbRefIter) {
00143 BBRef ref = *bbRefIter;
00144 node->fanin.push_back(ref);
00145 getNode(ref)->fanout.push_back(node->self);
00146
00147 node->optInfo->op2.push_back(ref);
00148 }
00149
00150 return node->self;
00151 }
00152
00153
00154
00155
00158
00159
00160 void
00161 RtlGraph::binaryBusInputOutputOpt(RtlNode::OptType ot,
00162 int numOutBits, vector<BBRef>& in1,
00163 vector<BBRef>& in2, vector<BBRef>& out) {
00164
00165 assert(in1.size() == in2.size());
00166
00167
00168
00169
00170
00171
00172 RtlNode* node = newNode();
00173 node->funcType = RtlNode::OPERATOR;
00174 node->optType = ot;
00175 node->numOutputBits = numOutBits;
00176
00177 addNode(node);
00178 node->optInfo = new RtlNode::RtlOptNodeInfo();
00179
00180
00181 for(vector<BBRef>::iterator bbRefIter = in1.begin(); bbRefIter != in1.end();
00182 ++ bbRefIter) {
00183 BBRef ref = *bbRefIter;
00184 node->fanin.push_back(ref);
00185 getNode(ref)->fanout.push_back(node->self);
00186
00187 node->optInfo->op1.push_back(ref);
00188 }
00189 for(vector<BBRef>::iterator bbRefIter = in2.begin(); bbRefIter != in2.end();
00190 ++ bbRefIter) {
00191 BBRef ref = *bbRefIter;
00192 node->fanin.push_back(ref);
00193 getNode(ref)->fanout.push_back(node->self);
00194
00195 node->optInfo->op2.push_back(ref);
00196 }
00197
00198
00199 out.push_back(node->self);
00200 for(int i=1;i<numOutBits;i++){
00201 bbNodes.push_back(node);
00202 out.push_back(node->self+i);
00203 }
00204
00205 }
00206
00207
00208
00209
00212
00213
00214 void
00215 RtlGraph::unaryBusInputOutputOpt(RtlNode::OptType ot, int numOutBits,
00216 vector<BBRef>& in1, vector<BBRef>& out) {
00217
00218 assert(numOutBits > 1);
00219
00220
00221 RtlNode* node = newNode();
00222 node->funcType = RtlNode::OPERATOR;
00223 node->optType = ot;
00224 node->numOutputBits = numOutBits;
00225
00226 addNode(node);
00227 node->optInfo = new RtlNode::RtlOptNodeInfo();
00228
00229
00230 for(vector<BBRef>::iterator bbRefIter = in1.begin(); bbRefIter != in1.end();
00231 ++ bbRefIter) {
00232 BBRef ref = *bbRefIter;
00233 node->fanin.push_back(ref);
00234 getNode(ref)->fanout.push_back(node->self);
00235
00236 node->optInfo->op1.push_back(ref);
00237 }
00238
00239
00240 out.push_back(node->self);
00241 for(int i=1;i<numOutBits;i++){
00242 bbNodes.push_back(node);
00243 out.push_back(node->self+i);
00244 }
00245 }
00246
00247
00248
00249
00250
00259
00260
00261
00262 BBRef
00263 RtlGraph::bitSeq(RtlNode::SeqType st, BBRef D, BBRef clock,
00264 BBRef aLoad, BBRef aData) {
00265
00266
00267 RtlNode* node = newNode();
00268 node->funcType = RtlNode::SEQ;
00269 node->seqType = st;
00270 addNode(node);
00271
00272
00273 if(st == RtlNode::LATCH){
00274 node->seqInfo = new RtlNode::RtlSeqNodeInfo(D, clock, getNull(),
00275 getNull());
00276 node->fanin.push_back(D);
00277 getNode(D)->fanout.push_back(node->self);
00278 node->fanin.push_back(clock);
00279 getNode(clock)->fanout.push_back(node->self);
00280 }else{
00281 assert(st == RtlNode::DFF);
00282 node->seqInfo = new RtlNode::RtlSeqNodeInfo(D, clock, aLoad, aData);
00283 node->fanin.push_back(D);
00284 node->fanin.push_back(clock);
00285 node->fanin.push_back(aLoad);
00286 node->fanin.push_back(aData);
00287 getNode(D)->fanout.push_back(node->self);
00288 getNode(clock)->fanout.push_back(node->self);
00289 getNode(aLoad)->fanout.push_back(node->self);
00290 getNode(aData)->fanout.push_back(node->self);
00291 }
00292
00293 return node->self;
00294
00295 }
00296
00297 BBRef
00298 RtlGraph::bitSeq(RtlNode::SeqType st, BBRef D) {
00299
00300 return bitSeq(st, D, getNull(), getNull(), getNull());
00301 }
00302
00303
00305
00306
00307
00308
00309
00310
00311
00312
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00327
00328
00329
00330
00331
00332
00333
00334
00335
00339
00340
00341
00342 BBRef
00343 RtlGraph::bitMux(BBRef in1, BBRef in2, BBRef sel) {
00344
00345
00346 RtlNode* node = newNode();
00347 node->funcType = RtlNode::CONTROL;
00348 addNode(node);
00349
00350 node->fanin.push_back(in1);
00351 node->fanin.push_back(in2);
00352 node->fanin.push_back(sel);
00353 getNode(in1)->fanout.push_back(node->self);
00354 getNode(in2)->fanout.push_back(node->self);
00355 getNode(sel)->fanout.push_back(node->self);
00356
00357
00358 node->muxInfo = new RtlNode::RtlMuxNodeInfo();
00359 node->muxInfo->in.push_back(in1);
00360 node->muxInfo->in.push_back(in2);
00361 node->muxInfo->sel.push_back(sel);
00362
00363 return node->self;
00364 }
00365
00366
00367
00368
00372
00373
00374
00375 BBRef
00376 RtlGraph::busMux(vector<BBRef>& in, vector<BBRef>& sel) {
00377
00378
00379 RtlNode* node = newNode();
00380 node->funcType = RtlNode::CONTROL;
00381 addNode(node);
00382
00383 vector<BBRef>::iterator bbRefIter;
00384
00385
00386 for(bbRefIter = in.begin(); bbRefIter != in.end(); ++ bbRefIter) {
00387 node->fanin.push_back(*bbRefIter);
00388 getNode(*bbRefIter)->fanout.push_back(node->self);
00389 }
00390 for(bbRefIter = sel.begin(); bbRefIter != sel.end(); ++ bbRefIter) {
00391 node->fanin.push_back(*bbRefIter);
00392 getNode(*bbRefIter)->fanout.push_back(node->self);
00393 }
00394
00395
00396 node->muxInfo = new RtlNode::RtlMuxNodeInfo();
00397 back_insert_iterator<list<BBRef> > biiIn(node->muxInfo->in);
00398 copy(in.begin(), in.end(), biiIn);
00399 back_insert_iterator<list<BBRef> > biiSel(node->muxInfo->in);
00400 copy(in.begin(), in.end(), biiSel);
00401 copy(sel.begin(), sel.end(), biiSel);
00402
00403 return node->self;
00404 }
00405
00406
00407
00408
00412
00413
00414
00415 void
00416 RtlGraph::busMux(vector<BBRef>& in1, vector<BBRef>& in2, vector<BBRef>& sel,
00417 vector<BBRef>& outputs) {
00418
00419
00420 QUIT_ON_INTERNAL_ERROR;
00421
00422 assert(in1.size() == in2.size());
00423
00424
00425 RtlNode* node = newNode();
00426 node->funcType = RtlNode::CONTROL;
00427 node->numOutputBits = in1.size();
00428
00429 addNode(node);
00430
00431 vector<BBRef>::iterator bbRefIter;
00432
00433
00434 for(bbRefIter = in1.begin(); bbRefIter != in1.end(); ++ bbRefIter) {
00435 node->fanin.push_back(*bbRefIter);
00436 getNode(*bbRefIter)->fanout.push_back(node->self);
00437 }
00438 for(bbRefIter = in2.begin(); bbRefIter != in2.end(); ++ bbRefIter) {
00439 node->fanin.push_back(*bbRefIter);
00440 getNode(*bbRefIter)->fanout.push_back(node->self);
00441 }
00442 for(bbRefIter = sel.begin(); bbRefIter != sel.end(); ++ bbRefIter) {
00443 node->fanin.push_back(*bbRefIter);
00444 getNode(*bbRefIter)->fanout.push_back(node->self);
00445 }
00446
00447
00448 for(size_t i=0;i<in1.size();i++){
00449 bbNodes.push_back(node);
00450 outputs.push_back(node->self+i);
00451 }
00452
00453
00454 }
00455
00456
00457
00458
00462
00463
00464 void
00465 RtlGraph::addNode(RtlNode* node) {
00466
00467 node->self = bbNodes.size();
00468 bbNodes.push_back(node);
00469
00470
00471 }
00472
00473 RtlNode* RtlGraph::newNode() {
00474 RtlNode* node = new RtlNode();
00475 dataBBNodes.push_back(node);
00476 node->self = BBRef(-1);
00477 node->funcType = RtlNode::NULL_FUNC;
00478 return node;
00479 }
00480
00481 BBRef
00482 RtlGraph::newTerminal(BBRef driver) {
00483
00484
00485 RtlNode *node = newNode();
00486 addNode(node);
00487 node->funcType = RtlNode::TERMINAL;
00488 node->fanin.push_back(driver);
00489
00490
00491 getNode(driver)->fanout.push_back(node->self);
00492
00493 DEBUG_PRINTLN("new TERM = " << node->self << " \tdriver=" << driver);
00494 return node->self;
00495 }
00496
00497
00498
00499
00508
00509
00510 void
00511 RtlGraph::removeFromFanout(BBRef x, BBRef fanout) {
00512 if (isNull(x) || isNull(fanout))
00513 return;
00514
00515 RtlNode *node = getNode(x);
00516
00517 list<BBRef>::iterator it = node->fanout.begin();
00518 while(it != node->fanout.end()) {
00519 BBRef current = *it;
00520 if (current == fanout) {
00521 node->fanout.erase(it);
00522 return;
00523 }
00524 ++it;
00525 }
00526
00527
00528 cerr << "ERROR: Node " << fanout << " not found in fanout of " << x << endl;
00529 QUIT_ON_INTERNAL_ERROR;
00530 }
00531
00532
00533
00534
00541
00542
00543 void
00544 RtlGraph::setTerminalDriver(BBRef terminal, BBRef driver) {
00545 RtlNode *node = getNode(terminal);
00546 assert(node);
00547 assert(node->funcType == RtlNode::TERMINAL);
00548
00549
00550
00551
00552
00553
00554
00555 removeFromFanout(node->fanin.front(), terminal);
00556
00557 assert(node->fanin.size() == 1);
00558 node->fanin.front() = driver;
00559
00560 getNode(driver)->fanout.push_back(terminal);
00561 }
00562
00563
00564
00565
00568
00569
00570 void
00571 RtlGraph::print(ostream& os, RtlNode* node) {
00572 os << "BBNode " << node->self << ":" << RtlNode::funcTypeName[node->funcType];
00573 if(node->funcType == RtlNode::OPERATOR)
00574 os << "." << RtlNode::optTypeName[node->optType];
00575 else if(node->funcType == RtlNode::SEQ)
00576 os << "." << RtlNode::seqTypeName[node->seqType];
00577 }
00578
00579
00580
00581
00584
00585
00586 void
00587 RtlGraph::print(ostream& os) {
00588 os << "========================================================" << endl;
00589 os << "Begin of RtlGraph:" << endl;
00590
00591
00592 for(vector<RtlNode*>::iterator bbIter = dataBBNodes.begin(); bbIter !=
00593 dataBBNodes.end(); ++ bbIter){
00594 RtlNode* node = *bbIter;
00595 print(os, node);
00596 os << endl;
00597 }
00598
00599
00600 for(vector<RtlNode*>::iterator bbIter = bbNodes.begin(); bbIter !=
00601 bbNodes.end(); ++ bbIter){
00602 RtlNode* node = *bbIter;
00603
00604 os << "N" << node->self << ": " << endl;
00605 os << "Fanouts: ";
00606 for(list<BBRef>::iterator listIter = node->fanout.begin(); listIter !=
00607 node->fanout.end(); ++ listIter){
00608 os << getNode(*listIter)->self << ",";
00609 }
00610 os << endl;
00611
00612 os << "Fanins: ";
00613 for(list<BBRef>::iterator listIter = node->fanin.begin(); listIter !=
00614 node->fanin.end(); ++ listIter){
00615 os << getNode(*listIter)->self << ",";
00616 }
00617 os << endl;
00618 }
00619
00620 os << "End of RtlGraph:" << endl;
00621 os << "========================================================" << endl;
00622 os.flush();
00623 }
00624
00625
00627
00628
00629
00630
00631
00650
00651 unsigned int
00652 RtlGraph::newTraversalID() {
00653
00654
00655
00656 if (++currentTraversalID == 0) {
00657 for(vector<RtlNode*>::iterator nodeIter = dataBBNodes.begin(); nodeIter
00658 != dataBBNodes.end(); ++ nodeIter){
00659 (*nodeIter)->traversalID = 0;
00660 }
00661 currentTraversalID = 1;
00662 }
00663
00664 return currentTraversalID;
00665 }
00666
00667
00668
00669
00678
00679
00680 bool
00681 RtlGraph::hasCombinationalCycle() {
00682 unsigned int startingTravID = newTraversalID();
00683
00684 for(vector<RtlNode*>::iterator nodeIter = dataBBNodes.begin(); nodeIter !=
00685 dataBBNodes.end(); ++ nodeIter){
00686 newTraversalID();
00687 RtlNode* node = *nodeIter;
00688 BBRef ref = node->self;
00689 if (hasCombinationalCycle_recursive(ref, startingTravID)) {
00690 DEBUG_PRINTLN("Combinational cycle on node " << ref);
00691 return true;
00692 }
00693 }
00694
00695 return false;
00696 }
00697
00698
00699
00700
00701
00705
00706
00707 bool
00708 RtlGraph::hasCombinationalCycle_recursive(BBRef x, unsigned int startingTravID) {
00709
00710 if (isNull(x)) {
00711 return false;
00712 }
00713 RtlNode *node = getNode(x);
00714
00715 if (node->funcType == RtlNode::SEQ
00716 || node->funcType == RtlNode::CONSTANT0
00717 || node->funcType == RtlNode::CONSTANT1) {
00718 return false;
00719 }
00720
00721 if (node->traversalID == currentTraversalID) {
00722 return true;
00723 }
00724
00725 if (node->traversalID >= startingTravID) {
00726 return false;
00727 }
00728 node->traversalID = currentTraversalID;
00729
00730 if (node->funcType == RtlNode::CONTROL || node->funcType == RtlNode::OPERATOR) {
00731 bool result = false;
00732 for(list<BBRef>::iterator refIter = node->fanin.begin(); refIter !=
00733 node->fanin.end(); ++ refIter)
00734 result = result || hasCombinationalCycle_recursive(*refIter, startingTravID);
00735 node->traversalID = startingTravID;
00736 return result;
00737 }
00738 else if (node->funcType == RtlNode::TERMINAL) {
00739 bool result = hasCombinationalCycle_recursive(getTerminalDriver(x), startingTravID);
00740 node->traversalID = startingTravID;
00741 return result;
00742 }
00743
00744 QUIT_ON_INTERNAL_ERROR;
00745 return false;
00746 }
00747
00748
00749
00750
00751
00773
00774
00775 void
00776 RtlGraph::getTransitiveFanin(BBRef x, vector<BBRef> &transitiveFanin,
00777 bool includeRoots, bool crossSequential) {
00778 newTraversalID();
00779 getTransitiveFanin_recursive(x, transitiveFanin, includeRoots, crossSequential);
00780
00781 transitiveFanin.pop_back();
00782 }
00783
00784
00785
00786
00787
00812
00813
00814 void
00815 RtlGraph::getTransitiveFanin(list<BBRef> x, vector<BBRef> &transitiveFanin,
00816 bool includeRoots, bool crossSequential) {
00817
00818
00819
00820 newTraversalID();
00821 for(list<BBRef>::iterator xIter = x.begin(); xIter != x.end(); xIter++) {
00822 getTransitiveFanin_recursive(*xIter, transitiveFanin,
00823 includeRoots, crossSequential);
00824
00825 transitiveFanin.pop_back();
00826 }
00827 }
00828
00829
00830
00831
00832
00836
00837
00838 void
00839 RtlGraph::getTransitiveFanin_recursive(BBRef x, vector<BBRef> &transitiveFanin,
00840 bool includeRoots, bool crossSequential) {
00841 markVisited(x);
00842
00843 vector<BBRef> fanin;
00844
00845 RtlNode *node = getNode(x);
00846
00847 switch(node->funcType) {
00848
00849 case RtlNode::CONTROL:
00850 case RtlNode::OPERATOR: {
00851 for(list<BBRef>::iterator refIter = node->fanin.begin(); refIter !=
00852 node->fanin.end(); ++ refIter)
00853 fanin.push_back(*refIter);
00854 break;
00855 }
00856 case RtlNode::TERMINAL:
00857 fanin.push_back(getTerminalDriver(x));
00858 break;
00859 case RtlNode::SEQ:
00860
00861
00862
00863
00864
00865
00866
00867 for(list<BBRef>::iterator refIter = node->fanin.begin(); refIter !=
00868 node->fanin.end(); ++ refIter)
00869 fanin.push_back(*refIter);
00870 break;
00871 case RtlNode::CONSTANT0:
00872 case RtlNode::CONSTANT1:
00873
00874 return;
00875 default:
00876 QUIT_ON_INTERNAL_ERROR;
00877 }
00878
00879 for(vector<BBRef>::iterator refIter = fanin.begin(); refIter != fanin.end();
00880 ++ refIter){
00881 BBRef currentFanin = *refIter;
00882 if (!isNull(currentFanin) && !isVisited(currentFanin)) {
00883 if (isTerminal(currentFanin) &&
00884 isNull(getTerminalDriver(currentFanin))
00885 || currentFanin == constantZero()
00886 || currentFanin == constantOne()
00887 || isSequential(currentFanin) && !crossSequential) {
00888
00889 if (includeRoots) {
00890 markVisited(currentFanin);
00891 transitiveFanin.push_back(currentFanin);
00892 }
00893 } else {
00894 getTransitiveFanin_recursive(currentFanin, transitiveFanin,
00895 includeRoots, crossSequential);
00896 }
00897 }
00898 }
00899
00900 transitiveFanin.push_back(x);
00901 }
00902
00903
00904
00905
00906
00928
00929
00930 void
00931 RtlGraph::getTransitiveFanin(BBRef x, list<BBRef> &transitiveFanin,
00932 bool includeRoots, bool crossSequential) {
00933 newTraversalID();
00934 getTransitiveFanin_recursive(x, transitiveFanin, includeRoots, crossSequential);
00935
00936 transitiveFanin.pop_back();
00937 }
00938
00939
00940
00941
00942
00964
00965
00966 void
00967 RtlGraph::getTransitiveFanin(list<BBRef> x, list<BBRef> &transitiveFanin,
00968 bool includeRoots, bool crossSequential) {
00969
00970
00971
00972 newTraversalID();
00973 for(list<BBRef>::iterator xIter = x.begin(); xIter!=x.end(); xIter++) {
00974 getTransitiveFanin_recursive(*xIter, transitiveFanin,
00975 includeRoots, crossSequential);
00976
00977 transitiveFanin.pop_back();
00978 }
00979 }
00980
00981
00982
00983
00987
00988
00989 void
00990 RtlGraph::getTransitiveFanin_recursive(BBRef x, list<BBRef> &transitiveFanin,
00991 bool includeRoots, bool crossSequential) {
00992 markVisited(x);
00993
00994 vector<BBRef> fanin;
00995
00996 RtlNode *node = getNode(x);
00997
00998 switch(node->funcType) {
00999 case RtlNode::CONTROL:
01000 case RtlNode::OPERATOR:
01001 for(list<BBRef>::iterator refIter = node->fanin.begin(); refIter !=
01002 node->fanin.end(); ++ refIter)
01003 fanin.push_back(*refIter);
01004 break;
01005 case RtlNode::TERMINAL:
01006 fanin.push_back(getTerminalDriver(x));
01007 break;
01008 case RtlNode::SEQ:
01009
01010
01011
01012
01013
01014
01015
01016 for(list<BBRef>::iterator refIter = node->fanin.begin(); refIter !=
01017 node->fanin.end(); ++ refIter)
01018 fanin.push_back(*refIter);
01019 break;
01020 case RtlNode::CONSTANT0:
01021 case RtlNode::CONSTANT1:
01022
01023 return;
01024 default:
01025 QUIT_ON_INTERNAL_ERROR;
01026 }
01027
01028 for(vector<BBRef>::iterator refIter = fanin.begin(); refIter != fanin.end();
01029 ++ refIter){
01030 BBRef currentFanin = *refIter;
01031 if (!isNull(currentFanin) && !isVisited(currentFanin)) {
01032 if (isTerminal(currentFanin) &&
01033 isNull(getTerminalDriver(currentFanin))
01034 || currentFanin == constantZero()
01035 || currentFanin == constantOne()
01036 || isSequential(currentFanin) && !crossSequential)
01037 {
01038
01039 if (includeRoots)
01040 {
01041 markVisited(currentFanin);
01042 transitiveFanin.push_back(currentFanin);
01043 }
01044 }
01045 else {
01046 getTransitiveFanin_recursive(currentFanin,
01047 transitiveFanin, includeRoots, crossSequential);
01048 }
01049 }
01050 }
01051
01052 transitiveFanin.push_back(x);
01053 }
01054
01055
01056
01057
01082
01083
01084 void
01085 RtlGraph::getTransitiveFanout(BBRef x, vector<BBRef> &transitiveFanout,
01086 bool includeRoots, bool crossSequential) {
01087 newTraversalID();
01088
01089 vector<BBRef> newReversedTransitiveFanout;
01090 getTransitiveFanout_recursive(x, newReversedTransitiveFanout, includeRoots, crossSequential);
01091
01092 newReversedTransitiveFanout.pop_back();
01093
01094 transitiveFanout.reserve(transitiveFanout.size()+newReversedTransitiveFanout.size());
01095 for(vector<BBRef>::reverse_iterator it = newReversedTransitiveFanout.rbegin();
01096 it != newReversedTransitiveFanout.rend(); it++) {
01097 transitiveFanout.push_back(*it);
01098 }
01099 }
01100
01101
01102
01103
01104
01132
01133
01134 void
01135 RtlGraph::getTransitiveFanout(list<BBRef> x, vector<BBRef> &transitiveFanout,
01136 bool includeRoots, bool crossSequential) {
01137
01138
01139
01140 newTraversalID();
01141 vector<BBRef> newReversedTransitiveFanout;
01142 for(list<BBRef>::iterator it = x.begin(); it != x.end(); it++) {
01143
01144 getTransitiveFanout_recursive(*it, newReversedTransitiveFanout,
01145 includeRoots, crossSequential);
01146
01147 newReversedTransitiveFanout.pop_back();
01148 }
01149
01150 transitiveFanout.reserve(transitiveFanout.size()+newReversedTransitiveFanout.size());
01151 for(vector<BBRef>::reverse_iterator it2 = newReversedTransitiveFanout.rbegin();
01152 it2 != newReversedTransitiveFanout.rend(); it2++) {
01153 transitiveFanout.push_back(*it2);
01154 }
01155 }
01156
01157
01158
01159
01160
01166
01167
01168 void
01169 RtlGraph::getTransitiveFanout_recursive(BBRef x, vector<BBRef> &transitiveFanout,
01170 bool includeRoots, bool crossSequential) {
01171 markVisited(x);
01172
01173 if (getNodeType(x) == RtlNode::TERMINAL &&
01174 hasFanout(x) && !includeRoots) {
01175
01176 return;
01177 }
01178
01179 const list<BBRef> *immediateFanout = &getFanout(x);
01180 for(list<BBRef>::const_iterator it = immediateFanout->begin();
01181 it != immediateFanout->end(); ++it) {
01182 BBRef next = *it;
01183
01184
01185 assert(!isNull(next));
01186 assert(getNodeType(next) != RtlNode::CONSTANT0);
01187 assert(getNodeType(next) != RtlNode::CONSTANT1);
01188
01189
01190 if (isVisited(next)) {
01191 continue;
01192 }
01193
01194 if (getNodeType(next) == RtlNode::SEQ && !crossSequential) {
01195
01196 if (includeRoots) {
01197 markVisited(next);
01198 transitiveFanout.push_back(next);
01199 }
01200 } else {
01201
01202 getTransitiveFanout_recursive(next, transitiveFanout, includeRoots);
01203 }
01204 }
01205
01206 transitiveFanout.push_back(x);
01207 }
01208
01209
01210
01211
01236
01237
01238 void
01239 RtlGraph::getTransitiveFanout(list<BBRef> x, list<BBRef> &transitiveFanout,
01240 bool includeRoots, bool crossSequential) {
01241
01242
01243
01244 newTraversalID();
01245 list<BBRef> allNewFanout;
01246 for(list<BBRef>::iterator it = x.begin(); it != x.end(); it++) {
01247 list<BBRef> oneNewFanout;
01248 getTransitiveFanout_recursive(*it, oneNewFanout, includeRoots, crossSequential);
01249
01250 oneNewFanout.pop_front();
01251 allNewFanout.splice(allNewFanout.begin(), oneNewFanout);
01252 }
01253 transitiveFanout.splice(transitiveFanout.end(), allNewFanout);
01254 }
01255
01256
01257
01258
01259
01284
01285
01286 void
01287 RtlGraph::getTransitiveFanout(BBRef x, list<BBRef> &transitiveFanout,
01288 bool includeRoots, bool crossSequential) {
01289 newTraversalID();
01290 list<BBRef> newTransitiveFanout;
01291 getTransitiveFanout_recursive(x, newTransitiveFanout,
01292 includeRoots, crossSequential);
01293
01294 newTransitiveFanout.pop_front();
01295
01296 transitiveFanout.splice(transitiveFanout.end(), newTransitiveFanout);
01297 }
01298
01299
01300
01301
01302
01306
01307
01308 void
01309 RtlGraph::getTransitiveFanout_recursive(BBRef x, list<BBRef> &transitiveFanout,
01310 bool includeRoots, bool crossSequential) {
01311 markVisited(x);
01312
01313
01314 if (getNodeType(x) == RtlNode::TERMINAL &&
01315 hasFanout(x) && !includeRoots) {
01316
01317 return;
01318 }
01319
01320 const list<BBRef> *immediateFanout = &getFanout(x);
01321 for(list<BBRef>::const_iterator it = immediateFanout->begin();
01322 it != immediateFanout->end(); ++it) {
01323 BBRef next = *it;
01324
01325
01326 assert(!isNull(next));
01327 assert(getNodeType(next) != RtlNode::CONSTANT0);
01328 assert(getNodeType(next) != RtlNode::CONSTANT1);
01329
01330
01331 if (isVisited(next)) {
01332 continue;
01333 }
01334
01335 if (getNodeType(next) == RtlNode::SEQ && !crossSequential) {
01336
01337 if (includeRoots) {
01338 markVisited(next);
01339 transitiveFanout.push_front(next);
01340 }
01341 } else {
01342
01343 getTransitiveFanout_recursive(next, transitiveFanout, includeRoots);
01344 }
01345 }
01346
01347 transitiveFanout.push_front(x);
01348 }
01349
01350
01351
01352 }