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._ 221a2cf152SYinan 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, 43*6cdd85d9SYinan Xu fuSel: MicroOp => Bool, 44cafb3558SLinJiawei fuType: UInt, 45cafb3558SLinJiawei numIntSrc: Int, 46cafb3558SLinJiawei numFpSrc: Int, 47cafb3558SLinJiawei writeIntRf: Boolean, 48cafb3558SLinJiawei writeFpRf: Boolean, 493e60a357SLinJiawei hasRedirect: Boolean, 50c43ef4edSLinJiawei latency: HasFuLatency = CertainLatency(0), 51f83b578aSYinan Xu fastUopOut: Boolean = false, 52*6cdd85d9SYinan Xu fastImplemented: Boolean = false, 53*6cdd85d9SYinan Xu hasInputBuffer: Boolean = false 5414521086SLinJiawei) { 5514521086SLinJiawei def srcCnt: Int = math.max(numIntSrc, numFpSrc) 56c84054caSLinJiawei} 57c84054caSLinJiawei 58e18c367fSLinJiawei 592225d46eSJiawei Linclass FuOutput(val len: Int)(implicit p: Parameters) extends XSBundle { 60e50fb2d7SLinJiawei val data = UInt(len.W) 61e18c367fSLinJiawei val uop = new MicroOp 62e18c367fSLinJiawei} 63e18c367fSLinJiawei 64*6cdd85d9SYinan Xuclass FunctionUnitInput(val len: Int)(implicit p: Parameters) extends XSBundle { 6552c3f215SLinJiawei val src = Vec(3, UInt(len.W)) 6614521086SLinJiawei val uop = new MicroOp 67*6cdd85d9SYinan Xu} 68*6cdd85d9SYinan Xu 69*6cdd85d9SYinan Xuclass FunctionUnitIO(val len: Int)(implicit p: Parameters) extends XSBundle { 70*6cdd85d9SYinan Xu val in = Flipped(DecoupledIO(new FunctionUnitInput(len))) 71ead41f51SLinJiawei 72e50fb2d7SLinJiawei val out = DecoupledIO(new FuOutput(len)) 73ead41f51SLinJiawei 7414521086SLinJiawei val redirectIn = Flipped(ValidIO(new Redirect)) 752d7c7105SYinan Xu val flushIn = Input(Bool()) 7614521086SLinJiawei} 7714521086SLinJiawei 782225d46eSJiawei Linabstract class FunctionUnit(len: Int = 64)(implicit p: Parameters) extends XSModule { 7914521086SLinJiawei 8052c3f215SLinJiawei val io = IO(new FunctionUnitIO(len)) 8114521086SLinJiawei 821a2cf152SYinan Xu XSPerfAccumulate("in_valid", io.in.valid) 831a2cf152SYinan Xu XSPerfAccumulate("in_fire", io.in.fire) 841a2cf152SYinan Xu XSPerfAccumulate("out_valid", io.out.valid) 851a2cf152SYinan Xu XSPerfAccumulate("out_fire", io.out.fire) 861a2cf152SYinan Xu 8714521086SLinJiawei} 8814521086SLinJiawei 89adb5df20SYinan Xuabstract class FUWithRedirect(len: Int = 64)(implicit p: Parameters) extends FunctionUnit(len: Int) with HasRedirectOut 90adb5df20SYinan Xu 9152c3f215SLinJiaweitrait HasPipelineReg { 9252c3f215SLinJiawei this: FunctionUnit => 93e18c367fSLinJiawei 94f64ff6e8SLinJiawei def latency: Int 9552c3f215SLinJiawei 9652c3f215SLinJiawei require(latency > 0) 9714521086SLinJiawei 9814521086SLinJiawei val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B)) 99b2482bc1SYinan Xu val rdyVec = (Array.fill(latency - 1)(Wire(Bool())) :+ io.out.ready) :+ WireInit(true.B) 10014521086SLinJiawei val uopVec = io.in.bits.uop +: Array.fill(latency)(Reg(new MicroOp)) 10114521086SLinJiawei 10214521086SLinJiawei 103dfd9e0a8SLinJiawei // if flush(0), valid 0 will not given, so set flushVec(0) to false.B 1049b09132dSYinan Xu val flushVec = validVec.zip(uopVec).map(x => x._1 && x._2.roqIdx.needFlush(io.redirectIn, io.flushIn)) 10514521086SLinJiawei 106b2482bc1SYinan Xu for (i <- 0 until latency - 1) { 10714521086SLinJiawei rdyVec(i) := !validVec(i + 1) || rdyVec(i + 1) 10814521086SLinJiawei } 10914521086SLinJiawei 11014521086SLinJiawei for (i <- 1 to latency) { 11156477dc6SLinJiawei when(rdyVec(i - 1) && validVec(i - 1) && !flushVec(i - 1)){ 11214521086SLinJiawei validVec(i) := validVec(i - 1) 11314521086SLinJiawei uopVec(i) := uopVec(i - 1) 11456477dc6SLinJiawei }.elsewhen(flushVec(i) || rdyVec(i)){ 11556477dc6SLinJiawei validVec(i) := false.B 11614521086SLinJiawei } 11714521086SLinJiawei } 11814521086SLinJiawei 11914521086SLinJiawei io.in.ready := rdyVec(0) 120b2482bc1SYinan Xu io.out.valid := validVec.takeRight(2).head 121b2482bc1SYinan Xu io.out.bits.uop := uopVec.takeRight(2).head 12214521086SLinJiawei 12375f32f6bSLinJiawei def regEnable(i: Int): Bool = validVec(i - 1) && rdyVec(i - 1) && !flushVec(i - 1) 12475f32f6bSLinJiawei 12514521086SLinJiawei def PipelineReg[TT <: Data](i: Int)(next: TT) = RegEnable( 12614521086SLinJiawei next, 12775f32f6bSLinJiawei enable = regEnable(i) 12814521086SLinJiawei ) 12914521086SLinJiawei 13014521086SLinJiawei def S1Reg[TT <: Data](next: TT): TT = PipelineReg[TT](1)(next) 13114521086SLinJiawei 13214521086SLinJiawei def S2Reg[TT <: Data](next: TT): TT = PipelineReg[TT](2)(next) 13314521086SLinJiawei 13414521086SLinJiawei def S3Reg[TT <: Data](next: TT): TT = PipelineReg[TT](3)(next) 13514521086SLinJiawei 13614521086SLinJiawei def S4Reg[TT <: Data](next: TT): TT = PipelineReg[TT](4)(next) 13714521086SLinJiawei 13814521086SLinJiawei def S5Reg[TT <: Data](next: TT): TT = PipelineReg[TT](5)(next) 13914521086SLinJiawei} 140