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