1 ------------------------------------------------------------ 2 file name: scalar.cc 3 0001 /**** SimCore since 2002-05-15 by Kenji KISE ****/ 4 0002 /************************************************/ 5 0003 #include 6 0004 #include "scalar.h" 7 0005 8 0006 /** system_config for RealScalar **/ 9 0007 /************************************************/ 10 0008 system_config_s::system_config_s(char **opt){ 11 0009 btb_entry = 512; 12 0010 icache_entry = 512; 13 0011 icache_penalty = 10; 14 0012 dcache_entry = 512; 15 0013 dcache_penalty = 10; 16 0014 } 17 0015 18 0016 /** print usage for SimCore_RealScalar **/ 19 0017 /************************************************/ 20 0018 void usage_rs(){ 21 0019 char UsageMessage[] = "\ 22 0020 Usage: SimCore_RealScalar [-option] command\n\ 23 0021 -d: debug mode\n\ 24 0022 -z: verify mode\n\ 25 0023 -a: print simple evaluation result\n\ 26 0024 -c: print systemcall trace\n\ 27 0025 -t[num][m]: print execution trace\n\ 28 0026 -e[num][m]: end simulation at num code run. \ 29 0027 m means million\n\ 30 0028 -f[num]: set fd_adjust to verify simulation\n\ 31 0029 -v[num]: verbose mode, prints '.'\ 32 0030 by VERBOSE_INTERVAL\n\ 33 0031 -i[file_name]: file_name as STDIN input file\n\ 34 0032 "; 35 0033 printf("\n%s", UsageMessage); exit(0); 36 0034 } 37 0035 38 0036 /************************************************/ 39 0037 void scalar_chip::print_result(){ 40 0038 class evaluation_result *e = ev->e; 41 0039 printf("===\n"); 42 0040 printf("=== BTB entry : %11d\n", 43 0041 ev->sc2->btb_entry); 44 0042 printf("=== Branch_Miss_Penalty : %11d\n", 45 0043 PBRED_MISS_PENALTY); 46 0044 printf("=== Conditional Branch : %11lld\n", 47 0045 ev->e2->c_branch); 48 0046 49 0047 printf("=== Cond Branch HIT : %11lld\n", 50 0048 ev->e2->c_branch_hit); 51 0049 printf("=== Cond Branch MISS : %11lld\n", 52 0050 ev->e2->c_branch_mis); 53 0051 printf("=== Cond Branch HIT Rate : %11.3f\n", 54 0052 (double)ev->e2->c_branch_hit / 55 0053 (double) 56 0054 (ev->e2->c_branch_hit + ev->e2->c_branch_mis)); 57 0055 printf("===\n"); 58 0056 59 0057 printf("=== UnConditional Branch : %11lld\n", 60 0058 ev->e2->unc_branch); 61 0059 printf("===\n"); 62 0060 63 0061 uint_64t icache_hit = 64 0062 ev->e2->icache_access - ev->e2->icache_mis; 65 0063 printf("=== Icache entry : %11d\n", 66 0064 ev->sc2->icache_entry); 67 0065 printf("=== Icache Miss Penalty : %11d\n", 68 0066 ev->sc2->icache_penalty); 69 0067 printf("=== Icache ACCESS : %11lld\n", 70 0068 ev->e2->icache_access); 71 0069 printf("=== Icache HIT : %11lld\n", 72 0070 icache_hit); 73 0071 printf("=== Icache MISS : %11lld\n", 74 0072 ev->e2->icache_mis); 75 0073 printf("=== Icache HIT Rate : %11.3f\n", 76 0074 (double)icache_hit / 77 0075 (double)(ev->e2->icache_access)); 78 0076 printf("===\n"); 79 0077 80 0078 printf("=== Dcache entry : %11d\n", 81 0079 ev->sc2->dcache_entry); 82 0080 printf("=== Dcache Miss Penalty : %11d\n", 83 0081 ev->sc2->dcache_penalty); 84 0082 85 0083 uint_64t dcache_hit = 86 0084 ev->e2->dcache_access - ev->e2->dcache_mis; 87 0085 printf("=== Dcache ACCESS : %11lld\n", 88 0086 ev->e2->dcache_access); 89 0087 printf("=== Dcache HIT : %11lld\n", 90 0088 dcache_hit); 91 0089 printf("=== Dcache MISS : %11lld\n", 92 0090 ev->e2->dcache_mis); 93 0091 printf("=== Dcache HIT Rate : %11.3f\n", 94 0092 (double)(dcache_hit)/ 95 0093 (double)(ev->e2->dcache_access)); 96 0094 printf("===\n"); 97 0095 98 0096 printf("=== Clock Cycles : %11lld\n", 99 0097 ev->e2->clock); 100 0098 printf("=== CPI(cycles per inst.): %11.3f\n", 101 0099 (double)ev->e2->clock/ 102 0100 (double)e->retired_inst); 103 0101 fflush(stdout); 104 0102 } 105 0103 106 0104 #define FLYING_CODE_MASK 0x3ff 107 0105 #define FLYING_CODE_MAX (FLYING_CODE_MASK+1) 108 0106 /************************************************/ 109 0107 InstBuf::InstBuf(Env *ev){ /* Constructor */ 110 0108 buf = new instruction_s*[FLYING_CODE_MAX]; 111 0109 for(int i=0; isc; 128 0126 evaluation_result *e = ev->e; 129 0127 evaluation_result_s *e2 = ev->e2; 130 0128 static int wd_cnt = 0; /* watch dog count */ 131 0129 132 0130 e2->clock++; 133 0131 134 0132 /*** watch dog timer check by 0xff cycles ***/ 135 0133 if((e2->clock&WD_INT)==WD_INT){ 136 0134 if(wd_cnt==0){ 137 0135 printf("\nWatch Dog Timer: retired %lld\n", 138 0136 e->retired_inst); 139 0137 exit(1); 140 0138 } 141 0139 wd_cnt=0; 142 0140 } 143 0141 144 0142 if(sc->trace_flag!=0 && 145 0143 sc->trace_flag<=(e->retired_inst+1)) 146 0144 print_pipeline(); 147 0145 148 0146 instruction_s *pt = stg[5]; 149 0147 /** write back stage has a code to retire **/ 150 0148 if(pt!=Inull){ 151 0149 e->retired_inst++; 152 0150 wd_cnt++; 153 0151 154 0152 if(sc->verify_flag) verify(); 155 0153 if(sc->debug_flag) ev->deb->debugmode(pt); 156 0154 157 0155 if(sc->verbose_interval && 158 0156 (e->retired_inst % 159 0157 sc->verbose_interval)==0){ 160 0158 write(1, ".", 1); 161 0159 } 162 0160 163 0161 if(sc->end_tc && e->retired_inst>=sc->end_tc) 164 0162 ev->sys->running = 0; 165 0163 166 0164 /**** branch instruction_s *****/ 167 0165 if(pt->BR || pt->Op==OP_JSR){ 168 0166 /*** un-conditional branch ***/ 169 0167 if(pt->Op==OP_JSR || 170 0168 pt->CI==_BR__ || pt->CI==_BSR_){ 171 0169 e2->unc_branch++; 172 0170 } 173 0171 /*** conditional branch ***/ 174 0172 else{ 175 0173 e2->c_branch++; 176 0174 if(pt->Ppc==pt->Npc) e2->c_branch_hit++; 177 0175 else e2->c_branch_mis++; 178 0176 } 179 0177 } 180 0178 } 181 0179 } 182 0180 183 0181 /* print pipeline state if -t option is used. */ 184 0182 /************************************************/ 185 0183 void scalar_chip::print_pipeline(){ 186 0184 if(ev->e2->clock==1){ 187 0185 printf(" cycle| IF ID RR "); 188 0186 printf("EX MM WB |la:D:IC:DC:\n"); 189 0187 } 190 0188 printf("%06lld| ", ev->e2->clock); 191 0189 for(int i=0; iCpc&0xffff); 196 0194 } 197 0195 } 198 0196 if(w->code_stall) printf("|%2d:",insn_latency); 199 0197 else printf("|--:"); 200 0198 201 0199 if(w->data_stall) printf("d:"); 202 0200 else printf("-:"); 203 0201 204 0202 if(w->icache_stall) 205 0203 printf("%2d:", w->icache_stall); 206 0204 else printf("--:"); 207 0205 208 0206 if(w->dcache_stall) 209 0207 printf("%2d|", w->dcache_stall); 210 0208 else printf("--|"); 211 0209 212 0210 if(stg[5]->LD) printf("ld"); 213 0211 else if(stg[5]->ST) printf("st"); 214 0212 else if(stg[5]->CM) printf("cm"); 215 0213 else if(stg[5]->BR) printf("br"); 216 0214 else printf(" "); 217 0215 printf("|"); 218 0216 219 0217 if(stg[5]->ir){ 220 0218 printf("%04lld ", ev->e->retired_inst + 1); 221 0219 int id = stg[5]->CI; 222 0220 printf("%02x.%04x", id>>16, id & 0xffff); 223 0221 } 224 0222 printf("\n"); 225 0223 226 0224 if(w->flush_bpr){ 227 0225 printf("Branch_Miss_Prediction %05lld", 228 0226 ev->e2->bpred_miss + 1); 229 0227 printf(" (%04llx -> %04llx)\n\n", 230 0228 stg[3]->Ppc & 0xffff, 231 0229 stg[3]->Npc & 0xffff); 232 0230 } 233 0231 } 234 0232 235 0233 /************************************************/ 236 0234 void scalar_chip::verify(){ 237 0235 simple_chip *c = s_chip; 238 0236 ADDR_TYPE c_cpc = c->ev->as->rr(0); 239 0237 c->step(); 240 0238 241 0239 int error = 0; 242 0240 for(int i=1; i<=64; i++) 243 0241 if(c->ev->as->rr(i)!=ev->as->rr(i)) error=1; 244 0242 if(c_cpc!=stg[5]->Cpc) error=1; 245 0243 246 0244 if(error){ 247 0245 instruction *cp = c->p; 248 0246 instruction_s *sp = stg[5]; 249 0247 250 0248 printf("** Verify Error:% lld code retire\n", 251 0249 ev->e->retired_inst); 252 0250 printf("** simple_chip / real_scalar\n\n"); 253 0251 printf("Cpc:%16llx %16llx\n", 254 0252 c_cpc, stg[5]->Cpc); 255 0253 printf("Npc:%16llx %16llx\n", 256 0254 cp->Npc, sp->Npc); 257 0255 printf("Rav:%16llx %16llx\n", 258 0256 cp->Rav, sp->Rav); 259 0257 printf("Rbv:%16llx %16llx\n", 260 0258 cp->Rbv, sp->Rbv); 261 0259 printf("Rcv:%16llx %16llx\n", 262 0260 cp->Rcv, sp->Rcv); 263 0261 printf("Adr:%16llx %16llx\n", 264 0262 cp->Adr, sp->Adr); 265 0263 266 0264 for(int i=1; i<=32; i++){ 267 0265 print_register_name(i-1); 268 0266 printf("%02d:%016llx %016llx", i-1, 269 0267 c->ev->as->rr(i), ev->as->rr(i)); 270 0268 if(c->ev->as->rr(i)!=ev->as->rr(i)) 271 0269 printf("*"); 272 0270 else 273 0271 printf(" "); 274 0272 printf(" f:%016llx %016llx", 275 0273 c->ev->as->rr(i+32), 276 0274 ev->as->rr(i+32)); 277 0275 if(c->ev->as->rr(i+32)!=ev->as->rr(i+32)) 278 0276 printf("*"); 279 0277 else 280 0278 printf(" "); 281 0279 printf("\n"); 282 0280 } 283 0281 exit(1); 284 0282 } 285 0283 } 286 0284 287 0285 /************************************************/ 288 0286 scalar_chip::scalar_chip(char *prog, char **opt){ 289 0287 ev = new Env_s(); 290 0288 ev->sc = new system_config(prog, opt); 291 0289 ev->e = new evaluation_result(); 292 0290 ev->as = new architecture_state(ev); 293 0291 ev->mem = new memory_system(ev); 294 0292 ev->deb = new debug(ev); 295 0293 ev->sys = new system_manager(ev); 296 0294 297 0295 ev->sc2 = new system_config_s(opt); 298 0296 ev->e2 = new evaluation_result_s(); 299 0297 300 0298 pc_gen = new PCgen(ev); 301 0299 b_pred = new Bpred(ev); 302 0300 icache = new Icache(ev); 303 0301 dcache = new Dcache(ev); 304 0302 inst_buf = new InstBuf(ev); 305 0303 w = new chip_wire(); 306 0304 307 0305 Inull = new instruction_s(ev); 308 0306 Inull->ir = 0; 309 0307 Inull->Slot(); 310 0308 311 0309 stg = new instruction_s*[P_DEPTH]; 312 0310 w->stg= new instruction_s*[P_DEPTH]; 313 0311 for(int i=0; istg[i] = stg[i] = Inull; 315 0313 } 316 0314 s_chip = NULL; 317 0315 318 0316 insn_latency = 1; 319 0317 } 320 0318 321 0319 /************************************************/ 322 0320 scalar_chip::~scalar_chip(){ /** destructor **/ 323 0321 print_evaluation_result(ev); 324 0322 if(!ev->sc->simple_result) print_result(); 325 0323 } 326 0324 327 0325 /************************************************/ 328 0326 void scalar_chip::Init(){ 329 0327 w->pcgen_pc = pc_gen->pc; 330 0328 331 0329 w->stg[0] = Inull; 332 0330 for(int i=1; istg[i]=stg[i-1]; 333 0331 334 0332 instruction_s *p1 = w->stg[5]; 335 0333 w->dc_wir = (p1->ST) ? p1->ir : 0; 336 0334 w->dc_wadr = (p1->ST) ? p1->Adr : 0; 337 0335 w->dc_wdat = (p1->ST) ? p1->Rav : 0; 338 0336 339 0337 instruction_s *p2 = w->stg[4]; 340 0338 w->dc_rir = (p2->LD) ? p2->ir : 0; 341 0339 w->dc_radr = (p2->LD) ? p2->Adr : 0; 342 0340 w->dc_rdat = 0; 343 0341 } 344 0342 345 0343 /** return the instruction_s latency **/ 346 0344 /** value must be modified concerning config. **/ 347 0345 /************************************************/ 348 0346 int scalar_chip::latency(char Op, int CI){ 349 0347 if(Op==OP_INTM) return 4; 350 0348 if(Op==OP_FLTI) return 5; 351 0349 return 1; /* default code latency */ 352 0350 } 353 0351 354 0352 /************************************************/ 355 0353 void scalar_chip::IDecode(){ 356 0354 instruction_s *pt = w->stg[1]; 357 0355 358 0356 pt->Slot(); 359 0357 pt->Issue(); 360 0358 361 0359 pt->Ra =(pt->Ar << 5) | pt->RA; 362 0360 pt->Rb =(pt->Br << 5) | pt->RB; 363 0361 pt->Rc =(pt->WB==31) ? 0xff: 364 0362 (WR(pt->Op)<< 5) | pt->WB; 365 0363 pt->Rm = (!pt->CM) ? 0xf0 : 366 0364 (WR(pt->Op)<< 5) | pt->WB; 367 0365 } 368 0366 369 0367 /************************************************/ 370 0368 void scalar_chip::RegRead(){ 371 0369 w->stg[2]->RegisterRead(); 372 0370 } 373 0371 374 0372 /************************************************/ 375 0373 void scalar_chip::Execute(){ 376 0374 static int busy=0; 377 0375 static int mis; 378 0376 data_t target_pc = 0; 379 0377 380 0378 w->code_stall = 0; 381 0379 w->flush_bpr = 0; 382 0380 w->pcgen_bpr = 0; 383 0381 384 0382 instruction_s *pt = w->stg[3]; 385 0383 if(pt==Inull) return; 386 0384 387 0385 if(!busy){ /** fire new instruction_s **/ 388 0386 insn_latency = latency(pt->Op, pt->CI); 389 0387 pt->Execute(); 390 0388 target_pc = pt->ev->as->pc; 391 0389 mis=(pt->Ppc!=target_pc); 392 0390 393 0391 if(insn_latency==1){ 394 0392 w->flush_bpr = (mis) ? 1 : 0; 395 0393 w->pcgen_bpr = (mis) ? target_pc : 0; 396 0394 busy=0; 397 0395 } 398 0396 else{ 399 0397 busy=1; 400 0398 w->code_stall=1; 401 0399 } 402 0400 } 403 0401 else{ /** executing multi-cycle inst. **/ 404 0402 if(insn_latency>1) insn_latency--; 405 0403 if(insn_latency==1){ 406 0404 w->flush_bpr = (mis) ? 1 : 0; 407 0405 w->pcgen_bpr = (mis) ? target_pc : 0; 408 0406 busy=0; 409 0407 } 410 0408 else{ 411 0409 w->code_stall=1; 412 0410 } 413 0411 } 414 0412 } 415 0413 416 0414 /************************************************/ 417 0415 void scalar_chip::WriteBack(){ 418 0416 instruction_s *p = w->stg[5]; 419 0417 420 0418 int br = (p->Op==OP_JSR || p->BR); 421 0419 w->bpred_wtkn = (br) & 422 0420 (p->Cpc+4 != p->Npc); 423 0421 w->bpred_wpc = (br) ? p->Cpc : 0; 424 0422 w->bpred_wnpc = (br) ? p->Npc : 0; 425 0423 426 0424 /***** Data Cache Flush by PAL*****/ 427 0425 if(p!=Inull && p->Op==OP_PAL) dcache->flush(); 428 0426 429 0427 if(p!=Inull){ 430 0428 ev->as->pc = p->Npc; 431 0429 p->WriteBack(); /** Write Back **/ 432 0430 } 433 0431 434 0432 int pal = (p!=Inull && p->Op==OP_PAL); 435 0433 /* sigreturn updates as->ps */ 436 0434 w->pcgen_pal = (pal) ? ev->as->pc : 0; 437 0435 w->flush_pal = (pal) ? 1 : 0; 438 0436 } 439 0437 440 0438 /************************************************/ 441 0439 void scalar_chip::Step(){ 442 0440 /***** data deps stall calculation *****/ 443 0441 if(w->stg[2]==Inull || w->stg[3]==Inull){ 444 0442 w->data_stall = 0; 445 0443 } 446 0444 else{ 447 0445 instruction_s *pr = w->stg[2]; 448 0446 instruction_s *pw = w->stg[3]; 449 0447 450 0448 /** dependency: RegRead after Load **/ 451 0449 int w1 = pw->LD && pw->WB!=31 && 452 0450 (pr->Ra == pw->Rc || pr->Rb == pw->Rc); 453 0451 454 0452 /** depencency: CMOV after Load **/ 455 0453 int w2 = pr->CM && pw->LD && pw->WB!=31 && 456 0454 pr->Rm == pw->Rc; 457 0455 458 0456 w->data_stall = w1 | w2; 459 0457 } 460 0458 } 461 0459 462 0460 /************************************************/ 463 0461 void scalar_chip::Update1(){ 464 0462 /***** Set fetched code info. *****/ 465 0463 if(!w->icache_stall){ 466 0464 instruction_s *p = inst_buf->alloc(); 467 0465 p->ir = w->ic_out; 468 0466 p->Cpc = w->pcgen_pc; 469 0467 p->Npc = w->pcgen_npc; 470 0468 p->Ppc = (w->bpred_tkn) ? w->bpred_targ : 471 0469 w->pcgen_npc; 472 0470 w->stg[0] = p; 473 0471 } 474 0472 475 0473 /***** Set Rcv from the data cache *****/ 476 0474 if(w->stg[4]->LD) w->stg[4]->Rcv=w->dc_rdat; 477 0475 } 478 0476 479 0477 /************************************************/ 480 0478 void scalar_chip::Update2(){ 481 0479 /**** Data forwarding to Rav & Rbv & Adr ****/ 482 0480 if(w->stg[2]!=Inull){ 483 0481 instruction_s *pr = w->stg[2]; 484 0482 for(int i=5; i>=3; i--){ 485 0483 instruction_s *pw = w->stg[i]; 486 0484 if(pw!=Inull){ 487 0485 if(pr->Ra==pw->Rc) pr->Rav=pw->Rcv; 488 0486 if(pr->Rb==pw->Rc) pr->Rbv=pw->Rcv; 489 0487 if(pr->Rm==pw->Rc) pr->Adr=pw->Rcv; 490 0488 } 491 0489 } 492 0490 } 493 0491 494 0492 } 495 0493 496 0494 /************************************************/ 497 0495 void scalar_chip::Update3(){ 498 0496 int hazard = w->flush_pal | w->dcache_stall | 499 0497 w->flush_bpr | w->code_stall | w->data_stall; 500 0498 if(!hazard){ 501 0499 for(int i=0; istg[i]; 503 0501 } 504 0502 } 505 0503 else { 506 0504 /******** Update Pipeline Registers ********/ 507 0505 int p_null = 0x000000; /* pipe null */ 508 0506 int p_update = 0x111111; /* pipe update */ 509 0507 510 0508 /***** (1) Flush by PAL Code *****/ 511 0509 if(w->flush_pal){ 512 0510 p_null = 0x111110; 513 0511 p_update = 0x111111; 514 0512 } 515 0513 /***** (2) Stall by D-cache Miss *****/ 516 0514 else if(w->dcache_stall){ 517 0515 p_null = 0x000010; 518 0516 p_update = 0x000011; 519 0517 } 520 0518 /***** (3) Flush by Branch Mis-pred *****/ 521 0519 else if(w->flush_bpr){ 522 0520 p_null = 0x111000; 523 0521 p_update = 0x111111; 524 0522 ev->e2->bpred_miss++; /** evaluation **/ 525 0523 } 526 0524 /***** (4) Stall by Code Latency *****/ 527 0525 else if(w->code_stall){ 528 0526 p_null = 0x100100; 529 0527 p_update = 0x000111; 530 0528 } 531 0529 /***** (5) Stall by Data Dependene *****/ 532 0530 else if(w->data_stall){ 533 0531 p_null = 0x101000; 534 0532 p_update = 0x001111; 535 0533 } 536 0534 537 0535 static int msk[P_DEPTH] ={ 538 0536 0x100000, 0x010000, 0x001000, 539 0537 0x000100, 0x000010, 0x000001}; 540 0538 541 0539 for(int i=0; istg[i] = Inull; 543 0541 if(p_update & msk[i]) stg[i] = w->stg[i]; 544 0542 } 545 0543 } 546 0544 } 547 0545 548 0546 /************************************************/ 549 0547 void scalar_chip::main_loop(){ 550 0548 while(ev->sys->running){ 551 0549 /******** (1) Init ********/ 552 0550 Init(); 553 0551 554 0552 /******** (2) Step ********/ 555 0553 Step(); 556 0554 pc_gen->Step(w); /* IF */ 557 0555 b_pred->Step(w); /* IF */ 558 0556 icache->Step(w); /* IF */ 559 0557 dcache->Step(w); /* MM */ 560 0558 IDecode(); /* ID */ 561 0559 RegRead(); /* RR */ 562 0560 Execute(); /* EX */ 563 0561 WriteBack(); /* WB */ 564 0562 565 0563 /******** (3) Update ********/ 566 0564 Update1(); 567 0565 Update2(); 568 0566 Update3(); 569 0567 570 0568 pc_gen->Update(w); 571 0569 b_pred->Update(w); 572 0570 icache->Update(w); 573 0571 dcache->Update(w); 574 0572 575 0573 /******** etc. ********/ 576 0574 house_keeping(); 577 0575 } 578 0576 } 579 0577 580 0578 /************************************************/ 581 0579 int main(int argc, char **argv){ 582 0580 printf("%s/%s %s\n", PROJ, RS_NAME, RS_VER); 583 0581 if(argc==1) usage_rs(); 584 0582 585 0583 char *p = argv[argc-1]; /* program name */ 586 0584 char **opt = argv; /* options */ 587 0585 scalar_chip *c = new scalar_chip(p, opt); 588 0586 589 0587 if(c->ev->sc->verify_flag){ 590 0588 char *op[OPTION_MAX]; 591 0589 option_from_file(op, "verify.txt"); 592 0590 c->s_chip = new simple_chip(p, op); 593 0591 } 594 0592 595 0593 c->main_loop(); 596 0594 597 0595 delete c; 598 0596 return 0; 599 0597 } 600 0598 /************************************************/ 601 ------------------------------------------------------------ 602 file name: fetch.cc 603 0001 /**** SimCore since 2002-05-15 by Kenji KISE ****/ 604 0002 /************************************************/ 605 0003 #include "scalar.h" 606 0004 607 0005 /************************************************/ 608 0006 #define WEAKLY_TAKEN 2 /* Initial Value */ 609 0007 Bpred::Bpred(Env_s *ev){ 610 0008 size = ev->sc2->btb_entry; 611 0009 ent = new class btb_entry[size]; 612 0010 for(int i=0; ipcgen_pc; 625 0023 int index = (pc>>2) % size; 626 0024 btb_entry *e = &ent[index]; 627 0025 int bc = e->predict; 628 0026 w->bpred_tkn = (e->tag==pc && bc>=2) ? 1 : 0; 629 0027 w->bpred_targ = e->target; 630 0028 } 631 0029 632 0030 /************************************************/ 633 0031 void Bpred::Update(chip_wire *w){ 634 0032 if(w->bpred_wpc!=0){ 635 0033 int taken = w->bpred_wtkn; 636 0034 ADDR_TYPE pc = w->bpred_wpc; 637 0035 ADDR_TYPE npc = w->bpred_wnpc; 638 0036 int index = (pc>>2) % size; 639 0037 btb_entry *e = &ent[index]; 640 0038 641 0039 if(e->tag==pc){ 642 0040 if( taken && e->predict<3) e->predict++; 643 0041 if(!taken && e->predict>0) e->predict--; 644 0042 } 645 0043 else{ 646 0044 e->tag = pc; 647 0045 e->predict = WEAKLY_TAKEN; 648 0046 } 649 0047 650 0048 e->target = (taken) ? npc : e->target; 651 0049 } 652 0050 } 653 0051 654 0052 /** PC Generation Unit **/ 655 0053 /************************************************/ 656 0054 PCgen::PCgen(Env_s *e){ /* Constructor */ 657 0055 ev = e; 658 0056 pc= e->as->pc; /* Entry PC */ 659 0057 } 660 0058 661 0059 /************************************************/ 662 0060 void PCgen::Init(chip_wire *w){} 663 0061 664 0062 /************************************************/ 665 0063 void PCgen::Step(chip_wire *w){ 666 0064 w->pcgen_npc = pc+4; 667 0065 } 668 0066 669 0067 /************************************************/ 670 0068 void PCgen::Update(chip_wire *w){ 671 0069 int stall = w->data_stall | w->code_stall | 672 0070 w->icache_stall | w->dcache_stall; 673 0071 674 0072 pc = 675 0073 (w->pcgen_pal) ? w->pcgen_pal : 676 0074 (w->pcgen_bpr) ? w->pcgen_bpr : 677 0075 (stall) ? pc : 678 0076 (w->bpred_tkn) ? w->bpred_targ : 679 0077 w->pcgen_npc; 680 0078 } 681 0079 /************************************************/ 682 ------------------------------------------------------------ 683 file name: cache.cc 684 0001 /**** SimCore since 2002-05-15 by Kenji KISE ****/ 685 0002 /************************************************/ 686 0003 #include "scalar.h" 687 0004 688 0005 /** Data Cache Unit **/ 689 0006 /************************************************/ 690 0007 Dcache::Dcache(Env_s *env){ 691 0008 ev = env; 692 0009 nw = DCLINE_SIZE/DDATA_SIZE; 693 0010 size = ev->sc2->dcache_entry; 694 0011 buf = new dcache_line[size]; 695 0012 696 0013 stall=0; 697 0014 for(int i=0; i>DCLINE_SFT) % size; 723 0040 dcache_line *cl = &buf[index]; 724 0041 ADDR_TYPE tag = buf[index].tag; 725 0042 726 0043 if(cl->valid && cl->dirty){ 727 0044 for(int i=0; id[i]; 730 0047 a = ((tag<mem->st_nbyte(DDATA_SIZE, &a, d); 732 0049 } 733 0050 } 734 0051 } 735 0052 736 0053 /************************************************/ 737 0054 void Dcache::ld_line(ADDR_TYPE adr){ 738 0055 ADDR_TYPE tag = (adr>>DCLINE_SFT); 739 0056 int index = (adr>>DCLINE_SFT) % size; 740 0057 dcache_line *cl = &buf[index]; 741 0058 742 0059 cl->valid = 1; 743 0060 cl->dirty = 0; 744 0061 cl->tag = tag; 745 0062 for(int i=0; id[i]; 748 0065 a = ((tag<mem->ld_nbyte(DDATA_SIZE, &a, d); 750 0067 } 751 0068 } 752 0069 753 0070 /************************************************/ 754 0071 void Dcache::Step(chip_wire *w){ 755 0072 w->dcache_stall = stall; /* default */ 756 0073 757 0074 if(w->dc_radr==0) return; 758 0075 759 0076 /***** Waiting for the data *****/ 760 0077 if(stall){ 761 0078 w->dcache_stall = stall; 762 0079 return; 763 0080 } 764 0081 765 0082 /** Load Instruction **/ 766 0083 ADDR_TYPE adr = w->dc_radr; 767 0084 ADDR_TYPE tag = (adr>>DCLINE_SFT); 768 0085 int index = (adr>>DCLINE_SFT) % size; 769 0086 int offset = (adr>>DDATA_SFT ) % nw; 770 0087 dcache_line *cl = &buf[index]; 771 0088 772 0089 /**** D-Cache Hit ****/ 773 0090 if(cl->valid && cl->tag==tag){ 774 0091 stall = 0; 775 0092 w->dcache_stall = 0; 776 0093 ev->e2->dcache_access++; 777 0094 data_t tmp = cl->d[offset]; 778 0095 779 0096 /*** Store -> Load data forwarding ***/ 780 0097 if((w->dc_radr>>3)== 781 0098 (w->dc_wadr>>3)){ 782 0099 data_t dat; 783 0100 DATA_TYPE mask; 784 0101 int ci = get_code(w->dc_wir); 785 0102 set_st_data(ci, st_bytes(ci), 786 0103 &w->dc_wadr, 787 0104 &w->dc_wdat, &dat, &mask); 788 0105 tmp= ((cl->d[offset] & mask) | dat); 789 0106 } 790 0107 791 0108 { 792 0109 int ci = get_code(w->dc_rir); 793 0110 set_ld_data(ci, ld_bytes(ci), &w->dc_radr, 794 0111 &tmp, &w->dc_rdat); 795 0112 } 796 0113 } 797 0114 /**** D-Cache Miss ****/ 798 0115 else{ 799 0116 stall = ev->sc2->dcache_penalty; 800 0117 mis_adr = adr; 801 0118 w->dcache_stall = stall; 802 0119 st_line(adr); 803 0120 ld_line(adr); 804 0121 ev->e2->dcache_mis++; 805 0122 } 806 0123 } 807 0124 808 0125 /************************************************/ 809 0126 void Dcache::Update(chip_wire *w){ 810 0127 if(stall>0) stall--; 811 0128 812 0129 if(w->dc_wadr==0) return; 813 0130 814 0131 data_t dat; 815 0132 DATA_TYPE mask; 816 0133 int ci = get_code(w->stg[5]->ir); 817 0134 set_st_data(ci, st_bytes(ci), &w->dc_wadr, 818 0135 &w->dc_wdat, &dat, &mask); 819 0136 820 0137 /***** Store to the cache *****/ 821 0138 ADDR_TYPE adr = w->dc_wadr; 822 0139 ADDR_TYPE tag = (adr>>DCLINE_SFT); 823 0140 int index = (adr>>DCLINE_SFT) % size; 824 0141 int offset = (adr>>DDATA_SFT ) % 825 0142 (DCLINE_SIZE/DDATA_SIZE); 826 0143 dcache_line *cl = &buf[index]; 827 0144 828 0145 /**** D-Cache Hit ****/ 829 0146 if(cl->valid && cl->tag==tag){ 830 0147 cl->d[offset] = ((cl->d[offset] 831 0148 & mask) | dat); 832 0149 cl->dirty=1; 833 0150 } 834 0151 /**** D-Cache Miss ****/ 835 0152 else{ /** Store to the memory **/ 836 0153 ev->mem->st_8byte(&w->dc_wadr, &dat, mask); 837 0154 } 838 0155 } 839 0156 840 0157 /** Instruction Cache Unit **/ 841 0158 /************************************************/ 842 0159 Icache::Icache(Env_s *env){ 843 0160 stall = 0; 844 0161 ev = env; 845 0162 nw = ICLINE_SIZE/ICODE_SIZE; 846 0163 size = ev->sc2->icache_entry; 847 0164 buf = new icache_line[size]; 848 0165 for(int i=0; i0) stall--; 860 0177 if(stall==1) ld_line(mis_pc); 861 0178 } 862 0179 863 0180 /************************************************/ 864 0181 void Icache::ld_line(ADDR_TYPE pc){ 865 0182 ADDR_TYPE tag = (pc>>ICLINE_SFT); 866 0183 int index = (pc>>ICLINE_SFT) % size; 867 0184 icache_line *e = &buf[index]; 868 0185 869 0186 e->tag = tag; 870 0187 e->valid = 1; 871 0188 ADDR_TYPE adr = tag << ICLINE_SFT; 872 0189 for(int i=0; imem->ld_inst(&a, &e->d[i]); 876 0193 } 877 0194 } 878 0195 879 0196 /************************************************/ 880 0197 void Icache::Step(chip_wire *w){ 881 0198 ADDR_TYPE pc = w->pcgen_pc; 882 0199 ADDR_TYPE tag = (pc>>ICLINE_SFT); 883 0200 int index = (pc>>ICLINE_SFT) % size; 884 0201 int offset = (pc>>ICODE_SFT) % nw; 885 0202 886 0203 icache_line *e = &buf[index]; 887 0204 888 0205 if(stall){ /** Waiting for the data **/ 889 0206 w->icache_stall = stall; 890 0207 } 891 0208 else{ 892 0209 /**** I-Cache Hit ****/ 893 0210 if(e->valid && e->tag==tag){ 894 0211 stall = 0; 895 0212 w->icache_stall = 0; 896 0213 ev->e2->icache_access++; 897 0214 } 898 0215 /**** I-Cache Miss ****/ 899 0216 else{ 900 0217 stall = ev->sc2->icache_penalty; 901 0218 w->icache_stall = ev->sc2->icache_penalty; 902 0219 mis_pc = pc; 903 0220 ev->e2->icache_mis++; 904 0221 } 905 0222 } 906 0223 w->ic_out = (stall) ? 0 : e->d[offset]; 907 0224 } 908 0225 /************************************************/ 909 ------------------------------------------------------------ 910 file name: scalar.h 911 0001 /*** Yet Another Alpha Processor Simulator ***/ 912 0002 /*** in C++ since 2002-05-15 by Kenji KISE ***/ 913 0003 /************************************************/ 914 0004 #include "SimCore/define.h" 915 0005 916 0006 #define PROJ "SimCore" 917 0007 #define RS_NAME "Alpha RealScalar" 918 0008 #define RS_VER "Version 0.9.30 2003-10-03" 919 0009 920 0010 #define BUF_SIZE 4096 921 0011 #define B_TKN 1 /* Branch Taken */ 922 0012 #define B_UNT 0 /* Branch Untaken */ 923 0013 924 0014 /* pipeline depth */ 925 0015 #define P_DEPTH 6 926 0016 #define PBRED_MISS_PENALTY 2 927 0017 928 0018 /** instruction for RealScalar **/ 929 0019 /************************************************/ 930 0020 class instruction_s : public instruction{ 931 0021 public: 932 0022 char Ra; /* 6b: for dependency check */ 933 0023 char Rb; /* 6b: for dependency check */ 934 0024 char Rm; /* 6b: for dependency check */ 935 0025 char Rc; /* 6b: for dependency check */ 936 0026 data_t Ppc; /* bpred predicted PC */ 937 0027 instruction_s(Env *ev) : instruction(ev) {} 938 0028 }; 939 0029 940 0030 /** system_config for RealScalar **/ 941 0031 /************************************************/ 942 0032 class system_config_s{ 943 0033 public: 944 0034 int btb_entry; 945 0035 int icache_entry; 946 0036 int icache_penalty; 947 0037 int dcache_entry; 948 0038 int dcache_penalty; 949 0039 system_config_s(char**); 950 0040 }; 951 0041 952 0042 /** evaluation_result for RealScalar **/ 953 0043 /************************************************/ 954 0044 class evaluation_result_s{ 955 0045 public: 956 0046 /* retired Conditional branches */ 957 0047 uint_64t c_branch; 958 0048 uint_64t c_branch_hit; 959 0049 uint_64t c_branch_mis; 960 0050 /* retired Unconditional branches */ 961 0051 uint_64t unc_branch; 962 0052 uint_64t bpred_miss; 963 0053 uint_64t icache_access; 964 0054 uint_64t icache_mis; 965 0055 uint_64t dcache_access; 966 0056 uint_64t dcache_mis; 967 0057 uint_64t clock; 968 0058 evaluation_result_s(){ 969 0059 memset(this, 0, 970 0060 sizeof(class evaluation_result_s)); 971 0061 } 972 0062 }; 973 0063 974 0064 /************************************************/ 975 0065 class Env_s : public Env{ 976 0066 public: 977 0067 class system_config_s *sc2; 978 0068 class evaluation_result_s *e2; 979 0069 }; 980 0070 981 0071 /************************************************/ 982 0072 class chip_wire { /***** Wires *****/ 983 0073 public: 984 0074 INST_TYPE ic_out; /* Instruction Cache Out */ 985 0075 986 0076 INST_TYPE dc_wir; /* Data-Cache Write Ir */ 987 0077 data_t dc_wadr; /* Data-Cache Write Adr */ 988 0078 data_t dc_wdat; /* Data-Cache Write Data */ 989 0079 INST_TYPE dc_rir; /* Data-Cache Read Ir */ 990 0080 data_t dc_radr; /* Data-Cache Read Adr */ 991 0081 data_t dc_rdat; /* Data-Cache Read Data */ 992 0082 993 0083 int bpred_tkn; /* prediction taken/not */ 994 0084 data_t bpred_targ; /* prediction target */ 995 0085 int bpred_wtkn; /* taken for update */ 996 0086 data_t bpred_wpc; /* pc for update */ 997 0087 data_t bpred_wnpc; /* npc for update */ 998 0088 999 0089 int icache_stall; /* stall by I-cache miss */ 1000 0090 int dcache_stall; /* stall by D-cache miss */ 1001 0091 int code_stall; /* stall by code latency */ 1002 0092 int data_stall; /* stall by data deps */ 1003 0093 1004 0094 int flush_pal; /* 1b: flush by PAL code */ 1005 0095 int flush_bpr; /* 1b: flush by mis-br */ 1006 0096 1007 0097 data_t pcgen_pc; /* PC in PCgen Unit */ 1008 0098 data_t pcgen_npc; /* next PC in PCgen */ 1009 0099 data_t pcgen_bpr; /* branch miss PC */ 1010 0100 data_t pcgen_pal; /* PC by PAL code */ 1011 0101 1012 0102 instruction_s **stg; /* Pipeline Stage */ 1013 0103 }; 1014 0104 1015 0105 /************************************************/ 1016 0106 class btb_entry { /*** BTB Entry ***/ 1017 0107 public: 1018 0108 ADDR_TYPE tag; 1019 0109 ADDR_TYPE target; 1020 0110 int predict; 1021 0111 }; 1022 0112 /************************************************/ 1023 0113 class Bpred{ /*** Branch Target Buffer ***/ 1024 0114 int size; /* entry size */ 1025 0115 btb_entry *ent; /* table */ 1026 0116 public: 1027 0117 Bpred(Env_s*); /* Constructor */ 1028 0118 void Init(chip_wire*); /* Reserved */ 1029 0119 void Step(chip_wire*); /* Reserved */ 1030 0120 void Update(chip_wire*); /* Reserved */ 1031 0121 }; 1032 0122 1033 0123 /************************************************/ 1034 0124 #define ICLINE_SIZE 64 /* size in byte */ 1035 0125 #define ICODE_SIZE 4 /* code size in byte */ 1036 0126 #define ICLINE_SFT 6 /* 2^x = ICLINE_SIZE */ 1037 0127 #define ICODE_SFT 2 /* 2^x = ICODE_SIZE */ 1038 0128 /************************************************/ 1039 0129 class icache_line { 1040 0130 public: 1041 0131 int valid; 1042 0132 ADDR_TYPE tag; 1043 0133 INST_TYPE d[ICLINE_SIZE/ICODE_SIZE]; /* =16 */ 1044 0134 }; 1045 0135 1046 0136 /************************************************/ 1047 0137 class Icache { 1048 0138 Env_s *ev; 1049 0139 int size; /* the number of cache lines */ 1050 0140 int nw; /* the number of word in line */ 1051 0141 icache_line *buf; 1052 0142 int stall; /* cache status */ 1053 0143 ADDR_TYPE mis_pc; /* PC of the cache Miss */ 1054 0144 public: 1055 0145 Icache(Env_s*); 1056 0146 void ld_line(ADDR_TYPE); 1057 0147 void Init(chip_wire*); /* Reserved */ 1058 0148 void Step(chip_wire*); /* Reserved */ 1059 0149 void Update(chip_wire*); /* Reserved */ 1060 0150 }; 1061 0151 1062 0152 /************************************************/ 1063 0153 #define DCLINE_SIZE 64 /* size in byte, 8 word */ 1064 0154 #define DDATA_SIZE 8 /* data size in byte */ 1065 0155 #define DCLINE_SFT 6 /* 2^x = DCLINE_SIZE */ 1066 0156 #define DDATA_SFT 3 /* 2^x = DDATA_SIZE */ 1067 0157 /************************************************/ 1068 0158 class dcache_line { 1069 0159 public: 1070 0160 int valid; 1071 0161 int dirty; 1072 0162 ADDR_TYPE tag; 1073 0163 data_t d[DCLINE_SIZE/DDATA_SIZE]; 1074 0164 }; 1075 0165 /************************************************/ 1076 0166 class Dcache { 1077 0167 Env_s *ev; 1078 0168 int size; /* the number of cache lines */ 1079 0169 int nw; /* the number of word in line */ 1080 0170 dcache_line *buf; 1081 0171 int stall; /* cache status */ 1082 0172 ADDR_TYPE mis_adr; /* Adr of the cache Miss */ 1083 0173 public: 1084 0174 Dcache(Env_s*); 1085 0175 void ld_line(ADDR_TYPE); 1086 0176 void st_line(ADDR_TYPE); 1087 0177 void flush(); 1088 0178 void Init(chip_wire*); /* Reserved */ 1089 0179 void Step(chip_wire*); /* Reserved */ 1090 0180 void Update(chip_wire*); /* Reserved */ 1091 0181 }; 1092 0182 1093 0183 /************************************************/ 1094 0184 class PCgen{ 1095 0185 Env_s *ev; 1096 0186 public: 1097 0187 data_t pc; /* Program Counter */ 1098 0188 PCgen(Env_s*); /* Constructor */ 1099 0189 void Init(chip_wire*); /* Reserved */ 1100 0190 void Step(chip_wire*); /* Reserved */ 1101 0191 void Update(chip_wire*); /* Reserved */ 1102 0192 }; 1103 0193 1104 0194 /************************************************/ 1105 0195 class InstBuf{ /*** Instruction_S Buffer ***/ 1106 0196 instruction_s **buf; 1107 0197 public: 1108 0198 InstBuf(Env*); /* Constructor */ 1109 0199 instruction_s *alloc(); /* code allocatior */ 1110 0200 }; 1111 0201 1112 0202 /************************************************/ 1113 0203 class scalar_chip{ 1114 0204 void IDecode(); /* Pipeline stg1 */ 1115 0205 void RegRead(); /* Pipeline stg2 */ 1116 0206 void Execute(); /* Pipeline stg3 */ 1117 0207 void WriteBack(); /* Pipeline stg5 */ 1118 0208 void Init(); /* Reserved */ 1119 0209 void Step(); /* Reserved */ 1120 0210 void Update1(); /* Reserved */ 1121 0211 void Update2(); /* Reserved */ 1122 0212 void Update3(); /* Reserved */ 1123 0213 PCgen *pc_gen; /* PC Generation U */ 1124 0214 Bpred *b_pred; /* Branch Prediction U */ 1125 0215 Icache *icache; /* Instruction Cache U */ 1126 0216 Dcache *dcache; /* Data Cache U */ 1127 0217 chip_wire *w; /* set of wires */ 1128 0218 InstBuf *inst_buf; /* Instruction Buffer */ 1129 0219 instruction_s *Inull; /* NULL instruction */ 1130 0220 int insn_latency; /* Instruction latency */ 1131 0221 public: 1132 0222 Env_s *ev; /* Environment */ 1133 0223 simple_chip *s_chip; /* Simple Chip */ 1134 0224 instruction_s **stg; /* Pipeline Stage */ 1135 0225 scalar_chip(char*, char**); /* constructor */ 1136 0226 ~scalar_chip(); /* destructor */ 1137 0227 int latency(char, int); 1138 0228 void print_pipeline(); 1139 0229 void house_keeping(); 1140 0230 void verify(); 1141 0231 void main_loop(); 1142 0232 void print_result(); /* print evaluation res */ 1143 0233 }; 1144 0234 /************************************************/