Ibuffer.scala 6.6 KB
Newer Older
L
LinJiawei 已提交
1 2 3 4 5 6 7
package xiangshan.frontend

import chisel3._
import chisel3.util._

import xiangshan._
import utils._
8
import xiangshan.backend.fu.HasExceptionNO
L
Lingrui98 已提交
9
import xiangshan.backend.ftq.FtqPtr
Z
zoujr 已提交
10 11 12 13 14 15 16 17 18 19 20 21

class IbufPtr extends CircularQueuePtr(IbufPtr.IBufSize) { }

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

22 23 24 25 26 27
class IBufferIO extends XSBundle {
  val flush = Input(Bool())
  val in = Flipped(DecoupledIO(new FetchPacket))
  val out = Vec(DecodeWidth, DecoupledIO(new CtrlFlow))
}

Z
zoujr 已提交
28
class Ibuffer extends XSModule with HasCircularQueuePtrHelper {
29
  val io = IO(new IBufferIO)
L
LinJiawei 已提交
30 31 32 33 34

  class IBufEntry extends XSBundle {
    val inst = UInt(32.W)
    val pc = UInt(VAddrBits.W)
    val pd = new PreDecodeInfo
35
    val ipf = Bool()
36
    val acf = Bool()
37
    val crossPageIPFFix = Bool()
L
Lingrui98 已提交
38 39 40
    val pred_taken = Bool()
    val ftqPtr = new FtqPtr
    val ftqOffset = UInt(log2Ceil(PredictWidth).W)
L
LinJiawei 已提交
41 42 43
  }

  // Ignore
44 45 46
  // io.loopBufPar <> DontCare
  // io.loopBufPar.LBredirect.valid := false.B
  // io.loopBufPar.inLoop := false.B
47 48


L
LinJiawei 已提交
49
  for(out <- io.out) {
50
    // out.bits.exceptionVec := DontCare
L
LinJiawei 已提交
51
    out.bits.intrVec := DontCare
52
    // out.bits.crossPageIPFFix := DontCare
L
LinJiawei 已提交
53 54 55
  }

  // Ibuffer define
56
  // val ibuf = Reg(Vec(IBufSize, new IBufEntry))
Z
zoujr 已提交
57
  val ibuf = Module(new SyncDataModuleTemplate(new IBufEntry, IBufSize, DecodeWidth, PredictWidth))
58
  ibuf.io.wdata.map(w => dontTouch(w.ftqOffset))
Z
zoujr 已提交
59
  val head_ptr = RegInit(IbufPtr(false.B, 0.U))
Z
zoujr 已提交
60
  val next_head_ptr = WireInit(head_ptr)
61 62
  val tail_vec = RegInit(VecInit((0 until PredictWidth).map(_.U.asTypeOf(new IbufPtr))))
  val tail_ptr = tail_vec(0)
L
LinJiawei 已提交
63

Z
zoujr 已提交
64
  // val validEntries = distanceBetween(tail_ptr, head_ptr) // valid entries
Y
Yinan Xu 已提交
65
  val validEntries = RegInit(0.U(log2Up(IBufSize + 1).W))// valid entries
Z
zoujr 已提交
66
  val allowEnq = RegInit(true.B)
L
LinJiawei 已提交
67

Z
zoujr 已提交
68
  // val enqValid = (IBufSize.U - PredictWidth.U) >= validEntries
Z
zoujr 已提交
69
  val deqValid = validEntries > 0.U
L
LinJiawei 已提交
70

Z
zoujr 已提交
71 72
  val numEnq = Mux(io.in.fire, PopCount(io.in.bits.mask), 0.U)
  val numDeq = Mux(deqValid, PopCount(io.out.map(_.fire)), 0.U)
L
LinJiawei 已提交
73

Z
zoujr 已提交
74 75
  validEntries := validEntries + numEnq - numDeq
  allowEnq := (IBufSize.U - PredictWidth.U) >= (validEntries + numEnq)
Z
zoujr 已提交
76

Z
zoujr 已提交
77
  // Enque
Z
zoujr 已提交
78
  io.in.ready := allowEnq
Z
zoujr 已提交
79
 
80
  val offset = Wire(Vec(PredictWidth, UInt(log2Up(PredictWidth).W)))
Z
zoujr 已提交
81 82
  for(i <- 0 until PredictWidth) {
    if (i == 0) {
83
      offset(i) := 0.U
Z
zoujr 已提交
84
    } else {
85
      offset(i) := PopCount(io.in.bits.pdmask(i-1, 0))
Z
zoujr 已提交
86 87
    }
  }
L
LinJiawei 已提交
88

Z
zoujr 已提交
89
  when(io.in.fire && !io.flush) {
L
LinJiawei 已提交
90
    for(i <- 0 until PredictWidth) {
Z
zoujr 已提交
91
      val inWire = Wire(new IBufEntry)
Z
zoujr 已提交
92
      inWire := DontCare
L
LinJiawei 已提交
93

Z
zoujr 已提交
94 95 96 97 98 99 100
      when(io.in.bits.mask(i)) {
        inWire.inst := io.in.bits.instrs(i)
        inWire.pc := io.in.bits.pc(i)
        inWire.pd := io.in.bits.pd(i)
        inWire.ipf := io.in.bits.ipf
        inWire.acf := io.in.bits.acf
        inWire.crossPageIPFFix := io.in.bits.crossPageIPFFix
L
Lingrui98 已提交
101 102 103
        inWire.pred_taken := io.in.bits.pred_taken(i)
        inWire.ftqPtr := io.in.bits.ftqPtr
        inWire.ftqOffset := i.U
104
        // ibuf(tail_vec(offset(i)).value) := inWire
Z
zoujr 已提交
105
      }
106 107 108 109
      ibuf.io.waddr(i) := tail_vec(offset(i)).value
      ibuf.io.wdata(i) := inWire
      ibuf.io.wen(i) := io.in.bits.mask(i)

L
LinJiawei 已提交
110 111
    }

112
    tail_vec := VecInit(tail_vec.map(_ + PopCount(io.in.bits.mask)))
113 114 115 116
  }.otherwise {
    ibuf.io.wen.foreach(_ := false.B)
    ibuf.io.waddr := DontCare
    ibuf.io.wdata := DontCare
L
LinJiawei 已提交
117 118 119 120
  }

  // Deque
  when(deqValid) {
Z
zoujr 已提交
121
    val validVec = UIntToMask(Mux(validEntries >= DecodeWidth.U, DecodeWidth.U, validEntries), DecodeWidth)
122

Z
zoujr 已提交
123
    io.out.zipWithIndex.foreach{case (e, i) => e.valid := validVec(i)}
Z
zoujr 已提交
124
    next_head_ptr := head_ptr + PopCount(io.out.map(_.fire))
Z
zoujr 已提交
125

L
LinJiawei 已提交
126
    for(i <- 0 until DecodeWidth) {
127
      val outWire = ibuf.io.rdata(i)
Z
zoujr 已提交
128

Z
zoujr 已提交
129 130 131
      io.out(i).bits.instr := outWire.inst
      io.out(i).bits.pc := outWire.pc
      // io.out(i).bits.exceptionVec := Mux(outWire.ipf, UIntToOH(instrPageFault.U), 0.U)
Z
zhanglinjuan 已提交
132
      io.out(i).bits.exceptionVec := 0.U.asTypeOf(Vec(16, Bool()))
Z
zoujr 已提交
133
      io.out(i).bits.exceptionVec(instrPageFault) := outWire.ipf
134
      io.out(i).bits.exceptionVec(instrAccessFault) := outWire.acf
Z
zoujr 已提交
135
      // io.out(i).bits.brUpdate := outWire.brInfo
L
Lingrui98 已提交
136 137 138 139 140
      io.out(i).bits.pd := outWire.pd
      io.out(i).bits.pred_taken := outWire.pred_taken
      io.out(i).bits.ftqPtr := outWire.ftqPtr
      io.out(i).bits.ftqOffset := outWire.ftqOffset

Z
zoujr 已提交
141
      io.out(i).bits.crossPageIPFFix := outWire.crossPageIPFFix
Z
zoujr 已提交
142 143 144
      
      val head_wire = next_head_ptr.value + i.U
      ibuf.io.raddr(i) := head_wire
L
LinJiawei 已提交
145
    }
Z
zoujr 已提交
146
    head_ptr := next_head_ptr
L
LinJiawei 已提交
147
  }.otherwise {
148
    ibuf.io.raddr := DontCare
L
LinJiawei 已提交
149 150 151 152 153 154
    io.out.foreach(_.valid := false.B)
    io.out.foreach(_.bits <> DontCare)
  }

  // Flush
  when(io.flush) {
Z
zoujr 已提交
155 156
    validEntries := 0.U
    allowEnq := true.B
Z
zoujr 已提交
157 158
    head_ptr.value := 0.U
    head_ptr.flag := false.B
159
    tail_vec := VecInit((0 until PredictWidth).map(_.U.asTypeOf(new IbufPtr)))
L
LinJiawei 已提交
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
  }

  // Debug info
  XSDebug(io.flush, "IBuffer Flushed\n")

  when(io.in.fire) {
    XSDebug("Enque:\n")
    XSDebug(p"MASK=${Binary(io.in.bits.mask)}\n")
    for(i <- 0 until PredictWidth){
        XSDebug(p"PC=${Hexadecimal(io.in.bits.pc(i))} ${Hexadecimal(io.in.bits.instrs(i))}\n")
    }
  }

  when(deqValid) {
    XSDebug("Deque:\n")
    for(i <- 0 until DecodeWidth){
Z
zhanglinjuan 已提交
176 177
        XSDebug(p"${Hexadecimal(io.out(i).bits.instr)} PC=${Hexadecimal(io.out(i).bits.pc)} v=${io.out(i).valid} r=${io.out(i).ready} " +
          p"excpVec=${Binary(io.out(i).bits.exceptionVec.asUInt)} crossPageIPF=${io.out(i).bits.crossPageIPFFix}\n")
L
LinJiawei 已提交
178 179 180
    }
  }

Z
zoujr 已提交
181 182 183 184
  XSDebug(p"ValidEntries: ${validEntries}\n")
  XSDebug(p"EnqNum: ${numEnq}\n")
  XSDebug(p"DeqNum: ${numDeq}\n")

Z
zoujr 已提交
185 186 187 188 189 190 191 192 193 194 195 196 197 198
  // XSDebug(p"last_head_ptr=$head_ptr  last_tail_ptr=$tail_ptr\n")
  // for(i <- 0 until IBufSize/8) {
  //   XSDebug("%x v:%b | %x v:%b | %x v:%b | %x v:%b | %x v:%b | %x v:%b | %x v:%b | %x v:%b\n",
  //     ibuf(i*8+0).inst, ibuf_valid(i*8+0),
  //       ibuf(i*8+1).inst, ibuf_valid(i*8+1),
  //       ibuf(i*8+2).inst, ibuf_valid(i*8+2),
  //       ibuf(i*8+3).inst, ibuf_valid(i*8+3),
  //       ibuf(i*8+4).inst, ibuf_valid(i*8+4),
  //       ibuf(i*8+5).inst, ibuf_valid(i*8+5),
  //       ibuf(i*8+6).inst, ibuf_valid(i*8+6),
  //       ibuf(i*8+7).inst, ibuf_valid(i*8+7)
  //   )
  // }

199 200 201 202 203 204 205 206 207 208 209 210 211
  // XSDebug(p"validEntries=$validEntries, last_head_ptr=$head_ptr  last_tail_ptr=$tail_ptr\n")
  // for(i <- 0 until IBufSize/8) {
  //   XSDebug("%x | %x | %x | %x | %x | %x | %x | %x\n",
  //     ibuf(i*8+0).inst,
  //       ibuf(i*8+1).inst,
  //       ibuf(i*8+2).inst,
  //       ibuf(i*8+3).inst,
  //       ibuf(i*8+4).inst,
  //       ibuf(i*8+5).inst,
  //       ibuf(i*8+6).inst,
  //       ibuf(i*8+7).inst
  //   )
  // }
Y
Yinan Xu 已提交
212

213
  XSPerf("ibuf_utilization", validEntries)
Z
zoujr 已提交
214
}