-------------------------------------------------------------------------------- -- Structural implementation of a barrel shifter that rotates its input data -- to the left. -- Multile levels of shift units are generated that combine to form a component -- that shifts input data an arbitrary number of bits. -- The top most level will shift half of the data width -- the level below one quarter of the data width, etc. -- until at the lowest level where just one bit is shifted over. -- -- For details see the Application Note for 2003 Winter. -- -- $Id: barrel_shift.vhd,v 1.1 2003/03/25 20:32:41 leendert Exp $ -- library ieee; use ieee.std_logic_1164.all; library work; use work.barrel_shift_pkg.all; entity barrel_shift is -- see the package declaration for signal descriptions. generic (selectorWidth: positive := 4); -- 2**4 bit wide shifter port ( numShifts: in std_logic_vector(selectorWidth-1 downto 0); shiftIn: in std_logic_vector(2**selectorWidth-1 downto 0); shiftOut: out std_logic_vector(2**selectorWidth-1 downto 0) ); end entity barrel_shift; architecture structural of barrel_shift is type intermediate_vector is array (natural range <>) of std_logic_vector(2**selectorWidth-1 downto 0); -- all the intermediate shifted signals between the multiplexers signal intermediates: intermediate_vector(selectorWidth downto 0); begin -- assign the input and output data intermediates(0) <= shiftIn; shiftOut <= intermediates(selectorWidth); -- generate the different levels of shifters level_gen: for level in 0 to selectorWidth-1 generate begin -- generate the muxes on each level mux_gen: for muxNum in 0 to 2**level-1 generate -- constants that describe each mux constant numMuxes: natural := 2**level; constant dataWidth: natural := 2**selectorWidth; constant muxWidth: natural := dataWidth/numMuxes; constant muxStart: natural := muxNum * muxWidth + muxWidth/2; constant muxEnd: natural := muxStart + muxWidth-1; constant shiftIndex: natural := selectorWidth - level - 1; begin -- shift the data when numShifts(this level) is '1' shift_gen: for i in muxStart to muxEnd generate begin -- a 2N to N mux, shifts data to the left when '1' -- other wise does not shift the data intermediates(level+1)(i mod dataWidth) <= (intermediates(level)(i mod dataWidth) and (not numShifts(shiftIndex))) or (intermediates(level)((i-muxWidth/2) mod dataWidth) and numShifts(shiftIndex)); end generate shift_gen; end generate mux_gen; end generate level_gen; end architecture structural;