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

oagFpgaRtlGraph.cpp

Go to the documentation of this file.
00001 #include "oagFpgaRtlGraph.h"
00002 #include "oagFpgaDebug.h"
00003 
00004 using namespace std;
00005 
00006 namespace oagFpga {
00007 
00008 // initialization of static member
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 // unaryOpt()
00026 //
00029 // *****************************************************************************
00030 
00031 BBRef
00032 RtlGraph::unaryOpt(RtlNode::OptType ot, BBRef driver) {
00033 
00034     // create output node of this unary operator
00035     RtlNode* node = newNode();
00036     node->funcType = RtlNode::OPERATOR;
00037     node->optType = ot;
00038     addNode(node);
00039     node->optInfo = new RtlNode::RtlOptNodeInfo();
00040 
00041     // build connection between new node and driver
00042     node->fanin.push_back(driver);
00043     getNode(driver)->fanout.push_back(node->self);
00044 
00045     // setup input ports
00046     node->optInfo->op1.push_back(driver);
00047 
00048     return node->self;
00049 }
00050 
00051 // *****************************************************************************
00052 // binaryOpt()
00053 //
00056 // *****************************************************************************
00057 
00058 BBRef
00059 RtlGraph::binaryOpt(RtlNode::OptType ot, BBRef in1, BBRef in2) {
00060 
00061     // create output node of this binary operator
00062     RtlNode* node = newNode();
00063     node->funcType = RtlNode::OPERATOR;
00064     node->optType = ot;
00065     addNode(node);
00066     node->optInfo = new RtlNode::RtlOptNodeInfo();
00067 
00068     // build connections
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     // setup input ports
00075     node->optInfo->op1.push_back(in1);
00076     node->optInfo->op1.push_back(in2);
00077 
00078     return node->self;
00079 }
00080 
00081 // *****************************************************************************
00082 // unaryBusOpt()
00083 //
00086 // *****************************************************************************
00087 
00088 BBRef
00089 RtlGraph::unaryBusOpt(RtlNode::OptType ot, vector<BBRef>& ins) {
00090     
00091     // create output node of this multiple operator
00092     RtlNode* node = newNode();
00093     node->funcType = RtlNode::OPERATOR;
00094     node->optType = ot;
00095     addNode(node);
00096     node->optInfo = new RtlNode::RtlOptNodeInfo();
00097 
00098     // build connections
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         // setup input ports
00106         node->optInfo->op1.push_back(ref);
00107     }
00108 
00109     return node->self;
00110 }
00111 
00112 // *****************************************************************************
00113 // binaryBusOpt()
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     // create output node of this multiple operator
00126     RtlNode* node = newNode();
00127     node->funcType = RtlNode::OPERATOR;
00128     node->optType = ot;
00129     addNode(node);
00130     node->optInfo = new RtlNode::RtlOptNodeInfo();
00131 
00132     // build connections
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         // setup input ports
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         // setup input ports
00147         node->optInfo->op2.push_back(ref);
00148     }
00149 
00150     return node->self;
00151 }
00152 
00153 // *****************************************************************************
00154 // binaryBusInputOutputOpt()
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     // YH: TODO: need to check back!!!
00167     // the output of a ripper adder should be one-bit wider than the inputs, but
00168     // currently i assume the number of input/output bits are equal
00169     //assert(numOutBits > 1);
00170     
00171     // create output node of this multiple operator
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     // build connections
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         // setup input ports
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         // setup input ports
00195         node->optInfo->op2.push_back(ref);
00196     }
00197 
00198     // setup output bits according numOutBits
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 // unaryBusInputOutputOpt()
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     // create output node of this multiple operator
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     // build connections
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         // setup input ports
00236         node->optInfo->op1.push_back(ref);
00237     }
00238 
00239     // setup output bits according numOutBits
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 // bitSeq()
00250 //
00259 //
00260 // *****************************************************************************
00261 
00262 BBRef
00263 RtlGraph::bitSeq(RtlNode::SeqType st, BBRef D, BBRef clock, 
00264         BBRef aLoad, BBRef aData) {
00265 
00266     // create output node of this multiple operator
00267     RtlNode* node = newNode();
00268     node->funcType = RtlNode::SEQ;
00269     node->seqType = st;
00270     addNode(node);
00271 
00272     // build connections
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 // YH: a general mux could be much more complicated
00306 // a general CONTROL element for following Verilog statement:
00307 // 
00308 // CASE A: out <= a;
00309 // CASE B: out <= b;
00310 // 
00311 // should be
00312 //
00314 //           +---+
00315 //      A--->|   |          +-----+
00316 //           | = |------->--|     |
00317 //       +-->|   |          | AND |-->-+
00318 //       |   +---+    a-->--|     |    |     +----+
00319 // sel-->+                  +-----+    +--->-|    |
00320 //       |   +---+                           | OR |-->
00321 //       +-->|   |          +-----+    +--->-|    |
00322 //           | = |------->--|     |    |     +----+
00323 //      B--->|   |          | AND |-->-+
00324 //           +---+    b-->--|     |
00325 //                          +-----+
00327 //
00328 // However, if A and B are constant (e.g., integers), this statement should
00329 // be inferred as a MUX with sel properly encoded.
00330 // *****************************************************************************
00331 
00332 
00333 // *****************************************************************************
00334 // bitMux()
00335 //
00339 //
00340 // *****************************************************************************
00341 
00342 BBRef
00343 RtlGraph::bitMux(BBRef in1, BBRef in2, BBRef sel) {
00344 
00345     // create output node of this multiple operator
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     // setup data inputs and selection bits
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 // busMux()
00368 //
00372 //
00373 // *****************************************************************************
00374 
00375 BBRef
00376 RtlGraph::busMux(vector<BBRef>& in, vector<BBRef>& sel) {
00377 
00378     // create output node of this multiple operator
00379     RtlNode* node = newNode();
00380     node->funcType = RtlNode::CONTROL;
00381     addNode(node);
00382 
00383     vector<BBRef>::iterator bbRefIter;
00384 
00385     // setup inputs of this blackbox
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     // setup data inputs and selection bits
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 // busMux()
00408 //
00412 //
00413 // *****************************************************************************
00414 
00415 void
00416 RtlGraph::busMux(vector<BBRef>& in1, vector<BBRef>& in2, vector<BBRef>& sel,
00417         vector<BBRef>& outputs) {
00418 
00419     // i haven't seen the usefulness of this routine...
00420     QUIT_ON_INTERNAL_ERROR;
00421 
00422     assert(in1.size() == in2.size());
00423 
00424     // create output node of this multiple operator
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     // setup inputs of this blackbox
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     // setup output bits
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     // TODO: setup data inputs and selection bits
00454 }
00455 
00456 // *****************************************************************************
00457 // addNode()
00458 //
00462 //
00463 // *****************************************************************************
00464 void 
00465 RtlGraph::addNode(RtlNode* node) {
00466 
00467     node->self = bbNodes.size();
00468     bbNodes.push_back(node);
00469     
00470     //TODO: check missing??
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     // create a new terminal node
00485     RtlNode *node = newNode();
00486     addNode(node);
00487     node->funcType = RtlNode::TERMINAL;
00488     node->fanin.push_back(driver);
00489 
00490     // add this node to driver's fanout 
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 // removeFromFanout()
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     // node not found in fanout list?
00528     cerr << "ERROR: Node " << fanout << " not found in fanout of " << x << endl;
00529     QUIT_ON_INTERNAL_ERROR;
00530 }
00531 
00532 // *****************************************************************************
00533 // setTerminalDriver()
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     // mark dirty; existing graph structure may be modified
00551     dirtyMarker++;
00552     */
00553 
00554     // decrement old fan-in
00555     removeFromFanout(node->fanin.front(), terminal);
00556     // update terminal driver
00557     assert(node->fanin.size() == 1);
00558     node->fanin.front() = driver;
00559     // increment new fan-in
00560     getNode(driver)->fanout.push_back(terminal);
00561 }
00562 
00563 // *****************************************************************************
00564 // print()
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 // print()
00581 //
00584 // *****************************************************************************
00585 
00586 void
00587 RtlGraph::print(ostream& os) {
00588     os << "========================================================" << endl;
00589     os << "Begin of RtlGraph:" << endl;
00590 
00591     // print all unique BB nodes
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     // print all connections
00600     for(vector<RtlNode*>::iterator bbIter = bbNodes.begin(); bbIter !=
00601             bbNodes.end(); ++ bbIter){
00602         RtlNode* node = *bbIter;
00603         // output all fanouts
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         // output all fanins
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 // newTraversalID()
00631 //
00650 // *****************************************************************************
00651 unsigned int
00652 RtlGraph::newTraversalID() {
00653 
00654     // clear all travsersalIDs (if and only if currentTraversalID is out of
00655     // unsigned int bound (0xffffffff)
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 // hasCombinationalCycle()
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 // hasCombinationalCycle()
00701 //
00705 //
00706 // *****************************************************************************
00707 bool
00708 RtlGraph::hasCombinationalCycle_recursive(BBRef x, unsigned int startingTravID) {
00709     // is this a null reference
00710     if (isNull(x)) {
00711         return false;
00712     }
00713     RtlNode *node = getNode(x);
00714     // is this node non-combinational?
00715     if (node->funcType == RtlNode::SEQ 
00716             || node->funcType == RtlNode::CONSTANT0
00717             || node->funcType == RtlNode::CONSTANT1) {
00718         return false;
00719     }
00720     // does this form a cycle?
00721     if (node->traversalID == currentTraversalID) {
00722         return true;
00723     }
00724     // has this already been proved to be cycle-free?
00725     if (node->traversalID >= startingTravID) {
00726         return false;
00727     }
00728     node->traversalID = currentTraversalID;
00729     // otherwise, continue backward
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 // getTransitiveFanin()
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   // remove initial node
00781   transitiveFanin.pop_back(); 
00782 }
00783 
00784 
00785 // *****************************************************************************
00786 // getTransitiveFanin()
00787 //
00812 //
00813 // *****************************************************************************
00814 void
00815 RtlGraph::getTransitiveFanin(list<BBRef> x, vector<BBRef> &transitiveFanin, 
00816                           bool includeRoots, bool crossSequential) {
00817 
00818   // transitiveFanin = { transitiveFanin, fanin(x_1), fanin(x_2) ... fanin(x_n) }
00819   
00820   newTraversalID();
00821   for(list<BBRef>::iterator xIter = x.begin(); xIter != x.end(); xIter++) {
00822     getTransitiveFanin_recursive(*xIter, transitiveFanin, 
00823                                  includeRoots, crossSequential);
00824     // remove initial nodes
00825     transitiveFanin.pop_back();
00826   }
00827 }
00828 
00829 
00830 // *****************************************************************************
00831 // getTransitiveFanin_recursive()
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       // the transitive fanins of "nextState" input of a sequential node will be
00862       // returned
00863       fanin.push_back(getNextState(x));
00864       */
00865       // All fanins including Data-input, clock and asynchronous signals will be
00866       // returned
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       // do nothing for constant0/1
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                 // only include if includeRoots is true
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 // getTransitiveFanin()
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   // remove initial node
00936   transitiveFanin.pop_back(); 
00937 }
00938 
00939 
00940 // *****************************************************************************
00941 // getTransitiveFanin()
00942 //
00964 //
00965 // *****************************************************************************
00966 void
00967 RtlGraph::getTransitiveFanin(list<BBRef> x, list<BBRef> &transitiveFanin,
00968                           bool includeRoots, bool crossSequential) {
00969 
00970   // transitiveFanin = { transitiveFanin, fanin(x_1), fanin(x_2) ... fanin(x_n-1), fanin(x_n) }
00971 
00972   newTraversalID();
00973   for(list<BBRef>::iterator xIter = x.begin(); xIter!=x.end(); xIter++) {
00974     getTransitiveFanin_recursive(*xIter, transitiveFanin, 
00975                                  includeRoots, crossSequential);
00976     // remove initial nodes
00977     transitiveFanin.pop_back();
00978   }
00979 }
00980 
00981 // *****************************************************************************
00982 // getTransitiveFanin_recursive()
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         // the transitive fanins of "nextState" input of a sequential node will
01011         // be returned
01012         fanin.push_back(getNextState(x));
01013         */
01014         // All fanins including Data-input, clock and asynchronous signals will be
01015         // returned
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         // do nothing for constant 0/1
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                 // only include if includeRoots is true 
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 // getTransitiveFanout()
01057 //
01082 //
01083 // *****************************************************************************
01084 void
01085 RtlGraph::getTransitiveFanout(BBRef x, vector<BBRef> &transitiveFanout, 
01086                           bool includeRoots, bool crossSequential) {
01087   newTraversalID();
01088   // generate the reversed forward topological ordering of transitive fanout
01089   vector<BBRef> newReversedTransitiveFanout;
01090   getTransitiveFanout_recursive(x, newReversedTransitiveFanout, includeRoots, crossSequential);
01091   // remove initial node
01092   newReversedTransitiveFanout.pop_back(); 
01093   // append reversed result to original vector
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 // getTransitiveFanout()
01104 //
01132 //
01133 // *****************************************************************************
01134 void
01135 RtlGraph::getTransitiveFanout(list<BBRef> x, vector<BBRef> &transitiveFanout,
01136                           bool includeRoots, bool crossSequential) {
01137 
01138   // transitiveFanout = { transitiveFanout, rev(fanout(x_n)) ... rev(fanout(2)), rev(fanout(1)) }
01139 
01140   newTraversalID();
01141   vector<BBRef> newReversedTransitiveFanout;
01142   for(list<BBRef>::iterator it = x.begin(); it != x.end(); it++) {
01143     // generate the reversed forward topological ordering of transitive fanout
01144     getTransitiveFanout_recursive(*it, newReversedTransitiveFanout,
01145                                   includeRoots, crossSequential);
01146     // remove initial node
01147     newReversedTransitiveFanout.pop_back(); 
01148   }
01149   // append reversed result to original vector
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 // getTransitiveFanout_recursive()
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       // only include if includeRoots is true
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       // there shouldn't be fanout to a null or constant node
01185       assert(!isNull(next));
01186       assert(getNodeType(next) != RtlNode::CONSTANT0);
01187       assert(getNodeType(next) != RtlNode::CONSTANT1);
01188 
01189       // have we already explored this node?
01190       if (isVisited(next)) {
01191         continue;
01192       }
01193             
01194       if (getNodeType(next) == RtlNode::SEQ && !crossSequential) {
01195         // only include if includeRoots is true
01196         if (includeRoots) {
01197           markVisited(next);
01198           transitiveFanout.push_back(next);
01199         }
01200       } else {
01201         // continue traversal
01202         getTransitiveFanout_recursive(next, transitiveFanout, includeRoots);
01203       }
01204     }
01205 
01206     transitiveFanout.push_back(x);
01207 }
01208 
01209 // *****************************************************************************
01210 // getTransitiveFanout()
01211 //
01236 //
01237 // *****************************************************************************
01238 void
01239 RtlGraph::getTransitiveFanout(list<BBRef> x, list<BBRef> &transitiveFanout,
01240                           bool includeRoots, bool crossSequential) {
01241 
01242   // transitiveFanout = { transitiveFanout, fanout(x_n) ... fanout(2), fanout(1) }
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     // remove initial node
01250     oneNewFanout.pop_front();
01251     allNewFanout.splice(allNewFanout.begin(), oneNewFanout);
01252   }
01253   transitiveFanout.splice(transitiveFanout.end(), allNewFanout);
01254 }
01255 
01256 
01257 // *****************************************************************************
01258 // getTransitiveFanout()
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   // remove initial node
01294   newTransitiveFanout.pop_front(); 
01295   // append reversed result to original vector
01296   transitiveFanout.splice(transitiveFanout.end(), newTransitiveFanout);
01297 }
01298 
01299 
01300 // *****************************************************************************
01301 // getTransitiveFanout_recursive()
01302 //
01306 //
01307 // *****************************************************************************
01308 void
01309 RtlGraph::getTransitiveFanout_recursive(BBRef x, list<BBRef> &transitiveFanout, 
01310                                      bool includeRoots, bool crossSequential) {
01311     markVisited(x);
01312 
01313     // YH question: don't understand what's the case here??
01314     if (getNodeType(x) == RtlNode::TERMINAL && 
01315         hasFanout(x) && !includeRoots) {
01316       // only include if includeRoots is true
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       // there shouldn't be fanout to a null or constant node
01326       assert(!isNull(next));
01327       assert(getNodeType(next) != RtlNode::CONSTANT0);
01328       assert(getNodeType(next) != RtlNode::CONSTANT1);
01329 
01330       // have we already explored this node?
01331       if (isVisited(next)) {
01332         continue;
01333       }
01334             
01335       if (getNodeType(next) == RtlNode::SEQ && !crossSequential) {
01336         // only include if includeRoots is true
01337         if (includeRoots) {
01338           markVisited(next);
01339           transitiveFanout.push_front(next);
01340         }
01341       } else {
01342         // continue traversal
01343         getTransitiveFanout_recursive(next, transitiveFanout, includeRoots);
01344       }
01345     }
01346 
01347     transitiveFanout.push_front(x);
01348 }
01349 
01350 
01351 
01352 }

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