perilus

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

commit 1d79656fbee5a3f89cdef2bf54200038de6280e1
parent fe59fd001fad39f32451291684008c4331e40720
Author: Bradley Gannon <bradley@bradleygannon.com>
Date:   Mon, 30 Mar 2026 22:01:20 -0400

Add support for jalr

Diffstat:
Msrc/main/scala/controlUnit.scala | 21++++++++++++++++++++-
Msrc/test/scala/perilus/main.scala | 20++++++++++++++++----
2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/src/main/scala/controlUnit.scala b/src/main/scala/controlUnit.scala @@ -83,6 +83,8 @@ class ControlUnit(withDebug: Boolean = false) extends Module { state := ControlUnitState.executeI }.elsewhen(io.op === Opcode.jal) { state := ControlUnitState.jal + }.elsewhen(io.op === Opcode.jalr) { + state := ControlUnitState.jalrLink }.elsewhen(io.op === Opcode.branch) { state := ControlUnitState.branch }.elsewhen(io.op === Opcode.env || io.op === Opcode.fence) { @@ -143,6 +145,22 @@ class ControlUnit(withDebug: Boolean = false) extends Module { pcUpdate := true.B state := ControlUnitState.aluWb } + is(ControlUnitState.jalrLink) { + io.aluSrcA := AluSrcA.oldPc + io.aluSrcB := AluSrcB.four + io.resultSrc := ResultSrc.aluResult + io.regWrite := true.B + aluOp := AluOp.arithmetic + state := ControlUnitState.jalrJump + } + is(ControlUnitState.jalrJump) { + io.aluSrcA := AluSrcA.rd1 + io.aluSrcB := AluSrcB.immExt + io.resultSrc := ResultSrc.aluResult + aluOp := AluOp.arithmetic + pcUpdate := true.B + state := ControlUnitState.fetch + } is(ControlUnitState.branch) { io.aluSrcA := AluSrcA.rd1 io.aluSrcB := AluSrcB.rd2 @@ -251,7 +269,8 @@ class InstructionDecoder extends Module { } object ControlUnitState extends ChiselEnum { - val fetch, decode, memAdr, memRead, memWb, memWrite, executeR, aluWb, executeI, jal, branch = + val fetch, decode, memAdr, memRead, memWb, memWrite, executeR, aluWb, executeI, jal, jalrLink, + jalrJump, branch = Value } diff --git a/src/test/scala/perilus/main.scala b/src/test/scala/perilus/main.scala @@ -37,12 +37,14 @@ class PerilusTests extends AnyFunSpec with ChiselSim { rs1: Int, rs1Value: Int, imm: Int, - operation: (Int, Int) => Int + operation: (Int, Int) => Int, + pc: Int = 4, + opcode: Int = 19 ): Unit = { var registerFile = ArrayBuffer.fill(32)(0x00000000) registerFile(rs1) = rs1Value val memory = ArrayBuffer.fill(64)(0x00000000) - val instr = assembleIType(funct3, funct7_5, rd, rs1, rs1Value, imm, 19) + val instr = assembleIType(funct3, funct7_5, rd, rs1, rs1Value, imm, opcode) memory(0) = instr val expected = operation(rs1Value, imm) @@ -65,7 +67,7 @@ class PerilusTests extends AnyFunSpec with ChiselSim { perilusDebug.regData.expect(if (rs1 == rd) toULong(rs1Value) else 0) perilus.clock.step(4) - perilus.io.pc.expect(4) + perilus.io.pc.expect(toULong(pc)) perilusDebug.memAddr.poke(0) perilusDebug.memData.expect(toULong(instr)) @@ -273,7 +275,17 @@ class PerilusTests extends AnyFunSpec with ChiselSim { ) } it("jalr") { - cancel("Not yet implemented") + testIType( + funct3 = 0, + funct7_5 = false, + rd = 3, + rs1 = 8, + rs1Value = 32, + imm = 10, + operation = (_rs1, _imm) => 4, + pc = 42, + opcode = 103 + ) } } describe("executes U-type RV32I instructions") {