Как написать аккумулятор с помощью ScalaBlackBox? - PullRequest
1 голос
/ 07 июня 2019

Я хочу создать несколько новых типов чисел, таких как DspReal для dsptools, таких как DspPosit и DspQuire.DspPosit основан на posit, у меня есть некоторый Java-код, а DspQuire основан на quire, который является своего рода аккумулятором для posit.Потому что я просто хочу симуляции сейчас, поэтому я написал много ScalaBlackBox для их работы, например, DspReal.Однако я обнаружил, что ScalaBlackBox не может создавать последовательную логику.Например, токовый выход аккумулятора Quire зависит от его входа и последнего выхода.Но ScalaBlackBox не может получить значение вывода.Кроме того, шаг (n) также влияет на вывод.Потому что аккумулятор будет читать свой вход за такт.

Я обнаружил некоторые системные проблемы с педалью.Во-первых, функция ScalaBlackBox, twoOp и oneOp и так далее будет вызываться много раз.Я не знаю почему.Во-вторых, step (n) является функцией PeekPokeTester, к которой ScalaBlackBox не может получить доступ.В-третьих, я пытаюсь прочитать текущий вывод, но система выдает ошибки.

trait DspBlackBlackBoxImpl extends BlackBoxImplementation with ScalaBlackBox

abstract class DspQuireAccumulator extends DspBlackBlackBoxImpl {

  lazy val accValue = Quire32() // initial value

  /**
    * sub-classes must implement this two argument function
    *
    * @param posit  accumulate element
    * @return       quire operation result
    */
  def accOp(posit: Posit32): Unit

  def outputDependencies(outputName: String): Seq[(String)] = {
    outputName match {
      case "out" => Seq("in") // Seq("out", "in") gives errors
      case _ => Seq.empty
    }
  }

  def cycle(): Unit = {}

  def execute(inputValues: Seq[Concrete], tpe: Type, outputName: String): Concrete = {
    val arg1 :: _ = inputValues
    val positArg = Posit32(arg1.value)
    accOp(positArg)
    val result = quire32ToBigInt(accValue)
    ConcreteSInt(result, DspQuire.underlyingWidth, arg1.poisoned).asUInt
  }

  def getOutput(inputValues: Seq[BigInt], tpe: Type, outputName: String): BigInt = {
    val arg1 :: _ = inputValues
    val positArg = Posit32(arg1)
    accOp(positArg)
    quire32ToBigInt(accValue)
  }
}
class DspQuireAddAcc(val name: String) extends DspQuireAccumulator {
  def accOp(posit: Posit32): Unit = accValue += posit
}
class QuireBlackboxAccOperand extends BlackBox {
  val io = IO(new Bundle() {
    val in = Input(UInt(DspPosit.underlyingWidth.W))
    val out = Output(UInt(DspQuire.underlyingWidth.W))
  })
}

class BBQAddAcc extends QuireBlackboxAccOperand

class TreadleDspQuireFactory extends ScalaBlackBoxFactory {
  def createInstance(instanceName: String, blackBoxName: String): Option[ScalaBlackBox] = {
    blackBoxName match {
      case "BBQAddAcc" => Some(add(new DspQuireAddAcc(instanceName)))
...

accOp будет вызываться много раз.Итак, если я хочу накапливать List (1, 2, 3), результат может быть 0 + 1 + 1 + 2 + 2 + ... И функция peek снова вызовет accOp, это также меня смущает.

1 Ответ

2 голосов
/ 08 июня 2019

Я полагаю, что большинство ваших проблем на данный момент вызваны смешением двух разных подходов. Я думаю, что вы не должны использовать BlackBoxImplmentation, потому что это более старая схема, используемая с firrtl-интерпретатором . Просто используйте ScalaBlackBox и реализуйте методы, описанные на вики-странице Black Boxes and Treadle и показанные в TreadleTest BlackBoxWithState .

Не используйте outputDependencies, а вместо этого укажите любые зависимости между входами и выходами с помощью getDependencies. inputChanged будет вызываться всякий раз, когда изменяется входной IO. Таким образом, в этом методе вы хотите записать или обновить внутреннее состояние вашего черного ящика. clockChange будет вызываться при каждом изменении часов и предоставит информацию о переходе, чтобы вы могли решить, что произойдет потом. Тредл будет вызывать getOutput всякий раз, когда ему понадобится этот вывод вашего черного ящика, поскольку вы не будете использовать outputDependencies, вы можете игнорировать входы и просто предоставлять выходное значение в зависимости от вашего внутреннего состояния.

Я все еще пытаюсь воспроизвести работающую версию вашего кода здесь, но у меня будет немного времени собрать ее вместе, если вы сможете попробовать мои предложения выше и сообщить мне, как это будет полезно. Я заинтересован в том, чтобы сделать эту функцию в Treadle лучше и проще в использовании, поэтому все отзывы приветствуются.

...