`timescale 1ns / 1ps // VGA Pong v1.0 Chris Fallin module motion( clk, paddle1_up, paddle1_down, paddle2_up, paddle2_down, paddle1_v, paddle2_v, ball_v_dir, ball_h_dir, ball_v, ball_h, game, reset); input clk; input paddle1_up; input paddle1_down; input paddle2_up; input paddle2_down; output ball_v_dir; output ball_h_dir; output [9:0] paddle1_v; output [9:0] paddle2_v; output [9:0] ball_v; output [9:0] ball_h; output game; input reset; reg [9:0] paddle1_v; reg [9:0] paddle2_v; reg [9:0] ball_v; reg [9:0] ball_h; reg ball_v_dir; reg ball_h_dir; reg game; // game over wire paddle1_inrange; assign paddle1_inrange = (ball_v + 16) >= paddle1_v && ball_v < (paddle1_v + 48); wire paddle2_inrange; assign paddle2_inrange = (ball_v + 16) >= paddle2_v && ball_v < (paddle2_v + 48); // these collision-detections leave 1-pixel buffer because of 1-cycle delay on bounces wire collide_top; assign collide_top = (ball_v == 1) && (ball_v_dir == 0); wire collide_bottom; assign collide_bottom = ((ball_v + 16) == 479) && (ball_v_dir == 1); wire collide_side1; assign collide_side1 = ball_h == (16 + 1) && (ball_h_dir == 0); wire collide_side2; assign collide_side2 = (ball_h + 16) == (640 - 16 - 1) && (ball_h_dir == 1); initial begin // keep in sync with reset block below paddle1_v <= 480 / 2; paddle2_v <= 280; ball_v <= 480 / 2; ball_h <= 480 / 2; ball_v_dir <= 1; ball_h_dir <= 1; game <= 0; end always @(posedge reset or posedge clk) begin if(reset) begin paddle1_v <= 480 / 2; paddle2_v <= 280; // so the ball gets the first bounce ball_v <= 480 / 2; ball_h <= 480 / 2; ball_v_dir <= 1; ball_h_dir <= 1; game <= 0; end else if(~game) begin if(collide_top | collide_bottom) ball_v_dir <= ~ball_v_dir; if(collide_side1) begin if(paddle1_inrange) ball_h_dir <= ~ball_h_dir; else game <= 1; end else if(collide_side2) begin if(paddle2_inrange) ball_h_dir <= ~ball_h_dir; else game <= 1; end if(ball_v_dir) ball_v <= ball_v + 1; else ball_v <= ball_v - 1; if(ball_h_dir) ball_h <= ball_h + 1; else ball_h <= ball_h - 1; if(paddle1_up) paddle1_v <= paddle1_v - 1; else if(paddle1_down) paddle1_v <= paddle1_v + 1; if(paddle2_up) paddle2_v <= paddle2_v - 1; else if(paddle2_down) paddle2_v <= paddle2_v + 1; end end endmodule