xref: /XiangShan/src/main/scala/xiangshan/backend/VecExcpDataMergeModule.scala (revision e43bb916638748d37d5d74f879174402ad12a740)
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