commit ed4fa0d20b16ab0b623fac80a43d2d24fd6acb9b
parent 19e57583faaf31adaec537c7c56993ca7d82c285
Author: mbbutler <m.brady.butler@gmail.com>
Date: Fri, 2 Jan 2026 16:08:37 -0500
beq test not working. need to check imm extender
Diffstat:
6 files changed, 211 insertions(+), 57 deletions(-)
diff --git a/assets/mem-beq-64x32.hex b/assets/mem-beq-64x32.hex
@@ -0,0 +1,64 @@
+02618563
+00930863
+5ee7809a
+947924f4
+fc24525a
+6c858974
+4996dd8c
+50415755
+b329e2c1
+99a84ca8
+ca029ae4
+a57954e9
+a7b0a4b1
+5f1c57ea
+bab5ee54
+e63aec6d
+7afaad60
+334c7d51
+bc83bea3
+63b83aab
+e1940fda
+4812b9fa
+7c224e0a
+305c08cc
+85e21635
+6e0cd50c
+d976069b
+f7f1ab0f
+24d8e524
+0f15069c
+1fa3eed3
+f73d90fa
+bd46aca5
+a519ad77
+70cd4ed3
+a722ba58
+cec41109
+9955f8a8
+ba5eb4f8
+cb32fd9d
+4f3fc791
+43bcbe26
+c1600d35
+0b5fc381
+dddfa0c3
+0331db73
+1e088fee
+9a0cdee4
+29580f62
+043925f7
+653647af
+d5e9eb13
+3e559887
+f098fa6f
+0f3f9400
+07163d81
+b37a3f8e
+0c11b791
+b3fa9fcf
+9d6ae141
+a34ef0d5
+3e850e1a
+2a410325
+8fce4057
diff --git a/assets/reg-beq-x32.hex b/assets/reg-beq-x32.hex
@@ -0,0 +1,32 @@
+00000000
+00000000
+00000000
+abcdef01
+00000000
+00000000
+abcde012
+00000000
+00000000
+abcde012
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
diff --git a/src/main/scala/alu.scala b/src/main/scala/alu.scala
@@ -15,6 +15,7 @@ class Alu extends Module {
switch(io.aluControl) {
is(AluControl.add) {
+ printf(cf"srcA = ${io.srcA}, srcB = ${io.srcB}\n")
io.aluResult := io.srcA + io.srcB
}
is(AluControl.sub) {
diff --git a/src/main/scala/controlUnit.scala b/src/main/scala/controlUnit.scala
@@ -46,6 +46,7 @@ class ControlUnit(withDebug: Boolean = false) extends Module {
io.resultSrc := ResultSrc.aluOutBuf
// Main FSM (Figure 7.45, page 436)
+ printf(cf"state = $state\n")
switch(state) {
is(ControlUnitState.fetch) {
io.adrSrc := false.B
diff --git a/src/main/scala/main.scala b/src/main/scala/main.scala
@@ -32,6 +32,7 @@ class Perilus(
val io = IO(new Bundle {
val memory = Module(new Memory(memorySizeWords, width, initMem, withDebug))
val registerFile = Module(new RegisterFile(width, initRegs, withDebug))
+ val pc = Output(UInt(width))
val debug =
if (withDebug) Some(new Bundle {
val reg = Input(UInt(5.W))
@@ -69,6 +70,8 @@ class Perilus(
pc := pcNext
}
+ io.pc := pc
+
val oldPc = RegInit(0.U(width))
when(controlUnit.io.irWrite) {
oldPc := pc
@@ -90,7 +93,10 @@ class Perilus(
val aluOutBuf = RegInit(0.U(width))
aluOutBuf := alu.io.aluResult
+ printf(cf"aluOutBuf = $aluOutBuf\n")
+
val result = WireDefault(0.U(width))
+ pcNext := result
switch(controlUnit.io.resultSrc) {
is(ResultSrc.aluOutBuf) {
result := aluOutBuf
@@ -151,6 +157,10 @@ class Perilus(
io.registerFile.io.a3 := instr(11, 7)
io.registerFile.io.writeData3 := result
io.registerFile.io.writeEnable3 := controlUnit.io.regWrite
+
+ printf("----\n")
+ printf(cf"pcNext = $pcNext\n")
+ printf(cf"pc = $pc\n")
}
object Perilus extends App {
diff --git a/src/test/scala/perilus/main.scala b/src/test/scala/perilus/main.scala
@@ -7,84 +7,130 @@ import com.rinthyAi.perilus.main._
class PerilusTests extends AnyFunSpec with ChiselSim {
describe("Perilus") {
- it("executes lw") {
- simulate(
- new Perilus(
- initRegs = System.getProperty("user.dir") + "/assets/reg-lw-x32.hex",
- initMem = System.getProperty("user.dir") + "/assets/mem-lw-64x32.hex",
- withDebug = true
- )
- ) { perilus =>
- {
- val perilusDebug = perilus.io.debug.get
+ // it("executes lw") {
+ // simulate(
+ // new Perilus(
+ // initRegs = System.getProperty("user.dir") + "/assets/reg-lw-x32.hex",
+ // initMem = System.getProperty("user.dir") + "/assets/mem-lw-64x32.hex",
+ // withDebug = true
+ // )
+ // ) { perilus =>
+ // {
+ // val perilusDebug = perilus.io.debug.get
- // lw x21, 0x2a(x11)
- val rd = 21
- val rs1 = 11
- val base = 0xc
- val imm = 0x2a
- val memAddr = (base + imm).U
- val memData = 0x0f3f9400
+ // // lw x21, 0x2a(x11)
+ // val rd = 21
+ // val rs1 = 11
+ // val base = 0xc
+ // val imm = 0x2a
+ // val memAddr = (base + imm).U
+ // val memData = 0x0f3f9400
- // rs1 contains the base pointer
- perilusDebug.reg.poke(rs1)
- perilusDebug.regData.expect(base)
+ // // rs1 contains the base pointer
+ // perilusDebug.reg.poke(rs1)
+ // perilusDebug.regData.expect(base)
- // rd is empty
- perilusDebug.reg.poke(rd)
- perilusDebug.regData.expect(0.U)
+ // // rd is empty
+ // perilusDebug.reg.poke(rd)
+ // perilusDebug.regData.expect(0.U)
- // memAddr contains memData
- perilusDebug.memAddr.poke(memAddr)
- perilusDebug.memData.expect(memData)
+ // // memAddr contains memData
+ // perilusDebug.memAddr.poke(memAddr)
+ // perilusDebug.memData.expect(memData)
- // execute the instruction
- perilus.clock.step(6)
+ // // execute the instruction
+ // perilus.clock.step(6)
- // rd contains memData
- perilusDebug.reg.poke(rd)
- perilusDebug.regData.expect(memData)
+ // // rd contains memData
+ // perilusDebug.reg.poke(rd)
+ // perilusDebug.regData.expect(memData)
- // contents of memAddr have not changed
- perilusDebug.memAddr.poke(memAddr)
- perilusDebug.memData.expect(memData)
- }
- }
- }
- it("executes sw") {
+ // // contents of memAddr have not changed
+ // perilusDebug.memAddr.poke(memAddr)
+ // perilusDebug.memData.expect(memData)
+ // }
+ // }
+ // }
+ // it("executes sw") {
+ // simulate(
+ // new Perilus(
+ // initRegs = System.getProperty("user.dir") + "/assets/reg-sw-x32.hex",
+ // initMem = System.getProperty("user.dir") + "/assets/mem-sw-64x32.hex",
+ // withDebug = true
+ // )
+ // ) { perilus =>
+ // {
+ // val perilusDebug = perilus.io.debug.get
+
+ // // sw x6, -4(x9)
+ // // sw rs2, imm(rs1)
+ // val rs2 = 6
+ // val rs1 = 9
+ // val base = 0x3a
+ // val imm = -4
+ // val memAddr = (base + imm).U
+ // val memData = 0x01830169
+
+ // // rs1 contains the base pointer
+ // perilusDebug.reg.poke(rs1)
+ // perilusDebug.regData.expect(base)
+
+ // // rs2 contains data to be stored
+ // perilusDebug.reg.poke(rs2)
+ // perilusDebug.regData.expect(memData)
+
+ // // execute the instruction
+ // perilus.clock.step(5)
+
+ // // contents of memAddr have not changed
+ // perilusDebug.memAddr.poke(memAddr)
+ // perilusDebug.memData.expect(memData)
+ // }
+ // }
+ // }
+ it("executes beq") {
simulate(
new Perilus(
- initRegs = System.getProperty("user.dir") + "/assets/reg-sw-x32.hex",
- initMem = System.getProperty("user.dir") + "/assets/mem-sw-64x32.hex",
+ initRegs = System.getProperty("user.dir") + "/assets/reg-beq-x32.hex",
+ initMem = System.getProperty("user.dir") + "/assets/mem-beq-64x32.hex",
withDebug = true
)
) { perilus =>
{
val perilusDebug = perilus.io.debug.get
- // sw x6, -4(x9)
- // sw rs2, imm(rs1)
+ val rs1 = 3
val rs2 = 6
- val rs1 = 9
- val base = 0x3a
- val imm = -4
- val memAddr = (base + imm).U
- val memData = 0x01830169
+ val rs3 = 9
+ val offset = 16.U
- // rs1 contains the base pointer
+ // Verify that registers are/aren't equal as expected
perilusDebug.reg.poke(rs1)
- perilusDebug.regData.expect(base)
-
- // rs2 contains data to be stored
+ val rs1_t = perilusDebug.regData.peek()
perilusDebug.reg.poke(rs2)
- perilusDebug.regData.expect(memData)
+ val rs2_t = perilusDebug.regData.peek()
+ perilusDebug.reg.poke(rs3)
+ val rs3_t = perilusDebug.regData.peek()
+ assert(rs1_t.litValue != rs2_t.litValue)
+ assert(rs2_t.litValue == rs3_t.litValue)
+
+ var pc_t = perilus.io.pc.peek()
+ // execute the first beq instruction:fe64ae23
+ // beq x3, x6, 0x4
+ perilus.clock.step(4)
+
+ // pc should be at address 1 because x3 != x6
+ val expected_1 = pc_t.litValue + 4
+ // perilus.io.pc.expect(expected_1.U)
+ pc_t = perilus.io.pc.peek()
- // execute the instruction
- perilus.clock.step(5)
+ // execute the second beq instruction:
+ // beq x6, x9, 0x4
+ perilus.clock.step(4)
- // contents of memAddr have not changed
- perilusDebug.memAddr.poke(memAddr)
- perilusDebug.memData.expect(memData)
+ // pc should be at address 5 because x6 == x9
+ val expected_2 = pc_t.litValue + offset.litValue
+ // perilus.io.pc.expect(expected_2.U)
}
}
}