Skip to content

Commit

Permalink
Merge pull request #3560 from joey0320/trace-wb-dev
Browse files Browse the repository at this point in the history
Add hardware debug ROB
  • Loading branch information
jerryz123 authored Jan 29, 2024
2 parents 8026b6b + fd2316d commit baa9f45
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 20 deletions.
91 changes: 91 additions & 0 deletions src/main/scala/rocket/DebugROB.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import chisel3.util._
import chisel3.experimental.{IntParam}
import org.chipsalliance.cde.config.{Parameters}
import freechips.rocketchip.tile.{HasCoreParameters}
import freechips.rocketchip.util.DecoupledHelper

case class DebugROBParams(size: Int)

class WidenedTracedInstruction extends Bundle {
val valid = Bool()
Expand Down Expand Up @@ -102,3 +104,92 @@ object DebugROB {
debug_rob_push_wb.io.wb_data := data
}
}

class TaggedInstruction(val nXPR: Int)(implicit val p: Parameters) extends Bundle {
val insn = new TracedInstruction
val tag = UInt(log2Up(nXPR + 1).W)
val waiting = Bool()
}

class TaggedWbData(implicit val p: Parameters) extends Bundle with HasCoreParameters {
val valid = Bool()
val data = UInt(xLen.W)
}

class HardDebugROB(val traceRatio: Int, val nXPR: Int)(implicit val p: Parameters)
extends Module with HasCoreParameters
{
val io = IO(new Bundle {
val i_insn = Input(new TracedInstruction)
val should_wb = Input(Bool())
val has_wb = Input(Bool())
val tag = Input(UInt(log2Up(nXPR + 1).W))

val wb_val = Input(Bool())
val wb_tag = Input(UInt(log2Up(nXPR + 1).W))
val wb_data = Input(UInt(xLen.W))

val o_insn = Output(new TracedInstruction)
})

val iq = Module(new Queue(new TaggedInstruction(nXPR), traceRatio * nXPR, flow = true))

// No backpressure
assert(iq.io.enq.ready)

iq.io.enq.valid := io.i_insn.valid || io.i_insn.exception || io.i_insn.interrupt
iq.io.enq.bits.insn := io.i_insn
iq.io.enq.bits.tag := io.tag
iq.io.enq.bits.waiting := io.should_wb && !io.has_wb

val wb_q = Seq.fill(nXPR)(Reg(new TaggedWbData))

for (i <- 0 until nXPR) {
when (io.wb_val && i.U === io.wb_tag) {
assert(wb_q(i).valid === false.B)
wb_q(i).valid := true.B
wb_q(i).data := io.wb_data
}
}

val tag_matches = Seq.fill(nXPR)(Wire(Bool()))
for (i <- 0 until nXPR) {
val is_match = iq.io.deq.bits.waiting &&
(iq.io.deq.bits.tag === i.U) &&
wb_q(i).valid
when (is_match) {
tag_matches(i) := true.B
} .otherwise {
tag_matches(i) := false.B
}
}

val tag_match = tag_matches.reduce(_ || _)
val vinsn_rdy = !iq.io.deq.bits.waiting ||
(iq.io.deq.bits.tag >= nXPR.U) || // not integer instruction
tag_match
val maybeFire = Mux(iq.io.deq.bits.insn.valid, vinsn_rdy, true.B)
val fireTrace = DecoupledHelper(
iq.io.deq.valid,
maybeFire)

iq.io.deq.ready := fireTrace.fire(iq.io.deq.valid)
io.o_insn := iq.io.deq.bits.insn
io.o_insn.valid := iq.io.deq.fire && iq.io.deq.bits.insn.valid

for (i <- 0 until nXPR) {
when (tag_match && fireTrace.fire() && i.U === iq.io.deq.bits.tag) {
io.o_insn.wdata.get := wb_q(i).data
wb_q(i).valid := false.B
}
}

val qcnt = RegInit(0.U(64.W))
when (iq.io.enq.fire && !iq.io.deq.fire) {
qcnt := qcnt + 1.U
} .elsewhen (!iq.io.enq.fire && iq.io.deq.fire) {
qcnt := qcnt - 1.U
} .otherwise {
qcnt := qcnt
}
}
49 changes: 34 additions & 15 deletions src/main/scala/rocket/RocketCore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ case class RocketCoreParams(
mimpid: Int = 0x20181004, // release date in BCD
mulDiv: Option[MulDivParams] = Some(MulDivParams()),
fpu: Option[FPUParams] = Some(FPUParams()),
debugROB: Boolean = false, // if enabled, uses a C++ debug ROB to generate trace-with-wdata
debugROB: Option[DebugROBParams] = None, // if size < 1, SW ROB, else HW ROB
haveCease: Boolean = true, // non-standard CEASE instruction
haveSimTimeout: Boolean = true // add plusarg for simulation timeout
haveSimTimeout: Boolean = true, // add plusarg for simulation timeout
) extends CoreParams {
val lgPauseCycles = 5
val haveFSDirty = false
Expand All @@ -61,7 +61,7 @@ case class RocketCoreParams(
val retireWidth: Int = 1
val instBits: Int = if (useCompressed) 16 else 32
val lrscCycles: Int = 80 // worst case is 14 mispredicted branches + slop
val traceHasWdata: Boolean = false // ooo wb, so no wdata in trace
val traceHasWdata: Boolean = debugROB.isDefined // ooo wb, so no wdata in trace
override val customIsaExt = Option.when(haveCease)("xrocket") // CEASE instruction
override def minFLen: Int = fpu.map(_.minFLen).getOrElse(32)
override def customCSRs(implicit p: Parameters) = new RocketCustomCSRs
Expand Down Expand Up @@ -761,18 +761,37 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p)
io.rocc.csrs <> csr.io.roccCSRs
io.trace.time := csr.io.time
io.trace.insns := csr.io.trace
if (rocketParams.debugROB) {
val csr_trace_with_wdata = WireInit(csr.io.trace(0))
csr_trace_with_wdata.wdata.get := rf_wdata
DebugROB.pushTrace(clock, reset,
io.hartid, csr_trace_with_wdata,
(wb_ctrl.wfd || (wb_ctrl.wxd && wb_waddr =/= 0.U)) && !csr.io.trace(0).exception,
wb_ctrl.wxd && wb_wen && !wb_set_sboard,
wb_waddr + Mux(wb_ctrl.wfd, 32.U, 0.U))

io.trace.insns(0) := DebugROB.popTrace(clock, reset, io.hartid)

DebugROB.pushWb(clock, reset, io.hartid, ll_wen, rf_waddr, rf_wdata)
if (rocketParams.debugROB.isDefined) {
val sz = rocketParams.debugROB.get.size
if (sz < 1) { // use unsynthesizable ROB
val csr_trace_with_wdata = WireInit(csr.io.trace(0))
csr_trace_with_wdata.wdata.get := rf_wdata
DebugROB.pushTrace(clock, reset,
io.hartid, csr_trace_with_wdata,
(wb_ctrl.wfd || (wb_ctrl.wxd && wb_waddr =/= 0.U)) && !csr.io.trace(0).exception,
wb_ctrl.wxd && wb_wen && !wb_set_sboard,
wb_waddr + Mux(wb_ctrl.wfd, 32.U, 0.U))

io.trace.insns(0) := DebugROB.popTrace(clock, reset, io.hartid)

DebugROB.pushWb(clock, reset, io.hartid, ll_wen, rf_waddr, rf_wdata)
} else { // synthesizable ROB (no FPRs)
val csr_trace_with_wdata = WireInit(csr.io.trace(0))
csr_trace_with_wdata.wdata.get := rf_wdata

val debug_rob = Module(new HardDebugROB(sz, 32))
debug_rob.io.i_insn := csr_trace_with_wdata
debug_rob.io.should_wb := (wb_ctrl.wfd || (wb_ctrl.wxd && wb_waddr =/= 0.U)) &&
!csr.io.trace(0).exception
debug_rob.io.has_wb := wb_ctrl.wxd && wb_wen && !wb_set_sboard
debug_rob.io.tag := wb_waddr + Mux(wb_ctrl.wfd, 32.U, 0.U)

debug_rob.io.wb_val := ll_wen
debug_rob.io.wb_tag := rf_waddr
debug_rob.io.wb_data := rf_wdata

io.trace.insns(0) := debug_rob.io.o_insn
}
} else {
io.trace.insns := csr.io.trace
}
Expand Down
9 changes: 5 additions & 4 deletions src/main/scala/subsystem/Configs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -447,11 +447,12 @@ class WithFPUWithoutDivSqrt extends Config((site, here, up) => {
}
})

class WithRocketDebugROB(enable: Boolean = true) extends Config((site, here, up) => {
class WithRocketDebugROB(enable: Boolean = true, size: Int = 0) extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(debugROB = enable)
))
case tp: RocketTileAttachParams if (enable) =>
tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(debugROB = Some(DebugROBParams(size)))
))
}
})

Expand Down
4 changes: 3 additions & 1 deletion src/main/scala/tile/FPU.scala
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,9 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
val io = IO(new FPUIO)

val (useClockGating, useDebugROB) = coreParams match {
case r: RocketCoreParams => (r.clockGate, r.debugROB)
case r: RocketCoreParams =>
val sz = if (r.debugROB.isDefined) r.debugROB.get.size else 1
(r.clockGate, sz < 1)
case _ => (false, false)
}
val clock_en_reg = Reg(Bool())
Expand Down

0 comments on commit baa9f45

Please sign in to comment.