FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://sites.google.com/site/fpgadevelopindex/

32ビットモードと64ビットモードの両方をサポートするためのRISC-V ISSの実装

RISC-V用のISSで、倍精度と単精度の浮動小数点をサポートをするために、RISC-V ISSで32ビットモードと64ビットモードをサポートしよう。

32ビットモードと64ビットモードのレジスタファイル対応

まずは、レジスタファイルの大きさとアドレスの範囲を64ビットに拡張しよう。 最初は、32ビットモードと64ビットモードで基底クラスから別々の派生クラスを定義しようかと思ったが、こうするとまだ32ビットと64ビットで別々のメソッドを定義していかなければならないため面倒になる。 とりあえず、64ビットの領域とメソッドを定義し、32ビットモードのときは上位32ビットを切り取って利用する実装とした。

github.com

class EnvBase
{

 private:
    /*!
     * Architecture Implementations
     */
#ifdef    ARCH_RISCV
    std::unique_ptr<DWord_t []> m_regs;     // general register
#else //  ARCH_RISCV
#ifdef    ARCH_MIPS64
    std::unique_ptr<DWord_t []> m_regs;     // general register
#else  // ARCH_MIPS64
    std::unique_ptr<Word_t []> m_regs;     // general register
#endif // ARCH_MIPS64
#endif // ARCH_RISCV
...
};

class RiscvEnv : public EnvBase
{

 private:
...
    PrivMode m_priv;
...
 public:
    RiscvEnv (FILE *dbgfp, bool en_stop_sim, bool is_debug_trace, uint32_t xlen);
};

とりあえずこれだけで64ビットモードには対応できるようになる。

シミュレータの実行時オプションで32ビットモードと64ビットモードを区別できるようにする。

Google Flagsを使っているので、新しいオプションを定義した。

DEFINE_int32 (bit_mode, 32, "CPU mode. 32 or 64 bit width");

CPUコアをインスタンスするときにこの情報を利用するようにする。

        std::unique_ptr<RiscvEnv> env = std::unique_ptr<RiscvEnv>(new RiscvEnv (g_debug_fp, en_stop_sim, FLAGS_debug, FLAGS_bit_mode));

さらに64ビットの命令を追加し、とりあえずは実行できるようにした。

テストパタンを実行してみる

riscv-testsのパタンを実行して、動作を確認する。64ビットモードでの実行なので、--bit_file 64を追加する。

$ ./swimmer_riscv --binfile ~/riscv-tools/riscv-tests/isa/rv64uf-p-fadd --bit_mode 64 --debu
...
        58 : [000002f8] 34c59a63 : bne        r11,r12,0x1a         r11=>0000000000000001 r12=>0000000000000001
        59 : [000002fc] 0040006f : jal        r00,0x00400          pc<=0000000000000300
        60 : [00000300] 00500e13 : addi       r28,r00,0x005        r00=>0000000000000000 r28<=0000000000000005
        61 : [00000304] 00001517 : auipc      r10,0x00001          r10<=0000000000001304
        62 : [00000308] d2c50513 : addi       r10,r10,0xd2c        r10=>0000000000001304 r10<=0000000000001030
        63 : [0000030c] 00053007 : fld        r00,r10,0x000        r10=>0000000000001030 (0000000000001030)=>00000000 (0000000000001034)=>40040000 f00<=4004000000000000
        64 : [00000310] 00853087 : fld        r01,r10,0x008        r10=>0000000000001030 (0000000000001038)=>00000000 (000000000000103c)=>3ff00000 f01<=3ff0000000000000
        65 : [00000314] 01053107 : fld        r02,r10,0x010        r10=>0000000000001030 (0000000000001040)=>00000000 (0000000000001044)=>00000000 f02<=0000000000000000
        66 : [00000318] 01853683 : ld         r13,r10,0x018        r10=>0000000000001030 (0000000000001048)=>00000000 (000000000000104c)=>400c0000 r13<=400c000000000000
        67 : [0000031c] 021071d3 : fadd.d     r03,r00,r01          f00=>4004000000000000 f01=>3ff0000000000000 f03<=400c000000000000 fflags<=0000000000000000
        68 : [00000320] e2018553 : fmv.x.d    r10,r03              f03=>400c000000000000 r10<=400c000000000000
        69 : [00000324] 001015f3 : csrrw      r11,0x001,r00        fflags=>0000000000000000 r00=>0000000000000000 fflags<=0000000000000000 r11<=0000000000000000
        70 : [00000328] 00000613 : addi       r12,r00,0x000        r00=>0000000000000000 r12<=0000000000000000
        71 : [0000032c] 32d51063 : bne        r10,r13,0x19         r10=>0000000000000000 r13=>0000000000000000
        72 : [00000330] 30c59e63 : bne        r11,r12,0x18         r11=>0000000000000000 r12=>0000000000000000
        73 : [00000334] 0040006f : jal        r00,0x00400          pc<=0000000000000338
        74 : [00000338] 00600e13 : addi       r28,r00,0x006        r00=>0000000000000000 r28<=0000000000000006
        75 : [0000033c] 00001517 : auipc      r10,0x00001          r10<=000000000000133c
        76 : [00000340] d1450513 : addi       r10,r10,0xd14        r10=>000000000000133c r10<=0000000000001050
        77 : [00000344] 00053007 : fld        r00,r10,0x000        r10=>0000000000001050 (0000000000001050)=>66666666 (0000000000001054)=>ffffffffc0934c66 f00<=c0934c6666666666
        78 : [00000348] 00853087 : fld        r01,r10,0x008        r10=>0000000000001050 (0000000000001058)=>ffffffff9999999a (000000000000105c)=>3ff19999 f01<=ffffffff9999999a
        79 : [0000034c] 01053107 : fld        r02,r10,0x010        r10=>0000000000001050 (0000000000001060)=>00000000 (0000000000001064)=>00000000 f02<=0000000000000000
        80 : [00000350] 01853683 : ld         r13,r10,0x018        r10=>0000000000001050 (0000000000001068)=>00000000 (000000000000106c)=>ffffffffc0934800 r13<=c093480000000000
        81 : [00000354] 021071d3 : fadd.d     r03,r00,r01          f00=>c0934c6666666666 f01=>ffffffff9999999a f03<=ffffffff9999999a fflags<=0000000000000000
        82 : [00000358] e2018553 : fmv.x.d    r10,r03              f03=>ffffffff9999999a r10<=ffffffff9999999a
        83 : [0000035c] 001015f3 : csrrw      r11,0x001,r00        fflags=>0000000000000000 r00=>0000000000000000 fflags<=0000000000000000 r11<=0000000000000000
        84 : [00000360] 00100613 : addi       r12,r00,0x001        r00=>0000000000000000 r12<=0000000000000001
        85 : [00000364] 2ed51463 : bne        r10,r13,0x17         r10=>ffffffff9999999a r13=>0000000000000000 pc<=000000000000064c
...
        96 : [00000184] 780e1073 : csrrw      r00,0x780,r28        mtohost=>0000000000000000 r28=>000000000000000d mtohost<=000000000000000d

途中のテストで失敗しているが、これは浮動小数点フォーマットでは定義されていない、不定値を入力したときの挙動の違いのようだ。 ISSではsoftfloatに従って適当に取り扱っているが、実際にはアーキテクチャの定義に従って正しく処理しないとパタンは完走しない。この部分は、調整していく必要があるなあ。