perilus

git clone https://git.bradleygannon.com/perilus.git
Log | Files | Refs | Submodules | README

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:
Msrc/main/scala/controlUnit.scala | 3+++
Msrc/main/scala/main.scala | 12++++++++----
Msrc/test/scala/perilus/main.scala | 39+++++++++++++++++++++++++++++++++++++++
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)