xref: /XiangShan/src/main/scala/xiangshan/backend/rob/RobDeqPtrWrapper.scala (revision 195ef4a53ab54326d879e884c4e1568f424f2668)
1/***************************************************************************************
2 * Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3 * Copyright (c) 2020-2021 Peng Cheng Laboratory
4 *
5 * XiangShan is licensed under Mulan PSL v2.
6 * You can use this software according to the terms and conditions of the Mulan PSL v2.
7 * You may obtain a copy of Mulan PSL v2 at:
8 *          http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 *
14 * See the Mulan PSL v2 for more details.
15 ***************************************************************************************/
16
17package xiangshan.backend.rob
18
19import org.chipsalliance.cde.config.Parameters
20import chisel3._
21import chisel3.util._
22import difftest._
23import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
24import utility._
25import utils._
26import xiangshan._
27import xiangshan.backend.BackendParams
28import xiangshan.backend.Bundles.{DynInst, ExceptionInfo, ExuOutput}
29import xiangshan.backend.fu.{FuConfig, FuType}
30import xiangshan.frontend.FtqPtr
31import xiangshan.mem.{LqPtr, LsqEnqIO, SqPtr}
32import xiangshan.backend.Bundles.{DynInst, ExceptionInfo, ExuOutput}
33import xiangshan.backend.ctrlblock.{DebugLSIO, DebugLsInfo, LsTopdownInfo}
34import xiangshan.backend.fu.vector.Bundles.VType
35import xiangshan.backend.rename.SnapshotGenerator
36
37class NewRobDeqPtrWrapper(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper {
38  val io = IO(new Bundle {
39    // for commits/flush
40    val state = Input(UInt(2.W))
41    val deq_v = Vec(CommitWidth, Input(Bool()))
42    val deq_w = Vec(CommitWidth, Input(Bool()))
43    val hasCommitted = Vec(CommitWidth, Input(Bool()))
44    val allCommitted = Input(Bool())
45    val exception_state = Flipped(ValidIO(new RobExceptionInfo))
46    // for flush: when exception occurs, reset deqPtrs to range(0, CommitWidth)
47    val intrBitSetReg = Input(Bool())
48    val hasNoSpecExec = Input(Bool())
49    val interrupt_safe = Input(Bool())
50    val blockCommit = Input(Bool())
51    // output: the CommitWidth deqPtr
52    val out = Vec(CommitWidth, Output(new RobPtr))
53    val next_out = Vec(CommitWidth, Output(new RobPtr))
54    val commitCnt = Output(UInt(log2Up(CommitWidth+1).W))
55    val canCommitPriorityCond = Output(Vec(CommitWidth+1,Bool()))
56    val commitEn = Output(Bool())
57  })
58
59  val bankAddrWidth = log2Up(CommitWidth)
60  val deqPtrVec = RegInit(VecInit((0 until CommitWidth).map(_.U.asTypeOf(new RobPtr))))
61  val deqPosition = deqPtrVec(0).value(bankAddrWidth - 1, 0)
62
63  // for exceptions (flushPipe included) and interrupts:
64  // only consider the first instruction
65  val intrEnable = io.intrBitSetReg && !io.hasNoSpecExec && io.interrupt_safe
66  val exceptionEnable = io.deq_w(deqPosition) && io.exception_state.valid && io.exception_state.bits.not_commit && io.exception_state.bits.robIdx === deqPtrVec(0)
67  val redirectOutValid = io.state === 0.U && io.deq_v(deqPosition) && (intrEnable || exceptionEnable)
68
69  // for normal commits: only to consider when there're no exceptions
70  // we don't need to consider whether the first instruction has exceptions since it wil trigger exceptions.
71  val realCommitLast = deqPtrVec(0).lineHeadPtr + Fill(bankAddrWidth, 1.U)
72  val commit_exception = io.exception_state.valid && !isAfter(io.exception_state.bits.robIdx, realCommitLast)
73  val canCommit = VecInit((0 until CommitWidth).map(i => io.deq_v(i) && io.deq_w(i) || io.hasCommitted(i)))
74  val normalCommitCnt = PriorityEncoder(canCommit.map(c => !c) :+ true.B) - PopCount(io.hasCommitted)
75  // when io.intrBitSetReg or there're possible exceptions in these instructions,
76  // only one instruction is allowed to commit
77  val allowOnlyOne = commit_exception || io.intrBitSetReg
78  val commitCnt = Mux(allowOnlyOne, canCommit(realCommitLast.value), normalCommitCnt)
79  val allowOnlyOneCond = Wire(chiselTypeOf(io.canCommitPriorityCond))
80  allowOnlyOneCond.zipWithIndex.map{ case (value,i) => {
81    if (i==0) value := false.B
82    else value := Mux((i-1).U === deqPosition, canCommit(deqPosition), false.B)
83  }
84  }
85  io.canCommitPriorityCond := Mux(allowOnlyOne, allowOnlyOneCond, VecInit(canCommit.map(c => !c) :+ true.B))
86
87  val commitDeqPtrAll = VecInit((0 until 2*CommitWidth).map{case i => deqPtrVec(0).lineHeadPtr + i.U})
88  val commitDeqPtrVec = Wire(chiselTypeOf(deqPtrVec))
89  for (i <- 0 until CommitWidth){
90    commitDeqPtrVec(i) := PriorityMuxDefault(io.canCommitPriorityCond.zip(commitDeqPtrAll.drop(i).take(CommitWidth+1)), deqPtrVec(i))
91  }
92  val deqPtrVec_next = Mux(io.state === 0.U && !redirectOutValid && !io.blockCommit, commitDeqPtrVec, deqPtrVec)
93
94  deqPtrVec := deqPtrVec_next
95
96  io.next_out := deqPtrVec_next
97  io.out      := deqPtrVec
98  io.commitCnt := commitCnt
99  io.commitEn := io.state === 0.U && !redirectOutValid && !io.blockCommit
100
101  when (io.state === 0.U) {
102    XSInfo(io.state === 0.U && commitCnt > 0.U, "retired %d insts\n", commitCnt)
103  }
104  if(backendParams.debugEn){
105    dontTouch(commitDeqPtrVec)
106    dontTouch(commitDeqPtrAll)
107    dontTouch(allowOnlyOneCond)
108    dontTouch(io.canCommitPriorityCond)
109    dontTouch(redirectOutValid)
110  }
111
112}