Restored LS estimator + averaging. Fixed some issues in higher rates

master
ismagom 9 years ago
parent cd5f750c86
commit 1454286ae3

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

@ -1,25 +1,47 @@
clear
enbConfig=struct('NCellID',1,'CyclicPrefix','Normal','CellRefP',1);
pdschConfig=struct('Modulation','64QAM','RV',0,'TxScheme','Port0');
enbConfig=struct('NCellID',0,'CyclicPrefix','Normal','CellRefP',1);
pdschConfig=struct('Modulation','64QAM','RV',1,'TxScheme','Port0','NTurboDecIts',10);
addpath('../../build/srslte/lib/phch/test')
TBs=36696;
e_bits=41400;
error=zeros(size(TBs));
for i=1:length(TBs)
trblkin=randi(2,TBs(i),1)-1;
%TBs=18336;
i=1;
e_bits=3450*6;
%error=zeros(size(TBs));
%for i=1:length(TBs)
%trblkin=randi(2,TBs(i),1)-1;
trblkin=read_uchar('../../build/data_in');
fprintf('e_bits=%d, trblkin=%d\n',e_bits,length(trblkin));
[mat, info]=lteDLSCH(enbConfig,pdschConfig,e_bits,trblkin);
lib=srslte_dlsch_encode(enbConfig,pdschConfig,e_bits,trblkin);
error(i)=mean(abs(double(mat)-double(lib)));
end
if (length(TBs) == 1)
%disp(info)
disp(error)
n=1:length(mat);
plot(abs(double(mat)-double(lib)))
else
plot(error)
end
mat(mat==0)=-1;
mat=mat*10;
rec = lteRateRecoverTurbo(mat,length(trblkin),pdschConfig.RV);
rec2 = reshape(reshape(rec{1},[],3)',[],1);
out = lteTurboDecode(rec{1});
x=read_int16('../../build/rmout_0.dat');
subplot(2,1,1)
plot(abs(double(x)-double(rec2)));
t=1:100;
%plot(t,double(x(t)),t,double(rec2(t)))
subplot(2,1,2)
llr=read_int16('../../build/llr.dat');
plot(abs(double(mat)-double(llr)))
[data, crc,state] = lteDLSCHDecode(enbConfig, pdschConfig, length(trblkin), mat);
disp(crc)
%end
%
% if (length(TBs) == 1)
% %disp(info)
% disp(error)
% n=1:length(mat);
% plot(abs(double(mat)-double(lib)))
% else
% plot(error)
% end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

@ -6,25 +6,25 @@ clear
plot_noise_estimation_only=false;
SNR_values_db=30;%linspace(0,40,7);
SNR_values_db=30;%linspace(0,30,8);
Nrealizations=1;
Lp=10;
Lp=5;
N=512;
K=300;
rstart=(N-K)/2;
P=K/6;
Rhphp=zeros(P,P);
Rhhp=zeros(K,P);
Rhh=zeros(K,K);
enb.NDLRB = 25; % Number of resource blocks
enb.CellRefP = 1; % One transmit antenna port
enb.NCellID = 0; % Cell ID
enb.CyclicPrefix = 'Normal'; % Normal cyclic prefix
enb.DuplexMode = 'FDD'; % FDD
K=enb.NDLRB*12;
rstart=(N-K)/2;
P=K/6;
Rhphp=zeros(P,P);
Rhhp=zeros(K,P);
Rhh=zeros(K,K);
%% Channel Model Configuration
cfg.Seed = 0; % Random channel seed
cfg.InitTime = 0;
@ -33,7 +33,7 @@ cfg.DelayProfile = 'EPA';
% doppler 5, 70 300
cfg.DopplerFreq = 50; % 120Hz Doppler frequency
cfg.DopplerFreq = 5; % 120Hz Doppler frequency
cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
cfg.NTerms = 16; % Oscillators used in fading model
cfg.ModelType = 'GMEDS'; % Rayleigh fading model type
@ -58,7 +58,7 @@ L = gridsize(2); % Number of OFDM symbols in one subframe
Ports = gridsize(3); % Number of transmit antenna ports
%% Allocate memory
Ntests=5;
Ntests=4;
hest=cell(1,Ntests);
for i=1:Ntests
hest{i}=zeros(K,140);
@ -67,7 +67,7 @@ hls=zeros(4,4*P*10);
MSE=zeros(Ntests,Nrealizations,length(SNR_values_db));
noiseEst=zeros(Ntests,Nrealizations,length(SNR_values_db));
legends={'matlab','ls.linear','mmse','r.mmse','r.mmse2'};
legends={'matlab','ls.linear','mmse','r.smooth'};
colors={'bo-','rx-','m*-','k+-','c+-'};
colors2={'b-','r-','m-','k-','c-'};
@ -224,72 +224,39 @@ snr_lin=10^(SNR_values_db(snr_idx)/10);
Wi=((Rhphp+(1/snr_lin)*eye(P)))^-1;
W = Rhhp*Wi;
% for i=1:length(hidx)
% hp=hls(3,(1:P)+P*(i-1));
% hest{3}(:,hidx(i))=W*transpose(hp);
% end
w=reshape(transpose(W),1,[]);
[tmp, ~, ~, noiseEst(3,nreal,snr_idx)] = srslte_chest(enb.NCellID,enb.CellRefP,rxGrid,w);
hest{3}=reshape(tmp, size(hest{1}));
%% Robust MMSE estimation using srsLTE (Eurecom paper)
%% Low-pass filter smoother
prows=rstart+(1:6:K);
t=0:Lp-1;
alfa=log(2*Lp)/Lp;
c_l=exp(-t*alfa);
c_l=c_l/sum(c_l);
C_l=diag(1./c_l);
prows=rstart+(1:6:K);
F=dftmtx(N);
F_p=F(prows,1:Lp);
F_l=F((rstart+1):(K+rstart),1:Lp);
Wi=(F_p'*F_p+C_l*0.01)^(-1);
W2=F_l*Wi*F_p';
% for i=1:length(hidx)
% hp=hls(3,(1:P)+P*(i-1));
% hest{4}(:,hidx(i))=W2*transpose(hp);
% end
w2=reshape(transpose(W2),1,[]);
[tmp, ~, ~, noiseEst(4,nreal,snr_idx)] = srslte_chest(enb.NCellID,enb.CellRefP,rxGrid,w2);
hest{4}=reshape(tmp, size(hest{1}));
%% Another robust method from Infocom research paper
c_l=ones(Lp,1)/Lp;
c_l2=[c_l; zeros(N-Lp,1)];
c_l2=[c_l zeros(1,N-Lp)];
C_l=diag(c_l2);
F=dftmtx(N);
R_hh=F*C_l*F';
R_hphp=R_hh(prows,prows);
R_hhp=R_hh((rstart+1):(K+rstart),prows);
W3=R_hhp*(R_hphp+(1/snr_lin)*eye(P))^-1;
% for i=1:length(hidx)
% hp=hls(3,(1:P)+P*(i-1));
% hest{5}(:,hidx(i))=W3*transpose(hp);
% end
R_hh=R_hh(prows,prows);
W3=R_hh*(R_hh+0.05*eye(P))^-1;
w3=reshape(transpose(W3),1,[]);
[tmp, ~, ~, noiseEst(5,nreal,snr_idx)] = srslte_chest(enb.NCellID,enb.CellRefP,rxGrid,w3);
hest{5}=reshape(tmp, size(hest{1}));
[tmp, pilot_avg, ~, noiseEst(4,nreal,snr_idx)] = srslte_chest(enb.NCellID,enb.CellRefP,rxGrid,w3);
hest{4}=reshape(tmp, size(hest{1}));
%% Compute MSE
for i=1:Ntests
MSE(i,nreal,snr_idx)=mean(mean(abs(h(:,:)-hest{i}(:,:)).^2));
MSE(i,nreal,snr_idx)=mean(mean(abs(h(:,hidx)-hest{i}(:,hidx)).^2));
fprintf('MSE test %d: %f\n',i, 10*log10(MSE(i,nreal,snr_idx)));
end
%% Plot a single realization
if (length(SNR_values_db) == 1)
subplot(1,2,1)
subplot(2,1,1)
sym=1;
ref_idx=1:P;
ref_idx_x=[1:6:K];% (292:6:360)-216];% 577:6:648];
@ -310,33 +277,13 @@ if (length(SNR_values_db) == 1)
xlabel('SNR (dB)')
ylabel('Channel Gain')
grid on;
u(1+ceil(chinfo.PathSampleDelays))=chinfo.PathGains(1,:);
subplot(1,2,2)
plot(1:P,real(W(150,:)),1:P,real(W2(150,:)),1:P,real(W3(150,:)))
legend('mmse','robust1','robust2')
grid on
fprintf('Mean MMSE Robust %.2f dB\n', 10*log10(MSE(4,nreal,snr_idx)))
fprintf('Mean MMSE matlab %.2f dB\n', 10*log10(MSE(1,nreal,snr_idx)))
% u=zeros(N,1);
% u(1+ceil(chinfo.PathSampleDelays))=mean(chinfo.PathGains(7680+(1:512+40),:));
%
% subplot(2,2,1)
% plot(1:length(u),abs(u))
%
% subplot(2,2,2)
% plot(abs(fftshift(fft(u,N))))
%
% subplot(2,2,3)
% hf=[zeros((N-K)/2,1); h(1:K/2,1); 0; h(K/2+1:end,1); zeros((N-K)/2-1,1)];
% plot(1:Lp,real(ifft(ifftshift(h(:,1)),Lp)))
%
% subplot(2,2,4)
% plot(abs(hf))
%
subplot(2,1,2)
plot(1:P,abs(W3(P/2,:)))
end
end
@ -350,7 +297,7 @@ mean_snr=10*log10(1./mean(noiseEst,2));
%% Plot average over all SNR values
if (length(SNR_values_db) > 1)
subplot(1,2,1)
subplot(1,1,1)
for i=1:Ntests
plot(SNR_values_db, 10*log10(mean_mse(i,:)),colors{i})
hold on;
@ -361,21 +308,21 @@ if (length(SNR_values_db) > 1)
xlabel('SNR (dB)')
ylabel('MSE (dB)')
subplot(1,2,2)
plot(SNR_values_db, SNR_values_db,'k:')
hold on;
for i=1:Ntests
plot(SNR_values_db, mean_snr(i,:), colors{i})
end
hold off
tmp=cell(Ntests+1,1);
tmp{1}='Theory';
for i=2:Ntests+1
tmp{i}=legends{i-1};
end
legend(tmp)
grid on
xlabel('SNR (dB)')
ylabel('Estimated SNR (dB)')
% subplot(1,2,2)
% plot(SNR_values_db, SNR_values_db,'k:')
% hold on;
% for i=1:Ntests
% plot(SNR_values_db, mean_snr(i,:), colors{i})
% end
% hold off
% tmp=cell(Ntests+1,1);
% tmp{1}='Theory';
% for i=2:Ntests+1
% tmp{i}=legends{i-1};
% end
% legend(tmp)
% grid on
% xlabel('SNR (dB)')
% ylabel('Estimated SNR (dB)')
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

@ -6,8 +6,8 @@
recordedSignal=[];
Npackets = 100;
SNR_values = linspace(2,10,10);
Npackets = 20;
SNR_values = linspace(2,6,10);
Lp=12;
N=256;
@ -127,7 +127,7 @@ for snr_idx=1:length(SNR_values)
if (rmccFgOut.PDSCH.TrBlkSizes(sf_idx+1) > 0)
[dec2, data, pdschRx, pdschSymbols2, cws2] = srslte_pdsch(rmccFgOut, rmccFgOut.PDSCH, ...
rmccFgOut.PDSCH.TrBlkSizes(sf_idx+1), ...
subframe_rx,w2);
subframe_rx);
else
dec2 = 1;
end

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -74,7 +74,6 @@ typedef struct {
bool disable_plots;
bool disable_plots_except_constellation;
bool disable_cfo;
bool use_robust_lmmse;
uint32_t time_offset;
int force_N_id_2;
uint16_t rnti;
@ -95,7 +94,6 @@ typedef struct {
void args_default(prog_args_t *args) {
args->disable_plots = false;
args->use_robust_lmmse = false;
args->disable_plots_except_constellation = false;
args->nof_subframes = -1;
args->rnti = SRSLTE_SIRNTI;
@ -118,7 +116,7 @@ void args_default(prog_args_t *args) {
}
void usage(prog_args_t *args, char *prog) {
printf("Usage: %s [agpPoOcilLdDnruv] -f rx_frequency (in Hz) | -i input_file\n", prog);
printf("Usage: %s [agpPoOcildDnruv] -f rx_frequency (in Hz) | -i input_file\n", prog);
#ifndef DISABLE_RF
printf("\t-a RF args [Default %s]\n", args->rf_args);
printf("\t-g RF fix RX gain [Default AGC]\n");
@ -133,7 +131,6 @@ void usage(prog_args_t *args, char *prog) {
printf("\t-c cell_id for input file [Default %d]\n", args->file_cell_id);
printf("\t-r RNTI in Hex [Default 0x%x]\n",args->rnti);
printf("\t-l Force N_id_2 [Default best]\n");
printf("\t-L (Experimental) Use Robust LMMSE estimation [Default false]\n");
printf("\t-C Disable CFO correction [Default %s]\n", args->disable_cfo?"Disabled":"Enabled");
printf("\t-t Add time offset [Default %d]\n", args->time_offset);
#ifndef DISABLE_GRAPHICS
@ -153,7 +150,7 @@ void usage(prog_args_t *args, char *prog) {
void parse_args(prog_args_t *args, int argc, char **argv) {
int opt;
args_default(args);
while ((opt = getopt(argc, argv, "aoglLipPcOCtdDnvrfuUsS")) != -1) {
while ((opt = getopt(argc, argv, "aoglipPcOCtdDnvrfuUsS")) != -1) {
switch (opt) {
case 'i':
args->input_file_name = argv[optind];
@ -197,9 +194,6 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
case 'l':
args->force_N_id_2 = atoi(argv[optind]);
break;
case 'L':
args->use_robust_lmmse = true;
break;
case 'u':
args->net_port = atoi(argv[optind]);
break;
@ -413,11 +407,6 @@ int main(int argc, char **argv) {
/* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */
srslte_ue_dl_set_rnti(&ue_dl, prog_args.rnti);
/* (Experimental) setup robust LMMSE estimation */
if (prog_args.use_robust_lmmse) {
srslte_chest_dl_set_robust_mmse_filter(&ue_dl.chest);
}
/* Initialize subframe counter */
sf_cnt = 0;

@ -50,16 +50,18 @@
#include "srslte/common/phy_common.h"
#include "srslte/sync/pss.h"
#define SRSLTE_CHEST_MAX_FILTER_FREQ_LEN 21
#define SRSLTE_CHEST_MAX_FILTER_TIME_LEN 40
#define SRSLTE_CHEST_DL_MAX_SMOOTH_FIL_LEN 65
typedef struct {
srslte_cell_t cell;
srslte_refsignal_cs_t csr_signal;
cf_t *pilot_estimates;
cf_t *pilot_estimates_average;
cf_t *pilot_recv_signal;
cf_t *tmp_noise;
cf_t *w_filter;
uint32_t smooth_filter_len;
float smooth_filter[SRSLTE_CHEST_DL_MAX_SMOOTH_FIL_LEN];
srslte_interp_linsrslte_vec_t srslte_interp_linvec;
srslte_interp_lin_t srslte_interp_lin;
@ -80,10 +82,9 @@ SRSLTE_API int srslte_chest_dl_init(srslte_chest_dl_t *q,
SRSLTE_API void srslte_chest_dl_free(srslte_chest_dl_t *q);
SRSLTE_API void srslte_chest_dl_set_filter_w(srslte_chest_dl_t *q,
cf_t *w);
SRSLTE_API void srslte_chest_dl_set_robust_mmse_filter(srslte_chest_dl_t *q);
SRSLTE_API void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q,
float *filter,
uint32_t filter_len);
SRSLTE_API int srslte_chest_dl_estimate(srslte_chest_dl_t *q,
cf_t *input,

@ -49,12 +49,8 @@ SRSLTE_API void srslte_scrambling_b_offset(srslte_sequence_t *s,
int len);
SRSLTE_API void srslte_scrambling_bytes(srslte_sequence_t *s,
uint8_t *data);
SRSLTE_API void srslte_scrambling_bytes_offset(srslte_sequence_t *s,
uint8_t *data,
int offset,
int len);
uint8_t *data,
int len);
SRSLTE_API void srslte_scrambling_f(srslte_sequence_t *s,
float *data);

@ -41,8 +41,28 @@
#define ESTIMATE_NOISE_LS_PSS
#include "robust_mmse_25prb.h"
#include "robust_mmse_50prb.h"
#define DEFAULT_FILTER_LEN 3
static void set_default_filter(srslte_chest_dl_t *q, int filter_len) {
float fil[SRSLTE_CHEST_DL_MAX_SMOOTH_FIL_LEN];
for (int i=0;i<filter_len/2;i++) {
fil[i] = i+1;
fil[i+filter_len/2+1]=filter_len/2-i;
}
fil[filter_len/2]=filter_len/2+1;
float s=0;
for (int i=0;i<filter_len;i++) {
s+=fil[i];
}
for (int i=0;i<filter_len;i++) {
fil[i]/=s;
}
srslte_chest_dl_set_smooth_filter(q, fil, filter_len);
}
/** 3GPP LTE Downlink channel estimator and equalizer.
* Estimates the channel in the resource elements transmitting references and interpolates for the rest
@ -77,6 +97,11 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, srslte_cell_t cell)
perror("malloc");
goto clean_exit;
}
q->pilot_estimates_average = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_REFSIGNAL_MAX_NUM_SF(cell.nof_prb));
if (!q->pilot_estimates_average) {
perror("malloc");
goto clean_exit;
}
q->pilot_recv_signal = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_REFSIGNAL_MAX_NUM_SF(cell.nof_prb));
if (!q->pilot_recv_signal) {
perror("malloc");
@ -98,7 +123,8 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, srslte_cell_t cell)
goto clean_exit;
}
q->w_filter = NULL;
q->smooth_filter_len = 0;
set_default_filter(q, DEFAULT_FILTER_LEN);
q->cell = cell;
}
@ -125,28 +151,15 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q)
if (q->pilot_estimates) {
free(q->pilot_estimates);
}
if (q->pilot_estimates_average) {
free(q->pilot_estimates_average);
}
if (q->pilot_recv_signal) {
free(q->pilot_recv_signal);
}
bzero(q, sizeof(srslte_chest_dl_t));
}
void srslte_chest_dl_set_filter_w(srslte_chest_dl_t *q, cf_t *w) {
q->w_filter = w;
}
void srslte_chest_dl_set_robust_mmse_filter(srslte_chest_dl_t *q) {
if (q->cell.nof_prb == 25) {
printf("Using robust LMMSE interpolation filter\n");
srslte_chest_dl_set_filter_w(q, (cf_t*) w_robust_25prb);
} else if (q->cell.nof_prb == 50) {
printf("Using robust LMMSE interpolation filter\n");
srslte_chest_dl_set_filter_w(q, (cf_t*) w_robust_50prb);
} else {
fprintf(stderr, "Error setting robust MMSE filter. Not available for %d PRB\n", q->cell.nof_prb);
}
}
/* Uses the difference between the averaged and non-averaged pilot estimates */
static float estimate_noise_pilots(srslte_chest_dl_t *q, cf_t *ce, uint32_t port_id)
{
@ -156,7 +169,7 @@ static float estimate_noise_pilots(srslte_chest_dl_t *q, cf_t *ce, uint32_t port
/* Substract noisy pilot estimates */
srslte_vec_sub_ccc(q->tmp_noise, q->pilot_estimates, q->tmp_noise, nref);
/* Compute average power */
float power = sqrt(2.0)*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_noise, nref);
float power = sqrt(2)*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_noise, nref);
return power;
}
@ -176,7 +189,7 @@ static float estimate_noise_pss(srslte_chest_dl_t *q, cf_t *input, cf_t *ce)
srslte_vec_sub_ccc(q->tmp_pss_noisy, q->tmp_pss, q->tmp_pss_noisy, SRSLTE_PSS_LEN);
/* Compute average power */
float power = q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_pss_noisy, SRSLTE_PSS_LEN)/sqrt(2);
float power = sqrt(2)*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_pss_noisy, SRSLTE_PSS_LEN);
return power;
}
@ -200,45 +213,6 @@ static float estimate_noise_empty_sc(srslte_chest_dl_t *q, cf_t *input) {
#define cesymb(i) ce[SRSLTE_RE_IDX(q->cell.nof_prb,i,0)]
static void interpolate_filter_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t *w, cf_t *ce, uint32_t port_id)
{
int nsymbols = srslte_refsignal_cs_nof_symbols(port_id);
int nsc=SRSLTE_NRE*q->cell.nof_prb;
int nref=2*q->cell.nof_prb;
// Interpolation filter in frequency domain
for (uint32_t s=0;s<nsymbols;s++) {
for (int i=0;i<nsc;i++) {
uint32_t sym_idx=srslte_refsignal_cs_nsymbol(s,q->cell.cp, port_id);
ce[nsc*sym_idx+i] = srslte_vec_dot_prod_ccc(&pilot_estimates[s*nref], &w[i*nref], nref);
}
}
/* Now interpolate in the time domain between symbols */
if (SRSLTE_CP_ISNORM(q->cell.cp)) {
if (nsymbols == 4) {
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(4), &cesymb(1), 3);
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(4), &cesymb(7), &cesymb(5), 2);
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(8), 3);
srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(7), &cesymb(11), &cesymb(11), &cesymb(12), 2);
} else {
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(8), &cesymb(1), &cesymb(0), 1);
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(2), 6);
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(8), &cesymb(9), 5);
}
} else {
if (nsymbols == 4) {
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(0), &cesymb(3), &cesymb(1), 2);
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(3), &cesymb(6), &cesymb(4), 2);
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(7), 2);
srslte_interp_linear_vector2(&q->srslte_interp_linvec, &cesymb(6), &cesymb(9), &cesymb(9), &cesymb(10), 2);
} else {
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(7), &cesymb(1), &cesymb(0), 1);
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(2), 5);
srslte_interp_linear_vector(&q->srslte_interp_linvec, &cesymb(1), &cesymb(7), &cesymb(8), 4);
}
}
}
static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t *ce, uint32_t port_id)
{
/* interpolate the symbols with references in the freq domain */
@ -279,6 +253,25 @@ static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t
}
}
void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, float *filter, uint32_t filter_len) {
if (filter_len < SRSLTE_CHEST_DL_MAX_SMOOTH_FIL_LEN) {
memcpy(q->smooth_filter, filter, filter_len*sizeof(float));
q->smooth_filter_len = filter_len;
} else {
fprintf(stderr, "Error setting smoothing filter: filter len exceeds maximum (%d>%d)\n",
filter_len, SRSLTE_CHEST_DL_MAX_SMOOTH_FIL_LEN);
}
}
static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint32_t port_id) {
uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id);
uint32_t nref = 2*q->cell.nof_prb;
for (int l=0;l<nsymbols;l++) {
srslte_conv_same_cf(&input[l*nref], q->smooth_filter, &output[l*nref], nref, q->smooth_filter_len);
}
}
float srslte_chest_dl_rssi(srslte_chest_dl_t *q, cf_t *input, uint32_t port_id) {
uint32_t l;
@ -300,22 +293,21 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u
srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->csr_signal.pilots[port_id/2][sf_idx],
q->pilot_estimates, SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id));
if (ce != NULL) {
/* TESTING: Use robust MMSE interpolation filter */
if (q->w_filter) {
interpolate_filter_pilots(q, q->pilot_estimates, q->w_filter, ce, port_id);
/* Estimate noise from difference from averaged and estimated pilots */
if (q->smooth_filter_len > 0) {
average_pilots(q, q->pilot_estimates, q->pilot_estimates_average, port_id);
interpolate_pilots(q, q->pilot_estimates_average, ce, port_id);
/* If averaging, compute noise from difference between received and averaged estimates */
if (sf_idx == 0 || sf_idx == 5) {
q->noise_estimate[port_id] = estimate_noise_pilots(q, ce, port_id);
}
/* If w filter not defined, resort to LS estimate + linear interpolation */
} else {
interpolate_pilots(q, q->pilot_estimates, ce, port_id);
interpolate_pilots(q, q->pilot_estimates, ce, port_id);
/* If not averaging, compute noise from empty subcarriers */
if (sf_idx == 0 || sf_idx == 5) {
#ifdef ESTIMATE_NOISE_LS_PSS
q->noise_estimate[port_id] = estimate_noise_pss(q, input, ce);
q->noise_estimate[port_id] = estimate_noise_pss(q, input, ce);
#else
q->noise_estimate[port_id] = estimate_noise_empty_sc(q, input);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -115,13 +115,6 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
output_signal2 = srslte_vec_malloc(nof_re * sizeof(cf_t));
srslte_precoding_init(&cheq, nof_re);
cf_t *w=NULL;
if (nrhs > NOF_INPUTS) {
mexutils_read_cf(prhs[NOF_INPUTS], &w);
srslte_chest_dl_set_filter_w(&chest, w);
}
/* Create output values */
if (nlhs >= 1) {
@ -173,28 +166,24 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
}
if (nlhs >= 1) {
for (int j=0;j<cell.nof_ports;j++) {
for (i=0;i<nof_re;i++) {
*outr0 = (double) crealf(ce[j][i]);
if (outi0) {
*outi0 = (double) cimagf(ce[j][i]);
}
outr0++;
outi0++;
}
}
for (i=0;i<nof_re;i++) {
*outr0 = (double) crealf(ce[0][i]);
if (outi0) {
*outi0 = (double) cimagf(ce[0][i]);
}
outr0++;
outi0++;
}
}
if (nlhs >= 2) {
for (int j=0;j<cell.nof_ports;j++) {
for (i=0;i<SRSLTE_REFSIGNAL_NUM_SF(cell.nof_prb,j);i++) {
*outr1 = (double) crealf(chest.pilot_estimates[i]);
if (outi1) {
*outi1 = (double) cimagf(chest.pilot_estimates[i]);
}
outr1++;
outi1++;
for (i=0;i<SRSLTE_REFSIGNAL_NUM_SF(cell.nof_prb,0);i++) {
*outr1 = (double) crealf(chest.pilot_estimates_average[i]);
if (outi1) {
*outi1 = (double) cimagf(chest.pilot_estimates_average[i]);
}
}
outr1++;
outi1++;
}
}
if (nlhs >= 3) {
for (i=0;i<nof_re;i++) {
@ -208,10 +197,6 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
}
}
if (w) {
free(w);
}
if (nlhs >= 4) {
plhs[3] = mxCreateDoubleScalar(noise_power);
}

@ -285,7 +285,8 @@ int srslte_rm_turbo_tx_lut(uint8_t *w_buff, uint8_t *systematic, uint8_t *parity
}
int srslte_rm_turbo_rx_lut(int16_t *input, int16_t *output, uint32_t in_len, uint32_t cb_idx, uint32_t rv_idx)
{
{
#ifdef LV_HAVE_AVX
return srslte_rm_turbo_rx_lut_avx(input, output, in_len, cb_idx, rv_idx);
#else
@ -295,9 +296,7 @@ int srslte_rm_turbo_rx_lut(int16_t *input, int16_t *output, uint32_t in_len, uin
if (rv_idx < 4 && cb_idx < SRSLTE_NOF_TC_CB_SIZES) {
uint32_t out_len = 3*srslte_cbsegm_cbsize(cb_idx)+12;
uint16_t *deinter = deinterleaver[cb_idx][rv_idx];
for (int i=0;i<in_len;i++) {
//printf("i=%d=%d goes to %d\n", i%out_len, input[i], deinter[i%out_len]);
for (int i=0;i<in_len;i++) {
output[deinter[i%out_len]] += input[i];
}
return 0;

@ -69,8 +69,9 @@ void mod_qpsk_bytes(srslte_modem_table_t* q, uint8_t *bits, cf_t* symbols, uint3
for (int i=0;i<nbits/8;i++) {
memcpy(&symbols[4*i], &q->symbol_table_qpsk[bits[i]], sizeof(qpsk_packed_t));
}
// Encode last 1, 2 or 3 bit pairs if not multiple of 8
for (int i=0;i<(nbits%8)/2;i++) {
symbols[8*(nbits/8)+i] = q->symbol_table[(bits[8*(nbits/8)]&mask_qpsk[i])>>shift_qpsk[i]];
symbols[4*(nbits/8)+i] = q->symbol_table[(bits[nbits/8]&mask_qpsk[i])>>shift_qpsk[i]];
}
}
@ -78,7 +79,10 @@ void mod_16qam_bytes(srslte_modem_table_t* q, uint8_t *bits, cf_t* symbols, uint
for (int i=0;i<nbits/8;i++) {
memcpy(&symbols[2*i], &q->symbol_table_16qam[bits[i]], sizeof(qam16_packed_t));
}
symbols[8*(nbits/8)] = q->symbol_table[(bits[8*(nbits/8)]&0xf0)>>4];
// Encode last 4 bits if not multiple of 8
if (nbits%8) {
symbols[2*(nbits/8)] = q->symbol_table[(bits[nbits/8]&0xf0)>>4];
}
}
void mod_64qam_bytes(srslte_modem_table_t* q, uint8_t *bits, cf_t* symbols, uint32_t nbits) {
@ -101,22 +105,22 @@ void mod_64qam_bytes(srslte_modem_table_t* q, uint8_t *bits, cf_t* symbols, uint
symbols[i*4+3] = q->symbol_table[in3];
}
if (nbits%24 >= 6) {
in80 = bits[24*(nbits/24)+0];
in80 = bits[3*(nbits/24)+0];
in0 = (in80&0xfc)>>2;
symbols[24*(nbits/24)+0] = q->symbol_table[in0];
symbols[4*(nbits/24)+0] = q->symbol_table[in0];
}
if (nbits%24 >= 12) {
in81 = bits[24*(nbits/24)+1];
in81 = bits[3*(nbits/24)+1];
in1 = (in80&0x03)<<4 | ((in81&0xf0)>>4);
symbols[24*(nbits/24)+1] = q->symbol_table[in1];
symbols[4*(nbits/24)+1] = q->symbol_table[in1];
}
if (nbits%24 >= 18) {
in82 = bits[24*(nbits/24)+2];
in82 = bits[3*(nbits/24)+2];
in2 = (in81&0x0f)<<2 | ((in82&0xc0)>>6);
symbols[24*(nbits/24)+2] = q->symbol_table[in2];
symbols[4*(nbits/24)+2] = q->symbol_table[in2];
}
}

@ -141,7 +141,7 @@ bool srslte_cqi_send(uint32_t I_cqi_pmi, uint32_t tti) {
/* SNR-to-CQI conversion, got from "Downlink SNR to CQI Mapping for Different Multiple Antenna Techniques in LTE"
* Table III.
*/
static float cqi_to_snr_table[15] = { 1.95, 4, 6, 8, 10, 11.95, 14.05, 16, 17.9, 19.9, 21.5, 24, 26, 28, 30};
static float cqi_to_snr_table[15] = { 1.95, 4, 6, 8, 10, 11.95, 14.05, 16, 17.9, 19.9, 21.5, 23.45, 25.0, 27.30, 29};
uint8_t srslte_cqi_from_snr(float snr)
{

@ -425,7 +425,7 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q,
* thus we don't need tot set it in the LLRs normalization
*/
srslte_demod_soft_demodulate_s(cfg->grant.mcs.mod, q->d, q->e, cfg->nbits.nof_re);
/* descramble */
if (rnti != q->rnti) {
srslte_sequence_t seq;
@ -522,10 +522,10 @@ int srslte_pdsch_encode_rnti(srslte_pdsch_t *q,
if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
return SRSLTE_ERROR;
}
srslte_scrambling_bytes_offset(&seq, (uint8_t*) q->e, 0, cfg->nbits.nof_bits);
srslte_scrambling_bytes(&seq, (uint8_t*) q->e, cfg->nbits.nof_bits);
srslte_sequence_free(&seq);
} else {
srslte_scrambling_bytes_offset(&q->seq[cfg->sf_idx], (uint8_t*) q->e, 0, cfg->nbits.nof_bits);
srslte_scrambling_bytes(&q->seq[cfg->sf_idx], (uint8_t*) q->e, cfg->nbits.nof_bits);
}
srslte_mod_modulate_bytes(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->e, q->d, cfg->nbits.nof_bits);

@ -527,10 +527,10 @@ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srs
if (srslte_sequence_pusch(&seq, rnti, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
return SRSLTE_ERROR;
}
srslte_scrambling_bytes_offset(&seq, (uint8_t*) q->q, 0, cfg->nbits.nof_bits);
srslte_scrambling_bytes(&seq, (uint8_t*) q->q, cfg->nbits.nof_bits);
srslte_sequence_free(&seq);
} else {
srslte_scrambling_bytes_offset(&q->seq[cfg->sf_idx], (uint8_t*) q->q, 0, cfg->nbits.nof_bits);
srslte_scrambling_bytes(&q->seq[cfg->sf_idx], (uint8_t*) q->q, cfg->nbits.nof_bits);
}
// Correct UCI placeholder bits

@ -390,7 +390,6 @@ static int decode_tb(srslte_sch_t *q,
n_e = Qm * ((uint32_t) ceilf((float) Gp/cb_segm->C));
}
bzero(softbuffer->buffer_f[i], (3*cb_len+12)*sizeof(int16_t));
/* Rate Unmatching */
if (srslte_rm_turbo_rx_lut(&e_bits[rp], softbuffer->buffer_f[i], n_e, cblen_idx, rv)) {
fprintf(stderr, "Error in rate matching\n");

@ -95,6 +95,8 @@ TARGET_LINK_LIBRARIES(pdsch_test srslte)
ADD_TEST(pdsch_test_qpsk pdsch_test -m 10 -n 50 -r 1)
ADD_TEST(pdsch_test_qam16 pdsch_test -m 20 -n 100)
ADD_TEST(pdsch_test_qam64 pdsch_test -m 28 -n 100 -r 0)
ADD_TEST(pdsch_test_qam64 pdsch_test -m 28 -n 100 -r 1)
ADD_TEST(pdsch_test_qam64 pdsch_test -m 28 -n 25 -r 2)
BuildMex(MEXNAME pdsch SOURCES pdsch_test_mex.c LIBRARIES srslte srslte_mex)
BuildMex(MEXNAME dlsch_encode SOURCES dlsch_encode_test_mex.c LIBRARIES srslte srslte_mex)

@ -108,6 +108,15 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
mexErrMsgTxt("Error computing CB segmentation\n");
return;
}
uint32_t tmp_rv=cfg.rv;
if (tmp_rv) {
cfg.rv = 0;
if (srslte_dlsch_encode(&dlsch, &cfg, &softbuffer, trblkin, e_bits)) {
mexErrMsgTxt("Error encoding TB\n");
return;
}
cfg.rv = tmp_rv;
}
if (srslte_dlsch_encode(&dlsch, &cfg, &softbuffer, trblkin, e_bits)) {
mexErrMsgTxt("Error encoding TB\n");
return;

@ -118,14 +118,6 @@ cf_t *slot_symbols[SRSLTE_MAX_PORTS];
srslte_pdsch_t pdsch;
srslte_ofdm_t ofdm_tx, ofdm_rx;
int dummy_function() {
#ifdef DO_OFDM
srslte_ofdm_rx_sf(&ofdm_rx, sf_symbols, slot_symbols[1]);
#endif
srslte_softbuffer_rx_reset_tbs(&softbuffer_rx, grant.mcs.tbs);
return srslte_pdsch_decode(&pdsch, &pdsch_cfg, &softbuffer_rx, slot_symbols[0], ce, 0, data);
}
int main(int argc, char **argv) {
uint32_t i, j;
int ret = -1;
@ -228,38 +220,53 @@ int main(int argc, char **argv) {
for (i=0;i<grant.mcs.tbs/8;i++) {
data[i] = rand()%256;
}
for (rv=0;rv<=rv_idx;rv++) {
pdsch_cfg.rv = rv;
uint8_t databit[100000];
srslte_bit_unpack_vector(data, databit, grant.mcs.tbs);
srslte_vec_save_file("data_in", databit, grant.mcs.tbs);
if (!input_file) {
if (!input_file) {
if (rv_idx) {
/* Do 1st transmission for rv_idx!=0 */
pdsch_cfg.rv = 0;
if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer_tx, data, slot_symbols)) {
fprintf(stderr, "Error encoding PDSCH\n");
goto quit;
}
}
pdsch_cfg.rv = rv_idx;
/* combine outputs */
for (i=0;i<cell.nof_ports;i++) {
for (j=0;j<SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);j++) {
if (i > 0) {
slot_symbols[0][j] += slot_symbols[i][j];
}
ce[i][j] = 1;
if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer_tx, data, slot_symbols)) {
fprintf(stderr, "Error encoding PDSCH\n");
goto quit;
}
}
/* combine outputs */
for (i=0;i<cell.nof_ports;i++) {
for (j=0;j<SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);j++) {
if (i > 0) {
slot_symbols[0][j] += slot_symbols[i][j];
}
ce[i][j] = 1;
}
}
#ifdef DO_OFDM
srslte_ofdm_tx_sf(&ofdm_tx, slot_symbols[0], sf_symbols);
srslte_ofdm_tx_sf(&ofdm_tx, slot_symbols[0], sf_symbols);
#endif
}
}
int M=1;
int r=0;
srslte_sch_set_max_noi(&pdsch.dl_sch, 10);
gettimeofday(&t[1], NULL);
for (i=0;i<M;i++) {
r = dummy_function();
#ifdef DO_OFDM
srslte_ofdm_rx_sf(&ofdm_rx, sf_symbols, slot_symbols[1]);
#endif
srslte_softbuffer_rx_reset_tbs(&softbuffer_rx, grant.mcs.tbs);
r = srslte_pdsch_decode(&pdsch, &pdsch_cfg, &softbuffer_rx, slot_symbols[0], ce, 0, data);
}
gettimeofday(&t[2], NULL);
get_time_interval(t);

@ -183,22 +183,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
for (i=0;i<cell.nof_ports;i++) {
ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
}
cf_t *w=NULL;
if (nrhs > NOF_INPUTS) {
mexutils_read_cf(prhs[NOF_INPUTS], &w);
srslte_chest_dl_set_filter_w(&chest, w);
srslte_chest_dl_estimate(&chest, input_fft, ce, cfg.sf_idx);
free(w);
} else {
srslte_chest_dl_estimate(&chest, input_fft, ce, cfg.sf_idx);
}
/*
if (nrhs > NOF_INPUTS) {
cf_t *cearray = NULL;
nof_re = mexutils_read_cf(prhs[NOF_INPUTS], &cearray);
int nof_re = mexutils_read_cf(prhs[NOF_INPUTS], &cearray);
cf_t *cearray_ptr = cearray;
for (i=0;i<cell.nof_ports;i++) {
for (int j=0;j<nof_re/cell.nof_ports;j++) {
@ -211,13 +199,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
} else {
srslte_chest_dl_estimate(&chest, input_fft, ce, cfg.sf_idx);
}
*/
float noise_power;
if (nrhs > NOF_INPUTS + 1) {
noise_power = mxGetScalar(prhs[NOF_INPUTS+1]);
} else {
noise_power = 0;
noise_power = srslte_chest_dl_get_noise_estimate(&chest);
}
uint8_t *data_bytes = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs.tbs/8);

@ -28,6 +28,7 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "srslte/utils/bit.h"
#include "srslte/utils/vector.h"
#include "srslte/scrambling/scrambling.h"
@ -58,47 +59,47 @@ void srslte_scrambling_c_offset(srslte_sequence_t *s, cf_t *data, int offset, in
srslte_vec_prod_cfc(data, &s->c_float[offset], data, len);
}
void scrambling_b(uint8_t *c, uint8_t *data, int offset, int len) {
int i;
// Do XOR on a word basis
if (!(len%8)) {
uint64_t *x = (uint64_t*) data;
uint64_t *y = (uint64_t*) &c[offset];
for (int i=0;i<len/8;i++) {
x[i] = (x[i] ^ y[i]);
}
} else if (!(len%4)) {
uint32_t *x = (uint32_t*) data;
uint32_t *y = (uint32_t*) &c[offset];
for (int i=0;i<len/4;i++) {
x[i] = (x[i] ^ y[i]);
}
} else if (!(len%2)) {
uint16_t *x = (uint16_t*) data;
uint16_t *y = (uint16_t*) &c[offset];
for (int i=0;i<len/2;i++) {
x[i] = (x[i] ^ y[i]);
}
} else {
for (i = 0; i < len; i++) {
data[i] = (data[i] ^ c[i + offset]);
}
void scrambling_b(uint8_t *c, uint8_t *data, int len) {
int i;
for (i = 0; i < len; i++) {
data[i] = (data[i] ^ c[i]);
}
}
void scrambling_b_word(uint8_t *c, uint8_t *data, int len) {
// Do XOR every 64 bits
// FIXME: Use 32-bit in 32-bit machines
uint64_t *x = (uint64_t*) data;
uint64_t *y = (uint64_t*) c;
for (int i=0;i<len/8;i++) {
x[i] = (x[i] ^ y[i]);
}
// Do XOR every 8 bits
scrambling_b(&c[8*(len/8)], &data[8*(len/8)], len%8);
}
void srslte_scrambling_b(srslte_sequence_t *s, uint8_t *data) {
scrambling_b(s->c, data, 0, s->len);
scrambling_b_word(s->c, data, s->len);
}
void srslte_scrambling_b_offset(srslte_sequence_t *s, uint8_t *data, int offset, int len) {
scrambling_b(s->c, data, offset, len);
}
void srslte_scrambling_bytes(srslte_sequence_t *s, uint8_t *data) {
scrambling_b(s->c_bytes, data, 0, s->len/8);
if (offset%8) {
// Do not load words if offset is not word-aligned
scrambling_b(&s->c[offset], data, len);
} else {
scrambling_b_word(&s->c[offset], data, len);
}
}
void srslte_scrambling_bytes_offset(srslte_sequence_t *s, uint8_t *data, int offset, int len) {
scrambling_b(s->c_bytes, data, offset, len/8);
void srslte_scrambling_bytes(srslte_sequence_t *s, uint8_t *data, int len) {
scrambling_b_word(s->c_bytes, data, len/8);
// Scramble last bits
if (len%8) {
uint8_t tmp_bits[8];
srslte_bit_unpack_vector(&data[len/8], tmp_bits, len%8);
scrambling_b(&s->c[8*(len/8)], tmp_bits, len%8);
srslte_bit_pack_vector(tmp_bits, &data[len/8], len%8);
}
}

Loading…
Cancel
Save