摘要:集成了乘累加單元(MAC)和單周期內核的MAXQ2000非常適合用作通用微控制器(μC) 。MAXQ2000所具有的性能和I/O外設適合多種應用:如鬧鐘、手持醫療設備、數字讀取器等需要低功耗、高性能和大量I/O的應用。集成MAC的MAXQ2000已可以進入DSP (μC)的應用領域。
本應用筆記要求的硬件包括MAXQ2000評估板和實現與計算機揚聲器接口的簡單電路。
現已提供的MAXQ2000評估板是了解MAXQ2000性能的最佳工具,它包括一塊LCD面板、一組LED。可通過評估板訪問MAXQ2000的所有I/O引腳。評估板集成的MAX1407 ADC/DAC可用于音頻輸出。
所需的第二部分硬件可由電路實驗板方便實現。演示使用的電路如圖1所示。它使用一個1 x 8的孔插座在J7處連接MAXQ2000評估板,需要和任意地電位相連(可選擇MAXQ2000評估板上的TP1)。揚聲器連接器可以是任意類型,圖中所示為一個3.5mm立體聲插孔,可方便實現與常用計算機揚聲器連接。注意兩輸入通道并聯,因為我們的演示僅使用一個音頻通道(單聲道)。
圖1. 音頻回放所需的其它硬件
該演示所需的軟件采用IAR嵌入式平臺創建并調試。該平臺提供一個良好的調試環境,使用了MAXQ2000的硬件調試支持。可設置斷點,設置或讀取寄存器和存儲器,在真實硬件環境中運行時可查看堆棧調用。
圖2. 使用零極點圖來生成一個簡單的FIR濾波器
普通濾波器的線性方程為:
y(n) + bKy(k) = aJx(j)
其中k表示濾波器反饋部分的階數,j表示濾波器前饋部分的階數。
一個IIR濾波器可由下式簡單表示:
y(n) = 0.5y(n-1) + x(n) - 0.8x(n-1)
一些濾波器被歸類為FIR濾波器,不包括反饋部分。換句話說,在濾波器特征方程中不包括y部分:
y(n) = aJx(j)
y(n) = x(n) - 0.2x(n - 1) + 0.035x(n - 3)
任何情況下濾波器都可歸結為一個特征方程,本質上是過去的輸入和輸出的加權平均。濾波器設計即生成Aj和Bk值。為高效計算濾波器輸出,需要能快速乘和加有符號數硬件的支持,這就是MAXQ2000的乘-累加單元。
這種解決方法是精度和速度的折衷。在許多情況下,該方法產生的誤差可忽略。出于診斷目的,小應用程序可顯示所計算濾波器的三條曲線。第一條曲線采用64位浮點數顯示理想濾波器的運行狀態。該曲線在圖2中以“Ideal Transform”標示。
圖3畫出了由小應用程序產生的其余曲線。其中第一條曲線顯示采用16位定點數的濾波效果。在許多情況下,誤差并不明顯。最后一條曲線為誤差指示,顯示的是理想頻響除以實際頻響。理想情況下,這是一條Y = 1的直線。
圖3. 16位濾波器實際效果和舍入誤差(視覺上沒有誤差)
簡單起見,小應用程序產生MAXQ?濾波器所需的浮點參數,因此,新濾波器可簡單通過將其剪切并粘貼到濾波器源文件(data.asm文件)中實現。小應用程序還產生另外兩個值,即濾波器階數(參數個數)和移位數,應用程序可適當移位最終結果。數據出現在小應用程序底部文本框中,可能會以以下方式呈現:
MAX1407含有一個12位ADC。而輸入數據為16位寬度,濾波器產生16位結果。盡管4個最低有效位(LSB)在本應用中沒有用到,但仍可按16位計算和輸出正常分析其性能(CD質量的音頻為16位)。
本例中,濾波器參數存儲在代碼區的表中。選擇一個濾波器后,應用程序找到合適的濾波器,讀取移位數及抽頭數,然后準備開始數字濾波。以下代碼應用了濾波器參數:
由于MAC以單周期工作,處理代碼較少。MCNT置為22h代表采用有符號整數。在主循環中,連續寫入MA,然后寫MB觸發乘-累加運算,結果在下一個時鐘周期準備就緒。由于累加器為48位(乘的結果為32位),因此不會產生溢出(除非濾波器中有64,000個抽頭!)。
可將用于產生音頻采樣的功能分成3部分:初始化、濾波器計算循環以及結果修正。在該例中,初始化需要38個周期,濾波器計算中每個濾波器參數需要17個周期,結果修正需要9 + (6 x S)個周期,其中S是移位數。通常,移位數為12,則結果修正為81個周期。因此,需要119 + (17 x N)個周期產生一個濾波輸出結果。20MHz時,MAXQ2000可以運行近11kHz的100抽頭濾波器,這已經是相當好的語音質量。
現在回到前面重新分析應用程序以進一步進行簡化。我們將主要針對濾波器循環,因為此處占用了多數周期,并且最煩瑣。
還可以對循環代碼進行幾處關鍵改進以提高效率。注意,我們采用了預先錄制并存儲在代碼區的音頻采樣。由于MAXQ采用哈佛體系結構,因此查找代碼空間比查找數據空間需要更多的時間。稱為UROM_MOVEDP1INC和UROM_MOVEDP0DEC的函數每個執行需要5個周期(LCALL為2周期,函數內部為3周期)。如果濾波器存儲在RAM中并處理存儲在RAM中的實時輸入數據,則每個只需兩周期(一個周期選擇指針,一個周期讀)。如果將RAM中的256個字用于濾波器,可用BP[Offs]實現一個環形緩沖區來存儲輸入數據。這些改動可將循環時間由17個周期縮短為11個。這樣的濾波器循環為下所示(在注釋中首先列出所需周期數):
現在回到前面的方程中。新方程保守估計開銷占用40個周期,每個循環迭代占5周期。采用與前面相同的100抽頭濾波器,MAXQ2000能夠處理16位、37kHz單聲道音頻數據,如表1所示。
表1. FIR濾波器最大采樣速率(20MHz MAXQ2000,循環)
對于需要更高采樣率的應用、可犧牲代碼空間進一步提高性能。可以“內嵌”濾波器參數,不再需要選擇有效指針和循環(該技術也稱為循環展開)。這種改變的代價是增加代碼空間,以前需要100個字來存儲一個100個點的濾波器;現在,則需要300個字來存儲(每個參數移動為2個字,每個數據移動為1個字)。在16k字的器件中,相對于性能的提高,這種代價可忽略。新代碼形式如下:
表2. FIR濾波器最大采樣速率(20MHz MAXQ2000,循環展開)
MAXQ2000的MAC能夠發揮多大的性能?本應用筆記以一個音頻濾波器為例來解釋此問題,并定量給出MAXQ2000支持的性能。
軟件和硬件要求
本應用筆記簡單演示一個音頻濾波器。音頻數據事先錄制,是由作者朗讀的 "The pipe began to rust while new"。這并不是隨機選擇的,它含有適當的頻率組合,可以檢驗濾波器的效果(http://www.cs.columbia.edu/~hgs/audio/harvard.html )。該音頻錄音可以用任意合適長度的8kHz錄音替代,但并不必要。本應用筆記要求的硬件包括MAXQ2000評估板和實現與計算機揚聲器接口的簡單電路。
現已提供的MAXQ2000評估板是了解MAXQ2000性能的最佳工具,它包括一塊LCD面板、一組LED。可通過評估板訪問MAXQ2000的所有I/O引腳。評估板集成的MAX1407 ADC/DAC可用于音頻輸出。
所需的第二部分硬件可由電路實驗板方便實現。演示使用的電路如圖1所示。它使用一個1 x 8的孔插座在J7處連接MAXQ2000評估板,需要和任意地電位相連(可選擇MAXQ2000評估板上的TP1)。揚聲器連接器可以是任意類型,圖中所示為一個3.5mm立體聲插孔,可方便實現與常用計算機揚聲器連接。注意兩輸入通道并聯,因為我們的演示僅使用一個音頻通道(單聲道)。
圖1. 音頻回放所需的其它硬件
該演示所需的軟件采用IAR嵌入式平臺創建并調試。該平臺提供一個良好的調試環境,使用了MAXQ2000的硬件調試支持。可設置斷點,設置或讀取寄存器和存儲器,在真實硬件環境中運行時可查看堆棧調用。
運行演示
MAXQ2000評估板上的按鍵用于選擇濾波器,并播放經過濾波的音頻采樣。使用按鍵SW4選擇濾波器,濾波器名稱將顯示在LCD上(HI為高通、LO為低通、BP為帶通,ALL為全通)。使用按鍵SW5播放通過所選濾波器的音頻。可在播放期間切換濾波器。設計一個簡單的FIR濾波器
本文使用一個Java?小應用程序來方便的產生新的濾波器。沒有采用標準加窗技術給出濾波器參數,而是如圖2所示,在零極點圖上放置零點來簡單“設計”濾波器。小應用程序可在坐標平面任意位置放置零點,自動更新演示所需FIR濾波器的參數。注意,演示僅支持全零點濾波器。支持IIR濾波器并不困難,在支持IIR濾波器一節中有詳細解釋。圖2. 使用零極點圖來生成一個簡單的FIR濾波器
普通濾波器的線性方程為:
y(n) + bKy(k) = aJx(j)
其中k表示濾波器反饋部分的階數,j表示濾波器前饋部分的階數。
一個IIR濾波器可由下式簡單表示:
y(n) = 0.5y(n-1) + x(n) - 0.8x(n-1)
一些濾波器被歸類為FIR濾波器,不包括反饋部分。換句話說,在濾波器特征方程中不包括y部分:
y(n) = aJx(j)
y(n) = x(n) - 0.2x(n - 1) + 0.035x(n - 3)
任何情況下濾波器都可歸結為一個特征方程,本質上是過去的輸入和輸出的加權平均。濾波器設計即生成Aj和Bk值。為高效計算濾波器輸出,需要能快速乘和加有符號數硬件的支持,這就是MAXQ2000的乘-累加單元。
使用乘-累加(MAC)單元實現一個濾波器
上一節中的小應用程序可通過在圖中指定零點坐標計算濾波器參數。但計算結果為浮點數,而MAC為純16位整數運算。為解決這一問題,本演示采用了一個定點數值系統,參數的0至15位為小數點右側的數值(第16位代表符號極性)。運算完成后,MAC累加器中的48位結果通過移位去掉剩余部分。這種解決方法是精度和速度的折衷。在許多情況下,該方法產生的誤差可忽略。出于診斷目的,小應用程序可顯示所計算濾波器的三條曲線。第一條曲線采用64位浮點數顯示理想濾波器的運行狀態。該曲線在圖2中以“Ideal Transform”標示。
圖3畫出了由小應用程序產生的其余曲線。其中第一條曲線顯示采用16位定點數的濾波效果。在許多情況下,誤差并不明顯。最后一條曲線為誤差指示,顯示的是理想頻響除以實際頻響。理想情況下,這是一條Y = 1的直線。
圖3. 16位濾波器實際效果和舍入誤差(視覺上沒有誤差)
簡單起見,小應用程序產生MAXQ?濾波器所需的浮點參數,因此,新濾波器可簡單通過將其剪切并粘貼到濾波器源文件(data.asm文件)中實現。小應用程序還產生另外兩個值,即濾波器階數(參數個數)和移位數,應用程序可適當移位最終結果。數據出現在小應用程序底部文本框中,可能會以以下方式呈現:
Zeroes: dc16 dc16 12, 11, 0x1000, 0x26d3, 0x1e42, 0xf9a3, 0xecde, 0xff31, 0xa94, 0x2ae, 0xfd0c, 0xff42, 0xde Shift amount: 12
用MAXQ匯編語言實現濾波器
為得到最佳性能,并進行準確的性能分析,實際濾波器采用匯編語言實現,這樣可精確計算產生一個輸出所需的循環次數,并由此估算其它數據設置的性能。MAX1407含有一個12位ADC。而輸入數據為16位寬度,濾波器產生16位結果。盡管4個最低有效位(LSB)在本應用中沒有用到,但仍可按16位計算和輸出正常分析其性能(CD質量的音頻為16位)。
本例中,濾波器參數存儲在代碼區的表中。選擇一個濾波器后,應用程序找到合適的濾波器,讀取移位數及抽頭數,然后準備開始數字濾波。以下代碼應用了濾波器參數:
move MCNT, #22h ; signed, mult-accum, clear regs first zeroes_filterloop: move A[0], DP[0] ; let's see if we are out of data cmp #W:rawaudiodata ; compare to the start of the audio data lcall UROM_MOVEDP1INC ; get next filter coefficient move MA, GR ; multiply filter coefficient... lcall UROM_MOVEDP0DEC ; get next filter data move MB, GR ; multiply audio sample... jump e, zeroes_outofdata ; stop if at the start of the audio data djnz LC[0], zeroes_filterloop zeroes_outofdata: move A[2], MC2 ; get MAC result HIGH move A[1], MC1 ; get MAC result MID move A[0], MC0 ; get MAC result LOW執行該代碼前,LC[0]裝入濾波器抽頭數,DP[0]裝入濾波器當前輸入字節地址,DP[1]裝入濾波器參數起始地址。DP[1]以遞增方式處理濾波器參數,DP[0]以遞減方式處理輸入數據(最近輸入的數據首先處理)。
由于MAC以單周期工作,處理代碼較少。MCNT置為22h代表采用有符號整數。在主循環中,連續寫入MA,然后寫MB觸發乘-累加運算,結果在下一個時鐘周期準備就緒。由于累加器為48位(乘的結果為32位),因此不會產生溢出(除非濾波器中有64,000個抽頭!)。
性能
該應用處理單聲道16位音頻數據并產生8kHz輸出,還沒有完全發揮微控制器的能力。由于使用匯編語言編寫濾波器,可用一個表達式方便算出用于計算長度為N的FIR濾波器所需的周期數。然后還可使用該表達式計算出采用前面所列算法的最大濾波速率。可將用于產生音頻采樣的功能分成3部分:初始化、濾波器計算循環以及結果修正。在該例中,初始化需要38個周期,濾波器計算中每個濾波器參數需要17個周期,結果修正需要9 + (6 x S)個周期,其中S是移位數。通常,移位數為12,則結果修正為81個周期。因此,需要119 + (17 x N)個周期產生一個濾波輸出結果。20MHz時,MAXQ2000可以運行近11kHz的100抽頭濾波器,這已經是相當好的語音質量。
現在回到前面重新分析應用程序以進一步進行簡化。我們將主要針對濾波器循環,因為此處占用了多數周期,并且最煩瑣。
還可以對循環代碼進行幾處關鍵改進以提高效率。注意,我們采用了預先錄制并存儲在代碼區的音頻采樣。由于MAXQ采用哈佛體系結構,因此查找代碼空間比查找數據空間需要更多的時間。稱為UROM_MOVEDP1INC和UROM_MOVEDP0DEC的函數每個執行需要5個周期(LCALL為2周期,函數內部為3周期)。如果濾波器存儲在RAM中并處理存儲在RAM中的實時輸入數據,則每個只需兩周期(一個周期選擇指針,一個周期讀)。如果將RAM中的256個字用于濾波器,可用BP[Offs]實現一個環形緩沖區來存儲輸入數據。這些改動可將循環時間由17個周期縮短為11個。這樣的濾波器循環為下所示(在注釋中首先列出所需周期數):
zeroes_filterloop: move A[0], DP[0] ; 1, let's see if we are out of data cmp #W:rawaudiodata ; 2, compare to the start of the audio data move DP[1], DP[1] ; 1, select DP[1] as our active pointer move GR, @DP[1]++ ; 1, get next filter coefficient move MA, GR ; 1, multiply filter coefficient... move BP, BP ; 1, select BP[Offs] as our active pointer move GR, @BP[Offs--] ; 1, get next filter data move MB, GR ; 1, multiply audio sample... jump e, zeroes_outofdata ; 1, stop if at the start of the audio data djnz LC[0], zeroes_filterloop ; 1將濾波器及輸入數據裝入RAM后還可以利用MAXQ體系結構的另一特點。MAXQ指令集高度不相關,在任何操作中,對采用何種源幾乎沒有限制。因此,可不將濾波器數據和輸入數據讀入GR,而是直接寫入MAC寄存器。這樣可使循環降至9個周期。
zeroes_filterloop: move A[0], DP[0] ; 1, let's see if we are out of data cmp #W:rawaudiodata ; 2, compare to the start of the audio data move DP[1], DP[1] ; 1, select DP[1] as our active pointer move MA, @DP[1]++ ; 1, multiply next filter coefficient move BP, BP ; 1, select BP[Offs] as our active pointer move MB, @BP[Offs--] ; 1, multiply next filter data jump e, zeroes_outofdata ; 1, stop if at the start of the audio data djnz LC[0], zeroes_filterloop ; 1最后的修改可極大改進該代碼。每次循環時,比較當前數據指針和音頻輸入數據起始位置,以查看是否越界(MOVE A[0], DP[0]語句,CMP比較語句以及JUMP E語句)。如果設置初始音頻數據(現在正在讀取的、BP[Offs]指向的環形緩沖)為全零,則可以省略這些檢查。與后面的幾千次采樣每次節省4周期相比,RAM初始化為全零的時間可忽略,新的循環代碼縮減至5個周期。
zeroes_filterloop: move DP[1], DP[1] ; 1, select DP[1] as our active pointer move MA, @DP[1]++ ; 1, multiply next filter coefficient move BP, BP ; 1, select BP[Offs] as our active pointer move MB, @BP[Offs--] ; 1, multiply next filter data djnz LC[0], zeroes_filterloop ; 1在回到性能方程之前,先查看一下結果計算。看起來當前并不需要移位48位結果。
move A[2], MC2 ; get MAC result HIGH move A[1], MC1 ; get MAC result MID move A[0], MC0 ; get MAC result LOW move APC, #0C2h ; clear AP, roll modulo 4, auto-dec AP shift_loop: ; ; Because we use fixed point precision, we need to shift to get a real ; sample value. This is not as efficient as it could be. If we had a ; dedicated filter, we might make use of the shift-by-2 and shift-by-4 ; instructions available on MAXQ. ; move AP, #2 ; select HIGH MAC result move c, #0 ; clear carry rrc ; shift HIGH MAC result rrc ; shift MID MAC result rrc ; shift LOW MAC result djnz LC[1], shift_loop ; shift to get result in A[0] move APC, #0 ; restore accumulator normalcy move AP, #0 ; use accumulator 0一個可能的方法是再次采用MAC。不采取右移12位(或0和16間的任一數值),而是向左移16減去該值的位數(如左移4位)。這會使結果處于MAC寄存器16位字的中間。注意,左移的實際結果是乘以2的若干次冪(假如開始準備右移12位時,為16)。
; ; don't care about high word, since we shift left and take the ; middle word. ; move A[1], MC1 ; 1, get MAC result MID move A[0], MC0 ; 1, get MAC result LOW move MCNT, #20h ; 1, clear the MAC, multiply mode only move AP, #0 ; 1, use accumulator 0 and #0F000h ; 2, only want the top 4 bits move MA, A[0] ; 1, lower word first move MB, #10h ; 1, multiply by 2^4 move A[0], MC1R ; 1, get the high word, only lowest 4 bits significant move MA, A[1] ; 1, now the upper word, we want lowest 12 bits move MB, #10h ; 1, multiply by 2^4 or MC1R ; 1, combine the previous result and this one ; ; result is in A[0] ;這將花費12個周期進行結果計算,而不是9 + (6 x S)個周期。
現在回到前面的方程中。新方程保守估計開銷占用40個周期,每個循環迭代占5周期。采用與前面相同的100抽頭濾波器,MAXQ2000能夠處理16位、37kHz單聲道音頻數據,如表1所示。
表1. FIR濾波器最大采樣速率(20MHz MAXQ2000,循環)
Filter Length (Taps) | Max Rate (Hz) |
50 | 68965.51724 |
100 | 37037.03704 |
150 | 25316.4557 |
200 | 19230.76923 |
250 | 15503.87597 |
300 | 12987.01299 |
350 | 11173.18436 |
對于需要更高采樣率的應用、可犧牲代碼空間進一步提高性能。可以“內嵌”濾波器參數,不再需要選擇有效指針和循環(該技術也稱為循環展開)。這種改變的代價是增加代碼空間,以前需要100個字來存儲一個100個點的濾波器;現在,則需要300個字來存儲(每個參數移動為2個字,每個數據移動為1個字)。在16k字的器件中,相對于性能的提高,這種代價可忽略。新代碼形式如下:
move BP, BP ; select BP[Offs] as our active pointer zeroes_filtertop: move MA, #FILTERCOEFF_0 ; 2, multiply next filter coefficient move MB, @BP[Offs--] ; 1, multiply next filter data move MA, #FILTERCOEFF_1 ; 2, multiply next filter coefficient move MB, @BP[Offs--] ; 1, multiply next filter data move MA, #FILTERCOEFF_2 ; 2, multiply next filter coefficient move MB, @BP[Offs--] ; 1, multiply next filter data . . . move MA, #FILTERCOEFF_N ; 2, multiply next filter coefficient move MB, @BP[Offs--] ; 1, multiply next filter data ; ; filter calculation complete ;為計算這種改動的性能優點,再次假設開銷為40周期,但是現在每循環迭代為3周期,但實際上消除了循環。這樣100抽頭濾波器最大可處理58kHz (參見表2)。
表2. FIR濾波器最大采樣速率(20MHz MAXQ2000,循環展開)
Filter Length (Taps) | Max Rate (Hz) |
50 | 105263.1579 |
100 | 58823.52941 |
150 | 40816.32653 |
200 | 31250 |
250 | 25316.4557 |
300 | 31250 |
350 | 27027.02703 |
支持IIR濾波器
盡管本應用筆記沒有演示IIR濾波器,但并不表明MAXQ2000不支持該濾波器。所需改動為:- 使用一段專用RAM來存儲最后的輸出采樣(環形緩沖中使用該方法最有效,BP[Offs]寄存器的使用方式與前面描述的相似)
- 包括濾波器的反饋(‘y'部分)特征參數
- 加入另一個循環,該循環持續累加濾波器反饋部分的乘積結果
評論
查看更多