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
00013
00020
00021
00022 SimMod::SimMod(oa::oaDesign *design) {
00023 assert(design);
00024 assert(design->getTopModule());
00025 this->design = design;
00026 clear();
00027
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
00039
00041
00042
00043 void
00044 SimMod::clear() {
00045 toBeSimulated.clear();
00046
00047
00048
00049
00050
00051
00052
00053 }
00054
00055
00056
00057
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
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
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
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
00195
00197
00198
00199 void
00200 SimMod::runFull() {
00201
00202 toBeSimulated.clear();
00203
00204
00205 AiModGraph::getInputs(design->getTopModule(), toBeSimulated);
00206 AiModGraph::getLocalStates(design->getTopModule(), toBeSimulated);
00207
00208 runIncremental();
00209 }
00210
00211
00212
00213
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
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
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
00259 for(vector<AiModRef>::iterator it = topoOrder.begin();
00260 it != topoOrder.end(); it++) {
00261
00262 runOne(*it);
00263 }
00264
00265 toBeSimulated.clear();
00266 }
00267
00268 }