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
用于下一个值。希望对您有所帮助