00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <iostream>
00014 #include "oagFuncSimOcc.h"
00015
00016 #include "oagFuncDebug.h"
00017
00018 using namespace std;
00019
00020 namespace oagFunc {
00021
00022
00023
00024
00025
00027
00028
00029 SimOcc::SimOcc(oa::oaDesign *design) {
00030 assert(design);
00031 assert(design->getTopOccurrence());
00032 clear();
00033 this->design = design;
00034
00035 BITS_PER_RAND = 0;
00036 for(unsigned int i=1; i<sizeof(int)*8; i++) {
00037 if (RAND_MAX >= (1<<i)) {
00038 BITS_PER_RAND++;
00039 }
00040 }
00041 }
00042
00043
00044
00045
00046
00048
00049
00050 void
00051 SimOcc::clear() {
00052 data.clear();
00053 toBeSimulated.clear();
00054 }
00055
00056
00057
00058
00059
00061
00064
00065
00066 void
00067 SimOcc::setVector(OccRef &ref, SimulationVector vec) {
00068 if (OccGraph::isInverted(ref)) {
00069 data[OccGraph::getNonInverted(ref)] = ~vec;
00070 } else {
00071 data[ref] = vec;
00072 }
00073 toBeSimulated.push_back(OccGraph::getNonInverted(ref));
00074 }
00075
00076
00077
00078
00079
00081
00082
00083 void
00084 SimOcc::generateRandomStateVectors() {
00085 list<OccRef> states;
00086 OccGraph::getStates(design->getTopOccurrence(), states);
00087 for(list<OccRef>::iterator it=states.begin(); it!=states.end(); ++it) {
00088 setVector(*it, randomVector());
00089 }
00090 }
00091
00092
00093
00094
00095
00097
00098
00099 void
00100 SimOcc::generateRandomInputVectors() {
00101 list<OccRef> inputs;
00102 OccGraph::getInputs(design->getTopOccurrence(), inputs);
00103 for(list<OccRef>::iterator it=inputs.begin(); it!=inputs.end(); ++it) {
00104 setVector(*it, randomVector());
00105 }
00106 }
00107
00108
00109
00110
00111
00113
00115
00116
00117 SimulationVector
00118 SimOcc::randomVector() {
00119 const int RAND_MASK = (1 << BITS_PER_RAND) - 1;
00120
00121 SimulationVector result = 0;
00122 int bits = sizeof(int)*8;
00123 while(bits>0) {
00124 result = (result << BITS_PER_RAND) | (rand() & RAND_MASK);
00125 bits -= BITS_PER_RAND;
00126 }
00127 return result;
00128 }
00129
00130
00131
00132
00133
00135
00136
00137 void
00138 SimOcc::runFull() {
00139
00140 toBeSimulated.clear();
00141 set<OccRef> alreadyVisited;
00142
00143
00144
00145
00146 list<OccRef> inputList, stateList;
00147 OccGraph::getInputs(design->getTopOccurrence(), inputList);
00148 OccGraph::getStates(design->getTopOccurrence(), stateList);
00149 for(list<OccRef>::iterator it = inputList.begin();
00150 it != inputList.end(); ++it) {
00151 toBeSimulated.push_back(*it);
00152 alreadyVisited.insert(*it);
00153 }
00154 for(list<OccRef>::iterator it = stateList.begin();
00155 it != stateList.end(); ++it) {
00156 toBeSimulated.push_back(*it);
00157 alreadyVisited.insert(*it);
00158 }
00159
00160 list<OccRef> zeroList, oneList;
00161 OccGraph::getConstants(design->getTopOccurrence(), zeroList, oneList);
00162 for(list<OccRef>::iterator it = zeroList.begin();
00163 it != zeroList.end(); ++it) {
00164 data[*it] = 0;
00165 toBeSimulated.push_back(*it);
00166 alreadyVisited.insert(*it);
00167 }
00168 for(list<OccRef>::iterator it = oneList.begin();
00169 it != oneList.end(); ++it) {
00170 data[*it] = ~(0);
00171 toBeSimulated.push_back(*it);
00172 alreadyVisited.insert(*it);
00173 }
00174
00175 while(!toBeSimulated.empty()) {
00176 oagFunc::OccRef ref = toBeSimulated.front();
00177 assert(!OccGraph::isInverted(ref));
00178 toBeSimulated.pop_front();
00179
00180 #ifdef DEBUG
00181 oa::oaString occPathString;
00182 if (ref.occurrence->getOccInst()) {
00183 ref.occurrence->getOccInst()->getPathName(oa::oaVerilogNS(), occPathString);
00184 } else {
00185 occPathString = "(top)";
00186 }
00187 DEBUG_PRINT("- ai " << occPathString << "." << ref.ref << "\t")
00188 #endif
00189
00190 switch(OccGraph::getNodeType(ref)) {
00191 case oagAi::Node::AND: {
00192 DEBUG_PRINTMORE("and")
00193
00194 OccRef left = OccGraph::getAndLeft(ref);
00195 OccRef nonInvLeft = OccGraph::getNonInverted(left);
00196 OccRef right = OccGraph::getAndRight(ref);
00197 OccRef nonInvRight = OccGraph::getNonInverted(right);
00198
00199 SimulationVector leftVec;
00200 if(OccGraph::getNodeType(nonInvLeft) == oagAi::Node::CONSTANT0) {
00201 leftVec = 0;
00202 } else if(data.find(nonInvLeft) == data.end()) {
00203 DEBUG_PRINTMORE(" need " << nonInvLeft.ref << endl)
00204 alreadyVisited.erase(ref);
00205 continue;
00206 } else {
00207 leftVec = data[nonInvLeft];
00208 }
00209 leftVec = OccGraph::isInverted(left) ? ~leftVec : leftVec;
00210
00211 SimulationVector rightVec;
00212 if(OccGraph::getNodeType(nonInvRight) == oagAi::Node::CONSTANT0) {
00213 rightVec = 0;
00214 } else if(data.find(nonInvRight) == data.end()) {
00215 DEBUG_PRINTMORE(" need " << nonInvRight.ref << endl)
00216 alreadyVisited.erase(ref);
00217 continue;
00218 } else {
00219 rightVec = data[nonInvRight];
00220 }
00221 rightVec = OccGraph::isInverted(right) ? ~rightVec : rightVec;
00222
00223 data[ref] = leftVec & rightVec;
00224
00225 break;
00226 }
00227
00228 case oagAi::Node::SEQUENTIAL: {
00229 DEBUG_PRINTMORE("seq")
00230 assert(data.find(ref) != data.end());
00231 break;
00232 }
00233
00234 case oagAi::Node::TERMINAL: {
00235 DEBUG_PRINTMORE("terminal")
00236 assert(data.find(ref) != data.end());
00237 break;
00238 }
00239
00240 default:
00241 break;
00242 }
00243
00244 DEBUG_PRINTMORE(" vector=" << data[ref])
00245
00246
00247 list<oagFunc::OccRef> fanoutList;
00248 OccGraph::getFanout(ref, fanoutList);
00249
00250 DEBUG_PRINTMORE(" (immediate fanout= " << fanoutList.size() << " ")
00251 for(list<OccRef>::iterator fanoutIter = fanoutList.begin();
00252 fanoutIter != fanoutList.end(); ++fanoutIter) {
00253 OccRef fanoutRef = *fanoutIter;
00254 assert(!OccGraph::isInverted(fanoutRef));
00255 if (OccGraph::getNodeType(fanoutRef) == oagAi::Node::AND &&
00256 alreadyVisited.find(fanoutRef) == alreadyVisited.end()) {
00257 toBeSimulated.push_back(fanoutRef);
00258 alreadyVisited.insert(fanoutRef);
00259 }
00260 }
00261
00262
00263 std::set<oagFunc::OccRef> connectedRefs;
00264 std::set<oa::oaOccBitNet*> connectedNets;
00265 OccGraph::getAllConnections(ref, connectedNets, connectedRefs,
00266 true, false, true, true, false, false);
00267
00268 DEBUG_PRINTMORE("though hierarchy= " << connectedRefs.size())
00269 for(std::set<OccRef>::iterator connectedIter = connectedRefs.begin();
00270 connectedIter != connectedRefs.end(); ++connectedIter) {
00271 OccRef connectedRef = *connectedIter;
00272 OccRef nonInvConnectedRef = OccGraph::getNonInverted(connectedRef);
00273 assert(OccGraph::getNodeType(connectedRef) == oagAi::Node::TERMINAL);
00274
00275 if (alreadyVisited.find(nonInvConnectedRef) != alreadyVisited.end()) {
00276 ;
00277 } else if (OccGraph::isInverted(connectedRef)) {
00278 data[nonInvConnectedRef] = ~data[ref];
00279 toBeSimulated.push_back(nonInvConnectedRef);
00280 alreadyVisited.insert(nonInvConnectedRef);
00281 } else {
00282 data[nonInvConnectedRef] = data[ref];
00283 toBeSimulated.push_back(nonInvConnectedRef);
00284 alreadyVisited.insert(nonInvConnectedRef);
00285 }
00286 }
00287
00288 DEBUG_PRINTMORE(")" << endl)
00289 }
00290 }
00291
00292
00293
00294
00295
00301
00302
00303 bool
00304 SimOcc::getVector(const OccRef &ref, SimulationVector &vec) {
00305 if (!toBeSimulated.empty() && data.find(ref) == data.end()) {
00306 return false;
00307 }
00308
00309 vec = data[ref];
00310 return true;
00311 }
00312
00313
00314
00315
00316
00318
00319
00320 void
00321 SimOcc::nextCycle() {
00322 list<OccRef> stateList;
00323 OccGraph::getStates(design->getTopOccurrence(), stateList);
00324 for(list<OccRef>::iterator it = stateList.begin();
00325 it != stateList.end(); ++it) {
00326 assert(!OccGraph::isInverted(*it));
00327 OccRef nextState = OccGraph::getNextState(*it);
00328 OccRef nonInvNextState = OccGraph::getNonInverted(nextState);
00329 if (OccGraph::isNull(nextState)) {
00330
00331 } else if (OccGraph::isInverted(nextState)) {
00332 data[*it] = ~data[nonInvNextState];
00333 } else {
00334 data[*it] = data[nonInvNextState];
00335 }
00336 toBeSimulated.push_back(*it);
00337 }
00338 }
00339
00340 }