00001
00022 #ifndef _routerReqReply_cc_INC
00023 #define _routerReqReply_cc_INC
00024
00025 #include "routerReqReply.h"
00026 using namespace std;
00027
00028 RouterReqReply::RouterReqReply ()
00029 {
00030 name = "RouterReqReply" ;
00031 ticking = false;
00032 }
00033
00034 RouterReqReply::~RouterReqReply()
00035 {
00036 }
00037
00038 void
00039 RouterReqReply::init (uint p, uint v, uint cr, uint bs)
00040 {
00041 ports =p;
00042 vcs =v;
00043 credits =cr;
00044 buffer_size = bs;
00045
00046 address = myId();
00047
00048
00049 in_buffers.resize(ports);
00050 decoders.resize(ports);
00051 input_buffer_state.resize(ports*vcs);
00052 sw_alloc.resize(ports);
00053 downstream_credits.resize(ports);
00054 cr_time.resize(ports);
00055 request_op.resize(ports);
00056 vca.set_no_msg_classes(no_msg_classes);
00057 vca.init(ports, vcs );
00058
00059
00060 stat_packet_out.resize(ports);
00061 stat_flit_out.resize(ports);
00062
00063
00064
00065 for(uint i=0; i<ports; i++)
00066 {
00067 decoders[i].node_ip = node_ip;
00068 decoders[i].address = address;
00069 stat_packet_out[i].resize(ports);
00070 stat_flit_out[i].resize(ports);
00071 }
00072
00073
00074 for(uint i=0; i<ports; i++)
00075 {
00076 downstream_credits[i].resize(vcs);
00077 cr_time[i].resize(vcs);
00078 in_buffers[i].resize( vcs, buffer_size );
00079 decoders[i].resize( vcs );
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 cr_time[i][j] = -1;
00087 input_buffer_state[i*vcs+j].pipe_stage = EMPTY;
00088 }
00089
00090
00091 stat_packets = 0;
00092 stat_flits = 0;
00093 stat_total_packet_latency = 0;
00094 stat_buffer_occupancy = 0;
00095 stat_swa_fail_msg_ratio = 0;
00096 stat_swa_load = 0;
00097 stat_vca_fail_msg_ratio = 0;
00098 stat_vca_load = 0;
00099 stat_ib_cycles = 0;
00100 stat_rc_cycles = 0;
00101 stat_vca_cycles = 0;
00102 stat_swa_cycles = 0;
00103 stat_st_cycles = 0;
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 IrisEvent* event = new IrisEvent();
00114 event->type = DETECT_DEADLOCK_EVENT;
00115 Simulator::Schedule( floor(Simulator::Now())+1, &NetworkComponent::process_event, this, event);
00116
00117 return ;
00118 }
00119
00122 void
00123 RouterReqReply::set_no_nodes( uint nodes )
00124 {
00125 for ( uint i=0; i<decoders.size(); i++)
00126 {
00127 decoders[i].grid_xloc.resize(nodes);
00128 decoders[i].grid_yloc.resize(nodes);
00129 }
00130 }
00131
00132 void
00133 RouterReqReply::set_grid_x_location( uint port, uint x_node, uint value)
00134 {
00135 decoders[port].grid_xloc[x_node]= value;
00136 }
00137
00138 void
00139 RouterReqReply::set_grid_y_location( uint port, uint y_node, uint value)
00140 {
00141 decoders[port].grid_yloc[y_node]= value;
00142 }
00143
00144
00145
00146 void
00147 RouterReqReply::process_event ( IrisEvent* e )
00148 {
00149 switch(e->type)
00150 {
00151 case LINK_ARRIVAL_EVENT:
00152 handle_link_arrival_event(e);
00153 break;
00154 case TICK_EVENT:
00155 handle_tick_event(e);
00156 break;
00157 case DETECT_DEADLOCK_EVENT:
00158 handle_detect_deadlock_event(e);
00159 break;
00160 default:
00161 _DBG("RouterReqReply:: Unk event exception %d", e->type);
00162 break;
00163 }
00164 return ;
00165 }
00166
00167 void
00168 RouterReqReply::handle_detect_deadlock_event(IrisEvent* e )
00169 {
00170 for ( uint i=0; i<ports; i++)
00171 for ( uint j=0; j<vcs; j++)
00172 {
00173 if( cr_time[i][j] != -1)
00174 {
00175 cr_time[i][j]++;
00176 if( cr_time[i][j] > 10000 )
00177 {
00178 _DBG_NOARG("************ KILLING SIMULATION *************");
00179 cout << "\ndeadlock detected op:"<< i << " ovc: " << j << endl;
00180 cout << "\ndeadlock mssg:"<< endl;
00181 cout << "ip\tic\top\toc\taddr:"<< endl;
00182 for ( uint ii=0; ii<ports*vcs; ii++)
00183 if(input_buffer_state[ii].output_port == i && input_buffer_state[ii].output_channel == j)
00184 {
00185 cout << dec << input_buffer_state[ii].input_port;
00186 cout << dec << "\t" << input_buffer_state[ii].input_channel;
00187 cout << dec << "\t" << input_buffer_state[ii].output_port;
00188 cout << dec << "\t" << input_buffer_state[ii].output_channel;
00189 cout << hex << "\t" << input_buffer_state[ii].address << endl;
00190 }
00191 cout << "*************************" << endl;
00192
00193
00194 exit(1);
00195 }
00196 }
00197 }
00198
00199 e->type = DETECT_DEADLOCK_EVENT;
00200 Simulator::Schedule( floor(Simulator::Now())+50, &NetworkComponent::process_event, this, e);
00201 }
00202
00203 void
00204 RouterReqReply::dump_buffer_state()
00205 {
00206 for ( uint i=0; i<ports*vcs; i++)
00207 if(input_buffer_state[i].pipe_stage != EMPTY && input_buffer_state[i].pipe_stage != INVALID)
00208 {
00209 cout << " Router[" << node_ip << "]->buff["<<i<<"] " << input_buffer_state[i].toString() << endl;
00210 }
00211 cout << endl;
00212
00213 return;
00214 }
00215
00216 string
00217 RouterReqReply::print_stats()
00218 {
00219 stringstream str;
00220 str << name ;
00221 str << "\n router[" << node_ip << "] packet latency: " << stat_total_packet_latency
00222 << "\n router[" << node_ip << "] flits/packet: " << (stat_flits+0.0)/(stat_packets)
00223 << "\n router[" << node_ip << "] average packet latency: " << (stat_total_packet_latency+0.0)/stat_packets
00224 << "\n router[" << node_ip << "] last_flit_out_cycle: " << last_flit_out_cycle
00225 << "\n router[" << node_ip << "] stat_buffer_occupancy: " << stat_buffer_occupancy
00226 << "\n router[" << node_ip << "] stat_swa_fail_msg_ratio: " << stat_swa_fail_msg_ratio
00227 << "\n router[" << node_ip << "] stat_swa_load: " << stat_swa_load
00228 << "\n router[" << node_ip << "] stat_vca_fail_msg_ratio: " << stat_vca_fail_msg_ratio
00229 << "\n router[" << node_ip << "] stat_vca_load: " << stat_vca_load
00230 << "\n router[" << node_ip << "] packets: " << stat_packets
00231 << "\n router[" << node_ip << "] flits: " << stat_flits
00232 << "\n router[" << node_ip << "] stat_ib_cycles: " << stat_ib_cycles
00233 << "\n router[" << node_ip << "] stat_rc_cycles: " << stat_rc_cycles
00234 << "\n router[" << node_ip << "] stat_vca_cycles: " << stat_vca_cycles
00235 << "\n router[" << node_ip << "] stat_swa_cycles: " << stat_swa_cycles
00236 << "\n router[" << node_ip << "] stat_st_cycles: " << stat_st_cycles
00237 << " ";
00238
00239 str << "\n router[" << node_ip << "] out_port_links_utilization: ";
00240 for( uint i=0; i<ports; i++)
00241 str << static_cast<GenericLink*>(output_connections[i])->flits_passed*1.0/max_sim_time << " ";
00242 str << endl;
00243
00244 if( stat_print_level > 2 )
00245 {
00246 for( uint i=0; i<ports; i++)
00247 for ( uint j=0; j<ports; j++)
00248 {
00249 string in_port = "Inv";
00250 switch( i )
00251 {
00252 case 0 :
00253 in_port = "Inj";
00254 break;
00255 case 1:
00256 in_port = 'E';
00257 break;
00258 case 2:
00259 in_port = 'W';
00260 break;
00261 case 3:
00262 in_port = 'S';
00263 break;
00264 case 4:
00265 in_port = 'N';
00266 break;
00267 default:
00268 in_port = "Invalid";
00269 break;
00270 }
00271
00272 string out_port = "Inv";
00273 switch( j )
00274 {
00275 case 0 :
00276 out_port = "Ejection";
00277 break;
00278 case 1:
00279 out_port = 'W';
00280 break;
00281 case 2:
00282 out_port = 'E';
00283 break;
00284 case 3:
00285 out_port = 'N';
00286 break;
00287 case 4:
00288 out_port = 'S';
00289 break;
00290 default:
00291 out_port = "Invalid";
00292 break;
00293 }
00294 if ( i != j)
00295 {
00296 str << "\n router[" << node_ip << "] Packets out " << in_port
00297 << " going " << out_port << " : " << stat_packet_out[i][j];
00298 str << "\n router[" << node_ip << "] Flits out " << in_port
00299 << " going " << out_port << " : " << stat_flit_out[i][j];
00300 }
00301
00302 }
00303 }
00304
00305
00306 return str.str();
00307 }
00308
00310 void
00311 RouterReqReply::handle_link_arrival_event ( IrisEvent* e )
00312 {
00313 LinkArrivalData* data = static_cast<LinkArrivalData*>(e->event_data.at(0));
00314 if(data->type == FLIT_ID)
00315 {
00316
00317
00318 bool found = false;
00319 uint port = -1;
00320
00321 for ( uint i=0 ; i< ports ; i++ )
00322 if(static_cast<GenericLink*>(input_connections[i])->input_connection)
00323 if( e->src_id == static_cast<GenericLink*>(input_connections[i])->input_connection->address)
00324 {
00325 found = true;
00326 port = i;
00327 break;
00328 }
00329
00330
00331 if( !found )
00332 {
00333 _DBG(" Input port not found src_addr: %d", e->src_id);
00334 }
00335
00336
00337 in_buffers[port].change_push_channel(data->vc);
00338 in_buffers[port].push(data->ptr);
00339
00340
00341
00342
00343 if(data->ptr->type !=HEAD)
00344 {
00345 istat->stat_router[node_ip]->ib_cycles++;
00346 stat_ib_cycles++;
00347 }
00348
00349 _DBG(" handle_link_arrival_event: port %d vc %d ft %d ps:%d ", port, data->vc, data->ptr->type, input_buffer_state[port].pipe_stage);
00350 if(data->ptr->type == HEAD)
00351 {
00352 cout << static_cast<HeadFlit*>(data->ptr)->addr<< endl;
00353 }
00354 }
00355 else if ( data->type == CREDIT_ID)
00356 {
00357
00358 bool found = false;
00359 uint port = -1;
00360 for ( uint i=0 ; ports ; i++ )
00361 if(static_cast<GenericLink*>(output_connections[i])->output_connection)
00362 if( static_cast<GenericLink*>(output_connections[i])->output_connection->address == e->src_id)
00363 {
00364 port = i;
00365 found = true;
00366 break;
00367 }
00368 if(!found)
00369 {
00370 _DBG(" Output port not found src_addr: %d", e->src_id);
00371 }
00372
00373 downstream_credits[port][data->vc]++;
00374 cr_time[port][data->vc] = -1;
00375
00376 #ifdef _DEBUG_ROUTER
00377 _DBG(" Got a credit port:%d vc:%d ", port, data->vc, downstream_credits[port][data->vc]);
00378 vector < uint > pending_ops ;
00379 vector < uint > pending_ips ;
00380 for( uint i=0; i<ports*vcs; i++)
00381 if(input_buffer_state[i].output_port == port && input_buffer_state[i].output_channel == data->vc)
00382 {
00383 pending_ops.push_back(port*vcs+data->vc);
00384 pending_ips.push_back(i);
00385 }
00386
00387 cout << " Can send msgs (i-o): " ;
00388 for( uint i=0; i<pending_ops.size(); i++)
00389 cout << pending_ips[i] <<"-" << pending_ops[i] << " occ/" << in_buffers[(int)(pending_ops[i]/vcs)].get_occupancy(pending_ops[i]%vcs)
00390 <<" bst:"<<input_buffer_state[i].pipe_stage << " ";
00391 pending_ops.clear();
00392 pending_ips.clear();
00393 #endif
00394
00395 }
00396 else
00397 {
00398 _DBG( "handle_link_arrival_event Unk data type %d ", data->type);
00399 }
00400
00401
00402 if(!ticking)
00403 {
00404 ticking = true;
00405 IrisEvent* event = new IrisEvent();
00406 event->type = TICK_EVENT;
00407 event->vc = e->vc;
00408 Simulator::Schedule( floor(Simulator::Now())+1, &NetworkComponent::process_event, this, event);
00409 }
00410
00411 delete data;
00412 delete e;
00413 return ;
00414 }
00415
00416 void
00417 RouterReqReply::do_input_buffering()
00418 {
00419 for( uint i=0; i<ports*vcs; i++)
00420 {
00421 uint inport = (uint)(i/vcs);
00422 uint invc = (uint)(i%vcs);
00423 if( input_buffer_state[i].pipe_stage == FULL || input_buffer_state[i].pipe_stage == EMPTY )
00424 {
00425 if( in_buffers[inport].get_occupancy(invc) > 0)
00426 {
00427
00428 in_buffers[inport].change_pull_channel(invc);
00429 Flit* f = in_buffers[inport].peek();
00430
00431
00432 if( f->type == HEAD )
00433 {
00434 HeadFlit* hf = static_cast<HeadFlit*>(f);
00435
00436 istat->stat_router[node_ip]->ib_cycles++;
00437 stat_ib_cycles++;
00438
00439
00440 input_buffer_state[inport*vcs+f->vc].input_port = inport;
00441 hf->inport = inport;
00442 decoders[inport].push(f,f->vc);
00443 input_buffer_state[inport*vcs+f->vc].input_channel = f->vc;
00444 input_buffer_state[inport*vcs+f->vc].address= hf->addr;
00445 input_buffer_state[inport*vcs+f->vc].destination= hf->dst_address;
00446 input_buffer_state[inport*vcs+f->vc].pipe_stage = IB;
00447 input_buffer_state[inport*vcs+f->vc].msg_class = hf->msg_class;
00448 input_buffer_state[inport*vcs+f->vc].possible_oports.clear();
00449 input_buffer_state[inport*vcs+f->vc].possible_ovcs.clear();
00450 uint no_adaptive_ports = decoders[inport].no_adaptive_ports(f->vc);
00451 uint no_adaptive_vcs = decoders[inport].no_adaptive_vcs(f->vc);
00452 istat->stat_router[node_ip]->rc_cycles++;
00453 stat_rc_cycles++;
00454
00455 for ( uint i=0; i<no_adaptive_ports; i++ )
00456 {
00457 uint rc_port = decoders[inport].get_output_port(f->vc);
00458 if( static_cast<GenericLink*>(output_connections[rc_port])->output_connection != NULL )
00459 input_buffer_state[inport*vcs+f->vc].possible_oports.push_back(rc_port);
00460 }
00461
00462 for ( uint i=0; i<no_adaptive_vcs; i++ )
00463 {
00464 uint rc_vc = decoders[inport].get_virtual_channel(f->vc);
00465 input_buffer_state[inport*vcs+f->vc].possible_ovcs.push_back(rc_vc);
00466 }
00467
00468 assert ( input_buffer_state[inport*vcs+f->vc].possible_oports.size() > 0);
00469 assert ( input_buffer_state[inport*vcs+f->vc].possible_ovcs.size() > 0);
00470
00471 input_buffer_state[inport*vcs+f->vc].length= hf->length;
00472 input_buffer_state[inport*vcs+f->vc].credits_sent= hf->length;
00473 input_buffer_state[inport*vcs+f->vc].arrival_time= Simulator::Now();
00474 input_buffer_state[inport*vcs+f->vc].clear_message= false;
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 ticking =true;
00488 }
00489 }
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 }
00516
00517 void
00518 RouterReqReply::do_switch_traversal()
00519 {
00520 for( uint i=0; i<(ports*vcs); i++)
00521 if( input_buffer_state[i].pipe_stage == SW_TRAVERSAL)
00522 {
00523 uint op = input_buffer_state[i].output_port;
00524 uint oc = input_buffer_state[i].output_channel;
00525 uint ip = input_buffer_state[i].input_port;
00526 uint ic= input_buffer_state[i].input_channel;
00527 if( in_buffers[ip].get_occupancy(ic)> 0
00528 && downstream_credits[op][oc]>0 )
00529 {
00530 in_buffers[ip].change_pull_channel(ic);
00531 Flit* f = in_buffers[ip].pull();
00532 f->vc = oc;
00533
00534 if(f->type != TAIL && !f->is_single_flit_pkt)
00535 {
00536 cout << " resetting ";
00537 input_buffer_state[i].pipe_stage = VCA_COMPLETE;
00538 request_switch_allocation();
00539 ticking = true;
00540 }
00541
00542
00543 last_flit_out_cycle = Simulator::Now();
00544 stat_flit_out[ip][op]++;
00545 stat_flits++;
00546 static_cast<GenericLink*>(output_connections[op])->flits_passed++;
00547 istat->stat_link[static_cast<GenericLink*>(output_connections[op])->link_id]->flits_transferred++;
00548
00549
00550
00551
00552
00553
00554
00555 istat->stat_router[node_ip]->st_cycles++;
00556 stat_st_cycles++;
00557
00558
00559 LinkArrivalData* data = new LinkArrivalData();
00560 data->type = FLIT_ID;
00561 data->vc = oc;
00562 data->ptr = f;
00563
00564 _DBG(" Fout %d=%d %d",ip*vcs+ic,op*vcs+oc, f->type);
00565
00566
00567
00568
00569
00570
00571 if( f->type == HEAD)
00572 {
00573 HeadFlit* hf = static_cast<HeadFlit*>(f);
00574 hf->hop_count++;
00575 _DBG(" Fout %d %d %d %d %d %d addr:%lld ",ip,ic,op,oc,hf->src_address, hf->dst_address, hf->addr);
00576 cout << f->is_single_flit_pkt;
00577
00578 }
00579 if( f->type == TAIL || f->is_single_flit_pkt )
00580 {
00581
00582 uint lat = Simulator::Now() - input_buffer_state[i].arrival_time + 1;
00583 stat_total_packet_latency += lat;
00584 stat_packets++;
00585
00586 if( f->type == HEAD)
00587 {
00588 HeadFlit* hf = static_cast<HeadFlit*>(f);
00589 hf->avg_network_latency += lat;
00590 }
00591 else
00592 {
00593 TailFlit* tf = static_cast<TailFlit*>(f);
00594 tf->avg_network_latency += lat;
00595 }
00596
00597 stat_packet_out[ip][op]++;
00598
00599 input_buffer_state[i].clear_message = true;
00600 if(in_buffers[ip].get_occupancy(ic) > 0)
00601 input_buffer_state[i].pipe_stage = FULL;
00602 else
00603 input_buffer_state[i].pipe_stage = EMPTY;
00604
00605 vca.clear_winner(ip*vcs+ic, oc );
00606 input_buffer_state[i].possible_oports.clear();
00607 input_buffer_state[i].possible_ovcs.clear();
00608 input_buffer_state[i].output_port = -1;
00609 input_buffer_state[i].output_channel = -1;
00610 }
00611
00612 cr_time[op][oc] = 0;
00613 IrisEvent* event = new IrisEvent();
00614 event->type = LINK_ARRIVAL_EVENT;
00615 event->event_data.push_back(data);
00616 event->src_id = address;
00617 event->dst_id = output_connections[op]->address;
00618 event->vc = data->vc;
00619
00620 Simulator::Schedule( Simulator::Now()+0.75,
00621 &NetworkComponent::process_event,
00622 static_cast<GenericLink*>(output_connections[op])->output_connection,event);
00623
00626 send_credit_back(i);
00627 downstream_credits[op][oc]--;
00628
00629 }
00630 }
00631 return;
00632 }
00633
00634 void
00635 RouterReqReply::do_switch_allocation()
00636 {
00637 bool was_swa_active = false;
00638 uint tot_swa_req = 0;
00639 uint swa_won=0;
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 for( uint i=0; i<ports; i++)
00653 {
00654 if( sw_alloc[i].size() )
00655 {
00656 uint winner_op = 0;
00657
00658
00659
00660 swa_won++;
00661 tot_swa_req += sw_alloc[i].size();
00662
00663 uint msg_id = sw_alloc[i][winner_op];
00664 uint ip = input_buffer_state[msg_id].input_port;
00665 uint ic = input_buffer_state[msg_id].input_channel;
00666 uint op = input_buffer_state[msg_id].output_port;
00667 uint oc = input_buffer_state[msg_id].output_channel;
00668 assert(op == i);
00669 vector<uint>::iterator it = find (sw_alloc[i].begin(), sw_alloc[i].end(), msg_id);;
00670 if( input_buffer_state[msg_id].pipe_stage == SWA_REQUESTED )
00671 {
00672 sw_alloc[i].erase(it);
00673 input_buffer_state[msg_id].pipe_stage = SW_TRAVERSAL;
00674 _DBG(" SW_TRAV %d=%d cr:%d occ:%d",ip*vcs+ic,op*vcs+oc,downstream_credits[op][oc], in_buffers[ip].get_occupancy(ic));
00675 ticking = true;
00676 was_swa_active = true;
00677 }
00678 }
00679 }
00680 if( tot_swa_req )
00681 {
00682 stat_swa_fail_msg_ratio += ((tot_swa_req - swa_won+0.0)/tot_swa_req);
00683 stat_swa_fail_msg_ratio = stat_swa_fail_msg_ratio/2;
00684 stat_swa_load += ((tot_swa_req+0.0)/(ports*vcs));
00685 stat_swa_load = stat_swa_load/2;
00686 }
00687
00688 if( was_swa_active )
00689 {
00690 istat->stat_router[node_ip]->sa_cycles++;
00691 stat_swa_cycles++;
00692 }
00693
00694 return;
00695 }
00696
00697 void
00698 RouterReqReply::do_virtual_channel_allocation()
00699 {
00700
00701
00702 bool was_vca_active = false;
00703 uint tot_vca_req = vca.get_no_requestors();
00704
00705 for( uint i=0; i<(ports*vcs); i++)
00706 if( input_buffer_state[i].pipe_stage == VCA_REQUESTED)
00707 {
00708 uint op=input_buffer_state[i].output_port;
00709 uint ip=input_buffer_state[i].input_port;
00710 uint ic=input_buffer_state[i].input_channel;
00711 uint mc=input_buffer_state[i].msg_class;
00712 uint at=input_buffer_state[i].arrival_time;
00713 uint mid=0;
00714
00715 if( do_request_reply_network)
00716 if( mc == ONE_FLIT_REQ || mc == REQUEST_PKT )
00717 mid = 1;
00718
00719 vca.request(op, mid, ip*vcs+ic, at);
00720
00721 }
00722 uint vca_won = 0;
00723 vca_won = vca.pick_winners();
00724
00725 for( uint i=0; i<no_msg_classes; i++)
00726 for( uint j=0; j<ports; j++)
00727 {
00728 map<uint ,uint>::iterator iter;
00729 for( iter = vca.winners[i][j].begin(); iter != vca.winners[i][j].end(); ++iter )
00730 {
00731 uint msg_index = iter->first;
00732 uint msg_oc = iter->second;
00733 if( input_buffer_state[msg_index].pipe_stage == VCA_REQUESTED )
00734 {
00735 uint op = input_buffer_state[msg_index].output_port;
00736 uint ip = input_buffer_state[msg_index].input_port;
00737 uint ic = input_buffer_state[msg_index].input_channel;
00738 assert( op == j);
00739
00740
00741
00742
00743 _DBG(" VCA COMP %d %d %lld",op,msg_oc, input_buffer_state[msg_index].address);
00744 input_buffer_state[msg_index].output_channel = msg_oc;
00745 input_buffer_state[msg_index].pipe_stage = VCA_COMPLETE;
00746 ticking = true;
00747 }
00748 }
00749 }
00750
00751 if( vca_won && tot_vca_req )
00752 {
00753 istat->stat_router[node_ip]->vca_cycles++;
00754 stat_vca_cycles++;
00755 stat_vca_fail_msg_ratio += ((tot_vca_req - vca_won+0.0)/tot_vca_req);
00756 stat_vca_fail_msg_ratio = stat_vca_fail_msg_ratio/2;
00757 stat_vca_load += ((tot_vca_req+0.0)/(ports*vcs));
00758 stat_vca_load = stat_vca_load/2;
00759 }
00760
00761 request_switch_allocation();
00762 }
00763
00764
00765
00766
00767 void
00768 RouterReqReply::request_switch_allocation()
00769 {
00770 for( uint i=0; i<(ports*vcs); i++)
00771 if( input_buffer_state[i].pipe_stage == VCA_COMPLETE)
00772 {
00773 uint ip = input_buffer_state[i].input_port;
00774 uint ic = input_buffer_state[i].input_channel;
00775 uint op = input_buffer_state[i].output_port;
00776 uint oc = input_buffer_state[i].output_channel;
00777
00778
00779
00780 if(in_buffers[ip].get_occupancy(ic) )
00781 {
00782
00783 sw_alloc[op].push_back(i);
00784 input_buffer_state[i].pipe_stage = SWA_REQUESTED;
00785 ticking = true;
00786 }
00787 }
00788 return;
00789 }
00790
00792 void
00793 RouterReqReply::handle_tick_event ( IrisEvent* e )
00794 {
00795 ticking = false;
00796 do_switch_traversal();
00797 do_switch_allocation();
00798 do_virtual_channel_allocation();
00799
00805 do_input_buffering();
00806
00807
00808
00809
00810
00812 for( uint i=0; i<(ports*vcs); i++)
00813 if( input_buffer_state[i].pipe_stage == IB )
00814 {
00815 uint ip = input_buffer_state[i].input_port;
00816 uint ic = input_buffer_state[i].input_channel;
00817 uint op = input_buffer_state[i].possible_oports[0];
00818
00819 {
00820 input_buffer_state[i].pipe_stage = VCA_REQUESTED;
00821 input_buffer_state[i].output_port = op;
00822
00823 ticking = true;
00824 }
00825 }
00826
00827
00828 for( uint i=0; i<ports; i++)
00829 for( uint j=0; j<vcs; j++)
00830 if(in_buffers[i].get_occupancy(j) )
00831 {
00832 double buff_occ =(in_buffers[i].get_occupancy(j)+0.0)/credits;
00833 stat_buffer_occupancy += buff_occ;
00834 stat_buffer_occupancy = stat_buffer_occupancy/2;
00835 }
00836
00837
00844 if(ticking)
00845 {
00846 ticking = true;
00847 IrisEvent* event = new IrisEvent();
00848 event->type = TICK_EVENT;
00849 event->vc = e->vc;
00850 Simulator::Schedule(Simulator::Now()+1, &NetworkComponent::process_event, this, event);
00851 }
00852
00853 delete e;
00854 return;
00855
00856 }
00857
00858 string
00859 RouterReqReply::toString() const
00860 {
00861 stringstream str;
00862 str << "RouterReqReply"
00863 << "\t addr: " << address
00864 << " node_ip: " << node_ip
00865 << "\n Input buffers: " << in_buffers.size() << " ";
00866 if( in_buffers.size() > 0)
00867 str << in_buffers[0].toString();
00868
00869 str << "\n decoders: " << decoders.size() << " ";
00870 if( decoders.size() > 0)
00871 str << decoders[0].toString();
00872
00873 return str.str();
00874 }
00875
00876 void
00877 RouterReqReply::send_credit_back(uint i)
00878 {
00879 input_buffer_state[i].credits_sent--;
00880 LinkArrivalData* data = new LinkArrivalData();
00881 uint port = input_buffer_state[i].input_port;
00882 data->type = CREDIT_ID;
00883 data->vc = input_buffer_state[i].input_channel;
00884 IrisEvent* event = new IrisEvent();
00885 event->type = LINK_ARRIVAL_EVENT;
00886 event->event_data.push_back(data);
00887 event->src_id = address;
00888 event->vc = data->vc;
00889 Simulator::Schedule(Simulator::Now()+0.75, &NetworkComponent::process_event,
00890 static_cast<GenericLink*>(input_connections[port])->input_connection, event);
00891
00892 static_cast<GenericLink*>(input_connections[port])->credits_passed++;
00893 istat->stat_link[static_cast<GenericLink*>(input_connections[port])->link_id]->credits_transferred++;
00894 }
00895
00896 #endif
00897