RENEWLab  1.1.0
RENEW project
ofdm_mimo.m File Reference

Functions

end fprintf ("Channel type: %s \n", chan_type)
 
Modulation order (2/4/16/64=BSPK/QPSK/16-QAM/64-QAM) TX_SCALE=0.5
 
Scale for Tx waveform ([0:1]) % OFDM params SC_IND_PILOTS = "iris"
 
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 ()
 
 if (N_BS_NODE > 1) b_scheds
 
 sdr_params (2)
 
 sdr_params (3)
 
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(tx_vecs_iris(:, sp)))
 
 axis ([0 length(tx_vecs_iris(:, sp)) -TX_SCALE TX_SCALE]) grid on
 
 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 (real(rx_vec_iris(sp,:)))
 
 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 (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 and Rx 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 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 Estimates(Magnitude)', 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)') %% EVM &SNR sym_errs
 
 evm_mat (:, sp)
 
 aevms (sp)
 
 snr_mat (sp)
 
subplot(2, N_UE, sp) plot(100 *evm_matlegend ('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
 
if ~isloaded pyversion usr bin python py print() %weird bug where py isn 't loaded in an external script end % Params Enable writing plots to PNG CHANNEL = 11
 
Channel to tune Tx and Rx radios SIM_MOD = 1
 
 DEBUG = 0
 
if SIM_MOD chan_type = "rayleigh"
 
Will use only Rayleigh for simulation sim_SNR_db = 15
 
Iris params
 
 N_UE = 2
 
 TX_FRQ = 2.5e9
 
 RX_FRQ = TX_FRQ
 
 TX_GN = 45
 
 TX_GN_ue = 48
 
 RX_GN = 23
 
 SMPL_RT = 5e6
 
 N_FRM = 50
 
 b_ids = string.empty()
 
 b_scheds = string.empty()
 
 ue_ids = string.empty()
 
 ue_scheds = string.empty()
 
 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 __pad0__
 
SIMULATION N_BS_NODE
 
 rx_vec_iris = rx_vec_iris.'
 
 b_prim_sched = "PGGGGGGGGGGRGGGG"
 
BS primary node s schedule
 
 ue_sched = "GGGGGGGGGGGPGGGG"
 
for iu
 
end number of samples in a frame n_samp = length(tx_vecs_iris)
 
Iris nodes parameters sdr_params
 
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
 
 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 ( )
Initial value:
= annotation('textbox', [0 0.87 1 0.1], ...
'String', 'LTS Correlations', ...
'EdgeColor', 'none', ...
'HorizontalAlignment', 'center')

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

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

end fprintf ( "Channel type: %s \n"  ,
chan_type   
)

◆ if() [1/2]

Insert the cyclic prefix if ( CP_LEN  ,
 
)

◆ if() [2/2]

if ( N_BS_NODE  ,
 
)

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

subplot (2,N_UE,sp) plot(100*evm_mat( 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
Here is the caller graph for this function:

◆ order()

Modulation order ( 2/4/16/  64 = BSPK/QPSK/16-QAM/64-QAM)
pure virtual
Here is the caller graph for this function:

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

◆ sdr_params() [1/2]

sdr_params ( )

◆ sdr_params() [2/2]

sdr_params ( )

◆ set() [1/5]

set ( bh  ,
'FaceColor'  ,
cond_clr   
)
Here is the caller graph for this function:

◆ 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 and Rx 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 Estimates(Magnitude)', 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 at BS ant. %d', sp )

◆ vector()

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

◆ waveform()

Scale for Tx waveform ( ) = "iris"

◆ 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

◆ __pad0__

SIMULATION __pad0__

◆ aevms

aevms = zeros(N_UE,1)

◆ ALGORITHM

MIMO ALGORITHM

◆ Author

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

◆ b_ids

just to agree with what the hardware spits out Init Iris nodes Set up the Iris experimenty else Device IDs of BS nodes and UE nodes b_ids = string.empty()

◆ b_prim_sched

b_prim_sched = "PGGGGGGGGGGRGGGG"

◆ b_scheds

UE schedule b_scheds = string.empty()

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

◆ burst

Number of OFDM symbols for burst

◆ bw_span

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

◆ cf

cf = 0

◆ chan_type

SIMULATION chan_type = "rayleigh"

◆ CHANNEL

if ~isloaded pyversion usr bin python py print () %weird bug where py isn't loaded in an external script end % Params Enable writing plots to PNG CHANNEL = 11

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

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

◆ ibs

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

◆ ifft_in_mat

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

◆ iu

for iu
Initial value:

◆ 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 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
Initial value:

◆ N_DATA_SYMS

Cyclic prefix length N_DATA_SYMS = N_OFDM_SYM * length(SC_IND_DATA)

◆ N_FRM

N_FRM = 50

◆ N_LTS_SYM

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

◆ N_OFDM_SYM

Time Domain Do N_OFDM_SYM = 44

◆ n_samp

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

◆ N_SC

Do N_SC = 64

◆ 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 = 2

◆ N_ZPAD_PRE

id N_ZPAD_PRE = 90

◆ off

hold off

◆ on

hold on

◆ padding

Leftover from zero padding

◆ params

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

◆ 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 = 23

◆ 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

end rx_vec_iris = rx_vec_iris.'

◆ 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]'

◆ schedule

BS primary node s schedule

◆ sdr_params

Iris nodes parameters sdr_params
Initial value:
= struct(...
'id', b_ids, ...
'n_chain',N_BS_NODE, ... % number of nodes chained together
'txfreq', TX_FRQ, ...
'rxfreq', RX_FRQ, ...
'txgain', TX_GN, ...
'rxgain', RX_GN, ...
'sample_rate', SMPL_RT, ...
'n_samp', n_samp, ... % number of samples per frame time.
'n_frame', N_FRM, ...
'tdd_sched', b_scheds, ... % number of zero-paddes samples
)

◆ sec_clr

sec_clr = [0.8500, 0.3250, 0.0980]

◆ SIM_MOD

Channel to tune Tx and Rx radios SIM_MOD = 1

◆ sim_SNR_db

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

Take only data SCs syms_eq_pc = syms_eq.* pilot_phase_corr

◆ tx_data

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

◆ TX_FRQ

TX_FRQ = 2.5e9

◆ TX_GN

TX_GN = 45

◆ TX_GN_ue

TX_GN_ue = 48

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

◆ ue_ids

end ue_ids = string.empty()

◆ ue_sched

BS schedule ue_sched = "GGGGGGGGGGGPGGGG"

◆ ue_scheds

end ue_scheds = string.empty()

◆ unos

unos = ones(size(preamble_common'))

◆ v1

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

◆ values

Insert the data and pilot values

◆ 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
syms_eq
else Do nz_sc(j))' *H_hat(Apply nz_sc(j))') *squeeze(Y_data(end syms_eq(:, nz_sc(j),:)
filter
Interpolate Zero pad then filter(same as interp or upfirdn without signal processing toolbox) tx_vec_air
ue_scheds
ue_scheds
Definition: ofdm_mimo.m:51
l_pre
l_pre
Definition: ofdm_mimo.m:85
length
num clusters if length(angcTx)
H
UL noise matrix H
Definition: rl_ofdm_mmimo_sim.m:186
jp
for jp
Definition: ofdm_mimo.m:88
subplot
subplot(N_UE, 2, 2 *sp)
n_zpad_samp
n_zpad_samp
Definition: iris_py.m:35
b_scheds
b_scheds
Definition: ofdm_mimo.m:49
TX_FRQ
TX_FRQ
Definition: ofdm_mimo.m:40
N_FRM
N_FRM
Definition: ofdm_mimo.m:46
pilots
Define the pilot tone values as BPSK symbols pilots
Definition: ofdm_mimo.m:101
sp_rows
else sp_rows
Definition: ofdm_mimo.m:414
v0
v0
Definition: siso_ofdm_mf_sim.m:143
iu
for iu
Definition: ofdm_mimo.m:163
ue_sched
ue_sched
Definition: ofdm_mimo.m:153
N_ZPAD_PRE
Number of samples that will go over the air N_ZPAD_PRE
Definition: ofdm_mimo.m:70
j
for j
Definition: ofdm_mimo.m:301
N_UE
N_UE
Definition: ofdm_mimo.m:39
RX_FRQ
RX_FRQ
Definition: ofdm_mimo.m:41
N_ZPAD_POST
configure the N_ZPAD_PRE N_ZPAD_POST
Definition: rl_ofdm_calib.m:123
samples
end Rx payload processing Extract the payload samples(integral number of OFDM symbols following preamble) payload_vec
iue
for iue
Definition: ofdm_mimo.m:265
SMPL_RT
SMPL_RT
Definition: ofdm_mimo.m:45
sp
end if DEBUG for sp
Definition: ofdm_mimo.m:248
N_BS_NODE
SIMULATION N_BS_NODE
Definition: ofdm_mimo.m:138
MIMO_ALG
MIMO_ALG
Definition: ofdm_mimo.m:53
TX_GN
TX_GN
Definition: ofdm_mimo.m:42
extract_pilots_data.frame
frame
Definition: extract_pilots_data.py:58
DO_APPLY_PHASE_ERR_CORRECTION
end DO_APPLY_PHASE_ERR_CORRECTION
Definition: ofdm_mimo.m:319
RX_GN
RX_GN
Definition: ofdm_mimo.m:44
error
otherwise error('Invalid MOD_ORDER(%d)! Must be in[2, 4, 16, 64]\n', MOD_ORDER)
n_samp
end number of samples in a frame n_samp
Definition: ofdm_mimo.m:168
b_ids
b_ids
Definition: ofdm_mimo.m:48
preamble
preamble
Definition: ofdm_mimo.m:87