104665835SMaxpicca-Lipackage xiangshan.cache.wpu 204665835SMaxpicca-Li 38891a219SYinan Xuimport org.chipsalliance.cde.config.{Field, Parameters} 404665835SMaxpicca-Liimport chisel3._ 504665835SMaxpicca-Liimport chisel3.util._ 6*bb2f3f51STang Haojinimport utility.XSPerfAccumulate 704665835SMaxpicca-Liimport xiangshan.cache.{HasL1CacheParameters, L1CacheParameters} 804665835SMaxpicca-Liimport xiangshan.{XSBundle, XSModule} 904665835SMaxpicca-Li 1004665835SMaxpicca-Li/* 1104665835SMaxpicca-Li// TODO: need to learn the specific grammar 1204665835SMaxpicca-Liabstract class WPUBaseModule[T <: Data](implicit P: Parameters) extends XSModule with HasWPUParameters{ 1304665835SMaxpicca-Li def apply[T <: Data] 1404665835SMaxpicca-Li def pred(vaddr: UInt, en: Bool) : T 1504665835SMaxpicca-Li def update(vaddr: UInt, data: T ,en: Bool) 1604665835SMaxpicca-Li} 1704665835SMaxpicca-Li*/ 1804665835SMaxpicca-Li 1904665835SMaxpicca-Licase object WPUParamsKey extends Field[WPUParameters] 2004665835SMaxpicca-Licase class WPUParameters 2104665835SMaxpicca-Li( 2204665835SMaxpicca-Li enWPU: Boolean = true, 2304665835SMaxpicca-Li algoName: String = "mru", 2404665835SMaxpicca-Li enCfPred: Boolean = false, 2504665835SMaxpicca-Li isICache: Boolean = false, 2604665835SMaxpicca-Li // how to impelement a extend inlcude hasL1Cache and L2 Cache 2704665835SMaxpicca-Li) 2804665835SMaxpicca-Li 2904665835SMaxpicca-Litrait HasWPUParameters extends HasL1CacheParameters{ 3004665835SMaxpicca-Li def AlgoWPUMap(wpuParam: WPUParameters, nPorts: Int): BaseWPU = { 3104665835SMaxpicca-Li wpuParam.algoName.toLowerCase match { 3204665835SMaxpicca-Li case "mru" => Module(new MruWPU(wpuParam, nPorts)) 3304665835SMaxpicca-Li case "mmru" => Module(new MmruWPU(wpuParam, nPorts)) 3404665835SMaxpicca-Li case "utag" => Module(new UtagWPU(wpuParam, nPorts)) 3504665835SMaxpicca-Li case t => throw new IllegalArgumentException(s"unknown WPU Algorithm $t") 3604665835SMaxpicca-Li } 3704665835SMaxpicca-Li } 3804665835SMaxpicca-Li} 3904665835SMaxpicca-Li 4004665835SMaxpicca-Liabstract class BaseWPUBundle(implicit P: Parameters) extends XSBundle 4104665835SMaxpicca-Liabstract class WPUModule(implicit P: Parameters) extends XSModule with HasWPUParameters 4204665835SMaxpicca-Li 4304665835SMaxpicca-Liclass BaseWpuUpdateBundle(nWays: Int)(implicit p: Parameters) extends BaseWPUBundle{ 4404665835SMaxpicca-Li val en = Bool() 4504665835SMaxpicca-Li val vaddr = UInt(VAddrBits.W) 4604665835SMaxpicca-Li val way_en = UInt(nWays.W) 4704665835SMaxpicca-Li} 4804665835SMaxpicca-Li 4904665835SMaxpicca-Liclass LookupWpuUpdateBundle(nWays: Int)(implicit p: Parameters) extends BaseWpuUpdateBundle(nWays){ 5004665835SMaxpicca-Li val pred_way_en = UInt(nWays.W) 5104665835SMaxpicca-Li} 5204665835SMaxpicca-Li 5304665835SMaxpicca-Liclass BaseWpuPredictIO(nWays: Int)(implicit p: Parameters) extends BaseWPUBundle{ 5404665835SMaxpicca-Li val en = Input(Bool()) 5504665835SMaxpicca-Li val vaddr = Input(UInt(VAddrBits.W)) 5604665835SMaxpicca-Li val way_en = Output(UInt(nWays.W)) 5704665835SMaxpicca-Li} 5804665835SMaxpicca-Li 5904665835SMaxpicca-Liclass WPUBaseIO(portNum: Int, nWays: Int)(implicit p:Parameters) extends BaseWPUBundle { 6004665835SMaxpicca-Li val predVec = Vec(portNum, new BaseWpuPredictIO(nWays)) 6104665835SMaxpicca-Li val updLookup = Input(Vec(portNum, new LookupWpuUpdateBundle(nWays))) 6204665835SMaxpicca-Li val updReplaycarry = Input(Vec(portNum, new BaseWpuUpdateBundle(nWays))) 6304665835SMaxpicca-Li val updTagwrite = Input(Vec(portNum, new BaseWpuUpdateBundle(nWays))) 6404665835SMaxpicca-Li} 6504665835SMaxpicca-Li 6604665835SMaxpicca-Liabstract class BaseWPU(wpuParam: WPUParameters, nPorts: Int)(implicit p:Parameters) extends WPUModule { 6704665835SMaxpicca-Li val cacheParams: L1CacheParameters = if (wpuParam.isICache) icacheParameters else dcacheParameters 6804665835SMaxpicca-Li 6904665835SMaxpicca-Li val setSize = nSets 7004665835SMaxpicca-Li val nTagIdx = nWays 7104665835SMaxpicca-Li // auxiliary 1 bit is used to judge whether cache miss 7204665835SMaxpicca-Li val auxWayBits = wayBits + 1 7304665835SMaxpicca-Li val TagIdxBits = log2Up(nTagIdx) 7404665835SMaxpicca-Li val utagBits = 8 7504665835SMaxpicca-Li 7604665835SMaxpicca-Li val io = IO(new WPUBaseIO(nPorts, nWays)) 7704665835SMaxpicca-Li 7804665835SMaxpicca-Li def get_wpu_idx(addr: UInt): UInt = { 7904665835SMaxpicca-Li addr(untagBits - 1, blockOffBits) 8004665835SMaxpicca-Li } 8104665835SMaxpicca-Li} 8204665835SMaxpicca-Li 8304665835SMaxpicca-Liclass MruWPU(wpuParam: WPUParameters, nPorts: Int)(implicit p:Parameters) extends BaseWPU(wpuParam, nPorts){ 8404665835SMaxpicca-Li println(" WpuType: MruWPU") 8504665835SMaxpicca-Li val predict_regs = RegInit(VecInit(Seq.fill(setSize)(0.U(wayBits.W)))) 8604665835SMaxpicca-Li 8704665835SMaxpicca-Li def write(upd: BaseWpuUpdateBundle): Unit = { 8804665835SMaxpicca-Li when(upd.en) { 8904665835SMaxpicca-Li val upd_setIdx = get_wpu_idx(upd.vaddr) 9004665835SMaxpicca-Li predict_regs(upd_setIdx) := OHToUInt(upd.way_en) 9104665835SMaxpicca-Li } 9204665835SMaxpicca-Li } 9304665835SMaxpicca-Li 9404665835SMaxpicca-Li def predict(pred: BaseWpuPredictIO): Unit = { 9504665835SMaxpicca-Li val predSetIdx = get_wpu_idx(pred.vaddr) 9604665835SMaxpicca-Li when(pred.en) { 9704665835SMaxpicca-Li pred.way_en := UIntToOH(predict_regs(predSetIdx)) 9804665835SMaxpicca-Li }.otherwise { 9904665835SMaxpicca-Li pred.way_en := 0.U(nWays.W) 10004665835SMaxpicca-Li } 10104665835SMaxpicca-Li } 10204665835SMaxpicca-Li 10304665835SMaxpicca-Li for(i <- 0 until nPorts){ 10404665835SMaxpicca-Li predict(io.predVec(i)) 10504665835SMaxpicca-Li write(io.updLookup(i)) 10604665835SMaxpicca-Li write(io.updReplaycarry(i)) 10704665835SMaxpicca-Li write(io.updTagwrite(i)) 10804665835SMaxpicca-Li } 10904665835SMaxpicca-Li 11004665835SMaxpicca-Li} 11104665835SMaxpicca-Li 11204665835SMaxpicca-Liclass MmruWPU(wpuParam: WPUParameters, nPorts: Int)(implicit p:Parameters) extends BaseWPU(wpuParam, nPorts){ 11304665835SMaxpicca-Li println(" WpuType: MmruWPU") 11404665835SMaxpicca-Li val predict_regs = RegInit(VecInit(Seq.fill(setSize)(VecInit(Seq.fill(nTagIdx)(0.U(auxWayBits.W)))))) 11504665835SMaxpicca-Li 11604665835SMaxpicca-Li def write(upd: BaseWpuUpdateBundle): Unit = { 11704665835SMaxpicca-Li when(upd.en) { 11804665835SMaxpicca-Li val updSetIdx = get_wpu_idx(upd.vaddr) 11904665835SMaxpicca-Li val updTagIdx = get_vir_tag(upd.vaddr) 12004665835SMaxpicca-Li predict_regs(updSetIdx)(updTagIdx) := OHToUInt(upd.way_en) 12104665835SMaxpicca-Li } 12204665835SMaxpicca-Li } 12304665835SMaxpicca-Li 12404665835SMaxpicca-Li def predict(pred: BaseWpuPredictIO): Unit = { 12504665835SMaxpicca-Li val predSetIdx = get_wpu_idx(pred.vaddr) 12604665835SMaxpicca-Li val predTagIdx = get_vir_tag(pred.vaddr) 12704665835SMaxpicca-Li when(pred.en) { 12804665835SMaxpicca-Li //UIntToOH(8.U(4.W))=100000000.U(16.W)=00000000.U(8.W) 12904665835SMaxpicca-Li //UIntToOH(8.U(4.W), 8)=00000001.U(8.W) 13004665835SMaxpicca-Li pred.way_en := UIntToOH(predict_regs(predSetIdx)(predTagIdx)) 13104665835SMaxpicca-Li }.otherwise { 13204665835SMaxpicca-Li pred.way_en := 0.U(nWays.W) 13304665835SMaxpicca-Li } 13404665835SMaxpicca-Li } 13504665835SMaxpicca-Li 13604665835SMaxpicca-Li for(i <- 0 until nPorts){ 13704665835SMaxpicca-Li predict(io.predVec(i)) 13804665835SMaxpicca-Li write(io.updLookup(i)) 13904665835SMaxpicca-Li write(io.updReplaycarry(i)) 14004665835SMaxpicca-Li write(io.updTagwrite(i)) 14104665835SMaxpicca-Li } 14204665835SMaxpicca-Li 14304665835SMaxpicca-Li} 14404665835SMaxpicca-Li 14504665835SMaxpicca-Liclass UtagWPU(wpuParam: WPUParameters, nPorts: Int)(implicit p:Parameters) extends BaseWPU(wpuParam, nPorts){ 14604665835SMaxpicca-Li println(" WpuType: UtagWPU") 14704665835SMaxpicca-Li val utag_regs = RegInit(VecInit(Seq.fill(setSize)(VecInit(Seq.fill(nWays)(0.U(utagBits.W)))))) 14804665835SMaxpicca-Li val valid_regs = RegInit(VecInit(Seq.fill(setSize)(VecInit(Seq.fill(nWays)(false.B))))) 14904665835SMaxpicca-Li 15004665835SMaxpicca-Li def get_hash_utag(addr: UInt): UInt = { 15104665835SMaxpicca-Li val utagQuotient = vtagBits / utagBits 15204665835SMaxpicca-Li val utagRemainder = vtagBits % utagBits 15304665835SMaxpicca-Li val vtag = get_vir_tag(addr) 15404665835SMaxpicca-Li 15504665835SMaxpicca-Li /* old */ 15604665835SMaxpicca-Li vtag(utagBits * 2 - 1, utagBits) ^ vtag(utagBits - 1, 0) 15704665835SMaxpicca-Li 15804665835SMaxpicca-Li /* new */ 15904665835SMaxpicca-Li // val tmp = vtag(utagQuotient * utagBits - 1, 0).asTypeOf(Vec(utagQuotient, UInt(utagBits.W))) 16004665835SMaxpicca-Li // val res1 = tmp.reduce(_ ^ _) 16104665835SMaxpicca-Li // val res2 = Wire(UInt(utagRemainder.W)) 16204665835SMaxpicca-Li // if(utagRemainder!=0){ 16304665835SMaxpicca-Li // res2 := res1(utagRemainder - 1, 0) ^ vtag(vtagBits - 1, utagBits * utagQuotient) 16404665835SMaxpicca-Li // Cat(res1(utagBits - 1, utagRemainder), res2) 16504665835SMaxpicca-Li // }else{ 16604665835SMaxpicca-Li // res1 16704665835SMaxpicca-Li // } 16804665835SMaxpicca-Li } 16904665835SMaxpicca-Li 17004665835SMaxpicca-Li def write_utag(upd: BaseWpuUpdateBundle): Unit = { 17104665835SMaxpicca-Li when(upd.en){ 17204665835SMaxpicca-Li val upd_setIdx = get_wpu_idx(upd.vaddr) 17304665835SMaxpicca-Li val upd_utag = get_hash_utag(upd.vaddr) 17404665835SMaxpicca-Li val upd_way = OHToUInt(upd.way_en) 17504665835SMaxpicca-Li utag_regs(upd_setIdx)(upd_way) := upd_utag 17604665835SMaxpicca-Li valid_regs(upd_setIdx)(upd_way) := true.B 17704665835SMaxpicca-Li } 17804665835SMaxpicca-Li } 17904665835SMaxpicca-Li 18004665835SMaxpicca-Li def unvalid_utag(upd: LookupWpuUpdateBundle): Unit = { 18104665835SMaxpicca-Li when(upd.en){ 18204665835SMaxpicca-Li val upd_setIdx = get_wpu_idx(upd.vaddr) 18304665835SMaxpicca-Li val upd_way = OHToUInt(upd.pred_way_en) 18404665835SMaxpicca-Li valid_regs(upd_setIdx)(upd_way) := false.B 18504665835SMaxpicca-Li } 18604665835SMaxpicca-Li } 18704665835SMaxpicca-Li 18804665835SMaxpicca-Li def predict(pred: BaseWpuPredictIO): Unit = { 18904665835SMaxpicca-Li val req_setIdx = get_wpu_idx(pred.vaddr) 19004665835SMaxpicca-Li val req_utag = get_hash_utag(pred.vaddr) 19104665835SMaxpicca-Li val pred_way_en = Wire(UInt(nWays.W)) 19204665835SMaxpicca-Li when(pred.en) { 19304665835SMaxpicca-Li pred_way_en := VecInit((0 until nWays).map(i => 19404665835SMaxpicca-Li req_utag === utag_regs(req_setIdx)(i) && valid_regs(req_setIdx)(i) 19504665835SMaxpicca-Li )).asUInt 19604665835SMaxpicca-Li }.otherwise { 19704665835SMaxpicca-Li pred_way_en := 0.U(nWays.W) 19804665835SMaxpicca-Li } 19904665835SMaxpicca-Li // avoid hash conflict 20004665835SMaxpicca-Li pred.way_en := UIntToOH(OHToUInt(pred_way_en)) 20104665835SMaxpicca-Li } 20204665835SMaxpicca-Li 20304665835SMaxpicca-Li val hash_conflict = Wire(Vec(nPorts, Bool())) 20404665835SMaxpicca-Li for(i <- 0 until nPorts){ 20504665835SMaxpicca-Li predict(io.predVec(i)) 20604665835SMaxpicca-Li val real_way_en = io.updLookup(i).way_en 20704665835SMaxpicca-Li val pred_way_en = io.updLookup(i).pred_way_en 20804665835SMaxpicca-Li val pred_miss = io.updLookup(i).en && !pred_way_en.orR 20904665835SMaxpicca-Li val real_miss = io.updLookup(i).en && !real_way_en.orR 21004665835SMaxpicca-Li val way_match = io.updLookup(i).en && pred_way_en === real_way_en 21104665835SMaxpicca-Li 21204665835SMaxpicca-Li hash_conflict(i) := !pred_miss && !way_match 21304665835SMaxpicca-Li // look up: vtag miss but tag hit 21404665835SMaxpicca-Li when(pred_miss && !real_miss) { 21504665835SMaxpicca-Li write_utag(io.updLookup(i)) 21604665835SMaxpicca-Li } 21704665835SMaxpicca-Li // look up: vtag hit but other tag hit ==> unvalid pred way; write real way 21804665835SMaxpicca-Li when(!pred_miss && !way_match) { 21904665835SMaxpicca-Li unvalid_utag(io.updLookup(i)) 22004665835SMaxpicca-Li } 22104665835SMaxpicca-Li when(!pred_miss && !real_miss && !way_match) { 22204665835SMaxpicca-Li write_utag(io.updLookup(i)) 22304665835SMaxpicca-Li } 22404665835SMaxpicca-Li // replay carry 22504665835SMaxpicca-Li write_utag(io.updReplaycarry(i)) 22604665835SMaxpicca-Li // tag write 22704665835SMaxpicca-Li write_utag(io.updTagwrite(i)) 22804665835SMaxpicca-Li } 22904665835SMaxpicca-Li 23004665835SMaxpicca-Li XSPerfAccumulate("utag_hash_conflict", PopCount(hash_conflict)) 23104665835SMaxpicca-Li}