SOC FPGA Design Lab

yakzephyrAI and Robotics

Nov 24, 2013 (3 years and 10 months ago)

73 views

SOC FPGA Design Lab

Discussion 6

SDR Lab Continued

DSP Blocks (Part II)

Schedule


Present Lab 6
briefly

and describe first step


Proceed to Lab to demonstrate lab 4 and 5.


When not being graded, work on building first
step of lab 6.


Return to lecture for complete discussion on
Lab 6 topics


After completion of lecture, Lab time for those
working on Lab 6 and Lab 5 debrief

Schedule


Next Week (4/2) :


Brief lecture describing the setup for migrating
your Lab 6 to the actual ADC / Signal Generators in
the laboratory


Covers hardware setup and timing constraints


Working session


4/9 Final Project Assigned


Working session in lab using ADC / Signal Gen for
Lab 6 testing


4/12 Lab 6 Due Electronically (11:55 pm)



Laboratory 6


Full SDR

DSP Primer


Goal : to enable debugging by understanding
how to use
Matlab

to model, verify, and
understand the signal processing chain used in
our SDR


Use
Matlab

to build
sinewaves


Take FFTs and interpret the results


Understand complex sampled data


Experiment with mixing

Construction of Sampled Sinusoids

f =
freq_of_my_sinusoid
;

Fs =
sampling_rate
;

A = amplitude;

n =
linspace
(1,numpoints,numpoints);

Sig = A * sin(2*pi*n*f/
fs
)

Builds
numpoints

of a sinusoid, sampled at Fs, with frequency f and amplitude A

n =
linspace
(1,1000,1000);

Sig = 4000 * sin(2*pi*n*1e5/25e6);

Plot(Sig);

Reminder : Euler’s Formula

Source :
http://en.wikipedia.org/wiki/Euler's_identity

Construction of Sampled Sinusoids
(Complex)

f =
freq_of_my_sinusoid
;

Fs =
sampling_rate
;

A = amplitude;

n =
linspace
(1,numpoints,numpoints);

Sig = A * exp(2*pi*j*n*f/
fs
)

Builds
numpoints

of a sinusoid, sampled at Fs, with frequency f and amplitude A

n =
linspace
(1,1000,1000);

Sig = 4000 * exp(2*pi*j*n*1e5/25e6);

Plot(Sig);

Plot(real(Sig));

Plot(
imag
(Sig));

FFT Interpretation


The N
-
point FFT taken on N input data points
can be thought of a bank of
correlators

where
each point k in the FFT represents the
correlation between the input signal and
complex sinusoid e^(j*2*pi*k*Fs/N)


Each point (bin) is of size Fs/N


Example : 8192 point FFT, Fs = 48kHz


Bin width is approx 6Hz.


FFT Interpretation

n =
linspace
(1,8000,8000);

Sig = 4000 * exp (2*pi*j*n*f/25e6);

f = 1 M

1M / (25e6/8000) = 320

f = 20 M

20M / (25e6/8000)
=6400

f =
-
5 M

FFT Interpretation

n =
linspace
(1,8000,8000);

Sig = 4000 * sin (2*pi*j*n*f/25e6);

f = 1 M

1M / (25e6/8000) = 320

At 8000
-
320,

Or
-
1MHz?

0

-
Fs/2

0

Fs/2

Frequency Translation

Graphics reprinted from :
http://bruce.cs.tut.fi/invocom/p3
-
1/p3
-
1_2_1.htm

Stated in words : if we have an input signal sig = e^(jw
1
t) and we would like to
change it’s frequency, it is as simple as multiplying by another complex
sinusoid e^(jw
2
t). The new signal is e^(j(w
1
+w
2
)t), with frequency w1+w2.

Simple Example

f1=5e6; f2=6e6;

amp1=5000; amp2=1000;

fs
=25000000;

n=
linspace
(1,10000,10000);

noise = 10*
randn
(1,100000);

sig = amp1 *
cos
(2*pi*n*f1/
fs
) + amp2*
cos
(2*pi*n*f2/
fs
);

plot(sig(1:100));

figure;

plot(20*log10(abs(
fft
(sig))));


12.5MHz

5M

6
M

Mixing for Frequency Translation

mixerfreq

=
-
3000000

mixertone

= exp(2*pi*j*n*
mixerfreq
/
fs
);

product =
mixertone

.* sig;

plot(n*
fs
/10000,(20*log10(abs(
fft
(product)))));


*

Just changes axis for plotting to put in units of Hz
instead of bins

DDS Slides


Following slides are not 100% screen captures
from the latest version of the tools


We have already discussed the DDS and you have
already made one


These slides will be talking points for the new
features which we will add for our
tuner

System parameters lets us pick how accurately we’d
like to be able to pick a frequency, and how good of
quality we’d like out of that
sinewave
. Frequency
resolution will affect the number of bits in the phase
increment, SFDR, will affect the number of bits on
the output. Your choice here, but make Resolution
<1Hz, and SFDR > 80

Use your DDS like you have
already become familiar with,
but make sure to get sine and
cosine out at the same time

CE used if sample rate is different than clock
rate. For Fs=CLK, this can be ‘1’, or not even
included.

Output_i

<=
dds_cos

*
adc_data

Output_q

<=
dds_sin

*
adc_data

We need to do a complex multiply
now, this can be done using
straight VHDL, or using the
Complex Multiplier Core. The latter
is a bit of overkill since one of our
inputs is real, but that’s ok

Mixer


Now we have:


Our input signal at Fs=25MHz


A sine and cosine signal from the DDS which is
what we will use to
downconvert

our signal to DC.


Our signal is real : x + 0*
i


DDS output =
cos

+
i
*sin


Product =
cos
*x +
i
(sin*x)


Result is a
complex

sinusoid, still sampled at
25MHz, where the entire frequency spectrum has
been shifted by the DDS frequency

After Mixing /
Downconversion

0 (DC)

12.5MHz

2.75

9.25

0 (DC)

12.5MHz

2.75

9.25

If we mixed correctly, then our channel of interest is sitting right at DC, where we

Can run it through our low pass filter from Lab 5.

One more example : Tuning


Lets start with one more set of frequencies for an example.
Two tones are created, one at 43.75, and one at 44.75.

f1=43.75e6; f2=44.75e6;

amp1=5000; amp2=1000;

fs
=25000000;

n=
linspace
(1,10000,10000);

sig = amp1*
cos
(2*pi*n*f1/
fs
) + amp2*
cos
(2*pi*n*f2/
fs
);

plot(n*
fs
/length(n),20*log10(abs(
fft
(sig))));

By plotting against this axis, our
binsize

Of
fs
/L is taken into account and the

Result is in Hz

43.75

Undersampling

: 43.75 shows up at 6.25 MHz, 44.75 shows up at 5.25 MHz

Tuning to 43.75

F1 mixed to DC

F2 mixed to
-
1MHz

f1=43750000; f2=44750000;

mixerfreq

=
-
6250000;

mixertone

= exp(2*pi*j*n*
mixerfreq
/
fs
);

product =
mixertone

.* sig;

plot(n*
fs
/length(n),(
20*log10(abs(
fft
(product)))));

If we tuned via our normal
method, all would work. We
take the resultant signal at
6.25MHz and bring it down
to 0. But notice we have a
“spectrum reversal”. Note
that 44.75 was lower in
frequency than 43.75 when
we looked at the spectrum
after under
-
sampling. That
still applies after mixing it
down, and isn’t our desired
behavior

“Correcting” Spectrum reversal


To fix this, we can take advantage of the fact that our
real signal has components at both positive and
negative frequency.

43.75 is also at
-
6.25MHz

44.75 is also at
-
5.25MHz

Normal order

Here!, lets mix this
up from
-
6.25 to
DC!

“Correcting” the Spectrum Reversal

F1 mixed to DC

F2 mixed to 1MHz

f1=43750000; f2=44750000;

mixerfreq

= +6250000;

mixertone

= exp(2*pi*j*n*
mixerfreq
/
fs
);

product =
mixertone

.* sig;

plot(n*
fs
/10000,(20*log10(abs(
fft
(product)))));

F1


which was at 6.25, gets mixed to 12.5,

F1^


which was at
-
6.25 gets mixed to 0

F2


was at 5.25, gets mixed to 11.5,

F2^
--

was at
-
5.25 gets mixed to 1

This process shows grabbing the
spectrum from
-
6.25 MHz and
mixing it up to 0 in order to
reverse the spectrum which got
flipped during the folding inherent
in our sampling


Result is just what we wanted : 43.75 shows up at DC, and 44.75 at 1MHz !

DSP Flow

ADC

DDS

X

Cos(fmix*t) + j* sin(fmix*t)

Sampled data (real)

FIR

Tuned data

(complex)

Decimated data (cplx)

L = I, R = Q

Rate = 25M / 512

= 48.8K

Generates samples of a sinusoid

DAC

To uBlaze FSL

For streaming

System Level issues in design


Clock domains


Consider where best point to cross clock domain is


Right after ADC?


Between filter and
microblaze
?


Latency of various blocks


Simulation of the DSP
blockset

without any
uBlaze

is relatively straightforward. With
uBlaze

works as
well, just a little slower


Design Issues : Tuning


Calculate aliased freq (due to
undersampling
)


Using # of bits in phase
accum
, Calculate
phase increment for desired mixer freq.


Ex : 25 bits means that each count of the phase
increment is (Fs/2^25) Hz = .745Hz

Design Issues Filtering


How to filter complex data?


Filter has scalar coefficients


Simply apply the same filter to both real and
complex paths


Dual channel filter can do this with a little logic at each
end for splitting and reconstructing the data


2 copies of the same filter wastes the coefficient
storage space, but is easier

Design Issues


Audio Sample Rate


The audio CODEC runs off of a different oscillator
than the main digitizer clock (which drives the data
rates through the system)


We have attempted to match those rates with our
decimating filter (/520), but this is only close, and even if it
were exact, the two oscillators would still creep relative to
one another.


What is the result? How can we manage this?


Real system would likely slave one clock to another
or have a complicated scheme to adaptively
resample. (Not here!)

Design Issues


Audio Sample Rate


Mismatch = (25e6/520)


48k = 76 samples / sec.


Our DSP chain will be creating 76 extra samples / second


We will handle this in the cheapest way possible, allowing some data
discontinuities (in the audio output only)

DSP

FIFO

DAC

IF

48.076

48

If FIFO is 1024 samples long, it will fill in 13 seconds. At which point we can

reset it and let it start again. Result will be a “pop” every 13 seconds. Ugly,

But since we are using the audio as a quick
-
look tool, it is perfectly acceptable

Alternative is handling this in the
Microblaze
!


which would be absolutely ok as well