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.exu 18 19 20import chipsalliance.rocketchip.config.Parameters 21import chisel3._ 22import chisel3.experimental.hierarchy.{Definition, instantiable, public} 23import chisel3.util._ 24import utils._ 25import utility._ 26import xiangshan._ 27import xiangshan.backend.fu.fpu.{FMA, FPUSubModule} 28import xiangshan.backend.fu.{CSR, FUWithRedirect, Fence, FenceToSbuffer} 29import xiangshan.backend.fu.vector.{VFPU, VPPU, VPUSubModule} 30 31class FenceIO(implicit p: Parameters) extends XSBundle { 32 val sfence = Output(new SfenceBundle) 33 val fencei = Output(Bool()) 34 val sbuffer = new FenceToSbuffer 35} 36 37@instantiable 38class ExeUnit(config: ExuConfig)(implicit p: Parameters) extends Exu(config) { 39 40 val disableSfence = WireInit(false.B) 41 val csr_frm = WireInit(frm.getOrElse(0.U(3.W))) 42 val csr_vxrm = WireInit(vxrm.getOrElse(0.U(2.W))) 43 val csr_vstart = WireInit(vstart.getOrElse(0.U(XLEN.W))) 44 45 val hasRedirect = config.fuConfigs.zip(functionUnits).filter(_._1.hasRedirect).map(_._2) 46 println(s"ExeUnit: ${functionUnits.map(_.name).reduce(_ + " " + _)} ${hasRedirect} hasRedirect: ${hasRedirect.length}") 47 if (hasRedirect.nonEmpty) { 48 require(hasRedirect.length <= 1) 49 io.out.bits.redirectValid := hasRedirect.head.asInstanceOf[FUWithRedirect].redirectOutValid 50 io.out.bits.redirect := hasRedirect.head.asInstanceOf[FUWithRedirect].redirectOut 51 } 52 53 if (config.fuConfigs.contains(csrCfg)) { 54 val csr = functionUnits.collectFirst{ 55 case c: CSR => c 56 }.get 57 csr.csrio <> csrio.get 58 csrio.get.tlb := DelayN(csr.csrio.tlb, 2) 59 csrio.get.customCtrl := DelayN(csr.csrio.customCtrl, 2) 60 csrio.get.trapTarget := RegNext(csr.csrio.trapTarget) 61 csr.csrio.exception := DelayN(csrio.get.exception, 2) 62 disableSfence := csr.csrio.disableSfence 63 // setup skip for hpm CSR read 64 io.out.bits.debug.isPerfCnt := RegNext(csr.csrio.isPerfCnt) // TODO: this is dirty 65 } 66 67 if (config.fuConfigs.contains(fenceCfg)) { 68 val fence = functionUnits.collectFirst{ 69 case f: Fence => f 70 }.get 71 fenceio.get.sfence <> fence.sfence 72 fenceio.get.fencei <> fence.fencei 73 fenceio.get.sbuffer <> fence.toSbuffer 74 fence.io.out.ready := true.B 75 fence.disableSfence := disableSfence 76 } 77 78 val fpModules = functionUnits.zip(config.fuConfigs.zipWithIndex).filter(_._1.isInstanceOf[FPUSubModule]) 79 val vfpModules = functionUnits.zip(config.fuConfigs.zipWithIndex).filter(_._1.isInstanceOf[VFPU]) 80 val vipuModules = functionUnits.zip(config.fuConfigs.zipWithIndex).filter(x => x._1.isInstanceOf[VPUSubModule]) 81 if (fpModules.nonEmpty) { 82 // frm is from csr/frm (from CSR) or instr_rm (from instruction decoding) 83 val fpSubModules = fpModules.map(_._1.asInstanceOf[FPUSubModule]) 84 fpSubModules.foreach(mod => { 85 val instr_rm = mod.io.in.bits.uop.ctrl.fpu.rm 86 mod.rm := Mux(instr_rm =/= 7.U, instr_rm, csr_frm) 87 }) 88 // fflags is selected by arbSelReg 89 require(config.hasFastUopOut, "non-fast not implemented") 90 val fflagsSel = fpModules.map{ case (fu, (cfg, i)) => 91 val fflagsValid = arbSelReg(i) 92 val fflags = fu.asInstanceOf[FPUSubModule].fflags 93 val fflagsBits = if (cfg.fastImplemented) fflags else RegNext(fflags) 94 (fflagsValid, fflagsBits) 95 } 96 io.out.bits.fflags := Mux1H(fflagsSel.map(_._1), fflagsSel.map(_._2)) 97 } 98 // Overwrite write operation of fpModules 99 if (vfpModules.nonEmpty) { 100 val vfpSubModules = vfpModules.map(_._1.asInstanceOf[VFPU]) 101 vfpSubModules.foreach(mod => { 102 mod.rm := csr_frm 103 }) 104 } 105 if (vipuModules.nonEmpty) { 106 vipuModules.map(_._1.asInstanceOf[VPUSubModule]).foreach(mod => { 107 mod.vxrm := csr_vxrm 108 mod.vstart := csr_vstart 109 io.out.bits.vxsat := mod.vxsat 110 }) 111 } 112 val fmaModules = functionUnits.filter(_.isInstanceOf[FMA]).map(_.asInstanceOf[FMA]) 113 if (fmaModules.nonEmpty) { 114 require(fmaModules.length == 1) 115 } 116 117 if (config.readIntRf) { 118 val in = io.fromInt 119 val out = io.out 120 XSDebug(in.valid, p"fromInt(${in.valid} ${in.ready}) toInt(${out.valid} ${out.ready})\n") 121 XSDebug(io.redirect.valid, p"Redirect:(${io.redirect.valid}) robIdx:${io.redirect.bits.robIdx}\n") 122 XSDebug(in.valid, p"src1:${Hexadecimal(in.bits.src(0))} src2:${Hexadecimal(in.bits.src(1))} " + 123 p"func:${Binary(in.bits.uop.ctrl.fuOpType)} pc:${Hexadecimal(in.bits.uop.cf.pc)} robIdx:${in.bits.uop.robIdx}\n") 124 XSDebug(out.valid, p"out res:${Hexadecimal(out.bits.data)} robIdx:${out.bits.uop.robIdx}\n") 125 } 126 127} 128 129class AluExeUnit(implicit p: Parameters) extends ExeUnit(AluExeUnitCfg) 130class JumpCSRExeUnit(implicit p: Parameters) extends ExeUnit(JumpCSRExeUnitCfg) 131class JumpExeUnit(implicit p: Parameters) extends ExeUnit(JumpExeUnitCfg) 132class StdExeUnit(implicit p: Parameters) extends ExeUnit(StdExeUnitCfg) 133class FmacExeUnit(implicit p: Parameters) extends ExeUnit(FmacExeUnitCfg) 134class FmiscExeUnit(implicit p: Parameters) extends ExeUnit(FmiscExeUnitCfg) 135 136object ExeUnitDef { 137 def apply(cfg: ExuConfig)(implicit p: Parameters): Definition[ExeUnit] = { 138 cfg match { 139 case JumpExeUnitCfg => Definition(new JumpExeUnit) 140 case AluExeUnitCfg => Definition(new AluExeUnit) 141 case MulDivExeUnitCfg => Definition(new MulDivExeUnit) 142 case JumpCSRExeUnitCfg => Definition(new JumpCSRExeUnit) 143 case FmacExeUnitCfg => Definition(new FmacExeUnit) 144 case FmiscExeUnitCfg => Definition(new FmiscExeUnit) 145 case _ => { 146 println(s"cannot generate exeUnit from $cfg") 147 null 148 } 149 } 150 } 151} 152 153