RENEWLab  1.1.0
RENEW project
rl_ofdm_mmimo_sim.m File Reference

Functions

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)
 

Variables

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
 

Function Documentation

◆ arrayfun()

mod_fcn_16qam, tx_ul_data arrayfun ( )
virtual

◆ Author:Mohamamdy:http:LICENSE:http:()

s Author:Mohamamdy:http:LICENSE:http: ( id  Doost,
[Mohamamdy] id  License,
[http] c  SOURCE,
[LICENSE] id  ,
[http] id  all 
)
virtual

◆ AWGN:()

id AWGN: ( 'shuffle'  rng)
staticvirtual

◆ calib_mat()

calib_mat ( ,
SC_IND_DATA   
)

◆ FFT()

Number of CP samples to use in FFT ( on  average)
pure virtual

◆ fprintf()

otherwise fprintf ( 'Invalid MOD_ORDER(%d)! Must be in\n'  [2, 4, 16, 64],
MOD_ORDER   
)

◆ if()

Insert the cyclic prefix if ( CP_LEN  ,
 
)

◆ ifft_in_mat() [1/2]

other subcarriers will remain at ifft_in_mat ( ,
SC_IND_DATA  ,
 
)

◆ ifft_in_mat() [2/2]

ifft_in_mat ( ,
SC_IND_PILOTS  ,
 
)

◆ modvec_bpsk()

1/sqrt(2 modvec_bpsk ( )
virtual

◆ N_UE()

id N_UE ( )
virtual

◆ order()

Modulation order ( 2/4/16/  64 = BSPK/QPSK/16-QAM/64-QAM)

◆ rng()

Generate mMIMO tranceivers random phase vector [-pi, pi] if DO_APPLY_HW_IMPERFECTION rng ( 'shuffle'  )

◆ symbols()

Number of data symbols ( one per data-bearing subcarrier per OFDM  symbol)

◆ tx_pilot_vec()

tx_pilot_vec ( i  ,
(i-1) *SYM_LEN+1:i SYM_LEN 
)

◆ waveform()

Scale for Tx waveform ( )

Variable Documentation

◆ calib_mat

end BS Calibration calib_mat = ones(N_BS_ANT, N_SC)

◆ CP_LEN

Number of subcarriers CP_LEN = 16

◆ demod_fcn_16qam

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

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

◆ demod_fcn_bpsk

demod_fcn_bpsk = @(x) double(real(x)>0)

◆ demod_fcn_qpsk

demod_fcn_qpsk = @(x) double(2*(real(x)>0) + 1*(imag(x)>0))

◆ dl_rx_calib

dl_rx_calib = repmat(H_ref, 1, N_SC) .* dl_tx_calib + Z_mat

◆ dl_rx_calib_fft

dl_rx_calib_fft = fft(dl_rx_calib, N_SC, 2) * rx_ref_hw_phase

◆ dl_rx_hw_phase

dl_rx_hw_phase = exp((2 * pi * repmat(rand(N_UE, 1), 1, N_SC) - pi) * 1j)

◆ dl_tx_calib

dl_tx_calib = ifft(repmat(lts_f, N_BS_ANT, 1) .* dl_tx_hw_phase, N_SC, 2)

◆ dl_tx_hw_phase

else dl_tx_hw_phase = exp((2 * pi * repmat(rand(N_BS_ANT, 1), 1, N_SC) - pi) * 1j)

◆ DO_APPLY_CFO_CORRECTION

Normalized threshold for LTS correlation DO_APPLY_CFO_CORRECTION = 0

◆ DO_APPLY_HW_IMPERFECTION

DO_APPLY_HW_IMPERFECTION = 1

◆ DO_APPLY_PHASE_ERR_CORRECTION

Enable SFO estimation correction DO_APPLY_PHASE_ERR_CORRECTION = 0

◆ DO_APPLY_SFO_CORRECTION

Enable CFO estimation correction DO_APPLY_SFO_CORRECTION = 0

◆ DO_RECIPROCAL_CALIBRATION

DO_RECIPROCAL_CALIBRATION = 1

◆ DO_SAVE_RX_DATA

DO_SAVE_RX_DATA = 0

◆ FFT_OFFSET

Rx processing params FFT_OFFSET = 16

◆ H

UL noise matrix H = sqrt(H_var/2) .* ( randn(N_BS_ANT, N_UE) + 1i*randn(N_BS_ANT, N_UE) )

◆ h_dl_calib

h_dl_calib = dl_rx_calib_fft .* repmat(lts_f, N_BS_ANT, 1)

◆ H_ref

H_ref = sqrt(H_var / 2) .* (randn(N_BS_ANT, 1) + 1i*randn(N_BS_ANT, 1))

◆ h_ul_calib

h_ul_calib = ul_rx_calib_fft .* repmat(lts_f, N_BS_ANT, 1)

◆ H_var

H_var = 1

◆ i

additional pilot as noise for i
Initial value:

◆ ifft_in_hw_mat

Apply hardware phase distortion ifft_in_hw_mat = ifft_in_mat .* repmat(ul_tx_hw_phase, 1, 1, N_OFDM_SYMS)

◆ ifft_in_mat

end IFFT Construct the IFFT input matrix ifft_in_mat = zeros(N_UE, N_SC, N_OFDM_SYMS)

◆ lts_f

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

lts_t = ifft(lts_f, 64)

◆ mod_fcn_16qam

mod_fcn_16qam = @(x) complex(modvec_16qam(1+bitshift(x, -2)), modvec_16qam(1+mod(x,4)))

◆ mod_fcn_64qam

mod_fcn_64qam = @(x) complex(modvec_64qam(1+bitshift(x, -3)), modvec_64qam(1+mod(x,8)))

◆ mod_fcn_bpsk

mod_fcn_bpsk = @(x) complex(modvec_bpsk(1+x),0)

◆ mod_fcn_qpsk

mod_fcn_qpsk = @(x) complex(modvec_bpsk(1+bitshift(x, -1)), modvec_bpsk(1+mod(x, 2)))

◆ MOD_ORDER

Number of OFDM symbols MOD_ORDER = 16

◆ modvec_16qam

modvec_16qam = (1/sqrt(10)) .* [-3 -1 +3 +1]

◆ modvec_64qam

modvec_64qam = (1/sqrt(43)) .* [-7 -5 -1 -3 +7 +5 +1 +3]

◆ N_0

N_0 = 1e-2

◆ N_BEGIN_ZERO_PAD

Trigger time offset toleration between Tx and Rx that can be accomodated N_BEGIN_ZERO_PAD = 100

◆ N_BS_ANT

N_BS_ANT = 64

◆ N_DATA_SYMS

Cyclic prefix length N_DATA_SYMS = N_OFDM_SYMS * length(SC_IND_DATA)

◆ N_END_ZERO_PAD

N_END_ZERO_PAD = 100

◆ N_OFDM_SYMS

Waveform params N_OFDM_SYMS = 24

◆ N_SC

Data subcarrier indices N_SC = 64

◆ N_SC_ZERO

Indices of subcarriers with no data N_SC_ZERO = length(SC_ZER0)

◆ N_UPLINK_SYMBOLS

N_BS_ANT N_UE N_UPLINK_SYMBOLS = N_OFDM_SYMS

◆ pt_pilots

Define the pilot tone values as BPSK symbols pt_pilots = [1 1 -1 1].'

◆ pt_pilots_mat

Repeat the pilots across all OFDM symbols pt_pilots_mat = zeros(N_UE, 4, N_OFDM_SYMS)

◆ return

return

◆ rx_ref_hw_phase

rx_ref_hw_phase = exp((2 * pi * rand - pi) * 1j)

◆ rx_vec_air

Spatial Channel Matrix rx_vec_air = H * tx_vec_air + Z_mat

◆ SAMP_FREQ

Enable Residual CFO estimation correction SAMP_FREQ = 20e6

◆ SC_IND_DATA

Pilot subcarrier indices SC_IND_DATA = [2:7 9:21 23:27 39:43 45:57 59:64]

◆ SC_ZER0

SC_ZER0 = [1 28:38]

◆ TRIGGER_OFFSET_TOL_NS

TRIGGER_OFFSET_TOL_NS = 3000

◆ tx_payload_mat

tx_payload_mat = ifft(ifft_in_hw_mat, N_SC, 2)

◆ tx_payload_vec

end Reshape to a vector tx_payload_vec = reshape(tx_payload_mat, N_UE, numel(tx_payload_mat(1,:,:)))

◆ tx_pilot_vec

tx_pilot_vec = zeros(N_UE, SYM_LEN * (N_UE+1))

◆ tx_ref_hw_phase

if DO_RECIPROCAL_CALIBRATION tx_ref_hw_phase = exp((2 * pi * rand - pi) * 1j)

◆ tx_ul_data

end Uplink Generate a payload of random integers tx_ul_data = randi(MOD_ORDER, N_UE, N_DATA_SYMS) - 1

◆ tx_ul_syms

case QPSK tx_ul_syms = arrayfun(mod_fcn_bpsk, tx_ul_data)

◆ tx_ul_syms_mat

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)

◆ tx_vec_air

tx_vec_air = TX_SCALE .* tx_vec ./ repmat(max(abs(tx_vec),[],2), 1, size(tx_vec, 2))

◆ ul_rx_calib

ul_rx_calib = H_ref * ul_tx_calib + Z_mat

◆ ul_rx_calib_fft

ul_rx_calib_fft = fft(ul_rx_calib, N_SC, 2) .* ul_rx_hw_phase

◆ ul_rx_hw_phase

ul_rx_hw_phase = exp((2 * pi * repmat(rand(N_BS_ANT, 1), 1, N_SC) - pi) * 1j)

◆ ul_tx_calib

ul_tx_calib = ifft(lts_f * tx_ref_hw_phase)

◆ ul_tx_hw_phase

ul_tx_hw_phase = exp((2 * pi * repmat(rand(N_UE, 1), 1, N_SC) - pi) * 1j)

◆ values

Insert the data and pilot values

◆ Z_mat

Z_mat = sqrt(1e-4 / 2) * (randn(N_BS_ANT, length(ul_tx_calib)) + 1i*randn(N_BS_ANT, length(ul_tx_calib)))
N_OFDM_SYMS
Waveform params N_OFDM_SYMS
Definition: rl_ofdm_mmimo_sim.m:20
N_UE
id N_UE()
Definition: ofdm_mimo.m:39
pt_pilots
Define the pilot tone values as BPSK symbols pt_pilots
Definition: rl_ofdm_mmimo_sim.m:140
i
for i
Definition: rl_ofdm_mmimo_sim.m:144
repmat
repmat(lts_t, N_LTS_SYM, 1)]
pt_pilots_mat
Repeat the pilots across all OFDM symbols pt_pilots_mat
Definition: rl_ofdm_mmimo_sim.m:143