【问题标题】:Verilog deterministic behaviorVerilog 确定性行为
【发布时间】:2021-03-24 20:10:53
【问题描述】:

以下代码是确定性的吗?即它可以触发error1或error2吗?有没有推荐的生成clk2的方法(和clk3一样)

module Test();
    reg         clk1;
    reg         clk2;
    reg         clk3;
    reg         reset;

    initial
    begin
        clk1 <= 0;
        forever
        begin
            #100;
            clk1 <= ~clk1; // 2x freq of clk2/clk3
        end
    end

    always @(posedge clk1)
    begin
        if(reset)   clk2 <= 0;
        else        clk2 <= ~clk2;
    end

    initial
    begin
        clk3 <= 0;
        #300;
        forever
        begin
            #200;
            clk3 <= ~clk3;
        end
    end

    initial
    begin
        reset <= 1;
        #500;
        reset <= 0;
        #100;
        repeat (20) @(posedge clk1);
        $display("Test end");
        $finish;
    end

    always @(posedge clk2)
    begin
        if(clk1 == 0)   $display("Error1");
    end
    
    always @(posedge clk3)
    begin
        if(clk1 == 0)   $display("Error2");
    end
endmodule;

【问题讨论】:

  • 您认为哪些情况不能确定?
  • 已编辑,即它可以触发error1或error2吗?
  • 生成任何时钟的推荐方法是永远不要在那里使用非阻塞分配。时钟线上的 NBA 肯定会导致数据竞争并使行为变得不确定。
  • 如何划分时钟?如clk2,使用BA?如果是 BA,综合会推断它是什么?
  • 是的,使用 bas。合成器不关心 ba/nba。这只是一个模拟神器。一般来说,它也不会合成#delays 和初始块。

标签: verilog system-verilog


【解决方案1】:

您的代码有问题,但与确定性无关——它是完全确定性的。这是使用 NBA &lt;= 产生问题的一种情况。 clk2clk1clk3 之后的delta 周期中更新。这意味着如果您有从后者到 clk2 的时钟域交叉

always_ff @(posedge clk3)
   A <= B;
always_ff @(posedge clk2)
   C <= A; // A has already been updated with the value of B

因此,切勿使用 NBA 来分配时钟。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 2020-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多