FPGA techniques for D/A and A/D

H

Hal Murray

Guest
I'm interested in getting some analog signals out of and into a FPGA.
The context is fine tuning the frequency of a crystal and measuring
temperature and supply voltages.

I don't need high speed. A 1 Hz response is overkill. I'm thinking of
16-20 bits of resolution.

I don't need absolute calibration on offset or scale, I can compensate
for that in software. I want the low bits to be clean. I want it to
be linear within a local region. I don't care (much) if the slope at
one end of the range is the same as the middle or other end. (I can
correct for that with software.)

Stability over time and temperature (and VCC) would be good. It's
probably OK if I can measure and correct for it.

This is for a hack/hobby project. (Or maybe just a thought experiment.)


One obvious approach is to get a D/A chip and let it do all the work.
Anybody got any favorite chips for this sort of application?

A quick scan on the net finds lots of Audio chips with many bits of
precision in the audio band, but I'm not sure what happens at very
low frequencies. I doubt if they are very stable over temperature
and VCC.

Pulse width modulation is the classic way to do low speed D/A from
digital logic. For this purpose, I think I can do better by spreading
the on bits over the whole time slot rather than clumping them all at
the beginning. (Better low frequency noise.) For example, if I wanted
slightly lower than 1/3 of full scale, I would send 1 on pulse, and 2
or 3 off pulses, adjusting the ratio of 2 and 3 off pulses to get the
best answer. What's the term for this approach? Is there a good
writeup someplace?

If I use 1 megohm and 1 uF as a filter, that's 1 Hz time constant, so
that's the right ballpark. If I run the clock at 1 MHz that's 20 bits
of resolution.

One advantage of this approach is that the output level doesn't depend
upon the value of the resistor (assuming no/tiny load). It's just the
ratio of on time to total time and that is easy to control in the digital
domain. So the temperature coefficient of the resistor doesn't matter.
If I use an op-amp as a buffer, the temp coefficient of the offset
voltage may be the limiting factor on stability.

How would you test/evaluate something like this? Make two and compare
them while you heat one of them?


--
The suespammers.org mail server is located in California. So are all my
other mailboxes. Please do not send unsolicited bulk e-mail or unsolicited
commercial e-mail to my suespammers.org address or any of my other addresses.
These are my opinions, not necessarily my employer's. I hate spam.
 
On Mon, 19 Apr 2004 09:10:38 -0000, hmurray@suespammers.org (Hal
Murray) wrote:

I'm interested in getting some analog signals out of and into a FPGA.
The context is fine tuning the frequency of a crystal and measuring
temperature and supply voltages.

I don't need high speed. A 1 Hz response is overkill. I'm thinking of
16-20 bits of resolution.
That's only a few microvolts...

I don't need absolute calibration on offset or scale, I can compensate
for that in software. I want the low bits to be clean. I want it to
be linear within a local region. I don't care (much) if the slope at
one end of the range is the same as the middle or other end. (I can
correct for that with software.)

Stability over time and temperature (and VCC) would be good. It's
probably OK if I can measure and correct for it.

This is for a hack/hobby project. (Or maybe just a thought experiment.)

One obvious approach is to get a D/A chip and let it do all the work.
Anybody got any favorite chips for this sort of application?
Given your very low speed and high resolution needs, I suspect you
may end up with a much cheaper solution *without* the external chips,
as you're obviously thinking yourself.

A quick scan on the net finds lots of Audio chips with many bits of
precision in the audio band, but I'm not sure what happens at very
low frequencies. I doubt if they are very stable over temperature
and VCC.
As you say, their DC performance tends to be iffy. But you do
get good resolution, and all the difficult digital stuff (noise
shaping digital filters, etc) is done for you. And they are
amazingly cheap for what you get.

Pulse width modulation is the classic way to do low speed D/A from
digital logic.
That would be my first port of call, too.

Given excellent D/A conversion, you have lots of options
for A/D. Cheapest of all is timing how long it takes to
charge a capacitor up to the input voltage from a known
source. Dual-slope techniques are great.

For this purpose, I think I can do better by spreading
the on bits over the whole time slot rather than clumping them all at
the beginning. (Better low frequency noise.) For example, if I wanted
slightly lower than 1/3 of full scale, I would send 1 on pulse, and 2
or 3 off pulses, adjusting the ratio of 2 and 3 off pulses to get the
best answer. What's the term for this approach? Is there a good
writeup someplace?
Nothing I've seen in the form you want, although it's exactly what
the hi-res audio converters do, and seaerching for information on
"delta-sigma modulation" and "noise shaping digital filter" should
turn up plenty of interesting stuff.

I've played with this sort of PWM before, so a few musings follow.
My guess is that you've thought about all these things already,
but just in case... see the bottom of this post.

If I use 1 megohm and 1 uF as a filter, that's 1 Hz time constant, so
that's the right ballpark. If I run the clock at 1 MHz that's 20 bits
of resolution.
You can do MUCH better than this, by noise shaping. Audio DACs get
20kHz+ bandwidth and 20-bit resolution with a clock of only a few MHz.
But your bandwidth is so very low that you probably don't need those
difficult digital tricks.

To understand what happens to your least significant bits in this
scheme, imagine that the PWM is set to a value of just 1 (one clock
on, a million clocks off). Now think about what your first-order
lowpass will do to that signal.

Don't forget that the 20-bit settling time of a first order
lowpass filter is much longer than one time constant:

time error effective resolution
(%) (bits)
1RC 37 1
2RC 13 3
3RC 5 4
4RC 1.8 5.5
5RC 0.7 6.8
....
10RC 0.0045 13.6
....
15RC 0.00003 20.3

One advantage of this approach is that the output level doesn't depend
upon the value of the resistor (assuming no/tiny load). It's just the
ratio of on time to total time and that is easy to control in the digital
domain. So the temperature coefficient of the resistor doesn't matter.
Nor does the tempco/value of the capacitor, which is likely to be
just as variable.

But the power supply voltages that you're switching most certainly do
have an effect.

If I use an op-amp as a buffer, the temp coefficient of the offset
voltage may be the limiting factor on stability.
And the offset current - remember you're using a fairly big resistor
in your first-order lowpass section.

How would you test/evaluate something like this? Make two and compare
them while you heat one of them?
Make a nice quiet well-filtered reference, subtract from your DAC
output, amplify???
Post something on sci.electronics.design and hope that the nanovolt
gurus there (notably Winfield Hill) will respond with some amazingly
cool suggestions???

Anyways, back to the FPGA-related stuff: Your idea of spreading
the PWM pulses out over the duration of the cycle is interesting,
specially for very low bandwidth applications. As you say, it
reduces the low frequency spuriae, and therefore makes it easier
to filter. I coined the name "distributed PWM" to contrast with
the traditional "block PWM" technique; I have no idea whether
these terms have any legitimacy. You can make a simple
distributed PWM by using a first order delta-sigma modulator;
it's essentially the same trick as Bresenham's algorithm
for drawing angled lines on a raster display. Conceptually
the algorithm is:
* maintain a signed accumulator register A
* establish a PWM cycle length, N clock cycles
* have a "desired output" value V
* on each clock cycle, accumulate A = A + V, and then...
- if A is negative, supply 0 as the output
- if A is positive, supply 1 as the output and modify
the accumulator by forming A = A - N

In practice you lose very little by making N an exact power
of 2, and then the last step (subtract N) comes free with
the arithmetic overflow that gave you a positive A; and
the output value is simply the most significant bit of A.
There's an interesting tweak: if you add the carry-out
from the A=A+V operation back in to the next operation,
then the effect is to make N just one less than the round
power of 2, and you can get the full range of "always off"
through to "always on" without needing an extra bit of
input. I can let you have VHDL or Verilog code examples
for all this if you are interested.

There are, however, several snags. First, like any PWM
generator, the output is directly affected by the power
supply and ground voltages that you're emitting on the
output pin. One easy workaround is to use the output
to switch a CMOS pass-switch (CD4066, or one of the newer
versions) which can be used to get the PWM output from a
clean voltage reference instead of the noisy digital supply.

Second, there is no guarantee that your switching is
symmetrical, so each switching transition introduces some
bias - and, unlike "block PWM", the number of switch
transitions per PWM cycle is very variable. This will
introduce some gruesome nonlinearities. However, it's
not hard to deal with this one too. The key is to
ensure that you get a fixed number of output transitions
in any reasonably short period of time. You can do this
by dividing the PWM cycle into a number of sub-cycles,
and use "block PWM" within each of these sub-cycles. If
this sub-cycle is never allowed to go always-off or
always-on, it is certain to have just one rising and one
falling transition on the output. Of course this stops
you from getting full-scale output, but from the sound
of your application that would not be a problem.
The delta-sigma accumulator now looks like:

* establish the range of values that you can produce
within a single sub-cycle: for example, if the
sub-cycle is 18 clocks long, its output can range
from 1/18 to 17/18, giving a range R of 16.
* establish the number of sub-cycles per PWM cycle,
S = N/R.
* at each sub-cycle boundary:
- form A = A + V
- find the required sub-cycle value X by taking
the whole-number part of A/S
- update A = A - X*S
- use X+1 as the sub-cycle PWM value
(to avoid always-off)

Obviously all this is much easier if S is a power of 2.

Now we have exactly two transitions per sub-cycle and
the transition-related error should be close to constant.
Be careful though: much of the transition-related error
will come from charge injection in your CMOS switch,
and its value will be affected by the digital supply.
With any luck, it's a second-order variation in a
second-order effect and should be negligible.

Apologies if this is all stuff you know about already.

Good luck!
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail:jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Mon, 19 Apr 2004 12:13:11 +0100, Jonathan Bromley
<jonathan.bromley@doulos.com> wrote:


[stuff]

Don't forget that the 20-bit settling time of a first order
lowpass filter is much longer than one time constant:

time error effective resolution
(%) (bits)
[snip wrong numbers]

Whoops, fingers slipped on spreadsheet...

time error effective resolution
(%) (bits)
1RC 37 1.4
2RC 13 2.8
3RC 5 4.3
4RC 1.8 5.8
5RC 0.7 7.2
....
10RC 0.0045 14.4
....
14RC 0.00008 20.2
15RC 0.00003 21.6

Doesn't really affect what I was saying, though.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail:jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Jonathan Bromley wrote:

On Mon, 19 Apr 2004 09:10:38 -0000, hmurray@suespammers.org (Hal
Murray) wrote:


I'm interested in getting some analog signals out of and into a FPGA.
The context is fine tuning the frequency of a crystal and measuring
temperature and supply voltages.

I don't need high speed. A 1 Hz response is overkill. I'm thinking of
16-20 bits of resolution.


That's only a few microvolts...
Yes.
A discrete solution with PWM or a DAC requires a comparator
being able to sense these microvolts. Considering that
the usual offset voltage is in the 2 digit microvolt region,
that won't be easy. Further a comparator needs overdrive.

It might be simpler to use a standard 20 or 24bit ADC,
eg LT2404, LT2424, LT2440 plus a few more. Also Analog Devices
has a few. They cost in the order of 7$US.
Getting them to produce between 16 and 20 bits is tricky enough.
Good luck.

Rene
--
Ing.Buero R.Tschaggelar - http://www.ibrtses.com
& commercial newsgroups - http://www.talkto.net
 
On Mon, 19 Apr 2004 09:10:38 -0000, hmurray@suespammers.org (Hal Murray) wrote:

I'm interested in getting some analog signals out of and into a FPGA.
The context is fine tuning the frequency of a crystal and measuring
temperature and supply voltages.
....
Pulse width modulation is the classic way to do low speed D/A from
digital logic. For this purpose, I think I can do better by spreading
the on bits over the whole time slot rather than clumping them all at
the beginning. (Better low frequency noise.) For example, if I wanted
slightly lower than 1/3 of full scale, I would send 1 on pulse, and 2
or 3 off pulses, adjusting the ratio of 2 and 3 off pulses to get the
best answer. What's the term for this approach? Is there a good
writeup someplace?
This is called a Bit Rate Multiplier. First popularized in the
Fairchild 7497 which is a 6 bit implementation. TI also makes it:

http://focus.ti.com/docs/prod/folders/print/sn7497.html

As you can see on page 5 of the data sheet, it is trivially
cascadeable, and page 3 shows you all you need to do an FPGA
implementation.


Philip

Philip Freidin
Fliptronics
 
On Mon, 19 Apr 2004 14:36:06 +0200, Rene Tschaggelar
<none@none.net> wrote:

I'm interested in getting some analog signals out of and into a FPGA.
The context is fine tuning the frequency of a crystal and measuring
temperature and supply voltages.
I don't need high speed. A 1 Hz response is overkill. I'm thinking of
16-20 bits of resolution.

That's only a few microvolts...

Yes.
A discrete solution with PWM or a DAC requires a comparator
being able to sense these microvolts. Considering that
the usual offset voltage is in the 2 digit microvolt region,
that won't be easy. Further a comparator needs overdrive.
Dual-slope techniques do a pretty good job of turning all
these effects (bias, overdrive...) into a near-constant
offset that can easily be calibrated away.

It might be simpler to use a standard 20 or 24bit ADC,
eg LT2404, LT2424, LT2440 plus a few more. Also Analog Devices
has a few. They cost in the order of 7$US.
True, but they do most grievously spoil the fun of the
thought-experiment.

Getting them to produce between 16 and 20 bits is tricky enough.
Indeed. It's very easy to get a rather small current to develop
tens of microvolts along a rather short piece of PCB trace.
And assembled PCBs are a rich source of thermoelectric
voltages, so any temperature gradient across your PCB is
likely to kill your accuracy. A nice big power-hungry
FPGA in a nice small package, close to a whole lot of nice
low-power analogue electronics... I suspect Hal Murray is
somewhat aware of these issues. If not, he soon will be ;O)
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail:jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Mon, 19 Apr 2004 16:40:04 GMT, Philip Freidin
<philip@fliptronics.com> wrote:

[re. distributing the pulses over a PWM cycle...]

This is called a Bit Rate Multiplier.
I believe the BRM arrangement gives significantly
worse low-frequency spuriae than the Bresenham
(or delta-sigma, or pulse distributor, or gradient
interpolator, or whatever you want to call it)
arrangement that I described in an earlier response.
However, I don't have a formal proof of that, so
it's possible I'm totally wrong. Refutations
welcome!
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail:jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
"Jonathan Bromley" <jonathan.bromley@doulos.com> wrote in message
news:kc9780d765fn0lor7msd06dhnk033aqp7p@4ax.com...
You can make a simple
distributed PWM by using a first order delta-sigma modulator;
it's essentially the same trick as Bresenham's algorithm
for drawing angled lines on a raster display. Conceptually
the algorithm is:
* maintain a signed accumulator register A
* establish a PWM cycle length, N clock cycles
* have a "desired output" value V
* on each clock cycle, accumulate A = A + V, and then...
- if A is negative, supply 0 as the output
- if A is positive, supply 1 as the output and modify
the accumulator by forming A = A - N

Very interesting! I've a question.
What's the algorithm for a second order delta-sigma modulator? N-order?

Cheers, Syms.
 
On Mon, 19 Apr 2004 02:10:38 -0700, Hal Murray wrote:


Pulse width modulation is the classic way to do low speed D/A from
digital logic. For this purpose, I think I can do better by spreading
the on bits over the whole time slot rather than clumping them all at
the beginning. (Better low frequency noise.) For example, if I wanted
slightly lower than 1/3 of full scale, I would send 1 on pulse, and 2 or
3 off pulses, adjusting the ratio of 2 and 3 off pulses to get the best
answer. What's the term for this approach? Is there a good writeup
someplace?

One term is rate multiplier, another is interleaved PWM.

Its easy to generate interleaved PWM by bit reversing the reference count
before comparing it with the PWM value. You can even trade off transitions
per cycle versus filter time constant by only bit reversing the desired
number of bits of the reference count.

The power on the FPGA tends to be noisy so I would add an external
74ACT04 or some such powered by a clean power supply for your actual
PWM...


Peter Wallace
 
The power on the FPGA tends to be noisy so I would add an external
74ACT04 or some such powered by a clean power supply for your actual
PWM...
Thanks. That was on my list but I left it out because of clutter.
The supply for that buffer also has to be well regulated. I suspect
that's just the tip of the analog iceberg.

--
The suespammers.org mail server is located in California. So are all my
other mailboxes. Please do not send unsolicited bulk e-mail or unsolicited
commercial e-mail to my suespammers.org address or any of my other addresses.
These are my opinions, not necessarily my employer's. I hate spam.
 

Welcome to EDABoard.com

Sponsor

Back
Top