----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    17:02:37 12/23/2013 
-- Design Name: 
-- Module Name:    vga - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------

--SuperVGA timing from NEC monitor manual
--Horizontal :
--                ______________                 _____________
--               |              |               |
--_______________|  VIDEO       |_______________|  VIDEO (next line)
--
--___________   _____________________   ______________________
--           |_|                     |_|
--            B C <------D-----><-E->
--            <----------A---------->
--
--
--Vertical :
--                ______________                 _____________
--               |              |               |           
--_______________|  VIDEO       |_______________|  VIDEO (next frame)
--
--___________   _____________________   ______________________
--           |_|                     |_|
--            P Q <------R-----><-S->
--            <----------O---------->
--
--For VESA 640*480 @ 60Hz:
--Fh (kHz) :37.88
--A  (us)  :32
--B  (us)  :3.84
--C  (us)  :5.76
--D  (us)  :25.6
--E  (ns)  :640=0.640(us)
--
--Fv (Hz)  :60.32
--O  (ms)  :16.5
--P  (us)  :64
--Q  (ms)  :0.82
--R  (ms)  :15.36
--S  (us)  :320
--
--
--Horizonal timing information:
--
--Mode name          Pixel      sync      back  active  front whole line
--                   clock      pulse     porch  time   porch  period
--                   (MHz)   (us)  (pix)  (pix)  (pix)  (pix)  (pix)
-- 
--VGA 800x600 60Hz   25       3.2   96     48    639    16    800
--
--Vertical timing information:
--Mode name          Lines   line    sync      back        active     front     whole frame
--                   Total   width   pulse     porch        time      porch        period
--                           (us)   (us)(lin) (us)(lin)  (us)  (lin)  (us)(lin)  (us)  (lin)
--
--VGA 800x600 60Hz    525    26.40  106   4   554   33   15945  480         10  16579  525
--


-----------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;

entity vga is
port(
clk:in std_logic;
reset:in std_logic;

RGB:out std_logic_vector(2 downto 0);
hsync :out std_logic;
vsync :out std_logic

);

end vga;

architecture Behavioral of vga is

COMPONENT dcm_clk
	PORT(
		CLKIN_IN : IN std_logic;
		RST_IN : IN std_logic;          
		CLKFX_OUT : OUT std_logic;
		CLKIN_IBUFG_OUT : OUT std_logic;
		CLK0_OUT : OUT std_logic;
		LOCKED_OUT : OUT std_logic
		);
	END COMPONENT;


constant           H_PIXELS      :integer  :=639;--display(640 pix)
constant           H_FRONTPORCH  :integer:= 15;--FRONT PORCH(16 pix) 
constant           H_SYNCTIME    :integer := 95;--retrace(96 pix)
constant           H_BACKPORCH   :integer  :=47;--BACK PORCH(48 pix)
constant           H_SYNCSTART   :integer := 655; -- H_PIXELS + H_FRONTPORCH=655 pix
constant           H_SYNCEND     :integer  :=752; -- H_SYNCSTART + H_SYNCTIME=752 pix
constant           H_PERIOD      :integer  :=800; --H_SYNCEND + H_BACKPORCH=800 pix
 --Vertical timing constants
constant          V_LINES       :integer  :=480;--display(480 line)         
constant          V_FRONTPORCH  :integer  :=10;--FRONT PORCH(10 line) 
constant          V_SYNCTIME    :integer  :=2;--retrace(2 line)
constant          V_BACKPORCH   :integer  :=33;--BACK PORCH(33 line)
constant          V_SYNCSTART   :integer :=490;--V_LINES + V_FRONTPORCH=490 line
constant          V_SYNCEND     :integer  :=492; -- V_SYNCSTART + V_SYNCTIME=492 line
constant         V_PERIOD      :integer   :=525;--V_SYNCEND + V_BACKPORCH=525 line
-------------------------





--constant           H_PIXELS      :integer  :=639;--display(640 pix)
--constant           H_FRONTPORCH  :integer:= 15;--FRONT PORCH(16 pix) 
--constant           H_SYNCTIME    :integer := 95;--retrace(96 pix)
--constant           H_BACKPORCH   :integer  :=47;--BACK PORCH(48 pix)
--constant           H_SYNCSTART   :integer := 655; -- H_PIXELS + H_FRONTPORCH=655 pix
--constant           H_SYNCEND     :integer  :=752; -- H_SYNCSTART + H_SYNCTIME=752 pix
--constant           H_PERIOD      :integer  :=800; --H_SYNCEND + H_BACKPORCH=800 pix
-- --Vertical timing constants
--constant          V_LINES       :integer  :=384000;--display(480 line)         
--constant          V_FRONTPORCH  :integer  :=8000;--FRONT PORCH(10 line) 
--constant          V_SYNCTIME    :integer  :=1600;--retrace(2 line)
--constant          V_BACKPORCH   :integer  :=23000;--BACK PORCH(33 line)
--constant          V_SYNCSTART   :integer :=392000;--V_LINES + V_FRONTPORCH=490 line
--constant          V_SYNCEND     :integer  :=383600; -- V_SYNCSTART + V_SYNCTIME=492 line
--constant         V_PERIOD      :integer   :=416800;--V_SYNCEND + V_BACKPORCH=525 line
-------------------------
   
 signal hcnt,vcnt:integer range 0 to 1023:=0;
 signal enable,hsyncint:std_logic;
 
 
 
 signal CLKIN_IN,RST_IN,CLK_25MHZ,CLKIN_IBUFG_OUT,CLK0_OUT,LOCKED_OUT:std_logic;





begin
Inst_dcm_clk: dcm_clk PORT MAP(
		CLKIN_IN => CLKIN_IN,
		RST_IN => '0',
		CLKFX_OUT =>CLK_25MHZ ,
		CLKIN_IBUFG_OUT =>CLKIN_IBUFG_OUT ,
		CLK0_OUT =>CLK0_OUT ,
		LOCKED_OUT => LOCKED_OUT
	);

------------------------------
Obuf_clk : OBUF
   generic map (
     --DRIVE => 24,
      IOSTANDARD => "DEFAULT"
     )
  port map (
     O => CLKIN_IN ,
     I => clk
   );   
------------------------









process(CLK_25MHZ,reset)
begin


if reset='0' then
 hcnt <= 0;
elsif rising_edge(CLK_25MHZ) then

if(hcnt<h_PERIOD) then
 hcnt <= hcnt + 1; 
 else
 hcnt <= 0;
end if;






end if;
end process;






--------------------------------------------------------------------------------
----Internal horizontal synchronization pulse generation (negative polarity)----
--------------------------------------------------------------------------------

process(CLK_25MHZ,reset)
begin

--
if reset='0' then
 hsyncint<= '1';
 
elsif rising_edge(CLK_25MHZ) then
hsync <= hsyncint;
 
if(hcnt >= h_SYNCSTART and hcnt <h_SYNCEND) then
 hsyncint <='0'; 
--hsync<='1';
else
 hsyncint<= '1';
--hsync<='0';  
end if;

end if;

end process;
-------------------------------------
----Vertical counter of lines--------
-------------------------------------
process(reset,hsyncint)
begin


if reset='0' then
vcnt<=0;
elsif rising_edge(hsyncint)  then
 
if(vcnt < v_PERIOD) then
vcnt <=vcnt + 1;
else
vcnt<=0;
end if;
end if;



end process;
------------------------------------------------------------------------
---Vertical synchronization pulse generation (negative polarity)--------
------------------------------------------------------------------------

process(hsyncint,reset)
begin


if reset='0' then
vsync <='1';
elsif rising_edge(hsyncint)  then
 
if(vcnt >= v_SYNCSTART and vcnt < v_SYNCEND) then
vsync <='0';
else 
vsync <='1';

end if;
end if;
end process;
---------------------------------------------
------Enabling of color outputs--------------
---------------------------------------------
process(CLK_25MHZ,reset)
begin
if reset='0' then
 enable<='0';
elsif rising_edge(CLK_25MHZ) then

if(hcnt >= 300 or vcnt >= 300) then
  enable<='0';  
 else
  enable<='1'; 
end if;

end if;

end process;
---------------------------------------------------------------------------
---Output image generation (horizontal or vertical color stripes)----------
---------------------------------------------------------------------------
process(enable ,reset,hcnt,vcnt)
begin

if reset='0' then
rgb <= "000";
elsif rising_edge(CLK_25MHZ) then

if enable='0' then

  rgb<="000";
 else
 
 
if(hcnt<200) then
   rgb<="000";
elsif(hcnt<300) then
    rgb<="001";
elsif(hcnt>=300) then
    rgb<="000";
elsif(hcnt<200) then
   rgb<="000";
elsif(hcnt<300) then
    rgb<="001";
elsif(hcnt>=300) then
    rgb<="000";
end if;	
	

end if;
end if;

end process;
	
	

end Behavioral;