Combinational Design for a 32-bit Barrel Shifter
Introduction
We are going to design a 32-bit combinational right barrel shifter here.
A 32-bit barrel shifter takes and rotates the bits right by the specified rotate
value of 0 to 31 (five bits). The rotation takes the bit in the MSB position and
moves it to the right by the specified value, all the bits to the right of MSB
are moved downward with all the values moving to the right until the LSB bit
is filled. The remainder of the bits fill the MSB bit downward in their
same bit order. The input is a 32-bit binary number, name as A,
a five-bit control word, name as C, and a 32-bit output, name as Q.
(A diagram below would be helpful if we didn't already know what about
barrel shifting).
Algorithm
The goal is to take the input values and pass them through a combinational
circuit that reorders the input bits by rotating them all by the specified
five bit input control word. A purely combinational barrel shifter can be
implemented by using five stages of Multiplexers.
The first stage takes the input and either barrel shifts it right by 16 places
or passes the value through unchanged. The selected value is passed to the
next stage which then shifts by 8, 4, 2, or 1. Thus, the total shift is the sum of
16 * Control(4) + 8 * Control(3) + 4 * Control(2) + 2 * Control(1) + 1* Control(0);
[As an aside, a combinatorial method is not the only way to do a barrel shift.
One could use a 32 bit shift register, and a 5 bit counter (loaded with the control
shift value), and just shift the register and decrement the counter on each clock
cycle, and stop when the shift control word reaches 0]
RTL Implementation
The RTL block diagram below has 8 blocks. The three register blocks added here
to store and buffer the input. This allows us to clock the values in and determine
the maximum clock period for a non-pipelined barrel shift.
Register, Reg_Din, can be reset, or loaded, and stores the 32 bit input value, Din.
Register, Reg_Cin, can be reset, or loaded, and stores the 5 bit input value, Cin.
Register, Reg_Dout, can be reset, or loaded, and stores the 32 bit output value, Dout.
(Dout is the final barrel shifted value.)
There are five combinational blocks.
These are Combo_Shft16, Combo_Shft8, Combo_Shft4, Combo_Shft2, and Combo_Shft1.
Each has a one bit input value that controls if the block passes directly
through the input 32 value, or performs a shift.
The Combo_Shft16 does a 16 bit shift, Combo_Shft8 does an 8 bit, and so on.
The stages are arranged in order with Combo_Shft16 having as input the 32-bit
buffered input signal, Buf_Din. The output of this stage is a 32-bit value,
Dout_Shft16. The output from the Combo_Shft16 block is input for the next block,
Combo_Shft8. The output from Combo_Shft8 feeds into the next block Combo_Shft4,
and so on till you reach the last stage whose output, Dout_Shft1, is buffered
by the register block, Reg_Dout. The output from the register block is the
final 32-bit barrel shifted value, Dout.
The control value for each stage is the buffered value of the input, Buf_Cntrl<4:0>.
The first bit, Buf_Cntrl<4>, is an input to the Combo_Shft16 stage,
if the value is 1 then this stage rotates its input value by 16.
The second stage, Combo_Shft8, is controlled in the same fashion by Buf_Cntrl<3>,
and so on.
Signal and block summary list in alphabetical order
Section 1. Input and Output signals to the entity
Cin<4:0> 5-bit input, encoding number bits to shift the input value, Din, to the right.
Din<31:0> 32-bit input value that is to be barrel shifted.
Dout<31:0> 32-bit output, rotated by number of places specified in the input value Cin.
Section 2. Alphabetical List of Register Blocks
Reg_Cin 5-bit register, load, reset. Used to store the input control signal value Cin.
Reg_Din 32-bit register, load, reset. Used to store the input control signal value Din.
Reg_Dout 32-bit register, load, reset. Used to store the result output, Dout.
Section 3. Alphabetical List of Combinational Blocks
Combo_Shft1 32-bit - 2to1 Mux's. Output is either input passed through or shifted by 1
Combo_Shft2 32-bit - 2to1 Mux's. Output is either input passed through or shifted by 2
Combo_Shft4 32-bit - 2to1 Mux's. Output is either input passed through or shifted by 4
Combo_Shft8 32-bit - 2to1 Mux's. Output is either input passed through or shifted by 8
Combo_Shft16 32-bit - 2to1 Mux's. Output is either input passed through or shifted by 16
Section 4. Alphabetical list of Signals (excludes entity inputs and outputs)
Buf_Din 32-bit output from the buffer register in block Reg_Din
Buf_Cntrl 5-bit output from the buffer register in block Reg_Cin
Dout_Shft1 32-bit output from the Combo_Shft1 block
Dout_Shft2 32-bit output from the Combo_Shft2 block
Dout_Shft4 32-bit output from the Combo_Shft4 block
Dout_Shft8 32-bit output from the Combo_Shft8 block
Dout_Shft16 32-bit output from the Combo_Shft16 block
RTL Block Diagram for a Combinational Right Barrel Shifter
VHDL Code
----------------------------------------------------------------------------------
-- Company: Computer Science
-- Engineer: Guili Liu
--
-- Create Date: 14:42:31 02/02/2009
-- Design Name: BarrelShft.vhd
-- Module Name: BarrelShft - Behavioral
-- Project Name: BarrelShifter
-- Target Devices: xc2vp30-6ff1152
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity BarrelShft is
Port ( Cin : in STD_LOGIC_VECTOR (4 downto 0);
Din : in STD_LOGIC_VECTOR (31 downto 0);
clk : in STD_LOGIC;
LoadDin : in STD_LOGIC;
LoadCin : in STD_LOGIC;
LoadDout : in STD_LOGIC;
Dout : out STD_LOGIC_VECTOR (31 downto 0));
end BarrelShft;
architecture Behavioral of BarrelShft is
signal Buf_Cntrl:STD_LOGIC_VECTOR (4 downto 0);
signal Buf_Din:STD_LOGIC_VECTOR (31 downto 0);
signal Dout_shft1:STD_LOGIC_VECTOR (31 downto 0);
signal Dout_Shft2:STD_LOGIC_VECTOR (31 downto 0);
signal Dout_Shft4:STD_LOGIC_VECTOR (31 downto 0);
signal Dout_Shft8:STD_LOGIC_VECTOR (31 downto 0);
signal Dout_Shft16:STD_LOGIC_VECTOR (31 downto 0);
begin
RegDin: Process (LoadDin, clk)
begin
if clk'event and clk = '1' then
if (loadDin = '1') then
Buf_Din <= Din;
else
Buf_Din <= (others => '0');
end if;
end if;
end process RegDin;
RegCin: Process (LoadCin, clk)
begin
if (clk'Event and clk = '1') then
if (loadCin = '1') then
Buf_Cntrl <= Cin;
else
Buf_Cntrl <= "00000";
end if;
end if;
end process RegCin;
Combo_Shft16: Process (LoadDin, LoadCin, Buf_Cntrl, Buf_Din)
begin
if (Buf_Cntrl(4) = '1') then
Dout_Shft16 <= Buf_Din (15 downto 0)& buf_Din (31 downto 16);
else
Dout_Shft16 <= Buf_Din;
end if;
end process Combo_Shft16;
Combo_Shft8: Process (LoadDin, LoadCin, Buf_Cntrl, Dout_Shft16)
begin
if (Buf_Cntrl(3) = '1') then
Dout_Shft8 <= Dout_Shft16 (7 downto 0)& Dout_Shft16 (31 downto 8);
else
Dout_Shft8 <= Dout_Shft16;
end if;
end process Combo_Shft8;
Combo_Shft4: Process (LoadDin, LoadCin, Buf_Cntrl, Dout_Shft8)
begin
if (Buf_Cntrl(2) = '1') then
Dout_Shft4 <= Dout_Shft8 (3 downto 0)& Dout_Shft8 (31 downto 4);
else
Dout_Shft4 <= Dout_Shft8;
end if;
end process Combo_Shft4;
Combo_Shft2: Process (LoadDin, LoadCin, Buf_Cntrl, Dout_Shft4)
begin
if (Buf_Cntrl(1) = '1') then
Dout_Shft2 <= Dout_Shft4 (1 downto 0)& Dout_Shft4 (31 downto 2);
else
Dout_Shft2 <= Dout_Shft4 (31 downto 0);
end if;
end process Combo_Shft2;
Combo_Shft1: Process (LoadDin, LoadCin, Buf_Cntrl, Dout_Shft2)
begin
if (Buf_Cntrl(0) = '1') then
Dout_Shft1 <= Dout_Shft2(0)& Dout_Shft2 (31 downto 1);
else
Dout_Shft1 <= Dout_Shft2 (31 downto 0);
end if;
end process Combo_Shft1;
RegDout: Process (clk, LoadDout)
begin
if clk'event and clk = '1' then
if (LoadDout ='1') then
Dout <=Dout_Shft1;
else
Dout <= (others => '0');
end if;
end if;
end process RegDout;
end Behavioral;