0

Below is the non restoring square root algorithm. It's working fine but during synthesis it's showing an error : "Line 46: Non-static loop limit exceeded".

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;
Cœur
  • 37,241
  • 25
  • 195
  • 267
user2195397
  • 1
  • 1
  • 1
  • 1
    In VHDL, you can use `elsif` instead of `else if`, which would require only one `end if`. You can see an example of it on [this question](http://stackoverflow.com/questions/14113125/short-way-to-write-vhdl-priority-encoder). – Bill Lynch Mar 21 '13 at 16:49

3 Answers3

5

I'm not going to read that code unless you reformat it properly. So I'll just give you an approximate description of the problem. [Edit : some kind person did reformat it]

Synthesis is not very good at handling loops with non-static bounds. This should be obvious when you think about it : for synthesis, loops (unless they include explicit WAIT statements) are unrolled until every iteration can be performed in parallel. Which means that the loop bounds define the size of the hardware generated.

So non-static bounds imply that you don't know how much hardware you need until the hardware is actually running! By which time it is a bit too late to generate more gates...

The answer is to transform the algorithm into an equivalent one with static loop bounds. In practice this usually isn't difficult : simply transform

while (Var > "00000000") loop
   do something;
end loop;

into

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;
1

Your process is sensitive to clk.

However, you also need (for the synthesiser) to say what edge of the clock you want to work on.

The simulator will be running your code on every clock edge (both rising and falling). The synthesiser will just run the code all the time, and it really wants to see clock edges.

If you wrap your process text in a

if rising_edge(clk) then

end if;

phrase, it will help.

Martin Thompson
  • 16,395
  • 1
  • 38
  • 56
0

be aware that you are defining hardware! as loops are unrolled in synthesis, the bounds must be static.

however, even if you use a for loop with static bounds, you will most probably define a whole lot of resources (e.g. with n=8 you would lead to 256 multipliers!) that are probably not available in a real system. try to adjust your code to use some pipelining and optimize for resource and speed!

for synthesisable code you should not only put the clock in the sensitivity list but also define the active clock edge

Process (clk)      
    ...   
begin
    if rising_edge(clk) then
        ...
baldyHDL
  • 1,387
  • 1
  • 10
  • 16