1cafb3558SLinJiaweipackage xiangshan.backend.fu 2cafb3558SLinJiawei 3cafb3558SLinJiaweiimport chisel3._ 4cafb3558SLinJiaweiimport chisel3.util._ 5cafb3558SLinJiaweiimport xiangshan._ 6e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu.divsqrt.DivSqrt 7e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu._ 8e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu.fma.FMA 9cafb3558SLinJiawei 10cafb3558SLinJiawei/* 11cafb3558SLinJiawei XiangShan Function Unit 12cafb3558SLinJiawei A Exu can have one or more function units 13cafb3558SLinJiawei */ 14cafb3558SLinJiawei 153e60a357SLinJiaweitrait HasFuLatency { 163e60a357SLinJiawei val latencyVal: Option[Int] 173e60a357SLinJiawei} 183e60a357SLinJiawei 193e60a357SLinJiaweicase class CertainLatency(value: Int) extends HasFuLatency{ 203e60a357SLinJiawei override val latencyVal: Option[Int] = Some(value) 213e60a357SLinJiawei} 223e60a357SLinJiawei 233e60a357SLinJiaweicase class UncertainLatency() extends HasFuLatency { 243e60a357SLinJiawei override val latencyVal: Option[Int] = None 253e60a357SLinJiawei} 263e60a357SLinJiawei 2716df83adSZhangZifei 2816df83adSZhangZifei 29cafb3558SLinJiaweicase class FuConfig 30cafb3558SLinJiawei( 31cafb3558SLinJiawei fuType: UInt, 32cafb3558SLinJiawei numIntSrc: Int, 33cafb3558SLinJiawei numFpSrc: Int, 34cafb3558SLinJiawei writeIntRf: Boolean, 35cafb3558SLinJiawei writeFpRf: Boolean, 363e60a357SLinJiawei hasRedirect: Boolean, 373e60a357SLinJiawei latency: HasFuLatency = CertainLatency(0) 3814521086SLinJiawei) { 3914521086SLinJiawei def srcCnt: Int = math.max(numIntSrc, numFpSrc) 40c84054caSLinJiawei} 41c84054caSLinJiawei 42e18c367fSLinJiawei 43e18c367fSLinJiawei 44e18c367fSLinJiaweiclass FuOutput extends XSBundle { 45e18c367fSLinJiawei val data = UInt(XLEN.W) 46e18c367fSLinJiawei val uop = new MicroOp 47e18c367fSLinJiawei} 48e18c367fSLinJiawei 49e18c367fSLinJiawei 5014521086SLinJiaweiclass FunctionUnitIO[TI <: Data, TO <: Data] 5114521086SLinJiawei( 5214521086SLinJiawei cfg: FuConfig, 53e18c367fSLinJiawei len: Int 5414521086SLinJiawei) extends XSBundle 5514521086SLinJiawei{ 5614521086SLinJiawei val in = Flipped(DecoupledIO(new Bundle() { 5714521086SLinJiawei val src = Vec(cfg.srcCnt, UInt(len.W)) 5814521086SLinJiawei val uop = new MicroOp 59ead41f51SLinJiawei 60ead41f51SLinJiawei def connectToExuInput(exuIn: ExuInput): Unit = { 61ead41f51SLinJiawei val exuSrcIn = Seq(exuIn.src1, exuIn.src2, exuIn.src3) 62ead41f51SLinJiawei src.zip(exuSrcIn).foreach{case (x, y) => x := y} 63ead41f51SLinJiawei uop := exuIn.uop 64ead41f51SLinJiawei } 6514521086SLinJiawei })) 66ead41f51SLinJiawei 67e18c367fSLinJiawei val out = DecoupledIO(new FuOutput) 68ead41f51SLinJiawei 6914521086SLinJiawei val redirectIn = Flipped(ValidIO(new Redirect)) 7012bb47ddSLinJiawei 7112bb47ddSLinJiawei override def cloneType: FunctionUnitIO.this.type = 72e18c367fSLinJiawei new FunctionUnitIO(cfg, len).asInstanceOf[this.type] 7314521086SLinJiawei} 7414521086SLinJiawei 75e18c367fSLinJiaweiabstract class FunctionUnit 7614521086SLinJiawei( 77e18c367fSLinJiawei val cfg: FuConfig, 78e18c367fSLinJiawei val len: Int = 64 7914521086SLinJiawei) extends XSModule { 8014521086SLinJiawei 81e18c367fSLinJiawei val io = IO(new FunctionUnitIO(cfg, len)) 8214521086SLinJiawei 8314521086SLinJiawei} 8414521086SLinJiawei 85e18c367fSLinJiaweitrait HasPipelineReg { this: FunctionUnit => 86e18c367fSLinJiawei 87e18c367fSLinJiawei require(cfg.latency.latencyVal.nonEmpty && cfg.latency.latencyVal.get > 0) 88e18c367fSLinJiawei val latency = cfg.latency.latencyVal.get 8914521086SLinJiawei 9014521086SLinJiawei val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B)) 9114521086SLinJiawei val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready 9214521086SLinJiawei val uopVec = io.in.bits.uop +: Array.fill(latency)(Reg(new MicroOp)) 9314521086SLinJiawei 9414521086SLinJiawei 953136ee6aSLinJiawei val flushVec = uopVec.zip(validVec).map(x => x._2 && x._1.roqIdx.needFlush(io.redirectIn)) 9614521086SLinJiawei 9714521086SLinJiawei for (i <- 0 until latency) { 9814521086SLinJiawei rdyVec(i) := !validVec(i + 1) || rdyVec(i + 1) 9914521086SLinJiawei } 10014521086SLinJiawei 10114521086SLinJiawei for (i <- 1 to latency) { 10214521086SLinJiawei when(flushVec(i - 1) || rdyVec(i) && !validVec(i - 1)) { 10314521086SLinJiawei validVec(i) := false.B 10414521086SLinJiawei }.elsewhen(rdyVec(i - 1) && validVec(i - 1) && !flushVec(i - 1)) { 10514521086SLinJiawei validVec(i) := validVec(i - 1) 10614521086SLinJiawei uopVec(i) := uopVec(i - 1) 10714521086SLinJiawei } 10814521086SLinJiawei } 10914521086SLinJiawei 11014521086SLinJiawei io.in.ready := rdyVec(0) 11114521086SLinJiawei io.out.valid := validVec.last && !flushVec.last 11214521086SLinJiawei io.out.bits.uop := uopVec.last 11314521086SLinJiawei 11414521086SLinJiawei def PipelineReg[TT <: Data](i: Int)(next: TT) = RegEnable( 11514521086SLinJiawei next, 11614521086SLinJiawei enable = validVec(i - 1) && rdyVec(i - 1) && !flushVec(i - 1) 11714521086SLinJiawei ) 11814521086SLinJiawei 11914521086SLinJiawei def S1Reg[TT <: Data](next: TT): TT = PipelineReg[TT](1)(next) 12014521086SLinJiawei 12114521086SLinJiawei def S2Reg[TT <: Data](next: TT): TT = PipelineReg[TT](2)(next) 12214521086SLinJiawei 12314521086SLinJiawei def S3Reg[TT <: Data](next: TT): TT = PipelineReg[TT](3)(next) 12414521086SLinJiawei 12514521086SLinJiawei def S4Reg[TT <: Data](next: TT): TT = PipelineReg[TT](4)(next) 12614521086SLinJiawei 12714521086SLinJiawei def S5Reg[TT <: Data](next: TT): TT = PipelineReg[TT](5)(next) 12814521086SLinJiawei} 129cafb3558SLinJiawei 130e18c367fSLinJiaweiobject FunctionUnit extends HasXSParameter { 131c84054caSLinJiawei 132*8a4dc19aSLinJiawei def multiplier = new ArrayMultiplier(XLEN+1, Seq(0, 2)) 133e18c367fSLinJiawei def divider = new Divider(XLEN) 134e18c367fSLinJiawei def alu = new Alu 135c84054caSLinJiawei 136e18c367fSLinJiawei def jmp = new Jump 137e18c367fSLinJiawei def fence = new Fence 138e18c367fSLinJiawei def csr = new CSR 139e18c367fSLinJiawei def i2f = new IntToFloatSingleCycle 140cafb3558SLinJiawei 141e18c367fSLinJiawei def fmac = new FMA 142e18c367fSLinJiawei def fcmp = new FCMP 143e18c367fSLinJiawei def fmv = new FMV(XLEN) 144e18c367fSLinJiawei def f2i = new FloatToInt 145e18c367fSLinJiawei def f32toF64 = new F32toF64 146e18c367fSLinJiawei def f64toF32 = new F64toF32 147e18c367fSLinJiawei def fdivSqrt = new DivSqrt 148cafb3558SLinJiawei 149e18c367fSLinJiawei def fmiscSel(fu: String)(x: FPUSubModule): Bool = { 150e18c367fSLinJiawei x.io.in.bits.uop.ctrl.fuOpType.head(4) === s"b$fu".U 151e18c367fSLinJiawei } 152b8f08ca0SZhangZifei 1536624015fSLinJiawei val lduCfg = 1543e60a357SLinJiawei FuConfig(FuType.ldu, 1, 0, writeIntRf = true, writeFpRf = true, hasRedirect = false, 1553e60a357SLinJiawei UncertainLatency() 1563e60a357SLinJiawei ) 1576624015fSLinJiawei 1586624015fSLinJiawei val stuCfg = 1593e60a357SLinJiawei FuConfig(FuType.stu, 2, 1, writeIntRf = false, writeFpRf = false, hasRedirect = false, 1603e60a357SLinJiawei UncertainLatency() 1613e60a357SLinJiawei ) 162cafb3558SLinJiawei 16368c44d2dSAllen val mouCfg = 1643e60a357SLinJiawei FuConfig(FuType.mou, 2, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false, 1653e60a357SLinJiawei UncertainLatency() 1663e60a357SLinJiawei ) 167cafb3558SLinJiawei} 168