1
0

debug: remove preexec. Simplify the state machine since you can always just 'execute' once.

This commit is contained in:
Megan Wachs 2017-04-11 09:27:02 -07:00 committed by Yunsup Lee
parent c5cb8b714f
commit 2dc4be6294
2 changed files with 34 additions and 100 deletions

View File

@ -52,19 +52,14 @@ object DsbRegAddrs{
def RESUMING = 0x108 def RESUMING = 0x108
def EXCEPTION = 0x10C def EXCEPTION = 0x10C
def FLAGS = 0x400
def ROMBASE = 0x800
def RESUME = 0x804
def WHERETO = 0x300 def WHERETO = 0x300
def ABSTRACT = 0x340 - 8 def ABSTRACT = 0x304
def PROGBUF = 0x340 def PROGBUF = 0x304 + 8
// This shows up in HartInfo // This shows up in HartInfo
def DATA = 0x380 def DATA(cfg: DebugModuleConfig) = {PROGBUF + (cfg.nProgramBufferWords * 4)}
//Not implemented: Serial. def FLAGS = 0x400
def ROMBASE = 0x800
} }
@ -226,8 +221,8 @@ class DebugCtrlBundle (nComponents: Int)(implicit val p: Parameters) extends Par
* provide the default MTVEC since it is mapped * provide the default MTVEC since it is mapped
* to address 0x0. * to address 0x0.
* *
* DebugModule is responsible for control registers and RAM. The Debug ROM is in a * DebugModule is responsible for control registers and RAM, and
* seperate module. It runs partially off of the dmiClk (e.g. TCK) and * Debug ROM. It runs partially off of the dmiClk (e.g. TCK) and
* the TL clock. Therefore, it is divided into "Outer" portion (running * the TL clock. Therefore, it is divided into "Outer" portion (running
* of off dmiClock and dmiReset) and "Inner" (running off tlClock and tlReset). * of off dmiClock and dmiReset) and "Inner" (running off tlClock and tlReset).
* This allows DMCONTROL.haltreq, hartsel, dmactive, and ndreset to be * This allows DMCONTROL.haltreq, hartsel, dmactive, and ndreset to be
@ -354,8 +349,7 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
io.debugInterrupts(component)(0) := debugIntRegs(component) io.debugInterrupts(component)(0) := debugIntRegs(component)
} }
// Halt request registers are written by write to DMCONTROL.haltreq // Halt request registers are set & cleared by writes to DMCONTROL.haltreq
// and cleared by writes to DMCONTROL.resumereq.
// resumereq also causes the core to execute a 'dret', // resumereq also causes the core to execute a 'dret',
// so resumereq is passed through to Inner. // so resumereq is passed through to Inner.
// hartsel must also be used by the DebugModule state machine, // hartsel must also be used by the DebugModule state machine,
@ -367,11 +361,8 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod
when (~dmactive) { when (~dmactive) {
debugIntNxt(component) := false.B debugIntNxt(component) := false.B
}. otherwise { }. otherwise {
when (DMCONTROLWrEn) { when (DMCONTROLWrEn && DMCONTROLWrData.hartsel === component.U) {
when (DMCONTROLWrData.hartsel === component.U) { debugIntNxt(component) := DMCONTROLWrData.haltreq
debugIntNxt(component) := (debugIntRegs(component) | DMCONTROLWrData.haltreq) &
~(DMCONTROLWrData.resumereq)
}
} }
} }
} }
@ -549,7 +540,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
val HARTINFORdData = Wire (init = (new HARTINFOFields()).fromBits(0.U)) val HARTINFORdData = Wire (init = (new HARTINFOFields()).fromBits(0.U))
HARTINFORdData.dataaccess := true.B HARTINFORdData.dataaccess := true.B
HARTINFORdData.datasize := cfg.nAbstractDataWords.U HARTINFORdData.datasize := cfg.nAbstractDataWords.U
HARTINFORdData.dataaddr := DsbRegAddrs.DATA.U HARTINFORdData.dataaddr := DsbRegAddrs.DATA(cfg).U
HARTINFORdData.nscratch := cfg.nScratch.U HARTINFORdData.nscratch := cfg.nScratch.U
//----HALTSUM (and halted registers) //----HALTSUM (and halted registers)
@ -597,8 +588,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
}.elsewhen (errorHaltResume) { }.elsewhen (errorHaltResume) {
ABSTRACTCSReg.cmderr := DebugAbstractCommandError.ErrHaltResume.id.U ABSTRACTCSReg.cmderr := DebugAbstractCommandError.ErrHaltResume.id.U
}.otherwise { }.otherwise {
//TODO: Should be write-1-to-clear & ~ABSTRACTCSWrData.cmderr when (ABSTRACTCSWrEn){
when (ABSTRACTCSWrEn /* && ABSTRACTCSWrData.cmderr === 0.U*/){
ABSTRACTCSReg.cmderr := ABSTRACTCSReg.cmderr & ~(ABSTRACTCSWrData.cmderr); ABSTRACTCSReg.cmderr := ABSTRACTCSReg.cmderr & ~(ABSTRACTCSWrData.cmderr);
} }
} }
@ -741,35 +731,15 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
// "Variable" ROM Generation // "Variable" ROM Generation
//-------------------------------------------------------------- //--------------------------------------------------------------
val goProgramBuffer = Wire(init = false.B) val goReg = Reg(Bool())
val goAbstract = Wire(init = false.B) val goAbstract = Wire(init = false.B)
val whereToReg = Reg(UInt(32.W))
val jalProgBuf = Wire(init = (new GeneratedUJ()).fromBits(rocket.Instructions.JAL.value.U))
jalProgBuf.setImm(PROGBUF - WHERETO)
jalProgBuf.rd := 0.U
val jalAbstract = Wire(init = (new GeneratedUJ()).fromBits(rocket.Instructions.JAL.value.U)) val jalAbstract = Wire(init = (new GeneratedUJ()).fromBits(rocket.Instructions.JAL.value.U))
jalAbstract.setImm(ABSTRACT - WHERETO) jalAbstract.setImm(ABSTRACT - WHERETO)
jalProgBuf.rd := 0.U
when (~io.dmactive) {
whereToReg := 0.U
}.otherwise{
when (goProgramBuffer) {
whereToReg := jalProgBuf.asUInt()
}.elsewhen (goAbstract) {
whereToReg := jalAbstract.asUInt()
}
}
val goReg = Reg(Bool())
when (~io.dmactive){ when (~io.dmactive){
goReg := false.B goReg := false.B
}.otherwise { }.otherwise {
when (goProgramBuffer | goAbstract) { when (goAbstract) {
goReg := true.B goReg := true.B
}.elsewhen (hartGoingWrEn){ }.elsewhen (hartGoingWrEn){
assert(hartGoingId === 0.U, "Unexpected 'GOING' hart.")//Chisel3 #540 %x, expected %x", hartGoingId, 0.U) assert(hartGoingId === 0.U, "Unexpected 'GOING' hart.")//Chisel3 #540 %x, expected %x", hartGoingId, 0.U)
@ -849,14 +819,14 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
abstractGeneratedI.rd := (accessRegisterCommandReg.regno & 0x1F.U) abstractGeneratedI.rd := (accessRegisterCommandReg.regno & 0x1F.U)
abstractGeneratedI.funct3 := accessRegisterCommandReg.size abstractGeneratedI.funct3 := accessRegisterCommandReg.size
abstractGeneratedI.rs1 := 0.U abstractGeneratedI.rs1 := 0.U
abstractGeneratedI.imm := DATA.U abstractGeneratedI.imm := DATA(cfg).U
abstractGeneratedS.opcode := ((new GeneratedS()).fromBits(rocket.Instructions.SW.value.U)).opcode abstractGeneratedS.opcode := ((new GeneratedS()).fromBits(rocket.Instructions.SW.value.U)).opcode
abstractGeneratedS.immlo := (DATA & 0x1F).U abstractGeneratedS.immlo := (DATA(cfg) & 0x1F).U
abstractGeneratedS.funct3 := accessRegisterCommandReg.size abstractGeneratedS.funct3 := accessRegisterCommandReg.size
abstractGeneratedS.rs1 := 0.U abstractGeneratedS.rs1 := 0.U
abstractGeneratedS.rs2 := (accessRegisterCommandReg.regno & 0x1F.U) abstractGeneratedS.rs2 := (accessRegisterCommandReg.regno & 0x1F.U)
abstractGeneratedS.immhi := (DATA >> 5).U abstractGeneratedS.immhi := (DATA(cfg) >> 5).U
nop := ((new GeneratedI()).fromBits(rocket.Instructions.ADDI.value.U)) nop := ((new GeneratedI()).fromBits(rocket.Instructions.ADDI.value.U))
nop.rd := 0.U nop.rd := 0.U
@ -872,7 +842,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
abstractGeneratedS.asUInt()), abstractGeneratedS.asUInt()),
nop.asUInt() nop.asUInt()
) )
abstractGeneratedMem(1) := Mux(/*TODO accessRegisterCommandReg.postexec*/ false.B, abstractGeneratedMem(1) := Mux(accessRegisterCommandReg.postexec,
nop.asUInt(), nop.asUInt(),
rocket.Instructions.EBREAK.value.U) rocket.Instructions.EBREAK.value.U)
} }
@ -887,15 +857,16 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
GOING -> Seq(WNotify(sbIdWidth, hartGoingId, hartGoingWrEn)), GOING -> Seq(WNotify(sbIdWidth, hartGoingId, hartGoingWrEn)),
RESUMING -> Seq(WNotify(sbIdWidth, hartResumingId, hartResumingWrEn)), RESUMING -> Seq(WNotify(sbIdWidth, hartResumingId, hartResumingWrEn)),
EXCEPTION -> Seq(WNotify(sbIdWidth, hartExceptionId, hartExceptionWrEn)), EXCEPTION -> Seq(WNotify(sbIdWidth, hartExceptionId, hartExceptionWrEn)),
DATA -> abstractDataMem.map(x => RegField(8, x)), DATA(cfg) -> abstractDataMem.map(x => RegField(8, x)),
PROGBUF -> programBufferMem.map(x => RegField(8, x)), PROGBUF -> programBufferMem.map(x => RegField(8, x)),
// These sections are read-only. // These sections are read-only.
ROMBASE -> DebugRomContents().map(x => RegField.r(8, (x & 0xFF).U(8.W))), WHERETO -> Seq(RegField.r(32, jalAbstract.asUInt)),
ABSTRACT -> abstractGeneratedMem.map{x => RegField.r(32, x)},
FLAGS -> flags.map{x => RegField.r(8, x.asUInt())}, FLAGS -> flags.map{x => RegField.r(8, x.asUInt())},
WHERETO -> Seq(RegField.r(32, whereToReg)), ROMBASE -> DebugRomContents().map(x => RegField.r(8, (x & 0xFF).U(8.W)))
ABSTRACT -> abstractGeneratedMem.map(x => RegField.r(32, x))
) )
// Override System Bus accesses with dmactive reset. // Override System Bus accesses with dmactive reset.
when (~io.dmactive){ when (~io.dmactive){
@ -909,7 +880,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
object CtrlState extends scala.Enumeration { object CtrlState extends scala.Enumeration {
type CtrlState = Value type CtrlState = Value
val Waiting, CheckGenerate, PreExec, Abstract, PostExec = Value val Waiting, CheckGenerate, Exec = Value
def apply( t : Value) : UInt = { def apply( t : Value) : UInt = {
t.id.U(log2Up(values.size).W) t.id.U(log2Up(values.size).W)
@ -957,13 +928,12 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
//------------------------ //------------------------
// Variable ROM STATE MACHINE // Variable ROM STATE MACHINE
// ----------------------- // -----------------------
when (ctrlStateReg === CtrlState(Waiting)){ when (ctrlStateReg === CtrlState(Waiting)){
when (wrAccessRegisterCommand || regAccessRegisterCommand) { when (wrAccessRegisterCommand || regAccessRegisterCommand) {
ctrlStateNxt := CtrlState(CheckGenerate) ctrlStateNxt := CtrlState(CheckGenerate)
} }
}.elsewhen (ctrlStateReg === CtrlState(CheckGenerate)){ }.elsewhen (ctrlStateReg === CtrlState(CheckGenerate)){
// We use this state to ensure that the COMMAND has been // We use this state to ensure that the COMMAND has been
@ -977,47 +947,11 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
errorHaltResume := true.B errorHaltResume := true.B
ctrlStateNxt := CtrlState(Waiting) ctrlStateNxt := CtrlState(Waiting)
}.otherwise { }.otherwise {
when (accessRegisterCommandReg.preexec) { ctrlStateNxt := CtrlState(Exec)
ctrlStateNxt := CtrlState(PreExec)
goProgramBuffer := true.B
}.otherwise {
ctrlStateNxt := CtrlState(Abstract)
goAbstract := true.B
}
}
}.elsewhen (ctrlStateReg === CtrlState(PreExec)) {
// We can't just look at 'hartHalted' here, because
// hartHaltedWrEn is overloaded to mean 'got an ebreak'
// which may have happened when we were already halted.
when(goReg === false.B && hartHaltedWrEn && (cfg.hartIdToHartSel(hartHaltedId) === selectedHartReg)){
ctrlStateNxt := CtrlState(Abstract)
goAbstract := true.B goAbstract := true.B
} }
when(hartExceptionWrEn) {
assert(hartExceptionId === 0.U, "Unexpected 'EXCEPTION' hart")// Chisel3 #540, %x, expected %x", hartExceptionId, 0.U) }.elsewhen (ctrlStateReg === CtrlState(Exec)) {
ctrlStateNxt := CtrlState(Waiting)
errorException := true.B
}
}.elsewhen (ctrlStateReg === CtrlState(Abstract)) {
// We can't just look at 'hartHalted' here, because
// hartHaltedWrEn is overloaded to mean 'got an ebreak'
// which may have happened when we were already halted.
when(goReg === false.B && hartHaltedWrEn && (cfg.hartIdToHartSel(hartHaltedId) === selectedHartReg)){
when (accessRegisterCommandReg.postexec) {
ctrlStateNxt := CtrlState(PostExec)
goProgramBuffer := true.B
}.otherwise {
ctrlStateNxt := CtrlState(Waiting)
}
}
when(hartExceptionWrEn) {
assert(hartExceptionId === 0.U, "Unexpected 'EXCEPTION' hart")//Chisel3 #540 %x, expected %x", hartExceptionId, selectedHartReg)
ctrlStateNxt := CtrlState(Waiting)
errorUnsupported := true.B
}
}.elsewhen (ctrlStateReg === CtrlState(PostExec)) {
// We can't just look at 'hartHalted' here, because // We can't just look at 'hartHalted' here, because
// hartHaltedWrEn is overloaded to mean 'got an ebreak' // hartHaltedWrEn is overloaded to mean 'got an ebreak'
@ -1027,7 +961,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
} }
when(hartExceptionWrEn) { when(hartExceptionWrEn) {
assert(hartExceptionId === 0.U, "Unexpected 'EXCEPTION' hart")//Chisel3 #540, %x, expected %x", hartExceptionId, 0.U) assert(hartExceptionId === 0.U, "Unexpected 'EXCEPTION' hart")//Chisel3 #540, %x, expected %x", hartExceptionId, 0.U)
ctrlStateNxt := CtrlState(Waiting) ctrlStateNxt := CtrlState(Waiting)
errorException := true.B errorException := true.B
} }
} }
@ -1040,6 +974,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p:
} }
} }
// Wrapper around TL Debug Module Inner and an Async DMI Sink interface. // Wrapper around TL Debug Module Inner and an Async DMI Sink interface.
// Handles the synchronization of dmactive, which is used as a synchronous reset // Handles the synchronization of dmactive, which is used as a synchronous reset
// inside the Inner block. // inside the Inner block.

View File

@ -28,9 +28,8 @@ class ACCESS_REGISTERFields extends Bundle {
*/ */
val size = UInt(3.W) val size = UInt(3.W)
// HACK -- for now I have not yet deleted preexecval reserved1 = UInt(1.W) val reserved1 = UInt(1.W)
val preexec = Bool()
/* When 1, execute the program in the Program Buffer exactly once /* When 1, execute the program in the Program Buffer exactly once
after performing the transfer, if any. after performing the transfer, if any.
*/ */