Roq.scala 16.9 KB
Newer Older
1 2
package xiangshan.backend.roq

3
import chisel3.ExcitingUtils._
4 5 6
import chisel3._
import chisel3.util._
import xiangshan._
L
LinJiawei 已提交
7
import utils._
L
Opt roq  
LinJiawei 已提交
8
import xiangshan.backend.LSUOpType
L
linjiawei 已提交
9
import xiangshan.backend.fu.fpu.Fflags
10

Y
Yinan Xu 已提交
11

Y
Yinan Xu 已提交
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
class RoqPtr extends CircularQueuePtr(RoqPtr.RoqSize) with HasCircularQueuePtrHelper {
  def needFlush(redirect: Valid[Redirect]): Bool = {
    redirect.valid && (redirect.bits.isException || redirect.bits.isFlushPipe || isAfter(this, redirect.bits.roqIdx))
  }
}

object RoqPtr extends HasXSParameter {
  def apply(f: Bool, v: UInt): RoqPtr = {
    val ptr = Wire(new RoqPtr)
    ptr.flag := f
    ptr.value := v
    ptr
  }
}

27 28 29 30 31 32 33
class RoqCSRIO extends XSBundle {
  val intrBitSet = Input(Bool())
  val trapTarget = Input(UInt(VAddrBits.W))

  val fflags = Output(new Fflags)
  val dirty_fs = Output(Bool())
}
Y
Yinan Xu 已提交
34

35
class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
36 37
  val io = IO(new Bundle() {
    val brqRedirect = Input(Valid(new Redirect))
W
William Wang 已提交
38
    val memRedirect = Input(Valid(new Redirect))
39
    val dp1Req = Vec(RenameWidth, Flipped(DecoupledIO(new MicroOp)))
Y
Yinan Xu 已提交
40
    val roqIdxs = Output(Vec(RenameWidth, new RoqPtr))
41
    val redirect = Output(Valid(new Redirect))
42
    val exception = Output(new MicroOp)
L
LinJiawei 已提交
43
    // exu + brq
44
    val exeWbResults = Vec(numWbPorts, Flipped(ValidIO(new ExuOutput)))
45
    val commits = Vec(CommitWidth, Valid(new RoqCommit))
46
    val bcommit = Output(UInt(BrTagWidth.W))
47
    val commitRoqIndex = Output(Valid(new RoqPtr))
Y
Yinan Xu 已提交
48
    val roqDeqPtr = Output(new RoqPtr)
49
    val csr = new RoqCSRIO
50
  })
W
William Wang 已提交
51

52
  val microOp = Mem(RoqSize, new MicroOp)
W
William Wang 已提交
53
  val valid = RegInit(VecInit(List.fill(RoqSize)(false.B)))
W
William Wang 已提交
54
  val flag = RegInit(VecInit(List.fill(RoqSize)(false.B)))
W
William Wang 已提交
55
  val writebacked = Reg(Vec(RoqSize, Bool()))
56

L
linjiawei 已提交
57
  val exuFflags = Mem(RoqSize, new Fflags)
58 59
  val exuData = Reg(Vec(RoqSize, UInt(XLEN.W)))//for debug
  val exuDebug = Reg(Vec(RoqSize, new DebugBundle))//for debug
W
William Wang 已提交
60

Y
Yinan Xu 已提交
61 62 63 64 65 66 67 68 69
  val enqPtrExt = RegInit(0.U.asTypeOf(new RoqPtr))
  val deqPtrExt = RegInit(0.U.asTypeOf(new RoqPtr))
  val walkPtrExt = Reg(new RoqPtr)
  val walkTgtExt = Reg(new RoqPtr)
  val enqPtr = enqPtrExt.value
  val deqPtr = deqPtrExt.value
  val walkPtr = walkPtrExt.value
  val isEmpty = enqPtr === deqPtr && enqPtrExt.flag ===deqPtrExt.flag
  val isFull = enqPtr === deqPtr && enqPtrExt.flag =/= deqPtrExt.flag
L
Opt roq  
LinJiawei 已提交
70
  val notFull = !isFull
W
William Wang 已提交
71

W
William Wang 已提交
72
  val s_idle :: s_walk :: s_extrawalk :: Nil = Enum(3)
W
William Wang 已提交
73 74
  val state = RegInit(s_idle)

L
LinJiawei 已提交
75 76
  io.roqDeqPtr := deqPtrExt

W
William Wang 已提交
77
  // Dispatch
78 79 80
  val noSpecEnq = io.dp1Req.map(i => i.bits.ctrl.noSpecExec)
  val hasNoSpec = RegInit(false.B)
  when(isEmpty){ hasNoSpec:= false.B }
L
Opt roq  
LinJiawei 已提交
81
  val validDispatch = io.dp1Req.map(_.valid)
W
William Wang 已提交
82
  XSDebug("(ready, valid): ")
Y
Yinan Xu 已提交
83
  for (i <- 0 until RenameWidth) {
L
Opt roq  
LinJiawei 已提交
84 85
    val offset = PopCount(validDispatch.take(i))
    val roqIdxExt = enqPtrExt + offset
Y
Yinan Xu 已提交
86
    val roqIdx = roqIdxExt.value
L
Opt roq  
LinJiawei 已提交
87

W
William Wang 已提交
88
    when(io.dp1Req(i).fire()){
L
Opt roq  
LinJiawei 已提交
89 90
      microOp(roqIdx) := io.dp1Req(i).bits
      valid(roqIdx) := true.B
Y
Yinan Xu 已提交
91
      flag(roqIdx) := roqIdxExt.flag
L
Opt roq  
LinJiawei 已提交
92
      writebacked(roqIdx) := false.B
93
      when(noSpecEnq(i)){ hasNoSpec := true.B }
W
William Wang 已提交
94
    }
L
Opt roq  
LinJiawei 已提交
95
    io.dp1Req(i).ready := (notFull && !valid(roqIdx) && state === s_idle) &&
96 97
      (!noSpecEnq(i) || isEmpty) &&
      !hasNoSpec
L
Opt roq  
LinJiawei 已提交
98
    io.roqIdxs(i) := roqIdxExt
Y
Yinan Xu 已提交
99
    XSDebug(false, true.B, "(%d, %d) ", io.dp1Req(i).ready, io.dp1Req(i).valid)
W
William Wang 已提交
100
  }
Y
Yinan Xu 已提交
101
  XSDebug(false, true.B, "\n")
W
William Wang 已提交
102

L
Opt roq  
LinJiawei 已提交
103 104
  val firedDispatch = Cat(io.dp1Req.map(_.fire()))
  val dispatchCnt = PopCount(firedDispatch)
W
William Wang 已提交
105
  when(firedDispatch.orR){
L
Opt roq  
LinJiawei 已提交
106 107
    enqPtrExt := enqPtrExt + dispatchCnt
    XSInfo("dispatched %d insts\n", dispatchCnt)
W
William Wang 已提交
108 109 110
  }

  // Writeback
L
Opt roq  
LinJiawei 已提交
111
  val firedWriteback = io.exeWbResults.map(_.fire())
112
  XSInfo(PopCount(firedWriteback) > 0.U, "writebacked %d insts\n", PopCount(firedWriteback))
L
LinJiawei 已提交
113
  for(i <- 0 until numWbPorts){
W
William Wang 已提交
114
    when(io.exeWbResults(i).fire()){
L
Opt roq  
LinJiawei 已提交
115
      val wbIdxExt = io.exeWbResults(i).bits.uop.roqIdx
Y
Yinan Xu 已提交
116
      val wbIdx = wbIdxExt.value
L
Opt roq  
LinJiawei 已提交
117 118
      writebacked(wbIdx) := true.B
      microOp(wbIdx).cf.exceptionVec := io.exeWbResults(i).bits.uop.cf.exceptionVec
119 120
      microOp(wbIdx).lqIdx := io.exeWbResults(i).bits.uop.lqIdx
      microOp(wbIdx).sqIdx := io.exeWbResults(i).bits.uop.sqIdx
Y
Yinan Xu 已提交
121
      microOp(wbIdx).ctrl.flushPipe := io.exeWbResults(i).bits.uop.ctrl.flushPipe
A
Allen 已提交
122
      microOp(wbIdx).diffTestDebugLrScValid := io.exeWbResults(i).bits.uop.diffTestDebugLrScValid
L
Opt roq  
LinJiawei 已提交
123
      exuData(wbIdx) := io.exeWbResults(i).bits.data
L
linjiawei 已提交
124
      exuFflags(wbIdx) := io.exeWbResults(i).bits.fflags
L
Opt roq  
LinJiawei 已提交
125 126 127
      exuDebug(wbIdx) := io.exeWbResults(i).bits.debug

      val debugUop = microOp(wbIdx)
Y
Yinan Xu 已提交
128 129 130 131
      XSInfo(true.B,
        p"writebacked pc 0x${Hexadecimal(debugUop.cf.pc)} wen ${debugUop.ctrl.rfWen} " +
        p"data 0x${Hexadecimal(io.exeWbResults(i).bits.data)} ldst ${debugUop.ctrl.ldest} pdst ${debugUop.ctrl.ldest} " +
        p"skip ${io.exeWbResults(i).bits.debug.isMMIO} roqIdx: ${wbIdxExt}\n"
132
      )
W
William Wang 已提交
133 134 135
    }
  }

L
Opt roq  
LinJiawei 已提交
136
  val deqUop = microOp(deqPtr)
137
  val deqPtrWritebacked = writebacked(deqPtr) && valid(deqPtr)
138
  val intrEnable = io.csr.intrBitSet && !isEmpty && !hasNoSpec &&
139
    deqUop.ctrl.commitType =/= CommitType.STORE && deqUop.ctrl.commitType =/= CommitType.LOAD// TODO: wanna check why has hasCsr(hasNoSpec)
140 141
  val exceptionEnable = deqPtrWritebacked && Cat(deqUop.cf.exceptionVec).orR()
  val isFlushPipe = deqPtrWritebacked && deqUop.ctrl.flushPipe
142
  io.redirect := DontCare
143
  io.redirect.valid := (state === s_idle) && (intrEnable || exceptionEnable || isFlushPipe)// TODO: add fence flush to flush the whole pipe
144
  io.redirect.bits.isException := intrEnable || exceptionEnable
145 146
  // reuse isFlushPipe to represent interrupt for CSR
  io.redirect.bits.isFlushPipe := isFlushPipe || intrEnable
147
  io.redirect.bits.target := Mux(isFlushPipe, deqUop.cf.pc + 4.U, io.csr.trapTarget)
L
Opt roq  
LinJiawei 已提交
148
  io.exception := deqUop
149 150 151 152
  XSDebug(io.redirect.valid,
    "generate redirect: pc 0x%x intr %d excp %d flushpp %d target:0x%x Traptarget 0x%x exceptionVec %b\n",
    io.exception.cf.pc, intrEnable, exceptionEnable, isFlushPipe, io.redirect.bits.target, io.csr.trapTarget,
    Cat(microOp(deqPtr).cf.exceptionVec))
153

L
Opt roq  
LinJiawei 已提交
154
  // Commit uop to Rename (walk)
W
William Wang 已提交
155
  val shouldWalkVec = Wire(Vec(CommitWidth, Bool()))
L
Opt roq  
LinJiawei 已提交
156
  val walkPtrMatchVec  = Wire(Vec(CommitWidth, Bool()))
Y
Yinan Xu 已提交
157
  val walkPtrVec = Wire(Vec(CommitWidth, new RoqPtr))
L
Opt roq  
LinJiawei 已提交
158 159 160 161 162 163 164
  for(i <- shouldWalkVec.indices){
    walkPtrVec(i) := walkPtrExt - i.U
    walkPtrMatchVec(i) := walkPtrVec(i) === walkTgtExt
    if(i == 0) shouldWalkVec(i) := !walkPtrMatchVec(i)
    else shouldWalkVec(i) := shouldWalkVec(i-1) && !walkPtrMatchVec(i)
  }
  val walkFinished = Cat(walkPtrMatchVec).orR()
W
William Wang 已提交
165

W
William Wang 已提交
166
  // extra space is used weh roq has no enough space, but mispredict recovery needs such info to walk regmap
L
Opt roq  
LinJiawei 已提交
167 168 169
  val needExtraSpaceForMPR = WireInit(VecInit(
    List.tabulate(RenameWidth)(i => io.brqRedirect.valid && io.dp1Req(i).valid && !io.dp1Req(i).ready)
  ))
W
William Wang 已提交
170 171 172
  val extraSpaceForMPR = Reg(Vec(RenameWidth, new MicroOp))
  val usedSpaceForMPR = Reg(Vec(RenameWidth, Bool()))

L
Opt roq  
LinJiawei 已提交
173 174
  val storeCommitVec = WireInit(VecInit(Seq.fill(CommitWidth)(false.B)))
  val cfiCommitVec = WireInit(VecInit(Seq.fill(CommitWidth)(false.B)))
L
linjiawei 已提交
175 176 177
  // wiring to csr
  val fflags = WireInit(0.U.asTypeOf(new Fflags))
  val dirty_fs = WireInit(false.B)
W
William Wang 已提交
178
  for(i <- 0 until CommitWidth){
W
William Wang 已提交
179 180 181
    io.commits(i) := DontCare
    switch(state){
      is(s_idle){
L
Opt roq  
LinJiawei 已提交
182 183 184
        val commitIdx = deqPtr + i.U
        val commitUop = microOp(commitIdx)
        val hasException = Cat(commitUop.cf.exceptionVec).orR() || intrEnable
185
        val canCommit = if(i!=0) (io.commits(i-1).valid && !io.commits(i-1).bits.uop.ctrl.flushPipe) else true.B
L
Opt roq  
LinJiawei 已提交
186 187 188 189 190 191
        val v = valid(commitIdx)
        val w = writebacked(commitIdx)
        io.commits(i).valid := v && w && canCommit && !hasException
        io.commits(i).bits.uop := commitUop

        storeCommitVec(i) := io.commits(i).valid &&
192
          commitUop.ctrl.commitType === CommitType.STORE
L
Opt roq  
LinJiawei 已提交
193 194 195 196

        cfiCommitVec(i) := io.commits(i).valid &&
          !commitUop.cf.brUpdate.pd.notCFI

L
linjiawei 已提交
197 198 199 200 201 202 203 204 205 206 207 208
        val commitFflags = exuFflags(commitIdx)
        when(io.commits(i).valid){
          when(commitFflags.asUInt.orR()){
            // update fflags
            fflags := exuFflags(commitIdx)
          }
          when(commitUop.ctrl.fpWen){
            // set fs to dirty
            dirty_fs := true.B
          }
        }

L
Opt roq  
LinJiawei 已提交
209
        when(io.commits(i).valid){v := false.B}
W
William Wang 已提交
210
        XSInfo(io.commits(i).valid,
L
linjiawei 已提交
211
          "retired pc %x wen %d ldest %d pdest %x old_pdest %x data %x fflags: %b\n",
L
Opt roq  
LinJiawei 已提交
212 213 214
          commitUop.cf.pc,
          commitUop.ctrl.rfWen,
          commitUop.ctrl.ldest,
215 216
          commitUop.pdest,
          commitUop.old_pdest,
L
linjiawei 已提交
217 218
          exuData(commitIdx),
          exuFflags(commitIdx).asUInt
W
William Wang 已提交
219
        )
L
Opt roq  
LinJiawei 已提交
220
        XSInfo(io.commits(i).valid && exuDebug(commitIdx).isMMIO,
W
William Wang 已提交
221
          "difftest skiped pc0x%x\n",
L
Opt roq  
LinJiawei 已提交
222
          commitUop.cf.pc
W
William Wang 已提交
223 224 225 226
        )
      }

      is(s_walk){
Y
Yinan Xu 已提交
227
        val idx = walkPtrVec(i).value
L
Opt roq  
LinJiawei 已提交
228 229 230 231
        val v = valid(idx)
        val walkUop = microOp(idx)
        io.commits(i).valid := v && shouldWalkVec(i)
        io.commits(i).bits.uop := walkUop
W
William Wang 已提交
232
        when(shouldWalkVec(i)){
L
Opt roq  
LinJiawei 已提交
233
          v := false.B
W
William Wang 已提交
234
        }
L
Opt roq  
LinJiawei 已提交
235 236 237 238 239
        XSInfo(io.commits(i).valid && shouldWalkVec(i), "walked pc %x wen %d ldst %d data %x\n",
          walkUop.cf.pc,
          walkUop.ctrl.rfWen,
          walkUop.ctrl.ldest,
          exuData(idx)
W
William Wang 已提交
240 241 242 243
        )
      }

      is(s_extrawalk){
L
Opt roq  
LinJiawei 已提交
244 245 246 247
        val idx = RenameWidth-i-1
        val walkUop = extraSpaceForMPR(idx)
        io.commits(i).valid := usedSpaceForMPR(idx)
        io.commits(i).bits.uop := walkUop
W
William Wang 已提交
248
        state := s_walk
L
Opt roq  
LinJiawei 已提交
249 250 251 252
        XSInfo(io.commits(i).valid, "use extra space walked pc %x wen %d ldst %d\n",
          walkUop.cf.pc,
          walkUop.ctrl.rfWen,
          walkUop.ctrl.ldest
W
William Wang 已提交
253
        )
254
      }
W
William Wang 已提交
255
    }
W
William Wang 已提交
256
    io.commits(i).bits.isWalk := state =/= s_idle
W
William Wang 已提交
257
  }
W
William Wang 已提交
258

259 260
  io.csr.fflags := fflags
  io.csr.dirty_fs := dirty_fs
L
linjiawei 已提交
261

L
Opt roq  
LinJiawei 已提交
262
  val validCommit = io.commits.map(_.valid)
W
William Wang 已提交
263 264 265 266 267
  when(state===s_walk) {
    //exit walk state when all roq entry is commited
    when(walkFinished) {
      state := s_idle
    }
L
Opt roq  
LinJiawei 已提交
268
    walkPtrExt := walkPtrExt - CommitWidth.U
W
William Wang 已提交
269
    // ringBufferWalkExtended := ringBufferWalkExtended - validCommit
Y
Yinan Xu 已提交
270
    XSInfo("rolling back: enqPtr %d deqPtr %d walk %d:%d\n", enqPtr, deqPtr, walkPtrExt.flag, walkPtr)
271
  }
W
William Wang 已提交
272

W
William Wang 已提交
273
  // move tail ptr
L
Opt roq  
LinJiawei 已提交
274
  val commitCnt = PopCount(validCommit)
W
William Wang 已提交
275
  when(state === s_idle){
L
Opt roq  
LinJiawei 已提交
276
    deqPtrExt := deqPtrExt + commitCnt
W
William Wang 已提交
277
  }
L
Opt roq  
LinJiawei 已提交
278
  val retireCounter = Mux(state === s_idle, commitCnt, 0.U)
W
William Wang 已提交
279
  XSInfo(retireCounter > 0.U, "retired %d insts\n", retireCounter)
280
  val commitOffset = PriorityEncoder((validCommit :+ false.B).map(!_))
281
  io.commitRoqIndex.valid := state === s_idle
282
  io.commitRoqIndex.bits := deqPtrExt + commitOffset
W
William Wang 已提交
283

284
  // commit branch to brq
L
Opt roq  
LinJiawei 已提交
285
  io.bcommit := PopCount(cfiCommitVec)
286

W
William Wang 已提交
287
  // when redirect, walk back roq entries
288
  when(io.brqRedirect.valid){ // TODO: need check if consider exception redirect?
W
William Wang 已提交
289
    state := s_walk
290
    walkPtrExt := Mux(state === s_walk && !walkFinished, walkPtrExt - CommitWidth.U, Mux(state === s_extrawalk, walkPtrExt, enqPtrExt - 1.U + dispatchCnt))
L
Opt roq  
LinJiawei 已提交
291 292
    walkTgtExt := io.brqRedirect.bits.roqIdx
    enqPtrExt := io.brqRedirect.bits.roqIdx + 1.U
W
William Wang 已提交
293
  }
W
William Wang 已提交
294

W
William Wang 已提交
295
  // no enough space for walk, allocate extra space
W
William Wang 已提交
296 297
  when(needExtraSpaceForMPR.asUInt.orR && io.brqRedirect.valid){
    usedSpaceForMPR := needExtraSpaceForMPR
L
Opt roq  
LinJiawei 已提交
298
    (0 until RenameWidth).foreach(i => extraSpaceForMPR(i) := io.dp1Req(i).bits)
W
William Wang 已提交
299 300
    state := s_extrawalk
    XSDebug("roq full, switched to s_extrawalk. needExtraSpaceForMPR: %b\n", needExtraSpaceForMPR.asUInt)
W
William Wang 已提交
301 302
  }

W
William Wang 已提交
303
  // when rollback, reset writebacked entry to valid
304
  when(io.memRedirect.valid) { // TODO: opt timing
W
William Wang 已提交
305
    for (i <- 0 until RoqSize) {
Y
Yinan Xu 已提交
306 307
      val recRoqIdx = RoqPtr(flag(i), i.U)
      when (valid(i) && isAfter(recRoqIdx, io.memRedirect.bits.roqIdx)) {
W
William Wang 已提交
308 309 310 311 312
        writebacked(i) := false.B
      }
    }
  }

313
  // when exception occurs, cancels all
314
  when (io.redirect.valid) { // TODO: need check for flushPipe
Y
Yinan Xu 已提交
315 316
    enqPtrExt := 0.U.asTypeOf(new RoqPtr)
    deqPtrExt := 0.U.asTypeOf(new RoqPtr)
Y
Yinan Xu 已提交
317 318 319
    for (i <- 0 until RoqSize) {
      valid(i) := false.B
    }
320
  }
321

W
William Wang 已提交
322
  // debug info
Y
Yinan Xu 已提交
323
  XSDebug(p"enqPtr ${enqPtrExt} deqPtr ${deqPtrExt}\n")
W
William Wang 已提交
324
  XSDebug("")
Y
Yinan Xu 已提交
325 326 327 328
  for(i <- 0 until RoqSize){
    XSDebug(false, !valid(i), "-")
    XSDebug(false, valid(i) && writebacked(i), "w")
    XSDebug(false, valid(i) && !writebacked(i), "v")
W
William Wang 已提交
329
  }
Y
Yinan Xu 已提交
330 331 332 333 334 335 336 337 338
  XSDebug(false, true.B, "\n")

  for(i <- 0 until RoqSize){
    if(i % 4 == 0) XSDebug("")
    XSDebug(false, true.B, "%x ", microOp(i).cf.pc)
    XSDebug(false, !valid(i), "- ")
    XSDebug(false, valid(i) && writebacked(i), "w ")
    XSDebug(false, valid(i) && !writebacked(i), "v ")
    if(i % 4 == 3) XSDebug(false, true.B, "\n")
W
William Wang 已提交
339
  }
W
William Wang 已提交
340

341
  //difftest signals
L
Opt roq  
LinJiawei 已提交
342
  val firstValidCommit = deqPtr + PriorityMux(validCommit, VecInit(List.tabulate(CommitWidth)(_.U)))
343

344 345 346 347
  val skip = Wire(Vec(CommitWidth, Bool()))
  val wen = Wire(Vec(CommitWidth, Bool()))
  val wdata = Wire(Vec(CommitWidth, UInt(XLEN.W)))
  val wdst = Wire(Vec(CommitWidth, UInt(32.W)))
A
Allen 已提交
348
  val diffTestDebugLrScValid = Wire(Vec(CommitWidth, Bool()))
349
  val wpc = Wire(Vec(CommitWidth, UInt(XLEN.W)))
350
  val trapVec = Wire(Vec(CommitWidth, Bool()))
351
  val isRVC = Wire(Vec(CommitWidth, Bool()))
352
  for(i <- 0 until CommitWidth){
353
    // io.commits(i).valid
L
Opt roq  
LinJiawei 已提交
354 355
    val idx = deqPtr+i.U
    val uop = io.commits(i).bits.uop
A
Allen 已提交
356
    val DifftestSkipSC = false
W
William Wang 已提交
357 358 359 360 361 362 363 364 365
    if(!DifftestSkipSC){
      skip(i) := exuDebug(idx).isMMIO && io.commits(i).valid
    }else{
      skip(i) := (
          exuDebug(idx).isMMIO || 
          uop.ctrl.fuType === FuType.mou && uop.ctrl.fuOpType === LSUOpType.sc_d ||
          uop.ctrl.fuType === FuType.mou && uop.ctrl.fuOpType === LSUOpType.sc_w
        ) && io.commits(i).valid
    }
366 367 368
    wen(i) := io.commits(i).valid && uop.ctrl.rfWen && uop.ctrl.ldest =/= 0.U
    wdata(i) := exuData(idx)
    wdst(i) := uop.ctrl.ldest
A
Allen 已提交
369
    diffTestDebugLrScValid(i) := uop.diffTestDebugLrScValid
370
    wpc(i) := SignExt(uop.cf.pc, XLEN)
371
    trapVec(i) := io.commits(i).valid && (state===s_idle) && uop.ctrl.isXSTrap
372
    isRVC(i) := uop.cf.brUpdate.pd.isRVC
373
  }
374 375 376 377 378

  val scFailed = !diffTestDebugLrScValid(0) && 
    io.commits(0).bits.uop.ctrl.fuType === FuType.mou &&
    (io.commits(0).bits.uop.ctrl.fuOpType === LSUOpType.sc_d || io.commits(0).bits.uop.ctrl.fuOpType === LSUOpType.sc_w)

379 380
  val instrCnt = RegInit(0.U(64.W))
  instrCnt := instrCnt + retireCounter
381

382
  val difftestIntrNO = WireInit(0.U(XLEN.W))
383
  val difftestCause = WireInit(0.U(XLEN.W))
384
  ExcitingUtils.addSink(difftestIntrNO, "difftestIntrNOfromCSR")
385 386
  ExcitingUtils.addSink(difftestCause, "difftestCausefromCSR")

Y
Yinan Xu 已提交
387 388
  XSDebug(difftestIntrNO =/= 0.U, "difftest intrNO set %x\n", difftestIntrNO)
  val retireCounterFix = Mux(io.redirect.valid, 1.U, retireCounter)
389
  val retirePCFix = SignExt(Mux(io.redirect.valid, microOp(deqPtr).cf.pc, microOp(firstValidCommit).cf.pc), XLEN)
L
Opt roq  
LinJiawei 已提交
390
  val retireInstFix = Mux(io.redirect.valid, microOp(deqPtr).cf.instr, microOp(firstValidCommit).cf.instr)
L
LinJiawei 已提交
391
  if(!env.FPGAPlatform){
392 393 394 395 396 397 398 399 400 401 402 403
    ExcitingUtils.addSource(RegNext(retireCounterFix), "difftestCommit", ExcitingUtils.Debug)
    ExcitingUtils.addSource(RegNext(retirePCFix), "difftestThisPC", ExcitingUtils.Debug)//first valid PC
    ExcitingUtils.addSource(RegNext(retireInstFix), "difftestThisINST", ExcitingUtils.Debug)//first valid inst
    ExcitingUtils.addSource(RegNext(skip.asUInt), "difftestSkip", ExcitingUtils.Debug)
    ExcitingUtils.addSource(RegNext(isRVC.asUInt), "difftestIsRVC", ExcitingUtils.Debug)
    ExcitingUtils.addSource(RegNext(wen.asUInt), "difftestWen", ExcitingUtils.Debug)
    ExcitingUtils.addSource(RegNext(wpc), "difftestWpc", ExcitingUtils.Debug)
    ExcitingUtils.addSource(RegNext(wdata), "difftestWdata", ExcitingUtils.Debug)
    ExcitingUtils.addSource(RegNext(wdst), "difftestWdst", ExcitingUtils.Debug)
    ExcitingUtils.addSource(RegNext(scFailed), "difftestScFailed", ExcitingUtils.Debug)
    ExcitingUtils.addSource(RegNext(difftestIntrNO), "difftestIntrNO", ExcitingUtils.Debug)
    ExcitingUtils.addSource(RegNext(difftestCause), "difftestCause", ExcitingUtils.Debug)
404

L
LinJiawei 已提交
405 406
    val hitTrap = trapVec.reduce(_||_)
    val trapCode = PriorityMux(wdata.zip(trapVec).map(x => x._2 -> x._1))
407
    val trapPC = SignExt(PriorityMux(wpc.zip(trapVec).map(x => x._2 ->x._1)), XLEN)
408

409 410 411 412 413
    ExcitingUtils.addSource(RegNext(hitTrap), "trapValid")
    ExcitingUtils.addSource(RegNext(trapCode), "trapCode")
    ExcitingUtils.addSource(RegNext(trapPC), "trapPC")
    ExcitingUtils.addSource(RegNext(GTimer()), "trapCycleCnt")
    ExcitingUtils.addSource(RegNext(instrCnt), "trapInstrCnt")
414
    ExcitingUtils.addSource(state === s_walk || state === s_extrawalk, "perfCntCondRoqWalk", Perf)
Y
Yinan Xu 已提交
415 416 417 418 419 420
    val deqNotWritebacked = valid(deqPtr) && !writebacked(deqPtr)
    val deqUopCommitType = deqUop.ctrl.commitType
    ExcitingUtils.addSource(deqNotWritebacked && deqUopCommitType === CommitType.INT,   "perfCntCondRoqWaitInt",   Perf)
    ExcitingUtils.addSource(deqNotWritebacked && deqUopCommitType === CommitType.FP,    "perfCntCondRoqWaitFp",    Perf)
    ExcitingUtils.addSource(deqNotWritebacked && deqUopCommitType === CommitType.LOAD,  "perfCntCondRoqWaitLoad",  Perf)
    ExcitingUtils.addSource(deqNotWritebacked && deqUopCommitType === CommitType.STORE, "perfCntCondRoqWaitStore", Perf)
Z
ZhangZifei 已提交
421

J
jinyue110 已提交
422
    if(EnableBPU){
423
      ExcitingUtils.addSource(hitTrap, "XSTRAP", ConnectionType.Debug)
J
jinyue110 已提交
424
    }
425
  }
426
}