# "Stitch" Your Way Out of Logic-Analyzer Memory Limitations

### Abstract

MATLAB® is a powerful tool that can be used to quickly analyze captured data from an analog-to-digital converter (ADC) output. This application note demonstrates how to use MATLAB to avoid limitations in the memory depth of logic analyzers. Three code-switching methods (basic, advanced, and reverse) are described and compared. Results for all three methods are presented.

### Introduction

Characterizing high-speed analog-to-digital converters (ADCs) requires that the digital output codes be captured and analyzed. Limitations in the memory depth of logic analyzers frequently prevent capturing enough data points to create high-resolution FFTs or accurate representations of INL/DNL graphs. A simple way to circumvent this problem is to concatenate multiple sets of data with a mathematical tool such as MATLAB (Figure 1). One drawback of concatenating data is the large discontinuity, which is often present at the point between the two data sets. While the discontinuity makes little difference for INL/DNL graphs, it will wreak havoc on a high-resolution FFT (Figure 2).  One can eliminate discontinuities by searching for identical groups of points (typically three or four) in each data set, and 'stitching' the two data sets together at these points (Figure 3). The easiest way to accomplish this stitching is to record the last four points in the first data set and then search for an identical set of points in the second data set. This position in the second data set is called the 'stitch point.' Any data in the second data set that precedes this stitch point is discarded; the remaining portion of the second data set is attached to the first. This technique is called Basic Code Stitching, is fairly simple to implement, and executes very quickly in MATLAB. With basic code stitching, sometimes up to half of the second data set needs to be discarded in order to find a set of points that match the last four points of the first data set. Alternatively, discarding a few samples at the tail end of the first data set often helps to find a stitch point closer to the beginning of the second data set (Figure 4). However, looking for a match that discards samples from the tail end of the first data set and the front end of the second data set can be difficult to implement. This process is called Advanced Code Stitching. Finding the ideal stitching point that yields the largest resulting data set requires considerable forethought and programming skill. But if implemented properly, advanced code stitching typically yields a final data set that is at least 90% of the sum of the two smaller data sets. Stitching the second data set (Matrix B) in front of the first data set (Matrix A) is called Reverse Code Stitching and may also result in a larger data set (Figure 5). This technique, however, doubles the processing time because the stitch point must be found when data set A precedes data set B, and when data set A follows data set B. In addition, reverse code stitching typically yields minimal gains when combined with the other stitching techniques. Consequently, due to the substantial increase in processing time required for reverse code stitching, the additional code gains may not be justified on a slower PC. Table 1 details a comparison among the three code-stitching methods. Stitch technique Size of final data set Description Data set numbers # of codes (averaged) % of two data sets (averaged) 1 + 2 3 + 4 1 + 4 Concatenate† N/A 16384 100% Will produce erroneous FFT; however, INL/DNL can be extracted from this data. Basic 11060 8192‡ 14384 11212 68.4% FFT is useable for calculating figures of merit. Reverse 11060 8192‡ 14384 11212 68.4% Advanced 13790 16046 16022 15286 93.3% Advanced + Reverse 15427 16176 16022 15875 96.9% *Two 8K (8192 code) data sets were stitched together using the techniques described above. To ensure accuracy, the test was repeated three times using four sets of 8192-point data (labeled 1 through 4). The resultant data from each test was averaged and is presented to the right of the test data. †Concatenation always yields 100% of the available data. ‡Unable to stitch data sets together.

### MATLAB Functional Description

The attached MATLAB code (StitchMatrices and FindStitchPoint in Appendices A and B, respectively) combines the above topics into one easy-to-use function. These functions accept two data sets (single-column matrices in MATLAB) and several input arguments that enable the advanced-/reverse-code-stitching features. The FindStitchPoint routine identifies offsets in data sets A and B. The StitchMatrices routine discards and combines data sets A and B together using the offsets from the FindStitchPoint routine. In addition, the stitch points in the final data set are recorded in the PrevStitchBins matrix for post-processing. When stitching multiple data sets together, the PrevStitchBins preserves the location of the old stitch points.

### Conclusion

Stitching two sets of data together can yield acceptable results. Figure 6 depicts the FFT plot of three 8192-point data sets stitched together (five stitch points used) using the stitching techniques described above. The resulting FFT is almost identical to the 16384-point continuous data set shown in Figure 2a above. #### Appendix A: StitchMatrices Routine (StitchMatrices.m)

```function [StitchedMatrix, StitchBins] = StitchMatrices(MatrixA, ...
MatrixB, StitchNumber, PrevStitchBins, ...
%Stitch Matrices Function
%Revision 1.0
%
%By Donald Schelle, May 2005
%Maxim Integrated
%160 Rio Robles
%Sunnyvale, CA, 94086
%
%This function will take two matrices (MatrixA and MatrixB), find a
%given number (StitchNumber) of identical points in each and
%concatenate the two matrices into one.
%
%Inputs = MatrixA, MatrixB (Data Matrices)
%           StitchNumber (Number of points to match)
%            PrevStitchBins (Bins of Previous Stitches in MatrixA)
%            AdvStitchEnabled (0 = NO, 1 = YES)
%            ReverseStitchEnabled (0 = NO, 1 = YES)
%Output = StitchedMatrix (MatrixA + MatrixB)
%            StitchBins (bins of StitchedMatrix where the two
%                           matrices were joined.)
%
%If the matrices can not be joined the function will output a NaN
%for both the StitchedMatrix variable and the StitchBins variable
%--------------------------------------------------------------------------

%Check to see that there are at least TWO StitchNumber Points
if StitchNumber < 2,
%Requested less than 2 stitch points
StitchedMatrix = NaN;
StitchBins = NaN;
return;
end;

%Calculate Size of MatrixA and MatrixB
[SizeA, Junk] = size(MatrixA);
[SizeB, Junk] = size(MatrixB);

%Find the Stitch Points in MatrixB
[NormalA, NormalB] = FindStitchPoint(MatrixA, MatrixB, ...
%Calculate the size of the NormalStitched Matrix
NormalStitchedSize = NormalA + SizeB - NormalB + 1;

%Check to see if the reverse function is enabled
if ReverseStitchEnabled == 1,
%Find Stitch Points for Reverse Matrices
[ReverseB, ReverseA] = FindStitchPoint(MatrixB, MatrixA, ...
%Calculate the size of the Revered Stitched Matrix
ReverseStitchedSize = ReverseB + SizeA - ReverseA + 1;
else
%Set Values to defaults
ReverseStitchedSize = NaN;       %MatrixB/A Stitch Size
ReverseA = NaN;
ReverseB = NaN;
end;

%Check to if it's possible to stitch two matrices
if isnan(NormalStitchedSize) & isnan(ReverseStitchedSize) == 1,
%The two matrices could not be stitched
StitchedMatrix = NaN;
StitchBins = NaN;
return;
end;

%--------------------- Normal Matrix Stitching Routine ---------------
if (NormalStitchedSize >= ReverseStitchedSize)| ...
isnan(ReverseStitchedSize) == 1,
%Stitch MatrixB to the end of MatrixA
StitchedMatrix = cat(1, MatrixA(1:NormalA), MatrixB(NormalB:SizeB));

%Update Stitch Bins
if isnan(PrevStitchBins) == 1,
%There are no previous stitch bins
StitchBins = [NormalA, NormalA + StitchNumber - 1];
else
%There are previous stitch bins
%Check for Snipped Stitches
[SizeStitchBins, Junk] = size(PrevStitchBins);

while (PrevStitchBins(SizeStitchBins, 2) > (NormalA - 1)),
%Second Bin is snipped from matrix. Check if first bin is snipped.
if (PrevStitchBins(SizeStitchBins, 1) > (NormalA - 1)),
%First Bin is snipped too. Delete Bin Pair
PrevStitchBins = PrevStitchBins(1:(SizeStitchBins-1),:);
else
%First Bin is not snipped but second bin is snipped
%Shrink Stitch Size
PrevStitchBins(SizeStitchBins, 2) = NormalA - 1;
end;

%Calculate size of new PrevStitchBin Matrix
[SizeStitchBins, Junk] = size(PrevStitchBins);
end;

%Insert New StitchBins
[SizeStitchBins, Junk] = size(PrevStitchBins);
StitchBins = PrevStitchBins;
StitchBins(SizeStitchBins + 1, :) = ...
[NormalA, NormalA + StitchNumber - 1];

%Check to see if the last two stitches need to be combined
[SizeStitchBins, Junk] = size(StitchBins);
if StitchBins(SizeStitchBins,1) == ...
(StitchBins((SizeStitchBins - 1),2) + 1),
%Combine Stitches
StitchBins((SizeStitchBins - 1),2) = StitchBins((SizeStitchBins),2);
%Shorten StitchBin Matrix
StitchBins = StitchBins(1:(SizeStitchBins - 1),:);
end;

end;
end;

%--------------------- Reverse Matrix Stitching Routine ---------------
if (ReverseStitchedSize >= NormalStitchedSize)| ...
isnan(NormalStitchedSize) == 1,
%Stitch MatrixA to the end of MatrixB
StitchedMatrix = cat(1,MatrixB(1:ReverseB), MatrixA(ReverseA:SizeA));

%Update Stitch Bins
if isnan(PrevStitchBins) == 1,
%There are no previous stitch bins
StitchBins = [ReverseB, ReverseB + StitchNumber - 1];
else
%There are previous stitch bins
%Check for Snipped Stitches
while (PrevStitchBins(1,1) < (ReverseA + StitchNumber - 1)),
%First Bin is snipped from matrix. Check if second is snipped
if (PrevStitchBins(1,2) < (ReverseA + StitchNumber - 1)),
%Second Bin is snipped too. Delete Bad Pair
[SizeStitchBins, Junk] = size(PrevStitchBins);
PrevStitchBins = PrevStitchBins(2:SizeStitchBins, :);
else
%Second Bin is not snipped, but first bin is snipped
%Shrink Old Stitch Size
PrevStitchBins(1,1) = ReverseA + StitchNumber - 1;
end;
end;

%Offset Stitch Bins by inserted amount
StitchBins = PrevStitchBins + ReverseB - ReverseA + 1;
%Make Room for new StitchBins
[SizeStitchBins, Junk] = size(PrevStitchBins);
StitchBins(2:SizeStitchBins+1, :) = StitchBins;
%Insert New Stitch Bins
StitchBins(1,:) = [ReverseB, ReverseB + StitchNumber - 1];

%Combine close stitches
if StitchBins(1,2) == StitchBins(2,1) - 1,
%Combine Stitches
StitchBins(2,1) = StitchBins(1,1);
%Shrink Stitch Bins Matrix
[SizeStitchBins, Junk] = size(StitchBins);
StitchBins = StitchBins(2:SizeStitchBins,:);
end;

end;
end;
```

#### Appendix B: FindStitchPoint Routine (FindStitchPoint.m)

```function [OutputBinA, OutputBinB]=FindStitchPoint(MatrixA, MatrixB, ...
%Find Stitch Points Function
%Revision 1.0
%
%By Donald Schelle, May 2005
%Maxim Integrated
%160 Rio Robles
%Sunnyvale, CA, 94086
%
%This function will find the IDEAL stitch point in Matrix B given
%the number of data points to match
%
%Inputs = MatrixA
%            MatrixB
%            Number of Records to Match
%            Advanced Stitch Find Enabled (0 = NO, 1 = YES)
%Output = (OutputBinA) End Bin of MatrixA to stitch data
%            (OutputBinB) Start Bin of Matrix B to stitch data
%
%If no bins are found, the function will output a NaN
%--------------------------------------------------------------------------

%Do argument error checking to see if there is enough arguments
if nargin < 2,
%The user has not supplied enough arguments
disp('Function requires TWO Matrices');
OutputBinA = NaN;
OutputBinB = NaN;
return;
elseif nargin < 3,
disp('Select a number of points to match');
OutputBinA = NaN;
OutputBinB = NaN;
return;
elseif nargin == 3,
%Advanced code stitching is NOT enabled
OutputBinA = NaN;
end;

%Ensure that Matrix A and B are single ROW matrices
[row col] = size(MatrixA);
if row > col, MatrixA = MatrixA'; end;
[row col] = size(MatrixB);
if row > col, MatrixB = MatrixB'; end;

%Determine Size of Matrices
[Junk, SizeA] = size(MatrixA);
[Junk, SizeB] = size(MatrixB);

%Initialize OutputBinB to NaN (which means that NO stitch points are found)
OutputBinB = NaN;
%Set initial size of BinA
BinA = SizeA - MatchNumber + 1;
%Initialize BinStop Variable
BinStop = SizeA-100;

%Loop to search through Matrix B numerous times.  This loop is only
%excuted once if Advanced Stitch Find is disabled.  The loop will stop when
%the 'ideal' stitch point is found
while BinA > BinStop,
%Stuff the Match Numbers into a separate Matrix
MatchMatrix = MatrixA(BinA:BinA+MatchNumber - 1);

%Find all bins in MatrixB that match the first number of the Match Matrix
MatchedBins = find(MatrixB == MatchMatrix(1));

%Compare the 2nd through nth number of the Match Matrix with the
%prospective series of numbers in MatrixB

%Calculate the size of the Matched Bins Matrix
[Junk, SizeMatchedBins] = size(MatchedBins);

%The advanced stitch mode optimizes search time by eliminating
%bad stitch points that would result in the final concatenated
%matrix being smaller than the last set of stitch points
if isnan(OutputBinB) == 0,
%A Stitch Point exists from a previous run.  Elimiate bad stitch points
%Calculate critical Stitch Point
MatrixSize = OutputBinA + (SizeB-OutputBinB) + 1;
CriticalBin = BinA + SizeB - MatrixSize - 1;
%Find maximum number in the MatchMatrix
%Eliminate Bad Bins (if there are any)
end;
%Calculate size of new Matched Bins Matrix
[Junk, SizeMatchedBins] = size(MatchedBins);
end;

%loop to cycle through initial matched bins
for i=1:SizeMatchedBins,
%Check to make sure that there isn't a MatrixB overrun
if (MatchedBins(i) + MatchNumber - 1) > SizeB,
break;
end;

%Assume that next few codes will match and set StitchBinGood = true
StitchBinGood = 1;
%Initialize MatchMatrixCounter
Count = 1;
%Cycle through MatrixB and compare Numbers with the MatchMatrix
for j=MatchedBins(i):(MatchedBins(i) + MatchNumber - 1),
if MatchMatrix(Count)==MatrixB(j),
%Number is good, continue and check next number
Count = Count + 1;
else
%Number is bad, break loop and try next sequence
StitchBinGood = 0;
break;
end;
end;

if StitchBinGood == 1,
%The optimal (first) stitch has been found
%Record the End bin of MatrixA
%Record the Start bin of MatrixB
OutputBinA = BinA;
OutputBinB = MatchedBins(i) + 1;
%Calculate the size of the joined Matrix and a new BinStop#
BinStop = OutputBinA-OutputBinB+1;
break;
end;
end;

%Advanced Stitch Find is enabled and we should make a new match
%matrix and search for these numbers
BinA = BinA - 1;
else
%Advanced Stitch Find is disabled and we should end the loop
break;
end;
end;

%Check to see if NO Bins Matched
if isnan(OutputBinB) == 1,
%NO Bins matched
OutputBinA = NaN;
end;
```