00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef _genericRouterPhy_cc_INC
00020 #define _genericRouterPhy_cc_INC
00021
00022 #include "genericRouterPhy.h"
00023 using namespace std;
00024
00025 GenericRouterPhy::GenericRouterPhy ()
00026 {
00027 name = "Router" ;
00028 ticking = false;
00029 }
00030
00031 GenericRouterPhy::~GenericRouterPhy()
00032 {
00033 }
00034
00035 void
00036 GenericRouterPhy::init (uint p, uint v, uint cr, uint bs)
00037 {
00038 ports =p;
00039 vcs =v;
00040 credits =cr;
00041 buffer_size = bs;
00042
00043 address = myId();
00044
00045
00046 in_buffers.resize(ports);
00047 decoders.resize(ports);
00048 input_buffer_state.resize(ports*vcs);
00049 swa.resize(ports);
00050 xbar.setup(ports,vcs);
00051 downstream_credits.resize(ports);
00052
00053
00054 stat_packet_out.resize(ports);
00055 stat_flit_out.resize(ports);
00056
00057
00058 for(uint i=0; i<ports; i++)
00059 {
00060 decoders[i].node_ip = node_ip;
00061 decoders[i].address = address;
00062 stat_packet_out[i].resize(ports);
00063 stat_flit_out[i].resize(ports);
00064 }
00065 swa.node_ip = node_ip;
00066 swa.address = address;
00067
00068
00069
00070
00071 for(uint i=0; i<ports; i++)
00072 {
00073 downstream_credits[i].resize(vcs);
00074 in_buffers[i].resize( vcs, buffer_size );
00075 decoders[i].resize( vcs );
00076 }
00077
00078
00079
00080
00081
00082 for(uint i=0; i<ports; i++)
00083 for(uint j=0; j<vcs; j++)
00084 {
00085 downstream_credits[i][j] = credits;
00086 input_buffer_state[i*vcs+j].pipe_stage = EMPTY;
00087 }
00088
00089
00090 packets = 0;
00091 flits = 0;
00092 total_packet_latency = 0;
00093
00094 return ;
00095 }
00096
00099 void
00100 GenericRouterPhy::set_no_nodes( uint nodes )
00101 {
00102 for ( uint i=0; i<decoders.size(); i++)
00103 {
00104 decoders[i].grid_xloc.resize(nodes);
00105 decoders[i].grid_yloc.resize(nodes);
00106 }
00107 }
00108
00109 void
00110 GenericRouterPhy::set_grid_x_location( uint port, uint x_node, uint value)
00111 {
00112 decoders[port].grid_xloc[x_node]= value;
00113 }
00114
00115 void
00116 GenericRouterPhy::set_grid_y_location( uint port, uint y_node, uint value)
00117 {
00118 decoders[port].grid_yloc[y_node]= value;
00119 }
00120
00121
00122
00123 void
00124 GenericRouterPhy::process_event ( IrisEvent* e )
00125 {
00126 switch(e->type)
00127 {
00128 case LINK_ARRIVAL_EVENT:
00129
00130
00131
00132 handle_link_arrival_event(e);
00133 break;
00134 case TICK_EVENT:
00135
00136
00137
00138 handle_tick_event(e);
00139 break;
00140 default:
00141
00142
00143
00144
00145 _DBG("GenericRouterPhy:: Unk event exception %d", e->type);
00146 break;
00147 }
00148 return ;
00149 }
00150
00157 string
00158 GenericRouterPhy::print_stats()
00159 {
00160 stringstream str;
00161 str << "\n router[" << node_ip << "] packet latency: " << total_packet_latency
00162 << "\n router[" << node_ip << "] flits/packets: " << (flits+0.0)/(packets)
00163 << "\n router[" << node_ip << "] average packet latency: " << (total_packet_latency+0.0)/packets
00164 << "\n router[" << node_ip << "] last_flit_out_cycle: " << last_flit_out_cycle
00165 << " ";
00166 str << "\n router[" << node_ip << "] packets: " << packets
00167 << "\n router[" << node_ip << "] flits: " << flits;
00168 if( stat_print_level > 2 )
00169 {
00170 for( uint i=0; i<ports; i++)
00171 for ( uint j=0; j<ports; j++)
00172 {
00173 string in_port = "Inv";
00174 switch( i )
00175 {
00176 case 0 :
00177 in_port = "Inj";
00178 break;
00179 case 1:
00180 in_port = 'E';
00181 break;
00182 case 2:
00183 in_port = 'W';
00184 break;
00185 case 3:
00186 in_port = 'S';
00187 break;
00188 case 4:
00189 in_port = 'N';
00190 break;
00191 default:
00192 in_port = "Invalid";
00193 break;
00194 }
00195
00196 string out_port = "Inv";
00197 switch( j )
00198 {
00199 case 0 :
00200 out_port = "Ejection";
00201 break;
00202 case 1:
00203 out_port = 'W';
00204 break;
00205 case 2:
00206 out_port = 'E';
00207 break;
00208 case 3:
00209 out_port = 'N';
00210 break;
00211 case 4:
00212 out_port = 'S';
00213 break;
00214 default:
00215 out_port = "Invalid";
00216 break;
00217 }
00218 if ( i!=j)
00219 {
00220 str << "\n router[" << node_ip << "] Packets out " << in_port
00221 << " going " << out_port << " : " << stat_packet_out[i][j];
00222 str << "\n router[" << node_ip << "] Flits out " << in_port
00223 << " going " << out_port << " : " << stat_flit_out[i][j];
00224 }
00225
00226 }
00227 }
00228
00229
00230 return str.str();
00231 }
00232
00234 void
00235 GenericRouterPhy::handle_link_arrival_event ( IrisEvent* e )
00236 {
00237 LinkArrivalData* data = static_cast<LinkArrivalData*>(e->event_data.at(0));
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 if(data->type == FLIT_ID)
00251 {
00252
00253 flits++;
00254 if( data->ptr->type == TAIL || data->ptr->is_single_flit_pkt )
00255 packets++;
00256
00257
00258 bool found = false;
00259 uint port = -1;
00260
00261 for ( uint i=0 ; i< ports ; i++ )
00262 if(static_cast<GenericLink*>(input_connections[i])->input_connection)
00263 if( e->src_id == static_cast<GenericLink*>(input_connections[i])->input_connection->address)
00264 {
00265 found = true;
00266 port = i;
00267 break;
00268 }
00269
00270
00271 if( !found )
00272 {
00273 _DBG(" Input port not found src_addr: %d", e->src_id);
00274 }
00275
00276
00277 in_buffers[port].change_push_channel(data->vc);
00278 in_buffers[port].push(data->ptr);
00279 decoders[port].push(data->ptr,data->vc);
00280
00281
00282
00283
00284
00285
00286 if( data->ptr->type == HEAD )
00287 {
00288 HeadFlit* hf = static_cast<HeadFlit*>(data->ptr);
00289 input_buffer_state[port*vcs+data->vc].input_port = port;
00290 input_buffer_state[port*vcs+data->vc].input_channel = data->vc;
00291 input_buffer_state[port*vcs+data->vc].pipe_stage = FULL;
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 input_buffer_state[port*vcs+data->vc].possible_oports.clear();
00313 input_buffer_state[port*vcs+data->vc].possible_ovcs.clear();
00314 input_buffer_state[port*vcs+data->vc].possible_oports.resize(1);
00315 input_buffer_state[port*vcs+data->vc].possible_ovcs.resize(1);
00316 input_buffer_state[port*vcs+data->vc].possible_oports[0] = decoders[port].get_output_port(data->vc);
00317 input_buffer_state[port*vcs+data->vc].possible_ovcs[0] = 0;
00318 input_buffer_state[port*vcs+data->vc].length= hf->length;
00319 input_buffer_state[port*vcs+data->vc].credits_sent= hf->length;
00320 input_buffer_state[port*vcs+data->vc].arrival_time= ceil(Simulator::Now());
00321 input_buffer_state[port*vcs+data->vc].clear_message= false;
00322 input_buffer_state[port*vcs+data->vc].flits_in_ib = 0;
00323
00324 }
00325 else
00326 {
00327 istat->stat_router[node_ip]->ib_cycles++;
00328 #ifdef _DEBUG_ROUTER
00329 _DBG(" BW inport:%d invc:%d oport:%d ovc:%d ft:%d", port, data->vc,
00330 input_buffer_state[port*vcs+data->vc].output_port, input_buffer_state[port*vcs+data->vc].output_channel, data->ptr->type);
00331 #endif
00332
00333 }
00334
00335 }
00336
00337
00338
00339 else if ( data->type == CREDIT_ID)
00340 {
00341
00342 bool found = false;
00343 uint port = -1;
00344 for ( uint i=0 ; ports ; i++ )
00345 if(static_cast<GenericLink*>(output_connections[i])->output_connection)
00346 if( static_cast<GenericLink*>(output_connections[i])->output_connection->address == e->src_id)
00347 {
00348 port = i;
00349 found = true;
00350 break;
00351 }
00352 if(!found)
00353 {
00354 _DBG(" Output port not found src_addr: %d", e->src_id);
00355 }
00356
00357 downstream_credits[port][data->vc]++;
00358 #ifdef _DEBUG_ROUTER
00359
00360
00361
00362
00363
00364
00365
00366
00367 _DBG(" Got a credit port:%d vc:%d in_buffers[port][vc]:%d ", port, data->vc, downstream_credits[port][data->vc]);
00368 #endif
00369
00370 }
00371 else
00372 {
00373 _DBG( "handle_link_arrival_event Unk data type %d ", data->type);
00374 }
00375
00376
00377
00378
00379 if(!ticking)
00380 {
00381 ticking = true;
00382 IrisEvent* event = new IrisEvent();
00383 event->type = TICK_EVENT;
00384 event->vc = e->vc;
00385 Simulator::Schedule( floor(Simulator::Now())+1, &NetworkComponent::process_event, this, event);
00386 }
00387
00388 delete data;
00389 delete e;
00390 return ;
00391 }
00392
00393 void
00394 GenericRouterPhy::do_switch_traversal()
00395 {
00396
00397
00398
00399
00400
00401
00402 for( uint i=0; i<ports*vcs; i++)
00403 if( input_buffer_state[i].pipe_stage == SW_TRAVERSAL)
00404 {
00405 uint oport = input_buffer_state[i].output_port;
00406 uint iport = input_buffer_state[i].input_port;
00407 ticking = true;
00408 if( !xbar.is_empty(oport,0)
00409 && input_buffer_state[i].flits_in_ib > 0
00410 && downstream_credits[oport][0]>0 )
00411 {
00412 istat->stat_router[node_ip]->st_cycles++;
00413 in_buffers[iport].change_pull_channel(0);
00414 Flit* f = in_buffers[iport].pull();
00415 input_buffer_state[i].flits_in_ib--;
00416
00417 last_flit_out_cycle = Simulator::Now();
00418
00419 LinkArrivalData* data = new LinkArrivalData();
00420 data->type = FLIT_ID;
00421 data->vc = 0;
00422 data->ptr = f;
00423
00424 stat_flit_out[iport][oport]++;
00425 #ifdef _DEEP_DEBUG
00426 _DBG(" FLIT OUT ftype: %d ", f->type);
00427 switch( f->type)
00428 {
00429 case HEAD:
00430 cout << static_cast<HeadFlit*>(f)->toString();
00431 break;
00432 case BODY:
00433 cout << static_cast<BodyFlit*>(f)->toString();
00434 break;
00435 case TAIL:
00436 cout << static_cast<TailFlit*>(f)->toString();
00437 break;
00438 }
00439 #endif
00440 IrisEvent* event = new IrisEvent();
00441 event->type = LINK_ARRIVAL_EVENT;
00442 event->event_data.push_back(data);
00443 event->src_id = address;
00444 event->dst_id = output_connections[oport]->address;
00445 event->vc = data->vc;
00446 Simulator::Schedule( Simulator::Now()+0.75,
00447 &NetworkComponent::process_event,
00448 static_cast<GenericLink*>(output_connections[oport])->output_connection,event);
00449 static_cast<GenericLink*>(output_connections[oport])->flits_passed++;
00450 downstream_credits[oport][0]--;
00451 if( f->type == TAIL || f->is_single_flit_pkt )
00452 {
00453
00454 double lat;
00455 if(do_two_stage_router)
00456 lat = Simulator::Now() - input_buffer_state[i].arrival_time;
00457 else
00458 lat = (Simulator::Now() - input_buffer_state[i].arrival_time)+1;
00459
00460 total_packet_latency+= lat;
00461 if( f->type == HEAD)
00462 {
00463 HeadFlit* hf = static_cast<HeadFlit*>(f);
00464 hf->avg_network_latency += lat;
00465 hf->hop_count++;
00466 }
00467 else
00468 {
00469 TailFlit* tf = static_cast<TailFlit*>(f);
00470 tf->avg_network_latency += lat;
00471 tf->hop_count++;
00472 }
00473 stat_packet_out[iport][oport]++;
00474
00475
00476
00477 input_buffer_state[i].clear_message = true;
00478 input_buffer_state[i].pipe_stage = EMPTY;
00479 swa.clear_winner(input_buffer_state[i].output_port, input_buffer_state[i].input_port);
00480 xbar.pull(input_buffer_state[i].output_port,input_buffer_state[i].output_channel);
00481 #ifdef _DEBUG_ROUTER
00482 _DBG(" Tail FO clear pkt for inport %d oport %d ", iport, oport);
00483 #endif
00484 }
00485 else
00486 {
00487 #ifdef _DEBUG_ROUTER
00488 _DBG(" Flit out for inport %d oport %d fty: %d ", iport, oport, f->type);
00489 #endif
00490 }
00491
00492
00493
00494
00495 send_credit_back(i);
00496
00497 }
00498 }
00499
00500 }
00501
00502 void
00503 GenericRouterPhy::do_switch_allocation()
00504 {
00505
00506 bool sa_active = false;
00507 for( uint i=0; i<ports*vcs; i++)
00508 if( input_buffer_state[i].pipe_stage == SWA_REQUESTED)
00509 {
00510 if ( !swa.is_empty())
00511 {
00512 uint oport = -1;
00513 SA_unit vca_winner;
00514 uint iport = input_buffer_state[i].input_port;
00515 for ( uint j=0; j<input_buffer_state[i].possible_oports.size(); j++)
00516 {
00517 oport = input_buffer_state[i].possible_oports[j];
00518 vca_winner = swa.pick_winner(oport);
00519 sa_active = true;
00520 }
00521
00522 if( vca_winner.port == iport )
00523 {
00524 input_buffer_state[i].pipe_stage = SW_TRAVERSAL;
00525 input_buffer_state[i].output_port = oport;
00526 input_buffer_state[i].output_channel = 0;
00527 xbar.configure_crossbar(iport,oport,0);
00528
00529
00530
00531
00532
00533 xbar.push(oport,0);
00534
00535 #ifdef _DEBUG_ROUTER
00536 _DBG(" SWA won for inport %d oport %d ", iport, oport);
00537 #endif
00538 }
00539 else
00540 {
00541 #ifdef _DEBUG_ROUTER
00542 _DBG(" Dint win for inport %d SWA winner was inport %d for oport %d "
00543 ,iport, vca_winner.port, oport);
00544 #endif
00545 swa.clear_requested(oport, iport);
00546 input_buffer_state[i].pipe_stage = FULL;
00547 input_buffer_state[i].flits_in_ib--;
00548
00549 }
00550 ticking = true;
00551 }
00552 else
00553 {
00554 cout << "ERROR SWA was requested but the switch allocator has no requests" << endl;
00555 }
00556 }
00557
00558 if(sa_active)
00559 istat->stat_router[node_ip]->sa_cycles++;
00560 }
00561
00562 void
00563 GenericRouterPhy::do_input_buffering()
00564 {
00565
00566
00567
00568
00569
00570 for( uint i=0; i<(ports*vcs); i++)
00571 if( input_buffer_state[i].pipe_stage == FULL )
00572 {
00573 #ifdef _DEBUG_ROUTER
00574 _DBG(" IB + RC inport:%d oport:%d length:%d arrival_time: %f", input_buffer_state[i].input_port,
00575 input_buffer_state[i].output_port, input_buffer_state[i].length, Simulator::Now());
00576 #endif
00577 input_buffer_state[i].pipe_stage = IB;
00578 input_buffer_state[i].flits_in_ib++;
00579 ticking = true;
00580 istat->stat_router[node_ip]->ib_cycles++;
00581 }
00582
00587 for( uint i=0; i<(ports*vcs); i++)
00588 {
00589 uint iport = input_buffer_state[i].input_port;
00590 uint oport = input_buffer_state[i].output_port ;
00591
00592
00593
00594
00595
00596
00597 if ((input_buffer_state[i].pipe_stage == SW_TRAVERSAL || input_buffer_state[i].pipe_stage == IB )
00598 || input_buffer_state[i].pipe_stage == SWA_REQUESTED
00599 && (input_buffer_state[i].flits_in_ib < in_buffers[iport].get_occupancy(0)))
00600 {
00601 input_buffer_state[i].flits_in_ib++;
00602 ticking = true;
00603 #ifdef _DEBUG_ROUTER
00604 _DBG(" IB for BODY/TAIL for inport %d oport %d ", iport, oport);
00605 #endif
00606 }
00607 }
00608
00609 return;
00610 }
00611
00618 void
00619 GenericRouterPhy::handle_tick_event ( IrisEvent* e )
00620 {
00621
00622 #ifdef _DEEP_DEBUG
00623 _DBG_NOARG("input_buffer_state matrix\n");
00624 for( uint i=0; i<ports*vcs; i++)
00625 cout <<i<<" "<< input_buffer_state[i].toString()<< " buff_occ:" <<in_buffers[input_buffer_state[i].
00626 input_port].get_occupancy(input_buffer_state[i].input_channel) << endl;
00627 #endif
00628
00629 ticking = false;
00630
00631 do_switch_traversal();
00632 do_switch_allocation();
00633
00634
00635
00636
00637
00638
00639
00640
00641 do_input_buffering();
00642
00643
00644
00645
00646 for( uint i=0; i<(ports*vcs); i++)
00647 {
00648 if( input_buffer_state[i].pipe_stage == IB )
00649 {
00650 uint iport = input_buffer_state[i].input_port;
00651 uint oport = input_buffer_state[i].possible_oports[0];
00652
00653 if( !swa.is_requested(oport,iport)
00654 && downstream_credits[oport][0] == credits)
00655 {
00656 swa.request(oport, iport);
00657 input_buffer_state[i].pipe_stage = SWA_REQUESTED;
00658 ticking = true;
00659 }
00660 }
00661 }
00662
00663 if(ticking)
00664 {
00665 ticking = true;
00666 IrisEvent* event = new IrisEvent();
00667 event->type = TICK_EVENT;
00668 event->vc = e->vc;
00669 Simulator::Schedule(Simulator::Now()+1, &NetworkComponent::process_event, this, event);
00670 }
00671
00672 delete e;
00673 return;
00674
00675 }
00676
00677 string
00678 GenericRouterPhy::toString() const
00679 {
00680 stringstream str;
00681 str << "GenericRouterPhy"
00682 << "\t addr: " << address
00683 << " node_ip: " << node_ip
00684 << "\n Input buffers: " << in_buffers.size() << " ";
00685 if( in_buffers.size() > 0)
00686 str << in_buffers[0].toString();
00687
00688 str << "\n SWA: " << swa.toString();
00689
00690 str << "\n decoders: " << decoders.size() << " ";
00691 if( decoders.size() > 0)
00692 str << decoders[0].toString();
00693
00694 str << "\n Xbar ";
00695 str << xbar.toString();
00696
00697 return str.str();
00698 }
00699
00700
00701
00702
00703 void
00704 GenericRouterPhy::send_credit_back(uint i)
00705 {
00706 input_buffer_state[i].credits_sent--;
00707 LinkArrivalData* data = new LinkArrivalData();
00708 uint port = input_buffer_state[i].input_port;
00709 data->type = CREDIT_ID;
00710 data->vc = input_buffer_state[i].input_channel;
00711 IrisEvent* event = new IrisEvent();
00712 event->type = LINK_ARRIVAL_EVENT;
00713 event->event_data.push_back(data);
00714 event->src_id = address;
00715 event->vc = data->vc;
00716 Simulator::Schedule(Simulator::Now()+0.75, &NetworkComponent::process_event,
00717 static_cast<GenericLink*>(input_connections[port])->input_connection, event);
00718
00719 #ifdef _DEBUG_ROUTER
00720 _DBG(" Credit back for inport %d inch %d ", port, data->vc);
00721 #endif
00722 }
00723
00724
00725 #endif
00726