Scala 使用亮片获取亮片中的项目
我试图写一个高速缓存,所以我创建了一个Scala 使用亮片获取亮片中的项目,scala,chisel,Scala,Chisel,我试图写一个高速缓存,所以我创建了一个Seq,类型为Mem,因为我试图同时访问一组高速缓存中的所有元素 val metaMem = Seq.fill(nWays) (Mem((nSets), new MetaData)) 然后我想建立如下索引: metaMem(way).write(set, MD) 但是,因为在我的代码中,way是UInt,而seq只接受Int进行索引,这将导致编译错误。 有人对如何解决这个问题有什么建议吗? 非常感谢通常,要使用UInt中的动态值访问硬件元素,必须使
Seq
,类型为Mem
,因为我试图同时访问一组高速缓存中的所有元素
val metaMem = Seq.fill(nWays) (Mem((nSets), new MetaData))
然后我想建立如下索引:
metaMem(way).write(set, MD)
但是,因为在我的代码中,way是UInt
,而seq只接受Int
进行索引,这将导致编译错误。
有人对如何解决这个问题有什么建议吗?
非常感谢通常,要使用
UInt
中的动态值访问硬件元素,必须使用Vec
。在这种情况下,最简单的方法是使用vecint
创建Vec
,给定一个seq,它定义Vec
并连接元素
但是内存不是数据的子类(正如Vec
/vecint
所要求的那样)。
下面是一个非常简单的模块示例,它创建了一个内存库,并提供对内存的读/写访问
/** 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
}
}
}
}
下面是一个单元测试,可以演示如何使用这个模块
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")
}
}
}
}
}
class MemBankTest使用ScaleScalateTester扩展了FreeSpec{
“MemBankSimulation应该起作用”{
测试(新MemBank(banks=3,bankDepth=3)){dut=>
//将值写入内存
dut.isRead.poke(假B)
for(非常感谢您的回复。但是,它给了我一个错误:重载方法值apply with alternations(…)无法应用于(Seq[kiffe3.Mem[memory.cache.MetaData]]))嗯,看起来这个错误是因为Mem
不是数据的子类,我会更深入一点,看看在实践中是如何做到的。我已经更新了一些对内存有效的答案。我认为访问最后一个内存的最后一个元素有一个小问题,但调试foldLeft
st应该不难arts带有种子值。在这种情况下,我将种子作为when(false.B){}
传递,它返回WhenContext
foldLeft
调用我提供的函数,该函数使用两个参数,第一个参数是该函数计算的最后一个值(在第一次迭代中是种子),另一个参数是要迭代的列表中的下一个值,case(a,b)=>…
正是表达函数foldLeft
needs的方法该函数的每个调用调用调用上一个WhenContext
的elsewhen
方法,并返回一个新的WhenContext
用于下一个值。希望对您有所帮助