C2C John Miller
VHDL Code to play the classic game of pong on the Atlys Board
The game takes on the following form
This code also supports the use of the switches on the Atlys board for modifying the speed of the ball.
The major problems that this project dealt with were:
1.2 -Implements the addition of "hot zones" on the paddle, which reflect the ball at different angles
This project relied heavily on the use of a finite state machine [FSM], which uses a mix of next state logic, memory, and output logic in order to determine the state of the machine. The inputs and current state are fed into the next state logic block which then determines what the state will be. The current state is then fed into the output logic, which then generates the output.
The following basic constructs were used to realize the state machine:
Flip-flop (memory element):
process(clk, reset)
begin
if (reset = '1') then
x_reg <= to_unsigned(400,11);
y_reg <= to_unsigned(200,11);
elsif rising_edge(clk) then
x_reg <= x_next;
y_reg <= y_next;
end if;
end process;
Next State logic:
process(ball_reg, ball_next, count_next, x_reg, y_reg, paddle_y_reg)
begin
ball_next <= ball_reg;
if(count_next = 0) then
case ball_reg is
when move =>
if (x_reg = 639) then
ball_next <= right;
elsif (x_reg = 10) then
ball_next <= left;
elsif (y_reg = 5) then
ball_next <= top;
elsif (y_reg = 479) then
ball_next <= bottom;
end if;
if (x_reg >10 and x_reg < 20) then
if ( (y_reg > paddle_y_reg - 45) and (y_reg< paddle_y_reg) ) then
ball_next <= paddle_hit_hi;
elsif( (y_reg < paddle_y_reg + 45) and (y_reg> paddle_y_reg) ) then
ball_next <= paddle_hit_lo;
end if;
end if;
when right =>
ball_next <= move;
when left =>
ball_next <= move;
when top =>
ball_next <= move;
when bottom =>
ball_next <= move;
when paddle_hit_hi =>
ball_next <= move;
when paddle_hit_lo =>
ball_next <= move;
end case;
end if;
end process;
Output Buffer
process( count_next)
begin
x_next<= x_reg;
y_next <= y_reg;
if(count_next = 0 and v_completed = '1' and stop_reg ='0') then
if(dx_reg = '1') then
x_next <= x_reg +1;
else
x_next <= x_reg -1;
end if;
if(dy_reg = '1') then
y_next <= y_reg -1;
else
y_next <= y_reg +1;
end if;
end if;
end process;
Output logic
ball_x <= x_next;
ball_y <= y_next;
The following modules were to implement the game
The modules are connected as shown below:
State transition diagram
Ball states :
The biggest troubles I had can be separated by module:
pixel_gen.vhd:
pong_control.vhd:
Although they would have been a more robust method of testing, testbenches were not used in debugging the code, instead, it was done in incremental stages.
the AF logo was created, which was changed by modifying the pixel_gen module slightly each time until the output matched the design requirements
The paddle and ball were drawn to make sure that their proportions were correct
The paddle was tested until it met movement requirements. This meant changing lines of code at a time until the paddle moved at a reliable rate
The ball was incrementally tested, first for horizontal movement, then for vertical movement. Then the ball was tested to make sure it would bounce off the walls, and then that it would bounce off of the paddle and that it would freeze if it hit the left hand wall.
Once the core gameplay was created, the code was modified to support ball speeds and "hot zones" on the paddle.
The hardest thing to test was the ball movement. The ball would work for periods of time and then it would "teleport", instantly moving to a different section of the screen.
C2C Ryan Good helped me with debouncing