1*c6d43980SLemover/*************************************************************************************** 2*c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3*c6d43980SLemover* 4*c6d43980SLemover* XiangShan is licensed under Mulan PSL v2. 5*c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2. 6*c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at: 7*c6d43980SLemover* http://license.coscl.org.cn/MulanPSL2 8*c6d43980SLemover* 9*c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 10*c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 11*c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 12*c6d43980SLemover* 13*c6d43980SLemover* See the Mulan PSL v2 for more details. 14*c6d43980SLemover***************************************************************************************/ 15*c6d43980SLemover 16cafb3558SLinJiaweipackage xiangshan.backend.fu 17cafb3558SLinJiawei 182225d46eSJiawei Linimport chipsalliance.rocketchip.config.Parameters 19cafb3558SLinJiaweiimport chisel3._ 20cafb3558SLinJiaweiimport chisel3.util._ 21cafb3558SLinJiaweiimport xiangshan._ 22e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu._ 23cafb3558SLinJiawei 243e60a357SLinJiaweitrait HasFuLatency { 253e60a357SLinJiawei val latencyVal: Option[Int] 263e60a357SLinJiawei} 273e60a357SLinJiawei 283e60a357SLinJiaweicase class CertainLatency(value: Int) extends HasFuLatency { 293e60a357SLinJiawei override val latencyVal: Option[Int] = Some(value) 303e60a357SLinJiawei} 313e60a357SLinJiawei 323e60a357SLinJiaweicase class UncertainLatency() extends HasFuLatency { 333e60a357SLinJiawei override val latencyVal: Option[Int] = None 343e60a357SLinJiawei} 353e60a357SLinJiawei 3616df83adSZhangZifei 37cafb3558SLinJiaweicase class FuConfig 38cafb3558SLinJiawei( 392225d46eSJiawei Lin fuGen: Parameters => FunctionUnit, 4052c3f215SLinJiawei fuSel: FunctionUnit => Bool, 41cafb3558SLinJiawei fuType: UInt, 42cafb3558SLinJiawei numIntSrc: Int, 43cafb3558SLinJiawei numFpSrc: Int, 44cafb3558SLinJiawei writeIntRf: Boolean, 45cafb3558SLinJiawei writeFpRf: Boolean, 463e60a357SLinJiawei hasRedirect: Boolean, 47c43ef4edSLinJiawei latency: HasFuLatency = CertainLatency(0), 4814521086SLinJiawei) { 4914521086SLinJiawei def srcCnt: Int = math.max(numIntSrc, numFpSrc) 50c84054caSLinJiawei} 51c84054caSLinJiawei 52e18c367fSLinJiawei 532225d46eSJiawei Linclass FuOutput(val len: Int)(implicit p: Parameters) extends XSBundle { 54e50fb2d7SLinJiawei val data = UInt(len.W) 55e18c367fSLinJiawei val uop = new MicroOp 56e18c367fSLinJiawei} 57e18c367fSLinJiawei 58e18c367fSLinJiawei 592225d46eSJiawei Linclass FunctionUnitIO(val len: Int)(implicit p: Parameters) extends XSBundle { 6014521086SLinJiawei val in = Flipped(DecoupledIO(new Bundle() { 6152c3f215SLinJiawei val src = Vec(3, UInt(len.W)) 6214521086SLinJiawei val uop = new MicroOp 6314521086SLinJiawei })) 64ead41f51SLinJiawei 65e50fb2d7SLinJiawei val out = DecoupledIO(new FuOutput(len)) 66ead41f51SLinJiawei 6714521086SLinJiawei val redirectIn = Flipped(ValidIO(new Redirect)) 682d7c7105SYinan Xu val flushIn = Input(Bool()) 6914521086SLinJiawei} 7014521086SLinJiawei 712225d46eSJiawei Linabstract class FunctionUnit(len: Int = 64)(implicit p: Parameters) extends XSModule { 7214521086SLinJiawei 7352c3f215SLinJiawei val io = IO(new FunctionUnitIO(len)) 7414521086SLinJiawei 7514521086SLinJiawei} 7614521086SLinJiawei 7752c3f215SLinJiaweitrait HasPipelineReg { 7852c3f215SLinJiawei this: FunctionUnit => 79e18c367fSLinJiawei 80f64ff6e8SLinJiawei def latency: Int 8152c3f215SLinJiawei 8252c3f215SLinJiawei require(latency > 0) 8314521086SLinJiawei 8414521086SLinJiawei val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B)) 8514521086SLinJiawei val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready 8614521086SLinJiawei val uopVec = io.in.bits.uop +: Array.fill(latency)(Reg(new MicroOp)) 8714521086SLinJiawei 8814521086SLinJiawei 89dfd9e0a8SLinJiawei // if flush(0), valid 0 will not given, so set flushVec(0) to false.B 909b09132dSYinan Xu val flushVec = validVec.zip(uopVec).map(x => x._1 && x._2.roqIdx.needFlush(io.redirectIn, io.flushIn)) 9114521086SLinJiawei 9214521086SLinJiawei for (i <- 0 until latency) { 9314521086SLinJiawei rdyVec(i) := !validVec(i + 1) || rdyVec(i + 1) 9414521086SLinJiawei } 9514521086SLinJiawei 9614521086SLinJiawei for (i <- 1 to latency) { 9756477dc6SLinJiawei when(rdyVec(i - 1) && validVec(i - 1) && !flushVec(i - 1)){ 9814521086SLinJiawei validVec(i) := validVec(i - 1) 9914521086SLinJiawei uopVec(i) := uopVec(i - 1) 10056477dc6SLinJiawei }.elsewhen(flushVec(i) || rdyVec(i)){ 10156477dc6SLinJiawei validVec(i) := false.B 10214521086SLinJiawei } 10314521086SLinJiawei } 10414521086SLinJiawei 10514521086SLinJiawei io.in.ready := rdyVec(0) 106dfd9e0a8SLinJiawei io.out.valid := validVec.last 10714521086SLinJiawei io.out.bits.uop := uopVec.last 10814521086SLinJiawei 10975f32f6bSLinJiawei def regEnable(i: Int): Bool = validVec(i - 1) && rdyVec(i - 1) && !flushVec(i - 1) 11075f32f6bSLinJiawei 11114521086SLinJiawei def PipelineReg[TT <: Data](i: Int)(next: TT) = RegEnable( 11214521086SLinJiawei next, 11375f32f6bSLinJiawei enable = regEnable(i) 11414521086SLinJiawei ) 11514521086SLinJiawei 11614521086SLinJiawei def S1Reg[TT <: Data](next: TT): TT = PipelineReg[TT](1)(next) 11714521086SLinJiawei 11814521086SLinJiawei def S2Reg[TT <: Data](next: TT): TT = PipelineReg[TT](2)(next) 11914521086SLinJiawei 12014521086SLinJiawei def S3Reg[TT <: Data](next: TT): TT = PipelineReg[TT](3)(next) 12114521086SLinJiawei 12214521086SLinJiawei def S4Reg[TT <: Data](next: TT): TT = PipelineReg[TT](4)(next) 12314521086SLinJiawei 12414521086SLinJiawei def S5Reg[TT <: Data](next: TT): TT = PipelineReg[TT](5)(next) 12514521086SLinJiawei} 126