xref: /XiangShan/src/main/scala/xiangshan/backend/exu/ExeUnit.scala (revision a1ea7f76add43b40af78084f7f646a0010120cd7)
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