FPGA開発日記

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

RISC-Vのアトミック演算について

RISC-VのISS実装を進めていっている。今回はアトミック演算についてだ。

アトミック演算は、Read Modify Writeを使って実現している。ReadModifyWriteは、メモリからの読み込み、値の変更、メモリへのストアを1つの命令で実現しており、またこれらのメモリアクセスは、同一メモリアドレスに対して別のアクセスが割り込むことがないことが保証されている。これにより、プロセス切り替え場合など、リソース管理が正確に実現できるようになる。

RISC-Vのアトミックアクセス

RISC-Vのアトミックアクセスについては、以下が定義されている。

f:id:msyksphinz:20160117015951p:plain

まず、32ビット版のアトミックアクセスについては以下が定義されている。

f:id:msyksphinz:20160117020031p:plain

次は64ビット版のアトミックアクセスについては以下が定義されている。

f:id:msyksphinz:20160117020059p:plain

これらについては、Privileged Manualに書いてあるとおり、

  1. rs1のレジスタ値をメモリアドレスとしてデータをロードする。
  2. ロードしたデータは、そのままレジスタrdに格納される。
  3. ロードしたデータと、rs2の値を演算し、その結果をrs1のレジスタ値をアドレスとしたメモリ領域にストアする。

これを実装すると、以下のようになった。今回は、最も分かりやすいAMOADD.W命令だ。

    UWord_t rs1_val  = m_env->GRegRead<Word_t> (rs1_addr);
    UWord_t rs2_val  = m_env->GRegRead<Word_t> (rs2_addr);

    Word_t mem;
    m_env->LoadMemory (rs1_val, Size_Word, &mem);
    DWord_t ret = mem + rs2_val;

    int32_t except = m_env->StoreMemory (rs1_val, ret, Size_Word);

    m_env->GRegWrite (rd_addr, mem);

これらを全ての命令分実装した。32ビットも64ビットも全て実装を完了した。

github.com

アトミック演算命令を正しく実装したことにより、リグレッションの通過率は85%まで上昇した。

$ ctest
...
433/434 Test #433: rv64ui-v-xor .....................   Passed    0.01 sec
        Start 434: rv64ui-v-xori
434/434 Test #434: rv64ui-v-xori ....................   Passed    0.02 sec

85% tests passed, 65 tests failed out of 434

Total Test time (real) =   6.67 sec

The following tests FAILED:
          1 - rv32mi-p-csr (Failed)
          3 - rv32mi-p-ma_addr (Failed)
          4 - rv32mi-p-ma_fetch (Failed)
          5 - rv32mi-pm-ipi (Failed)
          6 - rv32mi-p-sbreak (Failed)