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