ADC Sampling Breakthrough - Page 37 — Parallax Forums

# ADC Sampling Breakthrough

• Posts: 1,672
This whole topic of filtering I can not overview, so this is what I see:
A clean signal is just a single value at any time. Something like a constant voltage. A fourier transform of such a signal only has one component not zero: the frequency zero, or DC-level.
The moment a single value is different, the spectrum will show an infinite number of non zero values, frequency 1 (one) is showing the largest amplitude, amplitudes decreasing with increasing frequency.
Any filter that limits high frequencies leaves over lower frequencies, so a spike, originally seen as a single value, now is cutted in amplitude, but spread in time, nearly undetectable. But when we integrate the signal over time, the bump will integrate to nearly the same value as the former spike did. So we gain nothing.
Now, how does a optimal filter work? Such a filter knows about the signals characteristic ( for example: spikes are not allowed) and just REMOVES any component that is not allowed. For example: if there is a spike, that is, amplitude changes faster than allowed, the slope is just limited.
Let the signal be constant, the change allowed is +-1. If now a change of 10 occures, this change is limited to 1. When the spike ends, the change is -10, limited: -1. So the error introduced is 1 times duration of the spike instead of 10 times duration of the spike. No signal is spreaded.

What we do so far is: we apply proven knowledge to an application, that is different to the original problem, leading to that knowledge. It's like draining a swamp in the dessert by watering, growing a swamp and then draining it.

Software defined radio, that is: sending bits at highest density using an electromagnetic wave can rely on the fact, that electromagnetic waves are law-abiding, means: the laws of physics apply. Then you can go to the limits, e.g. rely on Shannons Theorem. If not, and this is the case in the Propellers ADC,we should not try to squeeze out the last bit by doing experiments on a wavering platform.
Theory is one side of the medal, not the medal itself.

• Posts: 13,631
TonyB_ wrote: »
cgracey wrote: »
TonyB_ wrote: »
Chip, I'll look into it now. A long Tukey-type window is definitely the best way to get more than an eight-bit output every clock as I don't think we have the logic for an extra filter.

We can repurpose the 17 trigger bits:

error[11:0] = input[11:0] - filter[16:5]
filter[16:0] = filter[16:0] + {{5{error[11]}}, error[11:0]}
sample[11:0] = filter[16:5]

The main issue with the Tukey/Hann/Blackman windows is their max values are only about half of the cascaded moving averages (CMA for short).

As an alternative, with fairly minor tap changes and a little bit of skipping, the long CMA can fit into 69 of the 70 available taps including zeroes, as follows:
```  +1 +2 +3 +4 +5 +6 +7 +8 +9 +8 +7 +6 +5 +4 +3 +2 +1 +0

0, 1, 3, 6,10,15,21,28,36,45,53,60,66,71,75,78,80,__,		sum =  648 \
80[35]	sum = 2800  > 4096
__,80,78,75,71,66,60,53,45,36,28,21,15,10, 6, 3, 1, 0		sum =  648 /

-1 -2 -3 -4 -5 -6 -7 -8 -9 -8 -7 -6 -5 -4 -3 -2 -1 -0
```
What would have been 81 is skipped twice. I've shown 80 as part of the ramps for clarity (I hope). Some skipping is needed for the other windows, too.

TonyB_, I don't understand how we are going to skip 81 twice and wind up with a plateau of 80. How can we do this this?
• Posts: 1,771
cgracey wrote: »
TonyB_ wrote: »
cgracey wrote: »
TonyB_ wrote: »
Chip, I'll look into it now. A long Tukey-type window is definitely the best way to get more than an eight-bit output every clock as I don't think we have the logic for an extra filter.

We can repurpose the 17 trigger bits:

error[11:0] = input[11:0] - filter[16:5]
filter[16:0] = filter[16:0] + {{5{error[11]}}, error[11:0]}
sample[11:0] = filter[16:5]

The main issue with the Tukey/Hann/Blackman windows is their max values are only about half of the cascaded moving averages (CMA for short).

As an alternative, with fairly minor tap changes and a little bit of skipping, the long CMA can fit into 69 of the 70 available taps including zeroes, as follows:
```  +1 +2 +3 +4 +5 +6 +7 +8 +9 +8 +7 +6 +5 +4 +3 +2 +1 +0

0, 1, 3, 6,10,15,21,28,36,45,53,60,66,71,75,78,80,__,		sum =  648 \
80[35]	sum = 2800  > 4096
__,80,78,75,71,66,60,53,45,36,28,21,15,10, 6, 3, 1, 0		sum =  648 /

-1 -2 -3 -4 -5 -6 -7 -8 -9 -8 -7 -6 -5 -4 -3 -2 -1 -0
```
What would have been 81 is skipped twice. I've shown 80 as part of the ramps for clarity (I hope). Some skipping is needed for the other windows, too.

TonyB_, I don't understand how we are going to skip 81 twice and wind up with a plateau of 80. How can we do this this?

Chip, it's tricky and I haven't got it working yet.
• Posts: 1,771
CMA67 filter now working in BASIC. It needs eight taps instead of six. Skipping was a red herring. I'll post code soon.
• Posts: 1,771
Here is the modified code with new window parameter c:
```'window parameters
'a = 4: b = 0: c = 0: m = 32 'cma14  t2 and t3 cancel out
'a = 4: b = 8: c = 0: m = 16 'cma22
'a = 8: b = 0: c = 0: m = 4  'cma30  t2 and t3 cancel out
'a = 8: b = 16: c = 0: m = 2 'cma46
'a = 8: b = 48: c = 0: m = 1 'cma78
a = 8: b = 35: c = 1: m = 1 'cma67  *NEW*

gx = 10 : cy = 270 : by = cy + 100 : ay = by + 100 : dy = ay + 50

t0 = 0
t1 = t0 + a + c
t2 = t1 + a
t21 = t1 + a - c ' same as t2 when c = 0
t3 = t2 + b
t31 = t2 + b + c ' same as t3 when c = 0
t4 = t3 + a
t5 = t4 + a + c

topbit = t5

'for x = 1 to 35: print : next x
print "taps"
print t0,t1,t21,t2,t3,t31,t4,t5
print

dim t(topbit)
for x = 0 to topbit: t(x) = 0: next x 'clear bits

inta = 0
intb = 0
intc = 0

for iter = 0 to topbit*2 + 1

for x = topbit to 1 step -1: t(x) = t(x-1): next x 'shift bits
t(0) = (iter <= topbit) 'new ADC bit
't(0) = 1 - t(1)
't(0) = int(rnd + 0.5)

delt = t(t0) - t(t1)*2 + t(t2)*2 - t(t21) - t(t3)*2 + t(t31) + t(t4)*2 - t(t5)

inta = inta + delt
intb = intb + inta
intc = intc + intb * m

clam = int(intc/4096)
samp = int(intc/16) - clam
print iter,t(0),delt,inta,intb,intc,samp,clam

x = gx + iter*4
line x, cy, x, cy - intc/16 'plot intc
line x, by, x, by - intb    'plot intb
line x, ay, x, ay - inta*2  'plot inta
line x, dy, x, dy - delt*8  'plot delta

next iter
```
• Posts: 13,631
TonyB_ wrote: »
Here is the modified code with new window parameter c:
```'window parameters
'a = 4: b = 0: c = 0: m = 32 'cma14  t2 and t3 cancel out
'a = 4: b = 8: c = 0: m = 16 'cma22
'a = 8: b = 0: c = 0: m = 4  'cma30  t2 and t3 cancel out
'a = 8: b = 16: c = 0: m = 2 'cma46
'a = 8: b = 48: c = 0: m = 1 'cma78
a = 8: b = 35: c = 1: m = 1 'cma67  *NEW*

gx = 10 : cy = 270 : by = cy + 100 : ay = by + 100 : dy = ay + 50

t0 = 0
t1 = t0 + a + c
t2 = t1 + a
t21 = t1 + a - c ' same as t2 when c = 0
t3 = t2 + b
t31 = t2 + b + c ' same as t3 when c = 0
t4 = t3 + a
t5 = t4 + a + c

topbit = t5

'for x = 1 to 35: print : next x
print "taps"
print t0,t1,t21,t2,t3,t31,t4,t5
print

dim t(topbit)
for x = 0 to topbit: t(x) = 0: next x 'clear bits

inta = 0
intb = 0
intc = 0

for iter = 0 to topbit*2 + 1

for x = topbit to 1 step -1: t(x) = t(x-1): next x 'shift bits
t(0) = (iter <= topbit) 'new ADC bit
't(0) = 1 - t(1)
't(0) = int(rnd + 0.5)

delt = t(t0) - t(t1)*2 + t(t2)*2 - t(t21) - t(t3)*2 + t(t31) + t(t4)*2 - t(t5)

inta = inta + delt
intb = intb + inta
intc = intc + intb * m

clam = int(intc/4096)
samp = int(intc/16) - clam
print iter,t(0),delt,inta,intb,intc,samp,clam

x = gx + iter*4
line x, cy, x, cy - intc/16 'plot intc
line x, by, x, by - intb    'plot intb
line x, ay, x, ay - inta*2  'plot inta
line x, dy, x, dy - delt*8  'plot delta

next iter
```

Fantastic, TonyB_!

Nice how you've got the filters sized at 14, +8, +8, +16, +32. Is the 67-tap's purpose to feed a filter for 12-bit samples?
• Posts: 13,631
jmg wrote: »
cgracey wrote: »
Thinking more, we just need a sum that has 12 contiguous 1's in its top bits.
Is that essential, given that’s well outside the rails on the ADC ?
I guess \$FFF is useful for easy clipping sense on the higher gain ranges, but 2040 could also be tested for ?

It's not essential, you're right. It just wouldn't need much explaining when someone used it.
• Posts: 13,631
edited 2018-12-16 22:11
TonyB_, okay, I see that CMA67 sums to 4096, which could be clamped to \$FFF to feed a filter for 12-bit samples. Super!

Do you have any thoughts on how we ought to filter that 12-bit output to get steady 12-bit samples?
• Posts: 1,771
edited 2018-12-16 22:19
cgracey wrote: »
Nice how you've got the filters sized at 14, +8, +8, +16, +32. Is the 67-tap's purpose to feed a filter for 12-bit samples?

CMA67's intended purpose is to give us full 12-bit or 8-bit samples and replace CMA78 that is too big to fit, then the four CMAx could be implemented instead of the Tukey/Hann/Blackman windows, depending on the logic size.

The BASIC program was written to generate all the different windows with common code and there is no need for eight taps apart from CMA67. As this is the largest window it makes some sort of sense that there is no skipping, which I think can only work when what is being skipped has the same delta as before and after. This means that skipping might have a part to play with the smaller windows so that more taps are common to all windows, however I haven't tried this yet.

We would have a spare config bit with CMAx. CMA46 has 11-bit output, CMA30 10-bit and maybe these could be extended to 12 bits to match CMA67? The numbers don't add up so well for the smallest window CMA22, which sums to 256 (and is Tukey-like).

Written before previous post was read.
• Posts: 1,771
edited 2018-12-16 22:54
cgracey wrote: »
TonyB_, okay, I see that CMA67 sums to 4096, which could be clamped to \$FFF to feed a filter for 12-bit samples. Super!

Do you have any thoughts on how we ought to filter that 12-bit output to get steady 12-bit samples?

Will the output still be quite noisy after passing through 67 taps? I've thought about partially overlapping the windows in software so that every bit has exactly equal weight, with a sample taken every 60 50 or so clocks.

Is there any scope (pardon the pun) for anything else in hardware because the registers are fully used and the logic will be configured differently for different modes? I don't see how we could feed the output into some other existing filter in the same smart pin.
• Posts: 34
cgracey wrote: »
TonyB_, okay, I see that CMA67 sums to 4096, which could be clamped to \$FFF to feed a filter for 12-bit samples. Super!

Do you have any thoughts on how we ought to filter that 12-bit output to get steady 12-bit samples?

I'm a bit concerned out all of this business of clipping 256 to 255 or 4096 to 4095 just to save a small amount of logic; rather than propagate the carry, or overflow bit to the next stage - since I strongly suspect that that could be a major source of 1/f noise; which should be plainly clear if I give an example. Suppose that you are in effect summing bits using whatever chosen methods are available; whether it is TukeyXYZ or cmaXYZ or whatever. So you get a maximum slew rate audio input for a few 10's of microseconds; and then input is actually at 655xx something, i.e., close to the rail; but not necessarily at the rail … still you get a bunch of consecutive 256's which get clipped to 255; maybe even 100 of them, so now you are 100 bits short on your long count; when you add all of the ones up; then the input swings the other way; and the long count slowly drops; but not just zero; but past zero farther than it should; because the long count is short that 100 or so bits; and it gets clipped again a few more times at the 4095 vs. 4096 boundary in another cascaded stage and whoops! .. there we go again, with another asymmetric source of accumulated non linear distortion; which would manifest over time as a 1/f in the audio.

Then again; if the theory holds that the equilibrium state of the modulator is when it cycles between 0,1,0,1,0,1 .. when there is "no input" or rather when the input is (1/2)(Vcc+GND), it would appear that eventually the apparent drift introduced would eventually be "forgotten" by the filters, as they get past the longest window. Still the noise added will be "an occasional" disparity resulting in ENOB never really making it reliably past 8 or 9 biits.
• Posts: 14,847
I think the Sinc3 filter is still in there ?
ie these other modes, are are additional scope-mode filters ?
The Sinc3 gives a predictable filter for external ADCs, which can deliver better than 16 bit performances.
• Posts: 6,479
My overall concern here is the time that is being spent on trying to solve what might be a endless chase. I did a fair amount of study at NSC with high speed and high resolution ADC's for Foveon cameras and it seems that everything eventually distills into sacrificing one thing for the other and you can't get something from nothing. You either have good resolution at low speed or diminished resolution at higher speed. The balancing act of the two is the endless chase I am referring to. I'm not saying to give up this effort. I just think everyone should be mindful of the circumstance and realize when you are chasing your own tail.
• Posts: 1,771
jmg wrote: »
I think the Sinc3 filter is still in there ?
ie these other modes, are are additional scope-mode filters ?
The Sinc3 gives a predictable filter for external ADCs, which can deliver better than 16 bit performances.

Here is how I see things. Both Sinc3 and scope modes are intended. The latter could provide an output every clock (which Sinc3 cannot do), either 8-bit triggered or 12-bit non-triggered. The former would be combined with byte outputs from three other pins to give four-channel, 32-bit values. The latter would be a higher-res output and as close to 16-bit as we could get every clock, probably.
• Posts: 1,771
lazarus666 wrote: »
cgracey wrote: »
TonyB_, okay, I see that CMA67 sums to 4096, which could be clamped to \$FFF to feed a filter for 12-bit samples. Super!

Do you have any thoughts on how we ought to filter that 12-bit output to get steady 12-bit samples?

I'm a bit concerned out all of this business of clipping 256 to 255 or 4096 to 4095 just to save a small amount of logic; rather than propagate the carry, or overflow bit to the next stage - since I strongly suspect that that could be a major source of 1/f noise; which should be plainly clear if I give an example. Suppose that you are in effect summing bits using whatever chosen methods are available; whether it is TukeyXYZ or cmaXYZ or whatever. So you get a maximum slew rate audio input for a few 10's of microseconds; and then input is actually at 655xx something, i.e., close to the rail; but not necessarily at the rail … still you get a bunch of consecutive 256's which get clipped to 255; maybe even 100 of them, so now you are 100 bits short on your long count; when you add all of the ones up; then the input swings the other way; and the long count slowly drops; but not just zero; but past zero farther than it should; because the long count is short that 100 or so bits; and it gets clipped again a few more times at the 4095 vs. 4096 boundary in another cascaded stage and whoops! .. there we go again, with another asymmetric source of accumulated non linear distortion; which would manifest over time as a 1/f in the audio.

Then again; if the theory holds that the equilibrium state of the modulator is when it cycles between 0,1,0,1,0,1 .. when there is "no input" or rather when the input is (1/2)(Vcc+GND), it would appear that eventually the apparent drift introduced would eventually be "forgotten" by the filters, as they get past the longest window. Still the noise added will be "an occasional" disparity resulting in ENOB never really making it reliably past 8 or 9 biits.

This is an interesting point, thanks for mentioning it. Clipping actually adds a little bit to the logic and here is comparison of the window filters again:
```Max values
CMA67 = 4096	Tukey68    = 2040
CMA46 = 2048	Tukey45    = 1020
CMA30 = 1024	Hann30     =  510
CMA22 =  256	Blackman22 =  256
```

The two Tukeys and the Hann would not need clipping.
• Posts: 1,771
edited 2018-12-17 01:38
cgracey wrote: »
TonyB_ wrote: »
Chip, I'll look into it now. A long Tukey-type window is definitely the best way to get more than an eight-bit output every clock as I don't think we have the logic for an extra filter.

We can repurpose the 17 trigger bits:

error[11:0] = input[11:0] - filter[16:5]
filter[16:0] = filter[16:0] + {{5{error[11]}}, error[11:0]}
sample[11:0] = filter[16:5]

I've just looked at this properly for the first time. What were the 17 trigger bits become filter[16:0] and the subtract and add are cascaded?

I'm wondering what this would do. I examined a short binomial/triangular filter [1,2,1] in software using three successive windowed outputs but the bits entering or leaving have very little weight and overall the three outputs varied so little it appeared to be useless, for the longer windows anyway.
• Posts: 13,631
TonyB_ wrote: »
cgracey wrote: »
TonyB_ wrote: »
Chip, I'll look into it now. A long Tukey-type window is definitely the best way to get more than an eight-bit output every clock as I don't think we have the logic for an extra filter.

We can repurpose the 17 trigger bits:

error[11:0] = input[11:0] - filter[16:5]
filter[16:0] = filter[16:0] + {{5{error[11]}}, error[11:0]}
sample[11:0] = filter[16:5]

I've just looked at this properly for the first time. What were the 17 trigger bits become filter[16:0] and the subtract and add are cascaded?

I'm thinking that maybe this belongs in the Sinc3, where there are already big adders. The trouble is, I cannot get 16-bit stable readings until I go to a 4th order filter. 3rd-order doesn't seem to do it.
• Posts: 71
My overall concern here is the time that is being spent on trying to solve what might be a endless chase. I did a fair amount of study at NSC with high speed and high resolution ADC's for Foveon cameras and it seems that everything eventually distills into sacrificing one thing for the other and you can't get something from nothing. You either have good resolution at low speed or diminished resolution at higher speed. The balancing act of the two is the endless chase I am referring to. I'm not saying to give up this effort. I just think everyone should be mindful of the circumstance and realize when you are chasing your own tail.

Chip was super happy with the tapered filter in post 1 of this thread. I'm honestly not convinced that what gets implemented in the end will be a ton better than that, which was already a huge improvement over the unfiltered ADC.

Is there a spreadsheet somewhere with all of these filters in it, the effective # of ADC bits, the approximate amount of logic added, and the update rate of the filtered output? So a decision could just be made that no further progress is happening? A simple 3D plot could show where new suggestions fall with respect to prior suggestions.
• Posts: 374
TonyB_ wrote: »
cgracey wrote: »
TonyB_ wrote: »
Chip, I'll look into it now. A long Tukey-type window is definitely the best way to get more than an eight-bit output every clock as I don't think we have the logic for an extra filter.

We can repurpose the 17 trigger bits:

error[11:0] = input[11:0] - filter[16:5]
filter[16:0] = filter[16:0] + {{5{error[11]}}, error[11:0]}
sample[11:0] = filter[16:5]

The main issue with the Tukey/Hann/Blackman windows is their max values are only about half of the cascaded moving averages (CMA for short).

As an alternative, with fairly minor tap changes and a little bit of skipping, the long CMA can fit into 69 of the 70 available taps including zeroes, as follows:
```  +1 +2 +3 +4 +5 +6 +7 +8 +9 +8 +7 +6 +5 +4 +3 +2 +1 +0

0, 1, 3, 6,10,15,21,28,36,45,53,60,66,71,75,78,80,__,		sum =  648 \
80[35]	sum = 2800  > 4096
__,80,78,75,71,66,60,53,45,36,28,21,15,10, 6, 3, 1, 0		sum =  648 /

-1 -2 -3 -4 -5 -6 -7 -8 -9 -8 -7 -6 -5 -4 -3 -2 -1 -0
```
What would have been 81 is skipped twice. I've shown 80 as part of the ramps for clarity (I hope). Some skipping is needed for the other windows, too.
It's great that you figured out how to modify the plateau. I was wondering about the construction of this, I guess you lowered the plateau from 81 to 80. Not necessarily a bad thing, but that was likely the cause of difficulty on the basic program. The ramp up matches a CMA9*9*51. The plateau value matches a CMA8*10*51. In the third derivative, sometimes the impulses combine together to increase the weight of a certain tap. This usually happens when using 2 filters of the length.

It's great that the triple integration method gives more flexibility than just CMA filters. We could design any filter we want as long as the 2nd, 3rd, or 4th derivative is sparse. You choose the number of integrations that minimizes the number of taps needed. The earlier Tukey windows were more efficeient at 2 integrations. The CMA filters are convenient as they guarantee smooth up and down curves and a very sparse derivative.
```CMA8*10*51
1    3    6   10   15   21   28   36   44   52   59   65   70   74   77   79   80    % sum=720
80[33]    %  80*33 = 2640  + 1440 = 4080  = 255*16
80   79   77   74   70   65   59   52   44   36   28   21   15   10    6    3    1   % sum=720

CMA5*19*43
1    3    6   10   15   20   25   30   35   40   45   50   55   60   65   70   75   80   85   89   92   94   95
95   95   95   95   95   95   95   95   95   95   95   95   95   95   95   95   95   95   95
95   94   92   89   85   80   75   70   65   60   55   50   45   40   35   30   25   20   15   10    6    3    1

WindowFn                Vpp98%         StdDev   HFNoisePower         Length            Sum      freq -3dB      freq -6dB
cma67                0.9453125     0.25685335    0.093979185             67           4096      2.2583008      3.0517578
cmafilter(9,9,51)   0.93359375     0.25360235    0.087876466             67           4131      2.2583008      3.0517578
cmafilter(8,10,51)  0.91015625      0.2462003    0.083966496             67           4080      2.2583008      3.0517578
cmafilter(7,11,53)  0.84765625     0.22993315    0.055827542             69           4081      2.1972656      2.9296875
cmafilter(5,19,43)  0.90234375     0.21898064    0.017175846             65           4085      2.5024414      3.4179688     Winner?
cmafilter(61,67)    0.44140625      0.1005641   0.0016081395            127           4087      1.4038086      1.8920898
cmafilter(7,8,73)   0.73828125     0.19108135    0.075131056             86           4088      1.6479492      2.1972656
cmafilter(3,29,47)   0.7734375      0.1800755    0.025439503             77           4089      2.1972656      2.9296875
cmafilter(12,11,31)  1.3359375     0.31267021     0.07171992             52           4092      3.3569336      4.5776367
cmafilter(2,23,89)   0.4609375     0.10954824   0.0084992018            112           4094      1.3427734      1.8310547
cmafilter(46,89)    0.37109375    0.084137484   0.0025121658            134           4094      1.2817383      1.7089844
cmafilter(7,13,45)   1.0039062     0.25080491      0.0549252             63           4095      2.5024414      3.3569336
cmafilter(9,13,35)   1.2304688     0.29084022    0.025621256             55           4095      3.0517578      4.1503906
cmafilter(7,15,39)      1.0625     0.25995787   0.0099692776             59           4095      2.8076172      3.7841797
cmafilter(13,15,21)  1.7851562     0.41339359    0.004897367             47           4095      4.0893555      5.6152344
cmafilter(23,23,23)    1.10677083     0.248253292   0.00663381155              67           12167      2.99072266      4.15039062
cmafilter(15,20,34)     0.9984375     0.224311137  0.000551419443              67           10200      2.80761719      3.84521484
cmafilter(18,18,18,16) 1.33077186     0.307690837  0.000285470381              67           93312      3.41796875      4.69970703
```
The closer all 3 numbers are, the closer we approximate sinc3.
• Posts: 13,631
edited 2018-12-17 06:37
Thanks for bearing through all this, Guys.

After a lot of experimenting and testing, I'm giving up on the live 16-bit and 12-bit sampling. If >8 bit sampling is wanted, the Sinc3 filter does a vastly superior job of filtering, with the caveat that you only get a sample every Nth clock, instead of on every clock.

I've found that to get the best A/D conversion, the pins involving the same Vxxxx supply pin should all be A/D inputs, in order to minimize noise. In a lot of experiments, I was using one pin for ADC and its neighbor pin for DAC. The DAC can variably draw several mA, which causes an IR drop on the bond wires and chip routing metal, which causes distortion in an ADC sharing those power signals. The interplay between ADC and DAC activity on same-power-supply pins had me thinking a few times that we had some strange problems, when we didn't.

In order to get around this shared-supply problem during development on the FPGA, with the two-I/O-pin test ASIC, I've resorted to recording ADC readings and then playing them back on a DAC, to avoid cross-talk. On the silicon, you need only use another 4-pin group with separate Vxxxx and GIO (GND) bond wires.

Here is what we can expect on the silicon. These are the bottom 8 bits of a 14-bit conversion of the apex of a sine wave. These samples were acquired in 256 clocks using the Sinc3 filter, and then decimated. Imagine that there are 64 more scope screens stacked vertically, in order to show the full scale. I think this is pretty good resolution:

• Posts: 13,631
edited 2018-12-17 06:44
So, TonyB_, we don't need any special-summing combos, anymore. Four nicely-spaced filters will do. I'll implement those with the trigger mechanism and call it done. Not sure if we should use the CMA or Tukey types.
• Posts: 4,423
Well spotted about that IR interplay, Chip.

Thanks for chasing these ADC improvements. Even with things as-are the ADC is mighty useful

What are your thoughts as to integrating capacitor reduction, still thinking 7/8 reduction? Or is that not required, now
• Posts: 176
cgracey wrote: »

The interplay between ADC and DAC activity on same-power-supply pins had me thinking a few times that we had some strange problems, when we didn't.

(So as a casual observer) is this what resolved the low frequency noise problem? I wasn't exactly sure what happened with that.
• Posts: 374
I figured out how to target an arbitrary sum value, as long as it's not prime. Hint: the product of the lengths is the sum of the full-scale value.
```WindowFn                Vpp98%         StdDev   HFNoisePower         Length            Sum      freq -3dB      freq -6dB
```
```cmafilter(15,16,17)  1.8710938     0.45310051   0.0097453259             46           4080      4.2114258       5.859375
cmafilter(12,17,20)  1.7851562     0.41339359    0.004897367             47           4095      4.0893555      5.6152344
cmafilter(13,15,21)   1.703125     0.41271856   0.0025632085             47           4080      4.0893555      5.6152344
cmafilter(10,17,24)  1.5546875     0.35814208    0.010309434             49           4080      3.7841797      5.1879883
cmafilter(11,12,31)  1.3359375     0.31267021     0.07171992             52           4092      3.3569336      4.5776367
cmafilter(8,17,30)   1.2695312     0.29777372    0.041569492             54           4080       3.112793      4.2724609
cmafilter(10,12,34)   1.265625     0.29298274    0.020882484             53           4080      3.3569336      4.5166016
cmafilter(8,15,34)   1.2304688     0.28550684     0.02088933             55           4080       3.112793      4.2114258
cmafilter(9,13,35)   1.2304688     0.29084022    0.025621256             55           4095      3.0517578      4.1503906
cmafilter(6,22,31)   1.0742188     0.25714119    0.027913922             57           4092      3.0517578      4.2114258
cmafilter(6,20,34)      1.0625     0.25995787   0.0099692776             59           4095      2.8076172      3.7841797
cmafilter(7,15,39)    1.046875     0.24883996     0.02482856             58           4080      2.9907227      4.0283203
cmafilter(5,24,34)    1.015625     0.23101449    0.026582745             61           4080      2.8076172      3.8452148
cmafilter(6,17,40)   1.0039062     0.25080491      0.0549252             63           4095      2.5024414      3.3569336
cmafilter(5,21,39)   0.9765625     0.23986534    0.011775686             61           4080      2.6855469      3.6621094
cmafilter(7,13,45)  0.97265625     0.22169555    0.028773534             66           4092      2.6245117      3.6010742
cmafilter(5,19,43)     0.96875     0.21869261    0.021288347             66           4080      2.6245117      3.6010742
cmafilter(4,30,34)   0.9453125      0.2219785    0.028801953             63           4095      2.6855469      3.6010742
cmafilter(4,31,33)  0.91015625      0.2462003    0.083966496             67           4080      2.2583008      3.0517578
cmafilter(8,10,51)  0.90234375     0.21898064    0.017175846             65           4085      2.5024414      3.4179688
cmafilter(5,17,48)   0.8828125     0.21550047     0.01768795             68           4080      2.3193359       3.112793
cmafilter(7,11,53)  0.84765625     0.22993315    0.055827542             69           4081      2.1972656      2.9296875
cmafilter(5,16,51)  0.84765625     0.18900605   0.0066547651             75           4080      2.3193359       3.112793
cmafilter(4,20,51)   0.8359375      0.2084993    0.018665709             70           4080      2.1972656      2.9907227
cmafilter(3,34,40)  0.82421875     0.18569615   0.0087039939             75           4095      2.3193359       3.112793
cmafilter(3,35,39)  0.79296875     0.19055261    0.016675073             73           4080      2.1972656      2.9296875
cmafilter(3,31,44)  0.78515625     0.20553193    0.091465996             79           4095      1.8310547      2.4414062
cmafilter(3,29,47)   0.7734375      0.1800755    0.025439503             77           4089      2.1972656      2.9296875
cmafilter(6,11,62)    0.765625      0.1784487    0.019493601             76           4092      2.2583008      3.0517578
cmafilter(4,17,60)    0.765625     0.20001477    0.054525232             77           4092      1.8920898      2.5634766
cmafilter(5,13,63)  0.73828125     0.19108135    0.075131056             86           4088      1.6479492      2.1972656
cmafilter(7,9,65)     0.734375     0.18651715    0.031620175             79           4095      1.8920898      2.5024414
cmafilter(6,10,68)     0.71875     0.18849886    0.074905481             82           4080      1.7700195      2.3193359
cmafilter(5,12,68)     0.71875     0.17393719    0.017857078             85           4080      1.7700195      2.3193359
cmafilter(4,15,68)   0.6953125     0.18060463    0.010035878             79           4080       1.953125      2.5634766
cmafilter(3,22,62)      0.6875     0.17827049    0.045283334             83           4080      1.7700195      2.3193359
cmafilter(7,8,73)    0.6796875     0.16979392    0.016435066             89           4088      1.6479492      2.1972656
cmafilter(3,21,65)   0.6640625     0.15440044    0.011133729             89           4080      1.7089844      2.3193359
cmafilter(3,20,68)     0.65625     0.16064566    0.015640098             85           4092      1.8310547      2.5024414
cmafilter(4,14,73)     0.65625     0.15789988    0.013131688             87           4095      1.7700195      2.3803711
cmafilter(2,40,51)  0.62890625     0.14304809   0.0056887585             91           4080      1.8920898      2.5634766
cmafilter(2,34,60)  0.62109375     0.15055978    0.057731851            103           4095      1.3427734      1.7700195
cmafilter(2,33,62)  0.61328125     0.14501547   0.0091484696            102           4080      1.4038086      1.8920898
cmafilter(6,8,85)   0.60546875     0.16565363    0.079584047             97           4080      1.4648438      1.8920898
cmafilter(2,31,66)  0.60546875     0.14378253    0.010198583            107           4095      1.3427734      1.7700195
cmafilter(2,30,68)   0.6015625     0.14457893   0.0072643578             98           4080      1.5258789      2.0141602
cmafilter(3,17,80)   0.6015625     0.14099539     0.03073128            106           4092      1.3427734      1.7700195
cmafilter(4,12,85)  0.59765625     0.14323234    0.004563578             94           4080      1.7700195      2.3803711
cmafilter(2,28,73)  0.58203125     0.13631145   0.0061415368             95           4092      1.7700195      2.3803711
cmafilter(3,16,85)      0.5625      0.1469321    0.031065718             99           4080      1.4648438      1.8920898
cmafilter(5,9,91)       0.5625     0.14958977    0.037040458            114           4080      1.2207031      1.6479492
cmafilter(4,11,93)  0.55859375      0.1313934   0.0099449442             97           4092      1.7089844      2.2583008
cmafilter(3,15,91)  0.55859375     0.12933839     0.01051853             98           4080      1.6479492      2.1972656
cmafilter(2,24,85)  0.55078125     0.12698544    0.053141074            127           4095      1.0986328      1.4648438
cmafilter(2,23,89)    0.546875     0.12927947   0.0087096441            101           4088      1.5869141      2.1362305
cmafilter(5,8,102)   0.5390625     0.15383191    0.058560707            113           4080      1.2207031      1.6479492
cmafilter(4,10,102) 0.51953125     0.12846422    0.015637843            119           4095      1.2207031      1.5869141
cmafilter(2,22,93)         0.5     0.11117836   0.0058186917            122           4080      1.2207031      1.5869141
cmafilter(3,13,105)  0.4921875     0.12480833    0.021968404            147           4080      0.9765625      1.2817383
cmafilter(2,20,102) 0.48828125     0.11417822   0.0074740046            115           4092      1.3427734      1.7089844
cmafilter(1,60,68)    0.484375     0.11695425   0.0096959977            109           4080      1.4038086      1.8920898
cmafilter(1,61,67)  0.47265625     0.12116007    0.021602631            136           4092      1.0375977      1.3427734
cmafilter(1,62,66)     0.46875     0.11493629    0.029272387            179           4080     0.79345703      1.0375977
cmafilter(1,63,65)   0.4609375     0.10954824   0.0084992018            112           4094      1.3427734      1.8310547
cmafilter(5,7,117)  0.44140625    0.096554634   0.0014085564            127           4080      1.4038086      1.8920898
cmafilter(1,56,73)  0.44140625      0.1005641   0.0016081395            127           4087      1.4038086      1.8920898
cmafilter(1,53,77)  0.44140625    0.097355869   0.0021470632            127           4092      1.4038086      1.8920898
cmafilter(1,51,80)      0.4375     0.12216849    0.051376129            145           4080      0.9765625      1.2817383
cmafilter(1,48,85)      0.4375     0.10967076   0.0044945432            151           4080      0.9765625      1.2817383
cmafilter(1,47,87)  0.43359375    0.093805836    0.036547378            211           4080     0.67138672     0.91552734
cmafilter(1,46,89)  0.42578125    0.095734222   0.0028626318            127           4095      1.4038086      1.8920898
cmafilter(1,45,91)    0.421875      0.1165705    0.045902376            155           4088     0.91552734       1.159668
cmafilter(1,44,93)  0.41796875    0.094900488    0.001994358            128           4088      1.4038086      1.8310547
cmafilter(3,11,124) 0.41015625    0.092538658   0.0014063601            129           4081      1.3427734      1.8310547
cmafilter(2,17,120) 0.41015625    0.097042155   0.0040005586            137           4080      1.0375977      1.4038086
cmafilter(1,43,95)  0.40234375    0.091554082   0.0027861622            132           4080      1.2817383      1.7089844
cmafilter(1,40,102)  0.3984375    0.091083422   0.0017300966            130           4080      1.3427734      1.7700195
cmafilter(1,39,105)   0.390625    0.098972526   0.0063637559            160           4088     0.91552734       1.159668
cmafilter(5,6,136)    0.390625     0.10342484    0.042696333            178           4080     0.79345703      1.0375977
cmafilter(3,10,136)   0.390625     0.08975344    0.012173962            214           4080     0.67138672     0.91552734
cmafilter(2,15,136) 0.38671875    0.087852367   0.0027309409            133           4089      1.2817383      1.7089844
cmafilter(1,35,117) 0.38671875    0.091018672   0.0065057791            170           4082     0.85449219      1.0986328
cmafilter(1,34,120)  0.3828125     0.08619121   0.0022953354            135           4095      1.2817383      1.6479492
cmafilter(4,7,146)   0.3828125    0.097783378    0.027860707            203           4095     0.73242188     0.91552734
cmafilter(1,33,124)  0.3828125    0.098549037    0.028855762            261           4080     0.61035156     0.73242188
cmafilter(2,14,146)      0.375     0.08361578    0.013937691            236           4086     0.61035156     0.79345703
cmafilter(1,31,132) 0.37109375    0.084137484   0.0025121658            134           4094      1.2817383      1.7089844
cmafilter(1,30,136) 0.37109375    0.083127214   0.0021773357            136           4092      1.2207031      1.6479492
cmafilter(1,29,141)  0.3671875    0.083783222   0.0021492163            137           4085      1.2207031      1.6479492
cmafilter(2,13,157) 0.35546875    0.081168118   0.0018333482            141           4080       1.159668      1.5258789
cmafilter(1,28,146) 0.35546875    0.079744889   0.0016885936            143           4095       1.159668      1.5258789
cmafilter(4,6,170)  0.35546875    0.089073563     0.01439288            263           4080     0.61035156     0.73242188
cmafilter(3,8,170)   0.3515625    0.078977605   0.0014575215            151           4095      1.0375977      1.4038086
cmafilter(2,12,170)  0.3515625    0.092569415    0.019813774            345           4080     0.48828125     0.61035156
cmafilter(1,26,157) 0.34765625    0.095855087    0.014478488            458           4086     0.36621094     0.48828125
cmafilter(1,24,170)    0.34375    0.090143548    0.019714252            346           4092     0.48828125     0.61035156
cmafilter(2,11,186) 0.33984375    0.089411431    0.010912252            197           4092     0.73242188      0.9765625
cmafilter(1,23,178) 0.33984375    0.079240485    0.027985958            234           4086     0.61035156     0.79345703
cmafilter(3,7,195)   0.3359375    0.086808399   0.0092910354            182           4080     0.79345703      1.0375977
cmafilter(1,22,186)   0.328125     0.07704787   0.0019535137            156           4092      1.0375977      1.3427734
cmafilter(4,5,204)    0.328125    0.075551914   0.0022640931            162           4092      0.9765625      1.2817383
cmafilter(2,10,204) 0.31640625    0.074725289    0.001546331            153           4080      1.0375977      1.3427734
cmafilter(1,21,195)     0.3125    0.074472429   0.0021856468            165           4080      0.9765625      1.2207031
cmafilter(1,20,204)     0.3125    0.074447446   0.0024512287            169           4089     0.91552734      1.2207031
cmafilter(1,19,215)     0.3125    0.081568518    0.024795057            278           4080     0.54931641     0.73242188
cmafilter(3,6,227)      0.3125    0.090265673    0.014256314            459           4095     0.36621094     0.48828125
cmafilter(2,9,227)   0.3046875    0.072080149   0.0028858426            173           4088     0.91552734       1.159668
cmafilter(1,18,227) 0.30078125    0.080948295    0.024483061            279           4095     0.54931641     0.73242188
cmafilter(1,17,240)   0.296875    0.077590502    0.011119039            514           4080     0.36621094     0.42724609
cmafilter(4,4,255)   0.2890625    0.071737802    0.015006185            299           4088     0.54931641     0.67138672
cmafilter(2,8,255)  0.28515625    0.067967424   0.0026656105            182           4082     0.85449219      1.0986328
cmafilter(1,16,255) 0.28515625    0.068167586   0.0022197291            207           4092     0.73242188      0.9765625
cmafilter(3,5,272)  0.28515625    0.077683673    0.011085855            515           4088     0.36621094     0.42724609
cmafilter(3,5,273)  0.28515625    0.085005963   0.0081914691            684           4086     0.30517578     0.36621094
cmafilter(1,15,272)    0.28125     0.06846468   0.0026564947            193           4080     0.79345703      1.0375977
cmafilter(1,15,273)    0.28125    0.064601198   0.0019532652            215           4095     0.73242188     0.91552734
```
• Posts: 13,631
edited 2018-12-17 07:24
The_Master wrote: »
cgracey wrote: »

The interplay between ADC and DAC activity on same-power-supply pins had me thinking a few times that we had some strange problems, when we didn't.

(So as a casual observer) is this what resolved the low frequency noise problem? I wasn't exactly sure what happened with that.

1/f noise is still an issue. The longer your measurement, the more of it you get. The Sinc3 filter is nice because it shortens measurements by getting more resolution in fewer counts. That not only increases efficiency, but reduces 1/f noise.
• Posts: 13,631
Tubular wrote: »
Well spotted about that IR interplay, Chip.

Thanks for chasing these ADC improvements. Even with things as-are the ADC is mighty useful

What are your thoughts as to integrating capacitor reduction, still thinking 7/8 reduction? Or is that not required, now

Reducing the integrator cap will help the ADC not muddle up high-frequency inputs. There should be no detrimental effect, other than you'll need to run the ADC at 8MHz+, instead of 1MHz+.
• Posts: 13,631
Saucy, can you please describe the three terms in your cmafilter(x,y,z)?
• Posts: 374
cgracey wrote: »
Thanks for bearing through all this, Guys.

After a lot of experimenting and testing, I'm giving up on the live 16-bit and 12-bit sampling. If >8 bit sampling is wanted, the Sinc3 filter does a vastly superior job of filtering, with the caveat that you only get a sample every Nth clock, instead of on every clock.

I've found that to get the best A/D conversion, the pins involving the same Vxxxx supply pin should all be A/D inputs, in order to minimize noise. In a lot of experiments, I was using one pin for ADC and its neighbor pin for DAC. The DAC can variably draw several mA, which causes an IR drop on the bond wires and chip routing metal, which causes distortion in an ADC sharing those power signals. The interplay between ADC and DAC activity on same-power-supply pins had me thinking a few times that we had some strange problems, when we didn't.

In order to get around this shared-supply problem during development on the FPGA, with the two-I/O-pin test ASIC, I've resorted to recording ADC readings and then playing them back on a DAC, to avoid cross-talk. On the silicon, you need only use another 4-pin group with separate Vxxxx and GIO (GND) bond wires.

Here is what we can expect on the silicon. These are the bottom 8 bits of a 14-bit conversion of the apex of a sine wave. These samples were acquired in 256 clocks using the Sinc3 filter, and then decimated. Imagine that there are 64 more scope screens stacked vertically, in order to show the full scale. I think this is pretty good resolution:
Wow, that looks good!

For the high resolution, what about an integrate and dump scheme? There could be 2 integrators so that one can be read while the other is accumulating. Or just a buffer that captures the value before dumping. Of course you won't have a value every clock. But you could fake it by adding the incoming scope filter value to the integrator value.

But really, Sinc3 is the right way to do it. It's just expensive to get a sample every clock. If we could tolerate having a FIFO hundreds of bits long, the integrating filter should be able to do it.
• Posts: 374
cgracey wrote: »
Saucy, can you please describe the three terms in your cmafilter(x,y,z)?

The numbers are the lengths of the moving averages. I prefer describing the filters that way because it describes how to construct the filters.
```octave:121> ones(8,1)'
ans =

1   1   1   1   1   1   1   1

octave:122> conv(ones(8,1),ones(10,1))'
ans =

1   2   3   4   5   6   7   8   8   8   7   6   5   4   3   2   1

octave:123> conv(conv(ones(8,1),ones(10,1)),ones(12,1))'
ans =

1    3    6   10   15   21   28   36   44   52   59   65   69   71   71   69   65   59   52   44   36   28   21   15   10    6    3    1

octave:125> cmafilter(8,10,12)'
ans =

1    3    6   10   15   21   28   36   44   52   59   65   69   71   71   69   65   59   52   44   36   28   21   15   10    6    3    1

octave:128> ones(8,1)'
ans =

1   1   1   1   1   1   1   1

octave:129> conv(ones(8,1),ones(8,1))'
ans =

1   2   3   4   5   6   7   8   7   6   5   4   3   2   1

octave:130> conv(conv(ones(8,1),ones(10,1)),ones(8,1))'
ans =

1    3    6   10   15   21   28   36   43   49   53   55   55   53   49   43   36   28   21   15   10    6    3    1

octave:131> cmafilter(8,8,8)'
ans =

1    3    6   10   15   21   28   36   42   46   48   48   46   42   36   28   21   15   10    6    3    1

```
• Posts: 13,631
cgracey wrote: »
Thanks for bearing through all this, Guys.

After a lot of experimenting and testing, I'm giving up on the live 16-bit and 12-bit sampling. If >8 bit sampling is wanted, the Sinc3 filter does a vastly superior job of filtering, with the caveat that you only get a sample every Nth clock, instead of on every clock.

I've found that to get the best A/D conversion, the pins involving the same Vxxxx supply pin should all be A/D inputs, in order to minimize noise. In a lot of experiments, I was using one pin for ADC and its neighbor pin for DAC. The DAC can variably draw several mA, which causes an IR drop on the bond wires and chip routing metal, which causes distortion in an ADC sharing those power signals. The interplay between ADC and DAC activity on same-power-supply pins had me thinking a few times that we had some strange problems, when we didn't.

In order to get around this shared-supply problem during development on the FPGA, with the two-I/O-pin test ASIC, I've resorted to recording ADC readings and then playing them back on a DAC, to avoid cross-talk. On the silicon, you need only use another 4-pin group with separate Vxxxx and GIO (GND) bond wires.

Here is what we can expect on the silicon. These are the bottom 8 bits of a 14-bit conversion of the apex of a sine wave. These samples were acquired in 256 clocks using the Sinc3 filter, and then decimated. Imagine that there are 64 more scope screens stacked vertically, in order to show the full scale. I think this is pretty good resolution:
Wow, that looks good!

For the high resolution, what about an integrate and dump scheme? There could be 2 integrators so that one can be read while the other is accumulating. Or just a buffer that captures the value before dumping. Of course you won't have a value every clock. But you could fake it by adding the incoming scope filter value to the integrator value.

But really, Sinc3 is the right way to do it. It's just expensive to get a sample every clock. If we could tolerate having a FIFO hundreds of bits long, the integrating filter should be able to do it.

I think if you wanted 4x overlapped 256-clock samples, you could set the Sinc3 counter reload to 64 and get acc3 readings every 64 clocks. You would maintain a FIFO buffer of the last four readings and sum them up to get a 256-count delta from which you'd compute your sample.