xref: /XiangShan/src/main/scala/xiangshan/mem/prefetch/PrefetcherMonitor.scala (revision 99ce5576f0ecce1b5045b7bc0dbbb2debd934fbb)
10d32f713Shappy-lxpackage xiangshan.mem.prefetch
20d32f713Shappy-lx
39e12e8edScz4eimport org.chipsalliance.cde.config.Parameters
40d32f713Shappy-lximport chisel3._
50d32f713Shappy-lximport chisel3.util._
60d32f713Shappy-lximport utils._
70d32f713Shappy-lximport utility._
89e12e8edScz4eimport xiangshan._
99e12e8edScz4eimport xiangshan.mem.L1PrefetchReq
10*99ce5576Scz4eimport xiangshan.mem.Bundles.LsPrefetchTrainBundle
110d32f713Shappy-lx
120d32f713Shappy-lxtrait HasPrefetcherMonitorHelper {
130d32f713Shappy-lx  val TIMELY_CHECK_INTERVAL = 1000
140d32f713Shappy-lx  val VALIDITY_CHECK_INTERVAL = 1000
150d32f713Shappy-lx
160d32f713Shappy-lx  val BAD_THRESHOLD = 400
170d32f713Shappy-lx  val DISABLE_THRESHOLD = 900
180d32f713Shappy-lx  val LATE_HIT_THRESHOLD = 900
190d32f713Shappy-lx  val LATE_MISS_THRESHOLD = 200
200d32f713Shappy-lx
210d32f713Shappy-lx  val BACK_OFF_INTERVAL = 100000
220d32f713Shappy-lx  val LOW_CONF_INTERVAL = 200000
230d32f713Shappy-lx
240d32f713Shappy-lx  // val enableDynamicPrefetcher = false
250d32f713Shappy-lx}
260d32f713Shappy-lx
270d32f713Shappy-lxclass PrefetchControlBundle()(implicit p: Parameters) extends XSBundle with HasStreamPrefetchHelper {
280d32f713Shappy-lx  val dynamic_depth = UInt(DEPTH_BITS.W)
290d32f713Shappy-lx  val flush = Bool()
300d32f713Shappy-lx  val enable = Bool()
310d32f713Shappy-lx  val confidence = UInt(1.W)
320d32f713Shappy-lx}
330d32f713Shappy-lx
340d32f713Shappy-lxclass PrefetcherMonitorBundle()(implicit p: Parameters) extends XSBundle {
350d32f713Shappy-lx  val timely = new XSBundle {
360d32f713Shappy-lx    val total_prefetch = Input(Bool())
370d32f713Shappy-lx    val late_hit_prefetch = Input(Bool())
380d32f713Shappy-lx    val late_miss_prefetch = Input(Bool())
390d32f713Shappy-lx    val prefetch_hit = Input(UInt(2.W))
400d32f713Shappy-lx  }
410d32f713Shappy-lx
420d32f713Shappy-lx  val validity = new XSBundle {
430d32f713Shappy-lx    val good_prefetch = Input(Bool())
440d32f713Shappy-lx    val bad_prefetch = Input(Bool())
450d32f713Shappy-lx  }
460d32f713Shappy-lx
470d32f713Shappy-lx  val pf_ctrl = Output(new PrefetchControlBundle)
480d32f713Shappy-lx}
490d32f713Shappy-lx
500d32f713Shappy-lxclass PrefetcherMonitor()(implicit p: Parameters) extends XSModule with HasPrefetcherMonitorHelper with HasStreamPrefetchHelper {
510d32f713Shappy-lx  val io = IO(new PrefetcherMonitorBundle)
520d32f713Shappy-lx
530d32f713Shappy-lx  val depth = Reg(UInt(DEPTH_BITS.W))
540d32f713Shappy-lx  val flush = RegInit(false.B)
550d32f713Shappy-lx  val enable = RegInit(true.B)
560d32f713Shappy-lx  val confidence = RegInit(1.U(1.W))
570d32f713Shappy-lx
580d32f713Shappy-lx  // TODO: mshr number
590d32f713Shappy-lx  // mshr full && load miss && load send mshr req && !load match,  -> decr nmax prefetch
600d32f713Shappy-lx  // mshr free
610d32f713Shappy-lx
620d32f713Shappy-lx  io.pf_ctrl.dynamic_depth := depth
630d32f713Shappy-lx  io.pf_ctrl.flush := flush
640d32f713Shappy-lx  io.pf_ctrl.enable := enable
650d32f713Shappy-lx  io.pf_ctrl.confidence := confidence
660d32f713Shappy-lx
670d32f713Shappy-lx  val depth_const = Wire(UInt(DEPTH_BITS.W))
68c686adcdSYinan Xu  depth_const := Constantin.createRecord(s"depth${p(XSCoreParamsKey).HartId}", initValue = 32)
690d32f713Shappy-lx
700d32f713Shappy-lx  val total_prefetch_cnt = RegInit(0.U((log2Up(TIMELY_CHECK_INTERVAL) + 1).W))
710d32f713Shappy-lx  val late_hit_prefetch_cnt = RegInit(0.U((log2Up(TIMELY_CHECK_INTERVAL) + 1).W))
720d32f713Shappy-lx  val late_miss_prefetch_cnt = RegInit(0.U((log2Up(TIMELY_CHECK_INTERVAL) + 1).W))
730d32f713Shappy-lx  val prefetch_hit_cnt = RegInit(0.U(32.W))
740d32f713Shappy-lx
750d32f713Shappy-lx  val good_prefetch_cnt = RegInit(0.U((log2Up(VALIDITY_CHECK_INTERVAL) + 1).W))
760d32f713Shappy-lx  val bad_prefetch_cnt = RegInit(0.U((log2Up(VALIDITY_CHECK_INTERVAL) + 1).W))
770d32f713Shappy-lx
780d32f713Shappy-lx  val back_off_cnt = RegInit(0.U((log2Up(BACK_OFF_INTERVAL) + 1).W))
790d32f713Shappy-lx  val low_conf_cnt = RegInit(0.U((log2Up(LOW_CONF_INTERVAL) + 1).W))
800d32f713Shappy-lx
816070f1e9Shappy-lx  val timely_reset = (total_prefetch_cnt === TIMELY_CHECK_INTERVAL.U) || (late_hit_prefetch_cnt >= TIMELY_CHECK_INTERVAL.U)
820d32f713Shappy-lx  val validity_reset = (good_prefetch_cnt + bad_prefetch_cnt) === VALIDITY_CHECK_INTERVAL.U
830d32f713Shappy-lx  val back_off_reset = back_off_cnt === BACK_OFF_INTERVAL.U
840d32f713Shappy-lx  val conf_reset = low_conf_cnt === LOW_CONF_INTERVAL.U
850d32f713Shappy-lx
860d32f713Shappy-lx  total_prefetch_cnt := Mux(timely_reset, 0.U, total_prefetch_cnt + io.timely.total_prefetch)
870d32f713Shappy-lx  late_hit_prefetch_cnt := Mux(timely_reset, 0.U, late_hit_prefetch_cnt + io.timely.late_hit_prefetch)
880d32f713Shappy-lx  late_miss_prefetch_cnt := Mux(timely_reset, 0.U, late_miss_prefetch_cnt + io.timely.late_miss_prefetch)
890d32f713Shappy-lx  prefetch_hit_cnt := Mux(timely_reset, 0.U, prefetch_hit_cnt + io.timely.prefetch_hit)
900d32f713Shappy-lx
910d32f713Shappy-lx  good_prefetch_cnt := Mux(validity_reset, 0.U, good_prefetch_cnt + io.validity.good_prefetch)
920d32f713Shappy-lx  bad_prefetch_cnt := Mux(validity_reset, 0.U, bad_prefetch_cnt + io.validity.bad_prefetch)
930d32f713Shappy-lx
940d32f713Shappy-lx  back_off_cnt := Mux(back_off_reset, 0.U, back_off_cnt + !enable)
950d32f713Shappy-lx  low_conf_cnt := Mux(conf_reset, 0.U, low_conf_cnt + !confidence.asBool)
960d32f713Shappy-lx
970d32f713Shappy-lx  val trigger_late_hit = timely_reset && (late_hit_prefetch_cnt >= LATE_HIT_THRESHOLD.U)
980d32f713Shappy-lx  val trigger_late_miss = timely_reset && (late_miss_prefetch_cnt >= LATE_MISS_THRESHOLD.U)
990d32f713Shappy-lx  val trigger_bad_prefetch = validity_reset && (bad_prefetch_cnt >= BAD_THRESHOLD.U)
1000d32f713Shappy-lx  val trigger_disable = validity_reset && (bad_prefetch_cnt >= DISABLE_THRESHOLD.U)
1010d32f713Shappy-lx
1020d32f713Shappy-lx  flush := Mux(flush, false.B, flush)
1030d32f713Shappy-lx  enable := Mux(back_off_reset, true.B, enable)
1040d32f713Shappy-lx  confidence := Mux(conf_reset, 1.U(1.W), confidence)
1050d32f713Shappy-lx
1060d32f713Shappy-lx  when(trigger_bad_prefetch) {
1070d32f713Shappy-lx    depth := Mux(depth === 1.U, depth, depth >> 1)
1080d32f713Shappy-lx  }
1090d32f713Shappy-lx  when(trigger_disable) {
1100d32f713Shappy-lx    confidence := 0.U(1.W)
1110d32f713Shappy-lx    enable := false.B
1120d32f713Shappy-lx    flush := true.B
1130d32f713Shappy-lx  }
1140d32f713Shappy-lx
1150d32f713Shappy-lx  when(trigger_late_miss) {
1160d32f713Shappy-lx    depth := Mux(depth === (1 << (DEPTH_BITS - 1)).U, depth, depth << 1)
1170d32f713Shappy-lx  }.elsewhen(trigger_late_hit) {
1180d32f713Shappy-lx    // for now, late hit will disable the prefether
1190d32f713Shappy-lx    confidence := 0.U(1.W)
1200d32f713Shappy-lx    enable := false.B
1210d32f713Shappy-lx  }
1220d32f713Shappy-lx
123c686adcdSYinan Xu  val enableDynamicPrefetcher_const = Constantin.createRecord(s"enableDynamicPrefetcher${p(XSCoreParamsKey).HartId}", initValue = 1)
1240d32f713Shappy-lx  val enableDynamicPrefetcher = enableDynamicPrefetcher_const === 1.U
1250d32f713Shappy-lx
1260d32f713Shappy-lx  when(!enableDynamicPrefetcher) {
1270d32f713Shappy-lx    depth := depth_const
1280d32f713Shappy-lx    flush := false.B
1290d32f713Shappy-lx    enable := true.B
1300d32f713Shappy-lx    confidence := 1.U
1310d32f713Shappy-lx  }.otherwise {
1320d32f713Shappy-lx    // for now, only dynamically disable prefetcher, without depth and flush
1330d32f713Shappy-lx    depth := depth_const
1340d32f713Shappy-lx    flush := false.B
1350d32f713Shappy-lx  }
1360d32f713Shappy-lx
1370d32f713Shappy-lx  when(reset.asBool) {
1380d32f713Shappy-lx    depth := depth_const
1390d32f713Shappy-lx  }
1400d32f713Shappy-lx
1410d32f713Shappy-lx  XSPerfAccumulate("total_prefetch", io.timely.total_prefetch)
1420d32f713Shappy-lx  XSPerfAccumulate("late_hit_prefetch", io.timely.late_hit_prefetch)
1430d32f713Shappy-lx  XSPerfAccumulate("late_miss_prefetch", io.timely.late_miss_prefetch)
1440d32f713Shappy-lx  XSPerfAccumulate("good_prefetch", io.validity.good_prefetch)
1450d32f713Shappy-lx  XSPerfAccumulate("bad_prefetch", io.validity.bad_prefetch)
1460d32f713Shappy-lx  for(i <- (0 until DEPTH_BITS)) {
1470d32f713Shappy-lx    val t = (1 << i)
1480d32f713Shappy-lx    XSPerfAccumulate(s"depth${t}", depth === t.U)
1490d32f713Shappy-lx  }
1500d32f713Shappy-lx  XSPerfAccumulate("trigger_disable", trigger_disable)
1510d32f713Shappy-lx  XSPerfAccumulate("prefetch_hit", io.timely.prefetch_hit)
15220e09ab1Shappy-lx  XSPerfAccumulate("disable_time", !enable)
1530d32f713Shappy-lx
1540d32f713Shappy-lx  assert(depth =/= 0.U, "depth should not be zero")
1550d32f713Shappy-lx}
156