FPGA開発日記

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

LiteXによるSoC環境構築を試行する (16. Litescopeによるデバッグを試行する)

LiteXでどのように波形をダンプしてデバッグすればよいかを調査していたのだが、LiteXはブリッジを通じてホストに対して情報をダンプする機能が多く備わっているらしい。 これは便利だ。 ChipScopeのように内部の信号まで取り出したいのだが、このためにはデバッグ用の信号をCPUサブシステムのトップまでもっていかなければならないのだろうか? ちょっといろいろ試行している。

CPUサブシステムのトップに、デバッグ用の信号を下記のように引き上げている。

   input logic [mycpu_lsu_pkg::L2_CMD_TAG_W+2-1:0] axi_if_r_id,

`ifdef ILA_DEBUG
  output mycpu_pkg::cmt_id_t      o_ila_debug_tile_rob_head_ptr,
  output mycpu_pkg::cmt_id_t      o_ila_debug_tile_rob_tail_ptr,
  output logic                     o_ila_debug_tile_rob_entry_valid,
  output logic                     o_ila_debug_tile_rob_entry_cmt_id_msb,
  output mycpu_pkg::grp_id_t      o_ila_debug_tile_rob_entry_grp_id,
  output mycpu_pkg::grp_id_t      o_ila_debug_tile_rob_entry_done_grp_id,
  output mycpu_pkg::grp_id_t      o_ila_debug_tile_rob_entry_dead,
  output mycpu_pkg::grp_id_t      o_ila_debug_tile_rob_entry_fflags_update_valid,
  output mycpu_pkg::fflags_t      o_ila_debug_tile_rob_entry_fflags_0,

これを、core.pyでバスに変換してデバッグ用に接続する。

  • core.py
        ila_debug_layout = [
            ("rob_head_ptr", 5),
            ("rob_tail_ptr", 5),
            ("rob_entry", [
                ("valid", 1),
                ("cmt_id_msb", 1),
                ("grp_id", 2),
                ("done_grp_id", 2),
                ("dead", 1),
                ("fflags_update_valid", 1),
                ("fflags_0", 5),
                ("fflags_1", 5),
                ("int_inserted", 1),
            ]),
            ("rob_payload", [
                ("disp0", [
                    ("pc_addr", 32),
                    ("typ", 1),
                    ("regidx", 5),
                    ("rnid", 7),
                    ("old_rnid", 7),
                    ("inst", 32),
                ]),
                ("disp1", [
                    ("pc_addr", 32),
                    ("typ", 1),
                    ("regidx", 5),
                    ("rnid", 7),
                    ("old_rnid", 7),
                    ("inst", 32),
                ]),
            ]),
        ]
        self.ila_debug_bus = ila_debug_bus = Record(ila_debug_layout)

        self.cpu_params.update (
            o_o_ila_debug_tile_rob_head_ptr                  = ila_debug_bus.rob_head_ptr,
            o_o_ila_debug_tile_rob_tail_ptr                  = ila_debug_bus.rob_tail_ptr,

            o_o_ila_debug_tile_rob_entry_valid               = ila_debug_bus.rob_entry.valid              ,
            o_o_ila_debug_tile_rob_entry_cmt_id_msb          = ila_debug_bus.rob_entry.cmt_id_msb         ,
            o_o_ila_debug_tile_rob_entry_grp_id              = ila_debug_bus.rob_entry.grp_id             ,
            o_o_ila_debug_tile_rob_entry_done_grp_id         = ila_debug_bus.rob_entry.done_grp_id        ,
            o_o_ila_debug_tile_rob_entry_dead                = ila_debug_bus.rob_entry.dead               ,
            o_o_ila_debug_tile_rob_entry_fflags_update_valid = ila_debug_bus.rob_entry.fflags_update_valid,
            o_o_ila_debug_tile_rob_entry_fflags_0            = ila_debug_bus.rob_entry.fflags_0           ,
            o_o_ila_debug_tile_rob_entry_fflags_1            = ila_debug_bus.rob_entry.fflags_1           ,
            o_o_ila_debug_tile_rob_entry_int_inserted        = ila_debug_bus.rob_entry.int_inserted       ,

            o_o_ila_debug_tile_rob_payload_disp0_pc_addr     = ila_debug_bus.rob_payload.disp0.pc_addr ,
            o_o_ila_debug_tile_rob_payload_disp0_typ         = ila_debug_bus.rob_payload.disp0.typ     ,
            o_o_ila_debug_tile_rob_payload_disp0_regidx      = ila_debug_bus.rob_payload.disp0.regidx  ,
            o_o_ila_debug_tile_rob_payload_disp0_rnid        = ila_debug_bus.rob_payload.disp0.rnid    ,
            o_o_ila_debug_tile_rob_payload_disp0_old_rnid    = ila_debug_bus.rob_payload.disp0.old_rnid,
            o_o_ila_debug_tile_rob_payload_disp0_inst        = ila_debug_bus.rob_payload.disp0.inst    ,

            o_o_ila_debug_tile_rob_payload_disp1_pc_addr     = ila_debug_bus.rob_payload.disp1.pc_addr ,
            o_o_ila_debug_tile_rob_payload_disp1_typ         = ila_debug_bus.rob_payload.disp1.typ     ,
            o_o_ila_debug_tile_rob_payload_disp1_regidx      = ila_debug_bus.rob_payload.disp1.regidx  ,
            o_o_ila_debug_tile_rob_payload_disp1_rnid        = ila_debug_bus.rob_payload.disp1.rnid    ,
            o_o_ila_debug_tile_rob_payload_disp1_old_rnid    = ila_debug_bus.rob_payload.disp1.old_rnid,
            o_o_ila_debug_tile_rob_payload_disp1_inst        = ila_debug_bus.rob_payload.disp1.inst    ,
        )

この結果、シミュレーション用の信号が以下のように追加される。

$ litex_sim --cpu-type=mycpu--output-dir mycpu_build --with-etherbone --with-analyzer --soc-csv csr.csv
assign analyzer_mux_payload_data = {simsoc_ila_debug_bus_rob_payload_disp1_inst, simsoc_ila_debug_bus_rob_payload_disp1_old_rnid, simsoc_ila_debug_bus_rob_payload_disp1_rnid, simsoc_ila_debug_bus_rob_payload_disp1_regidx, simsoc_ila_debug_bus_rob_payload_disp1_typ, simsoc_ila_debug_bus_rob_payload_disp1_pc_addr, simsoc_ila_debug_bus_rob_payload_disp0_inst, simsoc_ila_debug_bus_rob_payload_disp0_old_rnid, simsoc_ila_debug_bus_rob_payload_disp0_rnid, simsoc_ila_debug_bus_rob_payload_disp0_regidx, simsoc_ila_debug_bus_rob_payload_disp0_typ, simsoc_ila_debug_bus_rob_payload_disp0_pc_addr, simsoc_ila_debug_bus_rob_entry_int_inserted, simsoc_ila_debug_bus_rob_entry_fflags_1, simsoc_ila_debug_bus_rob_entry_fflags_0, simsoc_ila_debug_bus_rob_entry_fflags_update_valid, simsoc_ila_debug_bus_rob_entry_dead, simsoc_ila_debug_bus_rob_entry_done_grp_id, simsoc_ila_debug_bus_rob_entry_grp_id, simsoc_ila_debug_bus_rob_entry_cmt_id_msb, simsoc_ila_debug_bus_rob_entry_valid, simsoc_ila_debug_bus_rob_tail_ptr, simsoc_ila_debug_bus_rob_head_ptr, simsoc_mmio_axi_r_payload_data, simsoc_mmio_axi_r_param_id, simsoc_mmio_axi_r_ready, simsoc_mmio_axi_r_valid, simsoc_mmio_axi_ar_param_id, simsoc_mmio_axi_ar_payload_addr, simsoc_mmio_axi_ar_ready, simsoc_mmio_axi_ar_valid, simsoc_mmio_axi_w_payload_data, simsoc_mmio_axi_w_param_id, simsoc_mmio_axi_w_ready, simsoc_mmio_axi_w_valid, simsoc_mmio_axi_aw_param_id, simsoc_mmio_axi_aw_payload_addr, simsoc_mmio_axi_aw_ready, simsoc_mmio_axi_aw_valid};

/* ... 途中省略 ... */
    .axi_if_w_valid                                 (simsoc_mmio_axi_w_valid),
    .o_ila_debug_tile_rob_entry_cmt_id_msb          (simsoc_ila_debug_bus_rob_entry_cmt_id_msb),
    .o_ila_debug_tile_rob_entry_dead                (simsoc_ila_debug_bus_rob_entry_dead),
    .o_ila_debug_tile_rob_entry_done_grp_id         (simsoc_ila_debug_bus_rob_entry_done_grp_id),
    .o_ila_debug_tile_rob_entry_fflags_0            (simsoc_ila_debug_bus_rob_entry_fflags_0),
    .o_ila_debug_tile_rob_entry_fflags_1            (simsoc_ila_debug_bus_rob_entry_fflags_1),
    .o_ila_debug_tile_rob_entry_fflags_update_valid (simsoc_ila_debug_bus_rob_entry_fflags_update_valid),
    .o_ila_debug_tile_rob_entry_grp_id              (simsoc_ila_debug_bus_rob_entry_grp_id),