diff --git a/npc/core/src/main/scala/RegisterFile.scala b/npc/core/src/main/scala/RegisterFile.scala index bcfb2c0..d100344 100644 --- a/npc/core/src/main/scala/RegisterFile.scala +++ b/npc/core/src/main/scala/RegisterFile.scala @@ -31,32 +31,32 @@ class RegFileInterface[T <: Data](size: Int, tpe: T, numReadPorts: Int, numWrite } class RegisterFileCore[T <: Data](size: Int, tpe: T, numReadPorts: Int) extends Module { - printf("$numReadPorts\n") require(numReadPorts >= 0) val writePort = IO(new Bundle { val enable = Input(Bool()) - val addr = Input(UInt(size.W)) + val addr = Input(UInt(log2Ceil(size).W)) val data = Input(tpe) }) val readPorts = IO(Vec(numReadPorts, new Bundle { - val addr = Input(UInt(size.W)) + val addr = Input(UInt(log2Ceil(size).W)) val data = Output(tpe) })) - // val regFile = RegInit(VecInit(Seq.fill(size)(0.U))) - // val writeAddrOH = UIntToOH(writePort.addr) - // for ((reg, i) <- regFile.zipWithIndex) { - // reg := Mux(writeAddrOH(i) && writePort.enable, writePort.data, reg) - // } + val regFile = RegInit(VecInit(Seq.fill(size)(0.U(tpe.getWidth.W)))) + val writeAddrOH = UIntToOH(writePort.addr) + for ((reg, i) <- regFile.zipWithIndex.tail) { + reg := Mux(writeAddrOH(i) && writePort.enable, writePort.data, reg) + } + regFile(0) := 0.U - // for (readPort <- readPorts) { - // readPort.data := regFile(readPort.addr) - // } + for (readPort <- readPorts) { + readPort.data := regFile(readPort.addr) + } } object RegisterFile { def apply[T <: Data](size: Int, tpe: T, numReadPorts: Int, numWritePorts: Int): RegFileInterface[T] = { - val core = new RegisterFileCore(size, tpe, numReadPorts) + val core = Module(new RegisterFileCore(size, tpe, numReadPorts)) val _out = Wire(new RegFileInterface(size, tpe, numReadPorts, numWritePorts)) val clock = core.clock for (i <- 0 to numReadPorts) { @@ -67,6 +67,7 @@ object RegisterFile { core.writePort.data := MuxLookup(_out.control.writeSelect, 0.U)( _out.control.WriteSelect.all.map(x => (x -> _out.data.write.data(x.asUInt).asUInt)) ) + core.writePort.enable := _out.control.writeEnable _out } } diff --git a/npc/core/src/test/scala/RegisterFile.scala b/npc/core/src/test/scala/RegisterFile.scala index d7f5825..9308838 100644 --- a/npc/core/src/test/scala/RegisterFile.scala +++ b/npc/core/src/test/scala/RegisterFile.scala @@ -5,24 +5,57 @@ import chiseltest._ import org.scalatest.freespec.AnyFreeSpec import chiseltest.simulator.WriteVcdAnnotation -import flowpc.components._ +import chisel3.util.{SRAM} +import flowpc.components._ class RegisterFileSpec extends AnyFreeSpec with ChiselScalatestTester { "RegisterFileCore" - { - "(0) is always 0" - { - // val reg = new RegisterFileCore(32, UInt(32.W), 2) - test(new RegisterFileCore(32, UInt(32.W), 2)).withAnnotations(Seq(WriteVcdAnnotation)) { c => - c.readPorts(0).addr.poke(0) - c.readPorts(1).addr.poke(0) - c.writePort.enable.poke(true) - c.writePort.addr.poke(0) - c.writePort.data.poke(0xdeadbeef) + "register 0 is always 0" in { + test(new RegisterFileCore(32, UInt(32.W), 2)) { c => + c.readPorts(0).addr.poke(0) + c.readPorts(1).addr.poke(0) + c.writePort.enable.poke(true) + c.writePort.addr.poke(0) + c.writePort.data.poke(0x1234) - c.readPorts(0).data.expect(0) - c.readPorts(1).data.expect(0) - c.clock.step(1) - c.readPorts(0).data.expect(0) - c.readPorts(1).data.expect(0) + c.readPorts(0).data.expect(0) + c.readPorts(1).data.expect(0) + c.clock.step(2) + c.readPorts(0).data.expect(0) + c.readPorts(1).data.expect(0) + } + } + "register other than 0 can be written" in { + test(new RegisterFileCore(32, UInt(32.W), 2)) { c => + import scala.util.Random + val r = new Random() + for (i <- 1 until 32) { + val v = r.nextLong() & 0xFFFFFFFFL + c.readPorts(0).addr.poke(i) + c.writePort.enable.poke(true) + c.writePort.addr.poke(i) + c.writePort.data.poke(v) + + c.clock.step(1) + c.readPorts(0).data.expect(v) + } + } + } + } + "RegisterInterface" - { + class Top extends Module { + val io = RegisterFile(32, UInt(32.W), 2, 2) + } + "worked" in { + test(new Top) { c => + // import c.io.control.WriteSelect._ + // c.io.control.writeEnable.poke(true) + // c.io.control.writeSelect.poke(rAluOut) + // c.io.data.write.addr.poke(1) + // c.io.data.write.data(rAluOut.asUInt).poke(0xcdef) + // c.io.data.read(0).rs.poke(1) + // c.clock.step(1) + // c.io.data.read(0).src.expect(0xcdef) } } }