1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package xiangshan.mem 18 19import chisel3._ 20import chisel3.util._ 21import xiangshan._ 22import utils._ 23import xiangshan.cache._ 24 25class MaskedSyncDataModuleTemplate[T <: Data]( 26 gen: T, numEntries: Int, numRead: Int, numWrite: Int, numMRead: Int = 0, numMWrite: Int = 0 27) extends Module { 28 val io = IO(new Bundle { 29 // address indexed sync read 30 val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W))) 31 val rdata = Output(Vec(numRead, gen)) 32 // masked sync read (1H) 33 val mrmask = Input(Vec(numMRead, Vec(numEntries, Bool()))) 34 val mrdata = Output(Vec(numMRead, gen)) 35 // address indexed write 36 val wen = Input(Vec(numWrite, Bool())) 37 val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W))) 38 val wdata = Input(Vec(numWrite, gen)) 39 // masked write 40 val mwmask = Input(Vec(numMWrite, Vec(numEntries, Bool()))) 41 val mwdata = Input(Vec(numMWrite, gen)) 42 }) 43 44 val data = Reg(Vec(numEntries, gen)) 45 46 // read ports 47 for (i <- 0 until numRead) { 48 io.rdata(i) := data(RegNext(io.raddr(i))) 49 } 50 51 // masked read ports 52 for (i <- 0 until numMRead) { 53 io.mrdata(i) := Mux1H(RegNext(io.mrmask(i)), data) 54 } 55 56 // write ports (with priorities) 57 for (i <- 0 until numWrite) { 58 when (io.wen(i)) { 59 data(io.waddr(i)) := io.wdata(i) 60 } 61 } 62 63 // masked write 64 for (j <- 0 until numEntries) { 65 val wen = VecInit((0 until numMWrite).map(i => io.mwmask(i)(j))).asUInt.orR 66 when (wen) { 67 data(j) := VecInit((0 until numMWrite).map(i => { 68 Mux(io.mwmask(i)(j), io.mwdata(i), 0.U).asUInt 69 })).reduce(_ | _) 70 } 71 } 72 73 // DataModuleTemplate should not be used when there're any write conflicts 74 for (i <- 0 until numWrite) { 75 for (j <- i+1 until numWrite) { 76 assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j))) 77 } 78 } 79} 80