1*0f22ee7cSWilliam Wangpackage xiangshan.mem 2*0f22ee7cSWilliam Wang 3*0f22ee7cSWilliam Wangimport chisel3._ 4*0f22ee7cSWilliam Wangimport chisel3.util._ 5*0f22ee7cSWilliam Wangimport xiangshan._ 6*0f22ee7cSWilliam Wangimport utils._ 7*0f22ee7cSWilliam Wangimport xiangshan.cache._ 8*0f22ee7cSWilliam Wang 9*0f22ee7cSWilliam Wangclass MaskedSyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, numWrite: Int, numMRead: Int = 0, numMWrite: Int = 0) extends XSModule with HasDCacheParameters { 10*0f22ee7cSWilliam Wang val io = IO(new Bundle { 11*0f22ee7cSWilliam Wang // address indexed sync read 12*0f22ee7cSWilliam Wang val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W))) 13*0f22ee7cSWilliam Wang val rdata = Output(Vec(numRead, gen)) 14*0f22ee7cSWilliam Wang // masked sync read (1H) 15*0f22ee7cSWilliam Wang val mrmask = Input(Vec(numMRead, Vec(numEntries, Bool()))) 16*0f22ee7cSWilliam Wang val mrdata = Output(Vec(numMRead, gen)) 17*0f22ee7cSWilliam Wang // address indexed write 18*0f22ee7cSWilliam Wang val wen = Input(Vec(numWrite, Bool())) 19*0f22ee7cSWilliam Wang val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W))) 20*0f22ee7cSWilliam Wang val wdata = Input(Vec(numWrite, gen)) 21*0f22ee7cSWilliam Wang // masked write 22*0f22ee7cSWilliam Wang val mwmask = Input(Vec(numMWrite, Vec(numEntries, Bool()))) 23*0f22ee7cSWilliam Wang val mwdata = Input(Vec(numMWrite, gen)) 24*0f22ee7cSWilliam Wang }) 25*0f22ee7cSWilliam Wang 26*0f22ee7cSWilliam Wang val data = Reg(Vec(numEntries, gen)) 27*0f22ee7cSWilliam Wang 28*0f22ee7cSWilliam Wang // read ports 29*0f22ee7cSWilliam Wang for (i <- 0 until numRead) { 30*0f22ee7cSWilliam Wang io.rdata(i) := data(RegNext(io.raddr(i))) 31*0f22ee7cSWilliam Wang } 32*0f22ee7cSWilliam Wang 33*0f22ee7cSWilliam Wang // masked read ports 34*0f22ee7cSWilliam Wang for (i <- 0 until numMRead) { 35*0f22ee7cSWilliam Wang io.mrdata(i) := Mux1H(RegNext(io.mrmask(i)), data) 36*0f22ee7cSWilliam Wang } 37*0f22ee7cSWilliam Wang 38*0f22ee7cSWilliam Wang // write ports (with priorities) 39*0f22ee7cSWilliam Wang for (i <- 0 until numWrite) { 40*0f22ee7cSWilliam Wang when (io.wen(i)) { 41*0f22ee7cSWilliam Wang data(io.waddr(i)) := io.wdata(i) 42*0f22ee7cSWilliam Wang } 43*0f22ee7cSWilliam Wang } 44*0f22ee7cSWilliam Wang 45*0f22ee7cSWilliam Wang // masked write 46*0f22ee7cSWilliam Wang for (j <- 0 until numEntries) { 47*0f22ee7cSWilliam Wang val wen = VecInit((0 until numMWrite).map(i => io.mwmask(i)(j))).asUInt.orR 48*0f22ee7cSWilliam Wang when (wen) { 49*0f22ee7cSWilliam Wang data(j) := VecInit((0 until numMWrite).map(i => { 50*0f22ee7cSWilliam Wang Mux(io.mwmask(i)(j), io.mwdata(i), 0.U).asUInt 51*0f22ee7cSWilliam Wang })).reduce(_ | _) 52*0f22ee7cSWilliam Wang } 53*0f22ee7cSWilliam Wang } 54*0f22ee7cSWilliam Wang 55*0f22ee7cSWilliam Wang // DataModuleTemplate should not be used when there're any write conflicts 56*0f22ee7cSWilliam Wang for (i <- 0 until numWrite) { 57*0f22ee7cSWilliam Wang for (j <- i+1 until numWrite) { 58*0f22ee7cSWilliam Wang assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j))) 59*0f22ee7cSWilliam Wang } 60*0f22ee7cSWilliam Wang } 61*0f22ee7cSWilliam Wang} 62