锁相环黑盒和复位控制器

假设您想要定义一个 TopLevel 组件来实例化 PLL BlackBox ,并利用它创建一个新的时钟域,该时钟域将由您的核心逻辑使用。我们还假设您希望将一个外部的异步复位适配到这个核心时钟域的同步复位源中。

本页的代码示例中将默认使用以下导入:

import spinal.core._
import spinal.lib._

PLL BlackBox定义

这是定义PLL BlackBox 的方法:

case class PLL() extends BlackBox {
  val io = new Bundle {
    val clkIn = in Bool()
    val clkOut = out Bool()
    val isLocked = out Bool()
  }
  noIoPrefix()
}

其对应下面的VHDL组件:

component PLL is
  port(
    clkIn    : in std_logic;
    clkOut   : out std_logic;
    isLocked : out std_logic
  );
end component;

TopLevel定义

下面的例子展示了如何定义 TopLevel 来实例化锁相环,创建新的 ClockDomain 并将异步复位输入调整连接至同步复位端口:

case class TopLevel() extends Component {
  val io = new Bundle {
    val aReset = in Bool()
    val clk100Mhz = in Bool()
    val result = out UInt(4 bits)
  }

  // Create an Area to manage all clocks and reset things
  val clkCtrl = new Area {
    // Instantiate and drive the PLL
    val pll = new PLL
    pll.io.clkIn := io.clk100Mhz

    // Create a new clock domain named 'core'
    val coreClockDomain = ClockDomain.internal(
      name = "core",
      frequency = FixedFrequency(200 MHz)  // This frequency specification can be used
    )                                      // by coreClockDomain users to do some calculations

    // Drive clock and reset signals of the coreClockDomain previously created
    coreClockDomain.clock := pll.io.clkOut
    coreClockDomain.reset := ResetCtrl.asyncAssertSyncDeassert(
      input = io.aReset || ! pll.io.isLocked,
      clockDomain = coreClockDomain
    )
  }

  // Create a ClockingArea which will be under the effect of the clkCtrl.coreClockDomain
  val core = new ClockingArea(clkCtrl.coreClockDomain) {
    // Do your stuff which use coreClockDomain here
    val counter = Reg(UInt(4 bits)) init 0
    counter := counter + 1
    io.result := counter
  }
}