过程块中的语句是连续执行的,所以为什么没有任何block1、block2或block3推断锁存?
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是使用非阻塞赋值计算的,它应该将赋值推迟到始终块完成时。同时,使用阻塞赋值计算z,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
请有人解释一下,为什么不完整的灵敏度列表或在更新值之前使用变量不能推断组合块中的锁存器?
发布于 2015-01-24 23:45:51
组合块中使用的赋值类型不会影响合成。使用非阻塞(<=
)可能会导致RTL (预合成)门(后合成)模拟器错配.
对于敏感列表也是如此,合成将给出自动生成或完整列表的行为。
在时钟过程(@(posedge clk)
)中,使用非阻塞(<=
)来获得触发器的模拟行为。在时钟过程中也可以使用阻塞(=
),但是混合样式被认为是一种糟糕的编码实践。组合部分代码被移动到一个单独的组合块(always @*
)中。
锁存器是一个基本的存储器元件,如果电路不需要内存,那么它就不会被推断。
例如:
always @* begin:
v = (a & b) ^ c;
end
v
完全由输入定义,不涉及内存。与以下方面相比:
always @* begin
if (c == 1'b1) begin
w = (a & b) ^ c;
end
end
当c
为0w时,必须保存它的值,因此可以推断出锁存。
值得注意的是,虽然锁锁不坏,但必须注意打开和关闭时的时间,以确保它们捕获正确的数据。因此,推断锁存通常被看作是坏的,并且是来自糟糕的编码。
SystemVerilog具有以下语法,用于语义上暗示设计意图:
always_latch begin
if (c == 1'b1) begin
w = (a & b) ^ c;
end
end
https://stackoverflow.com/questions/28131084
复制相似问题