dataCache now implement invalidation sync
This commit is contained in:
parent
467a2bc488
commit
46207abbc4
|
@ -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,9 +545,12 @@ 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
|
||||||
io.cpu.execute.haltIt := True
|
if(counter != null){
|
||||||
|
when(counter =/= 0 || io.cpu.memory.isValid || io.cpu.writeBack.isValid){
|
||||||
|
io.cpu.execute.haltIt := True
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -563,16 +602,19 @@ 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(mmuRsp.physicalAddress(lineRange) =/= wayLineCount - 1) {
|
when(!hold) {
|
||||||
mmuRsp.physicalAddress.getDrivingReg(lineRange) := mmuRsp.physicalAddress(lineRange) + 1
|
when(mmuRsp.physicalAddress(lineRange) =/= wayLineCount - 1) {
|
||||||
} otherwise {
|
mmuRsp.physicalAddress.getDrivingReg(lineRange) := mmuRsp.physicalAddress(lineRange) + 1
|
||||||
valid := False
|
} otherwise {
|
||||||
|
valid := False
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -194,8 +194,9 @@ 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{
|
||||||
|
|
Loading…
Reference in New Issue