I have this following implementation of a shift left operation. I know that this implementation is weird or may not be synthesizable because the size of the cResult constant depends on the shift width. This code however simulates fine and is synthesised by Quartus 20.1, but the resulting logic does match the expected behavior (see attached RTL). Instead of the dynamic selected shift width it always performs a shift left by 1 bit. My iShift input is definitely not a constant 1 input.
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity my_shift is port ( iClk : in std_logic; iData : in unsigned(15 downto 0); iShift : in unsigned(3 downto 0); oData : out unsigned(15 downto 0) ); end entity; architecture behaviour of my_shift is function my_shift_left(x : unsigned; N : integer) return unsigned is constant cResult : unsigned := x & (N-1 downto 0 => '0'); begin return resize(cResult, x'length); end function; begin process begin wait until rising_edge(iClk); oData <= my_shift_left(iData, to_integer(iShift)); end process; end behaviour;
When I change the constant to a variable the sythesis fails with "expression is not constant" error. I had this code burried in other logic and it took me a while to find this. Please direct this to the appropriate people so that this bug gets fixed.