Forum Discussion
Costas Loop oscillates in ModelSim while locks in MATLAB!
Hello again,
I have designed a Costas Loop in MATLAB and it simulates very well... locking and recovering the carrier. Here are the results: http://www.alteraforum.com/forum/attachment.php?attachmentid=10456&stc=1 I ported the design to FPGA in VHDL, and simulated in ModelSim... however, the loop has a kinda oscillating behaviour... take a look: http://www.alteraforum.com/forum/attachment.php?attachmentid=10457&stc=1 This is the Loop Filter output: http://www.alteraforum.com/forum/attachment.php?attachmentid=10458&stc=1 Why is it oscillating? Is it the loop filter?46 Replies
- Altera_Forum
Honored Contributor
I am doing the sanity test now.
Let me inquire about some points here: --- Quote Start --- I did some experiments on this design in matlab running 1 Msamples and it locks for all cases nicely (symbols at +1 all = single tone, symbols at +1/-1 = single tone with jitter and random data. Though I used complex I/Q RF to avoid extra filter (for speed). So I am convinced it should lock eventually). It does not lock if I changed input to QPSK or 16QAM. The main point I noticed was that I have to update the NCO word once only every say 10 error updates (ignore 9) and revert back to initial nco word. The scaling is essential to match your phase resolution word of nco. You will get a nice oscillation that converges to perfect result or so (I got zero jitter at .01Fs). I did not use proportional term. Remember what aplies to software dsp does not apply to FPGA nco. DSP engineers do not know about fpga and are only orientated to their platform. Our nco has one control over phase and frequency (nco increment value). --- Quote End --- 1) You mean the Matlab design that I sent you? 2) Complex I/Q RF mean you used exp() instead of cos/sin functions and separate filters for channels right? 3) Regarding this point: --- Quote Start --- The main point I noticed was that I have to update the NCO word once only every say 10 error updates (ignore 9) and revert back to initial nco word. The scaling is essential to match your phase resolution word of nco. --- Quote End --- You did that in Matlab or in ModelSim? 4) You are right about proportional term... it seemed useless to me too. - Altera_Forum
Honored Contributor
Here is the chain sanity test result:
TX: https://www.alteraforum.com/forum/attachment.php?attachmentid=10474 RX: https://www.alteraforum.com/forum/attachment.php?attachmentid=10475 I believe the chain passes the test. So, problem is in the loop. Well... to be honest I still doubt in the NCO the problem in my point of view is in the nature of the NCO it self because as we discussed.. we are unable to control phase independently from frequency... but your point about using loop filter every 10 samples stirred some hope in me. So, what's next? - Altera_Forum
Honored Contributor
I did a new matlab model (private) using rtl model of nco (at tx and rx) as well as bit true modelling (except for loop filter which Ikept normalised for now).
Input: variety of symbols (BPSK,QAM) Tx: RRC upsampling by 2 to Rs*2, then mixing with 0.01Fs and directly taking I&Q of mixer as RF (this is just to avoid having high sideband and hence no need for filter) Rx: nco and loop filter. Thus the loop works at Rs*2 rate. I update the nco word once every 5, or 10,50,100 samples reverting back to initial nco word. Hence update rate is Rs*2/5...etc. The loop filter set to 0.0001 for alpha but other values work. I then use RRC decimating by 2 down to Rs after loop (RRC not inside loop). It locks for clean or jittered single tone for all cases (BPSK,QPSK,16QAM) but works only for BPSK random symbols (may be it needs more research to work for all but I understand from literature it shouldn't work for QPSK and other QAMs efficiently unless aided by slicing results) - Altera_Forum
Honored Contributor
1) Did you use multiplier as phase detector?
2) You didn't need RRC inside the loop because you took I/Q directly, right? 3) Do I update the nco word as you did? once every 10 samples? How do you revert back to initial word? I mean do you update nco word with error sample for one clock cycle only? - Altera_Forum
Honored Contributor
Yes I used same error as yours (real * imag)
Any filter for high sideband will do as long as it does the job but I kept loop at Rs*2 rate (not at symbol rate). Updating nco word conditionaly is like this: use sample counter e.g. 0~9 (not clock counter) if counter = 9 update with error else assign initial value (do not latch error update as it will lose frequency lock) - Altera_Forum
Honored Contributor
1) Did you keep loop at Rs*2 because this is the rate of the input signal to loop filter (sample rate)?
2) Updating with error is done by summing the error to the initial value or just feeding error to NCO? - Altera_Forum
Honored Contributor
--- Quote Start --- 1) Did you keep loop at Rs*2 because this is the rate of the input signal to loop filter (sample rate)? 2) Updating with error is done by summing the error to the initial value or just feeding error to NCO? --- Quote End --- I kept loop at sample rate of Rs*2 based on my past experience. Higher rate should be better in theory, loop @ symbol rate is something I haven't tried and not sure if it works as high sideband filter(branch filter) may get in trouble. updating means summing up fraction of error to nco word. Remember how rtl nco works: its accumulator starts from some value (zero or so) then increments by nco tuning word. The update will add to accumulator value pushing its phase (nudging it) then you revert back to nco tuning word, this means you keep track of frequency lock after each update having now a different accum value but same inc step. eventually we hope the error becomes zero and keeps accum happy. If you lose frequency lock then phase goes wild and out of control. I think software dsp don't have this problem as they control freq separately. - Altera_Forum
Honored Contributor
We hope error becomes zero... what about loop filter's output? do we hope it goes back to zero too?
If we do, this is impossible because inside the loop filter there is register that is summed with the incoming error, once error is zero it accumulates with its self. If we don't, then NCO word will be updated with the steady value of LF's output (if we suppose it settles... but it actually does not). This figure should depict what I mean: http://www.alteraforum.com/forum/attachment.php?attachmentid=10476&stc=1 I believe we should hope for the loop filter's output to be zero or so too. Because as you mentioned we are not like DSP guys and our NCO is different. - Altera_Forum
Honored Contributor
I didn't set loop at sYmbol rate... I actually corrected it to be at sAmple rate... previously it was running at 50 MHz and accumulating every single sample several times.
- Altera_Forum
Honored Contributor
as phase gets corrected then the error tends towards zero and this depends on how you have scaled it so the nudge effect gets less and less. Every nudge should reduce the amplitude of oscillation.
If it overshoots then the sense of error reverses and so on you have a loop error that pushes one way and pulls the other way from time to time (this is acceptable withing limits of specified jitter). In real world the loop keeps track of tx/rx oscillators freq and phase drift. If phase is correct to begin with then error starts as zero and should stay stay zero. I notice that with single tone bu haven't tried more.