FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

CPU開発に必須な検証手法の話

CPU開発をしていると、自分の設計したCPUが正しく動作しているかを検証する必要が必ず生じる。 プログラムを流して動作させているときに、そのプログラムが正しく動作したかを確かめるためには、いくつかの方法がある。 一つ目はプログラム自体に検証能力を持たせる方法(セルフチェックパタン)、もう一つはISS(命令セットシミュレータ)と比較する方法(ステップバイステップ)である。

セルフチェックパタン

セルフチェックパタンは、その名の通りパタン自身にプログラムの正常動作判定が含まれる。

total = 0;
for (int i = 1; i <= 10; i++) {
  total += i;
}
if (total == 55) {
  Pass ();
} else {
  Fail ();
}

これ、CPUが正しく動作することが分かっていれば間違い無くPass()なのだが、なにせ自作CPU、ちゃんと動作しているか分かったものではないため、ちゃんとプログラムが所望の場所を通ったか、このようなチェックポイントを設けて動作を確認する。

もちろん、この機構が正しく動作しない場合もある。例えばCPUが正しく演算出来ていなくても、たまたま最後に55という値になっていれば、このパタンは正常動作してしまう。 このため、もう一つのステップバイステップを用いてより詳細な検証を行う。

ステップバイステップ

ステップバイステップでは、プログラムの動作記録を自作CPUとISSの両方で取り、その一致を命令単位で確認する。

確認するポイントとしては、汎用レジスタの内容、メモリの内容などが一般的だ。

例えばCPUが以下のようなログを生成するとして、

          1185000000        53 [0000334c] 00012223 : SW        r 0,0x00                    : 
          1185000000        54 [00003350] da0ff0ef : JAL       r 1,0xda0ff         (40,35) : R 1<=00003354
          1445000000        55 [000028f0] 00100793 : ADDI      r15,r 0,0x001       (43,16) : R15<=00000001
          1445000000        56 [000028f4] 00f50023 : SB        r15,0x00                    : 
          1445000000        57 [000028f8] 00008067 : JALR      r 0,r 1,0x067               : 
          1905000000        58 [00003354] 00100513 : ADDI      r10,r 0,0x001       (44,39) : R10<=00000001
          1905000000        59 [00003358] b7cff0ef : JAL       r 1,0xb7cff         (45,40) : R 1<=0000335c
          2235000000        60 [000026d4] 00500793 : ADDI      r15,r 0,0x005       (46,43) : R15<=00000005
          2245000000        61 [000026d8] 04a7e263 : BLTU      r15,r10,0x02                : 
          2255000000        62 [000026dc] 000047b7 : LUI       r15,0x00004         (47,46) : R15<=00004000
          2265000000        63 [000026e0] f6478793 : ADDI      r15,r15,0xf64       (48,47) : R15<=00003f64
          2265000000        64 [000026e4] 00251513 : SLLI      r10,r10,0x02        (49,44) : R10<=00000004
          2285000000        65 [000026e8] 00f50533 : ADD       r10,r10,r15         (50,49) : R10<=00003f68
          2435000000        66 [000026ec] 00052783 : LW        r15,0x000           (51,48) : R15<=000026fc
          2445000000        67 [000026f0] 00078067 : JALR      r 0,r15,0x067               : 
          2645000000        68 [000026fc] 7e81a503 : LW        r10,0x7e8           (52,50) : R10<=00002704
          2645000000        69 [00002700] 00008067 : JALR      r 0,r 1,0x067               : 
          3135000000        70 [0000335c] 00a11623 : SH        r10,0x00                    : 
          3175000000        71 [00003360] 00200513 : ADDI      r10,r 0,0x002       (53,52) : R10<=00000002

ISSが以下のようなログを出したとする。

        53:M:MBar:[0000334c][P0000334c] 00012223 : sw         r00,0x004(r02)       r02=>0000bf78 r00=>00000000 (0000bf7c)<=00000000 
        54:M:MBar:[00003350][P00003350] da0ff0ef : jal        r01,0xda0ff          r01<=00003354 pc<=000028f0 
        55:M:MBar:[000028f0][P000028f0] 00100793 : addi       r15,r00,0x001        r00=>00000000 r15<=00000001 
        56:M:MBar:[000028f4][P000028f4] 00f50023 : sb         r15,0x000(r10)       r10=>0000bfc6 r15=>00000001 (0000bfc6)<=00000001 
        57:M:MBar:[000028f8][P000028f8] 00008067 : jalr       r00,r01,0x067        r01=>00003354 pc<=00003354 
        58:M:MBar:[00003354][P00003354] 00100513 : addi       r10,r00,0x001        r00=>00000000 r10<=00000001 
        59:M:MBar:[00003358][P00003358] b7cff0ef : jal        r01,0xb7cff          r01<=0000335c pc<=000026d4 
        60:M:MBar:[000026d4][P000026d4] 00500793 : addi       r15,r00,0x005        r00=>00000000 r15<=00000005 
        61:M:MBar:[000026d8][P000026d8] 04a7e263 : bltu       r15,r10,0x02         r15=>00000005 r10=>00000001 
        62:M:MBar:[000026dc][P000026dc] 000047b7 : lui        r15,0x00004          r15<=00004000 
        63:M:MBar:[000026e0][P000026e0] f6478793 : addi       r15,r15,0xf64        r15=>00004000 r15<=00003f64 
        64:M:MBar:[000026e4][P000026e4] 00251513 : slli       r10,r10,0x02         r10=>00000001 r10<=00000004 
        65:M:MBar:[000026e8][P000026e8] 00f50533 : add        r10,r10,r15          r10=>00000004 r15=>00003f64 r10<=00003f68 
        66:M:MBar:[000026ec][P000026ec] 00052783 : lw         r15,0x000(r10)       r10=>00003f68 (00003f68)=>000026fc r15<=000026fc 
        67:M:MBar:[000026f0][P000026f0] 00078067 : jalr       r00,r15,0x067        r15=>000026fc pc<=000026fc 
        68:M:MBar:[000026fc][P000026fc] 7e81a503 : lw         r10,0x7e8(r03)       r03=>00008010 (000087f8)=>00000000 r10<=00000000 
        69:M:MBar:[00002700][P00002700] 00008067 : jalr       r00,r01,0x067        r01=>0000335c pc<=0000335c 
        70:M:MBar:[0000335c][P0000335c] 00a11623 : sh         r10,0x00c(r02)       r02=>0000bf78 r10=>00000000 (0000bf84)<=736e0000 
        71:M:MBar:[00003360][P00003360] 00200513 : addi       r10,r00,0x002        r00=>00000000 r10<=00000002 

スクリプトを使ってこの2つのログが一致しているかを確認するのはとてもたやすい話だ。 さああなたは上記のログでどこが不一致か分かるかな?(まだバグあり笑)