--------------------------------------------------------------------------------
-- Company: 
-- Engineer:
--
-- Create Date:    11:15:39 10/21/05
-- Design Name:    
-- Module Name:    fsm_scan - Behavioral
-- Project Name:   
-- Target Device:  
-- Tool versions:  
-- Description:
--
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

use work.vga_types.all;

entity vga_sync is
	Generic
	(
		ts	: scan_timespec_t := (4,2,1,3,'0')
	);
	Port
	(
		rst			: in std_logic;
		clk			: in std_logic;
		ce			: in std_logic;
		pos			: out natural range 0 to ts.ncyc_scan-1;
		sync		: out std_logic;
		is_scan		: out std_logic;
		rdy_scan	: out std_logic
	);
	end vga_sync;

architecture Behavioral of vga_sync is

	type timing_state_t is (st_init, st_scan, st_front, st_sync, st_back); 

	-- Counter
	signal state, next_state	: timing_state_t;
	signal count_srst			: std_logic;
	signal count				: natural range 0 to ts.ncyc_scan-1;

begin

	pos	<= count;
	
---------------------------------------------------------------------------------------------
counter:
	process (clk)
	begin
		if rising_edge(clk) then
			if ce = '1' then
				if count_srst = '1' then
					count <= 0;
				else	
					count <= count + 1;
				end if;
			end if;	
		end if;
	end process;	

---------------------------------------------------------------------------------------------
SYNC_TIMING:
process (state, count)
	begin
		count_srst	<= '0';
		rdy_scan	<= '0';
		is_scan		<= '0';
		sync		<= '0';

		next_state <= state;  --default is to stay in current state

		case (state) is
		
		when st_init =>
			count_srst	<= '1';
			next_state	<= st_front;
		when st_front =>
			if count = ts.ncyc_porch_front - 1 then
				count_srst	<= '1';
				next_state <= st_sync;
			end if;
		when st_sync =>
			sync	<= '1';
			if count = ts.ncyc_sync_pulse - 1 then
				count_srst	<= '1';
				next_state	<= st_back;
			end if;
		when st_back =>
			if count = ts.ncyc_porch_back - 1 then
				count_srst	<= '1';
				next_state	<= st_scan;
            end if;
         when st_scan =>
			is_scan  <= '1';
			if count = ts.ncyc_scan - 1 then
				count_srst	<= '1';
				rdy_scan	<= '1';
				next_state	<= st_front;
			end if;
		when others =>	
			next_state <= st_init;
			
		end case;      
	end process;

SYNC_TIMING_NEXT:
	process (rst, clk)
	begin
		if rst = '1' then
			state <= st_init;
		elsif rising_edge(clk) and ce = '1' then
			state <= next_state;
		end if;
	end process;

---------------------------------------------------------------------------------------------
end Behavioral;
