fix(dcache): 解决写回时数据备份问题

This commit is contained in:
Liphen 2024-01-21 12:37:50 +08:00
parent 7a32abba57
commit c6d8f9ed8f
1 changed files with 32 additions and 42 deletions

View File

@ -161,9 +161,9 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
val wstrb = Vec(nway, UInt(nbank.W)) // 用于控制写回哪个bank val wstrb = Vec(nway, UInt(nbank.W)) // 用于控制写回哪个bank
})) }))
// 用于解决在replace时读写时序不一致的问题 // 用于解决在replace时发生写回时读写时序不一致的问题
val bank_windex = RegInit(0.U((offsetWidth - log2Ceil(XLEN / 8)).W)) val bank_wbindex = RegInit(0.U((offsetWidth - log2Ceil(XLEN / 8)).W))
val bank_replication = RegInit(VecInit(Seq.fill(nbank)(0.U(XLEN.W)))) val bank_wbdata = RegInit(VecInit(Seq.fill(nbank)(0.U(XLEN.W))))
// 是否使用exe的地址进行提前访存 // 是否使用exe的地址进行提前访存
val use_next_addr = (state === s_idle) || (state === s_wait) val use_next_addr = (state === s_idle) || (state === s_wait)
@ -346,12 +346,6 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
}.otherwise { }.otherwise {
when(!cache_hit) { when(!cache_hit) {
state := s_replace state := s_replace
bank_windex := 0.U
burst.wstrb(replace_way) := 1.U // 先写入第一块bank
when(replace_dirty) {
// cache行的脏位为真时需要写回备份一下cache行便于处理读写时序问题
(0 until nbank).map(i => bank_replication(i) := data(i)(replace_way))
}
}.otherwise { }.otherwise {
when(!dcache_stall) { when(!dcache_stall) {
// update lru and mark dirty // update lru and mark dirty
@ -402,9 +396,9 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
when(w.last) { when(w.last) {
wvalid := false.B wvalid := false.B
}.otherwise { }.otherwise {
bank_windex := bank_windex + 1.U bank_wbindex := bank_wbindex + 1.U
w.data := data(bank_windex + 1.U)(dirty_way) w.data := data(bank_wbindex + 1.U)(dirty_way)
when(bank_windex + 1.U === (cached_len).U) { when(bank_wbindex + 1.U === (cached_len).U) {
w.last := true.B w.last := true.B
} }
} }
@ -432,7 +426,7 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
w.strb := ~0.U(AXI_STRB_WID.W) w.strb := ~0.U(AXI_STRB_WID.W)
w.last := false.B w.last := false.B
wvalid := true.B wvalid := true.B
bank_windex := 0.U bank_wbindex := 0.U
fence := true.B fence := true.B
} }
}.otherwise { }.otherwise {
@ -451,9 +445,9 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
when(w.last) { when(w.last) {
wvalid := false.B wvalid := false.B
}.otherwise { }.otherwise {
bank_windex := bank_windex + 1.U bank_wbindex := bank_wbindex + 1.U
w.data := bank_replication(bank_windex + 1.U) w.data := bank_wbdata(bank_wbindex + 1.U)
when(bank_windex + 1.U === (cached_len).U) { when(bank_wbindex + 1.U === (cached_len).U) {
w.last := true.B w.last := true.B
} }
} }
@ -518,15 +512,17 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
tag_wdata := ptw_scratch.paddr.tag tag_wdata := ptw_scratch.paddr.tag
} }
when(replace_dirty) { when(replace_dirty) {
// cache行的脏位为真时需要写回备份一下cache行便于处理读写时序问题
(0 until nbank).map(i => bank_wbdata(i) := data(i)(replace_way))
aw.addr := Cat(tag(replace_way), replace_index, 0.U(offsetWidth.W)) aw.addr := Cat(tag(replace_way), replace_index, 0.U(offsetWidth.W))
aw.len := cached_len.U aw.len := cached_len.U
aw.size := cached_size.U aw.size := cached_size.U
awvalid := true.B awvalid := true.B
w.data := bank_replication(0) w.data := data(0)(replace_way)
w.strb := ~0.U(AXI_STRB_WID.W) w.strb := ~0.U(AXI_STRB_WID.W)
w.last := false.B w.last := false.B
wvalid := true.B wvalid := true.B
bank_windex := 0.U bank_wbindex := 0.U
} }
} }
} }
@ -672,12 +668,6 @@ class DCache(cacheConfig: CacheConfig)(implicit cpuConfig: CpuConfig) extends Mo
}.otherwise { }.otherwise {
ptw_scratch.replace := true.B ptw_scratch.replace := true.B
state := s_replace // 直接复用dcache的replace状态机帮我们进行replace操作 state := s_replace // 直接复用dcache的replace状态机帮我们进行replace操作
bank_windex := 0.U
burst.wstrb(replace_way) := 1.U // 先写入第一块bank
when(replace_dirty) {
// cache行的脏位为真时需要写回备份一下cache行便于处理读写时序问题
(0 until nbank).map(i => bank_replication(i) := data(i)(replace_way))
}
} }
} }
} }