00001
00024 #ifndef _genericaddressdecoder_cc_INC
00025 #define _genericaddressdecoder_cc_INC
00026
00027 #include "genericRC.h"
00028
00029 using namespace std;
00030
00031 GenericRC::GenericRC()
00032 {
00033 name = "AddrDecoder";
00034 node_ip = 0;
00035 address = 0;
00036 }
00037
00038 uint
00039 GenericRC::route_x_y(uint dest)
00040 {
00041 uint oport = -1;
00042 uint myx=-1, destx=-1, myy =-1, desty=-1;
00043 myx = grid_xloc[node_ip];
00044 myy = grid_yloc[node_ip];
00045 destx = grid_xloc[ dest ];
00046 desty = grid_yloc[ dest ];
00047 if ( myx == destx && myy == desty )
00048 oport = 0;
00049 else if ( myx == destx )
00050 {
00051 if( desty < myy )
00052 oport = 3;
00053 else
00054 oport = 4;
00055 }
00056 else
00057 {
00058 if( destx < myx )
00059 oport = 1;
00060 else
00061 oport = 2;
00062 }
00063
00064 #ifdef _DEBUG
00065 _DBG(" Route HEAD dest: %d oport: %d ", dest, oport);
00066 _DBG(" addr: %d myid_x: %d myid_y: %d destid_x: %d destid_y: %d", node_ip, myx, myy, destx, desty);
00067 #endif
00068
00069 return oport;
00070 }
00071
00072 void
00073 GenericRC::route_torus(HeadFlit* hf)
00074 {
00075 cout << " Torus routing not supported yet " << endl;
00076 exit(1);
00077 }
00078 void
00079 GenericRC::route_ring(HeadFlit* hf)
00080 {
00081 cout << " Rings not supported yet " << endl;
00082 exit(1);
00083 }
00084
00085 void
00086 GenericRC::route_negative_first(HeadFlit* hf)
00087 {
00088 uint dest = hf->dst_address;
00089 uint oport = -1;
00090 uint myx=-1, destx=-1, myy =-1, desty=-1;
00091 myx = grid_xloc[node_ip];
00092 myy = grid_yloc[node_ip];
00093 destx = grid_xloc[ dest ];
00094 desty = grid_yloc[ dest ];
00095 int deltax = destx - myx;
00096 int deltay = desty - myy;
00097 if( deltax == 0 && deltay == 0 )
00098 {
00099
00100 possible_out_ports.push_back(0);
00101 return;
00102 }
00103
00104 if ( deltax < 0 && deltay < 0 )
00105 {
00106
00107 possible_out_ports.push_back(1);
00108 possible_out_ports.push_back(3);
00109 return;
00110 }
00111 else if ( deltax < 0 )
00112 {
00113
00114 possible_out_ports.push_back(1);
00115 return;
00116 }
00117 else if ( deltay < 0 )
00118 {
00119
00120 possible_out_ports.push_back(3);
00121 return;
00122 }
00123 else if (deltax > 0 && deltay > 0 )
00124 {
00125
00126 possible_out_ports.push_back(2);
00127 possible_out_ports.push_back(4);
00128 return;
00129 }
00130 else if ( deltax == 0)
00131 {
00132 possible_out_ports.push_back(4);
00133 return;
00134 }
00135 else if( deltay == 0)
00136 {
00137 possible_out_ports.push_back(2);
00138 return;
00139 }
00140 else
00141 {
00142 _DBG(" ERROR: Some condition not covered deltax: %d , deltay:%d", deltax, deltay);
00143 }
00144 return;
00145 }
00146
00147 void
00148 GenericRC::route_west_first(HeadFlit* hf)
00149 {
00150 uint dest = hf->dst_address;
00151 uint oport = -1;
00152 uint myx=-1, destx=-1, myy =-1, desty=-1;
00153 myx = grid_xloc[node_ip];
00154 myy = grid_yloc[node_ip];
00155 destx = grid_xloc[ dest ];
00156 desty = grid_yloc[ dest ];
00157 int deltax = destx - myx;
00158 int deltay = desty - myy;
00159 if( deltax == 0 && deltay == 0 )
00160 {
00161 possible_out_ports.push_back(0);
00162 return;
00163 }
00164
00165 if ( deltax < 0 )
00166 {
00167 possible_out_ports.push_back(1);
00168 return;
00169 }
00170 else if ( deltax > 0 )
00171 {
00172 if ( deltay < 0)
00173 {
00174 possible_out_ports.push_back(2);
00175 possible_out_ports.push_back(3);
00176 return;
00177 }
00178 else if ( deltay > 0)
00179 {
00180 possible_out_ports.push_back(2);
00181 possible_out_ports.push_back(4);
00182 return;
00183 }
00184 else
00185 {
00186 possible_out_ports.push_back(2);
00187 return;
00188 }
00189 }
00190 else if ( deltax == 0 )
00191 {
00192 if ( deltay < 0)
00193 {
00194 possible_out_ports.push_back(3);
00195 return;
00196 }
00197 else if ( deltay > 0)
00198 {
00199 possible_out_ports.push_back(4);
00200 return;
00201 }
00202 else
00203 {
00204 cerr << "\nERROR should have exited earlier " << endl;
00205 }
00206 }
00207 else
00208 {
00209 _DBG(" ERROR: Some condition not covered deltax: %d , deltay:%d", deltax, deltay);
00210 }
00211 return;
00212 }
00213
00214 void
00215 GenericRC::route_north_last(HeadFlit* hf)
00216 {
00217 uint dest = hf->dst_address;
00218 uint oport = -1;
00219 uint myx=-1, destx=-1, myy =-1, desty=-1;
00220 myx = grid_xloc[node_ip];
00221 myy = grid_yloc[node_ip];
00222 destx = grid_xloc[ dest ];
00223 desty = grid_yloc[ dest ];
00224 int deltax = destx - myx;
00225 int deltay = desty - myy;
00226 if( deltax == 0 && deltay == 0 )
00227 {
00228 possible_out_ports.push_back(0);
00229 return;
00230 }
00231 if ( deltax < 0 )
00232 {
00233 if ( deltay < 0)
00234 {
00235 possible_out_ports.push_back(1);
00236 return;
00237 }
00238 else if ( deltay > 0 )
00239 {
00240 possible_out_ports.push_back(1);
00241 possible_out_ports.push_back(4);
00242 return;
00243 }
00244 else
00245 {
00246 possible_out_ports.push_back(1);
00247 return;
00248 }
00249 }
00250 else if ( deltax > 0 )
00251 {
00252 if ( deltay < 0)
00253 {
00254 possible_out_ports.push_back(2);
00255 return;
00256 }
00257 else if ( deltay > 0)
00258 {
00259 possible_out_ports.push_back(4);
00260 possible_out_ports.push_back(2);
00261 return;
00262 }
00263 else
00264 {
00265 possible_out_ports.push_back(2);
00266 return;
00267 }
00268 }
00269 else if ( deltax == 0 )
00270 {
00271 if ( deltay < 0)
00272 {
00273 possible_out_ports.push_back(3);
00274 return;
00275 }
00276 else if ( deltay > 0)
00277 {
00278 possible_out_ports.push_back(4);
00279 return;
00280 }
00281 else
00282 {
00283 cerr << "\nERROR should have exited earlier " << endl;
00284 }
00285 }
00286
00287 else
00288 {
00289 _DBG(" ERROR: Some condition not covered deltax: %d , deltay:%d", deltax, deltay);
00290 }
00291 return;
00292 }
00293
00294 void
00295 GenericRC::route_north_last_non_minimal(HeadFlit* hf)
00296 {
00297 uint dest = hf->dst_address;
00298 uint oport = -1;
00299 uint myx=-1, destx=-1, myy =-1, desty=-1;
00300 myx = grid_xloc[node_ip];
00301 myy = grid_yloc[node_ip];
00302 destx = grid_xloc[ dest ];
00303 desty = grid_yloc[ dest ];
00304 int deltax = destx - myx;
00305 int deltay = desty - myy;
00306 bool is_fringe_router = false;
00307 if ( node_ip%grid_size == 0 || (node_ip+1)%grid_size == 0
00308 || (node_ip+grid_size) > no_nodes || ( node_ip-grid_size)<0)
00309 is_fringe_router = true;
00310
00311
00312 if( is_fringe_router )
00313 {
00314 possible_out_ports.push_back(route_x_y(hf->dst_address));
00315 return;
00316 }
00317
00318 if( deltax == 0 && deltay == 0 )
00319 {
00320 possible_out_ports.push_back(0);
00321 return;
00322 }
00323 else if( hf->inport == 4 )
00324 {
00325 possible_out_ports.push_back(3);
00326 return;
00327 }
00328 if ( deltax != 0 || (deltax == 0 && deltay > 0) )
00329 {
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 if( hf->inport != 1 )
00344 {
00345 possible_out_ports.push_back(1);
00346
00347 }
00348 if( hf->inport != 2)
00349 {
00350 possible_out_ports.push_back(2);
00351
00352 }
00353 if( hf->inport != 4)
00354 {
00355 possible_out_ports.push_back(4);
00356
00357 }
00358 return;
00359 }
00360 else if ( deltax == 0 && deltay < 0)
00361 {
00362 possible_out_ports.push_back(3);
00363
00364
00365
00366
00367
00368
00369 return;
00370 }
00371 else
00372 {
00373 _DBG(" ERROR: Some condition not covered deltax: %d , deltay:%d", deltax, deltay);
00374 }
00375 return;
00376 }
00377
00378 void
00379 GenericRC::route_odd_even(HeadFlit* hf)
00380 {
00381 uint src = hf->src_address;
00382 uint dest = hf->dst_address;
00383 uint oport = -1;
00384 uint c0=-1, d0=-1, c1=-1, d1=-1, s0=-1, s1=-1;
00385 c0 = grid_xloc[node_ip];
00386 c1 = grid_yloc[node_ip];
00387 d0 = grid_xloc[ dest ];
00388 d1 = grid_yloc[ dest ];
00389 s0 = grid_xloc[ src ];
00390 s1 = grid_yloc[ src ];
00391 int e0 = d0-c0;
00392 int e1 = d1-c1;
00393
00394 if( e0 == 0 && e1 == 0 )
00395 {
00396 possible_out_ports.push_back(0);
00397 return;
00398 }
00399
00400 if( e0 == 0 )
00401 {
00402 if( e1>0 )
00403 possible_out_ports.push_back(3);
00404 else
00405 possible_out_ports.push_back(4);
00406 }
00407 else if ( e0 > 0 )
00408 {
00409 if ( e1 == 0 )
00410 possible_out_ports.push_back(2);
00411 else
00412 {
00413 if ((c0%2) != 0 || c0==s0 )
00414 {
00415 if ( e1 > 0 )
00416 possible_out_ports.push_back(3);
00417 else
00418 possible_out_ports.push_back(4);
00419 }
00420
00421 if ( (d0%2)!=0 || e0 != 1 )
00422 possible_out_ports.push_back(2);
00423 }
00424 }
00425 else
00426 {
00427 possible_out_ports.push_back(1);
00428 if ( (c0%2)==0 )
00429 {
00430 if ( e1 > 0 )
00431 possible_out_ports.push_back(3);
00432 else
00433 possible_out_ports.push_back(4);
00434 }
00435 }
00436
00437 if( possible_out_ports.size() == 0 )
00438 {
00439 _DBG(" ERROR: Some condition not covered d0: %d , d1:%d", d0, d1);
00440 }
00441 return;
00442 }
00443
00444 void
00445 GenericRC::push (Flit* f, uint ch )
00446 {
00447 if(ch > addresses.size())
00448 cout << "Invalid VC Exception " << endl;
00449
00450
00451
00452 if( f->type == HEAD )
00453 {
00454 HeadFlit* header = static_cast< HeadFlit* >( f );
00455 addresses[ch].last_adaptive_port = 0;
00456 addresses[ch].possible_out_ports.clear();
00457 addresses[ch].possible_out_vcs.clear();
00458 possible_out_ports.clear();
00459 possible_out_vcs.clear();
00460 addresses[ch].last_adaptive_port = 0;
00461
00462 if( rc_method == NEGATIVE_FIRST )
00463 {
00464 possible_out_ports.clear();
00465 route_negative_first( header );
00466 addresses [ch].out_port = possible_out_ports.at(0);
00467
00468 for ( uint i=0; i<possible_out_ports.size(); i++)
00469 addresses [ch].possible_out_ports.push_back(possible_out_ports[i]);
00470
00471 }
00472 else if( rc_method == WEST_FIRST)
00473 {
00474 possible_out_ports.clear();
00475 route_west_first( header );
00476 addresses [ch].out_port = possible_out_ports.at(0);
00477
00478 for ( uint i=0; i<possible_out_ports.size(); i++)
00479 addresses [ch].possible_out_ports.push_back(possible_out_ports[i]);
00480
00481 }
00482 else if( rc_method == NORTH_LAST)
00483 {
00484 possible_out_ports.clear();
00485 route_north_last( header );
00486 addresses [ch].out_port = possible_out_ports.at(0);
00487
00488 for ( uint i=0; i<possible_out_ports.size(); i++)
00489 addresses [ch].possible_out_ports.push_back(possible_out_ports[i]);
00490
00491 }
00492 else if( rc_method == ODD_EVEN)
00493 {
00494 possible_out_ports.clear();
00495 route_odd_even( header );
00496 addresses [ch].out_port = possible_out_ports.at(0);
00497 for ( uint i=0; i<possible_out_ports.size(); i++)
00498 addresses [ch].possible_out_ports.push_back(possible_out_ports[i]);
00499
00500 }
00501 else if( rc_method == NORTH_LAST_NON_MINIMAL)
00502 {
00503 possible_out_ports.clear();
00504 route_north_last_non_minimal( header );
00505 addresses [ch].out_port = possible_out_ports.at(0);
00506 for ( uint i=0; i<possible_out_ports.size(); i++)
00507 addresses [ch].possible_out_ports.push_back(possible_out_ports[i]);
00508
00509 }
00510 else if( rc_method == RING_ROUTING)
00511 {
00512 possible_out_ports.clear();
00513 possible_out_vcs.clear();
00514 route_ring( header );
00515
00516
00517 if( possible_out_vcs.size() == 0 )
00518 {
00519 if ( node_ip%grid_size == 0 && header->inport==1 )
00520 possible_out_vcs.push_back((vcs - header->vc -1)%vcs);
00521 else if( static_cast<int>(node_ip-grid_size)<0 && header->inport== 3 )
00522 possible_out_vcs.push_back((vcs - header->vc -1)%vcs);
00523 else
00524 possible_out_vcs.push_back(header->vc);
00525
00526 }
00527
00528 addresses[ch].possible_out_ports.push_back(possible_out_ports[0]);
00529 addresses[ch].possible_out_vcs.push_back(possible_out_vcs[0]);
00530
00531 addresses [ch].out_port = possible_out_ports.at(0);
00532 addresses [ch].channel = possible_out_vcs.at(0);
00533
00534
00535
00536 }
00537 else
00538 {
00539 addresses [ch].out_port = route_x_y(header->dst_address);
00540 addresses [ch].possible_out_ports.push_back(route_x_y(header->dst_address));
00541 }
00542
00543 if( rc_method != TORUS_ROUTING && rc_method != RING_ROUTING )
00544 {
00545 if( do_request_reply_network )
00546 {
00547 if( header->msg_class == RESPONSE_PKT )
00548 addresses[ch].possible_out_vcs.push_back(1);
00549 else
00550 addresses[ch].possible_out_vcs.push_back(0);
00551 }
00552 else
00553 {
00554 for ( uint i=0;i<vcs;i++)
00555 addresses[ch].possible_out_vcs.push_back(i);
00556 }
00557
00558 }
00559
00560 addresses [ch].route_valid = true;
00561
00562 #ifdef _DEEP_DEBUG
00563 _DBG(" computed oport %d %d dest: %d src:%d addr:%lld",addresses [ch].out_port, addresses [ch].channel, header->dst_address, header->src_address, header->addr);
00564 #endif
00565
00566 }
00567 else if(f->type == TAIL)
00568 {
00569 if( !addresses[ch].route_valid)
00570 {
00571 _DBG_NOARG("TAIL InvalidAddrException" );
00572 }
00573
00574 addresses[ch].route_valid = false;
00575 addresses[ch].possible_out_ports.clear();
00576 addresses[ch].possible_out_vcs.clear();
00577 addresses[ch].last_adaptive_port = 0;
00578 possible_out_ports.clear();
00579 possible_out_vcs.clear();
00580 }
00581 else if (f->type == BODY)
00582 {
00583 if( !addresses[ch].route_valid)
00584 {
00585 _DBG_NOARG("BODY InvalidAddrException" );
00586 }
00587 }
00588 else
00589 {
00590 _DBG(" InvalidFlitException fty: %d", f->type);
00591 }
00592
00593 return ;
00594 }
00595
00596
00597 uint
00598 GenericRC::get_output_port ( uint ch)
00599 {
00600 uint oport = -1;
00601 if (addresses[ch].last_adaptive_port == addresses[ch].possible_out_ports.size())
00602 addresses[ch].last_adaptive_port = 0;
00603 oport = addresses[ch].possible_out_ports[addresses[ch].last_adaptive_port];
00604 addresses[ch].last_adaptive_port++;
00605
00606 return oport;
00607 }
00608
00609 uint
00610 GenericRC::no_adaptive_vcs( uint ch )
00611 {
00612 return addresses[ch].possible_out_vcs.size();
00613 }
00614
00615 uint
00616 GenericRC::no_adaptive_ports( uint ch )
00617 {
00618 return addresses[ch].possible_out_ports.size();
00619 }
00620
00621 uint
00622 GenericRC::get_virtual_channel ( uint ch )
00623 {
00624 uint och = -1;
00625 if (addresses[ch].last_vc == addresses[ch].possible_out_vcs.size())
00626 addresses[ch].last_vc = 0;
00627
00628 och = addresses[ch].possible_out_vcs[addresses[ch].last_vc];
00629 addresses[ch].last_vc++;
00630
00631 return och;
00632 }
00633
00634 void
00635 GenericRC::resize ( uint ch )
00636 {
00637 vcs = ch;
00638 addresses.resize(ch);
00639 for ( uint i = 0 ; i<ch ; i++ )
00640 {
00641 addresses[i].route_valid = false;
00642 addresses[i].last_vc = 0;
00643 }
00644 return ;
00645 }
00646
00647 uint
00648 GenericRC::get_no_channels()
00649 {
00650 return addresses.size();
00651 }
00652
00653 bool
00654 GenericRC::is_empty ()
00655 {
00656 uint channels = addresses.size();
00657 for ( uint i=0 ; i<channels ; i++ )
00658 if(addresses[i].route_valid)
00659 return false;
00660
00661 return true;
00662 }
00663
00664 string
00665 GenericRC::toString () const
00666 {
00667 stringstream str;
00668 str << "GenericRC"
00669 << "\tchannels: " << addresses.size();
00670 return str.str();
00671 }
00672 #endif
00673