commit 060814f540ae291544ee1f8270ceabaffd8987b5
parent b3d3da633d592003778447152ee01711c5db2014
Author: Bradley Gannon <bradley@bradleygannon.com>
Date: Sat, 29 Nov 2025 19:57:24 -0500
Implement Memory
Diffstat:
3 files changed, 62 insertions(+), 7 deletions(-)
diff --git a/src/main/scala/main.scala b/src/main/scala/main.scala
@@ -22,7 +22,7 @@ class Perilus extends Module {
val alu = Module(new Alu())
val controlUnit = Module(new ControlUnit())
val extendUnit = Module(new ExtendUnit())
- val memory = Module(new Memory())
+ val memory = Module(new Memory(1024, 32.W))
val registerFile = Module(new RegisterFile())
// TODO connect inputs and outputs
diff --git a/src/main/scala/memory.scala b/src/main/scala/memory.scala
@@ -1,16 +1,27 @@
package com.rinthyAi.perilus.memory
import chisel3._
+import chisel3.util.log2Ceil
-class Memory extends Module {
+class Memory(numWords: Int, width: Width) extends Module {
val io = IO(new Bundle {
- val address = Input(UInt(32.W))
- val writeData = Input(UInt(32.W))
+ val address = Input(UInt(width))
+ val writeData = Input(UInt(width))
val writeEnable = Input(Bool())
- val readData = Output(UInt(32.W))
+ val readData = Output(UInt(width))
})
- // TODO implement
- io.readData := 0.U
+ val memory = RegInit(VecInit(Seq.fill(numWords)(0.U(width))))
+
+ // this fixes warnings related to width being too high or low to index memory
+ // see https://www.chisel-lang.org/docs/cookbooks/cookbook#how-do-i-resolve-dynamic-index--is-too-widenarrow-for-extractee-
+ val correctWidth = log2Ceil(numWords)
+ val correctWidthAddress = io.address.pad(correctWidth)(correctWidth - 1, 0)
+
+ when(io.writeEnable) {
+ memory(correctWidthAddress) := io.writeData
+ }
+
+ io.readData := memory(correctWidthAddress)
}
diff --git a/src/test/scala/perilus/memory.scala b/src/test/scala/perilus/memory.scala
@@ -0,0 +1,44 @@
+import chisel3._
+import chisel3.simulator.scalatest.ChiselSim
+import org.scalatest.funspec.AnyFunSpec
+
+import com.rinthyAi.perilus.memory._
+
+class MemoryTests extends AnyFunSpec with ChiselSim {
+ describe("Memory") {
+ it("stores and retrieves data") {
+ simulate(new Memory(1024, 32.W)) { memory =>
+ {
+ val addr1 = "h12e".U
+ val addr2 = "h0d7".U
+ val data1 = "he7d857de".U
+ val data2 = "h38cc122f".U
+
+ memory.io.address.poke(addr1)
+ memory.io.writeData.poke(data1)
+ memory.io.writeEnable.poke(true.B)
+ memory.io.readData.expect(0.U)
+ memory.clock.step(1)
+ memory.io.readData.expect(data1)
+
+ memory.io.address.poke(addr2)
+ memory.io.writeData.poke(data2)
+ memory.io.writeEnable.poke(true.B)
+ memory.io.readData.expect(0.U)
+ memory.clock.step(1)
+ memory.io.readData.expect(data2)
+
+ memory.io.writeData.poke(0.U)
+ memory.io.writeEnable.poke(false.B)
+ memory.clock.step(1)
+ memory.io.address.poke(addr1)
+ memory.io.readData.expect(data1)
+ memory.io.address.poke(addr2)
+ memory.io.readData.expect(data2)
+ memory.io.address.poke(0.U)
+ memory.io.readData.expect(0.U)
+ }
+ }
+ }
+ }
+}