From c4978712c9e14c049ac11134ade57c86bd861e0c Mon Sep 17 00:00:00 2001 From: Christopher Celio Date: Wed, 25 Oct 2017 13:58:26 -0700 Subject: [PATCH] csr: allow for superscalar decode (#1069) * CSR provides a decode port to check for an illegal instruction. * This commit now allows for multiple instructions in decode to get this illegal instruction information. * This commit leverages the existing decodeWidth parameter. This will potentially over-provision the number of decode ports needed for RVC-enabled cores. Closes #1068 --- src/main/scala/rocket/CSR.scala | 58 ++++++++++++++------------ src/main/scala/rocket/RocketCore.scala | 12 +++--- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index ab136f95..86ede45b 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -160,6 +160,16 @@ class TracedInstruction(implicit p: Parameters) extends CoreBundle { val tval = UInt(width = coreMaxAddrBits max iLen) } +class CSRDecodeIO extends 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) +} + class CSRFileIO(implicit p: Parameters) extends CoreBundle with HasCoreParameters { val interrupts = new TileInterrupts().asInput @@ -171,15 +181,7 @@ 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 decode = Vec(decodeWidth, new CSRDecodeIO) val csr_stall = Bool(OUTPUT) val eret = Bool(OUTPUT) @@ -453,24 +455,26 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param val insn_ret = system_insn && opcode(2) val insn_wfi = system_insn && opcode(5) - private def decodeAny(m: LinkedHashMap[Int,Bits]): Bool = m.map { case(k: Int, _: Bits) => io.decode.csr === k }.reduce(_||_) - val allow_wfi = Bool(!usingVM) || reg_mstatus.prv > PRV.S || !reg_mstatus.tw - val allow_sfence_vma = Bool(!usingVM) || reg_mstatus.prv > PRV.S || !reg_mstatus.tvm - val allow_sret = Bool(!usingVM) || reg_mstatus.prv > PRV.S || !reg_mstatus.tsr - 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 := reg_mstatus.prv < io.decode.csr(9,8) || - !decodeAny(read_mapping) || - io.decode.csr === CSRs.sptbr && !allow_sfence_vma || - (io.decode.csr.inRange(CSR.firstCtr, CSR.firstCtr + CSR.nCtr) || io.decode.csr.inRange(CSR.firstCtrH, CSR.firstCtrH + CSR.nCtr)) && reg_mstatus.prv <= PRV.S && hpm_mask(io.decode.csr(log2Ceil(CSR.firstCtr)-1,0)) || - Bool(usingDebug) && decodeAny(debug_csrs) && !reg_debug || - Bool(usingFPU) && decodeAny(fp_csrs) && 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 := reg_mstatus.prv < io.decode.csr(9,8) || - !io.decode.csr(5) && io.decode.csr(2) && !allow_wfi || - !io.decode.csr(5) && io.decode.csr(1) && !allow_sret || - io.decode.csr(5) && !allow_sfence_vma + for (io_dec <- io.decode) { + def decodeAny(m: LinkedHashMap[Int,Bits]): Bool = m.map { case(k: Int, _: Bits) => io_dec.csr === k }.reduce(_||_) + val allow_wfi = Bool(!usingVM) || reg_mstatus.prv > PRV.S || !reg_mstatus.tw + val allow_sfence_vma = Bool(!usingVM) || reg_mstatus.prv > PRV.S || !reg_mstatus.tvm + val allow_sret = Bool(!usingVM) || reg_mstatus.prv > PRV.S || !reg_mstatus.tsr + io_dec.fp_illegal := io.status.fs === 0 || !reg_misa('f'-'a') + io_dec.rocc_illegal := io.status.xs === 0 || !reg_misa('x'-'a') + io_dec.read_illegal := reg_mstatus.prv < io_dec.csr(9,8) || + !decodeAny(read_mapping) || + io_dec.csr === CSRs.sptbr && !allow_sfence_vma || + (io_dec.csr.inRange(CSR.firstCtr, CSR.firstCtr + CSR.nCtr) || io_dec.csr.inRange(CSR.firstCtrH, CSR.firstCtrH + CSR.nCtr)) && reg_mstatus.prv <= PRV.S && hpm_mask(io_dec.csr(log2Ceil(CSR.firstCtr)-1,0)) || + Bool(usingDebug) && decodeAny(debug_csrs) && !reg_debug || + Bool(usingFPU) && decodeAny(fp_csrs) && io_dec.fp_illegal + io_dec.write_illegal := io_dec.csr(11,10).andR + io_dec.write_flush := !(io_dec.csr >= CSRs.mscratch && io_dec.csr <= CSRs.mbadaddr || io_dec.csr >= CSRs.sscratch && io_dec.csr <= CSRs.sbadaddr) + io_dec.system_illegal := reg_mstatus.prv < io_dec.csr(9,8) || + !io_dec.csr(5) && io_dec.csr(2) && !allow_wfi || + !io_dec.csr(5) && io_dec.csr(1) && !allow_sret || + io_dec.csr(5) && !allow_sfence_vma + } val cause = Mux(insn_call, reg_mstatus.prv + Causes.user_ecall, diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index 7ac6b43d..ecf4c59c 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -200,17 +200,17 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) 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_sfence = id_ctrl.mem && id_ctrl.mem_cmd === M_SFENCE - val id_csr_flush = id_sfence || id_system_insn || (id_csr_en && !id_csr_ren && csr.io.decode.write_flush) + val id_csr_flush = id_sfence || id_system_insn || (id_csr_en && !id_csr_ren && csr.io.decode(0).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.decode.fp_illegal || io.fpu.illegal_rm) || + id_ctrl.fp && (csr.io.decode(0).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.decode.rocc_illegal || - id_csr_en && (csr.io.decode.read_illegal || !id_csr_ren && csr.io.decode.write_illegal) || - !ibuf.io.inst(0).bits.rvc && ((id_sfence || id_system_insn) && csr.io.decode.system_illegal) + id_ctrl.rocc && csr.io.decode(0).rocc_illegal || + id_csr_en && (csr.io.decode(0).read_illegal || !id_csr_ren && csr.io.decode(0).write_illegal) || + !ibuf.io.inst(0).bits.rvc && ((id_sfence || id_system_insn) && csr.io.decode(0).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) @@ -508,7 +508,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 := id_raw_inst(0)(31,20) + csr.io.decode(0).csr := id_raw_inst(0)(31,20) csr.io.exception := wb_xcpt csr.io.cause := wb_cause csr.io.retire := wb_valid