genericInterfaceNB.cc

Go to the documentation of this file.
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 }               /* -----  end of function GenericInterfaceNB::GenericInterfaceNB  ----- */
00029 
00030 GenericInterfaceNB::~GenericInterfaceNB()
00031 {
00032     in_packets.clear();
00033     out_packets.clear();
00034 }               /* -----  end of function GenericInterfaceNB::~GenericInterfaceNB  ----- */
00035 
00036 void
00037 GenericInterfaceNB::setup (uint v, uint cr, uint bs)
00038 {
00039     vcs =v;
00040     credits = cr;
00041     buffer_size = bs;
00042     /* All this is part of the init */
00043     address = myId();
00044     flast_vc = 0;
00045 //    convert_packet_cycles = DEFAULT_CONVERT_PACKET_CYCLES;
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     /*  init stats */
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     /* Init complete */
00082 
00083 
00084     return;
00085 }               /* -----  end of function GenericInterfaceNB::setup  ----- */
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 }               /* -----  end of function GenericInterfaceNB::toString  ----- */
00099 
00100 void
00101 GenericInterfaceNB::set_no_credits( int cr )
00102 {
00103 }               /* -----  end of function GenericInterfaceNB::toString  ----- */
00104 
00105 uint
00106 GenericInterfaceNB::get_no_credits() const
00107 {
00108     return credits;
00109 }               /* -----  end of function GenericInterfaceNB::toString  ----- */
00110 
00111 void
00112 GenericInterfaceNB::set_no_vcs( uint cr )
00113 {
00114 }               /* -----  end of function GenericInterfaceNB::toString  ----- */
00115 
00116 void
00117 GenericInterfaceNB::set_buffer_size( uint cr )
00118 {
00119 }               /* -----  end of function GenericInterfaceNB::toString  ----- */
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 }               /* -----  end of function GenericInterfaceNB::process_event ----- */
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 }               /* -----  end of function GenericInterfaceNB::handle_ready_event  ----- */
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 }               /* -----  end of function GenericInterfaceNB::handle_link_arrival  ----- */
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        if( pkt->msg_class == RESPONSE_PKT)
00294        pkt->virtual_channel = 1;
00295        else
00296        pkt->virtual_channel = 0;
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 }               /* -----  end of function GenericInterfaceNB::handle_new_packet_event  ----- */
00330 
00331 void
00332 GenericInterfaceNB::handle_tick_event(IrisEvent* e)
00333 {
00334     ticking = false;
00335 
00336 
00337     //out packet to out buffer
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); //out_packets[i].virtual_channel);
00342             Flit* ptr = out_packets[i].get_next_flit();
00343             ptr->vc = i; //out_packets[i].virtual_channel;
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     /* Request out arbiter if there are enough credits */
00357     for ( uint i=0; i<vcs ; i++)
00358     {
00359         /* A you need to interpret the pattern at which the interface output
00360          * flits for a given input rate uncomment the next two lines and track
00361          * the occupancy with the pkt complete flag
00362          _DBG("request: %d occ:%d cr:%d ",i,out_buffer.get_occupancy(i),downstream_credits[i]);
00363          cout <<" comp:"<<in_packet_complete[i];
00364          * */
00365         if( downstream_credits[i]>0 && out_buffer.get_occupancy(i)>0
00366             && in_packet_complete[i] )
00367         {
00368             //            out_buffer.change_pull_channel(i);
00369             //            Flit* f= out_buffer.peek();
00370             //            if((f->type != HEAD)||( f->type == HEAD  && downstream_credits[i] == credits))
00371             {
00372                 //                if ( !out_arbiter.is_requested(i) )
00373                 out_arbiter.request(i);
00374 
00375                 ticking = true;
00376             }
00377 
00378         }
00379     }
00380 
00381     /*---------- This is on the output side. From processor out to network --------- */
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; //out_packets[winner].virtual_channel;
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             //        _DBG("Flit out ft:%d vc:%d", f->type,arrival->vc);
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     /*---------- This is on the input side. From network in to the processor node --------- */
00451     // in packets to processor
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             //            break;
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             /* This should be done inside from_low_level_packet. FIXME */
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; //pkt->virtual_channel;
00523             arrival->type = CREDIT_ID;
00524             IrisEvent* event2 = new IrisEvent();
00525             event2->type = LINK_ARRIVAL_EVENT;
00526             event2->vc = orig_vc; //pkt->virtual_channel;
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     // arbitrate for the winner and push packets to in_buffer
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   /* ----- #ifndef _genericInterfaceNB_cc_INC  ----- */
00608 

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