FPGA Intellectual Property
PCI Express*, Networking and Connectivity, Memory Interfaces, DSP IP, and Video IP
6356 Discussions

OFDM using DSP Builder

Altera_Forum
Honored Contributor II
1,876 Views

Hi, 

 

I'm trying to implement a simplistic (4 channel) QPSK OFDM transmitter/receiver using Altera's DSP Builder and Megacore IP in Simulink. 

 

Let me just mention that I have very basic knowledge of OFDM and pretty much any book/reference material I read has too much detail and goes over my head. So correct me anywhere I start going off the track. 

 

Let me explain what I have so far (implementing what I have learned so far): 

 

Bits to Trasnmit: 11001011 

 

Since I am using 4 channels (all QPSK), I can transmit 8 bits in parallel. These bits get split up into pairs of two and go into seperate channel busses. Now I have: 

 

Channel 1: 11 

Channel 2: 00 

Channel 3: 10 

Channel 4: 11 

 

These bits get encoded into symbols (using Gray Coded QPSK). So now the channels contain: 

 

Channel 1 I: +0.7071 

Channel 1 Q: +0.7071 

Channel 2 I: -0.7071 

Channel 2 Q: -0.7071 

Channel 3 I: +0.7071 

Channel 3 Q: -0.7071 

Channel 4 I: +0.7071 

Channel 4 Q: +0.7071 

*note: each I/Q bus is 18 bits 

 

Now I know I need to send the data into the FFT block. The FFT block takes in a real and imag input and I'm completely lost.  

 

Reading the FFT block documentation, I need to scale the input by (2^data_precission - 1). The output should also be scaled by (2^-exp_out / 2^data_precission - 1).  

 

Any help or hint at the right direction would be greatly appreciated.
0 Kudos
19 Replies
Altera_Forum
Honored Contributor II
1,007 Views

You simply need to go back to: 

 

Channel 1: 11 

Channel 2: 00 

Channel 3: 10 

Channel 4: 11 

 

Instead of the +0.7071 and -0.7071 values, you may transmit the 1 and 0 values to the FFT engine. 

If you don't have pilot tones and you need only to transmit your payload data, that is simply what you need to do. 

Of course the output scaling can be done by choosing the appropriate output dynamic range and pushing the maximum and minimum binary values into the FFT engine instead of 1 and 0.
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Hi, 

 

I believe you mean (ifft) if Tx. 

I don't see how you send 1 & 0 to ifft unless it is (mapper + ifft). 

 

You have done some mapping to I/Q then just scale it to fft input.
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

I also have a question related to this, if you are using the streaming architecture for the FFT block (we would use it here wouldn't we?), should we be using the Avalon-ST interface? 

 

I don't quite understand the Avalon-ST, and all the examples I found on the web are from Quartus II, not DSP Builder.  

 

And since the FFT (streaming mode) can only take a max of an 24-bit bus for the Real and Imaginary inputs, we cannot just simply concatenate the output bits after mapping the symbols to their real and imaginary parts, how can this be solved?
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Hi, 

 

I don't use DSP builder(& I don't know anybody using it in the industry, only saw the party here!). 

 

If data precision is 24 for either Im/Re then it is more than enough.  

 

I believe by "streaming fft" altera means a continous output though processing is block based. I can use two fft cores swapping the processing resulting in continuous output but after initial delay. You can control this double processing yourself without the need for avalon hand.
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Thanks for your replies kaz, as for using DSP Builder, I don't have much of a choice since we are suppose to be learning it (Senior Project) and hopefully in the future it will become better; I hope so, I don't want to learn this and never use it! 

 

I think I know why most people in the industry don't bother with DSP builder, it's more expensive if you don't have a Matlab license and you have to get used to the Simulink way of doing things where you have to make sure your inputs/outputs match a certain type of signal, and I'm still not used to connecting blocks together, I feel like I'm in grade-school. :)
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Hi, 

 

I didn't want to discourage. It is great to have design acceleration tools to keep managers happy then lose your job at the end. We all have licenses and companies will pay for such tools readily. We all use cores but there is tool race and a variety(C => HDL, C => fpga,Matlab => fpga,Labview => fpga, 

... and vendor cores). Of these vendor cores are popular in the industry but as go up you lose the actual understanding of underlying concepts and get engaged with tool related problems and this slows it down. 

 

May be the new generation will make better use of it.
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Hi, 

 

Thank you all for your replies. 

 

*Correction about first post: I'm using the FFT block as an IFFT. As per OFDM design, the receiver contains an IFFT. 

 

orchestradirector

I don't understand what you mean when you say that I can transmit 1 and 0 values to the IFFT. In this case, where does the QPSK "constellation mapping" come in? 

 

kaz: 

I do I/Q mapping (QPSK). I mapped two bits into a symbol using QPSK. I and Q for each channel get the real and imaginary value. Based on my scenario, I have the following data after I/Q mapping: 

 

Channel 1 I: +0.7071 

Channel 1 Q: +0.7071 

Channel 2 I: -0.7071 

Channel 2 Q: -0.7071 

Channel 3 I: +0.7071 

Channel 3 Q: -0.7071 

Channel 4 I: +0.7071 

Channel 4 Q: +0.7071 

 

My overall question is: Based on my scenario, how do I input the data into the IFFT (Altera FFT Block) and what would the data look like?
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Hi, 

 

I can tell you about scaling for ifft but don't know about other signals around your ifft...I leave that to you. 

 

for n bits scale as follows(for I or Q): 

value = round(value*2^(n-1)-1) 

 

connect I to real input, Q to imaginary input.(you may reverse that for test) 

 

As to output: the best test is to check results numerically against Matlab function: 

y=ifft(complex(I,Q)) using the same scale inputs 

compare y(real and imaginary) to your output 

 

Just a simple way to understand ofdm idea: 

The mapped data is assumed in frequency domain then you do ifft to go to time domain. Remember one sinusoid in time domain corresponds to one constant value in frequency domain. So instead of generating tones in time domain you generate them in frequency domain through the ifft input vector, just put your constants or values there but needs correct spacing...each value results in one tone at the ifft output at corresponding frequency. As such ofdm can generate thousands of carriers without any NCO. and it goes on....the point here is one carrier only modulates one symbol while in classic modulators one carrier modulates a lot of symbols. The mass of tones cancel each other due to orthogonality and one symbol per carrier is left out clean that doesn't spread around. 

 

Kaz
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Hi zeep25, 

 

I just wanted to tell you that any kind of QPSK mapping (after appropriate scaling) will lead you to send to each channel of the IFFT block a +[quantity] and a -[quantity]. In order to maximize your IFFT output (exploit the whole dynamic range) you may simple send your ones and zeros as the maximum and minimum possible values depending on the chosen resolution. 

Example: if your IFFT input is 8-bits wide, an the values are unsigned, the zero will be 0x00 and the maximum will be 0x11. Of course take care if using 2s complement notation, these values must be converted into 2s complement. 

The IFFT output can be scaled if its amplitude must be changed depending of what is around your IFFT. 

Maybe I've synthesized my idea in a too short way... 

 

Cheers 

OD
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Hi, 

 

I agree with OD about the idea of full dynamic range and in that case you can scale to +127 & -127 for 8 bits. 

However, in actual systems with possibility of other modulation schemes e.g. QAM then you need to normalise all the levels to get unitary power. 

 

For QPSK the .707 per I/Q gives a unitary power as I^2+Q^2 = 1 

 

edit: 

if power levels are different in the final signal, you are likely to have a lot of head butting with the RF engineer especially so with ofdm as peak/average power is very high. 

 

Kaz
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

orchestradirector and kaz: Thank you both for your help. 

 

Greatly Appreciated!
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Before I continued with my design, I wanted to make sure I understood how to use the FFT(IFFT) megacore block properly. 

 

To test, I wrote a .m file where I performed the IFFT using the Matlab's built in ifft() function and Altera's IFFT megacore block using the .m file interface created when the block is generated. 

I got the result from Matlab's ifft function and Altera's IFFT block to come out to be exactly the same (note about scaling later). 

 

Now, I implemented the FFT block inside of DSP Builder and created a dummy setup with the same inputs as the data in the .m file. I compared the output of the Altera FFT block (from dsp builder) to the output of the Altera FFT (from matlab .m file) and they are totally different. 

 

Here's a screenshot giving you an idea of what I'm talking about: 

http://img353.imageshack.us/img353/5056/ifftcomparisonmh7.th.png (http://img353.imageshack.us/img353/5056/ifftcomparisonmh7.png

 

I'm attaching both files. 

 

------------------- 

 

Now about the scaling issue (this might be related to my problem). 

I have read many different things about "scaling" related the ifft block. 

 

You have to scale your FFT/IFFT block output by 

2^(-exponent)I have also read, that if your input is very small, then it's recommended to scale it on the input side and the same on the output side (aside from the 2^(-exponent)). 

 

In my .m file, to match the Matlab ifft block output with the Altera IFFT, I tried many scaling factor and somehow came upon this magical scaling property which works for all cases (different N points, different data or twiddle precision):Scale input by:2^(Nbits) Scale output by:2^(-exponent) / (2^(Nbits+Nbits-1)) WHEREo Nbits = log2(N) + 1 o N = transform length (points) The thing is, I don't know why it works, but it does (at least in the .m file). For different N (transform length/points) and different data/twiddle precision, it just works! 

 

Maybe I'm completely off here. I need some more help! 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Hi, 

 

Your output symbol shape looks ok to me. 

I believe your scaling must be wrong if you are getting this fiddle factor. 

 

you need to scale your inputs to the available input resolution as described in previous post e.g. for 8 bits your input can swing between integers -127 & +127. You can go lower if you wish but not higher). 

 

Use the same scaled input for Matlab ifft and altera ifft. 

 

Now pay attention to your output scaling:  

Matlab ifft: do not scale output, it is always done for you 

Altera ifft - for their convenience - has introduced scale factor of 2^-exp 

Make sure you are scaling correctly per each block of ifft(per each exp value): 

 

To multiply by 2^n: shift towards MSb (n) bits inserting leading zeros

To divide by 2^n:shift towards LSB (n) bits inserting the sign bits. 

 

If your shift is larger than available bit space then you must saturate, but this better be avoided in the first place by lowering the input scaling .
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Hi Kaz, 

 

So I'm back in Matlab making the changes you suggested. Things are starting to make sense. I just have 1 questions/problem now. 

 

The output of the Altera IFFT, I used the Matlab bitshift function to implement the 2^-exponent scaling. The output of Matlab IFFT and Alera IFFT do not match when I do this. Although if I change 2^-exponent to 2^exponent, then it comes out to be the same (change -outaltexp to outaltexp, on line 27 in fftTestMatlab.m). 

 

Next goal is to get the same output using DSP Builder.
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Hi, 

 

I am not familiar with Matlab bitshift but had a quick look at it. It only accepts unsigned integer values. Therefore I suggest you got one more task; you need to convert negative values to equivalent unsigned then reverse that as follows(however, since your function bitshift did not crash on negative values, may be it sees values as unsigned already...I don't how) 

 

for bitshift input: for n bits signed decimal 

if value is < 0 %negative 

value = value + 2^n; 

end 

 

for bitshift output:to recover negative values: 

if value >2^(n-1) 

value = value -2^n; 

end 

 

 

I can see how Matlab/DSP builder is making life so hard, you better do the shift by hand(in vhdl code) 

 

kaz
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Just a thought. Since you are working in Matlab platform,Why use bitshift?  

Why not just scale the altera_fft output by 2^-exp directly: 

 

altera_fft_scaled = altera_fft * 2^(-exp); % that's all 

 

kaz
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Hi Kaz, 

 

Even if I scale by multiplication of 2^-exp, I'm getting the same problem. The output scales in the wrong direction, its only equal to the Matlab IFFT output if I multilpy by 2^exp. I triple checked my code, it seems to be correct. Attaching my new .m file. 

 

My overall goal is to build an OFDM transceiver in DSP Builder using only Altera blocks, currently I'm stuck at the IFFT step of the transmitter. The matlab code was just to test my understanding of the Altera IFFT block and make sure I'm getting the correct result from it before I implement it in my design. 

 

The real problem here, is what I showed you in my previous post. In DSP Builder, using the same exact parameters of the Altera IFFT block, I'm getting different wave output (not scaled, but completely different shape) from DSP Builder Altera IFFT block compared with Altera IFFT block used from Matlab.
0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

Hi, 

 

little left to play around. 

 

Check that scaling is indeed as stated in the documentation 

 

Round up your results, just in case: 

symbols = round(inputScale * symbols); % scale the input 

 

check that altera fft doesn't centre output on dc(Matlab doesn't centre, it nees fftshift to centre it..) 

 

kaz 

0 Kudos
Altera_Forum
Honored Contributor II
1,007 Views

the Altera FFT core works the same as MATLAB's FFT in that it needs an FFT shift to center DC. 

 

edit: unless you're using bit-reversed modes.
0 Kudos
Reply