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