To illustrate transcribing the C program for the FIR filter into DSP assembly language, I will use the assembler syntax of the Lucent DSP32C processor. This processor is excellent for this purpose, because its assembler syntax is remarkably similar to C language and so makes it easy to see how the C code maps onto the underlying DSP architecture. It is important to note that the illustration remains valid in general for most DSP processors, since their basic design features are so similar: but the other processors have more impenetrable assembler syntax.
*r3 is equivalent to the C syntax *c_ptr
*r3++ is equivalent to the C syntax *c_ptr++
a1 is equivalent to the C declaration float temp
Some examples of simple DSP32C instructions show the similarity to C further:
- a1=*r3
- fetch a floating point value from memory pointed to by address register r2 and store it in the float register a1
- a1=*r3++
- fetch a floating point value from memory pointed to by address register r3 and store it in the float register a1: having done so, increment address register r3 to point to the next floating point value in memory
The general DSP32C instruction syntax shows the typical DSP processor's ability to perform a multiplication and addition in a single instruction: a = b + c * d
Each term in the instruction can be any of the four floating point registers, or up to three of the terms can access data through address registers used as pointers:
a0=a1 + a2 * a3 - using only registers
a0=a1 + *r2 * *r3 - using pointers for two memory reads
a1=a1 + *r2++ * *r3++ - using pointers for memory reads and incrementing those pointers
Armed with the above rudimentary knowledge of this DSP processor's assembler syntax, we can substitute assembler variables for the C variables:
temp: - a1 (floating point register)
y_ptr: - r2 (address register to be used as a pointer)
c_ptr: - r3 (address register to be used as a pointer)
x_ptr: - r4 (address register to be used as a pointer)
The appropriate assembler can now be written underneath the C code, exploiting the great similarity of the assembler to C in this case: temp = *c_ptr++) * *x_ptr--);
a1 = *r3++ * *r4--
for (k = 1; k < N-1; k++)
do 0,r1
temp = temp + *c_ptr++ * *x_ptr--)
a1 = a1 + *r3++ * *r4--
*y_ptr++ = temp
*r2++ = a1
Note that for this processor, one line of C compiles down to one assembler instruction.
The 'do 0,r1' instruction is an efficient and concise way to replace the loop control: it means, "do the next (0+1) instructions (r1+1) times. This is an example of a 'zero overhead do loop': the processor supports this special instruction with no overhead at all for the actual execution of the loop control. |