Fpu will not trap anymore on debug access if fs==0

This commit is contained in:
Charles Papon 2023-03-10 09:17:01 +08:00
parent 1179c6551f
commit 6be1531d36
2 changed files with 20 additions and 17 deletions

View File

@ -379,6 +379,7 @@ case class CsrMapping() extends Area with CsrInterface {
override def allowCsr() = allowCsrSignal := True override def allowCsr() = allowCsrSignal := True
override def isHazardFree() = hazardFree override def isHazardFree() = hazardFree
override def forceFailCsr() = doForceFailCsr := True 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 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 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 isContextSwitching = contextSwitching
override def inDebugMode(): Bool = if(withPrivilegedDebug) debugMode else False
object EnvCtrlEnum extends SpinalEnum(binarySequential){ object EnvCtrlEnum extends SpinalEnum(binarySequential){
val NONE, XRET = newElement() val NONE, XRET = newElement()
val WFI = if(wfiGenAsWait) newElement() else null val WFI = if(wfiGenAsWait) newElement() else null

View File

@ -188,7 +188,7 @@ class FpuPlugin(externalFpu : Boolean = false,
} }
}) })
val csrService = pipeline.service(classOf[CsrInterface])
val csr = pipeline plug new Area{ val csr = pipeline plug new Area{
val pendings = Reg(UInt(6 bits)) init(0) val pendings = Reg(UInt(6 bits)) init(0)
pendings := pendings + U(port.cmd.fire) - U(port.completion.fire) - U(port.rsp.fire) 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.UF init(False) setWhen(port.completion.fire && port.completion.flags.UF)
flags.NX init(False) setWhen(port.completion.fire && port.completion.flags.NX) 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) val rm = Reg(Bits(3 bits)) init(0)
service.rw(CSR.FCSR, 5, rm) csrService.rw(CSR.FCSR, 5, rm)
service.rw(CSR.FCSR, 0, flags) csrService.rw(CSR.FCSR, 0, flags)
service.rw(CSR.FRM, 0, rm) csrService.rw(CSR.FRM, 0, rm)
service.rw(CSR.FFLAGS, 0, flags) csrService.rw(CSR.FFLAGS, 0, flags)
val csrActive = service.duringAny() val csrActive = csrService.duringAny()
execute.arbitration.haltByOther setWhen(csrActive && hasPending) // pessimistic execute.arbitration.haltByOther setWhen(csrActive && hasPending) // pessimistic
val fs = Reg(Bits(2 bits)) init(1) 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)){ when(port.completion.fire && (port.completion.written || port.completion.flags.any)){
fs := 3 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 fs := 3
} }
service.rw(CSR.SSTATUS, 13, fs) csrService.rw(CSR.SSTATUS, 13, fs)
service.rw(CSR.MSTATUS, 13, fs) csrService.rw(CSR.MSTATUS, 13, fs)
service.r(CSR.SSTATUS, 31, sd) csrService.r(CSR.SSTATUS, 31, sd)
service.r(CSR.MSTATUS, 31, sd) csrService.r(CSR.MSTATUS, 31, sd)
val accessFpuCsr = False val accessFpuCsr = False
for (csr <- List(CSR.FRM, CSR.FCSR, CSR.FFLAGS)) { for (csr <- List(CSR.FRM, CSR.FCSR, CSR.FFLAGS)) {
service.during(csr) { csrService.during(csr) {
accessFpuCsr := True accessFpuCsr := True
} }
} }
when(accessFpuCsr && fs === 0) { when(accessFpuCsr && fs === 0 && !csrService.inDebugMode()) {
service.forceFailCsr() csrService.forceFailCsr()
} }
} }
decode plug new Area{ decode plug new Area{
import decode._ 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){ when(trap){
pipeline.service(classOf[DecoderService]).forceIllegal() 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 //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 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)) input(FPU_ENABLE).clearWhen(!input(LEGAL_INSTRUCTION))
arbitration.haltItself setWhen(arbitration.isValid && input(FPU_ENABLE) && hazard) arbitration.haltItself setWhen(arbitration.isValid && input(FPU_ENABLE) && hazard)