Always if2
一个常见的错误:如何避免产生锁存器。
当设计一的电路的时候,你首先应该从电路的角度去思考。
- 我想要一个逻辑门
- 我想要一个有着3和输入和3输出的组合逻辑电路。
- 我想要一个后边跟着一个触发器的组合逻辑电路。
你必须不能先写代码,然后就期待它能成为一个真正意义上的电路。
- if(cpu_overheated) then shut_off_computer = 1;
- if(~arrived) then keep_driving = ~gas_tank_empty;
语法正确的代码不意味着就一定可以变成合理的电路(组合逻辑 + 触发器)。
一般的理由是 “当你没有具体指定一些情况的时候会发生什么?”。
Verilog 的答案是:“保持输出不变”。
这种“保持输出不变” 的行为意味着当前的状态需要保存下来,这就会产生锁存器。
组合逻辑(例如:逻辑门)是不能记录任何状态的。注意警告“(10240): … inferring latch(es)”信息。
除非这个锁存器是你故意制造的,但是大多数情况都意味着一个 BUG。
组合逻辑电路必须要针对所有的情况设计一个值。这通常意味着你需要 else 或者给 output
指定默认值。
示例:
下面的代码包含了一个不正确的行为,导致产生了一个锁存器。解决掉这个 BUG 如果
你需要在过热的时候关掉电脑,不需要开车在你已经到地方了或者你也不需要去加油。
always @(*) begin
if (cpu_overheated)
shut_off_computer = 1;
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty;
end
答案
// 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 || gas_tank_empty)
keep_driving = 0;
else
keep_driving = 1;
end
endmodule