Scala 如何使用带浮动的凿子工具

Scala 如何使用带浮动的凿子工具,scala,fixed-point,chisel,Scala,Fixed Point,Chisel,我需要将Float32转换为凿子固定点,执行一些计算并将后固定点转换为Float32 例如,我需要以下内容: val a = 3.1F val b = 2.2F val res = a * b // REPL returns res: Float 6.82 现在,我这样做: import chisel3.experimental.FixedPoint val fp_tpe = FixedPoint(6.W, 2.BP) val a_fix = a.Something (fp_tpe) //

我需要将Float32转换为凿子固定点,执行一些计算并将后固定点转换为Float32

例如,我需要以下内容:

val a = 3.1F
val b = 2.2F
val res = a * b // REPL returns res: Float 6.82
现在,我这样做:

import chisel3.experimental.FixedPoint

val fp_tpe = FixedPoint(6.W, 2.BP)
val a_fix = a.Something (fp_tpe) // convert a to FixPoint
val b_fix = b.Something (fp_tpe) // convert b to FixPoint
val res_fix = a_fix * b_fix
val res0 = res_fix.Something (fp_tpe) // convert back to Float
因此,我希望三角洲在一个范围内,例如

val eps = 1e-4
assert ( abs(res - res0) < eps, "The error is too big")
val eps=1e-4
断言(abs(res-res0)

谁能为上面的伪代码提供凿岩3 FixedPoint类的工作示例?

请查看以下代码:

import chisel3._
import chisel3.core.FixedPoint
import dsptools._


class FPMultiplier extends Module {
  val io = IO(new Bundle {
    val a = Input(FixedPoint(6.W, binaryPoint = 2.BP))
    val b = Input(FixedPoint(6.W, binaryPoint = 2.BP))
    val c = Output(FixedPoint(12.W, binaryPoint = 4.BP))
  })

  io.c := io.a * io.b
}

class FPMultiplierTester(c: FPMultiplier) extends DspTester(c) {
  //
  // This will PASS, there is sufficient precision to model the inputs
  //
  poke(c.io.a, 3.25)
  poke(c.io.b, 2.5)

  step(1)
  expect(c.io.c, 8.125)

  //
  // This will FAIL, there is not sufficient precision to model the inputs
  // But this is only caught on output, this is likely the right approach
  // because you can't really pass in wrong precision data in hardware.
  //
  poke(c.io.a, 3.1)
  poke(c.io.b, 2.2)

  step(1)
  expect(c.io.c, 6.82)
}


object FPMultiplierMain {
  def main(args: Array[String]): Unit = {
    iotesters.Driver.execute(Array("-fiv"), () => new FPMultiplier) { c =>
      new FPMultiplierTester(c)
    }
  }
}

我还建议您看看,这会让您了解如何编写通过不同类型的硬件模块。通常,您从DSpreal开始,确认模型,然后开始使用定点大小进行实验/计算,以返回所需精度的结果。

为了其他好处,我从@Chick提供了一个改进的解决方案,用更抽象的Scala重写,具有可变的DSP公差

package my_pkg

import chisel3._
import chisel3.core.{FixedPoint => FP}

import dsptools.{DspTester, DspTesterOptions, DspTesterOptionsManager}

class FPGenericIO (inType:FP, outType:FP) extends Bundle {
  val a = Input(inType)
  val b = Input(inType)
  val c = Output(outType)
}

class FPMul (inType:FP, outType:FP) extends Module {
  val io  = IO(new FPGenericIO(inType, outType))
  io.c := io.a * io.b
}

class FPMulTester(c: FPMul) extends DspTester(c) {

  val uut = c.io

  // This will PASS, there is sufficient precision to model the inputs
  poke(uut.a, 3.25)
  poke(uut.b, 2.5)

  step(1)
  expect(uut.c, 3.25*2.5)

  // This will FAIL, if you won't increase tolerance, which is eps = 0.0 by default
  poke(uut.a, 3.1)
  poke(uut.b, 2.2)

  step(1)
  expect(uut.c, 3.1*2.2)
}


object FPUMain extends App {

  val fpInType  = FP(8.W, 4.BP)
  val fpOutType = FP(12.W, 6.BP)

// Update default DspTester options and increase tolerance
  val opts = new DspTesterOptionsManager {

    dspTesterOptions = DspTesterOptions(
      fixTolLSBs = 2,
      genVerilogTb = false,
      isVerbose = true
    )
  }

  dsptools.Driver.execute (() => new FPMul(fpInType, fpOutType), opts) {
    c => new FPMulTester(c)
  }
}

这是我的最终DSP乘法器实现,它应该支持定点和DSP复数@ChickMarkley,我如何更新这个类来实现一个复杂的乘法

package my_pkg

import chisel3._

import dsptools.numbers.{Ring,DspComplex}
import dsptools.numbers.implicits._
import dsptools.{DspContext}

import chisel3.core.{FixedPoint => FP}
import dsptools.{DspTester, DspTesterOptions, DspTesterOptionsManager}


class FPGenericIO[A <: Data:Ring, B <: Data:Ring] (inType:A, outType:B) extends Bundle {
  val a = Input(inType.cloneType)
  val b = Input(inType.cloneType)
  val c = Output(outType.cloneType)

  override def cloneType = (new FPGenericIO(inType, outType)).asInstanceOf[this.type]

}

class FPMul[A <: Data:Ring, B <: Data:Ring] (inType:A, outType:B) extends Module {

  val io  = IO(new FPGenericIO(inType, outType))

  DspContext.withNumMulPipes(3) {
    io.c := io.a * io.b
  }
}

class FPMulTester[A <: Data:Ring, B <: Data:Ring](c: FPMul[A,B]) extends DspTester(c) {

  val uut = c.io

  //
  // This will PASS, there is sufficient precision to model the inputs
  //
  poke(uut.a, 3.25)
  poke(uut.b, 2.5)

  step(1)
  expect(uut.c, 3.25*2.5)

  //
  // This will FAIL, there is not sufficient precision to model the inputs
  // But this is only caught on output, this is likely the right approach
  // because you can't really pass in wrong precision data in hardware.
  //
  poke(uut.a, 3.1)
  poke(uut.b, 2.2)

  step(1)
  expect(uut.c, 3.1*2.2)
}


object FPUMain extends App {

  val fpInType  = FP(8.W, 4.BP)
  val fpOutType = FP(12.W, 6.BP)
  //val comp = DspComplex[Double] // How to declare a complex DSP type ?

  val opts = new DspTesterOptionsManager {

    dspTesterOptions = DspTesterOptions(
      fixTolLSBs = 0,
      genVerilogTb = false,
      isVerbose = true
    )
  }

  dsptools.Driver.execute (() => new FPMul(fpInType, fpOutType), opts) {
  //dsptools.Driver.execute (() => new FPMul(comp, comp), opts) { // <-- this won't compile
    c => new FPMulTester(c)
  }
}
打包我的包
进口许可证3_
导入dsptools.number.{Ring,DspComplex}
导入dsptools.numbers.implicits_
导入dsptools.{DspContext}
导入3.core.{FixedPoint=>FP}
导入dsptools.{DspTester,DspTesterOptions,dsptesteroptionmanager}

类fpgenerico[A我无法编译此代码以及dsptools主文件夹中的参数化加法器。如果我编译:sbt“test:runMain examples.ParametrizedAdderSpec”或sbt“test:runMain my_pkg.fpmultiplerman”,我将获得未解析的依赖项:注意:未解析的依赖项路径:[warn]edu.berkeley.cs:凿毛3_2.12:3.2-SNAPSHOT(/home/bku/work/cores/bar/dsptools/build.sbt#L99)[warn]+-edu.berkeley.cs:dsptools#u 2.12:1.3-SNAPSHOT[warn]edu.berkeley.cs:凿子-iotesters#u 2.12:1.3-SNAPSHOT(/home/bku/work/cores/bar/dsptools/build.sbt#L99)dsptools仍在正式发布过程中,在主(开发)中存在一些问题分支。通过运行“git checkout 1.1.3”尝试更改为1.1.3版,然后运行testExcellent,这很有效!现在,如何设置peek公差?我尝试了dspter.setTol(1e-4,8)和this.setTol(1e-4,8),但这些不会编译。我认为您要查找的控件位于src/main/scala/dsptools/tester/DspTesterOptions.scala中。您可以通过向DspTesterOptions管理器中的dspTestersOptions实例添加标志来传递这些控件。这正是我所做的。我找到了解决方案,但我不知道如何将复数传递给我的module。在你的dsptools项目中没有关于复杂内容的示例!请检查我在问题中的最新代码。我发布了一个参数化的实现,需要更新它以支持复杂的环。谢谢!