|
| s | Author:Mohamamdy:http:LICENSE:http: (id Doost,[Mohamamdy] id License,[http] c SOURCE,[LICENSE] id,[http] id all) |
| |
| Modulation | order (2/4/16/64=BSPK/QPSK/16-QAM/64-QAM) TX_SCALE |
| |
| Scale for Tx | waveform ([0:1]) % OFDM params SC_IND_PILOTS |
| |
| Number of data | symbols (one per data-bearing subcarrier per OFDM symbol) SYM_LEN |
| |
| Number of CP samples to use in | FFT (on average) LTS_CORR_THRESH=0.8 |
| |
| id | N_UE () |
| |
| 1/sqrt(2 | modvec_bpsk () |
| |
| Generate mMIMO tranceivers random phase vector[-pi, pi] if DO_APPLY_HW_IMPERFECTION | rng ('shuffle') |
| |
| | calib_mat (:, SC_IND_DATA) |
| |
| mod_fcn_16qam, tx_ul_data | arrayfun () |
| |
| otherwise | fprintf ('Invalid MOD_ORDER(%d)! Must be in[2, 4, 16, 64]\n', MOD_ORDER) |
| |
| other subcarriers will remain at | ifft_in_mat (:, SC_IND_DATA, :) |
| |
| | ifft_in_mat (:, SC_IND_PILOTS, :) |
| |
| Insert the cyclic prefix | if (CP_LEN > 0) tx_cp |
| |
| | tx_pilot_vec (i,(i-1) *SYM_LEN+1:i *SYM_LEN) |
| |
| id | AWGN: ( 'shuffle' rng) |
| |
|
| Waveform params | N_OFDM_SYMS = 24 |
| |
| Number of OFDM symbols | MOD_ORDER = 16 |
| |
| Pilot subcarrier indices | SC_IND_DATA = [2:7 9:21 23:27 39:43 45:57 59:64] |
| |
| Data subcarrier indices | N_SC = 64 |
| |
| Number of subcarriers | CP_LEN = 16 |
| |
| Cyclic prefix length | N_DATA_SYMS = N_OFDM_SYMS * length(SC_IND_DATA) |
| |
| | SC_ZER0 = [1 28:38] |
| |
| Indices of subcarriers with no data | N_SC_ZERO = length(SC_ZER0) |
| |
| Rx processing params | FFT_OFFSET = 16 |
| |
| Normalized threshold for LTS correlation | DO_APPLY_CFO_CORRECTION = 0 |
| |
| Enable CFO estimation correction | DO_APPLY_SFO_CORRECTION = 0 |
| |
| Enable SFO estimation correction | DO_APPLY_PHASE_ERR_CORRECTION = 0 |
| |
| Enable Residual CFO estimation correction | SAMP_FREQ = 20e6 |
| |
| | TRIGGER_OFFSET_TOL_NS = 3000 |
| |
| Trigger time offset toleration between Tx and Rx that can be accomodated | N_BEGIN_ZERO_PAD = 100 |
| |
| | N_END_ZERO_PAD = 100 |
| |
| | N_BS_ANT = 64 |
| |
| N_BS_ANT N_UE | N_UPLINK_SYMBOLS = N_OFDM_SYMS |
| |
| | N_0 = 1e-2 |
| |
| | H_var = 1 |
| |
| | DO_SAVE_RX_DATA = 0 |
| |
| | DO_APPLY_HW_IMPERFECTION = 1 |
| |
| | DO_RECIPROCAL_CALIBRATION = 1 |
| |
| LTS for CFO and channel estimation | lts_f = [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] |
| |
| | lts_t = ifft(lts_f, 64) |
| |
| | modvec_16qam = (1/sqrt(10)) .* [-3 -1 +3 +1] |
| |
| | modvec_64qam = (1/sqrt(43)) .* [-7 -5 -1 -3 +7 +5 +1 +3] |
| |
| | mod_fcn_bpsk = @(x) complex(modvec_bpsk(1+x),0) |
| |
| | mod_fcn_qpsk = @(x) complex(modvec_bpsk(1+bitshift(x, -1)), modvec_bpsk(1+mod(x, 2))) |
| |
| | mod_fcn_16qam = @(x) complex(modvec_16qam(1+bitshift(x, -2)), modvec_16qam(1+mod(x,4))) |
| |
| | mod_fcn_64qam = @(x) complex(modvec_64qam(1+bitshift(x, -3)), modvec_64qam(1+mod(x,8))) |
| |
| | demod_fcn_bpsk = @(x) double(real(x)>0) |
| |
| | demod_fcn_qpsk = @(x) double(2*(real(x)>0) + 1*(imag(x)>0)) |
| |
| | demod_fcn_16qam = @(x) (8*(real(x)>0)) + (4*(abs(real(x))<0.6325)) + (2*(imag(x)>0)) + (1*(abs(imag(x))<0.6325)) |
| |
| | demod_fcn_64qam = @(x) (32*(real(x)>0)) + (16*(abs(real(x))<0.6172)) + (8*((abs(real(x))<(0.9258))&&((abs(real(x))>(0.3086))))) + (4*(imag(x)>0)) + (2*(abs(imag(x))<0.6172)) + (1*((abs(imag(x))<(0.9258))&&((abs(imag(x))>(0.3086))))) |
| |
| | dl_tx_hw_phase = exp((2 * pi * repmat(rand(N_BS_ANT, 1), 1, N_SC) - pi) * 1j) |
| |
| | dl_rx_hw_phase = exp((2 * pi * repmat(rand(N_UE, 1), 1, N_SC) - pi) * 1j) |
| |
| | ul_tx_hw_phase = exp((2 * pi * repmat(rand(N_UE, 1), 1, N_SC) - pi) * 1j) |
| |
| | ul_rx_hw_phase = exp((2 * pi * repmat(rand(N_BS_ANT, 1), 1, N_SC) - pi) * 1j) |
| |
| end BS Calibration | calib_mat = ones(N_BS_ANT, N_SC) |
| |
| if DO_RECIPROCAL_CALIBRATION | tx_ref_hw_phase = exp((2 * pi * rand - pi) * 1j) |
| |
| | rx_ref_hw_phase = exp((2 * pi * rand - pi) * 1j) |
| |
| | ul_tx_calib = ifft(lts_f * tx_ref_hw_phase) |
| |
| | H_ref = sqrt(H_var / 2) .* (randn(N_BS_ANT, 1) + 1i*randn(N_BS_ANT, 1)) |
| |
| | Z_mat = sqrt(1e-4 / 2) * (randn(N_BS_ANT, length(ul_tx_calib)) + 1i*randn(N_BS_ANT, length(ul_tx_calib))) |
| |
| | ul_rx_calib = H_ref * ul_tx_calib + Z_mat |
| |
| | ul_rx_calib_fft = fft(ul_rx_calib, N_SC, 2) .* ul_rx_hw_phase |
| |
| | h_ul_calib = ul_rx_calib_fft .* repmat(lts_f, N_BS_ANT, 1) |
| |
| | dl_tx_calib = ifft(repmat(lts_f, N_BS_ANT, 1) .* dl_tx_hw_phase, N_SC, 2) |
| |
| | dl_rx_calib = repmat(H_ref, 1, N_SC) .* dl_tx_calib + Z_mat |
| |
| | dl_rx_calib_fft = fft(dl_rx_calib, N_SC, 2) * rx_ref_hw_phase |
| |
| | h_dl_calib = dl_rx_calib_fft .* repmat(lts_f, N_BS_ANT, 1) |
| |
| end Uplink Generate a payload of random integers | tx_ul_data = randi(MOD_ORDER, N_UE, N_DATA_SYMS) - 1 |
| |
| Map the data values on to complex symbols switch MOD_ORDER case BPSK | tx_ul_syms = arrayfun(mod_fcn_bpsk, tx_ul_data) |
| |
| | return |
| |
| end Reshape the symbol vector to a matrix with one column per OFDM symbol | tx_ul_syms_mat = reshape(tx_ul_syms, N_UE, length(SC_IND_DATA), N_OFDM_SYMS) |
| |
| Define the pilot tone values as BPSK symbols | pt_pilots = [1 1 -1 1].' |
| |
| Repeat the pilots across all OFDM symbols | pt_pilots_mat = zeros(N_UE, 4, N_OFDM_SYMS) |
| |
| for | i |
| |
| end IFFT Construct the IFFT input matrix | ifft_in_mat = zeros(N_UE, N_SC, N_OFDM_SYMS) |
| |
| Insert the data and pilot | values |
| |
| Apply hardware phase distortion | ifft_in_hw_mat = ifft_in_mat .* repmat(ul_tx_hw_phase, 1, 1, N_OFDM_SYMS) |
| |
| Perform the IFFT | tx_payload_mat = ifft(ifft_in_hw_mat, N_SC, 2) |
| |
| end Reshape to a vector | tx_payload_vec = reshape(tx_payload_mat, N_UE, numel(tx_payload_mat(1,:,:))) |
| |
| | tx_pilot_vec = zeros(N_UE, SYM_LEN * (N_UE+1)) |
| |
| | tx_vec_air = TX_SCALE .* tx_vec ./ repmat(max(abs(tx_vec),[],2), 1, size(tx_vec, 2)) |
| |
| UL noise matrix | H = sqrt(H_var/2) .* ( randn(N_BS_ANT, N_UE) + 1i*randn(N_BS_ANT, N_UE) ) |
| |
| Spatial Channel Matrix | rx_vec_air = H * tx_vec_air + Z_mat |
| |