Jump to content
  • 0

FPGA audio - ADC and DAC



Good day wizards,

I've tried to introduce myself here, but now I would like to ask for a comment on my thoughts.

My goal is to master audio processing (mainly routing and level controls for a beginning) on FPGA. 

The diagram will be very simple:

Audio signal generator => ADC => FPGA => DAC => Analyzer (Spectrum, THD, Level)

Audio signal generator will be made of two NE555 clocks with different frequencies (say 1kHz and 15kHz) to have a difference between L and R channels.

ADC will be CS5381 (24bit@48k), I2S output.

DAC will be CS4390 (24bit@48k), I2S input. (later maybe something better, but for now I'll use whatever I have in a drawer).

Once I get this AD-DA conversion running properly, I'll try routing output of the ADC to my ARTY A7 input and pass that signal directly to the DAC. At this point I would like to see a low noise, low jitter signal passing thru.

Next step could be mixing L and R signals together, adding more converters generating AES/SPDIF signals on FPGA, etc..


But at very beginning, I have a fundamental problem with clocks. I want to run this setup at 48kHz, so I obviously need this clock and 48k*256=12.288MHz MSCLK.

Playing around with PLL Clock wizard didn't gave me the desired result (still + or - couple MHz). I understand that it would not be a massive problem and I could run any weird frequency, but there will be a sync problem with external digital equipment if I get around to do, say AES/SPDIF interface. Finding XTAL trimmed to 12.288 is not a problem, but can I just hook it up to any desired pin and use it? I have also seen some posts (if I got it right) discouraging of using multiple clocks as it can get messy (inter-sync problems?).

Before I dive into this, I would appreciate Your insights and critics. I will post all my story here as soon as I have something to share with You:)

Thank You!



Link to comment
Share on other sites

Recommended Posts

You only need a single 12.288MHz clock for the entire design. Generate the I2S bclk and lrclk signals using counters and registers clocked by the 12.288MHz clock. The Xilinx MMCM is capable of generating an exact 12.288MHz clock from the 100MHz clock input on the Arty board. If you need additional clock frequencies like 166.667MHz or 200MHz or something unrelated to 12.288MHz, you will need to use more than one MMCM in your design. Use a single clock wide enable in the 12.288MHz clock domain to indicate the presence of a new sample from or for your I2S interface.

It's been a very long time since I've looked at audio ADCs, DACs, and CODECs, but I seem to remember that most of the higher quality converters derive all their internal clocks from the 12.288MHz mclk clock and have internal PLLs to clean up any jitter on this 12.288MHz clock. The bclk and lrclk signals really are just signals used to frame the data and are not used as clocks for the converters.

Link to comment
Share on other sites

BTW, one more thought: If all you need to generate is a 1 kHz tone at 96 ksps, a perfect wavetable needs only 96 entries for a full period (or using simple symmetry, 1/4 of that). I don't see where the 12 bit come in. If in doubt, it should be trivial to run the wave calculation in floating point on a Microblaze processor, at least for debugging.

Now the THD+N reading from your screenshot is -74 dBc, which is suspiciously close to the quantization noise of a Nyquist-rate 12-bit DAC (eq 12, 6*12+1.7). A modern converter should reach -100 dBc, which would be your 0.001 % target.

Link to comment
Share on other sites

14 hours ago, zygot said:


Your project idea sounds nifty to me. I like the idea of using parts from a drawer; this could be challenging or at least very interesting for experienced engineers. I like your idea of using separate audio DAC and audio ADC devices from a project perspective ( not necessarily from an audio perspective ).I

I chose DACs and ADCs against combined codecs so I would not have to work on I2C to control it and I could easily replace it. Also there are not so many high end codecs and standalone converters scale better. 

I assume that you will be breadboarding your FPGA interface through the Arty regular PMOD. For best results you will have to pay attention to how this is accomplished. I suggest that you visit the Cirrus Logic website for application notes on this. Other audio IC vendors will have good guidance as well. As Cirrus Logic evaluation boards are priced to exclude the hobbyist element I assume that you will be breadboarding discrete chips. I'd make my own evaluation board using something like Express PCB. You may find this to be more expensive than you plan unless your parts drawer is stuffed with a lot of parts as buying small quantities of passive components isn't cost effective.

My first milestone is to get converters running, so it will land on breadboard first and then prototype PCB. I will definitely look at Express PCB, but previously I've used http://kicad-pcb.org/ 

As far as clocking goes, you have already discovered that getting precise clock frequencies from an arbitrary input clock is not always possible using FPGA clock generator resources. The JD PMOD has a number of pins that connect to the Artix clock routing resources if you want to use the correct clock for your ICs.

As far as having multiple clocks is concerned the answer is more complex than I can address here. I'll suggest that you do your homework to understand the difference between derived and unrelated clocks as well as the general concepts in digital design. Basically, multiple clock domains can be tricky even for seasoned FPGA developers. If these clock domains are unrelated then it can be tricky for the Xilinx synthesis and place and route tools as well unless you know how to present them with good constraints. I'd start off keeping all of the ADC, DAC, processing etc. logic in one clock domain preferably at a clock frequency preferred by the devices in your design. As you get farther along in your project you can experiment with ways to move data into another clock domain for extracting information to say, a PC for post-processing.

This comment: "I'll try routing output of the ADC to my ARTY A7 input and pass that signal directly to the DAC. At this point I would like to see a low noise, low jitter signal passing thru" bothers me a little as your audio source is NE555 based, but I'm not sure what you mean by "low jitter" or "low noise".

NE555 can give 50% duty cycle square and if its filtered properly, one can get quite good sinus signal on the output. Of course it can be replaced by any other generator, including soundcard. Unfortunately my Neutrik A1, died just a couple days ago.. :(((

Seeing that test signal at the other end of the FPGA would be what I am after. Unfortunately, because of the design, components, power, cabling, clocks etc., some noise, harmonic distortion will be present as well. 

Anyway, this could develop into quite an interesting enterprise; there are a lot of ways this could go in the future. Best wishes.


Link to comment
Share on other sites

@bikerglen thanks for Your comment - I will definitely try Your I2S code. 

For me its still quite hard to understand the whole architecture and design patterns of FPGA programming. I still have to read a lot and many videos to watch before I even try it. But lets see how fast I can get it:))

I see You have some experience with audio, maybe You have an idea how to calculate I2S delay on FPGA? If its 48k 24bit signal then it takes 

1/48000 = 0.00002083333 s for every bit to arrive

0.00002083333 * 24 = 0.0005 s for every 24 bits and that is only deserialization, same for serialization.. so 1 ms only to pass it thru? That doesn't sound right.. 

What am I missing here? Must be something fundamental.

Link to comment
Share on other sites


This topic is now archived and is closed to further replies.

  • Create New...