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 38*e50fb2d7SLinJiaweiclass FuOutput(val len: Int) extends XSBundle { 39*e50fb2d7SLinJiawei val data = UInt(len.W) 40e18c367fSLinJiawei val uop = new MicroOp 41e18c367fSLinJiawei} 42e18c367fSLinJiawei 43e18c367fSLinJiawei 44*e50fb2d7SLinJiaweiclass FunctionUnitIO(val 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 50*e50fb2d7SLinJiawei val out = DecoupledIO(new FuOutput(len)) 51ead41f51SLinJiawei 5214521086SLinJiawei val redirectIn = Flipped(ValidIO(new Redirect)) 5314521086SLinJiawei} 5414521086SLinJiawei 5552c3f215SLinJiaweiabstract class FunctionUnit(len: Int = 64) extends XSModule { 5614521086SLinJiawei 5752c3f215SLinJiawei val io = IO(new FunctionUnitIO(len)) 5814521086SLinJiawei 5914521086SLinJiawei} 6014521086SLinJiawei 6152c3f215SLinJiaweitrait HasPipelineReg { 6252c3f215SLinJiawei this: FunctionUnit => 63e18c367fSLinJiawei 64f64ff6e8SLinJiawei def latency: Int 6552c3f215SLinJiawei 6652c3f215SLinJiawei require(latency > 0) 6714521086SLinJiawei 6814521086SLinJiawei val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B)) 6914521086SLinJiawei val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready 7014521086SLinJiawei val uopVec = io.in.bits.uop +: Array.fill(latency)(Reg(new MicroOp)) 7114521086SLinJiawei 7214521086SLinJiawei 733136ee6aSLinJiawei val flushVec = uopVec.zip(validVec).map(x => x._2 && x._1.roqIdx.needFlush(io.redirectIn)) 7414521086SLinJiawei 7514521086SLinJiawei for (i <- 0 until latency) { 7614521086SLinJiawei rdyVec(i) := !validVec(i + 1) || rdyVec(i + 1) 7714521086SLinJiawei } 7814521086SLinJiawei 7914521086SLinJiawei for (i <- 1 to latency) { 8014521086SLinJiawei when(flushVec(i - 1) || rdyVec(i) && !validVec(i - 1)) { 8114521086SLinJiawei validVec(i) := false.B 8214521086SLinJiawei }.elsewhen(rdyVec(i - 1) && validVec(i - 1) && !flushVec(i - 1)) { 8314521086SLinJiawei validVec(i) := validVec(i - 1) 8414521086SLinJiawei uopVec(i) := uopVec(i - 1) 8514521086SLinJiawei } 8614521086SLinJiawei } 8714521086SLinJiawei 8814521086SLinJiawei io.in.ready := rdyVec(0) 8914521086SLinJiawei io.out.valid := validVec.last && !flushVec.last 9014521086SLinJiawei io.out.bits.uop := uopVec.last 9114521086SLinJiawei 9214521086SLinJiawei def PipelineReg[TT <: Data](i: Int)(next: TT) = RegEnable( 9314521086SLinJiawei next, 9414521086SLinJiawei enable = validVec(i - 1) && rdyVec(i - 1) && !flushVec(i - 1) 9514521086SLinJiawei ) 9614521086SLinJiawei 9714521086SLinJiawei def S1Reg[TT <: Data](next: TT): TT = PipelineReg[TT](1)(next) 9814521086SLinJiawei 9914521086SLinJiawei def S2Reg[TT <: Data](next: TT): TT = PipelineReg[TT](2)(next) 10014521086SLinJiawei 10114521086SLinJiawei def S3Reg[TT <: Data](next: TT): TT = PipelineReg[TT](3)(next) 10214521086SLinJiawei 10314521086SLinJiawei def S4Reg[TT <: Data](next: TT): TT = PipelineReg[TT](4)(next) 10414521086SLinJiawei 10514521086SLinJiawei def S5Reg[TT <: Data](next: TT): TT = PipelineReg[TT](5)(next) 10614521086SLinJiawei} 107cafb3558SLinJiawei 108e18c367fSLinJiaweiobject FunctionUnit extends HasXSParameter { 109c84054caSLinJiawei 1105018a303SLinJiawei def divider = new SRT4Divider(XLEN) 11152c3f215SLinJiawei 1128a4dc19aSLinJiawei def multiplier = new ArrayMultiplier(XLEN + 1, Seq(0, 2)) 1133ff0763bSljw 114e18c367fSLinJiawei def alu = new Alu 115c84054caSLinJiawei 116e18c367fSLinJiawei def jmp = new Jump 11752c3f215SLinJiawei 118e18c367fSLinJiawei def fence = new Fence 11952c3f215SLinJiawei 120e18c367fSLinJiawei def csr = new CSR 12152c3f215SLinJiawei 1227f1506e3SLinJiawei def i2f = new IntToFP 123cafb3558SLinJiawei 124e18c367fSLinJiawei def fmac = new FMA 12552c3f215SLinJiawei 1267f1506e3SLinJiawei def f2i = new FPToInt 12752c3f215SLinJiawei 1287f1506e3SLinJiawei def f2f = new FPToFP 12952c3f215SLinJiawei 130*e50fb2d7SLinJiawei def fdivSqrt = new FDivSqrt 131b8f08ca0SZhangZifei 1327f1506e3SLinJiawei def f2iSel(x: FunctionUnit): Bool = { 133*e50fb2d7SLinJiawei x.io.in.bits.uop.ctrl.rfWen 1347f1506e3SLinJiawei } 1357f1506e3SLinJiawei 1367f1506e3SLinJiawei def i2fSel(x: FunctionUnit): Bool = { 1377f1506e3SLinJiawei x.io.in.bits.uop.ctrl.fpu.fromInt 1387f1506e3SLinJiawei } 1397f1506e3SLinJiawei 1407f1506e3SLinJiawei def f2fSel(x: FunctionUnit): Bool = { 1417f1506e3SLinJiawei val ctrl = x.io.in.bits.uop.ctrl.fpu 1427f1506e3SLinJiawei ctrl.fpWen && !ctrl.div && !ctrl.sqrt 1437f1506e3SLinJiawei } 1447f1506e3SLinJiawei 1457f1506e3SLinJiawei def fdivSqrtSel(x: FunctionUnit): Bool = { 1467f1506e3SLinJiawei val ctrl = x.io.in.bits.uop.ctrl.fpu 1477f1506e3SLinJiawei ctrl.div || ctrl.sqrt 1487f1506e3SLinJiawei } 1497f1506e3SLinJiawei 15052c3f215SLinJiawei val aluCfg = FuConfig( 15152c3f215SLinJiawei fuGen = alu _, 15252c3f215SLinJiawei fuSel = _ => true.B, 15352c3f215SLinJiawei fuType = FuType.alu, 15452c3f215SLinJiawei numIntSrc = 2, 15552c3f215SLinJiawei numFpSrc = 0, 15652c3f215SLinJiawei writeIntRf = true, 15752c3f215SLinJiawei writeFpRf = false, 15852c3f215SLinJiawei hasRedirect = true 15952c3f215SLinJiawei ) 16052c3f215SLinJiawei 16152c3f215SLinJiawei val jmpCfg = FuConfig( 16252c3f215SLinJiawei fuGen = jmp _, 16352c3f215SLinJiawei fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.jmp, 16452c3f215SLinJiawei fuType = FuType.jmp, 16552c3f215SLinJiawei numIntSrc = 1, 16652c3f215SLinJiawei numFpSrc = 0, 16752c3f215SLinJiawei writeIntRf = true, 16852c3f215SLinJiawei writeFpRf = false, 16952c3f215SLinJiawei hasRedirect = true 17052c3f215SLinJiawei ) 17152c3f215SLinJiawei 17252c3f215SLinJiawei val fenceCfg = FuConfig( 17352c3f215SLinJiawei fuGen = fence _, 17452c3f215SLinJiawei fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.fence, 1750bdd9eadSZhangZifei FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false, 1760bdd9eadSZhangZifei UncertainLatency() // TODO: need rewrite latency structure, not just this value 17752c3f215SLinJiawei ) 17852c3f215SLinJiawei 17952c3f215SLinJiawei val csrCfg = FuConfig( 18052c3f215SLinJiawei fuGen = csr _, 18152c3f215SLinJiawei fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.csr, 18252c3f215SLinJiawei fuType = FuType.csr, 18352c3f215SLinJiawei numIntSrc = 1, 18452c3f215SLinJiawei numFpSrc = 0, 18552c3f215SLinJiawei writeIntRf = true, 18652c3f215SLinJiawei writeFpRf = false, 18752c3f215SLinJiawei hasRedirect = false 18852c3f215SLinJiawei ) 18952c3f215SLinJiawei 19052c3f215SLinJiawei val i2fCfg = FuConfig( 19152c3f215SLinJiawei fuGen = i2f _, 1927f1506e3SLinJiawei fuSel = i2fSel, 19352c3f215SLinJiawei FuType.i2f, 19452c3f215SLinJiawei numIntSrc = 1, 19552c3f215SLinJiawei numFpSrc = 0, 19652c3f215SLinJiawei writeIntRf = false, 19752c3f215SLinJiawei writeFpRf = true, 19852c3f215SLinJiawei hasRedirect = false, 19952c3f215SLinJiawei CertainLatency(0) 20052c3f215SLinJiawei ) 20152c3f215SLinJiawei 20252c3f215SLinJiawei val divCfg = FuConfig( 20352c3f215SLinJiawei fuGen = divider _, 20452c3f215SLinJiawei fuSel = (x: FunctionUnit) => MDUOpType.isDiv(x.io.in.bits.uop.ctrl.fuOpType), 20552c3f215SLinJiawei FuType.div, 20652c3f215SLinJiawei 2, 20752c3f215SLinJiawei 0, 20852c3f215SLinJiawei writeIntRf = true, 20952c3f215SLinJiawei writeFpRf = false, 21052c3f215SLinJiawei hasRedirect = false, 2113e60a357SLinJiawei UncertainLatency() 2123e60a357SLinJiawei ) 2136624015fSLinJiawei 21452c3f215SLinJiawei val mulCfg = FuConfig( 21552c3f215SLinJiawei fuGen = multiplier _, 21652c3f215SLinJiawei fuSel = (x: FunctionUnit) => MDUOpType.isMul(x.io.in.bits.uop.ctrl.fuOpType), 21752c3f215SLinJiawei FuType.mul, 21852c3f215SLinJiawei 2, 21952c3f215SLinJiawei 0, 22052c3f215SLinJiawei writeIntRf = true, 22152c3f215SLinJiawei writeFpRf = false, 22252c3f215SLinJiawei hasRedirect = false, 22352c3f215SLinJiawei CertainLatency(3) 22452c3f215SLinJiawei ) 22552c3f215SLinJiawei 22652c3f215SLinJiawei val fmacCfg = FuConfig( 22752c3f215SLinJiawei fuGen = fmac _, 22852c3f215SLinJiawei fuSel = _ => true.B, 229*e50fb2d7SLinJiawei FuType.fmac, 0, 3, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(4) 23052c3f215SLinJiawei ) 23152c3f215SLinJiawei 23252c3f215SLinJiawei val f2iCfg = FuConfig( 23352c3f215SLinJiawei fuGen = f2i _, 2347f1506e3SLinJiawei fuSel = f2iSel, 23552c3f215SLinJiawei FuType.fmisc, 0, 1, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(2) 23652c3f215SLinJiawei ) 23752c3f215SLinJiawei 2387f1506e3SLinJiawei val f2fCfg = FuConfig( 2397f1506e3SLinJiawei fuGen = f2f _, 240*e50fb2d7SLinJiawei fuSel = f2fSel, 24152c3f215SLinJiawei FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(2) 24252c3f215SLinJiawei ) 24352c3f215SLinJiawei 24452c3f215SLinJiawei val fdivSqrtCfg = FuConfig( 24552c3f215SLinJiawei fuGen = fdivSqrt _, 2467f1506e3SLinJiawei fuSel = fdivSqrtSel, 24752c3f215SLinJiawei FuType.fDivSqrt, 0, 2, writeIntRf = false, writeFpRf = true, hasRedirect = false, UncertainLatency() 24852c3f215SLinJiawei ) 24952c3f215SLinJiawei 25052c3f215SLinJiawei val lduCfg = FuConfig( 25152c3f215SLinJiawei null, // DontCare 25252c3f215SLinJiawei null, 25352c3f215SLinJiawei FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true, hasRedirect = false, 2543e60a357SLinJiawei UncertainLatency() 2553e60a357SLinJiawei ) 256cafb3558SLinJiawei 25752c3f215SLinJiawei val stuCfg = FuConfig( 25852c3f215SLinJiawei null, 25952c3f215SLinJiawei null, 26052c3f215SLinJiawei FuType.stu, 2, 1, writeIntRf = false, writeFpRf = false, hasRedirect = false, 26152c3f215SLinJiawei UncertainLatency() 26252c3f215SLinJiawei ) 26352c3f215SLinJiawei 26452c3f215SLinJiawei val mouCfg = FuConfig( 26552c3f215SLinJiawei null, 26652c3f215SLinJiawei null, 26752c3f215SLinJiawei FuType.mou, 2, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false, 2683e60a357SLinJiawei UncertainLatency() 2693e60a357SLinJiawei ) 270cafb3558SLinJiawei} 271