RENEWLab  1.1.0
RENEW project
rl_ofdm_downlink_mmimo.m File Reference

Functions

Scale for Tx waveform ([0:1]) % OFDM params SC_IND_PILOTS
 
id N_ZPAD_POST ()
 
Number of data symbols (one per data-bearing subcarrier per OFDM symbol) N_DATA_SC
 
Modulation order (2/4/16/64=BSPK/QPSK/16-QAM/64-QAM) % Rx processing params FFT_OFFSET
 
Number of CP samples to use in FFT (on average) RECIP_PLOT
 
 sched_id (REF_ANT)
 
end precoding_in_mat (:, SC_IND_DATA, N_PILOTS_SYMS+1:end)
 
 precoding_in_mat (:, SC_IND_PILOTS, N_PILOTS_SYMS+1:end)
 
 recip_tx (nid, start_index+1:start_index+N_SYM_SAMP)
 
 recip_tx (REF_ANT, start_index+1:start_index+N_SYM_SAMP)
 
 uplink_pilot_tx (jp, start_index+1:start_index+N_SYM_SAMP)
 
initialize UE node_bs sdrsync ()
 
Synchronize delays only for BS node_bs sdrrxsetup ()
 
node_bs sdr_setupbeacon ()
 
Burn beacon to the BS RAM node_ue sdr_configgainctrl ()
 
configure the N_ZPAD_PRE recip_tx (i, :) zeros(1
 
node_bs sdrtx_single (tx_data, i)
 
Burn data to the UE RAM end node_bs sdr_activate_rx ()
 
end recip_rx (ibs, :)
 
 if (ibs==REF_ANT) rx_fft_ref(sid
 
id start_index: (id N_SC)
 
else rx_fft (sid, :)
 
 cal_mat (nid, :)
 
end Uplink Pilot Collection and Channel Estimation node_bs set_n_frame (10)
 
node_bs set_tddconfig (1, bs_sched(bs_sched_id))
 
node_ue set_tddconfig (WIRED_UE, ue_sched(ue_sched_id))
 
Burn data to the UE RAM end if ~WIRED_UE node_ue sdr_setcorr ()
 
read data if ~WIRED_UE node_ue sdr_unsetcorr ()
 

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 Iris params
 
 WIRED_UE = 1
 
 TX_FRQ = 2.5e9
 
 RX_FRQ = TX_FRQ
 
 TX_GN = 75
 
 RX_GN = 60
 
 SMPL_RT = 5e6
 
 N_FRM = 1
 
 bs_ids = string.empty()
 
 bs_sched = string.empty()
 
Waveform params TX_SCALE = 0.5
 
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_SYM_SAMP = N_SC + CP_LEN
 
Number of samples that will go over the air N_SAMP = 4096
 
 N_ZPAD_PRE = 100
 
Number of OFDM symbols for burst
 
Number of OFDM symbols for it needs to be less than N_PILOTS_SYMS = 2
 
 N_DATA_SYMS = (N_OFDM_SYMS - N_PILOTS_SYMS)
 
 MOD_ORDER = 4
 
 PILOT_PLOT = 1
 
 DOWNLINK_PLOT = 1
 
Define the preamble LTS for fine CFO and channel estimation lts_f
 
 lts_t = ifft(lts_f, 64)
 
time domain lts = [lts_t(49:64) lts_t]
 
Init Iris nodes Set up the Iris experiment Create BS Hub and UE objects Note
 
else hub_id = []
 
 ue_ids = ["RF3E000103", "RF3E000180"]
 
All BS schedule
 
BS schedule ue_sched = ["GGPG", "GGRG"]
 
UE schedule N_BS_NODE = length(bs_ids)
 
 N_UE_NODE = length(ue_ids)
 
 REF_ANT = floor(N_BS_NODE/2)
 
 sched_id = ones(1, N_BS_NODE)
 
Generate a payload of random integers tx_data = randi(MOD_ORDER, N_UE_NODE, N_DATA_SC) - 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, N_UE_NODE, length(SC_IND_DATA), N_DATA_SYMS)
 
Define the pilot tone values as BPSK symbols pilots = [1 1 -1 1].'
 
Repeat the pilots across all OFDM symbols pilots_mat = zeros(N_UE_NODE, length(SC_IND_PILOTS), N_DATA_SYMS)
 
for i
 
end Construct the precoding input matrix precoding_in_mat = zeros(N_UE_NODE, N_SC, N_OFDM_SYMS)
 
Insert the data and pilot values
 
reciprocity calibration tx pilots N_BS = N_BS_NODE - 1
 
 DATA_REP = floor(N_OFDM_SYMS / N_BS)
 
 data_len = N_BS * DATA_REP * N_SYM_SAMP
 
 recip_tx = zeros(N_BS_NODE, data_len)
 
for jp
 
for rp
 
end end uplink tx piltos UE_DATA_REP = floor(N_OFDM_SYMS / N_UE_NODE)
 
 ue_pilot_len = UE_DATA_REP * N_SYM_SAMP
 
 ue_pilots_len = N_UE_NODE * ue_pilot_len
 
 uplink_pilot_tx = zeros(N_UE_NODE, ue_pilots_len)
 
end end recip_rx = zeros(N_BS_NODE, data_len)
 
 rx_fft = zeros(N_BS, N_SC)
 
 rx_fft_ref = zeros(N_BS, N_SC)
 
 cal_mat = ones(N_BS_NODE, N_SC)
 
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_NODE
 
ue_sdr_params tdd_sched = ue_sched
 
 node_bs = iris_py(bs_sdr_params, hub_id)
 
initialize BS node_ue = iris_py(ue_sdr_params, [])
 
Reciprocity Calibration recip_postfix_len = N_SAMP - data_len - N_ZPAD_PRE
 
configure the BS
 
activate reading stream [rx_vec_iris, ~] = node_bs.sdrrx(N_SAMP)
 
read data a = 1
 
 unos = ones(size(conj(lts)))
 
for ibs
 
 v1 = filter(unos, a, abs(rx_vec_iris(ibs, end - DATA_REP * N_SYM_SAMP: end)) .^ 2)
 
 lts_corr = (abs(v0) .^ 2) ./ v1
 
normalized correlation position of the last peak [~, max_idx] = max(abs(lts_corr))
 
 rx_data_start
 
 break
 
for sid
 
 start_index = CP_LEN + ((rid - 1) + (sid - 1) * DATA_REP) * N_SYM_SAMP
 
 __pad5__
 
 __pad6__
 
 bs_sched_id = 3
 
 ue_sched_id = 1
 
activate correlator end [rx_vec_pilot, data0_len] = node_bs.sdrrx(N_SAMP)
 
activate correlator end uplink_pilot_rx = zeros(N_BS_NODE, N_UE_NODE, ue_pilot_len)
 
 uplink_pilot_csi = zeros(N_BS_NODE, N_UE_NODE, N_SC)
 
 m_filt = (abs(v0) .^ 2) ./ v1
 
normalized correlation [~, max_idx] = max(abs(m_filt))
 
In case of bad correlatons
 

Function Documentation

◆ cal_mat()

cal_mat ( nid  ,
 
)

◆ FFT()

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

◆ if()

if ( ibs  = REF_ANT)

◆ N_ZPAD_POST()

id N_ZPAD_POST ( )
staticvirtual

◆ order()

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

◆ precoding_in_mat() [1/2]

end precoding_in_mat ( ,
SC_IND_DATA  ,
N_PILOTS_SYMS+1:end   
)

◆ precoding_in_mat() [2/2]

precoding_in_mat ( ,
SC_IND_PILOTS  ,
N_PILOTS_SYMS+1:end   
)

◆ recip_rx()

end recip_rx ( ibs  ,
 
)

◆ recip_tx() [1/3]

configure the N_ZPAD_PRE recip_tx ( i  ,
 
)

◆ recip_tx() [2/3]

recip_tx ( nid  ,
start_index+1:start_index N_SYM_SAMP 
)

◆ recip_tx() [3/3]

recip_tx ( REF_ANT  ,
start_index+1:start_index N_SYM_SAMP 
)

◆ rx_fft()

else rx_fft ( sid  ,
 
)

◆ sched_id()

sched_id ( REF_ANT  )

◆ sdr_activate_rx()

Burn data to the UE RAM end node_bs sdr_activate_rx ( )

◆ sdr_configgainctrl()

Burn beacon to the BS RAM node_ue sdr_configgainctrl ( )

◆ sdr_setcorr()

Burn data to the UE RAM end if ~WIRED_UE node_ue sdr_setcorr ( )

◆ sdr_setupbeacon()

node_bs sdr_setupbeacon ( )

◆ sdr_unsetcorr()

read data if ~WIRED_UE node_ue sdr_unsetcorr ( )

◆ sdrrxsetup()

Synchronize delays only for BS node_bs sdrrxsetup ( )

◆ sdrsync()

initialize UE node_bs sdrsync ( )

◆ sdrtx_single()

node_bs sdrtx_single ( tx_data  ,
i   
)

◆ set_n_frame()

end Uplink Pilot Collection and Channel Estimation node_bs set_n_frame ( 10  )

◆ set_tddconfig() [1/2]

node_bs set_tddconfig ( ,
bs_sched(bs_sched_id  
)

◆ set_tddconfig() [2/2]

node_ue set_tddconfig ( WIRED_UE  ,
ue_sched(ue_sched_id  
)

◆ start_index:()

id start_index: ( id  N_SC)
staticvirtual

◆ symbols()

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

◆ uplink_pilot_tx()

uplink_pilot_tx ( jp  ,
start_index+1:start_index N_SYM_SAMP 
)

◆ waveform()

Scale for Tx waveform ( )

Variable Documentation

◆ __pad5__

__pad5__

◆ __pad6__

__pad6__

◆ a

read data a = 1

◆ Author

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

◆ break

break

◆ BS

configure the BS

◆ bs_ids

end bs_ids = string.empty()

◆ bs_sched

All BS Ref Schedule bs_sched = string.empty()

◆ bs_sched_id

bs_sched_id = 3

◆ bs_sdr_params

Iris nodes parameters bs_sdr_params
Initial value:
= struct(...
'id', bs_ids, ...
'n_sdrs', N_BS_NODE, ...
'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', bs_sched, ... % number of zero-paddes samples
)

◆ burst

Number of OFDM symbols for burst

◆ cal_mat

cal_mat = ones(N_BS_NODE, N_SC)

◆ correlation

normalized correlation[~, max_idx] = max(abs(m_filt))

◆ correlatons

In case of bad correlatons

◆ CP_LEN

Number of subcarriers CP_LEN = 16

◆ data_len

data_len = N_BS * DATA_REP * N_SYM_SAMP

◆ DATA_REP

DATA_REP = floor(N_OFDM_SYMS / N_BS)

◆ DOWNLINK_PLOT

DOWNLINK_PLOT = 1

◆ end

activate correlator end[rx_vec_pilot, data0_len] = node_bs.sdrrx(N_SAMP)

◆ hub_id

else hub_id = []

◆ i

for i
Initial value:

◆ ibs

for ibs
Initial value:
% Correlation through filtering

◆ id

◆ jp

for jp
Initial value:
= 1:N_BS
nid = jp + (jp >= REF_ANT)

◆ lts

time domain lts = [lts_t(49:64) lts_t]

◆ lts_corr

lts_corr = (abs(v0) .^ 2) ./ v1

◆ lts_f

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_t

lts_t = ifft(lts_f, 64)

◆ m_filt

m_filt = (abs(v0) .^ 2) ./ v1

◆ MOD_ORDER

MOD_ORDER = 4

◆ N_BS

reciprocity calibration tx pilots N_BS = N_BS_NODE - 1

◆ N_BS_NODE

UE schedule N_BS_NODE = length(bs_ids)

◆ N_DATA_SYMS

N_DATA_SYMS = (N_OFDM_SYMS - N_PILOTS_SYMS)

◆ N_FRM

N_FRM = 1

◆ N_PILOTS_SYMS

Number of OFDM symbols for it needs to be less than N_PILOTS_SYMS = 2

◆ N_SAMP

Number of samples that will go over the air N_SAMP = 4096

◆ N_SC

N_SC = 64

◆ n_sdrs

◆ N_SYM_SAMP

Cyclic prefix length N_SYM_SAMP = N_SC + CP_LEN

◆ N_UE_NODE

N_UE_NODE = length(ue_ids)

◆ N_ZPAD_PRE

N_ZPAD_PRE = 100

◆ node_bs

node_bs = iris_py(bs_sdr_params, hub_id)

◆ node_ue

initialize BS node_ue = iris_py(ue_sdr_params, [])

◆ Note

Init Iris nodes Set up the Iris experiment Create BS Hub and UE objects Note

◆ params

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

◆ peak

normalized correlation position of the last peak[~, max_idx] = max(abs(lts_corr))

◆ PILOT_PLOT

PILOT_PLOT = 1

◆ pilots

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

◆ pilots_mat

Repeat the pilots across all OFDM symbols pilots_mat = zeros(N_UE_NODE, length(SC_IND_PILOTS), N_DATA_SYMS)

◆ precoding_in_mat

end Construct the precoding input matrix precoding_in_mat = zeros(N_UE_NODE, N_SC, N_OFDM_SYMS)

◆ recip_postfix_len

configure the N_ZPAD_PRE recip_postfix_len = N_SAMP - data_len - N_ZPAD_PRE

◆ recip_rx

end end recip_rx = zeros(N_BS_NODE, data_len)

◆ recip_tx

recip_tx = zeros(N_BS_NODE, data_len)

◆ REF_ANT

REF_ANT = floor(N_BS_NODE/2)

◆ rp

for rp
Initial value:
start_index = ((rp - 1) + (jp - 1) * DATA_REP) * N_SYM_SAMP

◆ rx_data_start

rx_data_start
Initial value:

◆ rx_fft

rx_fft = zeros(N_BS, N_SC)

◆ rx_fft_ref

rx_fft_ref = zeros(N_BS, N_SC)

◆ RX_FRQ

RX_FRQ = TX_FRQ

◆ RX_GN

RX_GN = 60

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

◆ sched_id

sched_id = ones(1, N_BS_NODE)

◆ schedule

All BS schedule

◆ sid

end end end end for sid
Initial value:
= 1:N_BS
for rid = 1:DATA_REP
% nid = sid + (sid >= REF_ANT)

◆ SMPL_RT

SMPL_RT = 5e6

◆ start_index

start_index = CP_LEN + ((rid - 1) + (sid - 1) * DATA_REP) * N_SYM_SAMP

◆ stream

activate reading stream[rx_vec_iris, ~] = node_bs.sdrrx(N_SAMP)

◆ tdd_sched

ue_sdr_params tdd_sched = ue_sched

◆ tx_data

Generate a payload of random integers tx_data = randi(MOD_ORDER, N_UE_NODE, N_DATA_SC) - 1

◆ TX_FRQ

TX_FRQ = 2.5e9

◆ TX_GN

TX_GN = 75

◆ TX_SCALE

Waveform params TX_SCALE = 0.5

◆ 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, N_UE_NODE, length(SC_IND_DATA), N_DATA_SYMS)

◆ UE_DATA_REP

end end uplink tx piltos UE_DATA_REP = floor(N_OFDM_SYMS / N_UE_NODE)

◆ ue_ids

ue_ids = ["RF3E000103", "RF3E000180"]

◆ ue_pilot_len

ue_pilot_len = UE_DATA_REP * N_SYM_SAMP

◆ ue_pilots_len

ue_pilots_len = N_UE_NODE * ue_pilot_len

◆ ue_sched

BS schedule ue_sched = ["GGPG", "GGRG"]

◆ ue_sched_id

ue_sched_id = 1

◆ ue_sdr_params

ue_sdr_params = bs_sdr_params

◆ unos

unos = ones(size(conj(lts)))

◆ uplink_pilot_csi

uplink_pilot_csi = zeros(N_BS_NODE, N_UE_NODE, N_SC)

◆ uplink_pilot_rx

activate correlator end uplink_pilot_rx = zeros(N_BS_NODE, N_UE_NODE, ue_pilot_len)

◆ uplink_pilot_tx

uplink_pilot_tx = zeros(N_UE_NODE, ue_pilots_len)

◆ v1

v1 = filter(unos, a, abs(rx_vec_iris(ibs, end - DATA_REP * N_SYM_SAMP: end)) .^ 2)

◆ values

Insert the data and pilot values

◆ WIRED_UE

WIRED_UE = 1
filter
Interpolate Zero pad then filter(same as interp or upfirdn without signal processing toolbox) tx_vec_air
n_zpad_samp
n_zpad_samp
Definition: iris_py.m:35
max_idx
position of the last peak max_idx
Definition: ofdm_mimo.m:228
v0
v0
Definition: siso_ofdm_mf_sim.m:143
display
if TX_GN display('WARNING:MAXIMUM TX GAIN IS 81!')
repmat
repmat(lts_t, N_LTS_SYM, 1)]
samples
end Rx payload processing Extract the payload samples(integral number of OFDM symbols following preamble) payload_vec
extract_pilots_data.frame
frame
Definition: extract_pilots_data.py:58
rx_vec_iris
rx_vec_iris
Definition: ofdm_mimo.m:139