00001
00019 #ifndef _genericInterfaceNB_cc_INC
00020 #define _genericInterfaceNB_cc_INC
00021
00022 #include "genericInterfaceNB.h"
00023
00024 GenericInterfaceNB::GenericInterfaceNB()
00025 {
00026 name = "GenericInterfaceNB";
00027 ticking =false;
00028 }
00029
00030 GenericInterfaceNB::~GenericInterfaceNB()
00031 {
00032 in_packets.clear();
00033 out_packets.clear();
00034 }
00035
00036 void
00037 GenericInterfaceNB::setup (uint v, uint cr, uint bs)
00038 {
00039 vcs =v;
00040 credits = cr;
00041 buffer_size = bs;
00042
00043 address = myId();
00044 flast_vc = 0;
00045
00046
00047 in_buffer.resize(vcs, buffer_size);
00048 out_buffer.resize(vcs, buffer_size);
00049 downstream_credits.resize(vcs);
00050
00051 out_packet_flit_index.resize(vcs);
00052 in_ready.resize(vcs);
00053 in_packets_flit_index.resize(vcs);
00054 in_packet_complete.resize(vcs);
00055
00056 in_packets.resize(vcs);
00057 in_packets_valid.resize(vcs);
00058 out_packets.resize(vcs);
00059 out_arbiter.set_no_requestors(vcs);
00060
00061
00062 for ( uint i=0; i<vcs ; i++ )
00063 {
00064 out_packet_flit_index[i] = 0;
00065 in_ready[i] = true;
00066 in_packet_complete[i] = false;
00067 in_packets[i].destination = address;
00068 in_packets[i].virtual_channel = i;
00069 in_packets[i].length= 10;
00070 downstream_credits[i] = credits;
00071 }
00072
00073
00074 packets_out = 0;
00075 flits_out = 0;
00076 packets_in = 0;
00077 flits_in = 0;
00078 total_packets_in_time = 0;
00079
00080 ticking = false;
00081
00082
00083
00084 return;
00085 }
00086
00087 string
00088 GenericInterfaceNB::toString () const
00089 {
00090 stringstream str;
00091 str << "GenericInterfaceNB: "
00092 << "\t VC: " << out_packets.size()
00093 << "\t address: " << address << " node_ip: " << node_ip
00094 << "\t OutputBuffers: " << out_buffer.toString()
00095 << "\t InputBuffer: " << in_buffer.toString()
00096 ;
00097 return str.str();
00098 }
00099
00100 void
00101 GenericInterfaceNB::set_no_credits( int cr )
00102 {
00103 }
00104
00105 uint
00106 GenericInterfaceNB::get_no_credits() const
00107 {
00108 return credits;
00109 }
00110
00111 void
00112 GenericInterfaceNB::set_no_vcs( uint cr )
00113 {
00114 }
00115
00116 void
00117 GenericInterfaceNB::set_buffer_size( uint cr )
00118 {
00119 }
00120
00121 void
00122 GenericInterfaceNB::process_event(IrisEvent* e)
00123 {
00124 switch(e->type)
00125 {
00128 case READY_EVENT:
00129 handle_ready_event(e);
00130 break;
00131
00134 case LINK_ARRIVAL_EVENT:
00135 handle_link_arrival(e);
00136 break;
00137
00140 case NEW_PACKET_EVENT:
00141 handle_new_packet_event(e);
00142 break;
00143
00151 case TICK_EVENT:
00152 handle_tick_event(e);
00153 break;
00154
00155 default:
00156 cout << "**Unkown event exception! " << e->type << endl;
00157 break;
00158 }
00159 }
00160
00161 void
00162 GenericInterfaceNB::handle_ready_event( IrisEvent* e)
00163 {
00167 #ifdef _DEBUG_INTERFACE
00168 if(is_mc_interface)
00169 {
00170 _DBG(" IntM got ready from NI %d ", e->vc);
00171 }
00172 else
00173 {
00174 _DBG(" Int got ready %d ", e->vc);
00175 }
00176 #endif
00177
00178 if( in_ready[e->vc] )
00179 {
00180 cout << " Error Recv incorrect READY !" << endl;
00181 exit(1);
00182 }
00183 in_ready[e->vc] = true;
00184 if(!ticking)
00185 {
00186 ticking = true;
00187 IrisEvent* event = new IrisEvent();
00188 event->type = TICK_EVENT;
00189 event->vc = e->vc;
00190 Simulator::Schedule( floor(Simulator::Now())+1, &NetworkComponent::process_event, this, event);
00191 }
00192
00193 delete e;
00194 return;
00195 }
00196
00197 void
00198 GenericInterfaceNB::handle_link_arrival ( IrisEvent* e)
00199 {
00209 LinkArrivalData* uptr = static_cast<LinkArrivalData* >(e->event_data.at(0));
00210
00211 if(uptr->type == FLIT_ID)
00212 {
00213 flits_in++;
00214 in_buffer.change_push_channel(uptr->vc);
00215 in_buffer.push(uptr->ptr);
00216 if( uptr->ptr->type == TAIL )
00217 {
00218 packets_in++;
00219 total_packets_in_time += (Simulator::Now() - static_cast<TailFlit*>(uptr->ptr)->packet_originated_time);
00220 static_cast<TailFlit*>(uptr->ptr)->avg_network_latency = ceil(Simulator::Now());
00221 }
00222
00223 #ifdef _DEBUG
00224 if( uptr->ptr->type == HEAD)
00225 {
00226 HeadFlit* hf = static_cast<HeadFlit*>(uptr->ptr);
00227 if( is_mc_interface)
00228 {
00229 _DBG(" ROUTER->MINT vc%d %llx",uptr->vc,hf->addr);
00230 }
00231 else
00232 {
00233 _DBG(" ROUTER->INT vc%d %llx",uptr->vc,hf->addr);
00234 }
00235 }
00236 #endif
00237
00238 if( uptr->ptr->type == HEAD && static_cast<HeadFlit*>(uptr->ptr)->msg_class == ONE_FLIT_REQ )
00239 {
00240 packets_in++;
00241 total_packets_in_time += (Simulator::Now() - static_cast<HeadFlit*>(uptr->ptr)->packet_originated_time);
00242 static_cast<HeadFlit*>(uptr->ptr)->avg_network_latency = ceil(Simulator::Now())
00243 -static_cast<HeadFlit*>(uptr->ptr)->avg_network_latency;
00244 }
00245 uptr->valid = false;
00246
00247 if( !(uptr->ptr->type == TAIL ||
00248 ( uptr->ptr->type == HEAD && static_cast<HeadFlit*>(uptr->ptr)->msg_class == ONE_FLIT_REQ )))
00249 {
00250 LinkArrivalData* arrival = new LinkArrivalData();
00251 arrival->vc = uptr->ptr->vc;
00252 arrival->type = CREDIT_ID;
00253 IrisEvent* event = new IrisEvent();
00254 event->type = LINK_ARRIVAL_EVENT;
00255 event->vc = uptr->ptr->vc;
00256 event->event_data.push_back(arrival);
00257 event->src_id = address;
00258 Simulator::Schedule( floor(Simulator::Now())+0.75,
00259 &NetworkComponent::process_event,
00260 static_cast<GenericLink*>(input_connection)->input_connection, event);
00261 static_cast<GenericLink*>(input_connection)->credits_passed++;
00262 istat->stat_link[static_cast<GenericLink*>(input_connection)->link_id]->credits_transferred++;
00263
00264 }
00265 }
00266 else if ( uptr->type == CREDIT_ID)
00267 {
00268 downstream_credits[uptr->vc]++;
00269 }
00270 else
00271 {
00272 cout << "Exception: Unk link arrival data type! " << endl;
00273 }
00274
00275 if(!ticking)
00276 {
00277 ticking = true;
00278 IrisEvent* new_event = new IrisEvent();
00279 new_event->type = TICK_EVENT;
00280 new_event->vc = e->vc;
00281 Simulator::Schedule( floor(Simulator::Now())+1, &GenericInterfaceNB::process_event, this, new_event);
00282 }
00283 delete uptr;
00284 delete e;
00285 return;
00286 }
00287
00288 void
00289 GenericInterfaceNB::handle_new_packet_event(IrisEvent* e)
00290 {
00291 HighLevelPacket* pkt = static_cast<HighLevelPacket*>(e->event_data.at(0));
00292
00293
00294
00295
00296
00297
00298
00299 pkt->to_low_level_packet(&out_packets[pkt->virtual_channel]);
00300
00301 #ifdef _DEBUG_INTERFACE
00302 _DBG(" IntM NI->MInt ch%d %llx", pkt->virtual_channel,pkt->addr);
00303 cout << out_packets[pkt->virtual_channel].toString() ;
00304 cout << "HLP: " << pkt->toString() ;
00305 if(is_mc_interface)
00306 {
00307 _DBG(" IntM NI->MInt ch%d %llx", pkt->virtual_channel,pkt->addr);
00308 }
00309 else
00310 {
00311 _DBG(" Int Proc->Int ch%d %llx", pkt->virtual_channel,pkt->addr);
00312 }
00313 #endif
00314
00315 out_packet_flit_index[ pkt->virtual_channel ] = 0;
00316 delete pkt;
00317
00318 if( !ticking)
00319 {
00320 ticking = true;
00321 IrisEvent* event = new IrisEvent();
00322 event->type = TICK_EVENT;
00323 event->vc = e->vc;
00324 Simulator::Schedule(Simulator::Now()+1, &NetworkComponent::process_event, this, event);
00325 }
00326
00327 delete e;
00328 return;
00329 }
00330
00331 void
00332 GenericInterfaceNB::handle_tick_event(IrisEvent* e)
00333 {
00334 ticking = false;
00335
00336
00337
00338 for ( uint i=0; i<vcs ; i++)
00339 if ( out_packets[i].size() > 0 && out_packet_flit_index[i] < out_packets[i].length )
00340 {
00341 out_buffer.change_push_channel(i);
00342 Flit* ptr = out_packets[i].get_next_flit();
00343 ptr->vc = i;
00344 out_buffer.push( ptr);
00345 out_packet_flit_index[i]++;
00346
00347 if(out_packet_flit_index[i] == out_packets[i].length )
00348 {
00349 out_packet_flit_index[i] = 0;
00350 out_packets[i].flits.clear();
00351 in_packet_complete[i] = true;
00352 }
00353 ticking = true;
00354 }
00355
00356
00357 for ( uint i=0; i<vcs ; i++)
00358 {
00359
00360
00361
00362
00363
00364
00365 if( downstream_credits[i]>0 && out_buffer.get_occupancy(i)>0
00366 && in_packet_complete[i] )
00367 {
00368
00369
00370
00371 {
00372
00373 out_arbiter.request(i);
00374
00375 ticking = true;
00376 }
00377
00378 }
00379 }
00380
00381
00382 if ( !out_arbiter.is_empty())
00383 {
00384 uint winner = out_arbiter.pick_winner();
00385 if ( winner > vcs )
00386 {
00387 cout << " ERROR: Interface Arbiter picked incorrect vc to send " << endl;
00388 exit(1);
00389 }
00390 IrisEvent* event = new IrisEvent();
00391 LinkArrivalData* arrival = new LinkArrivalData();
00392 arrival->type = FLIT_ID;
00393 arrival->vc = winner;
00394 event->vc = arrival->vc;
00395 out_buffer.change_pull_channel(arrival->vc);
00396 arrival->ptr = out_buffer.pull();
00397 arrival->ptr->vc = arrival->vc;
00398 downstream_credits[arrival->vc]--;
00399 flits_out++;
00400 out_arbiter.clear_winner();
00401
00402 event->event_data.push_back(arrival);
00403 event->type = LINK_ARRIVAL_EVENT;
00404 event->src_id = address;
00405 event->vc = arrival->vc;
00406
00407 Flit* f = arrival->ptr;
00408
00409 Simulator::Schedule(Simulator::Now()+0.75,
00410 &NetworkComponent::process_event,
00411 static_cast<GenericLink*>(output_connection)->output_connection, event);
00412 static_cast<GenericLink*>(output_connection)->flits_passed++;
00413 istat->stat_link[static_cast<GenericLink*>(output_connection)->link_id]->flits_transferred++;
00414 ticking = true;
00415
00416 if ( f->type == HEAD )
00417 {
00418
00419 HeadFlit* hf = static_cast<HeadFlit*>(f);
00420
00421 #ifdef _DEBUG
00422 if(is_mc_interface)
00423 {
00424 _DBG("INTM->ROUTER vc:%d %llx",arrival->vc,hf->addr);
00425 }
00426 else
00427 {
00428 _DBG("INT->ROUTER vc:%d %llx",arrival->vc, hf->addr);
00429 }
00430 #endif
00431
00432 static_cast<HeadFlit*>(f)->avg_network_latency = Simulator::Now()
00433 - static_cast<HeadFlit*>(f)->avg_network_latency;
00434 }
00435
00436 if (f->type == TAIL || ( f->type == HEAD && static_cast<HeadFlit*>(f)->msg_class == ONE_FLIT_REQ) )
00437 {
00438 packets_out++;
00439 in_packet_complete[winner] = false;
00440
00441 IrisEvent* event = new IrisEvent();
00442 event->type = READY_EVENT;
00443 event->vc = winner;
00444 Simulator::Schedule(floor(Simulator::Now())+1, &NetworkComponent::process_event, processor_connection, event);
00445 }
00446 out_arbiter.clear_winner();
00447
00448 }
00449
00450
00451
00452 bool found = false;
00453 for ( uint i=flast_vc+1; i<vcs ; i++)
00454 if ( in_ready[i] )
00455 {
00456 flast_vc = i;
00457 found = true;
00458 break;
00459 }
00460
00461 if(!found)
00462 { for ( uint i=0; i<=flast_vc ; i++)
00463 if ( in_ready[i] )
00464 {
00465 flast_vc = i;
00466 found = true;
00467 break;
00468 }
00469 }
00470
00471 bool pkt_fnd = false;
00472 uint comp_pkt_index = -1;
00473 for ( uint i=0; i<vcs ; i++)
00474 if ( in_packets_flit_index[i]!=0 && in_packets_flit_index[i] == in_packets[i].length)
00475 {
00476 pkt_fnd = true;
00477 comp_pkt_index = i;
00478
00479 }
00480
00481
00482 if ( found && pkt_fnd )
00483 {
00484 if(!static_cast<Processor*>(processor_connection)->ni_recv)
00485 {
00486 static_cast<Processor*>(processor_connection)->ni_recv = true;
00487 in_ready[flast_vc] = false;
00488 HighLevelPacket* pkt = new HighLevelPacket();
00489 pkt->from_low_level_packet(&in_packets[comp_pkt_index]);
00490 uint orig_vc = pkt->virtual_channel;
00491 pkt->virtual_channel = flast_vc;
00492 in_packets[comp_pkt_index].virtual_channel = flast_vc;
00493 pkt->recv_time = Simulator::Now();
00494
00495
00496 pkt->avg_network_latency = in_packets[comp_pkt_index].avg_network_latency;
00497 pkt->hop_count = in_packets[comp_pkt_index].hop_count;
00498 pkt->req_start_time = in_packets[comp_pkt_index].req_start_time;
00499 pkt->waiting_in_ni = in_packets[comp_pkt_index].waiting_in_ni;
00500
00501 #ifdef _DEBUG
00502 if(is_mc_interface)
00503 {
00504 _DBG(" PKT->NI %llx vc%d",pkt->addr, pkt->virtual_channel);
00505 }
00506 else
00507 {
00508 _DBG(" PKT->PROC vc%d",pkt->virtual_channel);
00509 }
00510 #endif
00511
00512 in_packets_flit_index[comp_pkt_index] = 0;
00513 IrisEvent* event = new IrisEvent();
00514 event->type = NEW_PACKET_EVENT;
00515 event->event_data.push_back(pkt);
00516 event->src_id = address;
00517 event->vc = pkt->virtual_channel;
00518 Simulator::Schedule(floor(Simulator::Now())+ 1,
00519 &NetworkComponent::process_event, processor_connection, event);
00520
00521 LinkArrivalData* arrival = new LinkArrivalData();
00522 arrival->vc = orig_vc;
00523 arrival->type = CREDIT_ID;
00524 IrisEvent* event2 = new IrisEvent();
00525 event2->type = LINK_ARRIVAL_EVENT;
00526 event2->vc = orig_vc;
00527 event2->event_data.push_back(arrival);
00528 event2->src_id = address;
00529 Simulator::Schedule( floor(Simulator::Now())+0.75,
00530 &NetworkComponent::process_event,
00531 static_cast<GenericLink*>(input_connection)->input_connection, event2);
00532 static_cast<GenericLink*>(input_connection)->credits_passed++;
00533 istat->stat_link[static_cast<GenericLink*>(input_connection)->link_id]->credits_transferred++;
00534 ticking = true;
00535
00536 }
00537 else
00538 ticking =true;
00539 }
00540
00541
00542 for ( uint i=0; i<vcs ; i++ )
00543 if( in_buffer.get_occupancy(i) > 0 && in_packets_flit_index[i] < in_packets[i].length )
00544 {
00545 in_buffer.change_pull_channel(i);
00546 Flit* ptr = in_buffer.pull();
00547 in_packets[i].add(ptr);
00548
00549 in_packets_flit_index[i]++;
00550 ticking = true;
00551
00552 if( ptr->type == HEAD && static_cast<HeadFlit*>(ptr)->dst_address != node_ip)
00553 {
00554 HeadFlit* hf = static_cast<HeadFlit*>(ptr);
00555 _DBG("ERROR IncorrectDestinationException pkt_dest: %d node_ip: %d addr:%lld", in_packets[i].destination, node_ip, hf->addr);
00556 }
00557
00558 }
00559
00560 if(ticking)
00561 {
00562 ticking = true;
00563 IrisEvent* new_event = new IrisEvent();
00564 new_event->type = TICK_EVENT;
00565 new_event->vc = e->vc;
00566 Simulator::Schedule( floor(Simulator::Now())+1, &GenericInterfaceNB::process_event, this, new_event);
00567 }
00568
00569 delete e;
00570 }
00571
00572
00573 string
00574 GenericInterfaceNB::print_stats()
00575 {
00576 stringstream str;
00577 str << "\n interface[" << node_ip <<"] flits_in: " << flits_in
00578 << "\n interface[" << node_ip <<"] packets_in: " << packets_in
00579 << "\n interface[" << node_ip <<"] flits_out: " << flits_out
00580 << "\n interface[" << node_ip <<"] packets_out: " << packets_out
00581 << "\n interface[" << node_ip <<"] total_packet_latency(In packets): " << total_packets_in_time;
00582 if(packets_in != 0)
00583 str << "\n interface[" << node_ip <<"] avg_packet_latency(In packets): " << (total_packets_in_time+0.0)/packets_in
00584 ;
00585 return str.str();
00586
00587 }
00588
00589 ullint
00590 GenericInterfaceNB::get_flits_out()
00591 {
00592 return flits_out;
00593 }
00594
00595 ullint
00596 GenericInterfaceNB::get_packets_out()
00597 {
00598 return packets_out;
00599 }
00600
00601 ullint
00602 GenericInterfaceNB::get_packets()
00603 {
00604 return packets_out + packets_in;
00605 }
00606
00607 #endif
00608