00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <assert.h>
00023
00024 #include "cache.h"
00025
00026
00027
00028
00029
00030 int Cache::simulate(char rw,unsigned int address,unsigned int global_time)
00031 {
00032 unsigned int this_tag=address>>(_c-_s);
00033 unsigned int this_index=(address>>_b)&((1<<(_c-_b-_s))-1);
00034
00035 unsigned int location=this_index*_blocks_in_set;
00036 int miss_or_hit;
00037 unsigned int old_time;
00038 int miss_or_hit_last_time;
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 if(rw=='r')
00051
00052 {
00053 _reads++;
00054
00055 miss_or_hit=0;
00056
00057 int index;
00058 for(int i=0;i<_blocks_in_set;i++)
00059 {
00060 index=location+i;
00061 if(_valid_array[index]=='v' && _tag_array[index]==this_tag)
00062 {
00063 miss_or_hit=1;
00064 break;
00065 }
00066 }
00067
00068
00069
00070 if(miss_or_hit==1)
00071
00072 {
00073
00074
00075
00076
00077
00078
00079
00080
00081
00083 old_time=_time_array[index];
00084 miss_or_hit_last_time=_miss_or_hit_array[index];
00085 _miss_or_hit_array[index]=1;
00087
00088 _time_array[index]=global_time;
00089 }
00090
00091 else
00092
00093 {
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 _reads_in_miss++;
00104
00105
00106 int i;
00107 int target;
00108 for(i=0;i<_blocks_in_set;i++)
00109 {
00110 int index=location+i;
00111 if(_valid_array[index]=='i')
00112 {
00114 _miss_or_hit_array[index]=0;
00116
00117 _valid_array[index]='v';
00118 _dirty_array[index]='c';
00119 _tag_array[index]=this_tag;
00120 _time_array[index]=global_time;
00121 target=i;
00122 break;
00123 }
00124 }
00125
00126 if(i==_blocks_in_set)
00127 {
00128 target=0;
00129 for(int j=1;j<_blocks_in_set;j++)
00130 {
00131 if(_time_array[location+target]>_time_array[location+j])
00132 {
00133 target=j;
00134 }
00135 }
00136
00137
00138 int index=location+target;
00139 if(_dirty_array[index]=='d')
00140 {
00141 _writebacks++;
00142 }
00143
00145 _miss_or_hit_array[index]=0;
00147
00148 _valid_array[index]='v';
00149 _dirty_array[index]='c';
00150 _tag_array[index]=this_tag;
00151 _time_array[index]=global_time;
00152 }
00153 }
00154
00155 }
00156
00157 else if(rw=='w')
00158
00159 {
00160 _writes++;
00161
00162 miss_or_hit=0;
00163
00164 int index;
00165 for(int i=0;i<_blocks_in_set;i++)
00166 {
00167 index=location+i;
00168 if(_valid_array[index]=='v' && _tag_array[index]==this_tag)
00169 {
00170 miss_or_hit=1;
00171 break;
00172 }
00173 }
00174
00175
00176 if(miss_or_hit==1)
00177
00178 {
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 if(_wp==0)
00189 {
00190 _dirty_array[index]='d';
00191 }
00192 else if(_wp==1)
00193 {
00194 _dirty_array[index]='c';
00195 _writebacks++;
00196 }
00197
00198 _tag_array[index]=this_tag;
00199
00201 old_time=_time_array[index];
00202 miss_or_hit_last_time=_miss_or_hit_array[index];
00203 _miss_or_hit_array[index]=1;
00205
00206 _time_array[index]=global_time;
00207 }
00208
00209 else
00210
00211 {
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 if(_wp==1)
00222 {
00223 _writebacks++;
00224 }
00225 else if(_wp==0)
00226 {
00227 _writes_in_miss++;
00228
00229
00230 int i;
00231 int target;
00232 for(i=0;i<_blocks_in_set;i++)
00233 {
00234 int index=location+i;
00235 if(_valid_array[index]=='i')
00236 {
00238 _miss_or_hit_array[index]=0;
00240
00241 _valid_array[index]='v';
00242 _tag_array[index]=this_tag;
00243 _dirty_array[index]='d';
00244 _time_array[index]=global_time;
00245 target=i;
00246 break;
00247 }
00248 }
00249
00250 if(i==_blocks_in_set)
00251 {
00252 target=0;
00253 for(int j=1;j<_blocks_in_set;j++)
00254 {
00255 if(_time_array[location+target]>_time_array[location+j])
00256 {
00257 target=j;
00258 }
00259 }
00260
00261
00262 int index=location+target;
00263 if(_dirty_array[index]=='d')
00264 {
00265 _writebacks++;
00266 }
00267
00269 _miss_or_hit_array[index]=0;
00271
00272 _valid_array[index]='v';
00273 _dirty_array[index]='d';
00274 _tag_array[index]=this_tag;
00275 _time_array[index]=global_time;
00276 }
00277 }
00278 }
00279
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 if(miss_or_hit==1 && old_time==global_time)
00296 {
00297 return miss_or_hit_last_time;
00298 }
00299 else
00300 {
00301 return miss_or_hit;
00302 }
00303 }
00304
00305 void Cache::print_this_index(int this_index,int location)
00306 {
00307 fprintf(stderr," set %5d:",this_index);
00308
00309 for(int i=0;i<_blocks_in_set;i++)
00310 {
00311 int index=location+i;
00312 if(_valid_array[index]=='v')
00313 {
00314 fprintf(stderr," %8x",_tag_array[index]);
00315 if(_dirty_array[index]=='d')
00316 {
00317 fprintf(stderr," D");
00318 }
00319 else
00320 {
00321 fprintf(stderr," ");
00322 }
00323
00324 fprintf(stderr," (%d)",i);
00325 }
00326 }
00327
00328 fprintf(stderr,"\n");
00329 }
00330
00331 void Cache::report(FILE *f)
00332 {
00333 fprintf(f,"\treads:\t\t%d\n",_reads);
00334 fprintf(f,"\tread misses:\t%d\n",_reads_in_miss);
00335 fprintf(f,"\twrites:\t\t%d\n",_writes);
00336 fprintf(f,"\twrite misses:\t%d\n",_writes_in_miss);
00337 fprintf(f,"\twritebacks from L1:\t%d\n",_writebacks);
00338 double miss=(double)(_reads_in_miss+_writes_in_miss)/(_reads+_writes);
00339 fprintf(f,"\tL1 miss rate:\t%.4f\n",miss);
00340 }
00341
00342 void Cache::show_cache(FILE *f)
00343 {
00344 fprintf(f,"\tSIZE:\t\t\t%d bytes (%.1f KB)\n",_bytes_in_cache,(double)_bytes_in_cache/1024);
00345 fprintf(f,"\tASSOC:\t\t\t%d\n",_blocks_in_set);
00346 fprintf(f,"\tBLOCKSIZE:\t\t%d bytes\n",_bytes_in_block);
00347 if(_wp==0)
00348 {
00349 fprintf(f,"\tWrite Policy:\t\tWBWA\n");
00350 }
00351 else if(_wp==1)
00352 {
00353 fprintf(f,"\tWrite Policy:\t\tWTNA\n");
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 }
00372
00373 void Banked_Cache::show_cache(FILE *f)
00374 {
00375 fprintf(f,"bank0\n");
00376 _bank0->show_cache(f);
00377 fprintf(f,"bank1\n");
00378 _bank1->show_cache(f);
00379 }
00380
00381 void Banked_Cache::report(FILE *f)
00382 {
00383 fprintf(f,"bank0\n");
00384 _bank0->report(f);
00385 fprintf(f,"bank1\n");
00386 _bank1->report(f);
00387
00388
00389 fprintf(f, "Overall: \n");
00390 fprintf(f, "cache accesses: %d, cache misses: %d \n", t_cache_access,
00391 t_cache_misses);
00392 fprintf(f, "access both banks: %d \n", t_cache_access_both_banks);
00393 fprintf(f, "miss rate: %f, miss penalties: %d\n", t_cache_misses * 1.0 /
00394 t_cache_access, t_cache_misses * 12);
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 int Banked_Cache::total_num_of_miss()
00408 {
00409 int bank0_miss=_bank0->total_num_of_miss();
00410 int bank1_miss=_bank1->total_num_of_miss();
00411
00412 return bank0_miss+bank1_miss;
00413 }