自作CPUをChipyardの環境で動かすために、何が必要かを久しぶりに確認した。
前回、Sensitivity List関連で何故シミュレーションが失敗するのかを見つけるために、デバッグビルドで再実行したのだった。
./simulator-chipyard-MSRHConfig-debug +verbose -v rv64ui-p-add.vcd $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add
これを見ると、FPU周りだということが分かってくるが、まだ詳細がつかめない。もう少し詳細をつかむために、FPUも搭載していない最小構成でChipyardシミュレーションを作り直してみて、問題が発生するか確認した。
-V{t1,96}+ VTestHarness___024root___change_request_880 -V{t1,97}+ VTestHarness___024root___change_request_879 -V{t1,98}+ VTestHarness___024root___change_request_878 -V{t1,99}+ VTestHarness___024root___change_request_877 -V{t1,100}+ VTestHarness___024root___change_request_876 -V{t1,101}+ VTestHarness___024root___change_request_875 -V{t1,102}+ VTestHarness___024root___change_request_874 -V{t1,103}+ VTestHarness___024root___change_request_873 -V{t1,104} CHANGE: /home/msyksphinz/work/riscv/chipyard_msrh/generators/msrh/src/main/resources/vsrc/MSRHCoreBlackbox.preprocessed.sv:20803 -V{t1,105} CHANGE: /home/msyksphinz/work/riscv/chipyard_msrh/generators/msrh/src/main/resources/vsrc/MSRHCoreBlackbox.preprocessed.sv:20803 -V{t1,106} CHANGE: /home/msyksphinz/work/riscv/chipyard_msrh/generators/msrh/src/main/resources/vsrc/MSRHCoreBlackbox.preprocessed.sv:20803 -V{t1,107} CHANGE: /home/msyksphinz/work/riscv/chipyard_msrh/generators/msrh/src/main/resources/vsrc/MSRHCoreBlackbox.preprocessed.sv:20803 -V{t1,108} CHANGE: /home/msyksphinz/work/riscv/chipyard_msrh/generators/msrh/src/main/resources/vsrc/MSRHCoreBlackbox.preprocessed.sv:20803 -V{t1,109} CHANGE: /home/msyksphinz/work/riscv/chipyard_msrh/generators/msrh/src/main/resources/vsrc/MSRHCoreBlackbox.preprocessed.sv:20803 -V{t1,110} CHANGE: /home/msyksphinz/work/riscv/chipyard_msrh/generators/msrh/src/main/resources/vsrc/MSRHCoreBlackbox.preprocessed.sv:20803 -V{t1,111} CHANGE: /home/msyksphinz/work/riscv/chipyard_msrh/generators/msrh/src/main/resources/vsrc/MSRHCoreBlackbox.preprocessed.sv:20803 -V{t1,112} CHANGE: /home/msyksphinz/work/riscv/chipyard_msrh/generators/msrh/src/main/resources/vsrc/MSRHCoreBlackbox.preprocessed.sv:20803 -V{t1,113} CHANGE: /home/msyksphinz/work/riscv/chipyard_msrh/generators/msrh/src/main/resources/vsrc/MSRHCoreBlackbox.preprocessed.sv:20803 -V{t1,114} CHANGE: /home/msyksphinz/work/riscv/chipyard_msrh/generators/msrh/src/main/resources/vsrc/MSRHCoreBlackbox.preprocessed.sv:20803 -V{t1,115} CHANGE: /home/msyksphinz/work/riscv/chipyard_msrh/generators/msrh/src/main/resources/vsrc/MSRHCoreBlackbox.preprocessed.sv:20803 %Error: /home/msyksphinz/work/riscv/chipyard_msrh/sims/verilator/generated-src/chipyard.TestHarness.MSRHConfig/chipyard.TestHarness.MSRHConfig.harness.v:3849: Verilated model didn't DC converge - See https://verilator.org/warn/DIDNOTCONVERGE Aborting...
やはり同じエラーで落ちるようになった。しかし今度は場所が違い、リネーム論理辺りで問題が発生する。やはり同じサブモジュール内で問題が発生しているようだ。しかしこのモジュールは単体シミュレーションでも使っており、何故問題が発生するのか分からない。
VL_INLINE_OPT QData VTestHarness___024root___change_request_17(VTestHarness___024root* vlSelf) { if (false && vlSelf) {} // Prevent unused VTestHarness__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp; VL_DEBUG_IF(VL_DBG_MSGF("+ VTestHarness___024root___change_request_17\n"); ); // Body // Change detection QData __req = false; // Logically a bool __req |= ((vlSelf->TestHarness__DOT__dut__DOT__system__DOT__MSRH_tile__DOT__core__DOT__u_msrh_tile__DOT__u_msrh_int_rename__DOT__u_msrh_rename_map__DOT__map_loop__BRA__18__KET____DOT__genblk1__DOT__bit_rnid_or__DOT__w_selected_array [1U] ^ vlSelf->__Vchglast__TOP__TestHarness__DOT__dut__DOT__system__DOT__MSRH_tile__DOT__core__DOT__u_msrh_tile__DOT__u_msrh_int_rename__DOT__u_msrh_rename_map__DOT__map_loop__BRA__18__KET____DOT__genblk1__DOT__bit_rnid_or__DOT__w_selected_array [1U]) | (vlSelf->TestHarness__DOT__dut__DOT__system__DOT__MSRH_tile__DOT__core__DOT__u_msrh_tile__DOT__u_msrh_int_rename__DOT__u_msrh_rename_map__DOT__map_loop__BRA__19__KET____DOT__genblk1__DOT__extract_latest_rd_bit__DOT__u_bit_tree__DOT__in_shift_array [0U] ^ vlSelf->__Vchglast__TOP__TestHarness__DOT__dut__DOT__system__DOT__MSRH_tile__DOT__core__DOT__u_msrh_tile__DOT__u_msrh_int_rename__DOT__u_msrh_rename_map__DOT__map_loop__BRA__19__KET____DOT__genblk1__DOT__extract_latest_rd_bit__DOT__u_bit_tree__DOT__in_shift_array [0U]) | (vlSelf->TestHarness__DOT__dut__DOT__system__DOT__MSRH_tile__DOT__core__DOT__u_msrh_tile__DOT__u_msrh_int_rename__DOT__u_msrh_rename_map__DOT__map_loop__BRA__19__KET____DOT__genblk1__DOT__extract_latest_rd_bit__DOT__u_bit_tree__DOT__in_shift_array [1U] ^ vlSelf->__Vchglast__TOP__TestHarness__DOT__dut__DOT__system__DOT__MSRH_tile__DOT__core__DOT__u_msrh_tile__DOT__u_msrh_int_rename__DOT__u_msrh_rename_map__DOT__map_loop__BRA__19__KET____DOT__genblk1__DOT__extract_latest_rd_bit__DOT__u_bit_tree__DOT__in_shift_array [1U]) | (vlSelf->TestHarness__DOT__dut__DOT__system__DOT__MSRH_tile__DOT__core__DOT__u_msrh_tile__DOT__u_msrh_int_rename__DOT__u_msrh_rename_map__DOT__map_loop__BRA__19__KET____DOT__genblk1__DOT__bit_rnid_or__DOT__w_selected_array [0U] ^ vlSelf->__Vchglast__TOP__TestHarness__DOT__dut__DOT__system__DOT__MSRH_tile__DOT__core__DOT__u_msrh_tile__DOT__u_msrh_int_rename__DOT__u_msrh_rename_map__DOT__map_loop__BRA__19__KET____DOT__genblk1__DOT__bit_rnid_or__DOT__w_selected_array [0U]) | (vlSelf->TestHarness__DOT__dut__DOT__system__DOT__MSRH_tile__DOT__core__DOT__u_msrh_tile__DOT__u_msrh_int_rename__DOT__u_msrh_rename_map__DOT__map_loop__BRA__19__KET____DOT__genblk1__DOT__bit_rnid_or__DOT__w_selected_array
問題の論理は、Arrayから1つのエントリを選択する論理なのだが、これ自体は問題はいハズだ。
module select_oh #( parameter SEL_WIDTH = 5, parameter KEY_WIDTH = 8, parameter DATA_WIDTH = 32 ) ( input logic [KEY_WIDTH-1: 0] i_cmp_key, input logic [SEL_WIDTH-1:0] i_valid, input logic [KEY_WIDTH-1: 0] i_keys [SEL_WIDTH], input logic [DATA_WIDTH-1: 0] i_data [SEL_WIDTH], output logic o_valid, output logic [DATA_WIDTH-1: 0] o_data ); /* verilator lint_off UNOPTFLAT */ logic [SEL_WIDTH-1:0] valid_tmp; generate for (genvar i = 0; i < SEL_WIDTH; i++) begin always_comb begin if (i_valid[i] && i_keys[i] == i_cmp_key) begin valid_tmp[i] = 1'b1; end else begin valid_tmp[i] = 1'b0; end end // always_comb end endgenerate /* 以下略 */
うーん、何が良くないんだ?