我对VHDL有疑问。下面的代码用于+/- 2度恒温器,它工作和模拟很好,但我有一些无法解释的警告,其中一个特别是真的在烦我。
LIBRARY IEEE;
USE IEEE.std_logic_1164.all, IEEE.std_logic_arith.all;
ENTITY thermo IS
PORT (
Tset, Tact: in integer;
Heaton: out std_logic
);
END ENTITY thermo;
ARCHITECTURE sequential OF thermo IS
BEGIN
PROCESS (Tact, Tset) IS
VARIABLE ONOFF: std_logic;
BEGIN
IF Tact <= (Tset - 2) then
ONOFF := '1';
ELSIF Tact >= (Tset + 2) then
ONOFF := '0';
ELSE ONOFF := ONOFF;
END IF;
Heaton <= ONOFF;
END PROCESS;
END ARCHITECTURE sequential;
警告我的警告信息是:
警告(10631):在thermo.vhd(19)处的VHDL过程语句警告:推断信号或变量“ONOFF”的锁存器,其在过程中的一个或多个路径中保持其先前值&lt;
就像我说的那样,代码在ModelSim上工作正常,但这让我觉得我的事情是错误的。有什么建议 ? 谢谢 Danny J
答案 0 :(得分:2)
指定进程使用以下行保存当前值ONOFF
:
ELSE ONOFF := ONOFF;
保持基于组合输入的值,如Tact
和Tset
,需要一个锁存器,如警告中所述,因为通常锁存意味着设计人员创建了具有无意副作用的代码。 / p>
如果你想保持状态,那么考虑做一个时钟进程; this answer中提供了一个模板。
如果需要组合输出,则获取内部ONOFF
过程变量的岭,并确保在if
语句的所有分支中分配显式值。
答案 1 :(得分:1)
您已为信号ONOFF
描述了SR latch。这在仿真中工作得很好但在FPGA中产生问题以及由分立元件构建的数字电路。
当表达式Tact <= (Tset - 2)
为真时,您的锁存器已设置。现在对锁存器当前处于状态'0'
和Tact = Tset
的时间点进行成像。因此,闩锁键'0'
如预期的那样。只要Tact
没有变化,这就有效。现在让温度下降到Tact = Tset-1
。根据上面的表达式,锁存器应保持在状态'0'
。但是,这在实际硬件中无法确保,因为表达式不会立即进行评估。相反,<=
运算符的多位比较器可能产生glitch,因为比较器本身由几个门组成。如果这些门中的一个切换速度比另一个更快,则可能存在中间结果,其中表达式为真,因此,您的锁存器变为'1'
。
要通知设计人员,锁存器容易出现毛刺,综合编译器会发出上述警告。为了解决这个问题,FPGA提供D flip-flops哪个状态仅在时钟边沿更新。 FPGA工具链的时序分析器确保在下一个上升(或下降)时钟边沿之前完成上述表达式的评估。所以,设计师不必担心毛刺!
您可以用VHDL描述时钟边沿触发的SR触发器,然后通过综合工具将其映射到FPGA的D触发器。代码样式如下:
signal Q : std_logic; -- declare signal in the declarations part of the architecture
...
process(clock)
begin
if rising_edge(clock) then -- flip-flop triggered at the rising clock edge
if set_expression then
Q <= '1';
elsif reset_expression then
Q <= '0';
end if;
end if;
end if;
SR触发器的状态保存在信号Q
中。我在这里使用了信号而不是变量,因为变量更难调试。 (我建议尽可能频繁地使用信号。)在此代码示例中,如果set_expression
和reset_expression
都为真,则“set”优先。 (如果需要,可以翻转。)如果没有任何表达式为真,则触发器根据需要保存旧状态。