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.backend.issue 18 19import chipsalliance.rocketchip.config.Parameters 20import chisel3._ 21import chisel3.util._ 22import xiangshan._ 23import utils._ 24import xiangshan.backend.decode.{ImmUnion, Imm_U} 25import xiangshan.backend.exu.ExuConfig 26 27class DataArrayReadIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle { 28 val addr = Input(UInt(numEntries.W)) 29 val data = Vec(numSrc, Output(UInt(dataBits.W))) 30 31 override def cloneType: DataArrayReadIO.this.type = 32 new DataArrayReadIO(numEntries, numSrc, dataBits).asInstanceOf[this.type] 33} 34 35class DataArrayWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle { 36 val enable = Input(Bool()) 37 val mask = Vec(numSrc, Input(Bool())) 38 val addr = Input(UInt(numEntries.W)) 39 val data = Vec(numSrc, Input(UInt(dataBits.W))) 40 41 override def cloneType: DataArrayWriteIO.this.type = 42 new DataArrayWriteIO(numEntries, numSrc, dataBits).asInstanceOf[this.type] 43} 44 45class DataArrayMultiWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle { 46 val enable = Input(Bool()) 47 val addr = Vec(numSrc, Input(UInt(numEntries.W))) 48 val data = Input(UInt(dataBits.W)) 49 50 override def cloneType: DataArrayMultiWriteIO.this.type = 51 new DataArrayMultiWriteIO(numEntries, numSrc, dataBits).asInstanceOf[this.type] 52} 53 54class DataArrayIO(params: RSParams)(implicit p: Parameters) extends XSBundle { 55 val read = Vec(params.numDeq + 1, new DataArrayReadIO(params.numEntries, params.numSrc, params.dataBits)) 56 val write = Vec(params.numEnq, new DataArrayWriteIO(params.numEntries, params.numSrc, params.dataBits)) 57 val multiWrite = Vec(params.numWakeup, new DataArrayMultiWriteIO(params.numEntries, params.numSrc, params.dataBits)) 58 val delayedWrite = if (params.delayedRf) Vec(params.numEnq, Flipped(ValidIO(UInt(params.dataBits.W)))) else null 59 val partialWrite = if (params.hasMidState) Vec(params.numDeq, new DataArrayWriteIO(params.numEntries, params.numSrc - 1, params.dataBits)) else null 60 61 override def cloneType: DataArrayIO.this.type = 62 new DataArrayIO(params).asInstanceOf[this.type] 63} 64 65class DataArray(params: RSParams)(implicit p: Parameters) extends XSModule { 66 val io = IO(new DataArrayIO(params)) 67 68 for (i <- 0 until params.numSrc) { 69 val delayedWen = if (i == 1 && params.delayedRf) io.delayedWrite.map(_.valid) else Seq() 70 val delayedWaddr = if (i == 1 && params.delayedRf) RegNext(VecInit(io.write.map(_.addr))) else Seq() 71 val delayedWdata = if (i == 1 && params.delayedRf) io.delayedWrite.map(_.bits) else Seq() 72 73 val partialWen = if (i < 2 && params.hasMidState) io.partialWrite.map(_.enable) else Seq() 74 val partialWaddr = if (i < 2 && params.hasMidState) io.partialWrite.map(_.addr) else Seq() 75 val partialWdata = if (i < 2 && params.hasMidState) io.partialWrite.map(_.data(i)) else Seq() 76 77 val wen = io.write.map(w => w.enable && w.mask(i)) ++ io.multiWrite.map(_.enable) ++ delayedWen ++ partialWen 78 val waddr = io.write.map(_.addr) ++ io.multiWrite.map(_.addr(i)) ++ delayedWaddr ++ partialWaddr 79 val wdata = io.write.map(_.data(i)) ++ io.multiWrite.map(_.data) ++ delayedWdata ++ partialWdata 80 81 val dataModule = Module(new SyncRawDataModuleTemplate(UInt(params.dataBits.W), params.numEntries, io.read.length, wen.length)) 82 dataModule.io.rvec := VecInit(io.read.map(_.addr)) 83 io.read.map(_.data(i)).zip(dataModule.io.rdata).foreach{ case (d, r) => d := r } 84 dataModule.io.wen := wen 85 dataModule.io.wvec := waddr 86 dataModule.io.wdata := wdata 87 for (i <- 0 until params.numEntries) { 88 val w = VecInit(wen.indices.map(j => dataModule.io.wen(j) && dataModule.io.wvec(j)(i))) 89 assert(RegNext(PopCount(w) <= 1.U)) 90 when(PopCount(w) > 1.U) { 91 XSDebug("ERROR: RS DataArray write overlap!\n") 92 } 93 } 94 } 95 96} 97 98class ImmExtractor(numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSModule { 99 val io = IO(new Bundle { 100 val uop = Input(new MicroOp) 101 val data_in = Vec(numSrc, Input(UInt(dataBits.W))) 102 val data_out = Vec(numSrc, Output(UInt(dataBits.W))) 103 }) 104 io.data_out := io.data_in 105} 106 107class JumpImmExtractor(implicit p: Parameters) extends ImmExtractor(2, 64) { 108 val jump_pc = IO(Input(UInt(VAddrBits.W))) 109 val jalr_target = IO(Input(UInt(VAddrBits.W))) 110 111 when (SrcType.isPc(io.uop.ctrl.srcType(0))) { 112 io.data_out(0) := SignExt(jump_pc, XLEN) 113 } 114 io.data_out(1) := jalr_target 115} 116 117class AluImmExtractor(implicit p: Parameters) extends ImmExtractor(2, 64) { 118 when (SrcType.isImm(io.uop.ctrl.srcType(1))) { 119 val imm32 = Mux(io.uop.ctrl.selImm === SelImm.IMM_U, 120 ImmUnion.U.toImm32(io.uop.ctrl.imm), 121 ImmUnion.I.toImm32(io.uop.ctrl.imm) 122 ) 123 io.data_out(1) := SignExt(imm32, XLEN) 124 } 125} 126 127object ImmExtractor { 128 def apply(params: RSParams, uop: MicroOp, data_in: Vec[UInt], pc: Option[UInt], target: Option[UInt]) 129 (implicit p: Parameters): Vec[UInt] = { 130 val immExt = (params.isJump, params.isAlu) match { 131 case (true, false) => { 132 val ext = Module(new JumpImmExtractor) 133 ext.jump_pc := pc.get 134 ext.jalr_target := target.get 135 ext 136 } 137 case (false, true) => Module(new AluImmExtractor) 138 case _ => Module(new ImmExtractor(params.numSrc, params.dataBits)) 139 } 140 immExt.io.uop := uop 141 immExt.io.data_in := data_in 142 immExt.io.data_out 143 } 144} 145