摘要:MATLAB?是一個強有力的工具,可用來快速分析從模數轉換器(ADC)輸出所捕獲的數據。本應用筆記演示了如何使用MATLAB來突破邏輯分析儀存儲深度的局限。描述并比較了三種數碼拼接方式(基本,超前和反轉)。并給出了三種方法所得的結果。
圖1. 連接后的數據在兩組數據之間出現不連續。
圖2. a) 捕獲單組16384點數據并分析;b) 捕獲兩組8192點數據,連接,然后分析“拼接”技術。
有一種辦法可以消除不連續性,就是在各組數據中尋找相同的點簇(一般為3到4個點),然后在這些點將兩組數據“拼接”在一起(圖3)。最簡單的“拼接”方法是,記錄下第一組數據中的最后四個點,然后在第二組數據里尋找相同的點簇。相同點簇出現在第二組數據中的位置稱為“拼接點”。第二組數據中在拼接點之前的所有數據均被舍棄;第二組數據中的剩余部分與第一組數據合并。這種技術即所謂的基本數碼拼接,實現起來非常簡單,可以在MATLAB中非常快地運行。
圖3. 基本數碼拼接后得到的最終“拼接”數組。
采用基本拼接方法拼接數據時,有時必須丟掉第二組數據中的近一半,才能找到與第一組數據最后四個點相匹配的一簇點。作為另一種選擇,丟掉第一組數據尾部的幾個點,常常有助于找到更靠近第二組數據起點的拼接點(圖4)。然而,通過丟掉第一組數據尾部、第二組數據頭部的部分采樣點來尋找匹配點的方法實現起來比較困難。這種處理被稱為超前數碼拼接。理想拼接點應該能夠保留盡可能多的數據點,尋找這樣的拼接點需要認真的考慮和一定的編程技巧。正確地實現之后,超前拼接技術通常能夠得到兩組小數組所含數據點總數的至少90%。
圖4. 采用超前拼接技術尋找理想拼接點,最終得到“拼接”后的數組。
將第二組數據(數組B)拼接到第一組數據(數組A)之前被稱為反轉拼接,這種方式有可能得到更大的拼接數組(圖5)。但是,這種技術會使處理時間翻倍,因為必須在A領先于B和B領先于A兩種情況下尋找拼接點。此外,當與其他拼接技術一起使用時,反轉拼接方式所帶來的好處通常很少。因此,對于較慢的PC,反轉拼接技術大幅度增加的處理時間開銷較之它所帶來的好處而言并不太值。表1詳細比較了這三種代碼拼接方法。
圖5. 反轉拼接的處理時間加倍,但常常收效甚微。
表1. 三種拼接技術對比*
*采用上述拼接技術對兩組8K (8192個)數據進行拼接。為確保準確性,采用四組8192點數據(分別編號為1至4)重復本測試。每組測試所合成的數據取平均后列于測試數據的右側。
? 直接連接總能得到100%的數據。
? 無法拼接數據。
圖6. 數碼拼接后得到精確的FFT圖。
附錄A:StitchMatrices例程(StitchMatrices.m)
介紹
要評估一個高速模數轉換器(ADC)的性能,就需要捕獲其數字輸出碼,然后進行分析。邏輯分析儀的存儲深度常常成為一個重要局限,妨礙系統捕獲足夠的數據點,以生成高分辨率FFT,或者精確的INL/DNL圖。解決該問題的一個簡單辦法是使用某種數學工具,例如MATLAB? (圖1),將多組數據連接起來。連接數據的一個缺點是,通常會在兩組數據之間的連接點出現很大的不連續性。盡管不連續性對INL/DNL圖的影響極小,但對高分辨率FFT而言,幾乎是毀滅性的(圖2)。圖1. 連接后的數據在兩組數據之間出現不連續。
圖2. a) 捕獲單組16384點數據并分析;b) 捕獲兩組8192點數據,連接,然后分析“拼接”技術。
有一種辦法可以消除不連續性,就是在各組數據中尋找相同的點簇(一般為3到4個點),然后在這些點將兩組數據“拼接”在一起(圖3)。最簡單的“拼接”方法是,記錄下第一組數據中的最后四個點,然后在第二組數據里尋找相同的點簇。相同點簇出現在第二組數據中的位置稱為“拼接點”。第二組數據中在拼接點之前的所有數據均被舍棄;第二組數據中的剩余部分與第一組數據合并。這種技術即所謂的基本數碼拼接,實現起來非常簡單,可以在MATLAB中非常快地運行。
圖3. 基本數碼拼接后得到的最終“拼接”數組。
采用基本拼接方法拼接數據時,有時必須丟掉第二組數據中的近一半,才能找到與第一組數據最后四個點相匹配的一簇點。作為另一種選擇,丟掉第一組數據尾部的幾個點,常常有助于找到更靠近第二組數據起點的拼接點(圖4)。然而,通過丟掉第一組數據尾部、第二組數據頭部的部分采樣點來尋找匹配點的方法實現起來比較困難。這種處理被稱為超前數碼拼接。理想拼接點應該能夠保留盡可能多的數據點,尋找這樣的拼接點需要認真的考慮和一定的編程技巧。正確地實現之后,超前拼接技術通常能夠得到兩組小數組所含數據點總數的至少90%。
圖4. 采用超前拼接技術尋找理想拼接點,最終得到“拼接”后的數組。
將第二組數據(數組B)拼接到第一組數據(數組A)之前被稱為反轉拼接,這種方式有可能得到更大的拼接數組(圖5)。但是,這種技術會使處理時間翻倍,因為必須在A領先于B和B領先于A兩種情況下尋找拼接點。此外,當與其他拼接技術一起使用時,反轉拼接方式所帶來的好處通常很少。因此,對于較慢的PC,反轉拼接技術大幅度增加的處理時間開銷較之它所帶來的好處而言并不太值。表1詳細比較了這三種代碼拼接方法。
圖5. 反轉拼接的處理時間加倍,但常常收效甚微。
表1. 三種拼接技術對比*
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% |
*采用上述拼接技術對兩組8K (8192個)數據進行拼接。為確保準確性,采用四組8192點數據(分別編號為1至4)重復本測試。每組測試所合成的數據取平均后列于測試數據的右側。
? 直接連接總能得到100%的數據。
? 無法拼接數據。
MATLAB函數說明
本文后附的MATLAB代碼(附錄A和B中的StitchMatrices和FindStitchPoint)將上述論點結合到一個易于使用的函數中。這些函數可接受兩組數據(MATLAB中的單列矩陣)和幾個輸入變量(用來選擇超前/反轉拼接功能)。FindStitchPoint例程用來確定拼接點在數組A和B中的偏移量。StitchMatrices例程則根據FindStitchPoint例程給出的偏移量對兩組數據A和B進行舍棄和組合。同時,最終數據的拼接點被記錄在PrevStitchBins數組中,以便于后續處理。當拼接多組數據時,PrevStitchBins可保存老的拼接點。結論
拼接兩組數據可以得到一組理想的結果。圖6給出了三組8192點數據使用上述拼接技術拼接起來(使用5個拼接點)后的FFT圖。所得的FFT幾乎與前面圖2a所示,基于16384個連續點所得結果相同。圖6. 數碼拼接后得到精確的FFT圖。
附錄A:StitchMatrices例程(StitchMatrices.m)
function [StitchedMatrix, StitchBins] = StitchMatrices(MatrixA, ... MatrixB, StitchNumber, PrevStitchBins, ... AdvCodeStitchEnabled, ReverseStitchEnabled); %Stitch Matrices Function %Revision 1.0 % %By Donald Schelle, May 2005 %Maxim Integrated Products %120 San Gabriel Drive %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, ... StitchNumber, AdvCodeStitchEnabled); %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, ... StitchNumber, AdvCodeStitchEnabled); %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;附錄B:FindStitchPoint例程(FindStitchPoint.m)
function [OutputBinA, OutputBinB]=FindStitchPoint(MatrixA, MatrixB, ... MatchNumber, AdvancedStitchFindEnabled) %Find Stitch Points Function %Revision 1.0 % %By Donald Schelle, May 2005 %Maxim Integrated Products %120 San Gabriel Drive %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; AdvancedStitchFindEnabled=0; 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 BadBin = find(MatchedBins > CriticalBin); %Eliminate Bad Bins (if there are any) if isempty(BadBin) == 0, MatchedBins = MatchedBins(1:BadBin(1) - 1); 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; if AdvancedStitchFindEnabled == 1, %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;
評論
查看更多