使用时钟的两个边沿

电器工程 FPGA 验证日志 英特尔-FPGA
2022-01-14 13:46:46

我正在使用 Verilog 和 Quartus II 对 Altera Cyclone IV 进行编程。在我的设计中,我想使用时钟的两个边沿,这样我就可以用 50% 占空比的奇数因子进行时钟分频。这是我的代码片段:

  always @(posedge low_jitter_clock_i or negedge low_jitter_clock_i or posedge reset_i) begin
    if(reset_i) begin
      fixed_clock <= 1'b0;
      divider_dummy <= 'b0;
    end else begin
      fixed_clock <= fixed_clock_next;
      divider_dummy <= divider_dummy_next;
    end
  end

现在,当我编译它时,Quartus II 会抛出以下错误:

Verilog HDL 始终在 adc_clocking.v(83) 处构造错误:事件控制无法测试变量“low_jitter_clock_i”的上升沿和下降沿

如何在我的设计中同时使用给定时钟的上升沿和下降沿?

4个回答

当您分配给边缘敏感的始终块中的寄存器时,您正在定义一个触发器。FPGA 没有可以在时钟的两个边沿触发的触发器。

为了做你想做的事,你需要有两个独立的 always 块,一个用于时钟的每个边沿,然后想办法组合两个块的输出而不会产生毛刺。

例如,一个 always 块可以包含您的可编程分频器。将其设计为在给定奇数时输出占空比小于 50%。使用第二个 always 块(在另一个时钟沿)将第一个块的输出延迟 1/2 个时钟,然后将两个输出相或。为偶数分频器值禁用第二个模块的输出。

如果这是用于内部逻辑,您可能必须写得更接近可用的触发器。除了 Coolrunner-II,我不知道任何具有固有双沿寄存器的可编程逻辑。

因此,您必须创建两个always块,一个用于 negedge,一个用于 posedge,并将它们的输出与一些组合逻辑结合起来。

或者使用 PLL 将时钟加倍,然后您可以使用传统的单边逻辑。

我最终使用此处描述的方法为奇数除法因子实现了 50% 的占空比

正如 Dave Tweed 所指出的,除非 FPGA 包含可以在时钟的两个边沿上运行的触发器硬件,否则有必要编写自己的逻辑来使用传统的单边沿触发器实现所需的行为。虽然有许多不同的方式可以实现一个电路,该电路的行为很像一个双边触发器,但这种电路通常会添加一些与触发器相关的时序约束不同的时序约束。

例如,一种简单的方法是让一个模块结合两个 2 输入异或和一对“T”触发器(时钟脉冲到达时的输入状态指示该时钟沿是否应该切换输出),一个一个由上升沿触发,一个由下降沿触发。模块的输出将是触发器输出的异或,两个触发器的输入将是模块输出与其输入的异或。

以这种方式设计的电路基本上可以像双边触发器一样工作,尽管设置和传播时间更长,但有额外的时序约束。不在反馈路径上的普通触发器不会介意时钟边沿的开始是否有一堆欠幅脉冲,前提是时钟稳定在有效电平,并且设置时间限制是从之前测量的满足第一个欠幅脉冲和从时钟脉冲稳定激活的时间开始测量的保持时间和时钟激活时间限制。触发器输出的行为将在时钟不稳定期间未定义,但将在时钟稳定后定义。double-xor-double-flop 模块将添加额外的时序约束,即任何会改变输出的时钟边沿必须与可能这样做的任何其他时钟边沿保持安全距离。未能满足该约束条件,例如,在输入与输出不匹配时具有三个非常接近的连续时钟边沿,可能会使输出处于不确定或亚稳态(请注意,涉及偶数个边沿的情况不是问题,因为这种情况只涉及欠幅脉冲;三沿情况(或其他大于一的奇数情况)是一个问题,因为在欠幅脉冲之后会有一个有效脉冲。

另一种电路设计是具有上述两个触发器,但将它们的输出馈送到多路复用器。该电路不会因欠缺脉冲而进入不良状态,并且其时钟约束与底层锁存器相同,但它的缺点是输出高且应保持(或低且应保持低) ) 所以可能会在时钟边沿短暂出现故障。在某些电路中,这无关紧要,但在其他电路中,它会。

逻辑综合工具可能会通过分析哪些时序约束被指定为重要来自动实现双边触发器,但这样做会有些困难。它还会增加对设计的微小更改可能导致实施发生重大变化并因此产生重大和意外的行为变化的风险。