00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef ED_ROUTER_H
00026 #define ED_ROUTER_H
00027
00028 #include <map>
00029 #include <list>
00030 #include <deque>
00031 #include <string>
00032 #include <vector>
00033
00034 #include <queue>
00035 #include <sst/core/eventFunctor.h>
00036 #include <sst/core/component.h>
00037 #include <sst/core/log.h>
00038 #include <sst/core/link.h>
00039
00040 #include "SS_network.h"
00041
00042 using namespace SST;
00043
00044 #define SS_ROUTER_DBG 1
00045 #ifndef SS_ROUTER_DBG
00046 #define SS_ROUTER_DBG 0
00047 #endif
00048
00049 #include "SS_network.h"
00050
00051 using namespace std;
00052
00053 #define DBprintf(fmt,args...) \
00054 m_dbg.write( "%s():%d: "fmt, __FUNCTION__, __LINE__, ##args)
00055
00056 #define cycle() m_cycle
00057
00058 enum rtrEventType { iLCB_internalXferDone, InQ_tailXferDone, InQ_headXferDone,
00059 OutQ_tailXferDone, OutQ_headXferDone, oLCB_internalXferDone,
00060 oLCB_externalXferDone, Debug
00061 };
00062
00063 typedef struct rtrEvent_s rtrEvent_t;
00064
00065
00066
00067
00068 class rtrP
00069 {
00070 public:
00071 RtrEvent *event;
00072 int ilink;
00073 int olink;
00074 int ivc, ovc;
00075 int flits;
00076 };
00077
00078
00079
00080
00081 struct rtrEvent_s {
00082 long long unsigned cycle;
00083 rtrEventType type;
00084 rtrP *rp;
00085 };
00086
00087
00088
00089 inline bool rtrEvent_gt (rtrEvent_t* a, rtrEvent_t *b) {
00090 return (a->cycle > b->cycle);
00091 }
00092
00093
00094
00095
00096 class rtrEventPool {
00097 private:
00098 vector<rtrEvent_t*> thePool;
00099 int count;
00100 public:
00101 rtrEventPool() {
00102 rtrEvent_t *event;
00103 for (int i = 0; i < 10; i++) {
00104 event = new rtrEvent_t;
00105 thePool.push_back(event);
00106 }
00107 count = 10;
00108 }
00109
00110 rtrEvent_t *getEvent() {
00111 rtrEvent_t *event;
00112 if (count > 0) {
00113 event = thePool.back();
00114 thePool.pop_back();
00115 count--;
00116 } else {
00117 event = new rtrEvent_t;
00118 thePool.push_back(event);
00119 event = new rtrEvent_t;
00120 count++;
00121 }
00122 return event;
00123 }
00124
00125 void returnEvent(rtrEvent_t* e) {
00126 thePool.push_back(e);
00127 count++;
00128 }
00129 };
00130
00131
00132
00133
00134
00135 class rtrPPool {
00136 private:
00137 vector<rtrP*> thePool;
00138 int count;
00139 public:
00140 rtrPPool() {
00141 rtrP *rp;
00142 for (int i = 0; i < 10; i++) {
00143 rp = new rtrP;
00144 thePool.push_back(rp);
00145 }
00146 count = 10;
00147 }
00148
00149 rtrP *getRp() {
00150 rtrP *rp;
00151 if (count > 0) {
00152 rp = thePool.back();
00153 thePool.pop_back();
00154 count--;
00155 } else {
00156 rp = new rtrP;
00157 thePool.push_back(rp);
00158 rp = new rtrP;
00159 count++;
00160 }
00161 return rp;
00162 }
00163
00164 void returnRp(rtrP* rp) {
00165 thePool.push_back(rp);
00166 count++;
00167 }
00168 };
00169
00170
00171
00172
00173 class SS_router : public Component
00174 {
00175 bool findRoute( int destNid, int inputVC, int inputDir,
00176 int& outVC, int& outDir );
00177 int findOutputDir( int destNid );
00178 int findOutputVC( int inVC, int inDir, int outDir );
00179 int dimension( int dir );
00180 bool iAmDateline( int dimension );
00181 int changeVC( int vc );
00182 int calcXPosition( int nodeNumber, int xSize, int ySize, int zSize );
00183 int calcYPosition( int nodeNumber, int xSize, int ySize, int zSize );
00184 int calcZPosition( int nodeNumber, int xSize, int ySize, int zSize );
00185 int calcDirection( int src, int dst, int size );
00186
00187 vector<char> m_routingTableV;
00188 vector<bool> m_datelineV;
00189
00190
00191 int neighbor[ROUTER_NUM_LINKS];
00192 int neighborID (int dir) {
00193 return neighbor[dir];
00194 }
00195
00196 inline int NODE_ID(int x, int y, int z,Network *net) {
00197 return z * net->xDimSize() * net->yDimSize() + y * net->xDimSize() + x;
00198 }
00199
00200 void find_neighbors(Network *net, int x, int y, int z) {
00201
00202 DBprintf("located at (%d, %d, %d)\n", x, y, z);
00203
00204 int posx,posy,posz,negx,negy,negz;
00205 posx = (x + 1) % net->xDimSize();
00206 posy = (y + 1) % net->yDimSize();
00207 posz = (z + 1) % net->zDimSize();
00208 negx = (x == 0) ? net->xDimSize() - 1 : (x - 1);
00209 negy = (y == 0) ? net->yDimSize() - 1 : (y - 1);
00210 negz = (z == 0) ? net->zDimSize() - 1 : (z - 1);
00211
00212 neighbor[LINK_NEG_X] = NODE_ID(negx,y,z, net);
00213 neighbor[LINK_POS_X] = NODE_ID(posx,y,z, net);
00214
00215 neighbor[LINK_NEG_Y] = NODE_ID(x,negy,z, net);
00216 neighbor[LINK_POS_Y] = NODE_ID(x,posy,z, net);
00217
00218 neighbor[LINK_NEG_Z] = NODE_ID(x,y,negz, net);
00219 neighbor[LINK_POS_Z] = NODE_ID(x,y,posz, net);
00220 DBprintf("X %d %d\n", neighbor[LINK_NEG_X], neighbor[LINK_POS_X]);
00221 DBprintf("Y %d %d\n", neighbor[LINK_NEG_Y], neighbor[LINK_POS_Y]);
00222 DBprintf("Z %d %d\n", neighbor[LINK_NEG_Z], neighbor[LINK_POS_Z]);
00223 }
00224
00225 friend class oLCB_t;
00226
00227 private:
00228 double overheadMultP;
00229 protected:
00230
00231 vector<rtrEvent_t*> rtrEventQ;
00232
00233
00234 rtrEventPool eventPool;
00235
00236 rtrPPool rpPool;
00237
00238 int routerID;
00239
00240 int iLCBLat;
00241
00242 int oLCBLat;
00243
00244 int routingLat;
00245
00246 int iQLat;
00247
00248 int rtrOutput_maxQSize_flits[ROUTER_NUM_LINKS + 1];
00249
00250 int rtrInput_maxQSize_flits[ROUTER_NUM_LINKS + 1];
00251
00252 int oLCB_maxSize_flits;
00253
00254
00255
00256
00257
00258
00259
00260 typedef map< pair<int, int>, pair<int, int> > routingTable_t;
00261
00262 routingTable_t routingTable;
00263
00264 public:
00265 void updateToken_flits (int dir, int vc, int flits );
00266 void returnToken_flits (int dir, int vc, int flits );
00267
00268 protected:
00269
00270 struct netlink {
00271 Link *link;
00272 int dir;
00273 };
00274
00275 typedef netlink* link_t;
00276
00277
00278 link_t rx_netlinks[ROUTER_NUM_LINKS];
00279
00280 link_t tx_netlinks[ROUTER_NUM_LINKS];
00281
00282
00283 map <Link*, int> rxNeighbor;
00284
00285
00286 int txCount[ROUTER_NUM_OUTQS];
00287
00288 int rxCount[ROUTER_NUM_INQS];
00289
00290 typedef deque<rtrP*> packetQ;
00291
00292
00293
00294
00295
00296 struct inQ_t
00297 {
00298 bool head_busy;
00299 int link, vc_rr, ready_vcQs;
00300 queue<int> skipQs;
00301 int size_flits[ROUTER_NUM_VCS];
00302 packetQ vcQ[ROUTER_NUM_VCS];
00303 bool ready () {
00304 return ((ready_vcQs > 0) && (!head_busy));
00305 }
00306 };
00307
00308 inQ_t inputQ[ROUTER_NUM_INQS];
00309
00310
00311
00312 bool ready_inQ;
00313
00314
00315
00316
00317 struct outQ_t
00318 {
00319 packetQ vcQ[ROUTER_NUM_VCS];
00320 int size_flits[ROUTER_NUM_VCS];
00321 };
00322
00323
00324 outQ_t outputQ[ROUTER_NUM_OUTQS][ROUTER_NUM_INQS];
00325
00326
00327
00328 struct oLCB_t
00329 {
00330 int size_flits;
00331 bool external_busy;
00332 bool internal_busy;
00333 int link;
00334 int vc_rr, ready_vc_count;
00335 queue<int> skipped_vcs;
00336 int ready_outQ_count[ROUTER_NUM_VCS];
00337 int ilink_rr[ROUTER_NUM_VCS];
00338 int vcTokens[ROUTER_NUM_VCS];
00339 int stall4tokens[ROUTER_NUM_VCS];
00340 packetQ dataQ;
00341
00342 bool readyXfer() {
00343 return (!dataQ.empty() && !external_busy);
00344 }
00345 bool readyInternal() {
00346 return ((ready_vc_count > 0) && !internal_busy);
00347 }
00348
00349 };
00350
00351
00352
00353 struct iLCB_t
00354 {
00355 int size_flits;
00356 bool internal_busy;
00357 int link;
00358 packetQ dataQ;
00359 bool readyInternal() {
00360 return (!dataQ.empty() && !internal_busy);
00361 }
00362 };
00363
00364
00365 oLCB_t outLCB[ROUTER_NUM_OUTQS];
00366
00367 iLCB_t inLCB[ROUTER_NUM_INQS];
00368
00369
00370
00371 bool ready_oLCB;
00372
00373
00374 bool ready_iLCB;
00375
00376 Network *network;
00377
00378 vector<Link*> linkV;
00379
00380 bool handleNicParcel(Event*);
00381 bool handleParcel(Event*,int dir);
00382 bool route(rtrP*);
00383
00384 void InLCB ( RtrEvent *e, int ilink, int ivc, int flits);
00385
00386 bool LCBtoInQ_start(rtrP *rp);
00387 void LCBtoInQ_readyNext(rtrP *rp);
00388 void LCBtoInQ_done (rtrP *rp, int ivc, int ilink);
00389 void InQtoOutQ_start (rtrP *rp);
00390 void InQtoOutQ_readyNext (rtrP *rp);
00391 void InQtoOutQ_done (rtrP *rp, int ovc, int ilink, int olink);
00392 void OutQtoLCB_start (rtrP *rp);
00393 void OutQtoLCB_readyNext (rtrP *rp, int olink, int ilink, int ovc, int flits);
00394 void OutQtoLCB_done (rtrP *rp);
00395 void LCBxfer_start (int dir);
00396 void LCBxfer_readyNext (int dir);
00397 void LCBxfer_done (rtrP *rp, int olink, int flits);
00398
00399 void arbitrateOutToLCB ();
00400 void arbitrateInToOut ();
00401 void iLCBtoIn ();
00402
00403 void setup();
00404 void dumpStats(FILE *fp);
00405 void finish();
00406
00407 void setupRoutingTable ( Params_t, int nodes, int xDim, int yDim, int zDim);
00408 void setVCRoutes ( int node, int dir, bool *crossDateline );
00409
00410 void advanceEventQ();
00411 void DebugEvent ();
00412
00413 int debug_interval;
00414 bool dumpTables;
00415
00416 public:
00417
00418 SS_router ( ComponentId_t id, Params_t& params );
00419
00420 private:
00421 SS_router();
00422 SS_router( const SS_router& );
00423 ~SS_router() {
00424 ;
00425 }
00426
00427
00428
00429
00430
00431 bool clock( Cycle_t cycle )
00432 {
00433
00434 m_cycle = cycle;
00435
00436 if (!rtrEventQ.empty())
00437 advanceEventQ();
00438
00439
00440 if (ready_oLCB)
00441 arbitrateOutToLCB ();
00442
00443 if (ready_inQ)
00444 arbitrateInToOut ();
00445
00446 if (ready_iLCB)
00447 iLCBtoIn();
00448 return true;
00449 }
00450
00451
00452 char LINK_DIR_STR[6][8];
00453
00454 int getID() {
00455 return routerID;
00456 }
00457
00458 void dumpTable( FILE* fp);
00459 void dumpState();
00460
00461 void txlinkTo ( Link* neighbor, int dir);
00462 bool checkLinks ();
00463
00464 Cycle_t m_cycle;
00465 bool m_print_info;
00466 Log< SS_ROUTER_DBG >& m_dbg;
00467 Log<>& m_log;
00468 };
00469
00470 #include "SS_router-inline.h"
00471
00472 #endif