【问题标题】:Inferring latches in Verilog/SystemVerilog在 Verilog/SystemVerilog 中推断锁存器
【发布时间】:2015-01-24 22:40:17
【问题描述】:

程序块中的语句按顺序执行,为什么块1、块2或块3中的任何一个都没有推断出锁存器?

module testing(
    input  logic a, b, c,
    output logic x, y, z, v
    );

    logic tmp_ref, tmp1, tmp2, tmp3;

    //reference
    always_comb begin: ref_block
        tmp_ref = a & b;
        x = tmp_ref ^ c;
    end

    always_comb begin: block1
        y = tmp1 ^ c;
        tmp1 = a & b;
    end

    always @(*) begin: block2
        tmp2 <= a & b;
        z = tmp2 ^ c;
    end

    always @(c) begin: block3
        tmp3 = a & b;
        v = tmp3 ^ c;
    end
endmodule: testing

在 block1 中,y 是在 tmp1 的新值可用之前使用阻塞分配计算的。

在 block2 中,tmp2 是使用非阻塞赋值计算的,它应该将赋值推迟到 always 块完成时。同时,z是使用blocking assignment计算的,tmp2的新值尚不可用。

在 block3 中,有一个不完整的敏感度列表,仍然没有锁存器。

这是 Quartus II 14.1 的综合结果:

仅当我添加此块时,才会推断出闩锁:

//infers a latch
always @(*) begin: block4
    if (c == 1'b1) begin
        tmp4 = a & b;
        w = tmp4 ^ c;
    end
end

有人能解释一下为什么不完整的敏感度列表或在值更新之前使用变量不会推断出组合块中的锁存器吗?

【问题讨论】:

    标签: memory verilog system-verilog quartus


    【解决方案1】:

    组合块中使用的赋值类型不会影响合成。使用非阻塞 (&lt;=) 可能会导致 RTL(综合前)与门(综合后)模拟器不匹配。

    敏感性列表也是如此,综合将给出自动生成或完整列表的行为。

    在时钟进程 (@(posedge clk)) 中,使用非阻塞 (&lt;=) 来获得触发器的模拟行为。也可以使用阻塞 (=) 以及在时钟进程中使用组合代码,但混合样式被认为是一种不好的编码实践。组合部分代码只需移动到单独的组合块 (always @*)。

    锁存器是一种基本的记忆元件,如果电路不需要记忆,则不会被推断出来。

    例如:

    always @* begin: 
        v = (a & b) ^ c;
    end
    

    v 完全由输入定义,不涉及内存。相比:

    always @* begin
      if (c == 1'b1) begin
        w = (a & b) ^ c;
      end
    end
    

    c 为 0 时,w 必须保持其值,因此推断为锁存器。

    值得注意的是,虽然锁存器还不错,但必须注意打开和关闭的时间,以确保它们捕获正确的数据。因此推断的锁存器通常被认为是错误的,并且是由于编码不佳造成的。

    SystemVerilog 具有以下语义暗示设计意图的语法:

    always_latch begin
      if (c == 1'b1) begin
        w = (a & b) ^ c;
      end
    end
    

    【讨论】:

    • 感谢您的回答,它非常有用,我已投赞成票。不过我有一个问题。我现在明白,从综合工具的角度来看,在我的示例中,ref_block、block2 和 block3 之间没有区别。只有在模拟 RTL/门时会有区别。但是,如果您能帮助我理解 ref_block 和 block1 之间没有区别吗?我看不出该工具如何忽略 tmp1 的旧值用于 y 计算,然后更新为新值。
    • @evilpascal Block1 是这里的问题,综合和 RTL 将不匹配。因为tmp1 是组合的,所以没有真正的旧值,只有当前值。对于组合块,参数的顺序应该无关紧要,如果确实存在错误。由于模拟器评估代码的方式(程序上),您可能会被诱使认为它将使用旧值,合成不会。将= 阻塞分配视为并行发生。
    猜你喜欢
    • 1970-01-01
    • 2021-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多