library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity shifter is
port(
ShMode : in std_logic_vector(1 downto 0);
Sht : in std_logic_vector(2 downto 0);
V : in std_logic_vector(15 downto 0);
ShOut : out std_logic_vector(15 downto 0)
);
end shifter;
architecture arch of shifter is
alias logical : std_logic is ShMode(1);
alias dir : std_logic is ShMode(0);
signal sl1, sl2, sl3 : std_logic_vector(15 downto 0);
signal sr1 : std_logic_vector(17 downto 0);
signal sr2 : std_logic_vector(19 downto 0);
signal sr3 : std_logic_vector(15 downto 0);
signal fill : std_logic;
signal vr : std_logic_vector(16 downto 0);
begin
-- shift left (logical only)
g0 : for i in 0 to 15 generate
g1 : if i /= 0 generate
sl1(i) <= V(i) when Sht(0) = '0' else V(i - 1);
end generate;
g2 : if i = 0 generate
sl1(i) <= V(i) when Sht(0) = '0' else '0';
end generate;
end generate;
h0 : for i in 0 to 15 generate
h1 : if i >= 2 generate
sl2(i) <= sl1(i) when Sht(1) = '0' else sl1(i - 2);
end generate;
h2 : if i >= 0 and i <= 1 generate
sl2(i) <= sl1(i) when Sht(1) = '0' else '0';
end generate;
end generate;
i0 : for i in 0 to 15 generate
i1 : if i >= 4 generate
sl3(i) <= sl2(i) when Sht(2) = '0' else sl2(i - 4);
end generate;
i2 : if i >= 0 and i <= 3 generate
sl3(i) <= sl2(i) when Sht(2) = '0' else '0';
end generate;
end generate;
-- shift right (logical/arithmetic)
fill <= V(15) when logical = '0' else '0';
vr <= fill & V;
sr1(17 downto 16) <= (others => fill);
sr2(19 downto 16) <= (others => fill);
l0 : for i in 15 downto 0 generate
sr1(i) <= vr(i) when Sht(0) = '0' else vr(i + 1);
end generate;
m0 : for i in 15 downto 0 generate
sr2(i) <= sr1(i) when Sht(1) = '0' else sr1(i + 2);
end generate;
n0 : for i in 15 downto 0 generate
sr3(i) <= sr2(i) when sht(2) = '0' else sr2(i + 4);
end generate;
ShOut <= sl3 when dir = '0' else sr3;
end arch;