fpu merge load/commit

This commit is contained in:
Dolu1990 2021-01-18 13:09:08 +01:00
parent a9d8c0a19f
commit 6cb498cdb2
5 changed files with 37 additions and 53 deletions

View File

@ -102,6 +102,16 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
val lockFreeId = OHMasking.first(lock.map(!_.valid))
}
val commitFork = new Area{
val load, commit = Vec(Stream(FpuCommit(p)), portCount)
for(i <- 0 until portCount){
val fork = new StreamFork(FpuCommit(p), 2)
fork.io.input << io.port(i).commit
fork.io.outputs(0) >> load(i)
fork.io.outputs(1) >> commit(i)
}
}
val commitLogic = for(source <- 0 until portCount) yield new Area{
val fire = False
val target, hit = Reg(UInt(log2Up(rfLockCount) bits)) init(0)
@ -109,14 +119,14 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
hit := hit + 1
}
io.port(source).commit.ready := False
when(io.port(source).commit.valid) {
commitFork.commit(source).ready := False
when(commitFork.commit(source).valid) {
for (lock <- rf.lock) {
when(lock.valid && lock.source === source && lock.id === hit) {
fire := True
lock.commited := True
lock.write := io.port(source).commit.write
io.port(source).commit.ready := True
lock.write := commitFork.commit(source).write
commitFork.commit(source).ready := True
}
}
}
@ -274,10 +284,11 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
val load = new Area{
val input = decode.load.stage()
def feed = io.port(input.source).load
val filtred = commitFork.load.map(port => port.takeWhen(port.load))
def feed = filtred(input.source)
val hazard = !feed.valid
val output = input.haltWhen(hazard).swapPayload(WriteInput())
io.port.foreach(_.load.ready := False)
filtred.foreach(_.ready := False)
feed.ready := input.valid && output.ready
output.source := input.source
output.lockId := input.lockId
@ -286,7 +297,7 @@ case class FpuCore( portCount : Int, p : FpuParameter) extends Component{
}
val store = new Area{
val rspLogic = new Area{
val input = decode.store.stage()
input.ready := io.port.map(_.rsp.ready).read(input.source)

View File

@ -55,9 +55,7 @@ case class FpuCmd(p : FpuParameter) extends Bundle{
case class FpuCommit(p : FpuParameter) extends Bundle{
val write = Bool()
}
case class FpuLoad(p : FpuParameter) extends Bundle{
val load = Bool()
val value = p.storeLoadType() // IEEE 754
}
@ -68,11 +66,10 @@ case class FpuRsp(p : FpuParameter) extends Bundle{
case class FpuPort(p : FpuParameter) extends Bundle with IMasterSlave {
val cmd = Stream(FpuCmd(p))
val commit = Stream(FpuCommit(p))
val load = Stream(FpuLoad(p))
val rsp = Stream(FpuRsp(p))
override def asMaster(): Unit = {
master(cmd, commit, load)
master(cmd, commit)
slave(rsp)
}
}

View File

@ -21,7 +21,6 @@ class DAxiCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
trait DBusEncodingService {
def addLoadWordEncoding(key: MaskedLiteral): Unit
def addStoreWordEncoding(key: MaskedLiteral): Unit
def encodingHalt(): Unit
def bypassStore(data : Bits) : Unit
}
@ -91,9 +90,6 @@ class DBusCachedPlugin(val config : DataCacheConfig,
)
}
var haltFromEncoding : Bool = null
override def encodingHalt(): Unit = haltFromEncoding := True
override def bypassStore(data: Bits): Unit = {
pipeline.stages.last.input(MEMORY_STORE_DATA) := data
}
@ -220,8 +216,6 @@ class DBusCachedPlugin(val config : DataCacheConfig,
privilegeService = pipeline.service(classOf[PrivilegeService])
pipeline.update(DEBUG_BYPASS_CACHE, False)
haltFromEncoding = False
}
override def build(pipeline: VexRiscv): Unit = {
@ -496,9 +490,8 @@ class DBusCachedPlugin(val config : DataCacheConfig,
}
}
when(haltFromEncoding){
when(stages.last.arbitration.haltByOther){
cache.io.cpu.writeBack.isValid := False
managementStage.arbitration.haltItself := True
}
if(csrInfo){

View File

@ -44,9 +44,7 @@ class FpuPlugin(externalFpu : Boolean = false,
val fpu = FpuCore(1, p)
fpu.io.port(0).cmd << port.cmd
fpu.io.port(0).commit << port.commit
fpu.io.port(0).load << port.load
fpu.io.port(0).rsp >> port.rsp
}
@ -70,26 +68,12 @@ class FpuPlugin(externalFpu : Boolean = false,
insert(FPU_FORKED) := forked || port.cmd.fire
}
memory plug new Area{
import memory._
val isCommit = input(FPU_FORKED) && input(FPU_COMMIT)
val commit = Stream(FpuCommit(p))
commit.valid := isCommit && arbitration.isMoving
commit.write := arbitration.isValid
arbitration.haltItself setWhen(isCommit && !commit.ready) //Assume commit.ready do not look at commit.valid
port.commit <-/< commit //TODO can't commit in memory, in case a load fail
}
writeBack plug new Area{
import writeBack._
val dBusEncoding = pipeline.service(classOf[DBusEncodingService])
val isLoad = input(FPU_FORKED) && input(FPU_LOAD)
val isStore = input(FPU_FORKED) && input(FPU_STORE)
val isCommit = input(FPU_FORKED) && input(FPU_COMMIT)
//Manage $store and port.rsp
port.rsp.ready := False
@ -99,20 +83,22 @@ class FpuPlugin(externalFpu : Boolean = false,
dBusEncoding.bypassStore(port.rsp.value)
}
when(!port.rsp.valid){
dBusEncoding.encodingHalt()
arbitration.haltByOther := True
}
}
// Manage $load
val load = Stream(FpuLoad(p))
load.valid := isLoad && arbitration.isMoving
load.value.assignFromBits(output(DBUS_DATA))
val commit = Stream(FpuCommit(p))
commit.valid := isCommit && arbitration.isMoving
commit.value.assignFromBits(output(DBUS_DATA))
commit.write := arbitration.isValid
commit.load := input(FPU_LOAD)
when(arbitration.isValid && !load.ready){
dBusEncoding.encodingHalt()
when(arbitration.isValid && !commit.ready){
arbitration.haltByOther := True
}
port.load <-/< load
port.commit <-/< commit
}
Component.current.afterElaboration{

View File

@ -31,7 +31,6 @@ class FpuTest extends FunSuite{
val cpus = for(id <- 0 until portCount) yield new {
val cmdQueue = mutable.Queue[FpuCmd => Unit]()
val commitQueue = mutable.Queue[FpuCommit => Unit]()
val loadQueue = mutable.Queue[FpuLoad => Unit]()
val rspQueue = mutable.Queue[FpuRsp => Unit]()
StreamDriver(dut.io.port(id).cmd ,dut.clockDomain){payload =>
@ -56,12 +55,6 @@ class FpuTest extends FunSuite{
}
}
StreamDriver(dut.io.port(id).load ,dut.clockDomain){payload =>
if(loadQueue.isEmpty) false else {
loadQueue.dequeue().apply(payload)
true
}
}
def loadRaw(rd : Int, value : BigInt): Unit ={
cmdQueue += {cmd =>
@ -74,9 +67,8 @@ class FpuTest extends FunSuite{
}
commitQueue += {cmd =>
cmd.write #= true
}
loadQueue += {cmd =>
cmd.value #= value
cmd.load #= true
}
}
@ -112,6 +104,7 @@ class FpuTest extends FunSuite{
}
commitQueue += {cmd =>
cmd.write #= true
cmd.load #= false
}
}
@ -126,6 +119,7 @@ class FpuTest extends FunSuite{
}
commitQueue += {cmd =>
cmd.write #= true
cmd.load #= false
}
}
@ -140,6 +134,7 @@ class FpuTest extends FunSuite{
}
commitQueue += {cmd =>
cmd.write #= true
cmd.load #= false
}
}
@ -154,6 +149,7 @@ class FpuTest extends FunSuite{
}
commitQueue += {cmd =>
cmd.write #= true
cmd.load #= false
}
}
@ -168,6 +164,7 @@ class FpuTest extends FunSuite{
}
commitQueue += {cmd =>
cmd.write #= true
cmd.load #= false
}
}
}