1cafb3558SLinJiaweipackage xiangshan.backend.fu 2cafb3558SLinJiawei 3cafb3558SLinJiaweiimport chisel3._ 4cafb3558SLinJiaweiimport chisel3.util._ 5cafb3558SLinJiaweiimport xiangshan._ 652c3f215SLinJiaweiimport xiangshan.backend.MDUOpType 7e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu._ 8cafb3558SLinJiawei 93e60a357SLinJiaweitrait HasFuLatency { 103e60a357SLinJiawei val latencyVal: Option[Int] 113e60a357SLinJiawei} 123e60a357SLinJiawei 133e60a357SLinJiaweicase class CertainLatency(value: Int) extends HasFuLatency { 143e60a357SLinJiawei override val latencyVal: Option[Int] = Some(value) 153e60a357SLinJiawei} 163e60a357SLinJiawei 173e60a357SLinJiaweicase class UncertainLatency() extends HasFuLatency { 183e60a357SLinJiawei override val latencyVal: Option[Int] = None 193e60a357SLinJiawei} 203e60a357SLinJiawei 2116df83adSZhangZifei 22cafb3558SLinJiaweicase class FuConfig 23cafb3558SLinJiawei( 2452c3f215SLinJiawei fuGen: () => FunctionUnit, 2552c3f215SLinJiawei fuSel: FunctionUnit => Bool, 26cafb3558SLinJiawei fuType: UInt, 27cafb3558SLinJiawei numIntSrc: Int, 28cafb3558SLinJiawei numFpSrc: Int, 29cafb3558SLinJiawei writeIntRf: Boolean, 30cafb3558SLinJiawei writeFpRf: Boolean, 313e60a357SLinJiawei hasRedirect: Boolean, 323e60a357SLinJiawei latency: HasFuLatency = CertainLatency(0) 3314521086SLinJiawei) { 3414521086SLinJiawei def srcCnt: Int = math.max(numIntSrc, numFpSrc) 35c84054caSLinJiawei} 36c84054caSLinJiawei 37e18c367fSLinJiawei 38e18c367fSLinJiaweiclass FuOutput extends XSBundle { 39e18c367fSLinJiawei val data = UInt(XLEN.W) 40e18c367fSLinJiawei val uop = new MicroOp 41e18c367fSLinJiawei} 42e18c367fSLinJiawei 43e18c367fSLinJiawei 4452c3f215SLinJiaweiclass FunctionUnitIO(len: Int) extends XSBundle { 4514521086SLinJiawei val in = Flipped(DecoupledIO(new Bundle() { 4652c3f215SLinJiawei val src = Vec(3, UInt(len.W)) 4714521086SLinJiawei val uop = new MicroOp 4814521086SLinJiawei })) 49ead41f51SLinJiawei 50e18c367fSLinJiawei val out = DecoupledIO(new FuOutput) 51ead41f51SLinJiawei 5214521086SLinJiawei val redirectIn = Flipped(ValidIO(new Redirect)) 5312bb47ddSLinJiawei 5412bb47ddSLinJiawei override def cloneType: FunctionUnitIO.this.type = 5552c3f215SLinJiawei new FunctionUnitIO(len).asInstanceOf[this.type] 5614521086SLinJiawei} 5714521086SLinJiawei 5852c3f215SLinJiaweiabstract class FunctionUnit(len: Int = 64) extends XSModule { 5914521086SLinJiawei 6052c3f215SLinJiawei val io = IO(new FunctionUnitIO(len)) 6114521086SLinJiawei 6214521086SLinJiawei} 6314521086SLinJiawei 6452c3f215SLinJiaweitrait HasPipelineReg { 6552c3f215SLinJiawei this: FunctionUnit => 66e18c367fSLinJiawei 67f64ff6e8SLinJiawei def latency: Int 6852c3f215SLinJiawei 6952c3f215SLinJiawei require(latency > 0) 7014521086SLinJiawei 7114521086SLinJiawei val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B)) 7214521086SLinJiawei val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready 7314521086SLinJiawei val uopVec = io.in.bits.uop +: Array.fill(latency)(Reg(new MicroOp)) 7414521086SLinJiawei 7514521086SLinJiawei 763136ee6aSLinJiawei val flushVec = uopVec.zip(validVec).map(x => x._2 && x._1.roqIdx.needFlush(io.redirectIn)) 7714521086SLinJiawei 7814521086SLinJiawei for (i <- 0 until latency) { 7914521086SLinJiawei rdyVec(i) := !validVec(i + 1) || rdyVec(i + 1) 8014521086SLinJiawei } 8114521086SLinJiawei 8214521086SLinJiawei for (i <- 1 to latency) { 8314521086SLinJiawei when(flushVec(i - 1) || rdyVec(i) && !validVec(i - 1)) { 8414521086SLinJiawei validVec(i) := false.B 8514521086SLinJiawei }.elsewhen(rdyVec(i - 1) && validVec(i - 1) && !flushVec(i - 1)) { 8614521086SLinJiawei validVec(i) := validVec(i - 1) 8714521086SLinJiawei uopVec(i) := uopVec(i - 1) 8814521086SLinJiawei } 8914521086SLinJiawei } 9014521086SLinJiawei 9114521086SLinJiawei io.in.ready := rdyVec(0) 9214521086SLinJiawei io.out.valid := validVec.last && !flushVec.last 9314521086SLinJiawei io.out.bits.uop := uopVec.last 9414521086SLinJiawei 9514521086SLinJiawei def PipelineReg[TT <: Data](i: Int)(next: TT) = RegEnable( 9614521086SLinJiawei next, 9714521086SLinJiawei enable = validVec(i - 1) && rdyVec(i - 1) && !flushVec(i - 1) 9814521086SLinJiawei ) 9914521086SLinJiawei 10014521086SLinJiawei def S1Reg[TT <: Data](next: TT): TT = PipelineReg[TT](1)(next) 10114521086SLinJiawei 10214521086SLinJiawei def S2Reg[TT <: Data](next: TT): TT = PipelineReg[TT](2)(next) 10314521086SLinJiawei 10414521086SLinJiawei def S3Reg[TT <: Data](next: TT): TT = PipelineReg[TT](3)(next) 10514521086SLinJiawei 10614521086SLinJiawei def S4Reg[TT <: Data](next: TT): TT = PipelineReg[TT](4)(next) 10714521086SLinJiawei 10814521086SLinJiawei def S5Reg[TT <: Data](next: TT): TT = PipelineReg[TT](5)(next) 10914521086SLinJiawei} 110cafb3558SLinJiawei 111e18c367fSLinJiaweiobject FunctionUnit extends HasXSParameter { 112c84054caSLinJiawei 1135018a303SLinJiawei def divider = new SRT4Divider(XLEN) 11452c3f215SLinJiawei 1158a4dc19aSLinJiawei def multiplier = new ArrayMultiplier(XLEN + 1, Seq(0, 2)) 1163ff0763bSljw 117e18c367fSLinJiawei def alu = new Alu 118c84054caSLinJiawei 119e18c367fSLinJiawei def jmp = new Jump 12052c3f215SLinJiawei 121e18c367fSLinJiawei def fence = new Fence 12252c3f215SLinJiawei 123e18c367fSLinJiawei def csr = new CSR 12452c3f215SLinJiawei 125*7f1506e3SLinJiawei def i2f = new IntToFP 126cafb3558SLinJiawei 127e18c367fSLinJiawei def fmac = new FMA 12852c3f215SLinJiawei 129*7f1506e3SLinJiawei def f2i = new FPToInt 13052c3f215SLinJiawei 131*7f1506e3SLinJiawei def f2f = new FPToFP 13252c3f215SLinJiawei 133*7f1506e3SLinJiawei def fdivSqrt = new FDIvSqrt 134cafb3558SLinJiawei 13552c3f215SLinJiawei def fmiscSel(fu: String)(x: FunctionUnit): Bool = { 136e18c367fSLinJiawei x.io.in.bits.uop.ctrl.fuOpType.head(4) === s"b$fu".U 137e18c367fSLinJiawei } 138b8f08ca0SZhangZifei 139*7f1506e3SLinJiawei def f2iSel(x: FunctionUnit): Bool = { 140*7f1506e3SLinJiawei x.io.in.bits.uop.ctrl.fuType === FuType.i2f 141*7f1506e3SLinJiawei } 142*7f1506e3SLinJiawei 143*7f1506e3SLinJiawei def i2fSel(x: FunctionUnit): Bool = { 144*7f1506e3SLinJiawei x.io.in.bits.uop.ctrl.fpu.fromInt 145*7f1506e3SLinJiawei } 146*7f1506e3SLinJiawei 147*7f1506e3SLinJiawei def f2fSel(x: FunctionUnit): Bool = { 148*7f1506e3SLinJiawei val ctrl = x.io.in.bits.uop.ctrl.fpu 149*7f1506e3SLinJiawei ctrl.fpWen && !ctrl.div && !ctrl.sqrt 150*7f1506e3SLinJiawei } 151*7f1506e3SLinJiawei 152*7f1506e3SLinJiawei def fdivSqrtSel(x: FunctionUnit): Bool = { 153*7f1506e3SLinJiawei val ctrl = x.io.in.bits.uop.ctrl.fpu 154*7f1506e3SLinJiawei ctrl.div || ctrl.sqrt 155*7f1506e3SLinJiawei } 156*7f1506e3SLinJiawei 15752c3f215SLinJiawei val aluCfg = FuConfig( 15852c3f215SLinJiawei fuGen = alu _, 15952c3f215SLinJiawei fuSel = _ => true.B, 16052c3f215SLinJiawei fuType = FuType.alu, 16152c3f215SLinJiawei numIntSrc = 2, 16252c3f215SLinJiawei numFpSrc = 0, 16352c3f215SLinJiawei writeIntRf = true, 16452c3f215SLinJiawei writeFpRf = false, 16552c3f215SLinJiawei hasRedirect = true 16652c3f215SLinJiawei ) 16752c3f215SLinJiawei 16852c3f215SLinJiawei val jmpCfg = FuConfig( 16952c3f215SLinJiawei fuGen = jmp _, 17052c3f215SLinJiawei fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.jmp, 17152c3f215SLinJiawei fuType = FuType.jmp, 17252c3f215SLinJiawei numIntSrc = 1, 17352c3f215SLinJiawei numFpSrc = 0, 17452c3f215SLinJiawei writeIntRf = true, 17552c3f215SLinJiawei writeFpRf = false, 17652c3f215SLinJiawei hasRedirect = true 17752c3f215SLinJiawei ) 17852c3f215SLinJiawei 17952c3f215SLinJiawei val fenceCfg = FuConfig( 18052c3f215SLinJiawei fuGen = fence _, 18152c3f215SLinJiawei fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.fence, 1820bdd9eadSZhangZifei FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false, 1830bdd9eadSZhangZifei UncertainLatency() // TODO: need rewrite latency structure, not just this value 18452c3f215SLinJiawei ) 18552c3f215SLinJiawei 18652c3f215SLinJiawei val csrCfg = FuConfig( 18752c3f215SLinJiawei fuGen = csr _, 18852c3f215SLinJiawei fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.csr, 18952c3f215SLinJiawei fuType = FuType.csr, 19052c3f215SLinJiawei numIntSrc = 1, 19152c3f215SLinJiawei numFpSrc = 0, 19252c3f215SLinJiawei writeIntRf = true, 19352c3f215SLinJiawei writeFpRf = false, 19452c3f215SLinJiawei hasRedirect = false 19552c3f215SLinJiawei ) 19652c3f215SLinJiawei 19752c3f215SLinJiawei val i2fCfg = FuConfig( 19852c3f215SLinJiawei fuGen = i2f _, 199*7f1506e3SLinJiawei fuSel = i2fSel, 20052c3f215SLinJiawei FuType.i2f, 20152c3f215SLinJiawei numIntSrc = 1, 20252c3f215SLinJiawei numFpSrc = 0, 20352c3f215SLinJiawei writeIntRf = false, 20452c3f215SLinJiawei writeFpRf = true, 20552c3f215SLinJiawei hasRedirect = false, 20652c3f215SLinJiawei CertainLatency(0) 20752c3f215SLinJiawei ) 20852c3f215SLinJiawei 20952c3f215SLinJiawei val divCfg = FuConfig( 21052c3f215SLinJiawei fuGen = divider _, 21152c3f215SLinJiawei fuSel = (x: FunctionUnit) => MDUOpType.isDiv(x.io.in.bits.uop.ctrl.fuOpType), 21252c3f215SLinJiawei FuType.div, 21352c3f215SLinJiawei 2, 21452c3f215SLinJiawei 0, 21552c3f215SLinJiawei writeIntRf = true, 21652c3f215SLinJiawei writeFpRf = false, 21752c3f215SLinJiawei hasRedirect = false, 2183e60a357SLinJiawei UncertainLatency() 2193e60a357SLinJiawei ) 2206624015fSLinJiawei 22152c3f215SLinJiawei val mulCfg = FuConfig( 22252c3f215SLinJiawei fuGen = multiplier _, 22352c3f215SLinJiawei fuSel = (x: FunctionUnit) => MDUOpType.isMul(x.io.in.bits.uop.ctrl.fuOpType), 22452c3f215SLinJiawei FuType.mul, 22552c3f215SLinJiawei 2, 22652c3f215SLinJiawei 0, 22752c3f215SLinJiawei writeIntRf = true, 22852c3f215SLinJiawei writeFpRf = false, 22952c3f215SLinJiawei hasRedirect = false, 23052c3f215SLinJiawei CertainLatency(3) 23152c3f215SLinJiawei ) 23252c3f215SLinJiawei 23352c3f215SLinJiawei val fmacCfg = FuConfig( 23452c3f215SLinJiawei fuGen = fmac _, 23552c3f215SLinJiawei fuSel = _ => true.B, 23652c3f215SLinJiawei FuType.fmac, 0, 3, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(5) 23752c3f215SLinJiawei ) 23852c3f215SLinJiawei 23952c3f215SLinJiawei val f2iCfg = FuConfig( 24052c3f215SLinJiawei fuGen = f2i _, 241*7f1506e3SLinJiawei fuSel = f2iSel, 24252c3f215SLinJiawei FuType.fmisc, 0, 1, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(2) 24352c3f215SLinJiawei ) 24452c3f215SLinJiawei 245*7f1506e3SLinJiawei val f2fCfg = FuConfig( 246*7f1506e3SLinJiawei fuGen = f2f _, 247*7f1506e3SLinJiawei fuSel = f2iSel, 24852c3f215SLinJiawei FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(2) 24952c3f215SLinJiawei ) 25052c3f215SLinJiawei 25152c3f215SLinJiawei val fdivSqrtCfg = FuConfig( 25252c3f215SLinJiawei fuGen = fdivSqrt _, 253*7f1506e3SLinJiawei fuSel = fdivSqrtSel, 25452c3f215SLinJiawei FuType.fDivSqrt, 0, 2, writeIntRf = false, writeFpRf = true, hasRedirect = false, UncertainLatency() 25552c3f215SLinJiawei ) 25652c3f215SLinJiawei 25752c3f215SLinJiawei val lduCfg = FuConfig( 25852c3f215SLinJiawei null, // DontCare 25952c3f215SLinJiawei null, 26052c3f215SLinJiawei FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true, hasRedirect = false, 2613e60a357SLinJiawei UncertainLatency() 2623e60a357SLinJiawei ) 263cafb3558SLinJiawei 26452c3f215SLinJiawei val stuCfg = FuConfig( 26552c3f215SLinJiawei null, 26652c3f215SLinJiawei null, 26752c3f215SLinJiawei FuType.stu, 2, 1, writeIntRf = false, writeFpRf = false, hasRedirect = false, 26852c3f215SLinJiawei UncertainLatency() 26952c3f215SLinJiawei ) 27052c3f215SLinJiawei 27152c3f215SLinJiawei val mouCfg = FuConfig( 27252c3f215SLinJiawei null, 27352c3f215SLinJiawei null, 27452c3f215SLinJiawei FuType.mou, 2, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false, 2753e60a357SLinJiawei UncertainLatency() 2763e60a357SLinJiawei ) 277cafb3558SLinJiawei} 278