1780712aaSxiaofeibao-xjtu/*************************************************************************************** 2780712aaSxiaofeibao-xjtu * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3780712aaSxiaofeibao-xjtu * Copyright (c) 2020-2021 Peng Cheng Laboratory 4780712aaSxiaofeibao-xjtu * 5780712aaSxiaofeibao-xjtu * XiangShan is licensed under Mulan PSL v2. 6780712aaSxiaofeibao-xjtu * You can use this software according to the terms and conditions of the Mulan PSL v2. 7780712aaSxiaofeibao-xjtu * You may obtain a copy of Mulan PSL v2 at: 8780712aaSxiaofeibao-xjtu * http://license.coscl.org.cn/MulanPSL2 9780712aaSxiaofeibao-xjtu * 10780712aaSxiaofeibao-xjtu * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11780712aaSxiaofeibao-xjtu * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12780712aaSxiaofeibao-xjtu * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13780712aaSxiaofeibao-xjtu * 14780712aaSxiaofeibao-xjtu * See the Mulan PSL v2 for more details. 15780712aaSxiaofeibao-xjtu ***************************************************************************************/ 16780712aaSxiaofeibao-xjtu 17780712aaSxiaofeibao-xjtupackage xiangshan.backend.rob 18780712aaSxiaofeibao-xjtu 19780712aaSxiaofeibao-xjtuimport org.chipsalliance.cde.config.Parameters 20780712aaSxiaofeibao-xjtuimport chisel3._ 21780712aaSxiaofeibao-xjtuimport chisel3.util._ 22780712aaSxiaofeibao-xjtuimport difftest._ 23780712aaSxiaofeibao-xjtuimport freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp} 24780712aaSxiaofeibao-xjtuimport utility._ 25780712aaSxiaofeibao-xjtuimport utils._ 26780712aaSxiaofeibao-xjtuimport xiangshan._ 27780712aaSxiaofeibao-xjtuimport xiangshan.backend.BackendParams 28780712aaSxiaofeibao-xjtuimport xiangshan.backend.Bundles.{DynInst, ExceptionInfo, ExuOutput} 29780712aaSxiaofeibao-xjtuimport xiangshan.backend.fu.{FuConfig, FuType} 30780712aaSxiaofeibao-xjtuimport xiangshan.frontend.FtqPtr 31780712aaSxiaofeibao-xjtuimport xiangshan.mem.{LqPtr, LsqEnqIO, SqPtr} 32780712aaSxiaofeibao-xjtuimport xiangshan.backend.Bundles.{DynInst, ExceptionInfo, ExuOutput} 33780712aaSxiaofeibao-xjtuimport xiangshan.backend.ctrlblock.{DebugLSIO, DebugLsInfo, LsTopdownInfo} 34780712aaSxiaofeibao-xjtuimport xiangshan.backend.fu.vector.Bundles.VType 35780712aaSxiaofeibao-xjtuimport xiangshan.backend.rename.SnapshotGenerator 36780712aaSxiaofeibao-xjtu 37780712aaSxiaofeibao-xjtuclass NewRobDeqPtrWrapper(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper { 38780712aaSxiaofeibao-xjtu val io = IO(new Bundle { 39780712aaSxiaofeibao-xjtu // for commits/flush 40780712aaSxiaofeibao-xjtu val state = Input(UInt(2.W)) 41780712aaSxiaofeibao-xjtu val deq_v = Vec(CommitWidth, Input(Bool())) 42780712aaSxiaofeibao-xjtu val deq_w = Vec(CommitWidth, Input(Bool())) 43780712aaSxiaofeibao-xjtu val hasCommitted = Vec(CommitWidth, Input(Bool())) 44780712aaSxiaofeibao-xjtu val allCommitted = Input(Bool()) 45780712aaSxiaofeibao-xjtu val exception_state = Flipped(ValidIO(new RobExceptionInfo)) 46780712aaSxiaofeibao-xjtu // for flush: when exception occurs, reset deqPtrs to range(0, CommitWidth) 47780712aaSxiaofeibao-xjtu val intrBitSetReg = Input(Bool()) 48571677c9Sxiaofeibao-xjtu val allowOnlyOneCommit = Input(Bool()) 49780712aaSxiaofeibao-xjtu val hasNoSpecExec = Input(Bool()) 50780712aaSxiaofeibao-xjtu val interrupt_safe = Input(Bool()) 51780712aaSxiaofeibao-xjtu val blockCommit = Input(Bool()) 52780712aaSxiaofeibao-xjtu // output: the CommitWidth deqPtr 53780712aaSxiaofeibao-xjtu val out = Vec(CommitWidth, Output(new RobPtr)) 54780712aaSxiaofeibao-xjtu val next_out = Vec(CommitWidth, Output(new RobPtr)) 55780712aaSxiaofeibao-xjtu val commitCnt = Output(UInt(log2Up(CommitWidth+1).W)) 56780712aaSxiaofeibao-xjtu val canCommitPriorityCond = Output(Vec(CommitWidth+1,Bool())) 57780712aaSxiaofeibao-xjtu val commitEn = Output(Bool()) 58780712aaSxiaofeibao-xjtu }) 59780712aaSxiaofeibao-xjtu 60780712aaSxiaofeibao-xjtu val bankAddrWidth = log2Up(CommitWidth) 61780712aaSxiaofeibao-xjtu val deqPtrVec = RegInit(VecInit((0 until CommitWidth).map(_.U.asTypeOf(new RobPtr)))) 62780712aaSxiaofeibao-xjtu val deqPosition = deqPtrVec(0).value(bankAddrWidth - 1, 0) 63780712aaSxiaofeibao-xjtu 64780712aaSxiaofeibao-xjtu // for exceptions (flushPipe included) and interrupts: 65780712aaSxiaofeibao-xjtu // only consider the first instruction 66780712aaSxiaofeibao-xjtu val intrEnable = io.intrBitSetReg && !io.hasNoSpecExec && io.interrupt_safe 67780712aaSxiaofeibao-xjtu val exceptionEnable = io.deq_w(deqPosition) && io.exception_state.valid && io.exception_state.bits.not_commit && io.exception_state.bits.robIdx === deqPtrVec(0) 68780712aaSxiaofeibao-xjtu val redirectOutValid = io.state === 0.U && io.deq_v(deqPosition) && (intrEnable || exceptionEnable) 69780712aaSxiaofeibao-xjtu 70780712aaSxiaofeibao-xjtu // for normal commits: only to consider when there're no exceptions 71780712aaSxiaofeibao-xjtu // we don't need to consider whether the first instruction has exceptions since it wil trigger exceptions. 72780712aaSxiaofeibao-xjtu val realCommitLast = deqPtrVec(0).lineHeadPtr + Fill(bankAddrWidth, 1.U) 73780712aaSxiaofeibao-xjtu val commit_exception = io.exception_state.valid && !isAfter(io.exception_state.bits.robIdx, realCommitLast) 74780712aaSxiaofeibao-xjtu val canCommit = VecInit((0 until CommitWidth).map(i => io.deq_v(i) && io.deq_w(i) || io.hasCommitted(i))) 75780712aaSxiaofeibao-xjtu val normalCommitCnt = PriorityEncoder(canCommit.map(c => !c) :+ true.B) - PopCount(io.hasCommitted) 76780712aaSxiaofeibao-xjtu // when io.intrBitSetReg or there're possible exceptions in these instructions, 77780712aaSxiaofeibao-xjtu // only one instruction is allowed to commit 78571677c9Sxiaofeibao-xjtu val allowOnlyOne = io.allowOnlyOneCommit 79780712aaSxiaofeibao-xjtu val commitCnt = Mux(allowOnlyOne, canCommit(realCommitLast.value), normalCommitCnt) 80780712aaSxiaofeibao-xjtu val allowOnlyOneCond = Wire(chiselTypeOf(io.canCommitPriorityCond)) 81780712aaSxiaofeibao-xjtu allowOnlyOneCond.zipWithIndex.map{ case (value,i) => { 82780712aaSxiaofeibao-xjtu if (i==0) value := false.B 83780712aaSxiaofeibao-xjtu else value := Mux((i-1).U === deqPosition, canCommit(deqPosition), false.B) 84780712aaSxiaofeibao-xjtu } 85780712aaSxiaofeibao-xjtu } 86780712aaSxiaofeibao-xjtu io.canCommitPriorityCond := Mux(allowOnlyOne, allowOnlyOneCond, VecInit(canCommit.map(c => !c) :+ true.B)) 87780712aaSxiaofeibao-xjtu 88780712aaSxiaofeibao-xjtu val commitDeqPtrAll = VecInit((0 until 2*CommitWidth).map{case i => deqPtrVec(0).lineHeadPtr + i.U}) 89780712aaSxiaofeibao-xjtu val commitDeqPtrVec = Wire(chiselTypeOf(deqPtrVec)) 90780712aaSxiaofeibao-xjtu for (i <- 0 until CommitWidth){ 91780712aaSxiaofeibao-xjtu commitDeqPtrVec(i) := PriorityMuxDefault(io.canCommitPriorityCond.zip(commitDeqPtrAll.drop(i).take(CommitWidth+1)), deqPtrVec(i)) 92780712aaSxiaofeibao-xjtu } 93780712aaSxiaofeibao-xjtu val deqPtrVec_next = Mux(io.state === 0.U && !redirectOutValid && !io.blockCommit, commitDeqPtrVec, deqPtrVec) 94780712aaSxiaofeibao-xjtu 95780712aaSxiaofeibao-xjtu deqPtrVec := deqPtrVec_next 96780712aaSxiaofeibao-xjtu 97780712aaSxiaofeibao-xjtu io.next_out := deqPtrVec_next 98780712aaSxiaofeibao-xjtu io.out := deqPtrVec 99780712aaSxiaofeibao-xjtu io.commitCnt := commitCnt 100780712aaSxiaofeibao-xjtu io.commitEn := io.state === 0.U && !redirectOutValid && !io.blockCommit 101780712aaSxiaofeibao-xjtu 102780712aaSxiaofeibao-xjtu XSInfo(io.state === 0.U && commitCnt > 0.U, "retired %d insts\n", commitCnt) 103*8b33cd30Sklin02 104780712aaSxiaofeibao-xjtu if(backendParams.debugEn){ 105780712aaSxiaofeibao-xjtu dontTouch(commitDeqPtrVec) 106780712aaSxiaofeibao-xjtu dontTouch(commitDeqPtrAll) 107780712aaSxiaofeibao-xjtu dontTouch(allowOnlyOneCond) 108780712aaSxiaofeibao-xjtu dontTouch(io.canCommitPriorityCond) 109780712aaSxiaofeibao-xjtu dontTouch(redirectOutValid) 110780712aaSxiaofeibao-xjtu } 111780712aaSxiaofeibao-xjtu 112780712aaSxiaofeibao-xjtu}