Summary: You will work through a section of TI TMS320C54x assembly code by hand. The instructions include multiplication of fractional numbers in two's complement representation.
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 จะทำการใช้ FIR filter กับอินพุต channel ที่ 1 แล้วทำการส่งผลลัพธ์ที่ได้ไปยัง channel ที่ 1 พร้อมกับส่ง อินพุตที่ไปยัง channel ที่ 2
remez ในการสร้าง filter; อาจลองพิมพ์
help remez สำหรับ รายละเอียดของการใช้คำสั่ง และใช้คำสั่ง
save_coefsave filter แต่ละตัวคนละไฟล์ (ตรวจดูก่อน save ว่าได้ทำการกลับเวคเตอร์ ของ filter coef เรียบร้อยแล้ว)
ทำการ save filter ในรูปของ MATLAB matrix ด้วย เพราะคุณจะต้องใช้มันภายหลังในการสร้าง test เวคเตอร์
สารมารถทำได้โดย ใช้คำสั่ง save ใน MATLAB
เมื่อเสร็จเรียบร้อยแล้ว ให้ใช้คำสั่ง freqz
ในการสร้าง frequency response ให้แต่ละ filter
filter.asm เพื่อใช้ coefficient สำหรับ filter ตัวนี้
FIR_len เป็น
20. FIR_len โดยใช้ directive .set
ซึ่งสามารถ set ค่า ได้โดย assign ค่าตัวเลขให้ FIR_len .set 20.
.copy
directive copy ค่า coefficients ที่ถูกต้อง. เปลี่ยนชื่อไฟล์ เป็นชื่อไฟล์ที่เก็บค่า
ของ coefficients ที่ใช้สำหรับ filter ตัวแรก
.align และ
.space directives ต่างๆ ตามความเหมาะสม. TI
TMS320C54x DSP ต้องใช้ circular buffers, เพื่อใช้สำหรับ
FIR filter coefficient และ state buffers, ซึ่งถูก set ให้ตรงกัน
โดยให้ address เริ่มต้น เป็นค่ายกำลังสอง
so that they begin at an address that is a multiple of a power
of two greater than the length of the buffer. Since you are
using a 20-tap filter (ซึ่งใช้ 20-element state และ
coefficient บัฟเฟอร์), the next greater power of two is 32.
ฉะนั้นคุณจะต้องทำการตั้งค่า address ของทั้ง state และ coefficient
บัฟเฟอร์ เป็นจำนวนเท่าของ 32
(16-element บัฟเฟอร์จะต้องถูกตั้งค่าให้เป็นจำนวนเท่าของ 32 เช่นกัน)
ซึ่งสามารถทำได้โดยใช้คำสั่ง .align นอกจากนี้หน่วยความจำยัง
ต้องถูกจองไว้ให้ state บัฟเฟอร์ด้วย ทำได้ โดยใช้ directive
.space ซึ่งจะรับจำนวน bits
ของเนื้อที่ทที่ต้องการ . ฉะนั้นถ้าต้องการ เนื้อที่ 20 word จะต้องใช้
directive .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
PMST เป็น
0xFFE0, reset DSP, แล้ว run. ตรวจดูว่า ค่าความถี่ที่ตอกลับ
มานั้นถูกต้อง หลังจากที่แน่ใจว่า code ทำงานได้ถูกต้องแล้ว ให้เริ่มขั้นต่อไป
filter.asm ที่ถูกทำการแก้ไข
เรียบร้อยแล้ว จากไฟล์ Part 1.
ใช้ไฟล์นี้ในการทำงาน อย่าทำการแก้ไข filter ที่ใช้ก่อนหน้านี้ เพราะจะมี
การใช้ filter ตัวเดิมอีกในภายหลัง
.align และ
.copy คำสั่งในการ load ชุดของ coefficients ชุดที่สอง
ไปยัง data memory. นอกจากนี้จะต้องเพิ่มคำสั่ง เพื่อ initialize ค่าของ
pointer ให้ชี้ไปยัง coefficients ชุดที่สอง และคำนวณค่าให้ filter ตัวที่สอง
AR4 และ AR5 ได้หรือไม่ ?
ทำไมมันถึงยากกว่าปกติ ? การเปลี่ยนชื่อ AR4 และ AR5
โดยใช้ .asg ถือว่าไม่นับ!
firs instruction. แก้ไข
code จาก Part 1 เพื่อ implement
filter ที่ใช้ passband 4 kHz to 8 kHz โดยใช้ firs.
firs คำสั่งนี้จะทำให้ coefficients
ถูก locate ในส่วนของ program memory แทนที่จะใช้
data memory, และ (2) firs จะทำให้ states
ถูกแยกออกเป็น สอง circular buffer. อ้างอิงจาก firs
คำสั่งบน หน้า 4-59 ใน
คู่มือ Mnemonic Instruction Set ซึ่งมีทั้งคำอธิบายและตัวอย่างการใช้
หน้า 4-5 จนถึง 4-8 ของ Applications
Guide ถ้าหากต้องการข้อมูลเพิ่มเติม (Volumes 2 and
4 respectively of the TMS320C54x DSP Reference
Set).
AR0 ต้องถูกตั้งค่าเป็น -1 เพื่อที่จะให้โปรแกรมทำงานได้ถูกต้อง
ทำไม? COEFF เป็นตัวระบุว่า coeffients ตัวไหนที่จะถูกโหลดเข้า
ไปใน program memory. อ้างอิงจาก คำอธิบายของ
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 ผลลัพธ์เหมือนกันหรือไม่?
ทำไมเหมือนหรือทำไมไม่เหมือน? ตรวจให้แน่ใจว่าผลลัพธ์ถูกส่งไป
ที่ channel 1, และ ผลลัพธ์ที่ไม่ได้ ถูก filter ไปที่ output channel 2.
Comments, questions, feedback, criticisms?