Search code examples
vhdlxilinx

Non-static loop limit exceeded


I want to implement the K&R algorithm for hamming weight calculation of 256 bit vector. I have written my code in vhdl as:

entity counter_loop is
    Port ( dataIn : in  STD_LOGIC_VECTOR (255 downto 0);
              dataOut : out STD_LOGIC_VECTOR (8 downto 0);
           threshold : in  STD_LOGIC_VECTOR (8 downto 0);
           clk : in  STD_LOGIC;
           flag : out  STD_LOGIC);
end counter_loop;

architecture Behavioral of counter_loop is
    signal val : STD_LOGIC_VECTOR (255 downto 0) := X"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
begin
    process (clk)
        variable count : STD_LOGIC_VECTOR (8 downto 0):= "000000000";       
    begin
        flag <= '0';
        val <= dataIn;
        --if(clk'event and clk = '1') then 
            while (val > 0) loop
                count := count+1;
                val <= (val and (val-1));
                if (count > threshold) then
                    flag <= '1';
                end if;
            end loop;
                dataOut <= count;
        --end if;
    end process;
end Behavioral;

But, while synthesizing it using Xilinx, the error comes up as

Line 53: Non-static loop limit exceeded

Any clues please?

P.S: Line 53 is - while (val > 0) loop


Solution

  • So, I'm going to ignore issues of things actually meeting timing (val - 1 is expensive) and actually talk about your logic.

    Here's a piece of your code:

    signal val : std_logic_vector(255 downto 0) := (others => '1');
    
    process (clk)
    begin
        while (val > 0) loop
            val <= (val and (val-1));
        end loop;
    end process;
    

    val is a signal, not a variable. That means it will be updated when you finish the delta cycle. Which in this case, will be never. So you have an infinite loop.


    If you're just trying to calculate the popcount of a number, then why don't you just do this. Although I doubt this will meet timing as well (Probably need to break it up over multiple clock cycles).

    process (clk)
        variable count : std_logic_vector(8 downto 0) := "0" & x"00";
    begin
        if rising_edge(clk) then
            for i in dataIn'range loop
                if dataIn(i) = '1' then
                    count := count + 1;
                end if;
            end loop;
    
            dataOut <= count_i;
        end if;
    end process;
    

    And finally, most people would argue that algorithms designed for C code often perform poorly in hardware, because hardware has different capabilities than a fixed processor.