From 6be1531d366f30b306c381a0b455cbe1f7b4478a Mon Sep 17 00:00:00 2001 From: Charles Papon Date: Fri, 10 Mar 2023 09:17:01 +0800 Subject: [PATCH] Fpu will not trap anymore on debug access if fs==0 --- .../scala/vexriscv/plugin/CsrPlugin.scala | 4 +++ .../scala/vexriscv/plugin/FpuPlugin.scala | 33 +++++++++---------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index c1b6bec..ca72a91 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -379,6 +379,7 @@ case class CsrMapping() extends Area with CsrInterface { override def allowCsr() = allowCsrSignal := True override def isHazardFree() = hazardFree override def forceFailCsr() = doForceFailCsr := True + override def inDebugMode(): Bool = ??? } @@ -429,6 +430,7 @@ trait CsrInterface{ def readData() : Bits //Return the 32 bits internal signal of the CsrPlugin for you to override (if you want) def writeData() : Bits //Return the 32 bits value that the CsrPlugin want to write in the CSR (depend on readData combinatorialy) + def inDebugMode() : Bool } @@ -484,6 +486,8 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep override def isContextSwitching = contextSwitching + override def inDebugMode(): Bool = if(withPrivilegedDebug) debugMode else False + object EnvCtrlEnum extends SpinalEnum(binarySequential){ val NONE, XRET = newElement() val WFI = if(wfiGenAsWait) newElement() else null diff --git a/src/main/scala/vexriscv/plugin/FpuPlugin.scala b/src/main/scala/vexriscv/plugin/FpuPlugin.scala index ec9087d..db3868f 100644 --- a/src/main/scala/vexriscv/plugin/FpuPlugin.scala +++ b/src/main/scala/vexriscv/plugin/FpuPlugin.scala @@ -188,7 +188,7 @@ class FpuPlugin(externalFpu : Boolean = false, } }) - + val csrService = pipeline.service(classOf[CsrInterface]) val csr = pipeline plug new Area{ val pendings = Reg(UInt(6 bits)) init(0) pendings := pendings + U(port.cmd.fire) - U(port.completion.fire) - U(port.rsp.fire) @@ -202,15 +202,14 @@ class FpuPlugin(externalFpu : Boolean = false, flags.UF init(False) setWhen(port.completion.fire && port.completion.flags.UF) flags.NX init(False) setWhen(port.completion.fire && port.completion.flags.NX) - val service = pipeline.service(classOf[CsrInterface]) val rm = Reg(Bits(3 bits)) init(0) - service.rw(CSR.FCSR, 5, rm) - service.rw(CSR.FCSR, 0, flags) - service.rw(CSR.FRM, 0, rm) - service.rw(CSR.FFLAGS, 0, flags) + csrService.rw(CSR.FCSR, 5, rm) + csrService.rw(CSR.FCSR, 0, flags) + csrService.rw(CSR.FRM, 0, rm) + csrService.rw(CSR.FFLAGS, 0, flags) - val csrActive = service.duringAny() + val csrActive = csrService.duringAny() execute.arbitration.haltByOther setWhen(csrActive && hasPending) // pessimistic val fs = Reg(Bits(2 bits)) init(1) @@ -219,31 +218,31 @@ class FpuPlugin(externalFpu : Boolean = false, when(port.completion.fire && (port.completion.written || port.completion.flags.any)){ fs := 3 } - when(List(CSR.FRM, CSR.FCSR, CSR.FFLAGS).map(id => service.isWriting(id)).orR){ + when(List(CSR.FRM, CSR.FCSR, CSR.FFLAGS).map(id => csrService.isWriting(id)).orR){ fs := 3 } - service.rw(CSR.SSTATUS, 13, fs) - service.rw(CSR.MSTATUS, 13, fs) + csrService.rw(CSR.SSTATUS, 13, fs) + csrService.rw(CSR.MSTATUS, 13, fs) - service.r(CSR.SSTATUS, 31, sd) - service.r(CSR.MSTATUS, 31, sd) + csrService.r(CSR.SSTATUS, 31, sd) + csrService.r(CSR.MSTATUS, 31, sd) val accessFpuCsr = False for (csr <- List(CSR.FRM, CSR.FCSR, CSR.FFLAGS)) { - service.during(csr) { + csrService.during(csr) { accessFpuCsr := True } } - when(accessFpuCsr && fs === 0) { - service.forceFailCsr() + when(accessFpuCsr && fs === 0 && !csrService.inDebugMode()) { + csrService.forceFailCsr() } } decode plug new Area{ import decode._ - val trap = insert(FPU_ENABLE) && csr.fs === 0 && !stagesFromExecute.map(_.arbitration.isValid).orR + val trap = insert(FPU_ENABLE) && csr.fs === 0 && !csrService.inDebugMode() && !stagesFromExecute.map(_.arbitration.isValid).orR when(trap){ pipeline.service(classOf[DecoderService]).forceIllegal() } @@ -251,7 +250,7 @@ class FpuPlugin(externalFpu : Boolean = false, //Maybe it might be better to not fork before fire to avoid RF stall on commits val forked = Reg(Bool) setWhen(port.cmd.fire) clearWhen(!arbitration.isStuck) init(False) - val hazard = csr.pendings.msb || csr.csrActive || csr.fs === 0 + val hazard = csr.pendings.msb || csr.csrActive || csr.fs === 0 && !csrService.inDebugMode() input(FPU_ENABLE).clearWhen(!input(LEGAL_INSTRUCTION)) arbitration.haltItself setWhen(arbitration.isValid && input(FPU_ENABLE) && hazard)