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} 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 VsetCfg: FuConfig = FuConfig ( 224 name = "vset", 225 fuType = FuType.vset, 226 fuGen = null, // Todo 227 srcData = Seq( 228 Seq(IntData(), IntData()), 229 ), 230 writeIntRf = true, 231 writeFpRf = false, 232 latency = CertainLatency(0) 233 ) 234 235 val FmacCfg: FuConfig = FuConfig ( 236 name = "fmac", 237 fuType = FuType.fmac, 238 fuGen = (p: Parameters, cfg: FuConfig) => Module(new FMA(cfg)(p).suggestName("FMac")), 239 srcData = Seq( 240 Seq(FpData(), FpData()), 241 Seq(FpData(), FpData(), FpData()), 242 ), 243 writeIntRf = false, 244 writeFpRf = true, 245 writeFflags = true, 246 latency = UncertainLatency(), 247 needSrcFrm = true, 248 ) 249 250 val F2iCfg: FuConfig = FuConfig ( 251 name = "f2i", 252 fuType = FuType.fmisc, 253 fuGen = (p: Parameters, cfg: FuConfig) => Module(new FPToInt(cfg)(p).suggestName("F2i")), 254 srcData = Seq( 255 Seq(FpData(), FpData()), 256 Seq(FpData()), 257 ), 258 writeIntRf = true, 259 writeFpRf = false, 260 writeFflags = true, 261 latency = CertainLatency(2), 262 needSrcFrm = true, 263 ) 264 265 val F2fCfg: FuConfig = FuConfig ( 266 name = "f2f", 267 fuType = FuType.fmisc, 268 fuGen = (p: Parameters, cfg: FuConfig) => Module(new FPToFP(cfg)(p).suggestName("F2f")), 269 srcData = Seq( 270 Seq(FpData(), FpData()), 271 Seq(FpData()), 272 ), 273 writeIntRf = false, 274 writeFpRf = true, 275 writeFflags = true, 276 latency = CertainLatency(2), 277 needSrcFrm = true, 278 ) 279 280 val FDivSqrtCfg: FuConfig = FuConfig ( 281 name = "fDivSqrt", 282 fuType = FuType.fDivSqrt, 283 fuGen = (p: Parameters, cfg: FuConfig) => Module(new FDivSqrt(cfg)(p).suggestName("FDivSqrt")), 284 srcData = Seq( 285 Seq(FpData(), FpData()), 286 ), 287 writeIntRf = false, 288 writeFpRf = true, 289 writeFflags = true, 290 latency = UncertainLatency(), 291 hasInputBuffer = (true, 8, true), 292 needSrcFrm = true, 293 ) 294 295 val LduCfg: FuConfig = FuConfig ( 296 name = "ldu", 297 fuType = FuType.ldu, 298 fuGen = null, // Todo 299 srcData = Seq( 300 Seq(IntData()), 301 ), 302 writeIntRf = true, 303 writeFpRf = true, 304 latency = UncertainLatency(), 305 exceptionOut = Seq(loadAddrMisaligned, loadAccessFault, loadPageFault), 306 flushPipe = true, 307 replayInst = true, 308 hasLoadError = true, 309 immType = Set(SelImm.IMM_I), 310 ) 311 312 val StaCfg: FuConfig = FuConfig ( 313 name = "sta", 314 fuType = FuType.stu, 315 fuGen = null, // Todo 316 srcData = Seq( 317 Seq(IntData()), 318 ), 319 writeIntRf = false, 320 writeFpRf = false, 321 latency = UncertainLatency(), 322 exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault), 323 immType = Set(SelImm.IMM_S), 324 ) 325 326 val StdCfg: FuConfig = FuConfig ( 327 name = "std", 328 fuType = FuType.stu, 329 fuGen = (p: Parameters, cfg: FuConfig) => Module(new Std(cfg)(p).suggestName("Std")), 330 srcData = Seq( 331 Seq(IntData()), 332 Seq(FpData()), 333 ), 334 writeIntRf = false, 335 writeFpRf = false, 336 latency = CertainLatency(1), 337 exceptionOut = Seq(storeAddrMisaligned, storeAccessFault, storePageFault) 338 ) 339 340 val MouCfg: FuConfig = FuConfig ( 341 name = "mou", 342 fuType = FuType.mou, 343 fuGen = null, // Todo 344 srcData = Seq( 345 Seq(IntData()), 346 ), 347 writeIntRf = false, 348 writeFpRf = false, 349 latency = UncertainLatency(), 350 exceptionOut = (LduCfg.exceptionOut ++ StaCfg.exceptionOut ++ StdCfg.exceptionOut).distinct 351 ) 352 353 val MoudCfg: FuConfig = FuConfig ( 354 name = "moud", 355 fuType = FuType.mou, 356 fuGen = null, // Todo 357 srcData = Seq( 358 Seq(IntData()), 359 ), 360 writeIntRf = false, 361 writeFpRf = false, 362 latency = UncertainLatency() 363 ) 364 365 val VipuCfg: FuConfig = FuConfig ( 366 name = "vipu", 367 fuType = FuType.vipu, 368 fuGen = null, // Todo 369 srcData = Seq( 370 Seq(VecData(), VecData(), VecData(), MaskSrcData(), VConfigData()), // vs1, vs2, vd_old, v0 371 Seq(VecData(), VecData(), VecData(), VecData(), VConfigData()), // vs1_1, vs2, vs1_2, vs2_2 // no mask and vta 372 ), 373 writeIntRf = false, 374 writeFpRf = false, 375 writeVecRf = true, 376 latency = UncertainLatency(), 377 ) 378 379 val VfpuCfg: FuConfig = FuConfig ( 380 name = "vfpu", 381 fuType = FuType.vfpu, 382 fuGen = null, // Todo 383 srcData = Seq( 384 Seq(VecData(), VecData(), VecData(), MaskSrcData(), VConfigData()), // vs1, vs2, vd_old, v0 385 Seq(VecData(), VecData(), VecData(), VecData(), VConfigData()), // vs1_1, vs2, vs1_2, vs2_2 // no mask and vta 386 Seq(FpData(), VecData(), VecData(), MaskSrcData(), VConfigData()), // f[rs1], vs2, vd_old, v0 387 ), 388 writeIntRf = false, 389 writeFpRf = false, 390 writeVecRf = true, 391 latency = UncertainLatency(), 392 ) 393 // Todo 394 // def VlduCfg = FuConfig () 395 // def VstuCfg = FuConfig () 396 397} 398 399