vhdl – shift a std_logic_vector of n bit to right or left

vhdl – shift a std_logic_vector of n bit to right or left

Use the `ieee.numeric_std` library, and the appropriate vector type for the numbers you are working on (`unsigned` or `signed`).

Then the operators are `sla`/`sra` for arithmetic shifts (ie fill with sign bit on right shifts and lsb on left shifts) and `sll`/`srl` for logical shifts (ie fill with 0s).

You pass a parameter to the operator to define the number of bits to shift:

``````A <= B srl 2; -- logical shift right 2 bits
``````

Update:

I have no idea what I was writing above (thanks to Val for pointing that out!)

Of course the correct way to shift `signed` and `unsigned` types is with the `shift_left` and `shift_right` functions defined in `ieee.numeric_std`.

The shift and rotate operators `sll`, `ror` etc are for vectors of `boolean`, `bit` or `std_ulogic`, and can have interestingly unexpected behaviour in that the arithmetic shifts duplicate the end-bit even when shifting left.

And much more history can be found here:

http://jdebp.eu./FGA/bit-shifts-in-vhdl.html

However, the answer to the original question is still

``````sig <= tmp sll number_of_bits;
``````

There are two ways that you can achieve this. Concatenation, and shift/rotate functions.

• Concatenation is the manual way of doing things. You specify what part of the original signal that you want to keep and then concatenate on data to one end or the other. For example: tmp <= tmp(14 downto 0) & 0;

• Shift functions (logical, arithmetic): These are generic functions that allow you to shift or rotate a vector in many ways. The functions are: sll (shift left logical), srl (shift right logical). A logical shift inserts zeros. Arithmetric shifts (sra/sla) insert the left most or right most bit, but work in the same way as logical shift. Note that for all of these operations you specify what you want to shift (tmp), and how many times you want to perform the shift (n bits)

• Rotate functions: rol (rotate left), ror (rotate right). Rotating does just that, the MSB ends up in the LSB and everything shifts left (rol) or the other way around for ror.

Here is a handy reference I found (see the first page).

vhdl – shift a std_logic_vector of n bit to right or left

Personally, I think the concatenation is the better solution. The generic implementation would be

``````entity shifter is
generic (
REGSIZE  : integer := 8);
port(
clk      : in  str_logic;
Data_in  : in  std_logic;
Data_out : out std_logic(REGSIZE-1 downto 0);
end shifter ;

architecture bhv of shifter is
signal shift_reg : std_logic_vector(REGSIZE-1 downto 0) := (others<=0);
begin
process (clk) begin
if rising_edge(clk) then
shift_reg <= shift_reg(REGSIZE-2 downto 0) & Data_in;
end if;
end process;
end bhv;
Data_out <= shift_reg;
``````

Both will implement as shift registers. If you find yourself in need of more shift registers than you are willing to spend resources on (EG dividing 1000 numbers by 4) you might consider using a BRAM to store the values and a single shift register to contain indices that result in the correct shift of all the numbers.