00001 /* 00002 // Mesh routing 00003 inline bool SS_router::findRoute( int destNid, int inVC, int inDir, 00004 int& outVC, int& outDir ) 00005 { 00006 int xDim = network->xDimSize(); 00007 int yDim = network->yDimSize(); 00008 int zDim = network->zDimSize(); 00009 00010 int my_xPos = calcXPosition( routerID, xDim, yDim, zDim ); 00011 int my_yPos = calcYPosition( routerID, xDim, yDim, zDim ); 00012 int my_zPos = calcZPosition( routerID, xDim, yDim, zDim ); 00013 00014 int dst_xPos = calcXPosition( destNid, xDim, yDim, zDim ); 00015 int dst_yPos = calcYPosition( destNid, xDim, yDim, zDim ); 00016 int dst_zPos = calcZPosition( destNid, xDim, yDim, zDim ); 00017 00018 outVC = 0; 00019 00020 if ( my_xPos != dst_xPos ) { 00021 if ( my_xPos < dst_xPos ) outDir = 0; 00022 else outDir = 1; 00023 } 00024 else if ( my_yPos != dst_yPos ) { 00025 if ( my_yPos < dst_yPos ) outDir = 2; 00026 else outDir = 3; 00027 } 00028 else if ( my_zPos != dst_zPos ) { 00029 if ( my_zPos < dst_zPos ) outDir = 4; 00030 else outDir = 5; 00031 } 00032 else outDir = 6; 00033 00034 // printf("Routing (%d,%d,%d) to (%d,%d,%d) out port %d\n",my_xPos,my_yPos,my_zPos,dst_xPos,dst_yPos,dst_zPos,outDir); 00035 00036 return true; 00037 } 00038 */ 00039 00040 /* 00041 // Unidirectional torus routing 00042 inline bool SS_router::findRoute( int destNid, int inVC, int inDir, 00043 int& outVC, int& outDir ) 00044 { 00045 int xDim = network->xDimSize(); 00046 int yDim = network->yDimSize(); 00047 int zDim = network->zDimSize(); 00048 00049 int my_xPos = calcXPosition( routerID, xDim, yDim, zDim ); 00050 int my_yPos = calcYPosition( routerID, xDim, yDim, zDim ); 00051 int my_zPos = calcZPosition( routerID, xDim, yDim, zDim ); 00052 00053 int dst_xPos = calcXPosition( destNid, xDim, yDim, zDim ); 00054 int dst_yPos = calcYPosition( destNid, xDim, yDim, zDim ); 00055 int dst_zPos = calcZPosition( destNid, xDim, yDim, zDim ); 00056 00057 if ( my_xPos != dst_xPos ) { 00058 outDir = LINK_POS_X; 00059 if ( inDir == LINK_NEG_X ) { 00060 if ( iAmDateline(0) ) { 00061 // printf("Hit x dateline\n"); 00062 outVC = 2; 00063 } 00064 else outVC = inVC; 00065 } 00066 else outVC = 0; 00067 } 00068 else if ( my_yPos != dst_yPos ) { 00069 outDir = LINK_POS_Y; 00070 if ( inDir == LINK_NEG_Y ) { 00071 if ( iAmDateline(1) ) { 00072 // printf("Hit y dateline\n"); 00073 outVC = 2; 00074 } 00075 else outVC = inVC; 00076 } 00077 else outVC = 0; 00078 } 00079 else if ( my_zPos != dst_zPos ) { 00080 outDir = LINK_POS_Z; 00081 if ( inDir == LINK_NEG_Z ) { 00082 if ( iAmDateline(2) ) { 00083 // printf("Hit z dateline\n"); 00084 outVC = 2; 00085 } 00086 else outVC = inVC; 00087 } 00088 else outVC = 0; 00089 } 00090 else { 00091 outDir = 6; 00092 outVC = 0; 00093 } 00094 00095 return true; 00096 } 00097 */ 00098 /* 00099 // Full torus routing 00100 inline bool SS_router::findRoute( int destNid, int inVC, int inDir, 00101 int& outVC, int& outDir ) 00102 { 00103 int xDim = network->xDimSize(); 00104 int yDim = network->yDimSize(); 00105 int zDim = network->zDimSize(); 00106 00107 int my_xPos = calcXPosition( routerID, xDim, yDim, zDim ); 00108 int my_yPos = calcYPosition( routerID, xDim, yDim, zDim ); 00109 int my_zPos = calcZPosition( routerID, xDim, yDim, zDim ); 00110 00111 int dst_xPos = calcXPosition( destNid, xDim, yDim, zDim ); 00112 int dst_yPos = calcYPosition( destNid, xDim, yDim, zDim ); 00113 int dst_zPos = calcZPosition( destNid, xDim, yDim, zDim ); 00114 00115 if ( my_xPos != dst_xPos ) { 00116 outDir = LINK_POS_X; 00117 if ( inDir == LINK_NEG_X ) { 00118 if ( iAmDateline(0) ) { 00119 // printf("Hit x dateline\n"); 00120 outVC = 2; 00121 } 00122 else outVC = inVC; 00123 } 00124 else outVC = 0; 00125 } 00126 else if ( my_yPos != dst_yPos ) { 00127 outDir = LINK_POS_Y; 00128 if ( inDir == LINK_NEG_Y ) { 00129 if ( iAmDateline(1) ) { 00130 // printf("Hit y dateline\n"); 00131 outVC = 2; 00132 } 00133 else outVC = inVC; 00134 } 00135 else outVC = 0; 00136 } 00137 else if ( my_zPos != dst_zPos ) { 00138 outDir = LINK_POS_Z; 00139 if ( inDir == LINK_NEG_Z ) { 00140 if ( iAmDateline(2) ) { 00141 // printf("Hit z dateline\n"); 00142 outVC = 2; 00143 } 00144 else outVC = inVC; 00145 } 00146 else outVC = 0; 00147 } 00148 else { 00149 outDir = 6; 00150 outVC = 0; 00151 } 00152 00153 return true; 00154 } 00155 */ 00156 00157 inline bool SS_router::findRoute( int destNid, int inVC, int inDir, 00158 int& outVC, int& outDir ) 00159 { 00160 00161 if ( destNid >= network->size() ) { 00162 return false; 00163 } 00164 00165 outDir = findOutputDir( destNid ); 00166 outVC = findOutputVC( inVC, inDir, outDir ); 00167 DBprintf("XXX destNid=%d inVC=%d inDir=%d outVC=%d outDir=%d\n", 00168 destNid, inVC, inDir, outVC, outDir); 00169 // exit(0); 00170 // if ( inDir != ROUTER_HOST_PORT && inDir == outDir ) printf("Ping pong routing\n"); 00171 // if ( inDir != ROUTER_HOST_PORT && dimension(inDir) == dimension(outDir) && inVC != outVC ) printf("Crossing dateline\n"); 00172 // if ( inVC != outVC ) printf("Input/output VCs different\n"); 00173 // printf("oVC: %d\n",outVC); 00174 return true; 00175 } 00176 00177 00178 inline int SS_router::findOutputDir( int destNid ) 00179 { 00180 // DBprintf( "XXX destNid=%d dir=%d\n", destNid, m_routingTableV[destNid] ); 00181 return m_routingTableV[destNid]; 00182 } 00183 00184 inline int SS_router::dimension( int dir ) 00185 { 00186 // don't want to a modulo 00187 static int foo[] = { 0,0,1,1,2,2 }; 00188 return foo[dir]; 00189 } 00190 00191 inline bool SS_router::iAmDateline( int dimension ) 00192 { 00193 return m_datelineV[ dimension ]; 00194 } 00195 00196 inline int SS_router::changeVC( int vc ) 00197 { 00198 /* static int foo[] = { 1, 0, 3, 2 }; */ 00199 static int foo[] = { 2, 0, 0, 2 }; 00200 return foo[vc]; 00201 } 00202 00203 inline int SS_router::findOutputVC( int inVC, int inDir, int outDir ) 00204 { 00205 int outVC = inVC; 00206 int inDim = dimension( inDir ); 00207 int outDim = dimension( outDir ); 00208 00209 /* printf("---> %d %d %d %d\n",inDir,dimension(inDir),outDir,dimension(outDir)); */ 00210 00211 if ( inDir == ROUTER_HOST_PORT || outDir == ROUTER_HOST_PORT ) return 0; 00212 00213 /* if ( inDim == outDim ) printf("same dimension: %d %d %d\n",inDir,outDir,inDim); */ 00214 00215 /* printf("-----> %d: %d %d %d\n",routerID,inDim,outDim,iAmDateline( inDim )); */ 00216 if ( ( inDim == outDim ) && iAmDateline( inDim ) ) 00217 { 00218 outVC = changeVC( inVC ); 00219 /* printf("--> %d %d %d %d\n",inDim,outDim,inVC,outVC); */ 00220 } 00221 // DBprintf( "XXX inVC=%d inDir=%d outDir=%d outVC=%d\n", 00222 // inVC, inDir, outDir, outVC ); 00223 return outVC; 00224 } 00225 00226 inline int SS_router::calcXPosition( int nodeNumber, int x, int y, int z ) 00227 { 00228 return nodeNumber % x; 00229 } 00230 00231 inline int SS_router::calcYPosition( int nodeNumber, int x, int y, int z ) 00232 { 00233 return ( nodeNumber / x ) % y; 00234 } 00235 00236 inline int SS_router::calcZPosition( int nodeNumber, int x, int y, int z ) 00237 { 00238 return nodeNumber / ( x * y ); 00239 } 00240 00241 inline int SS_router::calcDirection( int srcPos, int dstPos, int size ) 00242 { 00243 int pos; 00244 int neg; 00245 if ( srcPos < dstPos ) { 00246 pos = ( dstPos - srcPos ); 00247 neg = srcPos + ( size - dstPos ) + 1; 00248 } else { 00249 neg = ( srcPos - dstPos ); 00250 pos = dstPos + ( size - srcPos ) + 1; 00251 } 00252 return pos > neg ? -1 : + 1; 00253 }