Merge branch 'debugPlugin' into dev
This commit is contained in:
commit
fa2899a1a2
|
@ -56,6 +56,7 @@ trait InterruptionInhibitor{
|
||||||
|
|
||||||
trait ExceptionInhibitor{
|
trait ExceptionInhibitor{
|
||||||
def inhibateException() : Unit
|
def inhibateException() : Unit
|
||||||
|
def inhibateEbreakException() : Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@ object CsrAccess {
|
||||||
object NONE extends CsrAccess
|
object NONE extends CsrAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case class ExceptionPortInfo(port : Flow[ExceptionCause],stage : Stage, priority : Int)
|
case class ExceptionPortInfo(port : Flow[ExceptionCause],stage : Stage, priority : Int)
|
||||||
case class CsrPluginConfig(
|
case class CsrPluginConfig(
|
||||||
catchIllegalAccess : Boolean,
|
catchIllegalAccess : Boolean,
|
||||||
|
@ -457,6 +459,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
|
||||||
|
|
||||||
var allowInterrupts : Bool = null
|
var allowInterrupts : Bool = null
|
||||||
var allowException : Bool = null
|
var allowException : Bool = null
|
||||||
|
var allowEbreakException : Bool = null
|
||||||
|
|
||||||
val csrMapping = new CsrMapping()
|
val csrMapping = new CsrMapping()
|
||||||
|
|
||||||
|
@ -565,6 +568,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
|
||||||
|
|
||||||
allowInterrupts = True
|
allowInterrupts = True
|
||||||
allowException = True
|
allowException = True
|
||||||
|
allowEbreakException = True
|
||||||
|
|
||||||
for (i <- interruptSpecs) i.cond = i.cond.pull()
|
for (i <- interruptSpecs) i.cond = i.cond.pull()
|
||||||
|
|
||||||
|
@ -577,6 +581,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
|
||||||
|
|
||||||
def inhibateInterrupts() : Unit = allowInterrupts := False
|
def inhibateInterrupts() : Unit = allowInterrupts := False
|
||||||
def inhibateException() : Unit = allowException := False
|
def inhibateException() : Unit = allowException := False
|
||||||
|
def inhibateEbreakException() : Unit = allowEbreakException := False
|
||||||
|
|
||||||
override def isUser() : Bool = privilege === 0
|
override def isUser() : Bool = privilege === 0
|
||||||
override def isSupervisor(): Bool = privilege === 1
|
override def isSupervisor(): Bool = privilege === 1
|
||||||
|
@ -1097,7 +1102,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(ebreakGen) when(arbitration.isValid && input(ENV_CTRL) === EnvCtrlEnum.EBREAK){
|
if(ebreakGen) when(arbitration.isValid && input(ENV_CTRL) === EnvCtrlEnum.EBREAK && allowEbreakException){
|
||||||
selfException.valid := True
|
selfException.valid := True
|
||||||
selfException.code := 3
|
selfException.code := 3
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,8 +176,6 @@ case class DebugExtensionIo() extends Bundle with IMasterSlave{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount : Int = 0) extends Plugin[VexRiscv] {
|
class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount : Int = 0) extends Plugin[VexRiscv] {
|
||||||
|
|
||||||
var io : DebugExtensionIo = null
|
var io : DebugExtensionIo = null
|
||||||
|
@ -226,6 +224,10 @@ class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount :
|
||||||
val isPipBusy = RegNext(stages.map(_.arbitration.isValid).orR || iBusFetcher.incoming())
|
val isPipBusy = RegNext(stages.map(_.arbitration.isValid).orR || iBusFetcher.incoming())
|
||||||
val godmode = RegInit(False) setWhen(haltIt && !isPipBusy)
|
val godmode = RegInit(False) setWhen(haltIt && !isPipBusy)
|
||||||
val haltedByBreak = RegInit(False)
|
val haltedByBreak = RegInit(False)
|
||||||
|
val debugUsed = RegInit(False) setWhen(io.bus.cmd.valid) addAttribute(Verilator.public)
|
||||||
|
val disableEbreak = RegInit(False)
|
||||||
|
|
||||||
|
val allowEBreak = debugUsed && !disableEbreak
|
||||||
|
|
||||||
val hardwareBreakpoints = Vec(Reg(new Bundle{
|
val hardwareBreakpoints = Vec(Reg(new Bundle{
|
||||||
val valid = Bool()
|
val valid = Bool()
|
||||||
|
@ -259,6 +261,7 @@ class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount :
|
||||||
haltIt setWhen (io.bus.cmd.data(17)) clearWhen (io.bus.cmd.data(25))
|
haltIt setWhen (io.bus.cmd.data(17)) clearWhen (io.bus.cmd.data(25))
|
||||||
haltedByBreak clearWhen (io.bus.cmd.data(25))
|
haltedByBreak clearWhen (io.bus.cmd.data(25))
|
||||||
godmode clearWhen(io.bus.cmd.data(25))
|
godmode clearWhen(io.bus.cmd.data(25))
|
||||||
|
disableEbreak setWhen (io.bus.cmd.data(18)) clearWhen (io.bus.cmd.data(26))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(0x1) {
|
is(0x1) {
|
||||||
|
@ -277,8 +280,6 @@ class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val allowEBreak = if(!pipeline.serviceExist(classOf[PrivilegeService])) True else pipeline.service(classOf[PrivilegeService]).isMachine()
|
|
||||||
|
|
||||||
decode.insert(DO_EBREAK) := !haltIt && (decode.input(IS_EBREAK) || hardwareBreakpoints.map(hb => hb.valid && hb.pc === (decode.input(PC) >> 1)).foldLeft(False)(_ || _)) && allowEBreak
|
decode.insert(DO_EBREAK) := !haltIt && (decode.input(IS_EBREAK) || hardwareBreakpoints.map(hb => hb.valid && hb.pc === (decode.input(PC) >> 1)).foldLeft(False)(_ || _)) && allowEBreak
|
||||||
when(execute.arbitration.isValid && execute.input(DO_EBREAK)){
|
when(execute.arbitration.isValid && execute.input(DO_EBREAK)){
|
||||||
execute.arbitration.haltByOther := True
|
execute.arbitration.haltByOther := True
|
||||||
|
@ -328,6 +329,12 @@ class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount :
|
||||||
}
|
}
|
||||||
if(pipeline.things.contains(DEBUG_BYPASS_CACHE)) pipeline(DEBUG_BYPASS_CACHE) := True
|
if(pipeline.things.contains(DEBUG_BYPASS_CACHE)) pipeline(DEBUG_BYPASS_CACHE) := True
|
||||||
}
|
}
|
||||||
|
when(allowEBreak) {
|
||||||
|
pipeline.plugins.foreach {
|
||||||
|
case p: ExceptionInhibitor => p.inhibateEbreakException()
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val wakeService = serviceElse(classOf[IWake], null)
|
val wakeService = serviceElse(classOf[IWake], null)
|
||||||
if(wakeService != null) when(haltIt){
|
if(wakeService != null) when(haltIt){
|
||||||
|
|
|
@ -1673,6 +1673,7 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
try {
|
try {
|
||||||
// run simulation for 100 clock periods
|
// run simulation for 100 clock periods
|
||||||
|
@ -3496,6 +3497,11 @@ public:
|
||||||
if(clientSuccess) pass();
|
if(clientSuccess) pass();
|
||||||
if(clientFail) fail();
|
if(clientFail) fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void postReset(){
|
||||||
|
Workspace::postReset();
|
||||||
|
top->VexRiscv->DebugPlugin_debugUsed = 1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue