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

oagFpgaSimMod.cpp

Go to the documentation of this file.
00001 
00002 #include "oagFpgaSimMod.h"
00003 #include <iostream>
00004 
00005 #include "oagFpgaDebug.h"
00006 
00007 using namespace std;
00008 
00009 namespace oagFpga {
00010 
00011 // *****************************************************************************
00012 // SimMod()
00013 //
00020 //
00021 // *****************************************************************************
00022 SimMod::SimMod(oa::oaDesign *design) { 
00023     assert(design);
00024     assert(design->getTopModule());
00025     this->design = design;
00026     clear();
00027     // determine BITS_PER_RAND
00028     BITS_PER_RAND = 0;
00029     for(unsigned int i=1; i<sizeof(int)*8; i++) {
00030       if (RAND_MAX >= (1<<i)) {
00031         BITS_PER_RAND++;
00032       }
00033     }
00034 }
00035 
00036 
00037 // *****************************************************************************
00038 // clear()
00039 //
00041 //
00042 // *****************************************************************************   
00043 void
00044 SimMod::clear() {
00045     toBeSimulated.clear();
00046     /*
00047     // refresh constant node
00048     AiModRef constant;
00049     constant = AiModGraph::constantZero(design->getTopModule());
00050     AiModGraph::setUserData(constant, SIM_USER_DATA_INDEX, 0);
00051     toBeSimulated.push_back(constant);
00052     */
00053 }
00054 
00055 
00056 // *****************************************************************************
00057 // generateRandomStateVectors()
00058 //
00060 //
00061 // *****************************************************************************
00062 void
00063 SimMod::generateRandomStateVectors() {
00064     list<AiModRef> states;
00065     AiModGraph::getLocalStates(design->getTopModule(), states);
00066     for(list<AiModRef>::iterator it=states.begin(); it!=states.end(); ++it) {
00067         setVector(*it, randomVector());
00068     }
00069 }
00070 
00071 
00072 // *****************************************************************************
00073 // generateRandomInputVectors()
00074 //
00076 //
00077 // *****************************************************************************
00078 void
00079 SimMod::generateRandomInputVectors() {
00080     list<AiModRef> inputs;
00081     AiModGraph::getInputs(design->getTopModule(), inputs);
00082     for(list<AiModRef>::iterator it=inputs.begin(); it!=inputs.end(); ++it) {
00083         setVector(*it, randomVector());
00084     }
00085 }
00086 
00087 
00088 // *****************************************************************************
00089 // randomVector()
00090 //
00092 //
00094 //
00095 // *****************************************************************************
00096 SimMod::SimVec
00097 SimMod::randomVector() {
00098     const int RAND_MASK = (1 << BITS_PER_RAND) - 1;
00099 
00100     SimVec result = 0;
00101     int bits = sizeof(int)*8;
00102     while(bits>0) {
00103       result = (result << BITS_PER_RAND) | (rand() & RAND_MASK);
00104       bits -= BITS_PER_RAND;
00105     }
00106     return result;
00107 }
00108 
00109     
00110 // *****************************************************************************
00111 // runOne()
00112 //
00118 //
00119 // *****************************************************************************
00120 void
00121 SimMod::runOne(const AiModRef & ref) {
00122     assert(!AiModGraph::isInverted(ref));
00123     assert(ref.module);
00124     
00125 #ifdef DEBUG_SIM
00126     oa::oaString nameString;
00127     ref.module->getName(nameString);
00128     DEBUG_PRINT("- ai " << nameString << "." << ref.ref << "\t");
00129 #endif
00130 
00131     switch(AiModGraph::getNodeType(ref)) {
00132     case oagAi::Node::AND: {
00133       DEBUG_PRINTMORE("and");
00134       
00135       AiModRef left = AiModGraph::getAndLeft(ref);
00136       AiModRef nonInvLeft = AiModGraph::getNonInverted(left);
00137       AiModRef right = AiModGraph::getAndRight(ref);
00138       AiModRef nonInvRight = AiModGraph::getNonInverted(right);
00139       
00140       SimVec leftVec = 0;
00141       if(AiModGraph::getNodeType(nonInvLeft) == oagAi::Node::CONSTANT0) {
00142         leftVec = 0;
00143       } else {
00144         leftVec = AiModGraph::getUserData(nonInvLeft, SIM_USER_DATA_INDEX);
00145       }
00146       leftVec = AiModGraph::isInverted(left) ? ~leftVec : leftVec;
00147             
00148       SimVec rightVec = 0;
00149       if(AiModGraph::getNodeType(nonInvRight) == oagAi::Node::CONSTANT0) {
00150         rightVec = 0;
00151       } else {
00152         rightVec = AiModGraph::getUserData(nonInvRight, SIM_USER_DATA_INDEX);
00153       }
00154       rightVec = AiModGraph::isInverted(right) ? ~rightVec : rightVec;
00155             
00156       AiModGraph::setUserData(ref, SIM_USER_DATA_INDEX, leftVec & rightVec);
00157             
00158       break;
00159     }
00160 
00161     case oagAi::Node::SEQUENTIAL: {
00162       DEBUG_PRINTMORE("seq")
00163       break;
00164     }
00165             
00166     case oagAi::Node::TERMINAL: {
00167       DEBUG_PRINTMORE("terminal")
00168 
00169       AiModRef driver = AiModGraph::getTerminalDriver(ref);
00170       AiModRef nonInvDriver = AiModGraph::getNonInverted(driver);
00171       SimVec driverVec = 0;
00172       if(AiModGraph::getNodeType(nonInvDriver) == oagAi::Node::CONSTANT0) {
00173         driverVec = 0;
00174       } else {
00175         driverVec = AiModGraph::getUserData(nonInvDriver, SIM_USER_DATA_INDEX);
00176       }
00177       driverVec = AiModGraph::isInverted(driver) ? ~driverVec : driverVec;
00178 
00179       AiModGraph::setUserData(ref, SIM_USER_DATA_INDEX, driverVec);
00180 
00181       break;
00182     }
00183             
00184     default:
00185       QUIT_ON_INTERNAL_ERROR;
00186       break;
00187     }
00188     
00189     DEBUG_PRINTMORE(" vector=" << AiModGraph::getUserData(ref, SIM_USER_DATA_INDEX));
00190 }
00191 
00192 
00193 // *****************************************************************************
00194 // runFull()
00195 //
00197 //
00198 // *****************************************************************************
00199 void
00200 SimMod::runFull() {
00201 
00202     toBeSimulated.clear();
00203 
00204     // seed all the start points
00205     AiModGraph::getInputs(design->getTopModule(), toBeSimulated);
00206     AiModGraph::getLocalStates(design->getTopModule(), toBeSimulated);
00207     
00208     runIncremental();
00209 }
00210 
00211 
00212 // *****************************************************************************
00213 // nextCycle()
00214 //
00216 //
00217 // *****************************************************************************
00218 void    
00219 SimMod::nextCycle() {
00220     list<AiModRef> stateList;
00221     AiModGraph::getLocalStates(design->getTopModule(), stateList);
00222     for(list<AiModRef>::iterator it = stateList.begin();
00223         it != stateList.end(); ++it) {
00224         assert(!AiModGraph::isInverted(*it));
00225         AiModRef nextState = AiModGraph::getNextState(*it);
00226         AiModRef nonInvNextState = AiModGraph::getNonInverted(nextState);
00227         if (AiModGraph::isNull(nextState)) {
00228             // no next state input.  do nothing
00229         } else if (AiModGraph::isInverted(nextState)) {
00230           AiModGraph::setUserData(*it, SIM_USER_DATA_INDEX,
00231                                 ~AiModGraph::getUserData(nonInvNextState, 
00232                                                        SIM_USER_DATA_INDEX));
00233         } else {
00234           AiModGraph::setUserData(*it, SIM_USER_DATA_INDEX,
00235                                 AiModGraph::getUserData(nonInvNextState, 
00236                                                       SIM_USER_DATA_INDEX));
00237         }
00238         toBeSimulated.push_back(*it);
00239     }    
00240 }
00241 
00242 
00243 // *****************************************************************************
00244 // runIncremental()
00245 //
00249 //
00250 // *****************************************************************************
00251 void
00252 SimMod::runIncremental() {
00253   if (toBeSimulated.empty()) return;
00254 
00255   vector<AiModRef> topoOrder;
00256   AiModGraph::getTransitiveFanout(toBeSimulated, topoOrder, true);
00257 
00258   // simulate in forward topological order
00259   for(vector<AiModRef>::iterator it = topoOrder.begin();
00260       it != topoOrder.end(); it++) {
00261     // compute vector at node
00262     runOne(*it);
00263   }
00264 
00265   toBeSimulated.clear();
00266 }
00267 
00268 }

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