Latch:锁存器,是一种在异步电路系统中,对输入信号电平敏感的单元,用来存储信息;
锁存器在数据未锁存时,输出端的信号随输入信号变化,就像信号通过一个缓冲器,一旦锁存信号有效,则数据被锁存,输入信号不起作用。因此,锁存器也被称为透明锁存器,指的是不锁存时输出对于输入是透明的。
Latch的危害:
1.对毛刺敏感;
2.不能异步复位;
3.复杂的静态时序分析;
4.占用更多逻辑资源;
5.额外的延时;
几种产生Latch的情况:
1.组合逻辑中if-else条件分支语句缺少else语句;
2.组合逻辑中case条件分支语句条件未完全列举,且缺少default语句;
3.组合逻辑中输出变量赋值给自己;
针对第一种情况:
正确代码:
module decoder(
input i_in1,
input i_in2,
input i_in3,
output reg [7:0] o_out
);
always@(*)
begin
if({i_in1,i_in2,i_in3} == 3'b000)
o_out = 8'b0000_0001;
else if({i_in1,i_in2,i_in3} == 3'b001)
o_out = 8'b0000_0010;
else if({i_in1,i_in2,i_in3} == 3'b010)
o_out = 8'b0000_0100;
else if({i_in1,i_in2,i_in3} == 3'b011)
o_out = 8'b0000_1000;
else if({i_in1,i_in2,i_in3} == 3'b100)
o_out = 8'b0001_0000;
else if({i_in1,i_in2,i_in3} == 3'b101)
o_out = 8'b0010_0000;
else if({i_in1,i_in2,i_in3} == 3'b110)
o_out = 8'b0100_0000;
else
o_out = 8'b1000_0000;
end
endmodule
RTL视图:
错误代码:
module decoder(
input i_in1,
input i_in2,
input i_in3,
output reg [7:0] o_out
);
always@(*)
begin
if({i_in1,i_in2,i_in3} == 3'b000)
o_out = 8'b0000_0001;
else if({i_in1,i_in2,i_in3} == 3'b001)
o_out = 8'b0000_0010;
else if({i_in1,i_in2,i_in3} == 3'b010)
o_out = 8'b0000_0100;
else if({i_in1,i_in2,i_in3} == 3'b011)
o_out = 8'b0000_1000;
else if({i_in1,i_in2,i_in3} == 3'b100)
o_out = 8'b0001_0000;
else if({i_in1,i_in2,i_in3} == 3'b101)
o_out = 8'b0010_0000;
else if({i_in1,i_in2,i_in3} == 3'b110)
o_out = 8'b0100_0000;
//else
// o_out = 8'b1000_0000;
end
endmodule
RTL视图:
第二种情况:
正确代码:
module decoder(
input i_in1,
input i_in2,
input i_in3,
output reg [7:0] o_out
);
always@(*)
begin
case({i_in1,i_in2,i_in3})
3'b000: o_out = 8'b0000_0001;
3'b001: o_out = 8'b0000_0010;
3'b010: o_out = 8'b0000_0100;
3'b011: o_out = 8'b0000_1000;
3'b100: o_out = 8'b0001_0000;
3'b101: o_out = 8'b0010_0000;
3'b110: o_out = 8'b0100_0000;
3'b111: o_out = 8'b1000_0000;
default:o_out = 8'b0000_0001;
endcase
end
endmodule
RTL视图:
错误代码:
module decoder(
input i_in1,
input i_in2,
input i_in3,
output reg [7:0] o_out
);
always@(*)
begin
case({i_in1,i_in2,i_in3})
3'b000: o_out = 8'b0000_0001;
3'b001: o_out = 8'b0000_0010;
3'b010: o_out = 8'b0000_0100;
3'b011: o_out = 8'b0000_1000;
3'b100: o_out = 8'b0001_0000;
3'b101: o_out = 8'b0010_0000;
3'b110: o_out = 8'b0100_0000;
//3'b111: o_out = 8'b1000_0000;
//default:o_out = 8'b0000_0001;
endcase
end
endmodule
RTL视图:
第三种情况:
代码如下:
module decoder(
input i_in1,
input i_in2,
input i_in3,
output reg [7:0] o_out
);
always@(*)
begin
case({i_in1,i_in2,i_in3})
3'b000: o_out = 8'b0000_0001;
3'b001: o_out = 8'b0000_0010;
3'b010: o_out = 8'b0000_0100;
3'b011: o_out = 8'b0000_1000;
3'b100: o_out = 8'b0001_0000;
3'b101: o_out = 8'b0010_0000;
3'b110: o_out = 8'b0100_0000;
3'b111: o_out = o_out;
default:o_out = 8'b0000_0001;
endcase
end
endmodule
RTL视图如下:
针对第三种情况,if-else中else把值赋给自己同样会产生Latch。