1
0

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
This commit is contained in:
Christopher Celio 2017-10-25 13:58:26 -07:00 committed by GitHub
parent 897b686377
commit c4978712c9
2 changed files with 37 additions and 33 deletions

View File

@ -160,6 +160,16 @@ class TracedInstruction(implicit p: Parameters) extends CoreBundle {
val tval = UInt(width = coreMaxAddrBits max iLen) 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 class CSRFileIO(implicit p: Parameters) extends CoreBundle
with HasCoreParameters { with HasCoreParameters {
val interrupts = new TileInterrupts().asInput val interrupts = new TileInterrupts().asInput
@ -171,15 +181,7 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle
val wdata = Bits(INPUT, xLen) val wdata = Bits(INPUT, xLen)
} }
val decode = new Bundle { val decode = Vec(decodeWidth, new CSRDecodeIO)
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_stall = Bool(OUTPUT)
val eret = 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_ret = system_insn && opcode(2)
val insn_wfi = system_insn && opcode(5) 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(_||_) 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_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_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 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_dec.fp_illegal := io.status.fs === 0 || !reg_misa('f'-'a')
io.decode.rocc_illegal := io.status.xs === 0 || !reg_misa('x'-'a') io_dec.rocc_illegal := io.status.xs === 0 || !reg_misa('x'-'a')
io.decode.read_illegal := reg_mstatus.prv < io.decode.csr(9,8) || io_dec.read_illegal := reg_mstatus.prv < io_dec.csr(9,8) ||
!decodeAny(read_mapping) || !decodeAny(read_mapping) ||
io.decode.csr === CSRs.sptbr && !allow_sfence_vma || io_dec.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)) || (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(usingDebug) && decodeAny(debug_csrs) && !reg_debug ||
Bool(usingFPU) && decodeAny(fp_csrs) && io.decode.fp_illegal Bool(usingFPU) && decodeAny(fp_csrs) && io_dec.fp_illegal
io.decode.write_illegal := io.decode.csr(11,10).andR io_dec.write_illegal := io_dec.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_dec.write_flush := !(io_dec.csr >= CSRs.mscratch && io_dec.csr <= CSRs.mbadaddr || io_dec.csr >= CSRs.sscratch && io_dec.csr <= CSRs.sbadaddr)
io.decode.system_illegal := reg_mstatus.prv < io.decode.csr(9,8) || io_dec.system_illegal := reg_mstatus.prv < io_dec.csr(9,8) ||
!io.decode.csr(5) && io.decode.csr(2) && !allow_wfi || !io_dec.csr(5) && io_dec.csr(2) && !allow_wfi ||
!io.decode.csr(5) && io.decode.csr(1) && !allow_sret || !io_dec.csr(5) && io_dec.csr(1) && !allow_sret ||
io.decode.csr(5) && !allow_sfence_vma io_dec.csr(5) && !allow_sfence_vma
}
val cause = val cause =
Mux(insn_call, reg_mstatus.prv + Causes.user_ecall, Mux(insn_call, reg_mstatus.prv + Causes.user_ecall,

View File

@ -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_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 = Mux(id_csr_ren, CSR.R, id_ctrl.csr)
val id_sfence = id_ctrl.mem && id_ctrl.mem_cmd === M_SFENCE 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 || val id_illegal_insn = !id_ctrl.legal ||
id_ctrl.div && !csr.io.status.isa('m'-'a') || id_ctrl.div && !csr.io.status.isa('m'-'a') ||
id_ctrl.amo && !csr.io.status.isa('a'-'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') || id_ctrl.dp && !csr.io.status.isa('d'-'a') ||
ibuf.io.inst(0).bits.rvc && !csr.io.status.isa('c'-'a') || ibuf.io.inst(0).bits.rvc && !csr.io.status.isa('c'-'a') ||
id_ctrl.rocc && csr.io.decode.rocc_illegal || id_ctrl.rocc && csr.io.decode(0).rocc_illegal ||
id_csr_en && (csr.io.decode.read_illegal || !id_csr_ren && csr.io.decode.write_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.system_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) // 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_aq = id_inst(0)(26)
val id_amo_rl = id_inst(0)(25) 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) } when (rf_wen) { rf.write(rf_waddr, rf_wdata) }
// hook up control/status regfile // 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.exception := wb_xcpt
csr.io.cause := wb_cause csr.io.cause := wb_cause
csr.io.retire := wb_valid csr.io.retire := wb_valid