1cafb3558SLinJiaweipackage xiangshan.backend.fu 2cafb3558SLinJiawei 3cafb3558SLinJiaweiimport chisel3._ 4cafb3558SLinJiaweiimport chisel3.util._ 5cafb3558SLinJiaweiimport xiangshan._ 652c3f215SLinJiaweiimport xiangshan.backend.MDUOpType 752c3f215SLinJiaweiimport xiangshan.backend.fu.fpu.FPUOpType.{FU_D2S, FU_DIVSQRT, FU_F2I, FU_FCMP, FU_FMV, FU_S2D} 8e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu.divsqrt.DivSqrt 9e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu._ 10e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu.fma.FMA 11cafb3558SLinJiawei 12cafb3558SLinJiawei/* 13cafb3558SLinJiawei XiangShan Function Unit 14cafb3558SLinJiawei A Exu can have one or more function units 15cafb3558SLinJiawei */ 16cafb3558SLinJiawei 173e60a357SLinJiaweitrait HasFuLatency { 183e60a357SLinJiawei val latencyVal: Option[Int] 193e60a357SLinJiawei} 203e60a357SLinJiawei 213e60a357SLinJiaweicase class CertainLatency(value: Int) extends HasFuLatency { 223e60a357SLinJiawei override val latencyVal: Option[Int] = Some(value) 233e60a357SLinJiawei} 243e60a357SLinJiawei 253e60a357SLinJiaweicase class UncertainLatency() extends HasFuLatency { 263e60a357SLinJiawei override val latencyVal: Option[Int] = None 273e60a357SLinJiawei} 283e60a357SLinJiawei 2916df83adSZhangZifei 30cafb3558SLinJiaweicase class FuConfig 31cafb3558SLinJiawei( 3252c3f215SLinJiawei fuGen: () => FunctionUnit, 3352c3f215SLinJiawei fuSel: FunctionUnit => Bool, 34cafb3558SLinJiawei fuType: UInt, 35cafb3558SLinJiawei numIntSrc: Int, 36cafb3558SLinJiawei numFpSrc: Int, 37cafb3558SLinJiawei writeIntRf: Boolean, 38cafb3558SLinJiawei writeFpRf: Boolean, 393e60a357SLinJiawei hasRedirect: Boolean, 403e60a357SLinJiawei latency: HasFuLatency = CertainLatency(0) 4114521086SLinJiawei) { 4214521086SLinJiawei def srcCnt: Int = math.max(numIntSrc, numFpSrc) 43c84054caSLinJiawei} 44c84054caSLinJiawei 45e18c367fSLinJiawei 46e18c367fSLinJiaweiclass FuOutput extends XSBundle { 47e18c367fSLinJiawei val data = UInt(XLEN.W) 48e18c367fSLinJiawei val uop = new MicroOp 49e18c367fSLinJiawei} 50e18c367fSLinJiawei 51e18c367fSLinJiawei 5252c3f215SLinJiaweiclass FunctionUnitIO(len: Int) extends XSBundle { 5314521086SLinJiawei val in = Flipped(DecoupledIO(new Bundle() { 5452c3f215SLinJiawei val src = Vec(3, UInt(len.W)) 5514521086SLinJiawei val uop = new MicroOp 5614521086SLinJiawei })) 57ead41f51SLinJiawei 58e18c367fSLinJiawei val out = DecoupledIO(new FuOutput) 59ead41f51SLinJiawei 6014521086SLinJiawei val redirectIn = Flipped(ValidIO(new Redirect)) 6112bb47ddSLinJiawei 6212bb47ddSLinJiawei override def cloneType: FunctionUnitIO.this.type = 6352c3f215SLinJiawei new FunctionUnitIO(len).asInstanceOf[this.type] 6414521086SLinJiawei} 6514521086SLinJiawei 6652c3f215SLinJiaweiabstract class FunctionUnit(len: Int = 64) extends XSModule { 6714521086SLinJiawei 6852c3f215SLinJiawei val io = IO(new FunctionUnitIO(len)) 6914521086SLinJiawei 7014521086SLinJiawei} 7114521086SLinJiawei 7252c3f215SLinJiaweitrait HasPipelineReg { 7352c3f215SLinJiawei this: FunctionUnit => 74e18c367fSLinJiawei 75*f64ff6e8SLinJiawei def latency: Int 7652c3f215SLinJiawei 7752c3f215SLinJiawei require(latency > 0) 7814521086SLinJiawei 7914521086SLinJiawei val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B)) 8014521086SLinJiawei val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready 8114521086SLinJiawei val uopVec = io.in.bits.uop +: Array.fill(latency)(Reg(new MicroOp)) 8214521086SLinJiawei 8314521086SLinJiawei 843136ee6aSLinJiawei val flushVec = uopVec.zip(validVec).map(x => x._2 && x._1.roqIdx.needFlush(io.redirectIn)) 8514521086SLinJiawei 8614521086SLinJiawei for (i <- 0 until latency) { 8714521086SLinJiawei rdyVec(i) := !validVec(i + 1) || rdyVec(i + 1) 8814521086SLinJiawei } 8914521086SLinJiawei 9014521086SLinJiawei for (i <- 1 to latency) { 9114521086SLinJiawei when(flushVec(i - 1) || rdyVec(i) && !validVec(i - 1)) { 9214521086SLinJiawei validVec(i) := false.B 9314521086SLinJiawei }.elsewhen(rdyVec(i - 1) && validVec(i - 1) && !flushVec(i - 1)) { 9414521086SLinJiawei validVec(i) := validVec(i - 1) 9514521086SLinJiawei uopVec(i) := uopVec(i - 1) 9614521086SLinJiawei } 9714521086SLinJiawei } 9814521086SLinJiawei 9914521086SLinJiawei io.in.ready := rdyVec(0) 10014521086SLinJiawei io.out.valid := validVec.last && !flushVec.last 10114521086SLinJiawei io.out.bits.uop := uopVec.last 10214521086SLinJiawei 10314521086SLinJiawei def PipelineReg[TT <: Data](i: Int)(next: TT) = RegEnable( 10414521086SLinJiawei next, 10514521086SLinJiawei enable = validVec(i - 1) && rdyVec(i - 1) && !flushVec(i - 1) 10614521086SLinJiawei ) 10714521086SLinJiawei 10814521086SLinJiawei def S1Reg[TT <: Data](next: TT): TT = PipelineReg[TT](1)(next) 10914521086SLinJiawei 11014521086SLinJiawei def S2Reg[TT <: Data](next: TT): TT = PipelineReg[TT](2)(next) 11114521086SLinJiawei 11214521086SLinJiawei def S3Reg[TT <: Data](next: TT): TT = PipelineReg[TT](3)(next) 11314521086SLinJiawei 11414521086SLinJiawei def S4Reg[TT <: Data](next: TT): TT = PipelineReg[TT](4)(next) 11514521086SLinJiawei 11614521086SLinJiawei def S5Reg[TT <: Data](next: TT): TT = PipelineReg[TT](5)(next) 11714521086SLinJiawei} 118cafb3558SLinJiawei 119e18c367fSLinJiaweiobject FunctionUnit extends HasXSParameter { 120c84054caSLinJiawei 1215018a303SLinJiawei def divider = new SRT4Divider(XLEN) 12252c3f215SLinJiawei 1238a4dc19aSLinJiawei def multiplier = new ArrayMultiplier(XLEN + 1, Seq(0, 2)) 1243ff0763bSljw 125e18c367fSLinJiawei def alu = new Alu 126c84054caSLinJiawei 127e18c367fSLinJiawei def jmp = new Jump 12852c3f215SLinJiawei 129e18c367fSLinJiawei def fence = new Fence 13052c3f215SLinJiawei 131e18c367fSLinJiawei def csr = new CSR 13252c3f215SLinJiawei 133e18c367fSLinJiawei def i2f = new IntToFloatSingleCycle 134cafb3558SLinJiawei 135e18c367fSLinJiawei def fmac = new FMA 13652c3f215SLinJiawei 137e18c367fSLinJiawei def fcmp = new FCMP 13852c3f215SLinJiawei 139e18c367fSLinJiawei def fmv = new FMV(XLEN) 14052c3f215SLinJiawei 141e18c367fSLinJiawei def f2i = new FloatToInt 14252c3f215SLinJiawei 143e18c367fSLinJiawei def f32toF64 = new F32toF64 14452c3f215SLinJiawei 145e18c367fSLinJiawei def f64toF32 = new F64toF32 14652c3f215SLinJiawei 147e18c367fSLinJiawei def fdivSqrt = new DivSqrt 148cafb3558SLinJiawei 14952c3f215SLinJiawei def fmiscSel(fu: String)(x: FunctionUnit): Bool = { 150e18c367fSLinJiawei x.io.in.bits.uop.ctrl.fuOpType.head(4) === s"b$fu".U 151e18c367fSLinJiawei } 152b8f08ca0SZhangZifei 15352c3f215SLinJiawei val aluCfg = FuConfig( 15452c3f215SLinJiawei fuGen = alu _, 15552c3f215SLinJiawei fuSel = _ => true.B, 15652c3f215SLinJiawei fuType = FuType.alu, 15752c3f215SLinJiawei numIntSrc = 2, 15852c3f215SLinJiawei numFpSrc = 0, 15952c3f215SLinJiawei writeIntRf = true, 16052c3f215SLinJiawei writeFpRf = false, 16152c3f215SLinJiawei hasRedirect = true 16252c3f215SLinJiawei ) 16352c3f215SLinJiawei 16452c3f215SLinJiawei val jmpCfg = FuConfig( 16552c3f215SLinJiawei fuGen = jmp _, 16652c3f215SLinJiawei fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.jmp, 16752c3f215SLinJiawei fuType = FuType.jmp, 16852c3f215SLinJiawei numIntSrc = 1, 16952c3f215SLinJiawei numFpSrc = 0, 17052c3f215SLinJiawei writeIntRf = true, 17152c3f215SLinJiawei writeFpRf = false, 17252c3f215SLinJiawei hasRedirect = true 17352c3f215SLinJiawei ) 17452c3f215SLinJiawei 17552c3f215SLinJiawei val fenceCfg = FuConfig( 17652c3f215SLinJiawei fuGen = fence _, 17752c3f215SLinJiawei fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.fence, 17852c3f215SLinJiawei FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false 17952c3f215SLinJiawei ) 18052c3f215SLinJiawei 18152c3f215SLinJiawei val csrCfg = FuConfig( 18252c3f215SLinJiawei fuGen = csr _, 18352c3f215SLinJiawei fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.csr, 18452c3f215SLinJiawei fuType = FuType.csr, 18552c3f215SLinJiawei numIntSrc = 1, 18652c3f215SLinJiawei numFpSrc = 0, 18752c3f215SLinJiawei writeIntRf = true, 18852c3f215SLinJiawei writeFpRf = false, 18952c3f215SLinJiawei hasRedirect = false 19052c3f215SLinJiawei ) 19152c3f215SLinJiawei 19252c3f215SLinJiawei val i2fCfg = FuConfig( 19352c3f215SLinJiawei fuGen = i2f _, 19452c3f215SLinJiawei fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.i2f, 19552c3f215SLinJiawei FuType.i2f, 19652c3f215SLinJiawei numIntSrc = 1, 19752c3f215SLinJiawei numFpSrc = 0, 19852c3f215SLinJiawei writeIntRf = false, 19952c3f215SLinJiawei writeFpRf = true, 20052c3f215SLinJiawei hasRedirect = false, 20152c3f215SLinJiawei CertainLatency(0) 20252c3f215SLinJiawei ) 20352c3f215SLinJiawei 20452c3f215SLinJiawei val divCfg = FuConfig( 20552c3f215SLinJiawei fuGen = divider _, 20652c3f215SLinJiawei fuSel = (x: FunctionUnit) => MDUOpType.isDiv(x.io.in.bits.uop.ctrl.fuOpType), 20752c3f215SLinJiawei FuType.div, 20852c3f215SLinJiawei 2, 20952c3f215SLinJiawei 0, 21052c3f215SLinJiawei writeIntRf = true, 21152c3f215SLinJiawei writeFpRf = false, 21252c3f215SLinJiawei hasRedirect = false, 2133e60a357SLinJiawei UncertainLatency() 2143e60a357SLinJiawei ) 2156624015fSLinJiawei 21652c3f215SLinJiawei val mulCfg = FuConfig( 21752c3f215SLinJiawei fuGen = multiplier _, 21852c3f215SLinJiawei fuSel = (x: FunctionUnit) => MDUOpType.isMul(x.io.in.bits.uop.ctrl.fuOpType), 21952c3f215SLinJiawei FuType.mul, 22052c3f215SLinJiawei 2, 22152c3f215SLinJiawei 0, 22252c3f215SLinJiawei writeIntRf = true, 22352c3f215SLinJiawei writeFpRf = false, 22452c3f215SLinJiawei hasRedirect = false, 22552c3f215SLinJiawei CertainLatency(3) 22652c3f215SLinJiawei ) 22752c3f215SLinJiawei 22852c3f215SLinJiawei val fmacCfg = FuConfig( 22952c3f215SLinJiawei fuGen = fmac _, 23052c3f215SLinJiawei fuSel = _ => true.B, 23152c3f215SLinJiawei FuType.fmac, 0, 3, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(5) 23252c3f215SLinJiawei ) 23352c3f215SLinJiawei 23452c3f215SLinJiawei val fcmpCfg = FuConfig( 23552c3f215SLinJiawei fuGen = fcmp _, 23652c3f215SLinJiawei fuSel = fmiscSel(FU_FCMP), 23752c3f215SLinJiawei FuType.fmisc, 0, 2, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(2) 23852c3f215SLinJiawei ) 23952c3f215SLinJiawei 24052c3f215SLinJiawei val fmvCfg = FuConfig( 24152c3f215SLinJiawei fuGen = fmv _, 24252c3f215SLinJiawei fuSel = fmiscSel(FU_FMV), 24352c3f215SLinJiawei FuType.fmisc, 0, 2, writeIntRf = true, writeFpRf = true, hasRedirect = false, CertainLatency(1) 24452c3f215SLinJiawei ) 24552c3f215SLinJiawei 24652c3f215SLinJiawei val f2iCfg = FuConfig( 24752c3f215SLinJiawei fuGen = f2i _, 24852c3f215SLinJiawei fuSel = fmiscSel(FU_F2I), 24952c3f215SLinJiawei FuType.fmisc, 0, 1, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(2) 25052c3f215SLinJiawei ) 25152c3f215SLinJiawei 25252c3f215SLinJiawei val s2dCfg = FuConfig( 25352c3f215SLinJiawei fuGen = f32toF64 _, 25452c3f215SLinJiawei fuSel = fmiscSel(FU_S2D), 25552c3f215SLinJiawei FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(2) 25652c3f215SLinJiawei ) 25752c3f215SLinJiawei 25852c3f215SLinJiawei val d2sCfg = FuConfig( 25952c3f215SLinJiawei fuGen = f64toF32 _, 26052c3f215SLinJiawei fuSel = fmiscSel(FU_D2S), 26152c3f215SLinJiawei FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(2) 26252c3f215SLinJiawei ) 26352c3f215SLinJiawei 26452c3f215SLinJiawei val fdivSqrtCfg = FuConfig( 26552c3f215SLinJiawei fuGen = fdivSqrt _, 26652c3f215SLinJiawei fuSel = fmiscSel(FU_DIVSQRT), 26752c3f215SLinJiawei FuType.fDivSqrt, 0, 2, writeIntRf = false, writeFpRf = true, hasRedirect = false, UncertainLatency() 26852c3f215SLinJiawei ) 26952c3f215SLinJiawei 27052c3f215SLinJiawei val lduCfg = FuConfig( 27152c3f215SLinJiawei null, // DontCare 27252c3f215SLinJiawei null, 27352c3f215SLinJiawei FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true, hasRedirect = false, 2743e60a357SLinJiawei UncertainLatency() 2753e60a357SLinJiawei ) 276cafb3558SLinJiawei 27752c3f215SLinJiawei val stuCfg = FuConfig( 27852c3f215SLinJiawei null, 27952c3f215SLinJiawei null, 28052c3f215SLinJiawei FuType.stu, 2, 1, writeIntRf = false, writeFpRf = false, hasRedirect = false, 28152c3f215SLinJiawei UncertainLatency() 28252c3f215SLinJiawei ) 28352c3f215SLinJiawei 28452c3f215SLinJiawei val mouCfg = FuConfig( 28552c3f215SLinJiawei null, 28652c3f215SLinJiawei null, 28752c3f215SLinJiawei FuType.mou, 2, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false, 2883e60a357SLinJiawei UncertainLatency() 2893e60a357SLinJiawei ) 290cafb3558SLinJiawei} 291