MUFF WIGGLER Forum Index
 FAQ & Terms of UseFAQ & Terms Of Use   Wiggler RadioMW Radio   Muff Wiggler TwitterTwitter   Support the site @ PatreonPatreon 
 SearchSearch   RegisterSign up   Log inLog in 
WIGGLING 'LITE' IN GUEST MODE

Looking into iCE40 FPGAs for delay duty
MUFF WIGGLER Forum Index -> Music Tech DIY  
Author Looking into iCE40 FPGAs for delay duty
deuS2eed1rou
I found the 1-bit-delay thread highly intriguing, but - being composed of
discrete logic and DRAM chips - the thing is too huge for my taste. So I
decided to take a closer whether I could put something similar into one of the
$20 iCE40 FPGA eval boards w/ 512kB SRAM by OLIMEX. iCE40 FPGAs do have a
completely open source toolchain, so messing with them is fun compared to
anything Xilinx or Altera, but I digress…

There is a reference design RD1066 by Lattice on how to build an sigma-delta ADC
with FPGAs: To my surprise, one doesn't even need an external comparator because
differential logic input pins _are_ comparators, and the eval board exposes 8 of
them. So, all you need for an ADC are one resistor and a capacitor per ADC.

I threw these at a breadboard and wrote a couple lines Verilog to implement a
sigma-delta ADC and DAC, skipping the digital filters in the paper and not yet
using the SRAM for a delay. I was expecting a messy low-fi affair, but after
playing a bit with the bias and buffering the reference input for the
comparator, I could no longer hear a difference between input and output.

Looking at it with a FFT, it shows about 75dB SNR and some harmonic distortino
when inputting a sine wave from an oscillator. Plotting both input and output
shows the same 75dB SNR and harmonic distortion for the oscillator itself, so
I'm afraid I'm actually measuring the oscillator instead of the breadboard
ADC+DAC confused

As soon as time permits, I will add some Verilog for the SRAM and a digital
filter and report back.


FFT with input as orange and green after ADC+DAC
guest
thats awesome, keep us posted. ill have to check out that dev board, its super cheap for that much memory. what frequency are you clocking the ADC and DAC at?
v8pete
Yeah, very nice work! Must check out that FPGA board too :-)
deuS2eed1rou
guest wrote:
what frequency are you clocking the ADC and DAC at?


For the experiment, I directly used the 100MHz crystal oscillator on the board
to clock the feedback flipflop. The ice40 also has a PLL on board.
Unfortunately, it doesn't seem to be runtime-reconfigurable, so to have CV
control over the sampling clock, I guess an external VCO would be needed (which
can then be multiplied using the onboard PLL) or maybe some additional
fractional division in the FPGA would work in combination with a very high PLL
frequency (datasheet says max 533 MHz).
guest
wow, thats really high, i wonder if the external integrator can respond that fast. it might be interesting to see how the quality degrades at lower frequencies. if it can perform the same down at 10MHz, you can use an external clock from a 4046, which is CV controllable.
deuS2eed1rou
guest wrote:

wow, thats really high, i wonder if the external integrator can respond that fast.


The wima pulse caps seem to do fine at 100MHz, but now that I have the SRAM
working, I hear feedback despite not wiring up feedback. I guess the 100MHz
jumps around on the breadboard due to lack of a ground plane and the flying
wires.

Also, now that the FPGA is more than 5% filled I hear much more noise than with
the simple earlier logic. Could also be that something's wrong with my
decimation code, since the numbers don't add up: I should be getting a 2.68s
delay with the 10 bit decimation and delaying 256k samples, but Ardour says it's
actually 2.2s. It's clearly not doing what I think it should.

Quote:

it might be interesting to see how the quality degrades at lower frequencies.
if it can perform the same down at 10MHz, you can use an external clock from aff 4046, which is CV controllable.


Ja, I could use the PLL on the ice40 for a first experiment with other sampling
rates. I guess a 4046 is the right way when putting it in module form.

Attached is a sample with the dry signal on the left channel and
ADC+decimation+SRAM+DAC on the right as well as my current code.
guest
i couldnt get the mp3 to play for some reason. entirely possible its something broken on my end.

also, why decimate versus just storing the bit stream? does it give better data densities for a given quality?
Synthiq
The mp3 file is actually an ogg file. Just rename the file extension before you play it.
Synthiq
guest wrote:
why decimate versus just storing the bit stream? does it give better data densities for a given quality?

Compressing 1024 single bit samples to a single 10-bit (or 16-bit) value will save a lot of memory. But after reading the RD1066 document from Lattice I'm a little concerned that the resulting effective number of bits is only around 8.5 bits. Most 16-bit and 32-bit microcontrollers have 12-bit ADCs (and sometimes DACs) with 2-3 bits better ENOBs.
peloazul
Just chiming in to say this super exciting! Good luck!
guest
Synthiq wrote:
Compressing 1024 single bit samples to a single 10-bit (or 16-bit) value will save a lot of memory.


this is the part i dont think i fully get, as the amount of memory something takes up is a function both of bit depth, and sample rate. assuredly a 10b number is way less space than 1024 single bits, but how often are each of those being saved? in the case of the 1024 single samples, only 1b is being saved at the clock rate. does this follow standard oversampling theory?

n1 bit samples at F1 sample rate can be summed k times to achieve a new sample rate of F1/k and k^0.5 the SNR (or +0.5*log_2(k) bits). so, for an initial bit depth of 1, data rate is F1 initially, and (1+0.5*log_2(k))*F1/k after k oversamples.

thats a fair bit of data reduction, at 32x oversampling you are compressed to 1/10th the original size. i guess the trick is, youre throwing away the high frequency information that you dont care about. but i see what youre saying about bit depth, an oversample of 256 times gives a nominal 9 bits (according to the above theory). this seems low to me, though, as most codecs do 256x oversampling and might have an internal 4b ADC, and still manage 14 usable bits. maybe the higher order sigma delta converters they use compress more noise into the upper frequency range, so the actual SNR improvement is better after thats been thrown away.

at any rate, i think i just answered my own question, but ill leave this here in case its helpful to someone else.
DMR
I haven't started playing with it yet, but I recently got a TinyFPGA BX board (https://tinyfpga.com/). It's small enough it could likely fit behind a 4HP panel.
Synthiq
guest wrote:
Synthiq wrote:

Compressing 1024 single bit samples to a single 10-bit (or 16-bit) value will save a lot of memory.


this is the part i dont think i fully get, as the amount of memory something takes up is a function both of bit depth, and sample rate. assuredly a 10b number is way less space than 1024 single bits, but how often are each of those being saved? in the case of the 1024 single samples, only 1b is being saved at the clock rate. does this follow standard oversampling theory?

n1 bit samples at F1 sample rate can be summed k times to achieve a new sample rate of F1/k and k^0.5 the SNR (or +0.5*log_2(k) bits). so, for an initial bit depth of 1, data rate is F1 initially, and (1+0.5*log_2(k))*F1/k after k oversamples.

thats a fair bit of data reduction, at 32x oversampling you are compressed to 1/10th the original size. i guess the trick is, youre throwing away the high frequency information that you dont care about. but i see what youre saying about bit depth, an oversample of 256 times gives a nominal 9 bits (according to the above theory). this seems low to me, though, as most codecs do 256x oversampling and might have an internal 4b ADC, and still manage 14 usable bits. maybe the higher order sigma delta converters they use compress more noise into the upper frequency range, so the actual SNR improvement is better after thats been thrown away.


When decimating the sample rate for a first order sigma-delta modulator the bits are simply summed during one period of the final sample rate. In this case 1024 samples are summed to get a 10 bit word at 97.7kHz sample rate.

The SNR increases by 9dB every time the oversampling rate doubles in a first order sigma-delta converter. First we get 3dB less noise in the baseband by spreading the quantization noise out over twice the bandwidth. Then we get another 6dB due to the integrator/lowpass filter in the loop that shapes the quantization noise and shift it to higher frequencies with a slope of 6dB/octave.

I think all commercial audio sigma-delta converters use second or higher order converters to achieve good dynamic range while maintaining a reasonable oversampling ratio. This however makes the decimation filter a lot more complex. For a second order converter, the SNR theoretically increases with 15dB every time the oversampling ratio doubles.
deuS2eed1rou
DMR wrote:
I haven't started playing with it yet, but I recently got a
TinyFPGA BX board (https://tinyfpga.com/). It's small enough it could likely fit
behind a 4HP panel.


These boards seem to lack an SRAM chip though, and I think only the B3 one is
compatible with the free software icestorm toolchain. The only smaller board
with SRAM I found so far is the IceZero board (also open source hardware).
deuS2eed1rou
Small update: I soldered everything on a protoboard with a ground plane: This
improved the noise a bit, but the spurious feedback is still there.

I also ANDed one of the buttons to gate the DAC, and most of the noise as well
as the feedback disappears when gating the DAC off. I suspect the feedback from
DAC to ADC is via the power rails. I might try a TL431 voltage reference and a
4066 analog switch for the ADC in the next iteration…

Sample attached. For a change, I've been using 50MHz sample rate with 9 bits
decimation this time.

And yes I'm afraid Synthiq is absolutely correct that hi-fi is impossible
without throwing more components and more sophisticated digital filters at it.
Currently, there's still room to experiment with a FIR/comb/whatever digital
filter on the ice40:

After placement:
PIOs 31 / 72
PLBs 54 / 160
BRAMs 0 / 16

guest
Synthiq wrote:
The SNR increases by 9dB every time the oversampling rate doubles in a first order sigma-delta converter.


so, for this application of 1024 (2^10) summed samples, wouldnt that be a 10*9dB = 90dB SNR? and ENOB = ~SNR/6 = 15b? whats odd about this to me, is thats way more bits than the 10 you get by summing. is the 9dB per doubling dependent upon an ideal filter; and the moving average filter here, having equal weightings is not ideal? if the taps had fractional weightings you could get greater bit depth.
guest
deuS2eed1rou wrote:
I also ANDed one of the buttons to gate the DAC, and most of the noise as well as the feedback disappears when gating the DAC off. I suspect the feedback from DAC to ADC is via the power rails. I might try a TL431 voltage reference and a 4066 analog switch for the ADC in the next iteration


ive had problems in the past where the feedback was from the DAC to SRAM, and the wrong bits were getting stored due to capacitive coupling of pcb traces (just another idea to check). i wonder if an external switch will help, if the internal comparator is also jumpy due to powersupply fluctuations. maybe some more powersupply decoupling caps could help.
deuS2eed1rou
guest wrote:
ive had problems in the past where the feedback was from the DAC
to SRAM, and the wrong bits were getting stored due to capacitive coupling of
pcb traces (just another idea to check).


Interesting - I discarded the idea that the spurious feedback happens on the
digital side because it doesn't sound very "digital". Also, clocking it slower
should have gotten rid of problems like a too short settling time or the address
counter loosing carry bits or something.

Quote:
i wonder if an external switch will help, if the internal comparator is
also jumpy due to powersupply fluctuations. maybe some more powersupply
decoupling caps could help.


I spent the last two hours soldering on a TL431 and a treasured, speedy
74AHC4066 switch - even without socket to get it closer to ground: There was no
improvement at all regarding the feedback confused


guest
deuS2eed1rou wrote:
I spent the last two hours soldering on a TL431 and a treasured, speedy 74AHC4066 switch - even without socket to get it closer to ground: There was no improvement at all regarding the feedback


sorry to hear that. i find the tl431 to be pretty noisey, though. i usually buffer and filter it with an opamp to get it a bit cleaner. youre right that it doesnt sound like digital glitching. maybe you can implement a differential ADC/DAC within the FPGA to reduce common mode? the DAC portion should be easy enough, you just need an inverted output.
Synthiq
guest wrote:
Synthiq wrote:

The SNR increases by 9dB every time the oversampling rate doubles in a first order sigma-delta converter.


so, for this application of 1024 (2^10) summed samples, wouldnt that be a 10*9dB = 90dB SNR? and ENOB = ~SNR/6 = 15b? whats odd about this to me, is thats way more bits than the 10 you get by summing. is the 9dB per doubling dependent upon an ideal filter; and the moving average filter here, having equal weightings is not ideal? if the taps had fractional weightings you could get greater bit depth.

To answer your question I had to go back to my old books. This is not my area of expertise, but as I understand it, the averaging filter is a sinc filter and the order of the sinc filter should be one higher than the analog modulator so in this case a sinc^2 filter is needed. So you are absolutely right that a simple summation over 1024 samples is not the ideal filter. I think these filters are either a combination of IIR filters and FIR filters or very long FIR filters.
MUFF WIGGLER Forum Index -> Music Tech DIY  
Page 1 of 1
Powered by phpBB © phpBB Group