module PongBall ( input i_Clk, input i_IsGameActive, input [5:0] i_CellX, input [5:0] i_CellY, output reg o_DoDrawBall, output reg [5:0] o_BallX, output reg [5:0] o_BallY ); parameter SCREEN_WIDTH_CELLS = 40; parameter SCREEN_HEIGHT_CELLS = 30; parameter CLOCKS_PER_SECOND = 25000000; parameter BALL_MOVE_TIME_MS = 50; parameter BALL_SPEED = 1250000; reg [$clog2(BALL_SPEED)-1:0] r_ballMoveCount; reg [5:0] r_PrevBallX; reg [5:0] r_PrevBallY; always @(posedge i_Clk) begin if (!i_IsGameActive) begin o_BallX <= SCREEN_WIDTH_CELLS / 2; o_BallY <= SCREEN_HEIGHT_CELLS / 2; r_PrevBallX <= SCREEN_WIDTH_CELLS / 2 + 1; r_PrevBallY <= SCREEN_HEIGHT_CELLS / 2 - 2; end else begin if (r_ballMoveCount < BALL_SPEED) begin r_ballMoveCount <= r_ballMoveCount + 1; end else begin r_ballMoveCount <= 0; r_PrevBallX <= o_BallX; r_PrevBallY <= o_BallY; if ( // at right edge, travelling right (r_PrevBallX < o_BallX && o_BallX == SCREEN_WIDTH_CELLS - 1) || // not at left edge (o_BallX < r_PrevBallX && o_BallX != 0) ) begin o_BallX <= o_BallX - 1; end else begin o_BallX <= o_BallX + 1; end if ( // at bottom edge, travelling up (r_PrevBallY < o_BallY && o_BallY == SCREEN_HEIGHT_CELLS - 1) || // not at left edge (o_BallY < r_PrevBallY && o_BallY != 0) ) begin o_BallY <= o_BallY - 1; end else begin o_BallY <= o_BallY + 1; end end end end always @(posedge i_Clk) begin if (i_CellX == o_BallX && i_CellY == o_BallY) begin o_DoDrawBall <= 1; end else begin o_DoDrawBall <= 0; end end endmodule