EE265 Lab 3 Notes

Due Thursday 2/5/2009

Winter 2008-2009
Instructor: Teresa Meng

What to submit

- demonstration of functionality and verification during office hours

- hard copies of

    - lab writeup

    - fir_proc.s55

    - Matlab plots of expected output, measured output, and absolute error for all four filter types and both channels 

- Submit to dropoff box soft copies of

    - fir_proc.s55

    - userlinker.cmd

    - Matlab verification .m file

 

Goals

- Correct functionality of time-domain filter and real-time filter changing

- Good code design

- At most 8000 cycles for fir_proc filtering will get you full credit for the "performance" component of your grade.

- Good writeup

 

Tips

 

*THIS CLASS STARTS GETTING SERIOUS FROM HERE, SO START EARLY!*

 

DESIGN

- Obtaining filter taps

If you modify your hw3 filters to have 81 taps, you should get filters that follow the same pattern as lab1, in terms of symmetry and periodic zeros. Just get rid of the 81st tap, which is 0. This way, you can reuse your lab1 code.

 

- Storing filter taps

As long as your algorithm is correct, you are allowed to manipulate exactly which coefficients to store in memory (e.g., store the zeros or not, store the other symmetrical half or not).

 

- Buffering strategy

You may need to use a buffer for this lab, similar to lab2d. It could be linear or circular addressed. There are a few possible buffering strategies. Which one you choose is up to you. It is recommended that you discuss your strategy with the TA before proceeding to development.

 

 

DEVELOPMENT

- C vs. assembly

You may prototype your filtering algorithm in a combination of C and assembly, but your final product should be entirely in assembly. Notice that you are not submitting audio.c.

 

- Arithmetic on circular-addressed registers

As some of you already know, there's a tricky thing about handling XAR with circular addressing. Let's say we want to increment XAR4 by 4, and XAR4 is addressed in circular mode. You may do this with ADD instruction, but that ADD instruction is simply arithmetic addition, so the AR4 modification is not circular. Instead, use AADD. See the manual for details.

 

- Nested loops

Set BRC0 and BRC1 before your outer loop. See Mnemonic Reference Guide page 5-407 for a description of what goes on.

- rounding / saturation on store
Probably you will use M40 and SATD for filtering. However, with M40, saturation occurs on the 40th bit of accumulator, providing larger signal range with guard bits. However, only the bits 31 to 16 ( HI(ACx) ) shall be stored at the end. MOV HI(ACx), Smem instruction can perform optional "saturate" and "rounding" with store operation (rounding is adding 0x00008000 to the accumulator,
which is a rounding of LO(ACx) to HI(ACx)). It is reported that sometimes the filtering error is slightly biased (average is not zero) if rounding is not used on store.

- rounding mode
Setting RDM doesn't do anything, unless you do rounding: either the rnd instruction or the rnd option in the store instruction. It only sets the rounding mode to 1. (default rounding mode is 0). For more information on rounding mode, look at the CPU Reference Guide. Generally, rounding mode doesn't affect the result much, but theoretically rounding mode '1' is better. Basically, rounding mode '0' rounds up, and rounding mode '1' rounds to the nearest value.


- Receive/Transmit buffer size
Audio receive/transmit buffer size is defined in audio.h. If you want to use a buffer size other than 192, modify the #define statement in audio.h. Your code should work for any even-numbered buffer size greater than or equal to the number of filter taps, but you will assess your performance based on a 192-sized receive/transmit buffer.

- Setting loop counter
Since we may (or may not) want to change the rcv/xmt buffer size (as mentioned above), it's not a good idea to hard code the outer loop count of filtering, and I'll expect you to use the value stored in _size to set the outer loop count. You can assume that the rcv/xmt buffer size is build time constant.

 

- Magic numbers (aka constants)

Please .set them at the top of your assembly code. The only ones that should appear in the body of your code are:

    - the number of filter taps

    - the period of the zeros in the filter taps

Don't worry about .set-ting pointer increment values, etc.

 

- change_filter_asm

Two basic strategies

  - use a bunch of branch instructions that use filterType (more cycles, less memory)

  - store a table of pointers to filter coefficient addresses, and use the filterType as an offset to the table (fewer cycles, more memory)

Which strategy you choose is up to you.

 

 

DEBUGGING
- Why does the processor crash?
Sometimes, your DSP crashes (e.g. CCS goes out, "S/W breakpoint..." in CCS display window, ...). The followings are frequently reported causes of system crash.
    - Setting a weird value to a pointer (XAR or XCDP), then performing a store
    - Using circular addressing, but not restoring the ARnLC before return
    - Using callee-saved registers without backup

    - Setting the loopcount too big, while the destination pointer doesn’t use circular addressing when it should

 

- Compiler complains that my RPTBLOCAL block is too big.

Try using RPTB instead of RPTBLOCAL.

 

- Compiler doesn't let me do *(CDP+T1)

But it does let you do *(CDP+T0). See Mnemonic Reference -> addressing modes for the legal uses. Yes, it's absurd, but that's life.

 

MATLAB verification
- I get huge errors when the signal level becomes small.

Don't look at the percent error (100*abs(orig - result)/orig). Just look at the absolute error (abs(orig - result)).

 

- I'm off by a factor of something.

That something is 2^15: 2^16 for the upper 16 bits of the accumulator stored in memory, and 2^-1 for the effect of the FRCT bit.