From 3c8a1bc4483b994e2bc8a781eec98d22ce4cc14c Mon Sep 17 00:00:00 2001 From: Wang Huizhe Date: Mon, 8 Jul 2019 11:20:14 +0800 Subject: [PATCH 01/12] Autocat: impl blackbox module for integration --- src/main/scala/l2cache/TLSimpleL2.scala | 10 ++++++++-- src/main/scala/lvna/controlplane/ControlPlane.scala | 7 +++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/scala/l2cache/TLSimpleL2.scala b/src/main/scala/l2cache/TLSimpleL2.scala index d3dc934e..5c90f4b5 100644 --- a/src/main/scala/l2cache/TLSimpleL2.scala +++ b/src/main/scala/l2cache/TLSimpleL2.scala @@ -13,7 +13,8 @@ import freechips.rocketchip.config.{Field, Parameters} import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ import freechips.rocketchip.tilelink._ -import lvna.{HasControlPlaneParameters, CPToL2CacheIO} +import lvna.{AutoCatIOInternal, CPToL2CacheIO, HasControlPlaneParameters} + import scala.math._ case class TLL2CacheParams( @@ -43,6 +44,8 @@ with HasControlPlaneParameters val nSets = p(NL2CacheCapacity) * 1024 / 64 / nWays println(s"nSets = $nSets") val cp = IO(new CPToL2CacheIO().flip()) + val autocat = IO(new (AutoCatIOInternal).flip()) + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => require(isPow2(nSets)) require(isPow2(nWays)) @@ -325,8 +328,11 @@ with HasControlPlaneParameters hit_way := Bits(0) (0 until nWays).foreach(i => when (tag_match_way(i)) { hit_way := Bits(i) }) + autocat.access_valid_in := dsid === 0.U && state === s_tag_read + autocat.hit_vec_in := (0 until nWays).map(tag_match_way(_)).asUInt + cp.dsid := dsid - val curr_mask = cp.waymask + val curr_mask = Mux(autocat.suggested_waymask_valid_out, cp.waymask, cp.waymask & autocat.suggested_waymask_out) val repl_way = Mux((curr_state_reg & curr_mask).orR, PriorityEncoder(curr_state_reg & curr_mask), Mux(curr_mask.orR, PriorityEncoder(curr_mask), UInt(0))) val repl_dsid = set_dsids_reg(repl_way) diff --git a/src/main/scala/lvna/controlplane/ControlPlane.scala b/src/main/scala/lvna/controlplane/ControlPlane.scala index 3fc58f3e..01126545 100644 --- a/src/main/scala/lvna/controlplane/ControlPlane.scala +++ b/src/main/scala/lvna/controlplane/ControlPlane.scala @@ -280,4 +280,11 @@ trait BindL2WayMask extends HasRocketTiles { trait BindL2WayMaskModuleImp extends HasRocketTilesModuleImp { val outer: BindL2WayMask outer._l2.module.cp <> outer._cp.module.io.l2 + val autocat = Module(new AutoCat) + autocat.io.clk_in := clock + autocat.io.reset_in := reset + autocat.io.access_valid_in := outer._l2.module.autocat.access_valid_in + autocat.io.hit_vec_in := outer._l2.module.autocat.hit_vec_in + outer._l2.module.autocat.suggested_waymask_valid_out := autocat.io.suggested_waymask_valid_out + outer._l2.module.autocat.suggested_waymask_out := autocat.io.suggested_waymask_out } From b77a248c830a0632f8fa00b21b4e900573ad2eb8 Mon Sep 17 00:00:00 2001 From: Wang Huizhe Date: Tue, 23 Jul 2019 18:10:03 +0800 Subject: [PATCH 02/12] Impl. L2 miss rate counting --- src/main/scala/devices/debug/Debug.scala | 5 +++ .../scala/devices/debug/dm_registers.scala | 9 ++++ src/main/scala/l2cache/TLSimpleL2.scala | 45 +++++++++++++++++++ .../lvna/controlplane/ControlPlane.scala | 29 ++++++++++++ 4 files changed, 88 insertions(+) diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index 4928d6af..f449d78f 100644 --- a/src/main/scala/devices/debug/Debug.scala +++ b/src/main/scala/devices/debug/Debug.scala @@ -1107,6 +1107,11 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I (CORE_CSR_PENDING_INT_HI << 2) -> Seq(RegField.r(32, io.zid(io.cp.hartSel).reg_mip(63, 32), RegFieldDesc("1", "1"))), (CORE_CSR_PENDING_INT_LO << 2) -> Seq(RegField.r(32, io.zid(io.cp.hartSel).reg_mip(31, 0), RegFieldDesc("1", "1"))), + (CP_L2_STAT_RESET<<2) -> Seq(RWNotify(1, WireInit(false.B), io.cp.updateData, WireInit(false.B), io.cp.l2_stat_reset_wen)), + (CP_L2_REQ_EN << 2) -> Seq(RWNotify(1, WireInit(0.U), WireInit(0.U), io.cp.l2_miss_en, WireInit(false.B))), + (CP_L2_REQ_MISS << 2) -> Seq(RegField.r(32, io.cp.l2_req_miss)), + (CP_L2_REQ_TOTAL<< 2) -> Seq(RegField.r(32, io.cp.l2_req_total)), + (CP_DSID_SEL << 2) -> Seq(RWNotify(dsidWidth, io.cp.dsidSel, io.cp.updateData, WireInit(false.B), io.cp.dsidSelWen, None)) ) diff --git a/src/main/scala/devices/debug/dm_registers.scala b/src/main/scala/devices/debug/dm_registers.scala index dd679d31..db5afd37 100644 --- a/src/main/scala/devices/debug/dm_registers.scala +++ b/src/main/scala/devices/debug/dm_registers.scala @@ -410,6 +410,15 @@ object DMI_RegAddrs { def CP_HART_ID = 0x7b + + /* L2 Miss */ + def CP_L2_REQ_MISS = 0x7c + + def CP_L2_REQ_TOTAL = 0x7d + + def CP_L2_STAT_RESET = 0x7e + + def CP_L2_REQ_EN = 0x7f } class DMSTATUSFields extends Bundle { diff --git a/src/main/scala/l2cache/TLSimpleL2.scala b/src/main/scala/l2cache/TLSimpleL2.scala index d83b07ce..25e750cc 100644 --- a/src/main/scala/l2cache/TLSimpleL2.scala +++ b/src/main/scala/l2cache/TLSimpleL2.scala @@ -368,6 +368,51 @@ with HasControlPlaneParameters val need_data_read = read_hit || write_hit || read_miss_writeback || write_miss_writeback + class MissStat() extends Bundle { + val miss = UInt(32.W) + val total = UInt(32.W) + } + + val miss_stat_array = DescribedSRAM( + name = "miss_stat", + desc = "L2 cache miss stat", + size = 1 << dsidWidth, + data = new MissStat() + ) + + val miss_stat_origin = miss_stat_array.read(dsid, state === s_tag_read_resp) + + val miss_stat_update = Wire(new MissStat()) + miss_stat_update.miss := miss_stat_origin.miss + Mux(hit, 0.U, 1.U) + miss_stat_update.total := miss_stat_origin.total + 1.U + + val miss_stat_query = miss_stat_array.read(cp.capacity_dsid, cp.req_miss_en) + cp.req_miss := miss_stat_query.miss + cp.req_total := miss_stat_query.total + when (RegNext(cp.req_miss_en)) { + log("query miss stat dsid %d miss %d total %d", cp.capacity_dsid, miss_stat_query.miss, miss_stat_query.total) + } + + val reset_miss_stat = cp.stat_reset || reset + val miss_stat_iter = Reg(UInt(dsidWidth.W)) + when (reset_miss_stat) { + miss_stat_iter := miss_stat_iter + 1.U + }.otherwise{ + miss_stat_iter := 0.U + } + val miss_stat_init = Wire(new MissStat()) + miss_stat_init.miss := 0.U + miss_stat_init.total := 0.U + val miss_stat_idx = Mux(reset_miss_stat, miss_stat_iter, dsid) + val miss_stat_data = Mux(reset_miss_stat, miss_stat_init, miss_stat_update) + when (state === s_tag_read || reset_miss_stat) { + when (reset_miss_stat) { + log("iter %d, miss_stat_data %x", miss_stat_idx, miss_stat_data.asUInt) + } + miss_stat_array.write(miss_stat_idx, miss_stat_data) + } + + when (state === s_tag_read) { log("hit: %d idx: %x curr_state_reg: %x waymask: %x hit_way: %x repl_way: %x", hit, idx, curr_state_reg, curr_mask, hit_way, repl_way) when (ren) { diff --git a/src/main/scala/lvna/controlplane/ControlPlane.scala b/src/main/scala/lvna/controlplane/ControlPlane.scala index c3cbc805..3ed4bf3b 100644 --- a/src/main/scala/lvna/controlplane/ControlPlane.scala +++ b/src/main/scala/lvna/controlplane/ControlPlane.scala @@ -90,6 +90,11 @@ class ControlPlaneIO(implicit val p: Parameters) extends Bundle with HasControlP val PC = UInt(OUTPUT, p(XLen)) val assertDebugInt = Bool(INPUT) + + val l2_miss_en = Bool(INPUT) + val l2_req_miss = UInt(OUTPUT, 32) + val l2_req_total = UInt(OUTPUT, 32) + val l2_stat_reset_wen = Bool(INPUT) } /* From ControlPlane's View */ @@ -98,6 +103,10 @@ class CPToL2CacheIO(implicit val p: Parameters) extends Bundle with HasControlPl val dsid = Input(UInt(dsidWidth.W)) // DSID from requests L2 cache received val capacity = Input(UInt(cacheCapacityWidth.W)) // Count on way numbers val capacity_dsid = Output(UInt(dsidWidth.W)) // Capacity query dsid + val req_miss = Input(UInt(32.W)) + val req_miss_en = Output(Bool()) + val req_total = Input(UInt(32.W)) + val stat_reset = Output(Bool()) } class BucketState(implicit val p: Parameters) extends Bundle with HasControlPlaneParameters with HasTokenBucketParameters { @@ -281,6 +290,22 @@ with HasTokenBucketParameters waymasks(currDsid) := io.cp.updateData } + // Miss + val l2_stat_reset = RegInit(false.B) + val sbus_l2_miss_en = Wire(Bool()) + val miss_en = sbus_l2_miss_en || io.cp.l2_miss_en + + io.l2.req_miss_en := miss_en + io.l2.stat_reset := l2_stat_reset + + when (io.cp.l2_stat_reset_wen) { + l2_stat_reset := io.cp.updateData + } + + io.cp.l2_req_miss := RegEnable(io.l2.req_miss, RegNext(RegNext(miss_en))) // Wait miss_stat sram addr changes + io.cp.l2_req_total := RegEnable(io.l2.req_total, RegNext(RegNext(miss_en))) // Wait miss_stat sram addr changes + + // TL node def offset(addr: Int): Int = { (addr - CP_HART_DSID) << 2 } @@ -320,6 +345,10 @@ with HasTokenBucketParameters offset(CP_HART_ID) -> Seq(RegField(32, progHartIds(hartSel))), offset(CP_TIMER_LO) -> Seq(RegField(32, timestamp_buffered(31, 0), ())), offset(CP_TIMER_HI) -> Seq(RegField(32, timestamp_buffered(63, 32), ())), + offset(CP_L2_REQ_EN) -> Seq(RWNotify(1, WireInit(false.B), WireInit(false.B), sbus_l2_miss_en, Wire(Bool()))), + offset(CP_L2_REQ_MISS) -> Seq(RegField.r(32, io.l2.req_miss)), + offset(CP_L2_REQ_TOTAL)-> Seq(RegField.r(32, io.l2.req_total)), + offset(CP_L2_STAT_RESET)->Seq(RWNotify(1, WireInit(false.B), l2_stat_reset, Wire(Bool()), WireInit(false.B))), ) From 0d8046e4932da1552bd53351c8988d303b6e53db Mon Sep 17 00:00:00 2001 From: Wang Huizhe Date: Tue, 23 Jul 2019 18:11:09 +0800 Subject: [PATCH 03/12] Enable nohype for emulation by default --- src/main/scala/lvna/LvNAConfigs.scala | 2 +- src/main/scala/system/TestHarness.scala | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/scala/lvna/LvNAConfigs.scala b/src/main/scala/lvna/LvNAConfigs.scala index b5be7ce9..42b5a151 100644 --- a/src/main/scala/lvna/LvNAConfigs.scala +++ b/src/main/scala/lvna/LvNAConfigs.scala @@ -35,7 +35,7 @@ class LvNABoomConfig extends Config( ++ new WithEmu ++ new WithBoom ++ new WithRationalRocketTiles - ++ new WithExtMemSize(0x8000000L) // 32MB + ++ new WithExtMemSize(0x8000000L * 2) // 32MB ++ new WithNoMMIOPort ++ new WithJtagDTM ++ new WithDebugSBA diff --git a/src/main/scala/system/TestHarness.scala b/src/main/scala/system/TestHarness.scala index 36120033..e309242d 100644 --- a/src/main/scala/system/TestHarness.scala +++ b/src/main/scala/system/TestHarness.scala @@ -101,6 +101,9 @@ class TestHarness()(implicit p: Parameters) extends Module { dut.coreclk := dut.clock } + dut.mem_part_en := true.B + dut.distinct_hart_dsid_en := true.B + dut.dontTouchPorts() dut.tieOffInterrupts() dut.connectSimAXIMem() From 5f092bae3d2100483b0fa5c5f4a7356d74d9c7cd Mon Sep 17 00:00:00 2001 From: Wang Huizhe Date: Tue, 23 Jul 2019 20:10:02 +0800 Subject: [PATCH 04/12] Dynamically enable autocat [Temp] tclsh> riscv dmi_write 0x58 0 # to disable tclsh> riscv dmi_write 0x58 1 # to enable --- src/main/scala/devices/debug/Debug.scala | 2 ++ .../scala/devices/debug/dm_registers.scala | 2 ++ .../lvna/controlplane/ControlPlane.scala | 22 +++++++++++++++++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index f449d78f..6a000db8 100644 --- a/src/main/scala/devices/debug/Debug.scala +++ b/src/main/scala/devices/debug/Debug.scala @@ -1112,6 +1112,8 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I (CP_L2_REQ_MISS << 2) -> Seq(RegField.r(32, io.cp.l2_req_miss)), (CP_L2_REQ_TOTAL<< 2) -> Seq(RegField.r(32, io.cp.l2_req_total)), + (CP_AUTOCAT_EN << 2) -> Seq(RWNotify(1, io.cp.autocat_en, io.cp.updateData, WireInit(false.B), io.cp.autocat_wen)), + (CP_DSID_SEL << 2) -> Seq(RWNotify(dsidWidth, io.cp.dsidSel, io.cp.updateData, WireInit(false.B), io.cp.dsidSelWen, None)) ) diff --git a/src/main/scala/devices/debug/dm_registers.scala b/src/main/scala/devices/debug/dm_registers.scala index db5afd37..83db6a46 100644 --- a/src/main/scala/devices/debug/dm_registers.scala +++ b/src/main/scala/devices/debug/dm_registers.scala @@ -386,6 +386,8 @@ object DMI_RegAddrs { def CP_TIMER_HI = 0x57 + def CP_AUTOCAT_EN = 0x58 + def CORE_PC_HI = 0x70 def CORE_PC_LO = 0x71 diff --git a/src/main/scala/lvna/controlplane/ControlPlane.scala b/src/main/scala/lvna/controlplane/ControlPlane.scala index 3ed4bf3b..d6fb95be 100644 --- a/src/main/scala/lvna/controlplane/ControlPlane.scala +++ b/src/main/scala/lvna/controlplane/ControlPlane.scala @@ -13,6 +13,7 @@ import freechips.rocketchip.util.{AsyncQueue, GTimer} import freechips.rocketchip.devices.debug.DMI_RegAddrs._ import freechips.rocketchip.devices.debug.RWNotify import freechips.rocketchip.regmapper.{RegField, RegReadFn, RegWriteFn} +import chisel3.util.Fill object log2Safe { def apply(n: BigInt): Int = { @@ -95,6 +96,9 @@ class ControlPlaneIO(implicit val p: Parameters) extends Bundle with HasControlP val l2_req_miss = UInt(OUTPUT, 32) val l2_req_total = UInt(OUTPUT, 32) val l2_stat_reset_wen = Bool(INPUT) + + val autocat_en = Bool(OUTPUT) + val autocat_wen = Bool(INPUT) } /* From ControlPlane's View */ @@ -306,6 +310,13 @@ with HasTokenBucketParameters io.cp.l2_req_total := RegEnable(io.l2.req_total, RegNext(RegNext(miss_en))) // Wait miss_stat sram addr changes + // Autocat + val autocat_en_reg = RegInit(true.B) + val autocat_en = IO(Output(Bool())) + autocat_en := autocat_en_reg + when (io.cp.autocat_wen) { + autocat_en_reg := io.cp.updateData + } // TL node def offset(addr: Int): Int = { (addr - CP_HART_DSID) << 2 } @@ -349,6 +360,12 @@ with HasTokenBucketParameters offset(CP_L2_REQ_MISS) -> Seq(RegField.r(32, io.l2.req_miss)), offset(CP_L2_REQ_TOTAL)-> Seq(RegField.r(32, io.l2.req_total)), offset(CP_L2_STAT_RESET)->Seq(RWNotify(1, WireInit(false.B), l2_stat_reset, Wire(Bool()), WireInit(false.B))), + offset(CP_AUTOCAT_EN) -> Seq(RegField.w(1, (valid: Bool, data: UInt) => { + when (valid) { + autocat_en_reg := data + } + true.B + })), ) @@ -640,8 +657,9 @@ trait BindL2WayMaskModuleImp extends HasRocketTilesModuleImp { val cat = Module(new autocat) cat.io.clk_in := clock cat.io.reset_in := reset - cat.io.access_valid_in := outer._l2.module.autocat.access_valid_in + cat.io.access_valid_in := outer._cp.module.autocat_en && outer._l2.module.autocat.access_valid_in cat.io.hit_vec_in := outer._l2.module.autocat.hit_vec_in - outer._l2.module.autocat.suggested_waymask_out := cat.io.suggested_waymask_out + outer._l2.module.autocat.suggested_waymask_out := + Mux(outer._cp.module.autocat_en, cat.io.suggested_waymask_out, Fill(p(NL2CacheWays), 1.U)) } } From 8dd1011f473139f21f26a6d0636ea977b218527f Mon Sep 17 00:00:00 2001 From: Wang Huizhe Date: Wed, 24 Jul 2019 20:34:30 +0800 Subject: [PATCH 05/12] autocat: reuse enable port --- src/main/scala/lvna/controlplane/ControlPlane.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/scala/lvna/controlplane/ControlPlane.scala b/src/main/scala/lvna/controlplane/ControlPlane.scala index d6fb95be..43638742 100644 --- a/src/main/scala/lvna/controlplane/ControlPlane.scala +++ b/src/main/scala/lvna/controlplane/ControlPlane.scala @@ -312,8 +312,7 @@ with HasTokenBucketParameters // Autocat val autocat_en_reg = RegInit(true.B) - val autocat_en = IO(Output(Bool())) - autocat_en := autocat_en_reg + io.cp.autocat_en := autocat_en_reg when (io.cp.autocat_wen) { autocat_en_reg := io.cp.updateData } @@ -657,9 +656,9 @@ trait BindL2WayMaskModuleImp extends HasRocketTilesModuleImp { val cat = Module(new autocat) cat.io.clk_in := clock cat.io.reset_in := reset - cat.io.access_valid_in := outer._cp.module.autocat_en && outer._l2.module.autocat.access_valid_in + cat.io.access_valid_in := outer._cp.module.io.cp.autocat_en && outer._l2.module.autocat.access_valid_in cat.io.hit_vec_in := outer._l2.module.autocat.hit_vec_in outer._l2.module.autocat.suggested_waymask_out := - Mux(outer._cp.module.autocat_en, cat.io.suggested_waymask_out, Fill(p(NL2CacheWays), 1.U)) + Mux(outer._cp.module.io.cp.autocat_en, cat.io.suggested_waymask_out, Fill(p(NL2CacheWays), 1.U)) } } From 8b7ce15edd9170aa793165c3641f9f452ae5535f Mon Sep 17 00:00:00 2001 From: Wang Huizhe Date: Wed, 24 Jul 2019 21:46:06 +0800 Subject: [PATCH 06/12] autocat: pass reset_bin_power from controlplane --- src/main/resources/vsrc/autocat.v | 8 +++++--- src/main/scala/devices/debug/Debug.scala | 3 ++- src/main/scala/devices/debug/dm_registers.scala | 2 ++ src/main/scala/lvna/AutoCat.scala | 13 +++++++++++-- src/main/scala/lvna/controlplane/ControlPlane.scala | 10 ++++++++++ 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/main/resources/vsrc/autocat.v b/src/main/resources/vsrc/autocat.v index 173b0f03..3288fb71 100644 --- a/src/main/resources/vsrc/autocat.v +++ b/src/main/resources/vsrc/autocat.v @@ -2,13 +2,15 @@ module autocat #( parameter CACHE_ASSOCIATIVITY = 16, // currently only support 16-way fix configuration parameter COUNTER_WIDTH = 32, - parameter RESET_BIN_POWER = 9, // 2^20 is about 1M requests parameter ALLOWED_GAP = 500 ) ( input clk_in, input reset_in, + // 2's power of reset limit + input [6 - 1 : 0] reset_bin_power, + input access_valid_in, input [CACHE_ASSOCIATIVITY - 1 : 0] hit_vec_in, @@ -20,7 +22,7 @@ reg access_valid_pre; reg [CACHE_ASSOCIATIVITY - 1 : 0] hit_vec_pre; reg [63 : 0] access_counter; -wire request_limit = access_counter == 2 ** RESET_BIN_POWER; +wire request_limit = access_counter == (1 << reset_bin_power); wire reset_with_request_limit = reset_in | request_limit; @@ -90,7 +92,7 @@ generate for(gen = 0; gen < CACHE_ASSOCIATIVITY; gen = gen + 1) begin assign post_calc_counter_flatted[gen * COUNTER_WIDTH +: COUNTER_WIDTH] = - post_sort_counter_flatted[gen * COUNTER_WIDTH +: COUNTER_WIDTH] >> (RESET_BIN_POWER - 4); + post_sort_counter_flatted[gen * COUNTER_WIDTH +: COUNTER_WIDTH] >> (reset_bin_power - 4); end endgenerate diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index 6a000db8..a5435249 100644 --- a/src/main/scala/devices/debug/Debug.scala +++ b/src/main/scala/devices/debug/Debug.scala @@ -20,7 +20,7 @@ import freechips.rocketchip.subsystem.{NL2CacheWays, NTiles} import freechips.rocketchip.system.UseEmu import freechips.rocketchip.tile.XLen import ila.BoomCSRILABundle -import lvna.{ControlPlaneIO, HasControlPlaneParameters} +import lvna.{AutoCatConstants, ControlPlaneIO, HasControlPlaneParameters} import freechips.rocketchip.diplomaticobjectmodel.DiplomaticObjectModelAddressing import freechips.rocketchip.diplomaticobjectmodel.model._ @@ -1113,6 +1113,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I (CP_L2_REQ_TOTAL<< 2) -> Seq(RegField.r(32, io.cp.l2_req_total)), (CP_AUTOCAT_EN << 2) -> Seq(RWNotify(1, io.cp.autocat_en, io.cp.updateData, WireInit(false.B), io.cp.autocat_wen)), + (CP_AUTOCAT_RESET_BIN_POWER << 2) -> Seq(RWNotify(AutoCatConstants.resetBinPowerWidth, io.cp.autocat_reset_bin_power, io.cp.updateData, WireInit(false.B), io.cp.autocat_reset_bin_power_wen)), (CP_DSID_SEL << 2) -> Seq(RWNotify(dsidWidth, io.cp.dsidSel, io.cp.updateData, WireInit(false.B), io.cp.dsidSelWen, None)) ) diff --git a/src/main/scala/devices/debug/dm_registers.scala b/src/main/scala/devices/debug/dm_registers.scala index 83db6a46..032e4b6d 100644 --- a/src/main/scala/devices/debug/dm_registers.scala +++ b/src/main/scala/devices/debug/dm_registers.scala @@ -388,6 +388,8 @@ object DMI_RegAddrs { def CP_AUTOCAT_EN = 0x58 + def CP_AUTOCAT_RESET_BIN_POWER = 0x59 + def CORE_PC_HI = 0x70 def CORE_PC_LO = 0x71 diff --git a/src/main/scala/lvna/AutoCat.scala b/src/main/scala/lvna/AutoCat.scala index db2c9838..8d251bb9 100644 --- a/src/main/scala/lvna/AutoCat.scala +++ b/src/main/scala/lvna/AutoCat.scala @@ -2,10 +2,19 @@ package lvna import chisel3._ +object AutoCatConstants { + val resetBinPowerWidth = 6 // 2^0 ~ 2^63 is enough. + val nrL2Ways = 16 // Currently fixed. +} + class AutoCatIOInternal extends Bundle { + import AutoCatConstants._ + val access_valid_in = Input(Bool()) - val hit_vec_in = Input(UInt(16.W)) - val suggested_waymask_out = Output(UInt(16.W)) + // 2's power of reset limit, say, update suggested waymask per 2^reset_bin_power cycles. + val reset_bin_power = Input(UInt(resetBinPowerWidth.W)) + val hit_vec_in = Input(UInt(nrL2Ways.W)) + val suggested_waymask_out = Output(UInt(nrL2Ways.W)) } class autocat extends BlackBox { diff --git a/src/main/scala/lvna/controlplane/ControlPlane.scala b/src/main/scala/lvna/controlplane/ControlPlane.scala index 43638742..ee3de52d 100644 --- a/src/main/scala/lvna/controlplane/ControlPlane.scala +++ b/src/main/scala/lvna/controlplane/ControlPlane.scala @@ -97,8 +97,11 @@ class ControlPlaneIO(implicit val p: Parameters) extends Bundle with HasControlP val l2_req_total = UInt(OUTPUT, 32) val l2_stat_reset_wen = Bool(INPUT) + import AutoCatConstants._ val autocat_en = Bool(OUTPUT) val autocat_wen = Bool(INPUT) + val autocat_reset_bin_power = UInt(OUTPUT, resetBinPowerWidth) + val autocat_reset_bin_power_wen = Bool(INPUT) } /* From ControlPlane's View */ @@ -311,11 +314,16 @@ with HasTokenBucketParameters // Autocat + import AutoCatConstants._ val autocat_en_reg = RegInit(true.B) + val autocat_reset_bin_power_reg = RegInit(10.U(resetBinPowerWidth.W)) io.cp.autocat_en := autocat_en_reg when (io.cp.autocat_wen) { autocat_en_reg := io.cp.updateData } + when (io.cp.autocat_reset_bin_power_wen) { + autocat_reset_bin_power_reg := io.cp.updateData + } // TL node def offset(addr: Int): Int = { (addr - CP_HART_DSID) << 2 } @@ -365,6 +373,7 @@ with HasTokenBucketParameters } true.B })), + offset(CP_AUTOCAT_RESET_BIN_POWER) -> Seq(RegField(resetBinPowerWidth, autocat_reset_bin_power_reg)), ) @@ -657,6 +666,7 @@ trait BindL2WayMaskModuleImp extends HasRocketTilesModuleImp { cat.io.clk_in := clock cat.io.reset_in := reset cat.io.access_valid_in := outer._cp.module.io.cp.autocat_en && outer._l2.module.autocat.access_valid_in + cat.io.reset_bin_power := outer._cp.module.io.cp.autocat_reset_bin_power cat.io.hit_vec_in := outer._l2.module.autocat.hit_vec_in outer._l2.module.autocat.suggested_waymask_out := Mux(outer._cp.module.io.cp.autocat_en, cat.io.suggested_waymask_out, Fill(p(NL2CacheWays), 1.U)) From 12240b84e4a5104bd9a6230e21943f0fadca94b0 Mon Sep 17 00:00:00 2001 From: Wang Huizhe Date: Thu, 25 Jul 2019 16:50:41 +0800 Subject: [PATCH 07/12] autocat: expose autocat_en value to system bus --- src/main/scala/lvna/controlplane/ControlPlane.scala | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/scala/lvna/controlplane/ControlPlane.scala b/src/main/scala/lvna/controlplane/ControlPlane.scala index ee3de52d..0569ecfd 100644 --- a/src/main/scala/lvna/controlplane/ControlPlane.scala +++ b/src/main/scala/lvna/controlplane/ControlPlane.scala @@ -367,12 +367,7 @@ with HasTokenBucketParameters offset(CP_L2_REQ_MISS) -> Seq(RegField.r(32, io.l2.req_miss)), offset(CP_L2_REQ_TOTAL)-> Seq(RegField.r(32, io.l2.req_total)), offset(CP_L2_STAT_RESET)->Seq(RWNotify(1, WireInit(false.B), l2_stat_reset, Wire(Bool()), WireInit(false.B))), - offset(CP_AUTOCAT_EN) -> Seq(RegField.w(1, (valid: Bool, data: UInt) => { - when (valid) { - autocat_en_reg := data - } - true.B - })), + offset(CP_AUTOCAT_EN) -> Seq(RegField(1, autocat_en_reg)), offset(CP_AUTOCAT_RESET_BIN_POWER) -> Seq(RegField(resetBinPowerWidth, autocat_reset_bin_power_reg)), ) From d82673899f51c81b28d18d5cb77834f0bec9f7e5 Mon Sep 17 00:00:00 2001 From: Wang Huizhe Date: Thu, 25 Jul 2019 20:18:06 +0800 Subject: [PATCH 08/12] autocat: configurable watching dsid and visible suggested waymask --- src/main/scala/devices/debug/Debug.scala | 2 ++ src/main/scala/devices/debug/dm_registers.scala | 4 ++++ src/main/scala/l2cache/TLSimpleL2.scala | 2 +- .../scala/lvna/controlplane/ControlPlane.scala | 17 ++++++++++++++++- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index a5435249..d1cc23bc 100644 --- a/src/main/scala/devices/debug/Debug.scala +++ b/src/main/scala/devices/debug/Debug.scala @@ -1114,6 +1114,8 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I (CP_AUTOCAT_EN << 2) -> Seq(RWNotify(1, io.cp.autocat_en, io.cp.updateData, WireInit(false.B), io.cp.autocat_wen)), (CP_AUTOCAT_RESET_BIN_POWER << 2) -> Seq(RWNotify(AutoCatConstants.resetBinPowerWidth, io.cp.autocat_reset_bin_power, io.cp.updateData, WireInit(false.B), io.cp.autocat_reset_bin_power_wen)), + (CP_AUTOCAT_SUGGEST_WAYMASK << 2) -> Seq(RegField.r(AutoCatConstants.nrL2Ways, io.cp.autocat_suggested_waymask)), + (CP_AUTOCAT_WATCHING_DSID << 2) -> Seq(RWNotify(dsidWidth, io.cp.autocat_watching_dsid, io.cp.updateData, WireInit(false.B), io.cp.autocat_watching_dsid_wen)), (CP_DSID_SEL << 2) -> Seq(RWNotify(dsidWidth, io.cp.dsidSel, io.cp.updateData, WireInit(false.B), io.cp.dsidSelWen, None)) ) diff --git a/src/main/scala/devices/debug/dm_registers.scala b/src/main/scala/devices/debug/dm_registers.scala index 032e4b6d..c2e62dd0 100644 --- a/src/main/scala/devices/debug/dm_registers.scala +++ b/src/main/scala/devices/debug/dm_registers.scala @@ -390,6 +390,10 @@ object DMI_RegAddrs { def CP_AUTOCAT_RESET_BIN_POWER = 0x59 + def CP_AUTOCAT_SUGGEST_WAYMASK = 0x5a + + def CP_AUTOCAT_WATCHING_DSID = 0x5b + def CORE_PC_HI = 0x70 def CORE_PC_LO = 0x71 diff --git a/src/main/scala/l2cache/TLSimpleL2.scala b/src/main/scala/l2cache/TLSimpleL2.scala index 25e750cc..5f392478 100644 --- a/src/main/scala/l2cache/TLSimpleL2.scala +++ b/src/main/scala/l2cache/TLSimpleL2.scala @@ -332,7 +332,7 @@ with HasControlPlaneParameters hit_way := Bits(0) (0 until nWays).foreach(i => when (tag_match_way(i)) { hit_way := Bits(i) }) - autocat.access_valid_in := dsid === 0.U && state === s_tag_read + autocat.access_valid_in := dsid === cp.autocat_watching_dsid && state === s_tag_read autocat.hit_vec_in := (0 until nWays).map(tag_match_way(_)).asUInt cp.dsid := dsid diff --git a/src/main/scala/lvna/controlplane/ControlPlane.scala b/src/main/scala/lvna/controlplane/ControlPlane.scala index 0569ecfd..33fc0338 100644 --- a/src/main/scala/lvna/controlplane/ControlPlane.scala +++ b/src/main/scala/lvna/controlplane/ControlPlane.scala @@ -102,6 +102,9 @@ class ControlPlaneIO(implicit val p: Parameters) extends Bundle with HasControlP val autocat_wen = Bool(INPUT) val autocat_reset_bin_power = UInt(OUTPUT, resetBinPowerWidth) val autocat_reset_bin_power_wen = Bool(INPUT) + val autocat_suggested_waymask = UInt(OUTPUT, nrL2Ways) + val autocat_watching_dsid = UInt(OUTPUT, dsidWidth) + val autocat_watching_dsid_wen = Bool(INPUT) } /* From ControlPlane's View */ @@ -114,6 +117,9 @@ class CPToL2CacheIO(implicit val p: Parameters) extends Bundle with HasControlPl val req_miss_en = Output(Bool()) val req_total = Input(UInt(32.W)) val stat_reset = Output(Bool()) + + val autocat_watching_dsid = Output(UInt(dsidWidth.W)) + val autocat_suggested_waymask = Input(UInt(p(NL2CacheWays).W)) } class BucketState(implicit val p: Parameters) extends Bundle with HasControlPlaneParameters with HasTokenBucketParameters { @@ -213,6 +219,7 @@ with HasTokenBucketParameters val mem_part_en = Bool().asInput val distinct_hart_dsid_en = Bool().asInput val progHartIds = Vec(nTiles, UInt(log2Safe(nTiles).W)).asOutput + val autocat_watching_change = Bool().asOutput }) val hartSel = RegInit(0.U(ldomDSidWidth.W)) @@ -317,6 +324,9 @@ with HasTokenBucketParameters import AutoCatConstants._ val autocat_en_reg = RegInit(true.B) val autocat_reset_bin_power_reg = RegInit(10.U(resetBinPowerWidth.W)) + val autocat_watching_dsid = RegInit(0.U(dsidWidth.W)) + val watch_change = WireInit(false.B) + io.autocat_watching_change := watch_change || io.cp.autocat_watching_dsid_wen io.cp.autocat_en := autocat_en_reg when (io.cp.autocat_wen) { autocat_en_reg := io.cp.updateData @@ -324,6 +334,9 @@ with HasTokenBucketParameters when (io.cp.autocat_reset_bin_power_wen) { autocat_reset_bin_power_reg := io.cp.updateData } + when (io.cp.autocat_watching_dsid_wen) { + autocat_watching_dsid := io.cp.updateData + } // TL node def offset(addr: Int): Int = { (addr - CP_HART_DSID) << 2 } @@ -369,6 +382,8 @@ with HasTokenBucketParameters offset(CP_L2_STAT_RESET)->Seq(RWNotify(1, WireInit(false.B), l2_stat_reset, Wire(Bool()), WireInit(false.B))), offset(CP_AUTOCAT_EN) -> Seq(RegField(1, autocat_en_reg)), offset(CP_AUTOCAT_RESET_BIN_POWER) -> Seq(RegField(resetBinPowerWidth, autocat_reset_bin_power_reg)), + offset(CP_AUTOCAT_SUGGEST_WAYMASK) -> Seq(RegField.r(nrL2Ways, io.l2.autocat_suggested_waymask)), + offset(CP_AUTOCAT_WATCHING_DSID) -> Seq(RWNotify(dsidWidth, autocat_watching_dsid, autocat_watching_dsid, WireInit(false.B), watch_change)), ) @@ -659,7 +674,7 @@ trait BindL2WayMaskModuleImp extends HasRocketTilesModuleImp { outer._l2.module.cp <> outer._cp.module.io.l2 val cat = Module(new autocat) cat.io.clk_in := clock - cat.io.reset_in := reset + cat.io.reset_in := reset || outer._cp.module.io.autocat_watching_change cat.io.access_valid_in := outer._cp.module.io.cp.autocat_en && outer._l2.module.autocat.access_valid_in cat.io.reset_bin_power := outer._cp.module.io.cp.autocat_reset_bin_power cat.io.hit_vec_in := outer._l2.module.autocat.hit_vec_in From 3820f69692e09726d8e5711dae62940c199bfedf Mon Sep 17 00:00:00 2001 From: Wang Huizhe Date: Sat, 27 Jul 2019 13:40:49 +0800 Subject: [PATCH 09/12] autocat: add config interface (WIP) --- src/main/scala/lvna/controlplane/ControlPlane.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/scala/lvna/controlplane/ControlPlane.scala b/src/main/scala/lvna/controlplane/ControlPlane.scala index 33fc0338..3ff50fd3 100644 --- a/src/main/scala/lvna/controlplane/ControlPlane.scala +++ b/src/main/scala/lvna/controlplane/ControlPlane.scala @@ -328,6 +328,9 @@ with HasTokenBucketParameters val watch_change = WireInit(false.B) io.autocat_watching_change := watch_change || io.cp.autocat_watching_dsid_wen io.cp.autocat_en := autocat_en_reg + io.cp.autocat_suggested_waymask := io.l2.autocat_suggested_waymask + io.cp.autocat_watching_dsid := autocat_watching_dsid + io.l2.autocat_watching_dsid := autocat_watching_dsid when (io.cp.autocat_wen) { autocat_en_reg := io.cp.updateData } @@ -678,6 +681,7 @@ trait BindL2WayMaskModuleImp extends HasRocketTilesModuleImp { cat.io.access_valid_in := outer._cp.module.io.cp.autocat_en && outer._l2.module.autocat.access_valid_in cat.io.reset_bin_power := outer._cp.module.io.cp.autocat_reset_bin_power cat.io.hit_vec_in := outer._l2.module.autocat.hit_vec_in + outer._cp.module.io.l2.autocat_suggested_waymask := cat.io.suggested_waymask_out outer._l2.module.autocat.suggested_waymask_out := Mux(outer._cp.module.io.cp.autocat_en, cat.io.suggested_waymask_out, Fill(p(NL2CacheWays), 1.U)) } From 3bd6e7459aafc168b0f9315b932745fb388d5be9 Mon Sep 17 00:00:00 2001 From: Wang Huizhe Date: Sat, 27 Jul 2019 13:43:42 +0800 Subject: [PATCH 10/12] Fix unexpected merged tweaks --- src/main/scala/lvna/LvNAConfigs.scala | 2 +- src/main/scala/lvna/controlplane/TokenBucketNode.scala | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/scala/lvna/LvNAConfigs.scala b/src/main/scala/lvna/LvNAConfigs.scala index b5be7ce9..6a92f3fd 100644 --- a/src/main/scala/lvna/LvNAConfigs.scala +++ b/src/main/scala/lvna/LvNAConfigs.scala @@ -119,7 +119,7 @@ class LvNAConfigemu extends Config( new WithoutFPU ++ new WithNonblockingL1(8) ++ new WithNL2CacheCapacity(256) - ++ new WithNBigCores(1) + ++ new WithNBigCores(2) ++ new WithEmu ++ new WithRationalRocketTiles ++ new WithExtMemSize(0x8000000L) // 32MB diff --git a/src/main/scala/lvna/controlplane/TokenBucketNode.scala b/src/main/scala/lvna/controlplane/TokenBucketNode.scala index ffa42399..1b33d238 100644 --- a/src/main/scala/lvna/controlplane/TokenBucketNode.scala +++ b/src/main/scala/lvna/controlplane/TokenBucketNode.scala @@ -27,10 +27,8 @@ class TokenBucketNodeImp(outer: TokenBucketNode) extends LazyModuleImp(outer) { bucketIO.fire := out.a.ready && out.a.valid && !phy bucketIO.size := (1.U << in.a.bits.size) >> 6 -// out.a.valid := in.a.valid && (phy || bucketIO.enable) -// in.a.ready := out.a.ready && (phy || bucketIO.enable) - out.a.valid := in.a.valid - in.a.ready := out.a.ready + out.a.valid := in.a.valid && (phy || bucketIO.enable) + in.a.ready := out.a.ready && (phy || bucketIO.enable) if (DEBUG_TB_FETCH) { when(in.a.valid && !out.a.valid) { printf(p"request blocked by token bucket: 0x${Hexadecimal(in.a.bits.address)}\n") From f1b4f9363dd43e3030154dcccff5cf9afb410acd Mon Sep 17 00:00:00 2001 From: Wang Huizhe Date: Thu, 8 Aug 2019 15:27:45 +0800 Subject: [PATCH 11/12] autocat: set sampling, tuning schmatics and exposing parameters Previously autocat counts pre-nth way consecutive hits, making counters inherently sorted. Now autocat counts hit per way, then sorts, and finally accumulates them together to find best partition index. However, currently we can only use a threshold to the total hits to decide partition index, but not its increasing rate. Exposed parameters: autocat_set: the sampling set mask autocat_gap: the threshold to decide best partition index. --- src/main/resources/vsrc/autocat.v | 61 ++++++++----- src/main/scala/devices/debug/Debug.scala | 2 + .../scala/devices/debug/dm_registers.scala | 4 + src/main/scala/l2cache/TLSimpleL2.scala | 17 +++- src/main/scala/lvna/AutoCat.scala | 1 + .../lvna/controlplane/ControlPlane.scala | 89 ++++++++++++++----- 6 files changed, 128 insertions(+), 46 deletions(-) diff --git a/src/main/resources/vsrc/autocat.v b/src/main/resources/vsrc/autocat.v index 3288fb71..c4fc4799 100644 --- a/src/main/resources/vsrc/autocat.v +++ b/src/main/resources/vsrc/autocat.v @@ -1,8 +1,7 @@ module autocat #( parameter CACHE_ASSOCIATIVITY = 16, // currently only support 16-way fix configuration - parameter COUNTER_WIDTH = 32, - parameter ALLOWED_GAP = 500 + parameter COUNTER_WIDTH = 32 ) ( input clk_in, @@ -10,10 +9,9 @@ module autocat // 2's power of reset limit input [6 - 1 : 0] reset_bin_power, - + input [32 - 1 : 0] allowed_gap, input access_valid_in, input [CACHE_ASSOCIATIVITY - 1 : 0] hit_vec_in, - output reg [CACHE_ASSOCIATIVITY - 1 : 0] suggested_waymask_out ); @@ -22,7 +20,7 @@ reg access_valid_pre; reg [CACHE_ASSOCIATIVITY - 1 : 0] hit_vec_pre; reg [63 : 0] access_counter; -wire request_limit = access_counter == (1 << reset_bin_power); +wire request_limit = access_counter == 2 ** reset_bin_power; wire reset_with_request_limit = reset_in | request_limit; @@ -34,12 +32,11 @@ begin access_valid_pre <= 0; hit_vec_pre <= 0; end - else begin access_valid_pre <= access_valid_in; hit_vec_pre <= hit_vec_in; - + if(~access_valid_pre & access_valid_in) access_counter <= access_counter + 1'b1; end @@ -49,9 +46,8 @@ wire [CACHE_ASSOCIATIVITY * COUNTER_WIDTH - 1 : 0] counter_flatted; wire [CACHE_ASSOCIATIVITY * COUNTER_WIDTH - 1 : 0] post_sort_counter_flatted; // hit counter array -generate genvar gen; - +generate for(gen = 0; gen < CACHE_ASSOCIATIVITY; gen = gen + 1) begin reg [COUNTER_WIDTH - 1 : 0] hit_counter; @@ -61,16 +57,15 @@ begin begin if(reset_with_request_limit) begin + $fwrite(32'h80000002, "counter %d: %d\n", gen, hit_counter); hit_counter <= 0; end - - else if(|(~hit_vec_pre[gen:0] & hit_vec_in[gen:0])) + else if(hit_vec_in[gen:gen]) // Per-way hit counting begin hit_counter <= hit_counter + 1'b1; end end end - endgenerate // sort all the hit counters @@ -88,12 +83,22 @@ sorter ); wire [CACHE_ASSOCIATIVITY * COUNTER_WIDTH - 1 : 0] post_calc_counter_flatted; + +integer index; generate - for(gen = 0; gen < CACHE_ASSOCIATIVITY; gen = gen + 1) +for(gen = 0; gen < CACHE_ASSOCIATIVITY; gen = gen + 1) +begin + reg [COUNTER_WIDTH - 1:0] sum; + always@* begin - assign post_calc_counter_flatted[gen * COUNTER_WIDTH +: COUNTER_WIDTH] = - post_sort_counter_flatted[gen * COUNTER_WIDTH +: COUNTER_WIDTH] >> (reset_bin_power - 4); + sum = 'd0; + for (index = 0; index <= gen; index = index + 1) + begin + sum = sum + post_sort_counter_flatted[index * COUNTER_WIDTH +: COUNTER_WIDTH]; + end end + assign post_calc_counter_flatted[gen * COUNTER_WIDTH +: COUNTER_WIDTH] = sum >> (reset_bin_power - 4); +end endgenerate integer loop_index; @@ -105,8 +110,8 @@ begin : Find for(loop_index = 0; loop_index < CACHE_ASSOCIATIVITY; loop_index = loop_index + 1) begin - if(post_calc_counter_flatted[loop_index * COUNTER_WIDTH +: COUNTER_WIDTH] + ALLOWED_GAP >= - post_calc_counter_flatted[(CACHE_ASSOCIATIVITY - 1) * COUNTER_WIDTH +: COUNTER_WIDTH]) + if(post_calc_counter_flatted[loop_index * COUNTER_WIDTH +: COUNTER_WIDTH] + allowed_gap >= + post_calc_counter_flatted[(CACHE_ASSOCIATIVITY - 1) * COUNTER_WIDTH +: COUNTER_WIDTH]) begin /* verilator lint_off WIDTH */ first_best_partition = loop_index; @@ -116,28 +121,40 @@ begin : Find end end +always@(posedge clk_in) +begin : FindX + for(loop_index = 0; loop_index < CACHE_ASSOCIATIVITY; loop_index = loop_index + 1) + begin + if (reset_with_request_limit) begin + $fwrite(32'h80000002, "%d origin sorted %d, faltter %d\n", loop_index, + post_sort_counter_flatted[loop_index * COUNTER_WIDTH +: COUNTER_WIDTH], + post_calc_counter_flatted[loop_index * COUNTER_WIDTH +: COUNTER_WIDTH]); + end + end +end + always@(posedge clk_in) begin if(reset_in) begin suggested_waymask_out <= 16'b1111_1111_1111_1111; end - else if(request_limit) begin for(loop_index = 0; loop_index < CACHE_ASSOCIATIVITY; loop_index = loop_index + 1) begin /* verilator lint_off WIDTH */ - if(first_best_partition >= loop_index) begin - /* verilator lint_on WIDTH */ + if(first_best_partition >= loop_index) + begin + /* verilator lint_on WIDTH */ suggested_waymask_out[loop_index] <= 1'b1; end - else begin + else + begin suggested_waymask_out[loop_index] <= 1'b0; $fwrite(32'h80000002, "suggest updating, loop_index %d\n", loop_index); end end end end - endmodule diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index d1cc23bc..f22a344b 100644 --- a/src/main/scala/devices/debug/Debug.scala +++ b/src/main/scala/devices/debug/Debug.scala @@ -1116,6 +1116,8 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I (CP_AUTOCAT_RESET_BIN_POWER << 2) -> Seq(RWNotify(AutoCatConstants.resetBinPowerWidth, io.cp.autocat_reset_bin_power, io.cp.updateData, WireInit(false.B), io.cp.autocat_reset_bin_power_wen)), (CP_AUTOCAT_SUGGEST_WAYMASK << 2) -> Seq(RegField.r(AutoCatConstants.nrL2Ways, io.cp.autocat_suggested_waymask)), (CP_AUTOCAT_WATCHING_DSID << 2) -> Seq(RWNotify(dsidWidth, io.cp.autocat_watching_dsid, io.cp.updateData, WireInit(false.B), io.cp.autocat_watching_dsid_wen)), + (CP_AUTOCAT_SET << 2) -> Seq(RWNotify(32, io.cp.autocat_set, io.cp.updateData, WireInit(false.B), io.cp.autocat_set_wen)), + (CP_AUTOCAT_GAP << 2) -> Seq(RWNotify(32, io.cp.autocat_gap, io.cp.updateData, WireInit(false.B), io.cp.autocat_gap_wen)), (CP_DSID_SEL << 2) -> Seq(RWNotify(dsidWidth, io.cp.dsidSel, io.cp.updateData, WireInit(false.B), io.cp.dsidSelWen, None)) ) diff --git a/src/main/scala/devices/debug/dm_registers.scala b/src/main/scala/devices/debug/dm_registers.scala index c2e62dd0..f6ba887e 100644 --- a/src/main/scala/devices/debug/dm_registers.scala +++ b/src/main/scala/devices/debug/dm_registers.scala @@ -394,6 +394,10 @@ object DMI_RegAddrs { def CP_AUTOCAT_WATCHING_DSID = 0x5b + def CP_AUTOCAT_SET = 0x5c + + def CP_AUTOCAT_GAP = 0x5d + def CORE_PC_HI = 0x70 def CORE_PC_LO = 0x71 diff --git a/src/main/scala/l2cache/TLSimpleL2.scala b/src/main/scala/l2cache/TLSimpleL2.scala index 5f392478..664d970d 100644 --- a/src/main/scala/l2cache/TLSimpleL2.scala +++ b/src/main/scala/l2cache/TLSimpleL2.scala @@ -8,6 +8,7 @@ package freechips.rocketchip.subsystem import Chisel._ +import chisel3.core.WireInit import chisel3.util.IrrevocableIO import freechips.rocketchip.config.{Field, Parameters} import freechips.rocketchip.diplomacy._ @@ -332,11 +333,23 @@ with HasControlPlaneParameters hit_way := Bits(0) (0 until nWays).foreach(i => when (tag_match_way(i)) { hit_way := Bits(i) }) - autocat.access_valid_in := dsid === cp.autocat_watching_dsid && state === s_tag_read + val autocat_is_sampling = WireInit((idx & cp.autocat_set) === cp.autocat_set) + autocat.access_valid_in := dsid === cp.autocat_watching_dsid && autocat_is_sampling && state === s_tag_read autocat.hit_vec_in := (0 until nWays).map(tag_match_way(_)).asUInt cp.dsid := dsid - val curr_mask = cp.waymask & Mux(dsid === 0.U, autocat.suggested_waymask_out, ~autocat.suggested_waymask_out).asUInt + val curr_mask = Wire(UInt(nWays.W)) + curr_mask := cp.waymask // default + when (cp.autocat_en) { + when (!autocat_is_sampling) { // not sampling, under control + when (dsid === cp.autocat_watching_dsid) { + curr_mask := cp.waymask & autocat.suggested_waymask_out + }.otherwise { + curr_mask := cp.waymask & (~autocat.suggested_waymask_out).asUInt + } + } + } + val repl_way = Mux((curr_state_reg & curr_mask).orR, PriorityEncoder(curr_state_reg & curr_mask), Mux(curr_mask.orR, PriorityEncoder(curr_mask), UInt(0))) val repl_dsid = set_dsids_reg(repl_way) diff --git a/src/main/scala/lvna/AutoCat.scala b/src/main/scala/lvna/AutoCat.scala index 8d251bb9..67622f59 100644 --- a/src/main/scala/lvna/AutoCat.scala +++ b/src/main/scala/lvna/AutoCat.scala @@ -13,6 +13,7 @@ class AutoCatIOInternal extends Bundle { val access_valid_in = Input(Bool()) // 2's power of reset limit, say, update suggested waymask per 2^reset_bin_power cycles. val reset_bin_power = Input(UInt(resetBinPowerWidth.W)) + val allowed_gap = Input(UInt(32.W)) val hit_vec_in = Input(UInt(nrL2Ways.W)) val suggested_waymask_out = Output(UInt(nrL2Ways.W)) } diff --git a/src/main/scala/lvna/controlplane/ControlPlane.scala b/src/main/scala/lvna/controlplane/ControlPlane.scala index 3ff50fd3..fe2f9881 100644 --- a/src/main/scala/lvna/controlplane/ControlPlane.scala +++ b/src/main/scala/lvna/controlplane/ControlPlane.scala @@ -3,6 +3,7 @@ package lvna import Chisel._ import boom.system.{HasBoomTiles, HasBoomTilesModuleImp} import chisel3.core.{IO, Input, Output, WireInit} +import chisel3.experimental.chiselName import freechips.rocketchip.config.{Field, Parameters} import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp, SimpleDevice} import freechips.rocketchip.subsystem._ @@ -105,6 +106,10 @@ class ControlPlaneIO(implicit val p: Parameters) extends Bundle with HasControlP val autocat_suggested_waymask = UInt(OUTPUT, nrL2Ways) val autocat_watching_dsid = UInt(OUTPUT, dsidWidth) val autocat_watching_dsid_wen = Bool(INPUT) + val autocat_set = UInt(OUTPUT, 32) + val autocat_set_wen = Bool(INPUT) + val autocat_gap = UInt(OUTPUT, 32) + val autocat_gap_wen = Bool(INPUT) } /* From ControlPlane's View */ @@ -120,6 +125,8 @@ class CPToL2CacheIO(implicit val p: Parameters) extends Bundle with HasControlPl val autocat_watching_dsid = Output(UInt(dsidWidth.W)) val autocat_suggested_waymask = Input(UInt(p(NL2CacheWays).W)) + val autocat_set = Output(UInt(32.W)) + val autocat_en = Output(Bool()) } class BucketState(implicit val p: Parameters) extends Bundle with HasControlPlaneParameters with HasTokenBucketParameters { @@ -322,24 +329,47 @@ with HasTokenBucketParameters // Autocat import AutoCatConstants._ - val autocat_en_reg = RegInit(true.B) - val autocat_reset_bin_power_reg = RegInit(10.U(resetBinPowerWidth.W)) - val autocat_watching_dsid = RegInit(0.U(dsidWidth.W)) - val watch_change = WireInit(false.B) - io.autocat_watching_change := watch_change || io.cp.autocat_watching_dsid_wen - io.cp.autocat_en := autocat_en_reg + + @chiselName + def cpRegTmpl(init: UInt, enable: Bool): UInt = RegEnable(io.cp.updateData, init, enable) + io.cp.autocat_suggested_waymask := io.l2.autocat_suggested_waymask + + /** + * AutoCat Enable + */ + val autocat_en_reg = cpRegTmpl(false.B, io.cp.autocat_wen) + io.cp.autocat_en := autocat_en_reg + io.l2.autocat_en := autocat_en_reg + + /** + * Decide autocat refresh cycles: 2**(value) + */ + val autocat_reset_bin_power_reg = cpRegTmpl(10.U(resetBinPowerWidth.W), io.cp.autocat_reset_bin_power_wen) + io.cp.autocat_reset_bin_power := autocat_reset_bin_power_reg + + /** + * The label autocat are serving. + * Updating this field will refresh autocat's way hit counters. + */ + val autocat_watching_dsid = cpRegTmpl(0.U(dsidWidth.W), io.cp.autocat_watching_dsid_wen) io.cp.autocat_watching_dsid := autocat_watching_dsid io.l2.autocat_watching_dsid := autocat_watching_dsid - when (io.cp.autocat_wen) { - autocat_en_reg := io.cp.updateData - } - when (io.cp.autocat_reset_bin_power_wen) { - autocat_reset_bin_power_reg := io.cp.updateData - } - when (io.cp.autocat_watching_dsid_wen) { - autocat_watching_dsid := io.cp.updateData - } + val watch_change = WireInit(false.B) + io.autocat_watching_change := watch_change || io.cp.autocat_watching_dsid_wen + + /** + * The allowed hits gap between current allocated ways to full-occupied. + */ + val autocat_gap = cpRegTmpl(500.U(32.W), io.cp.autocat_gap_wen) + io.cp.autocat_gap := autocat_gap + + private val l2SetCnt: BigInt = p(NL2CacheCapacity) * 1024 / p(NL2CacheWays) / p(CacheBlockBytes) + private val l2SetBits = l2SetCnt.bitLength + println(s"cp: l2SetCnt $l2SetCnt, l2SetBits $l2SetBits") + val autocat_set_sampling_mask = cpRegTmpl(0xf.U(l2SetBits.W), io.cp.autocat_set_wen) + io.cp.autocat_set := autocat_set_sampling_mask + io.l2.autocat_set := autocat_set_sampling_mask // TL node def offset(addr: Int): Int = { (addr - CP_HART_DSID) << 2 } @@ -387,6 +417,8 @@ with HasTokenBucketParameters offset(CP_AUTOCAT_RESET_BIN_POWER) -> Seq(RegField(resetBinPowerWidth, autocat_reset_bin_power_reg)), offset(CP_AUTOCAT_SUGGEST_WAYMASK) -> Seq(RegField.r(nrL2Ways, io.l2.autocat_suggested_waymask)), offset(CP_AUTOCAT_WATCHING_DSID) -> Seq(RWNotify(dsidWidth, autocat_watching_dsid, autocat_watching_dsid, WireInit(false.B), watch_change)), + offset(CP_AUTOCAT_SET) -> Seq(RegField(32, autocat_set_sampling_mask)), + offset(CP_AUTOCAT_GAP) -> Seq(RegField(32, autocat_gap)), ) @@ -676,13 +708,26 @@ trait BindL2WayMaskModuleImp extends HasRocketTilesModuleImp { if (p(NL2CacheCapacity) != 0) { outer._l2.module.cp <> outer._cp.module.io.l2 val cat = Module(new autocat) + val cpio = outer._cp.module.io + val l2 = outer._l2.module + cat.io.clk_in := clock - cat.io.reset_in := reset || outer._cp.module.io.autocat_watching_change - cat.io.access_valid_in := outer._cp.module.io.cp.autocat_en && outer._l2.module.autocat.access_valid_in - cat.io.reset_bin_power := outer._cp.module.io.cp.autocat_reset_bin_power - cat.io.hit_vec_in := outer._l2.module.autocat.hit_vec_in - outer._cp.module.io.l2.autocat_suggested_waymask := cat.io.suggested_waymask_out - outer._l2.module.autocat.suggested_waymask_out := - Mux(outer._cp.module.io.cp.autocat_en, cat.io.suggested_waymask_out, Fill(p(NL2CacheWays), 1.U)) + cat.io.reset_in := reset || cpio.autocat_watching_change + cat.io.access_valid_in := cpio.cp.autocat_en && l2.autocat.access_valid_in + cat.io.reset_bin_power := cpio.cp.autocat_reset_bin_power + cat.io.allowed_gap := cpio.cp.autocat_gap + cat.io.hit_vec_in := l2.autocat.hit_vec_in + cpio.l2.autocat_suggested_waymask := cat.io.suggested_waymask_out + l2.autocat.suggested_waymask_out := + Mux(cpio.cp.autocat_en, cat.io.suggested_waymask_out, Fill(p(NL2CacheWays), 1.U)) + + when (cat.io.access_valid_in) { + printf("hit_vec_in %b\n", cat.io.hit_vec_in) + } + + val pre_way = RegNext(cat.io.suggested_waymask_out) + when (pre_way =/= cat.io.suggested_waymask_out) { + printf("suggested waymask %b\n", cat.io.suggested_waymask_out) + } } } From 543b33d6300e6d6714da1055b13a628c016ba0f0 Mon Sep 17 00:00:00 2001 From: Wang Huizhe Date: Thu, 8 Aug 2019 15:34:36 +0800 Subject: [PATCH 12/12] emu: disable max_cycles by default --- fpga/emu/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fpga/emu/Makefile b/fpga/emu/Makefile index bf408b6f..e15d8005 100644 --- a/fpga/emu/Makefile +++ b/fpga/emu/Makefile @@ -25,6 +25,7 @@ nohype_dtb = $(build_dir)/c0.dtb nohype_dtb_hex_file = $(build_dir)/c0.dtb.txt # max_cycles = 40000000 max_cycles = 2209069 +#has_max_cycles = -m $(max_cycles) $(emu): $(original_emu) ln -sf $< $@ @@ -52,7 +53,7 @@ DEBUG_ARGS = +jtag_rbb_enable=1 -r 4040 endif run-emu: $(emu) $(emu_bin_hex_file) $(nohype_dtb_hex_file) - cd $(dir $(emu)) && LD_LIBRARY_PATH=$(RISCV)/lib time $< $(DEBUG_ARGS) $(SEED) +verbose -m $(max_cycles) . 3>&1 1>&2 2>&3 \ + cd $(dir $(emu)) && LD_LIBRARY_PATH=$(RISCV)/lib time $< $(DEBUG_ARGS) $(SEED) +verbose $(has_max_cycles) . 3>&1 1>&2 2>&3 \ | spike-dasm > $(dir $(emu))/emu.log dtb-clean: