ロードストアのトレースログについては、以下のオプションを変更してリコンパイルすることで出力されるようになるらしい。リコンパイルには例によってかなり時間がかかってしまうのだけれども。
src/main/scala/common/parameters.scala
diff --git a/src/main/scala/common/parameters.scala b/src/main/scala/common/parameters.scala index 1a0c25fd..ca1d7edf 100644 --- a/src/main/scala/common/parameters.scala +++ b/src/main/scala/common/parameters.scala @@ -92,9 +92,9 @@ case class BoomCoreParams( clockGate: Boolean = false, /* debug stuff */ - enableCommitLogPrintf: Boolean = false, + enableCommitLogPrintf: Boolean = true, enableBranchPrintf: Boolean = false, - enableMemtracePrintf: Boolean = false + enableMemtracePrintf: Boolean = true // DOC include end: BOOM Parameters ) extends freechips.rocketchip.tile.CoreParams
これで同じようにシミュレーションを行うと、以下のようにトレース情報に加えてメモリアクセスの情報が出力される。
3425 3 0x00000000800031fa 0x034000ef jal pc + 0x34 x 1 0x00000000800031fe 3432 3 0x000000008000322e 0x00000517 auipc a0, 0x0 x10 0x000000008000322e 3436 3 0x0000000080003232 0x1d250513 addi a0, a0, 466 x10 0x0000000080003400 3438 3 0x0000000080003236 0x6108 c.ld a0, 0(a0) x10 0xdeadbeef00000000 MT 0000000000003df6 01 00 3 0080003400 0000000000000000 deadbeef00000000 3439 3 0x0000000080003238 0x8082 ret 3441 3 0x00000000800031fe 0x87aa c.mv a5, a0 x15 0xdeadbeef00000000 3442 3 0x0000000080003200 0x85be c.mv a1, a5 x11 0xdeadbeef00000000 3442 3 0x0000000080003202 0x00000517 auipc a0, 0x0 x10 0x0000000080003202 3442 3 0x0000000080003206 0x1ee50513 addi a0, a0, 494 x10 0x00000000800033f0 3442 3 0x000000008000320a 0xaefff0ef jal pc - 0x512 x 1 0x000000008000320e 3443 3 0x0000000080002cf8 0x7159 c.addi16sp sp, -112 x 2 0x0000000080023300 3443 3 0x0000000080002cfa 0xf406 c.sdsp ra, 40(sp) 3443 3 0x0000000080002cfc 0xf022 c.sdsp s0, 32(sp) 3443 3 0x0000000080002cfe 0x1800 c.addi4spn s0, sp, 48 x 8 0x0000000080023330 MT 0000000000003dfb 02 01 3 0080023328 000000008000320e 2a3549fad288d2d0 MT 0000000000003dfb 02 01 3 0080023320 0000000080023380 9b41f14b36cbd0ae 3444 3 0x0000000080002d00 0xfca43c23 sd a0, -40(s0) MT 0000000000003dfc 02 01 3 0080023308 00000000800033f0 b0d68963f68c7912 3445 3 0x0000000080002d04 0xe40c c.sd a1, 8(s0) 3445 3 0x0000000080002d06 0xe810 c.sd a2, 16(s0) 3445 3 0x0000000080002d08 0xec14 c.sd a3, 24(s0) 3445 3 0x0000000080002d0a 0xf018 c.sd a4, 32(s0) MT 0000000000003dfd 02 01 3 0080023338 deadbeef00000000 605e758e69ca86a0 MT 0000000000003dfd 02 01 3 0080023340 0000000080003480 24726ea7be9d2eb6 MT 0000000000003dfd 02 01 3 0080023348 0000000080023200 a85fb40e04d7f7e8 MT 0000000000003dfd 02 01 3 0080023350 0000000000000000 c29b4f52e59f9f04 3446 3 0x0000000080002d0c 0xf41c c.sd a5, 40(s0) MT 0000000000003dfe 02 01 3 0080023358 deadbeef00000000 bfde1696b4cac50a 3447 3 0x0000000080002d0e 0x03043823 sd a6, 48(s0) 3447 3 0x0000000080002d12 0x03143c23 sd a7, 56(s0)
なるほど、最初のMT
はMemTraceのことか、マニュアル運転のことかと思った。
src/main/scala/lsu/lsu.scala
if (MEMTRACE_PRINTF) { when (commit_store || commit_load) { val uop = Mux(commit_store, stq(idx).bits.uop, ldq(idx).bits.uop) val addr = Mux(commit_store, stq(idx).bits.addr.bits, ldq(idx).bits.addr.bits) val stdata = Mux(commit_store, stq(idx).bits.data.bits, 0.U) val wbdata = Mux(commit_store, stq(idx).bits.debug_wb_data, ldq(idx).bits.debug_wb_data) printf("MT %x %x %x %x %x %x %x\n", io.core.tsc_reg, uop.uopc, uop.mem_cmd, uop.mem_size, addr, stdata, wbdata) } }
うーん、例えば以下のログについて考えてみると、
MT 0000000000003df6 01 00 3 0080003400 0000000000000000 deadbeef00000000
- TSCカウンタ(これはtimeレジスタとは違い、ずっと動いているタイプのものらしい)
- マイクロオペレーション
- マイクロオペレーション内のメモリコマンド
- メモリアクセスサイズ
- アドレス
- 書き込みデータ(読み込みと書き込みが両方表示されているようだが、たぶんアトミック操作のためかしら?)
が情報として並んでいるようだ。uops
は本当にコミットの情報をそのまま出しているのかな?uop
内にはどのような情報が入っているのかというと、
src/main/scala/common/micro-op.scala
class MicroOp(implicit p: Parameters) extends BoomBundle with freechips.rocketchip.rocket.constants.MemoryOpConstants with freechips.rocketchip.rocket.constants.ScalarOpConstants { val uopc = UInt(UOPC_SZ.W) // micro-op code val inst = UInt(32.W) val debug_inst = UInt(32.W) val is_rvc = Bool() val debug_pc = UInt(coreMaxAddrBits.W) val iq_type = UInt(IQT_SZ.W) // which issue unit do we use? val fu_code = UInt(FUConstants.FUC_SZ.W) // which functional unit do we use? val ctrl = new CtrlSignals ...
結構たくさん情報が入っている。これはちょっと簡単には追いかけられそうにないな。