1
0

Add D-mode single-step support

This commit is contained in:
Andrew Waterman 2016-06-15 16:21:24 -07:00
parent e3816d5fc7
commit 0b4c8e9af7
2 changed files with 19 additions and 11 deletions

View File

@ -107,8 +107,8 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle {
val csr_stall = Bool(OUTPUT) val csr_stall = Bool(OUTPUT)
val csr_xcpt = Bool(OUTPUT) val csr_xcpt = Bool(OUTPUT)
val eret = Bool(OUTPUT) val eret = Bool(OUTPUT)
val singleStep = Bool(OUTPUT)
val prv = UInt(OUTPUT, PRV.SZ)
val status = new MStatus().asOutput val status = new MStatus().asOutput
val ptbr = UInt(OUTPUT, paddrBits) val ptbr = UInt(OUTPUT, paddrBits)
val evec = UInt(OUTPUT, vaddrBitsExtended) val evec = UInt(OUTPUT, vaddrBitsExtended)
@ -168,10 +168,17 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
Causes.fault_store, Causes.fault_store,
Causes.user_ecall).map(1 << _).sum) Causes.user_ecall).map(1 << _).sum)
val exception = io.exception || io.csr_xcpt
val reg_debug = Reg(init=Bool(false)) val reg_debug = Reg(init=Bool(false))
val reg_dpc = Reg(UInt(width = vaddrBitsExtended)) val reg_dpc = Reg(UInt(width = vaddrBitsExtended))
val reg_dscratch = Reg(UInt(width = xLen)) val reg_dscratch = Reg(UInt(width = xLen))
val reg_singleStepped = Reg(Bool())
when (io.retire(0) || exception) { reg_singleStepped := true }
when (!io.singleStep) { reg_singleStepped := false }
assert(!io.singleStep || io.retire <= UInt(1))
assert(!reg_singleStepped || io.retire === UInt(0))
val reg_tdrselect = Reg(new TDRSelect) val reg_tdrselect = Reg(new TDRSelect)
val reg_bp = Reg(Vec(1 << log2Up(p(NBreakpoints)), new BP)) val reg_bp = Reg(Vec(1 << log2Up(p(NBreakpoints)), new BP))
@ -210,7 +217,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
val all_interrupts = m_interrupts | s_interrupts val all_interrupts = m_interrupts | s_interrupts
val interruptMSB = BigInt(1) << (xLen-1) val interruptMSB = BigInt(1) << (xLen-1)
val interruptCause = interruptMSB + PriorityEncoder(all_interrupts) val interruptCause = interruptMSB + PriorityEncoder(all_interrupts)
io.interrupt := all_interrupts.orR io.interrupt := all_interrupts.orR || reg_singleStepped
io.interrupt_cause := interruptCause io.interrupt_cause := interruptCause
io.bp := reg_bp take p(NBreakpoints) io.bp := reg_bp take p(NBreakpoints)
@ -350,7 +357,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
val insn_sfence_vm = do_system_insn && opcode(4) val insn_sfence_vm = do_system_insn && opcode(4)
val insn_wfi = do_system_insn && opcode(5) val insn_wfi = do_system_insn && opcode(5)
val csr_xcpt = (cpu_wen && read_only) || io.csr_xcpt := (cpu_wen && read_only) ||
(cpu_ren && (!priv_sufficient || !addr_valid || fp_csr && !io.status.fs.orR)) || (cpu_ren && (!priv_sufficient || !addr_valid || fp_csr && !io.status.fs.orR)) ||
(system_insn && !priv_sufficient) || (system_insn && !priv_sufficient) ||
insn_call || insn_break insn_call || insn_break
@ -359,36 +366,36 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
when (read_mip.orR) { reg_wfi := false } when (read_mip.orR) { reg_wfi := false }
val cause = val cause =
Mux(!csr_xcpt, io.cause, Mux(!io.csr_xcpt, io.cause,
Mux(insn_call, reg_mstatus.prv + Causes.user_ecall, Mux(insn_call, reg_mstatus.prv + Causes.user_ecall,
Mux[UInt](insn_break, Causes.breakpoint, Causes.illegal_instruction))) Mux[UInt](insn_break, Causes.breakpoint, Causes.illegal_instruction)))
val cause_lsbs = cause(log2Up(xLen)-1,0) val cause_lsbs = cause(log2Up(xLen)-1,0)
val causeIsDebugInt = cause(xLen-1) && cause_lsbs === debugIntCause val causeIsDebugInt = cause(xLen-1) && cause_lsbs === debugIntCause
val causeIsDebugBreak = cause === Causes.breakpoint && Cat(reg_dcsr.ebreakm, reg_dcsr.ebreakh, reg_dcsr.ebreaks, reg_dcsr.ebreaku)(reg_mstatus.prv) val causeIsDebugBreak = cause === Causes.breakpoint && Cat(reg_dcsr.ebreakm, reg_dcsr.ebreakh, reg_dcsr.ebreaks, reg_dcsr.ebreaku)(reg_mstatus.prv)
val trapToDebug = Bool(usingDebug) && (causeIsDebugInt || causeIsDebugBreak || reg_debug) val trapToDebug = Bool(usingDebug) && (reg_singleStepped || causeIsDebugInt || causeIsDebugBreak || reg_debug)
val delegate = Bool(p(UseVM)) && reg_mstatus.prv < PRV.M && Mux(cause(xLen-1), reg_mideleg(cause_lsbs), reg_medeleg(cause_lsbs)) val delegate = Bool(p(UseVM)) && reg_mstatus.prv < PRV.M && Mux(cause(xLen-1), reg_mideleg(cause_lsbs), reg_medeleg(cause_lsbs))
val debugTVec = Mux(reg_debug, UInt(0x808), UInt(0x800)) val debugTVec = Mux(reg_debug, UInt(0x808), UInt(0x800))
val tvec = Mux(trapToDebug, debugTVec, Mux(delegate, reg_stvec.sextTo(vaddrBitsExtended), reg_mtvec)) val tvec = Mux(trapToDebug, debugTVec, Mux(delegate, reg_stvec.sextTo(vaddrBitsExtended), reg_mtvec))
val epc = Mux(csr_debug, reg_dpc, Mux(Bool(p(UseVM)) && !csr_addr_priv(1), reg_sepc, reg_mepc)) val epc = Mux(csr_debug, reg_dpc, Mux(Bool(p(UseVM)) && !csr_addr_priv(1), reg_sepc, reg_mepc))
io.fatc := insn_sfence_vm io.fatc := insn_sfence_vm
io.evec := Mux(io.exception || csr_xcpt, tvec, epc) io.evec := Mux(exception, tvec, epc)
io.ptbr := reg_sptbr io.ptbr := reg_sptbr
io.csr_xcpt := csr_xcpt
io.eret := insn_ret io.eret := insn_ret
io.singleStep := reg_dcsr.step && !reg_debug
io.status := reg_mstatus io.status := reg_mstatus
io.status.sd := io.status.fs.andR || io.status.xs.andR io.status.sd := io.status.fs.andR || io.status.xs.andR
io.status.debug := reg_debug io.status.debug := reg_debug
if (xLen == 32) if (xLen == 32)
io.status.sd_rv32 := io.status.sd io.status.sd_rv32 := io.status.sd
when (io.exception || csr_xcpt) { when (exception) {
val epc = ~(~io.pc | (coreInstBytes-1)) val epc = ~(~io.pc | (coreInstBytes-1))
val pie = read_mstatus(reg_mstatus.prv) val pie = read_mstatus(reg_mstatus.prv)
when (trapToDebug) { when (trapToDebug) {
reg_debug := true reg_debug := true
reg_dpc := epc reg_dpc := epc
reg_dcsr.cause := Mux(causeIsDebugInt, UInt(3), UInt(1)) reg_dcsr.cause := Mux(reg_singleStepped, UInt(4), Mux(causeIsDebugInt, UInt(3), UInt(1)))
reg_dcsr.prv := reg_mstatus.prv reg_dcsr.prv := reg_mstatus.prv
}.elsewhen (delegate) { }.elsewhen (delegate) {
reg_sepc := epc reg_sepc := epc
@ -427,7 +434,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
} }
} }
assert(PopCount(insn_ret :: io.exception :: csr_xcpt :: Nil) <= 1, "these conditions must be mutually exclusive") assert(PopCount(insn_ret :: io.exception :: io.csr_xcpt :: Nil) <= 1, "these conditions must be mutually exclusive")
io.time := reg_cycle io.time := reg_cycle
io.csr_stall := reg_wfi io.csr_stall := reg_wfi
@ -490,6 +497,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
when (decoded_addr(CSRs.dcsr)) { when (decoded_addr(CSRs.dcsr)) {
val new_dcsr = new DCSR().fromBits(wdata) val new_dcsr = new DCSR().fromBits(wdata)
reg_dcsr.halt := new_dcsr.halt reg_dcsr.halt := new_dcsr.halt
reg_dcsr.step := new_dcsr.step
reg_dcsr.ebreakm := new_dcsr.ebreakm reg_dcsr.ebreakm := new_dcsr.ebreakm
if (usingVM) reg_dcsr.ebreaks := new_dcsr.ebreaks if (usingVM) reg_dcsr.ebreaks := new_dcsr.ebreaks
if (usingUser) reg_dcsr.ebreaku := new_dcsr.ebreaku if (usingUser) reg_dcsr.ebreaku := new_dcsr.ebreaku

View File

@ -297,7 +297,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
ex_ctrl.csr := id_csr ex_ctrl.csr := id_csr
ex_reg_btb_hit := io.imem.btb_resp.valid ex_reg_btb_hit := io.imem.btb_resp.valid
when (io.imem.btb_resp.valid) { ex_reg_btb_resp := io.imem.btb_resp.bits } when (io.imem.btb_resp.valid) { ex_reg_btb_resp := io.imem.btb_resp.bits }
ex_reg_flush_pipe := id_ctrl.fence_i || id_csr_flush ex_reg_flush_pipe := id_ctrl.fence_i || id_csr_flush || csr.io.singleStep
ex_reg_load_use := id_load_use ex_reg_load_use := id_load_use
for (i <- 0 until id_raddr.size) { for (i <- 0 until id_raddr.size) {