【问题标题】:Verilog race with clock divider using flops使用触发器的时钟分频器的 Verilog 竞赛
【发布时间】:2019-03-11 20:53:50
【问题描述】:

我在 eda playground 上针对我遇到的问题做了一个基本示例。 假设我有两个时钟 1x 和 2x。 2x 使用 flop 分频器从 1x 分频。

我有两个寄存器 a 和 b。 a 以 1x 计时,b 以 2x 计时。

b是a的采样值。

当我们有 1x 和 2x 时钟的上升沿时,b 没有取 a 的预期值,而是取下一个周期值。

这是因为这种时钟分频器方案,如果我们使用 icgs 进行分频,则它可以正常工作。 但是有没有办法让它使用这种带有触发器的时钟分频器方案?

EDA 操场链接:https://www.edaplayground.com/x/map#

module race_test;

  logic clk1x = 0;
  logic clk2x = 0;

  always
    #5ns clk1x = !clk1x;

  int a, b;


  always @(posedge clk1x) begin
    a <= a+1;
    clk2x <= !clk2x;
  end

  // Problem here is that b will sample postpone value of a
  // clk2x is not triggering at the same time than clk1x but a bit later
  // This can be workaround by putting blocking assignment for clock divider
  always @(posedge clk2x) begin
    b <= a;
  end

  initial begin
    $dumpfile("test.vcd");
    $dumpvars;
    #1us
    $stop;
  end
endmodule

【问题讨论】:

  • here
  • 感谢您的链接,这正是我所期待的。它使用时钟分频器的阻塞分配按预期工作。但是,如果我的时钟分频器不是模型而是将在我的芯片中的真正触发器,这是否正确?在书中他们说合成器会很好(希望)
  • 一般来说,经验法则是,您从不使用 NBA 作为时钟以避免比赛。

标签: verilog system-verilog clock race-condition edaplayground


【解决方案1】:

数字时钟分频器在模拟和物理时序方面都存在问题。

Verilog 的非阻塞赋值运算符假设每个读写相同变量的人都同步到相同的时钟事件。通过使用 NBA 写入 clk2x,您已将 a 的读取转移到另一个 delta 时间*,并且正如您所发现的,a 已经更新。

在实际硬件中,通常会存在相当大的传播延迟,可以避免这种情况。但是,您使用相同的 D-flop 分配给clk2x,因此那里也会有传播延迟。你最后一个always 块现在代表一个时钟域交叉问题。因此,根据两个时钟之间的偏差,您仍然可能有竞争条件。

纠正此问题的一种方法是使用具有更高频率时钟的时钟发生器模块

always #2.5ns clk = !clk;

always @(posedge clk) begin
       clk1x <= !clk1x;
       if (clk1x == 1)
         clk2x = !clk2x;

【讨论】:

  • 您好 Dave,如果代码用于建模或验证,您提供的解决方案很好。就我而言,用于时钟分频的触发器用于 RTL,我想确保合成器正确实现它。我发现修复它的最干净的方法是用 ICG 替换分隔方案,以防万一。但唯一不可能的情况是我生成的时钟必须是 50/50 占空比。有没有办法用 ICG 生成 50/50 时钟?
  • 我认为答案取决于您使用的技术以及 clk1x 的来源。对于electronics.stackexchange.com 来说可能是一个更好的问题
【解决方案2】:

当然你已经解决了这个问题,但我认为有更好的方法。 这本书说可以使用阻塞分配来避免竞争。但是阻塞 assignmentemnt 会导致 synopsys lint 检查出错。因此,避免出现 lint 错误的竞争问题的一种方法是使用虚拟逻辑,如下所示

wire [31:0] a_logic;
wire dummy_sel;
assign dummy_sel = 1'b0;
assign a_logic = dummy_sel ? ~a : a;
always @(posedge clk2x) begin
  b <= a_logic;
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多