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.
- Shift functions are found in numeric_std package file
- Shift functions can perform both logical (zero-fill) and arithmetic (keep sign) shifts
- Type of shift depends on input to function. Unsigned=Logical, Signed=Arithmetic
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"; begin process is begin -- 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;
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) begin 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