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 = false, 19 writeFpRf: Boolean = false, 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 needVecCtrl: Boolean = { 100 import FuType._ 101 Set(vipu, vialuF, vfpu, vppu).contains(fuType) 102 } 103 104 def isMul: Boolean = fuType == FuType.mul 105 106 def isDiv: Boolean = fuType == FuType.div 107 108 def isCsr: Boolean = fuType == FuType.csr 109 110 def isFence: Boolean = fuType == FuType.fence 111} 112 113object FuConfig { 114 val JmpCfg: FuConfig = FuConfig ( 115 name = "jmp", 116 fuType = FuType.jmp, 117 fuGen = (p: Parameters, cfg: FuConfig) => Module(new JumpUnit(cfg)(p)).suggestName("jmp"), 118 srcData = Seq( 119 Seq(IntData()), // jal 120 ), 121 writeIntRf = true, 122 writeFpRf = false, 123 immType = Set(SelImm.IMM_I, SelImm.IMM_UJ, SelImm.IMM_U), 124 ) 125 126 val BrhCfg: FuConfig = FuConfig ( 127 name = "brh", 128 fuType = FuType.brh, 129 fuGen = (p: Parameters, cfg: FuConfig) => Module(new BranchUnit(cfg)(p).suggestName("brh")), 130 srcData = Seq( 131 Seq(IntData(), IntData()), 132 ), 133 writeIntRf = false, 134 writeFpRf = false, 135 immType = Set(SelImm.IMM_SB), 136 ) 137 138 val I2fCfg: FuConfig = FuConfig ( 139 name = "i2f", 140 FuType.i2f, 141 fuGen = (p: Parameters, cfg: FuConfig) => Module(new IntToFP(cfg)(p).suggestName("i2f")), 142 srcData = Seq( 143 Seq(IntData()), 144 ), 145 writeIntRf = false, 146 writeFpRf = true, 147 writeFflags = true, 148 latency = CertainLatency(2), 149 needSrcFrm = true, 150 ) 151 152 val CsrCfg: FuConfig = FuConfig ( 153 name = "csr", 154 fuType = FuType.csr, 155 fuGen = (p: Parameters, cfg: FuConfig) => Module(new CSR(cfg)(p).suggestName("csr")), 156 srcData = Seq( 157 Seq(IntData()), 158 ), 159 writeIntRf = true, 160 writeFpRf = false, 161 exceptionOut = Seq(illegalInstr, breakPoint, ecallU, ecallS, ecallM), 162 flushPipe = true 163 ) 164 165 val AluCfg: FuConfig = FuConfig ( 166 name = "alu", 167 fuType = FuType.alu, 168 fuGen = (p: Parameters, cfg: FuConfig) => Module(new Alu(cfg)(p).suggestName("Alu")), 169 srcData = Seq( 170 Seq(IntData(), IntData()), 171 ), 172 writeIntRf = true, 173 writeFpRf = false, 174 immType = Set(SelImm.IMM_I, SelImm.IMM_U), 175 ) 176 177 val MulCfg: FuConfig = FuConfig ( 178 name = "mul", 179 fuType = FuType.mul, 180 fuGen = (p: Parameters, cfg: FuConfig) => Module(new MulUnit(cfg)(p).suggestName("Mul")), 181 srcData = Seq( 182 Seq(IntData(), IntData()), 183 ), 184 writeIntRf = true, 185 writeFpRf = false, 186 latency = CertainLatency(2), 187 ) 188 189 val DivCfg: FuConfig = FuConfig ( 190 name = "div", 191 fuType = FuType.div, 192 fuGen = (p: Parameters, cfg: FuConfig) => Module(new DivUnit(cfg)(p).suggestName("Div")), 193 srcData = Seq( 194 Seq(IntData(), IntData()), 195 ), 196 writeIntRf = true, 197 writeFpRf = false, 198 latency = UncertainLatency(), 199 hasInputBuffer = (true, 4, true) 200 ) 201 202 val FenceCfg: FuConfig = FuConfig ( 203 name = "fence", 204 FuType.fence, 205 fuGen = (p: Parameters, cfg: FuConfig) => Module(new Fence(cfg)(p).suggestName("Fence")), 206 srcData = Seq( 207 Seq(IntData(), IntData()), 208 ), 209 writeIntRf = false, 210 writeFpRf = false, 211 latency = UncertainLatency(), 212 exceptionOut = Seq(illegalInstr), 213 flushPipe = true 214 ) 215 216 // Todo: split it to simple bitmap exu and complex bku 217 val BkuCfg: FuConfig = FuConfig ( 218 name = "bku", 219 fuType = FuType.bku, 220 fuGen = (p: Parameters, cfg: FuConfig) => Module(new Bku(cfg)(p).suggestName("Bku")), 221 srcData = Seq( 222 Seq(IntData(), IntData()), 223 ), 224 writeIntRf = true, 225 writeFpRf = false, 226 latency = CertainLatency(1), 227 ) 228 229 val VSetRvfWvfCfg: FuConfig = FuConfig( 230 name = "vsetrvfwvf", 231 fuType = FuType.vsetiwf, 232 fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetRvfWvf(cfg)(p).suggestName("VSetRvfWvf")), 233 srcData = Seq( 234 Seq(FpData(), FpData()), 235 ), 236 writeIntRf = false, 237 writeFpRf = false, 238 writeVecRf = true, 239 latency = CertainLatency(0), 240 immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI), 241 ) 242 243 val VSetRiWvfCfg: FuConfig = FuConfig( 244 name = "vsetriwvf", 245 fuType = FuType.vsetiwf, 246 fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetRiWvf(cfg)(p).suggestName("VSetRiWvf")), 247 srcData = Seq( 248 Seq(IntData(), IntData()), 249 ), 250 writeIntRf = false, 251 writeFpRf = false, 252 writeVecRf = true, 253 latency = CertainLatency(0), 254 immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI), 255 ) 256 257 val VSetRiWiCfg: FuConfig = FuConfig( 258 name = "vsetriwi", 259 fuType = FuType.vsetiwi, 260 fuGen = (p: Parameters, cfg: FuConfig) => Module(new VSetRiWi(cfg)(p).suggestName("VSetRiWi")), 261 srcData = Seq( 262 Seq(IntData(), IntData()), 263 ), 264 writeIntRf = true, 265 writeFpRf = false, 266 latency = CertainLatency(0), 267 immType = Set(SelImm.IMM_VSETVLI, SelImm.IMM_VSETIVLI), 268 ) 269 270 val FmacCfg: FuConfig = FuConfig ( 271 name = "fmac", 272 fuType = FuType.fmac, 273 fuGen = (p: Parameters, cfg: FuConfig) => Module(new FMA(cfg)(p).suggestName("FMac")), 274 srcData = Seq( 275 Seq(FpData(), FpData()), 276 Seq(FpData(), FpData(), FpData()), 277 ), 278 writeIntRf = false, 279 writeFpRf = true, 280 writeFflags = true, 281 latency = UncertainLatency(), 282 needSrcFrm = true, 283 ) 284 285 val F2iCfg: FuConfig = FuConfig ( 286 name = "f2i", 287 fuType = FuType.fmisc, 288 fuGen = (p: Parameters, cfg: FuConfig) => Module(new FPToInt(cfg)(p).suggestName("F2i")), 289 srcData = Seq( 290 Seq(FpData(), FpData()), 291 Seq(FpData()), 292 ), 293 writeIntRf = true, 294 writeFpRf = false, 295 writeFflags = true, 296 latency = CertainLatency(2), 297 needSrcFrm = true, 298 ) 299 300 val F2fCfg: FuConfig = FuConfig ( 301 name = "f2f", 302 fuType = FuType.fmisc, 303 fuGen = (p: Parameters, cfg: FuConfig) => Module(new FPToFP(cfg)(p).suggestName("F2f")), 304 srcData = Seq( 305 Seq(FpData(), FpData()), 306 Seq(FpData()), 307 ), 308 writeIntRf = false, 309 writeFpRf = true, 310 writeFflags = true, 311 latency = CertainLatency(2), 312 needSrcFrm = true, 313 ) 314 315 val FDivSqrtCfg: FuConfig = FuConfig ( 316 name = "fDivSqrt", 317 fuType = FuType.fDivSqrt, 318 fuGen = (p: Parameters, cfg: FuConfig) => Module(new FDivSqrt(cfg)(p).suggestName("FDivSqrt")), 319 srcData = Seq( 320 Seq(FpData(), FpData()), 321 ), 322 writeIntRf = false, 323 writeFpRf = true, 324 writeFflags = true, 325 latency = UncertainLatency(), 326 hasInputBuffer = (true, 8, true), 327 needSrcFrm = true, 328 ) 329 330 val LduCfg: FuConfig = FuConfig ( 331 name = "ldu", 332 fuType = FuType.ldu, 333 fuGen = null, // Todo 334 srcData = Seq( 335 Seq(IntData()), 336 ), 337 writeIntRf = true, 338 writeFpRf = true, 339 latency = UncertainLatency(), 340 exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault), 341 flushPipe = true, 342 replayInst = true, 343 hasLoadError = true, 344 immType = Set(SelImm.IMM_I), 345 ) 346 347 val StaCfg: FuConfig = FuConfig ( 348 name = "sta", 349 fuType = FuType.stu, 350 fuGen = null, // Todo 351 srcData = Seq( 352 Seq(IntData()), 353 ), 354 writeIntRf = false, 355 writeFpRf = false, 356 latency = UncertainLatency(), 357 exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault), 358 immType = Set(SelImm.IMM_S), 359 ) 360 361 val StdCfg: FuConfig = FuConfig ( 362 name = "std", 363 fuType = FuType.stu, 364 fuGen = (p: Parameters, cfg: FuConfig) => Module(new Std(cfg)(p).suggestName("Std")), 365 srcData = Seq( 366 Seq(IntData()), 367 Seq(FpData()), 368 ), 369 writeIntRf = false, 370 writeFpRf = false, 371 latency = CertainLatency(1), 372 exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault) 373 ) 374 375 val MouCfg: FuConfig = FuConfig ( 376 name = "mou", 377 fuType = FuType.mou, 378 fuGen = null, // Todo 379 srcData = Seq( 380 Seq(IntData()), 381 ), 382 writeIntRf = true, 383 writeFpRf = false, 384 latency = UncertainLatency(), 385 exceptionOut = (LduCfg.exceptionOut ++ StaCfg.exceptionOut ++ StdCfg.exceptionOut).distinct 386 ) 387 388 val MoudCfg: FuConfig = FuConfig ( 389 name = "moud", 390 fuType = FuType.mou, 391 fuGen = null, // Todo 392 srcData = Seq( 393 Seq(IntData()), 394 ), 395 writeIntRf = false, 396 writeFpRf = false, 397 latency = UncertainLatency() 398 ) 399 400 val Vialu = FuConfig ( 401 name = "vialu", 402 fuType = FuType.vialuF, 403 fuGen = null, 404 srcData = Seq( 405 Seq(VecData(), VecData(), VecData(), MaskSrcData(), VConfigData()), // vs1, vs2, vd_old, v0, vtype&vl 406 ), 407 writeVecRf = true, 408 latency = CertainLatency(1), 409 ) 410 411 val VipuCfg: FuConfig = FuConfig ( 412 name = "vipu", 413 fuType = FuType.vipu, 414 fuGen = null, // Todo 415 srcData = Seq( 416 Seq(VecData(), VecData(), VecData(), MaskSrcData(), VConfigData()), // vs1, vs2, vd_old, v0 417 Seq(VecData(), VecData(), VecData(), VecData(), VConfigData()), // vs1_1, vs2, vs1_2, vs2_2 // no mask and vta 418 ), 419 writeIntRf = false, 420 writeFpRf = false, 421 writeVecRf = true, 422 latency = UncertainLatency(), 423 ) 424 425 val VfpuCfg: FuConfig = FuConfig ( 426 name = "vfpu", 427 fuType = FuType.vfpu, 428 fuGen = null, // Todo 429 srcData = Seq( 430 Seq(VecData(), VecData(), VecData(), MaskSrcData(), VConfigData()), // vs1, vs2, vd_old, v0 431 Seq(VecData(), VecData(), VecData(), VecData(), VConfigData()), // vs1_1, vs2, vs1_2, vs2_2 // no mask and vta 432 Seq(FpData(), VecData(), VecData(), MaskSrcData(), VConfigData()), // f[rs1], vs2, vd_old, v0 433 ), 434 writeIntRf = false, 435 writeFpRf = false, 436 writeVecRf = true, 437 latency = UncertainLatency(), 438 ) 439 // Todo 440 // def VlduCfg = FuConfig () 441 // def VstuCfg = FuConfig () 442 443} 444 445