Shift Left, Shift Right - VHDL Example

Create shift registers in your FPGA or ASIC

Performing shifts in VHDL is done via functions: shift_left() and shift_right(). The functions take two inputs: the first is the signal to shift, the second is the number of bits to shift. Shifting is a quick way to create a Shift Register. There are two types of shifts: Logical and Arithmetic. A logical shift means that the new bits are replaced with zeros. Arithmetic shift means that the replaced bits are substituted in order to maintain the sign of the original number.

At one point, there were actual shift operators built into VHDL. These were: srl, sll, sra, sla. However these shift operators never worked correctly and were removed from the language. This website goes into great detail about the history of these VHDL shift operators and discusses why they have been replaced by shift_right() and shift_left() functions.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;               -- Needed for shifts
entity example_shift is
end example_shift;

architecture behave of example_shift is
  signal r_Shift1     : std_logic_vector(3 downto 0) := "1000";
  signal r_Unsigned_L : unsigned(3 downto 0)         := "0000";
  signal r_Unsigned_R : unsigned(3 downto 0)         := "0000";
  signal r_Signed_L   : signed(3 downto 0)           := "0000";
  signal r_Signed_R   : signed(3 downto 0)           := "0000";

  process is
    -- Left Shift
    r_Unsigned_L <= shift_left(unsigned(r_Shift1), 1);
    r_Signed_L   <= shift_left(signed(r_Shift1), 1);
    -- Right Shift
    r_Unsigned_R <= shift_right(unsigned(r_Shift1), 2);
    r_Signed_R   <= shift_right(signed(r_Shift1), 2);

    wait for 100 ns;
  end process;
end architecture behave;

VHDL Shift Register
Shift Register - Modelsim Results

Shifting to Create a Shift Register

Below is VHDL code showing how to create a shift register. Shift registers are very important for aligning data in your FPGA. The shift function makes this code clean and compact. The shift register is 4 clock cycles long. It will delay any input by 4 clock cycles. Later on in your code, if you look for Input_Delay(3) it will show the same thing that was on Input 4 clock cycles ago.

signal Input_Delay : unsigned(3 downto 0);
process (clock)
  if rising_edge(clock) then
    -- Create a delayed version of signal Input
    Input_Delay    <= shift_left(Input_Delay, 1);
    Input_Delay(0) <= Input;

    -- FYI: Same Code not using Shift Operator:
    Input_Delay(1) <= Input_Delay(0);
    Input_Delay(2) <= Input_Delay(1);
    Input_Delay(3) <= Input_Delay(2);
    Input_Delay(0) <= Input;
    if Input_Delay(3) = '1' then
      -- Do Stuff

Help Me Make Great Content!     Support me on Patreon!     Buy a Go Board!