From e266678e90d89e249c09ae9bf45050a4838c4290 Mon Sep 17 00:00:00 2001 From: Liphen Date: Sun, 12 Nov 2023 16:27:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9cache=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chisel/playground/src/cache/DCache.scala | 122 ++++++++++++++++++-- chisel/playground/src/cache/ICache.scala | 15 ++- chisel/playground/src/defines/Bundles.scala | 41 +++---- chisel/playground/src/defines/Const.scala | 5 +- 4 files changed, 142 insertions(+), 41 deletions(-) diff --git a/chisel/playground/src/cache/DCache.scala b/chisel/playground/src/cache/DCache.scala index 4826975..b5998e3 100644 --- a/chisel/playground/src/cache/DCache.scala +++ b/chisel/playground/src/cache/DCache.scala @@ -9,20 +9,122 @@ import cpu.defines._ import cpu.CpuConfig import cpu.defines.Const._ -class WriteBufferUnit extends Bundle { - val data = UInt(DATA_WID.W) - val addr = UInt(DATA_ADDR_WID.W) - val strb = UInt(4.W) - val size = UInt(2.W) -} - class DCache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Module { val io = IO(new Bundle { - val cpu = Flipped(new Cache_DCache()) - val axi = new DCache_AXIInterface() + val cpu = Flipped(new Cache_DCache()) + val axi = new DCache_AXIInterface() }) // * fsm * // val s_idle :: s_read :: s_write :: s_finishwait :: Nil = Enum(4) - val state = RegInit(s_idle) + val status = RegInit(s_idle) + + val wstrb_gen = Wire(UInt(8.W)) + wstrb_gen := MuxLookup(io.cpu.size, "b1111_1111".U)( + Seq( + 0.U -> ("b1".U << io.cpu.addr(2, 0)), + 1.U -> ("b11".U << Cat(io.cpu.addr(2, 1), 0.U(1.W))), + 2.U -> ("b1111".U << Cat(io.cpu.addr(2), 0.U(2.W))), + 3.U -> ("b1111_1111".U) + ) + ) + + io.cpu.valid := status === s_finishwait + + val addr_err = io.cpu.addr(63, 32).orR + + // default + io.axi.aw.addr := 0.U + io.axi.aw.len := 0.U + io.axi.aw.size := 0.U + io.axi.aw.burst := BURST_FIXED.U + io.axi.aw.valid := 0.U + io.axi.w.data := 0.U + io.axi.w.strb := 0.U + io.axi.w.last := 1.U + io.axi.w.valid := 0.U + io.axi.b.ready := 1.U + io.axi.ar.addr := 0.U + io.axi.ar.len := 0.U + io.axi.ar.size := 0.U + io.axi.ar.burst := BURST_FIXED.U + io.axi.ar.valid := 0.U + io.axi.r.ready := 1.U + io.cpu.rdata := 0.U + + switch(status) { + is(s_idle) { + when(io.cpu.en) { + when(addr_err) { + io.cpu.acc_err := true.B + status := s_finishwait + }.otherwise { + when(io.cpu.write) { + io.axi.aw.addr := io.cpu.addr(31, 0) + io.axi.aw.size := Cat(false.B, io.cpu.size) + io.axi.aw.valid := true.B + io.axi.w.data := io.cpu.wdata + io.axi.w.strb := wstrb_gen + io.axi.w.valid := true.B + status := s_write + }.otherwise { + io.axi.ar.addr := io.cpu.addr(31, 0) + io.axi.ar.size := Cat(false.B, io.cpu.size) + io.axi.ar.valid := true.B + status := s_read + } + } + } + } + is(s_read) { + when(io.axi.ar.ready) { + io.axi.ar.valid := false.B + } + when(io.axi.r.valid) { + io.cpu.rdata := io.axi.r.data + io.cpu.acc_err := io.axi.r.resp =/= RESP_OKEY.U + status := s_finishwait + } + } + is(s_write) { + when(io.axi.aw.ready) { + io.axi.aw.valid := false.B + } + when(io.axi.w.ready) { + io.axi.w.valid := false.B + } + when(io.axi.b.valid) { + io.cpu.acc_err := io.axi.b.resp =/= RESP_OKEY.U + status := s_finishwait + } + } + is(s_finishwait) { + when(io.cpu.ready) { + io.cpu.acc_err := false.B + when(io.cpu.en) { + when(addr_err) { + io.cpu.acc_err := true.B + status := s_finishwait + }.otherwise { + when(io.cpu.write) { + io.axi.aw.addr := io.cpu.addr(31, 0) + io.axi.aw.size := Cat(false.B, io.cpu.size) + io.axi.aw.valid := true.B + io.axi.w.data := io.cpu.wdata + io.axi.w.strb := wstrb_gen + io.axi.w.valid := true.B + status := s_write + }.otherwise { + io.axi.ar.addr := io.cpu.addr(31, 0) + io.axi.ar.size := Cat(false.B, io.cpu.size) + io.axi.ar.valid := true.B + status := s_read + } + } + }.otherwise { + status := s_idle + } + } + } + } } diff --git a/chisel/playground/src/cache/ICache.scala b/chisel/playground/src/cache/ICache.scala index c99d1b8..009cbdd 100644 --- a/chisel/playground/src/cache/ICache.scala +++ b/chisel/playground/src/cache/ICache.scala @@ -20,6 +20,7 @@ class ICache(implicit config: CpuConfig) extends Module { io.cpu.valid := status === s_finishwait val addr_err = io.cpu.addr.orR + // default io.axi.ar.addr := 0.U io.axi.ar.len := 0.U io.axi.ar.size := 2.U @@ -32,12 +33,14 @@ class ICache(implicit config: CpuConfig) extends Module { switch(status) { is(s_idle) { when(io.cpu.en) { - io.cpu.acc_err := true.B - status := s_finishwait - }.otherwise { - io.axi.ar.addr := Cat(io.cpu.addr(31, 2), 0.U(2.W)) - io.axi.ar.valid := true.B - status := s_read + when(addr_err) { + io.cpu.acc_err := true.B + status := s_finishwait + }.otherwise { + io.axi.ar.addr := Cat(io.cpu.addr(31, 2), 0.U(2.W)) + io.axi.ar.valid := true.B + status := s_read + } } } is(s_read) { diff --git a/chisel/playground/src/defines/Bundles.scala b/chisel/playground/src/defines/Bundles.scala index acd5293..3aa7df8 100644 --- a/chisel/playground/src/defines/Bundles.scala +++ b/chisel/playground/src/defines/Bundles.scala @@ -116,10 +116,10 @@ class WriteBackCtrl extends Bundle { // cpu to icache class Cache_ICache(implicit val config: CpuConfig) extends Bundle { // read inst request from cpu - val en = Output(Bool()) - val ready = Output(Bool()) - val addr = Output(UInt(INST_ADDR_WID.W)) // virtual address and next virtual address - val fence = Output(Bool()) + val en = Output(Bool()) + val ready = Output(Bool()) + val addr = Output(UInt(INST_ADDR_WID.W)) // virtual address and next virtual address + val fence_i = Output(Bool()) // read inst result val rdata = Input(UInt(INST_WID.W)) @@ -129,20 +129,17 @@ class Cache_ICache(implicit val config: CpuConfig) extends Bundle { // cpu to dcache class Cache_DCache extends Bundle { - val cpu_stall = Output(Bool()) - val dcache_stall = Input(Bool()) + val addr = Output(UInt(DATA_ADDR_WID.W)) + val size = Output(UInt(2.W)) + val en = Output(Bool()) + val write = Output(Bool()) + val wdata = Output(UInt(DATA_WID.W)) + val ready = Output(Bool()) + val fence_i = Output(Bool()) - val execute_addr = Output(UInt(32.W)) - // 连接 mem unit - val rdata = Input(UInt(32.W)) - val en = Output(Bool()) - val wen = Output(UInt(4.W)) - val rlen = Output(UInt(2.W)) - val wdata = Output(UInt(32.W)) - val addr = Output(UInt(32.W)) - - val fence = Output(Bool()) - val fence_addr = Output(UInt(32.W)) + val rdata = Input(UInt(DATA_WID.W)) + val valid = Input(Bool()) + val acc_err = Input(Bool()) } // axi @@ -210,11 +207,11 @@ class ICache_AXIInterface extends Bundle { } class DCache_AXIInterface extends ICache_AXIInterface { - val aw = Decoupled(new AW()) - - val w = Decoupled(new W()) - - val b = Flipped(Decoupled()) + val aw = new AW() + val w = new W() + val b = new B() + val ar = new AR() + val r = new R() } class Cache_AXIInterface extends Bundle { diff --git a/chisel/playground/src/defines/Const.scala b/chisel/playground/src/defines/Const.scala index 7b339fe..8bcff72 100644 --- a/chisel/playground/src/defines/Const.scala +++ b/chisel/playground/src/defines/Const.scala @@ -146,13 +146,12 @@ trait Constants { val INST_ADDR_WID = PC_WID // data ram - val DATA_ADDR_WID = 32 + val DATA_ADDR_WID = PC_WID // GPR RegFile val AREG_NUM = 32 val REG_ADDR_WID = 5 - val DATA_WID = 32 - val HILO_WID = 64 + val DATA_WID = 64 // CP0寄存器 // CP0 Register (5.w), Select (3.w)