1package xiangshan.backend 2 3import chisel3.util._ 4import chisel3._ 5import org.chipsalliance.cde.config.Parameters 6import utility._ 7import xiangshan._ 8import xiangshan.backend.fu.vector.Bundles._ 9 10class VecExcpDataMergeModule(implicit p: Parameters) extends XSModule { 11 private val MaxLMUL = 8 12 private val VdIdxInGroupWidth = log2Ceil(MaxLMUL) // hold 0~7 13 private val minElemLen = 8 // 8 bits 14 private val maxElemNumPerVreg = VLEN / minElemLen 15 private val tailZeroBit = log2Ceil(maxElemNumPerVreg) // 16 -> 4 16 17 val i = IO(Input(new Bundle { 18 val fromExceptionGen = ValidIO(new VecExcpInfo) 19 val fromRab = new RabToVecExcpMod 20 val fromRat = new RatToVecExcpMod 21 val fromVprf = new VprfToExcpMod(maxMergeNumPerCycle * 2) 22 })) 23 val o = IO(Output(new Bundle { 24 val toVPRF = new ExcpModToVprf(maxMergeNumPerCycle * 2, maxMergeNumPerCycle) 25 val status = new Bundle { 26 val busy = Bool() 27 } 28 })) 29 30 private val oldPregVecFromRat: Vec[ValidIO[UInt]] = Wire(Vec(RabCommitWidth, ValidIO(UInt(VfPhyRegIdxWidth.W)))) 31 oldPregVecFromRat.zipWithIndex.foreach { case (oldPreg: ValidIO[UInt], idx) => 32 val vecOldVd = i.fromRat.vecOldVdPdest(idx) 33 val v0OldVd = i.fromRat.v0OldVdPdest(idx) 34 oldPreg.valid := (vecOldVd.valid || v0OldVd.valid) 35 oldPreg.bits := Mux1H(Seq( 36 vecOldVd.valid -> vecOldVd.bits, 37 v0OldVd.valid -> v0OldVd.bits, 38 )) 39 } 40 41 private val lregNewPregVecFromRab = WireInit(i.fromRab.logicPhyRegMap) 42 43 private val preMergedOldVd = WireInit(VecInit(i.fromVprf.rdata.take(maxMergeNumPerCycle).map(_.bits.asTypeOf(new VecElemData(VLEN))))) 44 private val preMergedNewVd = WireInit(VecInit(i.fromVprf.rdata.drop(maxMergeNumPerCycle).map(_.bits.asTypeOf(new VecElemData(VLEN))))) 45 private val preMoveOldVd = WireInit(VecInit(i.fromVprf.rdata.map(_.bits.asTypeOf(new VecElemData(VLEN))))) 46 47 private val sNoExcp_vecExcpInfo = WireInit(i.fromExceptionGen) 48 private val sNoExcp_vemul = sNoExcp_vecExcpInfo.bits.vlmul + sNoExcp_vecExcpInfo.bits.veew - sNoExcp_vecExcpInfo.bits.vsew 49 // data vemul 50 private val sNoExcp_dvemul = Mux( 51 sNoExcp_vecExcpInfo.bits.isIndexed, 52 sNoExcp_vecExcpInfo.bits.vlmul, 53 sNoExcp_vemul, 54 ) 55 // index vemul 56 private val sNoExcp_ivemul = WireInit(VLmul(), sNoExcp_vemul) 57 dontTouch(sNoExcp_vemul) 58 dontTouch(sNoExcp_dvemul) 59 dontTouch(sNoExcp_ivemul) 60 private val sNoExcp_dvemulNoLessThanM1 = VLmul.makeNoLessThanM1(sNoExcp_dvemul).take(2) 61 private val sNoExcp_ivemulNoLessThanM1 = VLmul.makeNoLessThanM1(sNoExcp_ivemul).take(2) 62 63 // if ivemul - dvemul = idx 64 private val sNoExcp_vemul_i_d = VecInit.tabulate(4)(idx => 65 sNoExcp_ivemulNoLessThanM1 === (sNoExcp_dvemulNoLessThanM1 +& idx.U) || 66 (idx == 0).B && (sNoExcp_ivemulNoLessThanM1 < sNoExcp_dvemulNoLessThanM1) 67 ) 68 private val sNoExcp_nonSegIndexed = sNoExcp_vecExcpInfo.bits.isIndexed && sNoExcp_vecExcpInfo.bits.nf === 0.U 69 70 private val commitNeeded = RegInit(VecInit.fill(MaxLMUL)(false.B)) 71 private val rabCommitted = RegInit(VecInit.fill(MaxLMUL)(false.B)) 72 private val ratCommitted = RegInit(VecInit.fill(MaxLMUL)(false.B)) 73 private val hasReadRf = RegInit(VecInit.fill(MaxLMUL)(false.B)) 74 75 private val regMaps = Reg(Vec(MaxLMUL, new LogicPhyRegMap)) 76 77 private val currentIdx = RegInit(0.U(log2Up(8 + 1).W)) 78 private val currentIdxVec = (0 until maxMergeNumPerCycle).map(idx => currentIdx + idx.U) 79 80 private val mergedVd = Reg(Vec(maxMergeNumPerCycle, new VecElemData(VLEN))) 81 82 private val sNoExcp_eewOH = SewOH.convertFromVSew(sNoExcp_vecExcpInfo.bits.veew) 83 private val sNoExcp_sewOH = SewOH.convertFromVSew(sNoExcp_vecExcpInfo.bits.vsew) 84 private val sNoExcp_deewOH = Mux( 85 sNoExcp_vecExcpInfo.bits.isIndexed, 86 sNoExcp_sewOH, 87 sNoExcp_eewOH, 88 ) 89 private val sNoExcp_voffset = Module(new GetE8OffsetInVreg(VLEN))(sNoExcp_deewOH, sNoExcp_vecExcpInfo.bits.vstart) 90 private val sNoExcp_idxRangeVec: Vec[HWRange] = Module(new NfMappedElemIdx(VLEN))(sNoExcp_vecExcpInfo.bits.nf, sNoExcp_deewOH) 91 private val sNoExcp_vstartIsAligned: Bool = Mux(!sNoExcp_vecExcpInfo.bits.isVlm, sNoExcp_voffset === 0.U, false.B) 92 93 private val sNoExcp_inRangeVec: Vec[Bool] = VecInit((0 until 8).map(idx => 94 if (idx == 0) { 95 sNoExcp_vecExcpInfo.bits.isVlm || 96 sNoExcp_idxRangeVec(idx).inRange (sNoExcp_vecExcpInfo.bits.vstart) 97 } else { 98 !sNoExcp_vecExcpInfo.bits.isVlm && 99 sNoExcp_idxRangeVec(idx).inRange (sNoExcp_vecExcpInfo.bits.vstart) 100 } 101 )) 102 // The last no exception vdIdx, hold 0~7. 103 // No need to hold 8, since if all vd are new, there is no exception occuration. 104 private val sNoExcp_useNewVdUntil: UInt = PriorityEncoder(sNoExcp_inRangeVec) 105 // The last exception vdIdx, hold 0~8. 106 // Need to hold 8. 107 private val sNoExcp_needMergeUntil: UInt = sNoExcp_useNewVdUntil + sNoExcp_vecExcpInfo.bits.nf +& 1.U 108 // the max vd idx need to write 109 private val sNoExcp_maxVdIdx = Mux( 110 sNoExcp_vecExcpInfo.valid, 111 MuxCase( 112 default = ((sNoExcp_vecExcpInfo.bits.nf +& 1.U) << sNoExcp_dvemulNoLessThanM1).asUInt, 113 Seq( 114 sNoExcp_vecExcpInfo.bits.isVlm -> 1.U, 115 sNoExcp_vecExcpInfo.bits.isWhole -> (sNoExcp_vecExcpInfo.bits.nf +& 1.U), 116 ) 117 ), 118 0.U 119 ) 120 121 private val sNoExcp_handleUntil = sNoExcp_maxVdIdx(3, 0) // [1, 8] 122 // strided vector load need 2 uop to move data, so skip these reg maps 123 private val sNoExcp_writeOffset = Mux(sNoExcp_vecExcpInfo.bits.isStride, 2.U, 1.U) 124 125 private val sWaitRab_vecExcpInfo = RegNextWithEnable(sNoExcp_vecExcpInfo) 126 127 // At the beginning of waitRab, 128 // when not offset not aligned, currentIdx = useNewVdUntil <= needMergeUntil <= handleUntil 129 // otherwise, currentIdx = needMergeUntil <= handleUntil 130 private val sWaitRab_useNewVdUntil = RegEnable(sNoExcp_useNewVdUntil, sNoExcp_vecExcpInfo.valid) 131 private val sWaitRab_needMergeUntil = RegEnable(sNoExcp_needMergeUntil, sNoExcp_vecExcpInfo.valid) 132 private val sWaitRab_e8offset = RegEnable( 133 Mux1H((0 until 4).map(idx => sNoExcp_deewOH(idx) -> ZeroExt(sNoExcp_voffset(tailZeroBit - 1, 0), tailZeroBit))), 134 sNoExcp_vecExcpInfo.valid 135 ) 136 private val sWaitRab_idxRangeVec = RegEnable(sNoExcp_idxRangeVec, sNoExcp_vecExcpInfo.valid) 137 private val sWaitRab_vstartIsAligned = RegEnable(sNoExcp_vstartIsAligned, sNoExcp_vecExcpInfo.valid) 138 private val sWaitRab_handleUntil = RegEnable(sNoExcp_handleUntil, sNoExcp_vecExcpInfo.valid) 139 140 private val sWaitRab_nonSegIndexed = RegEnable(sNoExcp_nonSegIndexed, sNoExcp_vecExcpInfo.valid) 141 private val sWaitRab_vemul_i_d = RegEnable(sNoExcp_vemul_i_d, sNoExcp_vecExcpInfo.valid) 142 private val sWaitRab_dvemulNoLessThanM1 = RegEnable(sNoExcp_dvemulNoLessThanM1, sNoExcp_vecExcpInfo.valid) 143 144 private val sWaitRab_rabWriteOffset = Reg(UInt(4.W)) // [1,10] 145 private val sWaitRab_ratWriteOffset = Reg(UInt(4.W)) // [1,10] 146 147 // segShuffledRegIdxTable(nf)(dvemul)(vdIdx) 148 private val segShuffledRegIdxTable: Seq[Seq[Seq[Int]]] = Seq.tabulate(8, 4) { 149 case (nf, dvemul) => 150 val nField = nf + 1 // 1~8 151 val dEMUL = 1 << dvemul // 1, 2, 4, 8 152 if (nField == 2 && dEMUL == 2) { 153 Seq(0, 2, 1, 3, 0, 0, 0, 0) 154 } 155 else if (nField == 2 && dEMUL == 4) { 156 Seq(0, 4, 1, 5, 2, 6, 3, 7) 157 } 158 else if (nField == 3 && dEMUL == 2) { 159 Seq(0, 2, 4, 1, 3, 5, 0, 0) 160 } 161 else if (nField == 4 && dEMUL == 2) { 162 Seq(0, 2, 4, 6, 1, 3, 5, 7) 163 } 164 else { 165 Seq(0, 1, 2, 3, 4, 5, 6, 7) 166 } 167 } 168 private val segRegTableHW: Vec[Vec[Vec[UInt]]] = WireInit(VecInit.tabulate(8, 4) { 169 case (nf, dvemul) => VecInit(segShuffledRegIdxTable(nf)(dvemul).map(_.U(VdIdxInGroupWidth.W))) 170 }) 171 172 // when nonSegIndexed load, iemul/demul = 1 << 2, vdLoc will be mapped as (0, 1, 2, 3, ...) -> (0, 4, ...) 173 private val oldVdLocVec: Vec[UInt] = VecInit(currentIdxVec.map(idx => 174 Mux( 175 sWaitRab_nonSegIndexed, 176 Mux1H(sWaitRab_vemul_i_d.zipWithIndex.map { case (i_d_n, ii) => i_d_n -> (idx << ii).asUInt }), 177 Mux( 178 sWaitRab_vecExcpInfo.bits.isWhole, 179 idx, 180 segRegTableHW(sWaitRab_vecExcpInfo.bits.nf)(sWaitRab_dvemulNoLessThanM1)(idx), 181 ) 182 ).take(VdIdxInGroupWidth) 183 )) 184 185 // when nonSegIndexed load, iemul/demul = 1 << 2, vdLoc will be mapped as (0, 1, 2, 3, ...) -> (3, 7, ...) 186 private val newVdLocVec = VecInit(currentIdxVec.map(idx => 187 Mux( 188 sWaitRab_nonSegIndexed, 189 Mux1H(sWaitRab_vemul_i_d.zipWithIndex.map { case (i_d_n, ii) => i_d_n -> ((idx << ii).asUInt | ((1 << ii) - 1).U) }), 190 Mux( 191 sWaitRab_vecExcpInfo.bits.isWhole, 192 idx, 193 segRegTableHW(sWaitRab_vecExcpInfo.bits.nf)(sWaitRab_dvemulNoLessThanM1)(idx), 194 ) 195 ).take(VdIdxInGroupWidth) 196 )) 197 198 dontTouch(oldVdLocVec) 199 dontTouch(newVdLocVec) 200 201 private object State extends ChiselEnum { 202 val noExcp = Value 203 val waitRab = Value 204 val mergeVd = Value 205 val mvOldVd = Value 206 val finish = Value 207 } 208 209 private val state: State.Type = RegInit(State.noExcp) 210 private val stateNext = WireInit(state) 211 state := stateNext 212 213 private val collectedAllRegMap = Wire(Bool()) 214 private val mergeFinished = currentIdx >= sWaitRab_needMergeUntil 215 private val mvFinished = currentIdx >= sWaitRab_handleUntil 216 217 // get lreg and new preg, the last mapped newPdest 218 private val filteredRabCommitedVec: Vec[Vec[Bool]] = WireInit(VecInit.tabulate(4, MaxLMUL) { case (i_d_n, vdIdx) => 219 val vdLoc = ((vdIdx + 1) << i_d_n) - 1 220 rabCommitted(if (vdLoc >= MaxLMUL) 0 else vdLoc) 221 }) 222 // get old preg, the first mapped oldPdest 223 private val filteredRatCommitedVec: Vec[Vec[Bool]] = WireInit(VecInit.tabulate(4, MaxLMUL) { case (i_d_n, vdIdx) => 224 val vdLoc = vdIdx << i_d_n 225 ratCommitted(if (vdLoc >= MaxLMUL) 0 else vdLoc) 226 }) 227 228 private val filteredRabCommited = Wire(Vec(MaxLMUL, Bool())) 229 private val filteredRatCommited = Wire(Vec(MaxLMUL, Bool())) 230 when (sWaitRab_nonSegIndexed) { 231 filteredRabCommited := Mux1H(sWaitRab_vemul_i_d, filteredRabCommitedVec) 232 filteredRatCommited := Mux1H(sWaitRab_vemul_i_d, filteredRatCommitedVec) 233 }.otherwise { 234 // No need to shuffle, since the vdIdx always compressed towards zero and left tail unused. 235 filteredRabCommited := rabCommitted 236 filteredRatCommited := ratCommitted 237 } 238 239 // 1. no need commit 240 // 2. need commit and both rab and rat committed 241 collectedAllRegMap := ((~commitNeeded.asUInt).asUInt | (commitNeeded.asUInt & filteredRabCommited.asUInt & filteredRatCommited.asUInt)).andR 242 243 switch(state) { 244 is(State.noExcp) { 245 when (i.fromExceptionGen.valid) { 246 stateNext := State.waitRab 247 } 248 } 249 is(State.waitRab) { 250 when (collectedAllRegMap) { 251 stateNext := State.mergeVd 252 currentIdx := sWaitRab_useNewVdUntil 253 } 254 } 255 is(State.mergeVd) { 256 when (mvFinished) { 257 stateNext := State.finish 258 }.elsewhen (mergeFinished) { 259 stateNext := State.mvOldVd 260 } 261 when(o.toVPRF.w.head.valid) { 262 currentIdx := currentIdx + PopCount(o.toVPRF.w.map(_.valid)) 263 } 264 } 265 is(State.mvOldVd) { 266 when (mvFinished) { 267 stateNext := State.finish 268 } 269 when(o.toVPRF.w.head.valid) { 270 currentIdx := currentIdx + PopCount(o.toVPRF.w.map(_.valid)) 271 } 272 } 273 is(State.finish) { 274 stateNext := State.noExcp 275 currentIdx := 0.U 276 } 277 } 278 279 private val regWriteFromRabVec: Vec[ValidIO[RegWriteFromRab]] = i.fromRab.logicPhyRegMap 280 private val regWriteFromRatVec: Vec[ValidIO[UInt]] = oldPregVecFromRat 281 282 val mergedVdWData: Vec[VecE8Vec] = Wire(Vec(maxMergeNumPerCycle, new VecE8Vec(VLEN))) 283 mergedVdWData.zipWithIndex.foreach { case (vd, vIdx) => 284 vd.data.zipWithIndex.foreach { case (vde, eIdx) => 285 vde := Mux( 286 state === State.mergeVd, 287 Mux( 288 eIdx.U >= sWaitRab_e8offset, 289 preMergedOldVd(vIdx).e8Vec(eIdx), 290 preMergedNewVd(vIdx).e8Vec(eIdx), 291 ), 292 preMoveOldVd(vIdx).e8Vec(eIdx), 293 ) 294 } 295 } 296 297 private val hasRabWrite = regWriteFromRabVec.head.valid 298 private val hasRatWrite = regWriteFromRatVec.head.valid 299 require( 300 2 * RabCommitWidth >= (MaxLMUL + 2), 301 "Cannot receive all 10 reg maps from RAB and RAT in two cycles. " + 302 "This module should be rewrited to support more than 2 cycles receiving" 303 ) 304 305 switch (state) { 306 is (State.noExcp) { 307 when (stateNext === State.waitRab) { 308 sWaitRab_rabWriteOffset := 0.U 309 sWaitRab_ratWriteOffset := 0.U 310 commitNeeded.zipWithIndex.foreach { case (needed, idx) => 311 needed := sNoExcp_maxVdIdx > idx.U 312 } 313 } 314 } 315 is (State.waitRab) { 316 when (hasRabWrite) { 317 sWaitRab_rabWriteOffset := sWaitRab_rabWriteOffset + 318 PriorityMux((0 until RabCommitWidth).map( 319 idx => i.fromRab.logicPhyRegMap.reverse(idx).valid -> (6 - idx).U 320 )) 321 } 322 when (hasRatWrite) { 323 sWaitRab_ratWriteOffset := sWaitRab_ratWriteOffset + 324 PriorityMux((0 until RabCommitWidth).map( 325 idx => regWriteFromRatVec.reverse(idx).valid -> (6 - idx).U 326 )) 327 } 328 329 when(sWaitRab_rabWriteOffset === 0.U) { 330 // the first patch of RAB commit consider offset 331 when(sWaitRab_vecExcpInfo.bits.isStride) { 332 (2 until RabCommitWidth).map { idx => 333 val vdIdx = idx - 2 334 when(regWriteFromRabVec(idx).valid) { 335 regMaps(vdIdx).lreg := regWriteFromRabVec(idx).bits.lreg 336 regMaps(vdIdx).newPreg := regWriteFromRabVec(idx).bits.preg 337 rabCommitted(vdIdx) := true.B 338 } 339 } 340 }.otherwise { 341 (1 until RabCommitWidth).map { idx => 342 val vdIdx = idx - 1 343 when(regWriteFromRabVec(idx).valid) { 344 regMaps(vdIdx).lreg := regWriteFromRabVec(idx).bits.lreg 345 regMaps(vdIdx).newPreg := regWriteFromRabVec(idx).bits.preg 346 rabCommitted(vdIdx) := true.B 347 } 348 } 349 } 350 }.otherwise { 351 // the second patch of RAB/RAT commit need no offset 352 when(sWaitRab_vecExcpInfo.bits.isStride) { 353 (0 until (MaxLMUL + 2 - RabCommitWidth)).map { idx => 354 val vdIdx = idx - 2 + RabCommitWidth 355 when(regWriteFromRabVec(idx).valid) { 356 regMaps(vdIdx).lreg := regWriteFromRabVec(idx).bits.lreg 357 regMaps(vdIdx).newPreg := regWriteFromRabVec(idx).bits.preg 358 rabCommitted(vdIdx) := true.B 359 } 360 } 361 }.otherwise { 362 (0 until MaxLMUL + 1 - RabCommitWidth).map { idx => 363 val vdIdx = idx - 1 + RabCommitWidth 364 when(regWriteFromRabVec(idx).valid) { 365 regMaps(vdIdx).lreg := regWriteFromRabVec(idx).bits.lreg 366 regMaps(vdIdx).newPreg := regWriteFromRabVec(idx).bits.preg 367 rabCommitted(vdIdx) := true.B 368 } 369 } 370 } 371 } 372 373 when (sWaitRab_ratWriteOffset === 0.U) { 374 // the first patch of RAT commit consider offset 375 when(sWaitRab_vecExcpInfo.bits.isStride) { 376 (2 until RabCommitWidth).map { idx => 377 val vdIdx = idx - 2 378 when(regWriteFromRatVec(idx).valid) { 379 regMaps(vdIdx).oldPreg := regWriteFromRatVec(idx).bits 380 ratCommitted(vdIdx) := true.B 381 } 382 } 383 }.otherwise { 384 (1 until RabCommitWidth).map { idx => 385 val vdIdx = idx - 1 386 when(regWriteFromRatVec(idx).valid) { 387 regMaps(vdIdx).oldPreg := regWriteFromRatVec(idx).bits 388 ratCommitted(vdIdx) := true.B 389 } 390 } 391 } 392 }.otherwise { 393 // the second patch of RAT commit need no offset 394 when(sWaitRab_vecExcpInfo.bits.isStride) { 395 (0 until (MaxLMUL + 2 - RabCommitWidth)).map { idx => 396 val vdIdx = idx - 2 + RabCommitWidth 397 when(regWriteFromRatVec(idx).valid) { 398 regMaps(vdIdx).oldPreg := regWriteFromRatVec(idx).bits 399 ratCommitted(vdIdx) := true.B 400 } 401 } 402 }.otherwise { 403 (0 until MaxLMUL + 1 - RabCommitWidth).map { idx => 404 val vdIdx = idx - 1 + RabCommitWidth 405 when(regWriteFromRatVec(idx).valid) { 406 regMaps(vdIdx).oldPreg := regWriteFromRatVec(idx).bits 407 ratCommitted(vdIdx) := true.B 408 } 409 } 410 } 411 } 412 } 413 is (State.finish) { 414 commitNeeded.foreach(_ := false.B) 415 rabCommitted.foreach(_ := false.B) 416 ratCommitted.foreach(_ := false.B) 417 hasReadRf .foreach(_ := false.B) 418 sWaitRab_rabWriteOffset := 0.U 419 sWaitRab_ratWriteOffset := 0.U 420 sWaitRab_vecExcpInfo.valid := false.B 421 } 422 } 423 424 switch (state) { 425 is (State.mergeVd, State.mvOldVd) { 426 (0 until maxMergeNumPerCycle).map(vIdx => 427 when(i.fromVprf.rdata(vIdx).valid) { 428 mergedVd(vIdx) := mergedVdWData(vIdx).asTypeOf(new VecElemData(VLEN)) 429 } 430 ) 431 } 432 } 433 434 when (state === State.mergeVd) { 435 (0 until maxMergeNumPerCycle).foreach { case (idx) => 436 val vdIdx = currentIdxVec(idx) 437 // when nonSegIndexed load, iemul/demul = 1 << 2, vdLoc will be mapped as (0, 1, 2, 3, ...) -> (0, 4, ...) 438 val oldVdLoc = oldVdLocVec(idx) 439 // when nonSegIndexed load, iemul/demul = 1 << 2, vdLoc will be mapped as (0, 1, 2, 3, ...) -> (3, 7, ...) 440 val newVdLoc = newVdLocVec(idx) 441 o.toVPRF.r(idx).valid := commitNeeded(vdIdx) && !hasReadRf(vdIdx) && vdIdx < sWaitRab_needMergeUntil 442 o.toVPRF.r(idx).bits.addr := regMaps(oldVdLoc).oldPreg 443 o.toVPRF.r(idx).bits.isV0 := (regMaps(oldVdLoc).lreg === 0.U) && (idx == 0).B 444 o.toVPRF.r(idx + maxMergeNumPerCycle).valid := commitNeeded(vdIdx) && !hasReadRf(vdIdx) && vdIdx < sWaitRab_needMergeUntil 445 o.toVPRF.r(idx + maxMergeNumPerCycle).bits.addr := regMaps(newVdLoc).newPreg 446 o.toVPRF.r(idx + maxMergeNumPerCycle).bits.isV0 := (regMaps(newVdLoc).lreg === 0.U) && (idx == 0).B 447 hasReadRf(vdIdx) := true.B && vdIdx < sWaitRab_needMergeUntil 448 } 449 }.elsewhen (state === State.mvOldVd) { 450 (0 until maxMergeNumPerCycle).foreach { case (idx) => 451 val vdIdx = currentIdxVec(idx) 452 // when nonSegIndexed load, iemul/demul = 1 << 2, vdLoc will be mapped as (0, 1, 2, 3, ...) -> (0, 4, ...) 453 val oldVdLoc = oldVdLocVec(idx) 454 // when nonSegIndexed load, iemul/demul = 1 << 2, vdLoc will be mapped as (0, 1, 2, 3, ...) -> (3, 7, ...) 455 val newVdLoc = newVdLocVec(idx) 456 o.toVPRF.r(idx).valid := commitNeeded(vdIdx) && !hasReadRf(vdIdx) && vdIdx < sWaitRab_handleUntil 457 o.toVPRF.r(idx).bits.addr := regMaps(oldVdLoc).oldPreg 458 o.toVPRF.r(idx).bits.isV0 := (regMaps(oldVdLoc).lreg === 0.U) && (idx == 0).B 459 o.toVPRF.r(idx + maxMergeNumPerCycle).valid := 0.U 460 o.toVPRF.r(idx + maxMergeNumPerCycle).bits.addr := 0.U 461 o.toVPRF.r(idx + maxMergeNumPerCycle).bits.isV0 := false.B 462 hasReadRf(vdIdx) := true.B && vdIdx < sWaitRab_handleUntil 463 } 464 }.otherwise { 465 o.toVPRF.r := 0.U.asTypeOf(chiselTypeOf(o.toVPRF.r)) 466 } 467 468 o.toVPRF.w.zipWithIndex.foreach { case (w, idx) => 469 val vdIdx = currentIdxVec(idx) 470 // when nonSegIndexed load, iemul/demul = 1 << 2, vdLoc will be mapped as (0, 1, 2, 3, ...) -> (0, 4, ...) 471 val oldVdLoc = oldVdLocVec(idx) 472 // when nonSegIndexed load, iemul/demul = 1 << 2, vdLoc will be mapped as (0, 1, 2, 3, ...) -> (3, 7, ...) 473 val newVdLoc = newVdLocVec(idx) 474 w.valid := RegNext(i.fromVprf.rdata(idx).valid) 475 w.bits.isV0 := (regMaps(newVdLoc).lreg === 0.U) && (idx == 0).B 476 w.bits.newVdAddr := regMaps(newVdLoc).newPreg 477 w.bits.newVdData := mergedVd(idx.U).asUInt 478 } 479 480 o.status.busy := DelayN(state.isOneOf(State.waitRab, State.mergeVd, State.mvOldVd), 1) 481} 482 483class LogicPhyRegMap(implicit p: Parameters) extends XSBundle { 484 val lreg = UInt(LogicRegsWidth.W) 485 val newPreg = UInt(VfPhyRegIdxWidth.W) 486 val oldPreg = UInt(VfPhyRegIdxWidth.W) 487} 488 489class RegWriteFromRab(implicit p: Parameters) extends XSBundle { 490 private val maxVregLMUL = 8 491 val lreg = UInt(LogicRegsWidth.W) 492 val preg = UInt(VfPhyRegIdxWidth.W) 493} 494 495class RabToVecExcpMod(implicit p: Parameters) extends XSBundle { 496 val logicPhyRegMap = Vec(RabCommitWidth, ValidIO(new RegWriteFromRab)) 497} 498 499class VecExcpInfo(implicit p: Parameters) extends XSBundle { 500 val vstart = Vstart() 501 val vsew = VSew() 502 val veew = VSew() 503 val vlmul = VLmul() 504 val nf = Nf() 505 val isStride = Bool() 506 val isIndexed = Bool() 507 val isWhole = Bool() 508 val isVlm = Bool() 509} 510 511class RatToVecExcpMod(implicit p: Parameters) extends XSBundle { 512 val vecOldVdPdest = Vec(RabCommitWidth, ValidIO(UInt(VfPhyRegIdxWidth.W))) 513 val v0OldVdPdest = Vec(RabCommitWidth, ValidIO(UInt(VfPhyRegIdxWidth.W))) 514} 515 516class VprfToExcpMod(numPort: Int)(implicit p: Parameters) extends XSBundle { 517 val rdata = Vec(numPort, ValidIO(UInt(VLEN.W))) 518} 519 520class ExcpModToVprf(numReadPort: Int, numWritePort: Int)(implicit p: Parameters) extends XSBundle { 521 val r = Vec(numReadPort, ValidIO(new Bundle { 522 val isV0 = Bool() 523 val addr = UInt(VfPhyRegIdxWidth.W) 524 })) 525 val w = Vec(numWritePort, ValidIO(new Bundle { 526 val isV0 = Bool() 527 val newVdAddr = UInt(VfPhyRegIdxWidth.W) 528 val newVdData = UInt(VLEN.W) 529 })) 530} 531 532class NfMappedElemIdx(vlen: Int) extends Module { 533 require(isPow2(vlen)) 534 // vlen = 128, idxWidth = 8, hold 0~128 535 val idxWidth = log2Up(vlen + 1) 536 537 val in = IO(Input(new Bundle { 538 val nf = Nf() 539 val eewOH = SewOH() 540 })) 541 val out = IO(Output(new Bundle { 542 val idxRangeVec = Vec(8, new HWRange(idxWidth)) 543 })) 544 545 private val minElemLen = 8 546 private val maxElemNumPerVreg = vlen / minElemLen 547 548 private val rangeTable: Vec[Vec[HWRange]] = VecInit.tabulate(8, 8) { case(nf, vdIdx) => 549 val nFields = nf + 1 550 // vector register group 551 val vrgIdx = vdIdx / nFields 552 HWRange(idxWidth)((maxElemNumPerVreg * vrgIdx).U, (maxElemNumPerVreg * (vrgIdx + 1)).U) 553 } 554 555 out.idxRangeVec := VecInit(rangeTable.map { case rangeVec: Vec[HWRange] => 556 Mux1H( 557 (0 until 4).map(i => 558 in.eewOH(i) -> VecInit(rangeVec.map( 559 x => HWRange(idxWidth)(x.from >> i, x.until >> i) 560 )) 561 ) 562 ) 563 })(in.nf) 564 565 dontTouch(out.idxRangeVec) 566 567 def apply(nf: UInt, eewOH: UInt): Vec[HWRange] = { 568 this.in.nf := nf 569 this.in.eewOH := eewOH 570 this.out.idxRangeVec 571 } 572} 573 574class GetE8OffsetInVreg(vlen: Int) extends Module { 575 require(isPow2(vlen)) 576 private val minElemLen = 8 577 private val maxElemNumPerVreg = vlen / minElemLen 578 private val tailZeroBit = log2Ceil(maxElemNumPerVreg) // 16 -> 4 579 580 val in = IO(Input(new Bundle { 581 val eewOH = SewOH() 582 val idx = UInt(log2Up(vlen).W) 583 })) 584 val out = IO(Output(new Bundle { 585 val offset = UInt(tailZeroBit.W) 586 })) 587 588 out.offset := Mux1H( 589 (0 until 4).map( 590 // eew=32(0b0100), idx=1, get offset=4 591 i => in.eewOH(i) -> (in.idx << i) 592 ) 593 ) 594 595 def apply(eewOH: UInt, idx: UInt): UInt = { 596 this.in.eewOH := eewOH 597 this.in.idx := idx 598 this.out.offset 599 } 600} 601 602class VecElemData(vlen: Int) extends Bundle { 603 val rawData = UInt(vlen.W) 604 605 def e8Vec = this.rawData.asTypeOf(new VecE8Vec(vlen)) 606 def e16Vec = this.rawData.asTypeOf(new VecE16Vec(vlen)) 607 def e32Vec = this.rawData.asTypeOf(new VecE32Vec(vlen)) 608 def e64Vec = this.rawData.asTypeOf(new VecE64Vec(vlen)) 609} 610 611class VecE8Vec(vlen: Int) extends Bundle { 612 val data = Vec(vlen / 8, UInt(8.W)) 613 614 def apply(idx: Int): UInt = this.data(idx) 615} 616 617class VecE16Vec(vlen: Int) extends Bundle { 618 val data = Vec(vlen / 16, UInt(16.W)) 619 620 def apply(idx: Int): UInt = this.data(idx) 621} 622 623class VecE32Vec(vlen: Int) extends Bundle { 624 val data = Vec(vlen / 32, UInt(32.W)) 625 626 def apply(idx: Int): UInt = this.data(idx) 627} 628 629class VecE64Vec(vlen: Int) extends Bundle { 630 val data = Vec(vlen / 64, UInt(64.W)) 631 632 def apply(idx: Int): UInt = this.data(idx) 633} 634 635class HWRange(w: Int) extends Bundle { 636 val from = UInt(w.W) 637 val until = UInt(w.W) 638 639 def inRange(uint: UInt) = { 640 uint >= this.from && uint < this.until 641 } 642 643 def apply(_from: Bits, _until: Bits): this.type = { 644 this.from := _from 645 this.until := _until 646 this 647 } 648} 649 650object HWRange { 651 def apply(w: Int)(_from: Bits, _until: Bits): HWRange = Wire(new HWRange(w)).apply(_from, _until) 652} 653 654