xref: /XiangShan/src/main/scala/xiangshan/mem/vector/VSegmentUnit.scala (revision 16c2d8bb27e9a24ed5ef5e4885693e6a30b536df)
188884326Sweiding liu/***************************************************************************************
288884326Sweiding liu  * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
388884326Sweiding liu  * Copyright (c) 2020-2021 Peng Cheng Laboratory
488884326Sweiding liu  *
588884326Sweiding liu  * XiangShan is licensed under Mulan PSL v2.
688884326Sweiding liu  * You can use this software according to the terms and conditions of the Mulan PSL v2.
788884326Sweiding liu  * You may obtain a copy of Mulan PSL v2 at:
888884326Sweiding liu  *          http://license.coscl.org.cn/MulanPSL2
988884326Sweiding liu  *
1088884326Sweiding liu  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
1188884326Sweiding liu  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
1288884326Sweiding liu  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
1388884326Sweiding liu  *
1488884326Sweiding liu  * See the Mulan PSL v2 for more details.
1588884326Sweiding liu  ***************************************************************************************/
1688884326Sweiding liu
1788884326Sweiding liupackage xiangshan.mem
1888884326Sweiding liu
1988884326Sweiding liuimport org.chipsalliance.cde.config.Parameters
2088884326Sweiding liuimport chisel3._
2188884326Sweiding liuimport chisel3.util._
2288884326Sweiding liuimport utils._
2388884326Sweiding liuimport utility._
2488884326Sweiding liuimport xiangshan._
2588884326Sweiding liuimport xiangshan.backend.rob.RobPtr
2688884326Sweiding liuimport xiangshan.backend.Bundles._
2788884326Sweiding liuimport xiangshan.mem._
28ccd66eefSAnzoooooimport xiangshan.backend.fu.{FuType, PMPRespBundle}
2988884326Sweiding liuimport freechips.rocketchip.diplomacy.BufferParams
3088884326Sweiding liuimport xiangshan.cache.mmu._
3188884326Sweiding liuimport xiangshan.cache._
3288884326Sweiding liuimport xiangshan.cache.wpu.ReplayCarry
3388884326Sweiding liuimport xiangshan.backend.fu.util.SdtrigExt
3488884326Sweiding liuimport xiangshan.ExceptionNO._
35785e3bfdSXuan Huimport xiangshan.backend.fu.vector.Bundles.{VConfig, VType}
3641d8d239Shappy-lximport xiangshan.backend.datapath.NewPipelineConnect
37726c5ee8SAnzoooooimport xiangshan.backend.fu.NewCSR._
38157b169cSweiding liuimport xiangshan.backend.fu.vector.Utils.VecDataToMaskDataVec
3988884326Sweiding liu
4088884326Sweiding liuclass VSegmentBundle(implicit p: Parameters) extends VLSUBundle
4188884326Sweiding liu{
4246e9ee74SHaoyuan Feng  val baseVaddr        = UInt(XLEN.W)
4388884326Sweiding liu  val uop              = new DynInst
4488884326Sweiding liu  val paddr            = UInt(PAddrBits.W)
4588884326Sweiding liu  val mask             = UInt(VLEN.W)
4688884326Sweiding liu  val alignedType      = UInt(alignTypeBits.W)
4788884326Sweiding liu  val vl               = UInt(elemIdxBits.W)
4869a3c27aSAnzooooo  val uopFlowNum       = UInt(elemIdxBits.W)
4969a3c27aSAnzooooo  val uopFlowNumMask   = UInt(elemIdxBits.W)
50e7ab4635SHuijin Li  val isVSegLoad       = Bool()
51e7ab4635SHuijin Li  val isVSegStore      = Bool()
5288884326Sweiding liu  // for exception
5388884326Sweiding liu  val vstart           = UInt(elemIdxBits.W)
5446e9ee74SHaoyuan Feng  val exceptionVaddr   = UInt(XLEN.W)
5546e9ee74SHaoyuan Feng  val exceptionGpaddr  = UInt(XLEN.W)
56ad415ae0SXiaokun-Pei  val exceptionIsForVSnonLeafPTE = Bool()
5788884326Sweiding liu  val exception_va     = Bool()
58a53daa0fSHaoyuan Feng  val exception_gpa    = Bool()
5988884326Sweiding liu  val exception_pa     = Bool()
6079656063Slwd  val exceptionVstart  = UInt(elemIdxBits.W)
611d1953a5SXuan Hu  // valid: have fof exception but can not trigger, need update all writebacked uop.vl with exceptionVl
621d1953a5SXuan Hu  val exceptionVl      = ValidIO(UInt(elemIdxBits.W))
63c41a9f78Slwd  val isFof            = Bool()
6488884326Sweiding liu}
6588884326Sweiding liu
66842df083Slwd// latch each uop's VecWen, pdest, v0Wen, uopIdx
67cf7e2642Sweiding liuclass VSegmentUop(implicit p: Parameters) extends VLSUBundle{
68842df083Slwd  val uop              = new DynInst
69cf7e2642Sweiding liu}
70cf7e2642Sweiding liu
7188884326Sweiding liuclass VSegmentUnit (implicit p: Parameters) extends VLSUModule
7288884326Sweiding liu  with HasDCacheParameters
7388884326Sweiding liu  with MemoryOpConstants
7488884326Sweiding liu  with SdtrigExt
7588884326Sweiding liu  with HasLoadHelper
7688884326Sweiding liu{
7788884326Sweiding liu  val io               = IO(new VSegmentUnitIO)
7888884326Sweiding liu
7988884326Sweiding liu  val maxSize          = VSegmentBufferSize
8088884326Sweiding liu
8188884326Sweiding liu  class VSegUPtr(implicit p: Parameters) extends CircularQueuePtr[VSegUPtr](maxSize){
8288884326Sweiding liu  }
8388884326Sweiding liu
8488884326Sweiding liu  object VSegUPtr {
8588884326Sweiding liu    def apply(f: Bool, v: UInt)(implicit p: Parameters): VSegUPtr = {
8688884326Sweiding liu      val ptr           = Wire(new VSegUPtr)
8788884326Sweiding liu      ptr.flag         := f
8888884326Sweiding liu      ptr.value        := v
8988884326Sweiding liu      ptr
9088884326Sweiding liu    }
9188884326Sweiding liu  }
9288884326Sweiding liu
93b240e1c0SAnzooooo  val maxSplitNum = 2
9469a3c27aSAnzooooo
9569a3c27aSAnzooooo  /**
9669a3c27aSAnzooooo  ********************************************************************************************************
9769a3c27aSAnzooooo  *  Use an example to illustrate the working logic of a segmentunit:                                    *
9869a3c27aSAnzooooo  *    For:                                                                                              *
9969a3c27aSAnzooooo  *      lmul=2 sew=32 emul=2 eew=32  vl=16                                                              *
10069a3c27aSAnzooooo  *    Then:                                                                                             *
10169a3c27aSAnzooooo  *      Access memory in the order:                                                                     *
10269a3c27aSAnzooooo  *        (V2,S0),(V4,S0),(V6,S0),(V8,S0),                                                              *
10369a3c27aSAnzooooo  *        (V2,S1),(V4,S1),(V6,S1),(V8,S1),                                                              *
10469a3c27aSAnzooooo  *        (V2,S2),(V4,S2),(V6,S2),(V8,S2),                                                              *
10569a3c27aSAnzooooo  *        (V2,S3),(V4,S3),(V6,S3),(V8,S3),                                                              *
10669a3c27aSAnzooooo  *        (V3,S4),(V5,S4),(V7,S4),(V9,S4),                                                              *
10769a3c27aSAnzooooo  *        (V3,S5),(V5,S5),(V7,S5),(V9,S5),                                                              *
10869a3c27aSAnzooooo  *        (V3,S6),(V5,S6),(V7,S6),(V9,S6),                                                              *
10969a3c27aSAnzooooo  *        (V3,S7),(V5,S7),(V7,S7),(V9,S7),                                                              *
11069a3c27aSAnzooooo  *                                                                                                      *
11169a3c27aSAnzooooo  *                                                                                                      *
11269a3c27aSAnzooooo  *    [[data]] saves the data generated by the access and corresponds to the register.                  *
11369a3c27aSAnzooooo  *    [[splitPtr]] controls the destination register written to.                                        *
11469a3c27aSAnzooooo  *                                                                                                      *
11569a3c27aSAnzooooo  *    splitptr offset can be seen in [[splitPtrNext]] is assignment logic,                              *
11669a3c27aSAnzooooo  *    which is mainly calculated in terms of [[fieldIdx]] and [[segmentIdx]]                            *
11769a3c27aSAnzooooo  *    First access different fields of the same segment, and then visit different segments.             *
11869a3c27aSAnzooooo  *    For the case of 'emul' greater than 1, such as the following example,                             *
11969a3c27aSAnzooooo  *    although 'v2' and 'v3' are different vd and the same field, they are still different segments,    *
12069a3c27aSAnzooooo  *    so they should be accessed sequentially.Just like the 'Access memory in the order' above.         *
12169a3c27aSAnzooooo  *                                                                                                      *
12269a3c27aSAnzooooo  *                         [[segmentIdx]]                                                               *
12369a3c27aSAnzooooo  *                               |                                                                      *
12469a3c27aSAnzooooo  *                               |                                                                      *
12569a3c27aSAnzooooo  *                               V                                                                      *
12669a3c27aSAnzooooo  *                                                                                                      *
12769a3c27aSAnzooooo  *                               S0               S1                S2                 S3               *
12869a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
12969a3c27aSAnzooooo  *  [[splitPtr]]--> v2  |     field0     |      field0     |      field0     |      field0         |    *
13069a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
13169a3c27aSAnzooooo  *                               S4               S5                S6                 S7               *
13269a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
13369a3c27aSAnzooooo  *                  v3  |     field0     |      field0     |      field0     |      field0         |    *
13469a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
13569a3c27aSAnzooooo  *                               S0               S1                S2                 S3               *
13669a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
13769a3c27aSAnzooooo  *                  v4  |     field1     |      field1     |      field1     |      field1         |    *
13869a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
13969a3c27aSAnzooooo  *                               S4               S5                S6                 S7               *
14069a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
14169a3c27aSAnzooooo  *                  v5  |     field1     |      field1     |      field1     |      field1         |    *
14269a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
14369a3c27aSAnzooooo  *                               S0               S1                S2                 S3               *
14469a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
14569a3c27aSAnzooooo  *                  v6  |     field2     |      field2     |      field2     |      field2         |    *
14669a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
14769a3c27aSAnzooooo  *                               S4               S5                S6                 S7               *
14869a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
14969a3c27aSAnzooooo  *                  v7  |     field2     |      field2     |      field2     |      field2         |    *
15069a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
15169a3c27aSAnzooooo  *                               S0               S1                S2                 S3               *
15269a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
15369a3c27aSAnzooooo  *                  v8  |     field3     |      field3     |      field3     |      field3         |    *
15469a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
15569a3c27aSAnzooooo  *                               S4               S5                S6                 S7               *
15669a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *
15769a3c27aSAnzooooo  *                  v9  |     field3     |      field3     |      field3     |      field3         |    *
15869a3c27aSAnzooooo  *                      ----------------------------------------------------------------------------    *                                                                                    *
15969a3c27aSAnzooooo  *                                                                                                      *                                                                                    *
16069a3c27aSAnzooooo  *                                                                                                      *                                                                                    *
16169a3c27aSAnzooooo  ********************************************************************************************************
16269a3c27aSAnzooooo  **/
16369a3c27aSAnzooooo
16469a3c27aSAnzooooo
16588884326Sweiding liu  // buffer uop
16688884326Sweiding liu  val instMicroOp       = Reg(new VSegmentBundle)
167321866f2Slwd  val instMicroOpValid  = RegInit(false.B)
16888884326Sweiding liu  val data              = Reg(Vec(maxSize, UInt(VLEN.W)))
169cf7e2642Sweiding liu  val uopq              = Reg(Vec(maxSize, new VSegmentUop))
17088884326Sweiding liu  val stride            = Reg(Vec(maxSize, UInt(VLEN.W)))
17188884326Sweiding liu  val allocated         = RegInit(VecInit(Seq.fill(maxSize)(false.B)))
17288884326Sweiding liu  val enqPtr            = RegInit(0.U.asTypeOf(new VSegUPtr))
17388884326Sweiding liu  val deqPtr            = RegInit(0.U.asTypeOf(new VSegUPtr))
17488884326Sweiding liu  val stridePtr         = WireInit(0.U.asTypeOf(new VSegUPtr)) // for select stride/index
175*16c2d8bbSAnzo  val stridePtrReg      = RegInit(0.U.asTypeOf(new VSegUPtr)) // for select stride/index
17688884326Sweiding liu
17788884326Sweiding liu  val segmentIdx        = RegInit(0.U(elemIdxBits.W))
17888884326Sweiding liu  val fieldIdx          = RegInit(0.U(fieldBits.W))
17946e9ee74SHaoyuan Feng  val segmentOffset     = RegInit(0.U(XLEN.W))
18088884326Sweiding liu  val splitPtr          = RegInit(0.U.asTypeOf(new VSegUPtr)) // for select load/store data
18188884326Sweiding liu  val splitPtrNext      = WireInit(0.U.asTypeOf(new VSegUPtr))
18288884326Sweiding liu
18388884326Sweiding liu  val exception_va      = WireInit(false.B)
184a53daa0fSHaoyuan Feng  val exception_gpa     = WireInit(false.B)
18588884326Sweiding liu  val exception_pa      = WireInit(false.B)
18688884326Sweiding liu
18787db1c4aSweiding liu  val maxSegIdx         = instMicroOp.vl - 1.U
18888884326Sweiding liu  val maxNfields        = instMicroOp.uop.vpu.nf
189af23f085Sweiding liu  val latchVaddr        = RegInit(0.U(VAddrBits.W))
190fa5e530dScz4e  val latchVaddrDup     = RegInit(0.U(VAddrBits.W))
19188884326Sweiding liu
192321866f2Slwd  XSError((segmentIdx > maxSegIdx) && instMicroOpValid, s"segmentIdx > vl, something error!\n")
193321866f2Slwd  XSError((fieldIdx > maxNfields) &&  instMicroOpValid, s"fieldIdx > nfields, something error!\n")
19488884326Sweiding liu
19551764047Sweiding liu  // MicroOp
196c41a9f78Slwd  val baseVaddr                       = instMicroOp.baseVaddr
19751764047Sweiding liu  val alignedType                     = instMicroOp.alignedType
19851764047Sweiding liu  val fuType                          = instMicroOp.uop.fuType
199e7ab4635SHuijin Li  val isVSegLoad                      = instMicroOp.isVSegLoad
200e7ab4635SHuijin Li  val isVSegStore                     = instMicroOp.isVSegStore
20151764047Sweiding liu  val mask                            = instMicroOp.mask
20251764047Sweiding liu  val exceptionVec                    = instMicroOp.uop.exceptionVec
20351764047Sweiding liu  val issueEew                        = instMicroOp.uop.vpu.veew
20451764047Sweiding liu  val issueLmul                       = instMicroOp.uop.vpu.vtype.vlmul
20551764047Sweiding liu  val issueSew                        = instMicroOp.uop.vpu.vtype.vsew
20651764047Sweiding liu  val issueEmul                       = EewLog2(issueEew) - issueSew + issueLmul
20769a3c27aSAnzooooo  val elemIdxInVd                     = segmentIdx & instMicroOp.uopFlowNumMask
20851764047Sweiding liu  val issueInstType                   = Cat(true.B, instMicroOp.uop.fuOpType(6, 5)) // always segment instruction
209839e1a88SAnzooooo  val issueUopFlowNumLog2             = GenRealFlowLog2(issueInstType, issueEmul, issueLmul, issueEew, issueSew, true) // max element number log2 in vd
21069a3c27aSAnzooooo  val issueVlMax                      = instMicroOp.uopFlowNum // max elementIdx in vd
211b2e0a7baSweiding liu  val issueMaxIdxInIndex              = GenVLMAX(Mux(issueEmul.asSInt > 0.S, 0.U, issueEmul), issueEew(1, 0)) // index element index in index register
2120869ae56Sweiding liu  val issueMaxIdxInIndexMask          = GenVlMaxMask(issueMaxIdxInIndex, elemIdxBits)
213b2e0a7baSweiding liu  val issueMaxIdxInIndexLog2          = GenVLMAXLog2(Mux(issueEmul.asSInt > 0.S, 0.U, issueEmul), issueEew(1, 0))
21451764047Sweiding liu  val issueIndexIdx                   = segmentIdx & issueMaxIdxInIndexMask
2155122476dSweiding liu  val segmentActive                   = (mask & UIntToOH(segmentIdx)).orR
21651764047Sweiding liu
21741d8d239Shappy-lx  // sbuffer write interface
21841d8d239Shappy-lx  val sbufferOut                      = Wire(Decoupled(new DCacheWordReqWithVaddrAndPfFlag))
21941d8d239Shappy-lx
220df3b4b92SAnzooooo
221df3b4b92SAnzooooo  // segment fof instrction buffer
222df3b4b92SAnzooooo  val fofBuffer                       = RegInit(0.U.asTypeOf(new DynInst))
223df3b4b92SAnzooooo  val fofBufferValid                  = RegInit(false.B)
224df3b4b92SAnzooooo
225df3b4b92SAnzooooo
22688884326Sweiding liu  // Segment instruction's FSM
227fe518d28Sweiding liu  /*
228fe518d28Sweiding liu  * s_idle: wait request
229fe518d28Sweiding liu  * s_flush_sbuffer_req: flush sbuffer
230fe518d28Sweiding liu  * s_wait_flush_sbuffer_resp: wait sbuffer empty
23151764047Sweiding liu  * s_tlb_req: request tlb
23251764047Sweiding liu  * s_wait_tlb_resp: wait tlb resp
23351764047Sweiding liu  * s_pm: check pmp
23451764047Sweiding liu  * s_cache_req: request cache
23551764047Sweiding liu  * s_cache_resp: wait cache resp
236b240e1c0SAnzooooo  * s_misalign_merge_data: merge unaligned data
23751764047Sweiding liu  * s_latch_and_merge_data: for read data
23851764047Sweiding liu  * s_send_data: for send write data
239cfebab2aSAnzo  * s_wait_to_sbuffer: Wait for data from the sbufferOut pipelayer to be sent to the sbuffer
240b240e1c0SAnzooooo  * s_finish: normal uop is complete
241df3b4b92SAnzooooo  * s_fof_fix_vl: Writeback the uop of the fof instruction to modify vl.
242fe518d28Sweiding liu  * */
243b240e1c0SAnzooooo  val s_idle :: s_flush_sbuffer_req :: s_wait_flush_sbuffer_resp :: s_tlb_req :: s_wait_tlb_resp :: s_pm ::s_cache_req :: s_cache_resp :: s_misalign_merge_data :: s_latch_and_merge_data :: s_send_data :: s_wait_to_sbuffer :: s_finish :: s_fof_fix_vl :: Nil = Enum(14)
24488884326Sweiding liu  val state             = RegInit(s_idle)
24588884326Sweiding liu  val stateNext         = WireInit(s_idle)
24688884326Sweiding liu  val sbufferEmpty      = io.flush_sbuffer.empty
247df3b4b92SAnzooooo  val isEnqfof          = io.in.bits.uop.fuOpType === VlduType.vleff && io.in.valid
248df3b4b92SAnzooooo  val isEnqFixVlUop     = isEnqfof && io.in.bits.uop.vpu.lastUop
249*16c2d8bbSAnzo  val nextBaseVaddr     = Wire(UInt(XLEN.W))
25088884326Sweiding liu
251b240e1c0SAnzooooo  // handle misalign sign
252b240e1c0SAnzooooo  val curPtr             = RegInit(false.B)
253b240e1c0SAnzooooo  val canHandleMisalign  = WireInit(false.B)
254b240e1c0SAnzooooo  val isMisalignReg      = RegInit(false.B)
255b240e1c0SAnzooooo  val isMisalignWire     = WireInit(false.B)
256b240e1c0SAnzooooo  val notCross16ByteReg  = RegInit(false.B)
257b240e1c0SAnzooooo  val notCross16ByteWire = WireInit(false.B)
258b240e1c0SAnzooooo  val combinedData       = RegInit(0.U(XLEN.W))
259b240e1c0SAnzooooo
260b240e1c0SAnzooooo  val lowPagePaddr       = RegInit(0.U(PAddrBits.W))
261b240e1c0SAnzooooo  val lowPageGPaddr      = RegInit(0.U(GPAddrBits.W))
262b240e1c0SAnzooooo
263b240e1c0SAnzooooo  val highPagePaddr      = RegInit(0.U(PAddrBits.W))
264b240e1c0SAnzooooo  val highPageGPaddr     = RegInit(0.U(GPAddrBits.W))
265b240e1c0SAnzooooo
266b240e1c0SAnzooooo  val isFirstSplit       = !curPtr
267b240e1c0SAnzooooo  val isSecondSplit      = curPtr
26888884326Sweiding liu  /**
26988884326Sweiding liu   * state update
27088884326Sweiding liu   */
27188884326Sweiding liu  state  := stateNext
27288884326Sweiding liu
27388884326Sweiding liu  /**
27488884326Sweiding liu   * state transfer
27588884326Sweiding liu   */
27688884326Sweiding liu  when(state === s_idle){
27788884326Sweiding liu    stateNext := Mux(isAfter(enqPtr, deqPtr), s_flush_sbuffer_req, s_idle)
27888884326Sweiding liu  }.elsewhen(state === s_flush_sbuffer_req){
27988884326Sweiding liu    stateNext := Mux(sbufferEmpty, s_tlb_req, s_wait_flush_sbuffer_resp) // if sbuffer is empty, go to query tlb
28088884326Sweiding liu
28188884326Sweiding liu  }.elsewhen(state === s_wait_flush_sbuffer_resp){
28288884326Sweiding liu    stateNext := Mux(sbufferEmpty, s_tlb_req, s_wait_flush_sbuffer_resp)
28388884326Sweiding liu
28488884326Sweiding liu  }.elsewhen(state === s_tlb_req){
285726c5ee8SAnzooooo    stateNext := Mux(segmentActive, s_wait_tlb_resp, Mux(isVSegLoad, s_latch_and_merge_data, s_send_data))
28688884326Sweiding liu
28788884326Sweiding liu  }.elsewhen(state === s_wait_tlb_resp){
288af23f085Sweiding liu    stateNext := Mux(io.dtlb.resp.fire,
289af23f085Sweiding liu                      Mux(!io.dtlb.resp.bits.miss,
290af23f085Sweiding liu                          s_pm,
291af23f085Sweiding liu                          s_tlb_req),
292af23f085Sweiding liu                      s_wait_tlb_resp)
29388884326Sweiding liu
29488884326Sweiding liu  }.elsewhen(state === s_pm){
295b240e1c0SAnzooooo    when(exception_pa || exception_va || exception_gpa) {
296b240e1c0SAnzooooo      stateNext := s_finish
297b240e1c0SAnzooooo    } .otherwise {
298b240e1c0SAnzooooo      when(canHandleMisalign && isMisalignWire && !notCross16ByteWire || (isMisalignReg && !notCross16ByteReg && isFirstSplit && isVSegStore)) {
299b240e1c0SAnzooooo        stateNext := s_tlb_req
300b240e1c0SAnzooooo      } .otherwise {
3018d790a87Sweiding liu        /* if is vStore, send data to sbuffer, so don't need query dcache */
302b240e1c0SAnzooooo        stateNext := Mux(isVSegLoad, s_cache_req, s_send_data)
303b240e1c0SAnzooooo      }
304b240e1c0SAnzooooo    }
30588884326Sweiding liu
30688884326Sweiding liu  }.elsewhen(state === s_cache_req){
3078d790a87Sweiding liu    stateNext := Mux(io.rdcache.req.fire, s_cache_resp, s_cache_req)
30888884326Sweiding liu
30988884326Sweiding liu  }.elsewhen(state === s_cache_resp){
3108d790a87Sweiding liu    when(io.rdcache.resp.fire) {
31169a3c27aSAnzooooo      when(io.rdcache.resp.bits.miss || io.rdcache.s2_bank_conflict) {
31288884326Sweiding liu        stateNext := s_cache_req
31388884326Sweiding liu      }.otherwise {
314b240e1c0SAnzooooo
315b240e1c0SAnzooooo        stateNext := Mux(isVSegLoad, Mux(isMisalignReg && !notCross16ByteReg, s_misalign_merge_data, s_latch_and_merge_data), s_send_data)
31688884326Sweiding liu      }
31788884326Sweiding liu    }.otherwise{
31888884326Sweiding liu      stateNext := s_cache_resp
31988884326Sweiding liu    }
320b240e1c0SAnzooooo  }.elsewhen(state === s_misalign_merge_data) {
321b240e1c0SAnzooooo    stateNext := Mux(!curPtr, s_tlb_req, s_latch_and_merge_data)
32288884326Sweiding liu  }.elsewhen(state === s_latch_and_merge_data) {
32397db011aSweiding liu    when((segmentIdx === maxSegIdx) && (fieldIdx === maxNfields) ||
32497db011aSweiding liu      ((segmentIdx === maxSegIdx) && !segmentActive)) {
32597db011aSweiding liu
32688884326Sweiding liu      stateNext := s_finish // segment instruction finish
32788884326Sweiding liu    }.otherwise {
32888884326Sweiding liu      stateNext := s_tlb_req // need continue
32988884326Sweiding liu    }
33097db011aSweiding liu    /* if segment is inactive, don't need to wait access all of the field */
331fe518d28Sweiding liu  }.elsewhen(state === s_send_data) { // when sbuffer accept data
332b240e1c0SAnzooooo    when(!sbufferOut.fire && segmentActive || (isMisalignReg && !notCross16ByteReg && isFirstSplit)) {
333fe518d28Sweiding liu      stateNext := s_send_data
334cfebab2aSAnzo    }.elsewhen(segmentIdx === maxSegIdx && (fieldIdx === maxNfields && sbufferOut.fire || !segmentActive && io.sbuffer.valid && !io.sbuffer.ready)) {
335cfebab2aSAnzo      stateNext := s_wait_to_sbuffer
336cfebab2aSAnzo    }.elsewhen(segmentIdx === maxSegIdx && !segmentActive){
337fe518d28Sweiding liu      stateNext := s_finish // segment instruction finish
338fe518d28Sweiding liu    }.otherwise {
339fe518d28Sweiding liu      stateNext := s_tlb_req // need continue
340fe518d28Sweiding liu    }
341cfebab2aSAnzo
342cfebab2aSAnzo  }.elsewhen(state === s_wait_to_sbuffer){
343cfebab2aSAnzo    stateNext := Mux(io.sbuffer.fire, s_finish, s_wait_to_sbuffer)
344cfebab2aSAnzo
34588884326Sweiding liu  }.elsewhen(state === s_finish){ // writeback uop
346df3b4b92SAnzooooo    stateNext := Mux(
347df3b4b92SAnzooooo      distanceBetween(enqPtr, deqPtr) === 0.U,
348df3b4b92SAnzooooo      Mux(fofBufferValid, s_fof_fix_vl, s_idle),
349df3b4b92SAnzooooo      s_finish
350df3b4b92SAnzooooo    )
351df3b4b92SAnzooooo  }.elsewhen(state === s_fof_fix_vl){ // writeback uop
352df3b4b92SAnzooooo    stateNext := Mux(!fofBufferValid, s_idle, s_fof_fix_vl)
3538b33cd30Sklin02  }.otherwise{ // unknown state
35488884326Sweiding liu    stateNext := s_idle
3558b33cd30Sklin02    assert(false.B)
35688884326Sweiding liu  }
35788884326Sweiding liu
35888884326Sweiding liu  /*************************************************************************
35988884326Sweiding liu   *                            enqueue logic
36088884326Sweiding liu   *************************************************************************/
36188884326Sweiding liu  io.in.ready                         := true.B
36288884326Sweiding liu  val fuOpType                         = io.in.bits.uop.fuOpType
36388884326Sweiding liu  val vtype                            = io.in.bits.uop.vpu.vtype
36488884326Sweiding liu  val mop                              = fuOpType(6, 5)
36588884326Sweiding liu  val instType                         = Cat(true.B, mop)
36688884326Sweiding liu  val eew                              = io.in.bits.uop.vpu.veew
36788884326Sweiding liu  val sew                              = vtype.vsew
36888884326Sweiding liu  val lmul                             = vtype.vlmul
36969a3c27aSAnzooooo  val emul                             = EewLog2(eew) - sew + lmul
37088884326Sweiding liu  val vl                               = instMicroOp.vl
37188884326Sweiding liu  val vm                               = instMicroOp.uop.vpu.vm
37288884326Sweiding liu  val vstart                           = instMicroOp.uop.vpu.vstart
37388884326Sweiding liu  val srcMask                          = GenFlowMask(Mux(vm, Fill(VLEN, 1.U(1.W)), io.in.bits.src_mask), vstart, vl, true)
37488884326Sweiding liu  // first uop enqueue, we need to latch microOp of segment instruction
375df3b4b92SAnzooooo  when(io.in.fire && !instMicroOpValid && !isEnqFixVlUop){
37669a3c27aSAnzooooo    // element number in a vd
37769a3c27aSAnzooooo    // TODO Rewrite it in a more elegant way.
378839e1a88SAnzooooo    val uopFlowNum                    = ZeroExt(GenRealFlowNum(instType, emul, lmul, eew, sew, true), elemIdxBits)
37946e9ee74SHaoyuan Feng    instMicroOp.baseVaddr             := io.in.bits.src_rs1
380321866f2Slwd    instMicroOpValid                  := true.B // if is first uop
381d73f3705SAnzo    instMicroOp.alignedType           := Mux(isIndexed(instType), sew(1, 0), eew)
38288884326Sweiding liu    instMicroOp.uop                   := io.in.bits.uop
38388884326Sweiding liu    instMicroOp.mask                  := srcMask
38488884326Sweiding liu    instMicroOp.vstart                := 0.U
38569a3c27aSAnzooooo    instMicroOp.uopFlowNum            := uopFlowNum
38669a3c27aSAnzooooo    instMicroOp.uopFlowNumMask        := GenVlMaxMask(uopFlowNum, elemIdxBits) // for merge data
38788884326Sweiding liu    instMicroOp.vl                    := io.in.bits.src_vl.asTypeOf(VConfig()).vl
3881d1953a5SXuan Hu    instMicroOp.exceptionVl.valid     := false.B
3891d1953a5SXuan Hu    instMicroOp.exceptionVl.bits      := io.in.bits.src_vl.asTypeOf(VConfig()).vl
39088884326Sweiding liu    segmentOffset                     := 0.U
39122380eafSAnzo    instMicroOp.isFof                 := (fuOpType === VlduType.vleff) && FuType.isVSegLoad(io.in.bits.uop.fuType)
392e7ab4635SHuijin Li    instMicroOp.isVSegLoad            := FuType.isVSegLoad(io.in.bits.uop.fuType)
393e7ab4635SHuijin Li    instMicroOp.isVSegStore           := FuType.isVSegStore(io.in.bits.uop.fuType)
394b240e1c0SAnzooooo    isMisalignReg                     := false.B
395b240e1c0SAnzooooo    notCross16ByteReg                 := false.B
39688884326Sweiding liu  }
39788884326Sweiding liu  // latch data
398df3b4b92SAnzooooo  when(io.in.fire && !isEnqFixVlUop){
39988884326Sweiding liu    data(enqPtr.value)                := io.in.bits.src_vs3
40088884326Sweiding liu    stride(enqPtr.value)              := io.in.bits.src_stride
401842df083Slwd    uopq(enqPtr.value).uop            := io.in.bits.uop
40288884326Sweiding liu  }
40388884326Sweiding liu
40488884326Sweiding liu  // update enqptr, only 1 port
405df3b4b92SAnzooooo  when(io.in.fire && !isEnqFixVlUop){
40688884326Sweiding liu    enqPtr                            := enqPtr + 1.U
40788884326Sweiding liu  }
40888884326Sweiding liu
40988884326Sweiding liu  /*************************************************************************
41088884326Sweiding liu   *                            output logic
41188884326Sweiding liu   *************************************************************************/
41288884326Sweiding liu
41388884326Sweiding liu  val indexStride                     = IndexAddr( // index for indexed instruction
414*16c2d8bbSAnzo                                                    index = stride(stridePtrReg.value),
41588884326Sweiding liu                                                    flow_inner_idx = issueIndexIdx,
41688884326Sweiding liu                                                    eew = issueEew
41788884326Sweiding liu                                                  )
41888884326Sweiding liu  val realSegmentOffset               = Mux(isIndexed(issueInstType),
41988884326Sweiding liu                                            indexStride,
42088884326Sweiding liu                                            segmentOffset)
421*16c2d8bbSAnzo
422*16c2d8bbSAnzo  val vaddr                           = nextBaseVaddr + realSegmentOffset
423af23f085Sweiding liu
424b240e1c0SAnzooooo  val misalignLowVaddr                = Cat(latchVaddr(latchVaddr.getWidth - 1, 3), 0.U(3.W))
425fa5e530dScz4e  val misalignLowVaddrDup             = Cat(latchVaddrDup(latchVaddrDup.getWidth - 1, 3), 0.U(3.W))
426fa5e530dScz4e  val misalignHighVaddr               = Cat(latchVaddr(latchVaddr.getWidth - 1, 3) + 1.U, 0.U(3.W))
427fa5e530dScz4e  val misalignHighVaddrDup            = Cat(latchVaddrDup(latchVaddrDup.getWidth - 1, 3) + 1.U, 0.U(3.W))
428b240e1c0SAnzooooo  val notCross16ByteVaddr             = Cat(latchVaddr(latchVaddr.getWidth - 1, 4), 0.U(4.W))
429fa5e530dScz4e  val notCross16ByteVaddrDup          = Cat(latchVaddrDup(latchVaddrDup.getWidth - 1, 4), 0.U(4.W))
430b240e1c0SAnzooooo //  val misalignVaddr                   = Mux(notCross16ByteReg, notCross16ByteVaddr, Mux(isFirstSplit, misalignLowVaddr, misalignHighVaddr))
431b240e1c0SAnzooooo  val misalignVaddr                   = Mux(isFirstSplit, misalignLowVaddr, misalignHighVaddr)
432fa5e530dScz4e  val misalignVaddrDup                = Mux(isFirstSplit, misalignLowVaddrDup, misalignHighVaddrDup)
433b240e1c0SAnzooooo  val tlbReqVaddr                     = Mux(isMisalignReg, misalignVaddr, vaddr)
434af23f085Sweiding liu  //latch vaddr
435b240e1c0SAnzooooo  when(state === s_tlb_req && !isMisalignReg){
43646e9ee74SHaoyuan Feng    latchVaddr := vaddr(VAddrBits - 1, 0)
437fa5e530dScz4e    latchVaddrDup := vaddr(VAddrBits - 1, 0)
438af23f085Sweiding liu  }
43988884326Sweiding liu  /**
44088884326Sweiding liu   * tlb req and tlb resq
44188884326Sweiding liu   */
44288884326Sweiding liu
44388884326Sweiding liu  // query DTLB IO Assign
44488884326Sweiding liu  io.dtlb.req                         := DontCare
44588884326Sweiding liu  io.dtlb.resp.ready                  := true.B
44651764047Sweiding liu  io.dtlb.req.valid                   := state === s_tlb_req && segmentActive
447e7ab4635SHuijin Li  io.dtlb.req.bits.cmd                := Mux(isVSegLoad, TlbCmd.read, TlbCmd.write)
448b240e1c0SAnzooooo  io.dtlb.req.bits.vaddr              := tlbReqVaddr(VAddrBits - 1, 0)
449b240e1c0SAnzooooo  io.dtlb.req.bits.fullva             := tlbReqVaddr
45046e9ee74SHaoyuan Feng  io.dtlb.req.bits.checkfullva        := true.B
45188884326Sweiding liu  io.dtlb.req.bits.size               := instMicroOp.alignedType(2,0)
452e7ab4635SHuijin Li  io.dtlb.req.bits.memidx.is_ld       := isVSegLoad
453e7ab4635SHuijin Li  io.dtlb.req.bits.memidx.is_st       := isVSegStore
45488884326Sweiding liu  io.dtlb.req.bits.debug.robIdx       := instMicroOp.uop.robIdx
45588884326Sweiding liu  io.dtlb.req.bits.no_translate       := false.B
45688884326Sweiding liu  io.dtlb.req.bits.debug.pc           := instMicroOp.uop.pc
45788884326Sweiding liu  io.dtlb.req.bits.debug.isFirstIssue := DontCare
45888884326Sweiding liu  io.dtlb.req_kill                    := false.B
45988884326Sweiding liu
46079656063Slwd  val canTriggerException              = segmentIdx === 0.U || !instMicroOp.isFof // only elementIdx = 0 or is not fof can trigger
461726c5ee8SAnzooooo
462726c5ee8SAnzooooo  val segmentTrigger = Module(new VSegmentTrigger)
463726c5ee8SAnzooooo  segmentTrigger.io.fromCsrTrigger.tdataVec             := io.fromCsrTrigger.tdataVec
464726c5ee8SAnzooooo  segmentTrigger.io.fromCsrTrigger.tEnableVec           := io.fromCsrTrigger.tEnableVec
465726c5ee8SAnzooooo  segmentTrigger.io.fromCsrTrigger.triggerCanRaiseBpExp := io.fromCsrTrigger.triggerCanRaiseBpExp
466726c5ee8SAnzooooo  segmentTrigger.io.fromCsrTrigger.debugMode            := io.fromCsrTrigger.debugMode
467726c5ee8SAnzooooo  segmentTrigger.io.memType                             := isVSegLoad
468b240e1c0SAnzooooo  segmentTrigger.io.fromLoadStore.vaddr                 := Mux(isMisalignReg, misalignVaddr, latchVaddr)
469726c5ee8SAnzooooo  segmentTrigger.io.fromLoadStore.isVectorUnitStride    := false.B
470726c5ee8SAnzooooo  segmentTrigger.io.fromLoadStore.mask                  := 0.U
471726c5ee8SAnzooooo
472726c5ee8SAnzooooo  val triggerAction = segmentTrigger.io.toLoadStore.triggerAction
473726c5ee8SAnzooooo  val triggerDebugMode = TriggerAction.isDmode(triggerAction)
474726c5ee8SAnzooooo  val triggerBreakpoint = TriggerAction.isExp(triggerAction)
475726c5ee8SAnzooooo
47688884326Sweiding liu  // tlb resp
47788884326Sweiding liu  when(io.dtlb.resp.fire && state === s_wait_tlb_resp){
478df3b4b92SAnzooooo      exceptionVec(storePageFault)      := io.dtlb.resp.bits.excp(0).pf.st
479df3b4b92SAnzooooo      exceptionVec(loadPageFault)       := io.dtlb.resp.bits.excp(0).pf.ld
480df3b4b92SAnzooooo      exceptionVec(storeGuestPageFault) := io.dtlb.resp.bits.excp(0).gpf.st
481df3b4b92SAnzooooo      exceptionVec(loadGuestPageFault)  := io.dtlb.resp.bits.excp(0).gpf.ld
482df3b4b92SAnzooooo      exceptionVec(storeAccessFault)    := io.dtlb.resp.bits.excp(0).af.st
483df3b4b92SAnzooooo      exceptionVec(loadAccessFault)     := io.dtlb.resp.bits.excp(0).af.ld
48488884326Sweiding liu      when(!io.dtlb.resp.bits.miss){
48588884326Sweiding liu        instMicroOp.paddr             := io.dtlb.resp.bits.paddr(0)
486189833a1SHaoyuan Feng        instMicroOp.exceptionVaddr    := io.dtlb.resp.bits.fullva
487a53daa0fSHaoyuan Feng        instMicroOp.exceptionGpaddr   := io.dtlb.resp.bits.gpaddr(0)
488ad415ae0SXiaokun-Pei        instMicroOp.exceptionIsForVSnonLeafPTE  := io.dtlb.resp.bits.isForVSnonLeafPTE
489b240e1c0SAnzooooo        lowPagePaddr  := Mux(isMisalignReg && !notCross16ByteReg && !curPtr, io.dtlb.resp.bits.paddr(0), lowPagePaddr)
490b240e1c0SAnzooooo        lowPageGPaddr := Mux(isMisalignReg && !notCross16ByteReg && !curPtr, io.dtlb.resp.bits.gpaddr(0), lowPageGPaddr)
491b240e1c0SAnzooooo
492b240e1c0SAnzooooo        highPagePaddr  := Mux(isMisalignReg && !notCross16ByteReg && curPtr, io.dtlb.resp.bits.paddr(0), highPagePaddr)
493b240e1c0SAnzooooo        highPageGPaddr := Mux(isMisalignReg && !notCross16ByteReg && curPtr, io.dtlb.resp.bits.gpaddr(0), highPageGPaddr)
49488884326Sweiding liu      }
49588884326Sweiding liu  }
49688884326Sweiding liu  // pmp
49788884326Sweiding liu  // NOTE: only handle load/store exception here, if other exception happens, don't send here
498ccd66eefSAnzooooo  val exceptionWithPf = exceptionVec(storePageFault) || exceptionVec(loadPageFault) || exceptionVec(storeGuestPageFault) || exceptionVec(loadGuestPageFault)
499ccd66eefSAnzooooo  val pmp = (io.pmpResp.asUInt & Fill(io.pmpResp.asUInt.getWidth, !exceptionWithPf)).asTypeOf(new PMPRespBundle())
50088884326Sweiding liu  when(state === s_pm) {
501b240e1c0SAnzooooo    val highAddress = LookupTree(Mux(isIndexed(issueInstType), issueSew(1, 0), issueEew(1, 0)), List(
502b240e1c0SAnzooooo      "b00".U -> 0.U,
503b240e1c0SAnzooooo      "b01".U -> 1.U,
504b240e1c0SAnzooooo      "b10".U -> 3.U,
505b240e1c0SAnzooooo      "b11".U -> 7.U
506*16c2d8bbSAnzo    )) + vaddr(4, 0)
507b240e1c0SAnzooooo
508c41a9f78Slwd    val addr_aligned = LookupTree(Mux(isIndexed(issueInstType), issueSew(1, 0), issueEew(1, 0)), List(
509c41a9f78Slwd      "b00".U   -> true.B,                   //b
510*16c2d8bbSAnzo      "b01".U   -> (vaddr(0)    === 0.U), //h
511*16c2d8bbSAnzo      "b10".U   -> (vaddr(1, 0) === 0.U), //w
512*16c2d8bbSAnzo      "b11".U   -> (vaddr(2, 0) === 0.U)  //d
513c41a9f78Slwd    ))
514b240e1c0SAnzooooo
515*16c2d8bbSAnzo    notCross16ByteWire   := highAddress(4) === vaddr(4)
516*16c2d8bbSAnzo    isMisalignWire       := !addr_aligned && !isMisalignReg
517b240e1c0SAnzooooo    canHandleMisalign    := !pmp.mmio && !triggerBreakpoint && !triggerDebugMode
518*16c2d8bbSAnzo    exceptionVec(loadAddrMisaligned)  := isMisalignWire && isVSegLoad  && canTriggerException && pmp.mmio
519*16c2d8bbSAnzo    exceptionVec(storeAddrMisaligned) := isMisalignWire && isVSegStore && canTriggerException && pmp.mmio
520b240e1c0SAnzooooo
52188884326Sweiding liu    exception_va  := exceptionVec(storePageFault) || exceptionVec(loadPageFault) ||
522726c5ee8SAnzooooo                     exceptionVec(storeAccessFault) || exceptionVec(loadAccessFault) ||
523*16c2d8bbSAnzo                     triggerBreakpoint || triggerDebugMode || pmp.mmio
524a53daa0fSHaoyuan Feng    exception_gpa := exceptionVec(storeGuestPageFault) || exceptionVec(loadGuestPageFault)
525df3b4b92SAnzooooo    exception_pa  := pmp.st || pmp.ld || pmp.mmio
52688884326Sweiding liu
52788884326Sweiding liu    instMicroOp.exception_pa  := exception_pa
52888884326Sweiding liu    instMicroOp.exception_va  := exception_va
529a53daa0fSHaoyuan Feng    instMicroOp.exception_gpa := exception_gpa
53079656063Slwd    // update storeAccessFault bit. Currently, we don't support vector MMIO
531e7ab4635SHuijin Li    exceptionVec(loadAccessFault)  := (exceptionVec(loadAccessFault) || pmp.ld || pmp.mmio)   && isVSegLoad  && canTriggerException
532e7ab4635SHuijin Li    exceptionVec(storeAccessFault) := (exceptionVec(storeAccessFault) || pmp.st || pmp.mmio)  && isVSegStore && canTriggerException
533726c5ee8SAnzooooo    exceptionVec(breakPoint)       := triggerBreakpoint && canTriggerException
53488884326Sweiding liu
535e7ab4635SHuijin Li    exceptionVec(storePageFault)      := exceptionVec(storePageFault)      && isVSegStore && canTriggerException
536e7ab4635SHuijin Li    exceptionVec(loadPageFault)       := exceptionVec(loadPageFault)       && isVSegLoad  && canTriggerException
537e7ab4635SHuijin Li    exceptionVec(storeGuestPageFault) := exceptionVec(storeGuestPageFault) && isVSegStore && canTriggerException
538e7ab4635SHuijin Li    exceptionVec(loadGuestPageFault)  := exceptionVec(loadGuestPageFault)  && isVSegLoad  && canTriggerException
539df3b4b92SAnzooooo
540a53daa0fSHaoyuan Feng    when(exception_va || exception_gpa || exception_pa) {
54179656063Slwd      when(canTriggerException) {
54279656063Slwd        instMicroOp.exceptionVstart := segmentIdx // for exception
543c41a9f78Slwd      }.otherwise {
5441d1953a5SXuan Hu        instMicroOp.exceptionVl.valid := true.B
5451d1953a5SXuan Hu        instMicroOp.exceptionVl.bits := segmentIdx
546c41a9f78Slwd      }
54788884326Sweiding liu    }
548726c5ee8SAnzooooo
549726c5ee8SAnzooooo    when(exceptionVec(breakPoint) || triggerDebugMode) {
550726c5ee8SAnzooooo      instMicroOp.uop.trigger := triggerAction
551726c5ee8SAnzooooo    }
552b240e1c0SAnzooooo
553*16c2d8bbSAnzo    when(isMisalignWire && !(exception_va || exception_gpa || exception_pa)) {
554b240e1c0SAnzooooo      notCross16ByteReg := notCross16ByteWire
555b240e1c0SAnzooooo      isMisalignReg       := true.B
556b240e1c0SAnzooooo    }
5571d7a45cfSweiding liu  }
55888884326Sweiding liu
55988884326Sweiding liu  /**
56088884326Sweiding liu   * flush sbuffer IO Assign
56188884326Sweiding liu   */
56288884326Sweiding liu  io.flush_sbuffer.valid           := !sbufferEmpty && (state === s_flush_sbuffer_req)
56388884326Sweiding liu
564b240e1c0SAnzooooo  /**
565b240e1c0SAnzooooo  * update curPtr
566b240e1c0SAnzooooo  * */
567b240e1c0SAnzooooo  when(state === s_finish || state === s_latch_and_merge_data || state === s_send_data && stateNext =/= s_send_data) {
568b240e1c0SAnzooooo    isMisalignReg     := false.B
569b240e1c0SAnzooooo    notCross16ByteReg := false.B
570b240e1c0SAnzooooo    curPtr := false.B
571b240e1c0SAnzooooo  } .otherwise {
572b240e1c0SAnzooooo    when(isVSegLoad) {
573b240e1c0SAnzooooo      when(isMisalignReg && !notCross16ByteReg && state === s_misalign_merge_data) {
574b240e1c0SAnzooooo        curPtr := true.B
575b240e1c0SAnzooooo      }
576b240e1c0SAnzooooo    } .otherwise {
577b240e1c0SAnzooooo      when(isMisalignReg && !notCross16ByteReg && state === s_pm) {
578b240e1c0SAnzooooo        curPtr := !curPtr
579b240e1c0SAnzooooo      } .elsewhen(isMisalignReg && !notCross16ByteReg && state === s_pm && stateNext === s_send_data) {
580b240e1c0SAnzooooo        curPtr := false.B
581b240e1c0SAnzooooo      } .elsewhen(isMisalignReg && !notCross16ByteReg && state === s_send_data && stateNext === s_send_data && sbufferOut.fire) {
582b240e1c0SAnzooooo        curPtr := !curPtr
583b240e1c0SAnzooooo      }
584b240e1c0SAnzooooo    }
585b240e1c0SAnzooooo  }
586b240e1c0SAnzooooo
587b240e1c0SAnzooooo
58888884326Sweiding liu
58988884326Sweiding liu  /**
59088884326Sweiding liu   * merge data for load
59188884326Sweiding liu   */
592af23f085Sweiding liu  val cacheData = LookupTree(latchVaddr(3,0), List(
59386e91daeSweiding liu    "b0000".U -> io.rdcache.resp.bits.data_delayed(63,    0),
59486e91daeSweiding liu    "b0001".U -> io.rdcache.resp.bits.data_delayed(63,    8),
59586e91daeSweiding liu    "b0010".U -> io.rdcache.resp.bits.data_delayed(63,   16),
59686e91daeSweiding liu    "b0011".U -> io.rdcache.resp.bits.data_delayed(63,   24),
59786e91daeSweiding liu    "b0100".U -> io.rdcache.resp.bits.data_delayed(63,   32),
59886e91daeSweiding liu    "b0101".U -> io.rdcache.resp.bits.data_delayed(63,   40),
59986e91daeSweiding liu    "b0110".U -> io.rdcache.resp.bits.data_delayed(63,   48),
60086e91daeSweiding liu    "b0111".U -> io.rdcache.resp.bits.data_delayed(63,   56),
60186e91daeSweiding liu    "b1000".U -> io.rdcache.resp.bits.data_delayed(127,  64),
60286e91daeSweiding liu    "b1001".U -> io.rdcache.resp.bits.data_delayed(127,  72),
60386e91daeSweiding liu    "b1010".U -> io.rdcache.resp.bits.data_delayed(127,  80),
60486e91daeSweiding liu    "b1011".U -> io.rdcache.resp.bits.data_delayed(127,  88),
60586e91daeSweiding liu    "b1100".U -> io.rdcache.resp.bits.data_delayed(127,  96),
60686e91daeSweiding liu    "b1101".U -> io.rdcache.resp.bits.data_delayed(127, 104),
60786e91daeSweiding liu    "b1110".U -> io.rdcache.resp.bits.data_delayed(127, 112),
60886e91daeSweiding liu    "b1111".U -> io.rdcache.resp.bits.data_delayed(127, 120)
60986e91daeSweiding liu  ))
610b240e1c0SAnzooooo
611b240e1c0SAnzooooo  val misalignLowData  = LookupTree(latchVaddr(3,0), List(
612b240e1c0SAnzooooo    "b1001".U -> io.rdcache.resp.bits.data_delayed(127,  72),
613b240e1c0SAnzooooo    "b1010".U -> io.rdcache.resp.bits.data_delayed(127,  80),
614b240e1c0SAnzooooo    "b1011".U -> io.rdcache.resp.bits.data_delayed(127,  88),
615b240e1c0SAnzooooo    "b1100".U -> io.rdcache.resp.bits.data_delayed(127,  96),
616b240e1c0SAnzooooo    "b1101".U -> io.rdcache.resp.bits.data_delayed(127, 104),
617b240e1c0SAnzooooo    "b1110".U -> io.rdcache.resp.bits.data_delayed(127, 112),
618b240e1c0SAnzooooo    "b1111".U -> io.rdcache.resp.bits.data_delayed(127, 120)
619b240e1c0SAnzooooo  ))
620b240e1c0SAnzooooo
621b240e1c0SAnzooooo  val misalignCombinedData = LookupTree(latchVaddr(3,0), List(
622b240e1c0SAnzooooo    "b1001".U -> Cat(io.rdcache.resp.bits.data_delayed, combinedData(55,    0))(63, 0),
623b240e1c0SAnzooooo    "b1010".U -> Cat(io.rdcache.resp.bits.data_delayed, combinedData(47,    0))(63, 0),
624b240e1c0SAnzooooo    "b1011".U -> Cat(io.rdcache.resp.bits.data_delayed, combinedData(39,    0))(63, 0),
625b240e1c0SAnzooooo    "b1100".U -> Cat(io.rdcache.resp.bits.data_delayed, combinedData(31,    0))(63, 0),
626b240e1c0SAnzooooo    "b1101".U -> Cat(io.rdcache.resp.bits.data_delayed, combinedData(23,    0))(63, 0),
627b240e1c0SAnzooooo    "b1110".U -> Cat(io.rdcache.resp.bits.data_delayed, combinedData(15,    0))(63, 0),
628b240e1c0SAnzooooo    "b1111".U -> Cat(io.rdcache.resp.bits.data_delayed, combinedData(7,     0))(63, 0)
629b240e1c0SAnzooooo  ))
630b240e1c0SAnzooooo  when(state === s_misalign_merge_data && segmentActive){
631b240e1c0SAnzooooo    when(!curPtr) {
632b240e1c0SAnzooooo      combinedData := misalignLowData
633b240e1c0SAnzooooo    } .otherwise {
634b240e1c0SAnzooooo      combinedData := misalignCombinedData
635b240e1c0SAnzooooo    }
636b240e1c0SAnzooooo  }
637b240e1c0SAnzooooo
638b240e1c0SAnzooooo  val shiftData    = (io.rdcache.resp.bits.data_delayed >> (latchVaddr(3, 0) << 3)).asUInt(63, 0)
639b240e1c0SAnzooooo  val mergemisalignData = Mux(notCross16ByteReg, shiftData, combinedData)
640b240e1c0SAnzooooo  val pickData  = rdataVecHelper(alignedType(1,0), Mux(isMisalignReg, mergemisalignData, cacheData))
64188884326Sweiding liu  val mergedData = mergeDataWithElemIdx(
64288884326Sweiding liu    oldData = data(splitPtr.value),
64388884326Sweiding liu    newData = Seq(pickData),
64488884326Sweiding liu    alignedType = alignedType(1,0),
64588884326Sweiding liu    elemIdx = Seq(elemIdxInVd),
64688884326Sweiding liu    valids = Seq(true.B)
64788884326Sweiding liu  )
64851764047Sweiding liu  when(state === s_latch_and_merge_data && segmentActive){
64988884326Sweiding liu    data(splitPtr.value) := mergedData
65088884326Sweiding liu  }
651b240e1c0SAnzooooo
652b240e1c0SAnzooooo
65388884326Sweiding liu  /**
65488884326Sweiding liu   * split data for store
65588884326Sweiding liu   * */
65688884326Sweiding liu  val splitData = genVSData(
65788884326Sweiding liu    data = data(splitPtr.value),
65888884326Sweiding liu    elemIdx = elemIdxInVd,
65988884326Sweiding liu    alignedType = alignedType
66088884326Sweiding liu  )
66188884326Sweiding liu  val flowData  = genVWdata(splitData, alignedType) // TODO: connect vstd, pass vector data
662af23f085Sweiding liu  val wmask     = genVWmask(latchVaddr, alignedType(1, 0)) & Fill(VLENB, segmentActive)
663b240e1c0SAnzooooo  val bmask     = genBasemask(latchVaddr, alignedType(1, 0)) & Fill(VLENB, segmentActive)
664b240e1c0SAnzooooo  val dcacheReqVaddr = Mux(isMisalignReg, misalignVaddr, latchVaddr)
665fa5e530dScz4e  val dcacheReqVaddrDup = Mux(isMisalignReg, misalignVaddrDup, latchVaddrDup)
666b240e1c0SAnzooooo  val dcacheReqPaddr = Mux(isMisalignReg, Cat(instMicroOp.paddr(instMicroOp.paddr.getWidth - 1, PageOffsetWidth), misalignVaddr(PageOffsetWidth - 1, 0)), instMicroOp.paddr)
66788884326Sweiding liu  /**
6688d790a87Sweiding liu   * rdcache req, write request don't need to query dcache, because we write element to sbuffer
66988884326Sweiding liu   */
670fe518d28Sweiding liu  io.rdcache.req                    := DontCare
671e7ab4635SHuijin Li  io.rdcache.req.valid              := state === s_cache_req && isVSegLoad
672fe518d28Sweiding liu  io.rdcache.req.bits.cmd           := MemoryOpConstants.M_XRD
673b240e1c0SAnzooooo  io.rdcache.req.bits.vaddr         := dcacheReqVaddr
674fa5e530dScz4e  io.rdcache.req.bits.vaddr_dup     := dcacheReqVaddrDup
675fe518d28Sweiding liu  io.rdcache.req.bits.mask          := mask
676fe518d28Sweiding liu  io.rdcache.req.bits.data          := flowData
677fe518d28Sweiding liu  io.rdcache.pf_source              := LOAD_SOURCE.U
678fe518d28Sweiding liu  io.rdcache.req.bits.id            := DontCare
679fe518d28Sweiding liu  io.rdcache.resp.ready             := true.B
680b240e1c0SAnzooooo  io.rdcache.s1_paddr_dup_lsu       := dcacheReqPaddr
681b240e1c0SAnzooooo  io.rdcache.s1_paddr_dup_dcache    := dcacheReqPaddr
682fe518d28Sweiding liu  io.rdcache.s1_kill                := false.B
68308b0bc30Shappy-lx  io.rdcache.s1_kill_data_read      := false.B
684fe518d28Sweiding liu  io.rdcache.s2_kill                := false.B
685fe518d28Sweiding liu  if (env.FPGAPlatform){
686fe518d28Sweiding liu    io.rdcache.s0_pc                := DontCare
687fe518d28Sweiding liu    io.rdcache.s1_pc                := DontCare
688fe518d28Sweiding liu    io.rdcache.s2_pc                := DontCare
689fe518d28Sweiding liu  }else{
690fe518d28Sweiding liu    io.rdcache.s0_pc                := instMicroOp.uop.pc
691fe518d28Sweiding liu    io.rdcache.s1_pc                := instMicroOp.uop.pc
692fe518d28Sweiding liu    io.rdcache.s2_pc                := instMicroOp.uop.pc
693fe518d28Sweiding liu  }
694fe518d28Sweiding liu  io.rdcache.replacementUpdated     := false.B
695b240e1c0SAnzooooo  io.rdcache.is128Req               := notCross16ByteReg
696fe518d28Sweiding liu
697fe518d28Sweiding liu
698fe518d28Sweiding liu  /**
699fe518d28Sweiding liu   * write data to sbuffer
700fe518d28Sweiding liu   * */
701b240e1c0SAnzooooo  val sbufferAddrLow4bit = latchVaddr(3, 0)
702b240e1c0SAnzooooo
703b240e1c0SAnzooooo  val notCross16BytePaddr          = Cat(instMicroOp.paddr(instMicroOp.paddr.getWidth - 1, 4), 0.U(4.W))
704b240e1c0SAnzooooo  val notCross16ByteData           = flowData << (sbufferAddrLow4bit << 3)
705b240e1c0SAnzooooo
706b240e1c0SAnzooooo  val Cross16ByteMask = Wire(UInt(32.W))
707b240e1c0SAnzooooo  val Cross16ByteData = Wire(UInt(256.W))
708b240e1c0SAnzooooo  Cross16ByteMask := bmask << sbufferAddrLow4bit
709b240e1c0SAnzooooo  Cross16ByteData := flowData << (sbufferAddrLow4bit << 3)
710b240e1c0SAnzooooo
711b240e1c0SAnzooooo  val vaddrLow  = Cat(latchVaddr(latchVaddr.getWidth - 1, 3), 0.U(3.W))
712b240e1c0SAnzooooo  val vaddrHigh = Cat(latchVaddr(latchVaddr.getWidth - 1, 3), 0.U(3.W)) + 8.U
713b240e1c0SAnzooooo
714b240e1c0SAnzooooo
715b240e1c0SAnzooooo  val paddrLow  = Cat(lowPagePaddr(lowPagePaddr.getWidth - 1, 3), 0.U(3.W))
716b240e1c0SAnzooooo  val paddrHigh = Cat(instMicroOp.paddr(instMicroOp.paddr.getWidth - 1, 3), 0.U(3.W))
717b240e1c0SAnzooooo
718b240e1c0SAnzooooo  val maskLow   = Cross16ByteMask(15, 0)
719b240e1c0SAnzooooo  val maskHigh  = Cross16ByteMask(31, 16)
720b240e1c0SAnzooooo
721b240e1c0SAnzooooo  val dataLow   = Cross16ByteData(127, 0)
722b240e1c0SAnzooooo  val dataHigh  = Cross16ByteData(255, 128)
723b240e1c0SAnzooooo
724b240e1c0SAnzooooo  val sbuffermisalignMask          = Mux(notCross16ByteReg, wmask, Mux(isFirstSplit, maskLow, maskHigh))
725b240e1c0SAnzooooo  val sbuffermisalignData          = Mux(notCross16ByteReg, notCross16ByteData, Mux(isFirstSplit, dataLow, dataHigh))
726b240e1c0SAnzooooo  val sbuffermisalignPaddr         = Mux(notCross16ByteReg, notCross16BytePaddr, Mux(isFirstSplit, paddrLow, paddrHigh))
727b240e1c0SAnzooooo  val sbuffermisalignVaddr         = Mux(notCross16ByteReg, notCross16ByteVaddr, Mux(isFirstSplit, vaddrLow, vaddrHigh))
728b240e1c0SAnzooooo
729b240e1c0SAnzooooo  val sbufferMask                  = Mux(isMisalignReg, sbuffermisalignMask, wmask)
730b240e1c0SAnzooooo  val sbufferData                  = Mux(isMisalignReg, sbuffermisalignData, flowData)
731b240e1c0SAnzooooo  val sbufferVaddr                 = Mux(isMisalignReg, sbuffermisalignVaddr, latchVaddr)
732b240e1c0SAnzooooo  val sbufferPaddr                 = Mux(isMisalignReg, sbuffermisalignPaddr, instMicroOp.paddr)
733b240e1c0SAnzooooo
734b240e1c0SAnzooooo  dontTouch(wmask)
735b240e1c0SAnzooooo  dontTouch(Cross16ByteMask)
73641d8d239Shappy-lx  sbufferOut.bits                  := DontCare
73741d8d239Shappy-lx  sbufferOut.valid                 := state === s_send_data && segmentActive
73841d8d239Shappy-lx  sbufferOut.bits.vecValid         := state === s_send_data && segmentActive
739b240e1c0SAnzooooo  sbufferOut.bits.mask             := sbufferMask
740b240e1c0SAnzooooo  sbufferOut.bits.data             := sbufferData
741b240e1c0SAnzooooo  sbufferOut.bits.vaddr            := sbufferVaddr
74241d8d239Shappy-lx  sbufferOut.bits.cmd              := MemoryOpConstants.M_XWR
74341d8d239Shappy-lx  sbufferOut.bits.id               := DontCare
744b240e1c0SAnzooooo  sbufferOut.bits.addr             := sbufferPaddr
745fe518d28Sweiding liu
74641d8d239Shappy-lx  NewPipelineConnect(
74741d8d239Shappy-lx    sbufferOut, io.sbuffer, io.sbuffer.fire,
74841d8d239Shappy-lx    false.B,
74941d8d239Shappy-lx    Option(s"VSegmentUnitPipelineConnect")
75041d8d239Shappy-lx  )
75188884326Sweiding liu
7522e0c78b3SAnzo  io.vecDifftestInfo.valid         := io.sbuffer.valid
7536edb1480SAnzooooo  io.vecDifftestInfo.bits          := uopq(deqPtr.value).uop
7546edb1480SAnzooooo
75588884326Sweiding liu  /**
75688884326Sweiding liu   * update ptr
75788884326Sweiding liu   * */
75841d8d239Shappy-lx  private val fieldActiveWirteFinish = sbufferOut.fire && segmentActive // writedata finish and is a active segment
75941d8d239Shappy-lx  XSError(sbufferOut.fire && !segmentActive, "Attempt write inactive segment to sbuffer, something wrong!\n")
76097db011aSweiding liu
761b240e1c0SAnzooooo  private val segmentInactiveFinish = ((state === s_latch_and_merge_data) || (state === s_send_data && stateNext =/= s_send_data)) && !segmentActive
76288884326Sweiding liu
763839e1a88SAnzooooo  val splitPtrOffset = Mux(
764839e1a88SAnzooooo    isIndexed(instType),
765839e1a88SAnzooooo    Mux(lmul.asSInt < 0.S, 1.U, (1.U << lmul).asUInt),
766839e1a88SAnzooooo    Mux(emul.asSInt < 0.S, 1.U, (1.U << emul).asUInt)
767839e1a88SAnzooooo  )
768404eeb7dSweiding liu  splitPtrNext :=
76997db011aSweiding liu    Mux(fieldIdx === maxNfields || !segmentActive, // if segment is active, need to complete this segment, otherwise jump to next segment
77069a3c27aSAnzooooo      // segment finish, By shifting 'issueUopFlowNumLog2' to the right to ensure that emul != 1 can correctly generate lateral offset.
77169a3c27aSAnzooooo     (deqPtr + ((segmentIdx +& 1.U) >> issueUopFlowNumLog2).asUInt),
77269a3c27aSAnzooooo      // next field.
77369a3c27aSAnzooooo     (splitPtr + splitPtrOffset)
77469a3c27aSAnzooooo    )
77569a3c27aSAnzooooo
776189d8d00SAnzo  if (backendParams.debugEn){
77769a3c27aSAnzooooo    dontTouch(issueUopFlowNumLog2)
77869a3c27aSAnzooooo    dontTouch(issueEmul)
779404eeb7dSweiding liu    dontTouch(splitPtrNext)
780404eeb7dSweiding liu    dontTouch(stridePtr)
78169a3c27aSAnzooooo    dontTouch(segmentActive)
782189d8d00SAnzo  }
78388884326Sweiding liu
78488884326Sweiding liu  // update splitPtr
785b240e1c0SAnzooooo  when(state === s_latch_and_merge_data || (state === s_send_data && stateNext =/= s_send_data && (fieldActiveWirteFinish || !segmentActive))){
78688884326Sweiding liu    splitPtr := splitPtrNext
787321866f2Slwd  }.elsewhen(io.in.fire && !instMicroOpValid){
78888884326Sweiding liu    splitPtr := deqPtr // initial splitPtr
78988884326Sweiding liu  }
79088884326Sweiding liu
791*16c2d8bbSAnzo
792*16c2d8bbSAnzo  val fieldIdxWire      = WireInit(fieldIdx)
793*16c2d8bbSAnzo  val segmentIdxWire    = WireInit(segmentIdx)
794*16c2d8bbSAnzo  val nextBaseVaddrWire = (baseVaddr + (fieldIdxWire << alignedType).asUInt)
795*16c2d8bbSAnzo
796*16c2d8bbSAnzo  nextBaseVaddr  := RegEnable(nextBaseVaddrWire, 0.U, stateNext === s_tlb_req)
797*16c2d8bbSAnzo
79888884326Sweiding liu  // update stridePtr, only use in index
79926c6e087Sweiding liu  val strideOffset     = Mux(isIndexed(issueInstType), segmentIdx >> issueMaxIdxInIndexLog2, 0.U)
800*16c2d8bbSAnzo  val strideOffsetWire = Mux(isIndexed(issueInstType), segmentIdxWire >> issueMaxIdxInIndexLog2, 0.U)
80188884326Sweiding liu  stridePtr       := deqPtr + strideOffset
802*16c2d8bbSAnzo  stridePtrReg    := deqPtr + strideOffsetWire
80388884326Sweiding liu
80488884326Sweiding liu  // update fieldIdx
805321866f2Slwd  when(io.in.fire && !instMicroOpValid){ // init
806*16c2d8bbSAnzo    fieldIdxWire := 0.U
807*16c2d8bbSAnzo    fieldIdx := fieldIdxWire
80897db011aSweiding liu  }.elsewhen(state === s_latch_and_merge_data && segmentActive ||
809b240e1c0SAnzooooo            (state === s_send_data && stateNext =/= s_send_data && fieldActiveWirteFinish)){ // only if segment is active
81097db011aSweiding liu
81197db011aSweiding liu    /* next segment, only if segment complete */
812*16c2d8bbSAnzo    fieldIdxWire := Mux(fieldIdx === maxNfields, 0.U, fieldIdx + 1.U)
813*16c2d8bbSAnzo    fieldIdx := fieldIdxWire
81497db011aSweiding liu  }.elsewhen(segmentInactiveFinish){ // segment is inactive, go to next segment
815*16c2d8bbSAnzo    fieldIdxWire := 0.U
816*16c2d8bbSAnzo    fieldIdx := fieldIdxWire
81788884326Sweiding liu  }
818*16c2d8bbSAnzo
819*16c2d8bbSAnzo
82051764047Sweiding liu  //update segmentIdx
821321866f2Slwd  when(io.in.fire && !instMicroOpValid){
822*16c2d8bbSAnzo    segmentIdxWire := 0.U
823*16c2d8bbSAnzo    segmentIdx := segmentIdxWire
824b240e1c0SAnzooooo  }.elsewhen(fieldIdx === maxNfields && (state === s_latch_and_merge_data || (state === s_send_data && stateNext =/= s_send_data && fieldActiveWirteFinish)) &&
82597db011aSweiding liu             segmentIdx =/= maxSegIdx){ // next segment, only if segment is active
82697db011aSweiding liu
827*16c2d8bbSAnzo    segmentIdxWire := segmentIdx + 1.U
828*16c2d8bbSAnzo    segmentIdx := segmentIdxWire
82997db011aSweiding liu  }.elsewhen(segmentInactiveFinish && segmentIdx =/= maxSegIdx){ // if segment is inactive, go to next segment
830*16c2d8bbSAnzo    segmentIdxWire := segmentIdx + 1.U
831*16c2d8bbSAnzo    segmentIdx := segmentIdxWire
83251764047Sweiding liu  }
83351764047Sweiding liu
834*16c2d8bbSAnzo
83588884326Sweiding liu  //update segmentOffset
83697db011aSweiding liu  /* when segment is active or segment is inactive, increase segmentOffset */
837b240e1c0SAnzooooo  when((fieldIdx === maxNfields && (state === s_latch_and_merge_data || (state === s_send_data && stateNext =/= s_send_data && fieldActiveWirteFinish))) ||
83897db011aSweiding liu       segmentInactiveFinish){
83997db011aSweiding liu
840b2e0a7baSweiding liu    segmentOffset := segmentOffset + Mux(isUnitStride(issueInstType), (maxNfields +& 1.U) << issueEew(1, 0), stride(stridePtr.value))
84188884326Sweiding liu  }
84288884326Sweiding liu
843*16c2d8bbSAnzo
84488884326Sweiding liu  //update deqPtr
84508b0bc30Shappy-lx  when((state === s_finish) && !isEmpty(enqPtr, deqPtr)){
84688884326Sweiding liu    deqPtr := deqPtr + 1.U
84788884326Sweiding liu  }
84888884326Sweiding liu
849df3b4b92SAnzooooo
850df3b4b92SAnzooooo  /*************************************************************************
851df3b4b92SAnzooooo   *                            fof logic
852df3b4b92SAnzooooo   *************************************************************************/
853df3b4b92SAnzooooo
854df3b4b92SAnzooooo  //Enq
855df3b4b92SAnzooooo  when(isEnqFixVlUop && !fofBufferValid) { fofBuffer := io.in.bits.uop }
856df3b4b92SAnzooooo  when(isEnqFixVlUop && !fofBufferValid) { fofBufferValid := true.B }
857df3b4b92SAnzooooo
858df3b4b92SAnzooooo  //Deq
859df3b4b92SAnzooooo  val fofFixVlValid                    = state === s_fof_fix_vl && fofBufferValid
860df3b4b92SAnzooooo
861df3b4b92SAnzooooo  when(fofFixVlValid) { fofBuffer      := 0.U.asTypeOf(new DynInst) }
862df3b4b92SAnzooooo  when(fofFixVlValid) { fofBufferValid := false.B }
863df3b4b92SAnzooooo
864df3b4b92SAnzooooo
86588884326Sweiding liu  /*************************************************************************
86688884326Sweiding liu   *                            dequeue logic
86788884326Sweiding liu   *************************************************************************/
868842df083Slwd  val vdIdxInField = GenUopIdxInField(Mux(isIndexed(instType), issueLmul, issueEmul), uopq(deqPtr.value).uop.vpu.vuopIdx)
869157b169cSweiding liu  /*select mask of vd, maybe remove in feature*/
870157b169cSweiding liu  val realEw        = Mux(isIndexed(issueInstType), issueSew(1, 0), issueEew(1, 0))
871157b169cSweiding liu  val maskDataVec: Vec[UInt] = VecDataToMaskDataVec(instMicroOp.mask, realEw)
872157b169cSweiding liu  val maskUsed      = maskDataVec(vdIdxInField)
8731d7a45cfSweiding liu
87488884326Sweiding liu  when(stateNext === s_idle){
875321866f2Slwd    instMicroOpValid := false.B
87688884326Sweiding liu  }
87708b0bc30Shappy-lx  // writeback to backend
87808b0bc30Shappy-lx  val writebackOut                     = WireInit(io.uopwriteback.bits)
879df3b4b92SAnzooooo  val writebackValid                   = (state === s_finish) && !isEmpty(enqPtr, deqPtr) || fofFixVlValid
880df3b4b92SAnzooooo
881df3b4b92SAnzooooo  when(fofFixVlValid) {
882df3b4b92SAnzooooo    writebackOut.uop                    := fofBuffer
8831d1953a5SXuan Hu    writebackOut.uop.vpu.vl             := instMicroOp.exceptionVl.bits
8841d1953a5SXuan Hu    writebackOut.data                   := instMicroOp.exceptionVl.bits
885df3b4b92SAnzooooo    writebackOut.mask.get               := Fill(VLEN, 1.U)
886df3b4b92SAnzooooo    writebackOut.uop.vpu.vmask          := Fill(VLEN, 1.U)
887df3b4b92SAnzooooo  }.otherwise{
88808b0bc30Shappy-lx    writebackOut.uop                    := uopq(deqPtr.value).uop
88908b0bc30Shappy-lx    writebackOut.uop.vpu                := instMicroOp.uop.vpu
8904598028fSAnzooooo    writebackOut.uop.trigger            := instMicroOp.uop.trigger
89108b0bc30Shappy-lx    writebackOut.uop.exceptionVec       := instMicroOp.uop.exceptionVec
89208b0bc30Shappy-lx    writebackOut.mask.get               := instMicroOp.mask
89308b0bc30Shappy-lx    writebackOut.data                   := data(deqPtr.value)
89408b0bc30Shappy-lx    writebackOut.vdIdx.get              := vdIdxInField
8951d1953a5SXuan Hu    writebackOut.uop.vpu.vl             := Mux(instMicroOp.exceptionVl.valid, instMicroOp.exceptionVl.bits, instMicroOp.vl)
8964598028fSAnzooooo    writebackOut.uop.vpu.vstart         := Mux(instMicroOp.uop.exceptionVec.asUInt.orR || TriggerAction.isDmode(instMicroOp.uop.trigger), instMicroOp.exceptionVstart, instMicroOp.vstart)
89708b0bc30Shappy-lx    writebackOut.uop.vpu.vmask          := maskUsed
89808b0bc30Shappy-lx    writebackOut.uop.vpu.vuopIdx        := uopq(deqPtr.value).uop.vpu.vuopIdx
899785e3bfdSXuan Hu    // when exception updates vl, should use vtu strategy.
900785e3bfdSXuan Hu    writebackOut.uop.vpu.vta            := Mux(instMicroOp.exceptionVl.valid, VType.tu, instMicroOp.uop.vpu.vta)
90108b0bc30Shappy-lx    writebackOut.debug                  := DontCare
90208b0bc30Shappy-lx    writebackOut.vdIdxInField.get       := vdIdxInField
90308b0bc30Shappy-lx    writebackOut.uop.robIdx             := instMicroOp.uop.robIdx
90408b0bc30Shappy-lx    writebackOut.uop.fuOpType           := instMicroOp.uop.fuOpType
905df3b4b92SAnzooooo  }
90608b0bc30Shappy-lx
90708b0bc30Shappy-lx  io.uopwriteback.valid               := RegNext(writebackValid)
90808b0bc30Shappy-lx  io.uopwriteback.bits                := RegEnable(writebackOut, writebackValid)
90908b0bc30Shappy-lx
91008b0bc30Shappy-lx  dontTouch(writebackValid)
91188884326Sweiding liu
91288884326Sweiding liu  //to RS
91308b0bc30Shappy-lx  val feedbackOut                      = WireInit(0.U.asTypeOf(io.feedback.bits))
91408b0bc30Shappy-lx  val feedbackValid                    = state === s_finish && !isEmpty(enqPtr, deqPtr)
91508b0bc30Shappy-lx  feedbackOut.hit                     := true.B
91608b0bc30Shappy-lx  feedbackOut.robIdx                  := instMicroOp.uop.robIdx
91708b0bc30Shappy-lx  feedbackOut.sourceType              := DontCare
91808b0bc30Shappy-lx  feedbackOut.flushState              := DontCare
91908b0bc30Shappy-lx  feedbackOut.dataInvalidSqIdx        := DontCare
92008b0bc30Shappy-lx  feedbackOut.sqIdx                   := uopq(deqPtr.value).uop.sqIdx
92108b0bc30Shappy-lx  feedbackOut.lqIdx                   := uopq(deqPtr.value).uop.lqIdx
92208b0bc30Shappy-lx
92308b0bc30Shappy-lx  io.feedback.valid                   := RegNext(feedbackValid)
92408b0bc30Shappy-lx  io.feedback.bits                    := RegEnable(feedbackOut, feedbackValid)
92508b0bc30Shappy-lx
92608b0bc30Shappy-lx  dontTouch(feedbackValid)
92788884326Sweiding liu
92888884326Sweiding liu  // exception
929c41a9f78Slwd  io.exceptionInfo                    := DontCare
930c41a9f78Slwd  io.exceptionInfo.bits.robidx        := instMicroOp.uop.robIdx
931842df083Slwd  io.exceptionInfo.bits.uopidx        := uopq(deqPtr.value).uop.vpu.vuopIdx
93279656063Slwd  io.exceptionInfo.bits.vstart        := instMicroOp.exceptionVstart
93379656063Slwd  io.exceptionInfo.bits.vaddr         := instMicroOp.exceptionVaddr
934a53daa0fSHaoyuan Feng  io.exceptionInfo.bits.gpaddr        := instMicroOp.exceptionGpaddr
935ad415ae0SXiaokun-Pei  io.exceptionInfo.bits.isForVSnonLeafPTE := instMicroOp.exceptionIsForVSnonLeafPTE
9361d1953a5SXuan Hu  io.exceptionInfo.bits.vl            := instMicroOp.exceptionVl.bits
93700242abeSweiding liu  io.exceptionInfo.valid              := (state === s_finish) && instMicroOp.uop.exceptionVec.asUInt.orR && !isEmpty(enqPtr, deqPtr)
93888884326Sweiding liu}
93988884326Sweiding liu
940