BOOMv3側の性能をKonataでチェックするために、BOOMのログからKanataのフォーマットを生成してみた。
まず、BOOMのログ生成部に以下のような変更を加えて、各命令におけるコミットのタイミングを出力する。 主にやっていることは、ログの生成と、ログの先頭にサイクル時間をつけ足していることだ。
diff --git a/src/main/scala/common/parameters.scala b/src/main/scala/common/parameters.scala index 24e2beb4..3328f55e 100644 --- a/src/main/scala/common/parameters.scala +++ b/src/main/scala/common/parameters.scala @@ -98,9 +98,9 @@ case class BoomCoreParams( scontextWidth: Int = 0, /* debug stuff */ - enableCommitLogPrintf: Boolean = false, - enableBranchPrintf: Boolean = false, - enableMemtracePrintf: Boolean = false + enableCommitLogPrintf: Boolean = true, + enableBranchPrintf: Boolean = true, + enableMemtracePrintf: Boolean = true // DOC include end: BOOM Parameters ) extends freechips.rocketchip.tile.CoreParams diff --git a/src/main/scala/exu/core.scala b/src/main/scala/exu/core.scala index b267c020..f777ec39 100644 --- a/src/main/scala/exu/core.scala +++ b/src/main/scala/exu/core.scala @@ -1332,20 +1332,23 @@ class BoomCore(usingTrace: Boolean)(implicit p: Parameters) extends BoomModule if (COMMIT_LOG_PRINTF) { var new_commit_cnt = 0.U + val time = csr.io.time + for (w <- 0 until coreWidth) { val priv = RegNext(csr.io.status.prv) // erets change the privilege. Get the old one // To allow for diffs against spike :/ def printf_inst(uop: MicroOp) = { when (uop.is_rvc) { - printf("(0x%x)", uop.debug_inst(15,0)) + printf("DASM(0x%x)", uop.debug_inst(15,0)) } .otherwise { - printf("(0x%x)", uop.debug_inst) + printf("DASM(0x%x)", uop.debug_inst) } } when (rob.io.commit.arch_valids(w)) { - printf("%d 0x%x ", + printf("%d %d 0x%x ", + time, priv, Sext(rob.io.commit.uops(w).debug_pc(vaddrBits-1,0), xLen)) printf_inst(rob.io.commit.uops(w))
これで、以下のようなログが生成される。
860 3 0x0000000080003282 addi a3, a4, 3 x13 0x0000000080006d6b 861 3 0x0000000080003286 sb a5, 2(a4) MT 000000000001955a 02 01 0 0080006d6a 0000000000000000 0000000000000000 862 3 0x000000008000328a bgeu a3, a6, pc + 128 874 3 0x000000008000328e addi a3, a4, 4 x13 0x0000000080006d6c 874 3 0x0000000080003292 sb a5, 3(a4) MT 0000000000019567 02 01 0 0080006d6b 0000000000000000 0000000000000000 875 3 0x0000000080003296 bgeu a3, a6, pc + 116 878 3 0x000000008000330a ret 881 3 0x0000000080003394 c.mv a0, s1 x10 0x0000000000000000 881 3 0x0000000080003396 c.mv a1, s2 x11 0x0000000000000001 882 3 0x0000000080003398 jal pc - 0x5ae x 1 0x000000008000339c 901 3 0x0000000080002dea c.beqz a0, pc + 4 904 3 0x0000000080002dee ret 907 3 0x000000008000339c c.li a1, 0 x11 0x0000000000000000 908 3 0x000000008000339e c.li a0, 0 x10 0x0000000000000000 909 3 0x00000000800033a0 jal pc + 0x132 x 1 0x00000000800033a4 927 3 0x00000000800034d2 c.addi16sp sp, -208 x 2 0x0000000080026b80 927 3 0x00000000800034d4 c.li a1, 1 x11 0x0000000000000001 928 3 0x00000000800034d6 auipc a5, 0x0 x15 0x00000000800034d6 934 3 0x00000000800034da addi a5, a5, 1698 x15 0x0000000080003b78
これをさらに加工してKanataフォーマットに変換するコードは以下だ:
#!/bin/ruby kanata_fp = File.open("kanata.boom.log", "w") kanata_fp.write("Kanata\t0004\n") kanata_fp.write("C\t0\n") inst_idx = 0 cycle = 0 while str = STDIN.gets if str =~ /^ +(\d+) \d (0x\h+) ([\w\-\+., \(\)]+)$/ then now_cycle = $1.to_i pc = $2 mnemonic = $3 else puts (str) next end if inst_idx != 0 then kanata_fp.write("E\t" + (inst_idx-1).to_s + "\t0\tCMT\n") kanata_fp.write("R\t" + (inst_idx-1).to_s + "\t" + (inst_idx-1).to_s + "\t0\n") end kanata_fp.write("I\t" + inst_idx.to_s + "\t" + inst_idx.to_s + "\t0\n") kanata_fp.write("L\t" + inst_idx.to_s + "\t0\t" + pc +":"+ mnemonic + "\n") kanata_fp.write("S\t" + inst_idx.to_s + "\t0\tCMT\n") kanata_fp.write("C\t" + (now_cycle - cycle).to_s + "\n") inst_idx = inst_idx + 1 cycle = now_cycle end
このコードはイマイチで、同時に複数コミットが発生した命令を正確に表示することができないが、まあ傾向はつかめるだろうからそれで良しとする。
これにより、以下のようなビューワでの表示が可能となる。
ちなみに、自作CPU側はもう少し詳細なログを出すことができる。