VHDL 推断锁存器
VHDL inferring latches
我有一个关于 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;
困扰我的警告消息是这样的:
Warning (10631): VHDL Process Statement warning at thermo.vhd(19): inferring latch(es) for signal or variable "ONOFF", which holds its previous value in one or more paths through the process<
就像我说的代码在 ModelSim 上运行正常,但这让我觉得我做事的方式是错误的。有什么建议么 ?
谢谢
丹尼 J
指定进程保存 ONOFF
的当前值,行:
ELSE ONOFF := ONOFF;
保持基于组合输入的值,如 Tact
和 Tset
,需要锁存器,正如警告中所报告的,因为通常锁存器意味着设计者创建的代码具有无意的副作用.
如果你想保持状态,那么考虑制作一个时钟进程; 中提供了模板。
如果您想要组合输出,则获取内部 ONOFF
过程变量的脊,并确保在 if
语句的所有分支中分配显式值。
您已经为信号 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" 优先。 (如果需要可以翻转。)如果表达式中的 none 为真,则按照触发器的要求保存旧状态。
我有一个关于 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;
困扰我的警告消息是这样的:
Warning (10631): VHDL Process Statement warning at thermo.vhd(19): inferring latch(es) for signal or variable "ONOFF", which holds its previous value in one or more paths through the process<
就像我说的代码在 ModelSim 上运行正常,但这让我觉得我做事的方式是错误的。有什么建议么 ? 谢谢 丹尼 J
指定进程保存 ONOFF
的当前值,行:
ELSE ONOFF := ONOFF;
保持基于组合输入的值,如 Tact
和 Tset
,需要锁存器,正如警告中所报告的,因为通常锁存器意味着设计者创建的代码具有无意的副作用.
如果你想保持状态,那么考虑制作一个时钟进程;
如果您想要组合输出,则获取内部 ONOFF
过程变量的脊,并确保在 if
语句的所有分支中分配显式值。
您已经为信号 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" 优先。 (如果需要可以翻转。)如果表达式中的 none 为真,则按照触发器的要求保存旧状态。