Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20680 Discussions

BPSK Demodulation

Altera_Forum
Honored Contributor II
4,277 Views

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?
0 Kudos
66 Replies
Altera_Forum
Honored Contributor II
1,508 Views

How did you design the costas loop? How do you control the loop> 

 

loop filter has to be separate filter from rrc. You will use it to control the lock of your costas loop and usually a simple IIR will do 

 

I have used rrc after costas locking section but I know some do it before but not as loop filter (there are different rx configurations and you better model it matlab before going to hardware).
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

I am sorry, it's my mistake... I didn't mention that after multiplication there is CIC filter... before RRC. 

So these are the waveforms: 

 

https://www.alteraforum.com/forum/attachment.php?attachmentid=10365  

 

Basically, I am trying to design this loop: 

 

https://www.alteraforum.com/forum/attachment.php?attachmentid=10366  

 

Instead of LPF, I used CIC filters, as they do filtering and decimation at the same time. Am I wrong? 

You are right, RRC has nothing to do with Costas Loop.
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

You need one filter per branch to remove the f1+f2 (sum term) leaving signal at dc (f1-f2). Any LPF will do (including rrc if you wish). 

The loop itself needs error detector and filter to smooth out the error. This loop filter can be an IIR with variable gain. 

The IIR filter represents the integral part of your loop control system. 

You may need further control terms such as proportional term. 

The filter error is then used to shift phase(or frequency) of NCO in the opposite sense. 

 

It takes sometime for the loop to lock. You observe the error and this should converge and settle with low jitter. 

 

I notice your bb_signal_I has plenty of zeros in it but not Q 

 

I wouldn't advice you to do any decimation inside loop as it could get complicated on you.
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

 

--- Quote Start ---  

You need one filter per branch to remove the f1+f2 (sum term) leaving signal at dc (f1-f2). Any LPF will do (including rrc if you wish). 

The loop itself needs error detector and filter to smooth out the error. This loop filter can be an IIR with variable gain. 

The IIR filter represents the integral part of your loop control system. 

You may need further control terms such as proportional term. 

The filter error is then used to shift phase(or frequency) of NCO in the opposite sense. 

--- Quote End ---  

 

 

The error detector you referred to is the mixer at the end of the loop, right? 

Regarding loop filter, I saw some structures that combine both integral and proportional terms, 

is it the same as you are suggesting? 

 

http://www.alteraforum.com/forum/attachment.php?attachmentid=10367&stc=1  

 

 

--- Quote Start ---  

I notice your bb_signal_I has plenty of zeros in it but not Q 

--- Quote End ---  

 

 

You mean zero crossings? is this bad? 

 

 

--- Quote Start ---  

I wouldn't advice you to do any decimation inside loop as it could get complicated on you. 

--- Quote End ---  

 

 

I thought decimating is beneficial before doing any further signal processing as this relaxes the requirements. 

I'll use regular LPFs then. How to choose the cutoff frequency of these LPFs?
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

The bb_I difference from bb_Q may be due to your nco phase. For now assume it is ok and focus on cutting off the f1+f2 term in each branch. 

The wanted signal will move close to dc and depending on your signal bandwidth. you need to cutoff clear of your signal bandwidth but kill the f1+f2 copy. 

 

So far you have downconverted your signal to dc but now and since signal centre may shift either side of dc due to uncertainties of oscilillators bewteen Tx and Rx you need to force it to dc all the time. The error detector is just a multiplier as you have found out. apply IIR LPF (integrator) to the error as it will be very noisy. The gain of IIR need to be manually adjusted until error shows dampened oscillations heading towards zero with some jitter.  

 

For testing you will need to move your RF centre either side and see that the loop does not lose lock otherwise the radio user will have to keep adjusting the tuning knob and lose interest in music. 

 

If your loop fails to lock try adding the proportional term to the output of IIR through a scaler that can be adjusted.
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

Hi, KAZ. 

 

I modeled it in MATLAB. 

After converting to DC, I am filtering using a FIR filter that utilizes Hamming window. The output of the filters are not clear of f1+f2 though! High component frequency is just attenuated, is this the purpose or I need to completely eliminate it? If I need so, filter required is of order 200+!! I think that's very much resource consuming when it's ported to FPGA, right? 

 

Regarding IIR filter, how do I design it? Do I use fdatool in MATLAB? or the structure I attached above is good?
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

for IIR you may try the leaky integrator: 

 

y(n) = alpha.x(n) + (1-alpha).y(n-1) (requires two mults) or its equivalent of one mult: 

 

y(n) = alpha.[x(n) - y(n-1)] + y(n-1) 

 

alpha will give you you control of cutoff but dc gain will stay unity (alpha = 0~1 normalised) 

 

you can also use power of 2 value for alpha to avoid that single mult if such cutoff resolution is enough. 

 

if required you can also increase/decrease dc gain (apart from cutoff) by scaling input as per your diagram or dividing final output by truncation. 

 

For f1+f2 frequency filtering you need to attenuate it enough e.g. by 40dB. 200 taps x 2 sounds way too much. You don't need to cutoff that sharp since the sum term will be at some distance and assuming you don't have much noise in your signal or that it can be filtered by rrc. I personally believe you better use rrc inside the loop for this purpose.
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

That's great! 

But, would you please explain what "200 taps x 2" mean?
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

 

--- Quote Start ---  

That's great! 

But, would you please explain what "200 taps x 2" mean? 

--- Quote End ---  

 

 

two filters each 200 taps
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

I did the LPFs that attenuate the f1+f2 components, and it filters perfectly (Using 200 taps x 2). 

Now, I am confused with the loop filter (IIR filter). Many texts suggest using the proportional-integral control technique that I attached before. 

I believe you are referring to the same thing except that yours has no proportional part (and you suggest to add it later if needed). 

It has this transfer function: H(z) = c1 + c2/(1 - z^-1) 

where c1 = 4*(theta)^2/(1+sqrt(2)*theta+theta^2) 

and c2 = 2*sqrt(2)*theta/(1+sqrt(2)*theta+theta^2) 

where theta = 2*pi*BW, BW is bandwidth of the filter in Hz. 

 

Let me ask you some questions: 

1- How to determine the cutoff frequency of this filter, regardless of the structure. 

2- Is leaky integrator the same as PI technique? How different they are? 

 

I think I have more questions but they relate to your answers of these.
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

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);
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

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?
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
1,508 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,387 Views

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!
0 Kudos
Reply