Skip to content

Commit

Permalink
Merge pull request #3613 from OpenXiangShan/illegal_rvc
Browse files Browse the repository at this point in the history
Add illegal instruction detection to RVC decoder
  • Loading branch information
jerryz123 committed Apr 23, 2024
2 parents 87b3a4d + c8eb0ee commit d8de943
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/main/scala/rocket/Frontend.scala
Expand Up @@ -243,7 +243,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
val rvcBranch = bits === Instructions.C_BEQZ || bits === Instructions.C_BNEZ
val rvcJAL = (xLen == 32).B && bits === Instructions32.C_JAL
val rvcJump = bits === Instructions.C_J || rvcJAL
val rvcImm = Mux(bits(14), new RVCDecoder(bits, xLen).bImm.asSInt, new RVCDecoder(bits, xLen).jImm.asSInt)
val rvcImm = Mux(bits(14), new RVCDecoder(bits, xLen, fLen).bImm.asSInt, new RVCDecoder(bits, xLen, fLen).jImm.asSInt)
val rvcJR = bits === Instructions.C_MV && bits(6,2) === 0.U
val rvcReturn = rvcJR && BitPat("b00?01") === bits(11,7)
val rvcJALR = bits === Instructions.C_ADD && bits(6,2) === 0.U
Expand Down
42 changes: 39 additions & 3 deletions src/main/scala/rocket/RVC.scala
Expand Up @@ -16,7 +16,7 @@ class ExpandedInstruction extends Bundle {
val rs3 = UInt(5.W)
}

class RVCDecoder(x: UInt, xLen: Int, useAddiForMv: Boolean = false) {
class RVCDecoder(x: UInt, xLen: Int, fLen: Int, useAddiForMv: Boolean = false) {
def inst(bits: UInt, rd: UInt = x(11,7), rs1: UInt = x(19,15), rs2: UInt = x(24,20), rs3: UInt = x(31,27)) = {
val res = Wire(new ExpandedInstruction)
res.bits := bits
Expand Down Expand Up @@ -153,20 +153,56 @@ class RVCDecoder(x: UInt, xLen: Int, useAddiForMv: Boolean = false) {
val s = q0 ++ q1 ++ q2 ++ q3
s(Cat(x(1,0), x(15,13)))
}

def q0_ill = {
def allz = !(x(12, 2).orR)
def fld = if (fLen >= 64) false.B else true.B
def flw32 = if (xLen == 64 || fLen >= 32) false.B else true.B
def fsd = if (fLen >= 64) false.B else true.B
def fsw32 = if (xLen == 64 || fLen >= 32) false.B else true.B
Seq(allz, fld, false.B, flw32, true.B, fsd, false.B, fsw32)
}

def q1_ill = {
def rd0 = if (xLen == 32) false.B else rd === 0.U
def immz = !(x(12) | x(6, 2).orR)
def arith_res = x(12, 10).andR && (if (xLen == 32) true.B else x(6) === 1.U)
Seq(false.B, rd0, false.B, immz, arith_res, false.B, false.B, false.B)
}

def q2_ill = {
def fldsp = if (fLen >= 64) false.B else true.B
def rd0 = rd === 0.U
def flwsp = if (xLen == 64) rd0 else if (fLen >= 32) false.B else true.B
def jr_res = !(x(12 ,2).orR)
def fsdsp = if (fLen >= 64) false.B else true.B
def fswsp32 = if (xLen == 64) false.B else if (fLen >= 32) false.B else true.B
Seq(false.B, fldsp, rd0, flwsp, jr_res, fsdsp, false.B, fswsp32)
}
def q3_ill = Seq.fill(8)(false.B)

def ill = {
val s = q0_ill ++ q1_ill ++ q2_ill ++ q3_ill
s(Cat(x(1,0), x(15,13)))
}
}

class RVCExpander(useAddiForMv: Boolean = false)(implicit val p: Parameters) extends Module with HasCoreParameters {
val io = IO(new Bundle {
val in = Input(UInt(32.W))
val out = Output(new ExpandedInstruction)
val rvc = Output(Bool())
val ill = Output(Bool())
})

if (usingCompressed) {
io.rvc := io.in(1,0) =/= 3.U
io.out := new RVCDecoder(io.in, p(XLen), useAddiForMv).decode
val decoder = new RVCDecoder(io.in, p(XLen), fLen, useAddiForMv)
io.out := decoder.decode
io.ill := decoder.ill
} else {
io.rvc := false.B
io.out := new RVCDecoder(io.in, p(XLen), useAddiForMv).passthrough
io.out := new RVCDecoder(io.in, p(XLen), fLen, useAddiForMv).passthrough
io.ill := false.B // only used for RVC
}
}

0 comments on commit d8de943

Please sign in to comment.