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._ 22771a6ec2Sxiaofeibaoimport utils.OptionWrapper 235844fcf0SLinJiaweiimport xiangshan._ 242aa3a761Ssinsanctionimport xiangshan.backend.datapath.DataConfig._ 2539c59369SXuan Huimport xiangshan.backend.exu.ExeUnitParams 265844fcf0SLinJiawei 27027c9765SXuan Huclass RfReadPort(dataWidth: Int, addrWidth: Int) extends Bundle { 289ab1568eSczw val addr = Input(UInt(addrWidth.W)) 299ab1568eSczw val data = Output(UInt(dataWidth.W)) 305844fcf0SLinJiawei} 315844fcf0SLinJiawei 32027c9765SXuan Huclass RfWritePort(dataWidth: Int, addrWidth: Int) extends Bundle { 335844fcf0SLinJiawei val wen = Input(Bool()) 349ab1568eSczw val addr = Input(UInt(addrWidth.W)) 359ab1568eSczw val data = Input(UInt(dataWidth.W)) 365844fcf0SLinJiawei} 375844fcf0SLinJiawei 38730cfbc0SXuan Huclass RfReadPortWithConfig(val rfReadDataCfg: DataConfig, addrWidth: Int) extends Bundle { 39730cfbc0SXuan Hu val addr: UInt = Input(UInt(addrWidth.W)) 40730cfbc0SXuan Hu val srcType: UInt = Input(UInt(3.W)) 41730cfbc0SXuan Hu 42b6b11f60SXuan Hu def readInt: Boolean = IntRegSrcDataSet.contains(rfReadDataCfg) 43b6b11f60SXuan Hu def readFp : Boolean = FpRegSrcDataSet .contains(rfReadDataCfg) 44b6b11f60SXuan Hu def readVec: Boolean = VecRegSrcDataSet.contains(rfReadDataCfg) 45fbe46a0aSxiaofeibao def readVf : Boolean = VecRegSrcDataSet .contains(rfReadDataCfg) 46730cfbc0SXuan Hu} 47730cfbc0SXuan Hu 48730cfbc0SXuan Huclass RfWritePortWithConfig(val rfWriteDataCfg: DataConfig, addrWidth: Int) extends Bundle { 49730cfbc0SXuan Hu val wen = Input(Bool()) 50730cfbc0SXuan Hu val addr = Input(UInt(addrWidth.W)) 51730cfbc0SXuan Hu val data = Input(UInt(rfWriteDataCfg.dataWidth.W)) 52730cfbc0SXuan Hu val intWen = Input(Bool()) 53730cfbc0SXuan Hu val fpWen = Input(Bool()) 54730cfbc0SXuan Hu val vecWen = Input(Bool()) 552aa3a761Ssinsanction val v0Wen = Input(Bool()) 562aa3a761Ssinsanction val vlWen = Input(Bool()) 57730cfbc0SXuan Hu def writeInt: Boolean = rfWriteDataCfg.isInstanceOf[IntData] 58730cfbc0SXuan Hu def writeFp : Boolean = rfWriteDataCfg.isInstanceOf[FpData] 59730cfbc0SXuan Hu def writeVec: Boolean = rfWriteDataCfg.isInstanceOf[VecData] 6007b5cc60Sxiaofeibao def writeV0 : Boolean = rfWriteDataCfg.isInstanceOf[V0Data] 6107b5cc60Sxiaofeibao def writeVl : Boolean = rfWriteDataCfg.isInstanceOf[VlData] 62730cfbc0SXuan Hu} 63730cfbc0SXuan Hu 645844fcf0SLinJiaweiclass Regfile 655844fcf0SLinJiawei( 66a1ca6e15SZhangZifei name: String, 67027c9765SXuan Hu numPregs: Int, 685844fcf0SLinJiawei numReadPorts: Int, 6993b61a80SYinan Xu numWritePorts: Int, 709684eb4fSLinJiawei hasZero: Boolean, 7173faecdcSXuan Hu len: Int, 7273faecdcSXuan Hu width: Int, 73b8ca25cbSxiaofeibao-xjtu bankNum: Int = 1, 7460052a3fSxiaofeibao isVlRegfile: Boolean = false, 75027c9765SXuan Hu) extends Module { 765844fcf0SLinJiawei val io = IO(new Bundle() { 7773faecdcSXuan Hu val readPorts = Vec(numReadPorts, new RfReadPort(len, width)) 7873faecdcSXuan Hu val writePorts = Vec(numWritePorts, new RfWritePort(len, width)) 79a8db15d8Sfdy val debug_rports = Vec(65, new RfReadPort(len, width)) 805844fcf0SLinJiawei }) 8160052a3fSxiaofeibao override def desiredName = name 82027c9765SXuan Hu println(name + ": size:" + numPregs + " read: " + numReadPorts + " write: " + numWritePorts) 8305f23f57SWilliam Wang 8460052a3fSxiaofeibao val mem_0 = if (isVlRegfile) RegInit(0.U(len.W)) else Reg(UInt(len.W)) 85027c9765SXuan Hu val mem = Reg(Vec(numPregs, UInt(len.W))) 8660052a3fSxiaofeibao val memForRead = Wire(Vec(numPregs, UInt(len.W))) 8760052a3fSxiaofeibao memForRead.zipWithIndex.map{ case(m, i) => 8860052a3fSxiaofeibao if (i == 0) m := mem_0 8960052a3fSxiaofeibao else m := mem(i) 9060052a3fSxiaofeibao } 9119203128Sxiaofeibao-xjtu require(Seq(1, 2, 4).contains(bankNum), "bankNum must be 1 or 2 or 4") 920c701001SLinJiawei for (r <- io.readPorts) { 93b8ca25cbSxiaofeibao-xjtu if (bankNum == 1) { 9460052a3fSxiaofeibao r.data := memForRead(RegNext(r.addr)) 950c701001SLinJiawei } 96b8ca25cbSxiaofeibao-xjtu else { 97b8ca25cbSxiaofeibao-xjtu val banks = (0 until bankNum).map { case i => 9860052a3fSxiaofeibao memForRead.zipWithIndex.filter{ case (m, index) => (index % bankNum) == i }.map(_._1) 99b8ca25cbSxiaofeibao-xjtu } 100b8ca25cbSxiaofeibao-xjtu val bankWidth = bankNum.U.getWidth - 1 101b8ca25cbSxiaofeibao-xjtu val hitBankWire = VecInit((0 until bankNum).map { case i => r.addr(bankWidth - 1, 0) === i.U }) 102b8ca25cbSxiaofeibao-xjtu val hitBankReg = Reg(Vec(bankNum, Bool())) 103b8ca25cbSxiaofeibao-xjtu hitBankReg := hitBankWire 104b8ca25cbSxiaofeibao-xjtu val banksRdata = Wire(Vec(bankNum, UInt(len.W))) 105b8ca25cbSxiaofeibao-xjtu for (i <- 0 until bankNum) { 106b8ca25cbSxiaofeibao-xjtu banksRdata(i) := RegEnable(VecInit(banks(i))(r.addr(r.addr.getWidth - 1, bankWidth)), hitBankWire(i)) 107b8ca25cbSxiaofeibao-xjtu } 108b8ca25cbSxiaofeibao-xjtu r.data := Mux1H(hitBankReg, banksRdata) 109b8ca25cbSxiaofeibao-xjtu } 110b8ca25cbSxiaofeibao-xjtu } 1111e6c281aSxiaofeibao-xjtu val writePorts = io.writePorts 1121e6c281aSxiaofeibao-xjtu for (i <- writePorts.indices) { 1131e6c281aSxiaofeibao-xjtu if (i < writePorts.size-1) { 1141e6c281aSxiaofeibao-xjtu val hasSameWrite = writePorts.drop(i + 1).map(w => w.wen && w.addr === writePorts(i).addr && writePorts(i).wen).reduce(_ || _) 1151e6c281aSxiaofeibao-xjtu assert(!hasSameWrite, "RegFile two or more writePorts write same addr") 1161e6c281aSxiaofeibao-xjtu } 1171e6c281aSxiaofeibao-xjtu } 1181e6c281aSxiaofeibao-xjtu for (i <- mem.indices) { 1191e6c281aSxiaofeibao-xjtu if (hasZero && i == 0) { 12060052a3fSxiaofeibao mem_0 := 0.U 1211e6c281aSxiaofeibao-xjtu } 1221e6c281aSxiaofeibao-xjtu else { 1231e6c281aSxiaofeibao-xjtu val wenOH = VecInit(io.writePorts.map(w => w.wen && w.addr === i.U)) 1241e6c281aSxiaofeibao-xjtu val wData = Mux1H(wenOH, io.writePorts.map(_.data)) 1251e6c281aSxiaofeibao-xjtu when(wenOH.asUInt.orR) { 12660052a3fSxiaofeibao if (i == 0) mem_0 := wData 12760052a3fSxiaofeibao else mem(i) := wData 1281e6c281aSxiaofeibao-xjtu } 1290c701001SLinJiawei } 1300c701001SLinJiawei } 1316624015fSLinJiawei 1322225d46eSJiawei Lin for (rport <- io.debug_rports) { 13360052a3fSxiaofeibao rport.data := memForRead(rport.addr) 134adb5df20SYinan Xu } 1355844fcf0SLinJiawei} 13644dead2fSZhangZifei 13793b61a80SYinan Xuobject Regfile { 138730cfbc0SXuan Hu // non-return version 13993b61a80SYinan Xu def apply( 140a1ca6e15SZhangZifei name : String, 14193b61a80SYinan Xu numEntries : Int, 14293b61a80SYinan Xu raddr : Seq[UInt], 143730cfbc0SXuan Hu rdata : Vec[UInt], 14493b61a80SYinan Xu wen : Seq[Bool], 14593b61a80SYinan Xu waddr : Seq[UInt], 14693b61a80SYinan Xu wdata : Seq[UInt], 14793b61a80SYinan Xu hasZero : Boolean, 1487154d65eSYinan Xu withReset : Boolean = false, 149b8ca25cbSxiaofeibao-xjtu bankNum : Int = 1, 150730cfbc0SXuan Hu debugReadAddr: Option[Seq[UInt]], 151730cfbc0SXuan Hu debugReadData: Option[Vec[UInt]], 15260052a3fSxiaofeibao isVlRegfile : Boolean = false, 153730cfbc0SXuan Hu )(implicit p: Parameters): Unit = { 15493b61a80SYinan Xu val numReadPorts = raddr.length 15593b61a80SYinan Xu val numWritePorts = wen.length 15693b61a80SYinan Xu require(wen.length == waddr.length) 15793b61a80SYinan Xu require(wen.length == wdata.length) 15893b61a80SYinan Xu val dataBits = wdata.map(_.getWidth).min 15993b61a80SYinan Xu require(wdata.map(_.getWidth).min == wdata.map(_.getWidth).max, s"dataBits != $dataBits") 16073faecdcSXuan Hu val addrBits = waddr.map(_.getWidth).min 16173faecdcSXuan Hu require(waddr.map(_.getWidth).min == waddr.map(_.getWidth).max, s"addrBits != $addrBits") 16273faecdcSXuan Hu 1638537b88aSTang Haojin val instanceName = name(0).toLower.toString() + name.drop(1) 16460052a3fSxiaofeibao require(instanceName != name, "Regfile Instance Name can't be same as Module name") 16560052a3fSxiaofeibao val regfile = Module(new Regfile(name, numEntries, numReadPorts, numWritePorts, hasZero, dataBits, addrBits, bankNum, isVlRegfile)).suggestName(instanceName) 166730cfbc0SXuan Hu rdata := regfile.io.readPorts.zip(raddr).map { case (rport, addr) => 16793b61a80SYinan Xu rport.addr := addr 16893b61a80SYinan Xu rport.data 16944dead2fSZhangZifei } 17073faecdcSXuan Hu 17193b61a80SYinan Xu regfile.io.writePorts.zip(wen).zip(waddr).zip(wdata).foreach{ case (((wport, en), addr), data) => 17293b61a80SYinan Xu wport.wen := en 17393b61a80SYinan Xu wport.addr := addr 17493b61a80SYinan Xu wport.data := data 175067dba72SLinJiawei } 17693b61a80SYinan Xu if (withReset) { 17793b61a80SYinan Xu val numResetCycles = math.ceil(numEntries / numWritePorts).toInt 17893b61a80SYinan Xu val resetCounter = RegInit(numResetCycles.U) 17993b61a80SYinan Xu val resetWaddr = RegInit(VecInit((0 until numWritePorts).map(_.U(log2Up(numEntries + 1).W)))) 18093b61a80SYinan Xu val inReset = resetCounter =/= 0.U 18193b61a80SYinan Xu when (inReset) { 18293b61a80SYinan Xu resetCounter := resetCounter - 1.U 18393b61a80SYinan Xu resetWaddr := VecInit(resetWaddr.map(_ + numWritePorts.U)) 18493b61a80SYinan Xu } 18593b61a80SYinan Xu when (!inReset) { 18693b61a80SYinan Xu resetWaddr.map(_ := 0.U) 18793b61a80SYinan Xu } 18893b61a80SYinan Xu for ((wport, i) <- regfile.io.writePorts.zipWithIndex) { 18993b61a80SYinan Xu wport.wen := inReset || wen(i) 19093b61a80SYinan Xu wport.addr := Mux(inReset, resetWaddr(i), waddr(i)) 19193b61a80SYinan Xu wport.data := wdata(i) 19293b61a80SYinan Xu } 19393b61a80SYinan Xu } 194730cfbc0SXuan Hu 195730cfbc0SXuan Hu require(debugReadAddr.nonEmpty == debugReadData.nonEmpty, "Both debug addr and data bundles should be empty or not") 19693b61a80SYinan Xu regfile.io.debug_rports := DontCare 197730cfbc0SXuan Hu if (debugReadAddr.nonEmpty && debugReadData.nonEmpty) { 198730cfbc0SXuan Hu debugReadData.get := VecInit(regfile.io.debug_rports.zip(debugReadAddr.get).map { case (rport, addr) => 19993b61a80SYinan Xu rport.addr := addr 20093b61a80SYinan Xu rport.data 201730cfbc0SXuan Hu }) 20293b61a80SYinan Xu } 20393b61a80SYinan Xu } 20493b61a80SYinan Xu} 20573faecdcSXuan Hu 20673faecdcSXuan Huobject IntRegFile { 207730cfbc0SXuan Hu // non-return version 20873faecdcSXuan Hu def apply( 209a1ca6e15SZhangZifei name : String, 21073faecdcSXuan Hu numEntries : Int, 21173faecdcSXuan Hu raddr : Seq[UInt], 212730cfbc0SXuan Hu rdata : Vec[UInt], 21373faecdcSXuan Hu wen : Seq[Bool], 21473faecdcSXuan Hu waddr : Seq[UInt], 21573faecdcSXuan Hu wdata : Seq[UInt], 216730cfbc0SXuan Hu debugReadAddr: Option[Seq[UInt]], 217730cfbc0SXuan Hu debugReadData: Option[Vec[UInt]], 21873faecdcSXuan Hu withReset : Boolean = false, 219b8ca25cbSxiaofeibao-xjtu bankNum : Int, 220730cfbc0SXuan Hu )(implicit p: Parameters): Unit = { 22173faecdcSXuan Hu Regfile( 222730cfbc0SXuan Hu name, numEntries, raddr, rdata, wen, waddr, wdata, 223b8ca25cbSxiaofeibao-xjtu hasZero = true, withReset, bankNum, debugReadAddr, debugReadData) 22473faecdcSXuan Hu } 22573faecdcSXuan Hu} 22673faecdcSXuan Hu 227771a6ec2Sxiaofeibaoobject IntRegFileSplit { 228771a6ec2Sxiaofeibao // non-return version 229771a6ec2Sxiaofeibao def apply( 230771a6ec2Sxiaofeibao name : String, 231771a6ec2Sxiaofeibao numEntries : Int, 232771a6ec2Sxiaofeibao splitNum : Int, 233771a6ec2Sxiaofeibao raddr : Seq[UInt], 234771a6ec2Sxiaofeibao rdata : Vec[UInt], 235771a6ec2Sxiaofeibao wen : Seq[Bool], 236771a6ec2Sxiaofeibao waddr : Seq[UInt], 237771a6ec2Sxiaofeibao wdata : Seq[UInt], 238771a6ec2Sxiaofeibao debugReadAddr: Option[Seq[UInt]], 239771a6ec2Sxiaofeibao debugReadData: Option[Vec[UInt]], 240771a6ec2Sxiaofeibao withReset : Boolean = false, 241771a6ec2Sxiaofeibao bankNum : Int, 242771a6ec2Sxiaofeibao )(implicit p: Parameters): Unit = { 243771a6ec2Sxiaofeibao require(Seq(1, 2, 4, 8).contains(splitNum)) 244771a6ec2Sxiaofeibao val rdataVec = Wire(Vec(splitNum, Vec(rdata.length, UInt((rdata.head.getWidth / splitNum).W)))) 245771a6ec2Sxiaofeibao rdata.zipWithIndex.map{ case (r, i) => 246771a6ec2Sxiaofeibao r := Cat((0 until splitNum).map(x => rdataVec(x)(i)).reverse) 247771a6ec2Sxiaofeibao } 248771a6ec2Sxiaofeibao val debugReadDataVec = OptionWrapper(debugReadData.nonEmpty, Wire(Vec(splitNum, Vec(debugReadData.get.length, UInt((debugReadData.get.head.getWidth / splitNum).W))))) 249771a6ec2Sxiaofeibao if (debugReadData.nonEmpty) { 250771a6ec2Sxiaofeibao debugReadData.get.zipWithIndex.map { case (r, i) => 251771a6ec2Sxiaofeibao r := Cat((0 until splitNum).map(x => debugReadDataVec.get(x)(i)).reverse) 252771a6ec2Sxiaofeibao } 253771a6ec2Sxiaofeibao } 254771a6ec2Sxiaofeibao for (i <- 0 until splitNum){ 255771a6ec2Sxiaofeibao val wdataThisPart = wdata.map { case x => 256771a6ec2Sxiaofeibao val widthThisPart = x.getWidth / splitNum 257771a6ec2Sxiaofeibao x((i + 1) * widthThisPart - 1, i * widthThisPart) 258771a6ec2Sxiaofeibao } 259771a6ec2Sxiaofeibao val nameSuffix = if (splitNum > 1) s"Part${i}" else "" 260771a6ec2Sxiaofeibao Regfile( 261771a6ec2Sxiaofeibao name + nameSuffix, numEntries, raddr, rdataVec(i), wen, waddr, wdataThisPart, 262771a6ec2Sxiaofeibao hasZero = true, withReset, bankNum, debugReadAddr, OptionWrapper(debugReadData.nonEmpty, debugReadDataVec.get(i))) 263771a6ec2Sxiaofeibao } 264771a6ec2Sxiaofeibao } 265771a6ec2Sxiaofeibao} 266771a6ec2Sxiaofeibao 26760f0c5aeSxiaofeibaoobject FpRegFile { 26860f0c5aeSxiaofeibao // non-return version 26960f0c5aeSxiaofeibao def apply( 27060f0c5aeSxiaofeibao name : String, 27160f0c5aeSxiaofeibao numEntries : Int, 27260f0c5aeSxiaofeibao raddr : Seq[UInt], 27360f0c5aeSxiaofeibao rdata : Vec[UInt], 27460f0c5aeSxiaofeibao wen : Seq[Bool], 27560f0c5aeSxiaofeibao waddr : Seq[UInt], 27660f0c5aeSxiaofeibao wdata : Seq[UInt], 27760f0c5aeSxiaofeibao debugReadAddr: Option[Seq[UInt]], 27860f0c5aeSxiaofeibao debugReadData: Option[Vec[UInt]], 27960f0c5aeSxiaofeibao withReset : Boolean = false, 28060f0c5aeSxiaofeibao bankNum : Int, 28160052a3fSxiaofeibao isVlRegfile : Boolean = false, 28260f0c5aeSxiaofeibao )(implicit p: Parameters): Unit = { 28360f0c5aeSxiaofeibao Regfile( 28460f0c5aeSxiaofeibao name, numEntries, raddr, rdata, wen, waddr, wdata, 28560052a3fSxiaofeibao hasZero = false, withReset, bankNum, debugReadAddr, debugReadData, isVlRegfile) 28660f0c5aeSxiaofeibao } 28760f0c5aeSxiaofeibao} 28860f0c5aeSxiaofeibao 289*748214a1Sxiaofeibaoobject FpRegFileSplit { 290*748214a1Sxiaofeibao // non-return version 291*748214a1Sxiaofeibao def apply( 292*748214a1Sxiaofeibao name : String, 293*748214a1Sxiaofeibao numEntries : Int, 294*748214a1Sxiaofeibao splitNum : Int, 295*748214a1Sxiaofeibao raddr : Seq[UInt], 296*748214a1Sxiaofeibao rdata : Vec[UInt], 297*748214a1Sxiaofeibao wen : Seq[Bool], 298*748214a1Sxiaofeibao waddr : Seq[UInt], 299*748214a1Sxiaofeibao wdata : Seq[UInt], 300*748214a1Sxiaofeibao debugReadAddr: Option[Seq[UInt]], 301*748214a1Sxiaofeibao debugReadData: Option[Vec[UInt]], 302*748214a1Sxiaofeibao withReset : Boolean = false, 303*748214a1Sxiaofeibao bankNum : Int, 304*748214a1Sxiaofeibao isVlRegfile : Boolean = false, 305*748214a1Sxiaofeibao )(implicit p: Parameters): Unit = { 306*748214a1Sxiaofeibao require(Seq(1, 2, 4, 8).contains(splitNum)) 307*748214a1Sxiaofeibao val rdataVec = Wire(Vec(splitNum, Vec(rdata.length, UInt((rdata.head.getWidth / splitNum).W)))) 308*748214a1Sxiaofeibao rdata.zipWithIndex.map{ case (r, i) => 309*748214a1Sxiaofeibao r := Cat((0 until splitNum).map(x => rdataVec(x)(i)).reverse) 310*748214a1Sxiaofeibao } 311*748214a1Sxiaofeibao val debugReadDataVec = OptionWrapper(debugReadData.nonEmpty, Wire(Vec(splitNum, Vec(debugReadData.get.length, UInt((debugReadData.get.head.getWidth / splitNum).W))))) 312*748214a1Sxiaofeibao if (debugReadData.nonEmpty) { 313*748214a1Sxiaofeibao debugReadData.get.zipWithIndex.map { case (r, i) => 314*748214a1Sxiaofeibao r := Cat((0 until splitNum).map(x => debugReadDataVec.get(x)(i)).reverse) 315*748214a1Sxiaofeibao } 316*748214a1Sxiaofeibao } 317*748214a1Sxiaofeibao for (i <- 0 until splitNum){ 318*748214a1Sxiaofeibao val wdataThisPart = wdata.map { case x => 319*748214a1Sxiaofeibao val widthThisPart = x.getWidth / splitNum 320*748214a1Sxiaofeibao x((i + 1) * widthThisPart - 1, i * widthThisPart) 321*748214a1Sxiaofeibao } 322*748214a1Sxiaofeibao val nameSuffix = if (splitNum > 1) s"Part${i}" else "" 323*748214a1Sxiaofeibao Regfile( 324*748214a1Sxiaofeibao name + nameSuffix, numEntries, raddr, rdataVec(i), wen, waddr, wdataThisPart, 325*748214a1Sxiaofeibao hasZero = false, withReset, bankNum, debugReadAddr, OptionWrapper(debugReadData.nonEmpty, debugReadDataVec.get(i)), isVlRegfile) 326*748214a1Sxiaofeibao } 327*748214a1Sxiaofeibao } 328*748214a1Sxiaofeibao} 329*748214a1Sxiaofeibao 33073faecdcSXuan Huobject VfRegFile { 331730cfbc0SXuan Hu // non-return version 33273faecdcSXuan Hu def apply( 333a1ca6e15SZhangZifei name : String, 33473faecdcSXuan Hu numEntries : Int, 33573faecdcSXuan Hu splitNum : Int, 33673faecdcSXuan Hu raddr : Seq[UInt], 337730cfbc0SXuan Hu rdata : Vec[UInt], 33873faecdcSXuan Hu wen : Seq[Seq[Bool]], 33973faecdcSXuan Hu waddr : Seq[UInt], 34073faecdcSXuan Hu wdata : Seq[UInt], 341730cfbc0SXuan Hu debugReadAddr: Option[Seq[UInt]], 342730cfbc0SXuan Hu debugReadData: Option[Vec[UInt]], 34373faecdcSXuan Hu withReset : Boolean = false, 344730cfbc0SXuan Hu )(implicit p: Parameters): Unit = { 34573faecdcSXuan Hu require(splitNum >= 1, "splitNum should be no less than 1") 34673faecdcSXuan Hu require(splitNum == wen.length, "splitNum should be equal to length of wen vec") 34773faecdcSXuan Hu if (splitNum == 1) { 348730cfbc0SXuan Hu Regfile( 349730cfbc0SXuan Hu name, numEntries, raddr, rdata, wen.head, waddr, wdata, 350b8ca25cbSxiaofeibao-xjtu hasZero = false, withReset, bankNum = 1, debugReadAddr, debugReadData) 351761d728dSZhangZifei } else { 352*748214a1Sxiaofeibao val dataWidth = wdata.head.getWidth / splitNum 353730cfbc0SXuan Hu val numReadPorts = raddr.length 35473faecdcSXuan Hu require(splitNum > 1 && wdata.head.getWidth == dataWidth * splitNum) 35573faecdcSXuan Hu val wdataVec = Wire(Vec(splitNum, Vec(wdata.length, UInt(dataWidth.W)))) 356730cfbc0SXuan Hu val rdataVec = Wire(Vec(splitNum, Vec(raddr.length, UInt(dataWidth.W)))) 357730cfbc0SXuan Hu val debugRDataVec: Option[Vec[Vec[UInt]]] = debugReadData.map(x => Wire(Vec(splitNum, Vec(x.length, UInt(dataWidth.W))))) 35873faecdcSXuan Hu for (i <- 0 until splitNum) { 35973faecdcSXuan Hu wdataVec(i) := wdata.map(_ ((i + 1) * dataWidth - 1, i * dataWidth)) 360730cfbc0SXuan Hu Regfile( 361730cfbc0SXuan Hu name + s"Part${i}", numEntries, raddr, rdataVec(i), wen(i), waddr, wdataVec(i), 362b8ca25cbSxiaofeibao-xjtu hasZero = false, withReset, bankNum = 1, debugReadAddr, debugRDataVec.map(_(i)) 363730cfbc0SXuan Hu ) 36473faecdcSXuan Hu } 36573faecdcSXuan Hu for (i <- 0 until rdata.length) { 366761d728dSZhangZifei rdata(i) := Cat(rdataVec.map(_ (i)).reverse) 36773faecdcSXuan Hu } 368730cfbc0SXuan Hu if (debugReadData.nonEmpty) { 369730cfbc0SXuan Hu for (i <- 0 until debugReadData.get.length) { 370730cfbc0SXuan Hu debugReadData.get(i) := Cat(debugRDataVec.get.map(_ (i)).reverse) 371730cfbc0SXuan Hu } 372730cfbc0SXuan Hu } 37373faecdcSXuan Hu } 374761d728dSZhangZifei } 37573faecdcSXuan Hu}