By Paul Dreik 2023-09-02

Increasing resolution of a DA converter

Imagine you have a DA converter, but it has poor resolution compared to what you want. On the other hand, it has a much higher update frequency than requested. Then you could do something like pulse width modulation. Say the DA is capable of 16 bits resolution, but you wish to have 24 bits. Then you determine the two closest 16 bit values, and flip between those such that the average output is the desired.

Example: the desired 24 bit output is 0x7D1225. The closest 16 bit values are 0x7D12 and 0x7D13. The bottom bits are 0x25. Let the output be 0x7D12 for 0x25 (37) samples and 0x7d13 for 0xDB (219) samples. The average value will be 0x7D1225.

 --------------       -----------
| DA converter | --> | LP filter | --> output
 --------------       -----------

Why is PWM not optimal?

Imaging the desired value to be right between two steps of the DA. (For example, wanting 0x7D1280 in the example above). Outputting 128 samples of 0x7D12 and then 128 samples with 0x7D13 would create a a square wave with a 1/256 frequency of the DA rate. Compare this to outputting the values interleaved (0x7D12, 0x7D13, 0x7D12, 0x7D13 and so on) which would give the square wave a frequency of 1/2 of the DA rate. This creates an error with much higher frequency, which is attenuated much more by the LP filter downstream of the DA converter.

Formulating an optimality problem

Assume the output sequence of the DA is to be repeated each N cycles. Assume the duty cycle of 0<M<=N which creates an average value M/N (for M=0 and M=N, there is no interpolation, the DAC can output those values perfectly). The problem is now to calculate a binary sequence (with M ones and N-M zeros) such that the noise after passing through the low pass filter is as small as possible. Because the output range can be time shifted without affecting the spectrum or average, we can assume the first output always is a one.

Calculating the output noise

A first order low pass filter has transfer function 1/(tau*s+1) where tau is the time constant in seconds. Assume the output of the DA converter (=our binary sequence) has fourier transform X (an array of N values) which can be calculated given the binary sequence. The gain of the low pass filter is calculated as Y (same size as X). The noise on the output of the low pass filter, will be sum |X(i)*Y(i)|^2. The first element (the DC value) could be skipped since that is given by M/N.

Brute forcing

I made a small program that tried random permutations, keeping the best. This is very time consuming, since the number of permutations is very high even for moderately sized problems. But I was able to see that the output sequence spreads the ones evenly, as opposed to PWM which puts them all in the beginning.

A practical solution - linear feedback shift register

One way to generate the output is to use something that generates a permutation of values 1-N and then output a one if the the output value is >=M and a zero otherwise. This relates to what I talked about in my 2019 talk Home made crypto for a non-cryptographic problem: the permutation can be generated by using a block crypto on a repeating counter.

A crypto is however expensive compared to using a linear feedback register

The suggestion is to use a m-bit linear feedback register where N=2^m-1 and output a one if the output is >=M. Any invertible transformation (such as an xor or bit rotation) can be inserted to increase the quality of the output.

Using feedback

I am an automatic control engineer, and of course I will try to approach the problem as a feedback problem. This uses a integral of the control error with a nonlinear controller.

Assume the desired output is M/N with M and N integers. For each time step k of the DA output, update the running sum s(k):

s(0)=0
u(0)=0
s(k+1)=s(k)+N*u(k)-M
u(k)= 1 if s(k)<0
      0 otherwise

I simulated this and there seems to be a cycle length of at most N. I think this can be proved by the pidgeon hole principle, since s(k) is integer and it is limited by N-M upwards and -M downwards.

This resembles the delta-sigma modulator. Also, see the Bresenham line algorithm.

There are related concepts which are very interesting: