From 24a2278fc40d0a335d5a490e78babf3f2ea9bde8 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Tue, 7 Mar 2017 14:33:51 -0800 Subject: [PATCH] Perform all illegal-instruction detection in ID stage This is simpler, reduces what would have become a critical path in the commit stage, and will make it easier to support the mbadinst CSR if it is implemented. --- src/main/scala/rocket/CSR.scala | 117 ++++++++++++------------- src/main/scala/rocket/IBuf.scala | 2 + src/main/scala/rocket/Rocket.scala | 26 +++--- src/main/scala/tile/FPU.scala | 133 ++++++++++++++--------------- 4 files changed, 135 insertions(+), 143 deletions(-) diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 4d640caa..bc3bbae3 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -143,8 +143,17 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle val wdata = Bits(INPUT, xLen) } + val decode = new Bundle { + val csr = UInt(INPUT, CSR.ADDRSZ) + val fp_illegal = Bool(OUTPUT) + val rocc_illegal = Bool(OUTPUT) + val read_illegal = Bool(OUTPUT) + val write_illegal = Bool(OUTPUT) + val write_flush = Bool(OUTPUT) + val system_illegal = Bool(OUTPUT) + } + val csr_stall = Bool(OUTPUT) - val csr_xcpt = Bool(OUTPUT) val eret = Bool(OUTPUT) val singleStep = Bool(OUTPUT) @@ -210,17 +219,11 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) Causes.fault_store, Causes.user_ecall).map(1 << _).sum) - val exception = io.exception || io.csr_xcpt val reg_debug = Reg(init=Bool(false)) val effective_prv = Cat(reg_debug, reg_mstatus.prv) val reg_dpc = Reg(UInt(width = vaddrBitsExtended)) val reg_dscratch = Reg(UInt(width = xLen)) - val reg_singleStepped = Reg(Bool()) - when (io.retire(0) || exception) { reg_singleStepped := true } - when (!io.singleStep) { reg_singleStepped := false } - assert(!io.singleStep || io.retire <= UInt(1)) - assert(!reg_singleStepped || io.retire === UInt(0)) val reg_tselect = Reg(UInt(width = log2Up(nBreakpoints))) val reg_bp = Reg(Vec(1 << log2Up(nBreakpoints), new BP)) @@ -257,6 +260,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) val reg_cycle = if (enableCommitLog) reg_instret else WideCounter(64) val reg_hpmevent = Seq.fill(nPerfCounters)(if (nPerfEvents > 1) Reg(UInt(width = log2Ceil(nPerfEvents))) else UInt(0)) val reg_hpmcounter = reg_hpmevent.map(e => WideCounter(64, ((UInt(0) +: io.events): Seq[UInt])(e))) + val hpm_mask = reg_mcounteren & Mux((!usingVM).B || reg_mstatus.prv === PRV.S, delegable_counters.U, reg_scounteren) val mip = Wire(init=reg_mip) mip.rocc := io.rocc_interrupt @@ -278,10 +282,6 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) io.interrupt_cause := UInt(interruptMSB) + CSR.debugIntCause } - val system_insn = io.rw.cmd === CSR.I - val cpu_ren = io.rw.cmd =/= CSR.N && !system_insn - val cpu_wen = cpu_ren && io.rw.cmd =/= CSR.R - val isaMaskString = (if (usingMulDiv) "M" else "") + (if (usingAtomics) "A" else "") + @@ -388,56 +388,37 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) } val decoded_addr = read_mapping map { case (k, v) => k -> (io.rw.addr === k) } - val addr_valid = decoded_addr.values.reduce(_||_) - val fp_csr = if (usingFPU) decoded_addr.filterKeys(fp_csrs contains _ ).values reduce(_||_) else Bool(false) - val hpm_csr = if (usingUser) io.rw.addr >= CSR.firstCtr && io.rw.addr < CSR.firstCtr + CSR.nCtr else Bool(false) - val hpm_en = effective_prv > PRV.S || (reg_mcounteren & Mux((!usingVM).B || reg_mstatus.prv === PRV.S, delegable_counters.U, reg_scounteren))(io.rw.addr(log2Ceil(CSR.nCtr)-1, 0)) - val csr_addr_priv = io.rw.addr(9,8) - - val debug_csr_mask = 0x090 // only debug CSRs have address bits 7 and 4 set - require((read_mapping -- debug_csrs.keys).keys.forall(x => (x & debug_csr_mask) != debug_csr_mask)) - require(debug_csrs.keys.forall(x => (x & debug_csr_mask) == debug_csr_mask)) - val csr_debug = Bool(usingDebug) && (io.rw.addr & debug_csr_mask) === debug_csr_mask - val priv_sufficient = reg_debug || (!csr_debug && reg_mstatus.prv >= csr_addr_priv) - val read_only = io.rw.addr(11,10).andR - val wen = cpu_wen && priv_sufficient && !read_only - val wdata = (Mux(io.rw.cmd.isOneOf(CSR.S, CSR.C), io.rw.rdata, UInt(0)) | io.rw.wdata) & ~Mux(io.rw.cmd === CSR.C, io.rw.wdata, UInt(0)) - val do_system_insn = priv_sufficient && system_insn + val system_insn = io.rw.cmd === CSR.I val opcode = UInt(1) << io.rw.addr(2,0) val insn_rs2 = io.rw.addr(5) - val insn_call = do_system_insn && !insn_rs2 && opcode(0) - val insn_break = do_system_insn && opcode(1) - val insn_ret = do_system_insn && opcode(2) - val allow_wfi = effective_prv > PRV.S || !reg_mstatus.tw - val want_wfi = do_system_insn && opcode(5) - val insn_wfi = want_wfi && allow_wfi - val allow_sfence_vma = effective_prv > PRV.S || !reg_mstatus.tvm - val want_sfence_vma = do_system_insn && insn_rs2 - val insn_sfence_vma = want_sfence_vma && allow_sfence_vma - val allow_fcsr = io.status.fs.orR && reg_misa('f'-'a') + val insn_call = system_insn && !insn_rs2 && opcode(0) + val insn_break = system_insn && opcode(1) + val insn_ret = system_insn && opcode(2) + val insn_wfi = system_insn && opcode(5) + val insn_sfence_vma = system_insn && insn_rs2 - io.csr_xcpt := (cpu_wen && read_only) || - (cpu_ren && - (!priv_sufficient || - !addr_valid || - (if (usingVM) decoded_addr(CSRs.sptbr) && !allow_sfence_vma else false.B) || - (hpm_csr && !hpm_en) || - (fp_csr && !allow_fcsr))) || - (system_insn && !priv_sufficient) || - insn_call || insn_break || - want_wfi && !allow_wfi || - want_sfence_vma && !allow_sfence_vma - - when (insn_wfi) { reg_wfi := true } - when (pending_interrupts.orR || exception) { reg_wfi := false } + val allow_wfi = Bool(!usingVM) || effective_prv > PRV.S || !reg_mstatus.tw + val allow_sfence_vma = Bool(!usingVM) || effective_prv > PRV.S || !reg_mstatus.tvm + io.decode.fp_illegal := io.status.fs === 0 || !reg_misa('f'-'a') + io.decode.rocc_illegal := io.status.xs === 0 || !reg_misa('x'-'a') + io.decode.read_illegal := effective_prv < io.decode.csr(9,8) || + !read_mapping.keys.map(io.decode.csr === _).reduce(_||_) || + io.decode.csr === CSRs.sptbr && !allow_sfence_vma || + io.decode.csr >= CSR.firstCtr && io.decode.csr < CSR.firstCtr + CSR.nCtr && effective_prv <= PRV.S && hpm_mask(io.decode.csr(log2Ceil(CSR.firstCtr)-1,0)) || + Bool(usingDebug) && !reg_debug && debug_csrs.keys.map(io.decode.csr === _).reduce(_||_) || + Bool(usingFPU) && fp_csrs.keys.map(io.decode.csr === _).reduce(_||_) && io.decode.fp_illegal + io.decode.write_illegal := io.decode.csr(11,10).andR + io.decode.write_flush := !(io.decode.csr >= CSRs.mscratch && io.decode.csr <= CSRs.mbadaddr || io.decode.csr >= CSRs.sscratch && io.decode.csr <= CSRs.sbadaddr) + io.decode.system_illegal := effective_prv < io.decode.csr(9,8) || + io.decode.csr(2) && !allow_wfi || + io.decode.csr(5) && !allow_sfence_vma val cause = - Mux(!io.csr_xcpt, io.cause, Mux(insn_call, reg_mstatus.prv + Causes.user_ecall, - Mux[UInt](insn_break, Causes.breakpoint, Causes.illegal_instruction))) + Mux[UInt](insn_break, Causes.breakpoint, io.cause)) val cause_lsbs = cause(log2Up(xLen)-1,0) val causeIsDebugInt = cause(xLen-1) && cause_lsbs === CSR.debugIntCause val causeIsDebugTrigger = !cause(xLen-1) && cause_lsbs === CSR.debugTriggerCause @@ -446,11 +427,10 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) val delegate = Bool(usingVM) && reg_mstatus.prv <= PRV.S && Mux(cause(xLen-1), reg_mideleg(cause_lsbs), reg_medeleg(cause_lsbs)) val debugTVec = Mux(reg_debug, UInt(0x808), UInt(0x800)) val tvec = Mux(trapToDebug, debugTVec, Mux(delegate, reg_stvec.sextTo(vaddrBitsExtended), reg_mtvec)) - val epc = Mux(csr_debug, reg_dpc, Mux(Bool(usingVM) && !csr_addr_priv(1), reg_sepc, reg_mepc)) io.fatc := insn_sfence_vma - io.evec := Mux(insn_ret, epc, tvec) + io.evec := tvec io.ptbr := reg_sptbr - io.eret := insn_ret + io.eret := insn_call || insn_break || insn_ret io.singleStep := reg_dcsr.step && !reg_debug io.status := reg_mstatus io.status.sd := io.status.fs.andR || io.status.xs.andR @@ -461,6 +441,18 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) if (xLen == 32) io.status.sd_rv32 := io.status.sd + val exception = insn_call || insn_break || io.exception + assert(PopCount(insn_ret :: insn_call :: insn_break :: io.exception :: Nil) <= 1, "these conditions must be mutually exclusive") + + when (insn_wfi) { reg_wfi := true } + when (pending_interrupts.orR || exception) { reg_wfi := false } + assert(!reg_wfi || io.retire === UInt(0)) + + when (io.retire(0)) { reg_singleStepped := true } + when (!io.singleStep) { reg_singleStepped := false } + assert(!io.singleStep || io.retire <= UInt(1)) + assert(!reg_singleStepped || io.retire === UInt(0)) + when (exception) { val epc = ~(~io.pc | (coreInstBytes-1)) val pie = read_mstatus(reg_mstatus.prv) @@ -494,25 +486,26 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) } when (insn_ret) { - when (Bool(usingVM) && !csr_addr_priv(1)) { + when (Bool(usingVM) && !io.rw.addr(9)) { when (reg_mstatus.spp.toBool) { reg_mstatus.sie := reg_mstatus.spie } reg_mstatus.spie := true reg_mstatus.spp := PRV.U new_prv := reg_mstatus.spp - }.elsewhen (csr_debug) { + io.evec := reg_sepc + }.elsewhen (Bool(usingDebug) && io.rw.addr(10)) { new_prv := reg_dcsr.prv reg_debug := false + io.evec := reg_dpc }.otherwise { when (reg_mstatus.mpp(1)) { reg_mstatus.mie := reg_mstatus.mpie } .elsewhen (Bool(usingVM) && reg_mstatus.mpp(0)) { reg_mstatus.sie := reg_mstatus.mpie } reg_mstatus.mpie := true reg_mstatus.mpp := legalizePrivilege(PRV.U) new_prv := reg_mstatus.mpp + io.evec := reg_mepc } } - assert(PopCount(insn_ret :: io.exception :: io.csr_xcpt :: Nil) <= 1, "these conditions must be mutually exclusive") - io.time := reg_cycle io.csr_stall := reg_wfi @@ -523,7 +516,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) reg_fflags := reg_fflags | io.fcsr_flags.bits } - when (wen) { + when (io.rw.cmd.isOneOf(CSR.S, CSR.C, CSR.W)) { when (decoded_addr(CSRs.mstatus)) { val new_mstatus = new MStatus().fromBits(wdata) reg_mstatus.mie := new_mstatus.mie @@ -574,7 +567,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) writeCounter(CSRs.mcycle, reg_cycle, wdata) writeCounter(CSRs.minstret, reg_instret, wdata) - if (usingFPU) when (allow_fcsr) { + if (usingFPU) { when (decoded_addr(CSRs.fflags)) { reg_fflags := wdata } when (decoded_addr(CSRs.frm)) { reg_frm := wdata } when (decoded_addr(CSRs.fcsr)) { reg_fflags := wdata; reg_frm := wdata >> reg_fflags.getWidth } @@ -606,7 +599,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) val new_sip = new MIP().fromBits(wdata) reg_mip.ssip := new_sip.ssip } - when (decoded_addr(CSRs.sptbr) && allow_sfence_vma) { + when (decoded_addr(CSRs.sptbr)) { val new_sptbr = new PTBR().fromBits(wdata) val valid_mode = new_sptbr.pgLevelsToMode(pgLevels) when (new_sptbr.mode === 0) { reg_sptbr.mode := 0 } diff --git a/src/main/scala/rocket/IBuf.scala b/src/main/scala/rocket/IBuf.scala index ec524c8b..d81f9a4b 100644 --- a/src/main/scala/rocket/IBuf.scala +++ b/src/main/scala/rocket/IBuf.scala @@ -15,6 +15,7 @@ class Instruction(implicit val p: Parameters) extends ParameterizedBundle with H val btb_hit = Bool() val rvc = Bool() val inst = new ExpandedInstruction + val raw = UInt(width = 32) require(coreInstBits == (if (usingCompressed) 16 else 32)) } @@ -92,6 +93,7 @@ class IBuf(implicit p: Parameters) extends CoreModule { val exp = Module(new RVCExpander) exp.io.in := curInst io.inst(i).bits.inst := exp.io.out + io.inst(i).bits.raw := curInst if (usingCompressed) { val replay = ic_replay(j) || (!exp.io.rvc && (btbHitMask(j) || ic_replay(j+1))) diff --git a/src/main/scala/rocket/Rocket.scala b/src/main/scala/rocket/Rocket.scala index 5c17c5f4..2ac26f9c 100644 --- a/src/main/scala/rocket/Rocket.scala +++ b/src/main/scala/rocket/Rocket.scala @@ -143,23 +143,21 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) take_pc_id := Bool(fastJAL) && !ctrl_killd && id_ctrl.jal val csr = Module(new CSRFile) - val id_csr_en = id_ctrl.csr =/= CSR.N - val id_system_insn = id_ctrl.csr === CSR.I - val id_csr_ren = (id_ctrl.csr === CSR.S || id_ctrl.csr === CSR.C) && id_raddr1 === UInt(0) + val id_csr_en = id_ctrl.csr.isOneOf(CSR.S, CSR.C, CSR.W) + val id_system_insn = id_ctrl.csr >= CSR.I + val id_csr_ren = id_ctrl.csr.isOneOf(CSR.S, CSR.C) && id_raddr1 === UInt(0) val id_csr = Mux(id_csr_ren, CSR.R, id_ctrl.csr) - val id_csr_addr = id_inst(0)(31,20) - // this is overly conservative - val safe_csrs = CSRs.sscratch :: CSRs.sepc :: CSRs.mscratch :: CSRs.mepc :: CSRs.mcause :: CSRs.mbadaddr :: Nil - val legal_csrs = collection.mutable.LinkedHashSet(CSRs.all:_*) - val id_csr_flush = id_system_insn || (id_csr_en && !id_csr_ren && !DecodeLogic(id_csr_addr, safe_csrs.map(UInt(_)), (legal_csrs -- safe_csrs).toList.map(UInt(_)))) + val id_csr_flush = id_system_insn || (id_csr_en && !id_csr_ren && csr.io.decode.write_flush) val id_illegal_insn = !id_ctrl.legal || id_ctrl.div && !csr.io.status.isa('m'-'a') || id_ctrl.amo && !csr.io.status.isa('a'-'a') || - id_ctrl.fp && !(csr.io.status.fs.orR && csr.io.status.isa('f'-'a')) || + id_ctrl.fp && (csr.io.decode.fp_illegal || io.fpu.illegal_rm) || id_ctrl.dp && !csr.io.status.isa('d'-'a') || ibuf.io.inst(0).bits.rvc && !csr.io.status.isa('c'-'a') || - id_ctrl.rocc && !(csr.io.status.xs.orR && csr.io.status.isa('x'-'a')) + id_ctrl.rocc && csr.io.decode.rocc_illegal || + id_csr_en && (csr.io.decode.read_illegal || !id_csr_ren && csr.io.decode.write_illegal) || + id_system_insn && csr.io.decode.system_illegal // stall decode for fences (now, for AMO.aq; later, for AMO.rl and FENCE) val id_amo_aq = id_inst(0)(26) val id_amo_rl = id_inst(0)(25) @@ -205,7 +203,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) // execute stage val bypass_mux = Vec(bypass_sources.map(_._3)) val ex_reg_rs_bypass = Reg(Vec(id_raddr.size, Bool())) - val ex_reg_rs_lsb = Reg(Vec(id_raddr.size, UInt())) + val ex_reg_rs_lsb = Reg(Vec(id_raddr.size, UInt(width = log2Ceil(bypass_sources.size)))) val ex_reg_rs_msb = Reg(Vec(id_raddr.size, UInt())) val ex_rs = for (i <- 0 until id_raddr.size) yield Mux(ex_reg_rs_bypass(i), bypass_mux(ex_reg_rs_lsb(i)), Cat(ex_reg_rs_msb(i), ex_reg_rs_lsb(i))) @@ -291,8 +289,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) val ex_slow_bypass = ex_ctrl.mem_cmd === M_XSC || Vec(MT_B, MT_BU, MT_H, MT_HU).contains(ex_ctrl.mem_type) val (ex_xcpt, ex_cause) = checkExceptions(List( - (ex_reg_xcpt_interrupt || ex_reg_xcpt, ex_reg_cause), - (ex_ctrl.fp && io.fpu.illegal_rm, UInt(Causes.illegal_instruction)))) + (ex_reg_xcpt_interrupt || ex_reg_xcpt, ex_reg_cause))) // memory stage val mem_br_taken = mem_reg_wdata(0) @@ -375,7 +372,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) val replay_wb_common = io.dmem.s2_nack || wb_reg_replay val replay_wb_rocc = wb_reg_valid && wb_ctrl.rocc && !io.rocc.cmd.ready val replay_wb = replay_wb_common || replay_wb_rocc - val wb_xcpt = wb_reg_xcpt || csr.io.csr_xcpt + val wb_xcpt = wb_reg_xcpt take_pc_wb := replay_wb || wb_xcpt || csr.io.eret // writeback arbitration @@ -417,6 +414,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) when (rf_wen) { rf.write(rf_waddr, rf_wdata) } // hook up control/status regfile + csr.io.decode.csr := ibuf.io.inst(0).bits.raw(31,20) csr.io.exception := wb_reg_xcpt csr.io.cause := wb_reg_cause csr.io.retire := wb_valid diff --git a/src/main/scala/tile/FPU.scala b/src/main/scala/tile/FPU.scala index db3001e7..9ce6a89c 100644 --- a/src/main/scala/tile/FPU.scala +++ b/src/main/scala/tile/FPU.scala @@ -60,7 +60,6 @@ trait HasFPUCtrlSigs { val fma = Bool() val div = Bool() val sqrt = Bool() - val round = Bool() val wflags = Bool() } @@ -72,71 +71,71 @@ class FPUDecoder(implicit p: Parameters) extends FPUModule()(p) { val sigs = new FPUCtrlSigs().asOutput } - val default = List(FCMD_X, X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X) + val default = List(FCMD_X, X,X,X,X,X,X,X,X,X,X,X,X,X,X,X) val f = - Array(FLW -> List(FCMD_X, Y,Y,N,N,N,X,X,Y,N,N,N,N,N,N,N,N), - FSW -> List(FCMD_MV_XF, Y,N,N,Y,N,Y,X,Y,N,Y,N,N,N,N,N,N), - FMV_S_X -> List(FCMD_MV_FX, N,Y,N,N,N,X,X,Y,Y,N,N,N,N,N,Y,N), - FCVT_S_W -> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,Y,Y,N,N,N,N,N,Y,Y), - FCVT_S_WU-> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,Y,Y,N,N,N,N,N,Y,Y), - FCVT_S_L -> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,Y,Y,N,N,N,N,N,Y,Y), - FCVT_S_LU-> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,Y,Y,N,N,N,N,N,Y,Y), - FMV_X_S -> List(FCMD_MV_XF, N,N,Y,N,N,N,X,Y,N,Y,N,N,N,N,Y,N), - FCLASS_S -> List(FCMD_MV_XF, N,N,Y,N,N,N,X,Y,N,Y,N,N,N,N,Y,N), - FCVT_W_S -> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,Y,N,Y,N,N,N,N,Y,Y), - FCVT_WU_S-> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,Y,N,Y,N,N,N,N,Y,Y), - FCVT_L_S -> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,Y,N,Y,N,N,N,N,Y,Y), - FCVT_LU_S-> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,Y,N,Y,N,N,N,N,Y,Y), - FEQ_S -> List(FCMD_CMP, N,N,Y,Y,N,N,N,Y,N,Y,N,N,N,N,N,Y), - FLT_S -> List(FCMD_CMP, N,N,Y,Y,N,N,N,Y,N,Y,N,N,N,N,N,Y), - FLE_S -> List(FCMD_CMP, N,N,Y,Y,N,N,N,Y,N,Y,N,N,N,N,N,Y), - FSGNJ_S -> List(FCMD_SGNJ, N,Y,Y,Y,N,N,N,Y,N,N,Y,N,N,N,N,N), - FSGNJN_S -> List(FCMD_SGNJ, N,Y,Y,Y,N,N,N,Y,N,N,Y,N,N,N,N,N), - FSGNJX_S -> List(FCMD_SGNJ, N,Y,Y,Y,N,N,N,Y,N,N,Y,N,N,N,N,N), - FMIN_S -> List(FCMD_MINMAX, N,Y,Y,Y,N,N,N,Y,N,N,Y,N,N,N,N,Y), - FMAX_S -> List(FCMD_MINMAX, N,Y,Y,Y,N,N,N,Y,N,N,Y,N,N,N,N,Y), - FADD_S -> List(FCMD_ADD, N,Y,Y,Y,N,N,Y,Y,N,N,N,Y,N,N,Y,Y), - FSUB_S -> List(FCMD_SUB, N,Y,Y,Y,N,N,Y,Y,N,N,N,Y,N,N,Y,Y), - FMUL_S -> List(FCMD_MUL, N,Y,Y,Y,N,N,N,Y,N,N,N,Y,N,N,Y,Y), - FMADD_S -> List(FCMD_MADD, N,Y,Y,Y,Y,N,N,Y,N,N,N,Y,N,N,Y,Y), - FMSUB_S -> List(FCMD_MSUB, N,Y,Y,Y,Y,N,N,Y,N,N,N,Y,N,N,Y,Y), - FNMADD_S -> List(FCMD_NMADD, N,Y,Y,Y,Y,N,N,Y,N,N,N,Y,N,N,Y,Y), - FNMSUB_S -> List(FCMD_NMSUB, N,Y,Y,Y,Y,N,N,Y,N,N,N,Y,N,N,Y,Y), - FDIV_S -> List(FCMD_DIV, N,Y,Y,Y,N,N,N,Y,N,N,N,N,Y,N,Y,Y), - FSQRT_S -> List(FCMD_SQRT, N,Y,Y,N,N,Y,X,Y,N,N,N,N,N,Y,Y,Y)) + Array(FLW -> List(FCMD_X, Y,Y,N,N,N,X,X,Y,N,N,N,N,N,N,N), + FSW -> List(FCMD_MV_XF, Y,N,N,Y,N,Y,X,Y,N,Y,N,N,N,N,N), + FMV_S_X -> List(FCMD_MV_FX, N,Y,N,N,N,X,X,Y,Y,N,N,N,N,N,N), + FCVT_S_W -> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,Y,Y,N,N,N,N,N,Y), + FCVT_S_WU-> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,Y,Y,N,N,N,N,N,Y), + FCVT_S_L -> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,Y,Y,N,N,N,N,N,Y), + FCVT_S_LU-> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,Y,Y,N,N,N,N,N,Y), + FMV_X_S -> List(FCMD_MV_XF, N,N,Y,N,N,N,X,Y,N,Y,N,N,N,N,N), + FCLASS_S -> List(FCMD_MV_XF, N,N,Y,N,N,N,X,Y,N,Y,N,N,N,N,N), + FCVT_W_S -> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,Y,N,Y,N,N,N,N,Y), + FCVT_WU_S-> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,Y,N,Y,N,N,N,N,Y), + FCVT_L_S -> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,Y,N,Y,N,N,N,N,Y), + FCVT_LU_S-> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,Y,N,Y,N,N,N,N,Y), + FEQ_S -> List(FCMD_CMP, N,N,Y,Y,N,N,N,Y,N,Y,N,N,N,N,Y), + FLT_S -> List(FCMD_CMP, N,N,Y,Y,N,N,N,Y,N,Y,N,N,N,N,Y), + FLE_S -> List(FCMD_CMP, N,N,Y,Y,N,N,N,Y,N,Y,N,N,N,N,Y), + FSGNJ_S -> List(FCMD_SGNJ, N,Y,Y,Y,N,N,N,Y,N,N,Y,N,N,N,N), + FSGNJN_S -> List(FCMD_SGNJ, N,Y,Y,Y,N,N,N,Y,N,N,Y,N,N,N,N), + FSGNJX_S -> List(FCMD_SGNJ, N,Y,Y,Y,N,N,N,Y,N,N,Y,N,N,N,N), + FMIN_S -> List(FCMD_MINMAX, N,Y,Y,Y,N,N,N,Y,N,N,Y,N,N,N,Y), + FMAX_S -> List(FCMD_MINMAX, N,Y,Y,Y,N,N,N,Y,N,N,Y,N,N,N,Y), + FADD_S -> List(FCMD_ADD, N,Y,Y,Y,N,N,Y,Y,N,N,N,Y,N,N,Y), + FSUB_S -> List(FCMD_SUB, N,Y,Y,Y,N,N,Y,Y,N,N,N,Y,N,N,Y), + FMUL_S -> List(FCMD_MUL, N,Y,Y,Y,N,N,N,Y,N,N,N,Y,N,N,Y), + FMADD_S -> List(FCMD_MADD, N,Y,Y,Y,Y,N,N,Y,N,N,N,Y,N,N,Y), + FMSUB_S -> List(FCMD_MSUB, N,Y,Y,Y,Y,N,N,Y,N,N,N,Y,N,N,Y), + FNMADD_S -> List(FCMD_NMADD, N,Y,Y,Y,Y,N,N,Y,N,N,N,Y,N,N,Y), + FNMSUB_S -> List(FCMD_NMSUB, N,Y,Y,Y,Y,N,N,Y,N,N,N,Y,N,N,Y), + FDIV_S -> List(FCMD_DIV, N,Y,Y,Y,N,N,N,Y,N,N,N,N,Y,N,Y), + FSQRT_S -> List(FCMD_SQRT, N,Y,Y,N,N,Y,X,Y,N,N,N,N,N,Y,Y)) val d = - Array(FLD -> List(FCMD_X, Y,Y,N,N,N,X,X,N,N,N,N,N,N,N,N,N), - FSD -> List(FCMD_MV_XF, Y,N,N,Y,N,Y,X,N,N,Y,N,N,N,N,N,N), - FMV_D_X -> List(FCMD_MV_FX, N,Y,N,N,N,X,X,N,Y,N,N,N,N,N,Y,N), - FCVT_D_W -> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,N,Y,N,N,N,N,N,Y,Y), - FCVT_D_WU-> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,N,Y,N,N,N,N,N,Y,Y), - FCVT_D_L -> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,N,Y,N,N,N,N,N,Y,Y), - FCVT_D_LU-> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,N,Y,N,N,N,N,N,Y,Y), - FMV_X_D -> List(FCMD_MV_XF, N,N,Y,N,N,N,X,N,N,Y,N,N,N,N,Y,N), - FCLASS_D -> List(FCMD_MV_XF, N,N,Y,N,N,N,X,N,N,Y,N,N,N,N,Y,N), - FCVT_W_D -> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,N,N,Y,N,N,N,N,Y,Y), - FCVT_WU_D-> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,N,N,Y,N,N,N,N,Y,Y), - FCVT_L_D -> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,N,N,Y,N,N,N,N,Y,Y), - FCVT_LU_D-> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,N,N,Y,N,N,N,N,Y,Y), - FCVT_S_D -> List(FCMD_CVT_FF, N,Y,Y,N,N,N,X,Y,N,N,Y,N,N,N,Y,Y), - FCVT_D_S -> List(FCMD_CVT_FF, N,Y,Y,N,N,N,X,N,N,N,Y,N,N,N,Y,Y), - FEQ_D -> List(FCMD_CMP, N,N,Y,Y,N,N,N,N,N,Y,N,N,N,N,N,Y), - FLT_D -> List(FCMD_CMP, N,N,Y,Y,N,N,N,N,N,Y,N,N,N,N,N,Y), - FLE_D -> List(FCMD_CMP, N,N,Y,Y,N,N,N,N,N,Y,N,N,N,N,N,Y), - FSGNJ_D -> List(FCMD_SGNJ, N,Y,Y,Y,N,N,N,N,N,N,Y,N,N,N,N,N), - FSGNJN_D -> List(FCMD_SGNJ, N,Y,Y,Y,N,N,N,N,N,N,Y,N,N,N,N,N), - FSGNJX_D -> List(FCMD_SGNJ, N,Y,Y,Y,N,N,N,N,N,N,Y,N,N,N,N,N), - FMIN_D -> List(FCMD_MINMAX, N,Y,Y,Y,N,N,N,N,N,N,Y,N,N,N,N,Y), - FMAX_D -> List(FCMD_MINMAX, N,Y,Y,Y,N,N,N,N,N,N,Y,N,N,N,N,Y), - FADD_D -> List(FCMD_ADD, N,Y,Y,Y,N,N,Y,N,N,N,N,Y,N,N,Y,Y), - FSUB_D -> List(FCMD_SUB, N,Y,Y,Y,N,N,Y,N,N,N,N,Y,N,N,Y,Y), - FMUL_D -> List(FCMD_MUL, N,Y,Y,Y,N,N,N,N,N,N,N,Y,N,N,Y,Y), - FMADD_D -> List(FCMD_MADD, N,Y,Y,Y,Y,N,N,N,N,N,N,Y,N,N,Y,Y), - FMSUB_D -> List(FCMD_MSUB, N,Y,Y,Y,Y,N,N,N,N,N,N,Y,N,N,Y,Y), - FNMADD_D -> List(FCMD_NMADD, N,Y,Y,Y,Y,N,N,N,N,N,N,Y,N,N,Y,Y), - FNMSUB_D -> List(FCMD_NMSUB, N,Y,Y,Y,Y,N,N,N,N,N,N,Y,N,N,Y,Y), - FDIV_D -> List(FCMD_DIV, N,Y,Y,Y,N,N,N,N,N,N,N,N,Y,N,Y,Y), - FSQRT_D -> List(FCMD_SQRT, N,Y,Y,N,N,Y,X,N,N,N,N,N,N,Y,Y,Y)) + Array(FLD -> List(FCMD_X, Y,Y,N,N,N,X,X,N,N,N,N,N,N,N,N), + FSD -> List(FCMD_MV_XF, Y,N,N,Y,N,Y,X,N,N,Y,N,N,N,N,N), + FMV_D_X -> List(FCMD_MV_FX, N,Y,N,N,N,X,X,N,Y,N,N,N,N,N,N), + FCVT_D_W -> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,N,Y,N,N,N,N,N,Y), + FCVT_D_WU-> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,N,Y,N,N,N,N,N,Y), + FCVT_D_L -> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,N,Y,N,N,N,N,N,Y), + FCVT_D_LU-> List(FCMD_CVT_FI, N,Y,N,N,N,X,X,N,Y,N,N,N,N,N,Y), + FMV_X_D -> List(FCMD_MV_XF, N,N,Y,N,N,N,X,N,N,Y,N,N,N,N,N), + FCLASS_D -> List(FCMD_MV_XF, N,N,Y,N,N,N,X,N,N,Y,N,N,N,N,N), + FCVT_W_D -> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,N,N,Y,N,N,N,N,Y), + FCVT_WU_D-> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,N,N,Y,N,N,N,N,Y), + FCVT_L_D -> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,N,N,Y,N,N,N,N,Y), + FCVT_LU_D-> List(FCMD_CVT_IF, N,N,Y,N,N,N,X,N,N,Y,N,N,N,N,Y), + FCVT_S_D -> List(FCMD_CVT_FF, N,Y,Y,N,N,N,X,Y,N,N,Y,N,N,N,Y), + FCVT_D_S -> List(FCMD_CVT_FF, N,Y,Y,N,N,N,X,N,N,N,Y,N,N,N,Y), + FEQ_D -> List(FCMD_CMP, N,N,Y,Y,N,N,N,N,N,Y,N,N,N,N,Y), + FLT_D -> List(FCMD_CMP, N,N,Y,Y,N,N,N,N,N,Y,N,N,N,N,Y), + FLE_D -> List(FCMD_CMP, N,N,Y,Y,N,N,N,N,N,Y,N,N,N,N,Y), + FSGNJ_D -> List(FCMD_SGNJ, N,Y,Y,Y,N,N,N,N,N,N,Y,N,N,N,N), + FSGNJN_D -> List(FCMD_SGNJ, N,Y,Y,Y,N,N,N,N,N,N,Y,N,N,N,N), + FSGNJX_D -> List(FCMD_SGNJ, N,Y,Y,Y,N,N,N,N,N,N,Y,N,N,N,N), + FMIN_D -> List(FCMD_MINMAX, N,Y,Y,Y,N,N,N,N,N,N,Y,N,N,N,Y), + FMAX_D -> List(FCMD_MINMAX, N,Y,Y,Y,N,N,N,N,N,N,Y,N,N,N,Y), + FADD_D -> List(FCMD_ADD, N,Y,Y,Y,N,N,Y,N,N,N,N,Y,N,N,Y), + FSUB_D -> List(FCMD_SUB, N,Y,Y,Y,N,N,Y,N,N,N,N,Y,N,N,Y), + FMUL_D -> List(FCMD_MUL, N,Y,Y,Y,N,N,N,N,N,N,N,Y,N,N,Y), + FMADD_D -> List(FCMD_MADD, N,Y,Y,Y,Y,N,N,N,N,N,N,Y,N,N,Y), + FMSUB_D -> List(FCMD_MSUB, N,Y,Y,Y,Y,N,N,N,N,N,N,Y,N,N,Y), + FNMADD_D -> List(FCMD_NMADD, N,Y,Y,Y,Y,N,N,N,N,N,N,Y,N,N,Y), + FNMSUB_D -> List(FCMD_NMSUB, N,Y,Y,Y,Y,N,N,N,N,N,N,Y,N,N,Y), + FDIV_D -> List(FCMD_DIV, N,Y,Y,Y,N,N,N,N,N,N,N,N,Y,N,Y), + FSQRT_D -> List(FCMD_SQRT, N,Y,Y,N,N,Y,X,N,N,N,N,N,N,Y,Y)) val insns = fLen match { case 32 => f @@ -146,7 +145,7 @@ class FPUDecoder(implicit p: Parameters) extends FPUModule()(p) { val s = io.sigs val sigs = Seq(s.cmd, s.ldst, s.wen, s.ren1, s.ren2, s.ren3, s.swap12, s.swap23, s.single, s.fromint, s.toint, s.fastpipe, s.fma, - s.div, s.sqrt, s.round, s.wflags) + s.div, s.sqrt, s.wflags) sigs zip decoder map {case(s,d) => s := d} } @@ -710,7 +709,7 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) { io.sboard_clr := !wb_cp_valid && (divSqrt_wen || (wen(0) && useScoreboard(x => wbInfo(0).pipeid === UInt(x._2)))) io.sboard_clra := waddr // we don't currently support round-max-magnitude (rm=4) - io.illegal_rm := ex_rm(2) && ex_ctrl.round + io.illegal_rm := io.inst(14) && (io.inst(13,12) < 3 || io.fcsr_rm >= 4) divSqrt_wdata := 0 divSqrt_flags := 0 @@ -750,7 +749,7 @@ class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) { divSqrt_wdata := Mux(divSqrt_single, divSqrt_toSingle.io.out, divSqrt_wdata_double) divSqrt_flags := divSqrt_flags_double | Mux(divSqrt_single, divSqrt_toSingle.io.exceptionFlags, Bits(0)) } else { - when (ex_ctrl.div || ex_ctrl.sqrt) { io.illegal_rm := true } + when (id_ctrl.div || id_ctrl.sqrt) { io.illegal_rm := true } } }