ECAD and Architecture Practical Classes
Displaying the bats
This next part of the practical will involve making use of the counter developed previously to keep track of where the bats are on the screen, together with implementing the logic that will actually draw the bats. Developing in a modular style like this allows us to re-use components, much like we are here. Instead of repeating the code twice, we create a single counter module, and then instantiate twice for the left and right bats.
Create a new project named bats (but still with the top-level module pong). Do not forget to import the pin assignments again, otherwise your project will not work. Initially, we have to alter the counter slightly to be tailored to our needs. The counter module will provide the y-co-ordinate of the bottom of each bat. Change the counter code so that it behaves in the following ways:
- At the moment it has an 8-bit output. The screen is 1024 (`vc) pixels high, hence the output width must be changed to allow values this large.
- The counter must not be able to move the bat below the bottom of the screen or above the top of the screen. Do not hard-code in values here, use parameters defined in defines.v instead. In this case, `vc and `batheight will be useful.
- The counter should have an asynchronous reset input that resets the bats to be in the centre of the screen.
Tip: remember that Verilog usually
works with unsigned numbers. So, for example, you might think that
x < y is logically equivalent to
x - y < 0 but the latter is always false since the
x - y can never be less than zero since the
result is unsigned.
Next, create another module that will calculate the logic needed for the game. Since logic is a keyword in Verilog, name this module game_logic instead. This module should instantiate the counter twice, once for each bat, and the values should be outputted from the game_logic module. The reset inputs should be connected to SW. Now you have the counters implemented in the game_logic module, remove the instances created in the previous stage from the top-level module. This module should now be instantiated at the top-level (in pong.v) and the 2 outputs wired into the renderer module. This is the module that, strangely enough, renders the image on the screen. It already has x and y inputs, these are the co-ordinate of the pixel currently being drawn on the screen. (0,0) is at the top-left. The if-else statement currently in the always-@ block is the section of code that draws the red rectangle on a blue background. Delete this code, and, using the bat inputs to this module, add code to draw blue bats on a green background. Again, do not hard-code parameters, use `batheight and `batwidth instead.
Compile and run the code, and you should be able to move the left hand bat up and down with KEY and KEY respectively, and similarly the right hand bat up and down with KEY and KEY respectively. For debugging purposes, you may find it useful to wire up the bat positions to HEX3, HEX2, HEX1 and HEX0 as you did in the counter exercise, to ensure that the counters are indeed not outputting values that will cause the bats to appear off-screen. You should end up with a screen looking like the image below.
Once this is running, you will notice the bats move very slowly up and down the screen. This is because they currently move one pixel per screen refresh. We really need the bats to move at a speed proportional to the ball speed. The parameter `batspeedup is used as a scale factor for this purpose. The next task is to edit the game_logic and counter modules to take into account these new factors.
The ball speed (in pixels-per-second) will be given by SW[7:0]. The logic module will need to keep track of this, together with computing the ball speed. The ball speed should then be passed as an input into the counter module, and this value will be the amount to increment/decrement the counter value by at each clock edge. Be careful to ensure that the counter can still never place the bat off-screen.
Once this has been implemented, you should be able to move the bats up and down at varying speeds depending on the values of the lower 8 switches. The next, and final, part of the project will be to add the ball on the screen.