Merge pull request #1002 from freechipsproject/trace
Add instruction-trace port
This commit is contained in:
commit
00cf089350
@ -65,6 +65,7 @@ case class TraceGenParams(
|
||||
memStart: BigInt, //p(ExtMem).base
|
||||
numGens: Int) extends GroundTestTileParams {
|
||||
def build(i: Int, p: Parameters): GroundTestTile = new TraceGenTile(i, this)(p)
|
||||
val trace = false
|
||||
}
|
||||
|
||||
trait HasTraceGenParams {
|
||||
|
@ -149,6 +149,16 @@ class PerfCounterIO(implicit p: Parameters) extends CoreBundle
|
||||
val inc = UInt(INPUT, log2Ceil(1+retireWidth))
|
||||
}
|
||||
|
||||
class TracedInstruction(implicit p: Parameters) extends CoreBundle {
|
||||
val valid = Bool()
|
||||
val addr = UInt(width = coreMaxAddrBits)
|
||||
val insn = UInt(width = iLen)
|
||||
val priv = UInt(width = 3)
|
||||
val exception = Bool()
|
||||
val cause = UInt(width = 1 + log2Ceil(xLen))
|
||||
val tval = UInt(width = coreMaxAddrBits max iLen)
|
||||
}
|
||||
|
||||
class CSRFileIO(implicit p: Parameters) extends CoreBundle
|
||||
with HasRocketCoreParameters {
|
||||
val interrupts = new TileInterrupts().asInput
|
||||
@ -192,6 +202,8 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle
|
||||
val bp = Vec(nBreakpoints, new BP).asOutput
|
||||
val pmp = Vec(nPMPs, new PMP).asOutput
|
||||
val counters = Vec(nPerfCounters, new PerfCounterIO)
|
||||
val inst = Vec(retireWidth, UInt(width = iLen)).asInput
|
||||
val trace = Vec(retireWidth, new TracedInstruction).asOutput
|
||||
}
|
||||
|
||||
class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Parameters) extends CoreModule()(p)
|
||||
@ -506,15 +518,14 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
||||
assert(!io.singleStep || io.retire <= UInt(1))
|
||||
assert(!reg_singleStepped || io.retire === UInt(0))
|
||||
|
||||
when (exception) {
|
||||
val epc = ~(~io.pc | (coreInstBytes-1))
|
||||
|
||||
val write_badaddr = cause isOneOf (Causes.illegal_instruction, Causes.breakpoint,
|
||||
Causes.misaligned_load, Causes.misaligned_store, Causes.misaligned_fetch,
|
||||
Causes.load_access, Causes.store_access, Causes.fetch_access,
|
||||
Causes.load_page_fault, Causes.store_page_fault, Causes.fetch_page_fault)
|
||||
val badaddr_value = Mux(write_badaddr, io.badaddr, 0.U)
|
||||
|
||||
when (exception) {
|
||||
when (trapToDebug) {
|
||||
when (!reg_debug) {
|
||||
reg_debug := true
|
||||
@ -756,6 +767,16 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
||||
}
|
||||
}
|
||||
|
||||
for (((t, insn), i) <- (io.trace zip io.inst).zipWithIndex) {
|
||||
t.exception := io.retire >= i && exception
|
||||
t.valid := io.retire > i || t.exception
|
||||
t.insn := insn
|
||||
t.addr := io.pc
|
||||
t.priv := Cat(reg_debug, reg_mstatus.prv)
|
||||
t.cause := Cat(cause(xLen-1), cause(log2Ceil(xLen)-1, 0))
|
||||
t.tval := badaddr_value
|
||||
}
|
||||
|
||||
def chooseInterrupt(masks: Seq[UInt]): (Bool, UInt) = {
|
||||
val nonstandard = supported_interrupts.getWidth-1 to 12 by -1
|
||||
// MEI, MSI, MTI, SEI, SSI, STI, UEI, USI, UTI
|
||||
|
@ -16,7 +16,6 @@ class Instruction(implicit val p: Parameters) extends ParameterizedBundle with H
|
||||
val rvc = Bool()
|
||||
val inst = new ExpandedInstruction
|
||||
val raw = UInt(width = 32)
|
||||
val cinst = UInt(width = 32)
|
||||
require(coreInstBits == (if (usingCompressed) 16 else 32))
|
||||
}
|
||||
|
||||
@ -96,7 +95,6 @@ class IBuf(implicit p: Parameters) extends CoreModule {
|
||||
exp.io.in := curInst
|
||||
io.inst(i).bits.inst := exp.io.out
|
||||
io.inst(i).bits.raw := curInst
|
||||
io.inst(i).bits.cinst := Mux(exp.io.rvc, curInst & 0xFFFF, curInst)
|
||||
|
||||
if (usingCompressed) {
|
||||
val replay = ic_replay(j) || (!exp.io.rvc && (btbHitMask(j) || ic_replay(j+1)))
|
||||
|
@ -136,7 +136,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
||||
val ex_reg_replay = Reg(Bool())
|
||||
val ex_reg_pc = Reg(UInt())
|
||||
val ex_reg_inst = Reg(Bits())
|
||||
val ex_reg_cinst = Reg(Bits())
|
||||
val ex_reg_raw_inst = Reg(UInt())
|
||||
|
||||
val mem_reg_xcpt_interrupt = Reg(Bool())
|
||||
val mem_reg_valid = Reg(Bool())
|
||||
@ -153,7 +153,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
||||
val mem_reg_sfence = Reg(Bool())
|
||||
val mem_reg_pc = Reg(UInt())
|
||||
val mem_reg_inst = Reg(Bits())
|
||||
val mem_reg_cinst = Reg(Bits())
|
||||
val mem_reg_raw_inst = Reg(UInt())
|
||||
val mem_reg_wdata = Reg(Bits())
|
||||
val mem_reg_rs2 = Reg(Bits())
|
||||
val take_pc_mem = Wire(Bool())
|
||||
@ -167,7 +167,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
||||
val wb_reg_sfence = Reg(Bool())
|
||||
val wb_reg_pc = Reg(UInt())
|
||||
val wb_reg_inst = Reg(Bits())
|
||||
val wb_reg_cinst = Reg(Bits())
|
||||
val wb_reg_raw_inst = Reg(UInt())
|
||||
val wb_reg_wdata = Reg(Bits())
|
||||
val wb_reg_rs2 = Reg(Bits())
|
||||
val take_pc_wb = Wire(Bool())
|
||||
@ -178,7 +178,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
||||
// decode stage
|
||||
val ibuf = Module(new IBuf)
|
||||
val id_expanded_inst = ibuf.io.inst.map(_.bits.inst)
|
||||
val id_nonexpanded_inst = ibuf.io.inst.map(_.bits.cinst)
|
||||
val id_raw_inst = ibuf.io.inst.map(_.bits.raw)
|
||||
val id_inst = id_expanded_inst.map(_.bits)
|
||||
ibuf.io.imem <> io.imem.resp
|
||||
ibuf.io.kill := take_pc
|
||||
@ -335,7 +335,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
||||
}
|
||||
}
|
||||
when (id_illegal_insn) {
|
||||
val inst = Mux(ibuf.io.inst(0).bits.rvc, ibuf.io.inst(0).bits.raw(15, 0), ibuf.io.inst(0).bits.raw)
|
||||
val inst = Mux(ibuf.io.inst(0).bits.rvc, id_raw_inst(0)(15, 0), id_raw_inst(0))
|
||||
ex_reg_rs_bypass(0) := false
|
||||
ex_reg_rs_lsb(0) := inst(log2Ceil(bypass_sources.size)-1, 0)
|
||||
ex_reg_rs_msb(0) := inst >> log2Ceil(bypass_sources.size)
|
||||
@ -344,7 +344,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
||||
when (!ctrl_killd || csr.io.interrupt || ibuf.io.inst(0).bits.replay) {
|
||||
ex_reg_cause := id_cause
|
||||
ex_reg_inst := id_inst(0)
|
||||
ex_reg_cinst := id_nonexpanded_inst(0)
|
||||
ex_reg_raw_inst := id_raw_inst(0)
|
||||
ex_reg_pc := ibuf.io.pc
|
||||
ex_reg_btb_resp := ibuf.io.btb_resp
|
||||
}
|
||||
@ -405,7 +405,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
||||
|
||||
mem_reg_cause := ex_cause
|
||||
mem_reg_inst := ex_reg_inst
|
||||
mem_reg_cinst := ex_reg_cinst
|
||||
mem_reg_raw_inst := ex_reg_raw_inst
|
||||
mem_reg_pc := ex_reg_pc
|
||||
mem_reg_wdata := alu.io.out
|
||||
|
||||
@ -453,7 +453,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
||||
}
|
||||
wb_reg_cause := mem_cause
|
||||
wb_reg_inst := mem_reg_inst
|
||||
wb_reg_cinst := mem_reg_cinst
|
||||
wb_reg_raw_inst := mem_reg_raw_inst
|
||||
wb_reg_pc := mem_reg_pc
|
||||
}
|
||||
|
||||
@ -513,10 +513,11 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
||||
when (rf_wen) { rf.write(rf_waddr, rf_wdata) }
|
||||
|
||||
// hook up control/status regfile
|
||||
csr.io.decode.csr := ibuf.io.inst(0).bits.raw(31,20)
|
||||
csr.io.decode.csr := id_raw_inst(0)(31,20)
|
||||
csr.io.exception := wb_xcpt
|
||||
csr.io.cause := wb_cause
|
||||
csr.io.retire := wb_valid
|
||||
csr.io.inst(0) := Cat(Mux(wb_reg_rvc, 0.U, wb_reg_inst >> 16), wb_reg_raw_inst(15, 0))
|
||||
csr.io.interrupts := io.interrupts
|
||||
csr.io.hartid := io.hartid
|
||||
io.fpu.fcsr_rm := csr.io.fcsr_rm
|
||||
@ -530,6 +531,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
||||
csr.io.rw.addr := wb_reg_inst(31,20)
|
||||
csr.io.rw.cmd := Mux(wb_reg_valid, wb_ctrl.csr, CSR.N)
|
||||
csr.io.rw.wdata := wb_reg_wdata
|
||||
io.trace := csr.io.trace
|
||||
|
||||
val hazard_targets = Seq((id_ctrl.rxs1 && id_raddr1 =/= UInt(0), id_raddr1),
|
||||
(id_ctrl.rxs2 && id_raddr2 =/= UInt(0), id_raddr2),
|
||||
@ -664,28 +666,24 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
||||
csr.io.counters foreach { c => c.inc := RegNext(perfEvents.evaluate(c.eventSel)) }
|
||||
|
||||
if (enableCommitLog) {
|
||||
val pc = Wire(SInt(width=xLen))
|
||||
pc := wb_reg_pc.asSInt
|
||||
val inst = wb_reg_inst
|
||||
val cinst = wb_reg_cinst
|
||||
val rd = RegNext(RegNext(RegNext(id_waddr)))
|
||||
val t = csr.io.trace(0)
|
||||
val rd = wb_waddr
|
||||
val wfd = wb_ctrl.wfd
|
||||
val wxd = wb_ctrl.wxd
|
||||
val has_data = wb_wen && !wb_set_sboard
|
||||
val priv = csr.io.status.prv
|
||||
|
||||
when (wb_valid) {
|
||||
when (t.valid) {
|
||||
when (wfd) {
|
||||
printf ("%d 0x%x (0x%x) f%d p%d 0xXXXXXXXXXXXXXXXX\n", priv, pc, cinst, rd, rd+UInt(32))
|
||||
printf ("%d 0x%x (0x%x) f%d p%d 0xXXXXXXXXXXXXXXXX\n", t.priv, t.addr, t.insn, rd, rd+UInt(32))
|
||||
}
|
||||
.elsewhen (wxd && rd =/= UInt(0) && has_data) {
|
||||
printf ("%d 0x%x (0x%x) x%d 0x%x\n", priv, pc, cinst, rd, rf_wdata)
|
||||
printf ("%d 0x%x (0x%x) x%d 0x%x\n", t.priv, t.addr, t.insn, rd, rf_wdata)
|
||||
}
|
||||
.elsewhen (wxd && rd =/= UInt(0) && !has_data) {
|
||||
printf ("%d 0x%x (0x%x) x%d p%d 0xXXXXXXXXXXXXXXXX\n", priv, pc, cinst, rd, rd)
|
||||
printf ("%d 0x%x (0x%x) x%d p%d 0xXXXXXXXXXXXXXXXX\n", t.priv, t.addr, t.insn, rd, rd)
|
||||
}
|
||||
.otherwise {
|
||||
printf ("%d 0x%x (0x%x)\n", priv, pc, cinst)
|
||||
printf ("%d 0x%x (0x%x)\n", t.priv, t.addr, t.insn)
|
||||
}
|
||||
}
|
||||
|
||||
@ -695,11 +693,11 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
||||
}
|
||||
else {
|
||||
printf("C%d: %d [%d] pc=[%x] W[r%d=%x][%d] R[r%d=%x] R[r%d=%x] inst=[%x] DASM(%x)\n",
|
||||
io.hartid, csr.io.time(31,0), wb_valid, wb_reg_pc,
|
||||
io.hartid, csr.io.time(31,0), csr.io.trace(0).valid, csr.io.trace(0).addr(vaddrBitsExtended-1, 0),
|
||||
Mux(rf_wen && !(wb_set_sboard && wb_wen), rf_waddr, UInt(0)), rf_wdata, rf_wen,
|
||||
wb_reg_inst(19,15), Reg(next=Reg(next=ex_rs(0))),
|
||||
wb_reg_inst(24,20), Reg(next=Reg(next=ex_rs(1))),
|
||||
wb_reg_cinst, wb_reg_cinst)
|
||||
csr.io.trace(0).insn, csr.io.trace(0).insn)
|
||||
}
|
||||
|
||||
val max_core_cycles = PlusArg("max-core-cycles",
|
||||
|
@ -21,6 +21,7 @@ trait TileParams {
|
||||
val dcache: Option[DCacheParams]
|
||||
val rocc: Seq[RoCCParams]
|
||||
val btb: Option[BTBParams]
|
||||
val trace: Boolean
|
||||
}
|
||||
|
||||
trait HasTileParameters {
|
||||
@ -37,6 +38,7 @@ trait HasTileParameters {
|
||||
|
||||
def xLen: Int = p(XLen)
|
||||
def xBytes: Int = xLen / 8
|
||||
def iLen: Int = 32
|
||||
def pgIdxBits: Int = 12
|
||||
def pgLevelBits: Int = 10 - log2Ceil(xLen / 32)
|
||||
def vaddrBits: Int = pgIdxBits + pgLevels * pgLevelBits
|
||||
@ -92,6 +94,10 @@ trait HasExternallyDrivenTileConstants extends Bundle with HasTileParameters {
|
||||
val reset_vector = UInt(INPUT, resetVectorLen)
|
||||
}
|
||||
|
||||
trait CanHaveInstructionTracePort extends Bundle with HasTileParameters {
|
||||
val trace = tileParams.trace.option(Vec(tileParams.core.retireWidth, new TracedInstruction).asOutput)
|
||||
}
|
||||
|
||||
/** Base class for all Tiles that use TileLink */
|
||||
abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends BareTile
|
||||
with HasTileParameters
|
||||
@ -102,6 +108,7 @@ abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends
|
||||
class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer)
|
||||
with HasTileLinkMasterPortBundle
|
||||
with HasExternallyDrivenTileConstants
|
||||
with CanHaveInstructionTracePort
|
||||
|
||||
class BaseTileModule[+L <: BaseTile, +B <: BaseTileBundle[L]](_outer: L, _io: () => B) extends BareTileModule(_outer, _io)
|
||||
with HasTileParameters
|
||||
|
@ -75,5 +75,6 @@ trait HasCoreIO extends HasTileParameters {
|
||||
val ptw = new DatapathPTWIO().flip
|
||||
val fpu = new FPUCoreIO().flip
|
||||
val rocc = new RoCCCoreIO().flip
|
||||
val trace = Vec(coreParams.retireWidth, new TracedInstruction).asOutput
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ case class RocketTileParams(
|
||||
btb: Option[BTBParams] = Some(BTBParams()),
|
||||
dataScratchpadBytes: Int = 0,
|
||||
boundaryBuffers: Boolean = false,
|
||||
trace: Boolean = false,
|
||||
name: Option[String] = Some("tile"),
|
||||
externalMasterBuffers: Int = 0,
|
||||
externalSlaveBuffers: Int = 0) extends TileParams {
|
||||
@ -139,6 +140,7 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
|
||||
val core = Module(p(BuildCore)(outer.p))
|
||||
decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector
|
||||
core.io.hartid := io.hartid // Pass through the hartid
|
||||
io.trace.foreach { _ := core.io.trace }
|
||||
outer.frontend.module.io.cpu <> core.io.imem
|
||||
outer.frontend.module.io.reset_vector := io.reset_vector
|
||||
outer.frontend.module.io.hartid := io.hartid
|
||||
@ -196,7 +198,7 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p:
|
||||
}
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val io = new CoreBundle with HasExternallyDrivenTileConstants {
|
||||
val io = new CoreBundle with HasExternallyDrivenTileConstants with CanHaveInstructionTracePort {
|
||||
val master = masterNode.bundleOut
|
||||
val slave = slaveNode.bundleIn
|
||||
val asyncInterrupts = asyncIntNode.bundleIn
|
||||
@ -206,6 +208,7 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p:
|
||||
// signals that do not change based on crossing type:
|
||||
rocket.module.io.hartid := io.hartid
|
||||
rocket.module.io.reset_vector := io.reset_vector
|
||||
io.trace.foreach { _ := rocket.module.io.trace.get }
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user