EXU.scala 3.7 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 16
    val dmem = new SimpleBusUC
    val mmio = new SimpleBusUC
Z
Zihao Yu 已提交
17
    val forward = new ForwardIO
Z
Zihao Yu 已提交
18
    //val wbData = Input(UInt(32.W))
Z
Zihao Yu 已提交
19 20
  })

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

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

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

29 30 31 32
  // when(io.in.valid){
  //   printf("EXv %b %b %b %b %x %x\n", fuValids(0), fuValids(1), fuValids(2), fuValids(3), fuType, io.flush)
  // }

Z
Zihao Yu 已提交
33
  val alu = Module(new ALU)
Z
Zihao Yu 已提交
34
  val aluOut = alu.access(valid = fuValids(FuType.alu), src1 = src1, src2 = src2, func = fuOpType)
Z
Zihao Yu 已提交
35
  alu.io.cfIn := io.in.bits.cf
Z
Zihao Yu 已提交
36
  alu.io.offset := io.in.bits.data.imm
Z
Zihao Yu 已提交
37
  alu.io.out.ready := true.B
Z
Zihao Yu 已提交
38

Z
Zihao Yu 已提交
39
  val lsu = Module(new LSU)
Z
Zihao Yu 已提交
40
  val lsuOut = lsu.access(valid = fuValids(FuType.lsu), src1 = src1, src2 = io.in.bits.data.imm, func = fuOpType)
Z
Zihao Yu 已提交
41
  lsu.io.wdata := src2
Z
Zihao Yu 已提交
42
  io.out.bits.isMMIO := lsu.io.isMMIO
Z
Zihao Yu 已提交
43
  io.dmem <> lsu.io.dmem
Z
Zihao Yu 已提交
44
  io.mmio <> lsu.io.mmio
Z
Zihao Yu 已提交
45
  lsu.io.out.ready := true.B
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 55 56
  csr.io.isInvOpcode := io.in.bits.ctrl.isInvOpcode
  csr.io.out.ready := true.B

Z
Zihao Yu 已提交
57 58
  io.out.bits.decode := DontCare
  (io.out.bits.decode.ctrl, io.in.bits.ctrl) match { case (o, i) =>
Z
Zihao Yu 已提交
59 60
    o.rfWen := i.rfWen
    o.rfDest := i.rfDest
Z
Zihao Yu 已提交
61
    o.fuType := i.fuType
Z
Zihao Yu 已提交
62
  }
Z
Zihao Yu 已提交
63 64
  io.out.bits.decode.cf.pc := io.in.bits.cf.pc
  io.out.bits.decode.cf.redirect <> Mux(csr.io.redirect.valid, csr.io.redirect, alu.io.redirect)
Z
Zihao Yu 已提交
65
  // FIXME: should handle io.out.ready == false
Z
Zihao Yu 已提交
66
  io.out.valid := io.in.valid && MuxLookup(fuType, true.B, List(
Z
Zihao Yu 已提交
67 68
    FuType.lsu -> lsu.io.out.valid,
    FuType.mdu -> mdu.io.out.valid
Z
Zihao Yu 已提交
69
  ))
70

Z
Zihao Yu 已提交
71 72 73 74
  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 已提交
75

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

78
  io.forward.valid := io.in.valid
Z
Zihao Yu 已提交
79 80 81
  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)
82
  io.forward.fuType := io.in.bits.ctrl.fuType
Z
Zihao Yu 已提交
83

Z
Zihao Yu 已提交
84
  val isBru = ALUOpType.isBru(fuOpType)
Z
Zihao Yu 已提交
85 86
  BoringUtils.addSource(alu.io.out.fire() && !isBru, "perfCntCondMaluInstr")
  BoringUtils.addSource(alu.io.out.fire() && isBru, "perfCntCondMbruInstr")
87 88 89
  BoringUtils.addSource(lsu.io.out.fire(), "perfCntCondMlsuInstr")
  BoringUtils.addSource(mdu.io.out.fire(), "perfCntCondMmduInstr")
  BoringUtils.addSource(csr.io.out.fire(), "perfCntCondMcsrInstr")
Z
Zihao Yu 已提交
90 91 92

  if (!p.FPGAPlatform) {
    val mon = Module(new Monitor)
Z
Zihao Yu 已提交
93 94
    val cycleCnt = WireInit(0.U(XLEN.W))
    val instrCnt = WireInit(0.U(XLEN.W))
Z
Zihao Yu 已提交
95 96 97 98 99
    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 已提交
100
    mon.io.trapPC := io.in.bits.cf.pc
Z
Zihao Yu 已提交
101 102 103 104 105 106 107
    mon.io.cycleCnt := cycleCnt
    mon.io.instrCnt := instrCnt

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