FPGA開発日記

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

自作RISC-V CPUコア実装(テストパタンデバッグ)

自作CPUのデバッグをチマチマ進めている。 現在、1つのVerilogファイルから10個程度のコンフィグレーションを生成するようにしてリグレッションを走らせている。 TLBの挙動がおかしくなってしまったので、いろいろ見ているのだが、どうもVerilatorの問題を踏んでしまっているような気がしている。

structで定義した入出力ポートに対してTLBの探索結果を返しているのだが、以下の.missがどう頑張っても所望の動作をしてくれない。 念のため無料版のModelSimで走らせても挙動が違うため、どうもVerilatorのバグを踏んでいるような気がする?

 // ------------------
 // Response of TLB
 // ------------------
 assign o_tlb_resp.pf.ld        = (w_bad_va && w_cmd_read) || (|(w_pf_ld_array & w_is_hit));
 assign o_tlb_resp.pf.st        = (w_bad_va && w_cmd_write_perms) || (|(w_pf_st_array & w_is_hit));
 assign o_tlb_resp.pf.inst      = w_bad_va || (|(w_pf_inst_array & w_is_hit));
 assign o_tlb_resp.ae.ld        = |(w_ae_ld_array & w_is_hit);
 assign o_tlb_resp.ae.st        = |(w_ae_st_array & w_is_hit);
 assign o_tlb_resp.ae.inst      = |(~w_px_array   & w_is_hit);
 assign o_tlb_resp.ma.ld        = |(w_ma_ld_array & w_is_hit);
 assign o_tlb_resp.ma.st        = |(w_ma_st_array & w_is_hit);
 assign o_tlb_resp.ma.inst      = 1'b0;   // this is up to the pipeline to figure out
 assign o_tlb_resp.cacheable    = |(w_c_array & w_is_hit);
 assign o_tlb_resp.must_alloc   = |(w_must_alloc_array & w_is_hit);
 // && edge.manager.managers.forall(m => !m.supportsAcquireB || m.supportsHint).B;
 assign o_tlb_resp.prefetchable = |(w_prefetchable_array & w_is_hit);
 logic                            w_tlb_resp_miss;
 assign w_tlb_resp_miss = w_do_refill | w_tlb_miss;
 assign o_tlb_resp.miss         = w_tlb_resp_miss; /* || multiplehits */;
 assign o_tlb_resp.paddr        = {w_ppn, i_tlb_req.vaddr[11: 0]};

ちなみにこういうstructの記述はVerilatorによって以下のようなC++に変換されているようだ。 正気ですか?みたいなコードが出てきた。これ、どうやってデバッグしろって言うんだ... もう少し問題を簡潔にして絞り込んでいくしかないような気がしている。

    vlSelf->o_tlb_resp = (((QData)((IData)((((((((IData)(
                                                         (0U
                                                          !=
                                                          (((IData)(vlSelf->__PVT__w_cmd_read)
                                                             ?
                                                            (~
                                                             ((IData)(vlSelf->__PVT__w_r_array)
                                                              | (IData)(vlSelf->__PVT__w_ptw_ae_array)))
                                                             : 0U)
                                                           & (IData)(vlSelf->__PVT__w_is_hit))))
                                                 << 1U)
                                                | (0U
                                                   !=
                                                   (((IData)(vlSelf->__PVT__w_cmd_write_perms)
                                                      ?
                                                     (~
                                                      ((IData)(vlSelf->__PVT__w_w_array)
                                                       | (IData)(vlSelf->__PVT__w_ptw_ae_array)))
                                                      : 0U)
                                                    & (IData)(vlSelf->__PVT__w_is_hit))))
                                               << 0xaU)
                                              | ((((IData)(
                                                           (0U
                                                            !=
                                                            ((~
                                                              ((IData)(vlSelf->__PVT__w_x_array)
                                                               | (IData)(vlSelf->__PVT__w_ptw_ae_array)))
                                                             & (IData)(vlSelf->__PVT__w_is_hit))))
                                                   << 3U)
                                                  | (((IData)(
                                                              (0U
                                                               !=
                                                               (((IData)(vlSelf->__PVT__w_cmd_read)
                                                                  ?
                                                                 ((IData)(__PVT__w_ae_array)
                                                                  | (~ (IData)(vlSelf->__PVT__w_pr_array)))
                                                                  : 0U)
                                                                & (IData)(vlSelf->__PVT__w_is_hit))))
                                                      << 2U)
                                                     | (((IData)(
                                                                 (0U
                                                                  !=
                                                                  (((((IData)(vlSelf->__PVT__w_cmd_write_perms)
f:id:msyksphinz:20220108021416p:plain