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