library ieee;
--library gold_lib;   --UNCOMMENT if you're using a GOLD model
use ieee.std_logic_1164.all;
--use gold_lib.all;   --UNCOMMENT if you're using a GOLD model

entity tb_shift_register is
generic (Period : Time := 10 ns);
end tb_shift_register;

architecture TEST of tb_shift_register is

  function INT_TO_STD_LOGIC( X: INTEGER; NumBits: INTEGER )
     return STD_LOGIC_VECTOR is
    variable RES : STD_LOGIC_VECTOR(NumBits-1 downto 0);
    variable tmp : INTEGER;
  begin
    tmp := X;
    for i in 0 to NumBits-1 loop
      if (tmp mod 2)=1 then
        res(i) := '1';
      else
        res(i) := '0';
      end if;
      tmp := tmp/2;
    end loop;
    return res;
  end;

  component shift_register
    PORT(
         CLK : in STD_LOGIC;
         LOAD : in STD_LOGIC;
         nRST : in STD_LOGIC;
         OPCODE_IN : in STD_LOGIC_VECTOR(3 downto 0);
         OPCODE_OUT : out STD_LOGIC_VECTOR(3 downto 0);
         DATA_IN : in STD_LOGIC_VECTOR(31 downto 0);
         DATA_OUT : out STD_LOGIC_VECTOR(511 downto 0);
         BUSY_OUT : out STD_LOGIC;
         READ : in STD_LOGIC
    );
  end component;

-- Insert signals Declarations here
  signal CLK : STD_LOGIC;
  signal LOAD : STD_LOGIC;
  signal nRST : STD_LOGIC;
  signal OPCODE_IN : STD_LOGIC_VECTOR(3 downto 0);
  signal OPCODE_OUT : STD_LOGIC_VECTOR(3 downto 0);
  signal DATA_IN : STD_LOGIC_VECTOR(31 downto 0);
  signal DATA_OUT : STD_LOGIC_VECTOR(511 downto 0);
  signal BUSY_OUT : STD_LOGIC;
  signal READ : STD_LOGIC;

-- signal <name> : <type>;

begin

CLKGEN: process
  variable CLK_tmp: std_logic := '0';
begin
  CLK_tmp := not CLK_tmp;
  CLK <= CLK_tmp;
  wait for Period/2;
end process;

  DUT: shift_register port map(
                CLK => CLK,
                LOAD => LOAD,
                nRST => nRST,
                OPCODE_IN => OPCODE_IN,
                OPCODE_OUT => OPCODE_OUT,
                DATA_IN => DATA_IN,
                DATA_OUT => DATA_OUT,
                BUSY_OUT => BUSY_OUT,
                READ => READ
                );

--   GOLD: <GOLD_NAME> port map(<put mappings here>);

process

  begin

-- Insert TEST BENCH Code Here

    LOAD <= '0';
    nRST <= '0';
    OPCODE_IN <= "0000";
    DATA_IN <= x"00000000";
    READ <= '0';

    wait for 15 ns;

    nRST <= '1';
    OPCODE_IN <= "0000";
    DATA_IN <= x"FFFFFFFF";
    LOAD <= '0';

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"EEEEEEEE";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"DDDDDDDD";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"CCCCCCCC";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"BBBBBBBB";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"AAAAAAAA";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"99999999";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"88888888";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"77777777";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"66666666";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"55555555";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"44444444";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"33333333";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"22222222";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"11111111";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"00000000";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';
    DATA_IN <= x"FFFFFFFF";

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;
    LOAD <= '0';

    wait for 60 ns;
    READ <= '1';

    wait for 10 ns;
    READ <= '0';

    wait for 20 ns;
    OPCODE_IN <= "0011";
    DATA_IN <= x"ABABABAB";
    LOAD <= '0';

    wait for 20 ns;
    LOAD <= '1';

    wait for 20 ns;

    wait for 1005 ns;

  end process;
end TEST;
