fix(cache): 将save状态改成wait,更符合作用
This commit is contained in:
parent
ac6aefff8a
commit
108c529698
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue