MATLAB Examples

# Eye Diagram Measurements

This example shows how to use the comm.EyeDiagram System object to perform eye diagram measurements on simulated signals.

## Using the comm.EyeDiagram System Object

The comm.EyeDiagram System object collects eye diagram data in the form of vertical and horizontal histograms. We can utilize these histograms to extract quantitative metrics on the system under test. These quantitative metrics are called eye diagram measurements. The following simulation parameters (sample rate, samples per symbol) are chosen to provide a high resolution for the analysis.

```% Initialize system parameters Fs = 10000; % Sample rate Rs = 100; % Symbol rate (Sps) sps = Fs/Rs; % Number of samples per symbol SNR = 30; % Signal to noise ratio (dB) Trise = 1/(5*Rs); % Rise time of the NRZ signal Tfall = 1/(5*Rs); % Fall time of the NRZ signal frameLen = 5000; % Number of symbols in a frame ```

The following code generates a binary non-return-to-zero (NRZ) signal utilizing the pattern generator provided in the communication sources package. Then we add additive white Gaussian noise (AWGN) to this signal via an AWGNChannel System object. Next, the time domain signal is plotted. Another way to examine the signal characteristics is to generate the signal's eye diagram using the eye diagram System object. Note that the SymbolsPerTrace property, which represents the number of symbols in a trace of the eye diagram, should be set to two to perform the measurements. The figure on the right shows the eye diagram of the same signal. The specified SampleOffset value is set to ensure that the eye is centered in the figure. For more detail on using the eye diagram object, please refer to the documentation (comm.EyeDiagram) and the example Eye and Constellation Diagram.

```% Set up the pattern generator src = commsrc.pattern('SamplingFrequency', Fs, ... 'SamplesPerSymbol', sps, ... 'RiseTime', Trise, ... 'FallTime', Tfall) %#ok % Generate NRZ signal message = generate(src, frameLen); % Create an comm.AWGNChannel System object. % Set the NoiseMethod property of the channel to 'Signal to noise ratio % (SNR)'. The commsrc.pattern object generates unit power signals; set the % SignalPower property to 1 Watt. channel = comm.AWGNChannel('NoiseMethod', 'Signal to noise ratio (SNR)',... 'SNR', SNR, 'SignalPower', 1); % Add AWGN received = channel(message); % Create an eye diagram and display properties eyeObj = comm.EyeDiagram(... 'YLimits', [-1.5 1.5], ... 'SamplesPerSymbol', sps, ... 'SampleRate', Fs, ... 'SampleOffset', 0.004*Fs, ... 'DisplayMode', '2D color histogram', ... 'ColorScale', 'Logarithmic') %#ok % Update the eye diagram object with the noisy NRZ signal eyeObj(received); % Plot the time domain signal t = 0:1/Fs:15/Rs-1/Fs; idx = round(t*Fs+1); hFig = figure('Position', [0 0 460 360]); plot(t, received(idx)); title('Noisy NRZ signal'); xlabel('Time (sec)'); ylabel('Amplitude'); grid on; % Manage the figures hFig.Position = [10 10 hFig.Position(3:4)]; eyeObj.Position = [hFig.Position(1)+hFig.Position(3)+10 hFig.Position(2) .... eyeObj.Position(3)*0.75 eyeObj.Position(4)*0.75]; ```
```src = Type: 'Pattern Generator' SamplingFrequency: 10000 SamplesPerSymbol: 100 SymbolRate: 100 PulseType: 'NRZ' OutputLevels: [-1 1] RiseTime: 0.0020 FallTime: 0.0020 DataPattern: 'PRBS7' Jitter: [1x1 commsrc.combinedjitter] eyeObj = comm.EyeDiagram with properties: Name: 'Eye Diagram' Trace configuration SampleRate: 10000 SamplesPerSymbol: 100 SampleOffset: 40 SymbolsPerTrace: 2 Display configuration DisplayMode: '2D color histogram' EnableMeasurements: 0 ShowImaginaryEye: 0 YLimits: [-1.5000 1.5000] ShowGrid: 1 Position: [320 282 640 460] Use get to show all properties ```

An important characteristic of communication signals, especially in high speed applications such as backplane communications, is the timing jitter. Timing jitter is defined as the deviation of a signal's timing clock from the ideal clock. Timing jitter can be divided into two main subcategories: deterministic and random jitter [ 1 ]. Two examples of deterministic jitter are periodic jitter and inter-symbol interference (ISI).

Periodic jitter can be modeled as a sum of sinusoids, while ISI can be modeled as a train of Dirac functions. Random jitter is modeled as Gaussian variation of the signal clock edges.

The jitter encountered in a communication system can be any combination of these components. A commonly used combination is the dual-Dirac model, where ISI and random jitter are combined [ 2 ]. ISI is modeled by two equal amplitude Dirac functions. The following figure shows the probability density functions of random jitter, periodic jitter, periodic and random jitter, and ISI and random jitter. We generated the jitter samples using the jitter generator provided in the communication sources package.

```histEdges = -0.1/Rs:1/(10*Fs):0.1/Rs; hFigPdf = figure; % Obtain PDF of random jitter generated by the combined jitter object. Set % random jitter standard deviation to 1% of symbol time. jitterSrc = commsrc.combinedjitter('SamplingFrequency', Fs, ... 'RandomJitter', 'on', 'RandomStd', 0.01/Rs); jitter = generate(jitterSrc, 1e6); rjPdf = histc(jitter, histEdges); rjPdf = rjPdf / sum(rjPdf); subplot(221); plot(histEdges*1e3,rjPdf); grid on; title('Random Jitter'); xlabel('Time (ms)'); ylabel('PDF'); % Obtain PDF of periodic jitter. Set jitter amplitude to 5% of symbol time % and jitter frequency to 3 Hz. set(jitterSrc, 'RandomJitter', 'off', 'PeriodicJitter', 'on', ... 'PeriodicAmplitude', 0.05/Rs, 'PeriodicFrequencyHz', 3); jitter = generate(jitterSrc, 1e6); rjPdf = histc(jitter, histEdges); rjPdf = rjPdf / sum(rjPdf); subplot(222); plot(histEdges*1e3,rjPdf); grid on; title('Periodic Jitter'); xlabel('Time (ms)'); ylabel('PDF'); % Obtain PDF of random and periodic jitter jitterSrc.RandomJitter = 'on'; jitter = generate(jitterSrc, 1e6); rjPdf = histc(jitter, histEdges); rjPdf = rjPdf / sum(rjPdf); subplot(223); plot(histEdges*1e3,rjPdf); grid on; title('Periodic and Random Jitter'); xlabel('Time (ms)'); ylabel('PDF'); % Obtain PDF of ISI and random jitter jitterSrc.PeriodicJitter = 'off'; jitterSrc.DiracJitter = 'on'; jitterSrc.DiracDelta = 0.05/Rs*[-1 1]; jitter = generate(jitterSrc, 1e6); rjPdf = histc(jitter, histEdges); rjPdf = rjPdf / sum(rjPdf); subplot(224); plot(histEdges*1e3,rjPdf); grid on; title('ISI and Random Jitter'); xlabel('Time (ms)'); ylabel('PDF'); ```

We can use the same jitter object in the pattern generator to inject jitter to the output signal. The following code generates a signal that is impaired not only by AWGN but also by random jitter. This example uses the same message data as in the previous case and compares the two signals. Note that the effect of jitter on the signal is not clear in this time domain figure.

```close(hFigPdf); hide(eyeObj); % Attach the jitter object to the pattern generator src.Jitter = jitterSrc; % Generate only random jitter with standard deviation 0.3 ms. src.Jitter.DiracJitter = 'off'; src.Jitter.RandomJitter = 'on'; src.Jitter.RandomStd = 0.3e-3; % Generate NRZ signal with random jitter and add AWGN reset(src); release(channel); message = generate(src, frameLen); received = channel(message); % Plot the jittered noisy NRZ signal with the noisy signal t = 0:1/Fs:15/Rs-1/Fs; idx = round(t*Fs+1); figure(hFig); hold on; plot(t, received(idx), 'r'); title('Noisy and Jittered NRZ signal'); xlabel('Time (sec)'); ylabel('Amplitude'); grid on; ```

The effect of jitter is better illustrated by the eye diagram of the signal. The next two eye diagram figures illustrate the impact of jitter. The width of the jittered signal at the zero amplitude level is considerably larger than the width of the non-jittered signal as a result of the added random jitter. Note that even though this example focuses on real signals, the eye diagram object can also display complex signals if the ShowImaginaryEye property is set to true.

```close(hFig) % Make a copy of the eye diagram object and reset eyeObjJitter = clone(eyeObj); release(eyeObjJitter); reset(eyeObjJitter); % Update the eye diagram object with the noisy, jittered signal eyeObjJitter(received); % Bring up the previous eye diagram for comparison show(eyeObj); show(eyeObjJitter); eyeObj.Name = 'Eye Diagram without Jitter'; eyeObjJitter.Name = 'Eye Diagram with Jitter'; eyeObjJitter.Position = [eyeObj.Position(1)+eyeObj.Position(3) eyeObj.Position(2) ... eyeObj.Position(3) eyeObj.Position(4)]; ```

The horizontal histogram can be utilized to examine the jitter characteristics more closely. The horizontal histogram is calculated at the amplitude level specified via the DecisionBoundary property. The figure shows the horizontal histogram at 0 Amplitude Units (AU). Since the eye diagram traces two symbol durations, it crosses the reference amplitude level at two locations, 5 ms and 15 ms. Note that the symbol duration is 10 ms. Also, both crossings have Gaussian characteristics since the signal is impaired with random jitter.

```% Enable vertical histogram overlay, and therefore measurements eyeObjJitter.EnableMeasurements = true; eyeObjJitter.Position = eyeObjJitter.Position + [0 0 0 eyeObjJitter.Position(4)*0.75]; eyeObjJitter.OverlayHistogram = 'Jitter'; % Need to step the input again for histograms to be collected: eyeObjJitter(received); % Also export the plotted horizontal histogram with the jitterHistogram % method horHist = jitterHistogram(eyeObjJitter); hide(eyeObj); ```

The vertical histogram can be utilized to examine the noise characteristics of the channel. The vertical histogram is collected at the best sampling time, i.e., at the value of the Eye Delay measurement, which corresponds to the average of the two crossing times.

```eyeObjJitter.OverlayHistogram = 'Noise'; % Also export the plotted vertical histogram, with the noiseHistogram % method verHist = noiseHistogram(eyeObjJitter); ```

The following code runs a simulation with random jitter, ISI, and AWGN. ISI is introduced by passing the signal through a raised cosine filter. The Hysteresis property is set to a value such that level crossings due to noise are suppressed. Note that changing most measurement settings may reset the Eye Diagram object. The MeasurementDelay is set to a value greater than the filter delay to eliminate the transient part of the signal. The simulation runs in a FOR loop so that the eye diagram object computes measurements in a streaming manner.

```eyeObjJitter.OverlayHistogram = 'None'; reset(eyeObjJitter); release(eyeObjJitter); % Set the jitter parameters src.Jitter.RandomStd = 0.1e-3; % Set jitter hysteresis value, measurement delay, and color scale eyeObjJitter.Hysteresis = 0.1; eyeObjJitter.MeasurementDelay = 6/Rs; eyeObjJitter.ColorScale = 'Linear'; % Set up the square root raised cosine filter. b = rcosdesign(0.5, 6, sps); b = b / sum(b); transmitFilter = dsp.FIRFilter('Numerator', b); % Run simulation frameLen = 1000; numFrames = 20; lastSymbol = 0; lastJitter = 0; release(channel); % Generate jittered signal message = generate(src, frameLen*numFrames); % Add ISI and noise messageISI = transmitFilter(message); received = channel(messageISI); for k = 1:800 % Update the eye diagram object with the signal eyeObjJitter( received( 1+(k-1)*10*2*sps : k*10*2*sps ) ); end % Also export the displayed measurements with the measurements method: meas = measurements(eyeObjJitter) %#ok<NOPTS> % For a detailed explanation of the measurements, please refer to the % documentation (type "doc comm.EyeDiagram" on the command line). Note that % since the simulation was run using less than 20000 symbols, the results % are not very accurate. ```
```meas = struct with fields: EyeLevels: [2x1 double] EyeAmplitude: 1.8519 EyeHeight: 1.5124 VerticalOpening: 1.0447 EyeSNR: 10.5280 QualityFactor: 16.0473 CrossingLevels: [2x1 double] CrossingTimes: [2x1 double] EyeDelay: 0.0104 EyeWidth: 0.0077 HorizontalOpening: 0.0048 RiseTime: 0.0066 FallTime: 0.0066 DeterministicJitter: 6.5994e-04 RandomJitter: 0.0045 TotalJitter: 0.0052 RMSJitter: 3.8680e-04 PeakToPeakJitter: 0.0049 ```

## Comparing Measurements

We can use the measurement exporting capability of comm.EyeDiagram to compare measurements obtained under different configurations. The next example examines the effect of random jitter on an NRZ system with a 10 Gsps symbol rate. The deterministic jitter is set to 2 ns. The standard deviation of the random jitter is increased from 300 ps to 500 ps, in 100 ps steps. The NRZ signal is passed through an AWGN channel with 40 dB SNR. Note that AWGN will increase the random jitter since the rise and fall times are non-zero.

```Fs = 10e9; Rs = 100e6; sps = Fs/Rs; Trise = 2e-9; Tfall = 2e-9; % Create a pattern generator object srcObj = commsrc.pattern( ... 'SamplingFrequency', Fs, ... 'SamplesPerSymbol', sps, ... 'DataPattern', 'PRBS31', ... 'RiseTime', Trise, ... 'FallTime', Tfall); srcObj.Jitter.RandomJitter = 'on'; srcObj.Jitter.DiracJitter = 'on'; srcObj.Jitter.DiracDelta = [-1e-9 1e-9]; % Create an eye diagram object eyeObj = comm.EyeDiagram(... 'SampleRate', Fs, ... 'SamplesPerSymbol', sps, ... 'YLimits', [-1.75 1.75], ... 'EnableMeasurements', true, ... 'MeasurementDelay', 6e-9); % Set the range of standard deviation for the random jitter stdVec = (300:50:500)*1e-12; % Set simulation parameters frameLen = 1000; numFrames = 100; cnt = 1; % Main loop for randStd = stdVec % Set the random jitter standard deviation and reset the eye diagram % object srcObj.Jitter.RandomStd = randStd; hide(eyeObj); reset(eyeObj); release(eyeObj); % Update the eye diagram object with the jittered and noisy source x = generate(srcObj, frameLen*numFrames); r = awgn(x, 40); eyeObj(r); meas(cnt) = measurements(eyeObj); % Adjust the eye center to the middle of the time axis timeOffsetSamps = 2*eyeObj.SamplesPerSymbol - Fs*meas(cnt).EyeDelay; eyeObj.SampleOffset = round(timeOffsetSamps); cnt = cnt+1; end hide(eyeObj); hide(eyeObjJitter); ```

The following figure shows the measurement results for Horizontal Opening, Random Jitter, and Deterministic Jitter. Since Random Jitter is measured for a bit error rate of 1e-12 (see the BER Threshold property), the expected value of random jitter is about 14 times the standard deviation of the jitter samples. For example, for a standard deviation of 300 ps, the random jitter at BER = 1e-12 is 4.2 ns.

```hFig = figure; plot(300:50:500, [meas.HorizontalOpening], 'b-*'); hold on; plot(300:50:500, [meas.RandomJitter], 'r-*'); hold on; plot(300:50:500, [meas.DeterministicJitter], 'g-*'); legend('Horizontal opening', 'Random jitter', 'Deterministic jitter', 'Location', 'northwest'); title('Measurement comparison for noisy NRZ signal'); xlabel('Standard deviation of random jitter (ps)'); ylabel('Time (s)'); grid on; ```

The horizontal and vertical openings can also be compared for different BER Threshold values using the available bathtub curve displays.

```eyeObj.ShowBathtub = 'Horizontal'; eyeObj.BathtubBER = [0.5 10.^-(1:3:13)]; show(eyeObj); ```

## References

1. Ou N. et al., "Jitter Models for the Design and Test of Gbps-Speed Serial Interconnects," IEEE® Design & Test of Computers, Vol. 21, July-August 2004, pp. 302-313.
2. Stephens R., "Jitter Analysis: The dual-Dirac Model, RJ/DJ, and Q-Scale," Agilent Technologies® Whitepaper, 2004. Available from www.Agilent.com.