EE265 Lab 3: Filtering
Winter 2008-2009
Instructor: Teresa Meng
I. Purpose:
The purpose of this lab is to
build the framework for real-time filtering. Additional modules in the DSP/BIOS
for handling host-to-EVM communication will be introduced. We will go into
detail on how to setup the DSP/BIOS and how to control the DSP program from the
host computer. As lab exercises, you will implement the framework for
filtering. We will look at the hardware implementation issues of digital
filters. And you will apply what you learned from the lectures and use this to
experiment with filtering theories you learned in the lecture.
II. Lab exercises:
As much as you think you know
about filtering, there are always things you can learn by implementing them in
real-time. In this lab, you will be playing with a variety of different filters
and hearing the differences. This will also be the last lab where detailed
procedure for working with the development tools will be given. From the next
lab on, you are on your own in the sense of figuring out how to incorporate
certain extended features of the DSP development tool into your code.
A. Host/EVM Control
A detailed procedure on how to setup
a host/EVM control channel is provided in this section. This allows you to use
a Visual Basic program to send control information to the EVM in real-time. As
in Lab 1's FIR filtering demo, this control information allows the host
computer to choose between several types of FIR filters to use for processing.
This is convenient in that you can compare different types of filters without
having to halt the DSP.
1. Configuring DSP/BIOS
- Start
a new DSK5509A session.
- A template based on the setup
in lab 2 is lab3/fir_tmpl. Create your own project directory
lab3/fir, and download and
decompress this template. Then, open the
project, fir.pjt,
in your lab3/fir directory.
- Expand
the DSP/BIOS Config folder and open the file, fir.cdb.
- Our first task is to enable
RTDX so that we can control our DSP code from the PC in real time. This will allow us to choose which specific FIR filter to use. To enable
RTDX, right click on the Input/Output->RTDX
module and select Properties.
- In the Properties dialog box, select Enable
Real-Time Data Exchange (RTDX).
- We now would like to
configure the DSP/BIOS so that our filter-changing routine gets executed
once every second. In order to do this, we need to schedule a
periodic interrupt so that it calls our change_filter
function. Under Scheduling,
insert a new PRD (right click on the PRD -
Periodic Function Manager module and select Insert PRD).
- Rename PRD0 to change_filter_PRD.
- Change the following
properties in the change_filter_PRD:
- period(ticks): - 1000. 1 period tick = 1 ms. This means that the function defined here will
execute once every second.
- function: - _change_filter.
This is the function that will be executed every 1000 period ticks.
Note: The PRD module uses the timer
interrupt to update the period ticks. You can see this by expanding the CLK - Clock Manager module. It is a PRD_clock object, which
calls the function PRD_F_tick
every 1 ms.
Expand
the SWI module. You will
see that a new object, PRD_swi,
is automatically added. The PRD_swi
is the software interrupt handler that executes a specific PRD object when that object's timing condition is
met. This software interrupt handles all PRD
objects.
Click
on the SWI module itself and look at
the priority listings. (In order to see the
listings, you may need to maximize your cdb-editor
window and possibly select "Property/value view" from the right-click
menu.) Note that the PRD_swi
has priority 2 and audioSwi
has priority 1.
- Raise the
priority of audioSwi
to 2 because audioSwi
is more critical to real-time operation.
- This is all we
need to do as far as DSP/BIOS is concerned. Save and close the configuration file, fir.cdb.
- Open
the file, audio.c,
for editing.
- Add the following lines to audio.c:
- Make
sure rtdx.h is included, like so:
#include <rtdx.h>
- Comment
out the _change_filter_asm function declaration, like so:
//extern Void _change_filter_asm(Void); /* Updates filter type */
This will be uncommented out later.
- Make sure the
filterType global variable is added, like so:
Uns filterType = 0;
- followed by a call to an RTDX C macro (which is needed to
create/initialize a new RTDX channel, called control_channel):
RTDX_CreateInputChannel(control_channel);
- followed by a function definition (this is the function
that the change_filter_PRD object calls):
Void change_filter(Void);
- In main(),
make sure that between the statements AIC23_setParams();
and fir_proc_init();
there is a statement for enabling the RTDX channel, control_channel:
RTDX_enableInput(&control_channel);
A functional overview of RTDX is in the DSP/BIOS
User's Guide under section 3.8. More information on the RTDX
functions is available in
the DSP/BIOS
API Reference Guide under section 2.19.
- Finally, add the change_filter() function to handle control information
sent by the host computer.
Void change_filter()
{
static Int control;
/* Read new filter control when host sends it */
if (!RTDX_channelBusy(&control_channel)) {
RTDX_readNB(&control_channel, &control, sizeof(control));
if ((control < 0) || (control > 4)) {
control=0;
} else {
filterType = control;
//change_filter_asm();
}
}
}
What this function does is it checks to see if the
RTDX control_channel is busy. The RTDX control_channel is busy if there is an outstanding request
for the host to write control data onto the control channel and the host has
not done so already. The inverse implies either that there is no control
request from the EVM board and/or the control data has already been written
onto the control channel. In the latter case, a new non-blocking control
request can be made and the control channel can be checked for data.
The change_filter_asm(); function is something you will have to write to
handle the filter type updates. At this point, it is commented out so the code
template can be built to test the control channel.
- Compile
the code and fix any compilation errors before you go on to the next
section.
2. Control via RTDX channel
As
mentioned above, the filter type is controlled on the host side (your PC) via
RTDX control channel. Thus, we need to have an appropriate control program on the
host side; that is,
a control application that sends the
filter type you specify to the DSP so that change_filter
function can set the proper filter type. You can find the already completed
control function in the fir_tmpl.zip.
This is a visual basic program, and if you are interested in the programming of
such an application, download visual_basic.zip, which includes a brief guide to making
visual basic RTDX control applications using MS visual studio, and the actual FIR_Control application project files for MS visual studio
.net platform.
NOTE that there might be some differences on the
development environment between old visual studio and visual studio .net. Also,
it seems that there's a problem running visual basic executable developed by
visual studio .net on network drive due to security issue. Hence, if you made
your own version of FIR_control, and it doesn't run from the network drive, then copy it to
local drive and try it again.
3. Host-EVM Channel Test
That's all the Visual Basic you
need to write. Now you will test the linkup between the host and the EVM board
in this section.
- If you have
already closed the DSK5509A
session, then start a new DSK5509A session.
- Reload
the project file, fir.pjt,
reset the DSP and reload the fir.out executable.
- Select Tools->RTDX->Configuration Control and the RTDX form will appear at the bottom of
the screen.
- In
the RTDX form, make sure that
RTDX is disabled. Then Click on Configure. The RTDX
Configuration Control Properties dialog box will be displayed.
- In
the Mode section of the RTDX Configuration Page tab, select Continuous
Mode.
- Click
on OK to close the dialog box.
- Now enable RTDX in the RTDX Configuration Control form.
- Open audio.c for
editing.
- Locate the variable filterType
and click on it to place the
cursor on
the variable name.
- Press
<CTRL>+W or right click and select Quick Watch. The filterType variable
should be displayed in the watch
window at the bottom of the DSK5509A session window.
- Run
the DSP program.
- Run the Visual
Basic program (either run the finished FIR_Control.exe or if you
have created the VB form yourself you can go to Visual Basic and select Run->Start).
The FIR_Control
form should now be running. Note: You should
start FIR_Control after you have started the DSP
program. Otherwise, the control_channel may not be correctly initialized.
- Go back to the DSK5509A session
and select Tools->RTDX->Channel
Viewer Control to open the RTDX
Channel Viewer Control window. You should see under the Input
Channels
listing the control_channel
item. It should also be checked.
- Go to the FIR_Control form that you ran and change the filter
type to Highpass.
- Go back to the VDSK5509A session and halt the DSP program.
- Check to see if filterType (in the watch window) is now set to 4. If not, go back and forth between the FIR_Control
and the DSK5509A session.
Change the filter type in the FIR_Control
form while the DSP program is running and stop the DSP program to look at
the filterType
value in the watch window.
Use this method to verify that all 5 filter types return different values.
- Once you have verified that
everything works as described, halt the DSP
program and close the FIR_Control form.
B. Complete the Demo
You now have both the working DSP
code and the host control program. You are to complete the demonstration that
you saw in lab 1 where real-time audio signals are processed using different
FIR filters.
1. Coding Specifications
The specifications of the FIR
filters are given below:
- Implement the 4 filters, lowpass, bandstop, bandpass, and highpass, using the
filter coefficients that you created in MATLAB for Homework #3.
- The file fir_proc.s55 currently contains these four
filters implemented as all zeros. You should have
this file in your lab3/fir directory. You will need to replace
these filters with your own filter coefficients. A function is
available in the fir_tmpl.zip
that may help you format these coefficients for cutting-and-pasting into
your assembly code: write_vector_to_file_for_DSP.m.
Make sure you convert the coefficients to 16-bit fractional format for
use by the DSP
- The "Original",
non-filtered, signal should be implemented as a simple audio loop-back
(from input to output) and should demand a processing load that is significantly
less than the filtering codes. The only complexity for this unfiltered
case will be introduced in deciding when and when not to filter.
- Define the filter
coefficients such that they are allocated in the memory section, SARAM or
DARAM.
- Implement the change_filter_asm() routine using the filterType variable defined in audio.c. When you
implement the change_filter_asm()
routine, do not do any data manipulation (i.e. copy coefficients from).
This routine should only modify the address pointers to the coefficients
stored in memory.
- Do the filtering using linear
convolution, i.e. straight multiply-add.
- Note that
filtering should be performed on both channels; left and right.
2. MATLAB Verification
As in Lab 2, you will be expected to write a script to
verify your code. Here are the requirements.
- Verify that your filtering
code works correctly for all 5 filter types. (Checking one is
insufficient, since there may be problems with a specific filter but not
all of them).
- The easiest way to check each
filter individually is to hard-code the filter type in audio.c
(force the filterType to a fixed value instead
of getting the value from the Visual Basic application).
Alternatively, the script can be used interactively with the Visual Basic
application for choosing the filter type. If you want to make it more
complicated, you could have the script control the filter chosen (by
manipulating the proper memory), but this is not recommended.
Regardless of what you do, make sure that the filter works with the
coefficients in the proper location.
- The input frame should be
replaced with random data before use in the filtering operation.
- You will need to save
successive input frame values, since the FIR filtering operation relies on
past samples to filter the current input frame (just as your assembly code
needs to keep past samples). Make sure that these "old"
values are initialized to 0 in both MATLAB and your assembly code.
- To compare your
implementation with the ideal result:
- Use MATLAB to concatenate
several frames of input data together and convolve this with the filter
coefficients. Compare this ideal filtered output to the concatenation of
the DSP's output frames.
- Use the MATLAB function conv to perform
the convolution. Keep in mind that this result might contain more samples
than your DSP code produces, so you may have to align and/or crop the two
results. (Plotting might help).
- You may have to consider
whether or not you used fractional multiplication in your DSP code, since
this can affect the amplitude of your results. (Once again, plotting can
be useful).
- As a metric for whether your
code is working or not, the error between DSP and MATLAB should be
reasonable. This is because the results from the DSP will have
limited precision, whereas the MATLAB result will be in full
floating-point precision, so they can't be expected to be equal. In fact,
error level depends on how you set the inputs to MATLAB filtering; e.g.
with the quantized input data and quantized coefficients, the error is mainly
due to the limited computation of the DSP, so the error shall be within 2^-16
(if you use normalized values for the verification), or 0.5 (if you use
integer values not scaled to the range -1 to +1).
3. What to Report
After you have simulated and
verified that your FIR filter works, do the following measurements and report
them in the write-up:
- Cycle count of
your filter loop to filter one full data
frame.
- Cycle count of
your filter loop when filterType
is set to Original.
- The number
of cycles, theoretically, to process a single data buffer of 32 words.
- The average
number of cycles the filtering routine requires to output one filtered output
Execution cycles
Last modified: 10:00 pm 1/29/2008