Line code – demonstration in Matlab and Python

Line code is the signaling scheme used to represent data on a communication line. There are several possible mapping schemes available for this purpose. Lets understand and demonstrate line code and PSD (power spectral density) in Matlab & Python.

Line codes – requirements

When transmitting binary data over long distances encoding the binary data using line codes should satisfying following requirements.

  • All possible binary sequences can be transmitted.
  • The line code encoded signal must occupy small transmission bandwidth, so that more information can be transmitted per unit bandwidth.
  • Error probability of the encoded signal should be as small as possible
  • Since long distance communication channels cannot transport low frequency content (example : DC component of the signal , such line codes should eliminate DC when encoding). The power spectral density of the encoded signal should also be suitable for the medium of transport.
  • The receiver should be able to extract timing information from the transmitted signal.
  • Guarantee transition of bits for timing recovery with long runs of 1s and 0s in the binary data.
  • Support error detection and correction capability to the communication system.

Unipolar Non-Return-to-Zero (NRZ) level and Return-to-Zero (RZ) level codes

Unipolar NRZ(L) is the simplest of all the line codes, where a positive voltage represent binary bit 1 and zero volts represents bit 0. It is also called on-off keying.

In unipolar return-to-zero (RZ) level line code, the signal value returns to zero between each pulse.

Unipolar Non Return to Zero (NRZ) and Return to Zero (RZ) line code - 5V peak voltage
Unipolar Non Return to Zero (NRZ) and Return to Zero (RZ) line code – 5V peak voltage

For both unipolar NRZ and RZ line coded signal, the average value of the signal is not zero and hence they have a significant DC component (note the impulse at zero frequency in the power spectral density (PSD) plot).

The DC impulses in the PSD do not carry any information and it also causes the transmission wires to heat up. This is a wastage of communication resource.

Unipolar coded signals do not include timing information, therefore long runs of 0s and 1s can cause loss of synchronization at the receiver.

Power spectral density of unipolar NRZ line code
Power spectral density of unipolar NRZ line code
Power spectral density of unipolar RZ line code
Power spectral density of unipolar RZ line code

Bipolar Non-Return-to-Zero (NRZ) level code

In bipolar NRZ(L) coding, binary bit 1 is mapped to positive voltage and bit 0 is mapped to negative voltage. Since there are two opposite voltages (positive and negative) it is a bipolar signaling scheme.

Bipolar Non Return to Zero (NRZ) and Return to Zero (RZ) line code - 5V peak voltage
Bipolar Non Return to Zero (NRZ) and Return to Zero (RZ) line code – 5V peak voltage

Evident from the power spectral densities, the bipolar NRZ signal is devoid of a significant impulse at the zero frequency (DC component is very close to zero). Furthermore, it has more power than the unipolar line code (note: PSD curve for bipolar NRZ is slightly higher compared to that of unipolar NRZ). Therefore, bipolar NRZ signals provide better signal-to-noise ratio (SNR) at the receiver.

Bipolar NRZ signal lacks embedded clock information, which posses synchronization problems at the receiver when the binary information has long runs of 0s and 1s.

Comparing power spectral densities of bipolar NRZ and unipolar NRZ line codes
Comparing power spectral densities of bipolar NRZ and unipolar NRZ line codes

Alternate Mark Inversion (AMI)

AMI is a bipolar signaling method, that encodes binary 0 as 0 Volt and binary 1 as +ve and -ve voltage (alternating between successive 1s).

Alternate Mark Inversion (AMI) line code
Alternate Mark Inversion (AMI) line code – 5V peak voltage

AMI eliminates DC component. Evident from the PSD plots below, AMI has reduced bandwidth (narrower bumps) and faster roll-offs compared to unipolar and bipolar NRZ line codes.

It has inbuilt error detection mechanism: a bit error results in violation of bipolar signaling. It has guaranteed timing transitions even for long runs of 1s and 0s.

Power spectral density of Alternate Mark Inversion (AMI) line code
Power spectral density of Alternate Mark Inversion (AMI) compared with unipolar and bipolar NRZ line codes

Manchester encoding

In Manchester encoding, the signal for each binary bit contains one transition. For example, bit 0 is represented by a transition from negative to positive voltage and bit 1 is represented by transitioning from one positive to negative voltage. Therefore, it is considered to be self clocking and it is devoid of DC component.

Digitally Manchester encoding can be implemented by XORing the binary data and the clock, followed by mapping the output to appropriate voltage levels.

Manchester encoding
Manchester encoding

From the PSD plot, we can conclude that Manchester encoded signal occupies twice the bandwidth of Bipolar NRZ(L) encoded signal.

Power spectral density of Manchester encoding
Power spectral density of Manchester encoding compared with that of Bipolar NRZ(L)

Matlab script

In this script, lines codes are simulated and their power spectral density (PSD) are plotted using pwelch command.

%Simulate line codes and plot power spectral densities (PSD)
%Author: Mathuranathan Viswanathan
clearvars; clc;
L = 32; %number of digital samples per data bit
Fs = 8*L; %Sampling frequency
voltageLevel = 5; %peak voltage level in Volts
data = rand(10000,1)>0.5; %random 1s and 0s for data
clk = mod(0:2*numel(data)-1,2).'; %clock samples

ami = 1*data; previousOne = 0; %AMI encoding
for ii=1:numel(data)
    if (ami(ii)==1) && (previousOne==0)
        ami(ii)= voltageLevel;
        previousOne=1;
    end 
    if (ami(ii)==1) && (previousOne==1)
        ami(ii)= -voltageLevel;
        previousOne = 0;
    end    
end

%converting the bits to sequences and mapping to voltage levels
clk_sequence=reshape(repmat(clk,1,L).',1,length(clk)*L);
data_sequence=reshape(repmat(data,1,2*L).',1,length(data)*2*L);
unipolar_nrz_l = voltageLevel*data_sequence;
nrz_encoded = voltageLevel*(2*data_sequence - 1);
unipolar_rz = voltageLevel*and(data_sequence,not(clk_sequence));
ami_sequence = reshape(repmat(ami,1,2*L).',1,length(ami)*2*L);
manchester_encoded = voltageLevel*(2*xor(data_sequence,clk_sequence)-1);

figure; %Plot signals in time domain 
subplot(7,1,1); plot(clk_sequence(1:800)); title('Clock');
subplot(7,1,2); plot(data_sequence(1:800)); title('Data')
subplot(7,1,3); plot(unipolar_nrz_l(1:800)); title('Unipolar non-return-to-zero level')
subplot(7,1,4); plot(nrz_encoded(1:800)); title('Bipolar Non-return-to-zero level')
subplot(7,1,5); plot(unipolar_rz(1:800)); title('Unipolar return-to-zero')
subplot(7,1,6); plot(ami_sequence(1:800)); title('Alternate Mark Inversion (AMI)')
subplot(7,1,7); plot(manchester_encoded(1:800)); title('Manchester Encoded - IEEE 802.3')

figure; %Plot power spectral density
ns = max(size(unipolar_nrz_l));
na = 16;%averaging factor to plot averaged welch spectrum
w = hanning(floor(ns/na));%Hanning window
%Plot Welch power spectrum using Hanning window
[Pxx1,F1] = pwelch(unipolar_nrz_l,w,[],[],1,'onesided');
[Pxx2,F2] = pwelch(nrz_encoded,w,[],[],1,'onesided'); 
[Pxx3,F3] = pwelch(unipolar_rz,w,[],[],1,'onesided'); 
[Pxx4,F4] = pwelch(ami_sequence,w,[],[],1,'onesided'); %
[Pxx5,F5] = pwelch(manchester_encoded,w,[],[],1,'onesided'); 

semilogy(F1,Pxx1,'DisplayName','Unipolar-NRZ-L');hold on;
semilogy(F2,Pxx2,'DisplayName','Bipolar NRZ(L)');
semilogy(F3,Pxx3,'DisplayName','Unipolar-RZ');
semilogy(F4,Pxx4,'DisplayName','AMI'); 
semilogy(F5,Pxx5,'DisplayName','Manchester');
legend();

Python code

Check out the python code in my Google Colab

Rate this article: PoorBelow averageAverageGoodExcellent (16 votes, average: 3.81 out of 5)

Books by the author

Wireless Communication Systems in Matlab
Wireless Communication Systems in Matlab
Second Edition(PDF)

PoorBelow averageAverageGoodExcellent (162 votes, average: 3.78 out of 5)

Digital modulations using Python
Digital Modulations using Python
(PDF ebook)

PoorBelow averageAverageGoodExcellent (123 votes, average: 3.60 out of 5)

digital_modulations_using_matlab_book_cover
Digital Modulations using Matlab
(PDF ebook)

PoorBelow averageAverageGoodExcellent (126 votes, average: 3.70 out of 5)

Hand-picked Best books on Communication Engineering
Best books on Signal Processing

4 thoughts on “Line code – demonstration in Matlab and Python”

  1. Love the python book and glad you are using colab to share new code. Here is the Q:
    1. Can you show also NRZ vs PAM-N showing things like the two lobes in one for PAM4 vs NRZ (see slide 26 https://www.xilinx.com/publications/events/designcon/2016/slides-pam4signalingfor56gserial-zhang-designcon.pdf)

    I have tried applying Welch method to get the PSD out of a PRBS15-1 26GHz clocked NRZ on my Keysight DCA at work and I don’t get even close to the same result you are showing no mater how I set the scope filter/BW to max or be at the 4rth order Bessel filter response required by the IEEE latest what ever 802 spec. I thought it was something to do with the root raised cosine of the tx from the Keysight BERT I don’t think that anymore. It would be awesome to show how to apply what you did theoretically to real world measurements even with just a I2c bus or AWG on a analog discovery

    Again the post and python book are great, thank you

    Reply

Post your valuable comments !!!