在组合逻辑中,有时候往往不需要生成latch,所以必须知道某些信号会综合为latch,通过实践发现下面两类会出现latch:
1.在if-else和case中没有else和default将会导致产生latch。这个在夏宇闻的verilog中有讲到。
2.即使if-else 和case语句都满足if都有else,caes都有default,此时还是有可能出现latch,例如:
代码A:
always @(enable or ina or inb) begin
if (enable) begin
data_out = ina;
end
else begin
data_out = inb;
end
end
代码B:
input[3:0] data_in;
always @(data_in)
begin
case(data_in)
0: out1 = 1'b1;
1,3: out2 = 1'b1;
2,4,5,6,7: out3 = 1'b1;
default: out4 = 1'b1;
endcase
end
verilog代码中避免出现latch方法
在上图两段代码都是标准的if-else 和case语句,但是第二段代码却可以生产latch,通过将第二段代码综合后看RTL就可以清楚看到:
第二段代码产生了4个latch。第二段代码之所以会出现latch,是因为:
out1,out2,out3,out4仅仅在data_in一种情况下赋值,当data_in在非条件下,就没有对该信号赋值。
由上面发现即使使用了if-else和 case-default这样标准的代码风格,还是会导致latch的产生的。通过测试可以发现要使得组合逻辑中,特别是在三段式状态机中代码不产生latch,必须做到下面几点:
1. if-else 和case-default必须配套,也就是出现if 必须出现else与之配套;有case必须在后面写一个default。
2.在所有条件下,对信号都进行赋值
下面解释一下第二点,还是按照前面的代码为例,如果将out1在所有条件下都赋值,也就是将代码修改为:
input[3:0] data_in;
always @(data_in)
begin
case(data_in)
0: out1 = 1'b1;
1,3: begin
out1 = 1,b0;
out2 = 1'b1;
end
2,4,5,6,7: begin
out3 = 1'b1;
out1 = 1'b0;
end
default: beign
out4 = 1'b1;
out1 = 1'b0;
end
endcase
end
然后综合后查看RTL,可以发现:
verilog代码中避免出现latch方法
可以看出out1没有产生latch。所以在信号不多的情况下,可以讲每个信号在所有条件下都进行赋值,这样就会消除latch的产生。
但是,在三段式状态机代码中,特别是状态机多,信号特别多的情况下,在每个条件下都给每个信号赋值,这样就会导致代码很冗长,此时可以给每个信号一个初值。修改方法为:
input[3:0] data_in;
always @(data_in)
begin
out1 = 1'b0;
out2 = 1'b0;
out3 = 1'b0;
out4 = 1'b0;
case(data_in)
0: out1 = 1'b1;
1,3: begin
out2 = 1'b1;
end
2,4,5,6,7: begin
out3 = 1'b1;
end
default: beign
out4 = 1'b1;
end
endcase
end
verilog代码中避免出现latch方法
这样就是在选择语句之前给信号赋一个初值,这样就不需要在所有条件都给信号赋值,减少代码的重复和代码量。上图代码综合后的RTL图为:
1.如果代码简单,信号少,直接在每个条件下都赋值
2.如果代码复杂,信号多,就可以在case或是if语句前给信号赋一个初值。
关于第二条,估计会产生一些迷惑,例如在前面代码中data_in为1,out2赋值为0还是赋值为1呢?
这里就涉及到阻塞赋值和非阻塞赋值的区别。在上面代码中一般都是阻塞赋值,也就是上面一句赋值都完成了,才进行第二条语句的赋值。在上面的代码中,就是先给out2赋值为0,然后再赋值为1。这个不同于非阻塞赋值,如果是非阻塞赋值的话,就会导致同时给out2赋值两个值,导致亚稳态。
最后需要注意的是:在组合逻辑中,always@()的括号里面,使用*代替敏感变量,这是在verilog2001中的代码风格,这样可以避免敏感变量不全的情况,建议在写组合逻辑中这样书写代码。
组合逻辑赋值给自己也会产生latch
always @(*) begin
if(condition)
aa = 1'b0;
else
aa = aa; //generate latch
end