diff --git a/src/main/scala/vexriscv/demo/GenCustomInterrupt.scala b/src/main/scala/vexriscv/demo/GenCustomInterrupt.scala new file mode 100644 index 0000000..cb8ef4f --- /dev/null +++ b/src/main/scala/vexriscv/demo/GenCustomInterrupt.scala @@ -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()) +} diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index 5c7e032..c93eaf7 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -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 = {} +} \ No newline at end of file