xref: /XiangShan/src/main/scala/xiangshan/backend/fu/FuncUnit.scala (revision 1592abd11eecf7bec0f1453ffe4a7617167f8ba9)
1730cfbc0SXuan Hupackage xiangshan.backend.fu
2730cfbc0SXuan Hu
383ba63b3SXuan Huimport org.chipsalliance.cde.config.Parameters
4730cfbc0SXuan Huimport chisel3._
5730cfbc0SXuan Huimport chisel3.util._
685a8d7caSZehao Liuimport utility._
76a35d972SXuan Huimport utils.OptionWrapper
8730cfbc0SXuan Huimport xiangshan._
9b6b11f60SXuan Huimport xiangshan.backend.Bundles.VPUCtrlSignals
10730cfbc0SXuan Huimport xiangshan.backend.rob.RobPtr
11730cfbc0SXuan Huimport xiangshan.frontend.{FtqPtr, PreDecodeInfo}
12730cfbc0SXuan Huimport xiangshan.backend.datapath.DataConfig._
13b6b11f60SXuan Huimport xiangshan.backend.fu.vector.Bundles.Vxsat
149a46f19dSsinsanctionimport xiangshan.ExceptionNO.illegalInstr
157e4f0b19SZiyue-Zhangimport xiangshan.backend.fu.vector.Bundles.VType
1615ed99a7SXuan Huimport xiangshan.backend.fu.wrapper.{CSRInput, CSRToDecode}
17730cfbc0SXuan Hu
186a35d972SXuan Huclass FuncUnitCtrlInput(cfg: FuConfig)(implicit p: Parameters) extends XSBundle {
19730cfbc0SXuan Hu  val fuOpType    = FuOpType()
20730cfbc0SXuan Hu  val robIdx      = new RobPtr
21730cfbc0SXuan Hu  val pdest       = UInt(PhyRegIdxWidth.W)
225edcc45fSHaojin Tang  val rfWen       = OptionWrapper(cfg.needIntWen, Bool())
235edcc45fSHaojin Tang  val fpWen       = OptionWrapper(cfg.needFpWen,  Bool())
245edcc45fSHaojin Tang  val vecWen      = OptionWrapper(cfg.needVecWen, Bool())
25db7becb6Sxiaofeibao  val v0Wen       = OptionWrapper(cfg.needV0Wen, Bool())
26db7becb6Sxiaofeibao  val vlWen       = OptionWrapper(cfg.needVlWen, Bool())
276a35d972SXuan Hu  val flushPipe   = OptionWrapper(cfg.flushPipe,  Bool())
286a35d972SXuan Hu  val preDecode   = OptionWrapper(cfg.hasPredecode, new PreDecodeInfo)
29dcdd1406SXuan Hu  val ftqIdx      = OptionWrapper(cfg.needPc || cfg.replayInst || cfg.isSta || cfg.isCsr, new FtqPtr)
30dcdd1406SXuan Hu  val ftqOffset   = OptionWrapper(cfg.needPc || cfg.replayInst || cfg.isSta || cfg.isCsr, UInt(log2Up(PredictWidth).W))
31dcdd1406SXuan Hu  val predictInfo = OptionWrapper(cfg.needPdInfo, new Bundle {
32730cfbc0SXuan Hu    val target    = UInt(VAddrData().dataWidth.W)
33730cfbc0SXuan Hu    val taken     = Bool()
346a35d972SXuan Hu  })
353bc74e23SzhanglyGit  val fpu         = OptionWrapper(cfg.writeFflags, new FPUCtrlSignals)
36b6b11f60SXuan Hu  val vpu         = OptionWrapper(cfg.needVecCtrl, new VPUCtrlSignals)
376a35d972SXuan Hu}
386a35d972SXuan Hu
396a35d972SXuan Huclass FuncUnitCtrlOutput(cfg: FuConfig)(implicit p: Parameters) extends XSBundle {
406a35d972SXuan Hu  val robIdx        = new RobPtr
416a35d972SXuan Hu  val pdest         = UInt(PhyRegIdxWidth.W) // Todo: use maximum of pregIdxWidth of different pregs
425edcc45fSHaojin Tang  val rfWen         = OptionWrapper(cfg.needIntWen, Bool())
435edcc45fSHaojin Tang  val fpWen         = OptionWrapper(cfg.needFpWen,  Bool())
445edcc45fSHaojin Tang  val vecWen        = OptionWrapper(cfg.needVecWen, Bool())
45db7becb6Sxiaofeibao  val v0Wen         = OptionWrapper(cfg.needV0Wen, Bool())
46db7becb6Sxiaofeibao  val vlWen         = OptionWrapper(cfg.needVlWen, Bool())
476a35d972SXuan Hu  val exceptionVec  = OptionWrapper(cfg.exceptionOut.nonEmpty, ExceptionVec())
486a35d972SXuan Hu  val flushPipe     = OptionWrapper(cfg.flushPipe,  Bool())
496a35d972SXuan Hu  val replay        = OptionWrapper(cfg.replayInst, Bool())
506a35d972SXuan Hu  val preDecode     = OptionWrapper(cfg.hasPredecode, new PreDecodeInfo)
513bc74e23SzhanglyGit  val fpu           = OptionWrapper(cfg.writeFflags, new FPUCtrlSignals)
52b6b11f60SXuan Hu  val vpu           = OptionWrapper(cfg.needVecCtrl, new VPUCtrlSignals)
536a35d972SXuan Hu}
546a35d972SXuan Hu
556a35d972SXuan Huclass FuncUnitDataInput(cfg: FuConfig)(implicit p: Parameters) extends XSBundle {
566a35d972SXuan Hu  val src       = MixedVec(cfg.genSrcDataVec)
572d12882cSxiaofeibao  val imm       = UInt(cfg.destDataBits.W)
586a35d972SXuan Hu  val pc        = OptionWrapper(cfg.needPc, UInt(VAddrData().dataWidth.W))
59a2fa0ad9Sxiaofeibao  val nextPcOffset = OptionWrapper(cfg.needPc, UInt((log2Up(PredictWidth) + 1).W))
60b6b11f60SXuan Hu
61b6b11f60SXuan Hu  def getSrcVConfig : UInt = src(cfg.vconfigIdx)
62b6b11f60SXuan Hu  def getSrcMask    : UInt = src(cfg.maskSrcIdx)
636a35d972SXuan Hu}
646a35d972SXuan Hu
656a35d972SXuan Huclass FuncUnitDataOutput(cfg: FuConfig)(implicit p: Parameters) extends XSBundle {
662d12882cSxiaofeibao  val data      = UInt(cfg.destDataBits.W)
6759607684SXuan Hu  val fflags    = OptionWrapper(cfg.writeFflags, UInt(5.W))
68b6b11f60SXuan Hu  val vxsat     = OptionWrapper(cfg.writeVxsat, Vxsat())
696a35d972SXuan Hu  val redirect  = OptionWrapper(cfg.hasRedirect, ValidIO(new Redirect))
706a35d972SXuan Hu}
716a35d972SXuan Hu
726a35d972SXuan Huclass FuncUnitInput(cfg: FuConfig)(implicit p: Parameters) extends XSBundle {
73472967baSxiaofeibao  val needCtrlPipe = cfg.latency.latencyVal.nonEmpty && (!cfg.isStd)
746a35d972SXuan Hu  val ctrl = new FuncUnitCtrlInput(cfg)
75472967baSxiaofeibao  val ctrlPipe = OptionWrapper(needCtrlPipe, Vec(cfg.latency.latencyVal.get + 1, new FuncUnitCtrlInput(cfg)))
76472967baSxiaofeibao  val validPipe = OptionWrapper(needCtrlPipe, Vec(cfg.latency.latencyVal.get + 1, Bool()))
776a35d972SXuan Hu  val data = new FuncUnitDataInput(cfg)
78b67a2036Sxiaofeibao  val dataPipe = OptionWrapper(needCtrlPipe, Vec(cfg.latency.latencyVal.get + 1, new FuncUnitDataInput(cfg)))
7996e858baSXuan Hu  val perfDebugInfo = new PerfDebugInfo()
80*1592abd1SYan Xu  val debug_seqNum = InstSeqNum()
81730cfbc0SXuan Hu}
82730cfbc0SXuan Hu
83730cfbc0SXuan Huclass FuncUnitOutput(cfg: FuConfig)(implicit p: Parameters) extends XSBundle {
846a35d972SXuan Hu  val ctrl = new FuncUnitCtrlOutput(cfg)
856a35d972SXuan Hu  val res = new FuncUnitDataOutput(cfg)
8696e858baSXuan Hu  val perfDebugInfo = new PerfDebugInfo()
87*1592abd1SYan Xu  val debug_seqNum = InstSeqNum()
88730cfbc0SXuan Hu}
89730cfbc0SXuan Hu
90d91483a6Sfdyclass FuncUnitIO(cfg: FuConfig)(implicit p: Parameters) extends XSBundle {
91730cfbc0SXuan Hu  val flush = Flipped(ValidIO(new Redirect))
92730cfbc0SXuan Hu  val in = Flipped(DecoupledIO(new FuncUnitInput(cfg)))
93730cfbc0SXuan Hu  val out = DecoupledIO(new FuncUnitOutput(cfg))
94007f6122SXuan Hu  val csrin = OptionWrapper(cfg.isCsr, new CSRInput)
957e4f0b19SZiyue-Zhang  val csrio = OptionWrapper(cfg.isCsr, new CSRFileIO)
9615ed99a7SXuan Hu  val csrToDecode = OptionWrapper(cfg.isCsr, Output(new CSRToDecode))
977e4f0b19SZiyue-Zhang  val fenceio = OptionWrapper(cfg.isFence, new FenceIO)
987e4f0b19SZiyue-Zhang  val frm = OptionWrapper(cfg.needSrcFrm, Input(UInt(3.W)))
997e4f0b19SZiyue-Zhang  val vxrm = OptionWrapper(cfg.needSrcVxrm, Input(UInt(2.W)))
100b8db7211Sxiaofeibao  val vtype = OptionWrapper(cfg.writeVlRf, (Valid(new VType)))
101b8db7211Sxiaofeibao  val vlIsZero = OptionWrapper(cfg.writeVlRf, Output(Bool()))
102b8db7211Sxiaofeibao  val vlIsVlmax = OptionWrapper(cfg.writeVlRf, Output(Bool()))
103c1b28b66STang Haojin  val instrAddrTransType = Option.when(cfg.isJmp || cfg.isBrh)(Input(new AddrTransType))
104730cfbc0SXuan Hu}
105730cfbc0SXuan Hu
10685a8d7caSZehao Liuabstract class FuncUnit(val cfg: FuConfig)(implicit p: Parameters) extends XSModule with HasCriticalErrors {
107730cfbc0SXuan Hu  val io = IO(new FuncUnitIO(cfg))
108*1592abd1SYan Xu  PerfCCT.updateInstPos(io.in.bits.debug_seqNum, PerfCCT.InstPos.AtFU.id.U, io.in.valid, clock, reset)
109*1592abd1SYan Xu  PerfCCT.updateInstPos(io.out.bits.debug_seqNum, PerfCCT.InstPos.AtBypassVal.id.U, io.out.valid, clock, reset)
11085a8d7caSZehao Liu  val criticalErrors = Seq(("none", false.B))
111730cfbc0SXuan Hu
112730cfbc0SXuan Hu  // should only be used in non-piped fu
113730cfbc0SXuan Hu  def connectNonPipedCtrlSingal: Unit = {
114c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.robIdx := RegEnable(io.in.bits.ctrl.robIdx, io.in.fire)
115c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.pdest  := RegEnable(io.in.bits.ctrl.pdest, io.in.fire)
116c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.rfWen  .foreach(_ := RegEnable(io.in.bits.ctrl.rfWen.get, io.in.fire))
117c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.fpWen  .foreach(_ := RegEnable(io.in.bits.ctrl.fpWen.get, io.in.fire))
118c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.vecWen .foreach(_ := RegEnable(io.in.bits.ctrl.vecWen.get, io.in.fire))
119db7becb6Sxiaofeibao    io.out.bits.ctrl.v0Wen .foreach(_ := RegEnable(io.in.bits.ctrl.v0Wen.get, io.in.fire))
120db7becb6Sxiaofeibao    io.out.bits.ctrl.vlWen .foreach(_ := RegEnable(io.in.bits.ctrl.vlWen.get, io.in.fire))
12178115a00SXuan Hu    // io.out.bits.ctrl.flushPipe should be connected in fu
122c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.preDecode.foreach(_ := RegEnable(io.in.bits.ctrl.preDecode.get, io.in.fire))
123c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.fpu      .foreach(_ := RegEnable(io.in.bits.ctrl.fpu.get, io.in.fire))
124c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.vpu      .foreach(_ := RegEnable(io.in.bits.ctrl.vpu.get, io.in.fire))
125c1e19666Sxiaofeibao-xjtu    io.out.bits.perfDebugInfo := RegEnable(io.in.bits.perfDebugInfo, io.in.fire)
126*1592abd1SYan Xu    io.out.bits.debug_seqNum := RegEnable(io.in.bits.debug_seqNum, io.in.fire)
127c1e19666Sxiaofeibao-xjtu  }
128c1e19666Sxiaofeibao-xjtu
12965b2b1eaSxiaofeibao-xjtu  def connectNonPipedCtrlSingalForCSR: Unit = {
13065b2b1eaSxiaofeibao-xjtu    io.out.bits.ctrl.robIdx := DataHoldBypass(io.in.bits.ctrl.robIdx, io.in.fire)
13165b2b1eaSxiaofeibao-xjtu    io.out.bits.ctrl.pdest := DataHoldBypass(io.in.bits.ctrl.pdest, io.in.fire)
13265b2b1eaSxiaofeibao-xjtu    io.out.bits.ctrl.rfWen.foreach(_ := DataHoldBypass(io.in.bits.ctrl.rfWen.get, io.in.fire))
13365b2b1eaSxiaofeibao-xjtu    io.out.bits.ctrl.fpWen.foreach(_ := DataHoldBypass(io.in.bits.ctrl.fpWen.get, io.in.fire))
13465b2b1eaSxiaofeibao-xjtu    io.out.bits.ctrl.vecWen.foreach(_ := DataHoldBypass(io.in.bits.ctrl.vecWen.get, io.in.fire))
13565b2b1eaSxiaofeibao-xjtu    io.out.bits.ctrl.v0Wen.foreach(_ := DataHoldBypass(io.in.bits.ctrl.v0Wen.get, io.in.fire))
13665b2b1eaSxiaofeibao-xjtu    io.out.bits.ctrl.vlWen.foreach(_ := DataHoldBypass(io.in.bits.ctrl.vlWen.get, io.in.fire))
13765b2b1eaSxiaofeibao-xjtu    // io.out.bits.ctrl.flushPipe should be connected in fu
13865b2b1eaSxiaofeibao-xjtu    io.out.bits.ctrl.preDecode.foreach(_ := DataHoldBypass(io.in.bits.ctrl.preDecode.get, io.in.fire))
13965b2b1eaSxiaofeibao-xjtu    io.out.bits.ctrl.fpu.foreach(_ := DataHoldBypass(io.in.bits.ctrl.fpu.get, io.in.fire))
14065b2b1eaSxiaofeibao-xjtu    io.out.bits.ctrl.vpu.foreach(_ := DataHoldBypass(io.in.bits.ctrl.vpu.get, io.in.fire))
14165b2b1eaSxiaofeibao-xjtu    io.out.bits.perfDebugInfo := DataHoldBypass(io.in.bits.perfDebugInfo, io.in.fire)
142*1592abd1SYan Xu    io.out.bits.debug_seqNum := DataHoldBypass(io.in.bits.debug_seqNum, io.in.fire)
14365b2b1eaSxiaofeibao-xjtu  }
14465b2b1eaSxiaofeibao-xjtu
145c1e19666Sxiaofeibao-xjtu  def connect0LatencyCtrlSingal: Unit = {
146c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.robIdx := io.in.bits.ctrl.robIdx
147c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.pdest := io.in.bits.ctrl.pdest
148c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.rfWen.foreach(_ := io.in.bits.ctrl.rfWen.get)
149c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.fpWen.foreach(_ := io.in.bits.ctrl.fpWen.get)
150c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.vecWen.foreach(_ := io.in.bits.ctrl.vecWen.get)
151db7becb6Sxiaofeibao    io.out.bits.ctrl.v0Wen.foreach(_ := io.in.bits.ctrl.v0Wen.get)
152db7becb6Sxiaofeibao    io.out.bits.ctrl.vlWen.foreach(_ := io.in.bits.ctrl.vlWen.get)
153c1e19666Sxiaofeibao-xjtu    // io.out.bits.ctrl.flushPipe should be connected in fu
154c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.preDecode.foreach(_ := io.in.bits.ctrl.preDecode.get)
155c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.fpu.foreach(_ := io.in.bits.ctrl.fpu.get)
156c1e19666Sxiaofeibao-xjtu    io.out.bits.ctrl.vpu.foreach(_ := io.in.bits.ctrl.vpu.get)
157c1e19666Sxiaofeibao-xjtu    io.out.bits.perfDebugInfo := io.in.bits.perfDebugInfo
158*1592abd1SYan Xu    io.out.bits.debug_seqNum := io.in.bits.debug_seqNum
159730cfbc0SXuan Hu  }
160730cfbc0SXuan Hu}
161730cfbc0SXuan Hu
162730cfbc0SXuan Hu/**
163730cfbc0SXuan Hu  * @author LinJiaWei, Yinan Xu
164730cfbc0SXuan Hu  */
165730cfbc0SXuan Hutrait HasPipelineReg { this: FuncUnit =>
166730cfbc0SXuan Hu  def latency: Int
167730cfbc0SXuan Hu
1689e200047Slewislzh  val latdiff :Int = cfg.latency.extraLatencyVal.getOrElse(0)
16934588aebSlewislzh  val preLat :Int = latency - latdiff
1709e200047Slewislzh  require(latency >= 0 && latdiff >=0)
171730cfbc0SXuan Hu
17234588aebSlewislzh  def pipelineReg(init: FuncUnitInput , valid:Bool, ready: Bool,latency: Int, flush:ValidIO[Redirect]): (Seq[FuncUnitInput],Seq[Bool],Seq[Bool])={
17334588aebSlewislzh    val rdyVec = Seq.fill(latency)(Wire(Bool())) :+ ready
17434588aebSlewislzh    val validVec = valid +: Seq.fill(latency)(RegInit(false.B))
17534588aebSlewislzh    val ctrlVec = init.ctrl +: Seq.fill(latency)(Reg(chiselTypeOf(io.in.bits.ctrl)))
17634588aebSlewislzh    val dataVec = init.data +: Seq.fill(latency)(Reg(chiselTypeOf(io.in.bits.data)))
17734588aebSlewislzh    val perfVec = init.perfDebugInfo +: Seq.fill(latency)(Reg(chiselTypeOf(io.in.bits.perfDebugInfo)))
178*1592abd1SYan Xu    val seqNumVec = init.debug_seqNum +: Seq.fill(latency)(Reg(chiselTypeOf(io.in.bits.debug_seqNum)))
179ea0f92d8Sczw
18059607684SXuan Hu    val robIdxVec = ctrlVec.map(_.robIdx)
181730cfbc0SXuan Hu
182730cfbc0SXuan Hu    // if flush(0), valid 0 will not given, so set flushVec(0) to false.B
18334588aebSlewislzh    val flushVec = validVec.zip(robIdxVec).map(x => x._1 && x._2.needFlush(flush))
184730cfbc0SXuan Hu
185730cfbc0SXuan Hu    for (i <- 0 until latency) {
18634588aebSlewislzh      rdyVec(i) := !validVec(i + 1) || rdyVec(i + 1).asTypeOf(Bool())
187730cfbc0SXuan Hu    }
18878115a00SXuan Hu    for (i <- 1 to latency) {
189730cfbc0SXuan Hu      validVec(i) := validVec(i - 1)
190472967baSxiaofeibao      when(rdyVec(i - 1) && validVec(i - 1)) {
19159607684SXuan Hu        ctrlVec(i) := ctrlVec(i - 1)
19259607684SXuan Hu        dataVec(i) := dataVec(i - 1)
19396e858baSXuan Hu        perfVec(i) := perfVec(i - 1)
194*1592abd1SYan Xu        seqNumVec(i) := seqNumVec(i-1)
195730cfbc0SXuan Hu      }
196730cfbc0SXuan Hu    }
197730cfbc0SXuan Hu
198*1592abd1SYan Xu    (ctrlVec.zip(dataVec).zip(perfVec).zip(seqNumVec).map{
199*1592abd1SYan Xu      case(((ctrl,data), perf), debug_seqNum) => {
20034588aebSlewislzh        val out = Wire(new FuncUnitInput(cfg))
20134588aebSlewislzh        out.ctrl := ctrl
202472967baSxiaofeibao        out.ctrlPipe.foreach(_ := 0.U.asTypeOf(out.ctrlPipe.get))
203472967baSxiaofeibao        out.validPipe.foreach(_ := 0.U.asTypeOf(out.validPipe.get))
204b67a2036Sxiaofeibao        out.dataPipe.foreach(_ := 0.U.asTypeOf(out.dataPipe.get))
20534588aebSlewislzh        out.data := data
20634588aebSlewislzh        out.perfDebugInfo := perf
207*1592abd1SYan Xu        out.debug_seqNum := debug_seqNum
20834588aebSlewislzh        out
20934588aebSlewislzh      }
21034588aebSlewislzh    },validVec, rdyVec)
21134588aebSlewislzh  }
212472967baSxiaofeibao  val (pipeReg : Seq[FuncUnitInput], validVecThisFu ,rdyVec ) = pipelineReg(io.in.bits, io.in.valid,io.out.ready,preLat, io.flush)
213472967baSxiaofeibao  val validVec = io.in.bits.validPipe.get.zip(validVecThisFu).map(x => x._1 && x._2)
214472967baSxiaofeibao  val ctrlVec = io.in.bits.ctrlPipe.get
215b67a2036Sxiaofeibao  val dataVec = io.in.bits.dataPipe.get
21634588aebSlewislzh  val perfVec = pipeReg.map(_.perfDebugInfo)
217*1592abd1SYan Xu  val seqNumVec = pipeReg.map(_.debug_seqNum)
21834588aebSlewislzh
21934588aebSlewislzh
22034588aebSlewislzh  val fixtiminginit = Wire(new FuncUnitInput(cfg))
22134588aebSlewislzh  fixtiminginit.ctrl := ctrlVec.last
222472967baSxiaofeibao  fixtiminginit.ctrlPipe.foreach(_ := 0.U.asTypeOf(fixtiminginit.ctrlPipe.get))
223472967baSxiaofeibao  fixtiminginit.validPipe.foreach(_ := 0.U.asTypeOf(fixtiminginit.validPipe.get))
224b67a2036Sxiaofeibao  fixtiminginit.dataPipe.foreach(_ := 0.U.asTypeOf(fixtiminginit.dataPipe.get))
22534588aebSlewislzh  fixtiminginit.data := dataVec.last
22634588aebSlewislzh  fixtiminginit.perfDebugInfo := perfVec.last
227*1592abd1SYan Xu  fixtiminginit.debug_seqNum := seqNumVec.last
22834588aebSlewislzh
22934588aebSlewislzh  // fixtiming pipelinereg
23034588aebSlewislzh  val (fixpipeReg : Seq[FuncUnitInput], fixValidVec, fixRdyVec) = pipelineReg(fixtiminginit, validVec.last,rdyVec.head ,latdiff, io.flush)
23134588aebSlewislzh  val fixDataVec = fixpipeReg.map(_.data)
23234588aebSlewislzh  val fixPerfVec = fixpipeReg.map(_.perfDebugInfo)
233*1592abd1SYan Xu  val fixSeqNumVec = fixpipeReg.map(_.debug_seqNum)
23434588aebSlewislzh  val pcVec = fixDataVec.map(_.pc)
23534588aebSlewislzh
23634588aebSlewislzh  io.in.ready := fixRdyVec.head
23734588aebSlewislzh  io.out.valid := fixValidVec.last
2389a46f19dSsinsanction
239472967baSxiaofeibao  io.out.bits.ctrl.robIdx := ctrlVec.last.robIdx
240472967baSxiaofeibao  io.out.bits.ctrl.pdest := ctrlVec.last.pdest
241472967baSxiaofeibao  io.out.bits.ctrl.rfWen.foreach(_ := ctrlVec.last.rfWen.get)
242472967baSxiaofeibao  io.out.bits.ctrl.fpWen.foreach(_ := ctrlVec.last.fpWen.get)
243472967baSxiaofeibao  io.out.bits.ctrl.vecWen.foreach(_ := ctrlVec.last.vecWen.get)
244472967baSxiaofeibao  io.out.bits.ctrl.v0Wen.foreach(_ := ctrlVec.last.v0Wen.get)
245472967baSxiaofeibao  io.out.bits.ctrl.vlWen.foreach(_ := ctrlVec.last.vlWen.get)
246472967baSxiaofeibao  io.out.bits.ctrl.fpu.foreach(_ := ctrlVec.last.fpu.get)
247472967baSxiaofeibao  io.out.bits.ctrl.vpu.foreach(_ := ctrlVec.last.vpu.get)
24834588aebSlewislzh  io.out.bits.perfDebugInfo := fixPerfVec.last
249*1592abd1SYan Xu  io.out.bits.debug_seqNum := fixSeqNumVec.last
2509a46f19dSsinsanction
2519a46f19dSsinsanction  // vstart illegal
2529a46f19dSsinsanction  if (cfg.exceptionOut.nonEmpty) {
253472967baSxiaofeibao    val outVstart = ctrlVec.last.vpu.get.vstart
2549a46f19dSsinsanction    val vstartIllegal = outVstart =/= 0.U
2559a46f19dSsinsanction    io.out.bits.ctrl.exceptionVec.get := 0.U.asTypeOf(io.out.bits.ctrl.exceptionVec.get)
2569a46f19dSsinsanction    io.out.bits.ctrl.exceptionVec.get(illegalInstr) := vstartIllegal
2579a46f19dSsinsanction  }
258730cfbc0SXuan Hu
259472967baSxiaofeibao  def regEnable(i: Int): Bool = validVec(i - 1) && rdyVec(i - 1)
260730cfbc0SXuan Hu
26134588aebSlewislzh  def PipelineReg[TT <: Data](i: Int)(next: TT) = {
26234588aebSlewislzh    val lat = preLat min i
26334588aebSlewislzh    RegEnable(
264730cfbc0SXuan Hu      next,
26534588aebSlewislzh      regEnable(lat)
266730cfbc0SXuan Hu    )
26734588aebSlewislzh  }
26834588aebSlewislzh
26934588aebSlewislzh  def SNReg[TT <: Data](in: TT, n: Int): TT ={
27034588aebSlewislzh    val lat = preLat min n
27134588aebSlewislzh    var next = in
27234588aebSlewislzh    for (i <- 1 to lat) {
27334588aebSlewislzh      next = PipelineReg[TT](i)(next)
27434588aebSlewislzh    }
27534588aebSlewislzh    next
27634588aebSlewislzh  }
277730cfbc0SXuan Hu
278730cfbc0SXuan Hu  def S1Reg[TT <: Data](next: TT): TT = PipelineReg[TT](1)(next)
279730cfbc0SXuan Hu
280730cfbc0SXuan Hu  def S2Reg[TT <: Data](next: TT): TT = PipelineReg[TT](2)(next)
281730cfbc0SXuan Hu
282730cfbc0SXuan Hu  def S3Reg[TT <: Data](next: TT): TT = PipelineReg[TT](3)(next)
283730cfbc0SXuan Hu
284730cfbc0SXuan Hu  def S4Reg[TT <: Data](next: TT): TT = PipelineReg[TT](4)(next)
285730cfbc0SXuan Hu
286730cfbc0SXuan Hu  def S5Reg[TT <: Data](next: TT): TT = PipelineReg[TT](5)(next)
287730cfbc0SXuan Hu
288730cfbc0SXuan Hu}
289730cfbc0SXuan Hu
29078115a00SXuan Huabstract class PipedFuncUnit(override val cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg)
29178115a00SXuan Hu  with HasPipelineReg {
29278115a00SXuan Hu  override def latency: Int = cfg.latency.latencyVal.get
29378115a00SXuan Hu}
294