CSE467-Lab 7 --latest revision: 2/16/05

PARTS 1,2 DUE: No later than beginning of Lab, week of 2/21.
PARTS 3,4 DUE: No later than beginning of Lab, week of 2/28.

Collaboration Policy:
Unless otherwise noted, your group may collaborate with other CSE467 groups on the lab assignments. Collaboration means that you may discuss the experiments and make notes during the discussion, but you may not copy another group’s work when doing the experiments; you may not copy experimental results from another group; and you may not copy any part of another group’s lab report. In addition, every individual in a group must understand the experiments, must participate in the writeup, and should understand the results. Collaboration does not mean that one person may perform the experiments and another write up the results – all lab partners must share equally in all parts of the lab assignment.


In this lab you will design circuits that you will need to drive the audio board. You will simulate and debug these circuits and download them and run them on the hardware this week. Before we let you download and run your designs, you must show that your design produces the right clocks and data. You will do this using both simulation and the scope or logic analyzer.

Part 1 – The Audio Codec Interface

We will be using a custom board designed in-house to generate audio signals.  This board uses the AK4529 codec (go here for the documentation). This codec takes a stream of digital values representing sound samples and turns it into an analog audio signal. Powered speakers can be plugged directly into the audio board. The first module you will design for this lab is the interface to this codec. We will describe the essentials of the codec in this document, but you will have to look at the documentation, especially the timing diagrams, to see exactly how the codec works.

The codec pins connected to the XCV1000 board are shown in the table below.

XCV1000 pin

AK4529 name

AK4529 pin





Master clock (50MHz/3) 6x BICK
















0= Power down, 1= Power on












Stereo serial input stream 1




Stereo serial input stream 3








64x LRCK




Audio sample clock




Stereo serial input stream 2




Stereo serial input stream 4





The PDN pin is very important.  If you are not using the codec, then the PDN pin must be set to 0 to protect the codec.  If PDN is 0, then the other pins can be left floating. When you are using the codec, you should set PDN to 0 when reset is asserted to cause the CODEC to be reset, and then set it to 1.

There are four stereo outputs on the codec, and each is driven by a different serial bit stream, SDTI1-4. At least to begin with, we will use only the first channel. The transfer mode timing that we will use is mode 2 (Table 7), which is shown in Figure 3, page 18. Data for the left and right channel are sent in bit serial fashion, 24 bits per channel. The 24-bit number is left-justified, with the high-order bit shifted first. Shorter numbers are filled out on the right with zeros. The BICK clock is used as the serial shift clock.  There are 64 BICK clock cycles per stereo sample, 32 cycles for the left channel, followed by 32 cycles for the right channel. Since only the first 24 cycles for each channel are used, data for the last 8 cycles are don’t cares. Make sure you study the timing diagram so that you use the appropriate edge of the clock to clock the serial data. 

The LRCK serves two purposes: first it is the sample clock and must run at the sample frequency of the audio stream. Second, the clock level determines whether the left channel or right channel data is being transferred. BICK runs at 64 x LRCK.  In addition to BICK and LRCK, the MCLK clock must be provided. We will generate MCLK from our 50MHz system clock by a divide by 3 circuit to generate a 16.67MHz MCLK. We will then divide the MCLK by 6 to generate BICK with a frequency of 2.78MHz. Finally, when the BICK is divided by 64, we will have a sample frequency for LRCK of 43.4KHz which is close enough to 44.1KHz.

The I/O for the codec interface module is shown below:

The input to this interface is two sample streams, one for each channel. Initially we will connect the two inputs together so that both channels get the same data. This input stream uses the standard DataValid/TakingData handshake, although the Codec interface assumes there is always data when it needs it and so ignores the DataValid. We will give you test fixtures for both the input stream and the audio codec.  The input stream test fixture will read a file and generate the corresponding data streams. The codec will take the serial data you send it and write it out to a file which should have the same values as the input file.  You can also turn this file into a WAV file, although it might take a long simulation to generate enough data. You will have to prove that your codec interface generates the correct clocks and serial output before you can download your circuit to the board. Then you should hold the PDN signal inactive (low, 0) in your Verilog, while you use the scope or logic analyzer to check your signals.

Demonstrate your simulated interface to the TA. Remember to do the measurements for your associated homework assignment.

Files for this lab:

fifo_out_tf.v : Test fixture that writes a random test stream to the FIFO (or any module that takes a standard stream)
fifo_in_tf.v : Test fixture that reads the data stream for a FIFO and checks that the data values are correct
(Note that the input/output naming for the FIFO is backwards from the audio....)

pipe_reg.v : Solution to the pipeline register design problem

audioin_tf.v : Test fixture that reads a files of samples generates a standard stream that can be fed to the codec interface
File can have at most 1000 samples (see code)
audioout_tf.v : Test fixture that writes a stream of sample values to a file.
codec_tf.v : Codec test fixture that takes a serial data stream from the codec interface and writes a file of stereo samples
codec_test.v : Top level file for testing the codec interface. Includes the clock generator and fifo.

scalegen.v : Generates a scale of frequencies for testing the wavetable synthesis module

mono.raw : Large file of mono audio samples (cut this down for input to the test fixture)

stereo.raw : Large file of stereo audio samples (same as mono.raw)

Part 2 – Wavetable Synthesis

In this part, you will write the Verilog version of the program you wrote in C for the Microblaze. First, modify the program you wrote to produce the wavetable include file, to write a Verilog file instead. Here is the format you should use for this file. This will compile into an efficient implementation in the FPGA.

module rom512x16 (data, clk, addr );
input clk;
input [8:0] addr;
output [15:0] data;
   reg [8:0] addr_reg;
   reg [15:0] data /* synthesis syn_romstyle = "block_rom" */;
 initial addr_reg <= 0;
   always @(posedge clk) begin
   	addr_reg <= addr;
 always @(addr_reg) begin
   case (addr_reg)
   	9'h0: data = 16'h0034; 
   	9'h1: data = 16'h012c; 
   	9'h2: data = 16'h02a5; 
   	9'h1FE: data = 16'hfeac;
   	9'h4FF: data = 16'hff83;
   	default: data = 0;
   endcase // case(addr_reg)
 end // always @ (...

Now write a module that takes an increment value as input and generates a sequence of samples for a tone of that frequency. You should write a simple test fixture that gives your module some increments, and check the output by adding the test fixture that writes the sample stream to a WAV file.

Demonstrate your results the the TA.

Part 3 – Adding Microblaze

The next piece of the lab is to drive your Wavetable synthesizer with the Microblaze. Use your Lab 6 code as a beginning, and add a 32-bit GPIO interface with several registers (see below) to feed data to the wavetable synthesizer.

To put together the entire system, you will control values to your wavetable synthesizer, which plugs into the codec interface.  Note that you should be able to plug a FIFO or pipeline register between the wavetable synthesizer and the codec. Demo your design, showing that it produces the right waveforms and the right output file, and have the TA sign off on your programs. Turn in your printouts of your Verilog programs, any schematics and simulation files you use. 

Part 4 – Putting it all together

Next we'll turn the wavetable synthesizer into a string model in Verilog. Use this model:

You'll need to control the delay length (frequency), trigger, Pluck point, pickup point, and filter coefficients from the Microblaze, so you'll need some more registers in your GPIO interface. How is the delay length related to the output frequency and the sample rate?

Demonstrate your string model to the TA. Hand in your Verilog for the String model.

Part 4 – Alternative for those who are having trouble:

For those having trouble we are providing a set of solution files. If you choose this option you will receive slightly less credit than the check-off above. Inform the TAs of your selection of this option, and they will provide you the URL to the solution. We will publish the solution after Thursday's lab HERE.