In my final year project I used the Xilinx ML605 Virtex-6 development board. Whilst having a large number of I/O options, it lacks any audio output. It does have 7, 5V CMOS I/O pins plus voltage rails used by a socketed 24-character LCD board, which were appropriated for this project.
The chosen audio Digital-to-Analog Converter (DAC) was the The Cirrus Logic CS4344, as it is easy to source, does 5V logic, and requires few pins to interface with. The CS4344 takes I2S (Intergrated Interchip Sound), a 4-wire bus protocol for serially transmitting sound data to a DAC. A search found Eric Brombaugh‘s site, where he provides Verilog for producing I2S samples. Using this already tested and written code saved time writing our own, so thanks Eric.
CS4344 datasheet [PDF] provides an example circuit appropriate for our application. The schematic is reproduced below.
The CS4344 comes in a TSSOP10 surface mount package. For prototyping, it was attached to a DIP socket and placed on a breadboard.
To interface with the FPGA systems already built a the I2S generator was wapped in a VHDL state machine that takes input from a FSL Slave. FSL was chosen as a small amount of VHDL is needed to produce a port, and the interface is appropriate for feeding sequential sound samples. To integrate with Xilinx’s XPS toolflow, the following directory structure is required:
fsl_i2s_v1_00_a/ |-- data | |-- fsl_i2s_v2_1_0.mpd | `-- fsl_i2s_v2_1_0.pao `-- hdl |-- verilog | |-- clkgen.v | `-- i2s_out.v `-- vhdl `-- fsl_i2s.vhd
The .pao file lists the HDL code present in the module. .mpd files are used to indicate what buses are used, and the name and type of I/O pins to expose to XPS, and any configuration paramaters. The version numbers for these files corresponds to Xilinx’s requirements, not the version of the IP.
HDL files are placed under their own directory, with a subdirectory used for the language used. The entire lot is placed in the pcores directory at the root of a project. When launching XPS, the module will now show up as a usable in the IP Catalog tab.
The frequency of the I2S clocks can be selected from one of a number of options depending on the desired output frequency. Table 1 in the CS4344 data sheet describe the options. It was chosen that a 44.1kHz output rate would be chosen, meaning an 88.2kHz LRCLK, and MCLK would be 11.2896MHz. Due to the properties of the ML605’s MMCM (Multi-Mode Clock Module), the exact frequency chosen was 11.290323MHz, for 64ppm of error. A python script used to select the clock, and calculate the error, can be downloaded here.
By connecting the FSL slave of the nes_fsl to a Microblaze and supplying the appropriate clock, sound can be output by performing 32-bit writes to the slave. The upper half-word is the left sample, and the lower half-word the right. Samples are 16-bit signed little big endian, that native endianness of the Microblaze. The use of the swapix function can be removed from fsl_i2s.vhd if it is more convenient to use little endian data.
A number of enhancements were made to the base audio output peripheral:
- It will intentionally cause the output to ‘pop’ if samples are not received when the state machine tries to fetch them. This highlights the importance of meeting real-time requirements in an audio systems.
- A deadline counter, providing an 8-bit register that counts logarithmically up whenever a deadline miss occurs, and down whenever a sample is successfully retrieved. Â This can be hooked up to the 8-bit LEDs on the ML605 to make the counter externally visible.
- A second FSL slave was added to provide a hardware mixer. This was not completed.
The peripheral can be downloaded here. To use, unzip it into the pcores directory of a XPS project and add it to your system. The clock port needs to be connected to a 11.2896MHz clock, and the SFSL interface connected to the slave port of a FSL. It would be great to hear from you if you happen to use it as part of a design.