> configure(npc)
ysyx_22040000 李心杨 Linux calcite 6.6.19 #1-NixOS SMP PREEMPT_DYNAMIC Fri Mar 1 12:35:11 UTC 2024 x86_64 GNU/Linux 19:57:48 up 2 days 10:48, 2 users, load average: 1.32, 1.10, 0.90
This commit is contained in:
parent
f7f19ed102
commit
ee22c1541d
2 changed files with 60 additions and 26 deletions
|
@ -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 {
|
class RegisterFileCore[T <: Data](size: Int, tpe: T, numReadPorts: Int) extends Module {
|
||||||
printf("$numReadPorts\n")
|
|
||||||
require(numReadPorts >= 0)
|
require(numReadPorts >= 0)
|
||||||
val writePort = IO(new Bundle {
|
val writePort = IO(new Bundle {
|
||||||
val enable = Input(Bool())
|
val enable = Input(Bool())
|
||||||
val addr = Input(UInt(size.W))
|
val addr = Input(UInt(log2Ceil(size).W))
|
||||||
val data = Input(tpe)
|
val data = Input(tpe)
|
||||||
})
|
})
|
||||||
val readPorts = IO(Vec(numReadPorts, new Bundle {
|
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 data = Output(tpe)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// val regFile = RegInit(VecInit(Seq.fill(size)(0.U)))
|
val regFile = RegInit(VecInit(Seq.fill(size)(0.U(tpe.getWidth.W))))
|
||||||
// val writeAddrOH = UIntToOH(writePort.addr)
|
val writeAddrOH = UIntToOH(writePort.addr)
|
||||||
// for ((reg, i) <- regFile.zipWithIndex) {
|
for ((reg, i) <- regFile.zipWithIndex.tail) {
|
||||||
// reg := Mux(writeAddrOH(i) && writePort.enable, writePort.data, reg)
|
reg := Mux(writeAddrOH(i) && writePort.enable, writePort.data, reg)
|
||||||
// }
|
}
|
||||||
|
regFile(0) := 0.U
|
||||||
|
|
||||||
// for (readPort <- readPorts) {
|
for (readPort <- readPorts) {
|
||||||
// readPort.data := regFile(readPort.addr)
|
readPort.data := regFile(readPort.addr)
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object RegisterFile {
|
object RegisterFile {
|
||||||
def apply[T <: Data](size: Int, tpe: T, numReadPorts: Int, numWritePorts: Int): RegFileInterface[T] = {
|
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 _out = Wire(new RegFileInterface(size, tpe, numReadPorts, numWritePorts))
|
||||||
val clock = core.clock
|
val clock = core.clock
|
||||||
for (i <- 0 to numReadPorts) {
|
for (i <- 0 to numReadPorts) {
|
||||||
|
@ -67,6 +67,7 @@ object RegisterFile {
|
||||||
core.writePort.data := MuxLookup(_out.control.writeSelect, 0.U)(
|
core.writePort.data := MuxLookup(_out.control.writeSelect, 0.U)(
|
||||||
_out.control.WriteSelect.all.map(x => (x -> _out.data.write.data(x.asUInt).asUInt))
|
_out.control.WriteSelect.all.map(x => (x -> _out.data.write.data(x.asUInt).asUInt))
|
||||||
)
|
)
|
||||||
|
core.writePort.enable := _out.control.writeEnable
|
||||||
_out
|
_out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,24 +5,57 @@ import chiseltest._
|
||||||
import org.scalatest.freespec.AnyFreeSpec
|
import org.scalatest.freespec.AnyFreeSpec
|
||||||
import chiseltest.simulator.WriteVcdAnnotation
|
import chiseltest.simulator.WriteVcdAnnotation
|
||||||
|
|
||||||
import flowpc.components._
|
import chisel3.util.{SRAM}
|
||||||
|
|
||||||
|
import flowpc.components._
|
||||||
class RegisterFileSpec extends AnyFreeSpec with ChiselScalatestTester {
|
class RegisterFileSpec extends AnyFreeSpec with ChiselScalatestTester {
|
||||||
"RegisterFileCore" - {
|
"RegisterFileCore" - {
|
||||||
"(0) is always 0" - {
|
"register 0 is always 0" in {
|
||||||
// val reg = new RegisterFileCore(32, UInt(32.W), 2)
|
test(new RegisterFileCore(32, UInt(32.W), 2)) { c =>
|
||||||
test(new RegisterFileCore(32, UInt(32.W), 2)).withAnnotations(Seq(WriteVcdAnnotation)) { c =>
|
c.readPorts(0).addr.poke(0)
|
||||||
c.readPorts(0).addr.poke(0)
|
c.readPorts(1).addr.poke(0)
|
||||||
c.readPorts(1).addr.poke(0)
|
c.writePort.enable.poke(true)
|
||||||
c.writePort.enable.poke(true)
|
c.writePort.addr.poke(0)
|
||||||
c.writePort.addr.poke(0)
|
c.writePort.data.poke(0x1234)
|
||||||
c.writePort.data.poke(0xdeadbeef)
|
|
||||||
|
|
||||||
c.readPorts(0).data.expect(0)
|
c.readPorts(0).data.expect(0)
|
||||||
c.readPorts(1).data.expect(0)
|
c.readPorts(1).data.expect(0)
|
||||||
c.clock.step(1)
|
c.clock.step(2)
|
||||||
c.readPorts(0).data.expect(0)
|
c.readPorts(0).data.expect(0)
|
||||||
c.readPorts(1).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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue