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.
This commit is contained in:
@@ -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
|
||||
|
Reference in New Issue
Block a user