Почему DspContext не работает, например, с NumAddPipes? - PullRequest
1 голос
/ 12 июня 2019

Недавно я изучал DspContext и классы типов в dsptools. Я просто запустил тестовый код в соответствии с руководством. Он показывает, как добавлять конвейеры к математическим операциям. Но я обнаружил, что этот пример не работает, как ожидалось. Вот пример кода:

class SimpleDspIo[T <: Data:RealBits](gen: T) extends Bundle {
  val x = Input(gen.cloneType)
  val y = Input(gen.cloneType)
  val z = Output(gen.cloneType)
  override def cloneType: this.type = new SimpleDspIo(gen).asInstanceOf[this.type]
}

class SimpleDspModule[T <: Data:RealBits](gen: T, val addPipes: Int) extends Module {
  val io = IO(new SimpleDspIo(gen))

  DspContext.withNumAddPipes(addPipes) { 
    io.z := io.x + io.y
  }
} 

И его тестовая программа:

class SimpleDspModuleTester[T <: Data:RealBits](c: SimpleDspModule[T]) extends DspTester(c) {
  val x = Seq(-1.1, -0.4, 0.4, 1.1)
  val z = x map (2 * _)
  for (i <- 0 until (x.length + c.addPipes)) {
    val in = x(i % x.length)

    poke(c.io.x, in)

    updatableDspVerbose.withValue(false) {
      poke(c.io.y, in)
    }

    step(1)

    peek(c.io.z)
  }
}

class SimpleDspModuleSpec extends FlatSpec with Matchers {

  val testOptions = new DspTesterOptionsManager {
    dspTesterOptions = DspTesterOptions(
        fixTolLSBs = 1,
        isVerbose = true)

    commonOptions = commonOptions.copy(targetDirName = "test_run_dir/simple_dsp_fix")
  }

  behavior of "simple dsp module"

  it should "properly add fixed point types" in {
    dsptools.Driver.execute(() => new SimpleDspModule(FixedPoint(16.W, 12.BP), addPipes = 3), testOptions) { c =>
      new SimpleDspModuleTester(c)
    } should be (true)
  }

Когда я его запустил, на терминале показывалось:

[info] [0.001] SEED 1560341324819
[info] [0.005]   POKE SimpleDspModule.io_x <- -1.1, Q3.12
[info] [0.005] STEP 1x -> 1
[info] [0.006]   PEEK SimpleDspModule.io_z -> -2.2001953125, Q3.12
[info] [0.006]   POKE SimpleDspModule.io_x <- -0.4, Q3.12
[info] [0.006] STEP 1x -> 2
[info] [0.006]   PEEK SimpleDspModule.io_z -> -0.7998046875, Q3.12
[info] [0.006]   POKE SimpleDspModule.io_x <- 0.4, Q3.12
[info] [0.007] STEP 1x -> 3
[info] [0.007]   PEEK SimpleDspModule.io_z -> 0.7998046875, Q3.12
[info] [0.007]   POKE SimpleDspModule.io_x <- 1.1, Q3.12
[info] [0.007] STEP 1x -> 4
[info] [0.007]   PEEK SimpleDspModule.io_z -> 2.2001953125, Q3.12
[info] [0.007]   POKE SimpleDspModule.io_x <- -1.1, Q3.12
[info] [0.007] STEP 1x -> 5
[info] [0.007]   PEEK SimpleDspModule.io_z -> -2.2001953125, Q3.12
[info] [0.008]   POKE SimpleDspModule.io_x <- -0.4, Q3.12
[info] [0.008] STEP 1x -> 6
[info] [0.008]   PEEK SimpleDspModule.io_z -> -0.7998046875, Q3.12
[info] [0.008]   POKE SimpleDspModule.io_x <- 0.4, Q3.12
[info] [0.008] STEP 1x -> 7
[info] [0.008]   PEEK SimpleDspModule.io_z -> 0.7998046875, Q3.12

Вывод был сгенерирован мгновенно, а не задержан правильно. Идя дальше, я нахожу правильный способ - вызвать функцию plusContext. Просто так:

class SimpleDspIo extends Bundle {
  val x = Input(FixedPoint(16.W, 12.BP))
  val y = Input(FixedPoint(16.W, 12.BP))
  val z = Output(FixedPoint(16.W, 12.BP))
}

class SimpleDspModule(val addPipes: Int) extends Module {
  val io = IO(new SimpleDspIo)

  DspContext.withNumAddPipes(addPipes) { 
    io.z := FixedPointRealImpl.plusContext(io.x, io.y)
  }
}

Теперь все работает как положено:

[info] [0.000] SEED 1560343025741
[info] [0.004]   POKE SimpleDspModule.io_x <- -1.1, Q3.12
[info] [0.005] STEP 1x -> 1
[info] [0.005]   PEEK SimpleDspModule.io_z -> 0.0, Q3.12
[info] [0.005]   POKE SimpleDspModule.io_x <- -0.4, Q3.12
[info] [0.005] STEP 1x -> 2
[info] [0.006]   PEEK SimpleDspModule.io_z -> 0.0, Q3.12
[info] [0.006]   POKE SimpleDspModule.io_x <- 0.4, Q3.12
[info] [0.006] STEP 1x -> 3
[info] [0.006]   PEEK SimpleDspModule.io_z -> -2.2001953125, Q3.12
[info] [0.006]   POKE SimpleDspModule.io_x <- 1.1, Q3.12
[info] [0.006] STEP 1x -> 4
[info] [0.006]   PEEK SimpleDspModule.io_z -> -0.7998046875, Q3.12
[info] [0.006]   POKE SimpleDspModule.io_x <- -1.1, Q3.12
[info] [0.007] STEP 1x -> 5
[info] [0.007]   PEEK SimpleDspModule.io_z -> 0.7998046875, Q3.12
[info] [0.007]   POKE SimpleDspModule.io_x <- -0.4, Q3.12
[info] [0.007] STEP 1x -> 6
[info] [0.007]   PEEK SimpleDspModule.io_z -> 2.2001953125, Q3.12
[info] [0.007]   POKE SimpleDspModule.io_x <- 0.4, Q3.12
[info] [0.007] STEP 1x -> 7
[info] [0.007]   PEEK SimpleDspModule.io_z -> -2.2001953125, Q3.12

Не существует явного способа конвертировать "+" в "plusContext" (и другие функции). Является ли dsptools незавершенным?

1 Ответ

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

В старых версиях dsptools ваш исходный код работал бы так, как вы ожидали. Однако часто было странно, что поведение + зависит от наличия неявного для класса типов. Если я правильно помню, казалось бы, безобидные изменения в вашем импорте могут кардинально изменить поведение вашей схемы.

Решение, которое мы в итоге приняли, состояло в том, что если у типа долота есть оператор, класс типов не должен изменять это поведение никогда. Если вы хотите использовать версии операторов, которые используют контекст (конвейерная обработка, округление и т. Д.), Вы должны использовать отдельные операторы, у которых все имеют context_ в качестве префикса. a + b и a context_+ b нельзя перепутать.

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

...