错误:超出了非静态循环限制

0 vhdl

下面是非恢复平方根算法.它工作正常,但在综合过程中显示错误:"第46行:超出非静态循环限制".

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;

ENTITY code IS
    GENERIC(n: NATURAL:= 8);
    PORT(
        Xin: IN STD_LOGIC_VECTOR(2*n-1 DOWNTO 0);
        clk :IN STD_LOGIC ;
        root: OUT STD_LOGIC_VECTOR(n-1 DOWNTO 0) ;
        root2: OUT STD_LOGIC_VECTOR(2*n-1 DOWNTO 0) ;
        intval: IN STD_LOGIC_VECTOR(n-1 DOWNTO 0)  
    );
END code;

architecture Behavioral of code is

    Signal Outp : STD_LOGIC_VECTOR(n-1 DOWNTO 0);
    Signal Const1 : STD_LOGIC_VECTOR(n-1 DOWNTO 0) ;
    Signal Const2 : STD_LOGIC_VECTOR(n-1 DOWNTO 0) ;

--Signal Var : STD_LOGIC_VECTOR(n-1 DOWNTO 0);

begin

    Const1 <= "00000010";
    Const2 <= "00000000";
    --D <= intval;
    --Var <= intval;

    Process (clk) 
        Variable Acc1 : STD_LOGIC_VECTOR(2*n-1 DOWNTO 0);
        Variable Acc2 : STD_LOGIC_VECTOR(n-1 DOWNTO 0);
        Variable D   : STD_LOGIC_VECTOR(n-1 DOWNTO 0);
        Variable Var : STD_LOGIC_VECTOR(n-1 DOWNTO 0);
        Variable Q : STD_LOGIC_VECTOR(2*n-1 DOWNTO 0);
    begin
        Var := "00000000";
        D   := intval;
        Var := intval;

        while (Var > "00000000") loop

            Q := signed(D)*signed(D);
            Acc1 := signed(Xin) - signed(Q);

            if  (Acc1 = "0000000000000000") then
                var:= Const2;

            elsif (Acc1 < "1000000000000000") then
                --root2<=Acc1;
                Acc2 := '0' & var(n-1 downto 1);
                Var := Acc2;
                D := signed(D) + signed(Var);

            elsif (Acc1 > "0111111111111111") then
                --root2<=Acc1; 
                Acc2 := '0' & var(n-1 downto 1);
                Var := Acc2;
                --root <= Var;
                D := signed(D) - signed(Var);

            end if;
        end loop;

        Outp <= D;
    end process;

    root <= Outp;
end Behavioral;
Run Code Online (Sandbox Code Playgroud)

Bri*_*ond 5

除非你正确地重新格式化,否则我不会阅读该代码.所以我只是给你一个问题的近似描述.[编辑:有些人确实重新格式化了]

合成在处理具有非静态边界的循环方面不是很好.当您考虑它时,这应该是显而易见的:对于合成,循环(除非它们包括显式WAIT语句)被展开,直到每个迭代可以并行执行.这意味着循环边界定义了生成的硬件的大小.

所以非静态边界意味着在硬件实际运行之前你不知道需要多少硬件!到那时生成更多门有点太晚了......

答案是将算法转换为具有静态循环边界的等效算法.在实践中,这通常并不困难:简单地转换

while (Var > "00000000") loop
   do something;
end loop;
Run Code Online (Sandbox Code Playgroud)

constant max_iterations : natural := <some number>;

for i in 1 to max_iterations loop
   -- assuming Var is numeric_std.unsigned, you can simply compare it to 0
   if Var > 0 then      
         do something
   end if;
end loop;
Run Code Online (Sandbox Code Playgroud)