ECAD and Architecture Practical Classes
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:
Tip: remember that Verilog usually
works with unsigned numbers. So, for example, you might think that
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