Summary: You will implement band-pass finite impulse-response (FIR) filters with time-domain processing.
filter.asm1 .copy "core.asm" ; Copy in core file 2 ; This initializes DSP and jumps to "main" 3 4 FIR_len .set 8 ; This is an 8-tap filter. 5 6 .sect ".data" ; Flag following as data declarations 7 8 .align 16 ; Align to a multiple of 16 9 coef ; assign label "coeff" 10 .copy "coef.asm" ; Copy in coefficients 11 12 .align 16 13 firstate 14 .space 16*8 ; Allocate 8 words of storage for 15 ; filter state. 16 17 .sect ".text" ; Flag the following as program code 18 main 19 ; Initialize various pointers 20 stm #FIR_len,BK ; initialize circular buffer length 21 stm #coef,AR2 ; initialize coefficient pointer 22 stm #firstate,AR3 ; initialize state pointer 23 stm #1,AR0 ; initialize AR0 for pointer increment 24 25 loop 26 ; Wait for a new block of 64 samples to come in 27 WAITDATA 28 29 ; BlockLen = the number of samples that come from WAITDATA (64) 30 stm #BlockLen-1, BRC ; Put repeat count into repeat counter 31 rptb endblock-1 ; Repeat between here and 'endblock' 32 33 ld *AR6,16, A ; Receive ch1 into A accumulator 34 mar *+AR6(2) ; Rcv data is in every other channel 35 ld *AR6,16, B ; Receive ch2 into B accumulator 36 mar *+AR6(2) ; Rcv data is in every other channel 37 38 ld A,B ; Transfer A into B for safekeeping 39 40 ; The following code executes a single FIR filter. 41 42 sth A,*AR3+% ; store current input into state buffer 43 rptz A,(FIR_len-1) ; clear A and repeat 44 mac *AR2+0%,*AR3+0%,A ; multiply coef. by state & accumulate 45 46 rnd A ; Round off value in 'A' to 16 bits 47 48 ; end of FIR filter code. Output is in the high part of 'A.' 49 50 sth A, *AR7+ ; Store filter output (from A) into ch1 51 sth B, *AR7+ ; Store saved input (from B) into ch2 52 53 sth B, *AR7+ ; Store saved input to ch3...ch6 also 54 sth B, *AR7+ ; ch4 55 sth B, *AR7+ ; ch5 56 sth B, *AR7+ ; ch6 57 58 endblock: 59 b loop 図 1 |
filter.asmは入力チャンネル1からの信号にFIRフィルタを適用し、その結果生じた出力を出力チャンネル1に送ります。さらに、それは、オリジナル信号も出力チャンネル2に送ります。
remezコマンドを使用して下さい。 詳細はhelp remezをタイプしてください。 これらのフィルタを別々に異なるファイルへ保存するために、save_coefコマンドを使用してください。(保存する前にフィルタ係数のベクトルを逆にすることを確かめてください。) 後に、テスト・ベクトルを生成するためにフィルタが必要になるので、MATLABマトリックスとしてフィルタを保存してください。これはMATLABのsaveコマンドを使って行うことができます。一旦これが終わった後、各フィルタの周波数レスポンスのグラフを描画するfreqzコマンドを使用してください。
filter.asmを編集してください。
FIR_lenを20に変更する必要があります。FIR_lenは、数字を記号名に指定する.setという指示を使用するセットです。これをFIR_len .set 20に変更して下さい。
.copyという指示が正しい係数を導くことを確かめて下さい。最初のフィルタ用に係数を含んでいるファイルを示すためにファイル名を変更してください。
.alignと.spaceの指示を適切に修正します。 TI TMS320C54x DSPは、バッファーの長さより2乗倍数以上であるアドレスで始まるように、FIRフィルタ係数およびステートバッファのために使用される循環的なバッファーが提携することを必要とします。 ここでは(20要素からなるステートおよび係数バッファーを使用する)20-タップフィルタを使用しているので、次の2乗は32です。
したがって、32倍のアドレスにステートおよび係数バッファを整列させる必要があるでしょう。(16要素からなるバッファーは、さらに32の倍数に整列させる必要があるでしょう。)
これは.alignコマンドで終了します。さらに、メモリはステートバッファのために保存されるでしょう。これは、.spaceという指示(割り付けるためのスペースのビット数を入力)を使用して終わります。したがって、20単語の記憶域を割り付けるためには、以下のように.space 16*20をいう指示を使用してください:
1 .align 32 % Align to a multiple of 32
2 coef .copy "filter1.asm" % Copy FIR filter coefficients
3
4 .align 32 % Align to a multiple of 32
5 state .space 16*20 % Allocate 20 words of data space
0xFFE0にPMSTをセットしてDSPをリセットし、実行してください。 それが正確な周波数反応である事を確認してください。 このコードが適切に動くことを確認した後、次のステップに移ってください。
filter.asmファイルのコピーを作ってください。 前パートからの作動中のフィルタを修正して作業するのではなく、このコピーから作業してください。 そのコードは後に使用されます。
.alignと.copyを使用する必要があります。 また、係数の第2セットへのポインターを初期化し、第2フィルタのために計算をする指示を加える必要があります。
AR4およびAR5を使用せずに、デュアルチャネルシステムを実行することができますか。 これがより困難なのは何故でしょうか。.asgを使用してAR4とAR5を改名する方法は、正解ではありません!
firsという指示が、係数がデータ・メモリの代わりにプログラム・メモリ内に配置されるのを予期することと、(2)firsが、そのステートが2つの別個の循環バッファーへ分割されるのを要求することです。 4-59ページに記載されているMnemonic
Instruction Setというマニュアル内のfirsの指示を参考にしなさい。また、詳細(Volumes 2 and
4 と TMS320C54x DSP Reference
Set)についてはApplications
Guideの4-5ページ から 4-8ページにある、その使用法の説明と例も参考にしなさい。
AR0は、このコードが適切に機能するために、-1にセットされる必要があります。なぜでしょうか?
COEFF は,今プログラム・メモリにあると予想される係数へのラベルです。詳細はfirsに関する記述を参照しなさい。
1 mvdd *AR2,*AR3+0% ; write x(-N/2) over x(-N)
2 sth A,*AR2 ; write x(0) over x(-N/2)
3 add *AR2+0%,*AR3+0%,A ; add x(0) and x(-(N-1))
4 ; (prepare for first multiply)
5
6 rptz B,#(FIR_len/2-1)
7 firs *AR2+0%,*AR3+0%,COEFF
8 mar ??????? ; Fill in these two instructions
9 mar ??????? ; They modify AR2 and AR3.
10
11 ; note that the result is now in the
12 ; B accumulator
1 stm #(FIR_len/2),BK ; initialize circular buffer length
2 stm #firstate_,AR2 ; initialize location containing first
3 ; half of states
4
5 stm #-1,AR0 ; Initialize AR0 to -1
6
7 stm #firstate2_,AR3 ; initialize location containing last half
macという指示を使用して実行された同じフィルタの出力と比較しなさい。 結果は同じですか? その理由は何故でしょうか? フィルタされた出力が、チャンネル1を出力するために送られる事と、未変更の出力が、まだチャンネル2を出力するために送られることを確認しなさい。
Comments, questions, feedback, criticisms?