From e1e1be5797ae83e3b73c40030c2d9eb639184bf0 Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Tue, 8 Jun 2021 12:19:08 +0200 Subject: [PATCH] exception code can now be bigger than 4 bits --- src/main/scala/vexriscv/Services.scala | 13 +++++++++--- .../scala/vexriscv/plugin/CsrPlugin.scala | 21 +++++++++++-------- .../plugin/HaltOnExceptionPlugin.scala | 6 +++--- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/main/scala/vexriscv/Services.scala b/src/main/scala/vexriscv/Services.scala index 59a8162..64ce5ae 100644 --- a/src/main/scala/vexriscv/Services.scala +++ b/src/main/scala/vexriscv/Services.scala @@ -26,13 +26,20 @@ trait DecoderService{ def addDefault(key : Stageable[_ <: BaseType], value : Any) } -case class ExceptionCause() extends Bundle{ - val code = UInt(4 bits) +case class ExceptionCause(codeWidth : Int) extends Bundle{ + val code = UInt(codeWidth bits) val badAddr = UInt(32 bits) + + def resizeCode(width : Int): ExceptionCause ={ + val ret = ExceptionCause(width) + ret.badAddr := badAddr + ret.code := code.resized + ret + } } trait ExceptionService{ - def newExceptionPort(stage : Stage, priority : Int = 0) : Flow[ExceptionCause] + def newExceptionPort(stage : Stage, priority : Int = 0, codeWidth : Int = 4) : Flow[ExceptionCause] def isExceptionPending(stage : Stage) : Bool } diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index ea60f64..60d1b34 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -34,7 +34,7 @@ object CsrAccess { -case class ExceptionPortInfo(port : Flow[ExceptionCause],stage : Stage, priority : Int) +case class ExceptionPortInfo(port : Flow[ExceptionCause],stage : Stage, priority : Int, codeWidth : Int) case class CsrPluginConfig( catchIllegalAccess : Boolean, mvendorid : BigInt, @@ -441,9 +441,9 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep //Mannage ExceptionService calls val exceptionPortsInfos = ArrayBuffer[ExceptionPortInfo]() - override def newExceptionPort(stage : Stage, priority : Int = 0) = { - val interface = Flow(ExceptionCause()) - exceptionPortsInfos += ExceptionPortInfo(interface,stage,priority) + override def newExceptionPort(stage : Stage, priority : Int = 0, codeWidth : Int = 4) = { + val interface = Flow(ExceptionCause(codeWidth)) + exceptionPortsInfos += ExceptionPortInfo(interface,stage,priority,codeWidth) interface } @@ -847,10 +847,11 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep //Aggregate all exception port and remove required instructions val exceptionPortCtrl = exceptionPortsInfos.nonEmpty generate new Area{ + val codeWidth = exceptionPortsInfos.map(_.codeWidth).max val firstStageIndexWithExceptionPort = exceptionPortsInfos.map(i => indexOf(i.stage)).min val exceptionValids = Vec(stages.map(s => Bool().setPartialName(s.getName()))) val exceptionValidsRegs = Vec(stages.map(s => Reg(Bool).init(False).setPartialName(s.getName()))).allowUnsetRegToAvoidLatch - val exceptionContext = Reg(ExceptionCause()) + val exceptionContext = Reg(ExceptionCause(codeWidth)) val exceptionTargetPrivilegeUncapped = U"11" switch(exceptionContext.code){ @@ -876,17 +877,19 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep val groupedByStage = exceptionPortsInfos.map(_.stage).distinct.map(s => { val stagePortsInfos = exceptionPortsInfos.filter(_.stage == s).sortWith(_.priority > _.priority) val stagePort = stagePortsInfos.length match{ - case 1 => stagePortsInfos.head.port + case 1 => { + stagePortsInfos.head.port.translateWith(stagePortsInfos.head.port.payload.resizeCode(codeWidth)) + } case _ => { - val groupedPort = Flow(ExceptionCause()) + val groupedPort = Flow(ExceptionCause(codeWidth)) val valids = stagePortsInfos.map(_.port.valid) - val codes = stagePortsInfos.map(_.port.payload) + val codes = stagePortsInfos.map(_.port.payload.resizeCode(codeWidth)) groupedPort.valid := valids.orR groupedPort.payload := MuxOH(OHMasking.first(stagePortsInfos.map(_.port.valid).asBits), codes) groupedPort } } - ExceptionPortInfo(stagePort,s,0) + ExceptionPortInfo(stagePort,s,0, codeWidth) }) val sortedByStage = groupedByStage.sortWith((a, b) => pipeline.indexOf(a.stage) < pipeline.indexOf(b.stage)) diff --git a/src/main/scala/vexriscv/plugin/HaltOnExceptionPlugin.scala b/src/main/scala/vexriscv/plugin/HaltOnExceptionPlugin.scala index 6e39948..b104223 100644 --- a/src/main/scala/vexriscv/plugin/HaltOnExceptionPlugin.scala +++ b/src/main/scala/vexriscv/plugin/HaltOnExceptionPlugin.scala @@ -16,9 +16,9 @@ class HaltOnExceptionPlugin() extends Plugin[VexRiscv] with ExceptionService { //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) + 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