commit 04a30bbe98c1ee6f8e97ac3dcacd54faf1dadedd
parent e73974f94f044a98ccf733852fd863c606e31e10
Author: Bradley Gannon <bradley@bradleygannon.com>
Date: Tue, 24 Feb 2026 21:11:22 -0500
Add NOP impls for environment instructions
Specifically ecall, ebreak, fence, fence.tso, and pause
Diffstat:
3 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/src/main/scala/controlUnit.scala b/src/main/scala/controlUnit.scala
@@ -71,6 +71,8 @@ class ControlUnit(withDebug: Boolean = false) extends Module {
state := ControlUnitState.jal
}.elsewhen(io.op === Opcode.branch) {
state := ControlUnitState.branch
+ }.elsewhen(io.op === Opcode.env || io.op === Opcode.fence) {
+ state := ControlUnitState.fetch
}
}
is(ControlUnitState.memAdr) {
@@ -231,6 +233,7 @@ object ControlUnitState extends ChiselEnum {
object Opcode extends ChiselEnum {
val load = Value("b0000011".U)
+ val fence = Value("b0001111".U)
val immediate = Value("b0010011".U)
val auipc = Value("b0010111".U)
val store = Value("b0100011".U)
diff --git a/src/main/scala/main.scala b/src/main/scala/main.scala
@@ -39,10 +39,15 @@ class Perilus(
val regData = Output(UInt(width))
val memAddr = Input(UInt(width))
val memData = Output(UInt(width))
+ val state = Output(ControlUnitState())
})
else None
})
+ val alu = Module(new Alu())
+ val controlUnit = Module(new ControlUnit(withDebug))
+ val extendUnit = Module(new ExtendUnit())
+
io.registerFile.io.debug.foreach(r => {
r.reg := 0.U
})
@@ -58,12 +63,11 @@ class Perilus(
m.memAddr := d.memAddr
d.memData := m.memData
})
+ controlUnit.io.debug.foreach(c => {
+ d.state := c.state
+ })
})
- val alu = Module(new Alu())
- val controlUnit = Module(new ControlUnit())
- val extendUnit = Module(new ExtendUnit())
-
val pc = RegInit(0.U(width))
val pcNext = WireDefault(UInt(width), 0.U)
when(controlUnit.io.pcWrite) {
diff --git a/src/test/scala/perilus/main.scala b/src/test/scala/perilus/main.scala
@@ -8,6 +8,7 @@ import scala.collection.mutable.ArrayBuffer
import com.rinthyAi.perilus.main._
import com.rinthyAi.perilus.test.utils.TestUtils.initMemFile
+import com.rinthyAi.perilus.controlUnit.ControlUnitState
class PerilusTests extends AnyFunSpec with ChiselSim {
describe("Perilus") {
@@ -386,6 +387,44 @@ class PerilusTests extends AnyFunSpec with ChiselSim {
cancel("Not yet implemented")
}
}
+ describe("skips environment instructions") {
+ def testNop(instruction: Int): Unit = {
+ var registerFile = ArrayBuffer.fill(32)(0x00000000)
+ var memory = ArrayBuffer.fill(64)(0x00000000)
+ memory(0) = instruction
+ simulate(
+ new Perilus(
+ initRegs = initMemFile(registerFile),
+ initMem = initMemFile(memory),
+ withDebug = true
+ )
+ ) { perilus =>
+ {
+ val perilusDebug = perilus.io.debug.get
+ perilus.io.pc.expect(0.U)
+ perilusDebug.state.expect(ControlUnitState.fetch)
+ perilus.clock.step(2)
+ perilus.io.pc.expect(4.U)
+ perilusDebug.state.expect(ControlUnitState.fetch)
+ }
+ }
+ }
+ it("ecall") {
+ testNop(0x00000073)
+ }
+ it("ebreak") {
+ testNop(0x00100073)
+ }
+ it("fence") {
+ testNop(0x0000000f)
+ }
+ it("fence.tso") {
+ testNop(0x8330000f)
+ }
+ it("pause") {
+ testNop(0x0100000f)
+ }
+ }
it("executes jal") {
var registerFile = ArrayBuffer.fill(32)(0x00000000)
var memory = ArrayBuffer.fill(64)(0x00000000)