source: ReferenceDesigns/w3_802.11/sysgen/wlan_phy_tx_pmd/wlan_phy_tx_init.m

Last change on this file was 6325, checked in by murphpo, 17 months ago

Added register to Rx PHY to capture 40-sample running sum of Rx IQ magnitude.
Sim-only changes to Tx.

File size: 12.0 KB
Line 
1% Mango 802.11 Reference Design
2% WLAN PHY Tx Init script
3% Copyright 2016 Mango Communications
4% Distributed under the Mango Research License:
5% http://mangocomm.com/802.11/license
6
7%clear
8addpath('./util');
9addpath('./mcode_blocks');
10addpath('./blackboxes');
11
12%Define sane values for maximum parameter values; these maximums define
13% the bit widths of various signals throughout the design. Increasing
14% these maximum values will increae resource usage in hardware.
15MAX_NUM_BYTES = 4096;
16MAX_NUM_SC = 64;
17MAX_CP_LEN = 32;
18MAX_NUM_SAMPS = 50e3;
19MAX_NUM_SYMS = 600;
20MAX_DATA_BITS_PER_SYM_PERIOD = 2*260; %64-QAM 5/6 rate N_SS=2
21MAX_NCBPS = 312; %Max coded bits per OFDM sym sets size of de-interleave RAM
22
23%%
24%Define a few interesting MPDU payloads. These byte sequences start with
25% the MAC header, followed by the MAC payload, followed by the FCS. The FCS
26% is calculated and inserted by the PHY automatically, so 4 zeros are defined
27% as placeholders in each byte sequence below.
28
29%Null data frame:
30% Frame Control field: 0x4811
31% Duration: 0x2c00 (44 usec)
32% Receiver address:    40-d8-55-04-21-4a
33% Transmitter address: 40-d8-55-04-21-5a
34% Destination address: 40-d8-55-04-21-4a
35% Fragment/Seq Num field: 0xf092
36% FCS placeholder: 0x00000000
37MPDU_Null_Data = sscanf('48 11 2c 00 40 d8 55 04 21 4a 40 d8 55 04 21 5a 40 d8 55 04 21 4a f0 92 00 00 00 00', '%02x');
38
39%Data frames:
40% Frame Control field: 0x0801
41% Duration: 0x2c00 (44 usec)
42% Receiver address:    40-d8-55-04-21-4a
43% Transmitter address: 40-d8-55-04-21-5a
44% Destination address: 40-d8-55-04-21-6a
45% Fragment/Seq Num field: 0xb090
46% LLC header: aa-aa-03-00-00-00-08-00
47% Arbitrary payload: 00-01-02...0f
48% FCS placeholder: 0x00000000
49
50%Short pkt - 16 payload bytes
51MPDU_Data_short = sscanf(['08 01 2c 00 40 d8 55 04 21 4a 40 d8 55 04 21 5a 40 d8 55 04 21 6a b0 90 aa aa 03 00 00 00 08 00 ' sprintf('%02x ', [0:15]) ' 00 00 00 00'], '%02x');
52
53%Mid-size pkt - 150 payload bytes
54MPDU_Data_mid = sscanf(['08 01 2c 00 40 d8 55 04 21 4a 40 d8 55 04 21 5a 40 d8 55 04 21 6a b0 90 aa aa 03 00 00 00 08 00 ' sprintf('%02x ', mod([1:513], 256)) ' 00 00 00 00'], '%02x');
55
56%Long pkt - 1420 payload bytes
57MPDU_Data_long = sscanf(['08 01 2c 00 40 d8 55 04 21 4a 40 d8 55 04 21 5a 40 d8 55 04 21 6a b0 90 aa aa 03 00 00 00 08 00 ' sprintf('%02x ', mod([1:1434], 256)) ' 00 00 00 00'], '%02x');
58
59%ACK frame:
60% Frame Control field: 0xd400
61% Duration: 0x0000 (0 usec)
62% Receiver address: 40-d8-55-04-21-4a
63% FCS placeholder: 0x00000000
64ControlFrame_ACK = sscanf('d4 00 00 00 40 d8 55 04 21 4a 00 00 00 00', '%02x');
65
66%CTS frame:
67% Frame Control field: 0xc400
68% Duration: 0x01F4 (500 usec)
69% Receiver address: 40-d8-55-04-21-4a
70% FCS placeholder: 0x00000000
71ControlFrame_CTS = sscanf('c4 00 F4 01 40 d8 55 04 21 4a 00 00 00 00', '%02x');
72
73%100-Byte random payload with valid FCS, used with IEEE waveform generator
74%wgen_pyld = sscanf(['26 bd 8e b7 f4 13 e7 5c 31 c6 a4 5b ac 95 e9 5c 7c dc 42 10 6d 73 0f 0c 82 8e d9 b2 c8 48 f3 e2 75 fe 92 20 f4 74 f1 fa e0 ae cb 06 55 70 ed 63 1a 9b e7 6e 2b 61 7a df f4 fc b6 20 ba d1 09 8f 31 ea 8b de 1d 77 ce 78 c3 0b dd 25 d2 55 63 23 7c 31 cd 35 f5 75 1e 08 b2 2e 5b a4 67 3f 95 26 a3 54 37 cd'], '%02x');
75
76ltg_pyld = sscanf('08 02 26 00 40 d8 55 04 24 f4 40 d8 55 04 24 b6 40 d8 55 04 24 b6 30 f1 aa aa 03 00 00 00 90 90 13 3f bc 02 00 00 00 00 79 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 96 6d 42 55', '%02x'); 
77
78%Setup params for the sim
79% In hardware these params are set per packet by the MAC core/code
80% Bypass if running multiple sims via the gen_sim_waveforms script
81if(~exist('gen_waveform_mode', 'var'))
82    tx_sim = struct();
83    tx_sim.MAC_payload = ControlFrame_CTS;
84    tx_sim.payload_len = length(tx_sim.MAC_payload);
85    tx_sim.PHY_mode = 1; %1=11a, 2=11n
86    tx_sim.mcs = 0;
87    tx_sim.samp_rate = 40; %Must be in [10 20 40]
88    tx_sim.num_pkts = 1;
89end
90
91%MCS6, length=57, HTSIG should be:
92% 06 39 00 07 E0 00 (per IEEE waveform gen)
93% instead, current sim is:
94% 06 39 00 07 48 00 - clearly CRC calc is wrong for some MCS/Length values
95
96%Construct the initial value for the simulated packet buffer
97% This code is only for sim - CPU Low handles the packet buffer
98%  init in the actual design
99
100%Tx packet buffer bytes (zero indexed):
101%11a Tx:
102% [ 0: 2] SIGNAL field
103% [ 3: 4] SERVICE field (always [0 0])
104% [ 5:15] Reserved (ignored by Tx PHY logic)
105% [16: N] MAC payload
106%
107%11n Tx:
108% [ 0: 2] L-SIG field
109% [ 3: 8] HT-SIG
110% [ 9:10] SERVICE field (always [0 0])
111% [11:15] Reserved (ignored by Tx PHY logic)
112% [16: N] MAC payload
113
114PPDU_bytes = zeros(1, MAX_NUM_BYTES);
115
116[SIGNAL, HTSIG] = calc_phy_preamble(tx_sim.PHY_mode, tx_sim.mcs, tx_sim.payload_len);
117
118if(tx_sim.PHY_mode == 1) 
119    PPDU_bytes(1:3) = SIGNAL;
120
121    %Insert SERVICE field (always 0)
122    PPDU_bytes(4:5) = [0 0];
123   
124    %Reserved bytes
125    PPDU_bytes(6:16) = zeros(1,11);
126else
127    [SIGNAL, HTSIG] = calc_phy_preamble(2, tx_sim.mcs, tx_sim.payload_len);
128   
129    %11n mode - L-SIG contains rate=6Mbps, length corresponding to TX_TIME
130    PPDU_bytes(1:3) = SIGNAL;
131
132    %HT-SIG field
133    PPDU_bytes(4:9) = HTSIG;
134   
135    %Insert SERVICE field (always 0)
136    PPDU_bytes(10:11) = [0 0];
137   
138    %Reserved bytes
139    PPDU_bytes(12:16) = zeros(1, 5);
140end
141
142%Insert MAC payload - payload starts at byte index 16
143PPDU_bytes(16 + (1:numel(tx_sim.MAC_payload))) = tx_sim.MAC_payload;
144
145%Reshape byte vector to u32 vector, necessary to initialize the 32-bit BRAM in the simulation
146PPDU_bytes4 = reshape(PPDU_bytes, 4, numel(PPDU_bytes)/4);
147PPDU_words = sum(PPDU_bytes4 .* repmat(2.^[0:8:24]', 1, size(PPDU_bytes4,2)));
148
149
150%Define the complex-valued sequence for the preamble ROMs
151PLCP_Preamble = PLCP_Preamble_gen;
152Preamble_IQ = PLCP_Preamble.Preamble_t;
153
154%% Register Init
155
156%Sane initial values for PHY config registers. These values will be overwritten
157% at run-time by the software in CPU Low
158PHY_CONFIG_NUM_SC = 64;
159PHY_CONFIG_CP_LEN = 16;
160PHY_CONFIG_FFT_SCALING = bin2dec('101010');
161PHY_TX_ACTIVE_EXTENSION = 1;
162PHY_TX_RF_EN_EXTENSION = 50;
163PHY_TX_RXSIG_INVALID_EXTENSION = 120;
164
165REG_Tx_Timing = ...
166    2^0  * (PHY_TX_ACTIVE_EXTENSION) + ... %b[7:0]
167    2^10  * (PHY_TX_RF_EN_EXTENSION) + ... %b[15:8]
168    2^20 * (PHY_TX_RXSIG_INVALID_EXTENSION) + ... %b[23:16]
169    0;
170
171REG_TX_FFT_Config = ...
172    2^0  * (PHY_CONFIG_NUM_SC) +...  %b[7:0]
173    2^8  * (PHY_CONFIG_CP_LEN) +...  %b[15:8]
174    2^24 * (PHY_CONFIG_FFT_SCALING) + ... b[29:24]
175    0;
176
177REG_TX_Config = ...
178    2^0  * 1 + ... %Force RxEN to radio_controller
179    2^1  * 0 + ... %Reset scrambler per pkt
180    2^2  * 1 + ... %Enable Tx on RF A
181    2^3  * 0 + ... %Enable Tx on RF B
182    2^4  * 0 + ... %Enable Tx on RF C
183    2^5  * 0 + ... %Enable Tx on RF D
184    2^6  * 1 + ... %Use ant mask from MAC hw port
185    2^7  * 0 + ... %Use un-delayed TX_ACTIVE signal on debug port
186    2^12 * 1 + ... %PHY mode (1=11a, 2=11n), only used for software-initiated Tx
187    0;
188
189REG_TX_PKT_BUF_SEL = ...
190    2^0  * 0  + ... %b[3:0] pkt buf index
191    2^4  * 32 + ... %b[9:4] timestamp insert start byte
192    2^10 * 31 + ... %b[15:10] timestamp insert end byte
193    2^16 * 0  + ... %b[23:16] pkt buf address offset
194    0;
195
196REG_TX_Output_Scaling = (2.0 * 2^12) + (2^16 * 2.0 * 2^12); %UFix16_12 values
197
198
199%% Cyclic Redundancy Check parameters
200CRCPolynomial32 = hex2dec('04c11db7'); %CRC-32, for payload FCS
201CRC_Table32 = CRC_table_gen(CRCPolynomial32, 32);
202
203CRCPolynomial8 = hex2dec('07'); %CRC-8, for HT-SIG
204CRC_Table8 = CRC_table_gen(CRCPolynomial8, 8);
205
206%%
207%Load the MCS info table
208[mcs_rom_11ag, mcs_rom_11n] = tx_mcs_info_rom_init();
209
210
211
212%% Constellation scaling
213
214%Common scaling for preamble and all constellations that keeps all points within
215% numeric range of Fix16_15 values at input to IFFT
216ALL_MOD_SCALING = ( 1.0 - (2^-15) )/(7/sqrt(42));
217Preamble_IQ_scaled = ALL_MOD_SCALING * Preamble_IQ;
218
219Mod_Constellation_BPSK(1) = ALL_MOD_SCALING * -1;
220Mod_Constellation_BPSK(2) = ALL_MOD_SCALING *  1;
221
222Mod_Constellation_QPSK(1) = ALL_MOD_SCALING * -1/sqrt(2);
223Mod_Constellation_QPSK(2) = ALL_MOD_SCALING *  1/sqrt(2);
224
225Mod_Constellation_16QAM(1) = ALL_MOD_SCALING * -3/sqrt(10);
226Mod_Constellation_16QAM(2) = ALL_MOD_SCALING * -1/sqrt(10);
227Mod_Constellation_16QAM(3) = ALL_MOD_SCALING *  3/sqrt(10);
228Mod_Constellation_16QAM(4) = ALL_MOD_SCALING *  1/sqrt(10);
229
230Mod_Constellation_64QAM(1) = ALL_MOD_SCALING * -7/sqrt(42);
231Mod_Constellation_64QAM(2) = ALL_MOD_SCALING * -5/sqrt(42);
232Mod_Constellation_64QAM(3) = ALL_MOD_SCALING * -1/sqrt(42);
233Mod_Constellation_64QAM(4) = ALL_MOD_SCALING * -3/sqrt(42);
234Mod_Constellation_64QAM(5) = ALL_MOD_SCALING *  7/sqrt(42);
235Mod_Constellation_64QAM(6) = ALL_MOD_SCALING *  5/sqrt(42);
236Mod_Constellation_64QAM(7) = ALL_MOD_SCALING *  1/sqrt(42);
237Mod_Constellation_64QAM(8) = ALL_MOD_SCALING *  3/sqrt(42);
238
239
240%% HT preamble
241
242%Define the frequency domain 20MHz HT-STF (IEEE 802.11-2012 20.3.9.4.5)
243% Array indexes [0 ... 63] correspond to subcarriers [0 1 ... 31 -32 -31 ... -1]
244ht_stf_20_fd = zeros(1,64);
245ht_stf_20_fd(1:27) = [0 0 0 0 -1-1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0 0 1+1i 0 0];
246ht_stf_20_fd(39:64) = [0 0 1+1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0 -1-1i 0 0 0 -1-1i 0 0 0 1+1i 0 0 0];
247
248%Define the frequency domain 20MHz HT-LTF (IEEE 802.11-2012 20.3.9.4.6)
249% Array indexes [0 ... 63] correspond to subcarriers [0 1 ... 31 -32 -31 ... -1]
250ht_ltf_20_fd = [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 -1 -1 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 1 1];
251
252%Define init vector for HT preamble ROM
253% 20MHz HT-STF and HT-LTF are concatenated
254% FIXME: HT-STF scaling isn't quite right - it should be a bit bigger
255% Need to figure out best way to build that, given IFFT Fix16_15 input type
256ht_preamble_rom = [ht_stf_20_fd ALL_MOD_SCALING .* ht_ltf_20_fd];
257
258%% Interleaver and subcarrier maps
259
260% Use util script to generate interleaver address mapping ROM contents
261wlan_tx_interleave_rom = wlan_tx_interleave_rom_gen();
262
263%Initialize a vector defining the subcarrier map
264% This vector is used by the interleaver control logic to select which
265% subcarriers carry data symbols. A value of MAX_NUM_SC tells the hardware to
266% not use the subcarrier for data.
267sc_ind_data_11a = [2:7 9:21 23:27 39:43 45:57 59:64];
268sc_data_sym_map_11a = MAX_NUM_SC*ones(1,MAX_NUM_SC);
269sc_data_sym_map_11a(sc_ind_data_11a) = 0:length(sc_ind_data_11a)-1;
270sc_data_sym_map_11a_bool = double(sc_data_sym_map_11a ~= MAX_NUM_SC);
271
272sc_ind_data_11n = [2:7 9:21 23:29 37:43 45:57 59:64];
273sc_data_sym_map_11n = MAX_NUM_SC*ones(1,MAX_NUM_SC);
274sc_data_sym_map_11n(sc_ind_data_11n) = 0:length(sc_ind_data_11n)-1;
275sc_data_sym_map_11n_bool = double(sc_data_sym_map_11n ~= MAX_NUM_SC);
276
Note: See TracBrowser for help on using the repository browser.