You are right, as the assignment is not constant, synthesis may not
recognize that it needs to build a multiplexer there. Quartus does also
not like it, so it's not just Vivado.
Here is a possible solution using a process:
1 | process (a, shiftAmt)
|
2 | begin
|
3 | b <= (others => '0'); -- to prevent latches from bein built
|
4 | for i in 0 to 2**WIDTH - 1 loop
|
5 | if (shiftAmt = i) then
|
6 | b <= a(i-1 downto 0) & a(2**WIDTH - 1 downto i);
|
7 | end if;
|
8 | end loop;
|
9 | end process;
|
This implements the multiplexer required by choosing based on the
shiftwidth.
Another possibility would be something like that:
1 | gshift: for i in 0 to 2**WIDTH - 1 generate
|
2 | begin
|
3 | b(i) <= a(2**WIDTH - 1 - shiftAmt) when ((shiftAmt + i) > (2**WIDTH - 1))
|
4 | else a(shiftAmt + i);
|
5 | end generate;
|
Which does exactly the same by assigning the correct source bit to the
target bit.
Not sure if the correct bit is picked, was just a short test if it
builds.
I still would just write like that:
1 | b <= std_logic_vector(unsigned(a) ror shiftAmt);
|
As it's easiest to read and hard to build an error into it.
All 3 variantes require exact same amount of ressources.