Laboratory 7 (individual) -- I/O devices

Worth: 50 points
Assigned: 20 February 2009
Due: 6 March 2009

Overview

In this lab, you will gain experience writing assembly-language programs and interacting with I/O devices. You will write a device driver, which is a function in E100 assembly language that interacts with an I/O device, and write an assembly-language program that tests your device driver. You should run your device driver and program initially on ase100. You should then run your device driver and program on a hardware E100 processor, which you will create by adding I/O controllers to your Lab 6 processor.

Each member of your team should choose a different I/O device and write a device driver and test program for that device.

I/O controllers for the E100

The DE2 contains a variety of I/O devices. An E100 program interacts with an I/O device by talking with that device's I/O controller. Add the following files to your Lab 6 E100 to include these I/O controllers. For your convenience, here is a ZIP file containing all the files (extract them with the unzip command).

I/O ports

E100 programs talk with I/O controllers via I/O ports. There are two types of I/O ports.

The following table lists all I/O ports available on the E100.
Port number Port type Definition Use
0in bits 15-0: DPDT_SW[15:0] binary input
1out bits 15-0: LED_RED[15:0] binary output
2out bits 7-0: LED_GREEN[7:0] binary output
3out bits 15-0: displayed on HEX3-HEX0 hexadecimal output
4out bits 15-0: displayed on HEX7-HEX4 hexadecimal output
5in bits 15-0: real-time clock measure time
10out bit 0: lcd_valid LCD display
11in bit 0: lcd_ack
12out bits 3-0: lcd_x[3:0]
13out bit 0: lcd_y
14out bit 7-0: lcd_ascii[7:0]
20in bit 0: ps2_valid PS/2 keyboard
21out bit 0: ps2_ack
22in bit 0: ps2_pressed
23in bits 7-0: ps2_ascii[7:0]
30out bit 0: sdram_valid SDRAM memory
31in bit 0: sdram_ack
32out bit 0: sdram_write
33out bits 10-0: sdram_x[10:0]
34out bits 10-0: sdram_y[10:0]
35out bit 15-0: sdram_data_write[15:0]
36in bit 15-0: sdram_data_read[15:0]
40out bit 0: speaker_valid speaker
41in bit 0: speaker_ack
42out bits 15-0: speaker_sample[15:0]
50in bit 0: microphone_valid microphone
51out bit 0: microphone_ack
52in bits 15-0: microphone_sample[15:0]
60out bit 0: vga_valid VGA monitor
61in bit 0: vga_ack
62out bit 0: vga_write
63out bits 9-0: vga_x1[9:0]
64out bits 8-0: vga_y1[8:0]
65out bits 9-0: vga_x2[9:0]
66out bits 8-0: vga_y2[8:0]
67out bit 7-0: vga_color_write[7:0]
68in bit 7-0: vga_color_read[7:0]
70in bit 0: mouse_valid USB mouse
71out bit 0: mouse_ack
72in bits 15-0: mouse_deltax
73in bits 15-0: mouse_deltay
74in bit 0: mouse_button1
75in bit 0: mouse_button2
76in bit 0: mouse_button3
80in bit 0: sd_valid SD card
81out bit 0: sd_ack
82in bits 15-0: sd_data[15:0]
90in bit 0: serial_receive_valid serial port
91out bit 0: serial_receive_ack
92in bits 7-0: serial_receive_data[7:0]
100out bit 0: serial_send_valid
101in bit 0: serial_send_ack
102out bits 7-0: serial_send_data[7:0]
110out bit 0: fft_send_valid Fast Fourier Transform
111in bit 0: fft_send_ack
112out bits 15-0: fft_send_real[15:0]
113out bits 15-0: fft_send_imaginary[15:0]
114out bits 0: fft_send_inverse
115out bit 0: fft_send_end
120in bit 0: fft_receive_valid
121out bit 0: fft_receive_ack
122in bits 15-0: fft_receive_real[15:0]
123in bits 15-0: fft_receive_imaginary[15:0]

I/O device protocol

At first glance, it seems easy to send/receive data to/from an I/O device. For example, one could send a sample to the speaker simply by executing an out instruction on port 42 (the speaker_sample port). While this does change the current value of the speaker_sample port, this is not quite enough to output a sequence of samples. One problem is that the speaker controller doesn't know when the program has set the speaker_sample port to the next sample. Another problem is that the program doesn't know when the speaker controller has read the last sample and is ready to receive the next sample. These problems are addressed by an I/O device protocol.

A protocol is used to guide the interaction between two parties. In the context of I/O devices, an I/O protocol is used to guide the interaction between an E100 program and an I/O device. A protocol defines the steps involved in the interaction and includes how each party knows when the current step is complete. We will use one protocol for sending data to an I/O device and the complementary protocol for receiving data from an I/O device.

The part of an E100 program that implements the E100's side of an I/O protocol is called a device driver.

Output protocol

The output protocol uses three signals to allow an E100 program to send data to an output device (e.g., speaker, LCD display, VGA monitor, serial port send).

The steps involved in sending data to an output device are:
valid ack Description
0 0 System is idle.
1 0 E100 program has set data to the value it wants to send. E100 program is waiting for device to read this value.
1 1 Device sets ack to 1 to tell the E100 program that it has read the value of data.
0 1 E100 program sets valid to 0 to tell the device that the program has seen the device's acknowledgment. After this state, the device sets ack back to 0, and the system returns to the Idle state.

Input protocol

The input protocol uses three signals to allow an E100 program to receive data from an input device (e.g., microphone, USB mouse, PS/2 keyboard, SD card, serial port receive).

The steps involved in receiving data from an input device are:
valid ack Description
0 0 System is idle.
1 0 Device has set data to the value it wants to send. Device is waiting for the E100 program to read this value.
1 1 E100 program sets ack to 1 to tell the device that it has read the value of data.
0 1 Device sets valid to 0 to tell the E100 program that the device has seen the E100 program's acknowledgment. After this state, the E100 program sets ack back to 0, and the system returns to the Idle state.

E100 devices

Your task is to write a device driver and test program for one of the following E100 devices: speaker, microphone, VGA monitor, LCD display, PS/2 keyboard, USB mouse, SD card. The following sections describe the interface to these devices and the test program that you should write for each device. The real-time clock, SDRAM controller, and serial port controller are also described, but they should not be chosen for this lab.

Your test program and device drivers should be in separate files. Include the device driver file in your test program by adding a line at the end of your test program, such as:

#include driver.e

Speaker controller

The speaker controller handles the low-level details of producing audio output on the DE2 and provides a simple interface for the E100 to send samples to the DE2 line out connector. The speaker controller is implemented in speaker.v. You will also need codec_config.v, which configures the DE2's audio codec chip, the Wolfson WM8731 codec (codec stands for encoder/decoder).

See Lab 8's discussion on digital audio to learn how samples values correspond to sound.

E100 programs interact with the speaker controller via I/O ports 40-42. These ports provide the following signals: speaker_valid, speaker_ack, and speaker_sample[15:0]. speaker_valid and speaker_ack implement the standard output protocol described above. The data being transferred is speaker_sample.

Using the standard output protocol, an E100 program sends a sequence of speaker_sample values to the speaker controller. The speaker controller plays these samples at an 8 KHz sampling rate. If the E100 program sends samples more quickly than 8 KHz, the speaker controller will delay the acknowledgment of a new sample until it has played the last sample. If the E100 program sends samples slower than 8 KHz, the speaker controller will generate periods of silence between samples.

ase100 simulates the speaker controller accurately enough for you to test your device driver and to run assembly-language programs. Because ase100 does not run quickly enough to produce sounds in real-time, it instead graphs the sound values, as a yellow line in the upper half of the audio window. You can save the speaker samples as a WAV file by clicking in the audio window. You can then play back the WAV file on your computer.

Lab 7 task: Write a device driver for the speaker controller that a program can call to send a sound sample to the sound controller. Then, write a test program that repeatedly sends a set of samples to the speaker, looping when it reaches the end of the set. The set of samples should be stored in an array, with the length of the array specified by another variable. Remember that sample values are in the range [-32768, 32767].

Microphone controller

The microphone controller handles the low-level details of receiving sound samples from the DE2's microphone input. The microphone controller is implemented in microphone.v.

E100 programs interact with the microphone controller via I/O ports 50-52. These ports provide the following signals: microphone_valid, microphone_ack, and microphone_sample. microphone_valid and microphone_ack implement the standard input protocol described above. The data being transferred from the microphone controller to the E100 is microphone_sample, which contains the most recent 16-bit sound sample received by the microphone.

The microphone controller takes input from the microphone at an 8 KHz sampling rate. A new sample overwrites the current sample, even if the E100 has not yet read the current sample. After the E100 reads the current sample via the I/O protocol, microphone_valid will be 0 until there is a new sample from the microphone.

ase100 simulates the microphone controller accurately enough for you to test your device driver and to run assembly-language programs. ase100 reads microphone samples from a WAV file, which you select when your program runs. ase100 graphs the microphone values as a purple line in the lower half of the audio window.

The WAV file given to ase100 must be in the PCM format, with 16-bit, mono samples at an 8 KHz sampling rate. You can use the concert A file given in Lab 8, which is in the right format. If you want to use your own sound file, use the sox program on Linux to convert the file to the right format. For example, to convert file1.wav to file2.wav, run the following command:

sox file1.wav -w -s -c 1 -r 8000 file2.wav

Lab 7 task: Write a device driver for the microphone controller that a program can call to read a sound sample from the microphone controller. Then, write a test program that displays the minimum and maximum values for the sound samples it has received from the microphone onto the hexdigits.

Optional: If one of your teammates has written a driver for the speaker, try sending the values you read from the microphone to the speaker.

PS/2 keyboard controller

The PS/2 controller handles the low-level details of communicating with a PS/2 keyboard. The PS/2 controller is implemented in ps2_keyboard.v, ps2_serial.v, ps2_serial_buf.v, and keyboard_ram.v.

E100 programs interact with the PS/2 controller via I/O ports 20-23. These ports provide the following signals: ps2_valid, ps2_ack, ps2_pressed, and ps2_ascii[7:0]. ps2_valid and ps2_ack implement the standard input protocol described above.

The data being transferred from the PS/2 controller to the E100 are keyboard events. An event is described by which key was acted on (ps2_ascii), and whether the action was a key press or key release (ps2_pressed). If ps2_pressed is 1, the event was a key press. If ps2_pressed is 0, the event was a key release. ps2_ascii contains the ASCII value for the key that was pressed or released. Note that ps2_pressed is part of the data being sent from the PS/2 controller to the E100 program; ps2_valid is the control signal in the protocol that signifies when this data is valid.

ase100 simulates the PS/2 keyboard controller accurately enough to test your device driver and to run assembly-language programs. ase100 sees keyboard events when the mouse is in the VGA window.

Lab 7 task: Write a device driver for the PS/2 controller that a program can call to read a keyboard event from the keyboard controller. Remember that the keyboard sends press events and release events. Then, write a test program that reads a password from the keyboard and compares it to the correct password. The correct password should be stored in an array, with the length of the array specified by another variable. If the password is correct, light up the green LEDS. If the password is wrong, light up the red LEDs.

Optional: If one of your teammates has written a driver for the LCD, try displaying the characters you read from the keyboard on the LCD.

Useful trivia: the wiring in most computer keyboards prevents them from detecting new key presses if 2-3 keys are already held down.

USB mouse controller

The USB mouse controller works with the DE2's USB controller to communicate with a USB mouse. The USB mouse controller is implemented in usbmouse.v, usbram.v, and usbram.mif.

E100 programs interact with the USB mouse controller via I/O ports 70-76. These ports provide the following signals: mouse_valid, mouse_ack, mouse_deltax, mouse_deltay, mouse_button1, mouse_button2, and mouse_button3, mouse_valid and mouse_ack implement the standard input protocol described above.

The data being transferred from the USB mouse controller to the E100 are mouse_deltax, mouse_deltay, mouse_button1, mouse_button2, and mouse_button3. mouse_deltax and mouse_deltay describe the movement of the mouse since the last time the mouse was read. Positive values for mouse_deltax indicate motion to the right. Positive values for mouse_deltay indicate motion downward (toward your body); this matches the orientation used for VGA coordinates. mouse_button1, mouse_button2, and mouse_button3 are 1 when the corresponding mouse button is pressed and 0 otherwise.

ase100 simulates the USB mouse controller accurately enough to test your device driver and to run assembly-language programs. The simulator typically pays attention to mouse movement and buttons whenever the mouse is in the VGA window. If you want to move the mouse without affecting the data being sent to the simulator (e.g., you want to move the mouse to another window), type Control-m (hold the Control button down and type m). Type Control-m again to reactivate the mouse.

The mouse cursor will change to a star shape when ase100 is paying attention to the mouse. This mouse cursor exists only as a convenience when running ase100, so you can see where the mouse is on the host computer's screen. This means that the position of star cursor will typically not match the (x,y) position maintained by your program. Remember that star-shaped mouse cursor in ase100 has no hardware equivalent: the mouse controller on the DE2 only sends mouse movements and does not maintain a mouse position.

Lab 7 task: Write a device driver for the USB mouse controller that a program can call to read a mouse event from the USB mouse controller. Then, write a test program that maintains a current (x,y) position for the mouse and displays this position on the hexdigits. Constrain x to be in the range [0,639]; constrain y to be in the range [0,479].

Optional: If one of your teammates has written a driver for the VGA monitor, try displaying the current mouse position as a pixel on the VGA monitor.

LCD controller

The DE2 includes a 16x2 character LCD module. The LCD controller handles the low-level details of communicating with the LCD module. The LCD controller is implemented in lcd.v.

E100 programs interact with the LCD controller via I/O ports 10-14. These ports provide the following signals: lcd_valid, lcd_ack, lcd_x[3:0], lcd_y, and lcd_ascii[7:0]. lcd_valid and lcd_ack implement the standard output protocol described above.

The data being transferred are lcd_x, lcd_y, and lcd_ascii. Using the standard output protocol, an E100 program sends lcd_x, lcd_y, and lcd_ascii to the LCD controller. lcd_ascii specifies the ASCII value of the character to be written, and lcd_x and lcd_y specify the (x,y) location of the character to be written. The coordinate of the upper left character is (0,0); the coordinate of the lower right character is (1,15).

ase100 simulates the LCD controller accurately enough for you to test your device driver and to run assembly-language programs.

Lab 7 task: Write a device driver for the LCD controller that a program can call to write a character to a specified position on the LCD. Then, write a test program that prints a message to the LCD display. The message should be stored as an array of ASCII values, with the length of the array specified by another variable.

VGA controller

The VGA controller handles the low-level details of communicating with a monitor over a VGA connector. The VGA controller is implemented in vga.v.

The VGA controller maintains a 2-dimensional array of 8-bit values in video memory. The width of the array is 640 (0-639), and the height of the array is 480 (0-479). Each value represents the color of a pixel: bits 5-4 specify the amount of red; bits 3-2 specify the amount of green; and bits 1-0 specify the amount of blue (bits 7-6 have no effect on the color displayed on the screen).

Pixel coordinates are denoted as (x,y). The coordinate of the upper left pixel is (0,0); the coordinate of the lower right pixel is (639,479).

E100 programs interact with the VGA controller via I/O ports 60-68. These ports provide the following signals: vga_valid, vga_ack, vga_write, vga_x1[9:0], vga_y1[8:0], vga_x2[9:0], vga_y2[8:0], vga_color_write[7:0], and vga_color_read[7:0].

vga_valid and vga_ack implement a protocol similar to the standard output protocol, but the VGA controller allows data to be transferred in both directions. The data being transferred from the E100 program to the VGA controller are vga_write, vga_x1, vga_y1, vga_x2, vga_y2, and vga_color_write. The data being transferred from the VGA controller to the E100 program is vga_color_read.

Using the standard output protocol, an E100 program sends vga_write, vga_x1, vga_y1, vga_x2, vga_y2, and vga_color_write to the VGA controller. If the E100 program sends a command with vga_write=1, this signifies that the program wants to set the color of a rectangle to vga_color_write. The upper-left corner of the rectangle is (vga_x1, vga_y1), and the lower-right corner of the rectangle is (vga_x2, vga_y2). vga_x1 must be less than or equal to vga_x2, and vga_y1 must be less than or equal to vga_y2.

If the E100 program sends a command with vga_write=0, this signifies that the program wants to read the color of the pixel at (vga_x1, vga_y1). The VGA controller returns this data via vga_color_read. The value of vga_color_read is guaranteed to be stable only when vga_valid is 1, vga_write is 0, and vga_ack is 1. That is, the VGA controller sets vga_ack to 1 to signify that it has seen the command with vga_write=0 and has set the value of vga_color_read to the value of the pixel being read.

ase100 simulates the VGA controller accurately enough for you to test your device driver and to run assembly-language programs. Click the Save VGA button to save the contents of VGA memory to a file.

Lab 7 task: Write a device driver for the VGA controller that a program can call to write a pixel to the monitor at a specified (x,y) coordinate. Then, write a program that sends an array of color values to the VGA monitor. The color values should be stored in an array, with the length of the array specified by another variable. Write the color values in the array to the pixels in the top row of the VGA monitor. You may want to first set the monitor to be completely black, so you can see your array of colors more easily.

Optional: If you want an extra challenge, add a device driver function to read pixels from the video memory. Then write a test program that complements the color value for each pixel (use the not instruction) and updates the monitor display with the complemented color value for each pixel.

SDRAM controller

Note: you may not choose SDRAM for this lab.

The DE2 includes synchronous DRAM (SDRAM) that can stores 4 megawords, i.e. 4194304 16-bit words. Which SDRAM word is being read or written is specified by an (x,y) coordinate. x and y are each in the range of [0,2047] (11 bits). The SDRAM controller handles the low-level details of communicating with SDRAM. The SDRAM controller is implemented in sdram.v.

E100 programs interact with the SDRAM controller via I/O ports 30-36. These ports provide the following signals: sdram_valid, sdram_ack, sdram_write, sdram_x[10:0], sdram_y[10:0], sdram_data_write[15:0], and sdram_data_read[15:0].

sdram_valid and sdram_ack implement a protocol similar to the standard output protocol, but the SDRAM controller allows data to be transferred in both directions. The data being transferred from the E100 program to the SDRAM controller are sdram_write, sdram_x, sdram_y, and sdram_data_write. The data being transferred from the SDRAM controller to the E100 program is sdram_data_read.

Using the standard output protocol, an E100 program sends sdram_write, sdram_x, sdram_y, and sdram_data_write to the SDRAM controller. If the E100 program sends a command with sdram_write=1, this signifies that the program wants to write the value contained in sdram_data_write to the specified word of SDRAM. This protocol is the same as that used to send data to the speaker and LCD controllers.

If the E100 program sends a command with sdram_write=0, this signifies that the program wants to read the value of the specified word of SDRAM. The SDRAM controller returns the data read from SDRAM in sdram_data_read. The value of sdram_data_read is guaranteed to be stable only when sdram_valid is 1, sdram_write is 0, and sdram_ack is 1. That is, the SDRAM controller sets sdram_ack to 1 to signify that it has seen the command with sdram_write=0 and has set the value of sdram_data_read to the value of the location being read.

ase100 simulates the SDRAM controller accurately enough for you to test your device driver and to run assembly-language programs. Click the Save SDRAM button to save the contents of SDRAM to a file.

SD card controller

The SD card controller handles the low-level details of reading data from the DE2's SD card. The SD controller is implemented in sd.v.

The SD card controller reads data sequentially from the SD card, starting with the first 16-bit word stored on the card. It cannot write data to the SD card.

E100 programs interact with the SD card controller via I/O ports 80-82. These ports provide the following signals: sd_valid, sd_ack, and sd_data. sd_valid and sd_ack implement the standard input protocol described above. The data being transferred from the SD card controller to the E100 is sd_data, which contains the next 16-bit value stored on the SD card.

To initialize the contents of an SD card, create a file with the desired contents, then carry out the following steps at a computer in 2331 or 2431 EECS:

  1. Login to the computer.
  2. Remove all removable media (e.g., USB drives) from the computer.
  3. If you're in 2331 EECS, use the built-in multi-card writer on the front panel of the computer. If you're in 2431 EECS, plug an SD card writer (SanDisk ImageMate or SanDisk MobileMate) into the computer.
  4. Insert the SD card into the SD writer. If the operating system mounts any partitions from the SD card, unmount them before continuing.
  5. Wait at least 15 seconds. During this time, the operating system detects the SD card writer and changes permissions on the device file.
  6. Run the following command:
    dd if=FILE of=DEVICE
    
    Replace FILE with the name of the file that has the contents you want to write to the SD card. Replace DEVICE with the device name from the following table (depending on which room you're in and which SD card writer you're using):

    2331 EECS 2431 EECS
    Built-in multi-card writer /dev/sde
    SanDisk ImageMate /dev/sdh /dev/sdd
    SanDisk MobileMate /dev/sdf /dev/sdb
  7. Wait for the dd command to finish and the SD card writer light to stop flashing.

ase100 simulates the SD card controller accurately enough for you to test your device driver and to run assembly-language programs. ase100 simulates the SD card by reading data from a file, which you select when your program runs.

Lab 7 task: Write a device driver for the SD card controller that a program can call to read a value from the SD card. Then, write a program that reads a sequence of values from the SD card and displays each value on LED_RED. Initialize the SD card with the contents of this data file; it has a slowly changing sequence of numbers that will generate a recognizable pattern on the LEDs.

Serial port controller

Note: you may not choose the serial port for this lab.

The DE2's serial port provides a way to communicate with another DE2 board (via a null-modem cable) or with another computer (via a straight-through serial cable). The serial port controller handles the low-level details of receiving and sending data across the serial port. The serial port controller is implemented in serial_receive.v, serial_receive_fifo.v, and serial_send.v.

E100 programs receive data from the serial port via I/O ports 90-92, which provide the following signals: serial_receive_valid, serial_receive_ack, and serial_receive_data. serial_receive_valid and serial_receive_ack implement the standard input protocol described above. The data being received from the serial port to the E100 is serial_receive_data, which contains an 8-bit value.

E100 programs send data to the serial port via I/O ports 100-102, which provide the following signals: serial_send_valid, serial_send_ack, and serial_send_data. serial_send_valid and serial_send_ack implement the standard output protocol described above. The data being sent to the serial port to the E100 is serial_send_data, which contains an 8-bit value.

The serial port controller will buffer 256 bytes of received data if the E100 program doesn't read it right away. If this buffer fills up, the serial port controller will drop new data until space frees up in the buffer.

Use these connection parameters if you want to connect the serial port to a host computer: 8 data bits, no parity bit, 1 stop bit, 115200 baud.

ase100 simulates the serial port controller accurately enough for you to test your device driver and to run assembly-language programs. ase100 simulates the serial port by communicating through a virtual serial cable (implemented as a network server) that you name when your program runs. Run two copies of ase100 (on the same or different computers) and enter the same serial cable name to connect the simulated DE2's together.

Real-time clock

Note: you may not choose the real-time clock for this lab.

The E100 provides a free-running, real-time clock. Every 42 ms, the real-time clock value increases by 1. You can read the current value of the real-time clock by reading port 5. When the clock value reaches 32767, it rolls back to 0.

ase100 simulates the real-time clock accurately enough for you to test your device driver and to run assembly-language programs.

Fast Fourier Transform

Note: you may not choose the Fast Fourier Transform for this lab.

The Fast Fourier Transform is an important algorithm in digital signal processing. It provides a fast way to convert between the time domain and frequency domain representations of a sequence of sound samples (or other types of data). Time domain represents sound as a series of values changing over time (like the graph in Lab 8). Frequency domain represents sound as the sum of sine and cosine waves of different amplitudes, frequencies, and phases. For example, the graph in Lab 8 could be represented by giving a single sine wave with amplitude 1000 and frequency 440 Hz. To learn more, see The Scientist and Engineer's Guide to Digital Signal Processing (or take EECS 216 and EECS 451).

For your music synthesizer project, the FFT can help you find or modify the frequency components of sound segments.

It is possible to compute an FFT in software on the E100. However, the E100 can not run the FFT algorithm fast enough to keep up with the audio sampling rate, so we provide a co-processor that computes an FFT in hardware. This section describes how to use the FFT co-processor.

To use the FFT co-processor, an E100 program sends a sequence of up to 512 data points to the FFT co-processor, which then computes the FFT of that sequence. Later, the E100 program reads the result of the FFT, which is also a sequence of 512 data points.

Each data point in a sequence consists of a real and imaginary component. For time-domain data, the real component represents the magnitude of a sound sample, and the imaginary component is not used. For frequency-domain data, the real and imaginary components represent a frequency component in the complex plane. The magnitude of this frequency component is square_root(real*real + imaginary*imaginary). The phase of this frequency component is arctangent(imaginary/real).

When sending or receiving time-domain data, data points are given in order of increasing time.

When sending or receiving frequency-domain data, data points are given in increasing order of frequency. Point #0 is for frequency 0 Hz, and each succeeding point is for a frequency that is 15.625 Hz more than the last point, up until point #256 (the 257th point), which is for frequency 4000 Hz (the Nyquist frequency, for our audio rate). After point #256, the frequencies goes down by 15.625 Hz between points; each of these points are the complex conjugates of the corresponding point in the first 256 samples. [This description assumes that sequences represent samples taken at the standard audio rate of 8 KHz. More generally, the frequency gap between points is the sampling frequency divided by the number of samples.]

E100 programs send each data point to the FFT co-processor using the standard output protocol. fft_send_valid and fft_send_ack implement the standard output protocol. fft_send_real, fft_send_imaginary specify the real and imaginary components of a data point.

fft_send_inverse specifies the direction of the transform and is used only on the first data point in a sequence (it is ignored on other points in the sequence). fft_send_inverse=0 specifies a forward transform (time domain -> frequency domain); fft_send_inverse=1 specifies an inverse transform (frequency domain -> time domain).

fft_send_end=1 specifies that this data point is the last point in the sequence. If the E100 program ends a sequence before sending 512 points (by setting fft_send_end=1), the FFT co-processor will assume the remaining data points are (0, 0). The FFT co-processor will automatically end the sequence after the E100 sends 512 points.

After sending a sequence of data points to be transformed, the E100 program can read the results (another sequence of data points) from the FFT controller. fft_receive_valid and fft_receive_ack implement the standard input protocol. fft_receive_real and fft_receive_imaginary specify the real and imaginary components of a data point.

If the E100 program starts sending a new sequence of points to the FFT controller, the controller will flush all remaining points in the result sequence.

ase100 simulates the FFT co-processor accurately enough for you to test your device driver and to run assembly-language programs. The exact results returned by ase100's simulated FFT co-processor may differ slightly from those returned by the DE2's FFT co-processor.

The FFT co-processor on the DE2 uses a time-limited module that is intended for lab use (not for final deployment). If the DE2 board is disconnected from USB-Blaster, the FFT co-processor will only work for 1 hour. If the DE2 board is connected to a host computer via USB-Blaster, the FFT co-processor will work indefinitely.

Pre-lab assignment

Your pre-lab assignment is to write, test, and debug your device driver and test program. These tasks can be done by running the E100 assembler and simulator, ase100. Debugging on ase100 is much easier than debugging on the DE2 because you can control the execution of your program and view its state as it executes.

Most of your testing and debugging should occur before your lab section. The lab section is meant for running final tests on the DE2 board and for demonstrating your program to the GSI.

In-lab demonstration

Demonstrate your test program and device driver on the DE2 to the GSI. After you've demonstrated your program, submit your final version of your test program and device driver.