The Cyclic Prefix for OFDM

In a previous post, we have elaborated about the building blocks of OFDM.

There, we have stated two benefits of using a cyclic prefix between subsequent OFDM symbols:

  • The CP isolates different OFDM blocks from each other when the wireless channel contains multiple paths, i.e. is frequency-selective.
  • The CP turns the linear convolution with the channel into a circular convolution. Only with a circular convolution, we can use the single-tap equalization OFDM is so famous for.

In the following, we will elaborate on these two aspects. First, let us define some parameters for our OFDM system:

N = 128     # OFDM block length (i.e. subcarrier count)
NCP = 32    # Length of OFDM CP

ofdm1 = np.arange(N)                      # generate some arbitrary signal for one OFDM block
ofdm2 = 2*N + np.arange(N)                # generate some arbitrary signal for another OFDM block
symb1 = np.hstack([ofdm1[-NCP:], ofdm1])  # add the CP to each block
symb2 = np.hstack([ofdm2[-NCP:], ofdm2])

# concatenate both blocks into a single signal
signal = np.hstack([symb1, symb2])
t = np.arange(len(signal)) - N - NCP - NCP

As we see, the CP of an OFDM symbol is obtained by prepending a copy of the last $N_{CP}$ samples from the end of the OFDM signal to its beginning. This way we obtain a circular signal structure, i.e. the first $N_{CP}$ and last $N_{CP}$ samples are equal in each OFDM symbol.

Let us have a more detailed look at the OFDM signal structure:

def showOFDMStructure(t, sig, withTicks=True):
    H = 20
    I = np.tile(sig.reshape(1,-1), (H, 1))
    y = np.arange(H)
    plt.pcolormesh(t, y, I); 
showOFDMStructure(t, signal)

In the above figure, we see two subsequent OFDM symbols, each having a dedicated CP. The colors encode the signal value. The cyclic prefix at the beginning of each OFDM symbol shows a copy of the color of end of the OFDM symbol. When the signal is demodulated, the N-point FFT is taken at the position after the CP, which is indicated with FFT window.

Now, let us consider, what happens when this signal $x[n]$ is sent over a linear time-invariant (LTI) multipath channel. We know, in the discrete domain, we can model this channel with its impulse response $h[n]$. Let us choose an exponentially decaying impulse response and truncate it after $L=20$ samples.

L = 20
h = lambda t: (t >= 0) * (t <= L) * np.exp(-0.2*t)
plt.stem(t, h(t));

1) The Cyclic Prefix inhibits inter-symbol interference (ISI) between adjacent OFDM symbols

Then, the signal at the receiver $y[n]$ (ignoring the noise) is given by the (linear) convolution of the transmitted signal with the channel impulse response, i.e.

$$y[n] = h[n]*x[n].$$

More explicitely we can write the convolution as a sum

$$y[n] = \sum_{n'=-\infty}^{\infty} h[n']\cdot x[n-n'].$$

Now, since we know that $h[n]\neq0$ only for $n=0,\dots,L-1$, we can also write this a $$y[n] = \sum_{n'=0}^{L-1}h[n']\cdot x[n-n'].$$ This means, the output signal $y[n]$ at time $n$ depends only on the previous $L$ samples of the transmit signal. Let us illustrate this with the following figure. We see how the channel impulse response is sliding over the transmit signal and we also see that the output of the convolution at time $n_0$ only depends on the last $L$ samples.

def showNoISIBetweenBlocks(n0):
    showOFDMStructure(t, signal)
    plt.plot(t, 20*h(n0-t), 'k', lw=2)
 

We can see the following: As soon as the convolution output at $n_0$ enters the FFT window, the convolution window is entirely located on the cyclic prefix. This means, that no interference from the previous OFDM symbol is smeared into the currently received OFDM symbol. Hence, there is no inter-symbol interference between adjacent OFDM symbols. Instead, the convolution output within the FFT window only depends on the signal of the current OFDM symbol, because the CP contains an exact copy of the end of the OFDM symbol.

Naturally, this technique only works, if the channel impulse response is shorter than the cyclic prefix. If the CP is not long enough, it cannot completely mitigate ISI and the detection performance will become worse.

2) The Cyclic Prefix converts the linear convolution into a circular convolution

To understand this fact, let us create two adjacent, a little bit more elaborate, OFDM symbols.

# Generate some random OFDM signals
td1 = abs(N*np.fft.ifft(np.random.randn(5)+1j*np.random.randn(5), N));
td2 = abs(N*np.fft.ifft(np.random.randn(5)+1j*np.random.randn(5), N));
# Add CP and join two blocks together
td1_withCP = np.hstack([td1[-NCP:], td1])
td2_withCP = np.hstack([td2[-NCP:], td2])
td_full = np.hstack([td1_withCP, td2_withCP])

Let's have a look at the resulting signal. As we see, two adjacent symbols, separated by a cyclic prefix, and the cyclic prefix contains a copy of the end of each symbol.

plt.plot(t, td_full)

Now, lets see again what happens, if this signal is linearly convolved with the channel impulse response.

def showOFDMConvolution(shift):
    ax1 = plt.subplot(211)
    t_cyc = np.arange(N+NCP)-NCP
    h_cyc = h(shift-t_cyc)
    plt.plot(t_cyc, h_cyc)
    plt.plot(t_cyc, td2_withCP)
    plt.plot(t_cyc, h_cyc * td2_withCP)
    
    ax2 = plt.subplot(212)
    t_part = np.arange(N)
    h_part = h((shift-t_part)%N)
    plt.plot(t_part, h_part)
    plt.plot(t_part, td2)
    plt.plot(t_part, h_part * td2)
 

In the top figure we show the linear convolution of the channel with the signal, over the duration of the FFT window which will be used for demodulating the signal. We see, how the channel, when it enters the FFT window, convolves values from the CP region into the FFT window. This operation is still a linear convolution. However, we know that the CP is just a copy of the end of the OFDM symbol. Hence, we can understand the linear convolution over the CP also as a circular convolution within the OFDM FFT window: When the channel impulse response is above the CP area, this is equivalent to the channel impulse response being wrapped around on the FFT window, and smearing the end of the block into the beginning of the block.

Again, this naturally only works exactly, if the channel impulse response is shorter than the cyclic prefix. Otherwise, we suffer from inter-symbol interference, which cannot be represented by the circular convolution on the FFT window.

Hence, we can write the expression for the received signal within the FFT window also with a circular convolution:

$$\begin{align}y[n] &= \sum_{n'=0}^{L-1}h[n']\cdot x[n-n']&&\text{Linear convolution}\\ y[n]&=\sum_{n'=0}^{L-1}h[n']\cdot x[(n-n')_N]&&\text{Circular convolution}\end{align},$$

where $(n'-n)_N$ denotes the remainder of dividing $n'-n$ by $N$. It's only this property of OFDM which allows to perform the one-tap equalization with the channel impulse response. The convolution theorem in discrete domain states

$$\text{DFT}_N\{h[n]\otimes x[n]\}=H[k]X[k],$$

i.e. after performing the DFT over the FFT window we have

$$Y[k]=H[k]X[k],$$

and we know that $H[k]$ contains the QAM symbols that were sent from the transmitter. Then, we can perform the simple equalization

$$\hat{X}[k]=\frac{Y[k]}{H[k]}$$

to get back to the transmitted data symbols. It's exactly this propertly of OFDM which made it so popular for being used in multipath fading channels.

Summary

  • The cyclic prefix (CP) of OFDM provides two benefits:
    • It inhibits ISI between subsequent OFDM symbols.
    • It turns linear convolution into circular convolution with the FFT window.
  • Only circular convolution allows to apply the convolution theorem and use the single-tap equalizer.
  • The CP only works correctly, if it is longer than the channel impulse response.

Do you have questions or comments? Let's dicuss below!