介紹
要評估一個高速模數(shù)轉(zhuǎn)換器(ADC)的性能,就需要捕獲其數(shù)字輸出碼,然后進行分析。邏輯分析儀的存儲深度常常成為一個重要局限,妨礙系統(tǒng)捕獲足夠的數(shù)據(jù)點,以生成高分辨率FFT,或者精確的INL/DNL圖。解決該問題的一個簡單辦法是使用某種數(shù)學(xué)工具,例如MATLAB? (圖1),將多組數(shù)據(jù)連接起來。連接數(shù)據(jù)的一個缺點是,通常會在兩組數(shù)據(jù)之間的連接點出現(xiàn)很大的不連續(xù)性。盡管不連續(xù)性對INL/DNL圖的影響極小,但對高分辨率FFT而言,幾乎是毀滅性的(圖2)。圖1. 連接后的數(shù)據(jù)在兩組數(shù)據(jù)之間出現(xiàn)不連續(xù)。
圖2. a) 捕獲單組16384點數(shù)據(jù)并分析;b) 捕獲兩組8192點數(shù)據(jù),連接,然后分析“拼接”技術(shù)。
有一種辦法可以消除不連續(xù)性,就是在各組數(shù)據(jù)中尋找相同的點簇(一般為3到4個點),然后在這些點將兩組數(shù)據(jù)“拼接”在一起(圖3)。最簡單的“拼接”方法是,記錄下第一組數(shù)據(jù)中的最后四個點,然后在第二組數(shù)據(jù)里尋找相同的點簇。相同點簇出現(xiàn)在第二組數(shù)據(jù)中的位置稱為“拼接點”。第二組數(shù)據(jù)中在拼接點之前的所有數(shù)據(jù)均被舍棄;第二組數(shù)據(jù)中的剩余部分與第一組數(shù)據(jù)合并。這種技術(shù)即所謂的基本數(shù)碼拼接,實現(xiàn)起來非常簡單,可以在MATLAB中非常快地運行。
圖3. 基本數(shù)碼拼接后得到的最終“拼接”數(shù)組。
采用基本拼接方法拼接數(shù)據(jù)時,有時必須丟掉第二組數(shù)據(jù)中的近一半,才能找到與第一組數(shù)據(jù)最后四個點相匹配的一簇點。作為另一種選擇,丟掉第一組數(shù)據(jù)尾部的幾個點,常常有助于找到更靠近第二組數(shù)據(jù)起點的拼接點(圖4)。然而,通過丟掉第一組數(shù)據(jù)尾部、第二組數(shù)據(jù)頭部的部分采樣點來尋找匹配點的方法實現(xiàn)起來比較困難。這種處理被稱為超前數(shù)碼拼接。理想拼接點應(yīng)該能夠保留盡可能多的數(shù)據(jù)點,尋找這樣的拼接點需要認真的考慮和一定的編程技巧。正確地實現(xiàn)之后,超前拼接技術(shù)通常能夠得到兩組小數(shù)組所含數(shù)據(jù)點總數(shù)的至少90%。
圖4. 采用超前拼接技術(shù)尋找理想拼接點,最終得到“拼接”后的數(shù)組。
將第二組數(shù)據(jù)(數(shù)組B)拼接到第一組數(shù)據(jù)(數(shù)組A)之前被稱為反轉(zhuǎn)拼接,這種方式有可能得到更大的拼接數(shù)組(圖5)。但是,這種技術(shù)會使處理時間翻倍,因為必須在A領(lǐng)先于B和B領(lǐng)先于A兩種情況下尋找拼接點。此外,當(dāng)與其他拼接技術(shù)一起使用時,反轉(zhuǎn)拼接方式所帶來的好處通常很少。因此,對于較慢的PC,反轉(zhuǎn)拼接技術(shù)大幅度增加的處理時間開銷較之它所帶來的好處而言并不太值。表1詳細比較了這三種代碼拼接方法。
圖5. 反轉(zhuǎn)拼接的處理時間加倍,但常常收效甚微。
表1. 三種拼接技術(shù)對比*
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% |
*采用上述拼接技術(shù)對兩組8K (8192個)數(shù)據(jù)進行拼接。為確保準(zhǔn)確性,采用四組8192點數(shù)據(jù)(分別編號為1至4)重復(fù)本測試。每組測試所合成的數(shù)據(jù)取平均后列于測試數(shù)據(jù)的右側(cè)。
? 直接連接總能得到100%的數(shù)據(jù)。
? 無法拼接數(shù)據(jù)。
MATLAB函數(shù)說明
本文后附的MATLAB代碼(附錄A和B中的StitchMatrices和FindStitchPoint)將上述論點結(jié)合到一個易于使用的函數(shù)中。這些函數(shù)可接受兩組數(shù)據(jù)(MATLAB中的單列矩陣)和幾個輸入變量(用來選擇超前/反轉(zhuǎn)拼接功能)。FindStitchPoint例程用來確定拼接點在數(shù)組A和B中的偏移量。StitchMatrices例程則根據(jù)FindStitchPoint例程給出的偏移量對兩組數(shù)據(jù)A和B進行舍棄和組合。同時,最終數(shù)據(jù)的拼接點被記錄在PrevStitchBins數(shù)組中,以便于后續(xù)處理。當(dāng)拼接多組數(shù)據(jù)時,PrevStitchBins可保存老的拼接點。結(jié)論
拼接兩組數(shù)據(jù)可以得到一組理想的結(jié)果。圖6給出了三組8192點數(shù)據(jù)使用上述拼接技術(shù)拼接起來(使用5個拼接點)后的FFT圖。所得的FFT幾乎與前面圖2a所示,基于16384個連續(xù)點所得結(jié)果相同。圖6. 數(shù)碼拼接后得到精確的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;
評論
查看更多