----------------------------------------------------------------------------------
-- Company: 
-- Engineer: Carsten Meyer
-- 
-- Create Date:  17:17:17 04/27/2008 
-- Design Name: 
-- Module Name:  MPX3_XOR - Behavioral 
-- Project Name: ct-Lab AsteroidsClock
----------------------------------------------------------------------------------
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 instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity fbas_count is
	Port ( SYSCLK: in  STD_LOGIC;
				 VIDEO:	 out STD_LOGIC_VECTOR (2 downto 0);
				 SYNC: 	 out  STD_LOGIC
			);
			
end fbas_count;

architecture behavioral of fbas_count is

	constant ball_size: std_logic_vector(9 downto 0):= conv_std_logic_vector(8,10);
	
	signal count_h, count_v : std_logic_vector (9 downto 0) := (others => '0');
	signal clk_int : Integer Range 0 to 63 := 0;
	signal clk_int_tick, video_on_h, video_on_v, video_test : std_logic := '0';
	signal sync_v, sync_h : std_logic := '0';

	signal ball_on, ball_direction : std_logic;
	signal ball_x_motion, ball_y_motion             : std_logic_vector(9 downto 0);
	signal ball_x_pos, ball_y_pos    : std_logic_vector(9 downto 0);
	signal rnd : std_logic_vector (15 downto 0) :=x"05A0";


begin

prescaler: process (SYSCLK)
-- erzeugt 100 ns Ticks
begin
	if rising_edge(SYSCLK) then
	  clk_int_tick <= '0';
		clk_int <= clk_int + 1;
		if clk_int = 4 then
			clk_int <=	0;	
			clk_int_tick <= '1';
		end if;
	end if;
end process;

VIDEO <= (ball_on & '0' & video_test) when (video_on_h = '1') and (video_on_v = '1') else "000";
SYNC <= not (sync_v xor sync_h);
		
raster_scan: process (SYSCLK, clk_int_tick)
begin
	if rising_edge(SYSCLK) and (clk_int_tick = '1') then
		count_h <= count_h + 1;
		
		if count_h = 519 then -- nach 52 µs
			video_on_h <= '0';
		end if;
		if count_h = 535 then -- nach 53,5 µs
			sync_h <= '1';
		end if;
		if count_h = 581 then -- nach 58,2 µs
			sync_h <= '0';
		end if;
		if count_h = 639 then -- Reset auf 0
			count_h <= (others => '0');
			count_v <= count_v + 1;
			video_on_h <= '1';
			
			if count_v = 239 then
			  video_on_v <= '0';
			end if;
			if count_v = 244 then
				sync_v <= '1';
			end if;
			if count_v = 249 then
				sync_v <= '0';
			end if;
			if count_v = 254 then
			  video_on_v <= '1';
				count_v <= (others => '0');
			end if;
		end if;
		video_test <= (count_h(5) xor count_v(4));
	end if;
end process;



ball_display: process (ball_x_pos, ball_y_pos, count_v, count_h)
begin
	if ('0' & ball_x_pos <= count_h + ball_size) and (ball_x_pos + ball_size >= '0' & count_h) 
			and ('0' & ball_y_pos <= count_v + ball_size) and (ball_y_pos + ball_size >= '0' & count_v) then
		ball_on <= '1';
	else
		ball_on <= '0';
	end if;

end process;

 

move_ball: process (sync_v)
begin
-- Move ball once every vertical sync
	if rising_edge(sync_v) then
	-- Bounce off left or right edge of screen
		if ('0' & ball_x_pos) >= conv_std_logic_vector(520,10) - ball_size then
			ball_x_motion <= x"FF" & '0' & rnd(1);
			ball_y_motion <= not ball_y_motion;
		elsif ball_y_pos <= ball_size + ball_size then
			ball_x_motion <= x"00" & '1' & rnd(1);
			ball_y_motion <= not ball_y_motion;
		end if;
	-- Compute next ball X position
		ball_x_pos <= ball_x_pos + ball_x_motion;
		
	-- Bounce off top or bottom of screen
		if ('0' & ball_y_pos) >= conv_std_logic_vector(240,10) - ball_size then
			ball_y_motion <= x"FF" & '0' & rnd(1);
			ball_x_motion <= not ball_x_motion;
		elsif ball_y_pos <= ball_size + ball_size then
			ball_y_motion <= x"00" & '1' & rnd(1);
			ball_x_motion <= not ball_x_motion;
		end if;
	-- Compute next ball Y position
		ball_y_pos <= ball_y_pos + ball_y_motion;
	end if;
end process;

set_noise: process (sync_v)
begin
	if rising_edge(sync_v) then
		-- Zufallsgenerator per 16-Bit-LFSR
		rnd(15 downto 1) <= rnd(14 downto 0) ;
		rnd(0) <= not(rnd(15) XOR rnd(14) XOR rnd(13) XOR rnd(4));
	end if;
end process;

end Behavioral;

