dataCache now implement invalidation sync

This commit is contained in:
Dolu1990 2020-04-16 01:28:38 +02:00
parent 467a2bc488
commit 46207abbc4
2 changed files with 66 additions and 22 deletions

View File

@ -80,11 +80,16 @@ case class DataCacheConfig(cacheSize : Int,
dataWidth = 32, dataWidth = 32,
lengthWidth = log2Up(this.bytePerLine), lengthWidth = log2Up(this.bytePerLine),
sourceWidth = 0, sourceWidth = 0,
contextWidth = 1, contextWidth = if(!withWriteResponse) 1 else 0,
canRead = true, canRead = true,
canWrite = true, canWrite = true,
alignment = BmbParameter.BurstAlignement.LENGTH, alignment = BmbParameter.BurstAlignement.LENGTH,
maximumPendingTransactionPerId = Int.MaxValue maximumPendingTransactionPerId = Int.MaxValue,
canInvalidate = withInvalidate,
canSync = withInvalidate,
canExclusive = withExclusive,
invalidateLength = log2Up(this.bytePerLine),
invalidateAlignment = BmbParameter.BurstAlignement.LENGTH
) )
} }
@ -193,12 +198,17 @@ case class DataCacheAck(p : DataCacheConfig) extends Bundle{
val hit = Bool() val hit = Bool()
} }
case class DataCacheSync(p : DataCacheConfig) extends Bundle{
}
case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave{ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave{
val cmd = Stream (DataCacheMemCmd(p)) val cmd = Stream (DataCacheMemCmd(p))
val rsp = Flow (DataCacheMemRsp(p)) val rsp = Flow (DataCacheMemRsp(p))
val inv = p.withInvalidate generate Stream(DataCacheInv(p)) val inv = p.withInvalidate generate Stream(DataCacheInv(p))
val ack = p.withInvalidate generate Stream(DataCacheAck(p)) val ack = p.withInvalidate generate Stream(DataCacheAck(p))
val sync = p.withInvalidate generate Stream(DataCacheSync(p))
override def asMaster(): Unit = { override def asMaster(): Unit = {
master(cmd) master(cmd)
@ -207,6 +217,7 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
if(p.withInvalidate) { if(p.withInvalidate) {
slave(inv) slave(inv)
master(ack) master(ack)
slave(sync)
} }
} }
@ -342,11 +353,11 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
def toBmb() : Bmb = { def toBmb() : Bmb = {
val pipelinedMemoryBusConfig = p.getBmbParameter() val pipelinedMemoryBusConfig = p.getBmbParameter()
val bus = Bmb(pipelinedMemoryBusConfig) val bus = Bmb(pipelinedMemoryBusConfig).setCompositeName(this,"toBmb", true)
bus.cmd.valid := cmd.valid bus.cmd.valid := cmd.valid
bus.cmd.last := cmd.last bus.cmd.last := cmd.last
bus.cmd.context(0) := cmd.wr if(!p.withWriteResponse) bus.cmd.context(0) := cmd.wr
bus.cmd.opcode := (cmd.wr ? B(Bmb.Cmd.Opcode.WRITE) | B(Bmb.Cmd.Opcode.READ)) bus.cmd.opcode := (cmd.wr ? B(Bmb.Cmd.Opcode.WRITE) | B(Bmb.Cmd.Opcode.READ))
bus.cmd.address := cmd.address.resized bus.cmd.address := cmd.address.resized
bus.cmd.data := cmd.data bus.cmd.data := cmd.data
@ -356,22 +367,33 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
cmd.ready := bus.cmd.ready cmd.ready := bus.cmd.ready
rsp.valid := bus.rsp.valid && !bus.rsp.context(0) rsp.valid := bus.rsp.valid
if(!p.withWriteResponse) rsp.valid clearWhen(bus.rsp.context(0))
rsp.data := bus.rsp.data rsp.data := bus.rsp.data
rsp.error := bus.rsp.isError rsp.error := bus.rsp.isError
rsp.last := bus.rsp.last
if(p.withExclusive) rsp.exclusive := bus.rsp.exclusive if(p.withExclusive) rsp.exclusive := bus.rsp.exclusive
bus.rsp.ready := True bus.rsp.ready := True
if(p.withInvalidate){ if(p.withInvalidate){
bus.ack.arbitrationFrom(ack) inv.arbitrationFrom(bus.inv)
//TODO manage lenght ?
inv.address := bus.inv.address inv.address := bus.inv.address
// inv.opcode := bus.inv.opcode inv.enable := bus.inv.all
???
bus.ack.arbitrationFrom(ack) bus.ack.arbitrationFrom(ack)
sync.arbitrationFrom(bus.sync)
// bus.ack.arbitrationFrom(ack)
// //TODO manage lenght ?
// inv.address := bus.inv.address
//// inv.opcode := bus.inv.opcode
// ???
//
// bus.ack.arbitrationFrom(ack)
} }
bus bus
} }
@ -440,9 +462,10 @@ class DataCache(val p : DataCacheConfig) extends Component{
//Reads //Reads
val tagsReadRsp = tags.readSync(tagsReadCmd.payload, tagsReadCmd.valid && !io.cpu.memory.isStuck) val tagsReadRsp = tags.readSync(tagsReadCmd.payload, tagsReadCmd.valid && !io.cpu.memory.isStuck)
val tagsInvReadRsp = withInvalidate generate tags.readSync(tagsInvReadCmd.payload, tagsReadCmd.valid && !io.cpu.memory.isStuck)
val dataReadRsp = data.readSync(dataReadCmd.payload, dataReadCmd.valid && !io.cpu.memory.isStuck) val dataReadRsp = data.readSync(dataReadCmd.payload, dataReadCmd.valid && !io.cpu.memory.isStuck)
val tagsInvReadRsp = withInvalidate generate tags.readSync(tagsInvReadCmd.payload, tagsInvReadCmd.valid)
//Writes //Writes
when(tagsWriteCmd.valid && tagsWriteCmd.way(i)){ when(tagsWriteCmd.valid && tagsWriteCmd.way(i)){
tags.write(tagsWriteCmd.address, tagsWriteCmd.data) tags.write(tagsWriteCmd.address, tagsWriteCmd.data)
@ -494,9 +517,22 @@ class DataCache(val p : DataCacheConfig) extends Component{
val full = RegNext(counter.msb) val full = RegNext(counter.msb)
val last = counter === 1 val last = counter === 1
if(!withInvalidate) {
io.cpu.execute.haltIt setWhen(full)
}
rspSync clearWhen (!last || !memCmdSent)
rspLast clearWhen (!last)
}
val sync = withInvalidate generate new Area{
io.mem.sync.ready := True
val counter = Reg(UInt(log2Up(pendingMax) + 1 bits)) init(0)
counter := counter + U(io.mem.cmd.fire && io.mem.cmd.wr) - U(io.mem.sync.fire)
val full = RegNext(counter.msb)
io.cpu.execute.haltIt setWhen(full) io.cpu.execute.haltIt setWhen(full)
rspSync clearWhen(!last || !memCmdSent)
rspLast clearWhen(!last)
} }
@ -509,12 +545,15 @@ class DataCache(val p : DataCacheConfig) extends Component{
val dataColisions = collisionProcess(io.cpu.execute.address(lineRange.high downto wordRange.low), mask) val dataColisions = collisionProcess(io.cpu.execute.address(lineRange.high downto wordRange.low), mask)
val wayInvalidate = B(0, wayCount bits) //Used if invalidate enabled val wayInvalidate = B(0, wayCount bits) //Used if invalidate enabled
if(withWriteResponse) when(io.cpu.execute.fence){ when(io.cpu.execute.fence){
when(pending.counter =/= 0 || io.cpu.memory.isValid || io.cpu.writeBack.isValid){ val counter = if(withInvalidate) sync.counter else if(withWriteResponse) pending.counter else null
if(counter != null){
when(counter =/= 0 || io.cpu.memory.isValid || io.cpu.writeBack.isValid){
io.cpu.execute.haltIt := True io.cpu.execute.haltIt := True
} }
} }
} }
}
val stageA = new Area{ val stageA = new Area{
def stagePipe[T <: Data](that : T) = if(mergeExecuteMemory) CombInit(that) else RegNextWhen(that, !io.cpu.memory.isStuck) def stagePipe[T <: Data](that : T) = if(mergeExecuteMemory) CombInit(that) else RegNextWhen(that, !io.cpu.memory.isStuck)
@ -563,18 +602,21 @@ class DataCache(val p : DataCacheConfig) extends Component{
//Evict the cache after reset logics //Evict the cache after reset logics
val flusher = new Area { val flusher = new Area {
val valid = RegInit(False) val valid = RegInit(False)
val hold = False
when(valid) { when(valid) {
tagsWriteCmd.valid := valid tagsWriteCmd.valid := valid
tagsWriteCmd.address := mmuRsp.physicalAddress(lineRange) tagsWriteCmd.address := mmuRsp.physicalAddress(lineRange)
tagsWriteCmd.way.setAll() tagsWriteCmd.way.setAll()
tagsWriteCmd.data.valid := False tagsWriteCmd.data.valid := False
io.cpu.writeBack.haltIt := True io.cpu.writeBack.haltIt := True
when(!hold) {
when(mmuRsp.physicalAddress(lineRange) =/= wayLineCount - 1) { when(mmuRsp.physicalAddress(lineRange) =/= wayLineCount - 1) {
mmuRsp.physicalAddress.getDrivingReg(lineRange) := mmuRsp.physicalAddress(lineRange) + 1 mmuRsp.physicalAddress.getDrivingReg(lineRange) := mmuRsp.physicalAddress(lineRange) + 1
} otherwise { } otherwise {
valid := False valid := False
} }
} }
}
io.cpu.flush.ready := False io.cpu.flush.ready := False
val start = RegInit(True) //Used to relax timings val start = RegInit(True) //Used to relax timings
@ -867,6 +909,7 @@ class DataCache(val p : DataCacheConfig) extends Component{
//Invalidate cache tag //Invalidate cache tag
when(wayHit) { when(wayHit) {
tagsWriteCmd.valid := True tagsWriteCmd.valid := True
stageB.flusher.hold := True
tagsWriteCmd.address := input.address(lineRange) tagsWriteCmd.address := input.address(lineRange)
tagsWriteCmd.data.valid := False tagsWriteCmd.data.valid := False
tagsWriteCmd.way := wayHits tagsWriteCmd.way := wayHits

View File

@ -184,7 +184,7 @@ class DBusCachedPlugin(val config : DataCacheConfig,
case true if !withExternalAmo => dBus.rsp.m2sPipe() case true if !withExternalAmo => dBus.rsp.m2sPipe()
case true if withExternalAmo => { case true if withExternalAmo => {
val rsp = Flow (DataCacheMemRsp(cache.p)) val rsp = Flow (DataCacheMemRsp(cache.p))
rsp.valid := RegNext(dBus.rsp.valid) rsp.valid := RegNext(dBus.rsp.valid) init(False)
rsp.exclusive := RegNext(dBus.rsp.exclusive) rsp.exclusive := RegNext(dBus.rsp.exclusive)
rsp.error := RegNext(dBus.rsp.error) rsp.error := RegNext(dBus.rsp.error)
rsp.last := RegNext(dBus.rsp.last) rsp.last := RegNext(dBus.rsp.last)
@ -196,6 +196,7 @@ class DBusCachedPlugin(val config : DataCacheConfig,
if(withInvalidate) { if(withInvalidate) {
cache.io.mem.inv << dBus.inv cache.io.mem.inv << dBus.inv
cache.io.mem.ack >> dBus.ack cache.io.mem.ack >> dBus.ack
cache.io.mem.sync << dBus.sync
} }
pipeline plug new Area{ pipeline plug new Area{