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 38e50fb2d7SLinJiaweiclass FuOutput(val len: Int) extends XSBundle { 39e50fb2d7SLinJiawei val data = UInt(len.W) 40e18c367fSLinJiawei val uop = new MicroOp 41e18c367fSLinJiawei} 42e18c367fSLinJiawei 43e18c367fSLinJiawei 44e50fb2d7SLinJiaweiclass 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 50e50fb2d7SLinJiawei 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 92*75f32f6bSLinJiawei def regEnable(i: Int): Bool = validVec(i - 1) && rdyVec(i - 1) && !flushVec(i - 1) 93*75f32f6bSLinJiawei 9414521086SLinJiawei def PipelineReg[TT <: Data](i: Int)(next: TT) = RegEnable( 9514521086SLinJiawei next, 96*75f32f6bSLinJiawei enable = regEnable(i) 9714521086SLinJiawei ) 9814521086SLinJiawei 9914521086SLinJiawei def S1Reg[TT <: Data](next: TT): TT = PipelineReg[TT](1)(next) 10014521086SLinJiawei 10114521086SLinJiawei def S2Reg[TT <: Data](next: TT): TT = PipelineReg[TT](2)(next) 10214521086SLinJiawei 10314521086SLinJiawei def S3Reg[TT <: Data](next: TT): TT = PipelineReg[TT](3)(next) 10414521086SLinJiawei 10514521086SLinJiawei def S4Reg[TT <: Data](next: TT): TT = PipelineReg[TT](4)(next) 10614521086SLinJiawei 10714521086SLinJiawei def S5Reg[TT <: Data](next: TT): TT = PipelineReg[TT](5)(next) 10814521086SLinJiawei} 109cafb3558SLinJiawei 110e18c367fSLinJiaweiobject FunctionUnit extends HasXSParameter { 111c84054caSLinJiawei 1125018a303SLinJiawei def divider = new SRT4Divider(XLEN) 11352c3f215SLinJiawei 1148a4dc19aSLinJiawei def multiplier = new ArrayMultiplier(XLEN + 1, Seq(0, 2)) 1153ff0763bSljw 116e18c367fSLinJiawei def alu = new Alu 117c84054caSLinJiawei 118e18c367fSLinJiawei def jmp = new Jump 11952c3f215SLinJiawei 120e18c367fSLinJiawei def fence = new Fence 12152c3f215SLinJiawei 122e18c367fSLinJiawei def csr = new CSR 12352c3f215SLinJiawei 1247f1506e3SLinJiawei def i2f = new IntToFP 125cafb3558SLinJiawei 126e18c367fSLinJiawei def fmac = new FMA 12752c3f215SLinJiawei 1287f1506e3SLinJiawei def f2i = new FPToInt 12952c3f215SLinJiawei 1307f1506e3SLinJiawei def f2f = new FPToFP 13152c3f215SLinJiawei 132e50fb2d7SLinJiawei def fdivSqrt = new FDivSqrt 133b8f08ca0SZhangZifei 1347f1506e3SLinJiawei def f2iSel(x: FunctionUnit): Bool = { 135e50fb2d7SLinJiawei x.io.in.bits.uop.ctrl.rfWen 1367f1506e3SLinJiawei } 1377f1506e3SLinJiawei 1387f1506e3SLinJiawei def i2fSel(x: FunctionUnit): Bool = { 1397f1506e3SLinJiawei x.io.in.bits.uop.ctrl.fpu.fromInt 1407f1506e3SLinJiawei } 1417f1506e3SLinJiawei 1427f1506e3SLinJiawei def f2fSel(x: FunctionUnit): Bool = { 1437f1506e3SLinJiawei val ctrl = x.io.in.bits.uop.ctrl.fpu 1447f1506e3SLinJiawei ctrl.fpWen && !ctrl.div && !ctrl.sqrt 1457f1506e3SLinJiawei } 1467f1506e3SLinJiawei 1477f1506e3SLinJiawei def fdivSqrtSel(x: FunctionUnit): Bool = { 1487f1506e3SLinJiawei val ctrl = x.io.in.bits.uop.ctrl.fpu 1497f1506e3SLinJiawei ctrl.div || ctrl.sqrt 1507f1506e3SLinJiawei } 1517f1506e3SLinJiawei 15252c3f215SLinJiawei val aluCfg = FuConfig( 15352c3f215SLinJiawei fuGen = alu _, 15452c3f215SLinJiawei fuSel = _ => true.B, 15552c3f215SLinJiawei fuType = FuType.alu, 15652c3f215SLinJiawei numIntSrc = 2, 15752c3f215SLinJiawei numFpSrc = 0, 15852c3f215SLinJiawei writeIntRf = true, 15952c3f215SLinJiawei writeFpRf = false, 16052c3f215SLinJiawei hasRedirect = true 16152c3f215SLinJiawei ) 16252c3f215SLinJiawei 16352c3f215SLinJiawei val jmpCfg = FuConfig( 16452c3f215SLinJiawei fuGen = jmp _, 16552c3f215SLinJiawei fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.jmp, 16652c3f215SLinJiawei fuType = FuType.jmp, 16752c3f215SLinJiawei numIntSrc = 1, 16852c3f215SLinJiawei numFpSrc = 0, 16952c3f215SLinJiawei writeIntRf = true, 17052c3f215SLinJiawei writeFpRf = false, 17152c3f215SLinJiawei hasRedirect = true 17252c3f215SLinJiawei ) 17352c3f215SLinJiawei 17452c3f215SLinJiawei val fenceCfg = FuConfig( 17552c3f215SLinJiawei fuGen = fence _, 17652c3f215SLinJiawei fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.fence, 1770bdd9eadSZhangZifei FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false, 1780bdd9eadSZhangZifei UncertainLatency() // TODO: need rewrite latency structure, not just this value 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 _, 1947f1506e3SLinJiawei fuSel = i2fSel, 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, 231e50fb2d7SLinJiawei FuType.fmac, 0, 3, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(4) 23252c3f215SLinJiawei ) 23352c3f215SLinJiawei 23452c3f215SLinJiawei val f2iCfg = FuConfig( 23552c3f215SLinJiawei fuGen = f2i _, 2367f1506e3SLinJiawei fuSel = f2iSel, 23752c3f215SLinJiawei FuType.fmisc, 0, 1, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(2) 23852c3f215SLinJiawei ) 23952c3f215SLinJiawei 2407f1506e3SLinJiawei val f2fCfg = FuConfig( 2417f1506e3SLinJiawei fuGen = f2f _, 242e50fb2d7SLinJiawei fuSel = f2fSel, 24352c3f215SLinJiawei FuType.fmisc, 0, 1, writeIntRf = false, writeFpRf = true, hasRedirect = false, CertainLatency(2) 24452c3f215SLinJiawei ) 24552c3f215SLinJiawei 24652c3f215SLinJiawei val fdivSqrtCfg = FuConfig( 24752c3f215SLinJiawei fuGen = fdivSqrt _, 2487f1506e3SLinJiawei fuSel = fdivSqrtSel, 24952c3f215SLinJiawei FuType.fDivSqrt, 0, 2, writeIntRf = false, writeFpRf = true, hasRedirect = false, UncertainLatency() 25052c3f215SLinJiawei ) 25152c3f215SLinJiawei 25252c3f215SLinJiawei val lduCfg = FuConfig( 25352c3f215SLinJiawei null, // DontCare 25452c3f215SLinJiawei null, 25552c3f215SLinJiawei FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true, hasRedirect = false, 2563e60a357SLinJiawei UncertainLatency() 2573e60a357SLinJiawei ) 258cafb3558SLinJiawei 25952c3f215SLinJiawei val stuCfg = FuConfig( 26052c3f215SLinJiawei null, 26152c3f215SLinJiawei null, 26252c3f215SLinJiawei FuType.stu, 2, 1, writeIntRf = false, writeFpRf = false, hasRedirect = false, 26352c3f215SLinJiawei UncertainLatency() 26452c3f215SLinJiawei ) 26552c3f215SLinJiawei 26652c3f215SLinJiawei val mouCfg = FuConfig( 26752c3f215SLinJiawei null, 26852c3f215SLinJiawei null, 26952c3f215SLinJiawei FuType.mou, 2, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false, 2703e60a357SLinJiawei UncertainLatency() 2713e60a357SLinJiawei ) 272cafb3558SLinJiawei} 273