MATLAB Examples

Authoring a reference design for audio system on a Zynq board

This example shows how to:

  1. Generate IP cores for peripheral interfaces using HDL Workflow Advisor
  2. Build a reference design to run an audio algorithm and access audio input and output

Contents

Introduction

In this example you will create a reference design which receives audio input from Zedboard, performs some processing on it and transmits the processed audio data out of Zedboard. To perform audio processing on Zedboard, you need the following 2 protocols:

  1. I2C to configure the ADAU1761 audio codec chip on Zedboard.
  2. I2S to stream the digitized audio data between the codec chip and zynq fabric.

The above figure is a high level architecture diagram that shows how the reference design is used by the Filtering Algorithm IP. I2S IP operates at 50MHz frequency whereas one may want to run the Filtering Algorithm IP at a higher frequency. This frequency is controlled in Step 1.4 in HDL Workflow Advisor. In this example, assume that the filter operates at 100MHz. Since I2S and Filtering Algorithm IPs operate at different frequencies, we need FIFOs to handle clock domain crossing. Depending on the type of filter selected, Filtering Algorithm IP filters a range of frequencies from the incoming audio data and passes the filtered audio data out. In the above figure, the Filtering Algorithm IP is our main algorithm that we are modeling in Simulink. While FIFO IP is provided in Vivado, the I2C and I2S IPs need to be created. Here, the user has 3 choices: (a) use pre-packaged IP, e.g., if one exists, (b) model it in Simulink and generate an IP core using IP core generation workflow or (c) use legacy HDL code. To create an IP out of legacy HDL code, use a Simulink model to black box the HDL code and generate IP core from it. FIFO IPs handle the clock domain crossing between incoming audio data at 50MHz and the filter IP running at 100MHZ. I2C, I2S, PLL, FIFO IPs and Processing System form a part of the reference design.

The following steps are used to create the reference design described above:

  1. Generate IP Cores for peripheral interfaces
  2. Create a custom audio codec reference design in Vivado
  3. Create the reference design definition file
  4. Verify the reference design

1. Generate IP Cores for peripheral interfaces using HDL Workflow Advisor

In this example,

  1. I2C IP is developed by modeling it using Stateflow blocks, and also using legacy VHDL code for tristate buffer.
  2. I2S IP is developed by modeling it in Simulink.

1.1 Creation of I2C IP

I2C bus is also called Inter-IC bus. It is a simple multi-master, multi-slave bidirectional two wire bus consists of serial data(SDA) and serial clock(SCL) lines. I2C bus has two nodes, master node and slave node. Master node generates the clock and initiates the communication with slave. Slave node receives the clock and responds to the master. The master starts the communication by sending start bit followed by 7 or 10 bit address of the slave followed by read(1) or write(0) bit. If the slave is present, then it responds with ACK bit. The figure below shows the timing diagram of the I2C protocol.

1) Model the required I2C interface in Simulink. I2C_ADAU1761 is the DUT subsystem which generates the I2C control signal to configure the ADAU1761 audio codec chip. It consists of two Stateflow charts and one blackbox subsystem. The i2c_mstr chart is used to send the data in I2C protocol format and the i2c_cfg chart sends the registers needed for the audio codec chip configuration to i2c_mstr chart. The blackbox subsystem i2c_bidir is used for I2C bidirectional functionality which is created by importing legacy hdl file for tristate buffer in HDL workflow advisor. In the HDL Block Properties of the i2c_bidir subsystem, the Architecture is set to BlackBox, the EntityName is set to i2c_bidir. Ensure that these names match with the entity and port names in the legacy HDL code that you want to integrate into the generated IP Core.

modelname = 'hdlcoder_I2C_adau1761';
open_system(modelname);
open_system([modelname, '/I2C_ADAU1761']);

2) Start the HDL Workflow Advisor from the DUT subsystem. In Task 1.1, Select IP Core Generation for Target workflow, Generic Xilinx Platform for Target platform and Xilinx Vivado for Synthesis Tool. In Task 1.2, set the Target Platform Interfaces to "External Port" for all the ports.

3) The Tristate HDL logic is present in the VHDL file hdlcoder_I2C_tristate_ADAU1761.vhd. Copy it into your current working directory.

>> copyfile(fullfile(matlabroot,'toolbox','hdlcoder','hdlcoderdemos','hdlcoder_I2C_tristate_ADAU1761.vhd'),'hdlcoder_I2C_tristate_ADAU1761.vhd');

4) Then add the VHDL code in the Additional source files section of Task 3.2 and generate the IP Core.

1.2 Creation of I2S IP

Design a model in Simulink with a matlab function which implements the I2S protocol.

modelname = 'hdlcoder_I2S_adau1761';
open_system(modelname);

Create a test bench in the model to mimic the incoming audio data from the codec.

Feed this data to the Subsystem block which does the I2S operation. Verify the output of the Subsystem on a Scope.

Start the HDL Workflow Advisor from the DUT subsystem. In Task 1.1, keep the same settings as those of I2C IP generated earlier. in Task 1.2, set the Target Platform Interfaces as shown below:

Run Task 3.2 and generate the ip core.

2. Create a custom audio codec reference design in Vivado

I2C, I2S and FIFO IPs are incorporated in the custom reference design. To create a custom reference design, refer to the "Create and export a custom reference design using Xilinx Vivado" section in the Define and Register Custom Board and Reference Design for SoC Workflow example.

Key points to be noted while creating this custom reference design:

  1. We must understand the theory of operation of the audio codec chip on the Zedboard.
  2. The FIFOs are set to default values for their configuration.
  3. For the IP cores generated using HDL Workflow Advisor, IPCORE_CLK and AXI4_Lite_ACLK should be connected to the same clock source.
  4. On validating the block design in Vivado, there should be no critical warnings except for the unconnected ports.
  5. In this reference design, the audio codec is configured to operate in the Master mode.

The following signals run between the reference design on Zynq Soc and the audio codec on Zedboard:

  1. Bit_clock is the product of the sampling frequency, the number of bits per channel and the number of channels. It is driven by the audio codec in master mode. In this example, Sampling frequency is 48KHz, No of channels is 2, Number of bits per channel is 24.
  2. Left_right_select is to distinguish between left audio channel data and right audio channel data. It is in sync with the Bit clock.
  3. Serial_data_in is the analog to digital converted audio data from the codec.
  4. Serial_data_out is the digital audio data going to codec to be converted into analog form.
  5. I2C_CLK and I2C_DATA are standard I2C signals
  6. ADDR0 and ADDR1 are the I2C Address Bits.
  7. Clk_24MHz is the 24MHz clock signal required by the codec.

The custom audio codec reference design created for this example is shown below:

3. Create the reference design definition file

The following code describes the contents of the Zedboard reference design definition file plugin_rd.m for the above reference design. For more details on how to define and register custom board, refer to Define and Register Custom Board and Reference Design for SoC Workflow example.

Go to Zedboard folder using the following command:

All files that are required for the reference design such as IP core files, XDC files, plugin_rd file etc should be added to the matlab path, inside Zedboard folder using the hierarchy shown below. The user generated IP core files should be in +vivado folder. plugin_rd.m, tcl files and xdc files should be in the reference design plugin folder, for example, +vivado_audio_filter_2016_2 folder.

4. Verify the reference design

In order to ensure that the reference design and the interfaces in the reference design work as expected, design a Simulink model which just sends the audio through the Algorithm IP, integrate it with the reference design and test it on Zedboard. The user should be able to hear the audio loop back.

modelname = 'hdlcoder_audio_pass_through';
open_system(modelname);

The interfaces in the model should be selected as shown below:

To generate IP core from a model and integrate it with the audio codec reference design, refer to Running an audio filter on live audio input using a Zynq board example.