1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* 4* XiangShan is licensed under Mulan PSL v2. 5* You can use this software according to the terms and conditions of the Mulan PSL v2. 6* You may obtain a copy of Mulan PSL v2 at: 7* http://license.coscl.org.cn/MulanPSL2 8* 9* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12* 13* See the Mulan PSL v2 for more details. 14***************************************************************************************/ 15 16package xiangshan.backend.issue 17 18import chipsalliance.rocketchip.config.Parameters 19import chisel3._ 20import chisel3.util._ 21import xiangshan._ 22import utils._ 23import xiangshan.backend.decode.{ImmUnion, Imm_U} 24import xiangshan.backend.exu.ExuConfig 25 26class DataArrayReadIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle { 27 val addr = Input(UInt(numEntries.W)) 28 val data = Vec(numSrc, Output(UInt(dataBits.W))) 29 30 override def cloneType: DataArrayReadIO.this.type = 31 new DataArrayReadIO(numEntries, numSrc, dataBits).asInstanceOf[this.type] 32} 33 34class DataArrayWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle { 35 val enable = Input(Bool()) 36 val mask = Vec(numSrc, Input(Bool())) 37 val addr = Input(UInt(numEntries.W)) 38 val data = Vec(numSrc, Input(UInt(dataBits.W))) 39 40 override def cloneType: DataArrayWriteIO.this.type = 41 new DataArrayWriteIO(numEntries, numSrc, dataBits).asInstanceOf[this.type] 42} 43 44class DataArrayMultiWriteIO(numEntries: Int, numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSBundle { 45 val enable = Input(Bool()) 46 val addr = Vec(numSrc, Input(UInt(numEntries.W))) 47 val data = Input(UInt(dataBits.W)) 48 49 override def cloneType: DataArrayMultiWriteIO.this.type = 50 new DataArrayMultiWriteIO(numEntries, numSrc, dataBits).asInstanceOf[this.type] 51} 52 53class DataArrayIO(params: RSParams)(implicit p: Parameters) extends XSBundle { 54 val read = Vec(params.numDeq, new DataArrayReadIO(params.numEntries, params.numSrc, params.dataBits)) 55 val write = Vec(params.numEnq, new DataArrayWriteIO(params.numEntries, params.numSrc, params.dataBits)) 56 val multiWrite = Vec(params.numWakeup, new DataArrayMultiWriteIO(params.numEntries, params.numSrc, params.dataBits)) 57 val delayedWrite = if (params.delayedRf) Vec(params.numEnq, Flipped(ValidIO(UInt(params.dataBits.W)))) else null 58 59 override def cloneType: DataArrayIO.this.type = 60 new DataArrayIO(params).asInstanceOf[this.type] 61} 62 63class DataArray(params: RSParams)(implicit p: Parameters) extends XSModule { 64 val io = IO(new DataArrayIO(params)) 65 66 for (i <- 0 until params.numSrc) { 67 val delayedWen = if (i == 1 && params.delayedRf) io.delayedWrite.map(_.valid) else Seq() 68 val delayedWaddr = if (i == 1 && params.delayedRf) RegNext(VecInit(io.write.map(_.addr))) else Seq() 69 val delayedWdata = if (i == 1 && params.delayedRf) io.delayedWrite.map(_.bits) else Seq() 70 71 val wen = io.write.map(w => w.enable && w.mask(i)) ++ io.multiWrite.map(_.enable) ++ delayedWen 72 val waddr = io.write.map(_.addr) ++ io.multiWrite.map(_.addr(i)) ++ delayedWaddr 73 val wdata = io.write.map(_.data(i)) ++ io.multiWrite.map(_.data) ++ delayedWdata 74 75 val dataModule = Module(new AsyncRawDataModuleTemplate(UInt(params.dataBits.W), params.numEntries, io.read.length, wen.length)) 76 dataModule.io.rvec := VecInit(io.read.map(_.addr)) 77 io.read.map(_.data(i)).zip(dataModule.io.rdata).map{ case (d, r) => d := r } 78 dataModule.io.wen := wen 79 dataModule.io.wvec := waddr 80 dataModule.io.wdata := wdata 81 } 82 83} 84 85class ImmExtractor(numSrc: Int, dataBits: Int)(implicit p: Parameters) extends XSModule { 86 val io = IO(new Bundle { 87 val uop = Input(new MicroOp) 88 val data_in = Vec(numSrc, Input(UInt(dataBits.W))) 89 val data_out = Vec(numSrc, Output(UInt(dataBits.W))) 90 }) 91 io.data_out := io.data_in 92} 93 94class JumpImmExtractor(implicit p: Parameters) extends ImmExtractor(2, 64) { 95 val jump_pc = IO(Input(UInt(VAddrBits.W))) 96 val jalr_target = IO(Input(UInt(VAddrBits.W))) 97 98 when (SrcType.isPc(io.uop.ctrl.srcType(0))) { 99 io.data_out(0) := SignExt(jump_pc, XLEN) 100 } 101 io.data_out(1) := jalr_target 102} 103 104class AluImmExtractor(implicit p: Parameters) extends ImmExtractor(2, 64) { 105 when (SrcType.isImm(io.uop.ctrl.srcType(1))) { 106 val imm32 = Mux(io.uop.ctrl.selImm === SelImm.IMM_U, 107 ImmUnion.U.toImm32(io.uop.ctrl.imm), 108 ImmUnion.I.toImm32(io.uop.ctrl.imm) 109 ) 110 io.data_out(1) := SignExt(imm32, XLEN) 111 } 112} 113 114object ImmExtractor { 115 def apply(params: RSParams, uop: MicroOp, data_in: Vec[UInt], pc: Option[UInt], target: Option[UInt]) 116 (implicit p: Parameters): Vec[UInt] = { 117 val immExt = (params.isJump, params.isAlu) match { 118 case (true, false) => { 119 val ext = Module(new JumpImmExtractor) 120 ext.jump_pc := pc.get 121 ext.jalr_target := target.get 122 ext 123 } 124 case (false, true) => Module(new AluImmExtractor) 125 case _ => Module(new ImmExtractor(params.numSrc, params.dataBits)) 126 } 127 immExt.io.uop := uop 128 immExt.io.data_in := data_in 129 immExt.io.data_out 130 } 131} 132