Hello
In the last month I've been working on a custom digital interpolation FIR filter implemented on an FPGA. This filter does pretty much the same thing as well known DF1706, SM5847, PMD100, and so on. However, its ability to reconstruct and attenuate a signal is way beyond those
🙂
The filter contains 8192 coefficients and it interpolates the data by a factor of 16 times (e.g. 44.1 kHz to 705.6 kHz and 48 kHz to 768 kHz). It has several FIFOs built in since its core is running asynchrounsly (at 225 MHz) while the MCLK is used only to clock data out of FIFO and to create LE (latch enable) signal for the DAC.
In fact, this filter does always interpolate to 705.6 kHz and 768 kHz (an integer factor of the input) and accepts data up to 768 kHz / 32 bits. In order to do that it works like a sample rate converter, so it interpolates and decimates at the same time. However, it should be noted that for 44.1 kHz and 48 kHz it does not decimate at all, but for anything higher than 44.1 kHz and 48 kHz it still interpolates data 16 times, so e.g. having 96 kHz input means that the data is interpolated up to 1536 kHz, but decimated back to 768 kHz. The same goes to 768 kHz input which is interpolated to 12.288 MHz (in a mathematical sense of course) and decimated back to 768 kHz.
It should be noted that along with huge amount of coefficients (8192) this filter incorporates multiply-accumulate units of 32x35 bits wide. It means that the input data word is fully accepted up to 32 bits (without any truncation for that matter) and coefficients are quantized on 35 bits resulting in unmatchable accuracy of the math it does to calculate the output sample
😉
In the title of this thread I did mention you can drive PCM56, PCM58, PCM63, AD1862, AD1865 and so on up to 768 kHz. How is that possible? The filter contains a self reconfiguratable oscillator which sets its frequency depending on the output length (16, 18, 20 or 24 bits). It means that the output bit clock (CLK) is running fully asynchronously from the LE (latch enable) signal which is generated by dividing the provided MCLK signal, so data is latched in almost all DACs without any extra jitter introduced by the oscillator itself. In fact, the filter contains 3 sets of FIFOs (6 FIFOs for both channels) - one in its input (I2S) before going to the core, another one on the core output and the last one for the final oscillator to clock data into the DAC. Besides all of that this technique introduces a quiet zone after the latch signal going down, so it should give DAC some time to settle down with its output before clocking in another sample
😉
Depending on the word length the following frequencies are created on the CLK output:
16 bits - 14 MHz
18 bits - 15.5 MHz
20 bits - 17 MHz
24 bits - 20 MHz
It means that certain DACs such as PCM56 and AD1865 will be running at the edge with 768 kHz stream, but they will work just fine according to my tests. The LE (latch enable) signal is always 705.6 kHz or 768 kHz depending on the input (either multiply of 44.1 kHz or 48 kHz).
0 dBFS @ 20 kHz:
-60 dBFS @ 1 kHz:
Jitter test @ 48 kHz with LSB toggled @ 250 Hz:
Filter attenuation (linear phase) - white noise @ 48 kHz:
All measurements were performed using PCM58.
The filter has I2S input with signals of MCLK, BCLK, LRCK and DATA. However, MCLK can be fed by the same source as BCLK signal (if no MCLK is available) assuming that BCLK has a rate of 32x, 64x, 96x, 128x Fs or similar since the filter has to determine its frequency to know how to divide it in order to create LE (latch enable) signal. Any exotic values of BCLK rate will not work as MCLK, so keep that in mind. The jitter and synchronization of FIFOs depends purely on the MCLK signal, so in the long term it needs to be synchronous with LRCK (in almost all cases it is, since BCLK and LRCK should be derived from a divided MCLK clock).
Following frequencies are supported as MCLK:
49.152 MHz
45.1584 MHz
36.864 MHz *
33.8688 MHz *
24.576 MHz
22.5792 MHz
18.432 MHz *
16.9344 MHz *
12.288 MHz
11.2896 MHz
9.2160 MHz *
8.4672 MHz *
6.144 MHz
5.6448 MHz
4.608 MHz *
4.2336 MHz *
3.072 MHz
2.8224 MHz
1.536 MHz
1.4112 MHz
Those with asterisk are usually used in CD-Players and it should be possible to use the filter within a CD-Player once input is attenuated using 170 Ohm or so resistor per line (in order not to damage the FPGA and its I/O pins due to 5V logic levels). The filter can be powered by an external supply (5V or higher) or by providing a direct 3.3V power supply (it is up the user).
Following outputs are provided by the filter:
CLK - clock for data
LE - latch enable signal
SD_L - serial data for the left channel (and its inversion with the line above it, so you can create a differential DAC for XLR outputs)
SD_R - serial data for the right channel (and its inversion with the line above it, so you can create a differential DAC for XLR outputs)
3.3V - main power supply
GND - ground
It should be noted that the filter does have a TDPF (triangular probability density function) dithering algorithm as well. It can be turned on or off by a jumper depending on your preferences.
The price for a fully assembled and ready to use board will be 250 EUR.
Final revision of 16x interpolation version:
ROM jumper selects which type of filter should be loaded during boot process. There are two filters available, one is linear phase and the other one is a minimum phase
🙂 Both of them have 8192 taps.
The filter can be directly powered by an external USB to I2S converter, but it draws about 300 mA of extra current, so keep that in mind. Also, it is a 4-layer PCB. Dimensions are 50 mm x 47 mm.
For more information and orders please visit:
Digital Interpolation Filter (FIR) - KuSy Audio
I am rarely available on forums nowadays, so a friend of mine will take care of your questions.