DecodeStage.scala 2.5 KB
Newer Older
1 2 3 4 5
package xiangshan.backend.decode

import chisel3._
import chisel3.util._
import xiangshan._
L
LinJiawei 已提交
6
import xiangshan.backend.brq.BrqPtr
L
LinJiawei 已提交
7
import utils._
8

9
class DecodeStage extends XSModule {
10
  val io = IO(new Bundle() {
11
    // enq Brq
12
    val toBrq = Vec(DecodeWidth, DecoupledIO(new CfCtrl))
13
    // get brMask/brTag
L
LinJiawei 已提交
14
    val brTags = Input(Vec(DecodeWidth, new BrqPtr))
15 16

    // from Ibuffer
17
    val in = Vec(DecodeWidth, Flipped(DecoupledIO(new CtrlFlow)))
18 19

    // to DecBuffer
20 21
    val out = Vec(DecodeWidth, DecoupledIO(new CfCtrl))
  })
22 23 24 25 26 27
  val decoders = Seq.fill(DecodeWidth)(Module(new Decoder))
  val decoderToBrq = Wire(Vec(DecodeWidth, new CfCtrl)) // without brTag and brMask
  val decoderToDecBuffer = Wire(Vec(DecodeWidth, new CfCtrl)) // with brTag and brMask

  // Handshake ---------------------
  // 1. if current instruction is valid, then:
28
  //    First, assert toBrq(i).valid if (in.valid and out.ready and isBr) and present toBrq(i).bits
29 30 31 32 33 34 35 36 37 38
  //    Second, check toBrq(i).ready and connect it to io.out(i).valid
  // 2. To Decode Buffer:
  //    First, assert in(i).ready if out(i).ready
  //    Second, assert out(i).valid iff in(i).valid and instruction is valid (not implemented) and toBrq(i).ready

  for (i <- 0 until DecodeWidth) {
    decoders(i).io.in <> io.in(i).bits
    decoderToBrq(i) := decoders(i).io.out // CfCtrl without bfTag and brMask
    decoderToBrq(i).brTag := DontCare
    io.toBrq(i).bits := decoderToBrq(i)
39

40 41 42
    decoderToDecBuffer(i) := decoders(i).io.out
    decoderToDecBuffer(i).brTag := io.brTags(i)
    io.out(i).bits := decoderToDecBuffer(i)
43 44

    val thisReady = io.out(i).ready && io.toBrq(i).ready
45 46 47
    val isMret = decoders(i).io.out.cf.instr === BitPat("b001100000010_00000_000_00000_1110011")
    val isSret = decoders(i).io.out.cf.instr === BitPat("b000100000010_00000_000_00000_1110011")
    val thisBrqValid = io.in(i).valid && (!decoders(i).io.out.cf.brUpdate.pd.notCFI || isMret || isSret) && io.out(i).ready
48 49 50 51 52 53
    val thisOutValid =  io.in(i).valid && io.toBrq(i).ready
    io.in(i).ready    := { if (i == 0) thisReady    else io.in(i-1).ready && thisReady }
    io.out(i).valid   := { if (i == 0) thisOutValid else io.in(i-1).ready && thisOutValid }
    io.toBrq(i).valid := { if (i == 0) thisBrqValid else io.in(i-1).ready && thisBrqValid }

    XSDebug(io.in(i).valid || io.out(i).valid || io.toBrq(i).valid, "i:%d In(%d %d) Out(%d %d) ToBrq(%d %d) pc:%x instr:%x\n", i.U, io.in(i).valid, io.in(i).ready, io.out(i).valid, io.out(i).ready, io.toBrq(i).valid, io.toBrq(i).ready, io.in(i).bits.pc, io.in(i).bits.instr)
54
  }
55
}