- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am trying to implement a hardware system which uses current to compute distances. The incoming current is obtained from a sensor, and will be sampled and input into my FPGA. The ADC is 14bit, 250MSPS. A lock-in amplifier will be designed within the FPGA to extract the noise from a large amount of noise. Now my problem is: My current signal is 154KHz. When I tried to build a PLL module using the ALT_PLL megafunction, the lowest required input frequency is 10MHz... Now I am thinking of using two PLL modules, one to divide the 10MHz into 154Khz, if that is possible, the other to create its reference signal. Am I doing the right way? Is there a better way? Also, I guess I need to build a buffer before ADC. but I dont know what type of buffer / where to get information about that. Could anyone help me? Thanks!Link Copied
- « Previous
-
- 1
- 2
- Next »
27 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Why is it too fast? You need to keep in mind that the input bandwidth to the ADC needs to be consistent with its sample rate. So if your ADC is designed to operate at 40MHz and it has an input filter with 20MHz of bandwidth, regardless of what clock rate you operate it at, it will be letting in 20MHz worth of noise. To eliminate that noise, you can either change the filter and the sample rate, or you can sample at 40MHz and then use digital decimation filters. --- Quote End --- well...in lock-in amplifier, after demodulation. I need to build a LPF to keep the DC component and the cutoff frequency is 1khz (so I will keep 154+-1khz signal). in this case, isn't 40msps too high as a sampling frequency? the filter will have extremely high order. and that will make the system very slow. that was my consideration... --- Quote Start --- It depends. If you never know what is being filtered, then you have to design for worst-case input signals. If you control the type of input signal and know what it should be (and monitor it in the hardware), then you can optimize for just the signals you expect. That is part of the modeling task :) For example, will the sensors have amplifiers, so that the ADC input range is always driven over its full amplitude range, or will there be some minimum and maximum amplitude over which it operates? Systems with ADCs that have fewer bits will often be driven by automatic-gain control (AGC) amplifiers that keep the amplitude at the input to the ADC constant. --- Quote End --- hmm... I guess I didn't make myself clear enough or I am not following... for example, the input of the filter is 32bit, the coefficients are 16bit, the order is 32, then the output will be 32+16+log2(32)=53, full precision. but if my output is 32bit, i need to cut 16LSB, and [2:6] MSBs, is that correct? Thanks!! Allison
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Dave, I read the .m file and ran it step by step... realize again how many things I don't know yet...=(. especially the analysis of noise.
here are something I dont understand or am not sure about: 1. why is NCO signal and filter datapath 2-bit longer than ADC input? was it randomly assigned? 2. The incoherent mean is the power of the window, right? it is a normalization factor in computing spectrum. 3. why should I use multirate processing? i mean, the decimation. I had this question when I saw your diagram of the lock-in amplifier. is it necessary to downsample? so I should build a CIC filter instead of a FIR? 4. why need h(max) as an extra normalization factor? 5. Ns=Na*Nt+Nh, why? why do we need the extra samples from the window? 6. in the quantization of NCO signals, instead of 2^(B_noc-1), you used 2^(B_nco)-1, is it supposed to prevent overflowing? but it is only for NCO signals... 7.The way you quantized z_q(z_q = filter(h_q,1,y_q), then times 2^(B_out-1), round the number, divided by 2^(B_out-1)). in the hardware case, we just cut off LSB and MSB to keep the signed bit and B_out-1 bits, right? 8. The quantization noise floor I have always been confused, never understood it in the slides... can you explain to me more clearly? 9. in the figure(1) plot(fn,10*log10(Rxx+10^(-10))); why adding 10^(-10)? what we are interested is the amplitude of z_q right? I guess tat's all my questions for now.... I really really appreciate your kindly and patient help. That makes my learning of FPGA and my project much easier....:-P Allison- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- 1. why is NCO signal and filter datapath 2-bit longer than ADC input? was it randomly assigned? --- Quote End --- You have the code, change it and see what happens :) NCOs have spurious harmonics. If you look at the example figures in the slides I sent a link to, you will see how the harmonics create spurious images in the demodulated response. By adding a couple more bits, you push the level of the images below the quantization noise floor of the demodulated output. This is why you requantize the demodulated signal; the full bit-width product is corrupted by harmonic content, so there is no point in keeping it, and wasting logic processing the extra bits. --- Quote Start --- 2. The incoherent mean is the power of the window, right? it is a normalization factor in computing spectrum. --- Quote End --- When you window a coherent signal like a sinewave, you attenuate the signal at the ends, and its power is lowered by the coherent signal gain. When you window a noise-like signal, you attenuate the RMS (the standard deviation) of the signal at the ends, and its power is lowered by the incoherent signal gain. The paper on using windows with the DFT by Harris (1978) has more details. --- Quote Start --- 3. why should I use multirate processing? i mean, the decimation. I had this question when I saw your diagram of the lock-in amplifier. is it necessary to downsample? so I should build a CIC filter instead of a FIR? --- Quote End --- When you have a sample rate that is orders-of-magnitude higher than the signal bandwidth of interest, then you are 'wasting' processing resources by processing every sample. A more efficient solution is to cascade a series of digital filters that first eliminate noise and then resample to a 'new' sample rate. Eventually the decimated signal is 'sampled' at a rate consistent with the bandwidth of the signal. The best solution is design dependent, but in your case, a CIC filter followed by a FIR or half-band FIR, would probably work nicely. --- Quote Start --- 4. why need h(max) as an extra normalization factor? --- Quote End --- An ideal low pass filter is a rect function in the frequency domain, eg. rect(f/B ), which has an inverse Fourier transform B*sinc(B*t), where f is in normalized frequency units (-0.5 to 0.5) and hence B < 1. The filter coefficients are essentially B*sinc(B*t), so the maximum coefficient is about the size B. If you scale your coefficients into fractional integer format, then since B < 1, you never use the MSBs of your coefficients. To minimize quantization errors in the filter coefficients, you 'normalize' the coefficients by 1/B > 1. This acts like gain in your signal path, so you need to account for it. --- Quote Start --- 5. Ns=Na*Nt+Nh, why? why do we need the extra samples from the window? --- Quote End --- Plot the data from the filtered signal that includes the Nh samples. You'll see that the filtered response looks 'funky' (FIR filter technical term). The first samples out of the filter were calculated while the filter was not completely full. Its easier just to discard those output samples, so they don't produce artifacts in the spectrum. --- Quote Start --- 6. in the quantization of NCO signals, instead of 2^(B_noc-1), you used 2^(B_nco)-1, is it supposed to prevent overflowing? but it is only for NCO signals... --- Quote End --- Read the code again. The amplitude was set to 2^(B_nco-1)-1, because the sinusoid can only take on values -2^(B_nco-1) to +2^(B_nco-1)-1, so you cannot use 2^(B_nco-1), as the sinusoid positive peak cannot be represented. --- Quote Start --- 7.The way you quantized z_q(z_q = filter(h_q,1,y_q), then times 2^(B_out-1), round the number, divided by 2^(B_out-1)). in the hardware case, we just cut off LSB and MSB to keep the signed bit and B_out-1 bits, right? --- Quote End --- No. You need to 'convergent' round. Look at the slides and paper I sent links to. --- Quote Start --- 8. The quantization noise floor I have always been confused, never understood it in the slides... can you explain to me more clearly? --- Quote End --- When you take a continuous signal x(t) and quantize it to y(t), you can consider y(t) to have been 'created' by adding noise to it, eg. y(t) = x(t) + q(t), where q(t) = y(t) - x(t). If you go and perform this calculation for say Gaussian noise in MATLAB, eg., x(t) = 0.25*randn(1,Nt)*2^(B-1), and then create the quantized version via y(t) = round(x(t)) and set any codes outside the range -2^(B-1) to 2^(B-1)-1 to their respective limits. Now plot q(t). You will see that the error is between -0.5 and +0.5. If you plot a histogram, hist(q), you will see that the noise is fairly uniform. The Fourier transform of a uniform noise signal is N*sigma^2, where sigma is the variance of the noise, i.e., 1/sqrt(12). When you calculate the spectrum of a quantized signal, this 'noise' determines the noise floor. When you normalize the signal to fractional integer format, the noise RMS is 1/sqrt(12)*1/2^(B-1). When you calculate the power level of this noise, its 10*log10( 1/12 * 1/2^(2*B-2) ) = 10*log10( 1/3 * 1/2^(2*B ) ) = -4.77dB - 6.02*B. The highest level sinusoid you can represent in fractional integer format has an amplitude of 1.0, which is an RMS of -3dB, so the signal to noise of a quantized sinusoid is -3dB - (-4.77dB - 6.02*B ) = 6.02*B + 1.76dB, and viola, you have the 'rule of thumb' you'll see in many references (but usually without explanation). In the figures my m-file produces, the expected 'noise floor' is drawn at -(6.02*B + 4.77dB ). The peak of an input sinusoid with -3dB power (an amplitude of ~1.0) actually lies above the -3dB point on the power spectrum plot due to the coherent gain of the FFT; if you increase the number of samples used per FFT, the peak will go up. This coherent gain is due to the fact that the power spectrum is normalized so that the power level of incoherent noise signals is fixed relative to the y-axis, i.e., given Nt-samples of noise with standard deviation sigma in the time domain, we expect a variance Nt*sigma^2 in the frequency domain, and hence normalize by Nt, so that we can plot the expected power at 10*log10(sigma^2). The expected peak of a sinusoid is (Nt/2), which in power is (Nt/2)^2, which once normalized by Nt is (Nt/4), and 10*log10(Nt/4) = 10*log10(Nt/2) - 3dB, where the -3dB is the sinusoid power, and the 10*log10(Nt/2) is the coherent gain of the FFT. --- Quote Start --- 9. in the figure(1) plot(fn,10*log10(Rxx+10^(-10))); why adding 10^(-10)? --- Quote End --- log10() does not like to see zeros. Adding a small value sets the noise floor at -100dB. Cheers, Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Dave,
I have finished my MATLAB model of the lock-in amplifier and tested on the training data. It works greatly. Thank you very much for your kindly help!! Now I am facing the challenge of implementing the amplifier in FPGA (which I assume is much harder than the previous work...). Since the lock-in amp consists of PLL, NCO, mixer and filter. I used the megacore function to generate each part. The design of filter is a little bit confusing. I need to design a CIC filter followed by a compensation FIL filter. In my case, the sampling frequency is 4Mhz, the frequency of interest is 154khz, the passband width is 1khz. So I probably need a bigger downsamping factor, I set it to 128. The CIC parameters: input signal datapath 16bit, R=128, N=9, M=1, full precision data length is 16+N*log2(R*M)=16+9*7=79bit. Since I want 16bit output, the megafunction uses Hogenauer pruning technique to reduce the data widths. The FIR design: Megafuncton would generate a matlab file that can generate a compensation filter. The coefficients would be loaded into QuartusII and generate the FIR filter. Am I on the right track? Allison- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I have finished my MATLAB model of the lock-in amplifier and tested on the training data. It works greatly. Thank you very much for your kindly help!! --- Quote End --- That is great! --- Quote Start --- Now I am facing the challenge of implementing the amplifier in FPGA (which I assume is much harder than the previous work...). Since the lock-in amp consists of PLL, NCO, mixer and filter. I used the megacore function to generate each part. The design of filter is a little bit confusing. I need to design a CIC filter followed by a compensation FIL filter. In my case, the sampling frequency is 4Mhz, the frequency of interest is 154khz, the passband width is 1khz. So I probably need a bigger downsamping factor, I set it to 128. The CIC parameters: input signal datapath 16bit, R=128, N=9, M=1, full precision data length is 16+N*log2(R*M)=16+9*7=79bit. Since I want 16bit output, the megafunction uses Hogenauer pruning technique to reduce the data widths. The FIR design: Megafuncton would generate a matlab file that can generate a compensation filter. The coefficients would be loaded into QuartusII and generate the FIR filter. Am I on the right track? --- Quote End --- Yes, you are on the right track. Before getting too involved in the Quartus solution, go back to MATLAB and look at their CIC and compensating FIR designs. I think they have a downconverter example that shows how to use it, or perhaps it was the book by Losada (available on the MATLAB site). Gain an understanding of how the CIC filter works first, and then what the compensating FIR filter is being used for. Only once you understand that, should you begin the implementation in Quartus. Cheers, Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- That is great! Before getting too involved in the Quartus solution, go back to MATLAB and look at their CIC and compensating FIR designs. I think they have a downconverter example that shows how to use it, or perhaps it was the book by Losada (available on the MATLAB site). Gain an understanding of how the CIC filter works first, and then what the compensating FIR filter is being used for. Only once you understand that, should you begin the implementation in Quartus. Cheers, Dave --- Quote End --- Hi Dave, I read through the CIC documentation and designed a CIC filter (R=4, M=1, N=9) in MATLAB as well as in QuartusII. In QuatursII, the megafunction of CIC filter generated a matlab file which output the compensating FIR filter coefficients in a .txt file and plot the response of CIC, compensating FIR and the total response. Now, I try to simulate the cascade filter (CIC followed by a FIR filter) object in matlab. The FIR filter is designed by using the output coefficients. but the frequency response of the cascaded filter block is nothing like what I expected. It's also different from the total response plotted by the matlab file. Rather, the FIR filter works nicely as a LPF filter... It really confuses me. Allison %%%%%MATLAB simulation%%%%%% Fs = 50e3; %%%sampling frequency is 50khz %%%CIC filter r = 4; %%%decimation m = 1; n = 9; %%%stage iwl=B_out; %%%input bit width owl=B_out; hm_cic=mfilt.cicdecim(r,m,n,iwl,owl); %%%multi-rate filter design fvtool(hm_cic); %%% filter visual tool %%%%FIR filter L=64; Fc=100; %%%cutoff frequency is 100hz myFIR_fir_comp_coeff(L, fs, Fc, true, true, 16); %%% matlab file generated by Quartus, which will output the compensating coeffcients into a .txt file and plot responses load myFIR_fir_comp_coeff.txt hm_fir = mfilt.firdecim(1,myFIR_fir_comp_coeff); %%%direct-form fir filter fvtool(hm_fir); %%%%cascading the two filters together hm = mfilt.cascade(hm_cic,hm_fir); fvtool(hm);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Allison,
Please see the attached m-file for an example of how you would decimate an input signal sampled at 4MHz to 8-bits, to 4kHz at 10-bits. The decimation sequence consists of a CIC filter that decimates the signal by 250, and then a Nyquist filter that decimates by 4 (this could also be implemented as a cascade of two half-band filters). The passband droop due to the CIC filter is not very large. Since you only want to detect the DC value (the demodulated sinusoid amplitude), I don't think you need to use a compensation FIR. You do want a combination of CIC plus FIR, but the FIR filter(s) are just used for the final decimation stages. Since the final FIR stages are operating at low clock rates, the 'optimal' implementation will depend on how Altera's FIR Compiler II implements time-demultiplexing (folding, or logic reuse). Run a few test designs through FIR Compiler II and see how well they work. NOTE: The final FIR decimation stage filter design is probably sub-optimal, in that the filter has a much faster transition edge than your application probably requires. For example, you could design an FIR filter with a slow transition from DC to the stop-band edge that will require fewer coefficients, and would not affect the DC measurement. However, assuming the FPGA is running at say 40MHz, and processing 16kHz samples, there is an oversampling ratio of 2500, so 'sub-optimal' may in fact be fine, given that the FPGA could use 1 multiplier and 2500 clocks to implement the FIR filter(s). Cheers, Dave
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- « Previous
-
- 1
- 2
- Next »