`timescale 1ns / 1ps

// VGA Pong v1.0     Chris Fallin <cfallin@nd.edu>

module top(reset, clk_50MHz,
				ps2_clk, ps2_data,
				vga_hsync, vga_vsync, vga_r, vga_g, vga_b,
				game,
				paddle1_up, paddle1_down, paddle2_up, paddle2_down);
	input reset;
	input clk_50MHz;
	input ps2_clk;
	input ps2_data;
   output vga_hsync;
   output vga_vsync;
   output vga_r;
   output vga_g;
   output vga_b;
	output game;
	output paddle1_up;
	output paddle1_down;
	output paddle2_up;
	output paddle2_down;

	wire vga_hsync;
	wire vga_vsync;
	wire vga_r;
	wire vga_g;
	wire vga_b;
	wire game;

	wire motion_clk;

	// -----
	// registers

	// VGA timing stuff
	wire active;
	wire [9:0] hpos;
	wire [9:0] vpos;

	// item positions
	wire [9:0] paddle1_v;
	wire [9:0] paddle2_v;

	wire [9:0] ball_v;
	wire [9:0] ball_h;
	wire ball_v_dir;
	wire ball_h_dir;

	wire paddle1_active;
	wire paddle2_active;
	wire ball_active;

	// -----
	// module instantiations

	motion_clock mtn_clk(
		.clk_50MHz(clk_50MHz),
		.clk_motion(motion_clk)
		);

	vga_sync sync(
		.vsync(vga_vsync),
		.hsync(vga_hsync),
		.vpos(vpos),
		.hpos(hpos),
		.active(active),
		.clk_50MHz(clk_50MHz),
		//.reset(reset)  --- don't reset VGA with the rest; monitor resync takes time
		.reset(0)
		);
		
	box_detect paddle1_box(
		.v(paddle1_v),
		.vsize(48),
		.h(0),
		.hsize(16),
		.vpos(vpos),
		.hpos(hpos),
		.q(paddle1_active)
		);
		
	assign vga_r = paddle1_active & active;
	
	box_detect paddle2_box(
		.v(paddle2_v),
		.vsize(48),
		.h(624),
		.hsize(16),
		.vpos(vpos),
		.hpos(hpos),
		.q(paddle2_active)
		);
		
	assign vga_b = paddle2_active & active;

	box_detect ball_box(
		.v(ball_v),
		.vsize(16),
		.h(ball_h),
		.hsize(16),
		.vpos(vpos),
		.hpos(hpos),
		.q(ball_active)
		);
		
	assign vga_g = ball_active & active;
	
	wire paddle1_up;
	wire paddle1_down;
	wire paddle2_up;
	wire paddle2_down;
	
	motion mtn(
		.reset(reset),
		.clk(motion_clk),
		.game(game),
		.ball_v(ball_v),
		.ball_h(ball_h),
		.ball_v_dir(ball_v_dir),
		.ball_h_dir(ball_h_dir),
		.paddle1_v(paddle1_v),
		.paddle2_v(paddle2_v),
		.paddle1_up(paddle1_up),
		.paddle1_down(paddle1_down),
		.paddle2_up(paddle2_up),
		.paddle2_down(paddle2_down)
		);

	kbd k(
		.clk(clk_50MHz),
		.reset(reset),
		.ps2_clk(ps2_clk),
		.ps2_data(ps2_data),
		.paddle1_up(paddle1_up),
		.paddle1_down(paddle1_down),
		.paddle2_up(paddle2_up),
		.paddle2_down(paddle2_down)
		);

endmodule
