|
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 |
|