Computer Laboratory

ECAD and Architecture Practical Classes

The ball

The final task for this project will be to add the ball logic to the project and display the ball on the screen, together with implementing a scoring system. For the purposes of this lab, the ball will continue moving around the screen regardless of whether a player hits it or misses it. A player scores a point simply by hitting the ball with their bat. (as an [optional!] extension, you could reset the screen each time the ball is missed, and it starts again when someone presses a button. The score could also be shown on screen). The scores will be shown on the remaining 4 7-segment displays, HEX7 and HEX6 for the left hand player, HEX5 and HEX4 for the right hand one.

Initially, create a new project as before, this time named pong. The top level module should still be set as pong as well. The first task should be to implement the logic for calculating where the ball is. This should be added to the game_logic module, which should keep track of the current position of the ball and it's speed, and calculate its new position at the start of each frame. You may find it useful to keep 2 flags to indicate which direction the ball is travelling both horizontally and vertically. You may find the parameter `ballsize useful here.

Suggestion: you might consider making your counter module more generic and using instances, one for the X direction and the other for Y. But some people find it conceptually easier to create a module which handles both X and Y together.

Once the logic has been implemented, connect these outputs up to the renderer module, and add some more code which draws the ball on screen. The ball should be a simple 32 by 32 square of pixels. If you wish to produce a more realistic ball, see the optional exercise below.

Compile and run the project, and the ball should be bouncing around the screen. The final task is to add scoring capabilities to the project. Logic should be implemented that can tell if the ball has hit the bat, and if it has, then the score for that respective player should be incremented. These scores should be output onto the 7-segment displays as mentioned earlier.

Compile and run this, and ensure that the scores increment only when they are meant to. That is the final task for this exercise completed :-)

Optional Exercise

Change the renderer to draw a more ball-like ball (rather than a square "ball"!). The following code fragment may be useful. This takes in a 5-bit x and y co-ordinate as an index into the ball bounding box, and outputs whether the pixel should be on or not.

  module ballshape(
      input [4:0] x,
      input [4:0] y,
      output pixel
      );

      assign pixel = linepattern[x];
 
      reg [31:0] linepattern;

      always_comb
          case(y)
              5'h00:   linepattern <= 32'b00000000000011111111000000000000;
              5'h01:   linepattern <= 32'b00000000011111111111111000000000;
              5'h02:   linepattern <= 32'b00000001111111111111111110000000;
	      5'h03:   linepattern <= 32'b00000011111111111111111111000000;
	      5'h04:   linepattern <= 32'b00000111111111111111111111100000;
	      5'h05:   linepattern <= 32'b00001111111111111111111111110000;
	      5'h06:   linepattern <= 32'b00011111111111111111111111111000;
	      5'h07:   linepattern <= 32'b00111111111111111111111111111100;
	      5'h08:   linepattern <= 32'b00111111111111111111111111111100;
	      5'h09:   linepattern <= 32'b01111111111111111111111111111110;
	      5'h0a:   linepattern <= 32'b01111111111111111111111111111110;
	      5'h0b:   linepattern <= 32'b01111111111111111111111111111110;
	      5'h0c:   linepattern <= 32'b11111111111111111111111111111111;
	      5'h0d:   linepattern <= 32'b11111111111111111111111111111111;
	      5'h0e:   linepattern <= 32'b11111111111111111111111111111111;
	      5'h0f:   linepattern <= 32'b11111111111111111111111111111111;
	      5'h10:   linepattern <= 32'b11111111111111111111111111111111;
	      5'h11:   linepattern <= 32'b11111111111111111111111111111111;
	      5'h12:   linepattern <= 32'b11111111111111111111111111111111;
	      5'h13:   linepattern <= 32'b11111111111111111111111111111111;
	      5'h14:   linepattern <= 32'b01111111111111111111111111111110;
	      5'h15:   linepattern <= 32'b01111111111111111111111111111110;
	      5'h16:   linepattern <= 32'b01111111111111111111111111111110;
	      5'h17:   linepattern <= 32'b00111111111111111111111111111100;
	      5'h18:   linepattern <= 32'b00111111111111111111111111111100;
	      5'h19:   linepattern <= 32'b00011111111111111111111111111000;
	      5'h1a:   linepattern <= 32'b00001111111111111111111111110000;
	      5'h1b:   linepattern <= 32'b00000111111111111111111111100000;
	      5'h1c:   linepattern <= 32'b00000011111111111111111111000000;
	      5'h1d:   linepattern <= 32'b00000001111111111111111110000000;
	      5'h1e:   linepattern <= 32'b00000000011111111111111000000000;
	      default: linepattern <= 32'b00000000000011111111000000000000;
	endcase
  endmodule   
  


Previous  |  Contents  |  Next