RENEWLab  1.1.0
RENEW project
siso_ofdm_mf_sim.m File Reference

Functions

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) N_LTS
 
Number of CP samples to use in FFT (on average) LTS_CORR_THRESH=0.8
 
MAX_TX_LEN, 2^20 min ()
 
id lts_f ()
 
1/sqrt(2 modvec_bpsk ()
 
mod_fcn_16qam, tx_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_pl (SC_IND_DATA, :)
 
 ifft_in_mat_pl (SC_IND_PILOTS, :)
 
Insert the cyclic prefix if (CP_LEN > 0) tx_cp
 
Interpolate Zero pad then filter (same as interp or upfirdn without signal processing toolbox) tx_vec_air
 
abs(tx_vec_air max ()
 
id filter: (id a)
 
 subplot (2, 1, 1)
 
 plot (real(rx_vec_air), 'b')
 
 axis ([0 length(rx_vec_air) -TX_SCALE TX_SCALE]) grid on
 
 title ('Rx Waveform(I)')
 
 subplot (2, 1, 2)
 
 plot (imag(rx_vec_air), 'r')
 
 title ('Rx Waveform(Q)')
 
Stop if no valid correlation peak was found if (isempty(lts_peaks)) fprintf('No LTS Correlation Peaks Found!\n')
 
end Rx payload processing Extract the payload samples (integral number of OFDM symbols following preamble) payload_vec
 
Remove the cyclic keeping FFT_OFFSET samples of CP (on average) payload_mat_noCP
 
 Equalize (zero-forcing, just divide by complex chan estimates) syms_eq_mat
 
 switch (MOD_ORDER) case 2 % BPSK rx_data
 
 figure (cf)
 
 plot (real(tx_vec_air), 'b')
 
 title ('Tx Waveform(I)')
 
 plot (imag(tx_vec_air), 'r')
 
 title ('Tx Waveform(Q)')
 
 if (WRITE_PNG_FILES) print(gcf
 
 sprintf ('wl_ofdm_plots_%s_txIQ', example_mode_string)
 
 sprintf ('wl_ofdm_plots_%s_rxIQ', example_mode_string)
 
 plot (lts_to_plot, '.-b', 'LineWidth', 1)
 
 line ([1 length(lts_to_plot)], LTS_CORR_THRESH *max(lts_to_plot) *[1 1], 'LineStyle', '--', 'Color', 'r', 'LineWidth', 2)
 
 title ('LTS Correlation and Threshold') xlabel('Sample Index') myAxis
 
 sprintf ('wl_ofdm_plots_%s_ltsCorr', example_mode_string)
 
 plot (payload_syms_mat(:), 'ro', 'MarkerSize', 1)
 
 axis (1.5 *[-1 1 -1 1])
 
 plot (tx_syms_mat(:), 'bo')
 
 title ('Tx and Rx Constellations') legend('Rx'
 
 sprintf ('wl_ofdm_plots_%s_constellations', example_mode_string)
 
 set (h, 'Color',[1 0 0]) set(h
 
bold set (h, 'FontSize', 10) set(h
 
bold set (h, 'BackgroundColor',[1 1 1]) hold off xlabel('Data Symbol Index') ylabel('EVM(%)')
 
 legend ('Per-Symbol EVM', 'Average EVM', 'Location', 'NorthWest')
 
 title ('EVM vs. Data Symbol Index') grid on subplot(2
 
 imagesc (1:N_OFDM_SYMS,(SC_IND_DATA - N_SC/2), 100 *fftshift(evm_mat, 1)) grid on xlabel('OFDM Symbol Index') ylabel('Subcarrier Index') title('EVM vs.(Subcarrier &OFDM Symbol)') h
 

Variables

siso_ofdm_mf_sim m A sane example of Simulated OFDM sysetm Copyright(c) 2015 Mango Communications - All Rights Reserved % Distributed under the WARP License(http Params
 
Enable writing plots to PNG CHANNEL = 11
 
Channel to tune Tx and Rx radios SIM_snr_db = 30
 
simulation data SC SNR Waveform params N_OFDM_SYMS = 320
 
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)
 
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 WARPLab experiment params USE_AGC = true
 
Use the AGC if running on WARP hardware MAX_TX_LEN = 2^20
 
Maximum number of samples to use for this experiment TRIGGER_OFFSET_TOL_NS = 3000
 
 SAMP_FREQ = 40e6
 
 example_mode_string = 'sim'
 
Generate a payload of random integers tx_data = randi(MOD_ORDER, 1, N_DATA_SYMS) - 1
 
 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)))
 
Map the data values on to complex symbols switch MOD_ORDER case BPSK tx_syms = arrayfun(mod_fcn_bpsk, tx_data)
 
 return
 
end 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_SYMS)
 
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_SYMS)
 
IFFT Construct the IFFT input matrix ifft_in_mat_pl = zeros(N_SC, N_OFDM_SYMS)
 
Insert the data and pilot values
 
 ifft_in_mat = [repmat(lts_f.', 1, N_LTS) ifft_in_mat_pl]
 
Perform the IFFT tx_payload_mat = ifft(ifft_in_mat, N_SC, 1)
 
end lts_t = tx_payload_mat(:,1:N_LTS)
 
Reshape to a vector tx_payload_vec = reshape(tx_payload_mat, 1, numel(tx_payload_mat))
 
Calculate the noise variance SIM_snr =10^(0.1* SIM_snr_db)
 
 tx_vec_pow_avg = mean( abs(TX_SCALE .* tx_vec ./ max(abs(tx_vec))).^2)
 
Average power on each SC sim_N0 = tx_vec_pow_avg / SIM_snr
 
Pad with zeros for transmission tx_vec_padded = [zeros(1,100) tx_vec]
 
 TX_NUM_SAMPS = length(tx_vec_air)
 
AWGN __pad1__
 
 rx_vec_air = rx_vec_air + sqrt(sim_N0/2)*(randn(size(rx_vec_air)) + 1i*randn(size(rx_vec_air)))
 
 unos = ones(size(lts_t))'
 
 v0 = filter(fliplr(lts_t'),a, rx_vec_air)
 
 v1 = filter(unos,a,abs(rx_vec_air).^2)
 
 m_filt = (abs(v0).^2)./v1
 
 pkt_strt = ipos - N_LTS*(N_SC + CP_LEN)+1
 
 lts_peaks = find(m_filt(1:800) > LTS_CORR_THRESH*rho_max)
 
Rx signal figure
 
 clf
 
 payload_mat = reshape(payload_vec, (N_SC+CP_LEN), N_LTS + N_OFDM_SYMS)
 
Remove the cyclic prefix
 
Take the FFT syms_f_mat_sc = fft(payload_mat_noCP, N_SC, 1)
 
 syms_f_mat = syms_f_mat_sc(SC_IND_DATA,:)
 
 rx_lts_f = syms_f_mat(:,1:N_LTS)
 
 rx_H_est0 = rx_lts_f ./repmat(lts_f(SC_IND_DATA).', 1, N_LTS)
 
 rx_H_est = mean(rx_H_est0,2)
 
Apply the pilot phase correction per symbol payload_syms_mat =syms_eq_mat
 
Demodulate rx_syms = reshape(payload_syms_mat, 1, N_DATA_SYMS)
 
 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)))))
 
case QPSK rx_data = arrayfun(demod_fcn_qpsk, rx_syms)
 
end Plot Results cf = 0
 
 lts_to_plot = m_filt(1:1000)
 
hold on
 
axis square
 
 Tx
 
 Location
 
 EastOutside
 
 evm_mat = abs(payload_syms_mat - tx_syms_mat).^2
 
 aevms = mean(evm_mat(:))
 
 snr = 10*log10(1./aevms)
 
subplot(2, 1, 1) plot(100 *evm_math = text(round(.05*length(evm_mat(:))), 100*aevms+ .1*(myAxis(4)-myAxis(3)), sprintf('Effective SNR: %.1f dB', snr))
 
 FontWeight
 
bold EdgeColor
 

Function Documentation

◆ arrayfun()

mod_fcn_16qam, tx_data arrayfun ( )
virtual

◆ axis() [1/2]

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

◆ axis() [2/2]

axis ( )

◆ CP()

Remove the cyclic keeping FFT_OFFSET samples of CP ( on  average)

◆ Equalize()

Equalize ( zero-  forcing,
just divide by complex chan  estimates 
)

◆ FFT()

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

◆ figure()

figure ( cf  )

◆ filter()

Interpolate Zero pad then filter ( same as interp or upfirdn without signal processing  toolbox)

◆ filter:()

id filter: ( id  a)
virtual

◆ fprintf()

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

◆ if() [1/3]

Insert the cyclic prefix if ( CP_LEN  ,
 
)

◆ if() [2/3]

Stop if no valid correlation peak was found if ( isempty(lts_peaks )

◆ if() [3/3]

if ( WRITE_PNG_FILES  )

◆ ifft_in_mat_pl() [1/2]

other subcarriers will remain at ifft_in_mat_pl ( SC_IND_DATA  ,
 
)

◆ ifft_in_mat_pl() [2/2]

ifft_in_mat_pl ( SC_IND_PILOTS  ,
 
)

◆ imagesc()

imagesc ( 1:N_OFDM_SYMS  ,
(SC_IND_DATA - N_SC/2)  ,
100 *  fftshiftevm_mat, 1 
) &

◆ legend()

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

◆ line()

line ( LTS_CORR_THRESH *max(lts_to_plot) *  [1 1],
'LineStyle'  ,
'--'  ,
'Color'  ,
'r'  ,
'LineWidth'  ,
 
)

◆ lts_f()

id lts_f ( )
virtual

◆ max()

abs(tx_vec_air max ( )
staticvirtual

◆ min()

MAX_TX_LEN, 2^20 min ( )
virtual
Here is the caller graph for this function:

◆ modvec_bpsk()

1/sqrt(2 modvec_bpsk ( )
virtual

◆ order()

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

◆ plot() [1/7]

plot ( imag(rx_vec_air ,
'r'   
)

◆ plot() [2/7]

plot ( imag(tx_vec_air ,
'r'   
)

◆ plot() [3/7]

plot ( lts_to_plot  ,
'.-b'  ,
'LineWidth'  ,
 
)

◆ plot() [4/7]

plot ( payload_syms_mat(:)  ,
'ro'  ,
'MarkerSize'  ,
 
)

◆ plot() [5/7]

plot ( real(rx_vec_air ,
'b'   
)

◆ plot() [6/7]

plot ( real(tx_vec_air ,
'b'   
)

◆ plot() [7/7]

plot ( tx_syms_mat(:)  ,
'bo'   
)

◆ samples()

end Rx payload processing Extract the payload samples ( integral number of OFDM symbols following  preamble)
Here is the caller graph for this function:

◆ set() [1/3]

bold set ( h  ,
'BackgroundColor'   
)

◆ set() [2/3]

set ( h  ,
'Color'   
)

◆ set() [3/3]

bold set ( h  ,
'FontSize'  ,
10   
)

◆ sprintf() [1/4]

sprintf ( 'wl_ofdm_plots_%s_constellations'  ,
example_mode_string   
)

◆ sprintf() [2/4]

sprintf ( 'wl_ofdm_plots_%s_ltsCorr'  ,
example_mode_string   
)

◆ sprintf() [3/4]

sprintf ( 'wl_ofdm_plots_%s_rxIQ'  ,
example_mode_string   
)

◆ sprintf() [4/4]

sprintf ( 'wl_ofdm_plots_%s_txIQ'  ,
example_mode_string   
)
Here is the caller graph for this function:

◆ subplot() [1/2]

subplot ( ,
,
 
)

◆ subplot() [2/2]

subplot ( ,
,
 
)

◆ switch()

switch ( MOD_ORDER  )

◆ symbols()

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

◆ title() [1/7]

title ( 'EVM vs. Data Symbol Index'  )

◆ title() [2/7]

title ( 'LTS Correlation and Threshold'  )

◆ title() [3/7]

title ( 'Rx Waveform(I)'  )

◆ title() [4/7]

title ( 'Rx Waveform(Q)'  )

◆ title() [5/7]

title ( 'Tx and Rx Constellations'  )

◆ title() [6/7]

title ( 'Tx Waveform(I)'  )

◆ title() [7/7]

title ( 'Tx Waveform(Q)'  )

◆ waveform()

Scale for Tx waveform ( )

Variable Documentation

◆ __pad1__

AWGN __pad1__

◆ aevms

aevms = mean(evm_mat(:))

◆ cf

Tx signal cf = 0

◆ CHANNEL

Enable writing plots to PNG CHANNEL = 11

◆ clf

clf

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

◆ DO_APPLY_CFO_CORRECTION

Normalized threshold for LTS correlation DO_APPLY_CFO_CORRECTION = 0

◆ 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

◆ EastOutside

EastOutside

◆ EdgeColor

bold EdgeColor

◆ evm_mat

evm_mat = abs(payload_syms_mat - tx_syms_mat).^2

◆ example_mode_string

example_mode_string = 'sim'

◆ FFT_OFFSET

Rx processing params FFT_OFFSET = 16

◆ figure

Rx signal figure

◆ FontWeight

FontWeight

◆ h

subplot (2,1,1) plot(100*evm_mat( h = text(round(.05*length(evm_mat(:))), 100*aevms+ .1*(myAxis(4)-myAxis(3)), sprintf('Effective SNR: %.1f dB', snr))

◆ ifft_in_mat

ifft_in_mat = [repmat(lts_f.', 1, N_LTS) ifft_in_mat_pl]

◆ ifft_in_mat_pl

IFFT Construct the IFFT input matrix ifft_in_mat_pl = zeros(N_SC, N_OFDM_SYMS)

◆ Location

Location

◆ lts_peaks

lts_peaks = find(m_filt(1:800) > LTS_CORR_THRESH*rho_max)

◆ lts_t

lts_t = tx_payload_mat(:,1:N_LTS)

◆ lts_to_plot

lts_to_plot = m_filt(1:1000)

◆ m_filt

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

◆ MAX_TX_LEN

Use the AGC if running on WARP hardware MAX_TX_LEN = 2^20

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

Cyclic prefix length N_DATA_SYMS = N_OFDM_SYMS * length(SC_IND_DATA)

◆ N_OFDM_SYMS

simulation data SC SNR Waveform params N_OFDM_SYMS = 320

◆ N_SC

Data subcarrier indices N_SC = 64

◆ on

hold on

◆ Params

siso_ofdm_mf_sim m A sane example of Simulated OFDM sysetm Copyright (c) 2015 Mango Communications - All Rights Reserved % Distributed under the WARP License (http Params

◆ payload_mat

payload_mat = reshape(payload_vec, (N_SC+CP_LEN), N_LTS + N_OFDM_SYMS)

◆ payload_syms_mat

Apply the pilot phase correction per symbol payload_syms_mat =syms_eq_mat

◆ 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 = repmat(pilots, 1, N_OFDM_SYMS)

◆ pkt_strt

pkt_strt = ipos - N_LTS*(N_SC + CP_LEN)+1

◆ prefix

Remove the cyclic prefix

◆ return

return

◆ rx_data

case QPSK rx_data = arrayfun(demod_fcn_qpsk, rx_syms)

◆ rx_H_est

rx_H_est = mean(rx_H_est0,2)

◆ rx_H_est0

rx_H_est0 = rx_lts_f ./repmat(lts_f(SC_IND_DATA).', 1, N_LTS)

◆ rx_lts_f

rx_lts_f = syms_f_mat(:,1:N_LTS)

◆ rx_syms

Demodulate rx_syms = reshape(payload_syms_mat, 1, N_DATA_SYMS)

◆ rx_vec_air

rx_vec_air = rx_vec_air + sqrt(sim_N0/2)*(randn(size(rx_vec_air)) + 1i*randn(size(rx_vec_air)))

◆ SAMP_FREQ

SAMP_FREQ = 40e6

◆ SC_IND_DATA

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

◆ sim_N0

Average power on each SC sim_N0 = tx_vec_pow_avg / SIM_snr

◆ SIM_snr

Calculate the noise variance SIM_snr =10^(0.1* SIM_snr_db)

◆ SIM_snr_db

Channel to tune Tx and Rx radios SIM_snr_db = 30

◆ snr

snr = 10*log10(1./aevms)

◆ square

axis square

◆ syms_f_mat

syms_f_mat = syms_f_mat_sc(SC_IND_DATA,:)

◆ syms_f_mat_sc

Take the FFT syms_f_mat_sc = fft(payload_mat_noCP, N_SC, 1)

◆ TRIGGER_OFFSET_TOL_NS

Maximum number of samples to use for this experiment TRIGGER_OFFSET_TOL_NS = 3000

◆ Tx

Tx

◆ tx_data

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

◆ TX_NUM_SAMPS

TX_NUM_SAMPS = length(tx_vec_air)

◆ tx_payload_mat

tx_payload_mat = ifft(ifft_in_mat, N_SC, 1)

◆ tx_payload_vec

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

◆ tx_syms

case QPSK tx_syms = arrayfun(mod_fcn_bpsk, tx_data)

◆ tx_syms_mat

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

◆ tx_vec_padded

Pad with zeros for transmission tx_vec_padded = [zeros(1,100) tx_vec]

◆ tx_vec_pow_avg

tx_vec_pow_avg = mean( abs(TX_SCALE .* tx_vec ./ max(abs(tx_vec))).^2)

◆ unos

unos = ones(size(lts_t))'

◆ USE_AGC

Enable Residual CFO estimation correction WARPLab experiment params USE_AGC = true

◆ v0

v0 = filter(fliplr(lts_t'),a, rx_vec_air)

◆ v1

v1 = filter(unos,a,abs(rx_vec_air).^2)

◆ values

Insert the data and pilot values