EXU.scala 4.5 KB
Newer Older
Z
Zihao Yu 已提交
1
package noop
Z
Zihao Yu 已提交
2 3 4

import chisel3._
import chisel3.util._
5
import chisel3.util.experimental.BoringUtils
Z
Zihao Yu 已提交
6

7
import utils._
8
import bus.simplebus._
Z
Zihao Yu 已提交
9

Z
Zihao Yu 已提交
10
class EXU(implicit val p: NOOPConfig) extends NOOPModule {
Z
Zihao Yu 已提交
11
  val io = IO(new Bundle {
Z
Zihao Yu 已提交
12
    val in = Flipped(Decoupled(new DecodeIO))
Z
Zihao Yu 已提交
13
    val out = Decoupled(new CommitIO)
14
    val flush = Input(Bool())
15
    val dmem = new SimpleBusUC
Z
Zihao Yu 已提交
16
    val forward = new ForwardIO
17
    val memMMU = Flipped(new MemMMUIO)
Z
Zihao Yu 已提交
18 19
  })

20 21
  val src1 = io.in.bits.data.src1
  val src2 = io.in.bits.data.src2
22

Z
Zihao Yu 已提交
23
  val (fuType, fuOpType) = (io.in.bits.ctrl.fuType, io.in.bits.ctrl.fuOpType)
Z
Zihao Yu 已提交
24

Z
Zihao Yu 已提交
25 26
  val fuValids = Wire(Vec(FuType.num, Bool()))
  (0 until FuType.num).map (i => fuValids(i) := (fuType === i.U) && io.in.valid && !io.flush)
27

Z
Zihao Yu 已提交
28
  val alu = Module(new ALU)
Z
Zihao Yu 已提交
29
  val aluOut = alu.access(valid = fuValids(FuType.alu), src1 = src1, src2 = src2, func = fuOpType)
Z
Zihao Yu 已提交
30
  alu.io.cfIn := io.in.bits.cf
Z
Zihao Yu 已提交
31
  alu.io.offset := io.in.bits.data.imm
Z
Zihao Yu 已提交
32
  alu.io.out.ready := true.B
Z
Zihao Yu 已提交
33

Z
Zihao Yu 已提交
34
  val lsu = Module(new LSU)
35 36
  val lsuTlbPF = WireInit(false.B)
  val lsuOut = lsu.access(valid = fuValids(FuType.lsu), src1 = src1, src2 = io.in.bits.data.imm, func = fuOpType, dtlbPF = lsuTlbPF)
Z
Zihao Yu 已提交
37
  lsu.io.wdata := src2
38
  lsu.io.instr := io.in.bits.cf.instr
Z
Zihao Yu 已提交
39
  io.out.bits.isMMIO := lsu.io.isMMIO
Z
Zihao Yu 已提交
40 41
  io.dmem <> lsu.io.dmem
  lsu.io.out.ready := true.B
42 43 44 45
  
  Debug() {
    printf("[EXU-flush] %d flush:%d inValid:%d lsuValid:%d\n", GTimer(), io.flush, io.in.valid, lsu.io.in.valid)
  }
Z
Zihao Yu 已提交
46

Z
Zihao Yu 已提交
47
  val mdu = Module(new MDU)
Z
Zihao Yu 已提交
48
  val mduOut = mdu.access(valid = fuValids(FuType.mdu), src1 = src1, src2 = src2, func = fuOpType)
Z
Zihao Yu 已提交
49
  mdu.io.out.ready := true.B
Z
Zihao Yu 已提交
50

51
  val csr = Module(new CSR)
Z
Zihao Yu 已提交
52
  val csrOut = csr.access(valid = fuValids(FuType.csr), src1 = src1, src2 = src2, func = fuOpType)
Z
Zihao Yu 已提交
53
  csr.io.cfIn := io.in.bits.cf
54
  csr.io.instrValid := io.in.valid && !io.flush
Z
Zihao Yu 已提交
55
  io.out.bits.intrNO := csr.io.intrNO
56 57
  csr.io.out.ready := true.B

58 59
  csr.io.imemMMU <> io.memMMU.imem
  csr.io.dmemMMU <> io.memMMU.dmem
60

Z
Zihao Yu 已提交
61 62 63 64 65
  val mou = Module(new MOU)
  // mou does not write register
  mou.access(valid = fuValids(FuType.mou), src1 = src1, src2 = src2, func = fuOpType)
  mou.io.cfIn := io.in.bits.cf
  mou.io.out.ready := true.B
66
  
Z
Zihao Yu 已提交
67 68
  io.out.bits.decode := DontCare
  (io.out.bits.decode.ctrl, io.in.bits.ctrl) match { case (o, i) =>
69
    o.rfWen := i.rfWen && (!lsuTlbPF || !fuValids(FuType.lsu)) && !(csr.io.wenFix && fuValids(FuType.csr))
Z
Zihao Yu 已提交
70
    o.rfDest := i.rfDest
Z
Zihao Yu 已提交
71
    o.fuType := i.fuType
Z
Zihao Yu 已提交
72
  }
Z
Zihao Yu 已提交
73
  io.out.bits.decode.cf.pc := io.in.bits.cf.pc
W
William Wang 已提交
74

75
  io.out.bits.decode.cf.instr := io.in.bits.cf.instr
Z
Zihao Yu 已提交
76 77
  io.out.bits.decode.cf.redirect <>
    Mux(mou.io.redirect.valid, mou.io.redirect,
78
      Mux(csr.io.redirect.valid, csr.io.redirect, alu.io.redirect))
79
  Debug(){
80 81
    when(mou.io.redirect.valid || csr.io.redirect.valid || alu.io.redirect.valid){
      printf("[REDIRECT] mou %x csr %x alu %x", mou.io.redirect.valid, csr.io.redirect.valid, alu.io.redirect.valid)
82 83
    }
  }
Z
Zihao Yu 已提交
84

Z
Zihao Yu 已提交
85
  // FIXME: should handle io.out.ready == false
Z
Zihao Yu 已提交
86
  io.out.valid := io.in.valid && MuxLookup(fuType, true.B, List(
Z
Zihao Yu 已提交
87 88
    FuType.lsu -> lsu.io.out.valid,
    FuType.mdu -> mdu.io.out.valid
Z
Zihao Yu 已提交
89
  ))
90

Z
Zihao Yu 已提交
91 92 93 94
  io.out.bits.commits(FuType.alu) := aluOut
  io.out.bits.commits(FuType.lsu) := lsuOut
  io.out.bits.commits(FuType.csr) := csrOut
  io.out.bits.commits(FuType.mdu) := mduOut
Z
Zihao Yu 已提交
95
  io.out.bits.commits(FuType.mou) := 0.U
Z
Zihao Yu 已提交
96

Z
Zihao Yu 已提交
97 98
  io.in.ready := !io.in.valid || io.out.fire()

99
  io.forward.valid := io.in.valid
Z
Zihao Yu 已提交
100 101 102
  io.forward.wb.rfWen := io.in.bits.ctrl.rfWen
  io.forward.wb.rfDest := io.in.bits.ctrl.rfDest
  io.forward.wb.rfData := Mux(alu.io.out.fire(), aluOut, lsuOut)
103
  io.forward.fuType := io.in.bits.ctrl.fuType
Z
Zihao Yu 已提交
104

Z
Zihao Yu 已提交
105
  val isBru = ALUOpType.isBru(fuOpType)
Z
Zihao Yu 已提交
106 107
  BoringUtils.addSource(alu.io.out.fire() && !isBru, "perfCntCondMaluInstr")
  BoringUtils.addSource(alu.io.out.fire() && isBru, "perfCntCondMbruInstr")
108 109 110
  BoringUtils.addSource(lsu.io.out.fire(), "perfCntCondMlsuInstr")
  BoringUtils.addSource(mdu.io.out.fire(), "perfCntCondMmduInstr")
  BoringUtils.addSource(csr.io.out.fire(), "perfCntCondMcsrInstr")
Z
Zihao Yu 已提交
111 112 113

  if (!p.FPGAPlatform) {
    val mon = Module(new Monitor)
Z
Zihao Yu 已提交
114 115
    val cycleCnt = WireInit(0.U(XLEN.W))
    val instrCnt = WireInit(0.U(XLEN.W))
Z
Zihao Yu 已提交
116 117 118 119 120
    val nooptrap = io.in.bits.ctrl.isNoopTrap && io.in.valid
    mon.io.clk := clock
    mon.io.reset := reset.asBool
    mon.io.isNoopTrap := nooptrap
    mon.io.trapCode := io.in.bits.data.src1
Z
Zihao Yu 已提交
121
    mon.io.trapPC := io.in.bits.cf.pc
Z
Zihao Yu 已提交
122 123 124 125 126 127 128
    mon.io.cycleCnt := cycleCnt
    mon.io.instrCnt := instrCnt

    BoringUtils.addSink(cycleCnt, "simCycleCnt")
    BoringUtils.addSink(instrCnt, "simInstrCnt")
    BoringUtils.addSource(nooptrap, "nooptrap")
  }
Z
Zihao Yu 已提交
129
}