EE421 A-1 Spring-2023
EE421 A-1 Spring-2023
Inputs:
Active low reset signal (does not reset the screen buffer).
Resetn
Digital circuits with state elements should always contain a reset.
Clock signal.
Clock The VGA Adapter core must be fed with a 50MHz clock to function
correctly.
Pixel colour (3 bits).
Sets the colour of the pixel to be drawn. The three bits indicate the
Colour (2 down to 0)
presence of Red, Green and Blue components for a total of 8 colour
combinations.
x (7 down to 0) X coordinate of pixel to be drawn (8 bits) – supported values 0 ≤ x < 160.
Note that you will connect the outputs of the VGA Adapter core directly to appropriate output
pins of the FPGA (please see the datasheet for your particular board).
You can picture the VGA screen as a grid of pixels shown in Figure 3. The X/Y position (0,0) is
located on the top-left corner and (159,119) pixel located at the bottom-right corner. The role of
the VGA Adapter core is to continuously draw the same thing on the screen at the monitor’s
refresh rate, e.g. 60 Hz. To do this, it has an internal memory that stores the colour of each pixel.
Your circuit will write pixel colours to the VGA Adapter core.
Download the VGA core from UofT website. The Verilog files describing the VGA Adapter core
can be included into Altera Quartus II project. You shouldn’t be modifying the VGA Adapter Core
code at all!!!
In order to understand the VGA Adapter core, create a top level vga_demo.v file. This file does
nothing but connect the VGA Adapter core I/O to switches on the board so you can experiment.
It will let you understand how the inputs of the core work.
This task is not worth any marks, but you should do it to ensure that everything else is working
(e.g. your VGA Cable is good) before starting the main task below.
Make sure you include the Adaptor Core files in your project: vga_adapter.v, vga_controller.v,
vga_address_translator.v and vga_pll.v. And remember to set up your pin assignments for your
board.
function circle_bresenham ( xc , yc , r )
x := 0
y := r
d := 3-2*r
loop
if x > y exit loop
setPixel (xc + x, yc + y)
setPixel (xc - x, yc + y)
setPixel (xc + x, yc - y)
setPixel (xc - x, yc - y)
setPixel (xc + y, yc + x)
setPixel (xc - y, yc + x)
setPixel (xc + y, yc - x)
setPixel (xc - y, yc - x)
x := x + 1
if d < 0 then
d := d + (4 * x) + 6
else
d := d + 4 * (x – y) + 10
y := y – 1
end if-else
end loop
end function
The algorithm is quite efficient: it contains no multiplication or division (multiplication by
multiples of 2 can be implemented by a shift-register that shifts left). Because of its simplicity
and efficiency, the Bresenham Circle Algorithm can be found in many software graphics libraries,
and in graphics chips.
In this task, you will implement a circuit that behaves as follows:
1. The switch KEY[3] is an asynchronous reset. When the machine is reset, it will start
clearing the screen to black. Hint: Task2 is basically clearing the screen if you set all pixels
to black. Clearing the screen will take at least 160*120 cycles.
2. Once the screen is cleared, your circuit will idle. At this point, the user can set switches 7
down to 3 (SW[7:3]), which indicates the radius, and switches 2 down to 0 (SW[2:0]),
which indicates one of 8 possible colours used to draw the line. IMPORTANT: Restrict
user entered radius to be within 0 to 59. If you don’t, you will see some unexpected
behavior (strange patterns being drawn instead of a circle). For example, if the user set
the switches to indicate a value of 70 for radius, just clip it to 59.
3. When the user presses KEY[0], the circuit will draw a circle. Centre of the circle should be
the centre of the screen (location 80,60) and radius as specified by the user. Of course,
this will take multiple cycles; the number of cycles depends on the radius of the circle.
4. Once the circle is done, the circuit will go back to step 3, allowing the user to choose
another radius and color. Do not clear the screen between iterations. At any time, the
user can press KEY[3], the asynchronous reset, to go back to the start and clear the screen.
The reset signal on the VGA Core does not clear the screen. That’s why you need to do it
manually in step 1. But this also means that you don’t have to do anything special to retain
previously drawn circles on the screen.
Note that you are using CLOCK_50, the 50MHz clock, to clock your circuit. You must clearly
distinguish the datapath from the FSM in your Verilog code (i.e. don’t write one giant always
block to do everything). The reason that this is a requirement is that we want you to practice
manual partitioning of the datapath and FSM for now.
Technical Grading:
10 marks (initializing screen black after reset)
10 marks (structure of FSM and Datapath; clear separation of code)
30 marks for Task-2
40 marks for Task-3
10 marks for challenge circuit