上一篇讲解了什麽是 latch,其又与 flip-flop 差在哪,也解释了我们要去避免它的原因,那麽这篇将会告诉你有哪几种情况会产生 latch。
在组合逻辑中,不完整的 if-else 语句会导致 latch 的生成,那怎样是不完整呢?
就是最後缺少了 else,正是因为没有写 else,会被系统认定为该值不需要改变,而自动生成 latch 来帮你储存
会生成 latch 的例子:
module latch_test(
in,
en,
out
);
input in;
input en;
output out;
reg out;
always@(*)begin
if(en) out = in;//no else
end
endmodule
解决方法:
SOL1:补齐 else 语句
module latch_test(
in,
en,
out
);
input in;
input en;
output out;
reg out;
always@(*)begin
if(en) out = in;
else out = 1'b0;//add
end
endmodule
SOL2:在 always 内最上方加上初值
module latch_test(
in,
en,
out
);
input in;
input en;
output out;
reg out;
always@(*)begin
out = 1'b0;//initialization
if(en) out = in;
end
endmodule
但这里有一点该注意,其实讲补齐 if-else 算是拢统的说法,因为以下这个例子其实也会产生 latch,原因就在同一个变数在不同 if 条件下都要叙述完整,否则还是会生成 latch。
module latch_test(
in1,
in2,
en,
out1,
out2
);
input in1;
input in2;
input en;
output out1;
output out2;
reg out1;
reg out2;
always@(*)begin
if(en) out1 = in1;
else out2 = in2;
end
endmodule
应改成
module latch_test(
in1,
in2,
en,
out1,
out2
);
input in1;
input in2;
input en;
output out1;
output out2;
reg out1;
reg out2;
always@(*)begin
if(en)begin
out1 = in1;
out2 = 1'b0;//add
end
else begin
out1 = 1'b0;//add
out2 = in2;
end
end
endmodule
这里值得注意的是,在循序逻辑中(clock触发),不完整的 if-else 并不会生成 latch,因为 register 具有储存前态的功能,并只有在正负缘才会改变值~
逻辑跟 if-else 相似,就是最後缺少了 default,正是因为没有写 default,进入到未被定义的 case 时会被系统认定为该值不需要改变,而自动生成 latch 来帮你储存。
会生成 latch 的例子:
module latch_test(
in1,
in2,
sel,
out
);
input in1;
input in2;
input [1:0] sel;
output out;
reg out;
always@(*)begin
case(sel)
2'd0:out = in1;
2'd1:out = in2;
endcase
end
endmodule
应改成
module latch_test(
in1,
in2,
sel,
out
);
input in1;
input [1:0] sel;
output out;
reg out;
always@(*)begin
case(sel)
2'd0:out = in1;
2'd1:out = in2;
default:out = 1'b0;//add
endcase
end
endmodule
或是补上初值也是可以的!
因为会用到变数的前态而自动生成 latch 来帮你储存。
会生成 latch 的例子:
reg a;
reg b;
always@(*)begin
if(a | b)a = 1'b0;
else a = 1'b1;
end
以及
reg a;
reg b;
always@(*)begin
if(b)a = a;
else a = a + 1'b1;
end
当然 wire 也不例外
wire a;
wire c;
reg b;
assign a = (a & b)?(1'b0):(1'b1);
assign c = (a & b)?(c):(1'b0);
这种其实不太能解,就是尽量不要这样写
或是,如果输出没有非常及时,也可以延後一个 clk 将值锁在 register 内
EX:
reg a;
reg b;
reg a_temp;
always@(posedge clkSys)begin
a_temp <= a;
end
always@(*)begin
if(a_temp | b)a = 1'b0;
else a = 1'b1;
end
用先前储存的 a_temp 来当判断元素,也可以避免。
等号右边的所有变数或判断元素都应盖列入 alway 触发条件中
会生成 latch 的例子:
module latch_test(
in1,
in2,
sel,
out
);
input in1;
input in2;
input sel;
output out;
reg out;
always@(in1 or in2)begin
if(sel)out = in1;
else out = in2;
end
endmodule
应改成
module latch_test(
in1,
in2,
sel,
out
);
input in1;
input in2;
input sel;
output out;
reg out;
always@(in1 or in2 or sel)begin//add sel
if(sel)out = in1;
else out = in2;
end
endmodule
以上四种就是常见的 latch 生成原因以及相对应解决的方法~~
<<: Re: 新手让网页 act 起来: Day13 - Hook Flow
>>: Day13 - 物理模拟篇 - 弹跳球世界IV - 成为Canvas Ninja ~ 理解2D渲染的精髓
本文内容 接续,Day27 的内容,纪录阅读有关 Angular Route 的 pathMatch...
#odoo #开源系统 #数位赋能 #E化自主 企业之广告行销手法,除了透过email、UTMs、问...
Youtube 频道:https://www.youtube.com/c/kaochenlong ...
以实务来说,总是会有一些情况导致使用者没办法正常收到认证码,所以系统必须具备 retry on fa...
本文内容 本文内容为阅读与 Angular 的 pathMatch:full 和 redirectT...