2

I have a problem in synthesis with my VHDL code : I am trying to get the logarithm value of an input signal S_ink:

My code :

entity ....
....

architecture rtl of myEntity is
attribute syn_looplimit : integer;
attribute syn_looplimit of loopabc : label is 16384;

logcalc:process(I_clk)
  variable temp : integer;
  variable log  : integer;
  begin

    if(I_clk'event and I_clk='1') then
      if (IN_rst='0') then
        S_klog<=0;
        temp:=0; 
        log:=0;
      else 
        temp := S_ink+1;               --S_ink is an input of my entity (integer)
        log:=0;
        loopabc:while (temp/=0) loop
          temp:=temp/2;
          log :=log+1;
        end loop loopabc;
        S_klog<=3*log;
      end if;
    end if;
end process;

It works very well in simulation but doesn't synthesize. The error message is : "While loop is not terminating. You can set the maximum of loop iterations with the syn_looplimit attribute"

However, this code synthesize (but that is not what I want)

entity ....
....

architecture rtl of myEntity is
attribute syn_looplimit : integer;
attribute syn_looplimit of loopabc : label is 16384;

logcalc:process(I_clk)
  variable temp : integer;
  variable log  : integer;
  begin

    if(I_clk'event and I_clk='1') then
      if (IN_rst='0') then
        S_klog<=0;
        temp:=0; 
        log:=0;
      else
        temp := 3000;       -- a random constant value
        log:=0;
        loopabc:while (temp/=0) loop
          temp:=temp/2;
          log :=log+1;
        end loop loopabc;
        S_klog<=3*log;
      end if;
    end if;
end process;

2 Answers 2

2

When the synthesis tool translates the design, it will make a circuit with a topology that does not depend on the data values, but where the wires carries the data values. The circuit must have a fixed calculation latency between each level of flip-flops, so timing analysis can determine if the amount of logic between flip-flops can fit for the specified frequency. In this process any loops are unrolled, and you can think of this as converting the loop to a long sequence of ordinary (non-loop) statements. To do this unrolling, the synthesis tool must be able to determine the number of iterations in the loops, so it can repeated the loop body this number of times when doing loop unrolling.

In the first code example the number of iterations in the loop depends on the S_ink value, so the synthesis tool can't unroll the loop to a fixed circuit, since the circuit depends on the data value.

In the second code example the synthesis tool can determine the number of iterations in the loop, thus do the unrolling to a fixed circuit.

One way to address this is make the algorithm with a fixed number of iteration, where this number of iterations can handle the worst case input data, and where any superfluous iteration on other input data will not change the result.

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you for your response. The problem is S_ink is an integer between 1 and 16384 .... so my "fixed number of iteration loop" would be too long. The number of iterations is unknown by the synthesis tool but the syn_looplimit attribute should resolve this problem ?
@ Dimitri Lecomte If the maximum value of S_ink is 16384, the maximum number of iterations of your loop is 14 (or 15?). Always loop that number of times, but only execute log := log + 1; if temp greater than zero.
@Morten Zilmer Ironically, implement the same algorithm using a recursive function and it synthesises just fine.
Thank you for your response. You are right the maximum value is 14. I will post the correct answer but I still don't understand why the syn_looplimit doesn't work in my first example. With this property, the synthesis tool know the maximum number of iterations ...
@DimitriLecomte: I assume you use Lattice, since I could not find attribute syn_looplimit defined for Altera nor Xilinx. In the example Lattice gives the number of loops is still a constant, thus not data dependent, so it appears that syn_looplimit is only a hint to the tool. So even when applying syn_looplimit the tool can't determine the number of iterations when unrolling the loop.
|
1

Solution :

process(I_clk)
  variable temp : integer;
  variable log  : integer;
  begin

    if(I_clk'event and I_clk='1') then
      if (IN_rst='0') then
        S_klog<=0;
        temp:=0; 
        log:=0;
      else 
        temp := S_ink+1;
        log:=0;
        for I in 1 to 14 loop
          temp := temp/2;
          if (temp /=0) then
            log :=log+1;
          end if;
        end loop;
        S_klog<=3*log;                           -- 3*log because of my application
      end if;
end if;
end process;

2 Comments

I would recommend using a for loop rather than a while loop in synthesisable code., ie for I in 1 to maxloop loop or something like that. It is more likely to synthesise on any old synthesiser, I would have thought. Anyway, you have effectively coded your own for loop manually using a while loop.
While loop changed. Thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.