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:
parent
897b686377
commit
c4978712c9
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user