From bfe65da1ebd8b87421a1b8ce4fe4e640b599916f Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 20 Apr 2021 23:23:18 +0200 Subject: [PATCH 1/3] implement #176 DebugPlugin.allowEBreak is now disabled until the debug bus is used. --- src/main/scala/vexriscv/plugin/DebugPlugin.scala | 5 +++-- src/test/cpp/regression/main.cpp | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/DebugPlugin.scala b/src/main/scala/vexriscv/plugin/DebugPlugin.scala index c75db10..45e9a97 100644 --- a/src/main/scala/vexriscv/plugin/DebugPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DebugPlugin.scala @@ -226,6 +226,9 @@ class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount : val isPipBusy = RegNext(stages.map(_.arbitration.isValid).orR || iBusFetcher.incoming()) val godmode = RegInit(False) setWhen(haltIt && !isPipBusy) val haltedByBreak = RegInit(False) + val allowEBreak = RegInit(False) setWhen(io.bus.cmd.valid) +// val allowEBreak = if(!pipeline.serviceExist(classOf[PrivilegeService])) True else pipeline.service(classOf[PrivilegeService]).isMachine() + val hardwareBreakpoints = Vec(Reg(new Bundle{ val valid = Bool() @@ -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 when(execute.arbitration.isValid && execute.input(DO_EBREAK)){ execute.arbitration.haltByOther := True diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index e58aba3..48120d2 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -2824,13 +2824,16 @@ public: socklen_t addr_size; char buffer[1024]; uint32_t timeSpacer = 0; - bool taskValid = false; + bool taskValid; DebugPluginTask task; DebugPlugin(Workspace* ws){ this->ws = ws; this->top = ws->top; + taskValid = true; //true as a Workaround to enable the ebreak + task.wr = false; + task.address = 0; #ifdef DEBUG_PLUGIN_EXTERNAL ws->mTimeCmp = ~0; From 32e4ea406f52759557c29a494a9681ecc1ae07b9 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Thu, 22 Apr 2021 13:59:33 +0200 Subject: [PATCH 2/3] update #176 when DebugPlugin ebreak are enabled it disable CsrPlugin ebreak. Also, DebugPlugin ebreak can be disabled via the debug bus. --- src/main/scala/vexriscv/Services.scala | 1 + src/main/scala/vexriscv/plugin/CsrPlugin.scala | 7 ++++++- src/main/scala/vexriscv/plugin/DebugPlugin.scala | 14 ++++++++++---- src/test/cpp/regression/main.cpp | 11 +++++++---- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/main/scala/vexriscv/Services.scala b/src/main/scala/vexriscv/Services.scala index 5da43af..59a8162 100644 --- a/src/main/scala/vexriscv/Services.scala +++ b/src/main/scala/vexriscv/Services.scala @@ -56,6 +56,7 @@ trait InterruptionInhibitor{ trait ExceptionInhibitor{ def inhibateException() : Unit + def inhibateEbreakException() : Unit } diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 456d688..71f3c8a 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -32,6 +32,8 @@ object CsrAccess { object NONE extends CsrAccess } + + case class ExceptionPortInfo(port : Flow[ExceptionCause],stage : Stage, priority : Int) case class CsrPluginConfig( catchIllegalAccess : Boolean, @@ -457,6 +459,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep var allowInterrupts : Bool = null var allowException : Bool = null + var allowEbreakException : Bool = null val csrMapping = new CsrMapping() @@ -565,6 +568,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep allowInterrupts = True allowException = True + allowEbreakException = True 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 inhibateException() : Unit = allowException := False + def inhibateEbreakException() : Unit = allowEbreakException := False override def isUser() : Bool = privilege === 0 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.code := 3 } diff --git a/src/main/scala/vexriscv/plugin/DebugPlugin.scala b/src/main/scala/vexriscv/plugin/DebugPlugin.scala index 45e9a97..cc302c9 100644 --- a/src/main/scala/vexriscv/plugin/DebugPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DebugPlugin.scala @@ -176,8 +176,6 @@ case class DebugExtensionIo() extends Bundle with IMasterSlave{ } } - - class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount : Int = 0) extends Plugin[VexRiscv] { var io : DebugExtensionIo = null @@ -226,9 +224,10 @@ class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount : val isPipBusy = RegNext(stages.map(_.arbitration.isValid).orR || iBusFetcher.incoming()) val godmode = RegInit(False) setWhen(haltIt && !isPipBusy) val haltedByBreak = RegInit(False) - val allowEBreak = RegInit(False) setWhen(io.bus.cmd.valid) -// val allowEBreak = if(!pipeline.serviceExist(classOf[PrivilegeService])) True else pipeline.service(classOf[PrivilegeService]).isMachine() + 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 valid = Bool() @@ -262,6 +261,7 @@ class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount : haltIt setWhen (io.bus.cmd.data(17)) clearWhen (io.bus.cmd.data(25)) haltedByBreak 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) { @@ -329,6 +329,12 @@ class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount : } 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) if(wakeService != null) when(haltIt){ diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index 48120d2..c8ad579 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -1673,6 +1673,7 @@ public: } #endif + bool failed = false; try { // run simulation for 100 clock periods @@ -2824,16 +2825,13 @@ public: socklen_t addr_size; char buffer[1024]; uint32_t timeSpacer = 0; - bool taskValid; + bool taskValid = false; DebugPluginTask task; DebugPlugin(Workspace* ws){ this->ws = ws; this->top = ws->top; - taskValid = true; //true as a Workaround to enable the ebreak - task.wr = false; - task.address = 0; #ifdef DEBUG_PLUGIN_EXTERNAL ws->mTimeCmp = ~0; @@ -3499,6 +3497,11 @@ public: if(clientSuccess) pass(); if(clientFail) fail(); } + + virtual void postReset(){ + Workspace::postReset(); + top->VexRiscv->DebugPlugin_debugUsed = 1; + } }; #endif From 0a0998fcea10c34a45be8f3a10c2c6d5d017b262 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Thu, 22 Apr 2021 14:02:46 +0200 Subject: [PATCH 3/3] #176 fix typo --- src/main/scala/vexriscv/plugin/DebugPlugin.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/vexriscv/plugin/DebugPlugin.scala b/src/main/scala/vexriscv/plugin/DebugPlugin.scala index cc302c9..b7f621c 100644 --- a/src/main/scala/vexriscv/plugin/DebugPlugin.scala +++ b/src/main/scala/vexriscv/plugin/DebugPlugin.scala @@ -329,7 +329,7 @@ class DebugPlugin(var debugClockDomain : ClockDomain, hardwareBreakpointCount : } if(pipeline.things.contains(DEBUG_BYPASS_CACHE)) pipeline(DEBUG_BYPASS_CACHE) := True } - when(!allowEBreak) { + when(allowEBreak) { pipeline.plugins.foreach { case p: ExceptionInhibitor => p.inhibateEbreakException() case _ =>