# Apply AWGN noise to QPSK-OFDM symbol

I'm working on an OFDM-QPSK based system and I'm having some trouble to match the BER of my system with the theoretical curve. My OFDM implementation fills all the subcarriers and have t_symbol s duration and t_cp cyclic prefix duration. I'm trying this to validate my system implementation before go on with my system development. I'm using the following python code for apply noise:

def awgn(self,data,noise_power):
Es = sum(abs(data)**2.)
Eb = Es/(self.OFDM_SIZE*2.)
EbN0_dB = noise_power + 10*log10(self.t_symbol/(self.t_symbol - self.t_cp))
EbN0 = (10.)**(EbN0_dB/10.)
N0 = Eb/EbN0
noise = sqrt(N0/2.)*(random.standard_normal((data.size,)) + random.standard_normal((data.size,))*1j)
return (data + noise)

I just realize that the normalization done here is not correct, since this signal is post OFDM modulation. But the problem remains.

The equation for the theoretical curve used is:

BER_t   = 0.5*erfc(n_sqrt((10.**(EbN0_vt/10.))/2.))

I had used similar code before on Matlab and it worked fine, but now It's not.

I guess it's not working now because my system don't have the constellation with (1+1j),(1-1j)... I have to use values that are less than one, since my system is implemented in fixed point. Now I'm using 0.75 as an amplitude but it's arbitrary chosen. I tried to correct the energy symbol to get a mean energy equal to one but using this take my signal out of range. I'm thinking about correct the EbN0 before apply on the theoretical BER equation, but I'm just wondering how.

Can anyone give me the correct way to go?

## My central question

Trying to improve my question: What I need to know is how to apply awgn on ofdm signal when it's subcarrier are modulated with QPSK and how to match it with the theoretical BER plot. My QPSK symbol have an amplitude of 0.75. The above code is to show how I'm doing it now.

## update

I run the code changing the FFT subsystem to the scipy.fftpack and the amplitude of the QPSK symbol to 1 instead of 0.75. And the curve match. I also had corrected the theoretical curve to:

BER_t   = 0.5*erfc(n_sqrt((10.**(EbN0_vec/10.))))

So I still think it's a matter of correct the EbN0 in the above equation.

## update2

After several testing of the above functions I found thet they are correct. The source of the problem is that I'm dealing with fixed point implementation of IFFT/FFT and I have to handle the channel model with this situation in mind. I'm trying to figure out how to handle this but without a solution yet.

• If you scale your signal by $0.75$, then the energy-per-bit $E_b$ will be scaled by $(0.75)^2$. Perhaps that's the problem that you're running into. It would be easier to understand your problem more clearly if you posted a full source code example showing how you generate the signal and measure the discrepancy that you're talking about. Commented Apr 4, 2013 at 13:00
• Well, I can't post the full source code and I guess it will be too big to put here, but the relevant code is there. The signal is generated by qpsk mapping and running into a IFFT to generate an OFDM symbol. The system works without channel, but since it's a communication system, I must have some channel to test the system against to validate before "real world" testing. I'm trying to apply the scaling. Commented Apr 4, 2013 at 13:29
• I wouldn't say that the relevant code is there. There are a lot of details that have to be correct in order for you to get the answer that you're looking for. The code above isn't anything close to a self-contained runnable example, which is going to get you the best answer. Commented Apr 4, 2013 at 14:17
• I see your point. But unfortunately, I can't share the full code and some parts of the system are third party under nda. Let me know what you're missing and I'll try to improve my question. Commented Apr 4, 2013 at 14:20
• Specifically, the only code you showed was a function that you use for adding noise to the signal. While this is an important part of the simulation in order to get the right BER answer, seeing what you're passing into that function, as well as a plot of what you're getting out, would be helpful. Right now, there isn't much to go on. Commented Apr 4, 2013 at 17:48

Your measurement of the symbol and noise energy is not correct. Please note that the following is pseudo-code, not valid Python code. EbN0_dB should be an input to this code, not an output.

Esymbol = sum(real(data*conj(data))) / numSymbolsInData