Rocket-Chip で測定したベンチマークプログラムを、アウトオブオーダプロセッサであるBOOMでも測定してみたい。
BOOMはVersion1 (BOOMv1) と Version2 (BOOMv2) が存在しているのだが、とりあえずBOOMv2 で試してみよう。
結構試行錯誤しないと動作しなかったのでまとめておく。
BootROM の改造
BOOMv2のブートROMは、デフォルトでは./bootrom/bootrom.img
を使っている。
- bootrom/bootrom.S
.text .global _start _start: // This boot ROM doesn't know about any boot devices, so it just spins, // waiting for the debugger to load a program and change the PC. j _start // reset vector .word 0 // reserved .word 0 // reserved ...
これでは、デフォルトではループしっぱなしである。別のブートROMを用意して、そちらからブートするように変更する。
- program/boomv2_boot/bootrom.S
#define DRAM_BASE 0x80000000 .section .text.start, "ax", @progbits .globl _start _start: j start_routine .rept 15 nop .endr start_routine: csrr a0, mhartid la a1, _dtb li sp, 0x80010000 li a2, 0x80000000 jr a2 fin_loop: j fin_loop
BootROMの設定は、以下のscala記述によって設定されている。
diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 3f265d84..dcd0b0d3 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -26,7 +26,7 @@ class BaseCoreplexConfig extends Config ((site, here, up) => { case NTiles => site(RocketTilesKey).size case CBusConfig => TLBusConfig(beatBytes = site(XLen)/8) case L1toL2Config => TLBusConfig(beatBytes = site(XLen)/8) // increase for more PCIe bandwidth - case BootROMFile => "./bootrom/bootrom.img" + case BootROMFile => "../../program/boomv2_boot/bootrom.img" case BroadcastConfig => BroadcastConfig() case BankedL2Config => BankedL2Config() case CacheBlockBytes => 64
詳細は不明だが、どうやらBootROMの0x0cの場所は0でなければならないらしい?そんなルールは不要なので削除する。
これらをパッチとして用意し、Verilogを生成する際に適用する。
diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index 78f4bb9c..23e98af8 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -93,8 +93,8 @@ object GenerateBootROM { require(address == address.toInt) val configStringAddr = address.toInt + rom.capacity - require(rom.getInt(12) == 0, - "Config string address position should not be occupied by code") + // require(rom.getInt(12) == 0, + // "Config string address position should not be occupied by code") rom.putInt(12, configStringAddr) rom.array() ++ (configString.getBytes.toSeq) }
デバッグ情報を生成する
たとえシミュレーションができるようになっても、デバッグ情報が出てこないと正しく命令が実行できているかを解析できない。 そこで、scalaの実装の部分を少し変更し、コミットログを表示させて、加工しやすいように変更する。BOOMv2 の実装の、ログ生成部分に以下の変更を加える。
diff --git a/src/main/scala/consts.scala b/src/main/scala/consts.scala index de697d3..38deea9 100755 --- a/src/main/scala/consts.scala +++ b/src/main/scala/consts.scala @@ -22,7 +22,7 @@ import util.Str trait BOOMDebugConstants { val DEBUG_PRINTF = false // use the Chisel printf functionality - val COMMIT_LOG_PRINTF = false // dump commit state, for comparision against ISA sim + val COMMIT_LOG_PRINTF = true // dump commit state, for comparision against ISA sim val O3PIPEVIEW_PRINTF = false // dump trace for O3PipeView from gem5 val O3_CYCLE_TIME = (1000)// "cycle" time expected by o3pipeview.py diff --git a/src/main/scala/core.scala b/src/main/scala/core.scala index ae238d5..de7a91f 100755 --- a/src/main/scala/core.scala +++ b/src/main/scala/core.scala @@ -1249,20 +1249,20 @@ class BoomCore(implicit p: Parameters, edge: uncore.tilelink2.TLEdgeOut) extends { when (rob.io.commit.uops(w).dst_rtype === RT_FIX && rob.io.commit.uops(w).ldst =/= UInt(0)) { - printf("%d 0x%x (0x%x) x%d 0x%x\n", - priv, Sext(rob.io.commit.uops(w).pc(vaddrBits,0), xLen), rob.io.commit.uops(w).inst, - rob.io.commit.uops(w).inst(RD_MSB,RD_LSB), rob.io.commit.uops(w).debug_wdata) + printf("%d %d 0x%x DASM(%x) x%d 0x%x\n", + debug_tsc_reg, priv, Sext(rob.io.commit.uops(w).pc(vaddrBits,0), xLen), rob.io.commit.uops(w).inst, + rob.io.commit.uops(w).inst(RD_MSB,RD_LSB), rob.io.commit.uops(w).debug_wdata) } .elsewhen (rob.io.commit.uops(w).dst_rtype === RT_FLT) { - printf("%d 0x%x (0x%x) f%d 0x%x\n", - priv, Sext(rob.io.commit.uops(w).pc(vaddrBits,0), xLen), rob.io.commit.uops(w).inst, - rob.io.commit.uops(w).inst(RD_MSB,RD_LSB), rob.io.commit.uops(w).debug_wdata) + printf("%d %d 0x%x DASM(%x) f%d 0x%x\n", + debug_tsc_reg, priv, Sext(rob.io.commit.uops(w).pc(vaddrBits,0), xLen), rob.io.commit.uops(w).inst, + rob.io.commit.uops(w).inst(RD_MSB,RD_LSB), rob.io.commit.uops(w).debug_wdata) } .otherwise { - printf("%d 0x%x (0x%x)\n", - priv, Sext(rob.io.commit.uops(w).pc(vaddrBits,0), xLen), rob.io.commit.uops(w).inst) + printf("%d %d 0x%x DASM(%x)\n", + debug_tsc_reg, priv, Sext(rob.io.commit.uops(w).pc(vaddrBits,0), xLen), rob.io.commit.uops(w).inst) } } }
ベンチマークプログラムのhexファイル生成
上記のブートコードでは、プログラムの開始位置を0x8000_0000に設定してある。これはCoreplexの外部にあるAXIメモリの先頭にあたる。
このAXIメモリもScalaで記述されており、そこに$readmemh
でプログラムのhexファイルを配置すれば良さそうだ。
と思って配置しようとしたら、大変なことに気がついた。8ビット毎にメモリが区切って実装してある!
- rtl/rocketchip.BOOMConfig.v
module AXI4RAM( ... reg [7:0] mem_0 [0:33554432-1]; ... reg [7:0] mem_1 [0:33554432-1]; ... reg [7:0] mem_6 [0:33554432-1]; ... reg [7:0] mem_7 [0:33554432-1];
AXIメモリを改造することもできるけど、面倒なのでhexファイルを8分割した。1バイト毎に8個のhexファイルに分割する。
- tp_F_fadd_s.dmp
... 80000020: 04000e13 li t3,64 80000024: 00000697 auipc a3,0x0 80000028: 1806a787 flw fa5,384(a3) # 800001a4 <run_bench+0x14> 8000002c: 00f7f753 fadd.s fa4,fa5,fa5 80000030: 00f7f6d3 fadd.s fa3,fa5,fa5 80000034: 00f7f653 fadd.s fa2,fa5,fa5 80000038: 00f7f5d3 fadd.s fa1,fa5,fa5 8000003c: 00f7f553 fadd.s fa0,fa5,fa5 80000040: 00f7f053 fadd.s ft0,fa5,fa5 80000044: fffe039b addiw t2,t3,-1 80000048: 00f7f753 fadd.s fa4,fa5,fa5 8000004c: 00f7f6d3 fadd.s fa3,fa5,fa5 80000050: 00f7f653 fadd.s fa2,fa5,fa5 ...
- tp_F_fadd_s.hex
... 13 0e 00 04 97 06 00 00 87 a7 06 18 53 f7 f7 00 d3 f6 f7 00 53 f6 f7 00 d3 f5 f7 00 53 f5 f7 00 53 f0 f7 00 9b 03 fe ff 53 f7 f7 00 d3 f6 f7 00
- tp_F_fadd_s.hex_0
89 30 00 23 13 87 d3 d3 53 53 53 53 1b d3 ...
こんな感じの細切れのhexファイルを生成するスクリプトを作って読み込ませた。
実行結果は以下だ。ここでは、tp_F_fadd_s.hex
を実行した例だ。 fadd.s 命令のスループットを測定する。
依存関係のある命令の実行だ。命令がキャッシュに載っている状態で、単精度の加算命令は演算に7サイクル必要であることが分かる。
... 3699 3 0x00000000800000bc fadd.s ft0, fa0, fa5 f 0 0x53babba753babba7 3706 3 0x00000000800000c0 fadd.s ft3, ft0, fa5 f 3 0x35d9bb6b35d9bb6b 3713 3 0x00000000800000c4 fadd.s ft4, ft3, fa5 f 4 0x53babba753babba7 3720 3 0x00000000800000c8 fadd.s ft5, ft4, fa5 f 5 0x35d9bb6b35d9bb6b 3727 3 0x00000000800000cc fadd.s ft6, ft5, fa5 f 6 0x53babba753babba7 3734 3 0x00000000800000d0 fadd.s ft7, ft6, fa5 f 7 0x35d9bb6b35d9bb6b 3741 3 0x00000000800000d4 fadd.s ft0, ft7, fa5 f 0 0x53babba753babba7 3748 3 0x00000000800000d8 fadd.s fa6, ft0, fa5 f16 0x35d9bb6b35d9bb6b 3755 3 0x00000000800000dc fadd.s fa7, fa6, fa5 f17 0x53babba753babba7 3762 3 0x00000000800000e0 fadd.s ft8, fa7, fa5 f28 0x35d9bb6b35d9bb6b 3769 3 0x00000000800000e4 fadd.s ft9, ft8, fa5 f29 0x53babba753babba7 ...