This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
labs:pong_part_1 [2019/09/10 17:18] jgoeders [Exercise #3 - Drawing Pong Objects on the VGA Display] |
labs:pong_part_1 [2019/11/15 10:30] (current) jgoeders [Exercise #2 - BallDrawer SystemVerilog Module] |
||
---|---|---|---|
Line 19: | Line 19: | ||
<color #ed1c24>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).</color> | <color #ed1c24>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).</color> | ||
- | <color #ed1c24>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? | + | <color #ed1c24>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? |
</color> | </color> | ||
Line 35: | Line 35: | ||
| clk | Input | 1 | 100 MHz Input Clock | | | clk | Input | 1 | 100 MHz Input Clock | | ||
| reset | Input | 1 | Reset | | | reset | Input | 1 | Reset | | ||
- | | start | Input | 1 | High to start drawing a ball | | + | | 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| | | 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 | | | done | Output | 1 | High on cycle that last pixel location is output | | ||
Line 43: | Line 43: | ||
| y_out | Output | 8 | y-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 a corresponding waveform for drawing this ball at (100,50). |
- | + | ||
- | The following shows a diagram of a ball with 5 pixels, and the corresponding waveform for drawing this ball at (100,50). | + | |
{{:labs:lab_pong:ball_drawing_5.png| }} | {{:labs:lab_pong:ball_drawing_5.png| }} | ||
+ | {{:labs:lab_pong:ball_drawing2.png| }} | ||
- | {{:labs:lab_pong:ball_drawing2.png| }} | + | 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: |
+ | * The state machine should wait for the ''start'' signal before starting to draw a ball. | ||
+ | * For each pixel that needs to be drawn, the state machine should output an (x,y) coordinate using the ''x_out'' and ''y_out'' outputs, and assert the ''draw'' signal to indicate that a valid pixel is being output. | ||
+ | * The ''done'' signal should be asserted for exactly 1 cycle after the ball is done being drawn (or during the last pixel). | ||
+ | * The state machine should wait for the ''start'' signal to go low before allowing another ball to be drawn. | ||
Line 58: | Line 61: | ||
- | <color #ed1c24>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</color>). | ||
** Exercise #1 Pass-off:** Show the TA your state machine and describe how you verified that it meets the requirements described above. | ** Exercise #1 Pass-off:** Show the TA your state machine and describe how you verified that it meets the requirements described above. | ||
Line 84: | Line 86: | ||
- | Simulate your ''BallDrawer'' module to ensure it meets the timing behavior shown above. | + | 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). |
- | <color #ed1c24>Include a copy of your TCL file in your lab report.</color> | + | <file tcl> |
+ | 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 | ||
- | ** 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. | + | # 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 |
- | ==== Exercise #3 - Drawing Pong Objects on the VGA Display ==== | + | add_force start 0 |
+ | run 20ns | ||
- | 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. | + | # 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 | ||
+ | </file> | ||
- | Basically, the module works by connecting up the appropriate signals from your ''BallDrawer'' module to the ''BitmapToVga'' module. | ||
- | <file SystemVerilog top_object_drawer.sv> | + | ** Exercise #2 Pass-off:** Show the TA a simulation of your ''BallDrawer'' module and explain how you tested its functionality. |
- | /*************************************************************************** | + | |
- | * 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 | + | ---- |
+ | ==== Exercise #3 - Drawing Pong Objects on the VGA Display ==== | ||
- | module top_object_drawer( | + | 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. |
- | input wire logic clk, | + | |
- | input wire logic CPU_RESETN, | + | |
- | output logic [3:0] VGA_R, | + | 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. |
- | output logic [3:0] VGA_G, | + | |
- | output logic [3:0] VGA_B, | + | |
- | output logic VGA_HS, | + | |
- | output logic VGA_VS, | + | |
- | input wire logic btnc | + | {{ :labs:lab_pong:top_object_drawer.sv |}} |
- | + | ||
- | ); | + | |
- | logic clk_100; | + | 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. |
- | 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 | + | |
- | </file> | + | |
- | + | ||
- | 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 #3 Pass-Off:** Show your display to the TA. The TA will verify that you are successfully drawing a ball on the screen. | ||
---- | ---- | ||
- | ==== Exercise #4 - Line Drawer (10% of lab pass-off grade) ==== | + | ==== Exercise #4 - Line Drawer ==== |
/* ** You only need to complete this exercise if you want to complete the full Pong game next lab.** */ | /* ** You only need to complete this exercise if you want to complete the full Pong game next lab.** */ | ||
+ | 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 that can be used to draw a vertical line. Use a state machine to implement the described behavior. | + | Create the following module. Use a state machine to implement the described behavior. |
^ Module Name = VLineDrawer ^^^^ | ^ Module Name = VLineDrawer ^^^^ | ||
Line 196: | Line 144: | ||
| reset | Input | 1 | Reset | | | reset | Input | 1 | Reset | | ||
| start | Input | 1 | High to start drawing a line | | | 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 | | | done | Output | 1 | High on cycle that last pixel is drawn | | ||
| x_in | Input | 9 | x-Coordinate of line to be drawn | | | x_in | Input | 9 | x-Coordinate of line to be drawn | | ||
Line 203: | Line 152: | ||
| y_out | Output | 8 | y-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. | + | 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 the corresponding waveform for drawing this line at (100, 50). | + | The following shows a diagram of a line 6 pixels tall, and a waveform for drawing this line at (100, 50). |
{{:labs:lab_pong:line_drawing.png |}} | {{:labs:lab_pong:line_drawing.png |}} | ||
Line 211: | Line 160: | ||
{{:labs:lab_pong:line_drawing_waveform.png|}} | {{:labs:lab_pong:line_drawing_waveform.png|}} | ||
+ | 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. | ||
+ | |||
+ | <color #ed1c24>Paste your TCL simulation file in your lab report.</color> | ||
+ | |||
+ | Modify the top-level from the last exercise to draw a vertical line instead of a ball. | ||
\\ | \\ | ||
- | ** 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. | + | ** Exercise #4 Pass-off:** Show the TA your ''VLineDrawer'' module and the line drawing correctly on the monitor. |
+ | |||
+ | ---- | ||
+ | |||
+ | ==== Final Pass-Off === | ||
- | <color red>Submit your SystemVerilog modules using the code submission on Learning Suite.</color> (Make sure your SystemVerilog conforms to the lab SystemVerilog coding standards). | + | <color red>Submit your final lab report on Learning Suite. Submit the SystemVerilog code of your two modules.</color> |
+ | There is no personal exploration for this lab. |