root/ResearchApps/PHY/MIMO_OFDM/ofdm_tx_mimo_init.m

Revision 1024, 11.5 kB (checked in by murphpo, 21 hours ago)

Re-worked pilot phase calculation

Line 
1warning off;
2
3%Compile-time maximum values; used to set precision of control logic values
4max_OFDM_symbols = 2047;
5max_num_subcarriers = 64;
6max_CP_length = 16;
7max_num_baseRateSymbols = 31;
8max_num_trainingSymbols = 15;
9max_numBytes = 16384;
10
11%Hard-coded OFDM parameters for now; these might be dynamic some day
12numSubcarriers = 64;
13CPLength = 16;
14
15%Set SISO mode
16tx_SISO_Mode = 1;
17
18%Cyclic Redundancy Check parameters
19CRCPolynomial = hex2dec('04c11db7');
20CRC_Table = CRC_table_gen(CRCPolynomial);
21
22%Define the preamble which is pre-pended to each packet
23%These long and short symbols are borrowed from the 802.11a PHY standard
24shortSymbol_freq = [0 0 0 0 0 0 0 0 1+i 0 0 0 -1+i 0 0 0 -1-i 0 0 0 1-i 0 0 0 -1-i 0 0 0 1-i 0 0 0 0 0 0 0 1-i 0 0 0 -1-i 0 0 0 1-i 0 0 0 -1-i 0 0 0 -1+i 0 0 0 1+i 0 0 0 0 0 0 0].';
25shortSymbol_time = ifft(fftshift(shortSymbol_freq));
26shortSymbol_time = shortSymbol_time(1:16).';
27
28longSymbol_freq_bot = [0 0 0 0 0 0 1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 1]';
29longSymbol_freq_top = [1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1 0 0 0 0 0]';
30longSymbol_freq = [longSymbol_freq_bot ; 0 ; longSymbol_freq_top];
31longSymbol_time = ifft(fftshift(longSymbol_freq)).';
32
33%Concatenate 10 short symbols together
34shortsyms_10 = repmat(shortSymbol_time,1,10);
35
36%Concatenate and cyclicly extend two long symbols
37%longsyms_2 = [longSymbol_time(33:64) repmat(longSymbol_time,1,2)];
38%longSymbol_time = linspace(-1/6, 1/6, 64);
39longsyms_2 = [repmat(longSymbol_time,1,2) longSymbol_time(1:32)];
40
41%Scale the resulting time-domain preamble to fit [-1,1]
42preamble = 6*[0 shortsyms_10 longsyms_2];
43preamble_I = real(preamble);%[+1*ones(1,length(preamble)-1) -0.1];
44preamble_Q = imag(preamble);%[-1*ones(1,length(preamble)-1) +0.1];
45
46%Configure the pilot tone registers
47pilot1_indicies = 7 + ( (64-7) * 2^16);
48pilot2_indicies = 21 + ( (64-21) * 2^16);
49pilotValue_pos = hex2dec('7FFF') + (2^16 * 0);%+0.9;
50pilotValue_neg = hex2dec('8000') + (2^16 * 0);%-0.9;
51
52%Training sequence, borrowed from 802.11a
53train = [0 -1 1 -1 1 -1 1 -1 1 -1 -1 -1 -1 1 1 -1 1 1 1 1 1 -1 -1 1 1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 1 -1 1 1 1 -1 -1 -1 -1 1 1 -1 1 -1 1 1 -1 1 1 1 -1 -1 -1 -1 -1 -1];
54train = train * -1;
55train(22) = -1;
56train(58) = 1;
57
58%MIMO training; use the same sequence for both antennas
59train = [train train];
60
61%Maximum number of bytes per packet
62%RAM_init_size = 4096;
63BER_RAM_init_size = 2048; %only support BER tests up to 2048 bytes/packet
64RAM_init_size = max_numBytes;
65
66%Standard 48-active subcarriers
67subcarrier_masks = ones(1,numSubcarriers);
68subcarrier_masks(1)=0;  %DC tone at Xk=0
69subcarrier_masks(8)=0; %pilot tone at Xk=7
70subcarrier_masks(22)=0; %pilot tone at Xk=21
71subcarrier_masks(44)=0; %pilot tone at Xk=43
72subcarrier_masks(58)=0; %pilot tone at Xk=57
73subcarrier_masks([28:32])=0; %zeros at higher frequencies
74subcarrier_masks([33:38])=0; %zeros at higher frequencies
75
76%Choose the modulation schemes to use for the base-rate and full-rate symbols
77%Valid values are [0,2,4,6,8], meaning 0, QPSK, 16/64/256 QAM symbols per subcarrier
78mod_baseRate = 2;
79modMask_antA = 2;
80modMask_antB = 2*(1-tx_SISO_Mode); %If in MIMO mode, load modulated symbols for ant B
81
82modulation_antA = modMask_antA*subcarrier_masks;
83modulation_antB = modMask_antB*subcarrier_masks;
84
85modulation_antA = 15*subcarrier_masks;
86modulation_antB = 15*subcarrier_masks;
87
88modulation_baseRate = mod_baseRate*subcarrier_masks;
89
90%Final vector must be: [AntennaA AntennaB BaseRate]
91%AntA = AntB = BaseRate = 48 non-zero subcarriers -> 12 bytes/OFDM symbol with QPSK
92subcarrier_QAM_Values = [modulation_antA modulation_antB modulation_baseRate];
93numBytes_BaseRateOFDMSymbol = sum(modulation_baseRate)/8;
94
95numBytes_AFullRateOFDMSymbol = sum(bitand(modMask_antA,modulation_antA))/8;
96numBytes_BFullRateOFDMSymbol = sum(bitand(modMask_antB,modulation_antB))/8;
97
98%numBytes_FullRateOFDMSymbol = sum(modulation_antA)/8;
99numBytes_FullRateOFDMSymbol = numBytes_AFullRateOFDMSymbol;
100if(tx_SISO_Mode == 1)
101        numBytes_FullRateOFDMSymbol = numBytes_AFullRateOFDMSymbol;
102else
103        numBytes_FullRateOFDMSymbol = (numBytes_AFullRateOFDMSymbol + numBytes_BFullRateOFDMSymbol)/2;
104end
105
106%Example of how modulation data gets formatted as bytes in the packet's header; useed for simulation
107subcarrier_QAM_Values_bytes = reshape([modulation_antA modulation_antB], 2, numSubcarriers);
108subcarrier_QAM_Values_bytes = sum(subcarrier_QAM_Values_bytes .* [ones(1,64).*2^4; ones(1,64)]);
109
110%Setup the packet length for simulation
111numTrainingSymbols = 2;
112numBaseRateSymbols = 2;
113
114%Setup the packet contents
115rand('state',1); %Get the same packet each time for BER testing
116
117%Calculate the number of bytes in the packet, based on the number of OFDM symbols specified above
118% In hardware, the user code will provide this value per-packet
119pkt_numPayloadBytes = 1250;%6*24+1;
120
121%Calculate the number of full rate OFDM symbols
122% This number is actually the number of FFT frames which are calculated
123% In SISO mode, it is double the number of actual OFDM symbols transmitted
124% As a result, this value must be even, in any mode
125if(tx_SISO_Mode == 1)
126        numFullRateSymbols = 2*ceil(pkt_numPayloadBytes/numBytes_FullRateOFDMSymbol);%124;
127else
128        numFullRateSymbols = ceil(pkt_numPayloadBytes/numBytes_FullRateOFDMSymbol);%124;
129end
130numFullRateSymbols = numFullRateSymbols + mod(numFullRateSymbols, 2);
131
132%Define the indicies (zero-indexed, like C) of some important bytes in the header
133byteIndex_numPayloadBytes = [3 2];
134byteIndex_simpleDynModMasks = 0;
135numHeaderBytes = 24;
136
137%Total number of bytes to process (header + payload + 32-bit payload checksum)
138pkt_totalBytes = numHeaderBytes + pkt_numPayloadBytes + 4;
139
140%Construct the packet header
141% The PHY only cares about 3 bytess (length_lsb, length_msb and modMasks)
142% In hardware, the MAC will use the rest of the header for MAC-ish stuff
143packetHeader = [...
144        (modMask_antA + modMask_antB*2^4) ... %byte 0
145        0 ...
146        floor((pkt_totalBytes/256))... %byte 2
147        mod(pkt_totalBytes,256)... %byte 3
148        zeros(1,20)     ...
149];
150
151%Endian-flip at 64-bit boundaries to mimic the PLB packet buffer interface in hardware
152packetHeader = [fliplr(packetHeader(1:8)) fliplr(packetHeader(9:16)) fliplr(packetHeader(17:24))];
153
154%Assemble the rest of the packet, using random bytes for the full-rate payload
155packet = [packetHeader 1:(pkt_numPayloadBytes-length(packetHeader)-4)];
156%packet = [packetHeader 255.*ones(1, (pkt_numPayloadBytes-length(packetHeader)-4))];
157
158packet = mod(packet,256); %Make sure each element is really just one byte
159
160%Add the 32-bit checksum to the end of the payload
161% In hardware, the checksum automatically over-writes the last four bytes of the payload
162packet = [packet calcTxCRC(packet)];
163
164%This value allows the simulated transmitter to start new packets
165% leaving a few hundred cycles of idle time between each packet
166simOnly_numSamples = length(preamble)+( (numSubcarriers+CPLength)*(numTrainingSymbols + numBaseRateSymbols + numFullRateSymbols/2) );
167
168%Default value for the Tx symbol counts register
169txReg_symbolCounts = (2^16 * numFullRateSymbols) + (2^8 *numBaseRateSymbols ) + numTrainingSymbols;
170
171%Parameters to initialize the packet buffers
172% The default packet is loaded at configuration, allowing real-time BER tests
173% This packet will be overwritten in hardware when user-code loads packets
174packet_length = length(packet)-1;
175RAM_init_values = [packet, zeros(1,RAM_init_size-1-packet_length)];
176
177BER_RAM_init_values = RAM_init_values(1:BER_RAM_init_size);
178BER_RAM_init_values = reshape(flipud(reshape(BER_RAM_init_values, 8, BER_RAM_init_size/8)), 1, BER_RAM_init_size);
179
180%LPF coefficients for the interpolation/decimation filters
181lpf_h = [1.296923e-003 1.408510e-003 1.257711e-003 3.226648e-005 -2.519384e-003 -6.198394e-003 -1.022530e-002 -1.333438e-002 -1.410672e-002 -1.149196e-002 -5.345330e-003 3.224983e-003 1.190534e-002 1.770326e-002 1.787723e-002 1.101327e-002 -2.108767e-003 -1.821814e-002 -3.204219e-002 -3.756010e-002 -2.972681e-002 -6.174810e-003 3.165421e-002 7.836874e-002 1.256233e-001 1.640445e-001 1.855768e-001 1.855768e-001 1.640445e-001 1.256233e-001 7.836874e-002 3.165421e-002 -6.174810e-003 -2.972681e-002 -3.756010e-002 -3.204219e-002 -1.821814e-002 -2.108767e-003 1.101327e-002 1.787723e-002 1.770326e-002 1.190534e-002 3.224983e-003 -5.345330e-003 -1.149196e-002 -1.410672e-002 -1.333438e-002 -1.022530e-002 -6.198394e-003 -2.519384e-003 3.226648e-005 1.257711e-003 1.408510e-003 1.296923e-003];
182lpf_h = firpm(53,[0 .18 .21 1],[1 1 0 0]);
183%B = RCOSFIR(R, N_T, RATE, T)
184lpf_h_tx = rcosfir(.25, 5, 5, 1, 'sqrt');
185%lpf_h_rx = firpm(53,[0 .5 .55 1],[1 1 0 0]);
186lpf_h_rx = rcosfir(.25, 5, 5, 1, 'sqrt');
187
188%LSFR parameters, used for random payload mode
189txLSFR_numBits = 13;
190txLSFR_polynomials = {'21' '35' '0B' '1D' '35' '0B' '3D' '2B'};
191txLSFR_initValues = {'3F' '1B' '03' '35' '17' '0A' '74' '39'};
192
193%Precision for the constants which store the modulation values
194modConstellation_prec = 8;
195modConstellation_bp = 7;
196
197%Defintion of the various constellations
198%Gray coded bit-symbol mappings
199%Borrowed from the IEEE 802.16 specification
200% IEEE Std 802.16-2004 Tables 153-155 (pg. 329)
201
202%QPSK constellation
203%2 bits per symbol, 1 bit per I/Q
204% I = MSB, Q = LSB
205%modConstellation_qpsk = [1 -1];
206modConstellation_qpsk = [1 -1]./sqrt(2);
207%modConstellation_qpsk = (1-2^-modConstellation_bp).*modConstellation_qpsk./(max(abs(modConstellation_qpsk)));
208
209%16-QAM constellation
210%4 bits per symbol, 2 bits per I/Q
211% I = 2MSB, Q = 2LSB
212modConstellation_qam16 = .75*[1 3 -1 -3]./3;
213%modConstellation_qam16 = [1 3 -1 -3];
214%modConstellation_qam16 = [1 3 -1 -3]./sqrt(10);
215%modConstellation_qam16 = (1-2^-modConstellation_bp).*modConstellation_qam16./(max(abs(modConstellation_qam16)));
216
217%FIXME: 64/256QAM constellations exceed +/-1, which won't fit in the current data types!
218%64-QAM constellation
219%6 bits per symbol, 3 bits per I/Q
220% I = 3MSB, Q = 3LSB
221modConstellation_qam64 = 0.875*[3 1 5 7 -3 -1 -5 -7]./7;
222%modConstellation_qam64 = [3 1 5 7 -3 -1 -5 -7];
223%modConstellation_qam64 = [3 1 5 7 -3 -1 -5 -7]./(7*3/sqrt(10));%sqrt(42);
224%modConstellation_qam64 = (1-2^-modConstellation_bp).*modConstellation_qam64./(max(abs(modConstellation_qam64)));
225
226%256-QAM constellation
227%8 bits per symbol, 4 bits per I/Q
228% I = 4MSB, Q = 4LSB
229modConstellation_qam256 = 0.9375*[3 1 5 7 11 9 13 15 -3 -1 -5 -7 -11 -9 -13 -15]./15;
230%modConstellation_qam256 = [3 1 5 7 11 9 13 15 -3 -1 -5 -7 -11 -9 -13 -15];
231%1/(modnorm(qammod(0:255,256),'avpow',1))^2
232%modConstellation_qam256 = [3 1 5 7 11 9 13 15 -3 -1 -5 -7 -11 -9 -13 -15]./sqrt(170);
233%modConstellation_qam256 = (1-2^-modConstellation_bp).*modConstellation_qam256./(max(abs(modConstellation_qam256)));
234
235%interpFilter = firpm(40, [0 0.18 0.25 1], [1 1 0 0]);
236[x, interpFilter] = interp(longSymbol_time, 5);
237[x, interpFilter_4] = interp(longSymbol_time, 4);
238
239antB_preambleShift = 4;
240
241%Fill in the TxControlBits register; each bit has a different purpose
242%0x1: 1 SISO Mode
243%0x2: 2 Random payload
244%0x4: 4 Disable AntB preamble
245%0x8: 8 Enable Pilot Scrambling (2^3)
246tx_controlBits = (antB_preambleShift * 2^4) + (2^0 * tx_SISO_Mode) + 4*0 + 8*1;
247
248%12-bit value: bits[5:0]=TxFFTScaling, bits[11:6]=RxFFTScaling
249TxRx_FFTScaling = bin2dec('010111') + (bin2dec('000101') * 2^6);
250
251
252%DataScrambling_Seq = zeros(1,32);
253TxDataScrambling_Seq = [40 198 78 63 82 173 102 245 48 111 172 115 147 230 216 93 72 65 62 2 205 242 122 90 128 83 105 97 73 10 5 252];
254RxDataScrambling_Seq = [40 198 78 63 82 173 102 245 48 111 172 115 147 230 216 93 72 65 62 2 205 242 122 90 128 83 105 97 73 10 5 252];
Note: See TracBrowser for help on using the browser.