RISC-VのOoOコアであるSonicBOOMのデザインを勉強している。前回に続いて、以下のテストパタンを用いてALUのデータパスがどのようにして選択されているのかを観察している。
.section .text .global simple_add simple_add: addi x10, x0, 1 addi x11, x10, 2 addi x12, x11, 3 addi x13, x12, 4 addi x14, x13, 5 addi x15, x14, 6 addi x16, x15, 7 addi x17, x16, 8 addi x18, x17, 9 mv x10, x18 ret
データパスの構成方法について、BOOMでは以下のような記述で演算器を構築することができるようになっている。
src/main/scala/exu/core.scala
// Only holds integer-registerfile execution units. val exe_units = new boom.exu.ExecutionUnits(fpu=false)
src/main/scala/exu/execution-units/execution-units.scala
/** * Top level class to wrap all execution units together into a "collection" * * @param fpu using a FPU? */ class ExecutionUnits(val fpu: Boolean)(implicit val p: Parameters) extends HasBoomCoreParameters { ... if (!fpu) { val int_width = issueParams.find(_.iqType == IQT_INT.litValue).get.issueWidth for (w <- 0 until memWidth) { val memExeUnit = Module(new ALUExeUnit( hasAlu = false, hasMem = true)) memExeUnit.io.ll_iresp.ready := DontCare exe_units += memExeUnit } for (w <- 0 until int_width) { def is_nth(n: Int): Boolean = w == ((n) % int_width) val alu_exe_unit = Module(new ALUExeUnit( hasJmpUnit = is_nth(0), hasCSR = is_nth(1), hasRocc = is_nth(1) && usingRoCC, hasMul = is_nth(2), hasDiv = is_nth(3), hasIfpu = is_nth(4) && usingFPU)) exe_units += alu_exe_unit } } else { val fp_width = issueParams.find(_.iqType == IQT_FP.litValue).get.issueWidth for (w <- 0 until fp_width) { val fpu_exe_unit = Module(new FPUExeUnit(hasFpu = true, hasFdiv = usingFDivSqrt && (w==0), hasFpiu = (w==0))) exe_units += fpu_exe_unit } } ...
一見すると意味不明だが、最初のfor
ループでメモリアドレス計算のためのALUを生成し、次のループで整数演算用のALUユニットを生成している。ALUユニットの生成においてis_nth()
というのを使っているが、これはつまりn
個のALUを生成するときに、
0 % n
番目のALUはJmpUnit用1 % n
番目のALUはCSR用1 % n
番目のALUはRoCC用2 % n
番目のALUはMultiplier用3 % n
番目のALUはDivider用4 % n
番目のALUはFPUの整数側用
という割り付けになっている(記事を書きながら思ったが、つまりこれは4番目以降の演算器を生成してもデフォルト(通常算術演算)用以外のALUを生成することは出来ないということか)。
このALUに入力するためのデータ入力だが、基本的にはiregfile
からの入力となっているがそれ以外にBypassからの入力も受け付けている。これらの入力オペランドの選択はiregister_read
ユニットによって行われており、ここでBypassデータの選択が行われている。