This lab and the next lab work together to build a Pong game on the VGA display. In this lab you will create two modules, a ball drawer and a vertical line drawer.
In this lab you will again be using the BitmapToVga module. Make sure you remember how this module works.
What 3-bit binary value would you provide to the module to set the color of a pixel to cyan? Provide your answer in SystemVerilog literal form (ex 3'b000).
Assuming you can write 1 pixel per clock cycle, what is the minimum number of cycles required to change the entire image to blue? How many microseconds would this take, given your system clock?
Design a state machine (on paper) that can be used to draw a ball. The module behavior is described below:
Module Name = BallDrawer | |||
---|---|---|---|
Port Name | Direction | Width | Description |
clk | Input | 1 | 100 MHz Input Clock |
reset | Input | 1 | Reset |
start | Input | 1 | High to start drawing a ball, must go back low before drawing another ball. |
draw | Output | 1 | High when the module is outputting a valid pixel location to draw |
done | Output | 1 | High on cycle that last pixel location is output |
x_in | Input | 9 | Leftmost x-Coordinate of ball to be drawn |
y_in | Input | 8 | Topmost y-Coordinate of ball to be drawn |
x_out | Output | 9 | x-Coordinate to be drawn |
y_out | Output | 8 | y-Coordinate to be drawn |
The following shows a diagram of a ball with 5 pixels, and a corresponding waveform for drawing this ball at (100,50).
Your state machine does not need to produce the exact same timing as the waveform above, but it does not to obey a few rules:
start
signal before starting to draw a ball. x_out
and y_out
outputs, and assert the draw
signal to indicate that a valid pixel is being output. done
signal should be asserted for exactly 1 cycle after the ball is done being drawn (or during the last pixel). start
signal to go low before allowing another ball to be drawn.Here are some other ball shapes you can use, or you can design your own. Your ball needs to have at least 4 pixels.
Exercise #1 Pass-off: Show the TA your state machine and describe how you verified that it meets the requirements described above.
Create the BallDrawer
SystemVerilog module that implements your state machine.
module BallDrawer ( input wire logic clk, input wire logic reset, input wire logic start, output logic draw, output logic done, input wire logic [8:0] x_in, input wire logic [7:0] y_in, output logic [8:0] x_out, output logic [7:0] y_out ); endmodule
Simulate your BallDrawer
module. You can use the following TCL script. It will test drawing your Ball in two different locations. Make sure your state machine doesn't draw the second ball until the start
signal goes low and then back high the second time. (Remember that on the waveform you can select multiple signals and right-click to change the radix. It may be helpful to display the x,y coordinates as unsigned decimal).
restart add_force clk {0 0} {1 5ns} -repeat_every 10ns add_force reset 1 add_force start 0 run 10ns add_force reset 0 run 10ns # Draw ball at 100, 200 add_force x_in -radix dec 100 add_force y_in -radix dec 200 add_force start 1 run 120ns # Lower start signal add_force start 0 run 20ns # Draw ball at 150, 20 add_force x_in -radix dec 150 add_force y_in -radix dec 20 add_force start 1 run 120ns
Exercise #2 Pass-off: Show the TA a simulation of your BallDrawer
module and explain how you tested its functionality.
In this exercise you will verify that your BallDrawer
module works correctly, by drawing a ball to the VGA display. The following top-level module can be used. Look it over and make sure you understand it.
The module works by connecting up the appropriate signals from your BallDrawer
module to the BitmapToVga
module. You shouldn't have to change this file to get it to work properly; however, you may decide to change it later to modify the ball location or color.
Add the above file to your Vivado project and make sure it is configured as the top-level module. Add a constraints file to your project that is configured appropriately.
Exercise #3 Pass-Off: Show your display to the TA. The TA will verify that you are successfully drawing a ball on the screen.
Now that you have created a module to draw a ball, you will follow the same process to create a module that can draw vertical lines of arbitrary height.
Create the following module. Use a state machine to implement the described behavior.
Module Name = VLineDrawer | |||
---|---|---|---|
Port Name | Direction | Width | Description |
clk | Input | 1 | 100 MHz Input Clock |
reset | Input | 1 | Reset |
start | Input | 1 | High to start drawing a line |
draw | Output | 1 | High when the module is outputting a valid pixel location to draw |
done | Output | 1 | High on cycle that last pixel is drawn |
x_in | Input | 9 | x-Coordinate of line to be drawn |
y_in | Input | 8 | y-Coordinate of top of the line |
height | Input | 8 | Height of line in pixels |
x_out | Output | 9 | x-Coordinate to be drawn |
y_out | Output | 8 | y-Coordinate to be drawn |
This module should work very similarly to your BallDrawer
module, except now there is a height
input that dictates the height of the line. Since the height can be changed, you can't use one state per pixel being drawn. Instead, your state machine will need to interact with a counter to keep track of how many pixels you need to draw.
The following shows a diagram of a line 6 pixels tall, and a waveform for drawing this line at (100, 50).
Simulate your VLineDrawer
module to ensure it is working correctly. You can probably re-use the TCL above with minimal changes. Make sure to set the height
input, and test drawing two lines of different height.
Paste your TCL simulation file in your lab report.
Modify the top-level from the last exercise to draw a vertical line instead of a ball.
Exercise #4 Pass-off: Show the TA your VLineDrawer
module and the line drawing correctly on the monitor.
Submit your final lab report on Learning Suite. Submit the SystemVerilog code of your two modules.
There is no personal exploration for this lab.