How to shift left/right a STD_LOGIC_VECTOR value within a WHEN statement?
There are a couple of ways to go with this. If you want to use sra, then you need to use the correct types. The left operand must be a BIT_VECTOR and the right must be an integer. It's output is a BIT_VECTOR. So you can define your inputs and outputs as BIT_VECTOR instead of STD_LOGIC_VECTOR and then use a cast to get just your X into an integer. I think the proper casts would be something like this (but you'll have to double check me as I don't have a VHDL compiler on this machine):

--Declaration
A, B, X : in  BIT_VECTOR(N downto 0);
--Usage
OUTPUT &lt;= (A sra to_integer(unsigned(to_stdlogicvector(X)) WHEN OPERATION = "1001" ELSE


Or, if possible define A as a BIT_VECTOR and X as a STD_LOGIC_VECTOR to leave out the extra cast.

Alternatively, you could continue to use STD_LOGIC_VECTOR for your inputs and outputs. But you would then need to cast both operands to the appropriate types and then cast the output:

--Declaration
A, B, X : in  STD_LOGIC_VECTOR(N downto 0);
--Usage
OUTPUT &lt;= to_stdlogicvector(to_bitvector(A) sra to_integer(unsigned(X)) WHEN OPERATION = "1001" ELSE


These should all be available in ieee.numeric_std.ALL and IEEE.STD_LOGIC_1164.



The difference between BIT_VECTOR and STD_LOGIC_VECTOR is that BIT_VECTOR only has two values: 0 and 1. Whereas STD_LOGIC_VECTOR has nine: U, X, 0, 1, Z, W, L ,H and -. Where:

U = uninitialized
X = unknown - a multisource line is driven '0' and '1' simultaneously (*)
0 = logic 0
1 = logic 1
Z = high impedance (tri state)
W = weak unknown
L = weak "0"
H = weak "1"
-  = don't care

In general it is better to use STD_LOGIC_VECTOR as it is more flexible and a better model of real world signals.



Looking at your code for the concatenation, I'm not entirely sure of what you're trying to do. It looks like you're trying to assign the MSB of X concatenated with the MSB down to the LSB + 1 of X to A and then assign that to TEMP_OUTPUT. I think it's the double &lt;= assignment that is causing the error.

What you want for an arithmetic right shift is to set the right most bits, less shift number of most significant bits of the output to the left most bits less shift number of least significant bits of the input. Then set all of the shift number of most significant bits of the output to the most significant bit of the input.

The first part is a bit tricky but the second part can easily be accomplished with the others keyword.

--|right most - shift # * MSB of output|   |left most - shift # * LSB of input| |MSBs of output|  
((N - to_integer(unsigned(X))) downto 0 =&gt; A(N downto to_integer(unsigned(X))), others =&gt; A(N)) WHEN OPERATION = "1001" ELSE


The basic problem you are having is one of type conversions. So you will need to think about what signal needs to be of what type and what types of operands the functions you are using require and cast accordingly.