00001
00027 #ifndef SIMINIT_H_
00028 #define SIMINIT_H_
00029
00030 #include <vector>
00031 #include <map>
00032 #include <set>
00033 #include <string>
00034 #include <iostream>
00035
00036 #include <cassert>
00037
00038 #include "Galois/Graphs/Graph.h"
00039
00040 #include "comDefs.h"
00041 #include "logicDefs.h"
00042 #include "LogicFunctions.h"
00043 #include "NetlistParser.h"
00044 #include "LogicUpdate.h"
00045
00046
00047 #include "Event.h"
00048 #include "Input.h"
00049 #include "LogicGate.h"
00050 #include "OneInputGate.h"
00051 #include "Output.h"
00052 #include "SimObject.h"
00053 #include "AbstractSimObject.h"
00054 #include "TwoInputGate.h"
00055
00056 class SimInit {
00057
00058 public:
00059 typedef NetlistParser::StimulusMapType StimulusMapType;
00060 typedef SimObject::Graph Graph;
00061 typedef SimObject::GNode GNode;
00062 typedef SimObject::EventTy EventTy;
00063
00064 private:
00065
00067 Graph& graph;
00068
00069
00071 NetlistParser parser;
00072
00074 std::vector<SimObject*> inputObjs;
00075
00077 std::vector<GNode> inputNodes;
00078
00080 std::vector<SimObject*> outputObjs;
00081
00083 std::vector<EventTy > initEvents;
00084
00086 std::vector<SimObject*> gateObjs;
00087
00089 size_t numEdges;
00090
00092 size_t numNodes;
00093
00095 size_t simObjCntr;
00096
00101 static const std::map<std::string, OneInputFunc* > oneInputFuncMap () {
00102 static std::map<std::string, OneInputFunc*> oneInMap;
00103 oneInMap.insert(std::make_pair (toLowerCase ("INV"), new INV()));
00104 return oneInMap;
00105 }
00106
00111 static const std::map<std::string, TwoInputFunc*> twoInputFuncMap () {
00112 static std::map<std::string, TwoInputFunc*> twoInMap;
00113 twoInMap.insert(std::make_pair (toLowerCase ("AND2") , new AND2()));
00114 twoInMap.insert(std::make_pair (toLowerCase ("NAND2") , new NAND2()));
00115 twoInMap.insert(std::make_pair (toLowerCase ("OR2") , new OR2()));
00116 twoInMap.insert(std::make_pair (toLowerCase ("NOR2") , new NOR2()));
00117 twoInMap.insert(std::make_pair (toLowerCase ("XOR2") , new XOR2()));
00118 twoInMap.insert(std::make_pair (toLowerCase ("XNOR2") , new XNOR2()));
00119 return twoInMap;
00120 }
00121
00122
00123 private:
00124
00125 static std::string addInPrefix(const std::string& name) {
00126 return "in_" + name;
00127 }
00128
00129 static std::string addOutPrefix (const std::string& name) {
00130 return "out_" + name;
00131 }
00132
00136 void createInputObjs() {
00137 const std::vector<std::string>& inputNames = parser.getInputNames ();
00138 for (std::vector<std::string>::const_iterator i = inputNames.begin (), e = inputNames.end (); i != e; ++i) {
00139 const std::string& out = *i;
00140 std::string in = addInPrefix(out);
00141
00142 inputObjs.push_back(new Input((simObjCntr++), out, in));
00143 }
00144 }
00145
00149 void createOutputObjs() {
00150 const std::vector<std::string>& outputNames = parser.getOutputNames ();
00151 for (std::vector<std::string>::const_iterator i = outputNames.begin (), e = outputNames.end (); i != e; ++i) {
00152 const std::string& in = *i;
00153 std::string out = addOutPrefix(in);
00154
00155 outputObjs.push_back(new Output((simObjCntr++), out, in));
00156 }
00157 }
00158
00159
00163 void createInitEvents() {
00164
00165 const StimulusMapType& inputStimulusMap = parser.getInputStimulusMap();
00166
00167 for (std::vector<GNode>::const_iterator i = inputNodes.begin (), ei = inputNodes.end (); i != ei; ++i ) {
00168
00169 const GNode& n = *i;
00170 Input* currInput =
00171 dynamic_cast<Input* > (graph.getData (n, Galois::NONE));
00172
00173 assert ((currInput != NULL));
00174
00175 size_t in = currInput->getInputIndex (currInput->getInputName ());
00176
00177 StimulusMapType::const_iterator it = inputStimulusMap.find (currInput->getOutputName ());
00178 assert ((it != inputStimulusMap.end ()));
00179 const std::vector<std::pair<SimTime, LogicVal> >& tvList = it->second;
00180
00181 std::vector<EventTy > myEvents;
00182
00183 for (std::vector< std::pair<SimTime, LogicVal> >::const_iterator j = tvList.begin (), ej = tvList.end ();
00184 j != ej; ++j) {
00185 const std::pair<SimTime, LogicVal>& p = *j;
00186 LogicUpdate lu(currInput->getOutputName(), p.second);
00187
00188 EventTy e = currInput->makeEvent(currInput, currInput, EventTy::REGULAR_EVENT, lu, p.first);
00189
00190
00191 currInput->recvEvent(in, e);
00192
00193 initEvents.push_back(e);
00194 myEvents.push_back(e);
00195 }
00196
00197
00198
00199 EventTy fe = currInput->makeEvent (currInput, currInput, EventTy::NULL_EVENT, LogicUpdate (), INFINITY_SIM_TIME);
00200
00201 currInput->recvEvent (in, fe);
00202
00203 currInput->updateActive ();
00204
00205 }
00206
00207 }
00208
00212 void createGateObjs() {
00213 const std::vector<GateRec>& gateRecs = parser.getGates();
00214
00215 for (std::vector<GateRec>::const_iterator i = gateRecs.begin (), ei = gateRecs.end (); i != ei; ++i) {
00216 const GateRec& grec = *i;
00217
00218 if (oneInputFuncMap().count (grec.name) > 0) {
00219 const OneInputFunc* func = (oneInputFuncMap().find (grec.name))->second;
00220
00221 assert ((grec.outputs.size () == 1));
00222 const std::string& out = grec.outputs[0];
00223
00224 assert ((grec.inputs.size() == 1));
00225 const std::string& in = grec.inputs[0];
00226
00227 const SimTime& delay = grec.delay;
00228
00229 OneInputGate* g = new OneInputGate ((simObjCntr++), *func, out, in, delay);
00230
00231 this->gateObjs.push_back(g);
00232
00233 } else if (twoInputFuncMap().count (grec.name) > 0) {
00234 const TwoInputFunc* func = (twoInputFuncMap().find (grec.name))->second;
00235
00236 assert (grec.outputs.size() == 1);
00237 const std::string& out = grec.outputs[0];
00238
00239 assert (grec.inputs.size() == 2);
00240 const std::string& in1 = grec.inputs[0];
00241 const std::string& in2 = grec.inputs[1];
00242
00243 const SimTime& delay = grec.delay;
00244
00245 TwoInputGate* g = new TwoInputGate ((simObjCntr++), *func, out, in1, in2, delay);
00246
00247 this->gateObjs.push_back(g);
00248
00249 } else {
00250 std::cerr << "Found a gate with unknown name: " << grec.getName() << std::endl;
00251 abort ();
00252 }
00253
00254 }
00255
00256 }
00257
00262 void createGraphNodes (const std::vector<SimObject*>& simObjs) {
00263 for (std::vector<SimObject*>::const_iterator i = simObjs.begin (), ei = simObjs.end (); i != ei; ++i) {
00264 SimObject* so = *i;
00265 GNode n = graph.createNode(so);
00266 graph.addNode(n, Galois::NONE);
00267 ++numNodes;
00268 }
00269 }
00275 void createConnections() {
00276
00277
00278 std::vector<GNode> allNodes;
00279
00280 for (Graph::active_iterator i = graph.active_begin (), ei = graph.active_end (); i != ei; ++i) {
00281 allNodes.push_back (*i);
00282 }
00283
00284 for (std::vector<GNode>::iterator i = allNodes.begin (), ei = allNodes.end (); i != ei; ++i) {
00285 GNode& src = *i;
00286 LogicGate* srcGate =
00287 dynamic_cast<LogicGate* > (graph.getData (src, Galois::NONE));
00288
00289 assert (srcGate != NULL);
00290 const std::string& srcOutName = srcGate->getOutputName ();
00291
00292 for (std::vector<GNode>::iterator j = allNodes.begin (), ej = allNodes.end (); j != ej; ++j) {
00293 GNode& dst = *j;
00294 LogicGate* dstGate =
00295 dynamic_cast<LogicGate* > (graph.getData (dst, Galois::NONE));
00296
00297 assert (dstGate != NULL);
00298
00299 if (dstGate->hasInputName (srcOutName)) {
00300 assert (srcGate != dstGate);
00301 if (!src.hasNeighbor (dst)) {
00302 ++numEdges;
00303 graph.addEdge (src, dst, Galois::NONE);
00304 }
00305
00306 }
00307
00308 }
00309 }
00310
00311
00312 }
00313
00323 void initialize() {
00324 numNodes = 0;
00325 numEdges = 0;
00326
00327
00328
00329 createInputObjs();
00330 createOutputObjs();
00331
00332 createGateObjs();
00333
00334
00335 for (std::vector<SimObject*>::const_iterator i = inputObjs.begin (), ei = inputObjs.end (); i != ei; ++i) {
00336 SimObject* so = *i;
00337
00338 GNode n = graph.createNode(so);
00339 graph.addNode(n, Galois::NONE);
00340 ++numNodes;
00341 inputNodes.push_back(n);
00342 }
00343
00344 createInitEvents();
00345
00346
00347 createGraphNodes (outputObjs);
00348
00349
00350 createGraphNodes (gateObjs);
00351
00352
00353 createConnections();
00354 }
00355
00360 template <typename T>
00361 static void destroyVec (std::vector<T*>& vec) {
00362 for (typename std::vector<T*>::iterator i = vec.begin (), ei = vec.end (); i != ei; ++i) {
00363 delete *i;
00364 *i = NULL;
00365 }
00366 }
00367
00371 void destroy () {
00372 destroyVec (inputObjs);
00373 destroyVec (outputObjs);
00374 destroyVec (gateObjs);
00375 }
00376
00377 public:
00384 SimInit(Graph& graph, const char* netlistFile)
00385 : graph(graph), parser(netlistFile), simObjCntr(0) {
00386 initialize();
00387 }
00388
00389 ~SimInit () {
00390 destroy ();
00391 }
00392
00398 const Graph& getGraph() const {
00399 return graph;
00400 }
00401
00407 const std::vector<EventTy >& getInitEvents() const {
00408 return initEvents;
00409 }
00410
00416 const std::vector<std::string>& getInputNames() const {
00417 return parser.getInputNames();
00418 }
00419
00425 const std::vector<SimObject*>& getInputObjs() const {
00426 return inputObjs;
00427 }
00428
00434 const std::vector<std::string>& getOutputNames() const {
00435 return parser.getOutputNames();
00436 }
00437
00443 const std::vector<SimObject*> getOutputObjs() const {
00444 return outputObjs;
00445 }
00446
00452 const std::map<std::string, LogicVal>& getOutValues() const {
00453 return parser.getOutValues();
00454 }
00455
00461 size_t getNumEdges() const {
00462 return numEdges;
00463 }
00464
00470 size_t getNumNodes() const {
00471 return numNodes;
00472 }
00473
00479 const std::vector<GNode>& getInputNodes() const {
00480 return inputNodes;
00481 }
00482 };
00483
00484
00485 #endif