CSE logo University of Washington Department of Computer Science & Engineering
 CSE 378, Winter 2007
 Machine Organization and Assembly Language Programming
  CSE Home  About Us    Search    Contact Info 

 Academic (Mis)Conduct
 Course wiki
 Mailing list
 Lectures and readings
 Lab hours
 Your Grades
Anonymous Feedback
 Submit Feedback
 Read Feedback
Printable view

Lab 4 Part B: Hazards - HW

Assigned: 2/21/2007
Due: 3/2/2007


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.

Phase 0: Administration

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.

  1. Download the lab4-hw.zip file, and extract to a convenient location.
  2. Go to the extracted directory
  3. Install the Bootloader using the 378Bootloader.msi installer
  4. Copy the Hardware directory into the src directory of your design
  5. Copy the files in lib378 to the lib378/src directory.
  6. Start Active-HDL, And set lib378 as the active design
  7. Execute the update_lib378.do macro.
  8. Set lab4 as the active design.
  9. Execute the following command to make board.bde appear
    addfile -bde $DSN\src\Hardware\board.bde

Phase 1: Synthesis and Implementation

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:

  • HDL Synthesis: Synplicity Synplify Premier 8.6 with Design Planner
  • Implementation: Xilinx ISE/WebPack 8.2
  • Family: Xilinx8x Virtex2P

Part A: Setting Synthesis Options:

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.

  1. Set the top-level to board
  2. Verify that pcaddresscomputer.v, controller.v, comparator.v, forwardingunit.v, hazardunit.v, piperegister.v, cpu.bde, and board.bde are all included for synthesis
  3. Right-click the lib378.adf icon and select "Add all files to library"
  4. Go to the Generics/Parameters tab and verify that SYNTHESIS is in the "Verilog Compiler Directives" Box
  5. Close the options by hitting OK

Part B: Synthesis

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.

Part C: Implementation Options

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.

  1. Open the Implementation Options
  2. Change the .ucf file to be bios.ucf.
  3. Go to the Translate tab and set the "Macro Search Path" to the directory where the core files are stored.
  4. Check the following boxes:
    • "Do Not Run Post-Map STR" in tab Post-Map STR
    • "Do Not Run Post-PAR STR" in tab Post-PAR STR
    • "Do Not Run Simulation" in tab Simulation
    • "Create Bit File" in tab BitStream
  5. Hit OK to confirm the options

Part D: Implementation

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.

Phase 2: Testing

Part A: Configuring 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.

  1. Logon to a machine with an XUP Board
  2. Click-thru the "Found New Hardware Wizard"
  3. Open Impact via the XUP programmer icon on the desktop
  4. Right-Click the white window and select "Initialize Chain"
    1. If step 4 succeeded, go to step 5
    2. Otherwise, right-click and select "Cable-Setup"
    3. Choose the "Platform Cable USB" in the upper right, hit OK, and retry step 4
  5. Hit "Bypass" for the first two windows
  6. Find your board.bit file
  7. Right-Click the "Virtex2p" and select "Program", followed by OK

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.

Phase 3: BIOS and Bootloader

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.

Part A: BIOS Description

The BIOS is a simple program that resides in the ROM starting at address 0. The BIOS does the following things:

  1. turn on LED 0
  2. poll the SerialUART for new data
  3. read and Command Byte from the SerialUART
  4. read 4 data Bytes from the SerialUART
  5. Process data and possibly jump back to 1

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++

Part B: Bootloader

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.

Task i: Changing LEDs

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

  1. Use Impact to program the FPGA with your board.bit file
  2. Open the Bootloader and hit the "Connect" button
  3. Use manual commands to change the LEDs

Task ii: Processor Test

Now we will download a test program to the processor.

  1. Reset the board by hitting the white switch nearest the LEDs
  2. Hit the browse button and find Hardware/hanoi.hex
  3. Hit the Load Button
  4. Hit the Write Button to send the program to the board

If your processor is correct, then you will see the LEDs[3:1] blink several times.

Phase 4: I/O Devices

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.

Part A: Device Descriptions

Buttons and LEDs

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

Serial Port

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:


while(~DataReady) checkDataReady();
Data = readData();


while(~SendReady) checkSendReady();

VGA Controller

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.

  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)

Part B: C Programming

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:

Limitations of the C tools:

  • there is no "int main".  call your top-level function " int runme()"
  • there are only two include files: board.h, and smalllib.h
    contains MACROS for colors, and I/O addresses
    void *memcpy(void *dest, void *src, int length); -- copies length words from src to dest
    void *memset(void *mem, int c, int length); -- sets length words from mem to c
    char *strcpy(char *dest, char *src); -- copies from src to dest
    int strlen(char *) -- returns length of a string
    wait_for_n_cycles(n) -- delay loop
  • No dynamic allocation support (i.e. malloc, calloc, free, etc)

Compiling C:

This section will walk thru the creation of an application from a blink.c. This code simply blinks all the LEDs on and off.

  1. Go to the desktop, and double-click the MSYS icon (curvy blue M)
  2. In the resulting shell, navigate to the src/Hardware/C directory in your lab4 design
  3. Type the following command:
      make APP=blink
  4. Switch to Bootloader and find the file blink.dump in the src/Hardware/C directory.
  5. Load and Write blink.dump  to the board.

Phase 5: I/O Tasks

Download Updated board.h to Hardware/C/

  1. Write a file buttons.c that reads the contents of the buttons and lights up the corresponding LED. (i.e. PB_UP = LED[0], PB_DOWN=LED[1], etc )
  2. Write a file echo.c that returns any data sent from the PC to the CPU directly back to the PC using the serial port
  3. Write a file marquee.c that prints scrolling word or short phrase on the VGA.  It may wrap from line to line
  4. Write a file ball.c that prints a ball (3x3 or larger) in the center of the screen, and moves the ball based on button presses. You should maintain the position of the ball in local variables because you cannot read from the video memory. The ball should not leave the screen.


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.

Creative Commons License
This work is licensed under a Creative Commons Attribution-Share Alike 2.5 License.
Department of Computer Science & Engineering
University of Washington
Box 352350
Seattle, WA  98195-2350
(206) 543-1695 voice, (206) 543-2969 FAX
[comments to zahorjan]