我正在尝试编写一个缓存内存,所以我创建了一个Seq类型,Mem因为我试图同时访问一组缓存中的所有元素。
val metaMem = Seq.fill(nWays) (Mem((nSets), new MetaData))
Run Code Online (Sandbox Code Playgroud)
然后我想有如下索引:
metaMem(way).write(set, MD)
Run Code Online (Sandbox Code Playgroud)
但是,因为方式UInt在我的代码中,并且 seq 只接受Int索引,所以会导致编译错误。有没有人对如何解决这个问题有任何建议?非常感谢
通常要使用 a 中的动态值访问硬件元素,UInt您必须使用Vec. 在这种情况下,最简单的方法是Vec使用VecInitwhich创建 a ,给定一个 seq,定义Vec和连接您的元素。
但是Memories 不是 Data 的子类(正如Vec/所要求的那样VecInit)。这是一个简单模块的非常简单的示例,它创建了一组内存并提供对它们的读/写访问。
/** Simulate a VecLike bank of memories
*/
class MemBank(val banks: Int, val bankDepth: Int) extends MultiIOModule {
val bank = IO(Input(UInt(16.W)))
val address = IO(Input(UInt(16.W)))
val isRead = IO(Input(Bool()))
val inputValue = IO(Input(UInt(32.W)))
val outputValue = IO(Output(UInt(32.W)))
val mems = Seq.fill(banks) { Mem(bankDepth, UInt(32.W)) }
outputValue := DontCare
when(isRead) {
(0 until banks).foldLeft(when(false.B) {}) {
case (whenContext, bankIndex) =>
whenContext.elsewhen(bank === bankIndex.U) {
outputValue := mems(bankIndex)(address)
}
}
}.otherwise {
(0 until banks).foldLeft(when(false.B) {}) {
case (whenContext, bankIndex) =>
whenContext.elsewhen(bank === bankIndex.U) {
mems(bankIndex)(address) := inputValue
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个可以演示使用此模块的 UnitTest
class MemBankTest extends FreeSpec with ChiselScalatestTester {
"MemBankSimulation should work" in {
test(new MemBank(banks = 3, bankDepth = 3)) { dut =>
// write values into memory
dut.isRead.poke(false.B)
for (bank <- 0 until dut.banks) {
for (address <- 0 until dut.bankDepth) {
dut.clock.step()
dut.bank.poke(bank.U)
dut.address.poke(address.U)
dut.inputValue.poke((bank * 1000 + address).U)
}
}
// read values out of memory banks
dut.isRead.poke(true.B)
for (bank <- 0 until dut.banks) {
for (address <- 0 until dut.bankDepth) {
dut.clock.step()
dut.bank.poke(bank.U)
dut.address.poke(address.U)
println(f"Bank $bank%3d at address $address%3d contains ${dut.outputValue.peek().litValue()}%6d")
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
有很多其他方法可以做到这一点,我鼓励您查看其他凿子项目,如火箭芯片,以了解如何处理多个记忆。看看这种方法是如何工作的仍然很好。它创建了一个SeqofMem但它使用 foldLeft(一个非常有用的方法)来创建一组Mux选择您感兴趣的银行的es。它有两个并行的用途来分别控制读取和写入。我希望这会有所帮助,这是一个很好而棘手的问题。