EXU.scala 5.8 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
6
import utils._
7
import bus.simplebus._
L
FPUv0.1  
LinJiawei 已提交
8
import noop.fu.FPU
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(addrBits = VAddrBits)
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 || (AddressSpace.isMMIO(io.in.bits.cf.pc) && io.out.valid)
Z
Zihao Yu 已提交
40 41
  io.dmem <> lsu.io.dmem
  lsu.io.out.ready := true.B
Z
Zihao Yu 已提交
42

Z
Zihao Yu 已提交
43
  val mdu = Module(new MDU)
Z
Zihao Yu 已提交
44
  val mduOut = mdu.access(valid = fuValids(FuType.mdu), src1 = src1, src2 = src2, func = fuOpType)
Z
Zihao Yu 已提交
45
  mdu.io.out.ready := true.B
Z
Zihao Yu 已提交
46

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

56 57
  csr.io.imemMMU <> io.memMMU.imem
  csr.io.dmemMMU <> io.memMMU.dmem
58

Z
Zihao Yu 已提交
59 60 61 62 63
  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
L
FPUv0.1  
LinJiawei 已提交
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

  val (fpuOut,fpuOutValid) = if(HasFPU){
    val fpu = Module(new FPU)
    Debug(){
      when(io.in.valid){
        printf(p"[EXU] at pc=${Hexadecimal(io.in.bits.cf.pc)} " +
          p"fpu in valid=${fpu.io.in.valid} " +
          p"fpu out valid=${fpu.io.out.valid}\n")
      }
    }
    fpu.io.out.ready := true.B
    csr.io.fpu_csr <> fpu.io.fpu_csr
    fpu.io.fpWen := io.in.bits.ctrl.fpWen
    fpu.io.inputFunc := io.in.bits.ctrl.fpInputFunc
    fpu.io.outputFunc := io.in.bits.ctrl.fpOutputFunc
    fpu.io.instr := io.in.bits.cf.instr
    (fpu.access(fuValids(FuType.fpu), src1, src2, io.in.bits.data.imm, io.in.bits.ctrl.fuOpType), fpu.io.out.valid)
  } else {
    csr.io.fpu_csr <> DontCare
    (0.U,false.B)
  }

86
  
Z
Zihao Yu 已提交
87 88
  io.out.bits.decode := DontCare
  (io.out.bits.decode.ctrl, io.in.bits.ctrl) match { case (o, i) =>
89
    o.rfWen := i.rfWen && (!lsuTlbPF && !lsu.io.loadAddrMisaligned && !lsu.io.storeAddrMisaligned || !fuValids(FuType.lsu)) && !(csr.io.wenFix && fuValids(FuType.csr))
Z
Zihao Yu 已提交
90
    o.rfDest := i.rfDest
Z
Zihao Yu 已提交
91
    o.fuType := i.fuType
L
FPUv0.1  
LinJiawei 已提交
92
    o.fpWen := i.fpWen && (!lsuTlbPF && !lsu.io.loadAddrMisaligned && !lsu.io.storeAddrMisaligned || !fuValids(FuType.lsu)) && !(csr.io.wenFix && fuValids(FuType.csr))
Z
Zihao Yu 已提交
93
  }
Z
Zihao Yu 已提交
94
  io.out.bits.decode.cf.pc := io.in.bits.cf.pc
W
William Wang 已提交
95

96
  io.out.bits.decode.cf.instr := io.in.bits.cf.instr
Z
Zihao Yu 已提交
97 98
  io.out.bits.decode.cf.redirect <>
    Mux(mou.io.redirect.valid, mou.io.redirect,
99
      Mux(csr.io.redirect.valid, csr.io.redirect, alu.io.redirect))
100
  Debug(){
101 102 103 104
    //when(mou.io.redirect.valid || csr.io.redirect.valid || alu.io.redirect.valid){
      printf("[REDIRECT] inValid:%d mou %x csr %x alu %x \n", io.in.valid, mou.io.redirect.valid, csr.io.redirect.valid, alu.io.redirect.valid)
      printf("[REDIRECT] flush: %d mou %x csr %x alu %x\n", io.flush, mou.io.redirect.target, csr.io.redirect.target, alu.io.redirect.target)
    //}
105
  }
Z
Zihao Yu 已提交
106

Z
Zihao Yu 已提交
107
  // FIXME: should handle io.out.ready == false
Z
Zihao Yu 已提交
108
  io.out.valid := io.in.valid && MuxLookup(fuType, true.B, List(
Z
Zihao Yu 已提交
109
    FuType.lsu -> lsu.io.out.valid,
L
FPUv0.1  
LinJiawei 已提交
110 111
    FuType.mdu -> mdu.io.out.valid,
    FuType.fpu -> fpuOutValid
Z
Zihao Yu 已提交
112
  ))
113

Z
Zihao Yu 已提交
114 115 116 117
  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 已提交
118
  io.out.bits.commits(FuType.mou) := 0.U
L
FPUv0.1  
LinJiawei 已提交
119
  io.out.bits.commits(FuType.fpu) := fpuOut
Z
Zihao Yu 已提交
120

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

123
  io.forward.valid := io.in.valid
Z
Zihao Yu 已提交
124
  io.forward.wb.rfWen := io.in.bits.ctrl.rfWen
L
FPUv0.1  
LinJiawei 已提交
125
  io.forward.wb.fpWen := io.in.bits.ctrl.fpWen
Z
Zihao Yu 已提交
126 127
  io.forward.wb.rfDest := io.in.bits.ctrl.rfDest
  io.forward.wb.rfData := Mux(alu.io.out.fire(), aluOut, lsuOut)
128
  io.forward.fuType := io.in.bits.ctrl.fuType
Z
Zihao Yu 已提交
129

Z
Zihao Yu 已提交
130
  val isBru = ALUOpType.isBru(fuOpType)
Z
Zihao Yu 已提交
131 132
  BoringUtils.addSource(alu.io.out.fire() && !isBru, "perfCntCondMaluInstr")
  BoringUtils.addSource(alu.io.out.fire() && isBru, "perfCntCondMbruInstr")
133 134 135
  BoringUtils.addSource(lsu.io.out.fire(), "perfCntCondMlsuInstr")
  BoringUtils.addSource(mdu.io.out.fire(), "perfCntCondMmduInstr")
  BoringUtils.addSource(csr.io.out.fire(), "perfCntCondMcsrInstr")
Z
Zihao Yu 已提交
136 137

  if (!p.FPGAPlatform) {
Z
Zihao Yu 已提交
138
    val nooptrap = io.in.bits.ctrl.isNoopTrap && io.in.valid
Z
Zihao Yu 已提交
139 140
    val cycleCnt = WireInit(0.U(XLEN.W))
    val instrCnt = WireInit(0.U(XLEN.W))
Z
Zihao Yu 已提交
141 142 143

    BoringUtils.addSink(cycleCnt, "simCycleCnt")
    BoringUtils.addSink(instrCnt, "simInstrCnt")
Z
Zihao Yu 已提交
144 145 146 147 148 149

    BoringUtils.addSource(nooptrap, "trapValid")
    BoringUtils.addSource(io.in.bits.data.src1, "trapCode")
    BoringUtils.addSource(io.in.bits.cf.pc, "trapPC")
    BoringUtils.addSource(cycleCnt, "trapCycleCnt")
    BoringUtils.addSource(instrCnt, "trapInstrCnt")
Z
Zihao Yu 已提交
150
  }
Z
Zihao Yu 已提交
151
}