aboutsummaryrefslogtreecommitdiff
path: root/VexRiscv/src/main/scala/vexriscv/plugin/HaltOnExceptionPlugin.scala
blob: b1042236757aa882fc66ccb742e82461ae00b203 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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)
        }
      }
    })
  }
}