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,
lengthWidth = log2Up(this.bytePerLine),
sourceWidth = 0,
contextWidth = 1,
contextWidth = if(!withWriteResponse) 1 else 0,
canRead = true,
canWrite = true,
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()
}
case class DataCacheSync(p : DataCacheConfig) extends Bundle{
}
case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave{
val cmd = Stream (DataCacheMemCmd(p))
val rsp = Flow (DataCacheMemRsp(p))
val inv = p.withInvalidate generate Stream(DataCacheInv(p))
val ack = p.withInvalidate generate Stream(DataCacheAck(p))
val sync = p.withInvalidate generate Stream(DataCacheSync(p))
override def asMaster(): Unit = {
master(cmd)
@ -207,6 +217,7 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
if(p.withInvalidate) {
slave(inv)
master(ack)
slave(sync)
}
}
@ -342,11 +353,11 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
def toBmb() : Bmb = {
val pipelinedMemoryBusConfig = p.getBmbParameter()
val bus = Bmb(pipelinedMemoryBusConfig)
val bus = Bmb(pipelinedMemoryBusConfig).setCompositeName(this,"toBmb", true)
bus.cmd.valid := cmd.valid
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.address := cmd.address.resized
bus.cmd.data := cmd.data
@ -356,22 +367,33 @@ case class DataCacheMemBus(p : DataCacheConfig) extends Bundle with IMasterSlave
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.error := bus.rsp.isError
rsp.last := bus.rsp.last
if(p.withExclusive) rsp.exclusive := bus.rsp.exclusive
bus.rsp.ready := True
if(p.withInvalidate){
bus.ack.arbitrationFrom(ack)
//TODO manage lenght ?
inv.arbitrationFrom(bus.inv)
inv.address := bus.inv.address
// inv.opcode := bus.inv.opcode
???
inv.enable := bus.inv.all
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
}
@ -440,9 +462,10 @@ class DataCache(val p : DataCacheConfig) extends Component{
//Reads
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 tagsInvReadRsp = withInvalidate generate tags.readSync(tagsInvReadCmd.payload, tagsInvReadCmd.valid)
//Writes
when(tagsWriteCmd.valid && tagsWriteCmd.way(i)){
tags.write(tagsWriteCmd.address, tagsWriteCmd.data)
@ -494,11 +517,24 @@ class DataCache(val p : DataCacheConfig) extends Component{
val full = RegNext(counter.msb)
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)
}
val stage0 = new Area{
val mask = io.cpu.execute.size.mux (
@ -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 wayInvalidate = B(0, wayCount bits) //Used if invalidate enabled
if(withWriteResponse) when(io.cpu.execute.fence){
when(pending.counter =/= 0 || io.cpu.memory.isValid || io.cpu.writeBack.isValid){
when(io.cpu.execute.fence){
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
}
}
}
}
val stageA = new Area{
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
val flusher = new Area {
val valid = RegInit(False)
val hold = False
when(valid) {
tagsWriteCmd.valid := valid
tagsWriteCmd.address := mmuRsp.physicalAddress(lineRange)
tagsWriteCmd.way.setAll()
tagsWriteCmd.data.valid := False
io.cpu.writeBack.haltIt := True
when(!hold) {
when(mmuRsp.physicalAddress(lineRange) =/= wayLineCount - 1) {
mmuRsp.physicalAddress.getDrivingReg(lineRange) := mmuRsp.physicalAddress(lineRange) + 1
} otherwise {
valid := False
}
}
}
io.cpu.flush.ready := False
val start = RegInit(True) //Used to relax timings
@ -867,6 +909,7 @@ class DataCache(val p : DataCacheConfig) extends Component{
//Invalidate cache tag
when(wayHit) {
tagsWriteCmd.valid := True
stageB.flusher.hold := True
tagsWriteCmd.address := input.address(lineRange)
tagsWriteCmd.data.valid := False
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 => {
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.error := RegNext(dBus.rsp.error)
rsp.last := RegNext(dBus.rsp.last)
@ -196,6 +196,7 @@ class DBusCachedPlugin(val config : DataCacheConfig,
if(withInvalidate) {
cache.io.mem.inv << dBus.inv
cache.io.mem.ack >> dBus.ack
cache.io.mem.sync << dBus.sync
}
pipeline plug new Area{