1.4.4 if语句锁存器(或寄存器)
常见错误来源:如何避免生成锁存器
在设计电路时,你首先需要从电路的角度进行思考:
- 我想要这个逻辑门
- 我想要一个组合逻辑块,它有这些输入并产生这些输出
- 我想要一个组合逻辑块后面跟着一组触发器(flip-flops)
你不应该先编写代码,然后再希望它能生成一个合适的电路。
- 如果(cpu过热) 则 shut_off_computer = 1;
- 如果(~到达) 则 keep_driving = ~油箱为空;
语法上正确的代码不一定能生成合理的电路(组合逻辑+触发器)。 通常的原因是:“除了你指定的情况外,其他情况会发生什么?” Verilog的回答是:保持输出不变。
这种“保持输出不变”的行为意味着当前状态需要被记住,因而产生了锁存器。组合逻辑(如逻辑门)不能记忆任何状态。要注意警告(10240):“...推断出锁存器(latch)”的消息。除非锁存器是故意设置的,否则几乎总是表示存在一个错误。组合电路在所有条件下必须为所有输出分配一个值。这通常意味着你总是需要else子句或为输出分配一个默认值。
演示
下面的代码包含错误行为,会创建锁存器。修复这些错误,以便仅在计算机真正过热时关闭计算机,并且在到达目的地或需要加油时停止驾驶。
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 );