fix(dcache): bankoffset及时更新
This commit is contained in:
parent
fa41d30146
commit
277c3d31ad
|
@ -74,7 +74,7 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
|
|||
})
|
||||
|
||||
// * fsm * //
|
||||
val s_idle :: s_uncached :: s_writeback :: s_replace :: s_wait :: Nil = Enum(5)
|
||||
val s_idle :: s_uncached :: s_fence :: s_replace :: s_wait :: Nil = Enum(5)
|
||||
val state = RegInit(s_idle)
|
||||
|
||||
// ==========================================================
|
||||
|
@ -107,10 +107,21 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
|
|||
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 dirty_table = Wire(Vec(nindex, UInt(log2Ceil(nway).W)))
|
||||
val dirty_index = Wire(UInt(indexWidth.W))
|
||||
val dirty_way = dirty_table(dirty_index) // 用于指示哪个路的脏位为真
|
||||
val writeback_index = RegInit(0.U(indexWidth.W))
|
||||
|
||||
for (i <- 0 until nindex) {
|
||||
dirty_table(i) := PriorityEncoder(dirty(i))
|
||||
}
|
||||
|
||||
dirty_index := PriorityEncoder(dirty_table.map(w => w =/= 0.U))
|
||||
|
||||
// 对于uncached段使用writeFifo进行写回
|
||||
val writeFifo = Module(new Queue(new WriteBufferUnit(), writeFifoDepth))
|
||||
val writeFifo_axi_busy = RegInit(false.B)
|
||||
val writeFifo_busy = (writeFifo.io.deq.valid || writeFifo_axi_busy)
|
||||
val writeFifo_busy = writeFifo.io.deq.valid // || writeFifo_axi_busy 应该不需要这个判断
|
||||
|
||||
writeFifo.io.enq.valid := false.B
|
||||
writeFifo.io.enq.bits := 0.U.asTypeOf(new WriteBufferUnit())
|
||||
|
@ -141,6 +152,7 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
|
|||
val tag_wdata = RegInit(0.U(tagWidth.W))
|
||||
|
||||
val data = Wire(Vec(nbank, Vec(nway, UInt(XLEN.W))))
|
||||
// 使用寄存器类型才能防止idle时tag出现无法hit的错误
|
||||
val tag = RegInit(VecInit(Seq.fill(nway)(0.U(tagWidth.W))))
|
||||
|
||||
val tag_compare_valid = Wire(Vec(nway, Bool()))
|
||||
|
@ -164,6 +176,7 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
|
|||
io.cpu.rdata := Mux(state === s_wait, saved_rdata, data(bank_index)(select_way))
|
||||
|
||||
// bank tagv ram
|
||||
val tagRam = Seq.fill(nway)(Module(new LUTRam(nindex, tagWidth)))
|
||||
for { i <- 0 until nway } {
|
||||
val bank = Seq.fill(nbank)(Module(new SimpleDualPortRam(nindex, AXI_DATA_WID, byteAddressable = true)))
|
||||
for { j <- 0 until nbank } {
|
||||
|
@ -176,13 +189,12 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
|
|||
bank(j).io.wdata := replace_wdata
|
||||
bank(j).io.wstrb := replace_wstrb(j)(i)
|
||||
|
||||
val tagRam = Module(new LUTRam(nindex, tagWidth))
|
||||
tagRam.io.raddr := tag_rindex
|
||||
tag(i) := tagRam.io.rdata
|
||||
tagRam(i).io.raddr := tag_rindex
|
||||
tag(i) := tagRam(i).io.rdata
|
||||
|
||||
tagRam.io.wen := tag_wstrb(i)
|
||||
tagRam.io.waddr := replace_index
|
||||
tagRam.io.wdata := tag_wdata
|
||||
tagRam(i).io.wen := tag_wstrb(i)
|
||||
tagRam(i).io.waddr := replace_index
|
||||
tagRam(i).io.wdata := tag_wdata
|
||||
|
||||
tag_compare_valid(i) := tag(i) === io.cpu.tlb.ptag && valid(replace_index)(i) && io.cpu.tlb.translation_ok
|
||||
|
||||
|
@ -219,7 +231,7 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
|
|||
io.cpu.acc_err := acc_err
|
||||
|
||||
// write buffer
|
||||
when(writeFifo_axi_busy) { // To implement SC memory ordering, when store buffer busy, axi is unseable.
|
||||
when(writeFifo_axi_busy) {
|
||||
when(io.axi.aw.fire) {
|
||||
awvalid := false.B
|
||||
}
|
||||
|
@ -304,27 +316,27 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
|
|||
}
|
||||
}
|
||||
}.elsewhen(io.cpu.fence) {
|
||||
assert(false.B, "fence not implemented")
|
||||
// when(dirty(replace_index).contains(true.B)) {
|
||||
// // fence.i 需要将所有脏位为true的行写回
|
||||
// when(dirty.asUInt.orR) {
|
||||
// when(!writeFifo_busy) {
|
||||
// state := s_writeback
|
||||
// write_offset := 0.U // 从第一块bank开始写回
|
||||
// state := s_fence
|
||||
// writeback_index := dirty_index // 从第一个脏行开始写回
|
||||
// bank_woffset := 0.U // 从第一块bank开始写回
|
||||
|
||||
// // for axi write
|
||||
// aw.addr := Cat(tag(dirty(replace_index)(1)), replace_index, 0.U(offsetWidth.W))
|
||||
// tagRam.map(_.io.raddr := writeback_index)
|
||||
// val writeback_tag = Mux(dirty_way === 0.U, tagRam(0).io.rdata, tagRam(1).io.rdata)
|
||||
// aw.addr := Cat(writeback_tag, writeback_index, 0.U(offsetWidth.W))
|
||||
// aw.len := cached_len.U
|
||||
// aw.size := cached_size.U
|
||||
// awvalid := true.B
|
||||
// w.data := data(dirty(replace_index)(1))(bank_index)
|
||||
// w.data := data(writeback_index)(0)
|
||||
// w.strb := ~0.U(AXI_STRB_WID.W)
|
||||
// w.last := false.B
|
||||
// wvalid := true.B
|
||||
// }
|
||||
// }.otherwise {
|
||||
// when(valid(replace_index).contains(true.B)) {
|
||||
// valid(replace_index)(0) := false.B
|
||||
// valid(replace_index)(1) := false.B
|
||||
// }
|
||||
// // 当所有脏位为fault时,fence.i可以直接完成
|
||||
// state := s_wait
|
||||
// }
|
||||
}
|
||||
|
@ -339,14 +351,7 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
|
|||
state := s_wait
|
||||
}
|
||||
}
|
||||
is(s_writeback) {
|
||||
assert(false.B, "writeback not implemented")
|
||||
// when(burst_cnt.value =/= (cached_len).U) {
|
||||
// burst_cnt.inc()
|
||||
// }
|
||||
// read_ready_cnt := burst_cnt.value
|
||||
// read_buffer(read_ready_cnt) := data(dirty(index)(1))
|
||||
|
||||
is(s_fence) {
|
||||
// when(io.axi.aw.fire) {
|
||||
// awvalid := false.B
|
||||
// }
|
||||
|
@ -354,22 +359,17 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
|
|||
// when(w.last) {
|
||||
// wvalid := false.B
|
||||
// }.otherwise {
|
||||
// w.data := Mux(
|
||||
// ((axi_cnt.value + 1.U) === read_ready_cnt),
|
||||
// data(dirty(index)(1)),
|
||||
// read_buffer(axi_cnt.value + 1.U)
|
||||
// )
|
||||
// axi_cnt.inc()
|
||||
// when(axi_cnt.value + 1.U === (cached_len).U) {
|
||||
// bank_woffset := bank_woffset + 1.U
|
||||
// w.data := bank_replication(bank_woffset)
|
||||
// when(bank_woffset + 1.U === (cached_len).U) {
|
||||
// w.last := true.B
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// when(io.axi.b.valid) {
|
||||
// dirty(index)(dirty(index)(1)) := false.B
|
||||
// burst.valid := false.B
|
||||
// acc_err := io.axi.b.bits.resp =/= RESP_OKEY.U
|
||||
// state := s_idle
|
||||
// // TODO: 增加此处的错误处理
|
||||
// // acc_err := io.axi.b.bits.resp =/= RESP_OKEY.U
|
||||
// replace_dirty := false.B // 写回完成,清除脏位
|
||||
// }
|
||||
}
|
||||
is(s_replace) {
|
||||
|
@ -439,6 +439,7 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
|
|||
w.strb := ~0.U(AXI_STRB_WID.W)
|
||||
w.last := false.B
|
||||
wvalid := true.B
|
||||
bank_woffset := bank_woffset + 1.U // TODO:这里应该需要更新offset
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue