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;