------------------------------------------------------------------------------- -- Title : Barrel Shifter (Pure combbinational) -- Project : Barrel Shifter -------------------------------------------------------------------------------- -- File : BarrelShifter.VHD -- Author : Jamil Khatib (khatib@ieeee.org) -- Organization: OpenIPCore Project -- Created : 2000/08/2 -- Last update : 2005/05/23 -------------------------------------------------------------------------------- -- Revisions : -- Revision Number : 2 -- Version : 0.3 -- Date : 23rd May 2005 -- Modifier : Joao Pereira (jota__tecido@hotmail.com) -- Desccription : Introduce the rotattes operations -- -------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use utility.tools_pkg.all; entity BarrelShifter is generic ( REGSIZE : integer := 32; -- Register Size DIRECTION : integer := 0; -- Shift/Rotate Direction --0 Right 1 Left -->NEW MODE: integer:=1); -- Shift=0 Rotate=1 port ( inReg : in std_logic_vector(REGSIZE -1 downto 0); -- Input register ShSize : in std_logic_vector(log2(REGSIZE)-1 downto 0); -- Shift Size outReg : out std_logic_vector(REGSIZE -1 downto 0)); -- Shifted result end BarrelShifter; -------------------------------------------------------------------------------- architecture behave of BarrelShifter is constant SHIFTSIZE : integer := log2(REGSIZE); -- Shift size begin -- behave -------------------------------------------------------------------------------- SHIFT_RIGHT : if DIRECTION = 0 AND MODE=0 generate -- purpose: Perform the shifting -- type : combinational -- inputs : inReg, ShSize -- outputs: outReg Shift : process (inReg, Shsize) variable VarReg : std_logic_vector(REGSIZE -1 downto 0); -- Local storage for shifter begin -- process Shift VarReg := inReg; for i in 0 to SHIFTSIZE -2 loop if ShSize(i) = '1' then VarReg(REGSIZE -1 downto 0) := (REGSIZE-1 downto REGSIZE-(2**i) => '0') & VarReg(REGSIZE -1 downto (2**i)); end if; end loop; -- i if ShSize(SHIFTSIZE-1) = '1' then VarReg := (others => '0'); end if; outReg <= VarReg; end process Shift; end generate SHIFT_RIGHT; -------------------------------------------------------------------------------- SHIFT_LEFT : if DIRECTION = 1 and MODE = 0 generate -- purpose: Perform the shifting -- type : combinational -- inputs : inReg, ShSize -- outputs: outReg Shift : process (inReg, Shsize) variable VarReg : std_logic_vector(REGSIZE -1 downto 0); -- Local storage for shifter begin -- process Shift VarReg := inReg; for i in 0 to SHIFTSIZE -2 loop if ShSize(i) = '1' then VarReg(REGSIZE -1 downto 0) := VarReg( (REGSIZE-(2**i)-1) downto 0) & ((2**i)-1 downto 0 => '0'); end if; end loop; -- i if ShSize(SHIFTSIZE-1) = '1' then VarReg := (others => '0'); end if; outReg <= VarReg; end process Shift; end generate SHIFT_LEFT; ----------------------------------------------------------------------------------------------------- ROTATE_RIGHT : if DIRECTION = 0 and MODE = 1 generate -->NEW -- purpose: Perform the rotate -- type : combinational -- inputs : inReg, ShSize -- outputs: outReg rotate : process (inReg, Shsize) variable VarReg : std_logic_vector(REGSIZE -1 downto 0); variable count:integer:=0; variable aux_count:std_logic_vector(SHIFTSIZE-1 downto 0); begin -- process rotate VarReg := inReg; aux_count:=ShSize; if ShSize(SHIFTSIZE-1) = '1' then count:=conv_integer(Shsize); count:=count mod 2**(SHIFTSIZE-1); aux_count(SHIFTSIZE-2 downto 0):= conv_std_logic_vector(count,SHIFTSIZE-1); end if; for i in 0 to SHIFTSIZE -2 loop if ShSize(i) = '1' then VarReg(REGSIZE -1 downto 0) :=VarReg((2**i)-1 downto 0) & VarReg(REGSIZE -1 downto (2**i)); end if; end loop; -- i outReg <= VarReg; end process rotate; end generate ROTATE_RIGHT; ----------------------------------------------------------------------------------------------------- ROTATE_LEFT : if DIRECTION = 1 and MODE = 1 generate -->NEW -- purpose: Perform the rotate -- type : combinational -- inputs : inReg, ShSize -- outputs: outReg rotate : process (inReg, Shsize) variable VarReg : std_logic_vector(REGSIZE -1 downto 0); variable count:integer:=0; variable aux_count:std_logic_vector(SHIFTSIZE-1 downto 0); begin -- process rotate VarReg := inReg; aux_count:=ShSize; if ShSize(SHIFTSIZE-1) = '1' then count:=conv_integer(Shsize); count:=count mod 2**(SHIFTSIZE-1); aux_count(SHIFTSIZE-2 downto 0):= conv_std_logic_vector(count,SHIFTSIZE-1); end if; for i in 0 to SHIFTSIZE -2 loop if ShSize(i) = '1' then VarReg(REGSIZE -1 downto 0):= VarReg(REGSIZE-1 -(2**i) downto 0) & VarReg(REGSIZE - 1 downto REGSIZE - 2**i); end if; end loop; -- i outReg <= VarReg; end process rotate; end generate ROTATE_LEFT; -------------------------------------------------------------------------------- end behave;