Forum Discussion
Unwanted frequency shift in DA-converted signal
Hi,
i use Matlab/Simulink and DSP Builder for my project. In Matlab, I generate a digital source signal and program it in a LUT-Block in Simulink. This Block then sends the data to my DACs. The source signal is an overlayed signal of 10, 20 and 30 MHz. When I now check the analog signal with a spectrum analyser I can see a shift in my frequencies. The 10 MHz signal is actually at 9,99564 MHz, 20 MHz actually at 20,00656 and the 30 MHz signal at 30,00220 MHz. It is very important to reach the frequencies precisely. An ~100 Hz offset would be ok, but more than 2 KHz is too much. Why is there this frequency shift. How to avoid it? I use a 125 MHz crystal and a PLL the generate a 125 MHz clock inside the Cyclone II EP2C70. All internal and external components use the same clock. The crystal should not be the cause of this, as the frequency shift is not linear (different shift at different frequencies). Any hints on that? Thank you for your time! Leo12 Replies
- Altera_Forum
Honored Contributor
How did you generate the LUT? are you aware of wrap-up continuity? I mean for one cycle sinusoid your first sample should not repeat at the end of LUT as you will wrap up to start.
- Altera_Forum
Honored Contributor
That also came to my mind. It's just not possible to have continuous signals for all frequencies. But I hope the reason for the shift is something else.
There is no check that the phase of the signal at the end is correct (concerning to the next step, the start). There definitly is a not continous state when the LUT switches from end to start again - at least for some of the frequencies. - Altera_Forum
Honored Contributor
Phase must be continuous and can be done as follows (DDS structure):
LUT to contain one full cycle: data=round(32767*sin(2*pi*(0:255)/256)); --for 256 points, 16 bits signed or data = round(32767*exp(j*2*pi*(0:255)/256))); --for sin/cos then you address the LUT with 8 MSB of large n bit accumulator then the increment value decides the frequency: incr = 2^n *f/125,000,000 As such you keep phase continuity even when you change frequencies. - Altera_Forum
Honored Contributor
Thats not exactly what I need. I need a signal which is overlayed of different other signals. As in the example in the first post. My source signal consists of 3 different signals which are overlayed.
With your solution it's only possible to have one frequency at a time. I still guess that this incontinuity is not the problem of my phase shift. But I just dont know for sure. Mixed products at higher or multiple frequencies could be a consequence but a shift? - Altera_Forum
Honored Contributor
It might not be the issue of continuity, it is just a matter of exclusion.
You may try generate the three frequencies then add them up in hardware rather than pre-added in LUT. I agree phase discontinuity will show as spikes rather than offset. The offset may be explained on basis of clock, heating, timing or bug. - Altera_Forum
Honored Contributor
You didn't tell yet the involved DDS phase accumulator resolution. Insufficient accumulator bitwidth or coefficient calculation error would be the only plausible explanation in my opinion, assuming your analyzer has suffcient accuracy. Dependent on the specification, a crystal oscillator must be expected to have up to 100 ppm frequency error which adds to the DDS error.
You would want to check the clock frequency error separately. - Altera_Forum
Honored Contributor
Thank you for your replies.
I wasn't aware of a method DDS. The problem is that my project is a little bit more complex. I need the same signal on two analog channels going through a resonator circuit. The will be a different delay on these two lines so I have to sync the signals afterwards in the FPGA. So I need to send a sync signal at the beginning. A part of my code for the signal generation:
The frequency_vector contains the frequencies, e.g. 10, 20 and 30 Mhz. This digital signal is stored in a LUT on FPGA. My LUT is 8192 values long and addressed via a counter. During measurement the data is AD-converted and stored in RAM. Then I calculate the synced signal via the sync peak (see code) to avoid phase difference on the channels. Then this data is further processed. The frequency shift also occurs without the sync peak at the beginning. The Signal/Spectrum Analysers have a resolution in the lower Hz-range. There is no limitation here. I might try a simple DDS design now but it would be awesome to continue to use my LUT method as it is very adaptive and simple to handle. Thanks again!F_sample = 125e+6; %Which is also my FPGA clock (125 MHz) samples = 8192; %Generate Source Signals steps = 0:(samples-1); for index = 1:number_of_resonators Omega = 2*pi*frequency_vector(index)/F_sample; s(index,:) = amplitude_per_resonator*sin(Omega*steps); signal_source = signal_source + s(index,:); end %Add Sync Peaks: signal_source(1,11:(length(s(1,:))+10)) = signal_source(1,:); signal_source(1,1:5) = (samples-1); signal_source(1,6:10) = 0; - Altera_Forum
Honored Contributor
Consider a simpler test. use 10,20,40MHz then you can have a continuous clean vector in pre-added in LUT. This avoids the headache of three DDS plus adder in hardware
- Altera_Forum
Honored Contributor
I should have said:
12.5MHz, 25MHz, 50MHz - Altera_Forum
Honored Contributor
To demonstrate:
a1=sin(2*pi*(0:8189)*12.5/125); a2=sin(2*pi*(0:8189)*2*12.5/125); a3=sin(2*pi*(0:8189)*4*12.5/125); a=a1+a2+a3; %scale for LUT your LUT should run from 0 to 8189 only