71 lines
1.8 KiB
Verilog
71 lines
1.8 KiB
Verilog
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
|