Цикл в круговом буфере в долоте - PullRequest
1 голос
/ 25 сентября 2019

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

class MyBuffer() extends Module 
{
  val data = Reg(Vec(NUM_ELEMENTS, Bool())
  val head = RegInit(0.U(NUM_ELEMENTS_W.W))
  val tail = RegInit(0.U(NUM_ELEMENTS_W.W))
}



1 Ответ

0 голосов
/ 25 сентября 2019

Я не уверен, какова ваша цель зацикливания.Но рассмотрим следующий пример кода (с некоторыми опущенными деталями).В этом примере содержимое RingBuffer предоставляется в виде представления Vec с допустимыми элементами ViewLength.Я думаю, что это демонстрирует скромно элегантный метод для этого определения зацикливания, испускаемое аппаратное обеспечение (или идея представления) может быть не элегантным.Дайте мне знать, если вы не совсем поняли идею цикличности.

import chisel3._
import chisel3.util.log2Ceil

/**
  * This ring buffer presents its current contents through view
  *
  * @param depth
  * @param bitWidth
  */
class RingBuffer(depth: Int, bitWidth: Int) extends MultiIOModule {
  /*
  You need a bunch of IO's here to push and pop and get full status
  */

  val view       = IO(Output(Vec(depth, UInt(bitWidth.W))))
  val viewLength = IO(Output(UInt(log2Ceil(depth).W)))

  val data = Reg(Vec(depth, Bool()))
  val head = RegInit(0.U(bitWidth.W))
  val tail = RegInit(0.U(bitWidth.W))

  /* Need some code here to push and pop elements */


  // this constructs a mapping between the indices between current head and tail
  // to the 0 to n indices of the view
  def mappedIndex(i: Int): UInt = {
    val out = Wire(UInt(log2Ceil(depth).W))
    when((i.U + head) >= depth.U) {
      i.U + head
    }.otherwise {
      (i.U + head) - depth.U
    }
    out
  }

  // This creates the complicated Mux structure to map betweem
  // the ring buffer elements and 0 to n style view
  view.zipWithIndex.foreach { case (viewElement, index) =>
    viewElement := data(mappedIndex(index))
  }

  // This presents the number of valid elements in the current view
  val difference = tail - head
  when((difference) < 0.U) {
    viewLength := (difference) + depth.U
  }.otherwise {
    viewLength := (difference)
  }
}
...