Brq.scala 3.4 KB
Newer Older
1 2 3 4 5
package xiangshan.backend.brq

import chisel3._
import chisel3.util._
import xiangshan._
L
LinJiawei 已提交
6
import xiangshan.utils.XSInfo
7 8 9



L
LinJiawei 已提交
10
class Brq extends XSModule {
11
  val io = IO(new Bundle() {
12
    // interrupt/exception happen, flush Brq
13
    val roqRedirect = Input(Valid(new Redirect))
14
    // receive branch/jump calculated target
L
LinJiawei 已提交
15
    val exuRedirect = Vec(exuConfig.AluCnt + exuConfig.BruCnt, Flipped(ValidIO(new ExuOutput)))
16
    // from decode, branch insts enq
17
    val enqReqs = Vec(DecodeWidth, Flipped(DecoupledIO(new CfCtrl)))
18
    // to decode
19 20
    val brTags = Output(Vec(DecodeWidth, UInt(BrTagWidth.W)))
    val brMasks = Output(Vec(DecodeWidth, UInt(BrqSize.W)))
L
LinJiawei 已提交
21 22
    // to roq
    val out = ValidIO(new ExuOutput)
23
    // misprediction, flush pipeline
24 25
    val redirect = Output(Valid(new Redirect))
  })
L
LinJiawei 已提交
26

27 28
  class BrqEntry extends Bundle {
    val npc = UInt(VAddrBits.W)
L
LinJiawei 已提交
29
    val exuOut = new ExuOutput
30 31 32
  }

  val brQueue = Reg(Vec(BrqSize, new BrqEntry))
L
LinJiawei 已提交
33 34 35
  val brMask = RegInit(0.U(BrqSize.W))
  val wbFlags = RegInit(VecInit(Seq.fill(BrqSize)(false.B)))

L
LinJiawei 已提交
36
  val headPtr, tailPtr = RegInit(0.U((BrTagWidth+1).W))
L
LinJiawei 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

  def ptrToIndex(ptr: UInt): UInt = ptr.tail(1)
  def isEmpty(ptr1: UInt, ptr2: UInt): Bool = ptr1 === ptr2
  def isFull(ptr1: UInt, ptr2: UInt): Bool = (ptr1.head(1)=/=ptr2.head(1)) && (ptr1.tail(1)===ptr2.tail(1))


  // dequeue
  val headIdx = ptrToIndex(headPtr)
  val deqValid = wbFlags(headIdx)
  val deqEntry = brQueue(headIdx)

  val deqMask = (~Mux(deqValid, UIntToOH(headIdx), 0.U)).asUInt()
  val headPtrNext = WireInit(headPtr + deqValid)
  when(deqValid){
    wbFlags(headIdx) := false.B
  }
  headPtr := headPtrNext
L
LinJiawei 已提交
54 55 56 57
  io.redirect.valid := deqValid && (deqEntry.npc =/= deqEntry.exuOut.redirect.target)
  io.redirect.bits := deqEntry.exuOut.redirect
  io.out.valid := deqValid
  io.out.bits := deqEntry.exuOut
L
LinJiawei 已提交
58 59 60 61 62 63 64 65 66

  // branch insts enq
  var full = WireInit(isFull(headPtrNext, tailPtr))
  var tailPtrNext = WireInit(tailPtr)
  var brMaskNext = WireInit(brMask & deqMask)
  for(((enq, brMask), brTag) <- io.enqReqs.zip(io.brMasks).zip(io.brTags)){
    val tailIdx = ptrToIndex(tailPtrNext)
    enq.ready := !full
    brTag := tailIdx
67 68
    // TODO: check rvc and use predict npc
    when(enq.fire()){ brQueue(tailIdx).npc := enq.bits.cf.pc + 4.U }
L
LinJiawei 已提交
69 70 71 72 73 74 75 76 77 78
    brMaskNext = brMaskNext | Mux(enq.fire(), UIntToOH(tailIdx), 0.U)
    brMask := brMaskNext
    tailPtrNext = tailPtrNext + enq.fire()
    full = isFull(tailPtrNext, headPtrNext)
  }
  brMask := brMaskNext
  tailPtr := tailPtrNext

  // exu write back
  for(exuWb <- io.exuRedirect){
L
LinJiawei 已提交
79
    when(exuWb.valid){
L
LinJiawei 已提交
80
      wbFlags(exuWb.bits.uop.brTag) := true.B
L
LinJiawei 已提交
81
      brQueue(exuWb.bits.uop.brTag).exuOut := exuWb.bits
L
LinJiawei 已提交
82 83 84 85 86 87 88 89 90 91
    }
  }

  // when redirect, reset all regs
  when(io.roqRedirect.valid || io.redirect.valid){
    brMask := 0.U
    wbFlags.foreach(_ := false.B)
    headPtr := 0.U
    tailPtr := 0.U
  }
L
LinJiawei 已提交
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110




  // Debug info
  val debug_roq_redirect = io.roqRedirect.valid
  val debug_brq_redirect = io.redirect.valid && !debug_roq_redirect
  val debug_normal_mode = !(debug_roq_redirect || debug_brq_redirect)

  for(i <- 0 until DecodeWidth){
    XSInfo(
      debug_normal_mode,
      p"enq v:${io.enqReqs(i).valid} rdy:${io.enqReqs(i).ready} pc:${Hexadecimal(io.enqReqs(i).bits.cf.pc)}" +
        p" brMask:${Binary(io.brMasks(i))} brTag:${io.brTags(i)}\n"
    )
  }

  XSInfo(debug_roq_redirect, "roq redirect, flush brq\n")
  XSInfo(debug_brq_redirect, p"brq redirect, target:${Hexadecimal(io.redirect.bits.target)}\n")
111
}