Add UserInterruptPlugin

This commit is contained in:
Charles Papon 2019-11-07 19:52:32 +01:00
parent 2bf6a536c9
commit bb405e705b
2 changed files with 86 additions and 4 deletions

View File

@ -0,0 +1,67 @@
package vexriscv.demo
import spinal.core._
import vexriscv.plugin._
import vexriscv.{VexRiscv, VexRiscvConfig, plugin}
/**
* Created by spinalvm on 15.06.17.
*/
object GenCustomInterrupt extends App{
def cpu() = new VexRiscv(
config = VexRiscvConfig(
plugins = List(
new UserInterruptPlugin(
interruptName = "miaou",
code = 20
),
new UserInterruptPlugin(
interruptName = "rawrrr",
code = 24
),
new IBusSimplePlugin(
resetVector = 0x80000000l,
cmdForkOnSecondStage = false,
cmdForkPersistence = false,
prediction = NONE,
catchAccessFault = false,
compressedGen = false
),
new DBusSimplePlugin(
catchAddressMisaligned = false,
catchAccessFault = false
),
new CsrPlugin(CsrPluginConfig.smallest),
new DecoderSimplePlugin(
catchIllegalInstruction = false
),
new RegFilePlugin(
regFileReadyKind = plugin.SYNC,
zeroBoot = false
),
new IntAluPlugin,
new SrcPlugin(
separatedAddSub = false,
executeInsertion = true
),
new LightShifterPlugin,
new HazardSimplePlugin(
bypassExecute = true,
bypassMemory = true,
bypassWriteBack = true,
bypassWriteBackBuffer = true,
pessimisticUseSrc = false,
pessimisticWriteRegFile = false,
pessimisticAddressMatch = false
),
new BranchPlugin(
earlyBranch = false,
catchAddressMisaligned = false
),
new YamlPlugin("cpu0.yaml")
)
)
)
SpinalVerilog(cpu())
}

View File

@ -322,7 +322,6 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
//Mannage ExceptionService calls
val exceptionPortsInfos = ArrayBuffer[ExceptionPortInfo]()
def exceptionCodeWidth = 4
override def newExceptionPort(stage : Stage, priority : Int = 0) = {
val interface = Flow(ExceptionCause())
exceptionPortsInfos += ExceptionPortInfo(interface,stage,priority)
@ -459,6 +458,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
import pipeline._
import pipeline.config._
val fetcher = service(classOf[IBusFetcher])
val trapCodeWidth = log2Up((List(16) ++ interruptSpecs.map(_.id + 1) ++ exceptionPortsInfos.map(p => 1 << widthOf(p.port.code))).max)
//Define CSR mapping utilities
implicit class CsrAccessPimper(csrAccess : CsrAccess){
@ -511,7 +511,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
val mscratch = if(mscratchGen) Reg(Bits(xlen bits)) else null
val mcause = new Area{
val interrupt = Reg(Bool)
val exceptionCode = Reg(UInt(exceptionCodeWidth bits))
val exceptionCode = Reg(UInt(trapCodeWidth bits))
}
val mtval = Reg(UInt(xlen bits))
val mcycle = Reg(UInt(64 bits)) randBoot()
@ -582,7 +582,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
val scause = new Area {
val interrupt = Reg(Bool)
val exceptionCode = Reg(UInt(exceptionCodeWidth bits))
val exceptionCode = Reg(UInt(trapCodeWidth bits))
}
val stval = Reg(UInt(xlen bits))
val sepc = Reg(UInt(xlen bits))
@ -733,7 +733,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
//Process interrupt request, code and privilege
val interrupt = new Area {
val valid = if(pipelinedInterrupt) RegNext(False) init(False) else False
val code = if(pipelinedInterrupt) Reg(UInt(4 bits)) else UInt(4 bits).assignDontCare()
val code = if(pipelinedInterrupt) Reg(UInt(trapCodeWidth bits)) else UInt(trapCodeWidth bits).assignDontCare()
var privilegs = if (supervisorGen) List(1, 3) else List(3)
val targetPrivilege = if(pipelinedInterrupt) Reg(UInt(2 bits)) else UInt(2 bits).assignDontCare()
val privilegeAllowInterrupts = mutable.HashMap[Int, Bool]()
@ -1044,3 +1044,18 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
}
}
}
class UserInterruptPlugin(interruptName : String, code : Int, privilege : Int = 3) extends Plugin[VexRiscv]{
var interrupt, interruptEnable : Bool = null
override def setup(pipeline: VexRiscv): Unit = {
val csr = pipeline.service(classOf[CsrPlugin])
interrupt = in.Bool().setName(interruptName)
val interruptPending = RegNext(interrupt) init(False)
val interruptEnable = RegInit(False).setName(interruptName + "_enable")
csr.addInterrupt(interruptPending , code, privilege, Nil)
csr.r(csrAddress = CSR.MIP, bitOffset = code,interruptPending)
csr.rw(csrAddress = CSR.MIE, bitOffset = code, interruptEnable)
}
override def build(pipeline: VexRiscv): Unit = {}
}