From 82b091204699f8835d7f578a060d10a8c7f9f65b Mon Sep 17 00:00:00 2001 From: Liphen Date: Sun, 24 Dec 2023 14:04:29 +0800 Subject: [PATCH] =?UTF-8?q?fix(icache):=20=E4=BF=AE=E5=A4=8Dlru=E3=80=81va?= =?UTF-8?q?lid=E5=AD=98=E5=9C=A8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chisel/playground/src/CpuConfig.scala | 2 +- chisel/playground/src/cache/Cache.scala | 6 ++- chisel/playground/src/cache/ICache.scala | 47 +++++++++++++----------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/chisel/playground/src/CpuConfig.scala b/chisel/playground/src/CpuConfig.scala index 454497c..595d5a0 100644 --- a/chisel/playground/src/CpuConfig.scala +++ b/chisel/playground/src/CpuConfig.scala @@ -28,7 +28,7 @@ case class BranchPredictorConfig( val phtDepth: Int = 6) case class CacheConfig( - nway: Int = 2, // 路数 + nway: Int = 2, // 路数,目前只支持2路 nbank: Int, // 每个项目中的bank数 nindex: Int, // 每路的项目数 bytesPerBank: Int // 每个bank中的字节数 diff --git a/chisel/playground/src/cache/Cache.scala b/chisel/playground/src/cache/Cache.scala index 9409bf2..ec94b17 100644 --- a/chisel/playground/src/cache/Cache.scala +++ b/chisel/playground/src/cache/Cache.scala @@ -14,10 +14,12 @@ class Cache(implicit config: CpuConfig) extends Module { val axi = new AXI() }) + // 每个 bank 存 2 条 32 bit 指令 implicit val iCacheConfig = - CacheConfig(nindex = 64, nbank = 4, bytesPerBank = (INST_WID / 8) * config.instFetchNum) // 每个 bank 存 2 条 32 bit 指令 + CacheConfig(nindex = 64, nbank = 4, bytesPerBank = (INST_WID / 8) * config.instFetchNum) + // 每个 bank 存 1 条 XLEN bit 数据 implicit val dCacheConfig = - CacheConfig(nindex = 128, nbank = 8, bytesPerBank = XLEN / 8) // 每个 bank 存 1 条 XLEN bit 数据 + CacheConfig(nindex = 128, nbank = 8, bytesPerBank = XLEN / 8) val icache = Module(new ICache(iCacheConfig)) val dcache = Module(new DCache(dCacheConfig)) diff --git a/chisel/playground/src/cache/ICache.scala b/chisel/playground/src/cache/ICache.scala index 7eb02b1..972203a 100644 --- a/chisel/playground/src/cache/ICache.scala +++ b/chisel/playground/src/cache/ICache.scala @@ -53,14 +53,15 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul // * 128 bit for 4 inst * // // ========================================================= // | valid | tag | bank 0 | bank 1 | bank 2 | bank 3 | - // | 1111 | 20 | 128 | 128 | 128 | 128 | + // | 1 | 20 | 128 | 128 | 128 | 128 | // ========================================================= // | bank | // | inst 0 | inst 1 | inst 2 | inst 3 | // | 32 | 32 | 32 | 32 | // ===================================== - val valid = RegInit(VecInit(Seq.fill(nindex)(VecInit(Seq.fill(nbank)(false.B))))) + // 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) @@ -74,9 +75,6 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul val tag_wstrb = RegInit(VecInit(Seq.fill(nway)(false.B))) val tag_wdata = RegInit(0.U(tagWidth.W)) - // * lru * // - val lru = RegInit(VecInit(Seq.fill(nindex * nbank)(false.B))) // TODO:检查lru的正确性 - // * itlb * // when(tlb_fill) { tlb_fill := false.B } io.cpu.tlb.fill := tlb_fill @@ -88,6 +86,14 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul valid := 0.U.asTypeOf(valid) } + // * virtual index * // + val virtual_index = io.cpu.addr(0)(indexWidth + offsetWidth - 1, offsetWidth) + + // * lru * //// TODO:检查lru的正确性,增加可拓展性,目前只支持两路的cache + val lru = RegInit(VecInit(Seq.fill(nindex)(false.B))) + // 需要替换的路号 + val replace_way = lru(virtual_index) + // * replace index * // val replace_index = RegInit(0.U(indexWidth.W)) // 用于控制写入一行cache条目中的哪个bank, 一个bank可能有多次写入 @@ -95,21 +101,18 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul VecInit(Seq.fill(nway)(VecInit(Seq.fill(nbank)(VecInit(Seq.fill(instBlocksPerBank)((false.B))))))) ) - // * virtual index * // - val virtual_index = io.cpu.addr(0)(indexWidth + offsetWidth - 1, offsetWidth) - // * cache hit * // - val tag_compare_valid = VecInit(Seq.tabulate(nway)(i => tag(i) === io.cpu.tlb.tag && valid(virtual_index)(i))) + val tag_compare_valid = VecInit(Seq.tabulate(nway)(i => tag(i) === io.cpu.tlb.tag && valid(i)(virtual_index))) val cache_hit = tag_compare_valid.contains(true.B) val cache_hit_available = cache_hit && io.cpu.tlb.translation_ok && !io.cpu.tlb.uncached - val sel = tag_compare_valid(1) + val select_way = tag_compare_valid(1) // 1路命中时值为1,0路命中时值为0 //TODO:支持更多路数 // | bank | // | inst 0 | inst 1 | // | 32 | 32 | // 将一个 bank 中的指令分成 instFetchNum 份,每份 INST_WID bit val inst_in_bank = VecInit( - Seq.tabulate(instFetchNum)(i => data(sel)(bank_index).asUInt((i + 1) * INST_WID - 1, i * INST_WID)) + Seq.tabulate(instFetchNum)(i => data(select_way)(bank_index).asUInt((i + 1) * INST_WID - 1, i * INST_WID)) ) // 将 inst_in_bank 中的指令按照 bank_offset 位偏移量重新排列 @@ -142,6 +145,7 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul // bank tag ram for { i <- 0 until nway } { // 每一个条目中有nbank个bank,每个bank存储instFetchNum个指令 + // 每次写入cache时将写完一整个cache行 val bank = Seq.fill(nbank)( Seq.fill(instBlocksPerBank)( @@ -168,6 +172,7 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul } for { i <- 0 until nway } { + // 实例化了nway个tag ram val tag_bram = Module(new LUTRam(nindex, tagWidth)) tag_bram.io.raddr := tag_raddr tag(i) := tag_bram.io.rdata @@ -226,13 +231,13 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul arvalid := true.B replace_index := virtual_index - repalce_wstrb(lru(virtual_index)).map(_.map(_ := false.B)) - repalce_wstrb(lru(virtual_index))(0)(0) := true.B // 从第一个bank的第一个指令块开始写入 - tag_wstrb(lru(virtual_index)) := true.B - tag_wdata := io.cpu.tlb.tag - valid(virtual_index)(lru(virtual_index)) := true.B + repalce_wstrb(replace_way).map(_.map(_ := false.B)) + repalce_wstrb(replace_way)(0)(0) := true.B // 从第一个bank的第一个指令块开始写入 + tag_wstrb(replace_way) := true.B + tag_wdata := io.cpu.tlb.tag + valid(replace_way)(virtual_index) := true.B }.elsewhen(!io.cpu.icache_stall) { - lru(virtual_index) := ~sel + replace_way := ~select_way when(!io.cpu.cpu_ready) { state := s_save (1 until instFetchNum).foreach(i => saved(i).inst := inst(i)) @@ -266,12 +271,12 @@ class ICache(cacheConfig: CacheConfig)(implicit config: CpuConfig) extends Modul // * burst transport * // when(!io.axi.r.bits.last) { // 左移写掩码,写入下一个bank,或是同一个bank的下一个指令 - repalce_wstrb(lru(virtual_index)) := - ((repalce_wstrb(lru(virtual_index)).asUInt << 1)).asTypeOf(repalce_wstrb(lru(virtual_index))) + repalce_wstrb(replace_way) := + ((repalce_wstrb(replace_way).asUInt << 1)).asTypeOf(repalce_wstrb(replace_way)) }.otherwise { rready := false.B - repalce_wstrb(lru(virtual_index)).map(_.map(_ := false.B)) - tag_wstrb(lru(virtual_index)) := false.B + repalce_wstrb(replace_way).map(_.map(_ := false.B)) + tag_wstrb(replace_way) := false.B } }.elsewhen(!io.axi.r.ready) { state := s_idle