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

View File

@ -77,14 +77,14 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
val tlb_fill = RegInit(false.B)
// * 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)
// nway 每路 nindex 每行 nbank bank每行的nbank共用一个valid
val valid = RegInit(VecInit(Seq.fill(nway)(VecInit(Seq.fill(nindex)(false.B)))))
// * 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行
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指令时清空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)
}
@ -200,7 +200,7 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
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 arvalid = RegInit(false.B)
@ -222,14 +222,14 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
is(s_idle) {
when(tlb_fill) {
when(!io.cpu.tlb.hit) {
state := s_save
state := s_wait
saved(0).inst := 0.U
saved(0).valid := true.B
}
}.elsewhen(io.cpu.req) {
when(addr_err) {
acc_err := true.B
state := s_save
state := s_wait
saved(0).inst := 0.U
saved(0).valid := true.B
}.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
}.elsewhen(!io.cpu.icache_stall) {
replace_way := ~select_way
when(!io.cpu.cpu_ready) {
state := s_save
when(!io.cpu.complete_single_request) {
state := s_wait
(1 until instFetchNum).foreach(i => saved(i).inst := inst(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) {
// * 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).valid := true.B
rready := false.B
@ -300,8 +300,9 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul
state := s_idle
}
}
is(s_save) {
when(io.cpu.cpu_ready && !io.cpu.icache_stall) {
is(s_wait) {
// 等待流水线的allow_to_go信号防止多次发出读请求
when(io.cpu.complete_single_request) {
state := s_idle
(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 {
// read inst request from cpu
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 fence = Output(Bool())
@ -125,7 +125,7 @@ class Cache_DCache extends Bundle {
val en = Output(Bool())
val wen = Output(Bool())
val wdata = Output(UInt(XLEN.W))
val cpu_ready = Output(Bool())
val complete_single_request = Output(Bool())
val fence = Output(Bool())
val wstrb = Output(UInt(AXI_STRB_WID.W))