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 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

View File

@ -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)