Search code examples
processwhile-loopvhdlshiftsynthesis

VHDL shift operators?


I'm still trying to get used to some of the quirks of VHDL and I'm having a bit of an issue. First off, I understand that shift operators like rol, ror, ssl, srl, etc. are not synthesizeable. The purpose of this lab is to use a golden model to check against a synthesizeable version of the same thing in a testbench.

Now, the purpose of this program is to convert thermometer code into a 3-bit binary number. So, in other words, thermometer code "00000001" = "001", "00000011" = "010", "00000111" = "011", etc. I'm basically trying to count the number of 1's in the string from right to left. There will be no case where a '0' is placed between the string of 1's, so the vector "00011101" is invalid and will never occur.

I've devised a non-synthesizeable (and so far, non-compile-able) algorithm that I can't figure out how to get working. Basically, the idea is to read the thermometer code, shift it right and increment a counter until the thermometer code equals zero, and then assign the counter value to the 3-bit std_logic_vector. Below is the code I've done so-far.

library ieee;
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all;

entity therm2bin_g is
    port(therm : inout std_logic_vector(6 downto 0); -- thermometer code
         bin : out std_logic_vector(2 downto 0); -- binary code 
         i : integer range 0 to 7);
end therm2bin_g;    

architecture behavioral_g of therm2bin_g is
begin

golden : process(therm)
begin

    while(therm /= "00000000") loop
        therm <= therm srl 1;
        i = i + 1;      
    end loop;

    bin <= std_logic'(to_unsigned(i,3));

end process golden;
behavioral_g;

Solution

  • here's a version that is synthesisable. the while loop is replaced by a for loop. srl is implemented explicitly:

    entity therm2bin_g is
    port(therm : inout std_logic_vector(6 downto 0); -- thermometer code
         bin : out std_logic_vector(2 downto 0); -- binary code 
         i : out integer range 0 to 7);
    end therm2bin_g;    
    
    architecture behavioral_g of therm2bin_g is
    begin
    
    golden : process(therm)
        variable i_internal: integer range 0 to 7;
    begin
        i_internal:=0;
        for idx in 0 to therm'length loop
            if therm/="0000000" then
                therm<='0' & therm(therm'left downto 1);
                i_internal := i_internal + 1;     
            end if;
        end loop;
    
        bin<=std_logic_vector(to_unsigned(i_internal,bin'length));
        i<=i_internal;
    
    end process golden;
    end behavioral_g;