简体   繁体   English

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

[英]Why doesn't the DspContext work such as withNumAddPipes?

Recently, I have been studying DspContext and type classes in dsptools. 最近,我一直在研究DspContext和dsptools中的类型类。 I just ran a test code according to the tutorial. 我只是根据教程运行了一个测试代码。 It shows how to add pipelines to mathematical operations. 它显示了如何将管道添加到数学运算。 But I found this example didn't work as expected. 但是我发现这个例子没有按预期工作。 Here is the code of example: 这是示例代码:

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
  }
} 

And its test program: 及其测试程序:

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)
  }

When I ran it, the terminal displayed: 当我运行它时,终端显示:

[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

The output was generated instantly rather than was delayed correctly. 输出是立即生成的,而不是正确延迟的。 Going a step further, I find the right way is to call function plusContext. 更进一步,我发现正确的方法是调用函数plusContext。 Just like this: 像这样:

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)
  }
}

Now, it works as expected: 现在,它可以按预期工作:

[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

There is no explicit way to convert "+" into "plusContext"(and other functions). 没有明确的方法可以将“ +”转换为“ plusContext”(和其他函数)。 Is the dsptools uncompleted? dsptools是否未完成?

In older versions of dsptools, your original code would have worked as you expected it to. 在旧版本的dsptools中,您的原始代码将按预期工作。 However, it was often confusing to have + behavior depend on if an implicit for the typeclass is present. 但是,使+行为依赖于是否存在类型类的隐含对象常常令人困惑。 If I recall correctly, seemingly innocuous changes to your imports could dramatically change your circuit's behavior. 如果我没记错的话,看似无害的进口更改可能会极大地改变电路的行为。

The decision we ended up making was that if a chisel type has an operator, the typeclass should not change that behavior ever. 我们最终做出的决定是,如果凿子类型具有运算符,则类型类永远不会改变该行为。 If you want to use versions of the operators that use the context (pipelining, rounding, etc.), you have to use separate operators that all have context_ as a prefix. 如果要使用使用上下文的运算符版本(流水线,舍入等),则必须使用单独的运算符,所有运算符都将context_作为前缀。 a + b and a context_+ b can't be confused. 不能混淆a + ba context_+ b

I'm still not entirely satisfied with context_ as a prefix. 我仍然不完全满意context_作为前缀。 Maybe we should add some shorthand for these operators, but I think clarity is more important than brevity in this instance. 也许我们应该为这些运算符添加一些速记,但是在这种情况下,我认为清晰度比简洁更重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM