fix(dcache): 修复fence.i指令

This commit is contained in:
Liphen 2024-01-20 14:03:11 +08:00
parent 1ce49a39b3
commit a035dc5028
1 changed files with 13 additions and 27 deletions

View File

@ -132,29 +132,17 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
val dirty = RegInit(VecInit(Seq.fill(nindex)(VecInit(Seq.fill(nway)(false.B))))) val dirty = RegInit(VecInit(Seq.fill(nindex)(VecInit(Seq.fill(nway)(false.B)))))
val lru = RegInit(VecInit(Seq.fill(nindex)(false.B))) // TODO:支持更多路数目前只支持2路 val lru = RegInit(VecInit(Seq.fill(nindex)(false.B))) // TODO:支持更多路数目前只支持2路
// 对于2路组相连的cache: 0:第0路脏位为真1:第1路脏位为真2:两路都为假
val dirty_table = Wire(Vec(nindex, UInt(log2Ceil(nway + 1).W)))
// 用于指示哪个行的脏位为真 // 用于指示哪个行的脏位为真
val dirty_index = Wire(UInt(indexWidth.W)) val dirty_index = Wire(UInt(indexWidth.W))
dirty_index := PriorityEncoder(dirty.map(_.asUInt.orR))
// 用于指示哪个路的脏位为真 // 用于指示哪个路的脏位为真
val dirty_way = dirty_table(dirty_index) val dirty_way = dirty(dirty_index)(1)
for (i <- 0 until nindex) {
val dirtyMappings = (0 until nway).map { way =>
dirty(i)(way) -> way.U
}
dirty_table(i) := MuxCase(
nway.U,
dirtyMappings
)
}
dirty_index := PriorityEncoder(dirty_table.map(w => w =/= nway.U))
// 表示进入fence的写回状态 // 表示进入fence的写回状态
val fence = RegInit(false.B) val fence = RegInit(false.B)
// 表示准备好了fence的写回数据因为bank读数据要两拍
val fence_data_ready = RegInit(false.B) // 读取bank这类sram的数据需要两拍
val readsram = RegInit(false.B)
// 对于uncached段使用writeFifo进行写回 // 对于uncached段使用writeFifo进行写回
val writeFifo = Module(new Queue(new WriteBufferUnit(), writeFifoDepth)) val writeFifo = Module(new Queue(new WriteBufferUnit(), writeFifoDepth))
@ -177,7 +165,6 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
// 是否使用exe的地址进行提前访存 // 是否使用exe的地址进行提前访存
val use_next_addr = (state === s_idle) || (state === s_wait) val use_next_addr = (state === s_idle) || (state === s_wait)
val do_replace = RegInit(false.B) val do_replace = RegInit(false.B)
val readbank = RegInit(false.B)
// replace index 表示行的索引 // replace index 表示行的索引
val replace_index = Wire(UInt(indexWidth.W)) val replace_index = Wire(UInt(indexWidth.W))
replace_index := io.cpu.addr(indexWidth + offsetWidth - 1, offsetWidth) replace_index := io.cpu.addr(indexWidth + offsetWidth - 1, offsetWidth)
@ -380,8 +367,8 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
// fence.i 需要将所有脏位为true的行写回 // fence.i 需要将所有脏位为true的行写回
when(dirty.asUInt.orR) { when(dirty.asUInt.orR) {
when(!writeFifo_busy) { when(!writeFifo_busy) {
state := s_fence state := s_fence
fence_data_ready := false.B // bank读数据要两拍 readsram := false.B // bank读数据要两拍
} }
}.otherwise { }.otherwise {
// 当所有脏位为fault时fence.i可以直接完成 // 当所有脏位为fault时fence.i可以直接完成
@ -421,12 +408,13 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
// TODO: 增加此处的acc_err错误处理 // TODO: 增加此处的acc_err错误处理
// acc_err := io.axi.b.bits.resp =/= RESP_OKEY.U // acc_err := io.axi.b.bits.resp =/= RESP_OKEY.U
dirty(dirty_index)(dirty_way) := false.B // 写回完成清除脏位 dirty(dirty_index)(dirty_way) := false.B // 写回完成清除脏位
fence_data_ready := false.B
fence := false.B fence := false.B
} }
}.elsewhen(dirty.asUInt.orR) { }.elsewhen(dirty.asUInt.orR) {
when(fence_data_ready) { readsram := true.B
when(readsram) {
// for axi write // for axi write
readsram := false.B
aw.addr := Cat( aw.addr := Cat(
Mux(dirty_way === 0.U, tagRam(0).io.rdata, tagRam(1).io.rdata), Mux(dirty_way === 0.U, tagRam(0).io.rdata, tagRam(1).io.rdata),
dirty_index, dirty_index,
@ -441,8 +429,6 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
wvalid := true.B wvalid := true.B
bank_windex := 0.U bank_windex := 0.U
fence := true.B fence := true.B
}.otherwise {
fence_data_ready := true.B
} }
}.otherwise { }.otherwise {
state := s_wait state := s_wait
@ -506,9 +492,9 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
} }
}.otherwise { }.otherwise {
// 增加了一拍用于sram读取数据 // 增加了一拍用于sram读取数据
readbank := true.B readsram := true.B
when(readbank) { when(readsram) {
readbank := false.B readsram := false.B
do_replace := true.B do_replace := true.B
ar.len := cached_len.U ar.len := cached_len.U
ar.size := cached_size.U // 8 字节 ar.size := cached_size.U // 8 字节