目录
抛砖引玉
实际测试
从一个小例子引入设计:
我们需要设计一个电路,要实现的功能是,如果电脑CPU过热,则电脑关机;
你可能想到的伪代码是这样的:
- If (cpu_overheated) then shut_off_computer = 1;
可以,是对功能的描述。
但是存在一个情况就是其他情况呢?
如果默认不写回事会有什么问题?
答案也很简单,默认不写,就相当于保持输出原来的状态:
而组合逻辑中,这种“保持输出不变”的行为意味着需要记住当前状态,从而产生一个锁存器。组合逻辑(例如逻辑门)无法记住任何状态。组合电路必须在所有情况下都为所有输出分配一个值。这通常意味着您 始终需要else子句或分配给输出的默认值。
那么正确的做法应该是:
reg shut_off_computer;
always@(*) begin
if (cpu_overheated) shut_off_computer = 1;
else shut_off_computer = 0;
end
或
wire shut_off_computer;
assign shut_off_computer = cpu_overheated ? 1 : 0;
这个例子就是所谓的避免生成锁存器的最常见的一种情况,就是组合逻辑中,要把else子句或者case的default补上,并且给出输出的默认值。
另外一个小例子,各位自己想想吧。
如果没有达到目的地,且没油了,则停止驾驶,有油的话,继续驾驶。还有一种情况呢?如果达到了,当然没必要继续驾驶了。
- If (~arrived) then keep_driving = ~gas_tank_empty;
上面两个小例子的代码放到一个模块中:
// synthesis verilog_input_version verilog_2001
module top_module (
input cpu_overheated,
output reg shut_off_computer,
input arrived,
input gas_tank_empty,
output reg keep_driving ); //
always @(*) begin
if (cpu_overheated)
shut_off_computer = 1;
else
shut_off_computer = 0;
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty;
else
keep_driving = 0;
end
endmodule
最后附上,以前的总结:
23、写出会生成锁存器的三种情况?
1)组合逻辑中,if语句缺少else,或者else内未给输出赋值;
module test ( input [1:0] sel, input a, input b, input c, output out ); reg out; always@(*) begin if(sel == 2'b00) out = a; else if(sel == 2'b01) out = b; else if(sel == 2'b10) out = c; end endmodule
如果赋值了呢?
module test ( input [1:0] sel, input a, input b, input c, input d, output out ); reg out; always@(*) begin if(sel == 2'b00) out = a; else if(sel == 2'b01) out = b; else if(sel == 2'b10) out = c; else out = d; end endmodule
猜想:时序逻辑中if缺少else会怎么样?
module test ( input clk, input [1:0] sel, input a, input b, input c, //input d, output out ); reg out = 0; always@(posedge clk) begin if(sel == 2'b00) out <= a; else if(sel == 2'b01) out <= b; else if(sel == 2'b10) out <= c; //else out <= d; end endmodule
时序逻辑中if不缺少else会怎么样?
module test ( input clk, input [1:0] sel, input a, input b, input c, input d, output out ); reg out = 0; always@(posedge clk) begin if(sel == 2'b00) out <= a; else if(sel == 2'b01) out <= b; else if(sel == 2'b10) out <= c; else out <= d; end endmodule
2)组合逻辑中case缺少中情况未列全且缺少default,或者default中没有给输出赋值,或者自己赋值给自己,就会生成锁存器(Latch);
module test ( //input clk, input [1:0] sel, input a, input b, input c, //input d, output out ); reg out = 0; always@(*) begin case(sel) 2'b00: out = a; 2'b01: out = b; 2'b10: out = c; endcase end endmodule
如果组合逻辑case中default没有缺少,并且给输出赋值了,会是什么样子?
module test ( //input clk, input [1:0] sel, input a, input b, input c, input d, output out ); reg out; always@(*) begin case(sel) 2'b00: out = a; //2'b01: out = b; //2'b10: out = c; //2'b11: out = d; default: out = d; endcase end endmodule
3)组合逻辑中always@()块内敏感列表没有列全;
第三种情况,大概的意思就是如果敏感列表没有补全,该触发的时候没有触发,那么还不是保存了之前的输出结果,因而会生成锁存器。