Assignment 2
Assignment 2
Mahdi Shabany
Electrical Engineering Department
Sharif University of Technology
Introduction
The purpose of this laboratory is to further expand your understanding of finite state machines (FSMs) and
to learn how one can use a “Video Graphics Array” (VGA) Adapter to create pictures and animation on a
computer screen. You will create FSMs to interact with a VGA Adapter “core” that has been implemented
for you to control and generate images and animations on the screen.
Part I.a :
To familiarize yourself with the VGA Adapter module you will perform a simple exercise to display a custom
image on the screen. To do this you will need to use the bmp2mif converter provided in the starter kit. It is
a program that converts a bitmap image into a stream of bits that can be programmed into the memory on
an FPGA. To be able to display a picture you must first draw a picture using a graphics editing tool that can
save files in a BMP format. The Microsoft Windows “Paint” program is one such tool. The image you will
draw will cover the entire screen and thus has to be created correctly. Perform the following steps to draw
an image:
1. Start the Paint program, typically available from the Start Menu:
Start-> Programs->Accessories->Paint
2. Select the menu item Image->Attributes. In the dialog box set "width" equal to 160 and
"height" equal to 120, as this is the resolution of the monitor that the adapter uses. Select
"pixels" as the unit. Select "colors" as well.
3. Draw a picture of your own design; use simple colors like Red, Green and Blue.
4. Save the file, using File->Save As and save it as a 24-colour bitmap image.bmp.
5. Run the bmp2mif.exe converter program (a windows program described on the VGA website
and available from the download directory on that site) to convert your BMP file to a Memory
Initialization File (MIF) we will use next. (To do that, start up a DOS command shell on windows
using Start->Run and type "cmd" into the Open: box that pops up. This will create a window
you can type commands into. Change into a folder that contains both bmp2mif.exe and the
file.bmp you wish to convert. Then type "bmp2mif file.bmp." This will produce two .mif files -
image.mono.mif and image.colour.mif.)
Fig. 1. In-memory representation of the 4x4 pixel image. Each box holds a pixel color, a 3 bit value in our case
To ensure that you understand how the MIF file is used and what it represents, you are required to add a
cyan 2x2 square with the top left corner placed at coordinates (x,y), where x corresponds to the last two
digits of your student number and y corresponds to the second last two digits of your student number.
(Which location in the VGA Adapter memory would you have to change to alter to color of the specified
pixel?) You must use the MIF editor to do this. The MIF editor can be launched by simply opening the .mif
file in Quartus. Refer to Fig. 1 for an illustration of how the VGA framebuffer is organized. Recall from the
description of the VGA Adapter that it uses memory to store the current color of each pixel on the screen.
Usually, this memory is initialized to 0 at first and hence you only see a black background. However, we can
change the initial state of the VGA Adapter memory, causing it to display an image. You will use the image
you created earlier with paint as that background.
Perform the following steps to change the initial image displayed by the Adapter:
1. The project for this part is provided in the starter kit. Open the project named background in the
part1 subdirectory to begin your work.
2. The BMP2MIF converter created a file called image.colour.mif, where your background image is
stored. Copy this file to your working directory and change its name to display.mif. Note: The
choice of the file name is not accidental. If you look carefully at the implementation of the VGA
Adapter you will see that it has a parameter called BACKGROUND_IMAGE. This parameter is set to
"display.mif" by default and signifies that the Quartus II software should use display.mif file to
initialize the memory for the VGA Adapter. Note also that there can only be one display file which
is programmed into the memory when the FPGA is configured (when you ’download’ your design).
It is a common mistake to think that you can create many of these files and somehow cause the
FPGA to switch through them; this isn’t possible as the download only happens once.
DE2: Program the circuit onto the Altera DE2 board. When you program the DE2 board and connect
a monitor to its graphics port, you should be able to see the image you have drawn.
IMPORTANT: Make sure you understand how this initialization process works: the memory (in the case of
the VGA adapter, this memory is the framebuffer) is initialized with the contents of the MIF file (which
stands for "Memory Initialization File") only when the FPGA is programmed. The MIF file is just the stream
of raw data, and is not specific to the VGA Adapter - it can be used to initialize any kind of memory. The
memory initialized this way can be changed – by modifying individual pixels on the screen as discussed in
the VGA Adapter documentation. Note that as soon as you draw a pixel using the VGA Adapter, the contents
of this memory will be altered. Thus, if you used a background image as we have shown above, the
background image will be permanently altered. Resetting the VGA Adapter will NOT restore the
"background image."
Part I.b :
In this part you are asked to design a very simple circuit using the VGA adapter. The circuit has to perform
the following functions:
1. Accept the X and Y coordinate inputs and the color input from the switches on the DE2 board.
2. Set the given color of the pixel at the given coordinates when a push-button is pressed.
The schematic of the circuit is given in Fig. 2. You should reuse the project file from Part Ia and design a
circuit that connects up the switches on the DE2 board as given in the figure. After completing this circuit
you will be able to manually (and tediously) draw any picture on the screen. You will do this by choosing a
(binary) value for the X and Y location of each pixel to change, choose a value for the color, and then pushing
the "enable" button to cause the specific pixel to change.
Observe that any image which you loaded in Part 1a is over-written as you change the colors of the pixels.
This is because the VGA adapter has only one block of memory to store the value of each pixel (this block
is called a framebuffer in the graphics world. This buffer was initialized with your image, but as you change
the colors of the pixels, the old values are overwritten and lost.
Part II:
In this part you will learn how to draw pixels on the screen after your circuit begins running. To demonstrate
this, you will design a simple “Etch-a-Sketch” drawing system (see:
http://en.wikipedia.org/wiki/Etch_A_Sketch if you don’t know what that is).
This Etch-a-Sketch is a circuit that moves a cursor around the screen, either up, down, left, or right, and
draws a new pixel with every move the cursor makes. The system has 6 inputs, described below. The output
is facilitated by the VGA Adapter and appears on the screen. The inputs are:
1. Resetn - an active low input to reset the system. Reset should cause the cursor to go to position (0,0)
the top-left corner of the screen.
2. CLOCK_50 - the clock input to drive the finite state machine of the system as well as the VGA adapter.
3. Four switches labeled left, right, up, down - to indicate the direction to move the cursor in. Each time
an input, for example left is set to 1, the drawing system show move the cursor left by exactly 1 pixel.
(It should wait until the Left signal returns to 0 before moving the cursor again).
Fig. 3: Design Overview - State Machine, Datapath and VGA Adapter. Although not shown, ResetN signal
should be connected to all the registers in the circuit (including FSM state register).
The high-level design of the circuit for the etch-a-sketch system is given in Fig. 3. It contains 3 major blocks:
1. The VGA adapter responsible for the drawing of pixels on the screen, which you have been learning about
it parts I and II.
2. The ’datapath’ that controls the position of the cursor, providing the VGA adapter with the (X,Y) (i.e. column
and row) location where a pixel should be drawn.
3. A finite state machine that receives the input from a user and directs the datapath to change the position
of the cursor accordingly, by adding and/or subtracting from the (X,Y) position of the cursor.
You may use the circuit from Part I.b as a base for your design.
Part III:
Now that we covered drawing pixels on the screen we can proceed to create a simple animation. We will
create a circuit that takes a small image (16x16 pixels) and moves it around the screen. To accomplish this,
your circuit will have to make it seem as though the image is seemlessly moving around the screen. You will
implement the circuit in two steps. First, you will design a module that is able to draw (or erase) the image
at a given location. Then you will design another module that moves the image around the screen by quickly
redrawing it at the different locations.
To implement this part, you will have to create a circuit that takes as input the (screen_X, screen_Y)
coordinate of where the top left corner of the image is to be drawn or erased. The circuit will then either
draw the image from the memory (LPM_RAM_DQ module) or erase the image starting at position
(screen_X,screen_Y). Images are drawn or erased pixel by pixel. To draw an image, read a single entry
from memory and pass that value to the “Color” line on the VGA adapter. During this process, you must set
the X,Y values on the VGA adapter to the appropriate values. Erasing an image is a similar process, however,
instead of passing the values from the “Image RAM” to “Color”, you will set “Color” to black (constant 000).
To accomplish these steps, you will need to create a state machine that performs the following:
2. While Counter_X is less than 16, either load a pixel value from memory containing image.mif, or set
the pixel value to black (if erasing). Then draw that pixel at location (screen_X+Counter_X,
screen_Y+Counter_Y) on the screen. Increment Counter_X.
3. If Counter_Y is less than 15, then increment Counter_Y and set Counter_X to 0. Go to step 2.
The suggested circuit diagram is shown in Fig. 4. The “Blank” and “Plot” inputs may be used in several
different ways. One way is to have “Blank” input select whether the image should be drawn or erased (i.e.,
if the “Blank” is high when “Plot” is asserted, the image is erased). Another way is to have two separate
inputs, one to start drawing (“Plot”), and another to start erasing (“Blank”). You are free to choose
whichever method you want.
1. The project for this part is provided in the starter kit. Open the project named part3 in the part3
subdirectory to begin your work.
2. Create a 16x16 bitmap image that is to move around the screen. Make sure to set the image width and
height to 16 pixels.
3. Use the bmp2mif.exe converter to convert the image into an MIF file. Call it image.mif.
4. In your design instantiate a memory using an LPM_RAM_DQ and use image.mif as its memory
initialization file.
5. Create a circuit to draw an image at a specified location on the screen as discussed above.
6. Compile the circuit and download it onto the DE2 board. When your circuits starts you should be able
to see the image you have drawn somewhere on the screen.
Note that this can be done using Tools>MegaWizard Plug-In Manager, which is described in Tutorial II
on the course website.
The circuit from step 1 can be used to draw an image at any location (X,Y). To move the image, you will have
to first erase it from the location it is currently at and then draw it again at an alternate location. There is a
simple way to do that when the screen background is black. First, we draw an image at location (X,Y). Then
to move the image we simply draw a black box on top of the image (using the erase function of the circuit
from step 1) and redraw the image somewhere else. A suggested circuit is shown in Fig. 5, and you may use
it as a starting point.
1. Create a circuit to change the location of the top left corner of where the image is to be drawn, once
every 60th of a second. You may use circuit shown in figure 5 as a reference.
2. Put the circuits together to see if your image moves around the screen. Compile the circuit and program
it onto the FPGA to see if it works.
3. If the circuit works, think of a way to get the image to bounce of the sides of the screen as it moves
about. Implement the enhancement and show the circuit to your TA.