Forum Discussion
BPSK Demodulation
Hello again, I am still struggling with BPSK demodulation :)
OK, now I am trying to implement Costas Loop for carrier synchronization, which involves Inphase and Quadrature Phase paths. Inphase is looking good, and works as expected, however, the Q component looks awkward. Take a look at these waveforms: http://www.alteraforum.com/forum/attachment.php?attachmentid=10363&stc=1 I understand that multiplying sin * cos will produce a high frequency component, which is a sin modulated by half amplitude of the data signal. BPSK(t) * sin(2*pi*f*t) = 0.5 * [DATA(t) * sin(0) + DATA(t) * sin(2*pi*f*t)] => 0.5 * DATA(t) * sin(2*pi*f*t) => LPF{0.5 * DATA(t) * sin(2*pi*f*t)} = 0 I feel that problem is in my LPF. I used the same Matched RRC filter that I used in the in-phase arm. Papers I read didn't mention that these two filters should be different, that's why I used the same filter. (I think those are unpractical DSP writers, KAZ :D ) So, should I use a separate Loop Filter for Q component? How do I determine it's parameters?66 Replies
- Altera_Forum
Honored Contributor
That equation (I am not aware of) could be helpful. What I am suggesting is keep your controls as variables and change then till you get a lock and then keep them
If you want to follow the diagram you posted that is ok. C1 corresponds to scale factor on input and so keep it variable and start with the above equation value. C2 is a scale factor on input to integrator and there is no scale factor on feedback term. You can try that and keep C2 also variable. My IIR suggests a further scale factor on feedback term equal to (1-alpha) producing a typical IIR with unity dc gain. Your case does not care about filter dc gain and it may well work or get out of control. I suggest you add scale factor on feedback term and set to 1 if it turned out to be irrelevant. Thus the IIR cutoff is under control of these variables and these variables will eventually be fixed in design by trial and error. I don't know what is PI (proportional Integrator?).Yes we are talking about same thing but I am conceptually splitting the single system into two. - Altera_Forum
Honored Contributor
Very well...
Let's take your suggestion for now. I am trying to implement it in MATLAB, what I'm doing is evaluating the transfer function and I got this: H(z) = alpha/[1+(alpha-1)*z^-1] Is it correct? Then I chose a value for alpha = 0.1 finally I am filtering using this commad: b = [0.1]; a = [1 -0.9]; err = filter(b,a,error_sig); where error_sig is the output of the error detector. Please confirm my work if it's correct. - Altera_Forum
Honored Contributor
The first part should be:
H(z) = alpha/(1 – (1 - alpha).z-1) There is also + convention for denum term but is confusing Your entry is correct: b = alpha; a = [1, -(1-alpha)]; check it is LPF: freqz(b,a); - Altera_Forum
Honored Contributor
How can I model the feedback to NCO? I am using the generated MATLAB model of Altera NCO.
If you have another way to model it please tell me. I am sorry for all these questions, I hope that you bear with me. Thanks Mr Kazem. - Altera_Forum
Honored Contributor
You will need an indexed feedback loop that acts on one sample at a time fully modelling from input to output. The filtered error together with any proportional element have to be taken care of.
I have attached some old work. This was my initial attempt for qpsk/16QAM (I have lost everything else afterwards). It may not be that correct but should give some idea. It starts with modelling TX side to generate a signal (you may not need that) but focus on the loop. At this point you can try Modelsim before Matlab as it easier there. If you get in difficulty then you better model it in matlab. - Altera_Forum
Honored Contributor
looking back at my file it seems I have not completed the loop. (or left it open for some reason).
You will need the final value of carrier to loop back and reapply to input (update input). Thus the second sample when i = 2 will come from new updated vector coming from mixing carrier with signal and so on. Thus I update whole vector each time. This may not very efficient as you can update one sample at a time as well. - Altera_Forum
Honored Contributor
You mean embed the whole receive part in for loop, and each time I update the carrier vector and mix again?
Can I just calculate the value of carrier sample each time and mix it with input? I mean work on samples rather than vectors. One more question please, why did you use error accumulator in the end and not just using filtered_error? - Altera_Forum
Honored Contributor
OK this is my MATLAB code, it's taking tooooooooooo much time to execute. I actually halt it!
LPF.mat contains LPF coeffs. rf_signal is produced in another m file and is found in workspace. NCO_model is the generated MegaCore MATLAB model. It produces one sin & cos sample for one input phase sample.load LPF.mat N = length(rf_signal); phi_inc = zeros(1, N); bb_sig_I = zeros(1, N); bb_sig_Q = zeros(1, N); I_f = zeros(1, N); Q_f = zeros(1, N); error_sig = zeros(1, N); err = zeros(1, N); % NCO fs = 1.0E8; f = 5.0E6; phi_inc(1) = ((2^32)*f/fs); for i = 1:N = NCO_model(phi_inc(i)); % Downconverting to Baseband bb_sig_I(i) = rf_signal(i)*cos_out; bb_sig_Q(i) = rf_signal(i)*sin_out; % Filtering I_f(i) = filter(LPF, bb_sig_I(i)); I_f(i) = filter(LPF, I_f(i)); Q_f(i) = filter(LPF, bb_sig_Q(i)); Q_f(i) = filter(LPF, Q_f(i)); % Error error_sig(i) = I_f(i).*Q_f(i); % Loop Filter (Leaky Integrator) alpha = 0.1; err(i) = filter(alpha, , error_sig(i)); phi_inc(i+1) = phi_inc(i) + err(i); end - Altera_Forum
Honored Contributor
Looks ok to me except the filtering functions both rrc filters and loop filter need some change(Don't follow my wrong example, it was just for a start).
Matlab filter functions are based on convolution with previous samples (assumes zeros initially and towards the tail) This means using filter function samplewise will get wrong (as it sees [zeros value zeros]. How to filter per sample inside the loop? basically I ended up with some trick that I don't remember now. It was based on giving the filter all previous values in the loop to compute a new sample and update this initial string each time. something like this: y_f = filter(h,1,x(1:i)); I will try see my records this weekend while you try your efforts. Your nco is right but may need reversal of error sense and that will show up as you ran your code. loops are very slow in matlab so use shortest useful length. - Altera_Forum
Honored Contributor
You are right... I am getting wrong results! But I noticed that error is showing up at the mixer stage! In-phase component is not as it is without "for" loop.
I will try my efforts, thanks!