Merge branch 'debugPlugin' into dev

This commit is contained in:
Dolu1990 2021-04-26 11:11:38 +02:00
commit fa2899a1a2
4 changed files with 24 additions and 5 deletions

View File

@ -56,6 +56,7 @@ trait InterruptionInhibitor{
trait ExceptionInhibitor{ trait ExceptionInhibitor{
def inhibateException() : Unit def inhibateException() : Unit
def inhibateEbreakException() : Unit
} }

View File

@ -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
} }

View File

@ -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){

View File

@ -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