library IEEE;
use IEEE.std_logic_1164.all;

entity rolr16 is
    port (
        DIN:  in STD_LOGIC_VECTOR(15 downto 0);  -- Data inputs
        S:    in STD_LOGIC_VECTOR (3 downto 0);  -- Shift amount, 0-15
        DIR:  in STD_LOGIC;                      -- Shift direction, 0=>L, 1=>R
        DOUT: out STD_LOGIC_VECTOR(15 downto 0)  -- Data bus output
    );
end rolr16;

architecture rol16r_arch of rolr16 is
begin
process(DIN, S, DIR)
  variable X, Y, Z: STD_LOGIC_VECTOR(15 downto 0);
  variable CTRL0, CTRL1, CTRL2, CTRL3: STD_LOGIC_VECTOR(1 downto 0);
  begin
    CTRL0 := S(0) & DIR; CTRL1 := S(1) & DIR; CTRL2 := S(2) & DIR; CTRL3 := S(3) & DIR;
    case CTRL0 is 
      when "00" | "01" => X := DIN;
      when "10" => X := DIN(14 downto 0) & DIN(15);
      when "11" => X := DIN(0) & DIN(15 downto 1);
      when others => null;  end case;
    case CTRL1 is 
      when "00" | "01" => Y := X;
      when "10" => Y := X(13 downto 0) & X(15 downto 14);
      when "11" => Y := X(1 downto 0) & X(15 downto 2);
      when others => null;  end case;
    case CTRL2 is 
      when "00" | "01" => Z := Y;
      when "10" => Z := Y(11 downto 0) & Y(15 downto 12);
      when "11" => Z := Y(3 downto 0) & Y(15 downto 4);
      when others => null;  end case;
    case CTRL3 is 
      when "00" | "01" => DOUT := Z;
      when "10" | "11" => DOUT := Z(7 downto 0) & Z(15 downto 8);
      when others => null;  end case;
  end process;
end rol16r_arch;

