User Tools


This is an old revision of the document!


Pong: Part 1

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.

  • Exercise 1: Designing a BallDrawer state machine on paper.
  • Exercise 2: Implementing the BallDrawer state machine in SystemVerilog, and verify with simulation.
  • Exercise 3: Testing that your BallDrawer state machine correctly displays a ball on the VGA display.
  • Exercise 4: Create a VLineDrawer module that draws vertical lines, simulate, and test with the VGA display.

Learning Outcomes

  • Learn how to implement state machines using behavioral SystemVerilog.

Preliminary

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).

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?

Exercises

Exercise #1 - BallDrawer State Machine

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
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 module should output (x_out, y_out) coordinates to write to, starting with the cycle immediately following the assertion of the start signal, and continue each cycle until complete. The done signal should be asserted during the cycle of the last pixel.

The following shows a diagram of a ball with 5 pixels, and the corresponding waveform for drawing this ball at (100,50).

Here are some other ball shapes you can use, or you can design your own. Your ball needs to have at least 4 pixels.

Did you make sure that your state machine will produce the correct behavior, based on the timing diagram above?  Make sure that the first pixel location is output in the cycle immediately after start goes high, that a new pixel is output every cycle, and that the done signal is asserted during the last pixel (not afterwards).

Exercise #1 Pass-off: Show the TA your state machine and describe how you verified that it meets the requirements described above.


Exercise #2 - BallDrawer SystemVerilog Module

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 to ensure it meets the timing behavior shown above.

Include a copy of your TCL file in your lab report.

Exercise #2 Pass-off: Show the TA a simulation of your BallDrawer module. The waveform should be similar to above. You can choose the (x_in, y_in) values, but make sure they are non-zero values.


Exercise #3 - Drawing Pong Objects on the VGA Display

top_object_drawer.sv
/***************************************************************************
* Module: top_object_drawer
*
* Author: Jeff Goeders
* Date: May 13, 2019
*
* Description: Top-level module for drawing Pong objects on Nexys4DDR board.
****************************************************************************/
 
`default_nettype none
 
module top_object_drawer(
    input wire logic            clk,
    input wire logic            CPU_RESETN,
 
    output logic        [3:0]   VGA_R,
    output logic        [3:0]   VGA_G,
    output logic        [3:0]   VGA_B,
    output logic                VGA_HS,
    output logic                VGA_VS,
 
    input wire logic            btnc
 
 
);
 
logic           clk_100;
logic           clk_25;
logic           reset;
 
 
logic   [2:0]   vga_color;
logic   [8:0]   vga_x;
logic   [7:0]   vga_y;
logic           vga_wr_en;
 
assign reset = ~CPU_RESETN;
 
BallDrawer BallDrawer_inst(
    .clk(clk_100),
    .reset(reset),
    .start(btnc),
    .draw(vga_wr_en),
    .done(),
    .x_in(50),
    .y_in(50),
    .x_out(vga_x),
    .y_out(vga_y)
);
 
clk_generator clk_generator_inst
 (
    .clk_100(clk_100),
    .clk_25(clk_25),
    .clk_in_100(clk)
 );
 
BitmapToVga BitmapToVga_inst(
    .VGA_R(VGA_R),
    .VGA_G(VGA_G),
    .VGA_B(VGA_B),
    .clk(clk_100),
    .clk_vga(clk_25),
    .VGA_hsync(VGA_HS),
    .VGA_vsync(VGA_VS),
    .reset(reset),
    .wr_en(vga_wr_en),
    .x(vga_x),
    .y(vga_y),
    .color(3'b111)
);
 
 
endmodule

In this exercise you will create a Pong module that draws draws two balls to the screen.

The top-level SystemVerilog file is provided below. It instantiates the BitmapToVga module and the glk_generator module needed to draw graphics on the VGA monitor. Your Pong module is also instantiated, and note how the modules are connected. Your Pong module is responsible for generating the signals to write pixels to the bitmap.

Note: You shouldn't change the top-level file. However, be sure to add a constraints file to your project that is configured appropriately. The top-level module contains connections for the buttons. You don't need to use the buttons in this lab, but you will be using them in the next lab. Make sure you include the appropriate constraints for them now, otherwise Vivado will error when compiling the project.

Exercise #3 Pass-Off: Show your display to the TA. The TA will verify that you are drawing two balls on the screen of different color, and that you are using only one instance of your BallDrawer module.


Exercise #4 - Line Drawer (10% of lab pass-off grade)

Create the following module that can be used to draw a vertical line. 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
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

The module should output (x_out, y_out) coordinates to write to, starting with the cycle immediately following the assertion of the start signal, and continue each cycle until complete. The done signal should be asserted during the cycle of the last pixel.

The following shows a diagram of a line 6 pixels tall, and the corresponding waveform for drawing this line at (100, 50).


Exercise #4 Pass-off: Add an instantiation of your VLineDrawer to your Pong module from the last exercise, and change your state machine to draw a line and a ball. Show the TA the display.

Submit your SystemVerilog modules using the code submission on Learning Suite. (Make sure your SystemVerilog conforms to the lab SystemVerilog coding standards).