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.util._ 23import utils.{XSDebug, XSPerfAccumulate} 24import xiangshan._ 25import xiangshan.backend.Std 26import xiangshan.backend.fu.fpu.FPUSubModule 27import xiangshan.backend.fu.{CSR, FUWithRedirect, Fence, FenceToSbuffer} 28 29class FenceIO(implicit p: Parameters) extends XSBundle { 30 val sfence = Output(new SfenceBundle) 31 val fencei = Output(Bool()) 32 val sbuffer = new FenceToSbuffer 33} 34 35class ExeUnit(config: ExuConfig)(implicit p: Parameters) extends Exu(config: ExuConfig) { 36 val disableSfence = WireInit(false.B) 37 val csr_frm = WireInit(frm.getOrElse(0.U(3.W))) 38 39 val hasRedirect = config.fuConfigs.zip(functionUnits).filter(_._1.hasRedirect).map(_._2) 40 println(s"${functionUnits} ${hasRedirect} hasRedirect: ${hasRedirect.length}") 41 if (hasRedirect.nonEmpty) { 42 require(hasRedirect.length <= 1) 43 io.out.bits.redirectValid := hasRedirect.head.asInstanceOf[FUWithRedirect].redirectOutValid 44 io.out.bits.redirect := hasRedirect.head.asInstanceOf[FUWithRedirect].redirectOut 45 } 46 47 if (config.fuConfigs.contains(csrCfg)) { 48 val csr = functionUnits.collectFirst{ 49 case c: CSR => c 50 }.get 51 csr.csrio <> csrio.get 52 disableSfence := csr.csrio.disableSfence 53 csr_frm := csr.csrio.fpu.frm 54 } 55 56 if (config.fuConfigs.contains(fenceCfg)) { 57 val fence = functionUnits.collectFirst{ 58 case f: Fence => f 59 }.get 60 fenceio.get.sfence <> fence.sfence 61 fenceio.get.fencei <> fence.fencei 62 fenceio.get.sbuffer <> fence.toSbuffer 63 fence.io.out.ready := true.B 64 fence.disableSfence := disableSfence 65 } 66 67 val fpModules = functionUnits.zip(config.fuConfigs.zipWithIndex).filter(_._1.isInstanceOf[FPUSubModule]) 68 if (fpModules.nonEmpty) { 69 // frm is from csr/frm (from CSR) or instr_rm (from instruction decoding) 70 val fpSubModules = fpModules.map(_._1.asInstanceOf[FPUSubModule]) 71 fpSubModules.foreach(mod => { 72 val instr_rm = mod.io.in.bits.uop.ctrl.fpu.rm 73 mod.rm := Mux(instr_rm =/= 7.U, instr_rm, csr_frm) 74 }) 75 // fflags is selected by arbSelReg 76 require(config.hasFastUopOut, "non-fast not implemented") 77 val fflagsSel = fpModules.map{ case (fu, (cfg, i)) => 78 val fflagsValid = arbSelReg(i) 79 val fflags = fu.asInstanceOf[FPUSubModule].fflags 80 val fflagsBits = if (cfg.fastImplemented) fflags else RegNext(fflags) 81 (fflagsValid, fflagsBits) 82 } 83 io.out.bits.fflags := Mux1H(fflagsSel.map(_._1), fflagsSel.map(_._2)) 84 } 85 86 if (config.fuConfigs.contains(stdCfg)) { 87 val std = functionUnits.collectFirst { 88 case s: Std => s 89 }.get 90 stData.get.valid := std.io.out.valid 91 stData.get.bits.uop := std.io.out.bits.uop 92 stData.get.bits.data := std.io.out.bits.data 93 io.out.valid := false.B 94 io.out.bits := DontCare 95 } 96 if (config.readIntRf) { 97 val in = io.fromInt 98 val out = io.out 99 XSDebug(in.valid, p"fromInt(${in.valid} ${in.ready}) toInt(${out.valid} ${out.ready})\n") 100 XSDebug(io.redirect.valid, p"Redirect:(${io.redirect.valid}) roqIdx:${io.redirect.bits.roqIdx}\n") 101 XSDebug(in.valid, p"src1:${Hexadecimal(in.bits.src(0))} src2:${Hexadecimal(in.bits.src(1))} " + 102 p"func:${Binary(in.bits.uop.ctrl.fuOpType)} pc:${Hexadecimal(in.bits.uop.cf.pc)} roqIdx:${in.bits.uop.roqIdx}\n") 103 XSDebug(out.valid, p"out res:${Hexadecimal(out.bits.data)} roqIdx:${out.bits.uop.roqIdx}\n") 104 } 105 106} 107 108class AluExeUnit(implicit p: Parameters) extends ExeUnit(AluExeUnitCfg) 109class JumpCSRExeUnit(implicit p: Parameters) extends ExeUnit(JumpCSRExeUnitCfg) 110class JumpExeUnit(implicit p: Parameters) extends ExeUnit(JumpExeUnitCfg) 111class StdExeUnit(implicit p: Parameters) extends ExeUnit(StdExeUnitCfg) 112class FmacExeUnit(implicit p: Parameters) extends ExeUnit(FmacExeUnitCfg) 113class FmiscExeUnit(implicit p: Parameters) extends ExeUnit(FmiscExeUnitCfg) 114 115object ExeUnit { 116 def apply(cfg: ExuConfig)(implicit p: Parameters): ExeUnit = { 117 cfg match { 118 case JumpExeUnitCfg => Module(new JumpExeUnit) 119 case AluExeUnitCfg => Module(new AluExeUnit) 120 case MulDivExeUnitCfg => Module(new MulDivExeUnit) 121 case JumpCSRExeUnitCfg => Module(new JumpCSRExeUnit) 122 case FmacExeUnitCfg => Module(new FmacExeUnit) 123 case FmiscExeUnitCfg => Module(new FmiscExeUnit) 124 case StdExeUnitCfg => Module(new StdExeUnit) 125 case _ => { 126 println(s"cannot generate exeUnit from $cfg") 127 null 128 } 129 } 130 } 131} 132 133