[3922] | 1 | % Mango 802.11 Reference Design |
---|
| 2 | % WLAN PHY Rx Init script |
---|
[5713] | 3 | % Copyright 2017 Mango Communications |
---|
[3922] | 4 | % Distributed under the Mango Research License: |
---|
| 5 | % http://mangocomm.com/802.11/license |
---|
[2088] | 6 | |
---|
[5170] | 7 | %clear all |
---|
[2128] | 8 | addpath('./util'); |
---|
[2088] | 9 | addpath('./mcode_blocks'); |
---|
| 10 | addpath('./blackboxes'); |
---|
| 11 | |
---|
[2572] | 12 | %% Define an input signal for simulation |
---|
[5170] | 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; |
---|
[5190] | 20 | clear sim_sig; |
---|
[5170] | 21 | |
---|
[6177] | 22 | if 0 |
---|
[5170] | 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 |
---|
[6258] | 25 | xlLoadChipScopeData('high_snr_htmf_mcs7_bad_fcs_3.prn'); cs_interp = 1; cs_start = 669; cs_end = 3980;%length(ADC_I); |
---|
[6177] | 26 | sim_sig = complex(ADC_I([cs_start:cs_interp:cs_end]), ADC_Q(cs_start:cs_interp:cs_end)); |
---|
[6258] | 27 | %sim_sig = sim_sig .* exp(j*pi/4); |
---|
[6177] | 28 | end |
---|
| 29 | |
---|
[6168] | 30 | if 0 |
---|
[5170] | 31 | %Output of PHY Tx simulation |
---|
| 32 | % .mat files from Tx PHY sim store I/Q signal in 'wlan_tx_out' variable |
---|
[6299] | 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).'; |
---|
[5644] | 35 | |
---|
[6177] | 36 | %load waveforms_2M.mat |
---|
| 37 | %rx_iq = rx_iq_2M_ping_short(1:2:end); |
---|
| 38 | %wlan_tx_out = rx_iq.'; |
---|
[6194] | 39 | end |
---|
| 40 | |
---|
[6325] | 41 | if 1 |
---|
[6177] | 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; |
---|
[6168] | 46 | wlan_tx_out = [zeros(1,10) wlan_tx_out]; |
---|
[6151] | 47 | |
---|
[6177] | 48 | end |
---|
| 49 | |
---|
[6194] | 50 | if 1 |
---|
[5328] | 51 | %CFO |
---|
[6168] | 52 | %wlan_tx_out = wlan_tx_out .* exp(j*2*pi*-2e-3*(0:length(wlan_tx_out)-1)); |
---|
[5479] | 53 | |
---|
[6151] | 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 | |
---|
[5479] | 60 | %Phase offset |
---|
[6217] | 61 | %wlan_tx_out = wlan_tx_out .* exp(-j*pi/2); |
---|
[5238] | 62 | |
---|
[5328] | 63 | %AWGN |
---|
[6168] | 64 | %wlan_tx_out = [zeros(1,500) 1.25*wlan_tx_out]; |
---|
[6258] | 65 | %wlan_tx_out = wlan_tx_out + 1e-1*complex(randn(1,length(wlan_tx_out)), randn(1,length(wlan_tx_out))); |
---|
[6177] | 66 | %wlan_tx_out = [wlan_tx_out zeros(1,500)]; |
---|
[6208] | 67 | %wlan_tx_out = wlan_tx_out + 1e-3*complex(randn(1,length(wlan_tx_out)), randn(1,length(wlan_tx_out))); |
---|
[5190] | 68 | |
---|
[6168] | 69 | %DCO |
---|
| 70 | %wlan_tx_out = wlan_tx_out + (5e-2 + 1i*2e-2); |
---|
| 71 | |
---|
[5713] | 72 | % 1-pkt waveform |
---|
[6258] | 73 | sim_sig = wlan_tx_out(1:end).'; |
---|
[5713] | 74 | |
---|
| 75 | % 2-pkt waveform |
---|
[6258] | 76 | %sim_sig = [wlan_tx_out(1:end).'; zeros(500,1); wlan_tx_out(1:end).']; |
---|
[5190] | 77 | end |
---|
[5170] | 78 | end |
---|
[3615] | 79 | |
---|
[5238] | 80 | |
---|
[5170] | 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; |
---|
[4402] | 87 | |
---|
[2572] | 88 | %% |
---|
[2088] | 89 | |
---|
[3922] | 90 | %Fixed PHY parameters - these values affect data types throughout the design |
---|
[2088] | 91 | MAX_NUM_SC = 64; |
---|
| 92 | MAX_CP_LEN = 32; |
---|
| 93 | MAX_NUM_SAMPS = 50e3; |
---|
| 94 | MAX_NUM_SYMS = 600; |
---|
[4415] | 95 | MAX_NUM_BYTES = 2^16-1; |
---|
[2088] | 96 | |
---|
[3922] | 97 | %% Define the LTS correlation coefficients |
---|
| 98 | |
---|
[5170] | 99 | %Call util scripts to generate the PHY preamble signals |
---|
| 100 | PLCP_Preamble = PLCP_Preamble_gen; |
---|
| 101 | |
---|
[3922] | 102 | % Rx PHY uses Fix3_0 to store coefficients |
---|
[2088] | 103 | longCorr_coef_nbits = 3; |
---|
| 104 | longCorr_coef_bp = 0; |
---|
[3922] | 105 | long_cor_acc_n_bits = 6 * 2; |
---|
[3562] | 106 | |
---|
[3922] | 107 | %Scale, conjugate and time-reverse the standard LTS |
---|
| 108 | longCorr_coef = fliplr(conj(PLCP_Preamble.LTS_t./max(abs(PLCP_Preamble.LTS_t)))); |
---|
[3562] | 109 | |
---|
[3922] | 110 | longCorr_coef_i = [3*real(longCorr_coef)]; |
---|
| 111 | longCorr_coef_q = [3*imag(longCorr_coef)]; |
---|
[3562] | 112 | |
---|
[2088] | 113 | |
---|
[3922] | 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; |
---|
[2088] | 120 | |
---|
[3922] | 121 | %Define the frequency-domain training symbol coefficients |
---|
| 122 | % sign() here stores +/-1 (LTS is BPSK in freq domain) for smaller memory in hardware |
---|
[2088] | 123 | |
---|
[4394] | 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 | |
---|
[3922] | 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. |
---|
[4394] | 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); |
---|
[2088] | 140 | |
---|
[4394] | 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 | |
---|
[5170] | 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 | |
---|
[5238] | 152 | % FFT offset depends on PHY samp rate (and waveform format?) |
---|
[5713] | 153 | % 20: FFT_OFFSET=2 for zero cyclic prefix samps |
---|
| 154 | % 40: FFT_OFFSET=4 for zero cyclic prefix samps |
---|
[5238] | 155 | %PHY_CONFIG_FFT_OFFSET = (1+2*(rx_sim.samp_rate==40)) + 0; |
---|
[5736] | 156 | PHY_CONFIG_FFT_OFFSET = 7; |
---|
[5238] | 157 | |
---|
[2142] | 158 | PHY_CONFIG_RSSI_SUM_LEN = 8; |
---|
| 159 | |
---|
[4402] | 160 | PHY_SIGNAL_MIN_LEN = 14; |
---|
[2088] | 161 | |
---|
[6217] | 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; |
---|
[2142] | 166 | PHY_CONFIG_LTS_CORR_RSSI_THRESH = PHY_CONFIG_RSSI_SUM_LEN*400; |
---|
| 167 | |
---|
[4402] | 168 | PHY_CONFIG_LTS_CORR_TIMEOUT = 175; |
---|
[2088] | 169 | |
---|
[6168] | 170 | %DSSS auto correlation pkt det thresholds |
---|
[6194] | 171 | PHY_CONFIG_PKT_DET_CORR_THRESH_DSSS = 115; |
---|
| 172 | PHY_CONFIG_PKT_DET_ENERGY_THRESH_DSSS = 16; |
---|
[3562] | 173 | |
---|
[5238] | 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; |
---|
[3588] | 179 | |
---|
[5249] | 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 | |
---|
[5238] | 182 | %PHY_CONFIG_H_EST_SMOOTHING_A = 2000; |
---|
| 183 | %PHY_CONFIG_H_EST_SMOOTHING_B = 0; |
---|
| 184 | |
---|
[6325] | 185 | PHY_CONFIG_PKT_DET_CORR_THRESH = 100; |
---|
[6194] | 186 | PHY_CONFIG_PKT_DET_ENERGY_THRESH = 8; |
---|
[6168] | 187 | PHY_CONFIG_PKT_DET_MIN_DURR = 4; %UFix4_0 duration |
---|
[6217] | 188 | PHY_CONFIG_PKT_DET_RESET_EXT_DUR = 1;%hex2dec('3F'); |
---|
[2088] | 189 | |
---|
[2128] | 190 | CS_CONFIG_CS_RSSI_THRESH = 300 * PHY_CONFIG_RSSI_SUM_LEN; |
---|
[5646] | 191 | CS_CONFIG_POSTRX_EXTENSION = 6*20; %6usec as 120 20MHz samples |
---|
[2088] | 192 | |
---|
[5238] | 193 | SOFT_DEMAP_SCALE_BPSK = 15; |
---|
| 194 | SOFT_DEMAP_SCALE_QPSK = 15; |
---|
| 195 | SOFT_DEMAP_SCALE_16QAM = 18; |
---|
| 196 | SOFT_DEMAP_SCALE_64QAM = 22; |
---|
[2088] | 197 | |
---|
| 198 | REG_RX_PktDet_AutoCorr_Config = ... |
---|
[2870] | 199 | 2^0 * (PHY_CONFIG_PKT_DET_CORR_THRESH) +...%b[7:0] UFix8_8 |
---|
[6194] | 200 | 2^8 * (PHY_CONFIG_PKT_DET_ENERGY_THRESH) +...%b[21:8] UFix14_2 |
---|
[2870] | 201 | 2^22 * (PHY_CONFIG_PKT_DET_MIN_DURR) +...%b[25:22] |
---|
[2088] | 202 | 2^26 * (PHY_CONFIG_PKT_DET_RESET_EXT_DUR) + ...%b[31:26] |
---|
| 203 | 0; |
---|
| 204 | |
---|
[2142] | 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] |
---|
[2088] | 208 | 0; |
---|
| 209 | |
---|
[5713] | 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 | |
---|
[5238] | 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] |
---|
[6267] | 218 | 2^24 * 12; %PHY mode det threshold; 12 chosen experimentally |
---|
[5238] | 219 | 0; |
---|
| 220 | |
---|
[2142] | 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] |
---|
[5713] | 224 | 2^24 * 7 + ... %b[26:24] - 0x1/2/4 enables 63/64/65-sample spacing for LTS corr |
---|
[2142] | 225 | 0; |
---|
| 226 | |
---|
[2088] | 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 = ... |
---|
[5646] | 240 | 2^0 * 1 + ... %DSSS RX EN |
---|
[2184] | 241 | 2^1 * 1 + ... %Block inputs on INVALID input |
---|
| 242 | 2^2 * 1 + ... %Swap pkt buf byte order |
---|
[2671] | 243 | 2^3 * 1 + ... %Swap order of chan est u32 writes |
---|
[6177] | 244 | 2^4 * 0 + ... %Block DSSS Rx until DSSS pkt det has occurred |
---|
[5328] | 245 | 2^5 * 0 + ... %Bypass CFO est/correction |
---|
[2313] | 246 | 2^6 * 1 + ... %Enable chan est recording to pkt buf |
---|
[2671] | 247 | 2^7 * 0 + ... %Enable switching diversity |
---|
[6177] | 248 | 2^8 * 0 + ... %Disable OFDM pipeline |
---|
[2330] | 249 | 2^9 * 1 + ... %Enable pkt det on Ant A |
---|
| 250 | 2^10 * 0 + ... %Enable pkt det on Ant B |
---|
[2671] | 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) |
---|
[3562] | 256 | 2^17 * 2 + ... %Max SIGNAL.LENGTH value, in kB (UFix4_0) |
---|
[6151] | 257 | 2^21 * 0 + ... %Require auto-corr and RSSI pkt det for OFDM Rx |
---|
[5550] | 258 | 2^22 * 0 + ... %Rate-Length Busy holds pkt det high |
---|
[5051] | 259 | 2^23 * 1 + ... %DSSS asserts CCA busy |
---|
| 260 | 2^24 * 1 + ... %Enable 11n Rx support |
---|
[5850] | 261 | 2^25 * 1 + ... %Enable detection of 11ac waveforms based on VHT-SIG modulation |
---|
[6151] | 262 | 2^26 * 0 + ... %Require RSSI and AutoCorr detection for DSSS Rx |
---|
[6177] | 263 | 2^27 * 0 + ... %Reset pkt det counters |
---|
| 264 | 2^28 * 0 + ... %DSSS SYNC w/out pkt-det blocks pkt-det until done |
---|
[6217] | 265 | 2^29 * 0 + ... %OFDM Rx requires pkt det; 0=LTS correlation alone can start Rx |
---|
[2088] | 266 | 0; |
---|
| 267 | |
---|
| 268 | REG_RX_DSSS_RX_CONFIG = ... |
---|
[6151] | 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) |
---|
[3562] | 273 | 0; |
---|
[2088] | 274 | |
---|
[3562] | 275 | REG_RX_PktDet_DSSS_Config = ... |
---|
| 276 | 2^0 * (PHY_CONFIG_PKT_DET_CORR_THRESH_DSSS) +... %b[7:0] UFix8_7 |
---|
[6194] | 277 | 2^8 * (PHY_CONFIG_PKT_DET_ENERGY_THRESH_DSSS) +...%b[23:8] UFix14_2 |
---|
[3562] | 278 | 0; |
---|
| 279 | |
---|
[2088] | 280 | REG_RX_PKTDET_RSSI_CONFIG = ... |
---|
| 281 | 2^0 * (PHY_CONFIG_RSSI_SUM_LEN) + ... %b[4:0]: RSSI sum len |
---|
[2128] | 282 | 2^5 * (300*8) + ... %b[19:5]: RSSI thresh |
---|
| 283 | 2^20 * (4) + ... %b[24:20]: Min duration |
---|
[2088] | 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 | |
---|
[2313] | 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 |
---|
[4402] | 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) |
---|
[2313] | 296 | 0; |
---|
[2088] | 297 | |
---|
| 298 | REG_RX_FEC_Config = ... |
---|
[5176] | 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) + ... |
---|
[2088] | 303 | 0; |
---|
| 304 | |
---|
[4267] | 305 | REG_RX_PKT_BUF_Max_Write_Addr = 3800; |
---|
| 306 | |
---|
[2088] | 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 | |
---|
[3922] | 314 | %LFSR polynomial: x^7 + x^4 + 1 |
---|
[2088] | 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 |
---|
[3922] | 320 | |
---|
| 321 | %Convert bitwise descrambler states to bytewise descramber states |
---|
[4455] | 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 | %% |
---|
[3922] | 328 | %Generate the vector of addresses for the bytewise descramber ROM |
---|
[2088] | 329 | scr = [scr scr(1:10)]; |
---|
| 330 | scr_ind_rev = zeros(1,128); |
---|
| 331 | for ii=1:127 |
---|
[4455] | 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; |
---|
[2088] | 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 | |
---|
[4394] | 342 | CRCPolynomial8 = hex2dec('07'); %CRC-8 |
---|
| 343 | CRC_Table8 = CRC_table_gen(CRCPolynomial8, 8); |
---|
[2088] | 344 | |
---|
[4394] | 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 | |
---|
[3922] | 359 | %Max bits-per-symbol determines size of de-interleaver RAM |
---|
[4394] | 360 | MAX_NCBPS = NCBPS_11n_64QAM; |
---|
[3922] | 361 | |
---|
[4394] | 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; |
---|
[2184] | 370 | |
---|
[4394] | 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 |
---|
[3922] | 382 | % BPSK |
---|
[4394] | 383 | N_CBPS = NCBPS_11a_BPSK; |
---|
[2088] | 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 | |
---|
[4394] | 392 | interleave_11a_BPSK = i; |
---|
[2088] | 393 | clear N_CBPS N_BPSC s k i |
---|
| 394 | |
---|
[3922] | 395 | % QPSK |
---|
[4394] | 396 | N_CBPS = NCBPS_11a_QPSK; |
---|
[2088] | 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); |
---|
[4394] | 403 | interleave_11a_QPSK = j; |
---|
[2088] | 404 | clear N_CBPS N_BPSC s k i j |
---|
| 405 | |
---|
[3922] | 406 | % 16-QAM |
---|
[4394] | 407 | N_CBPS = NCBPS_11a_16QAM; |
---|
[2088] | 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); |
---|
[4394] | 414 | interleave_11a_16QAM = j; |
---|
[2088] | 415 | clear N_CBPS N_BPSC s k i j |
---|
| 416 | |
---|
[3922] | 417 | % 64-QAM |
---|
[4394] | 418 | N_CBPS = NCBPS_11a_64QAM; |
---|
[2153] | 419 | N_BPSC = 6; |
---|
| 420 | s = max(N_BPSC/2, 1); |
---|
[2088] | 421 | |
---|
[2153] | 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); |
---|
[4394] | 425 | interleave_11a_64QAM = j; |
---|
[2153] | 426 | clear N_CBPS N_BPSC s k i j |
---|
| 427 | |
---|
[2088] | 428 | %FFT Shift |
---|
[4394] | 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); |
---|
[2088] | 433 | |
---|
[4394] | 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 | |
---|
[3922] | 489 | %De-interleaver ROM contents - one ROM used for all rates |
---|
[2088] | 490 | deinterleave_ROM = []; |
---|
[4394] | 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 | |
---|
[6151] | 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 |
---|
[6258] | 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 |
---|