分形计算器
简介
此示例将展示使用数据流和定点计算实现一个未经优化的Mandelbrot分形计算器。
规范
该组件将接收像素任务的一个 Stream (其中包含Mandelbrot空间中的XY坐标),并将生成一个像素结果的一个 Stream (包含对应任务的迭代次数)。
定义组件的IO为:
| IO名称 | 方向 | 类型 | 描述 | 
|---|---|---|---|
| cmd | slave | Stream[PixelTask] | 提供XY坐标来处理 | 
| rsp | master | Stream[PixelResult] | 返回对应cmd交换所需的迭代次数 | 
让我们设计 PixelTask Bundle:
| 元素名称 | 类型 | 描述 | 
|---|---|---|
| x | SFix | Mandelbrot空间中的坐标 | 
| y | SFix | Mandelbrot空间中的坐标 | 
定义PixelResult Bundle :
| 元素名称 | 类型 | 描述 | 
|---|---|---|
| iteration | UInt | 求解Mandelbrot坐标所需的迭代次数 | 
细化参数(泛型)
让我们定义为系统提供构造参数的类:
case class PixelSolverGenerics(fixAmplitude: Int,
                               fixResolution: Int,
                               iterationLimit: Int) {
  val iterationWidth = log2Up(iterationLimit+1)
  def iterationType = UInt(iterationWidth bits)
  def fixType = SFix(
    peak=fixAmplitude exp,
    resolution=fixResolution exp
  )
}
备注
iterationType和fixType是可以调用来实例化新信号的函数,它就像C语言中的typedef。
Bundle定义
case class PixelTask(g: PixelSolverGenerics) extends Bundle {
  val x, y = g.fixType
}
case class PixelResult(g: PixelSolverGenerics) extends Bundle {
  val iteration = g.iterationType
}
组件实现
现在进行实现。下面是一个非常简单的实现,没有使用流水线处理/多线程技术。
case class PixelSolver(g: PixelSolverGenerics) extends Component {
  val io = new Bundle {
    val cmd = slave  Stream(PixelTask(g))
    val rsp = master Stream(PixelResult(g))
  }
  import g._
  // Define states
  val x, y = Reg(fixType) init(0)
  val iteration = Reg(iterationType) init(0)
  // Do some shared calculation
  val xx = x*x
  val yy = y*y
  val xy = x*y
  // Apply default assignment
  io.cmd.ready := False
  io.rsp.valid := False
  io.rsp.iteration := iteration
  when(io.cmd.valid) {
    // Is the mandelbrot iteration done ?
    when(xx + yy >= 4.0 || iteration === iterationLimit) {
      io.rsp.valid := True
      when(io.rsp.ready) {
        io.cmd.ready := True
        x := 0
        y := 0
        iteration := 0
      }
    } otherwise {
      x := (xx - yy + io.cmd.x).truncated
      y := (((xy) << 1) + io.cmd.y).truncated
      iteration := iteration + 1
    }
  }
}