aboutsummaryrefslogtreecommitdiff
path: root/VexRiscv/src/main/scala/vexriscv/plugin/HaltOnExceptionPlugin.scala
diff options
context:
space:
mode:
authorFriedrich Beckmann <friedrich.beckmann@hs-augsburg.de>2022-07-25 17:55:39 +0200
committerFriedrich Beckmann <friedrich.beckmann@hs-augsburg.de>2022-07-25 17:55:39 +0200
commit3fff6023602822531efdae30bc8ebf862967f1ef (patch)
tree16028102b8d850f8ab3115d28a8539ca6bc5f51d /VexRiscv/src/main/scala/vexriscv/plugin/HaltOnExceptionPlugin.scala
Initial Commit
Diffstat (limited to 'VexRiscv/src/main/scala/vexriscv/plugin/HaltOnExceptionPlugin.scala')
-rw-r--r--VexRiscv/src/main/scala/vexriscv/plugin/HaltOnExceptionPlugin.scala44
1 files changed, 44 insertions, 0 deletions
diff --git a/VexRiscv/src/main/scala/vexriscv/plugin/HaltOnExceptionPlugin.scala b/VexRiscv/src/main/scala/vexriscv/plugin/HaltOnExceptionPlugin.scala
new file mode 100644
index 0000000..b104223
--- /dev/null
+++ b/VexRiscv/src/main/scala/vexriscv/plugin/HaltOnExceptionPlugin.scala
@@ -0,0 +1,44 @@
+
+package vexriscv.plugin
+
+import spinal.core._
+import spinal.lib._
+import vexriscv._
+import vexriscv.Riscv._
+
+import scala.collection.mutable.ArrayBuffer
+import scala.collection.mutable
+
+
+class HaltOnExceptionPlugin() extends Plugin[VexRiscv] with ExceptionService {
+ def xlen = 32
+
+ //Mannage ExceptionService calls
+ val exceptionPortsInfos = ArrayBuffer[ExceptionPortInfo]()
+ def exceptionCodeWidth = 4
+ override def newExceptionPort(stage : Stage, priority : Int = 0, codeWidth : Int = 4) = {
+ val interface = Flow(ExceptionCause(4))
+ exceptionPortsInfos += ExceptionPortInfo(interface,stage,priority, codeWidth)
+ interface
+ }
+ override def isExceptionPending(stage : Stage): Bool = False
+
+
+ override def build(pipeline: VexRiscv): Unit = {
+ import pipeline._
+ import pipeline.config._
+ stages.head.insert(FORMAL_HALT) := False
+ stages.foreach(stage => {
+ val stagePorts = exceptionPortsInfos.filter(_.stage == stage)
+ if(stagePorts.nonEmpty) {
+ when(stagePorts.map(info => info.port.valid).orR) {
+ stage.output(FORMAL_HALT) := True
+ stage.arbitration.haltItself := True
+ }
+ for(stage <- stages){
+ stage.output(FORMAL_HALT) clearWhen(stage.arbitration.isFlushed)
+ }
+ }
+ })
+ }
+}