LiteXの続き。
UARTのアドレスに対して正しくアクセスできていないように見える。まず、.data
セクションの場所を確認すると、
Disassembly of section .data: 10000000 <s_flush_cpu_dcache>: 10000000: 0d60 .2byte 0xd60 10000002: 0000 .2byte 0x0 10000004: 4580 .2byte 0x4580 10000006: 0000 .2byte 0x0 10000008: 4594 .2byte 0x4594 1000000a: 0000 .2byte 0x0 1000000c: 0000 .2byte 0x0 /* ... */ 10000110 <s_sdram_init>: 10000110: 4234 .2byte 0x4234 10000112: 0000 .2byte 0x0 10000114: 4b88 .2byte 0x4b88 10000116: 0000 .2byte 0x0 10000118: 4b94 .2byte 0x4b94 1000011a: 0000 .2byte 0x0 1000011c: 0005 .2byte 0x5 ... 10000120 <__stdio>: 10000120: 0000 .2byte 0x0 10000122: 31e40003 lb zero,798(s0) 10000126: 0000 .2byte 0x0 10000128: 31c4 .2byte 0x31c4 1000012a: 0000 .2byte 0x0 1000012c: 0000 .2byte 0x0
まず、0x1000_0000がsim_rom.init
のどこに格納されているのかをチェックするが、ファイルの中を検索すると、5903行目に格納されていた。これは0x170f行目に相当し、アドレスで計算すると、0x5c3cとなる。
これによりどういう問題が発生するかというと、__stdio
は0x10000120
のハズなのだが、$readmemh()
で読まれる初期化ファイルの場所を見るとやはりずれており、単純に0x10000000にアクセスしても正しく読み込むことができない。
5897 100000b0 5898 100000c0 5899 100000d0 5900 100000e0 5901 100000f0 5902 10000100 5903 10000110 5904 00000d60 // 5903行目。つまり、0x170F x 4 = 0x5C3Cに相当している 5905 00004580 5906 00004594 5907 00000000 5908 00000e48 5909 000045ac 5910 000045b0 5911 00000000
これはテストベンチ内でどのように処理されているのかをトレースしていくことにした。
これは、ブート時にdataセクションのコピーによって実現している。これにより、ROMの初期値データがSRAMに移されていく。
00000000000000d4 <data_init>: d4: 20000297 auipc t0,0x20000 d8: f2c28293 addi t0,t0,-212 # 20000000 <s_flush_cpu_dcache> dc: 20000317 auipc t1,0x20000 e0: 10430313 addi t1,t1,260 # 200001e0 <_edata> e4: 00004397 auipc t2,0x4 e8: 5a438393 addi t2,t2,1444 # 4688 <_fdata_rom> 00000000000000ec <data_loop>: ec: 00628963 beq t0,t1,fe <bss_init> f0: 0003be03 ld t3,0(t2) f4: 01c2b023 sd t3,0(t0) f8: 02a1 addi t0,t0,8 fa: 03a1 addi t2,t2,8 fc: bfc5 j ec <data_loop>
これを見ると、__stdio
はこれでコピーされている。これをチェックするために、LiteX上で実行命令トレースを生成する記述を追加した。
`ifdef LITEX_SIMULATION integer litex_log_fp; initial begin litex_log_fp = $fopen ("scariv_inst.log", "w"); end logic [riscv_pkg::XLEN_W-1: 0] w_physical_int_data [scariv_pkg::RNID_SIZE + 32]; logic [riscv_pkg::FLEN_W-1: 0] w_physical_fp_data [scariv_pkg::RNID_SIZE + 32]; generate for (genvar r_idx = 0; r_idx < scariv_pkg::RNID_SIZE; r_idx++) begin: reg_loop assign w_physical_int_data[r_idx] = scariv_subsystem_wrapper.u_scariv_subsystem.u_tile.u_int_phy_registers.r_phy_regs[r_idx]; if (riscv_pkg::FLEN_W != 0) begin assign w_physical_fp_data [r_idx] = scariv_subsystem_wrapper.u_scariv_subsystem.u_tile.fpu.u_fp_phy_registers.r_phy_regs[r_idx]; end end endgenerate always_ff @(negedge i_clk, negedge i_reset_n) begin if (!i_reset_n) begin end else begin if (o_commit.commit) begin for (int grp_idx = 0; grp_idx < scariv_pkg::DISP_SIZE; grp_idx++) begin if (o_commit.grp_id[grp_idx] & ~o_commit.dead_id[grp_idx]) begin $fwrite (litex_log_fp, "%10t (%2d,%2d) PC=0x%010x: %08x DASM(%08x)\n", $time, w_out_cmt_id, 1 << grp_idx, w_out_entry.inst[grp_idx].pc_addr, w_out_entry.inst[grp_idx].rvc_inst_valid ? w_out_entry.inst[grp_idx].rvc_inst : w_out_entry.inst[grp_idx].inst, w_out_entry.inst[grp_idx].rvc_inst_valid ? w_out_entry.inst[grp_idx].rvc_inst : w_out_entry.inst[grp_idx].inst); $fflush (litex_log_fp); if (w_out_entry.inst[grp_idx].wr_reg.valid) begin $fwrite (litex_log_fp, " %s[%2d](%3x) <= %016x\n", w_out_entry.inst[grp_idx].wr_reg.typ == scariv_pkg::GPR ? "GPR" : "FPR", w_out_entry.inst[grp_idx].wr_reg.regidx, w_out_entry.inst[grp_idx].wr_reg.rnid, w_out_entry.inst[grp_idx].wr_reg.typ == scariv_pkg::GPR ? w_physical_int_data[w_out_entry.inst[grp_idx].wr_reg.rnid] : w_physical_fp_data [w_out_entry.inst[grp_idx].wr_reg.rnid]); end end // if (o_commit.grp_id[grp_idx] &... end // for (int grp_idx = 0; grp_idx < scariv_pkg::DISP_SIZE; grp_idx++) end // if (w_out_valid) end // else: !if(!i_scariv_reset_n) end // always_ff @ (negedge i_clk, negedge i_scariv_reset_n) `endif // `ifdef LITEX_SIMULATION
一応確認する。0x200001c0
はちゃんとコピーされている。
2106000000 (15, 1) PC=0x00000000ec: 00628963 beq t0, t1, pc + 18 2142000000 ( 0, 1) PC=0x00000000f0: 0003be03 ld t3, 0(t2) GPR[28](24) <= 0000000000000001 2143000000 ( 1, 1) PC=0x00000000f4: 01c2b023 sd t3, 0(t0) 2143000000 ( 1, 2) PC=0x00000000f8: 000002a1 c.addi t0, 8 GPR[ 5](2a) <= 00000000200001c0 2144000000 ( 2, 1) PC=0x00000000fa: 000003a1 c.addi t2, 8 GPR[ 7](02) <= 0000000000004848 2144000000 ( 2, 2) PC=0x00000000fc: 0000bfc5 c.j pc - 16 GPR[ 0](00) <= 0000000000000000 2145000000 ( 3, 1) PC=0x00000000ec: 00628963 beq t0, t1, pc + 18 2169000000 ( 4, 1) PC=0x00000000f0: 0003be03 ld t3, 0(t2) GPR[28](0a) <= 0000000000030000 // データのロード 2170000000 ( 5, 1) PC=0x00000000f4: 01c2b023 sd t3, 0(t0) // 0x200001c0への書き込み 2170000000 ( 5, 2) PC=0x00000000f8: 000002a1 c.addi t0, 8 GPR[ 5](2b) <= 00000000200001c8 2171000000 ( 6, 1) PC=0x00000000fa: 000003a1 c.addi t2, 8 GPR[ 7](27) <= 0000000000004850 2171000000 ( 6, 2) PC=0x00000000fc: 0000bfc5 c.j pc - 16 GPR[ 0](00) <= 0000000000000000
しかし次のロード命令で正しく反映されていないようだ。これは波形でのデバッグが必要になりそう。
7503000000 (15, 2) PC=0x0000001c9c: 6107b503 ld a0, 1552(a5) GPR[10](0a) <= 00000000200001c0 ... 7946000000 ( 4, 1) PC=0x0000001e62: 00254703 lbu a4, 2(a0) GPR[14](07) <= 0000000000000000 // これは0x3が読み込まれなければならない 7950000000 ( 5, 1) PC=0x0000001e66: 00853a03 ld s4, 8(a0) GPR[20](2a) <= 0000000000000000