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 <= (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 <= 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 <=
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 => A(N downto to_integer(unsigned(X))), others => 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.
Best Answer
Don't worry about it. A barrel shifter is just an array of multiplexers. If you have N different shift amounts, then the multiplexers need to have N inputs each. It doesn't matter if the shift amounts are positive or negative. The amount of logic synthesized in any case will be exactly the same.