FPGA開発日記

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

自作RISC-V CPUコア実装(LDQ/STQ間のフラッシュインタフェースの確認)

自作CPUの実装、ロードストア命令の物理アドレスが決まらないうえでのハザードが性能ボトルネックになっているのを見た。

次に検討するのは、LDQ/STQの最適化だ。以前の記事で説明したとおり、LDQとSTQの間でインタフェースを作成し、STQからのパイプラインが流れて段階でLDQのエントリをチェックするように変更する。

一応、単純な物理アドレス比較機構まで実装したので、本当にこの機能でフラッシュを検出したうえで正しく動作できるのか(というか逆に現在の段階でアグレッシブなロード命令発行を行った場合に問題が発生することを確認する。

一応実装してみると、なぜか問題を検出せずに正しく終了してしまった。問題になるのはパイプラインの選択時に常にストア側が選択されるというあまり意味のない状態になっていた。

msrh_pkg::issue_t                     w_ex0_replay_issue;
logic [MEM_Q_SIZE-1: 0] w_ex0_replay_index_oh;
assign w_ex0_replay_issue    = stq_replay_if.valid ? stq_replay_if.issue    : ldq_replay_if.issue;
assign w_ex0_replay_index_oh = stq_replay_if.valid ? stq_replay_if.index_oh : ldq_replay_if.index_oh;

assign ldq_replay_if.conflict = stq_replay_if.valid & ldq_replay_if.valid;
assign stq_replay_if.conflict = 1'b0;

これを修正して、ロードとストア同時にパイプラインに入った場合は古い命令の方を選択するようにする。

assign w_ld_selected = ldq_replay_if.valid & ~stq_replay_if.valid |
                       ldq_replay_if.valid &  stq_replay_if.valid & w_ld_is_older_than_st;

assign w_ex0_replay_issue    = w_ld_selected ? ldq_replay_if.issue    : stq_replay_if.issue   ;
assign w_ex0_replay_index_oh = w_ld_selected ? ldq_replay_if.index_oh : stq_replay_if.index_oh;

msrh_rough_older_check
u_pipe_age
  (
   .i_cmt_id0 (ldq_replay_if.issue.cmt_id),
   .i_grp_id0 (ldq_replay_if.issue.grp_id),

   .i_cmt_id1 (stq_replay_if.issue.cmt_id),
   .i_grp_id1 (stq_replay_if.issue.grp_id),

   .o_0_older_than_1 (w_ld_is_older_than_st)
   );


assign ldq_replay_if.conflict = ~w_ld_selected;
assign stq_replay_if.conflict =  w_ld_selected;
f:id:msyksphinz:20211122001135p:plain

ただしこれでも投機的なロードのミスが発生しない。もう少しアグレッシブなやつが必要かなあ。

という訳で、ストア命令のアドレス生成にdiv命令を挟んでストアの発行をメチャ遅くした。

loop:

    div     x3, x3, x4

    sd          x10,  0(x3)
    sd          x11,  8(x3)
    sd          x12, 16(x3)
    sd          x13, 24(x3)
    sd          x14, 32(x3)
    sd          x15, 40(x3)
    sd          x16, 48(x3)
    sd          x17, 56(x3)

    ld          x20,  0(x1)
    ld          x21,  8(x1)
    ld          x22, 16(x1)
    ld          x23, 24(x1)
    ld          x24, 32(x1)
    ld          x25, 40(x1)
    ld          x26, 48(x1)
    ld          x27, 56(x1)

この結果無事に投機的なロードに失敗することが出来た。さあここからフラッシュ機構の実装だ。

4558 : 22 : PC=[0000000080000058] (05,02) 00c1b823 sd      a2, 16(gp)
MW8(0x0000000080000110)=>00000000000000bb
4558 : 23 : PC=[000000008000005c] (05,04) 00d1bc23 sd      a3, 24(gp)
MW8(0x0000000080000118)=>0000000000011567
4566 : 24 : PC=[0000000080000060] (06,01) 02e1b023 sd      a4, 32(gp)
MW8(0x0000000080000120)=>0000000000011233
4566 : 25 : PC=[0000000080000064] (06,02) 02f1b423 sd      a5, 40(gp)
MW8(0x0000000080000128)=>00000000000110bb
4566 : 26 : PC=[0000000080000068] (06,04) 0301b823 sd      a6, 48(gp)
MW8(0x0000000080000130)=>0000000000022567
4566 : 27 : PC=[000000008000006c] (06,08) 0311bc23 sd      a7, 56(gp)
MW8(0x0000000080000138)=>0000000000022233
4570 : L1D Stq Store : 80000100(08) : ____________________________________00000000_00000233_00000000_00000567
4570 : 28 : PC=[0000000080000070] (07,01) 0000ba03 ld      s4, 0(ra)
MR8(0x0000000080000100)=>0000000000000567
==========================================
Wrong GPR[20](37): RTL = 0000000000000000, ISS = 0000000000000567
==========================================
===============================
SIMULATION FINISH : FAIL (CODE=100)
===============================