vhdl中的无限循环

Infinite loop in vhdl

我正在尝试从 std_logic_vector 中获取两位数。我知道......这不是一种专业的方法(我做的方式),但我正在学习中。我真正的问题是 'while' 循环。我不明白为什么它是一个无限循环。谁能帮忙? 在测试台中,d 的值为“10010”; 这是错误和代码:

[Synth 8-3380]loop condition does not converge after 2000 iterations [afisare.vhd:30]

第 30 行是 while aux>noua loop。我正在综合,之后想模拟

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity bcd is
    port( y0: out std_logic_vector(6 downto 0);
          y1: out std_logic_vector(6 downto 0);
          d: in std_logic_vector(4 downto 0);
          anode: out std_logic_vector(7 downto 0));
end bcd;


architecture afis of bcd is
begin
process(d)
variable prima: integer;
variable aux: std_logic_vector(4 downto 0);
variable din: std_logic_vector(3 downto 0);
variable noua: std_logic_vector(4 downto 0);
variable unu: std_logic;
variable zero: std_logic;
begin
prima:=0;
noua:="01001";
aux:=d;
unu:='1';
zero:='0';
while aux>noua loop
    if (aux(4)=unu and aux(3)=zero)  then
        aux(4):=zero;
    end if;
    if (aux(1)=unu and aux(0)=zero)  then
            aux(1):=zero;
     end if;
    aux:=aux xor noua;
    prima:=prima+1;
end loop;
din:=aux(3 downto 0);

case din is
    when "0000"=> y0<="0000001";
       when "0001"=>y0<="1001111";
       when "0010"=>y0<="0010010";
       when "0011"=>y0<="0000110";
       when "0100"=>y0<="1001100";
       when "0101"=>y0<="0100100";
       when "0110"=>y0<="0100000";
       when "0111"=>y0<="0001111";
       when "1000"=>y0<="0000000";
       when "1001"=>y0<="0000100";
       when others=>y0<="0110110";
end case;
case prima is 
when 0=>y1<="0000001";
when 1=>y1<="1001111";
when 2=>y1<="0010010";
when 3=>y1<="0000110";
when others=>y1<="0110110";
end case;
anode<="11111100";
end process;

end afis;

合成器不关心测试台,它会尝试创建一个硬件,该硬件将等效于您的循环并且适用于任何可能的输入。为了做到这一点,它以某种方式尝试了所有可能性 (32)。不幸的是,它显然不够聪明,无法检测到这个循环总是在最多 3 次迭代后终止(不确定这个“3”,我可能是错的)。

一般来说,对于综合来说,还是慎用循环为好(for循环的static bounds,while循环的static condition)。在这种情况下,很难说您是否超出了 Vivado 的能力范围。如果文档说综合支持 while 循环的非静态条件,您可以打开服务请求,您发现了一个错误。

总之,换个说法比较好。尝试固定迭代次数(通过模拟或简单推理验证3次就足够了,当然,我只是猜测):

for i in 1 to 3 loop
  if aux>noua then
    if (aux(4)=unu and aux(3)=zero) then
      aux(4):=zero;
    end if;
    if (aux(1)=unu and aux(0)=zero) then
      aux(1):=zero;
    end if;
    aux := aux xor noua;
    prima:=prima+1;
  end if;
end loop;