fpu add vex csr
This commit is contained in:
parent
f826a2ce51
commit
a7d148d0ff
|
@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue