## ADC In An FPGA

May 1, 2011This blog post has been moved to my new website, intentionallogic.com. Click here to be taken to ADC In An FPGA, Part 1.

Advertisements

My personal soapbox to rant about whatever is on my mind.

This blog post has been moved to my new website, intentionallogic.com. Click here to be taken to ADC In An FPGA, Part 1.

Advertisements

%d bloggers like this:

[…] This is part 2 of “ADC In an FPGA”. If you have not read part 1, here it is. […]

by ADC In An FPGA, Part 2 « David Kessner's Soapbox June 5, 2011 at 8:08 pmIt would seem to me that the constant (1-exp(-T/RC)) really isn’t that important after all, except for noting that it is constant. If we use the wrong constant, what will happen is that the final calculated value will be of by a constant factor. So, basically just make RC a magnitude or two bigger than T, and compensate after the low pass filter: when you’re reading out 20K samples per second or less, the overhead of a multiplication doesn’t matter that much. In my case, the R and C won’t be that precise anyway, so I’ll need to calibrate regardless. Of course I want to choose R and C such that I don’t end up with useless bits in my output, but that’s all.

So, my question: is it true we can exchange the positions of the RC model and the low pass filter?

If I understand correctly, we can just determine our desired bit depth N and use an N-bit counter for counting the number of clocks that Dout was high. Then every 2**N clocks, we latch the counter in an output register X and reset it. This way X will always have a value proportional to the input voltage.

Now only to figure out how I put together the necessary VHDL code for a generic that takes the number of bits N and clock C, and provide me with the output signals for the register X and its latch signal.

FYI, my concrete goal is to use a Xilinx Spartan 3 FPGA with a 40 MHz SPARC v8 LEON3 SoC on it (see gaisler.com) to control a 3D printer (see reprap.com). The DAC will be needed for reading a thermistor. Precision is more important than speed, but 8 bits of precision at 10 Hz would probably be sufficient. While I might be able to do this purely in software after all, I’d rather use 10 bits of a general purpose I/O register for an ADC.

-Geert

by Geert Bosch July 3, 2011 at 8:40 pmThe RC filter model is more than just a filter. An RC filter is inherently non-linear, and the model adjusts and compensates for that. In a “normal” DAC/ADC there will be a constant current source/sink that charges and discharges a cap. The cap voltage will go up or down a fixed amount based on the constant current and the time it is on. In our ADC, we have an external cap for this but instead of a constant current source we have a constant voltage source and a resistor. This isn’t exactly like a constant current source, since the current varies depending on how close the cap voltage is to the power rails. When the cap is at VCC/2 then it works great, but in the extremes it gets a bit nonlinear.

For our ADC, we could create an external constant current source but that would be a complex bit of circuitry for something that is supposed to be simple. So instead we deal with our non-constant-current source and model how that non-constant-ness behaves.

So to answer one of your questions: you cannot swap the positions of the RC model and the low pass filter.

Because of the RC model is compensating for the non-linearity of our external RC filter, the value of (1-exp(-T/RC)) is important. It is also important that it is basically a constant value that we have some control over. Still on my to-do list is to characterize how the accuracy of this constant (along with the tolerances of the external RC filter) effects the overall ADC performance. So stay tuned for more data on this particular subject.

You could just count the number of high pulses over 2**N clocks, but you would have several negative side effects: 1. You would get that non-linearity issue that the RC model corrects. 2. There would be potentially unwanted frequency distortion due to the way the analog signal is being sampled. And 3. Your bit depth and sample rate would be somewhat limited. My ADC should be free of those issues while not taking up much more logic.

I still have a lot of work on this ADC before it is ready for “prime time”, but currently I’m getting about 14 bits of precision with a 100 MHz master clock and a sample clock of around 20 to 40 KHz. Again, there’s lots of work to do but it looks very promising at the moment.

I should also mention that I’m being super nit-picky about this ADC design. Most of this won’t matter for your application, except the non-linear stuff. 10 Hz sample rate is fairly slow and you can get away with a lot of sloppy (but easy) math with that.

by david49152 July 3, 2011 at 10:28 pmThanks for your reply, David.

It seems you are saying in your article that the RC model is given by:

Ref_New= Ref_Current + (Dout-Ref_Current) * (1-exp(-T/RC))

Now, let’s substitute expression (1 – exp (-T/RC)), with constant K.

Also, instead of referring to Ref_New and Ref_Current, lets assume a series of N iterations, with Ref (J) and Dout (J) referring to the value of Ref_Current in iteration J. Also, let’s assume that the start state has Ref (0) = 0 and Dout (0) = 0.

Now we get:

Ref (J) = Ref (J – 1) + (Dout (J – 1) – Ref (J – 1)) * K,

for 1 <= J <= N.

Or:

Ref (J) = Ref (J – 1) + Dout (J – 1) * K + Ref (J – 1) * -K,

or:

Ref (J) = Ref (J – 1) * (1 – K) + Dout (J – 1).

If (1 – K) is not a convenient constant (such as a power of two), we can always make it one and add Dout (J – 1) / (1 – K) if Dout (J – 1) is 1 (and nothing if it is 0). The final Ref (N) must be multiplied by (1 – K) to get the correct result. This should be acceptable overhead and allow for easier selection of R and C. Am I missing something?

-Geert

by Geert Bosch July 4, 2011 at 6:33 pmI think your math is wrong. You can’t go from this:

Ref (J) = Ref (J – 1) + Dout (J – 1) * K + Ref (J – 1) * -K

To this:

Ref (J) = Ref (J – 1) * (1 – K) + Dout (J – 1)

But even if it were right, it doesn’t make selecting R and C any easier. You still need to select R and C to make your constant a power of 2– regardless of if your constant is K or 1-K.

One thing that I don’t like about WordPress is that a link within an article doesn’t always show up clearly, making them easy to miss. Check out Part 2 of this series. About half way down is a link called “adc_constants”. I just made it bold to highlight it. That link will take you to a spreadsheet of R and C combinations for a variety of clock frequencies. If it doesn’t have the frequency you want, just yell and I’ll add it.

by david49152 July 5, 2011 at 7:15 amHi,

Could you please tell me what software you are using to produce the scope traces and simulation results?

Thank you,

Neo.

by Neopolythe November 1, 2011 at 5:25 amI’m using ModelSim for VHDL simulation, which produced all the waveforms in this article.

by david49152 November 1, 2011 at 6:25 amThis article is quite a bit unclear about what you’re doing. You say “In the FPGA, the only real comparator would be a differential input buffer. LVDS, for example.” What do you mean by “differential input buffer”? An Op-Amp? No, those aren’t digital. I’ve never heard of a digital differential buffer. LVDS? That’s a specification, not a circuit component. So can you be a little more clear about what you’re talking about?

by krb686 December 4, 2013 at 8:17 amA “differential input buffer” is an input buffer that takes a differential signal of some kind. There are many standards for differential signals, and LVDS is one of them. An LVDS input buffer is an input buffer that follows the LVDS standard.

by david49152 December 4, 2013 at 9:01 amI am a university student and as a part of my final year project, I have to implement Sigma Delta ADC on Altera cyclone FPGA device. I searched VHDL code for that in internet but I could not find any code. I only found the theory about that. So I kindly request you to send me a VHDL code for Sigma Delta ADC. Please help me. Thank you. (Sorry about my bad English). My email- ddescw@gmail.com

by Deshitha Chamikara Wickramrathna June 17, 2014 at 5:41 am[…] second image is the solution i had found FPGA ADC. This also uses a single ended analog input, whereas i have a differential input across a […]

by ADC implementation | Question and Answer October 28, 2014 at 5:00 pmsir, can you help me get a code to make a overcurrent protection relay using FPGA. it’s my final year project cause i cant find a code on internet. my email alifsulamat@gmail.com

by alifsulamat November 19, 2014 at 11:13 amNo.

by david49152 November 19, 2014 at 8:09 pmHi, i am trying to implement the RC filter model and low pass filter digitally in the FPGA but dont know to. Is it possible for you to send me the vhdl code to abhishekpillai1993@hotmail.com that you had mentioned above?

Cheers

by Abhishek Pillai May 2, 2016 at 8:17 pm