RENEWLab  1.1.0
RENEW project
rl_ofdm_mimo.m File Reference

Functions

if ~isloaded pyversion usr bin python py print() %weird bug where py isn 't loaded in an external script end % Params Number of SDRs (Matlab scripts only using antenna A) N_UE
 
Scale for Tx waveform ([0:1]) bs_ids
 
id chains: (id RF3E000716)
 
Number of UE nodes end fprintf ("Channel type: %s \n", chan_type)
 
Modulation order (2/4/16/64=BSPK/QPSK/16-QAM/64-QAM) % OFDM params SC_IND_PILOTS
 
Number of data symbols (one per data-bearing subcarrier per OFDM symbol) per UE N_LTS_SYM
 
id FFT_OFFSET ()
 
Number of CP samples to use in FFT (on average) DO_APPLY_PHASE_ERR_CORRECTION
 
 repmat (lts_t, N_LTS_SYM, 1)]
 
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
 
N_ZPAD_PRE, N_UE zeros ()
 
 zeros (N_ZPAD_POST, N_UE)]
 
abs(tx_vecs_iris max ()
 
id a ()
 
 lts_corr (ibs,:)
 
Get the indices of N_UE largest corr values lts_peaks (ibs,:)
 
end payload_ind (ibs)
 
 rx_lts_mat (ibs,:)
 
 payload_rx (ibs, 1:length(pl_idx) -1)
 
 plot (lts_corr(sp,:))
 
 xlabel ('Samples')
 
 ylabel (y_label)
 
end sgtitle ('LTS correlations accross antennas') end %% Rx processing % Construct a matrix from the received pilots n_plt_samp
 
 Y_lts (:, iue,:)
 
else Do nz_sc(j))' *H_hat(Apply nz_sc(j))') *squeeze(Y_data(end syms_eq (:, nz_sc(j),:)
 
 channel_condition (nz_sc(j))
 
 channel_condition_db (nz_sc(j))
 
else Define an empty phase correction vector (used by plotting code below) pilot_phase_err
 
id D: (syms_eq_pc, N_UE,[] reshape)
 
 figure (cf)
 
 plot (real(rx_vec_iris(sp,:)))
 
 axis ([0 length(rx_vec_iris(sp,:)) -TX_SCALE TX_SCALE]) grid on
 
 title (sprintf('BS antenna %d Rx Waveform(I)', sp))
 
 subplot (N_BS_NODE, 2, 2 *sp)
 
 plot (imag(rx_vec_iris(sp,:)), 'color', sec_clr)
 
 title (sprintf('BS antenna %d Rx Waveform(Q)', sp))
 
 plot (real(tx_vecs_iris(:, sp)))
 
 title (sprintf('UE %d Tx Waveform(I)', sp))
 
 subplot (N_UE, 2, 2 *sp)
 
 plot (imag(tx_vecs_iris(:, sp)), 'color', sec_clr)
 
 title (sprintf('UE %d Tx Waveform(Q)', sp))
 
 plot (syms_eq_pc(:, sp), 'o', 'MarkerSize', 1, 'color', sec_clr)
 
 axis (1.5 *[-1 1 -1 1])
 
 plot (tx_syms(:, sp),' *', 'MarkerSize', 10, 'LineWidth', 2, 'color', fst_clr)
 
 title (sprintf('Equalized Uplink Tx(blue) and \n Rx(red) symbols for stream %d', sp))
 
 legend ({ 'Rx', 'Tx'}, 'Location', 'EastOutside', 'fontsize', 12)
 
 plot (squeeze(Y_data(sp,:,:)), 'co', 'MarkerSize', 1)
 
 axis (max(max(max(abs(Y_data)))) *[-1 1 -1 1])
 
 title (sprintf('Unequalized received symbols \n at BS ant. %d', sp))
 
 subplot (N_BS_NODE, N_UE, sp)
 
 bar (bw_span, fftshift(abs(squeeze(H_hat(ibs, iue, :)))), 1, 'LineWidth', 1)
 
 title (sprintf('UE %d -> BS ant. %d Channel Est.(Mag.)', iue, ibs)) xlabel('Baseband Frequency(MHz)') end end subplot(N_BS_NODE+1
 
 set (bh, 'FaceColor', cond_clr)
 
 title ('Channel Condition(dB)') xlabel('Baseband Frequency(MHz)') end %% EVM &SNR sym_errs
 
 evm_mat (:, sp)
 
 aevms (sp)
 
 snr_mat (sp)
 
 legend ('Per-Symbol EVM', 'Average EVM', 'Location', 'NorthWest')
 
 set (h, 'Color',[1 0 0]) set(h
 
bold set (h, 'FontSize', 10) set(h
 
bold set (h, 'BackgroundColor',[1 1 1]) title(sprintf('Stream from UE %d'
 
 imagesc (1:N_OFDM_SYM,(SC_IND_DATA - N_SC/2), 100 *fftshift(reshape(evm_mat(:, sp), [], N_OFDM_SYM), 1))
 
 set (h, 'LineStyle',':')
 
grid on xlabel ('OFDM Symbol Index')
 
 ylabel ('Subcarrier Index')
 
 title (sprintf('Stream from UE %d', sp))
 

Variables

 Author (s)[version, executable, isloaded] = pyversion
 
 WRITE_PNG_FILES = 0
 
Enable writing plots to PNG SIM_MOD = 0
 
 DEBUG = 0
 
 PLOT = 0
 
if SIM_MOD chan_type = "rayleigh"
 
Will use only Rayleigh for simulation sim_SNR_db = 15
 
 TX_SCALE = 1
 
 ue_ids = ones(1, N_UE)
 
else Iris params
 
 USE_HUB = 1
 
 TX_FRQ = 3.56e9
 
 RX_FRQ = TX_FRQ
 
 TX_GN = 80
 
 TX_GN_ue = 80
 
 RX_GN = 75
 
 SMPL_RT = 5e6
 
 N_FRM = 10
 
 BEACON_SWEEP = 0
 
 bs_ids = string.empty()
 
 ue_scheds = string.empty()
 
if USE_HUB Using chains of different size requires some internal calibration on the BS This functionality will be added later For now
 
 hub_id = "FH4B000021"
 
 N_BS_NODE = length(bs_ids)
 
Number of nodes antennas at the BS N_UE = length(ue_ids)
 
 MIMO_ALG = 'ZF'
 
MIMO ALGORITHM
 
Waveform params N_OFDM_SYM = 44
 
Number of OFDM symbols for burst
 
Number of OFDM symbols for it needs to be less than MOD_ORDER = 16
 
Pilot subcarrier indices SC_IND_DATA = [2:7 9:21 23:27 39:43 45:57 59:64]
 
Data subcarrier indices SC_IND_DATA_PILOT = [2:27 39:64]'
 
 N_SC = 64
 
Number of subcarriers CP_LEN = 16
 
Cyclic prefix length N_DATA_SYMS = N_OFDM_SYM * length(SC_IND_DATA)
 
Number of N_SYM_SAMP = N_SC + CP_LEN
 
Number of samples that will go over the air N_ZPAD_PRE = 90
 
Enable Residual CFO estimation correction Define the preamble LTS for fine CFO and channel estimation lts_f
 
 lts_t = ifft(lts_f, N_SC)
 
 l_pre = length(preamble_common)
 
 pre_z = zeros(size(preamble_common))
 
 preamble = zeros(N_UE * l_pre, N_UE)
 
for jp
 
end Generate a payload of random integers tx_data = randi(MOD_ORDER, N_DATA_SYMS, N_UE) - 1
 
 tx_syms = mod_sym(tx_data, MOD_ORDER)
 
Reshape the symbol vector to a matrix with one column per OFDM symbol tx_syms_mat = reshape(tx_syms, length(SC_IND_DATA), N_OFDM_SYM, N_UE)
 
Define the pilot tone values as BPSK symbols pilots = [1 1 -1 1].'
 
Repeat the pilots across all OFDM symbols pilots_mat = repmat(pilots, 1, N_OFDM_SYM, N_UE)
 
IFFT Construct the IFFT input matrix ifft_in_mat = zeros(N_SC, N_OFDM_SYM, N_UE)
 
Insert the data and pilot values
 
Perform the IFFT tx_payload_mat = ifft(ifft_in_mat, N_SC, 1)
 
end Reshape to a vector tx_payload_vecs = reshape(tx_payload_mat, ceil(numel(tx_payload_mat)/N_UE), N_UE)
 
Leftover from zero padding
 
SIMULATION __pad7__
 
Iris nodes parameters bs_sdr_params
 
 ue_sdr_params = bs_sdr_params
 
ue_sdr_params id = ue_ids
 
ue_sdr_params n_sdrs = N_UE
 
ue_sdr_params txgain = []
 
 rx_vec_iris = getRxVec(tx_vecs_iris, N_BS_NODE, N_UE, chan_type, sim_SNR_db, bs_sdr_params, ue_sdr_params, [])
 
just to agree with what the hardware spits out Init Iris nodes Set up the Iris experimenty else Create BS Hub and UE objects Note
 
BS schedule ue_sched = ["GGGGGGPG"]
 
UE schedule number of samples in a frame n_samp = length(tx_vecs_iris)
 
ue_sdr_params tdd_sched = ue_sched
 
end end l_rx_dec =length(rx_vec_iris)
 
 unos = ones(size(preamble_common'))
 
 lts_corr = zeros(N_BS_NODE, length(rx_vec_iris))
 
 data_len = (N_OFDM_SYM)*(N_SC +CP_LEN)
 
 rx_lts_mat = double.empty()
 
 payload_ind = int32.empty()
 
 payload_rx = zeros(N_BS_NODE, data_len)
 
 lts_peaks = zeros(N_BS_NODE, N_UE)
 
for ibs
 
 v1 = filter(unos,a,abs(rx_vec_iris(ibs,:)).^2)
 
normalized correlation Sort the correlation values sort_corr = sort(lts_corr(ibs,:), 'descend')
 
Take the N_UE largest values rho_max = sort_corr(1:N_UE)
 
position of the last peak max_idx = max(lts_peaks(ibs,:))
 
In case of bad correlatons
 
Real value doesn t matter since we have corrrupt data
 
 pream_ind_ibs = payload_ind(ibs) - length(preamble)
 
 pl_idx = payload_ind(ibs) : payload_ind(ibs) + data_len
 
end if DEBUG figure
 
end if DEBUG for sp
 
grid on
 
 y_label = sprintf('Anetnna %d',sp)
 
for iue
 
end Take N_SC spamples from each LTS rx_lts_idx = CP_LEN +1 : N_LTS_SYM * N_SC +CP_LEN
 
 Y_lts = Y_lts(:,:,rx_lts_idx)
 
Reshape the matix to have each lts pilot in a different dimension
 
Reshape the matix to have each lts pilot in a different N_LTS_SYM
 
Take FFT
 
Take Construct known pilot matrix to use i next step
 
Take Construct known pilot matrix to use i next N_BS_NODE *N_UE lts_f_mat = reshape(lts_f_mat, [], N_LTS_SYM, N_UE, N_BS_NODE)
 
Get the channel by dividing by the pilots G_lts = Y_lts_f ./ lts_f_mat
 
Estimate the channel by averaging over the two LTS symbols
 
Estimate the channel by averaging over the two LTS Calculate Condition Number validIdx = find(lts_f ~=0)
 
 condNum = zeros(1, length(validIdx))
 
for sc
 
end avgCond = mean(condNum)
 
 payload_noCP = payload_rx(:,CP_LEN-FFT_OFFSET+(1:N_SC),:)
 
Take FFT Y_data = fft(payload_noCP, N_SC, 2)
 
Apply ZF by multiplying the pseudo inverse of H_hat[N_BS_NODE x NUE] for each suubcarrier
 
 channel_condition = double.empty()
 
 channel_condition_db = double.empty()
 
for j
 
 x = HH_inv*squeeze(Y_data(:,nz_sc(j),:))
 
else Do yourselves
 
else Do nz_sc(j))' *H_hat(Apply BF
 
end DO_APPLY_PHASE_ERR_CORRECTION
 
 pilots_f_mat_comp = pilots_f_mat.* permute(pilots_mat, [3 1 2])
 
 pilot_phase_err = angle(mean(pilots_f_mat_comp,2))
 
end pilot_phase_err_corr = repmat(pilot_phase_err, 1, N_SC, 1)
 
 pilot_phase_corr = exp(-1i*(pilot_phase_err_corr))
 
Apply the pilot phase correction per symbol syms_eq_pc = syms_eq.* pilot_phase_corr
 
Demodulate rx_data = demod_sym(syms_eq_pc ,MOD_ORDER)
 
Plot results cf = 0
 
 fst_clr = [0, 0.4470, 0.7410]
 
 sec_clr = [0.8500, 0.3250, 0.0980]
 
 clf
 
 myAxis = axis()
 
tb FontWeight = 'bold'
 
else sp_rows = ceil(N_BS_NODE/2)+1
 
end sp_cols = ceil(N_BS_NODE/(sp_rows -1))
 
axis square
 
 cond_clr = [0.8500, 0.250, 0.1980]
 
 bw_span = (20/N_SC) * (-(N_SC/2):(N_SC/2 - 1)).'
 
 bh = bar(bw_span, fftshift(channel_condition_db) ,1, 'LineWidth', 1)
 
 bit_errs = length(find(dec2bin(bitxor(tx_data(:), rx_data(:)),8) == '1'))
 
 evm_mat = double.empty()
 
 aevms = zeros(N_UE,1)
 
 snr_mat = zeros(N_UE,1)
 
 h = text(round(.05*length(evm_mat(:,sp))), 100*aevms(sp), sprintf('Effective SINR: %.1f dB', snr_mat(sp)))
 
bold EdgeColor
 
hold off
 

Function Documentation

◆ a()

id a ( )
virtual

◆ aevms()

aevms ( sp  )

◆ axis() [1/3]

axis ( 1.5 *  [-1 1 -1 1])

◆ axis() [2/3]

axis ( )

◆ axis() [3/3]

axis ( max(max(max(abs(Y_data)))) *  [-1 1 -1 1])

◆ bar()

bar ( bw_span  ,
fftshift(abs(squeeze(H_hat(ibs, iue, :))))  ,
,
'LineWidth'  ,
 
)

◆ chains:()

id chains: ( id  RF3E000716)
virtual

◆ channel_condition()

channel_condition ( nz_sc(j )

◆ channel_condition_db()

channel_condition_db ( nz_sc(j )

◆ D:()

id D: ( syms_eq_pc  ,
N_UE  ,
[] reshape   
)
virtual

◆ evm_mat()

evm_mat ( ,
sp   
)

◆ FFT()

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

◆ FFT_OFFSET()

id FFT_OFFSET ( )
virtual

◆ figure()

figure ( cf  )

◆ fprintf()

Number of UE nodes end fprintf ( "Channel type: %s \n"  ,
chan_type   
)

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

◆ imagesc()

imagesc ( 1:N_OFDM_SYM  ,
(SC_IND_DATA - N_SC/2)  ,
100 *  fftshiftreshape(evm_mat(:, sp),[], N_OFDM_SYM), 1 
)

◆ legend() [1/2]

legend ( 'Per-Symbol EVM'  ,
'Average EVM'  ,
'Location ,
'NorthWest'   
)

◆ legend() [2/2]

legend ( { 'Rx', 'Tx'}  ,
'Location ,
'EastOutside ,
'fontsize'  ,
12   
)

◆ lts_corr()

lts_corr ( ibs  ,
 
)

◆ lts_peaks()

Get the indices of N_UE largest corr values lts_peaks ( ibs  ,
 
)

◆ max()

abs(tx_vecs_iris max ( )
staticvirtual

◆ order()

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

◆ payload_ind()

end payload_ind ( ibs  )

◆ payload_rx()

payload_rx ( ibs  ,
1:length(pl_idx) -  1 
)

◆ plot() [1/8]

plot ( imag(rx_vec_iris(sp,:))  ,
'color'  ,
sec_clr   
)

◆ plot() [2/8]

plot ( imag(tx_vecs_iris(:, sp))  ,
'color'  ,
sec_clr   
)

◆ plot() [3/8]

plot ( lts_corr(sp,:)  )

◆ plot() [4/8]

plot ( real(rx_vec_iris(sp,:))  )

◆ plot() [5/8]

plot ( real(tx_vecs_iris(:, sp))  )

◆ plot() [6/8]

plot ( squeeze(Y_data(sp,:,:))  ,
'co'  ,
'MarkerSize'  ,
 
)

◆ plot() [7/8]

plot ( syms_eq_pc(:, sp ,
'o'  ,
'MarkerSize'  ,
,
'color'  ,
sec_clr   
)

◆ plot() [8/8]

plot ( tx_syms(:, sp ,
' *'  ,
'MarkerSize'  ,
10  ,
'LineWidth'  ,
,
'color'  ,
fst_clr   
)

◆ repmat()

repmat ( lts_t  ,
N_LTS_SYM  ,
 
)

◆ rx_lts_mat()

rx_lts_mat ( ibs  ,
 
)

◆ SDRs()

if ~isloaded pyversion usr bin python py print () %weird bug where py isn't loaded in an external script end % Params Number of SDRs ( Matlab scripts only using antenna  A)

◆ set() [1/5]

set ( bh  ,
'FaceColor'  ,
cond_clr   
)

◆ set() [2/5]

bold set ( h  ,
'BackgroundColor'   
)

◆ set() [3/5]

set ( h  ,
'Color'   
)

◆ set() [4/5]

bold set ( h  ,
'FontSize'  ,
10   
)

◆ set() [5/5]

set ( h  ,
'LineStyle'  ,
':'   
)

◆ sgtitle()

end sgtitle ( 'LTS correlations accross antennas'  )

◆ snr_mat()

snr_mat ( sp  )

◆ subplot() [1/3]

subplot ( N_BS_NODE  ,
,
2 *  sp 
)

◆ subplot() [2/3]

subplot ( N_BS_NODE  ,
N_UE  ,
sp   
)

◆ subplot() [3/3]

subplot ( N_UE  ,
,
2 *  sp 
)

◆ symbols()

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

◆ syms_eq()

else Do nz_sc (j) )' * H_hat( Apply nz_sc (j) )') * squeeze(Y_data( end syms_eq ( ,
nz_sc(j ,
 
)

◆ title() [1/9]

title ( 'Channel Condition(dB)'  ) &

◆ title() [2/9]

title ( sprintf( 'BS antenna %d Rx Waveform(I)', sp )

◆ title() [3/9]

title ( sprintf( 'BS antenna %d Rx Waveform(Q)', sp )

◆ title() [4/9]

title ( sprintf( 'Equalized Uplink Tx(blue) and \n Rx(red) symbols for stream %d', sp )

◆ title() [5/9]

title ( sprintf( 'Stream from UE %d', sp )

◆ title() [6/9]

title ( sprintf( 'UE %d -> BS ant. %d Channel Est.(Mag.)', iue, ibs )

◆ title() [7/9]

title ( sprintf( 'UE %d Tx Waveform(I)', sp )

◆ title() [8/9]

title ( sprintf( 'UE %d Tx Waveform(Q)', sp )

◆ title() [9/9]

title ( sprintf( 'Unequalized received symbols \n at BS ant. %d', sp )

◆ vector()

else Define an empty phase correction vector ( used by plotting code  below)

◆ waveform()

Scale for Tx waveform ( )

◆ xlabel() [1/2]

grid on xlabel ( 'OFDM Symbol Index'  )

◆ xlabel() [2/2]

xlabel ( 'Samples'  )

◆ Y_lts()

Y_lts ( ,
iue  ,
 
)

◆ ylabel() [1/2]

ylabel ( 'Subcarrier Index'  )

◆ ylabel() [2/2]

ylabel ( y_label  )

◆ zeros() [1/2]

N_ZPAD_PRE, N_UE zeros ( )
virtual

◆ zeros() [2/2]

zeros ( N_ZPAD_POST  ,
N_UE   
)

Variable Documentation

◆ __pad7__

SIMULATION __pad7__

◆ aevms

aevms = zeros(N_UE,1)

◆ ALGORITHM

MIMO ALGORITHM

◆ Author

Author(s)[version, executable, isloaded] = pyversion

◆ avgCond

end avgCond = mean(condNum)

◆ BEACON_SWEEP

BEACON_SWEEP = 0

◆ BF

else Do nz_sc (j) )' * H_hat( Apply BF

◆ bh

bh = bar(bw_span, fftshift(channel_condition_db) ,1, 'LineWidth', 1)

◆ bit_errs

bit_errs = length(find(dec2bin(bitxor(tx_data(:), rx_data(:)),8) == '1'))

◆ bs_ids

else bs_ids = string.empty()

◆ bs_sdr_params

Iris nodes parameters bs_sdr_params
Initial value:
= struct(...
'id', bs_ids, ...
'n_sdrs', N_BS_NODE, ... % number of nodes chained together
'txfreq', [], ...
'rxfreq', [], ...
'txgain', [], ...
'rxgain', [], ...
'sample_rate', [], ...
'n_samp', n_samp, ... % number of samples per frame time.
'n_frame', [], ...
'tdd_sched', [], ... % number of zero-paddes samples
)

◆ burst

Number of OFDM symbols for burst

◆ bw_span

bw_span = (20/N_SC) * (-(N_SC/2):(N_SC/2 - 1)).'

◆ cf

end if PLOT cf = 0

◆ chan_type

if SIM_MOD chan_type = "rayleigh"

◆ channel_condition

channel_condition = double.empty()

◆ channel_condition_db

channel_condition_db = double.empty()

◆ clf

clf

◆ cond_clr

cond_clr = [0.8500, 0.250, 0.1980]

◆ condNum

condNum = zeros(1, length(validIdx))

◆ correlatons

In case of bad correlatons

◆ CP_LEN

Number of subcarriers CP_LEN = 16

◆ data

Real value doesn t matter since we have corrrupt data

◆ data_len

data_len = (N_OFDM_SYM)*(N_SC +CP_LEN)

◆ DEBUG

DEBUG = 0

◆ dimension

Reshape the matix to have each lts pilot in a different dimension

◆ DO_APPLY_PHASE_ERR_CORRECTION

end DO_APPLY_PHASE_ERR_CORRECTION
Initial value:
= 1
% Extract the pilots and calculate per-symbol phase error
pilots_f_mat = syms_eq(:,SC_IND_PILOTS,:)

◆ EdgeColor

bold EdgeColor

◆ evm_mat

evm_mat = double.empty()

◆ FFT

Take FFT

◆ figure

end if DEBUG figure

◆ FontWeight

FontWeight = 'bold'

◆ fst_clr

fst_clr = [0, 0.4470, 0.7410]

◆ G_lts

Get the channel by dividing by the pilots G_lts = Y_lts_f ./ lts_f_mat

◆ h

h = text(round(.05*length(evm_mat(:,sp))), 100*aevms(sp), sprintf('Effective SINR: %.1f dB', snr_mat(sp)))

◆ hub_id

hub_id = "FH4B000021"

◆ ibs

for ibs
Initial value:
% Correlation through filtering
v0 = filter(fliplr(preamble_common'),a,rx_vec_iris(ibs,:))

◆ id

◆ ifft_in_mat

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

◆ iue

for iue
Initial value:
= 1:N_UE
plt_j_ix = (iue-1) * n_plt_samp +1:iue * n_plt_samp

◆ j

for j
Initial value:
=1:length(nz_sc)
if(strcmp(MIMO_ALG,'ZF'))
% Pseudo-inverse:(H'*H)^(-1)*H':
HH_inv = inv((squeeze(H_hat(:,:, nz_sc(j) ) )' * squeeze(H_hat(:,:, nz_sc(j) ) ) ) ) * squeeze(H_hat(:,:, nz_sc(j) ) )'

◆ jp

for jp
Initial value:
= 1:N_UE
preamble((jp-1)*l_pre + 1: (jp-1)*l_pre+l_pre,jp) = preamble_common

◆ l_pre

l_pre = length(preamble_common)

◆ l_rx_dec

end end l_rx_dec =length(rx_vec_iris)

◆ lts_corr

◆ lts_f

Enable Residual CFO estimation correction Define the preamble LTS for fine CFO and channel estimation lts_f
Initial value:
= [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_f_mat

lts_f_mat = reshape(lts_f_mat, [], N_LTS_SYM, N_UE, N_BS_NODE)

◆ lts_peaks

lts_peaks = zeros(N_BS_NODE, N_UE)

◆ lts_t

lts_t = ifft(lts_f, N_SC)

◆ max_idx

In case of bad max_idx = max(lts_peaks(ibs,:))

◆ MIMO_ALG

MIMO MIMO_ALG = 'ZF'

◆ MOD_ORDER

Number of OFDM symbols for it needs to be less than MOD_ORDER = 16

◆ myAxis

myAxis = axis()

◆ N_BS_NODE

if N_BS_NODE = length(bs_ids)

◆ N_DATA_SYMS

Cyclic prefix length N_DATA_SYMS = N_OFDM_SYM * length(SC_IND_DATA)

◆ N_FRM

N_FRM = 10

◆ N_LTS_SYM

Take Construct known pilot matrix to use i next N_BS_NODE* N_UE* N_LTS_SYM

◆ N_OFDM_SYM

Waveform params N_OFDM_SYM = 44

◆ n_samp

UE schedule number of samples in a frame n_samp = length(tx_vecs_iris)

◆ N_SC

Take N_SC = 64

◆ n_sdrs

ue_sdr_params n_sdrs = N_UE

◆ N_SYM_SAMP

Number of N_SYM_SAMP = N_SC + CP_LEN

◆ N_UE

Reshape the matix to have each lts pilot in a different N_UE = length(ue_ids)

◆ N_ZPAD_PRE

Number of samples that will go over the air N_ZPAD_PRE = 90

◆ Note

just to agree with what the hardware spits out Init Iris nodes Set up the Iris experimenty else Create BS Hub and UE objects Note

◆ now

if USE_HUB Using chains of different size requires some internal calibration on the BS This functionality will be added later For now

◆ off

hold off

◆ on

hold on

◆ padding

Leftover from zero padding

◆ params

else Iris params

◆ payload_ind

payload_ind = int32.empty()

◆ payload_noCP

payload_noCP = payload_rx(:,CP_LEN-FFT_OFFSET+(1:N_SC),:)

◆ payload_rx

Reshape the payload and take subcarriers without the CP payload_rx = zeros(N_BS_NODE, data_len)

◆ pilot_phase_corr

pilot_phase_corr = exp(-1i*(pilot_phase_err_corr))

◆ pilot_phase_err

pilot_phase_err = angle(mean(pilots_f_mat_comp,2))

◆ pilot_phase_err_corr

end pilot_phase_err_corr = repmat(pilot_phase_err, 1, N_SC, 1)

◆ pilots

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

◆ pilots_f_mat_comp

pilots_f_mat_comp = pilots_f_mat.* permute(pilots_mat, [3 1 2])

◆ pilots_mat

Repeat the pilots across all OFDM symbols pilots_mat = repmat(pilots, 1, N_OFDM_SYM, N_UE)

◆ pl_idx

◆ PLOT

PLOT = 0

◆ pre_z

pre_z = zeros(size(preamble_common))

◆ pream_ind_ibs

pream_ind_ibs = payload_ind(ibs) - length(preamble)

◆ preamble

preamble = zeros(N_UE * l_pre, N_UE)

◆ rho_max

Take the N_UE largest values rho_max = sort_corr(1:N_UE)

◆ rx_data

Demodulate rx_data = demod_sym(syms_eq_pc ,MOD_ORDER)

◆ RX_FRQ

RX_FRQ = TX_FRQ

◆ RX_GN

RX_GN = 75

◆ rx_lts_idx

end Take N_SC spamples from each LTS rx_lts_idx = CP_LEN +1 : N_LTS_SYM * N_SC +CP_LEN

◆ rx_lts_mat

rx_lts_mat = double.empty()

◆ rx_vec_iris

else rx_vec_iris = getRxVec(tx_vecs_iris, N_BS_NODE, N_UE, chan_type, sim_SNR_db, bs_sdr_params, ue_sdr_params, [])

◆ sc

for sc
Initial value:
condNum(sc) = cond(H_hat(:, :, validIdx(sc))'*H_hat(:, :, validIdx(sc)))

◆ SC_IND_DATA

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

◆ SC_IND_DATA_PILOT

Data subcarrier indices SC_IND_DATA_PILOT = [2:27 39:64]'

◆ sec_clr

sec_clr = [0.8500, 0.3250, 0.0980]

◆ SIM_MOD

Enable writing plots to PNG SIM_MOD = 0

◆ sim_SNR_db

Will use only Rayleigh for simulation sim_SNR_db = 15

◆ SMPL_RT

SMPL_RT = 5e6

◆ snr_mat

snr_mat = zeros(N_UE,1)

◆ sort_corr

normalized correlation Sort the correlation values sort_corr = sort(lts_corr(ibs,:), 'descend')

◆ sp

grid on end for sp
Initial value:

◆ sp_cols

end sp_cols = ceil(N_BS_NODE/(sp_rows -1))

◆ sp_rows

else sp_rows = ceil(N_BS_NODE/2)+1

◆ square

axis square

◆ step

Take Construct known pilot matrix to use i next step

◆ suubcarrier

Apply ZF by multiplying the pseudo inverse of H_hat [N_BS_NODE x NUE] for each suubcarrier

◆ symbols

Estimate the channel by averaging over the two LTS symbols

◆ syms_eq_pc

syms_eq_pc = syms_eq.* pilot_phase_corr

◆ tdd_sched

ue_sdr_params tdd_sched = ue_sched

◆ tx_data

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

◆ TX_FRQ

TX_FRQ = 3.56e9

◆ TX_GN

TX_GN = 80

◆ TX_GN_ue

TX_GN_ue = 80

◆ tx_payload_mat

tx_payload_mat = ifft(ifft_in_mat, N_SC, 1)

◆ tx_payload_vecs

tx_payload_vecs = reshape(tx_payload_mat, ceil(numel(tx_payload_mat)/N_UE), N_UE)

◆ TX_SCALE

TX_SCALE = 1

◆ tx_syms

tx_syms = mod_sym(tx_data, MOD_ORDER)

◆ tx_syms_mat

Reshape the symbol vector to a matrix with one column per OFDM symbol tx_syms_mat = reshape(tx_syms, length(SC_IND_DATA), N_OFDM_SYM, N_UE)

◆ txgain

ue_sdr_params txgain = []

◆ ue_ids

end ue_ids = ones(1, N_UE)

◆ ue_sched

BS schedule ue_sched = ["GGGGGGPG"]

◆ ue_scheds

ue_scheds = string.empty()

◆ ue_sdr_params

ue_sdr_params = bs_sdr_params

◆ unos

unos = ones(size(preamble_common'))

◆ USE_HUB

USE_HUB = 1

◆ v1

v1 = filter(unos,a,abs(rx_vec_iris(ibs,:)).^2)

◆ validIdx

Estimate the channel by averaging over the two LTS Calculate Condition Number validIdx = find(lts_f ~=0)

◆ values

Insert the data and pilot values

◆ WRITE_PNG_FILES

WRITE_PNG_FILES = 0

◆ x

x = HH_inv*squeeze(Y_data(:,nz_sc(j),:))

◆ Y_data

Take FFT Y_data = fft(payload_noCP, N_SC, 2)

◆ y_label

y_label = sprintf('Anetnna %d',sp)

◆ Y_lts

Y_lts = Y_lts(:,:,rx_lts_idx)

◆ yourselves

else Do yourselves
filter
Interpolate Zero pad then filter(same as interp or upfirdn without signal processing toolbox) tx_vec_air
n_samp
UE schedule number of samples in a frame n_samp
Definition: rl_ofdm_mimo.m:215
length
num clusters if length(angcTx)
H
UL noise matrix H
Definition: rl_ofdm_mmimo_sim.m:186
iue
for iue
Definition: rl_ofdm_mimo.m:313
preamble
preamble
Definition: rl_ofdm_mimo.m:124
n_zpad_samp
n_zpad_samp
Definition: iris_py.m:35
DO_APPLY_PHASE_ERR_CORRECTION
end DO_APPLY_PHASE_ERR_CORRECTION
Definition: rl_ofdm_mimo.m:375
validIdx
Estimate the channel by averaging over the two LTS Calculate Condition Number validIdx
Definition: rl_ofdm_mimo.m:339
l_pre
l_pre
Definition: rl_ofdm_mimo.m:122
v0
v0
Definition: siso_ofdm_mf_sim.m:143
syms_eq
else Do nz_sc(j))' *H_hat(Apply nz_sc(j))') *squeeze(Y_data(end syms_eq(:, nz_sc(j),:)
pilots
Define the pilot tone values as BPSK symbols pilots
Definition: rl_ofdm_mimo.m:138
jp
for jp
Definition: rl_ofdm_mimo.m:125
samples
end Rx payload processing Extract the payload samples(integral number of OFDM symbols following preamble) payload_vec
sp
end if DEBUG for sp
Definition: rl_ofdm_mimo.m:296
condNum
condNum
Definition: rl_ofdm_mimo.m:340
N_BS_NODE
N_BS_NODE
Definition: rl_ofdm_mimo.m:83
sc
for sc
Definition: rl_ofdm_mimo.m:341
N_UE
Number of nodes antennas at the BS N_UE
Definition: rl_ofdm_mimo.m:84
bs_ids
bs_ids
Definition: rl_ofdm_mimo.m:65
j
for j
Definition: rl_ofdm_mimo.m:357
cond
pthread_cond_t cond
Definition: receiver.cc:25
subplot
subplot(N_BS_NODE, 2, 2 *sp)
extract_pilots_data.frame
frame
Definition: extract_pilots_data.py:58
error
otherwise error('Invalid MOD_ORDER(%d)! Must be in[2, 4, 16, 64]\n', MOD_ORDER)
N_ZPAD_PRE
Number of samples that will go over the air N_ZPAD_PRE
Definition: rl_ofdm_mimo.m:107
MIMO_ALG
MIMO_ALG
Definition: rl_ofdm_mimo.m:90