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