Search code examples
vhdlfpga

VHDL 10^x LUT With-Select


I have to write a VHDL code that calculates the 10^x function for integer values of x between zero and nine (including zero and nine). Entity should have one 4-bit unsigned integer (std_logic_vector) type input and one 32-bit unsigned integer (std_logic_vector) type output. 32 bit width is enough for 10^9. I have to use the LUT (Look-up table) logic for the solution. For this, I should use the signal assignment and with-select structure in the architecture block without using the process at all. By using with-select, I will have determined with a fixed assignment what the output (LUT) will be for each value of x.

Error when i start synthesizing: width mismatch in assignment; target has 32 bits, source has 1 bits

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity main is
Port ( 
    input : in std_logic_vector(3 downto 0);
    output: out std_logic_vector(31 downto 0)
     );
end main;

architecture Behavioral of main is

begin

with input select
   output <= "00000000000000000000000000000001" when "0000", --10^0
             "00000000000000000000000000001010" when "0001", --10^1
             "00000000000000000000000001100100" when "0010", --10^2
             "00000000000000000000001111101000" when "0011", --10^3
             "00000000000000000010011100010000" when "0100", --10^4
             "00000000000000011000011010100000" when "0101", --10^5
             "00000000000011110100001001000000" when "0110", --10^6
             "00000000100110001001011010000000" when "0111", --10^7
             "00000101111101011110000100000000" when "1000", --10^8
             "00111011100110101100101000000000" when "1001", --10^9
             "0" when others;
end Behavioral;

Solution

  • You understood what the problem was, so this answer is just to show you how to avoid the external computation of your ten 32-bits constants (with VHDL 2008), thanks to the ieee.numeric_std_unsigned package and a constant array of 32-bits vectors, computed by a function:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std_unsigned.all;
    
    entity main is
    ...
    end main;
    
    architecture Behavioral of main is
    
      type w32_array is array(0 to 15) of std_ulogic_vector(31 downto 0);
    
      function powers_of_ten return w32_array is
        variable res: w32_array := (others => (others => '0'));
      begin
        for i in 0 to 9 loop
          res(i) := to_stdulogicvector(10**i, 32);
        end loop;
        return res;
      end function powers_of_ten;
    
      constant pw10: w32_array := powers_of_ten;
    
    begin
    
      output <= pw10(to_integer(input));
    
    end architecture Behavioral;
    

    Note: and yes, it should be synthesisable, because it is the synthesizer that computes the constants during synthesis, not the synthesized hardware.