1package xiangshan.cache.wpu 2 3import chipsalliance.rocketchip.config.Parameters 4import chisel3._ 5import chisel3.util.{Fill, log2Up} 6import xiangshan._ 7import xiangshan.cache.HasDCacheParameters 8 9case class VictimList(nSets: Int, width: Int = 2) { 10 val victim_vec = RegInit(VecInit(Seq.fill(nSets)(0.U(width.W)))) 11 12 // replace to search 13 def replace(set: UInt) = { 14 when(victim_vec(set) =/= Fill(width, 1.U)) { 15 victim_vec(set) := victim_vec(set) + 1.U 16 } 17 } 18 19 def whether_sa(set:UInt) = victim_vec(set)(width-1) 20} 21 22trait WayConflictPredictParameters extends HasDCacheParameters { 23 val WCPSize = DCacheSets 24 val IdxBits = log2Up(WCPSize) 25 val CounterSize = 2 26 val PCOffBits = 2 27 def get_pc_idx(pc: UInt) = { pc(IdxBits+PCOffBits, PCOffBits)} 28 def get_addr_idx(addr: UInt) = { addr(IdxBits+DCacheSetOffset,DCacheSetOffset)} 29} 30 31abstract class WayConflictPredictorBundle(implicit P: Parameters) extends XSBundle with WayConflictPredictParameters 32abstract class WayConflictPredictorModule(implicit P: Parameters) extends XSModule with WayConflictPredictParameters 33 34class WayConflictPredIO (implicit p: Parameters) extends WayConflictPredictorBundle { 35 val en = Input(Bool()) 36 val vaddr = Input(UInt(VAddrBits.W)) 37 val way_conflict = Output(Bool()) 38} 39 40class WayConflictUpdIO (implicit p: Parameters) extends WayConflictPredictorBundle { 41 val en = Input(Bool()) 42 val vaddr = Input(UInt(VAddrBits.W)) 43 val dm_hit = Input(Bool()) 44 val sa_hit = Input(Bool()) 45} 46 47class WayConflictPredictor (nPorts: Int) (implicit p: Parameters) extends WayConflictPredictorModule{ 48 val io = IO(new Bundle() { 49 val pred = Vec(nPorts, new WayConflictPredIO) 50 val update = Vec(nPorts, new WayConflictUpdIO) 51 }) 52 val PredTable = RegInit(VecInit(Seq.fill(WCPSize)(0.U(CounterSize.W)))) 53 54 for (i <- 0 until nPorts){ 55 io.pred(i).way_conflict := io.pred(i).en & PredTable(get_addr_idx(io.pred(i).vaddr))(CounterSize-1) 56 // saturation counter 57 when(io.update(i).en && io.update(i).sa_hit) { 58 when(PredTable(get_addr_idx(io.update(i).vaddr)) === Fill(CounterSize, 1.U)) { 59 PredTable(get_addr_idx(io.update(i).vaddr)) := PredTable(get_addr_idx(io.update(i).vaddr)) 60 }.otherwise { 61 PredTable(get_addr_idx(io.update(i).vaddr)) := PredTable(get_addr_idx(io.update(i).vaddr)) + 1.U 62 } 63 }.elsewhen(io.update(i).en && io.update(i).dm_hit) { 64 when(PredTable(get_addr_idx(io.update(i).vaddr)) === Fill(CounterSize, 0.U)) { 65 PredTable(get_addr_idx(io.update(i).vaddr)) := PredTable(get_addr_idx(io.update(i).vaddr)) 66 }.otherwise { 67 PredTable(get_addr_idx(io.update(i).vaddr)) := PredTable(get_addr_idx(io.update(i).vaddr)) - 1.U 68 } 69 }.otherwise { 70 PredTable(get_addr_idx(io.update(i).vaddr)) := PredTable(get_addr_idx(io.update(i).vaddr)) 71 } 72 } 73 74}