1c6d43980SLemover/*************************************************************************************** 2c6d43980SLemover* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3f320e0f0SYinan Xu* Copyright (c) 2020-2021 Peng Cheng Laboratory 4c6d43980SLemover* 5c6d43980SLemover* XiangShan is licensed under Mulan PSL v2. 6c6d43980SLemover* You can use this software according to the terms and conditions of the Mulan PSL v2. 7c6d43980SLemover* You may obtain a copy of Mulan PSL v2 at: 8c6d43980SLemover* http://license.coscl.org.cn/MulanPSL2 9c6d43980SLemover* 10c6d43980SLemover* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11c6d43980SLemover* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12c6d43980SLemover* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13c6d43980SLemover* 14c6d43980SLemover* See the Mulan PSL v2 for more details. 15c6d43980SLemover***************************************************************************************/ 16c6d43980SLemover 17cafb3558SLinJiaweipackage xiangshan.backend.fu 18cafb3558SLinJiawei 192225d46eSJiawei Linimport chipsalliance.rocketchip.config.Parameters 20cafb3558SLinJiaweiimport chisel3._ 21cafb3558SLinJiaweiimport chisel3.util._ 22*1a2cf152SYinan Xuimport utils.XSPerfAccumulate 23cafb3558SLinJiaweiimport xiangshan._ 24e18c367fSLinJiaweiimport xiangshan.backend.fu.fpu._ 25cafb3558SLinJiawei 263e60a357SLinJiaweitrait HasFuLatency { 273e60a357SLinJiawei val latencyVal: Option[Int] 283e60a357SLinJiawei} 293e60a357SLinJiawei 303e60a357SLinJiaweicase class CertainLatency(value: Int) extends HasFuLatency { 313e60a357SLinJiawei override val latencyVal: Option[Int] = Some(value) 323e60a357SLinJiawei} 333e60a357SLinJiawei 343e60a357SLinJiaweicase class UncertainLatency() extends HasFuLatency { 353e60a357SLinJiawei override val latencyVal: Option[Int] = None 363e60a357SLinJiawei} 373e60a357SLinJiawei 3816df83adSZhangZifei 39cafb3558SLinJiaweicase class FuConfig 40cafb3558SLinJiawei( 411a0f06eeSYinan Xu name: String, 422225d46eSJiawei Lin fuGen: Parameters => FunctionUnit, 4352c3f215SLinJiawei fuSel: FunctionUnit => Bool, 44cafb3558SLinJiawei fuType: UInt, 45cafb3558SLinJiawei numIntSrc: Int, 46cafb3558SLinJiawei numFpSrc: Int, 47cafb3558SLinJiawei writeIntRf: Boolean, 48cafb3558SLinJiawei writeFpRf: Boolean, 493e60a357SLinJiawei hasRedirect: Boolean, 50c43ef4edSLinJiawei latency: HasFuLatency = CertainLatency(0), 5114521086SLinJiawei) { 5214521086SLinJiawei def srcCnt: Int = math.max(numIntSrc, numFpSrc) 53c84054caSLinJiawei} 54c84054caSLinJiawei 55e18c367fSLinJiawei 562225d46eSJiawei Linclass FuOutput(val len: Int)(implicit p: Parameters) extends XSBundle { 57e50fb2d7SLinJiawei val data = UInt(len.W) 58e18c367fSLinJiawei val uop = new MicroOp 59e18c367fSLinJiawei} 60e18c367fSLinJiawei 61e18c367fSLinJiawei 622225d46eSJiawei Linclass FunctionUnitIO(val len: Int)(implicit p: Parameters) extends XSBundle { 6314521086SLinJiawei val in = Flipped(DecoupledIO(new Bundle() { 6452c3f215SLinJiawei val src = Vec(3, UInt(len.W)) 6514521086SLinJiawei val uop = new MicroOp 6614521086SLinJiawei })) 67ead41f51SLinJiawei 68e50fb2d7SLinJiawei val out = DecoupledIO(new FuOutput(len)) 69ead41f51SLinJiawei 7014521086SLinJiawei val redirectIn = Flipped(ValidIO(new Redirect)) 712d7c7105SYinan Xu val flushIn = Input(Bool()) 7214521086SLinJiawei} 7314521086SLinJiawei 742225d46eSJiawei Linabstract class FunctionUnit(len: Int = 64)(implicit p: Parameters) extends XSModule { 7514521086SLinJiawei 7652c3f215SLinJiawei val io = IO(new FunctionUnitIO(len)) 7714521086SLinJiawei 78*1a2cf152SYinan Xu XSPerfAccumulate("in_valid", io.in.valid) 79*1a2cf152SYinan Xu XSPerfAccumulate("in_fire", io.in.fire) 80*1a2cf152SYinan Xu XSPerfAccumulate("out_valid", io.out.valid) 81*1a2cf152SYinan Xu XSPerfAccumulate("out_fire", io.out.fire) 82*1a2cf152SYinan Xu 8314521086SLinJiawei} 8414521086SLinJiawei 85adb5df20SYinan Xuabstract class FUWithRedirect(len: Int = 64)(implicit p: Parameters) extends FunctionUnit(len: Int) with HasRedirectOut 86adb5df20SYinan Xu 8752c3f215SLinJiaweitrait HasPipelineReg { 8852c3f215SLinJiawei this: FunctionUnit => 89e18c367fSLinJiawei 90f64ff6e8SLinJiawei def latency: Int 9152c3f215SLinJiawei 9252c3f215SLinJiawei require(latency > 0) 9314521086SLinJiawei 9414521086SLinJiawei val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B)) 9514521086SLinJiawei val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready 9614521086SLinJiawei val uopVec = io.in.bits.uop +: Array.fill(latency)(Reg(new MicroOp)) 9714521086SLinJiawei 9814521086SLinJiawei 99dfd9e0a8SLinJiawei // if flush(0), valid 0 will not given, so set flushVec(0) to false.B 1009b09132dSYinan Xu val flushVec = validVec.zip(uopVec).map(x => x._1 && x._2.roqIdx.needFlush(io.redirectIn, io.flushIn)) 10114521086SLinJiawei 10214521086SLinJiawei for (i <- 0 until latency) { 10314521086SLinJiawei rdyVec(i) := !validVec(i + 1) || rdyVec(i + 1) 10414521086SLinJiawei } 10514521086SLinJiawei 10614521086SLinJiawei for (i <- 1 to latency) { 10756477dc6SLinJiawei when(rdyVec(i - 1) && validVec(i - 1) && !flushVec(i - 1)){ 10814521086SLinJiawei validVec(i) := validVec(i - 1) 10914521086SLinJiawei uopVec(i) := uopVec(i - 1) 11056477dc6SLinJiawei }.elsewhen(flushVec(i) || rdyVec(i)){ 11156477dc6SLinJiawei validVec(i) := false.B 11214521086SLinJiawei } 11314521086SLinJiawei } 11414521086SLinJiawei 11514521086SLinJiawei io.in.ready := rdyVec(0) 116dfd9e0a8SLinJiawei io.out.valid := validVec.last 11714521086SLinJiawei io.out.bits.uop := uopVec.last 11814521086SLinJiawei 11975f32f6bSLinJiawei def regEnable(i: Int): Bool = validVec(i - 1) && rdyVec(i - 1) && !flushVec(i - 1) 12075f32f6bSLinJiawei 12114521086SLinJiawei def PipelineReg[TT <: Data](i: Int)(next: TT) = RegEnable( 12214521086SLinJiawei next, 12375f32f6bSLinJiawei enable = regEnable(i) 12414521086SLinJiawei ) 12514521086SLinJiawei 12614521086SLinJiawei def S1Reg[TT <: Data](next: TT): TT = PipelineReg[TT](1)(next) 12714521086SLinJiawei 12814521086SLinJiawei def S2Reg[TT <: Data](next: TT): TT = PipelineReg[TT](2)(next) 12914521086SLinJiawei 13014521086SLinJiawei def S3Reg[TT <: Data](next: TT): TT = PipelineReg[TT](3)(next) 13114521086SLinJiawei 13214521086SLinJiawei def S4Reg[TT <: Data](next: TT): TT = PipelineReg[TT](4)(next) 13314521086SLinJiawei 13414521086SLinJiawei def S5Reg[TT <: Data](next: TT): TT = PipelineReg[TT](5)(next) 13514521086SLinJiawei} 136