FPGA開発日記

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

RISC-VのLinuxブート環境をbuildrootで構築する (10. RMW命令周辺の修正)

RISC-VのLinuxブート環境を構築したので、次にこれをRTL環境で実行している。

別のコンフィグレーションで実行するとLinuxのブート途中で止まってしまった。これはLR/SCの更新論理がLSUのパイプラインの別々のところにあることによるものだった。 LSU0のLR/SC情報をアップデートしても、LSU1で別のLR/SCを実行したら失敗してしまう。そりゃそうだ。

MR8(0x0000000080013090)=>0000000000000060
GPR[15](76) <= 0000000000000060
2998382 : 2259197 : PC=[0000000080007a3c] (M,45,02) 0000953e c.add   a0, a5
GPR[10](149) <= 0000000080018060
2998382 : 2259198 : PC=[0000000080007a3e] (M,45,04) 0000460d c.li    a2, 3
GPR[12](93) <= 0000000000000003
11993534 : L1D Load-In     : 80017f00(01532) : 00000000_8000087c_00000000_80018000_00000000_8000087c_00000000_80018000_00000000_8000087c_00000000_80018000_00000000_8000087c_00000000_80018000
11993534 : Load ISS Check  : 80017f00        : 00000000_00000000_0000006e_65726574_6e756f63_6d2c6e65_7265746e_756f6373_00000000_8000087c_00000000_80018000_00000000_80018000_00000000_00000000
11993538 : L1D Stq Store  : 80017f00(01532) : ________________________________________________________________________00000000_8000087c_00000000_80018000____________________________________
11993538 : STQ  ISS Check : 80017f00        : 00000000_00000000_0000006e_65726574_6e756f63_6d2c6e65_7265746e_756f6373_00000000_8000087c_00000000_80018000_00000000_80018000_00000000_00000000
2998390 : 2259199 : PC=[0000000080007a40] (M,46,01) 00004589 c.li    a1, 2
GPR[11](181) <= 0000000000000002
2998390 : 2259200 : PC=[0000000080007a42] (M,46,02) e98fb0ef jal     pc - 0x4968
GPR[01](53) <= 0000000080007a46
2998420 : 2259201 : PC=[00000000800030da] (M,47,01) 00001141 c.addi  sp, -16
GPR[02](70) <= 0000000080017f00
2998420 : 2259202 : PC=[00000000800030dc] (M,47,02) 0000e422 c.sdsp  s0, 8(sp)
MW8(0x0000000080017f08)=>0000000080017f20
2998420 : 2259203 : PC=[00000000800030de] (M,47,04) 00000800 c.addi4spn s0, sp, 16
GPR[08](190) <= 0000000080017f10
2998420 : 2259204 : PC=[00000000800030e0] (M,47,08) 000087aa c.mv    a5, a0
GPR[15](186) <= 0000000080018060
11993698 : L1D Load-In     : 80017f00(01532) : 00000000_80017f20_00000000_00000000_00000000_80017f20_00000000_00000000_00000000_80017f20_00000000_00000000_00000000_80017f20_00000000_00000000
11993698 : Load ISS Check  : 80017f00        : 00000000_00000000_0000006e_65726574_6e756f63_6d2c6e65_7265746e_756f6373_00000000_8000087c_00000000_80018000_00000000_80017f20_00000000_00000000
11993702 : L1D Stq Store  : 80017f00(01532) : ____________________________________________________________________________________________________________00000000_80017f20__________________
11993702 : STQ  ISS Check : 80017f00        : 00000000_00000000_0000006e_65726574_6e756f63_6d2c6e65_7265746e_756f6373_00000000_8000087c_00000000_80018000_00000000_80017f20_00000000_00000000
2998426 : RTL(48,1) Exception Cause = CSR Update Flush(27) PC=0000800030e2, Inst=0f50000f, fence   iorw,ow
2998426 : 2259205 : PC=[00000000800030e2] (M,48,01) 0f50000f fence   iorw,ow
2998464 : 2259206 : PC=[00000000800030e6] (M,54,01) 1407b52f lr.d    a0, (a5)
MR8(0x0000000080018060)=>0000000000000002
GPR[10](69) <= 0000000000000002
2998464 : 2259207 : PC=[00000000800030ea] (M,54,02) 00b51563 bne     a0, a1, pc + 10
2998474 : 2259208 : PC=[00000000800030ee] (M,55,01) 1cc7b72f sc.d    a4, a2, (a5)
MW8(0x0000000080018060)=>0000000000000003
==========================================
Wrong GPR[14](142): RTL = 0000000000000001, ISS = 0000000000000000
==========================================

修正のため、LR/SCの情報を管理するためのインタフェースとモジュールを作った。

generate for (genvar p_idx = 0; p_idx < msrh_conf_pkg::LSU_INST_NUM; p_idx++) begin : lsu_port_loop
  assign w_lr_update_valids[p_idx] = lrsc_if[p_idx].lr_update_valid;
  assign w_sc_check_valids [p_idx] = lrsc_if[p_idx].sc_check_valid;

  assign w_lrsc_paddr_array[p_idx] = lrsc_if[p_idx].paddr;
  assign lrsc_if[p_idx].sc_success = w_sc_success;
end
endgenerate

bit_oh_or
  #(.T(msrh_pkg::paddr_t), .WORDS(msrh_conf_pkg::LSU_INST_NUM))
u_lr_addr_sel
  (.i_oh(w_lr_update_valids), .i_data(w_lrsc_paddr_array), .o_selected(w_lr_paddr_sel));


bit_oh_or
  #(.T(msrh_pkg::paddr_t), .WORDS(msrh_conf_pkg::LSU_INST_NUM))
u_sc_addr_sel
  (.i_oh(w_sc_check_valids), .i_data(w_lrsc_paddr_array), .o_selected(w_sc_paddr_sel));


always_ff @ (posedge i_clk, negedge i_reset_n) begin
  if (!i_reset_n) begin
    r_lr_registered_valid <= 1'b0;
    r_lr_paddr <= 'h0;
  end else begin
    if (|w_lr_update_valids) begin
      r_lr_registered_valid <= 1'b1;
      r_lr_paddr <= w_lr_paddr_sel;
    end else if (|w_sc_check_valids) begin
      r_lr_registered_valid <= 1'b0;
    end
  end
end

assign w_sc_success = r_lr_registered_valid & (r_lr_paddr == w_sc_paddr_sel);

これでもう一度シミュレーションを流してみる。