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_Line_Rasterization is
generic (Period : Time := 10 ns);
end tb_Line_Rasterization;

architecture TEST of tb_Line_Rasterization 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 Line_Rasterization
    PORT(
         CLK : in std_logic;
         nRST : in std_logic;
         DATA : in std_logic_vector(47 downto 0);
         SB_BUSY : in std_logic;
         RESULT : out std_logic_vector(23 downto 0);
         SB_ENABLE : out std_logic;
         ENABLE : in std_logic;
         BUSY : out std_logic;
         OPCODE : in std_logic_vector(1 downto 0)
    );
  end component;

-- Insert signals Declarations here
  signal CLK : std_logic;
  signal nRST : std_logic;
  signal DATA : std_logic_vector(47 downto 0);
  signal SB_BUSY : std_logic;
  signal RESULT : std_logic_vector(23 downto 0);
  signal SB_ENABLE : std_logic;
  signal ENABLE : std_logic;
  signal BUSY : std_logic;
  signal OPCODE : std_logic_vector(1 downto 0);

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


BUSYGEN: process
  variable CLK_tmp: std_logic := '0';
begin
  SB_BUSY <= '1';
  wait for Period*2;
  SB_BUSY <= '0';
  wait for Period*2;
  SB_BUSY <= '1';
end process;


  DUT: Line_Rasterization port map(
                CLK => CLK,
                nRST => nRST,
                DATA => DATA,
                SB_BUSY => SB_BUSY,
                RESULT => RESULT,
                SB_ENABLE => SB_ENABLE,
                ENABLE => ENABLE,
                BUSY => BUSY,
                OPCODE => OPCODE
                );

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

process

  begin

-- Insert TEST BENCH Code Here

 -- ALSO: TEST A SINGLE POINT, TEST OVER THE WHOLE DISPLAY, VERT LINE, etc.
    
    nRST <= '0';
    DATA <= x"000000000001";
--    SB_BUSY <= '0';
    ENABLE <= '0';
    OPCODE <= "00";
    wait for 10 ns;
    
    nRST <= '1';
    OPCODE <= "11";
    DATA <= x"0705000A0F10";            -- (7,5,0) to (10,15,16)
    wait for 10 ns;                     -- (loopY, y1->y2, + slope)
    
    ENABLE <= '1';                      -- enable
    wait for 30 ns;
    
 --   SB_BUSY <= '1';                     -- busyness should halt rendering
    wait for 30 ns;

--    SB_BUSY <= '0';
    
    wait for 10 ns;
    DATA <= x"000000000000";            -- trick it by switching data early
    
    wait until BUSY='0';
    
    DATA <= x"0A0F10070500";            -- (10,15,16) to (7,5,0)
    wait until BUSY='0';                -- (loopY, y2->y1, + slope)

    DATA <= x"0202050A0A00";            -- (2,2,5) to (10,10,0)
    wait until BUSY='0';                -- (loopX, x1->x2, + slope)

    DATA <= x"0A0A00020205";            -- (10,10,0) to (2,2,5) (Z REQ SGNDIV)
    wait until BUSY='0';                -- (loopX, x2->x1, + slope)

    DATA <= x"808080808080";            -- (128,128,128) to (128,128,128)
    wait until BUSY='0';                -- (single point)

    DATA <= x"0A0A00100A00";            -- (10,10,0) to (16,10,0)
    wait until BUSY='0';                -- (horizontal line)

    DATA <= x"0A0A000A1000";            -- (10,10,0) to (10,16,0)
    wait until BUSY='0';                -- (vertical line)

    DATA <= x"804000842020";            -- (128,64,0) to (132,32,32) (SGNDIV)
    wait until BUSY='0';                -- (loopX, x1->x2, - slope)

    DATA <= x"804000842020";            -- (132,32,32) to (128,64,0) (SGNDIV)
    wait until BUSY='0';                -- (loopX, x2->x1, - slope)
    
    DATA <= x"020A00050000";            -- (2,10,0) to (5,0,0) (REQ SIGNED DIV)
    wait until BUSY='0';                -- (loopY, y1->y2, - slope)

    DATA <= x"020A00050000";            -- (5,0,0) to (2,10,0) (REQ SIGNED DIV)
    wait until BUSY='0';                -- (loopY, y2->y1, - slope)

    DATA <= x"000000FFFFFF";            -- (0,0,0) to (255,255,255)
    wait until BUSY='0';                -- (over entire display)
    
    wait for 500 ns;

  end process;
end TEST;
