genericRouter4Stg.cc

Go to the documentation of this file.
00001 
00018 #ifndef  _genericRouter4Stg_cc_INC
00019 #define  _genericRouter4Stg_cc_INC
00020 
00021 #include        "genericRouter4Stg.h"
00022 using namespace std;
00023 
00024 GenericRouter4Stg::GenericRouter4Stg ()
00025 {
00026     name = "GenericRouter4Stg" ;
00027     ticking = false;
00028 }  /* -----  end of method GenericRouter4Stg::GenericRouter4Stg  (constructor)  ----- */
00029 
00030 GenericRouter4Stg::~GenericRouter4Stg()
00031 {
00032 }
00033 
00034 void
00035 GenericRouter4Stg::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     /*  set_input_ports(ports); */
00045     in_buffers.resize(ports);
00046     decoders.resize(ports);
00047     input_buffer_state.resize(ports*vcs);
00048     vca.setup(ports,vcs);
00049     swa.resize(ports,vcs);
00050     xbar.setup(ports,vcs);
00051     downstream_credits.resize(ports);
00052     cr_time.resize(ports);
00053 
00054     /*Resize per port stats */
00055     stat_packet_out.resize(ports);
00056     stat_flit_out.resize(ports);
00057 
00058 
00059     /* All decoders and vc arbiters need to know the node_ip for routing */
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     swa.node_ip = node_ip;
00068     swa.address = address;
00069     vca.node_ip = node_ip;
00070     vca.address = address;
00071 
00072     /*  set_no_virtual_channels(vcs); */
00073     for(uint i=0; i<ports; i++)
00074     {
00075         downstream_credits[i].resize(vcs);
00076         cr_time[i].resize(vcs);
00077         in_buffers[i].resize( vcs, buffer_size );
00078         decoders[i].resize( vcs );
00079     }
00080 
00081     for(uint i=0; i<ports; i++)
00082         for(uint j=0; j<vcs; j++)
00083         {
00084             downstream_credits[i][j] = credits;
00085             cr_time[i][j] = -1;
00086         }
00087 
00088     /* init the countes */
00089     packets = 0;
00090     flits = 0;
00091     total_packet_latency = 0;
00092 
00093         IrisEvent* event = new IrisEvent();
00094         event->type = DETECT_DEADLOCK_EVENT;
00095         Simulator::Schedule( floor(Simulator::Now())+1, &NetworkComponent::process_event, this, event);
00096 
00097     return ;
00098 }               /* -----  end of function GenericRouter4Stg::init  ----- */
00099 
00102 void
00103 GenericRouter4Stg::set_no_nodes( uint nodes )
00104 {
00105     for ( uint i=0; i<decoders.size(); i++)
00106     {
00107         decoders[i].grid_xloc.resize(nodes);
00108         decoders[i].grid_yloc.resize(nodes);
00109     }
00110 }
00111 
00112 void
00113 GenericRouter4Stg::set_grid_x_location( uint port, uint x_node, uint value)
00114 {
00115     decoders[port].grid_xloc[x_node]= value;
00116 }
00117 
00118 void
00119 GenericRouter4Stg::set_grid_y_location( uint port, uint y_node, uint value)
00120 {
00121     decoders[port].grid_yloc[y_node]= value;
00122 }
00123 
00124 /*  End of DOR grid location functions */
00125 
00126 void
00127 GenericRouter4Stg::process_event ( IrisEvent* e )
00128 {
00129     switch(e->type)
00130     {
00131         case LINK_ARRIVAL_EVENT:
00132             handle_link_arrival_event(e);
00133             break;
00134         case TICK_EVENT:
00135             handle_tick_event(e);
00136             break;
00137         case DETECT_DEADLOCK_EVENT:
00138             handle_detect_deadlock_event(e);
00139             break;
00140         default:
00141             _DBG("GenericRouter4Stg:: Unk event exception %d", e->type);
00142             break;
00143     }
00144     return ;
00145 }               /* -----  end of function GenericRouter4Stg::process_event  ----- */
00146 
00147 void 
00148 GenericRouter4Stg::handle_detect_deadlock_event(IrisEvent* e )
00149 {
00150     for ( uint i=0; i<ports; i++)
00151         for ( uint j=0; j<vcs; j++)
00152         {
00153             if( cr_time[i][j] != -1)
00154             {
00155                 cr_time[i][j]++;
00156             if( cr_time[i][j] > 500 )
00157                 {
00158                     _DBG_NOARG("************ KILLING SIMULATION *************");
00159                     cout << "\ndeadlock detected op:"<< i << " ovc: " << j <<  endl;
00160                     cout << "\ndeadlock mssg:"<< endl;
00161                     for ( uint ii=0; ii<ports*vcs; ii++)
00162                         if(input_buffer_state[ii].output_port == i && input_buffer_state[ii].output_channel == j)
00163                             cout << hex << input_buffer_state[ii].address << endl;
00164                     cout << "*************************" << endl;
00165 
00166 //                    print_state_at_deadlock();
00167                         exit(1);
00168                 }
00169             }
00170         }
00171 
00172     e->type = DETECT_DEADLOCK_EVENT;
00173     Simulator::Schedule( floor(Simulator::Now())+50, &NetworkComponent::process_event, this, e);
00174 }
00175 
00176 void 
00177 GenericRouter4Stg::dump_buffer_state()
00178 {
00179     for ( uint i=0; i<ports*vcs; i++)
00180         if(input_buffer_state[i].pipe_stage != EMPTY && input_buffer_state[i].pipe_stage != INVALID)
00181         {
00182             cout << " Router[" << node_ip << "]->buff["<<i<<"] " << input_buffer_state[i].toString() << endl;
00183         }
00184     cout << endl;
00185 
00186     return;
00187 }
00188 
00189 string
00190 GenericRouter4Stg::print_stats()
00191 {
00192     stringstream str;
00193     str << name ;
00194     str << "\n router[" << node_ip << "] packet latency: " << total_packet_latency
00195         << "\n router[" << node_ip << "] flits/packets: " << (flits+0.0)/(packets)
00196         << "\n router[" << node_ip << "] average packet latency: " << (total_packet_latency+0.0)/packets
00197         << "\n router[" << node_ip << "] last_flit_out_cycle: " << last_flit_out_cycle
00198         << " ";
00199     str << "\n router[" << node_ip << "] packets: " << packets
00200         << "\n router[" << node_ip << "] flits: " << flits;
00201     if( stat_print_level > 2 )
00202     {
00203         for( uint i=0; i<ports; i++)
00204             for ( uint j=0; j<ports; j++)
00205             {
00206                 string in_port = "Inv";
00207                 switch( i )
00208                 {
00209                     case 0 : 
00210                         in_port = "Inj";
00211                         break;
00212                     case 1:
00213                         in_port = 'E';
00214                         break;
00215                     case 2:
00216                         in_port = 'W';
00217                         break;
00218                     case 3:
00219                         in_port = 'S';
00220                         break;
00221                     case 4:
00222                         in_port = 'N';
00223                         break;
00224                     default:
00225                         in_port = "Invalid";
00226                         break;
00227                 }
00228 
00229                 string out_port = "Inv";
00230                 switch( j )
00231                 {
00232                     case 0 : 
00233                         out_port = "Ejection";
00234                         break;
00235                     case 1:
00236                         out_port = 'W';
00237                         break;
00238                     case 2:
00239                         out_port = 'E';
00240                         break;
00241                     case 3:
00242                         out_port = 'N';
00243                         break;
00244                     case 4:
00245                         out_port = 'S';
00246                         break;
00247                     default:
00248                         out_port = "Invalid";
00249                         break;
00250                 }
00251                 if ( i != j) 
00252                 {
00253                     str << "\n    router[" << node_ip << "] Packets out " << in_port 
00254                         << " going " << out_port << " : " << stat_packet_out[i][j];
00255                     str << "\n    router[" << node_ip << "] Flits out " << in_port 
00256                         << " going " << out_port << " : " << stat_flit_out[i][j];
00257                 }
00258 
00259             }
00260     }
00261 
00262 
00263     return str.str();
00264 }
00265 
00267 void
00268 GenericRouter4Stg::handle_link_arrival_event ( IrisEvent* e )
00269 {
00270     LinkArrivalData* data = static_cast<LinkArrivalData*>(e->event_data.at(0));
00271     if(data->type == FLIT_ID)
00272     {
00273         /*  Update stats */
00274         flits++;
00275         istat->stat_router[node_ip]->ib_cycles++;
00276         if( data->ptr->type == TAIL || data->ptr->is_single_flit_pkt )
00277             packets++;
00278 
00279         /*Find the port the flit came in on */
00280         bool found = false;
00281         uint port = -1;
00282         /*  Need to check for null here as there may be null links to corner routers */
00283         for ( uint i=0 ; i< ports ; i++ )
00284             if(static_cast<GenericLink*>(input_connections[i])->input_connection) 
00285                 if( e->src_id == static_cast<GenericLink*>(input_connections[i])->input_connection->address)
00286                 {
00287                     found = true;
00288                     port = i;
00289                     break;
00290                 }
00291 
00292         /* Throw and exception if it was not found */
00293         if( !found )
00294         {
00295             _DBG(" Input port not found src_addr: %d", e->src_id);
00296         }
00297 
00298         /* Push the flit into the buffer */
00299         in_buffers[port].change_push_channel(data->vc);
00300         in_buffers[port].push(data->ptr);
00301         if( data->ptr->type == HEAD )
00302         {
00303             HeadFlit* hf = static_cast<HeadFlit*>(data->ptr);
00304 #ifdef _DEBUG_ROUTER
00305             if( is_mc_router)
00306             {
00307                 _DBG("RouterM Msg in in:%d addr:%llx dest:%d src:%d ty:%d",port*vcs+e->vc, hf->addr, hf->dst_address
00308                      ,hf->src_address,hf->msg_class);
00309             }
00310             else
00311             {
00312                 _DBG("Router Msg in in:%d addr:%llx dest:%d src:%d ty:%d",port*vcs+e->vc, hf->addr, hf->dst_address
00313                      ,hf->src_address,hf->msg_class);
00314             }
00315 #endif
00316 
00317             input_buffer_state[port*vcs+data->vc].input_port = port;
00318             hf->inport = port;
00319             decoders[port].push(data->ptr,data->vc);
00320             input_buffer_state[port*vcs+data->vc].input_channel = data->vc;
00321             input_buffer_state[port*vcs+data->vc].address= hf->addr;
00322             input_buffer_state[port*vcs+data->vc].destination= hf->dst_address;
00323             input_buffer_state[port*vcs+data->vc].pipe_stage = FULL;
00324             input_buffer_state[port*vcs+data->vc].sa_head_done = false;
00325             input_buffer_state[port*vcs+data->vc].msg_class = hf->msg_class;
00326             input_buffer_state[port*vcs+data->vc].possible_oports.clear(); 
00327             input_buffer_state[port*vcs+data->vc].possible_ovcs.clear(); 
00328             //            input_buffer_state[port*vcs+data->vc].possible_oports.resize(1); 
00329             //            input_buffer_state[port*vcs+data->vc].possible_ovcs.resize(1); 
00330             uint no_adaptive_ports = decoders[port].no_adaptive_ports(data->vc);
00331             uint no_adaptive_vcs = decoders[port].no_adaptive_vcs(data->vc);
00332 
00333             for ( uint i=0; i<no_adaptive_ports; i++ )
00334             {
00335                 uint rc_port = decoders[port].get_output_port(data->vc);
00336                 if( static_cast<GenericLink*>(output_connections[rc_port])->output_connection != NULL )
00337                     input_buffer_state[port*vcs+data->vc].possible_oports.push_back(rc_port);
00338             } 
00339 
00340             for ( uint i=0; i<no_adaptive_vcs; i++ )
00341             {
00342                 uint rc_vc = decoders[port].get_virtual_channel(data->vc);
00343                 input_buffer_state[port*vcs+data->vc].possible_ovcs.push_back(rc_vc);
00344             } 
00345 
00346             assert ( input_buffer_state[port*vcs+data->vc].possible_oports.size() > 0);
00347             assert ( input_buffer_state[port*vcs+data->vc].possible_ovcs.size() > 0);
00348 
00349             input_buffer_state[port*vcs+data->vc].length= hf->length;
00350             input_buffer_state[port*vcs+data->vc].credits_sent= hf->length;
00351             input_buffer_state[port*vcs+data->vc].arrival_time= ceil(Simulator::Now());
00352             input_buffer_state[port*vcs+data->vc].clear_message= false;
00353             //            input_buffer_state[port*vcs+data->vc].flits_in_ib = 0;
00354 
00355             //            _DBG(" New Msg ip:%d ivc:%d pop:%d povc:%d ", input_buffer_state[port*vcs+data->vc].input_port,
00356             //                 input_buffer_state[port*vcs+data->vc].input_channel, input_buffer_state[port*vcs+data->vc].possible_oports.size(),
00357             //                 input_buffer_state[port*vcs+data->vc].possible_ovcs.size());
00358         }
00359         else
00360         {
00361             decoders[port].push(data->ptr,data->vc);
00362 
00363         }
00364     }
00365     else if ( data->type == CREDIT_ID)
00366     {
00367         /* Find the corresponding output port */
00368         bool found = false;
00369         uint port = -1;
00370         for ( uint i=0 ; ports ; i++ )
00371             if(static_cast<GenericLink*>(output_connections[i])->output_connection) /* Some links of corner routers may be null */
00372                 if( static_cast<GenericLink*>(output_connections[i])->output_connection->address == e->src_id)
00373                 {
00374                     port = i;
00375                     found = true;
00376                     break;
00377                 }
00378         if(!found)
00379         {
00380             _DBG(" Output port not found src_addr: %d", e->src_id);
00381         }
00382 
00383         downstream_credits[port][data->vc]++;
00384         cr_time[port][data->vc] = -1;
00385 
00386 #ifdef _DEBUG_ROUTER
00387         _DBG(" Got a credit port:%d vc:%d  ", port, data->vc, downstream_credits[port][data->vc]);
00388         vector < uint > pending_ops ;
00389         vector < uint > pending_ips ;
00390         for( uint i=0; i<ports*vcs; i++)
00391             if(input_buffer_state[i].output_port == port && input_buffer_state[i].output_channel == data->vc)
00392             {
00393                 pending_ops.push_back(port*vcs+data->vc);
00394                 pending_ips.push_back(i);
00395             }
00396 
00397         cout << " Can send msgs (i-o): " ;
00398         for( uint i=0; i<pending_ops.size(); i++)
00399             cout << pending_ips[i] <<"-" << pending_ops[i] << " occ/" << in_buffers[(int)(pending_ops[i]/vcs)].get_occupancy(pending_ops[i]%vcs)
00400                 <<" bst:"<<input_buffer_state[i].pipe_stage << " ";
00401         pending_ops.clear();
00402         pending_ips.clear();
00403 #endif
00404 
00405     }
00406     else
00407     {
00408         _DBG( "handle_link_arrival_event Unk data type %d ", data->type);
00409     }
00410 
00411     /* Tick since you update a credit or flit */
00412     if(!ticking)
00413     {
00414         ticking = true;
00415         IrisEvent* event = new IrisEvent();
00416         event->type = TICK_EVENT;
00417         event->vc = e->vc;
00418         Simulator::Schedule( floor(Simulator::Now())+1, &NetworkComponent::process_event, this, event);
00419     }
00420 
00421     delete data;
00422     delete e;
00423     return ;
00424 }               /* -----  end of function GenericRouter4Stg::handle_link_arrival_event  ----- */
00425 
00426 void
00427 GenericRouter4Stg::do_switch_traversal()
00428 {
00429     /* Switch traversal */
00430     for( uint i=0; i<ports*vcs; i++)
00431         if( input_buffer_state[i].pipe_stage == SW_TRAVERSAL)
00432         {
00433             uint op = input_buffer_state[i].output_port;
00434             uint oc = input_buffer_state[i].output_channel;
00435             uint ip = input_buffer_state[i].input_port;
00436             uint ic= input_buffer_state[i].input_channel;
00437             if( !xbar.is_empty(op,oc) 
00438                 && in_buffers[ip].get_occupancy(ic)> 0
00439                 && downstream_credits[op][oc]>0 )
00440             {
00441                 istat->stat_router[node_ip]->st_cycles++;
00442                 in_buffers[ip].change_pull_channel(ic);
00443                 Flit* f = in_buffers[ip].pull();
00444                 f->vc = oc;
00445                 //                    input_buffer_state[i].flits_in_ib--;
00446                 //                    swa.clear_winner(op, ip);
00447                 xbar.pull(op,oc);
00448                 //                    if(!(f->type == TAIL || f->is_single_flit_pkt)) 
00449                 {
00450                     swa.request(op, oc, ip, ic);
00451                     input_buffer_state[i].pipe_stage = SWA_REQUESTED;
00452                 }
00453 
00454                 last_flit_out_cycle = Simulator::Now();
00455                 stat_flit_out[ip][op]++;
00456                 static_cast<GenericLink*>(output_connections[op])->flits_passed++;
00457 
00458                 LinkArrivalData* data = new LinkArrivalData();
00459                 data->type = FLIT_ID;
00460                 data->vc = oc;
00461                 data->ptr = f;
00462 
00463                 if( f->type == HEAD)
00464                 {
00465 #ifdef _DEBUG_ROUTER
00466                     if( is_mc_router)
00467                     {
00468                         _DBG("RouterM Msg out addr %llx %d-%d",static_cast<HeadFlit*>(f)->addr,ip*vcs+ic, op*vcs+oc);
00469                     }
00470                     else
00471                     {
00472                         _DBG("Router Msg out addr %llx %d-%d",static_cast<HeadFlit*>(f)->addr,ip*vcs+ic, op*vcs+oc);
00473                     }
00474 #endif
00475                 }
00476 
00477                 if( f->type == TAIL || f->is_single_flit_pkt )
00478                 {
00479                     /* Update packet stats */
00480                     double lat;
00481                     if(do_two_stage_router)
00482                         lat = Simulator::Now() - input_buffer_state[i].arrival_time;
00483                     else
00484                         lat = (Simulator::Now() - input_buffer_state[i].arrival_time)+1;
00485 
00486                     total_packet_latency+= lat;
00487                     if( f->type == HEAD)
00488                     {
00489                         HeadFlit* hf = static_cast<HeadFlit*>(f);
00490                         hf->avg_network_latency += lat;
00491                         hf->hop_count++;
00492                     }
00493                     else
00494                     {
00495                         TailFlit* tf = static_cast<TailFlit*>(f);
00496                         tf->avg_network_latency += lat;
00497                         tf->hop_count++;
00498                     }
00499                     stat_packet_out[ip][op]++;
00500 
00501                     input_buffer_state[i].clear_message = true;
00502                     input_buffer_state[i].pipe_stage = EMPTY;
00503                     vca.clear_winner(op, oc, ip, ic);
00504                     swa.clear_requestor(op, ip,oc);
00505                     input_buffer_state[i].possible_oports.clear();
00506                     input_buffer_state[i].possible_ovcs.clear();
00507                 }
00508 
00509                 cr_time[op][oc] = 0;
00510                 IrisEvent* event = new IrisEvent();
00511                 event->type = LINK_ARRIVAL_EVENT;
00512                 event->event_data.push_back(data);
00513                 event->src_id = address;
00514                 event->dst_id = output_connections[op]->address;
00515                 event->vc = data->vc;
00516 
00520                 if(do_two_stage_router)
00521                     Simulator::Schedule( Simulator::Now()+0.75,
00522                                          &NetworkComponent::process_event,
00523                                          static_cast<GenericLink*>(output_connections[op])->output_connection,event);
00524                 else
00525                     Simulator::Schedule( Simulator::Now()+1.75,
00526                                          &NetworkComponent::process_event,
00527                                          static_cast<GenericLink*>(output_connections[op])->output_connection,event);
00528 
00531                 send_credit_back(i);
00532                 downstream_credits[op][oc]--;
00533 
00534             }
00535             else
00536             {
00537                 xbar.pull(op,oc);
00538                 input_buffer_state[i].pipe_stage = VCA_COMPLETE;
00539                 swa.clear_requestor(op, ip,oc);
00540             }
00541         }
00542 
00543 }
00544 
00545 void
00546 GenericRouter4Stg::do_switch_allocation()
00547 {
00548     /* Switch Allocation */
00549     for( uint i=0; i<ports*vcs; i++)
00550         if( input_buffer_state[i].pipe_stage == SWA_REQUESTED)
00551             if ( !swa.is_empty())
00552             {
00553                 uint op = -1, oc = -1;
00554                 SA_unit sa_winner;
00555                 uint ip = input_buffer_state[i].input_port;
00556                 uint ic = input_buffer_state[i].input_channel;
00557                 op = input_buffer_state[i].output_port;
00558                 oc= input_buffer_state[i].output_channel;
00559                 sa_winner = swa.pick_winner(op);
00560                 istat->stat_router[node_ip]->sa_cycles++;
00561 
00562                 if(input_buffer_state[i].sa_head_done)
00563                 {
00564                     if( sa_winner.port == ip && sa_winner.ch == ic
00565                         && in_buffers[ip].get_occupancy(ic) > 0
00566                         && downstream_credits[op][oc]>0 )
00567                     {
00568                         input_buffer_state[i].pipe_stage = SW_TRAVERSAL;
00569                         xbar.configure_crossbar(ip,op,oc);
00570                         xbar.push(op,oc); 
00571                         /* TODO: Remove oc from the crossbar. phy crossbar (pxp) */
00572                         ticking = true;
00573                     }
00574                     else
00575                     {
00576                         input_buffer_state[i].pipe_stage = VCA_COMPLETE;
00577                         swa.clear_requestor(op, ip,oc);
00578                     }
00579                 }
00580                 else
00581                 {
00582                     if( sa_winner.port == ip && sa_winner.ch == ic
00583                         //                        && in_buffers[ip].get_occupancy(ic) > 0
00584                         && downstream_credits[op][oc]==credits )
00585                     {
00586                         input_buffer_state[i].sa_head_done = true;
00587                         input_buffer_state[i].pipe_stage = SW_TRAVERSAL;
00588                         xbar.configure_crossbar(ip,op,oc);
00589                         xbar.push(op,oc); 
00590                         /* TODO: Remove oc from the crossbar. phy crossbar (pxp) */
00591                         ticking = true;
00592                     }
00593                     else
00594                     {
00595                         input_buffer_state[i].pipe_stage = VCA_COMPLETE;
00596                         swa.clear_requestor(op, ip,oc);
00597                     }
00598 
00599                 }
00600 
00601             }
00602 }
00603 
00605 void
00606 GenericRouter4Stg::handle_tick_event ( IrisEvent* e )
00607 {
00608     ticking = false;
00609 
00610     do_switch_allocation();
00611     do_switch_traversal();
00612 
00613     if(!vca.is_empty())
00614     {
00615         vca.pick_winner();
00616         istat->stat_router[node_ip]->sa_cycles++;
00617         /* 
00618            _DBG_NOARG(" VCA winners: " );
00619            for ( uint ai=0; ai<vca.current_winners.size(); ai++)
00620            if ( vca.current_winners[ai] != -1)
00621            cout << vca.current_winners[ai] << "-" << ai<< "\t";
00622          * */
00623     }
00624 
00625     for( uint i=0; i<(ports*vcs); i++)
00626         if( input_buffer_state[i].pipe_stage == VCA_REQUESTED)
00627         {
00628             uint ic = input_buffer_state[i].input_channel;
00629             uint ip = input_buffer_state[i].input_port;
00630             vector<uint> pos_win;
00631             /* 
00632                vector<uint> winners;
00633                for ( uint ai=0; ai<vca.current_winners.size(); ai++)
00634                winners.push_back(vca.current_winners[ai]);
00635 
00636                uint winnerin = -1;
00637                vector<uint>::iterator itr;
00638                itr = find(winners.begin(), winners.end(),ip*vcs + ivc);
00639                while (itr != winners.end())
00640                {
00641                winnerin = *itr;
00642                pos_win.push_back(itr - winners.begin());
00643                winners.erase(itr);
00644                itr = find(winners.begin(), winners.end(),ip*vcs + ivc);
00645                }
00646                winners.clear();        
00647                cout <<"\n winners for this inport: " << pos_win.size();
00648                for ( uint ai=0; ai<pos_win.size(); ai++)
00649                cout << "\t" << pos_win[ai];
00650              * */
00651 
00652             uint max_cr = 0;
00653             uint pref_op = -1;
00654             uint pref_oc = -1;
00655             for ( uint ai=0; ai<vca.current_winners.size(); ai++)
00656                 if ( vca.current_winners[ai] == ip*vcs+ic)
00657                 {
00658                     pos_win.push_back(ai);
00659                     uint a = (int)(ai/vcs);
00660                     uint b = ai%vcs;
00661                     if ( max_cr < downstream_credits[a][b])
00662                     {
00663                         pref_op = a;
00664                         pref_oc = b;
00665                         max_cr = downstream_credits[a][b];
00666                     }
00667                     //Can break here and use the first one found
00668                 }
00669 
00670             if( pos_win.size() > 0 )
00671             {
00672                 if(pref_op == -1)
00673                 {
00674                     uint pos = pos_win[0]; 
00675                     pref_op = (int)(pos/vcs);
00676                     pref_oc = pos%vcs;
00677                 }
00678 
00679                 input_buffer_state[i].output_port = pref_op;
00680                 input_buffer_state[i].output_channel= pref_oc;
00681 
00682                 vca.squash_requests(pref_op,pref_oc,ip,ic);
00683 
00684                 input_buffer_state[i].pipe_stage = VCA_COMPLETE;
00685             }
00686         }
00687 
00688     for( uint i=0; i<(ports*vcs); i++)
00689         if( input_buffer_state[i].pipe_stage == VCA_COMPLETE)
00690         {
00691             uint ip = input_buffer_state[i].input_port;
00692             uint ic = input_buffer_state[i].input_channel;
00693             uint op = input_buffer_state[i].output_port;
00694             uint oc = input_buffer_state[i].output_channel;
00695 
00696             //            if(!swa.is_requested(input_buffer_state[i].output_port,
00697             //                                 input_buffer_state[i].input_port,
00698             //                                 input_buffer_state[i].output_channel)
00699             if(in_buffers[ip].get_occupancy(ic))
00700             {
00701                 swa.request(op, oc, ip, ic);
00702                 input_buffer_state[i].pipe_stage = SWA_REQUESTED;
00703                 ticking = true;
00704             }
00705         }
00706 
00707     /*  Input buffering 
00708      *  Flits are pushed into the input buffer in the link arrival handler
00709      *  itself. To ensure the pipeline stages are executed in reverse pipe
00710      *  order IB is done here and all link_traversals have higher priority and get done before
00711      *  tick. Head/Body and Tail flits go thru the IB stage.*/
00712     for( uint i=0; i<(ports*vcs); i++)
00713         if( input_buffer_state[i].pipe_stage == FULL )
00714         {
00715             input_buffer_state[i].pipe_stage = IB;
00716             //            input_buffer_state[i].flits_in_ib++;
00717             ticking = true;
00718         }
00719 
00738     /* Request VCA */
00739     for( uint i=0; i<(ports*vcs); i++)
00740         if( input_buffer_state[i].pipe_stage == IB )
00741         {
00742             uint ip = input_buffer_state[i].input_port;
00743             uint ic = input_buffer_state[i].input_channel;
00744             uint op = -1;
00745             uint oc = -1;
00746             for ( uint aa=0; aa<input_buffer_state[i].possible_oports.size();aa++)
00747                 for ( uint aa=0; aa<input_buffer_state[i].possible_oports.size();aa++)
00748                     for ( uint ab=0; ab<input_buffer_state[i].possible_ovcs.size();ab++)
00749                     {
00750                         op = input_buffer_state[i].possible_oports[aa];
00751                         oc = input_buffer_state[i].possible_ovcs[ab];
00752                         if( downstream_credits[op][oc] == credits
00753                             && !vca.is_requested(op, oc, ip, ic) && vca.request(op, oc , ip, ic))
00754                         {
00755                             input_buffer_state[i].pipe_stage = VCA_REQUESTED;
00756                             ticking = true;
00757                         }
00758                     }
00759         }
00760 
00761     for( uint i=0; i<(ports*vcs); i++)
00762         if( input_buffer_state[i].pipe_stage == SW_TRAVERSAL )
00763             ticking = true;
00764     /* 
00765      * */
00766 
00767     if(ticking)
00768     {
00769         ticking = true;
00770         IrisEvent* event = new IrisEvent();
00771         event->type = TICK_EVENT;
00772         event->vc = e->vc;
00773         Simulator::Schedule(Simulator::Now()+1, &NetworkComponent::process_event, this, event);
00774     }
00775 
00776     delete e;
00777     return;
00778 
00779 }               /* -----  end of function GenericRouter4Stg::handle_input_arbitration_event  ----- */
00780 
00781 string
00782 GenericRouter4Stg::toString() const
00783 {
00784     stringstream str;
00785     str << "GenericRouter4Stg"
00786         << "\t addr: " << address
00787         << " node_ip: " << node_ip
00788         << "\n Input buffers: " << in_buffers.size() << " ";
00789     if( in_buffers.size() > 0)
00790         str << in_buffers[0].toString();
00791 
00792     str << "\n SWA: " << swa.toString();
00793 
00794     str << "\n decoders: " << decoders.size() << " ";
00795     if( decoders.size() > 0)
00796         str << decoders[0].toString();
00797 
00798     str << "\n Xbar ";
00799     str << xbar.toString();
00800 
00801     return str.str();
00802 }
00803 
00804 void
00805 GenericRouter4Stg::send_credit_back(uint i)
00806 {
00807     //    if( input_buffer_state[i].credits_sent)
00808     //    {
00809     input_buffer_state[i].credits_sent--;
00810     LinkArrivalData* data = new LinkArrivalData();
00811     uint port = input_buffer_state[i].input_port;
00812     data->type = CREDIT_ID;
00813     data->vc = input_buffer_state[i].input_channel;
00814     IrisEvent* event = new IrisEvent();
00815     event->type = LINK_ARRIVAL_EVENT;
00816     event->event_data.push_back(data);
00817     event->src_id = address;
00818     event->vc = data->vc; 
00819     static_cast<GenericLink*>(input_connections[port])->credits_passed++;
00820     if(do_two_stage_router)
00821         Simulator::Schedule(Simulator::Now()+0.75, &NetworkComponent::process_event,
00822                             static_cast<GenericLink*>(input_connections[port])->input_connection, event);
00823     else
00824         Simulator::Schedule(Simulator::Now()+1.75, &NetworkComponent::process_event,
00825                             static_cast<GenericLink*>(input_connections[port])->input_connection, event);
00826 
00827     //    if( input_buffer_state[i].pipe_stage == EMPTY)
00828     //        cout << " Sent cr back to i" << port*vcs+data->vc << " was tail" ;
00829     //    else
00830     //        cout << " Sent cr back to i" << port*vcs+data->vc ;
00831     /* 
00832        }
00833        else
00834        {
00835        _DBG(" Requested to send extra Credit back for inport %d ",
00836        input_buffer_state[i].input_port);
00837        }
00838      * */
00839 }
00840 
00841 #endif   /* ----- #ifndef _genericRouter4Stg_cc_INC  ----- */
00842 

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