Abstract
在Verilog中,always block可以用來代表Flip-Flop(边沿触发器), Combination Logic與Latch(锁存器,电平触发),本文比較在不寫else下,always block所代表的電路。
Introduction
在C語言裡,省略else只是代表不處理,但在Verilog裡,省略else所代表的是不同的電路。
对于正常的if-else语句,是会产生选择器Mux,在if与else两种情况下进行选择;但对于combinational logic,若未补全else,则会产生latch锁存缺省的else对应的状态。如下所示产生Mux的情况:
reg sel, a, b;
always @ (sel or a or b)
begin : if_else
if (sel == 1)
f = a;
else
f = b;
end
对于组合逻辑,补全的else是赋予某值时会产生预期的Mux;若else只是保持原值,则在一些编译器中与不加else都产生latch(因为只有当en=1时才会输出新值,否则保留之前值,这就是latch的功能),综合RTL图如下图所示:
<pre name="code" class="cpp">module top(
// input clk,
input en,
input da,
input db,
output reg q //for always,reg q
);
always@(en or da or db) begin
if(en)begin
q=da&db;
end
else q=0; //this is else
// else q=q; //this will still generate latch,not the else condition we want
end
endmodule
补全的else不是保持原值,产生Mux
补全的else保存原值的RTL图
组合logic结论:对于组合逻辑,为了维持输出之前值,产生了latch(对于vivado在编译时会提示warning,说产生了latch),而原本if-else语句是想实现选择器Mux;在vivado13.4中,是否加上else combination logic的rtl中均会出现latch,不是产生Mux。但推荐加上else补全缺省情况,这样便于理解,避免未知状况的发生(不同编译器会生成不同电路)。
对于时序逻辑,补全else与不加else综合RTL图如下图所示:
module top(
input clk,
input en,
input da,
input db,
output reg q
);
always@(posedge clk) begin
if(en)begin
q<=da&db;
end
// else q<=q;
end
endmodule
补全else RTL图
缺省else RTL图
时序电路结论:对于时序电路虽然也必須在~en保留原本的值,但由於flip-flop就有記憶的功能,所以不會產生latch。由对比图可知,此时是否补全else,RTL没有区别。