Connexions

You are here: Home » Content » FIR Filtering: Exercise for TI TMS320C54x (Japanese Version)
Content Actions

FIR Filtering: Exercise for TI TMS320C54x (Japanese Version)

Module by: Douglas L. Jones, Swaroop Appadwedula, Matthew Berry, Mark Haun, Jake Janovetz, Michael Kramer, Dima Moussa, Daniel Sachs, Brian Wade, Patrick Frantz, Emiko Yamai, Hironori Takaryo, Yoji Yamada Based on: FIR Filtering: Exercise for TI TMS320C54xDouglas L. Jones, Swaroop Appadwedula, Matthew Berry, Mark Haun, Jake Janovetz, Michael Kramer, Dima Moussa, Daniel Sachs, Brian Wade

Summary: You will implement band-pass finite impulse-response (FIR) filters with time-domain processing.

Introduction

この演習で、FIRフィルタを作成するためにDSPのアセンブリ言語でプログラムします。基礎的なFIRフィルタのためのアセンブリコードを勉強することから始めて下さい。filter.asm.
filter.asm
	   1	.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に送ります。
まず始めに、この演習中のファイルのためのネットワークドライブ上にワークディレクトリを作成し、それにfilter.asmcore.asm をコピーしてください。 次に、2つの20-タップFIRフィルタを生成するためにMATLABを使用してください。 第1フィルタは4kHzから8kHzの信号を通過させ、第2フィルタは8kHzから12kHzまでの信号を通過させます。 両方のフィルタに対し、フィルタ通過帯域の各端に1kHの遷移域を許可してください。 これらのフィルタを作成するために、最初にシステムの44.1kHzのサンプル割合に基づいたデジタル周波数にこれらの域の端を変換し、次に、このフィルタを生成するためにMATLABのremezコマンドを使用して下さい。 詳細はhelp remezをタイプしてください。 これらのフィルタを別々に異なるファイルへ保存するために、save_coefコマンドを使用してください。(保存する前にフィルタ係数のベクトルを逆にすることを確かめてください。) 後に、テスト・ベクトルを生成するためにフィルタが必要になるので、MATLABマトリックスとしてフィルタを保存してください。これはMATLABのsaveコマンドを使って行うことができます。一旦これが終わった後、各フィルタの周波数レスポンスのグラフを描画するfreqzコマンドを使用してください。

パート1: シングルチャネル FIRフィルタ

現時点では、4kHzから8kHzの通過帯域フィルタのみを実行します。いくつかの変更を加えて、このフィルタ用の係数を使用するためにfilter.asmを編集してください。
最初に、この演習用のFIRフィルタの長さは8ではなく20です。したがって、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
      
コードを組み立てて、0xFFE0PMSTをセットしてDSPをリセットし、実行してください。 それが正確な周波数反応である事を確認してください。 このコードが適切に動くことを確認した後、次のステップに移ってください。

パート2: 2重チャンネルFIRフィルター

最初に、パート1から修正済のfilter.asmファイルのコピーを作ってください。 前パートからの作動中のフィルタを修正して作業するのではなく、このコピーから作業してください。 そのコードは後に使用されます。
次にそのコードを修正し, チャンネル1を出力するための(4kHzから8kHzの通過域を備えた)最初のフィルタの出力および, チャンネル2を出力するためのフィルタされてない入力を送ることに加えて、それがチャンネル3を出力するための(8kHzから12kHzの通過域を備えた)2番めフィルタの出力を送る。 これを行うために、データ・メモリに係数の第2のセットをロードするための.align.copyを使用する必要があります。 また、係数の第2セットへのポインターを初期化し、第2フィルタのために計算をする指示を加える必要があります。
Problem 1: 発展問題
補助レジスタであるAR4およびAR5を使用せずに、デュアルチャネルシステムを実行することができますか。 これがより困難なのは何故でしょうか。.asgを使用してAR4AR5を改名する方法は、正解ではありません!
DSP Development Environment: Introductory Exercise for TI TMS320C54xで紹介されている技術を使って、適切なテスト・ベクトルと予想されるMATLABの出力を生成しなさい。 その後、DSP Development Environment: Introductory Exercise for TI TMS320C54xで紹介されているテストベクトルコアファイルを使用して、このテスト・ベクトルにより与えられるシステムの出力を見つけなさい。 MATLABで、予想されるフィルタの出力と実際のフィルタの出力、及びその2つの出力間の違いを作図しなさい。なぜDSPシステムからの出力は、MATLABからの出力と実際には同じではないのでしょうか。

パート3: 代替シングルチャンネルFIRの実行

対称なFIRフィルタを実行する為の代替方法では、firsという指示を使用します。firsを使用する、4kHzから8kHzの通過域を備えたフィルタを実行する為に、パート1からのコードを修正しなさい。
パート1からのコードと、このパートで書くコード間の実行における2つの差は、(1)firsという指示が、係数がデータ・メモリの代わりにプログラム・メモリ内に配置されるのを予期することと、(2)firsが、そのステートが2つの別個の循環バッファーへ分割されるのを要求することです。 4-59ページに記載されているMnemonic Instruction Setというマニュアル内のfirsの指示を参考にしなさい。また、詳細(Volumes 2 and 4TMS320C54x DSP Reference Set)についてはApplications Guide4-5ページ から 4-8ページにある、その使用法の説明と例も参考にしなさい。
AR0は、このコードが適切に機能するために、-1にセットされる必要があります。なぜでしょうか?
Note: 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
      
ステートと係数が、現時点で以前のFIR実行の時とは異なった扱いであるため、下記のようにポインターの初期化を修正する必要があります。
	
	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
	
      
2つのフィルタシステムをテストするために使用したのと同じテスト・ベクトルにより与えられるこのシステムの出力を見つけるために、テストベクトルコアファイルを使用しなさい。このコードの出力を、macという指示を使用して実行された同じフィルタの出力と比較しなさい。 結果は同じですか? その理由は何故でしょうか? フィルタされた出力が、チャンネル1を出力するために送られる事と、未変更の出力が、まだチャンネル2を出力するために送られることを確認しなさい。

Comments, questions, feedback, criticisms?

Discussion forum

Send feedback