为什么DspContext不起作用,例如withNumAddPipes?

时间:2019-06-12 12:59:31

标签: chisel

最近,我一直在研究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 个答案:

答案 0 :(得分:2)

在较早版本的dsptools中,您的原始代码将按预期工作。但是,使+的行为取决于是否存在类型类的隐含对象,这常常令人困惑。如果我没记错的话,看似无害的进口更改可能会极大地改变电路的行为。

我们最终做出的决定是,如果凿子类型具有运算符,则类型类永远都不应更改该行为。如果要使用使用上下文的运算符版本(流水线,舍入等),则必须使用单独的运算符,所有运算符都以context_作为前缀。 a + ba context_+ b不能混淆。

我仍然对context_作为前缀不完全满意。也许我们应该为这些运算符添加一些速记,但是在这种情况下,我认为清晰度比简洁更重要。