package noop import chisel3._ import chisel3.util._ import chisel3.util.experimental.BoringUtils import utils._ import bus.simplebus._ class EXU(implicit val p: NOOPConfig) extends NOOPModule { val io = IO(new Bundle { val in = Flipped(Decoupled(new DecodeIO)) val out = Decoupled(new CommitIO) val flush = Input(Bool()) val dmem = new SimpleBusUC val forward = new ForwardIO val tlb = new TLBExuIO val memMMU = Flipped(new MemMMUIO) }) val src1 = io.in.bits.data.src1 val src2 = io.in.bits.data.src2 val (fuType, fuOpType) = (io.in.bits.ctrl.fuType, io.in.bits.ctrl.fuOpType) val fuValids = Wire(Vec(FuType.num, Bool())) (0 until FuType.num).map (i => fuValids(i) := (fuType === i.U) && io.in.valid && !io.flush) val alu = Module(new ALU) val aluOut = alu.access(valid = fuValids(FuType.alu), src1 = src1, src2 = src2, func = fuOpType) alu.io.cfIn := io.in.bits.cf alu.io.offset := io.in.bits.data.imm alu.io.out.ready := true.B val lsu = Module(new LSU) val lsuOut = lsu.access(valid = fuValids(FuType.lsu), src1 = src1, src2 = io.in.bits.data.imm, func = fuOpType) lsu.io.wdata := src2 lsu.io.instr := io.in.bits.cf.instr io.out.bits.isMMIO := lsu.io.isMMIO io.dmem <> lsu.io.dmem lsu.io.out.ready := true.B val mdu = Module(new MDU) val mduOut = mdu.access(valid = fuValids(FuType.mdu), src1 = src1, src2 = src2, func = fuOpType) mdu.io.out.ready := true.B val csr = Module(new CSR) val csrOut = csr.access(valid = fuValids(FuType.csr), src1 = src1, src2 = src2, func = fuOpType) csr.io.cfIn := io.in.bits.cf csr.io.instrValid := io.in.valid && !io.flush io.out.bits.intrNO := csr.io.intrNO csr.io.out.ready := true.B csr.io.imemMMU <> io.memMMU.imem csr.io.dmemMMU <> io.memMMU.dmem /* csr.io.dmemMMU.loadPF := false.B csr.io.dmemMMU.storePF := false.B csr.io.dmemMMU.addr := 0.U csr.io.imemMMU.loadPF := false.B csr.io.imemMMU.storePF := false.B csr.io.imemMMU.addr := 0.U */ 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 //tlb: tlb is implemented outside - added by lemover-zhangzifei io.tlb.access(valid = fuValids(FuType.tlb), src1 = src1, src2 = src2, func = fuOpType, satp = csr.io.satp) //func no use here val tlbRedirect = fuTlb(cf = io.in.bits.cf, valid = fuValids(FuType.tlb)) io.out.bits.decode := DontCare (io.out.bits.decode.ctrl, io.in.bits.ctrl) match { case (o, i) => o.rfWen := i.rfWen o.rfDest := i.rfDest o.fuType := i.fuType } io.out.bits.decode.cf.pc := io.in.bits.cf.pc io.out.bits.decode.cf.instr := io.in.bits.cf.instr io.out.bits.decode.cf.redirect <> Mux(mou.io.redirect.valid, mou.io.redirect, Mux(csr.io.redirect.valid, csr.io.redirect, Mux(alu.io.redirect.valid, alu.io.redirect, tlbRedirect))) //add tlb // FIXME: should handle io.out.ready == false io.out.valid := io.in.valid && MuxLookup(fuType, true.B, List( FuType.lsu -> lsu.io.out.valid, FuType.mdu -> mdu.io.out.valid )) 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 io.out.bits.commits(FuType.mou) := 0.U io.out.bits.commits(FuType.tlb) := 0.U io.in.ready := !io.in.valid || io.out.fire() io.forward.valid := io.in.valid 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) io.forward.fuType := io.in.bits.ctrl.fuType val isBru = ALUOpType.isBru(fuOpType) BoringUtils.addSource(alu.io.out.fire() && !isBru, "perfCntCondMaluInstr") BoringUtils.addSource(alu.io.out.fire() && isBru, "perfCntCondMbruInstr") BoringUtils.addSource(lsu.io.out.fire(), "perfCntCondMlsuInstr") BoringUtils.addSource(mdu.io.out.fire(), "perfCntCondMmduInstr") BoringUtils.addSource(csr.io.out.fire(), "perfCntCondMcsrInstr") if (!p.FPGAPlatform) { val mon = Module(new Monitor) val cycleCnt = WireInit(0.U(XLEN.W)) val instrCnt = WireInit(0.U(XLEN.W)) 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 mon.io.trapPC := io.in.bits.cf.pc mon.io.cycleCnt := cycleCnt mon.io.instrCnt := instrCnt BoringUtils.addSink(cycleCnt, "simCycleCnt") BoringUtils.addSink(instrCnt, "simInstrCnt") BoringUtils.addSource(nooptrap, "nooptrap") } }