1 | % Mango 802.11 Reference Design |
---|
2 | % WLAN PHY Rx Init script |
---|
3 | % Copyright 2017 Mango Communications |
---|
4 | % Distributed under the Mango Research License: |
---|
5 | % http://mangocomm.com/802.11/license |
---|
6 | |
---|
7 | %clear all |
---|
8 | addpath('./util'); |
---|
9 | addpath('./mcode_blocks'); |
---|
10 | addpath('./blackboxes'); |
---|
11 | |
---|
12 | %% Define an input signal for simulation |
---|
13 | % Skip this if running a multi-sim test with the rx_sim_test script |
---|
14 | if(~exist('sim_many_waveform_mode','var')) |
---|
15 | % Ensure previously-defined waveforms are cleared |
---|
16 | clear wlan_tx_out; |
---|
17 | clear sig; |
---|
18 | clear tx_sig; |
---|
19 | clear ADC_I ADC_Q; |
---|
20 | clear sim_sig; |
---|
21 | |
---|
22 | if 0 |
---|
23 | %PHY debugging with ChipScope captures of I/Q |
---|
24 | % ChipScope waveforms must be saved in ASCII format with (at least) ADC_I and ADC_Q signals |
---|
25 | xlLoadChipScopeData('high_snr_htmf_mcs7_bad_fcs_3.prn'); cs_interp = 1; cs_start = 669; cs_end = 3980;%length(ADC_I); |
---|
26 | sim_sig = complex(ADC_I([cs_start:cs_interp:cs_end]), ADC_Q(cs_start:cs_interp:cs_end)); |
---|
27 | %sim_sig = sim_sig .* exp(j*pi/4); |
---|
28 | end |
---|
29 | |
---|
30 | if 0 |
---|
31 | %Output of PHY Tx simulation |
---|
32 | % .mat files from Tx PHY sim store I/Q signal in 'wlan_tx_out' variable |
---|
33 | load('rx_sigs/wlan_tx_NONHT_MCS4_52B.mat');wlan_tx_out = wlan_tx_out(1:1000).'; |
---|
34 | %load('rx_sigs/wlan_tx_HTMF_MCS7_52B.mat');wlan_tx_out = wlan_tx_out(1:1000).'; |
---|
35 | |
---|
36 | %load waveforms_2M.mat |
---|
37 | %rx_iq = rx_iq_2M_ping_short(1:2:end); |
---|
38 | %wlan_tx_out = rx_iq.'; |
---|
39 | end |
---|
40 | |
---|
41 | if 1 |
---|
42 | p = util_dsss_tx(20, 1:10, 2); |
---|
43 | w = p.wvfm / max(real(p.wvfm)); |
---|
44 | %wlan_tx_out = [5*w(1:4*20), 0.5*w(4*20+1:end)]; %mimic AGC |
---|
45 | wlan_tx_out = 0.5*w; |
---|
46 | wlan_tx_out = [zeros(1,10) wlan_tx_out]; |
---|
47 | |
---|
48 | end |
---|
49 | |
---|
50 | if 1 |
---|
51 | %CFO |
---|
52 | %wlan_tx_out = wlan_tx_out .* exp(j*2*pi*-2e-3*(0:length(wlan_tx_out)-1)); |
---|
53 | |
---|
54 | %sig = wlan_tx_out; |
---|
55 | %noise = 6e-2*complex(randn(size(wlan_tx_out)),randn(size(wlan_tx_out))); |
---|
56 | %wlan_tx_out = [zeros(1,0) sig + noise]; |
---|
57 | %wlan_tx_out = sig; |
---|
58 | |
---|
59 | |
---|
60 | %Phase offset |
---|
61 | %wlan_tx_out = wlan_tx_out .* exp(-j*pi/2); |
---|
62 | |
---|
63 | %AWGN |
---|
64 | %wlan_tx_out = [zeros(1,500) 1.25*wlan_tx_out]; |
---|
65 | %wlan_tx_out = wlan_tx_out + 1e-1*complex(randn(1,length(wlan_tx_out)), randn(1,length(wlan_tx_out))); |
---|
66 | %wlan_tx_out = [wlan_tx_out zeros(1,500)]; |
---|
67 | %wlan_tx_out = wlan_tx_out + 1e-3*complex(randn(1,length(wlan_tx_out)), randn(1,length(wlan_tx_out))); |
---|
68 | |
---|
69 | %DCO |
---|
70 | %wlan_tx_out = wlan_tx_out + (5e-2 + 1i*2e-2); |
---|
71 | |
---|
72 | % 1-pkt waveform |
---|
73 | sim_sig = wlan_tx_out(1:end).'; |
---|
74 | |
---|
75 | % 2-pkt waveform |
---|
76 | %sim_sig = [wlan_tx_out(1:end).'; zeros(500,1); wlan_tx_out(1:end).']; |
---|
77 | end |
---|
78 | end |
---|
79 | |
---|
80 | |
---|
81 | %Define the simulation paramters - waveform, sample rate, sim duration, etc |
---|
82 | rx_sim = struct(); |
---|
83 | rx_sim.waveform_RFA.time = []; |
---|
84 | rx_sim.waveform_RFA.signals.values = [zeros(50,1); sim_sig; zeros(500,1); ]; |
---|
85 | rx_sim.samp_rate = 20; %Must be in [10 20 40] |
---|
86 | rx_sim.sim_time = (160 / rx_sim.samp_rate) * length(rx_sim.waveform_RFA.signals.values) + 500; |
---|
87 | |
---|
88 | %% |
---|
89 | |
---|
90 | %Fixed PHY parameters - these values affect data types throughout the design |
---|
91 | MAX_NUM_SC = 64; |
---|
92 | MAX_CP_LEN = 32; |
---|
93 | MAX_NUM_SAMPS = 50e3; |
---|
94 | MAX_NUM_SYMS = 600; |
---|
95 | MAX_NUM_BYTES = 2^16-1; |
---|
96 | |
---|
97 | %% Define the LTS correlation coefficients |
---|
98 | |
---|
99 | %Call util scripts to generate the PHY preamble signals |
---|
100 | PLCP_Preamble = PLCP_Preamble_gen; |
---|
101 | |
---|
102 | % Rx PHY uses Fix3_0 to store coefficients |
---|
103 | longCorr_coef_nbits = 3; |
---|
104 | longCorr_coef_bp = 0; |
---|
105 | long_cor_acc_n_bits = 6 * 2; |
---|
106 | |
---|
107 | %Scale, conjugate and time-reverse the standard LTS |
---|
108 | longCorr_coef = fliplr(conj(PLCP_Preamble.LTS_t./max(abs(PLCP_Preamble.LTS_t)))); |
---|
109 | |
---|
110 | longCorr_coef_i = [3*real(longCorr_coef)]; |
---|
111 | longCorr_coef_q = [3*imag(longCorr_coef)]; |
---|
112 | |
---|
113 | |
---|
114 | %Define the size of the circular sample buffer before the FFT |
---|
115 | % This buffer must be large enough to hold the full LTS section of the |
---|
116 | % preamble plus enough post-preamble samples to acommodate the latency |
---|
117 | % of the FFT taking the transforms of the LTS. 4*lengh(LTS) is enough |
---|
118 | % for the standard preamble and 64 subcarriers |
---|
119 | preFFT_sampBuff_numSamps = 4*MAX_NUM_SC; |
---|
120 | |
---|
121 | %Define the frequency-domain training symbol coefficients |
---|
122 | % sign() here stores +/-1 (LTS is BPSK in freq domain) for smaller memory in hardware |
---|
123 | |
---|
124 | %L-LTF (legacy training symbol - 52 non-zero subcarriers) |
---|
125 | l_ltf_f = sign(PLCP_Preamble.LTS_f); |
---|
126 | |
---|
127 | %HT-LTF (11n training symbol - 56 non-zero subcarriers) |
---|
128 | ht_ltf_f = l_ltf_f; |
---|
129 | ht_ltf_f([28 29 37 38]) = [-1 -1 +1 +1]; |
---|
130 | |
---|
131 | |
---|
132 | %Initialize a vector defining the subcarrier map |
---|
133 | % This vector is used by the interleaver control logic to select which |
---|
134 | % subcarriers carry data symbols. A value of MAX_NUM_SC tells the hardware to |
---|
135 | % not use the subcarrier for data. |
---|
136 | sc_ind_data_11a = [2:7 9:21 23:27 39:43 45:57 59:64]; |
---|
137 | sc_data_sym_map_11a = MAX_NUM_SC*ones(1,MAX_NUM_SC); |
---|
138 | sc_data_sym_map_11a(sc_ind_data_11a) = fftshift(0:length(sc_ind_data_11a)-1); |
---|
139 | sc_data_sym_map_11a_bool = double(sc_data_sym_map_11a ~= MAX_NUM_SC); |
---|
140 | |
---|
141 | sc_ind_data_11n = [2:7 9:21 23:29 37:43 45:57 59:64]; |
---|
142 | sc_data_sym_map_11n = MAX_NUM_SC*ones(1,MAX_NUM_SC); |
---|
143 | sc_data_sym_map_11n(sc_ind_data_11n) = fftshift(0:length(sc_ind_data_11n)-1); |
---|
144 | sc_data_sym_map_11n_bool = double(sc_data_sym_map_11n ~= MAX_NUM_SC); |
---|
145 | |
---|
146 | %% |
---|
147 | %Initial values for Rx PHY registers |
---|
148 | PHY_CONFIG_NUM_SC = 64; |
---|
149 | PHY_CONFIG_CP_LEN = 16; |
---|
150 | PHY_CONFIG_FFT_SCALING = bin2dec('000101'); |
---|
151 | |
---|
152 | % FFT offset depends on PHY samp rate (and waveform format?) |
---|
153 | % 20: FFT_OFFSET=2 for zero cyclic prefix samps |
---|
154 | % 40: FFT_OFFSET=4 for zero cyclic prefix samps |
---|
155 | %PHY_CONFIG_FFT_OFFSET = (1+2*(rx_sim.samp_rate==40)) + 0; |
---|
156 | PHY_CONFIG_FFT_OFFSET = 7; |
---|
157 | |
---|
158 | PHY_CONFIG_RSSI_SUM_LEN = 8; |
---|
159 | |
---|
160 | PHY_SIGNAL_MIN_LEN = 14; |
---|
161 | |
---|
162 | PHY_CONFIG_LTS_CORR_THRESH_LOWSNR = 9000; |
---|
163 | PHY_CONFIG_LTS_CORR_THRESH_HIGHSNR = 9000; |
---|
164 | PHY_CONFIG_LTS_CORR_PEAKTYPE_THRESH_LOWSNR = 16384; |
---|
165 | PHY_CONFIG_LTS_CORR_PEAKTYPE_THRESH_HIGHSNR = 16384; |
---|
166 | PHY_CONFIG_LTS_CORR_RSSI_THRESH = PHY_CONFIG_RSSI_SUM_LEN*400; |
---|
167 | |
---|
168 | PHY_CONFIG_LTS_CORR_TIMEOUT = 175; |
---|
169 | |
---|
170 | %DSSS auto correlation pkt det thresholds |
---|
171 | PHY_CONFIG_PKT_DET_CORR_THRESH_DSSS = 115; |
---|
172 | PHY_CONFIG_PKT_DET_ENERGY_THRESH_DSSS = 16; |
---|
173 | |
---|
174 | % Channel estimate smooothing |
---|
175 | %PHY_CONFIG_H_EST_SMOOTHING_A = 2867; %round(0.7 * 2^12); |
---|
176 | %PHY_CONFIG_H_EST_SMOOTHING_B = 614; %round(0.15 * 2^12); |
---|
177 | PHY_CONFIG_H_EST_SMOOTHING_A = 2^12-1; |
---|
178 | PHY_CONFIG_H_EST_SMOOTHING_B = 0; |
---|
179 | |
---|
180 | %h = [.17 .7 .17 zeros(1,61)]; %Gives 0dB gain at 38 (FFT offset 5), better than 0dB gain at 32 (FFT offset 0) |
---|
181 | |
---|
182 | %PHY_CONFIG_H_EST_SMOOTHING_A = 2000; |
---|
183 | %PHY_CONFIG_H_EST_SMOOTHING_B = 0; |
---|
184 | |
---|
185 | PHY_CONFIG_PKT_DET_CORR_THRESH = 100; |
---|
186 | PHY_CONFIG_PKT_DET_ENERGY_THRESH = 8; |
---|
187 | PHY_CONFIG_PKT_DET_MIN_DURR = 4; %UFix4_0 duration |
---|
188 | PHY_CONFIG_PKT_DET_RESET_EXT_DUR = 1;%hex2dec('3F'); |
---|
189 | |
---|
190 | CS_CONFIG_CS_RSSI_THRESH = 300 * PHY_CONFIG_RSSI_SUM_LEN; |
---|
191 | CS_CONFIG_POSTRX_EXTENSION = 6*20; %6usec as 120 20MHz samples |
---|
192 | |
---|
193 | SOFT_DEMAP_SCALE_BPSK = 15; |
---|
194 | SOFT_DEMAP_SCALE_QPSK = 15; |
---|
195 | SOFT_DEMAP_SCALE_16QAM = 18; |
---|
196 | SOFT_DEMAP_SCALE_64QAM = 22; |
---|
197 | |
---|
198 | REG_RX_PktDet_AutoCorr_Config = ... |
---|
199 | 2^0 * (PHY_CONFIG_PKT_DET_CORR_THRESH) +...%b[7:0] UFix8_8 |
---|
200 | 2^8 * (PHY_CONFIG_PKT_DET_ENERGY_THRESH) +...%b[21:8] UFix14_2 |
---|
201 | 2^22 * (PHY_CONFIG_PKT_DET_MIN_DURR) +...%b[25:22] |
---|
202 | 2^26 * (PHY_CONFIG_PKT_DET_RESET_EXT_DUR) + ...%b[31:26] |
---|
203 | 0; |
---|
204 | |
---|
205 | REG_RX_LTS_Corr_Thresh = ... |
---|
206 | 2^0 * (PHY_CONFIG_LTS_CORR_THRESH_LOWSNR) +... %b[15:0] |
---|
207 | 2^16 * (PHY_CONFIG_LTS_CORR_THRESH_HIGHSNR) +... %b[31:16] |
---|
208 | 0; |
---|
209 | |
---|
210 | REG_RX_LTS_Corr_PeakType_Thresh = ... |
---|
211 | 2^0 * (PHY_CONFIG_LTS_CORR_PEAKTYPE_THRESH_LOWSNR) +... %b[15:0] |
---|
212 | 2^16 * (PHY_CONFIG_LTS_CORR_PEAKTYPE_THRESH_HIGHSNR) +... %b[31:16] |
---|
213 | 0; |
---|
214 | |
---|
215 | REG_RX_Chan_Est_Smoothing = ... |
---|
216 | 2^0 * (PHY_CONFIG_H_EST_SMOOTHING_A) +... %b[11:0] |
---|
217 | 2^12 * (PHY_CONFIG_H_EST_SMOOTHING_B) +... %b[23:12] |
---|
218 | 2^24 * 12; %PHY mode det threshold; 12 chosen experimentally |
---|
219 | 0; |
---|
220 | |
---|
221 | REG_RX_LTS_Corr_Confg = ... |
---|
222 | 2^0 * (PHY_CONFIG_LTS_CORR_TIMEOUT) + ... %b[7:0] |
---|
223 | 2^8 * (PHY_CONFIG_LTS_CORR_RSSI_THRESH) + ... %b[23:8] |
---|
224 | 2^24 * 7 + ... %b[26:24] - 0x1/2/4 enables 63/64/65-sample spacing for LTS corr |
---|
225 | 0; |
---|
226 | |
---|
227 | REG_RX_FFT_Config = ... |
---|
228 | 2^0 * (PHY_CONFIG_NUM_SC) +... %b[7:0] |
---|
229 | 2^8 * (PHY_CONFIG_CP_LEN) +... %b[15:8] |
---|
230 | 2^16 * (PHY_CONFIG_FFT_OFFSET) +... %b[23:16] |
---|
231 | 2^24 * (PHY_CONFIG_FFT_SCALING) + ... b[29:24] |
---|
232 | 0; |
---|
233 | |
---|
234 | REG_RX_Control = ... |
---|
235 | 2^0 * 0 + ... %b[0]: Global Reset |
---|
236 | 2^1 * 0 + ... %b[1]: Pkt done latch reset |
---|
237 | 0; |
---|
238 | |
---|
239 | REG_RX_Config = ... |
---|
240 | 2^0 * 1 + ... %DSSS RX EN |
---|
241 | 2^1 * 1 + ... %Block inputs on INVALID input |
---|
242 | 2^2 * 1 + ... %Swap pkt buf byte order |
---|
243 | 2^3 * 1 + ... %Swap order of chan est u32 writes |
---|
244 | 2^4 * 0 + ... %Block DSSS Rx until DSSS pkt det has occurred |
---|
245 | 2^5 * 0 + ... %Bypass CFO est/correction |
---|
246 | 2^6 * 1 + ... %Enable chan est recording to pkt buf |
---|
247 | 2^7 * 0 + ... %Enable switching diversity |
---|
248 | 2^8 * 0 + ... %Disable OFDM pipeline |
---|
249 | 2^9 * 1 + ... %Enable pkt det on Ant A |
---|
250 | 2^10 * 0 + ... %Enable pkt det on Ant B |
---|
251 | 2^11 * 0 + ... %Enable pkt det on Ant C |
---|
252 | 2^12 * 0 + ... %Enable pkt det on Ant D |
---|
253 | 2^13 * 0 + ... %Enable ext pkt det |
---|
254 | 2^14 * 0 + ... %PHY CCA mode (0=any, 1=all) |
---|
255 | 2^15 * 0 + ... %Manual ant sel when sel div disabled (2-bits, 00=RFA) |
---|
256 | 2^17 * 2 + ... %Max SIGNAL.LENGTH value, in kB (UFix4_0) |
---|
257 | 2^21 * 0 + ... %Require auto-corr and RSSI pkt det for OFDM Rx |
---|
258 | 2^22 * 0 + ... %Rate-Length Busy holds pkt det high |
---|
259 | 2^23 * 1 + ... %DSSS asserts CCA busy |
---|
260 | 2^24 * 1 + ... %Enable 11n Rx support |
---|
261 | 2^25 * 1 + ... %Enable detection of 11ac waveforms based on VHT-SIG modulation |
---|
262 | 2^26 * 0 + ... %Require RSSI and AutoCorr detection for DSSS Rx |
---|
263 | 2^27 * 0 + ... %Reset pkt det counters |
---|
264 | 2^28 * 0 + ... %DSSS SYNC w/out pkt-det blocks pkt-det until done |
---|
265 | 2^29 * 0 + ... %OFDM Rx requires pkt det; 0=LTS correlation alone can start Rx |
---|
266 | 0; |
---|
267 | |
---|
268 | REG_RX_DSSS_RX_CONFIG = ... |
---|
269 | 2^0 * (48) + ... %b[7:0]: UFix8_0 SYNC matching score thresh |
---|
270 | 2^8 * (45) + ... %b[15:8]: UFix8_0 SYNC matching timeout (multiplied by 32 in hw) |
---|
271 | 2^16 * (52) + ... %b[23:16]: UFix8_0 SFD matching timeout (multiplied by 32 in hw) |
---|
272 | 2^24 * (39) + ... %b[31:24]: UFix8_0 SYNC search time (samples) |
---|
273 | 0; |
---|
274 | |
---|
275 | REG_RX_PktDet_DSSS_Config = ... |
---|
276 | 2^0 * (PHY_CONFIG_PKT_DET_CORR_THRESH_DSSS) +... %b[7:0] UFix8_7 |
---|
277 | 2^8 * (PHY_CONFIG_PKT_DET_ENERGY_THRESH_DSSS) +...%b[23:8] UFix14_2 |
---|
278 | 0; |
---|
279 | |
---|
280 | REG_RX_PKTDET_RSSI_CONFIG = ... |
---|
281 | 2^0 * (PHY_CONFIG_RSSI_SUM_LEN) + ... %b[4:0]: RSSI sum len |
---|
282 | 2^5 * (300*8) + ... %b[19:5]: RSSI thresh |
---|
283 | 2^20 * (4) + ... %b[24:20]: Min duration |
---|
284 | 0; |
---|
285 | |
---|
286 | REG_RX_CCA_CONFIG = ... |
---|
287 | 2^0 * (CS_CONFIG_CS_RSSI_THRESH) + ... %b[15:0] |
---|
288 | 2^16 * (CS_CONFIG_POSTRX_EXTENSION) + ... %b[23:16] |
---|
289 | 0; |
---|
290 | |
---|
291 | REG_RX_PktBuf_Sel = ... |
---|
292 | 2^0 * 0 + ... %b[3:0]: OFDM Pkt Buf |
---|
293 | 2^8 * 0 + ... %b[11:8]: DSSS Pkt Buf |
---|
294 | 2^16 * 35 + ... %b[23:16]: Pkt buf offset for Rx bytes (u64 words) |
---|
295 | 2^24 * 3 + ... %b[31:24]: Pkt buf offset for chan est (u64 words) |
---|
296 | 0; |
---|
297 | |
---|
298 | REG_RX_FEC_Config = ... |
---|
299 | 2^0 * (SOFT_DEMAP_SCALE_BPSK) + ... |
---|
300 | 2^5 * (SOFT_DEMAP_SCALE_QPSK) + ... |
---|
301 | 2^10 * (SOFT_DEMAP_SCALE_16QAM) + ... |
---|
302 | 2^15 * (SOFT_DEMAP_SCALE_64QAM) + ... |
---|
303 | 0; |
---|
304 | |
---|
305 | REG_RX_PKT_BUF_Max_Write_Addr = 3800; |
---|
306 | |
---|
307 | %% |
---|
308 | bit_scrambler_lfsr = ones(1,7); |
---|
309 | bit_scrambler_lfsr_states = zeros(127, 7); |
---|
310 | scr = zeros(1,127); |
---|
311 | for ii=1:127 |
---|
312 | bit_scrambler_lfsr_states(ii, :) = bit_scrambler_lfsr; |
---|
313 | |
---|
314 | %LFSR polynomial: x^7 + x^4 + 1 |
---|
315 | x = xor(bit_scrambler_lfsr(4), bit_scrambler_lfsr(7)); |
---|
316 | bit_scrambler_lfsr = [x bit_scrambler_lfsr(1:6)]; |
---|
317 | |
---|
318 | scr(ii) = x; |
---|
319 | end |
---|
320 | |
---|
321 | %Convert bitwise descrambler states to bytewise descramber states |
---|
322 | % same as bit_scrambler_lfsr_bytes = bi2de(reshape(repmat(scr, 1, 8), 8, 127)', 'right-msb'); |
---|
323 | % without using bi2de |
---|
324 | bit_scrambler_lfsr_bytes = (reshape(repmat(scr, 1, 8), 8, 127)'); |
---|
325 | bit_scrambler_lfsr_bytes = sum(bit_scrambler_lfsr_bytes .* repmat(2.^[0:7], 127, 1),2); |
---|
326 | |
---|
327 | %% |
---|
328 | %Generate the vector of addresses for the bytewise descramber ROM |
---|
329 | scr = [scr scr(1:10)]; |
---|
330 | scr_ind_rev = zeros(1,128); |
---|
331 | for ii=1:127 |
---|
332 | %Same as scr_ind_rev(1 + bi2de(scr(ii:ii+6))) = ii - 1; |
---|
333 | % without using bi2de |
---|
334 | scr_ind_rev(1 + sum(2.^[0:1:6].*scr(ii:ii+6))) = ii - 1; |
---|
335 | end |
---|
336 | clear scr x bit_scrambler_lfsr ii |
---|
337 | |
---|
338 | %% Cyclic Redundancy Check parameters |
---|
339 | CRCPolynomial32 = hex2dec('04c11db7'); %CRC-32 |
---|
340 | CRC_Table32 = CRC_table_gen(CRCPolynomial32, 32); |
---|
341 | |
---|
342 | CRCPolynomial8 = hex2dec('07'); %CRC-8 |
---|
343 | CRC_Table8 = CRC_table_gen(CRCPolynomial8, 8); |
---|
344 | |
---|
345 | %% |
---|
346 | [mcs_rom_11ag, mcs_rom_11n] = mcs_info_rom_init(); |
---|
347 | |
---|
348 | %% Define numbers of coded and data bits per MCS |
---|
349 | NCBPS_11a_BPSK = 48; |
---|
350 | NCBPS_11a_QPSK = 96; |
---|
351 | NCBPS_11a_16QAM = 192; |
---|
352 | NCBPS_11a_64QAM = 288; |
---|
353 | |
---|
354 | NCBPS_11n_BPSK = 52; |
---|
355 | NCBPS_11n_QPSK = 104; |
---|
356 | NCBPS_11n_16QAM = 208; |
---|
357 | NCBPS_11n_64QAM = 312; |
---|
358 | |
---|
359 | %Max bits-per-symbol determines size of de-interleaver RAM |
---|
360 | MAX_NCBPS = NCBPS_11n_64QAM; |
---|
361 | |
---|
362 | NDBPS_11a_BPSK12 = 24; |
---|
363 | NDBPS_11a_BPSK34 = 36; |
---|
364 | NDBPS_11a_QPSK12 = 48; |
---|
365 | NDBPS_11a_QPSK34 = 72; |
---|
366 | NDBPS_11a_16QAM12 = 96; |
---|
367 | NDBPS_11a_16QAM34 = 144; |
---|
368 | NDBPS_11a_64QAM23 = 192; |
---|
369 | NDBPS_11a_64QAM34 = 216; |
---|
370 | |
---|
371 | NDBPS_11n_BPSK12 = 26; |
---|
372 | NDBPS_11n_QPSK12 = 52; |
---|
373 | NDBPS_11n_QPSK34 = 78; |
---|
374 | NDBPS_11n_16QAM12 = 104; |
---|
375 | NDBPS_11n_16QAM34 = 156; |
---|
376 | NDBPS_11n_64QAM23 = 208; |
---|
377 | NDBPS_11n_64QAM34 = 234; |
---|
378 | NDBPS_11n_64QAM56 = 260; |
---|
379 | |
---|
380 | %% Calculate de-interleaving vectors |
---|
381 | %11a |
---|
382 | % BPSK |
---|
383 | N_CBPS = NCBPS_11a_BPSK; |
---|
384 | N_BPSC = 1; |
---|
385 | s = max(N_BPSC/2, 1); |
---|
386 | |
---|
387 | %Interleaver (k=src bit index -> j=dest bit index) |
---|
388 | k = 0:N_CBPS-1; |
---|
389 | i = (N_CBPS/16) .* mod(k,16) + floor(k/16); |
---|
390 | %BPSK doesn't need j |
---|
391 | |
---|
392 | interleave_11a_BPSK = i; |
---|
393 | clear N_CBPS N_BPSC s k i |
---|
394 | |
---|
395 | % QPSK |
---|
396 | N_CBPS = NCBPS_11a_QPSK; |
---|
397 | N_BPSC = 2; |
---|
398 | s = max(N_BPSC/2, 1); |
---|
399 | |
---|
400 | k = 0:N_CBPS-1; |
---|
401 | i = (N_CBPS/16) .* mod(k,16) + floor(k/16); |
---|
402 | j = s * floor(i/s) + mod( (i + N_CBPS - floor(16*i/N_CBPS)), s); |
---|
403 | interleave_11a_QPSK = j; |
---|
404 | clear N_CBPS N_BPSC s k i j |
---|
405 | |
---|
406 | % 16-QAM |
---|
407 | N_CBPS = NCBPS_11a_16QAM; |
---|
408 | N_BPSC = 4; |
---|
409 | s = max(N_BPSC/2, 1); |
---|
410 | |
---|
411 | k = 0:N_CBPS-1; |
---|
412 | i = (N_CBPS/16) .* mod(k,16) + floor(k/16); |
---|
413 | j = s * floor(i/s) + mod( (i + N_CBPS - floor(16*i/N_CBPS)), s); |
---|
414 | interleave_11a_16QAM = j; |
---|
415 | clear N_CBPS N_BPSC s k i j |
---|
416 | |
---|
417 | % 64-QAM |
---|
418 | N_CBPS = NCBPS_11a_64QAM; |
---|
419 | N_BPSC = 6; |
---|
420 | s = max(N_BPSC/2, 1); |
---|
421 | |
---|
422 | k = 0:N_CBPS-1; |
---|
423 | i = (N_CBPS/16) .* mod(k,16) + floor(k/16); |
---|
424 | j = s * floor(i/s) + mod( (i + N_CBPS - floor(16*i/N_CBPS)), s); |
---|
425 | interleave_11a_64QAM = j; |
---|
426 | clear N_CBPS N_BPSC s k i j |
---|
427 | |
---|
428 | %FFT Shift |
---|
429 | interleave_11a_BPSK = mod(interleave_11a_BPSK + (NCBPS_11a_BPSK/2), NCBPS_11a_BPSK); |
---|
430 | interleave_11a_QPSK = mod(interleave_11a_QPSK + (NCBPS_11a_QPSK/2), NCBPS_11a_QPSK); |
---|
431 | interleave_11a_16QAM = mod(interleave_11a_16QAM + (NCBPS_11a_16QAM/2), NCBPS_11a_16QAM); |
---|
432 | interleave_11a_64QAM = mod(interleave_11a_64QAM + (NCBPS_11a_64QAM/2), NCBPS_11a_64QAM); |
---|
433 | |
---|
434 | %% |
---|
435 | %11n |
---|
436 | % BPSK |
---|
437 | N_CBPS = NCBPS_11n_BPSK; |
---|
438 | N_BPSC = 1; |
---|
439 | s = max(N_BPSC/2, 1); |
---|
440 | |
---|
441 | %Interleaver (k=src bit index -> j=dest bit index) |
---|
442 | k = 0:N_CBPS-1; |
---|
443 | i = (4 * N_BPSC) .* mod(k,13) + floor(k/13); |
---|
444 | %BPSK doesn't need j |
---|
445 | |
---|
446 | interleave_11n_BPSK = i; |
---|
447 | clear N_CBPS N_BPSC s k i |
---|
448 | |
---|
449 | % QPSK |
---|
450 | N_CBPS = NCBPS_11n_QPSK; |
---|
451 | N_BPSC = 2; |
---|
452 | s = max(N_BPSC/2, 1); |
---|
453 | |
---|
454 | k = 0:N_CBPS-1; |
---|
455 | i = (4 * N_BPSC) .* mod(k,13) + floor(k/13); |
---|
456 | j = s * floor(i/s) + mod( (i + N_CBPS - floor(13*i/N_CBPS)), s); |
---|
457 | interleave_11n_QPSK = j; |
---|
458 | clear N_CBPS N_BPSC s k i j |
---|
459 | |
---|
460 | % 16-QAM |
---|
461 | N_CBPS = NCBPS_11n_16QAM; |
---|
462 | N_BPSC = 4; |
---|
463 | s = max(N_BPSC/2, 1); |
---|
464 | |
---|
465 | k = 0:N_CBPS-1; |
---|
466 | i = (4 * N_BPSC) .* mod(k,13) + floor(k/13); |
---|
467 | j = s * floor(i/s) + mod( (i + N_CBPS - floor(13*i/N_CBPS)), s); |
---|
468 | interleave_11n_16QAM = j; |
---|
469 | clear N_CBPS N_BPSC s k i j |
---|
470 | |
---|
471 | % 64-QAM |
---|
472 | N_CBPS = NCBPS_11n_64QAM; |
---|
473 | N_BPSC = 6; |
---|
474 | s = max(N_BPSC/2, 1); |
---|
475 | |
---|
476 | k = 0:N_CBPS-1; |
---|
477 | i = (4 * N_BPSC) .* mod(k,13) + floor(k/13); |
---|
478 | j = s * floor(i/s) + mod( (i + N_CBPS - floor(13*i/N_CBPS)), s); |
---|
479 | interleave_11n_64QAM = j; |
---|
480 | clear N_CBPS N_BPSC s k i j |
---|
481 | |
---|
482 | %FFT Shift |
---|
483 | interleave_11n_BPSK = mod(interleave_11n_BPSK + (NCBPS_11n_BPSK/2), NCBPS_11n_BPSK); |
---|
484 | interleave_11n_QPSK = mod(interleave_11n_QPSK + (NCBPS_11n_QPSK/2), NCBPS_11n_QPSK); |
---|
485 | interleave_11n_16QAM = mod(interleave_11n_16QAM + (NCBPS_11n_16QAM/2), NCBPS_11n_16QAM); |
---|
486 | interleave_11n_64QAM = mod(interleave_11n_64QAM + (NCBPS_11n_64QAM/2), NCBPS_11n_64QAM); |
---|
487 | |
---|
488 | |
---|
489 | %De-interleaver ROM contents - one ROM used for all rates |
---|
490 | deinterleave_ROM = []; |
---|
491 | deinterleave_ROM = [deinterleave_ROM interleave_11a_BPSK zeros(1, 512-length(interleave_11a_BPSK))]; |
---|
492 | deinterleave_ROM = [deinterleave_ROM interleave_11a_QPSK zeros(1, 512-length(interleave_11a_QPSK))]; |
---|
493 | deinterleave_ROM = [deinterleave_ROM interleave_11a_16QAM zeros(1, 512-length(interleave_11a_16QAM))]; |
---|
494 | deinterleave_ROM = [deinterleave_ROM interleave_11a_64QAM zeros(1, 512-length(interleave_11a_64QAM))]; |
---|
495 | |
---|
496 | deinterleave_ROM = [deinterleave_ROM interleave_11n_BPSK zeros(1, 512-length(interleave_11n_BPSK))]; |
---|
497 | deinterleave_ROM = [deinterleave_ROM interleave_11n_QPSK zeros(1, 512-length(interleave_11n_QPSK))]; |
---|
498 | deinterleave_ROM = [deinterleave_ROM interleave_11n_16QAM zeros(1, 512-length(interleave_11n_16QAM))]; |
---|
499 | deinterleave_ROM = [deinterleave_ROM interleave_11n_64QAM zeros(1, 512-length(interleave_11n_64QAM))]; |
---|
500 | |
---|
501 | |
---|
502 | %%%%%%%%% NEW DSSS INIT |
---|
503 | % Define resampled spreading sequences |
---|
504 | % loads variables spread_seq_<11,20,40> |
---|
505 | load('./util/util_resampled_spread_seq.mat'); |
---|
506 | |
---|
507 | % Extract and scale 20-sample spreading sequence |
---|
508 | spread_seq_20 = spread_seq_20(40+(0:19)); |
---|
509 | spread_seq_20 = spread_seq_20 / sum(spread_seq_20); % for G=1 fitler response |
---|
510 | spread_seq_20 = spread_seq_20 - mean(spread_seq_20); % for DC=0 response |
---|
511 | |
---|
512 | DSSS_CLKS_PER_SAMP = 8; %160MHz clk / 20MSps I/Q |
---|
513 | DSSS_SAMPS_PER_SYM = 20; %sampling frequency, effective spreading seq length |
---|
514 | DSSS_BIT_MATCH_RAM_WIDTH = 32; % width of word-access ports |
---|
515 | DSSS_NUM_SYMS_PER_OFFSET = (2 * DSSS_CLKS_PER_SAMP * DSSS_BIT_MATCH_RAM_WIDTH); |
---|
516 | DSSS_NUM_SYMS_IN_RAM = DSSS_SAMPS_PER_SYM * DSSS_NUM_SYMS_PER_OFFSET; |
---|
517 | |
---|
518 | % Pad the target bit and mask vectors - the padding must be first so the matching |
---|
519 | % logic ignores the oldest bits (post-padding would ignore new bits) |
---|
520 | % Clause 16 scrambled SYNC: |
---|
521 | clause16_scr_sync = [0,1,1,1,1,1,1,0,1,1,1,0,1,1,0,0,1,1,1,0,1,0,0,0,1,0,1,0,0,1,0,0,1,1,1,1,1,0,0,1,1,0,0,1,0,1,0,1,1,0,0,0,1,1,0,0,0,0,1,0,0,1,0,1,1,1,1,0,1,0,1,0,1,0,0,0,0,0,1,0,1,1,0,1,0,1,1,1,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,1,0,1,0,0,1,1,0,1,1,0]; |
---|
522 | |
---|
523 | target_bits = clause16_scr_sync(5:64); |
---|
524 | %mask1 = ones(1, length(target_bits)); |
---|
525 | mask1 = [zeros(1,12) ones(1, 48)]; |
---|
526 | |
---|
527 | target_bits_pad = [zeros(1, DSSS_NUM_SYMS_PER_OFFSET - length(target_bits)) target_bits ]; |
---|
528 | mask1_pad = [zeros(1, DSSS_NUM_SYMS_PER_OFFSET - length(mask1)) mask1]; |
---|
529 | |
---|
530 | % Target bits RAM must contain 32 copies (BIT_MATCH_RAM_WIDTH) of the target |
---|
531 | % bit sequence. Each copy is cyclically shifted from the previous by 1 |
---|
532 | target_bits_ram_init = zeros(1, DSSS_NUM_SYMS_IN_RAM/32); |
---|
533 | mask_1_ram_init = zeros(1, DSSS_NUM_SYMS_IN_RAM/32); |
---|
534 | |
---|
535 | f_bit_vec_to_words = @(bv) 2.^(0:31) * reshape(bv(:), 32, []); |
---|
536 | |
---|
537 | for ii = 0:31 |
---|
538 | x = circshift(target_bits_pad, [0 -31+ii]); |
---|
539 | x = f_bit_vec_to_words(x); |
---|
540 | target_bits_ram_init([1:2*DSSS_CLKS_PER_SAMP] + ii*2*DSSS_CLKS_PER_SAMP) = x; |
---|
541 | |
---|
542 | x = circshift(mask1_pad, [0 -31+ii]); |
---|
543 | x = f_bit_vec_to_words(x); |
---|
544 | mask_1_ram_init([1:2*DSSS_CLKS_PER_SAMP] + ii*2*DSSS_CLKS_PER_SAMP) = x; |
---|
545 | |
---|
546 | end |
---|
547 | |
---|
548 | %% |
---|
549 | if 0 |
---|
550 | % Util code to calculate some Rx PHY latencies: |
---|
551 | t_first_samp = find(rx_sim_nonzero_iq_input, 1, 'first'); |
---|
552 | t_rx_active_dbg = find(rx_sim_phy_active_debug_out, 1, 'first'); |
---|
553 | t_rx_start = find(rx_sim_rx_start_mac_output, 1, 'first'); |
---|
554 | clk_freq_MHz = 160; |
---|
555 | |
---|
556 | % First sample -> rx_phy_active debug output |
---|
557 | rx_active_dbg_latency = (t_rx_active_dbg - t_first_samp); |
---|
558 | rx_active_dbg_latency_us = rx_active_dbg_latency/clk_freq_MHz; |
---|
559 | |
---|
560 | % First sample -> RX_START MAC output |
---|
561 | rx_start_latency = (t_rx_start - t_first_samp); |
---|
562 | rx_start_latency_us = rx_start_latency/clk_freq_MHz; |
---|
563 | |
---|
564 | fprintf('\n\nPHY Latencies:\n'); |
---|
565 | fprintf(' PHY Active Debug: %d cycles / %2.3f usec\n', rx_active_dbg_latency, rx_active_dbg_latency_us); |
---|
566 | fprintf(' RX_START to MAC: %d cycles / %2.3f usec\n\n', rx_start_latency, rx_start_latency_us); |
---|
567 | end |
---|