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 ----- */