fpu add vex csr

This commit is contained in:
Dolu1990 2021-01-19 15:53:11 +01:00
parent f826a2ce51
commit a7d148d0ff
5 changed files with 54 additions and 10 deletions

View File

@ -221,12 +221,14 @@ object Riscv{
val SIP = 0x144
val SATP = 0x180
def UCYCLE = 0xC00 // UR Machine ucycle counter.
def UCYCLEH = 0xC80
def UTIME = 0xC01 // rdtime
def UTIMEH = 0xC81
val FFLAGS = 0x1
val FRM = 0x2
val FCSR = 0x3
}
}

View File

@ -629,6 +629,10 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
val isCommited = rf.lock.map(_.commited).read(arbitrated.lockId)
val commited = arbitrated.haltWhen(!isCommited).toFlow
for(i <- 0 until portCount){
completion(i).increments += (RegNext(commited.fire && commited.source === i) init(False))
}
when(commited.valid){
for(i <- 0 until rfLockCount) when(commited.lockId === i){
rf.lock(i).valid := False
@ -639,10 +643,6 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
port.valid := commited.valid && rf.lock.map(_.write).read(commited.lockId)
port.address := commited.source @@ commited.rd
port.data := commited.value
for(i <- 0 until portCount){
completion(i).increments += (RegNext(port.fire && commited.source === i) init(False))
}
}
}

View File

@ -53,7 +53,7 @@ case class FpuParameter( internalMantissaSize : Int,
}
case class FpuFlags() extends Bundle{
val NV, DZ, OF, UF, NX = Bool()
val NX, UF, OF, DZ, NV = Bool()
}
case class FpuCompletion() extends Bundle{

View File

@ -307,6 +307,8 @@ case class CsrRead(that : Data , bitOffset : Int)
case class CsrReadToWriteOverride(that : Data, bitOffset : Int) //Used for special cases, as MIP where there shadow stuff
case class CsrOnWrite(doThat :() => Unit)
case class CsrDuringWrite(doThat :() => Unit)
case class CsrDuringRead(doThat :() => Unit)
case class CsrDuring(doThat :() => Unit)
case class CsrOnRead(doThat : () => Unit)
case class CsrMapping() extends CsrInterface{
val mapping = mutable.LinkedHashMap[Int,ArrayBuffer[Any]]()
@ -316,7 +318,10 @@ case class CsrMapping() extends CsrInterface{
override def r2w(csrAddress : Int, bitOffset : Int, that : Data): Unit = addMappingAt(csrAddress, CsrReadToWriteOverride(that,bitOffset))
override def onWrite(csrAddress: Int)(body: => Unit): Unit = addMappingAt(csrAddress, CsrOnWrite(() => body))
override def duringWrite(csrAddress: Int)(body: => Unit): Unit = addMappingAt(csrAddress, CsrDuringWrite(() => body))
override def duringRead(csrAddress: Int)(body: => Unit): Unit = addMappingAt(csrAddress, CsrDuringRead(() => body))
override def during(csrAddress: Int)(body: => Unit): Unit = addMappingAt(csrAddress, CsrDuring(() => body))
override def onRead(csrAddress: Int)(body: => Unit): Unit = addMappingAt(csrAddress, CsrOnRead(() => {body}))
override def duringAny(): Bool = ???
}
@ -324,6 +329,9 @@ trait CsrInterface{
def onWrite(csrAddress : Int)(doThat : => Unit) : Unit
def onRead(csrAddress : Int)(doThat : => Unit) : Unit
def duringWrite(csrAddress: Int)(body: => Unit): Unit
def duringRead(csrAddress: Int)(body: => Unit): Unit
def during(csrAddress: Int)(body: => Unit): Unit
def duringAny(): Bool
def r(csrAddress : Int, bitOffset : Int, that : Data): Unit
def w(csrAddress : Int, bitOffset : Int, that : Data): Unit
def rw(csrAddress : Int, bitOffset : Int,that : Data): Unit ={
@ -380,6 +388,8 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
interface
}
var exceptionPendings : Vec[Bool] = null
override def isExceptionPending(stage : Stage): Bool = exceptionPendings(pipeline.stages.indexOf(stage))
@ -446,6 +456,9 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
override def onWrite(csrAddress: Int)(body: => Unit): Unit = csrMapping.onWrite(csrAddress)(body)
override def duringWrite(csrAddress: Int)(body: => Unit): Unit = csrMapping.duringWrite(csrAddress)(body)
override def onRead(csrAddress: Int)(body: => Unit): Unit = csrMapping.onRead(csrAddress)(body)
override def duringRead(csrAddress: Int)(body: => Unit): Unit = csrMapping.duringRead(csrAddress)(body)
override def during(csrAddress: Int)(body: => Unit): Unit = csrMapping.during(csrAddress)(body)
override def duringAny(): Bool = pipeline.execute.arbitration.isValid && pipeline.execute.input(IS_CSR)
override def setup(pipeline: VexRiscv): Unit = {
import pipeline.config._
@ -1102,6 +1115,8 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
for (element <- jobs) element match {
case element : CsrDuringWrite => when(writeInstruction){element.doThat()}
case element : CsrDuringRead => when(readInstruction){element.doThat()}
case element : CsrDuring => {element.doThat()}
case _ =>
}
when(writeEnable) {

View File

@ -44,15 +44,42 @@ class FpuPlugin(externalFpu : Boolean = false,
override def build(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._
import Riscv._
val internal = !externalFpu generate pipeline plug new Area{
val fpu = FpuCore(1, p)
fpu.io.port(0).cmd << port.cmd
fpu.io.port(0).commit << port.commit
fpu.io.port(0).rsp >> port.rsp
fpu.io.port(0).completion <> port.completion
}
val csr = pipeline plug new Area{
val pendings = Reg(UInt(5 bits)) init(0)
pendings := pendings + U(port.cmd.fire) - port.completion.count
val hasPending = pendings =/= 0
val flags = Reg(FpuFlags())
flags.NV init(False) setWhen(port.completion.flag.NV)
flags.DZ init(False) setWhen(port.completion.flag.DZ)
flags.OF init(False) setWhen(port.completion.flag.OF)
flags.UF init(False) setWhen(port.completion.flag.UF)
flags.NX init(False) setWhen(port.completion.flag.NX)
val service = pipeline.service(classOf[CsrInterface])
val rm = Reg(Bits(3 bits))
service.rw(CSR.FCSR, 5,rm)
service.rw(CSR.FCSR, 0, flags)
service.rw(CSR.FRM, 5,rm)
service.rw(CSR.FFLAGS, 0,flags)
val csrActive = service.duringAny()
execute.arbitration.haltByOther setWhen(csrActive && hasPending) // pessimistic
}
decode plug new Area{
import decode._
@ -60,12 +87,12 @@ class FpuPlugin(externalFpu : Boolean = false,
val forked = Reg(Bool) setWhen(port.cmd.fire) clearWhen(!arbitration.isStuck) init(False)
val i2fReady = Reg(Bool()) setWhen(!arbitration.isStuckByOthers) clearWhen(!arbitration.isStuck)
val i2fHazard = input(FPU_OPCODE) === FpuOpcode.I2F && !i2fReady
val hazard = input(FPU_OPCODE) === FpuOpcode.I2F && !i2fReady || csr.pendings.msb || csr.csrActive
arbitration.haltItself setWhen(arbitration.isValid && i2fHazard)
arbitration.haltItself setWhen(arbitration.isValid && hazard)
arbitration.haltItself setWhen(port.cmd.isStall)
port.cmd.valid := arbitration.isValid && input(FPU_ENABLE) && !forked && !i2fHazard
port.cmd.valid := arbitration.isValid && input(FPU_ENABLE) && !forked && !hazard
port.cmd.opcode := input(FPU_OPCODE)
port.cmd.value := RegNext(output(RS1))
port.cmd.function := 0