1c6d43980SLemover/*************************************************************************************** 2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory 4c6d43980SLemover* 5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2. 6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2. 7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at: 8c6d43980SLemover* http://license.coscl.org.cn/MulanPSL2 9c6d43980SLemover* 10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13c6d43980SLemover* 14c6d43980SLemover* See the Mulan PSL v2 for more details. 15c6d43980SLemover***************************************************************************************/ 16c6d43980SLemover 175844fcf0SLinJiaweipackage xiangshan.backend.regfile 185844fcf0SLinJiawei 198891a219SYinan Xuimport org.chipsalliance.cde.config.Parameters 205844fcf0SLinJiaweiimport chisel3._ 215844fcf0SLinJiaweiimport chisel3.util._ 225844fcf0SLinJiaweiimport xiangshan._ 23b6b11f60SXuan Huimport xiangshan.backend.datapath.DataConfig.{DataConfig, FpData, FpRegSrcDataSet, IntData, IntRegSrcDataSet, VecData, VecRegSrcDataSet, VfRegSrcDataSet} 2439c59369SXuan Huimport xiangshan.backend.exu.ExeUnitParams 255844fcf0SLinJiawei 26027c9765SXuan Huclass RfReadPort(dataWidth: Int, addrWidth: Int) extends Bundle { 279ab1568eSczw val addr = Input(UInt(addrWidth.W)) 289ab1568eSczw val data = Output(UInt(dataWidth.W)) 295844fcf0SLinJiawei} 305844fcf0SLinJiawei 31027c9765SXuan Huclass RfWritePort(dataWidth: Int, addrWidth: Int) extends Bundle { 325844fcf0SLinJiawei val wen = Input(Bool()) 339ab1568eSczw val addr = Input(UInt(addrWidth.W)) 349ab1568eSczw val data = Input(UInt(dataWidth.W)) 355844fcf0SLinJiawei} 365844fcf0SLinJiawei 37730cfbc0SXuan Huclass RfReadPortWithConfig(val rfReadDataCfg: DataConfig, addrWidth: Int) extends Bundle { 38730cfbc0SXuan Hu val addr: UInt = Input(UInt(addrWidth.W)) 39730cfbc0SXuan Hu val srcType: UInt = Input(UInt(3.W)) 40730cfbc0SXuan Hu 41b6b11f60SXuan Hu def readInt: Boolean = IntRegSrcDataSet.contains(rfReadDataCfg) 42b6b11f60SXuan Hu def readFp : Boolean = FpRegSrcDataSet .contains(rfReadDataCfg) 43b6b11f60SXuan Hu def readVec: Boolean = VecRegSrcDataSet.contains(rfReadDataCfg) 44b6b11f60SXuan Hu def readVf : Boolean = VfRegSrcDataSet .contains(rfReadDataCfg) 45730cfbc0SXuan Hu} 46730cfbc0SXuan Hu 47730cfbc0SXuan Huclass RfWritePortWithConfig(val rfWriteDataCfg: DataConfig, addrWidth: Int) extends Bundle { 48730cfbc0SXuan Hu val wen = Input(Bool()) 49730cfbc0SXuan Hu val addr = Input(UInt(addrWidth.W)) 50730cfbc0SXuan Hu val data = Input(UInt(rfWriteDataCfg.dataWidth.W)) 51730cfbc0SXuan Hu val intWen = Input(Bool()) 52730cfbc0SXuan Hu val fpWen = Input(Bool()) 53730cfbc0SXuan Hu val vecWen = Input(Bool()) 54730cfbc0SXuan Hu def writeInt: Boolean = rfWriteDataCfg.isInstanceOf[IntData] 55730cfbc0SXuan Hu def writeFp : Boolean = rfWriteDataCfg.isInstanceOf[FpData] 56730cfbc0SXuan Hu def writeVec: Boolean = rfWriteDataCfg.isInstanceOf[VecData] 57730cfbc0SXuan Hu} 58730cfbc0SXuan Hu 595844fcf0SLinJiaweiclass Regfile 605844fcf0SLinJiawei( 61a1ca6e15SZhangZifei name: String, 62027c9765SXuan Hu numPregs: Int, 635844fcf0SLinJiawei numReadPorts: Int, 6493b61a80SYinan Xu numWritePorts: Int, 659684eb4fSLinJiawei hasZero: Boolean, 6673faecdcSXuan Hu len: Int, 6773faecdcSXuan Hu width: Int, 68b8ca25cbSxiaofeibao-xjtu bankNum: Int = 1, 69027c9765SXuan Hu) extends Module { 705844fcf0SLinJiawei val io = IO(new Bundle() { 7173faecdcSXuan Hu val readPorts = Vec(numReadPorts, new RfReadPort(len, width)) 7273faecdcSXuan Hu val writePorts = Vec(numWritePorts, new RfWritePort(len, width)) 73a8db15d8Sfdy val debug_rports = Vec(65, new RfReadPort(len, width)) 745844fcf0SLinJiawei }) 750c701001SLinJiawei 76027c9765SXuan Hu println(name + ": size:" + numPregs + " read: " + numReadPorts + " write: " + numWritePorts) 7705f23f57SWilliam Wang 78027c9765SXuan Hu val mem = Reg(Vec(numPregs, UInt(len.W))) 7919203128Sxiaofeibao-xjtu require(Seq(1, 2, 4).contains(bankNum), "bankNum must be 1 or 2 or 4") 800c701001SLinJiawei for (r <- io.readPorts) { 81b8ca25cbSxiaofeibao-xjtu if (bankNum == 1) { 826e8ad5a5Sxiaofeibao-xjtu r.data := mem(RegNext(r.addr)) 830c701001SLinJiawei } 84b8ca25cbSxiaofeibao-xjtu else { 85b8ca25cbSxiaofeibao-xjtu val banks = (0 until bankNum).map { case i => 86b8ca25cbSxiaofeibao-xjtu mem.zipWithIndex.filter{ case (m, index) => (index % bankNum) == i }.map(_._1) 87b8ca25cbSxiaofeibao-xjtu } 88b8ca25cbSxiaofeibao-xjtu val bankWidth = bankNum.U.getWidth - 1 89b8ca25cbSxiaofeibao-xjtu val hitBankWire = VecInit((0 until bankNum).map { case i => r.addr(bankWidth - 1, 0) === i.U }) 90b8ca25cbSxiaofeibao-xjtu val hitBankReg = Reg(Vec(bankNum, Bool())) 91b8ca25cbSxiaofeibao-xjtu hitBankReg := hitBankWire 92b8ca25cbSxiaofeibao-xjtu val banksRdata = Wire(Vec(bankNum, UInt(len.W))) 93b8ca25cbSxiaofeibao-xjtu for (i <- 0 until bankNum) { 94b8ca25cbSxiaofeibao-xjtu banksRdata(i) := RegEnable(VecInit(banks(i))(r.addr(r.addr.getWidth - 1, bankWidth)), hitBankWire(i)) 95b8ca25cbSxiaofeibao-xjtu } 96b8ca25cbSxiaofeibao-xjtu r.data := Mux1H(hitBankReg, banksRdata) 97b8ca25cbSxiaofeibao-xjtu } 98b8ca25cbSxiaofeibao-xjtu } 991e6c281aSxiaofeibao-xjtu val writePorts = io.writePorts 1001e6c281aSxiaofeibao-xjtu for (i <- writePorts.indices) { 1011e6c281aSxiaofeibao-xjtu if (i < writePorts.size-1) { 1021e6c281aSxiaofeibao-xjtu val hasSameWrite = writePorts.drop(i + 1).map(w => w.wen && w.addr === writePorts(i).addr && writePorts(i).wen).reduce(_ || _) 1031e6c281aSxiaofeibao-xjtu assert(!hasSameWrite, "RegFile two or more writePorts write same addr") 1041e6c281aSxiaofeibao-xjtu } 1051e6c281aSxiaofeibao-xjtu } 1061e6c281aSxiaofeibao-xjtu for (i <- mem.indices) { 1071e6c281aSxiaofeibao-xjtu if (hasZero && i == 0) { 1081e6c281aSxiaofeibao-xjtu mem(i) := 0.U 1091e6c281aSxiaofeibao-xjtu } 1101e6c281aSxiaofeibao-xjtu else { 1111e6c281aSxiaofeibao-xjtu val wenOH = VecInit(io.writePorts.map(w => w.wen && w.addr === i.U)) 1121e6c281aSxiaofeibao-xjtu val wData = Mux1H(wenOH, io.writePorts.map(_.data)) 1131e6c281aSxiaofeibao-xjtu when(wenOH.asUInt.orR) { 1141e6c281aSxiaofeibao-xjtu mem(i) := wData 1151e6c281aSxiaofeibao-xjtu } 1160c701001SLinJiawei } 1170c701001SLinJiawei } 1186624015fSLinJiawei 1192225d46eSJiawei Lin for (rport <- io.debug_rports) { 1202225d46eSJiawei Lin val zero_rdata = Mux(rport.addr === 0.U, 0.U, mem(rport.addr)) 1212225d46eSJiawei Lin rport.data := (if (hasZero) zero_rdata else mem(rport.addr)) 122adb5df20SYinan Xu } 1235844fcf0SLinJiawei} 12444dead2fSZhangZifei 12593b61a80SYinan Xuobject Regfile { 126730cfbc0SXuan Hu // non-return version 12793b61a80SYinan Xu def apply( 128a1ca6e15SZhangZifei name : String, 12993b61a80SYinan Xu numEntries : Int, 13093b61a80SYinan Xu raddr : Seq[UInt], 131730cfbc0SXuan Hu rdata : Vec[UInt], 13293b61a80SYinan Xu wen : Seq[Bool], 13393b61a80SYinan Xu waddr : Seq[UInt], 13493b61a80SYinan Xu wdata : Seq[UInt], 13593b61a80SYinan Xu hasZero : Boolean, 1367154d65eSYinan Xu withReset : Boolean = false, 137b8ca25cbSxiaofeibao-xjtu bankNum : Int = 1, 138730cfbc0SXuan Hu debugReadAddr: Option[Seq[UInt]], 139730cfbc0SXuan Hu debugReadData: Option[Vec[UInt]], 140730cfbc0SXuan Hu )(implicit p: Parameters): Unit = { 14193b61a80SYinan Xu val numReadPorts = raddr.length 14293b61a80SYinan Xu val numWritePorts = wen.length 14393b61a80SYinan Xu require(wen.length == waddr.length) 14493b61a80SYinan Xu require(wen.length == wdata.length) 14593b61a80SYinan Xu val dataBits = wdata.map(_.getWidth).min 14693b61a80SYinan Xu require(wdata.map(_.getWidth).min == wdata.map(_.getWidth).max, s"dataBits != $dataBits") 14773faecdcSXuan Hu val addrBits = waddr.map(_.getWidth).min 14873faecdcSXuan Hu require(waddr.map(_.getWidth).min == waddr.map(_.getWidth).max, s"addrBits != $addrBits") 14973faecdcSXuan Hu 150b8ca25cbSxiaofeibao-xjtu val regfile = Module(new Regfile(name, numEntries, numReadPorts, numWritePorts, hasZero, dataBits, addrBits, bankNum)) 151730cfbc0SXuan Hu rdata := regfile.io.readPorts.zip(raddr).map { case (rport, addr) => 15293b61a80SYinan Xu rport.addr := addr 15393b61a80SYinan Xu rport.data 15444dead2fSZhangZifei } 15573faecdcSXuan Hu 15693b61a80SYinan Xu regfile.io.writePorts.zip(wen).zip(waddr).zip(wdata).foreach{ case (((wport, en), addr), data) => 15793b61a80SYinan Xu wport.wen := en 15893b61a80SYinan Xu wport.addr := addr 15993b61a80SYinan Xu wport.data := data 160067dba72SLinJiawei } 16193b61a80SYinan Xu if (withReset) { 16293b61a80SYinan Xu val numResetCycles = math.ceil(numEntries / numWritePorts).toInt 16393b61a80SYinan Xu val resetCounter = RegInit(numResetCycles.U) 16493b61a80SYinan Xu val resetWaddr = RegInit(VecInit((0 until numWritePorts).map(_.U(log2Up(numEntries + 1).W)))) 16593b61a80SYinan Xu val inReset = resetCounter =/= 0.U 16693b61a80SYinan Xu when (inReset) { 16793b61a80SYinan Xu resetCounter := resetCounter - 1.U 16893b61a80SYinan Xu resetWaddr := VecInit(resetWaddr.map(_ + numWritePorts.U)) 16993b61a80SYinan Xu } 17093b61a80SYinan Xu when (!inReset) { 17193b61a80SYinan Xu resetWaddr.map(_ := 0.U) 17293b61a80SYinan Xu } 17393b61a80SYinan Xu for ((wport, i) <- regfile.io.writePorts.zipWithIndex) { 17493b61a80SYinan Xu wport.wen := inReset || wen(i) 17593b61a80SYinan Xu wport.addr := Mux(inReset, resetWaddr(i), waddr(i)) 17693b61a80SYinan Xu wport.data := wdata(i) 17793b61a80SYinan Xu } 17893b61a80SYinan Xu } 179730cfbc0SXuan Hu 180730cfbc0SXuan Hu require(debugReadAddr.nonEmpty == debugReadData.nonEmpty, "Both debug addr and data bundles should be empty or not") 18193b61a80SYinan Xu regfile.io.debug_rports := DontCare 182730cfbc0SXuan Hu if (debugReadAddr.nonEmpty && debugReadData.nonEmpty) { 183730cfbc0SXuan Hu debugReadData.get := VecInit(regfile.io.debug_rports.zip(debugReadAddr.get).map { case (rport, addr) => 18493b61a80SYinan Xu rport.addr := addr 18593b61a80SYinan Xu rport.data 186730cfbc0SXuan Hu }) 18793b61a80SYinan Xu } 18893b61a80SYinan Xu } 18993b61a80SYinan Xu} 19073faecdcSXuan Hu 19173faecdcSXuan Huobject IntRegFile { 192730cfbc0SXuan Hu // non-return version 19373faecdcSXuan Hu def apply( 194a1ca6e15SZhangZifei name : String, 19573faecdcSXuan Hu numEntries : Int, 19673faecdcSXuan Hu raddr : Seq[UInt], 197730cfbc0SXuan Hu rdata : Vec[UInt], 19873faecdcSXuan Hu wen : Seq[Bool], 19973faecdcSXuan Hu waddr : Seq[UInt], 20073faecdcSXuan Hu wdata : Seq[UInt], 201730cfbc0SXuan Hu debugReadAddr: Option[Seq[UInt]], 202730cfbc0SXuan Hu debugReadData: Option[Vec[UInt]], 20373faecdcSXuan Hu withReset : Boolean = false, 204b8ca25cbSxiaofeibao-xjtu bankNum : Int, 205730cfbc0SXuan Hu )(implicit p: Parameters): Unit = { 20673faecdcSXuan Hu Regfile( 207730cfbc0SXuan Hu name, numEntries, raddr, rdata, wen, waddr, wdata, 208b8ca25cbSxiaofeibao-xjtu hasZero = true, withReset, bankNum, debugReadAddr, debugReadData) 20973faecdcSXuan Hu } 21073faecdcSXuan Hu} 21173faecdcSXuan Hu 212*60f0c5aeSxiaofeibaoobject FpRegFile { 213*60f0c5aeSxiaofeibao // non-return version 214*60f0c5aeSxiaofeibao def apply( 215*60f0c5aeSxiaofeibao name : String, 216*60f0c5aeSxiaofeibao numEntries : Int, 217*60f0c5aeSxiaofeibao raddr : Seq[UInt], 218*60f0c5aeSxiaofeibao rdata : Vec[UInt], 219*60f0c5aeSxiaofeibao wen : Seq[Bool], 220*60f0c5aeSxiaofeibao waddr : Seq[UInt], 221*60f0c5aeSxiaofeibao wdata : Seq[UInt], 222*60f0c5aeSxiaofeibao debugReadAddr: Option[Seq[UInt]], 223*60f0c5aeSxiaofeibao debugReadData: Option[Vec[UInt]], 224*60f0c5aeSxiaofeibao withReset : Boolean = false, 225*60f0c5aeSxiaofeibao bankNum : Int, 226*60f0c5aeSxiaofeibao )(implicit p: Parameters): Unit = { 227*60f0c5aeSxiaofeibao Regfile( 228*60f0c5aeSxiaofeibao name, numEntries, raddr, rdata, wen, waddr, wdata, 229*60f0c5aeSxiaofeibao hasZero = false, withReset, bankNum, debugReadAddr, debugReadData) 230*60f0c5aeSxiaofeibao } 231*60f0c5aeSxiaofeibao} 232*60f0c5aeSxiaofeibao 23373faecdcSXuan Huobject VfRegFile { 234730cfbc0SXuan Hu // non-return version 23573faecdcSXuan Hu def apply( 236a1ca6e15SZhangZifei name : String, 23773faecdcSXuan Hu numEntries : Int, 23873faecdcSXuan Hu splitNum : Int, 23973faecdcSXuan Hu raddr : Seq[UInt], 240730cfbc0SXuan Hu rdata : Vec[UInt], 24173faecdcSXuan Hu wen : Seq[Seq[Bool]], 24273faecdcSXuan Hu waddr : Seq[UInt], 24373faecdcSXuan Hu wdata : Seq[UInt], 244730cfbc0SXuan Hu debugReadAddr: Option[Seq[UInt]], 245730cfbc0SXuan Hu debugReadData: Option[Vec[UInt]], 24673faecdcSXuan Hu withReset : Boolean = false, 247730cfbc0SXuan Hu )(implicit p: Parameters): Unit = { 24873faecdcSXuan Hu require(splitNum >= 1, "splitNum should be no less than 1") 24973faecdcSXuan Hu require(splitNum == wen.length, "splitNum should be equal to length of wen vec") 25073faecdcSXuan Hu if (splitNum == 1) { 251730cfbc0SXuan Hu Regfile( 252730cfbc0SXuan Hu name, numEntries, raddr, rdata, wen.head, waddr, wdata, 253b8ca25cbSxiaofeibao-xjtu hasZero = false, withReset, bankNum = 1, debugReadAddr, debugReadData) 254761d728dSZhangZifei } else { 25573faecdcSXuan Hu val dataWidth = 64 256730cfbc0SXuan Hu val numReadPorts = raddr.length 25773faecdcSXuan Hu require(splitNum > 1 && wdata.head.getWidth == dataWidth * splitNum) 25873faecdcSXuan Hu val wdataVec = Wire(Vec(splitNum, Vec(wdata.length, UInt(dataWidth.W)))) 259730cfbc0SXuan Hu val rdataVec = Wire(Vec(splitNum, Vec(raddr.length, UInt(dataWidth.W)))) 260730cfbc0SXuan Hu val debugRDataVec: Option[Vec[Vec[UInt]]] = debugReadData.map(x => Wire(Vec(splitNum, Vec(x.length, UInt(dataWidth.W))))) 26173faecdcSXuan Hu for (i <- 0 until splitNum) { 26273faecdcSXuan Hu wdataVec(i) := wdata.map(_ ((i + 1) * dataWidth - 1, i * dataWidth)) 263730cfbc0SXuan Hu Regfile( 264730cfbc0SXuan Hu name + s"Part${i}", numEntries, raddr, rdataVec(i), wen(i), waddr, wdataVec(i), 265b8ca25cbSxiaofeibao-xjtu hasZero = false, withReset, bankNum = 1, debugReadAddr, debugRDataVec.map(_(i)) 266730cfbc0SXuan Hu ) 26773faecdcSXuan Hu } 26873faecdcSXuan Hu for (i <- 0 until rdata.length) { 269761d728dSZhangZifei rdata(i) := Cat(rdataVec.map(_ (i)).reverse) 27073faecdcSXuan Hu } 271730cfbc0SXuan Hu if (debugReadData.nonEmpty) { 272730cfbc0SXuan Hu for (i <- 0 until debugReadData.get.length) { 273730cfbc0SXuan Hu debugReadData.get(i) := Cat(debugRDataVec.get.map(_ (i)).reverse) 274730cfbc0SXuan Hu } 275730cfbc0SXuan Hu } 27673faecdcSXuan Hu } 277761d728dSZhangZifei } 27873faecdcSXuan Hu}