--	Package File Template
--
--	Purpose: This package defines supplemental types, subtypes, 
--		 constants, and functions 


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.MATH_REAL.ALL;

package vga_types is
	
	-- Constants
	constant	VGA_NUM_CH		: natural := 2;
	
	-- Types
	type color_range_t is (r, g, b, a);
	type color_t is array (color_range_t) of unsigned(7 downto 0);
	type color_array_t is array (0 to VGA_NUM_CH-1) of color_t;

	type color_op_t is (op_over, op_xor, op_alpha);
	
	type scan_timespec_t is
	record
		ncyc_scan				: integer;
		ncyc_porch_front		: integer;
		ncyc_sync_pulse			: integer;
		ncyc_porch_back			: integer;
		sync_polarity			: std_logic;
	end record;

	type vga_timespec_t is
	record
		f_pxl_clk              : integer;
		nfps                   : integer;
		ts_h                   : scan_timespec_t;
		ts_v                   : scan_timespec_t;
	end record;

	-----------------------------------------------------------------------
	-- Common timimg specifications
	-----------------------------------------------------------------------
	-- For test bench (not for H/W use)
	constant ts_vga_testbench : vga_timespec_t :=
	(
		f_pxl_clk              => 40E6,
		nfps                   => 6,
		ts_h                   => (80,5,2,3,'0'),
		ts_v                   => (60,4,2,3,'0')
	);

	-- 640 x 480 @ 60 Hz (not recommended)
	constant ts_vga_640_480_60 : vga_timespec_t :=
	(
		f_pxl_clk              => 25175000,
		nfps                   => 60,
		ts_h                   => (640,16,96,48,'0'),
		ts_v                   => (480,11,2,31,'0')
	);

	-- 640 x 480 @ 72 Hz (not recommended)
	constant ts_vga_640_480_72 : vga_timespec_t :=
	(
		f_pxl_clk              => 31500000,
		nfps                   => 72,
		ts_h                   => (640,24,40,128,'0'),
		ts_v                   => (480,9,3,28,'0')
	);
 
	-- 800 x 600 @ 60 Hz (OK)
	constant ts_vga_800_600_60 : vga_timespec_t :=
	(
		f_pxl_clk              => 40000000,
		nfps                   => 60,
		ts_h                   => (800,40,128,88,'0'),
		ts_v                   => (600,1,4,23,'0')
	);
	
	-- 800 x 600 @ 72 Hz (OK)
	constant ts_vga_800_600_72 : vga_timespec_t :=
	(
		f_pxl_clk              => 50000000,
		nfps                   => 72,
		ts_h                   => (800,56,120,64,'0'),
		ts_v                   => (600,37,6,23,'0')
	);

	-- 1024 x 768 @ 60 Hz (Noisy)
	constant ts_vga_1024_768_60 : vga_timespec_t :=
	(
		f_pxl_clk              => 65000000,
		nfps                   => 60,
		ts_h                   => (1024,24,136,160,'0'),
		ts_v                   => (768,3,6,29,'0')
	);

	-- 1024 x 768 @ 70 Hz (OK)
	constant ts_vga_1024_768_70 : vga_timespec_t :=
	(
		f_pxl_clk              => 75000000,
		nfps                   => 70,
		ts_h                   => (1024,24,136,144,'0'),
		ts_v                   => (768,3,6,29,'0')
	);

	-- 1280 x 1024 @ 70 Hz (Noisy)
	constant ts_vga_1280_1024_70 : vga_timespec_t :=
	(
		f_pxl_clk              => 125000000,
		nfps                   => 70,
		ts_h                   => (1280,16,176,192,'0'),
		ts_v                   => (1024,3,3,42,'0')
	);

	-- 1280 x 1024 @ 72 Hz (OK)
	constant ts_vga_1280_1024_72 : vga_timespec_t :=
	(
		f_pxl_clk              => 130000000,
		nfps                   => 72,
		ts_h                   => (1280,32,160,224,'0'),
		ts_v                   => (1024,2,2,33,'0')
	);

	-- Functions
	function to_color_t(x : unsigned) return color_t;
	function to_unsigned(x : color_t) return unsigned;
	
end vga_types;


package body vga_types is

	function to_color_t(x : unsigned) return color_t is
	variable result : color_t;
	begin
		result(r)	:= x(x'right+7 downto x'right+0);
		result(g)	:= x(x'right+15 downto x'right+8);
		result(b)	:= x(x'right+23 downto x'right+16);
		result(a)	:= x(x'right+31 downto x'right+24);
		
		return result;
	end to_color_t;
	
	function to_unsigned(x : color_t) return unsigned is
	variable result : unsigned(31 downto 0);
	begin
		result(7 downto 0)		:= x(r);
		result(15 downto 8)		:= x(g);
		result(23 downto 16)	:= x(b);
		result(31 downto 24)	:= x(a);

		return result;
	end to_unsigned;

end vga_types;


