函数

使用 Scala 函数生成硬件的方式与 VHDL/Verilog 完全不同,原因有很多:

  • 您可以实例化寄存器、组合逻辑以及其中的组件。

  • 您不必使用限制信号赋值范围的 process/@always 块。

  • 一切都通过引用传递,这允许简化操作。
    例如,您可以将总线作为参数提供给函数,然后该函数可以在内部对其进行读/写。您还可以从 Scala 世界(函数、类型等)返回组件、总线或任何其他内容。

RGB信号转灰度信号

例如,如果您想使用系数将红/绿/蓝颜色转换为灰度,您可以使用函数来完成:

// Input RGB color
val r, g, b = UInt(8 bits)

// Define a function to multiply a UInt by a Scala Float value.
def coef(value: UInt, by: Float): UInt = (value * U((255 * by).toInt, 8 bits) >> 8)

// Calculate the gray level
val gray = coef(r, 0.3f) + coef(g, 0.4f) + coef(b, 0.3f)

Valid Ready Payload 总线

例如,如果您定义一个带有 valid, readypayload 信号的简单总线,则可以在其中定义一些有用的函数。

case class MyBus(payloadWidth: Int) extends Bundle with IMasterSlave {
  val valid   = Bool()
  val ready   = Bool()
  val payload = Bits(payloadWidth bits)

  // Define the direction of the data in a master mode
  override def asMaster(): Unit = {
    out(valid, payload)
    in(ready)
  }

  // Connect that to this
  def <<(that: MyBus): Unit = {
    this.valid   := that.valid
    that.ready   := this.ready
    this.payload := that.payload
  }

  // Connect this to the FIFO input, return the fifo output
  def queue(size: Int): MyBus = {
    val fifo = new MyBusFifo(payloadWidth, size)
    fifo.io.push << this
    return fifo.io.pop
  }
}

class MyBusFifo(payloadWidth: Int, depth: Int) extends Component {

  val io = new Bundle {
    val push = slave(MyBus(payloadWidth))
    val pop  = master(MyBus(payloadWidth))
  }

  val mem = Mem(Bits(payloadWidth bits), depth)

  // ...

}