2017-03-31 42 views
1

赛灵思正在推断我写的VHDL代码的锁存器。我查了可能的原因,发现这通常是由于不完整的if或case语句。我已经经历了,并确保包括其他人和别人发言时,但我仍然收到警告。我相信这也影响到我正在研究的另一个项目,所以我想了解为什么会出现这种情况。赛灵思VHDL闩锁警告故障排除

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

entity state_machine is 
    port(trig, en: in std_logic; cstate,nstate: out std_logic_vector(0 to 2)); 
end state_machine; 

architecture Behavioral of state_machine is 
signal cstate_s,nstate_s: std_logic_vector(0 to 2); 

begin 
cstate <= cstate_s; 
nstate <= nstate_s; 

process(en, cstate_s) 
begin 
    if en = '1' then 
     nstate_s <= "111"; 
     if cstate_s = "111" then 
      nstate_s <= "011"; 
     elsif cstate_s = "011" then 
      nstate_s <= "100"; 
     elsif cstate_s = "100" then 
      nstate_s <= "101"; 
     elsif cstate_s = "101" then 
      nstate_s <= "110"; 
     elsif cstate_s = "110" then 
      nstate_s <= "111"; 
     else 
      null; 
     end if; 
    else 
     null; 
    end if; 
end process; 

process(trig, nstate_s) 
begin 
    if rising_edge(trig) then 
     cstate_s <= nstate_s; 
    else 
     null; 
    end if; 
end process; 

end Behavioral; 

警告:XST:737 - 找到3位锁存器信号。锁存器可以从不完整的情况或者如果报表中生成 。我们不推荐在FPGA/CPLD设计中使用锁存器,因为它们可能导致 时序问题。

+1

您的n语句优先级编码器/多路复用器nstate_s不完整。您覆盖条件值“011”,“100”,“101”,“110”和“111”,并具有一个空语句的else语句。这意味着对于条件值“000”,“001”和“010”,您不会在nstate_s定义锁存器上驱动不同的值。更改else的情况来驱动cstate_s的当前值。 else null在cstate_s寄存器中是多余的,它保存在trig的上升沿设置的值。您应该可以在不使用空语句的情况下完成设计生涯。 – user1155120

+1

合成中使用的唯一值是二进制表示值('0','1','L'和'H'映射为'0'和'1',而'Z'用于推断高阻抗状态。其他(或其他选择的情况)应该覆盖合成的二进制值以及所有未指定的值以进行模拟。这两种用法不兼容。参见IEEE Std 1076-2008 16.8.2标准逻辑类型的解释。合成中忽略指定金属值(U','X','W'和' - ')的语句。 – user1155120

回答

3

对于存在时合成的组合过程要被合成的无闩锁,必须有beginend process;其中过程的所有输出未分配之间没有路径。这被称为完成分配。该过程的输出是在其内任何地方分配的任何signal

你有这样的路径。当执行任何包含null语句的路径时,您的第一个进程(nstate_s)的输出未分配给。因此,你将得到合成锁存器。只有null声明没有意义。如果您真的不在乎在这些路径中为您的输出分配了什么值,请将输出分配给'-',这意味着不在意VHDL中的

顺便说一句(假设trig是一个时钟),你的第二个过程是不组合(这是顺序),所以你不必完全服从分配;你的else分支是不必要的。