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_top_level is
generic (Period : Time := 4 ns);
end tb_top_level;

architecture TEST of tb_top_level 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 top_level
    PORT(
         CLK : IN STD_LOGIC;
         DATA_IN : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
         ENABLE1 : IN STD_LOGIC;
         LCD_CLK : IN STD_LOGIC;
         LOAD : IN STD_LOGIC;
         OPCODE_IN : IN STD_LOGIC_VECTOR (3 DOWNTO 0);
         nRST : IN STD_LOGIC;
         BUSY_OUT1 : OUT STD_LOGIC;
         PIXEL : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
         ROW : OUT STD_LOGIC;
         busy_out : OUT std_logic
    );
  end component;

-- Insert signals Declarations here
  signal CLK : STD_LOGIC;
  signal DATA_IN : STD_LOGIC_VECTOR (31 DOWNTO 0);
  signal ENABLE1 : STD_LOGIC;
  signal LCD_CLK : STD_LOGIC;
  signal LOAD : STD_LOGIC;
  signal OPCODE_IN : STD_LOGIC_VECTOR (3 DOWNTO 0);
  signal nRST : STD_LOGIC;
  signal BUSY_OUT1 : STD_LOGIC;
  signal PIXEL : STD_LOGIC_VECTOR (7 DOWNTO 0);
  signal ROW : STD_LOGIC;
  signal busy_out : 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;

LCDCLKGEN: process
  variable LCDCLK_tmp: std_logic := '0';
  variable LCD_Period: time := 8 ns;
begin
  LCDCLK_tmp := not LCDCLK_tmp;
  LCD_CLK <= LCDCLK_tmp;
  wait for LCD_Period/2;
end process;

  DUT: top_level port map(
                CLK => CLK,
                DATA_IN => DATA_IN,
                ENABLE1 => ENABLE1,
                LCD_CLK => LCD_CLK,
                LOAD => LOAD,
                OPCODE_IN => OPCODE_IN,
                nRST => nRST,
                BUSY_OUT1 => BUSY_OUT1,
                PIXEL => PIXEL,
                ROW => ROW,
                busy_out => busy_out
                );

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

process

  begin

-- Insert TEST BENCH Code Here

    ENABLE1 <= '1';

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

    wait for 8 ns;

    nRST <= '1';
--xfov 1.000000 
    OPCODE_IN <= "0011";
    DATA_IN <= "00000000000000010000000000000000";
    while BUSY_OUT1 = '1' loop
      wait for 12 ns;
    end loop;
    wait for 12 ns;
    LOAD <= '1';
    wait for 12 ns;
    LOAD <= '0';

--yfov 1.000000 
    OPCODE_IN <= "0100";
    DATA_IN <= "00000000000000010000000000000000";
    while BUSY_OUT1 = '1' loop
      wait for 12 ns;
    end loop;
    wait for 12 ns;
    LOAD <= '1';
    wait for 12 ns;
    LOAD <= '0';

--color 128
    OPCODE_IN <= "0111";
    DATA_IN <= "00000000000000000000000010000000";
   while BUSY_OUT1 = '1' loop
     wait for 12 ns;
   end loop;
    wait for 12 ns;
    LOAD <= '1';
    wait for 12 ns;
    LOAD <= '0';

--clr 
    OPCODE_IN <= "1000";
    while BUSY_OUT1 = '1' loop
      wait for 12 ns;
    end loop;
    wait for 12 ns;
    LOAD <= '1';
    wait for 12 ns;
    LOAD <= '0';

--rstmat 
    OPCODE_IN <= "0010";
    while BUSY_OUT1 = '1' loop
      wait for 12 ns;
    end loop;
    wait for 12 ns;
    LOAD <= '1';
    wait for 12 ns;
    LOAD <= '0';

--ln2d 0 0
--     128 128
    OPCODE_IN <= "1011";
    DATA_IN <= "00000000000000001000000010000000";
   while BUSY_OUT1 = '1' loop
     wait for 12 ns;
   end loop;
    wait for 12 ns;
    LOAD <= '1';
    wait for 12 ns;
    LOAD <= '0';

--color 192
    OPCODE_IN <= "0111";
    DATA_IN <= "00000000000000000000000011000000";
   while BUSY_OUT1 = '1' loop
     wait for 12 ns;
   end loop;
    wait for 12 ns;
    LOAD <= '1';
    wait for 12 ns;
    LOAD <= '0';

--ln2d 255 0
--     128 128
    OPCODE_IN <= "1011";
    DATA_IN <= "11111111000000001000000010000000";
   while BUSY_OUT1 = '1' loop
     wait for 12 ns;
   end loop;
    wait for 12 ns;
    LOAD <= '1';
    wait for 12 ns;
    LOAD <= '0';

--color 64
    OPCODE_IN <= "0111";
    DATA_IN <= "00000000000000000000000001000000";
   while BUSY_OUT1 = '1' loop
     wait for 12 ns;
   end loop;
    wait for 12 ns;
    LOAD <= '1';
    wait for 12 ns;
    LOAD <= '0';

--ln2d 128 128
--     0 255
    OPCODE_IN <= "1011";
    DATA_IN <= "10000000100000000000000011111111";
   while BUSY_OUT1 = '1' loop
     wait for 12 ns;
   end loop;
    wait for 12 ns;
    LOAD <= '1';
    wait for 12 ns;
    LOAD <= '0';

--color 96
    OPCODE_IN <= "0111";
    DATA_IN <= "00000000000000000000000001100000";
   while BUSY_OUT1 = '1' loop
     wait for 12 ns;
   end loop;
    wait for 12 ns;
    LOAD <= '1';
    wait for 12 ns;
    LOAD <= '0';

--ln2d 128 128
--     255 255
    OPCODE_IN <= "1011";
    DATA_IN <= "10000000100000001111111111111111";
   while BUSY_OUT1 = '1' loop
     wait for 12 ns;
   end loop;
    wait for 12 ns;
    LOAD <= '1';
    wait for 12 ns;
    LOAD <= '0';

--flip 
    OPCODE_IN <= "1001";
    while BUSY_OUT1 = '1' loop
      wait for 12 ns;
    end loop;
    wait for 12 ns;
    LOAD <= '1';
    wait for 12 ns;
    LOAD <= '0';

    wait for 1000000 ns;

  end process;
end TEST;
