00001
00023 #ifndef _genericInterfacePhy_cc_INC
00024 #define _genericInterfacePhy_cc_INC
00025
00026 #include "genericInterface.h"
00027 #include <algorithm>
00028
00029 GenericInterfacePhy::GenericInterfacePhy ()
00030 {
00031 name = "Interface";
00032 ticking =false;
00033 }
00034
00035 GenericInterfacePhy::~GenericInterfacePhy ()
00036 {
00037 in_packets.clear();
00038 out_packets.clear();
00039
00040 }
00041
00042 void
00043 GenericInterfacePhy::setup (uint v, uint cr)
00044 {
00045 vcs =v;
00046 int credits = cr;
00047
00048 address = myId();
00049
00050
00051 vector <uint>::iterator itr = find(mc_positions.begin(), mc_positions.end(), node_ip);
00052 if ( itr != mc_positions.end())
00053 is_for_mc = true;
00054 else
00055 is_for_mc = false;
00056
00057 in_packet_complete = false;
00058 in_buffer.resize(vcs, buffer_size);
00059 out_buffer.resize(vcs, buffer_size);
00060 downstream_credits.resize(vcs);
00061
00062 out_packet_flit_index.resize(vcs);
00063 in_ready.resize(vcs);
00064 in_packets_flit_index.resize(vcs);
00065
00066 in_packets.resize(vcs);
00067 in_packets_valid.resize(vcs);
00068 out_packets.resize(vcs);
00069
00070
00071 for ( uint i=0; i<vcs ; i++ )
00072 {
00073 out_packet_flit_index[i] = 0;
00074 in_ready[i] = true;
00075 in_packets[i].destination = address;
00076 in_packets[i].virtual_channel = i;
00077 in_packets[i].length= 10;
00078 downstream_credits[i] = credits;
00079 }
00080
00081
00082 packets_out = 0;
00083 flits_out = 0;
00084 packets_in = 0;
00085 flits_in = 0;
00086 total_packets_in_time = 0;
00087
00088
00089
00090
00091 return;
00092 }
00093
00094 void
00095 GenericInterfacePhy::set_no_vcs( uint v )
00096 {
00097 vcs = v;
00098 }
00099
00100 void
00101 GenericInterfacePhy::set_buffer_size( uint b )
00102 {
00103 buffer_size = b;
00104 }
00105
00106
00107
00108 uint
00109 GenericInterfacePhy::get_no_credits () const
00110 {
00111 return credits;
00112 }
00113
00114 void
00115 GenericInterfacePhy::set_no_credits ( int c)
00116 {
00117 credits = c;
00118 return;
00119 }
00120
00121 string
00122 GenericInterfacePhy::toString () const
00123 {
00124 stringstream str;
00125 str << "GenericInterfacePhy: "
00126 << "\t VC: " << out_packets.size()
00127 << "\t address: " << address << " node_ip: " << node_ip
00128 << "\t OutputBuffers: " << out_buffer.toString()
00129 << "\t InputBuffer: " << in_buffer.toString()
00130 ;
00131 return str.str();
00132 }
00133
00134 void
00135 GenericInterfacePhy::process_event(IrisEvent* e)
00136 {
00137 switch(e->type)
00138 {
00141 case READY_EVENT:
00142 handle_ready_event(e);
00143 break;
00144
00147 case LINK_ARRIVAL_EVENT:
00148 handle_link_arrival(e);
00149 break;
00150
00153 case NEW_PACKET_EVENT:
00154 handle_new_packet_event(e);
00155 break;
00156
00164 case TICK_EVENT:
00165 handle_tick_event(e);
00166 break;
00167
00168 default:
00169 cout << "**Unkown event exception! " << e->type << endl;
00170 break;
00171 }
00172 }
00173
00174 void
00175 GenericInterfacePhy::handle_ready_event( IrisEvent* e)
00176 {
00181 #ifdef _DEBUG_INTERFACE
00182 _DBG(" handle_ready_event %d ", e->vc);
00183 #endif
00184
00185 in_ready[0] = true;
00186 if(!ticking)
00187 {
00188 ticking = true;
00189 IrisEvent* event = new IrisEvent();
00190 event->type = TICK_EVENT;
00191 event->vc = 0;
00192 Simulator::Schedule( floor(Simulator::Now())+1, &NetworkComponent::process_event, this, event);
00193 }
00194
00195 delete e;
00196 return;
00197 }
00198
00199 void
00200 GenericInterfacePhy::handle_link_arrival ( IrisEvent* e)
00201 {
00211 LinkArrivalData* uptr = static_cast<LinkArrivalData* >(e->event_data.at(0));
00212
00213 if(uptr->type == FLIT_ID)
00214 {
00215 flits_in++;
00216 in_buffer.change_push_channel(0);
00217 in_buffer.push(uptr->ptr);
00218 if( uptr->ptr->type == TAIL )
00219 {
00220 packets_in++;
00221 total_packets_in_time += (ullint)(ceil(Simulator::Now() -
00222 static_cast<TailFlit*>(uptr->ptr)->packet_originated_time));
00223 static_cast<TailFlit*>(uptr->ptr)->avg_network_latency = ceil(Simulator::Now());
00224 }
00225 #ifdef _DEBUG_INTERFACE
00226 _DBG(" handle_link_arrival FLIT ticking: %d type: %d type: %d", uptr->type, ticking, uptr->ptr->type);
00227 #endif
00228
00229 if( uptr->ptr->is_single_flit_pkt )
00230 {
00231 packets_in++;
00232 total_packets_in_time += (ullint)(Simulator::Now() - static_cast<HeadFlit*>(uptr->ptr)->packet_originated_time);
00233 static_cast<HeadFlit*>(uptr->ptr)->avg_network_latency = ceil(Simulator::Now())-static_cast<HeadFlit*>(uptr->ptr)->avg_network_latency;
00234 }
00235 uptr->valid = false;
00236
00237 if( !(uptr->ptr->type == TAIL || uptr->ptr->is_single_flit_pkt))
00238 {
00239 LinkArrivalData* arrival = new LinkArrivalData();
00240 arrival->vc = 0;
00241 arrival->type = CREDIT_ID;
00242 IrisEvent* event = new IrisEvent();
00243 event->type = LINK_ARRIVAL_EVENT;
00244 event->vc = 0;
00245 event->event_data.push_back(arrival);
00246 event->src_id = address;
00247 Simulator::Schedule( floor(Simulator::Now())+0.75,
00248 &NetworkComponent::process_event, static_cast<GenericLink*>(input_connection)->input_connection, event);
00249 static_cast<GenericLink*>(input_connection)->credits_passed++;
00250
00251 }
00252 }
00253 else if ( uptr->type == CREDIT_ID)
00254 {
00255 downstream_credits[uptr->vc]++;
00256 #ifdef _DEBUG_INTERFACE
00257 _DBG(" got a credit vc: %d ftype: %d no_of_credits: %d ", uptr->vc, uptr->type, downstream_credits[uptr->vc] );
00258 #endif
00259 }
00260 else
00261 {
00262 cout << "Exception: Unk link arrival data type! " << endl;
00263 }
00264
00265 if(!ticking)
00266 {
00267 ticking = true;
00268 IrisEvent* new_event = new IrisEvent();
00269 new_event->type = TICK_EVENT;
00270 new_event->vc = e->vc;
00271 Simulator::Schedule( floor(Simulator::Now())+1, &GenericInterfacePhy::process_event, this, new_event);
00272 }
00273 delete uptr;
00274 delete e;
00275 return;
00276 }
00277
00278 void
00279 GenericInterfacePhy::handle_new_packet_event(IrisEvent* e)
00280 {
00281 HighLevelPacket* pkt = static_cast<HighLevelPacket*>(e->event_data.at(0));
00282 if( out_packets[0].size() !=0 )
00283 {
00284 cout << "Error got new pkt when old not emptied" << endl;
00285 exit(1);
00286 }
00287 pkt->to_low_level_packet(&out_packets[0]);
00288
00289
00290 out_packet_flit_index[ pkt->virtual_channel ] = 0;
00291 delete pkt;
00292
00293 #ifdef _DEBUG_INTERFACE
00294 _DBG("handle_new_packet_event vc: %d ", static_cast<unsigned int >(pkt->virtual_channel) );
00295 #endif
00296
00297 if( !ticking)
00298 {
00299 ticking = true;
00300 IrisEvent* event = new IrisEvent();
00301 event->type = TICK_EVENT;
00302 event->vc = e->vc;
00303 Simulator::Schedule(floor(Simulator::Now())+1, &NetworkComponent::process_event, this, event);
00304 }
00305
00306 delete e;
00307 return;
00308 }
00309
00310 void
00311 GenericInterfacePhy::handle_tick_event(IrisEvent* e)
00312 {
00313 ticking = false;
00314
00315 if( downstream_credits[0]>0 && out_buffer.get_occupancy(0)>0
00316 && in_packet_complete )
00317 {
00318 Flit* f;
00319 bool send_flit = true;
00320 out_buffer.change_pull_channel(0);
00321
00322
00323
00324 f= out_buffer.peek();
00325 if(f->type == HEAD && downstream_credits[0] != credits)
00326 send_flit = false;
00327
00328 if( send_flit )
00329 {
00330 IrisEvent* event = new IrisEvent();
00331 LinkArrivalData* arrival = new LinkArrivalData();
00332 arrival->type = FLIT_ID;
00333 arrival->vc = 0;
00334 out_buffer.change_pull_channel(0);
00335 f = out_buffer.pull();
00336 downstream_credits[arrival->vc]--;
00337
00338 if ( f->type == HEAD )
00339 static_cast<HeadFlit*>(f)->avg_network_latency = Simulator::Now() - static_cast<HeadFlit*>(f)->avg_network_latency;
00340
00341 if (f->type == TAIL || ( f->is_single_flit_pkt) )
00342 {
00343 packets_out++;
00344 in_packet_complete = false;
00345
00346 IrisEvent* event = new IrisEvent();
00347 event->type = READY_EVENT;
00348 event->vc = 0;
00349 Simulator::Schedule(floor(Simulator::Now())+1, &NetworkComponent::process_event, processor_connection, event);
00350 }
00351 flits_out++;
00352
00353 arrival->ptr = f;
00354
00355 event->event_data.push_back(arrival);
00356 event->type = LINK_ARRIVAL_EVENT;
00357 event->src_id = address;
00358 event->vc = arrival->vc;
00359
00360 ticking = true;
00361
00362 if(do_two_stage_router)
00363 Simulator::Schedule(Simulator::Now()+0.75,
00364 &NetworkComponent::process_event,
00365 static_cast<GenericLink*>(output_connection)->output_connection, event);
00366 else
00367 Simulator::Schedule(Simulator::Now()+1.75,
00368 &NetworkComponent::process_event,
00369 static_cast<GenericLink*>(output_connection)->output_connection, event);
00370 static_cast<GenericLink*>(output_connection)->flits_passed++;
00371 #ifdef _DEBUG_INTERFACE
00372 _DBG(" FLIT_OUT_EVENT credits_now: %d fty:%d", downstream_credits[0], arrival->ptr->type);
00373 #endif
00374 }
00375 }
00376
00377
00378 if ( out_packets[0].size() > 0 && out_packet_flit_index[0] < out_packets[0].length )
00379 {
00380 out_buffer.change_push_channel(0);
00381 Flit* ptr = out_packets[0].get_next_flit();
00382 out_buffer.push( ptr);
00383 out_packet_flit_index[0]++;
00384
00385 #ifdef _DEBUG_INTERFACE
00386 _DBG("Flit->OutBuffer ftype:%d outpkt_len:%d index:%d OB_size: %d ",ptr->type, out_packets[0].length, out_packet_flit_index[0], out_buffer.get_occupancy(0));
00387 #endif
00388
00389 if(out_packet_flit_index[0] == out_packets[0].length )
00390 {
00391 out_packet_flit_index[0] = 0;
00392 out_packets[0].flits.clear();
00393 in_packet_complete = true;
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 }
00407 ticking = true;
00408 }
00409
00410
00411
00412
00413
00414 if ( in_ready[0] && in_packets_flit_index[0]!=0 && in_packets_flit_index[0] == in_packets[0].length)
00415 {
00416 in_ready[0] = false;
00417 HighLevelPacket* pkt = new HighLevelPacket();
00418 pkt->from_low_level_packet(&in_packets[0]);
00419 pkt->avg_network_latency = in_packets[0].avg_network_latency;
00420 pkt->hop_count = in_packets[0].hop_count;
00421 pkt->recv_time = (ullint)Simulator::Now();
00422 pkt->req_start_time = in_packets[0].req_start_time;
00423 pkt->waiting_in_ni = in_packets[0].waiting_in_ni;
00424 #ifdef _DEBUG_INTERFACE
00425 _DBG( "Interface got a complete llp: %s ", in_packets[0].toString().c_str());
00426 _DBG("converted it %s",pkt->toString().c_str());
00427 #endif
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 in_packets_flit_index[0] = 0;
00448 IrisEvent* event = new IrisEvent();
00449 event->type = NEW_PACKET_EVENT;
00450 event->event_data.push_back(pkt);
00451 event->src_id = address;
00452 event->vc = 0;
00453 Simulator::Schedule(floor(Simulator::Now())+ 1,
00454 &NetworkComponent::process_event, processor_connection, event);
00455
00456 LinkArrivalData* arrival = new LinkArrivalData();
00457 arrival->vc = 0;
00458 arrival->type = CREDIT_ID;
00459 IrisEvent* event2 = new IrisEvent();
00460 event2->type = LINK_ARRIVAL_EVENT;
00461 event2->vc = 0;
00462 event2->event_data.push_back(arrival);
00463 event2->src_id = address;
00464 if(do_two_stage_router)
00465 Simulator::Schedule( floor(Simulator::Now())+0.75,
00466 &NetworkComponent::process_event, static_cast<GenericLink*>(input_connection)->input_connection, event2);
00467 else
00468 Simulator::Schedule( floor(Simulator::Now())+1.75,
00469 &NetworkComponent::process_event, static_cast<GenericLink*>(input_connection)->input_connection, event2);
00470 static_cast<GenericLink*>(input_connection)->credits_passed++;
00471 ticking = true;
00472 #ifdef _DEBUG_INTERFACE
00473 _DBG("Packet to Processor. Sent credit back: %s", pkt->toString().c_str());
00474 #endif
00475
00476 }
00477 else if ( !in_ready[0] && (in_packets_flit_index[0]!=0 && in_packets_flit_index[0] == in_packets[0].length))
00478 {
00479 ticking = true;
00480 }
00481
00482
00483 if( in_buffer.get_occupancy(0) > 0 && in_packets_flit_index[0] < in_packets[0].length )
00484 {
00485 in_buffer.change_pull_channel(0);
00486 Flit* ptr = in_buffer.pull();
00487 in_packets[0].add(ptr);
00488
00489 in_packets_flit_index[0]++;
00490 ticking = true;
00491 #ifdef _DEBUG_INTERFACE
00492 _DBG("Inpush flit ftype:%d", ptr->type);
00493 #endif
00494 if( ptr->type == HEAD && static_cast<HeadFlit*>(ptr)->dst_address != node_ip)
00495 {
00496 _DBG("ERROR IncorrectDestinationException pkt_dest: %d node_ip: %d", in_packets[0].destination, node_ip);
00497 }
00498
00499 }
00500
00501 if(ticking)
00502 {
00503 ticking = true;
00504 IrisEvent* new_event = new IrisEvent();
00505 new_event->type = TICK_EVENT;
00506 new_event->vc = e->vc;
00507 Simulator::Schedule( floor(Simulator::Now())+1, &GenericInterfacePhy::process_event, this, new_event);
00508 }
00509
00510 delete e;
00511 }
00512
00513 string
00514 GenericInterfacePhy::print_stats()
00515 {
00516 stringstream str;
00517 str << "\n interface[" << node_ip <<"] flits_in: " << flits_in
00518 << "\n interface[" << node_ip <<"] packets_in: " << packets_in
00519 << "\n interface[" << node_ip <<"] flits_out: " << flits_out
00520 << "\n interface[" << node_ip <<"] packets_out: " << packets_out
00521 << "\n interface[" << node_ip <<"] total_packet_latency(In packets): " << total_packets_in_time;
00522 if(packets_in != 0)
00523 str << "\n interface[" << node_ip <<"] avg_packet_latency(In packets): " << (total_packets_in_time+0.0)/packets_in
00524 ;
00525 return str.str();
00526
00527 }
00528
00529 ullint
00530 GenericInterfacePhy::get_flits_out()
00531 {
00532 return flits_out;
00533 }
00534
00535 ullint
00536 GenericInterfacePhy::get_packets_out()
00537 {
00538 return packets_out;
00539 }
00540
00541 ullint
00542 GenericInterfacePhy::get_packets()
00543 {
00544 return packets_out + packets_in;
00545 }
00546
00547 bool
00548 GenericInterfacePhy::is_pkt_in_progress(uint vc)
00549 {
00550 return pkt_in_progress[vc];
00551 }
00552
00553 #endif
00554