ptop_swa.cc

Go to the documentation of this file.
00001 /*
00002  * =====================================================================================
00003  *
00004  *       Filename:  myFullyVirtualArbiter.cc
00005  *
00006  *    Description:  
00007  *
00008  *        Version:  1.0
00009  *        Created:  04/27/2010 12:58:11 AM
00010  *       Revision:  none
00011  *       Compiler:  gcc
00012  *
00013  *         Author:  Mitchelle Rasquinha (), mitchelle.rasquinha@gatech.edu
00014  *        Company:  Georgia Institute of Technology
00015  *
00016  * =====================================================================================
00017  */
00018 
00019 #ifndef  _ptopswitcharbiter_cc_INC
00020 #define  _ptopswitcharbiter_cc_INC
00021 
00022 #include        "ptop_swa.h"
00023 
00024 PToPSwitchArbiter::PToPSwitchArbiter()
00025 {
00026     name = "swa";
00027 }
00028 
00029 PToPSwitchArbiter::~PToPSwitchArbiter()
00030 {
00031 }
00032 
00033 void
00034 PToPSwitchArbiter::resize(uint port)
00035 {
00036     PORTS = port;
00037     requested.resize(PORTS);
00038     priority_reqs.resize(PORTS);
00039     locked.resize(PORTS);
00040     done.resize(PORTS);
00041     last_port_winner.resize(PORTS);
00042     requesting_inputs.resize(PORTS);
00043     last_winner.resize(PORTS);
00044     port_locked.resize(PORTS);
00045 
00046     for ( uint i=0; i<PORTS; i++)
00047     {
00048         requested[i].resize(PORTS);
00049         priority_reqs[i].resize(PORTS);
00050         requesting_inputs[i].resize(PORTS);
00051     }
00052 
00053     for ( uint i=0; i<PORTS; i++)
00054         for ( uint j=0; j<PORTS; j++)
00055         {
00056             requested[i][j]=false;
00057             priority_reqs[i][j]=false;
00058         }
00059 
00060     for ( uint i=0; i<PORTS; i++)
00061         {
00062             locked[i] = false;
00063             done[i] = false;
00064             last_port_winner[i] = 0;
00065         }
00066 
00067 }
00068 
00069 bool
00070 PToPSwitchArbiter::is_requested( uint oport, uint inport )
00071 {
00072     return requested[oport][inport];
00073 }
00074 
00075 void
00076 PToPSwitchArbiter::request(uint oport, uint inport )
00077 {
00078     requested[oport][inport] = true;
00079     done[oport] = false;
00080     requesting_inputs[oport][inport].port = inport;
00081     requesting_inputs[oport][inport].in_time = (ullint)Simulator::Now();
00082     return;
00083 }
00084 
00085 void
00086 PToPSwitchArbiter::request(uint oport, uint inport, message_class m )
00087 {
00088     requested[oport][inport] = true;
00089     done[oport] = false;
00090     requesting_inputs[oport][inport].port = inport;
00091     requesting_inputs[oport][inport].in_time = (ullint)Simulator::Now();
00092     if( m == priority_msg_type)
00093         priority_reqs[oport][inport] = true;
00094     else
00095         priority_reqs[oport][inport] = false;
00096     return;
00097 }
00098 
00099 SA_unit
00100 PToPSwitchArbiter::pick_winner( uint oport)
00101 {
00102     switch ( sw_arbitration )
00103     {
00104         case ROUND_ROBIN:
00105             return do_round_robin_arbitration(oport);
00106             break;
00107         case ROUND_ROBIN_PRIORITY:
00108             return do_priority_round_robin_arbitration(oport);
00109             break;
00110         case FCFS:
00111             return do_fcfs_arbitration(oport);
00112             break;
00113         default:
00114             cout << " ERROR: Invalid switch arbitration" << endl;
00115             break;
00116     }
00117 
00118 }
00119 
00120 SA_unit
00121 PToPSwitchArbiter::do_round_robin_arbitration( uint oport)
00122 {
00123     if(!done[oport]) 
00124     {
00125         done[oport] = true;
00126         if(locked[oport] ) 
00127             return last_winner[oport];
00128 /* 
00129         else if ( requested[oport][0])
00130         {
00131             last_port_winner[oport] = 0;
00132             last_winner[oport].port = requesting_inputs[oport][0].port;
00133         }
00134 */
00135         else
00136         {
00137             locked[oport]= true;
00138 
00139                 /* Now look at contesting input ports on this channel and pick
00140                  * a winner*/
00141                 bool winner_found = false;
00142                 for( uint i=last_port_winner[oport]+1; i<(PORTS); i++)
00143                 {
00144                     if(requested[oport][i])
00145                     {
00146                         last_port_winner[oport] = i;
00147                         winner_found = true;
00148                         last_winner[oport].port = requesting_inputs[oport][i].port;
00149                         return last_winner[oport];
00150                     }
00151                 }
00152 
00153                 if(!winner_found)
00154                 for( uint i=0; i<=last_port_winner[oport]; i++)
00155                 {
00156                     if(requested[oport][i])
00157                     {
00158                         last_port_winner[oport] = i;
00159                         winner_found = true;
00160                         last_winner[oport].port = requesting_inputs[oport][i].port;
00161                         return last_winner[oport];
00162                     }
00163                 }
00164                 if(!winner_found)
00165                 {
00166                     _DBG_NOARG("ERROR: RR Cant find port winner" );
00167                     exit(1);
00168                 }
00169 
00170             }
00171     }
00172 
00173     return last_winner[oport];
00174 }
00175 
00176 SA_unit
00177 PToPSwitchArbiter::do_priority_round_robin_arbitration( uint oport)
00178 {
00179     if(!done[oport]) 
00180     {
00181         done[oport] = true;
00182         if(locked[oport] ) 
00183             return last_winner[oport];
00184 
00185         else
00186         {
00187             locked[oport]= true;
00188 
00189             /* Use priority vector to modify requested vector */
00190             for ( uint i=0; i<PORTS; i++)
00191             {
00192                 bool set_priority = false;
00193                 for ( uint j=0; j<PORTS; j++)
00194                     if ( priority_reqs[i][j])
00195                     {
00196                         set_priority = true;
00197                         break;
00198                     }
00199                         
00200                 if ( set_priority )
00201                     for ( uint j=0; j<PORTS; j++)
00202                     {
00203                         requested[i][j] = priority_reqs[i][j];
00204                     }
00205             }
00206 
00207                 /* Now look at contesting input ports on this channel and pick
00208                  * a winner*/
00209                 bool winner_found = false;
00210                 for( uint i=last_port_winner[oport]+1; i<(PORTS); i++)
00211                 {
00212                     if(requested[oport][i])
00213                     {
00214                         last_port_winner[oport] = i;
00215                         winner_found = true;
00216                         last_winner[oport].port = requesting_inputs[oport][i].port;
00217                         return last_winner[oport];
00218                     }
00219                 }
00220 
00221                 if(!winner_found)
00222                 for( uint i=0; i<=last_port_winner[oport]; i++)
00223                 {
00224                     if(requested[oport][i])
00225                     {
00226                         last_port_winner[oport] = i;
00227                         winner_found = true;
00228                         last_winner[oport].port = requesting_inputs[oport][i].port;
00229                         return last_winner[oport];
00230                     }
00231                 }
00232                 if(!winner_found)
00233                 {
00234                     _DBG_NOARG("ERROR: RR Cant find port winner" );
00235                     exit(1);
00236                 }
00237 
00238             }
00239     }
00240 
00241     return last_winner[oport];
00242 }
00243 
00244 SA_unit
00245 PToPSwitchArbiter::do_fcfs_arbitration( uint oport)
00246 {
00247     if(!done[oport]) 
00248     {
00249         done[oport] = true;
00250         if(locked[oport] ) 
00251             return last_winner[oport];
00252 
00253         else
00254         {
00255             locked[oport]= true;
00256 
00257             /* Now look at contesting input ports on this channel and pick
00258             * a winner*/
00259             uint max_time_waiting = 0;
00260             uint winner_inport = -1;
00261             for( uint i=0; i<PORTS; i++)
00262             {
00263                 if(requested[oport][i])
00264                 {
00265                     if( (Simulator::Now() - requesting_inputs[oport][i].in_time) > max_time_waiting )
00266                     {
00267                         max_time_waiting = (ullint)Simulator::Now() - requesting_inputs[oport][i].in_time;
00268                         winner_inport = i;
00269                     }
00270                 }
00271             }
00272             
00273                 if(winner_inport == -1)
00274                 {
00275                     _DBG_NOARG("ERROR: FCFS Cant find port winner" );
00276                     exit(1);
00277                 }
00278 
00279             last_winner[oport].port = requesting_inputs[oport][winner_inport].port;
00280             return last_winner[oport];
00281         }
00282     }
00283 
00284     return last_winner[oport];
00285 }
00286 
00287 
00288 void
00289 PToPSwitchArbiter::clear_winner( uint oport, uint inport)
00290 {
00291     done[oport]= false;
00292     locked[oport] = false;
00293 
00294     requested[oport][inport] = false;
00295     priority_reqs[oport][inport] = false;
00296     return;
00297 }
00298 
00299 void
00300 PToPSwitchArbiter::clear_requested( uint oport, uint inport)
00301 {
00302     requested[oport][inport] = false;
00303     priority_reqs[oport][inport] = false;
00304     return;
00305 }
00306 
00307 bool
00308 PToPSwitchArbiter::is_empty()
00309 {
00310 
00311     for( uint i=0; i<PORTS; i++)
00312         for( uint j=0; j<PORTS; j++)
00313             if(requested[i][j] )
00314                 return false;
00315 
00316     return true;
00317     
00318 }
00319 
00320 string
00321 PToPSwitchArbiter::toString() const
00322 {
00323     stringstream str;
00324     str << "PToPSwitchArbiter: matrix size "
00325         << "\t requested_qu row_size: " << requested.size();
00326     if( requested.size())
00327        str << " col_size: " << requested[0].size()
00328         ;
00329     return str.str();
00330 }
00331 #endif   /* ----- #ifndef _ptopswitcharbiter_cc_INC  ----- */

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