自作RISC-V CPUの検証をするため、メモリアクセスをSpikeで検証することを考える。 L1Dのアップデートのタイミングで、現状のメモリの状態を確認することを考えてみよう。
いくつかのチェックポイントがあるはずだ。
- L1Dからデータを外部に吐き出すタイミング
- L1Dにデータをロードするタイミング
- ストア命令がL1Dをアップデートするタイミング
残りの2つの対応を考えよう。L1Dにデータをロードするタイミングと、ストア命令がL1Dをアップデートするタイミングでは、いくつかの注意が必要となる。
ストア命令がL1Dをアップデートするときは、バイトイネーブルに注意して必要なところのみを比較する。
bool diff_found = false; fprintf(compare_log_fp, "%lld : STQ ISS Check : %llx : ", rtl_time, paddr); try { for (int i = size/8-1; i >= 0; i--) { uint64_t iss_ld_data; spike_core->read_mem(paddr + i * 8, 8, &iss_ld_data); fprintf(compare_log_fp, "%08x_%08x", iss_ld_data >> 32 & 0xffffffff, iss_ld_data & 0xffffffff); for (int b = 0; b < 8; b++) { if ((be >> ((i * 8) + b) & 0x01) && (((iss_ld_data >> (b * 8)) & 0xff) != (uint8_t)(l1d_data[i * 8 + b]))) { diff_found = true; } } if (i != 0) { fprintf (compare_log_fp, "_"); } } fprintf(compare_log_fp, "\n"); } catch (trap_t &t) { fprintf (compare_log_fp, "Catch exception at record_l1d_evict : PA = %08llx, %s\n", paddr, t.name()); } if (diff_found) { fprintf (compare_log_fp, "L1D Update Data Compare Error\n"); stop_sim (102); }
これらのチェッカーを搭載して、とりあえず基本的なフレームワークは完成した。 テストを走らせてみると、一応うまく動いているようだ。
43512 : 16016 : PC=[ffffffffffe0269c] (M,21,01) 000017b7 lui a5, 0x1 GPR[15](22) <= 0000000000001000 43512 : 16017 : PC=[ffffffffffe026a0] (M,21,02) 00fc0c33 add s8, s8, a5 GPR[24](28) <= 000000000003e000 43512 : 16018 : PC=[ffffffffffe026a4] (M,21,04) 0b3c0e63 beq s8, s3, pc + 188 43513 : 16019 : PC=[ffffffffffe026a8] (M,22,01) 00cc5793 srli a5, s8, 12 GPR[15](52) <= 000000000000003e 43513 : 16020 : PC=[ffffffffffe026ac] (M,22,02) 00479413 slli s0, a5, 4 GPR[08](23) <= 00000000000003e0 174078 : L1D Load-In : 800073e0(00927) : ffffffff_ffe07400_00000000_8006f000_00000000_00000000_00000000_00000000 174078 : Load ISS Check : 800073e0 : ffffffff_ffe07400_00000000_8006f000_00000000_00000000_00000000_00000000 174090 : L1D Evict : 80005be0(00735) : 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000 174090 : EVict ISS Check : 80005be0 : 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000 43525 : 16021 : PC=[ffffffffffe026b0] (M,23,01) 00848733 add a4, s1, s0 GPR[14](44) <= ffffffffffe073e0 43525 : 16022 : PC=[ffffffffffe026b4] (M,23,02) 00073703 ld a4, 0(a4) MR8(0xffffffffffe073e0)=>0000000000000000 GPR[14](11) <= 0000000000000000 43525 : 16023 : PC=[ffffffffffe026b8] (M,23,04) fe0702e3 beqz a4, pc - 28 43526 : 16024 : PC=[ffffffffffe0269c] (M,24,01) 000017b7 lui a5, 0x1 GPR[15](60) <= 0000000000001000 43526 : 16025 : PC=[ffffffffffe026a0] (M,24,02) 00fc0c33 add s8, s8, a5 GPR[24](6) <= 000000000003f000 43526 : 16026 : PC=[ffffffffffe026a4] (M,24,04) 0b3c0e63 beq s8, s3, pc + 188 174146 : L1D Load-In : 80007400(00928) : ffffffff_ffe07420_00000000_8004b000_ffffffff_ffe07410_00000000_80057000 174146 : Load ISS Check : 80007400 : ffffffff_ffe07420_00000000_8004b000_ffffffff_ffe07410_00000000_80057000 174158 : L1D Evict : 8004bc00(01504) : 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000 174158 : EVict ISS Check : 8004bc00 : 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000 43542 : 16027 : PC=[ffffffffffe02760] (M,03,01) 00090513 mv a0, s2 GPR[10](65) <= 0000000000000001 43542 : 16028 : PC=[ffffffffffe02764] (M,03,02) b41ff0ef jal pc - 0x4c0 GPR[01](29) <= ffffffffffe02768 174282 : L1D Load-In : 80001000(00128) : 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000 174282 : Load ISS Check : 80001000 : 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000 174294 : L1D Evict : 80005800(00704) : 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000 174294 : EVict ISS Check : 80005800 : 00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000 43574 : 16029 : PC=[ffffffffffe022a4] (M,04,01) fffff717 auipc a4, 0xfffff GPR[14](8) <= ffffffffffe012a4 43574 : 16030 : PC=[ffffffffffe022a8] (M,04,02) d5c70713 addi a4, a4, -676 GPR[14](9) <= ffffffffffe01000