genericVcAllocator.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef _genericvcallocator_cc_INC
00020 #define _genericvcallocator_cc_INC
00021
00022 #include "genericVcAllocator.h"
00023 using namespace std;
00024
00025 GenericVcAllocator::GenericVcAllocator()
00026 {
00027 name = "genericVcAllocator";
00028 }
00029
00030 GenericVcAllocator::~GenericVcAllocator()
00031 {
00032
00033 }
00034
00035 void
00036 GenericVcAllocator::setup( uint p, uint v )
00037 {
00038 ports = p;
00039 vcs = v;
00040 current_winners.resize(ports*vcs);
00041 done.resize(ports*vcs);
00042 locked.resize(ports*vcs);
00043 last_winner.resize(ports*vcs);
00044
00045 requested.resize(ports*vcs);
00046 requestor_inport.resize(ports*vcs);
00047 last_inport_winner.resize(ports*vcs);
00048
00049 for ( uint i=0; i<(vcs*ports); i++ )
00050 {
00051 requested[i].resize( ports );
00052 requestor_inport[i].resize(ports);
00053 last_inport_winner[i].resize(ports);
00054
00055 done[i] = false;
00056 locked[i] = false;
00057 last_winner[i] = 0;
00058 current_winners[i] = -1;
00059 }
00060
00061 for ( uint i=0; i<(ports*vcs); i++ )
00062 for ( uint j=0; j<ports; j++ )
00063 {
00064 requested[i][j] = false;
00065 last_inport_winner[i][j] = 0;
00066 requestor_inport[i][j].resize(vcs);
00067 }
00068
00069 for ( uint i=0; i<(ports*vcs); i++ )
00070 for ( uint j=0; j<ports; j++ )
00071 for ( uint k=0; k<vcs; k++)
00072 requestor_inport[i][j][k] = false;
00073 }
00074
00075 bool
00076 GenericVcAllocator::request( uint op , uint ovc, uint inp, uint invc )
00077 {
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 if( !locked[op*vcs+ovc] )
00104 {
00105 requestor_inport[op*vcs+ovc][inp][invc] = true;
00106 return true;
00107 }
00108 else
00109 return false;
00110
00111
00112 }
00113
00114 bool
00115 GenericVcAllocator::is_empty()
00116 {
00117 for ( uint i=0; i<(ports*vcs); i++ )
00118 for ( uint j=0; j<ports; j++)
00119 for ( uint k=0; k<vcs; k++)
00120 if ( requestor_inport[i][j][k] )
00121 return false;
00122
00123 return true;
00124 }
00125
00126 bool
00127 GenericVcAllocator::is_empty(uint i)
00128 {
00129 for ( uint j=0; j<ports; j++)
00130 for ( uint k=0; k<vcs; k++)
00131 if ( requestor_inport[i][j][k] )
00132 return false;
00133
00134 return true;
00135 }
00136
00137 void
00138 GenericVcAllocator::pick_winner()
00139 {
00140 if( !is_empty())
00141 {
00142 set_request_matrix();
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 do_round_robin_arbitration();
00168
00169
00170
00171
00172
00173
00174
00175
00176 }
00177 return;
00178 }
00179
00180 void
00181 GenericVcAllocator::set_request_matrix()
00182 {
00183 for ( uint i=0; i<(ports*vcs); i++ )
00184 {
00185 if( !locked[i])
00186 {
00187 for ( uint j=0; j<ports; j++)
00188 {
00189 requested[i][j] = false;
00190 for ( uint k=last_inport_winner[i][j]+1; k<vcs; k++)
00191 if ( requestor_inport[i][j][k])
00192 {
00193 requested[i][j] = true;
00194 last_inport_winner[i][j] = k;
00195 break;
00196 }
00197
00198 if( !requested[i][j])
00199 {
00200 for ( uint k=0 ; k<=last_inport_winner[i][j]; k++)
00201 {
00202 if ( requestor_inport[i][j][k])
00203 {
00204 requested[i][j] = true;
00205 last_inport_winner[i][j] = k;
00206 break;
00207 }
00208 }
00209 }
00210 }
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 }
00223
00224 return;
00225
00226 }
00227
00228 void
00229 GenericVcAllocator::do_round_robin_arbitration()
00230 {
00231 for ( uint aa=0; aa<(ports*vcs); aa++)
00232 {
00233 if ( !done[aa] )
00234 {
00235 if (!locked[aa])
00236 {
00237 current_winners[aa] = -1;
00238
00239 bool found_winner = false;
00240 for ( uint i=last_winner[aa]+1; i <ports; i++ )
00241 if ( requested[aa][i] )
00242 {
00243 found_winner = true;
00244 last_winner[aa] = i;
00245 current_winners[aa] = i*vcs+last_inport_winner[aa][i];
00246 done[aa] = true;
00247 locked[aa] = true;
00248 break;
00249 }
00250
00251 if ( !found_winner )
00252 for ( uint i=0; i<=last_winner[aa]; i++ )
00253 {
00254 if( requested [aa][i] )
00255 {
00256 found_winner = true;
00257 last_winner[aa] = i;
00258 current_winners[aa] = i*vcs+last_inport_winner[aa][i];
00259 done[aa] = true;
00260 locked[aa] = true;
00261 break;
00262 }
00263 }
00264 #ifdef _DEBUG
00265 if (!found_winner )
00266 cout << " VCA: no winner for this port " << (int)aa/vcs<< " vc: " << aa%vcs<< endl;
00267 #endif
00268 }
00269 }
00270 }
00271
00272 return ;
00273
00274 }
00275
00276 void
00277 GenericVcAllocator::clear_winner(uint op, uint ovc, uint ip, uint ivc)
00278 {
00279 if( current_winners[op*vcs+ovc] != ip*vcs+ivc )
00280 {
00281 _DBG("Error Clear incorrect winner! winner is %d requesting %d",
00282 current_winners[op*vcs+ovc], ip*vcs+ivc );
00283 exit(1);
00284 }
00285
00286 requested[op*vcs+ovc][ip] = false;
00287 requestor_inport[op*vcs+ovc][ip][ivc] = false;
00288 done[op*vcs+ovc] = false;
00289 locked[op*vcs+ovc] = false;
00290 current_winners[op*vcs+ovc] = -1;
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 }
00316
00317 bool
00318 GenericVcAllocator::is_requested( uint op, uint ovc, uint ip, uint ivc )
00319 {
00320 return requestor_inport[op*vcs+ovc][ip][ivc];
00321 }
00322
00323 void
00324 GenericVcAllocator::squash_requests( uint op, uint ovc, uint ip, uint ivc)
00325 {
00326 for ( uint i=0; i<current_winners.size(); i++)
00327 if (current_winners[i] == (ip*vcs+ivc) && i!=op*vcs+ovc)
00328 {
00329
00330
00331 requestor_inport[i][ip][ivc] = false;
00332 requested[i][ip] = false;
00333 done[i] = false;
00334 locked[i] = false;
00335 current_winners[i] = -1;
00336 }
00337
00338 bool is_there_winner = false;
00339 for ( uint i=op*vcs; i<(op*vcs+vcs); i++)
00340 if( current_winners[i] == ip*vcs+ivc )
00341 is_there_winner = true;
00342 if(is_there_winner)
00343 for ( uint i=op*vcs; i<(op*vcs+vcs); i++)
00344 if( current_winners[i] != ip*vcs+ivc )
00345 requestor_inport[i][ip][ivc] = false;
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 }
00371 #endif
00372