Express operating mode as an enum
- Previously, the machine vs. user mode was represented as a Bool --
convert this to a ChiselEnum, both for readability and potential
extension in the future.
Change-Id: I94387b4158385051a660924a3c766abacbf02f19
diff --git a/hdl/chisel/src/kelvin/scalar/Bru.scala b/hdl/chisel/src/kelvin/scalar/Bru.scala
index f76f257..bc4e7b4 100644
--- a/hdl/chisel/src/kelvin/scalar/Bru.scala
+++ b/hdl/chisel/src/kelvin/scalar/Bru.scala
@@ -105,13 +105,13 @@
io.interlock := interlock
// Assign state
- val mode = io.csr.out.mode // (0) machine, (1) user
+ val mode = io.csr.out.mode
val pcDe = io.req.bits.pc
val pc4De = io.req.bits.pc + 4.U
- val mret = (io.req.bits.op === BruOp.MRET) && !mode
- val call = ((io.req.bits.op === BruOp.MRET) && mode) ||
+ val mret = (io.req.bits.op === BruOp.MRET) && mode === CsrMode.Machine
+ val call = ((io.req.bits.op === BruOp.MRET) && mode === CsrMode.User) ||
io.req.bits.op.isOneOf(BruOp.EBREAK, BruOp.ECALL, BruOp.EEXIT,
BruOp.EYIELD, BruOp.ECTXSW, BruOp.MPAUSE)
@@ -152,13 +152,13 @@
val op = stateReg.bits.op
io.taken.valid := stateReg.valid && MuxLookup(op, false.B)(Seq(
- BruOp.EBREAK -> mode,
- BruOp.ECALL -> mode,
- BruOp.EEXIT -> mode,
- BruOp.EYIELD -> mode,
- BruOp.ECTXSW -> mode,
- BruOp.MPAUSE -> mode, // fault
- BruOp.MRET -> true.B, // fault if user mode.
+ BruOp.EBREAK -> (mode === CsrMode.User),
+ BruOp.ECALL -> (mode === CsrMode.User),
+ BruOp.EEXIT -> (mode === CsrMode.User),
+ BruOp.EYIELD -> (mode === CsrMode.User),
+ BruOp.ECTXSW -> (mode === CsrMode.User),
+ BruOp.MPAUSE -> (mode === CsrMode.User),
+ BruOp.MRET -> (mode === CsrMode.Machine),
BruOp.FENCEI -> true.B,
BruOp.JAL -> (true.B =/= stateReg.bits.fwd),
BruOp.JALR -> (true.B =/= stateReg.bits.fwd),
@@ -180,24 +180,25 @@
// Usage Fault.
val usageFault = stateReg.valid && Mux(
- mode, op.isOneOf(BruOp.MPAUSE, BruOp.MRET),
+ (mode === CsrMode.User),
+ op.isOneOf(BruOp.MPAUSE, BruOp.MRET),
op.isOneOf(BruOp.EBREAK, BruOp.ECALL, BruOp.EEXIT, BruOp.EYIELD,
BruOp.ECTXSW))
io.csr.in.mode.valid := stateReg.valid && Mux(
- mode, op.isOneOf(BruOp.EBREAK, BruOp.ECALL, BruOp.EEXIT, BruOp.EYIELD,
+ (mode === CsrMode.User), op.isOneOf(BruOp.EBREAK, BruOp.ECALL, BruOp.EEXIT, BruOp.EYIELD,
BruOp.ECTXSW, BruOp.MPAUSE, BruOp.MRET),
(op === BruOp.MRET))
- io.csr.in.mode.bits := ((op === BruOp.MRET) && !mode)
+ io.csr.in.mode.bits := Mux(((op === BruOp.MRET) && (mode === CsrMode.Machine)), CsrMode.Machine, CsrMode.User)
- io.csr.in.mepc.valid := stateReg.valid && mode &&
+ io.csr.in.mepc.valid := stateReg.valid && (mode === CsrMode.User) &&
op.isOneOf(BruOp.EBREAK, BruOp.ECALL, BruOp.EEXIT, BruOp.EYIELD,
BruOp.ECTXSW, BruOp.MPAUSE, BruOp.MRET)
io.csr.in.mepc.bits := Mux(op === BruOp.EYIELD, stateReg.bits.linkData,
stateReg.bits.pcEx)
io.csr.in.mcause.valid := stateReg.valid && (undefFault || usageFault ||
- (mode && op.isOneOf(BruOp.EBREAK, BruOp.ECALL, BruOp.EEXIT, BruOp.EYIELD,
+ ((mode === CsrMode.User) && op.isOneOf(BruOp.EBREAK, BruOp.ECALL, BruOp.EEXIT, BruOp.EYIELD,
BruOp.ECTXSW)))
val faultMsb = 1.U << 31
@@ -217,9 +218,9 @@
io.iflush := stateReg.valid && (op === BruOp.FENCEI)
// Pipeline will be halted.
- io.csr.in.halt := (stateReg.valid && (op === BruOp.MPAUSE) && !mode) ||
+ io.csr.in.halt := (stateReg.valid && (op === BruOp.MPAUSE) && (mode === CsrMode.Machine)) ||
io.csr.in.fault
- io.csr.in.fault := (undefFault && !mode) || (usageFault && !mode)
+ io.csr.in.fault := (undefFault && (mode === CsrMode.Machine)) || (usageFault && (mode === CsrMode.Machine))
// Assertions.
val ignore = op.isOneOf(BruOp.JAL, BruOp.JALR, BruOp.EBREAK, BruOp.ECALL,
diff --git a/hdl/chisel/src/kelvin/scalar/Csr.scala b/hdl/chisel/src/kelvin/scalar/Csr.scala
index 6db1af5..465c57b 100644
--- a/hdl/chisel/src/kelvin/scalar/Csr.scala
+++ b/hdl/chisel/src/kelvin/scalar/Csr.scala
@@ -30,6 +30,11 @@
val CSRRC = Value
}
+object CsrMode extends ChiselEnum {
+ val Machine = Value(0.U(1.W))
+ val User = Value(1.U(1.W))
+}
+
class CsrInIO(p: Parameters) extends Bundle {
val value = Input(Vec(12, UInt(32.W)))
}
@@ -57,7 +62,7 @@
class CsrBruIO(p: Parameters) extends Bundle {
val in = new Bundle {
- val mode = Valid(Bool())
+ val mode = Valid(CsrMode())
val mcause = Valid(UInt(32.W))
val mepc = Valid(UInt(32.W))
val mtval = Valid(UInt(32.W))
@@ -65,12 +70,12 @@
val fault = Output(Bool())
}
val out = new Bundle {
- val mode = Input(Bool())
+ val mode = Input(CsrMode())
val mepc = Input(UInt(32.W))
val mtvec = Input(UInt(32.W))
}
def defaults() = {
- out.mode := false.B
+ out.mode := CsrMode.Machine
out.mepc := 0.U
out.mtvec := 0.U
}
@@ -115,7 +120,7 @@
val fault = RegInit(false.B)
// Machine(0)/User(1) Mode.
- val mode = RegInit(false.B)
+ val mode = RegInit(CsrMode.Machine)
// CSRs parallel loaded when(reset).
val mpc = Reg(UInt(32.W))