Как сгенерировать случайный Scala Int в коде Chisel?

Я пытаюсь реализовать технику прогнозирования пути в ядре RocketChip (по порядку). Для этого мне нужно получить доступ в каждую сторону отдельно. Вот так выглядит SRAM для тегов после модификации (отдельная SRAM для каждого способа)

val tag_arrays = Seq.fill(nWays) { SeqMem(nSets, UInt(width = tECC.width(1 + tagBits)))}
val tag_rdata = Reg(Vec(nWays, UInt(width = tECC.width(1 + tagBits))))
for ((tag_array, i) <- tag_arrays zipWithIndex) {
  tag_rdata(i) := tag_array.read(s0_vaddr(untagBits-1,blockOffBits), !refill_done && s0_valid)
}

И я хочу получить к нему доступ, как

when (refill_done) {
  val enc_tag = tECC.encode(Cat(tl_out.d.bits.error, refill_tag))
  tag_arrays(repl_way).write(refill_idx, enc_tag)
  ccover(tl_out.d.bits.error, "D_ERROR", "I$ D-channel error")
}

Где repl_way - случайный UInt Chisel, сгенерированный LFSR. Но доступ к элементу Seq возможен только по индексу Scala Int, что вызывает ошибку компиляции. Затем я попытался получить к нему доступ вот так

when (refill_done) {
  val enc_tag = tECC.encode(Cat(tl_out.d.bits.error, refill_tag))
  for (i <- 0 until nWays) {
    when (repl_way === i.U) {tag_arrays(i).write(refill_idx, enc_tag)}
  }
  ccover(tl_out.d.bits.error, "D_ERROR", "I$ D-channel error")
}

Но напрашивается утверждение -

assert(PopCount(s1_tag_hit zip s1_tag_disparity map { case (h, d) => h && !d }) <= 1)

Я пытаюсь изменить файл ICache.scala. Есть идеи, как это сделать правильно? Спасибо!


person Khakim Akhunov    schedule 29.01.2020    source источник
comment
Причина возникновения вышеупомянутого утверждения заключалась в том, что я попытался собрать теги всех способов в одном регистре векторов, а затем сравнить их с входящим тегом в следующем цикле, в то время как исходное решение считывает все пути сразу в один вектор и сравнивает их в тот же цикл для определения попадания или пропуска кеша. Теперь я просто читаю каждый тег в отдельную переменную, а затем инициализирую вектор (т.е. 4 способа - 4 переменные - Vec из 4 элементов). То же и для data_arrays. Это работает, я имею в виду, я могу получить доступ к каждому способу отдельно и выбрать, какой способ получить доступ, но это больше не универсально.   -  person Khakim Akhunov    schedule 02.02.2020


Ответы (1)


Я думаю, вы можете просто использовать здесь Vec вместо Seq

val tag_arrays = Vec(nWays, SeqMem(nSets, UInt(width = tECC.width(1 + tagBits))))

Vec позволяет индексацию с UInt

person Chick Markley    schedule 29.01.2020
comment
Спасибо за ответ, но Vec не поддерживает SeqMem в качестве параметра. ICache.scala: 181: 20: значение перегруженного метода применяется с альтернативами: [ошибка] [T ‹: Chisel.Data] (elt0: T, elts: T *) Chisel.Vec [T] ‹and› [ошибка] [T ‹: Chisel.Data] (gen: T, n: Int) (неявные compileOptions: chisel3.core.CompileOptions) Chisel.Vec [T] ‹and› [ошибка] [T‹: chisel3.core.Data] (n: Int, gen: T) (неявный sourceInfo: chisel3.internal.sourceinfo.SourceInfo, неявный compileOptions: chisel3.core.CompileOptions) chisel3.core.Vec [T] [error] не может применяться к (Int, chisel3.core.SyncReadMem [Chisel.UInt]) - person Khakim Akhunov; 29.01.2020