genericInterfacePhy.cc

Go to the documentation of this file.
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 }               /* -----  end of function GenericInterfacePhy::GenericInterfacePhy  ----- */
00034 
00035 GenericInterfacePhy::~GenericInterfacePhy ()
00036 {
00037     in_packets.clear();
00038     out_packets.clear();
00039 
00040 }               /* -----  end of function GenericInterfacePhy::~GenericInterfacePhy  ----- */
00041 
00042 void
00043 GenericInterfacePhy::setup (uint v, uint cr)
00044 {
00045     vcs =v;
00046     int credits = cr;
00047     /* All this is part of the init */
00048     address = myId();
00049     //    convert_packet_cycles = DEFAULT_CONVERT_PACKET_CYCLES;
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     /*  init stats */
00082     packets_out = 0;
00083     flits_out = 0;
00084     packets_in = 0;
00085     flits_in = 0;
00086     total_packets_in_time = 0;
00087 
00088     /* Init complete */
00089 
00090 
00091     return;
00092 }               /* -----  end of function GenericInterfacePhy::setup  ----- */
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 /* We care about credits on the interface only for the output buffers ie on
00107  * the output side maintain credit info for the downstream buffers */
00108 uint
00109 GenericInterfacePhy::get_no_credits () const
00110 {
00111     return credits;
00112 }               /* -----  end of function GenericInterfacePhy::get_no_credits  ----- */
00113 
00114 void
00115 GenericInterfacePhy::set_no_credits ( int c)
00116 {
00117     credits = c;
00118     return;
00119 }               /* -----  end of function GenericInterfacePhy::set_no_credits  ----- */
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 }               /* -----  end of function GenericInterfacePhy::toString  ----- */
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 }               /* -----  end of function GenericInterfacePhy::process_event ----- */
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 }               /* -----  end of function GenericInterfacePhy::handle_ready_event  ----- */
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 }               /* -----  end of function GenericInterfacePhy::handle_link_arrival  ----- */
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 }               /* -----  end of function GenericInterfacePhy::handle_new_packet_event  ----- */
00309 
00310 void
00311 GenericInterfacePhy::handle_tick_event(IrisEvent* e)
00312 {
00313     ticking = false;
00314     /*---------- This is on the output side. From processor out to network --------- */
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         /* Needed for adaptive VCS and ensures the check for one msg per input
00322          * port of a router. However in DOR with packets of variable length
00323          * this leads to poor buffer utilization. Hence removing.*/
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     //out packet to out buffer
00378     if ( out_packets[0].size() > 0 && out_packet_flit_index[0] < out_packets[0].length ) //&& out_buffer.get_occupancy(0)>0)
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                if( out_packets[0].size()<1)
00397                {
00398 
00399                IrisEvent* event = new IrisEvent();
00400                event->type = READY_EVENT;
00401                event->vc = 0;
00402                Simulator::Schedule(floor(Simulator::Now())+1, &NetworkComponent::process_event, processor_connection, event);
00403                }
00404              * */
00405 
00406         }
00407         ticking = true;
00408     }
00409 
00410 
00411     /*---------- This is on the input side. From processor out to ntwk --------- */
00412     // in packets to processor
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            LowLevelPacket* llp = &in_packets[0];
00431            for( uint k=0; k<llp->flits.size(); k++)
00432            {
00433            for ( uint j=0;j<llp->flits[k]->phits.size() ;j++ )
00434            {
00435            llp->flits[k]->phits[j]->data.clear();
00436            delete (llp->flits[k]->phits[j]);
00437            }
00438            llp->flits[k]->phits.erase(llp->flits[k]->phits.begin(),llp->flits[k]->phits.end());
00439            llp->flits[k]->phits.clear();
00440            delete (llp->flits[k]);
00441            }
00442 
00443            llp->flits.erase(llp->flits.begin(),llp->flits.end());
00444            llp->flits.clear();
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     // arbitrate for the winner and push packets to in_buffer
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   /* ----- #ifndef _genericInterfacePhy_cc_INC  ----- */
00554 

Generated on Tue Oct 19 17:22:00 2010 for IRIS by  doxygen 1.5.8