1package xiangshan.backend.fu 2 3import chipsalliance.rocketchip.config.Parameters 4import chisel3._ 5import xiangshan.ExceptionNO._ 6import xiangshan.SelImm 7import xiangshan.backend.Std 8import xiangshan.backend.fu.fpu.{FDivSqrt, FMA, FPToFP, FPToInt, IntToFP} 9import xiangshan.backend.fu.wrapper.{Alu, BranchUnit, DivUnit, JumpUnit, MulUnit, VSetRiWi, VSetRiWvf, VSetRvfWvf} 10import xiangshan.backend.Bundles.ExuInput 11import xiangshan.backend.datapath.DataConfig._ 12 13case class FuConfig ( 14 name: String, 15 fuType: Int, 16 fuGen: (Parameters, FuConfig) => FuncUnit, 17 srcData: Seq[Seq[DataConfig]], 18 writeIntRf: Boolean, 19 writeFpRf: Boolean, 20 writeVecRf: Boolean = false, 21 writeFflags: Boolean = false, 22 writeVxsat: Boolean = false, 23 dataBits: Int = 64, 24 latency: HasFuLatency = CertainLatency(0), 25 hasInputBuffer: (Boolean, Int, Boolean) = (false, 0, false), 26 exceptionOut: Seq[Int] = Seq(), 27 hasLoadError: Boolean = false, 28 flushPipe: Boolean = false, 29 replayInst: Boolean = false, 30 trigger: Boolean = false, 31 needSrcFrm: Boolean = false, 32 immType: Set[UInt] = Set(), 33) { 34 def numIntSrc : Int = srcData.map(_.count(x => IntRegSrcDataSet.contains(x))).max 35 def numFpSrc : Int = srcData.map(_.count(x => FpRegSrcDataSet.contains(x))).max 36 def numVecSrc : Int = srcData.map(_.count(x => VecRegSrcDataSet.contains(x))).max 37 def numVfSrc : Int = srcData.map(_.count(x => VfRegSrcDataSet.contains(x))).max 38 def numRegSrc : Int = srcData.map(_.count(x => RegSrcDataSet.contains(x))).max 39 def numSrc : Int = srcData.map(_.length).max 40 41 def readFp: Boolean = numFpSrc > 0 42 43 def fuSel(uop: ExuInput): Bool = { 44 // Don't add more shit here!!! 45 // Todo: add new FuType to distinguish f2i, f2f 46 if (this.fuType == FuType.fmisc) { 47 this.name match { 48 case FuConfig.F2iCfg.name => uop.rfWen.get 49 case FuConfig.F2fCfg.name => uop.fpu.get.fpWen && !uop.fpu.get.div && !uop.fpu.get.sqrt 50 } 51 } else { 52 uop.fuType === this.fuType.U 53 } 54 } 55 56 /** 57 * params(i): data type set of the ith src port 58 * @return 59 */ 60 def getRfReadDataCfgSet: Seq[Set[DataConfig]] = { 61 val numSrcMax = srcData.map(_.length).max 62 // make srcData is uniform sized to avoid exception when transpose 63 val alignedSrcData: Seq[Seq[DataConfig]] = srcData.map(x => x ++ Seq.fill(numSrcMax - x.length)(null)) 64 alignedSrcData.transpose.map(_.toSet.intersect(RegSrcDataSet)) 65 } 66 67 def getSrcDataType(srcIdx: Int): Set[DataConfig] = { 68 srcData 69 .map((x: Seq[DataConfig]) => if(x.isDefinedAt(srcIdx)) Some(x(srcIdx)) else None) 70 .filter(_.nonEmpty) 71 .map(_.get) 72 .toSet 73 } 74 75 def hasNoDataWB: Boolean = { 76 !(writeIntRf || writeFpRf || writeVecRf) 77 } 78 79 def getSrcMaxWidthVec = { 80 getRfReadDataCfgSet.map(_.map(_.dataWidth).max) 81 } 82 83 def genSrcDataVec: Seq[UInt] = { 84 getSrcMaxWidthVec.map(w => UInt(w.W)) 85 } 86 87 // csr's redirect is in its exception bundle 88 def hasRedirect: Boolean = Seq(FuType.jmp, FuType.brh).contains(fuType) 89 90 def hasPredecode: Boolean = Seq(FuType.jmp, FuType.brh, FuType.csr).contains(fuType) 91 92 def needPc: Boolean = Seq(FuType.jmp, FuType.brh, FuType.csr, FuType.fence).contains(fuType) 93 94 def needFPUCtrl: Boolean = { 95 import FuType._ 96 Set(fmac, fDivSqrt, fmisc, i2f).contains(fuType) 97 } 98 99 def isMul: Boolean = fuType == FuType.mul 100 101 def isDiv: Boolean = fuType == FuType.div 102 103 def isCsr: Boolean = fuType == FuType.csr 104 105 def isFence: Boolean = fuType == FuType.fence 106} 107 108object FuConfig { 109 val JmpCfg: FuConfig = FuConfig ( 110 name = "jmp", 111 fuType = FuType.jmp, 112 fuGen = (p: Parameters, cfg: FuConfig) => Module(new JumpUnit(cfg)(p)).suggestName("jmp"), 113 srcData = Seq( 114 Seq(IntData()), // jal 115 ), 116 writeIntRf = true, 117 writeFpRf = false, 118 immType = Set(SelImm.IMM_I, SelImm.IMM_UJ, SelImm.IMM_U), 119 ) 120 121 val BrhCfg: FuConfig = FuConfig ( 122 name = "brh", 123 fuType = FuType.brh, 124 fuGen = (p: Parameters, cfg: FuConfig) => Module(new BranchUnit(cfg)(p).suggestName("brh")), 125 srcData = Seq( 126 Seq(IntData(), IntData()), 127 ), 128 writeIntRf = false, 129 writeFpRf = false, 130 immType = Set(SelImm.IMM_SB), 131 ) 132 133 val I2fCfg: FuConfig = FuConfig ( 134 name = "i2f", 135 FuType.i2f, 136 fuGen = (p: Parameters, cfg: FuConfig) => Module(new IntToFP(cfg)(p).suggestName("i2f")), 137 srcData = Seq( 138 Seq(IntData()), 139 ), 140 writeIntRf = false, 141 writeFpRf = true, 142 writeFflags = true, 143 latency = CertainLatency(2), 144 needSrcFrm = true, 145 ) 146 147 val CsrCfg: FuConfig = FuConfig ( 148 name = "csr", 149 fuType = FuType.csr, 150 fuGen = (p: Parameters, cfg: FuConfig) => Module(new CSR(cfg)(p).suggestName("csr")), 151 srcData = Seq( 152 Seq(IntData()), 153 ), 154 writeIntRf = true, 155 writeFpRf = false, 156 exceptionOut = Seq(illegalInstr, breakPoint, ecallU, ecallS, ecallM), 157 flushPipe = true 158 ) 159 160 val AluCfg: FuConfig = FuConfig ( 161 name = "alu", 162 fuType = FuType.alu, 163 fuGen = (p: Parameters, cfg: FuConfig) => Module(new Alu(cfg)(p).suggestName("Alu")), 164 srcData = Seq( 165 Seq(IntData(), IntData()), 166 ), 167 writeIntRf = true, 168 writeFpRf = false, 169 immType = Set(SelImm.IMM_I, SelImm.IMM_U), 170 ) 171 172 val MulCfg: FuConfig = FuConfig ( 173 name = "mul", 174 fuType = FuType.mul, 175 fuGen = (p: Parameters, cfg: FuConfig) => Module(new MulUnit(cfg)(p).suggestName("Mul")), 176 srcData = Seq( 177 Seq(IntData(), IntData()), 178 ), 179 writeIntRf = true, 180 writeFpRf = false, 181 latency = CertainLatency(2), 182 ) 183 184 val DivCfg: FuConfig = FuConfig ( 185 name = "div", 186 fuType = FuType.div, 187 fuGen = (p: Parameters, cfg: FuConfig) => Module(new DivUnit(cfg)(p).suggestName("Div")), 188 srcData = Seq( 189 Seq(IntData(), IntData()), 190 ), 191 writeIntRf = true, 192 writeFpRf = false, 193 latency = UncertainLatency(), 194 hasInputBuffer = (true, 4, true) 195 ) 196 197 val FenceCfg: FuConfig = FuConfig ( 198 name = "fence", 199 FuType.fence, 200 fuGen = (p: Parameters, cfg: FuConfig) => Module(new Fence(cfg)(p).suggestName("Fence")), 201 srcData = Seq( 202 Seq(IntData(), IntData()), 203 ), 204 writeIntRf = false, 205 writeFpRf = false, 206 latency = UncertainLatency(), 207 exceptionOut = Seq(illegalInstr), 208 flushPipe = true 209 ) 210 211 // Todo: split it to simple bitmap exu and complex bku 212 val BkuCfg: FuConfig = FuConfig ( 213 name = "bku", 214 fuType = FuType.bku, 215 fuGen = (p: Parameters, cfg: FuConfig) => Module(new Bku(cfg)(p).suggestName("Bku")), 216 srcData = Seq( 217 Seq(IntData(), IntData()), 218 ), 219 writeIntRf = true, 220 writeFpRf = false, 221 latency = CertainLatency(1), 222 ) 223 224 val VSetRvfWvfCfg: FuConfig = FuConfig( 225 name = "vsetrvfwvf", 226 fuType = FuType.vsetiwf, 227 fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetRvfWvf(cfg)(p).suggestName("VSetRvfWvf")), 228 srcData = Seq( 229 Seq(FpData(), FpData()), 230 ), 231 writeIntRf = false, 232 writeFpRf = false, 233 writeVecRf = true, 234 latency = CertainLatency(0), 235 immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI), 236 ) 237 238 val VSetRiWvfCfg: FuConfig = FuConfig( 239 name = "vsetriwvf", 240 fuType = FuType.vsetiwf, 241 fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetRiWvf(cfg)(p).suggestName("VSetRiWvf")), 242 srcData = Seq( 243 Seq(IntData(), IntData()), 244 ), 245 writeIntRf = false, 246 writeFpRf = false, 247 writeVecRf = true, 248 latency = CertainLatency(0), 249 immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI), 250 ) 251 252 val VSetRiWiCfg: FuConfig = FuConfig( 253 name = "vsetriwi", 254 fuType = FuType.vsetiwi, 255 fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetRiWi(cfg)(p).suggestName("VSetRiWi")), 256 srcData = Seq( 257 Seq(IntData(), IntData()), 258 ), 259 writeIntRf = true, 260 writeFpRf = false, 261 latency = CertainLatency(0), 262 immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI), 263 ) 264 265 val FmacCfg: FuConfig = FuConfig ( 266 name = "fmac", 267 fuType = FuType.fmac, 268 fuGen = (p: Parameters, cfg: FuConfig) => Module(new FMA(cfg)(p).suggestName("FMac")), 269 srcData = Seq( 270 Seq(FpData(), FpData()), 271 Seq(FpData(), FpData(), FpData()), 272 ), 273 writeIntRf = false, 274 writeFpRf = true, 275 writeFflags = true, 276 latency = UncertainLatency(), 277 needSrcFrm = true, 278 ) 279 280 val F2iCfg: FuConfig = FuConfig ( 281 name = "f2i", 282 fuType = FuType.fmisc, 283 fuGen = (p: Parameters, cfg: FuConfig) => Module(new FPToInt(cfg)(p).suggestName("F2i")), 284 srcData = Seq( 285 Seq(FpData(), FpData()), 286 Seq(FpData()), 287 ), 288 writeIntRf = true, 289 writeFpRf = false, 290 writeFflags = true, 291 latency = CertainLatency(2), 292 needSrcFrm = true, 293 ) 294 295 val F2fCfg: FuConfig = FuConfig ( 296 name = "f2f", 297 fuType = FuType.fmisc, 298 fuGen = (p: Parameters, cfg: FuConfig) => Module(new FPToFP(cfg)(p).suggestName("F2f")), 299 srcData = Seq( 300 Seq(FpData(), FpData()), 301 Seq(FpData()), 302 ), 303 writeIntRf = false, 304 writeFpRf = true, 305 writeFflags = true, 306 latency = CertainLatency(2), 307 needSrcFrm = true, 308 ) 309 310 val FDivSqrtCfg: FuConfig = FuConfig ( 311 name = "fDivSqrt", 312 fuType = FuType.fDivSqrt, 313 fuGen = (p: Parameters, cfg: FuConfig) => Module(new FDivSqrt(cfg)(p).suggestName("FDivSqrt")), 314 srcData = Seq( 315 Seq(FpData(), FpData()), 316 ), 317 writeIntRf = false, 318 writeFpRf = true, 319 writeFflags = true, 320 latency = UncertainLatency(), 321 hasInputBuffer = (true, 8, true), 322 needSrcFrm = true, 323 ) 324 325 val LduCfg: FuConfig = FuConfig ( 326 name = "ldu", 327 fuType = FuType.ldu, 328 fuGen = null, // Todo 329 srcData = Seq( 330 Seq(IntData()), 331 ), 332 writeIntRf = true, 333 writeFpRf = true, 334 latency = UncertainLatency(), 335 exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault), 336 flushPipe = true, 337 replayInst = true, 338 hasLoadError = true, 339 immType = Set(SelImm.IMM_I), 340 ) 341 342 val StaCfg: FuConfig = FuConfig ( 343 name = "sta", 344 fuType = FuType.stu, 345 fuGen = null, // Todo 346 srcData = Seq( 347 Seq(IntData()), 348 ), 349 writeIntRf = false, 350 writeFpRf = false, 351 latency = UncertainLatency(), 352 exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault), 353 immType = Set(SelImm.IMM_S), 354 ) 355 356 val StdCfg: FuConfig = FuConfig ( 357 name = "std", 358 fuType = FuType.stu, 359 fuGen = (p: Parameters, cfg: FuConfig) => Module(new Std(cfg)(p).suggestName("Std")), 360 srcData = Seq( 361 Seq(IntData()), 362 Seq(FpData()), 363 ), 364 writeIntRf = false, 365 writeFpRf = false, 366 latency = CertainLatency(1), 367 exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault) 368 ) 369 370 val MouCfg: FuConfig = FuConfig ( 371 name = "mou", 372 fuType = FuType.mou, 373 fuGen = null, // Todo 374 srcData = Seq( 375 Seq(IntData()), 376 ), 377 writeIntRf = true, 378 writeFpRf = false, 379 latency = UncertainLatency(), 380 exceptionOut = (LduCfg.exceptionOut ++ StaCfg.exceptionOut ++ StdCfg.exceptionOut).distinct 381 ) 382 383 val MoudCfg: FuConfig = FuConfig ( 384 name = "moud", 385 fuType = FuType.mou, 386 fuGen = null, // Todo 387 srcData = Seq( 388 Seq(IntData()), 389 ), 390 writeIntRf = false, 391 writeFpRf = false, 392 latency = UncertainLatency() 393 ) 394 395 val VipuCfg: FuConfig = FuConfig ( 396 name = "vipu", 397 fuType = FuType.vipu, 398 fuGen = null, // Todo 399 srcData = Seq( 400 Seq(VecData(), VecData(), VecData(), MaskSrcData(), VConfigData()), // vs1, vs2, vd_old, v0 401 Seq(VecData(), VecData(), VecData(), VecData(), VConfigData()), // vs1_1, vs2, vs1_2, vs2_2 // no mask and vta 402 ), 403 writeIntRf = false, 404 writeFpRf = false, 405 writeVecRf = true, 406 latency = UncertainLatency(), 407 ) 408 409 val VfpuCfg: FuConfig = FuConfig ( 410 name = "vfpu", 411 fuType = FuType.vfpu, 412 fuGen = null, // Todo 413 srcData = Seq( 414 Seq(VecData(), VecData(), VecData(), MaskSrcData(), VConfigData()), // vs1, vs2, vd_old, v0 415 Seq(VecData(), VecData(), VecData(), VecData(), VConfigData()), // vs1_1, vs2, vs1_2, vs2_2 // no mask and vta 416 Seq(FpData(), VecData(), VecData(), MaskSrcData(), VConfigData()), // f[rs1], vs2, vd_old, v0 417 ), 418 writeIntRf = false, 419 writeFpRf = false, 420 writeVecRf = true, 421 latency = UncertainLatency(), 422 ) 423 // Todo 424 // def VlduCfg = FuConfig () 425 // def VstuCfg = FuConfig () 426 427} 428 429