常见的错误来源:如何避免latch
在设计电路时,必须首先考虑电路:
- 我想要这个逻辑门
- 我想要一个具有这些输入并生成这些输出的组合逻辑
- 我想要一个逻辑组合点,后跟一组触发器
你不能做的是先编写代码,然后希望它生成一个合适的电路。
- if(cpu_overheated) 则 shut_off_computer = 1;
- if(~arrived),则 keep_driving = ~gas_tank_empty;
语法正确的代码并不一定会产生合理的电路(组合逻辑+触发器)。通常的原因是:"在你指定的那些情况下会发生什么?Verilog的答案是:保持输出不变。
这种"保持输出不变"的行为意味着需要记住当前状态,从而产生闩锁。组合逻辑(例如,逻辑门)不记得任何状态。注意警告 (10240): ...推断闩锁"消息。除非闩锁是故意的,否则它几乎总是表明存在错误。组合电路必须在所有条件下为所有输出分配一个值。这通常意味着您始终需要 else 子句或分配给输出的默认值。
题目所给的错误示范:
always @(*) begin
if (cpu_overheated)
shut_off_computer = 1;
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty;
end
分析:这题主要是寻找if—else语句中错误。在组合电路中,所有的输出都必须要有分配值,即便默认也要在语句块中体现。题目所给的是两种情况:一是在计算机过热时选择关闭计算机(if),相反即在计算机不过热时计算机继续运行(else),这是在给出if的条件下,语句块默认的;二是(机动车)驾驶时,要停止驾驶的条件是:到达目的地或者没油时(if),相反在没到达目的地和汽车有油时汽车继续行驶(else),else语句是题目所给的隐藏条件,在语句块中也是需要体现的。
代码如下:
// 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