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

oagFpgaSimOcc.cpp

Go to the documentation of this file.
00001 /* (c) Copyright 2004-2005, Cadence Design Systems, Inc.  All rights reserved. 
00002 
00003 This file is part of the OA Gear distribution.  See the COPYING file in
00004 the top level OA Gear directory for copyright and licensing information. */
00005 
00006 /*
00007 Author: Aaron P. Hurst <ahurst@eecs.berkeley.edu>
00008  
00009 ChangeLog:
00010 2005-11-08: ChangeLog started
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 // SimOcc()
00025 //
00027 //
00028 // *****************************************************************************
00029 SimOcc::SimOcc(oa::oaDesign *design) { 
00030     assert(design);
00031     assert(design->getTopOccurrence());
00032     clear();
00033     this->design = design;
00034     // determine BITS_PER_RAND
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 // clear()
00046 //
00048 //
00049 // *****************************************************************************   
00050 void
00051 SimOcc::clear() {
00052     data.clear();
00053     toBeSimulated.clear();
00054 }
00055 
00056 
00057 // *****************************************************************************
00058 // setVector()
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 // generateRandomStateVectors()
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 // generateRandomInputVectors()
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 // randomVector()
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 // runFull()
00133 //
00135 //
00136 // *****************************************************************************
00137 void
00138 SimOcc::runFull() {
00139 
00140     toBeSimulated.clear();
00141     set<OccRef> alreadyVisited;
00142  
00143     // seed all the start points
00144     
00145     // inputs and states
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     // constants
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         // first follow immediate fanout (to AND nodes)
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         // follow connections through OA hierarchy (to other terminal nodes)
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 // getVector()
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 // nextCycle()
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             // no next state input.  do nothing
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 }

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