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