fix(cache): 将save状态改成wait,更符合作用

This commit is contained in:
Liphen 2023-12-25 15:45:30 +08:00
parent ac6aefff8a
commit 108c529698
4 changed files with 42 additions and 53 deletions

View File

@ -133,6 +133,7 @@ class Core(implicit val config: CpuConfig) extends Module {
io.inst.fence := false.B io.inst.fence := false.B
io.data.fence := false.B io.data.fence := false.B
io.inst.req := !instFifo.full && !reset.asBool io.inst.req := !instFifo.full && !reset.asBool
io.inst.cpu_ready := ctrl.fetchUnit.allow_to_go
io.data.cpu_ready := ctrl.memoryUnit.allow_to_go io.inst.complete_single_request := ctrl.fetchUnit.allow_to_go
io.data.complete_single_request := ctrl.memoryUnit.allow_to_go
} }

View File

@ -74,7 +74,7 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
}) })
// * fsm * // // * fsm * //
val s_idle :: s_uncached :: s_writeback :: s_replace :: s_save :: Nil = Enum(5) val s_idle :: s_uncached :: s_writeback :: s_replace :: s_wait :: Nil = Enum(5)
val state = RegInit(s_idle) val state = RegInit(s_idle)
// ========================================================== // ==========================================================
@ -113,14 +113,13 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
writeFifo.io.deq.ready := false.B writeFifo.io.deq.ready := false.B
val axi_cnt = Counter(cached_len + 1) val axi_cnt = Counter(cached_len + 1)
val read_ready_cnt = RegInit(0.U(4.W)) val read_ready_cnt = RegInit(0.U((offsetWidth - log2Ceil(XLEN / 8)).W))
val read_ready_index = RegInit(0.U(6.W))
// * victim cache * // // * victim cache * //
val victim = RegInit(0.U.asTypeOf(new Bundle { val victim = RegInit(0.U.asTypeOf(new Bundle {
val valid = Bool() val valid = Bool()
val index = UInt(6.W) val index = UInt(indexWidth.W)
val waddr = UInt(10.W) val waddr = UInt((indexWidth + offsetWidth - log2Ceil(XLEN / 8) + 1).W)
val wstrb = Vec(nway, UInt(AXI_STRB_WID.W)) val wstrb = Vec(nway, UInt(AXI_STRB_WID.W))
val working = Bool() val working = Bool()
val writeback = Bool() val writeback = Bool()
@ -164,7 +163,7 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
val dcache_stall = Mux( val dcache_stall = Mux(
state === s_idle && !tlb_fill, state === s_idle && !tlb_fill,
Mux(io.cpu.en, (cached_stall || mmio_read_stall || mmio_write_stall || !io.cpu.tlb.translation_ok), io.cpu.fence), Mux(io.cpu.en, (cached_stall || mmio_read_stall || mmio_write_stall || !io.cpu.tlb.translation_ok), io.cpu.fence),
state =/= s_save state =/= s_wait
) )
io.cpu.dcache_ready := !dcache_stall io.cpu.dcache_ready := !dcache_stall
@ -176,7 +175,7 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
val last_wdata = RegNext(replace_wdata) val last_wdata = RegNext(replace_wdata)
val cache_data_forward = Wire(Vec(nway, UInt(XLEN.W))) val cache_data_forward = Wire(Vec(nway, UInt(XLEN.W)))
io.cpu.rdata := Mux(state === s_save, saved_rdata, cache_data_forward(select_way)) io.cpu.rdata := Mux(state === s_wait, saved_rdata, cache_data_forward(select_way))
// bank tagv ram // bank tagv ram
for { i <- 0 until nway } { for { i <- 0 until nway } {
@ -239,8 +238,6 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
} }
io.cpu.acc_err := acc_err io.cpu.acc_err := acc_err
val current_mmio_write_saved = RegInit(false.B)
// write buffer // write buffer
when(writeFifo_axi_busy) { // To implement SC memory ordering, when store buffer busy, axi is unseable. when(writeFifo_axi_busy) { // To implement SC memory ordering, when store buffer busy, axi is unseable.
when(io.axi.aw.fire) { when(io.axi.aw.fire) {
@ -273,34 +270,27 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
when(tlb_fill) { when(tlb_fill) {
tlb_fill := false.B tlb_fill := false.B
when(!io.cpu.tlb.hit) { when(!io.cpu.tlb.hit) {
state := s_save state := s_wait
} }
}.elsewhen(io.cpu.en) { }.elsewhen(io.cpu.en) {
when(addr_err) { when(addr_err) {
acc_err := true.B acc_err := true.B
}.elsewhen(!io.cpu.tlb.translation_ok) { }.elsewhen(!io.cpu.tlb.translation_ok) {
when(io.cpu.tlb.tlb1_ok) { when(io.cpu.tlb.tlb1_ok) {
state := s_save state := s_wait
}.otherwise { }.otherwise {
tlb_fill := true.B tlb_fill := true.B
} }
}.elsewhen(io.cpu.tlb.uncached) { }.elsewhen(io.cpu.tlb.uncached) {
when(io.cpu.wen.orR) { when(io.cpu.wen.orR) {
when(writeFifo.io.enq.ready && !current_mmio_write_saved) { when(writeFifo.io.enq.ready) {
writeFifo.io.enq.valid := true.B writeFifo.io.enq.valid := true.B
writeFifo.io.enq.bits.addr := Mux( writeFifo.io.enq.bits.addr := io.cpu.tlb.paddr
io.cpu.rlen === 2.U,
Cat(io.cpu.tlb.paddr(31, 2), 0.U(2.W)),
io.cpu.tlb.paddr
)
writeFifo.io.enq.bits.size := io.cpu.rlen writeFifo.io.enq.bits.size := io.cpu.rlen
writeFifo.io.enq.bits.strb := io.cpu.wstrb writeFifo.io.enq.bits.strb := io.cpu.wstrb
writeFifo.io.enq.bits.data := io.cpu.wdata writeFifo.io.enq.bits.data := io.cpu.wdata
current_mmio_write_saved := true.B state := s_wait
}
when(io.cpu.dcache_ready && io.cpu.cpu_ready) {
current_mmio_write_saved := false.B
} }
}.elsewhen(!(writeFifo.io.deq.valid || writeFifo_axi_busy)) { }.elsewhen(!(writeFifo.io.deq.valid || writeFifo_axi_busy)) {
ar.addr := Mux(io.cpu.rlen === 2.U, Cat(io.cpu.tlb.paddr(31, 2), 0.U(2.W)), io.cpu.tlb.paddr) ar.addr := Mux(io.cpu.rlen === 2.U, Cat(io.cpu.tlb.paddr(31, 2), 0.U(2.W)), io.cpu.tlb.paddr)
@ -316,7 +306,6 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
axi_cnt.reset() axi_cnt.reset()
victim.index := index victim.index := index
victim_cnt.reset() victim_cnt.reset()
read_ready_index := index
read_ready_cnt := 0.U read_ready_cnt := 0.U
victim.waddr := Cat(index, 0.U((offsetWidth - log2Ceil(XLEN / 8)).W)) victim.waddr := Cat(index, 0.U((offsetWidth - log2Ceil(XLEN / 8)).W))
victim.valid := true.B victim.valid := true.B
@ -328,9 +317,9 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
when(io.cpu.wen.orR) { when(io.cpu.wen.orR) {
dirty(index)(select_way) := true.B dirty(index)(select_way) := true.B
} }
when(!io.cpu.cpu_ready) { when(!io.cpu.complete_single_request) {
saved_rdata := cache_data_forward(select_way) saved_rdata := cache_data_forward(select_way)
state := s_save state := s_wait
} }
} }
} }
@ -342,7 +331,6 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
axi_cnt.reset() axi_cnt.reset()
victim.index := fence_index victim.index := fence_index
victim_cnt.reset() victim_cnt.reset()
read_ready_index := fence_index
read_ready_cnt := 0.U read_ready_cnt := 0.U
victim.valid := true.B victim.valid := true.B
} }
@ -351,7 +339,7 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
valid(fence_index)(0) := false.B valid(fence_index)(0) := false.B
valid(fence_index)(1) := false.B valid(fence_index)(1) := false.B
} }
state := s_save state := s_wait
} }
} }
} }
@ -362,7 +350,7 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
when(io.axi.r.valid) { when(io.axi.r.valid) {
saved_rdata := io.axi.r.bits.data saved_rdata := io.axi.r.bits.data
acc_err := io.axi.r.bits.resp =/= RESP_OKEY.U acc_err := io.axi.r.bits.resp =/= RESP_OKEY.U
state := s_save state := s_wait
} }
} }
is(s_writeback) { is(s_writeback) {
@ -370,7 +358,6 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
when(victim_cnt.value =/= (cached_len).U) { when(victim_cnt.value =/= (cached_len).U) {
victim_cnt.inc() victim_cnt.inc()
} }
read_ready_index := victim.index
read_ready_cnt := victim_cnt.value read_ready_cnt := victim_cnt.value
read_buffer(read_ready_cnt) := data(dirty(fence_index)(1)) read_buffer(read_ready_cnt) := data(dirty(fence_index)(1))
when(!aw_handshake) { when(!aw_handshake) {
@ -422,7 +409,6 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
when(victim_cnt.value =/= (cached_len).U) { when(victim_cnt.value =/= (cached_len).U) {
victim_cnt.inc() victim_cnt.inc()
} }
read_ready_index := victim.index
read_ready_cnt := victim_cnt.value read_ready_cnt := victim_cnt.value
read_buffer(read_ready_cnt) := data(replace_way) read_buffer(read_ready_cnt) := data(replace_way)
when(!aw_handshake) { when(!aw_handshake) {
@ -500,8 +486,9 @@ class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
} }
} }
} }
is(s_save) { is(s_wait) {
when(io.cpu.dcache_ready && io.cpu.cpu_ready) { // 等待流水线的allow_to_go信号防止多次发出读写请求
when(io.cpu.complete_single_request) {
state := s_idle state := s_idle
} }
} }

View File

@ -77,14 +77,14 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
val tlb_fill = RegInit(false.B) val tlb_fill = RegInit(false.B)
// * fsm * // // * fsm * //
val s_idle :: s_uncached :: s_replace :: s_save :: Nil = Enum(4) val s_idle :: s_uncached :: s_replace :: s_wait :: Nil = Enum(4)
val state = RegInit(s_idle) val state = RegInit(s_idle)
// nway 每路 nindex 每行 nbank bank每行的nbank共用一个valid // nway 每路 nindex 每行 nbank bank每行的nbank共用一个valid
val valid = RegInit(VecInit(Seq.fill(nway)(VecInit(Seq.fill(nindex)(false.B))))) val valid = RegInit(VecInit(Seq.fill(nway)(VecInit(Seq.fill(nindex)(false.B)))))
// * should choose next addr * // // * should choose next addr * //
val should_next_addr = (state === s_idle && !tlb_fill) || (state === s_save) val should_next_addr = (state === s_idle && !tlb_fill) || (state === s_wait)
// 读取一个cache条目中的所有bank行 // 读取一个cache条目中的所有bank行
val data = Wire(Vec(nway, Vec(nbank, Vec(instBlocksPerBank, UInt(AXI_DATA_WID.W))))) val data = Wire(Vec(nway, Vec(nbank, Vec(instBlocksPerBank, UInt(AXI_DATA_WID.W)))))
@ -101,7 +101,7 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
// * fence * // // * fence * //
// fence指令时清空cache等同于将所有valid位置0 // fence指令时清空cache等同于将所有valid位置0
when(io.cpu.fence && !io.cpu.icache_stall && io.cpu.cpu_ready) { when(io.cpu.fence && !io.cpu.icache_stall && io.cpu.complete_single_request) {
valid := 0.U.asTypeOf(valid) valid := 0.U.asTypeOf(valid)
} }
@ -200,7 +200,7 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
tagBram.io.wdata := tag_wdata tagBram.io.wdata := tag_wdata
} }
io.cpu.icache_stall := Mux(state === s_idle && !tlb_fill, (!cache_hit_available && io.cpu.req), state =/= s_save) io.cpu.icache_stall := Mux(state === s_idle && !tlb_fill, (!cache_hit_available && io.cpu.req), state =/= s_wait)
val ar = RegInit(0.U.asTypeOf(new AR())) val ar = RegInit(0.U.asTypeOf(new AR()))
val arvalid = RegInit(false.B) val arvalid = RegInit(false.B)
@ -222,14 +222,14 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
is(s_idle) { is(s_idle) {
when(tlb_fill) { when(tlb_fill) {
when(!io.cpu.tlb.hit) { when(!io.cpu.tlb.hit) {
state := s_save state := s_wait
saved(0).inst := 0.U saved(0).inst := 0.U
saved(0).valid := true.B saved(0).valid := true.B
} }
}.elsewhen(io.cpu.req) { }.elsewhen(io.cpu.req) {
when(addr_err) { when(addr_err) {
acc_err := true.B acc_err := true.B
state := s_save state := s_wait
saved(0).inst := 0.U saved(0).inst := 0.U
saved(0).valid := true.B saved(0).valid := true.B
}.elsewhen(!io.cpu.tlb.translation_ok) { }.elsewhen(!io.cpu.tlb.translation_ok) {
@ -256,8 +256,8 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
valid(replace_way)(virtual_index) := true.B valid(replace_way)(virtual_index) := true.B
}.elsewhen(!io.cpu.icache_stall) { }.elsewhen(!io.cpu.icache_stall) {
replace_way := ~select_way replace_way := ~select_way
when(!io.cpu.cpu_ready) { when(!io.cpu.complete_single_request) {
state := s_save state := s_wait
(1 until instFetchNum).foreach(i => saved(i).inst := inst(i)) (1 until instFetchNum).foreach(i => saved(i).inst := inst(i))
(0 until instFetchNum).foreach(i => saved(i).valid := inst_valid(i)) (0 until instFetchNum).foreach(i => saved(i).valid := inst_valid(i))
} }
@ -272,7 +272,7 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
} }
}.elsewhen(io.axi.r.fire) { }.elsewhen(io.axi.r.fire) {
// * uncached not support burst transport * // // * uncached not support burst transport * //
state := s_save state := s_wait
saved(0).inst := Mux(ar.addr(2), io.axi.r.bits.data(63, 32), io.axi.r.bits.data(31, 0)) saved(0).inst := Mux(ar.addr(2), io.axi.r.bits.data(63, 32), io.axi.r.bits.data(31, 0))
saved(0).valid := true.B saved(0).valid := true.B
rready := false.B rready := false.B
@ -300,8 +300,9 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
state := s_idle state := s_idle
} }
} }
is(s_save) { is(s_wait) {
when(io.cpu.cpu_ready && !io.cpu.icache_stall) { // 等待流水线的allow_to_go信号防止多次发出读请求
when(io.cpu.complete_single_request) {
state := s_idle state := s_idle
(0 until instFetchNum).foreach(i => saved(i).valid := false.B) (0 until instFetchNum).foreach(i => saved(i).valid := false.B)
} }

View File

@ -104,7 +104,7 @@ class WriteBackCtrl extends Bundle {
class Cache_ICache(implicit val config: CpuConfig) extends Bundle { class Cache_ICache(implicit val config: CpuConfig) extends Bundle {
// read inst request from cpu // read inst request from cpu
val req = Output(Bool()) val req = Output(Bool())
val cpu_ready = Output(Bool()) // !cpu_stall val complete_single_request = Output(Bool()) // !cpu_stall
val addr = Output(Vec(config.instFetchNum, UInt(INST_ADDR_WID.W))) // virtual address and next virtual address val addr = Output(Vec(config.instFetchNum, UInt(INST_ADDR_WID.W))) // virtual address and next virtual address
val fence = Output(Bool()) val fence = Output(Bool())
@ -125,7 +125,7 @@ class Cache_DCache extends Bundle {
val en = Output(Bool()) val en = Output(Bool())
val wen = Output(Bool()) val wen = Output(Bool())
val wdata = Output(UInt(XLEN.W)) val wdata = Output(UInt(XLEN.W))
val cpu_ready = Output(Bool()) val complete_single_request = Output(Bool())
val fence = Output(Bool()) val fence = Output(Bool())
val wstrb = Output(UInt(AXI_STRB_WID.W)) val wstrb = Output(UInt(AXI_STRB_WID.W))