-------------------------------------------------------------------------------
-- 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;