Assigned: 17 November 2007
Due: 7 December 2007
As usual, errata for this lab can be found at the lab 4 wiki page.
The hardware portion of this lab requires a successful implementation of Lab 4-SW. One big advantage of pipelining is that the synthesis and implementation steps both happen much faster. In addition, we now have several I/O choices. The best part is that a BIOS means that changing the program is no longer a full re-implementation.
There are several new tools being introduced this time around. To make things easy,we have provided a single zip file containing all of the necessary files and tools.
In order to properly synthesize your design, the Flow Settings for your design must be correctly set. Click on the Flow Settings button in the Design Flow Manager and verify that the following settings are correct:
There are several options that you must set before synthesis can take place. A step by step tutorial that points out each of these settings is available here. Once you have completed setting the options for synthesis, you can run Synplify to begin the process. This is also covered in the tutorial.
Be sure that you check the warnings produced by Synplify as some warnings may indicate significant problems with the design that could cause it to fail to implement correctly. A list of warnings grouped by severity can be found here. If you have run into a warning that is not listed on that page and are unsure about whether or not it is going to be a problem, contact one of the course staff.
Now that you have completed synthesis, verify that you have the required files for implementation. You should have a .edf file selected in the file list.
As with synthesis, you will need to set several options before beginning implementation. A detailed tutorial on setting up and running the implementation process is available here.
This process can be time consuming, so be prepared to wait anywhere from 10 to 30 minutes for it to complete. For this reason, please do NOT perform implementation on workstations that have XUP boards attached, as this will tie them up when others could be using them.
Once implementation is completed, you will have a .bit file that can be used to program the board.
The final step in getting your design onto the board is using Impact to program the board using the initialized .bit file. A detailed tutorial on using Impact is available here.
When the little hourglass disappears the pattern should start. At the end of the moves, the program turns on LED[0] and waits for commands from the Bootloader. To make it start from scratch, toggle the little white switch closest to the LEDs.
One major flaw in the previous hardware labs was the need to re-implement for every change to the program. To solve this issue we wrote a small BIOS routine that uses the serial port to communicate with a program running on the PC. This means that programs can now be downloaded to the board virtually instantaneously.
The BIOS is a simple program that resides in the ROM starting at address 0. The BIOS does the following things:
There are currently only 4 supported commands (shown below). Fortunately these allow the main task of downloading programs to memory, as well as a few other odds and ends.
Command Value Behavior Write Word 0x00 MEM[store_ptr] = data; store_ptr += 4 Set Pointer 0x01 store_ptr = data; Run Program 0x02 setup $sp, jump to 0x00400000 Write Byte 0x03 MEM[store_ptr] = data[7:0]; store_ptr++
The Bootloader is a simple terminal application. It has the ability to read two kinds of files and send the contents over the serial port to the processor. It also receives and displays content sent by the processor.
One of the first things the BIOS does it to turn on LED 0. A simple way to verify that the BIOS is working is to use the Bootloader to change the LEDs. The key to this process is knowing that the LEDs are located at address 0x80000040. From there, its just a matter of storing a new value to that address
Now we will download a test program to the processor.
If your processor is correct, then you will see the LEDs[3:1] blink several times.
There are a wealth of uses for LEDs, but sometimes something more is needed. To that end we have provided several memory-mapped I/O devices. This phase introduces these devices quickly and tasks that put them to use.
As you already know, there are 4 memory mapped LEDs whose values can be changed by storing to a specific address. There are also 5 push-buttons on the board organized like a directional pad. These devices have registers that are accessible using memory operations with specific addresses. The values are packed into bytes, so the table shows the bitmask to extract the specific signal from the byte.
Device | Addr | Load | Store | Size | bitmask |
---|---|---|---|---|---|
LED[0] | 0x80000040 | Y | Y | Byte | 0x01 |
LED[1] | Y | Y | Byte | 0x02 | |
LED[2] | Y | Y | Byte | 0x04 | |
LED[3] | Y | Y | Byte | 0x08 | |
PB_UP | 0x80000041 | Y | N | Byte | 0x01 |
PB_DOWN | Y | N | Byte | 0x02 | |
PB_LEFT | Y | N | Byte | 0x04 | |
PB_RIGHT | Y | N | Byte | 0x08 | |
PB_ENTER | Y | N | Byte | 0x10 |
To get this far you must have already used the serial port via the bootloader. Now its time to describe the API for the serial interface. Conceptually the serial port is a pair of one-byte registers: DataIn[7:0] at 0x80000001 and DataOut[7:0] at 0x80000004. Data sent from the PC to the FPGA comes in on DataIn[7:0]. Sending data to the PC is a matter of writing a byte to DataOut[7:0].
Device | Addr | Load | Store | Size | bitmask |
---|---|---|---|---|---|
DataReady | 0x80000000 | Y | N | Byte | 0x01 |
DataIn[7:0] | 0x80000001 | Y | N | Byte | 0xFF |
SendReady | 0x80000002 | Y | N | Byte | 0x01 |
PopData | 0x80000003 | N | Y | Byte | N/A |
DataOut[7:0] | 0x80000004 | N | Y | Byte | N/A |
Things become more complicated because there are variations in timing, so actually the registers are the head and tail respectively of FIFOs. Thus, the
program should never read the data without ensuring that data is ready, and should never right data unless there is space to write. Finally, reading is
actually a two stage process: Read the data, Deque the data. Pseudo-code for sending and receiving can be found below:
Reading Writing The final I/O device is the Text-Mode VGA
Controller. This VGA Controller supports
75 rows with 100 columns each, and 16 colors
per character. The VGA Controller is
write-only. Like the other I/O devices the VGA
Controller is memory-mapped. Writing to the
screen is as easy as storing a character to a
memory location and a color to a corresponding
memory location.
while(~DataReady) checkDataReady();
Data = readData();
DequeData();
while(~SendReady) checkSendReady();
sendData();
VGA Controller
Start | End | Size | Desc. | |
---|---|---|---|---|
VGA_TEXT_PLANE | 0x0000C000 | 0x0000DD4B | Byte | Writing ASCII to an address in this range sets the character |
VGA_COLOR_PLANE | 0x0000E000 | 0x0000FD4B | Nybble (4-bit) | Writing a COLOR to an address in range sets the color (colors are defined in board.h) |
The programming so far has been all in assembly because the processor couldn't support code generated by a compiler. There is a toolchain for compiling C to executables that the Bootloader can interpret. There are naturally a number of limitations:
This section will walk thru the creation of an application from a blink.c. This code simply blinks all the LEDs on and off.
To demonstrate that you have successfully implemented your design on the board, let one of the course staff know and they will verify that this is the case. If you are unable to find someone to check off your work, come in during office hours or email cse378-tas@cs to schedule a time when one of us can check off your work.