From 88cd40420a29655cd9eb2e26e25d370c38f998fe Mon Sep 17 00:00:00 2001 From: ismagom Date: Wed, 14 Oct 2015 22:30:41 +0200 Subject: [PATCH] Improved PDSCH reception --- matlab/tests/dlsch_test.m | 4 +- matlab/tests/pdsch_bler.m | 15 ++- matlab/tests/prach_test.m | 4 +- mex/include/srslte/mex/mexutils.h | 5 + mex/lib/mexutils.c | 12 ++ srslte/examples/pdsch_ue.c | 14 ++- srslte/include/srslte/fec/rm_turbo.h | 6 + srslte/include/srslte/phch/sch.h | 5 +- srslte/include/srslte/ue/ue_sync.h | 3 +- srslte/include/srslte/utils/bit.h | 4 +- srslte/lib/common/src/phy_common.c | 4 +- srslte/lib/fec/src/rm_turbo.c | 119 ++++++++++++++++--- srslte/lib/fec/src/softbuffer.c | 6 +- srslte/lib/fec/src/turbocoder.c | 4 +- srslte/lib/fec/src/turbodecoder_gen.c | 4 + srslte/lib/fec/src/turbodecoder_sse.c | 13 +- srslte/lib/fec/test/rm_turbo_test.c | 6 +- srslte/lib/modem/src/demod_soft.c | 56 ++++----- srslte/lib/phch/src/pdsch.c | 4 +- srslte/lib/phch/src/sch.c | 48 ++++---- srslte/lib/phch/test/dlsch_encode_test_mex.c | 9 +- srslte/lib/phch/test/pdsch_test_mex.c | 11 +- srslte/lib/phch/test/prach_test_mex.c | 1 + srslte/lib/sync/test/pss_file.c | 12 +- srslte/lib/ue/src/ue_mib.c | 4 +- srslte/lib/ue/src/ue_sync.c | 7 +- srslte/lib/utils/src/bit.c | 27 ++--- srslte/lib/utils/src/vector_simd.c | 2 +- 28 files changed, 277 insertions(+), 132 deletions(-) diff --git a/matlab/tests/dlsch_test.m b/matlab/tests/dlsch_test.m index e58bc37e1..15769f191 100644 --- a/matlab/tests/dlsch_test.m +++ b/matlab/tests/dlsch_test.m @@ -4,8 +4,8 @@ pdschConfig=struct('Modulation','64QAM','RV',0,'TxScheme','Port0'); addpath('../../build/srslte/lib/phch/test') -TBs=19848; -e_bits=38460; +TBs=36696; +e_bits=41400; error=zeros(size(TBs)); for i=1:length(TBs) trblkin=randi(2,TBs(i),1)-1; diff --git a/matlab/tests/pdsch_bler.m b/matlab/tests/pdsch_bler.m index a3b47bbed..364c7976e 100644 --- a/matlab/tests/pdsch_bler.m +++ b/matlab/tests/pdsch_bler.m @@ -6,11 +6,11 @@ recordedSignal=[]; -Npackets = 8; -SNR_values = linspace(10.5,13,4); +Npackets = 3; +SNR_values = linspace(12,16,4); %% Choose RMC -[waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.6',[1;0;0;1]); +[waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.9',[1;0;0;1]); waveform = sum(waveform,2); if ~isempty(recordedSignal) @@ -79,6 +79,7 @@ for snr_idx=1:length(SNR_values) frame_rx = lteOFDMDemodulate(rmccFgOut, rxWaveform); for sf_idx=0:Nsf + %sf_idx=9; subframe_rx=frame_rx(:,sf_idx*14+1:(sf_idx+1)*14); rmccFgOut.NSubframe=sf_idx; rmccFgOut.TotSubframes=1; @@ -95,11 +96,14 @@ for snr_idx=1:length(SNR_values) %% Same with srsLTE if (rmccFgOut.PDSCH.TrBlkSizes(sf_idx+1) > 0) - [dec2, data, pdschRx, pdschSymbols2, deb] = srslte_pdsch(rmccFgOut, rmccFgOut.PDSCH, ... + [dec2, data, pdschRx, pdschSymbols2, cws2, cb9, temp] = srslte_pdsch(rmccFgOut, rmccFgOut.PDSCH, ... rmccFgOut.PDSCH.TrBlkSizes(sf_idx+1), ... subframe_rx); else dec2 = 1; + end + if (~dec2) + fprintf('Error in sf=%d\n',sf_idx); end decoded_srslte(snr_idx) = decoded_srslte(snr_idx)+dec2; end @@ -120,7 +124,6 @@ if (length(SNR_values)>1) ylabel('BLER') axis([min(SNR_values) max(SNR_values) 1/Npackets/(Nsf+1) 1]) else - disp(decoded) - disp(decoded_srslte) + fprintf('Matlab: %d OK\nsrsLTE: %d OK\n',decoded, decoded_srslte); end diff --git a/matlab/tests/prach_test.m b/matlab/tests/prach_test.m index 75bce17b6..049fe1b2e 100644 --- a/matlab/tests/prach_test.m +++ b/matlab/tests/prach_test.m @@ -1,10 +1,10 @@ clear ueConfig=struct('NULRB',6,'DuplexMode','FDD','CyclicPrefix','Normal'); -prachConfig=struct('Format',0,'SeqIdx',0,'PreambleIdx',0,'CyclicShiftIdx',0,'HighSpeed',0,'TimingOffset',0,'FreqIdx',0,'FreqOffset',0); +prachConfig=struct('Format',0,'SeqIdx',0,'PreambleIdx',0,'CyclicShiftIdx',0,'HighSpeed',0,'TimingOffset',0,'FreqIdx',0,'FreqOffset',8); addpath('../../build/srslte/lib/phch/test') -NULRB=[6 15 25 50 100]; +NULRB=[100]; % FreqIdx, FreqOffset and TimeOffset need to be tested diff --git a/mex/include/srslte/mex/mexutils.h b/mex/include/srslte/mex/mexutils.h index a1aad15ca..8127bc524 100644 --- a/mex/include/srslte/mex/mexutils.h +++ b/mex/include/srslte/mex/mexutils.h @@ -63,6 +63,11 @@ SRSLTE_API int mexutils_write_f(float *buffer, uint32_t nr, uint32_t nc); +SRSLTE_API int mexutils_write_s(short *buffer, + mxArray **ptr, + uint32_t nr, + uint32_t nc); + SRSLTE_API int mexutils_write_cf(cf_t *buffer, mxArray **ptr, uint32_t nr, diff --git a/mex/lib/mexutils.c b/mex/lib/mexutils.c index fc9071019..b4b5da3fd 100644 --- a/mex/lib/mexutils.c +++ b/mex/lib/mexutils.c @@ -166,6 +166,18 @@ int mexutils_write_f(float *buffer, mxArray **ptr, uint32_t nr, uint32_t nc) { } } +int mexutils_write_s(short *buffer, mxArray **ptr, uint32_t nr, uint32_t nc) { + *ptr = mxCreateDoubleMatrix(nr, nc, mxREAL); + if (*ptr) { + double *outr = mxGetPr(*ptr); + for (int i=0;ifile_nof_prb = 25; args->file_nof_ports = 1; args->file_cell_id = 0; + args->file_offset = 0; args->uhd_args = ""; args->uhd_freq = -1.0; args->uhd_freq_offset = 0.0; @@ -116,7 +118,7 @@ void args_default(prog_args_t *args) { } void usage(prog_args_t *args, char *prog) { - printf("Usage: %s [agpPcildDnruv] -f rx_frequency (in Hz) | -i input_file\n", prog); + printf("Usage: %s [agpPOcildDnruv] -f rx_frequency (in Hz) | -i input_file\n", prog); #ifndef DISABLE_UHD printf("\t-a UHD args [Default %s]\n", args->uhd_args); printf("\t-g UHD fix RX gain [Default AGC]\n"); @@ -125,6 +127,7 @@ void usage(prog_args_t *args, char *prog) { printf("\t UHD is disabled. CUHD library not available\n"); #endif printf("\t-i input_file [Default USRP]\n"); + printf("\t-O offset samples for input file [Default %d]\n", args->file_offset); printf("\t-p nof_prb for input file [Default %d]\n", args->file_nof_prb); printf("\t-P nof_ports for input file [Default %d]\n", args->file_nof_ports); printf("\t-c cell_id for input file [Default %d]\n", args->file_cell_id); @@ -149,7 +152,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, "aoglipPcCtdDnvrfuUsS")) != -1) { + while ((opt = getopt(argc, argv, "aoglipPcOCtdDnvrfuUsS")) != -1) { switch (opt) { case 'i': args->input_file_name = argv[optind]; @@ -160,6 +163,9 @@ void parse_args(prog_args_t *args, int argc, char **argv) { case 'P': args->file_nof_ports = atoi(argv[optind]); break; + case 'O': + args->file_offset = atoi(argv[optind]); + break; case 'c': args->file_cell_id = atoi(argv[optind]); break; @@ -368,7 +374,7 @@ int main(int argc, char **argv) { cell.nof_ports = prog_args.file_nof_ports; cell.nof_prb = prog_args.file_nof_prb; - if (srslte_ue_sync_init_file(&ue_sync, prog_args.file_nof_prb, prog_args.input_file_name)) { + if (srslte_ue_sync_init_file(&ue_sync, prog_args.file_nof_prb, prog_args.input_file_name, prog_args.file_offset)) { fprintf(stderr, "Error initiating ue_sync\n"); exit(-1); } diff --git a/srslte/include/srslte/fec/rm_turbo.h b/srslte/include/srslte/fec/rm_turbo.h index 17d2b5975..aa2469f7c 100644 --- a/srslte/include/srslte/fec/rm_turbo.h +++ b/srslte/include/srslte/fec/rm_turbo.h @@ -83,6 +83,12 @@ SRSLTE_API int srslte_rm_turbo_rx_lut(int16_t *input, uint32_t cb_idx, uint32_t rv_idx); +SRSLTE_API int srslte_rm_turbo_rx_lut_simd(int16_t *input, + int16_t *output, + uint32_t in_len, + uint32_t cb_idx, + uint32_t rv_idx); + /* High-level API */ typedef struct SRSLTE_API { diff --git a/srslte/include/srslte/phch/sch.h b/srslte/include/srslte/phch/sch.h index 0bf3b431e..340aeb3be 100644 --- a/srslte/include/srslte/phch/sch.h +++ b/srslte/include/srslte/phch/sch.h @@ -47,9 +47,6 @@ #include "srslte/phch/pusch_cfg.h" #include "srslte/phch/uci.h" -#define SRSLTE_PDSCH_MAX_TDEC_ITERS 4 - - #ifndef SRSLTE_RX_NULL #define SRSLTE_RX_NULL 10000 #endif @@ -80,6 +77,8 @@ typedef struct SRSLTE_API { srslte_uci_cqi_pusch_t uci_cqi; + uint8_t temp_data[6000]; + } srslte_sch_t; SRSLTE_API int srslte_sch_init(srslte_sch_t *q); diff --git a/srslte/include/srslte/ue/ue_sync.h b/srslte/include/srslte/ue/ue_sync.h index 586cc5dfe..5b30eaa67 100644 --- a/srslte/include/srslte/ue/ue_sync.h +++ b/srslte/include/srslte/ue/ue_sync.h @@ -123,7 +123,8 @@ SRSLTE_API int srslte_ue_sync_init(srslte_ue_sync_t *q, SRSLTE_API int srslte_ue_sync_init_file(srslte_ue_sync_t *q, uint32_t nof_prb, - char *file_name); + char *file_name, + int offset); SRSLTE_API void srslte_ue_sync_free(srslte_ue_sync_t *q); diff --git a/srslte/include/srslte/utils/bit.h b/srslte/include/srslte/utils/bit.h index 29155116f..8958bef52 100644 --- a/srslte/include/srslte/utils/bit.h +++ b/srslte/include/srslte/utils/bit.h @@ -43,7 +43,7 @@ SRSLTE_API void srslte_bit_interleave(uint8_t *input, uint8_t *output, - uint32_t *interleaver, + uint16_t *interleaver, uint32_t nof_bits); SRSLTE_API void srslte_bit_copy(uint8_t *dst, @@ -54,7 +54,7 @@ SRSLTE_API void srslte_bit_copy(uint8_t *dst, SRSLTE_API void srslte_bit_interleave_w_offset(uint8_t *input, uint8_t *output, - uint32_t *interleaver, + uint16_t *interleaver, uint32_t nof_bits, uint32_t w_offset); diff --git a/srslte/lib/common/src/phy_common.c b/srslte/lib/common/src/phy_common.c index 0bfaf5bb0..407936279 100644 --- a/srslte/lib/common/src/phy_common.c +++ b/srslte/lib/common/src/phy_common.c @@ -35,9 +35,7 @@ #include "srslte/common/phy_common.h" #include "srslte/common/sequence.h" - -//#define USE_REDUCED_SAMPLING_RATES - +#define USE_REDUCED_SAMPLING_RATES /* Returns true if the structure pointed by cell has valid parameters diff --git a/srslte/lib/fec/src/rm_turbo.c b/srslte/lib/fec/src/rm_turbo.c index afb7908b1..7cdeb182c 100644 --- a/srslte/lib/fec/src/rm_turbo.c +++ b/srslte/lib/fec/src/rm_turbo.c @@ -37,6 +37,12 @@ #include "srslte/utils/vector.h" #include "srslte/fec/cbsegm.h" +//#define HAVE_SIMD + +#ifdef HAVE_SIMD +#include +#include +#endif #define NCOLS 32 #define NROWS_MAX NCOLS @@ -44,15 +50,18 @@ static uint8_t RM_PERM_TC[NCOLS] = { 0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, 6, 22, 14, 30, 1, 17, 9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23, 15, 31 }; -static uint32_t interleaver_systematic_bits[SRSLTE_NOF_TC_CB_SIZES][6148]; // 4 tail bits -static uint32_t interleaver_parity_bits[SRSLTE_NOF_TC_CB_SIZES][2*6148]; -static uint32_t deinterleaver[SRSLTE_NOF_TC_CB_SIZES][4][3*6148]; -static uint32_t k0_vec[SRSLTE_NOF_TC_CB_SIZES][4][2]; +/* Align tables to 16-byte boundary */ + +static uint16_t interleaver_systematic_bits[192][6160]; // 4 tail bits +static uint16_t interleaver_parity_bits[192][2*6160]; +static uint16_t deinterleaver[192][4][18448]; +static int k0_vec[SRSLTE_NOF_TC_CB_SIZES][4][2]; static bool rm_turbo_tables_generated = false; -static uint32_t temp_table1[3*6176], temp_table2[3*6176]; -void srslte_rm_turbo_gentable_systematic(uint32_t *table_bits, uint32_t k0_vec[4][2], uint32_t nrows, int ndummy) { +static uint16_t temp_table1[3*6176], temp_table2[3*6176]; + +void srslte_rm_turbo_gentable_systematic(uint16_t *table_bits, int k0_vec[4][2], uint32_t nrows, int ndummy) { bool last_is_null=true; int k_b=0, buff_idx=0; @@ -77,7 +86,7 @@ void srslte_rm_turbo_gentable_systematic(uint32_t *table_bits, uint32_t k0_vec[4 } } -void srslte_rm_turbo_gentable_parity(uint32_t *table_parity, uint32_t k0_vec[4][2], int offset, uint32_t nrows, int ndummy) { +void srslte_rm_turbo_gentable_parity(uint16_t *table_parity, int k0_vec[4][2], int offset, uint16_t nrows, int ndummy) { bool last_is_null=true; int k_b=0, buff_idx0=0; @@ -123,7 +132,7 @@ void srslte_rm_turbo_gentable_parity(uint32_t *table_parity, uint32_t k0_vec[4][ -void srslte_rm_turbo_gentable_receive(uint32_t *table, uint32_t cb_len, uint32_t rv_idx) +void srslte_rm_turbo_gentable_receive(uint16_t *table, uint32_t cb_len, uint32_t rv_idx) { int nrows = (uint32_t) (cb_len / 3 - 1) / NCOLS + 1; @@ -134,7 +143,7 @@ void srslte_rm_turbo_gentable_receive(uint32_t *table, uint32_t cb_len, uint32_t /* Undo bit collection. Account for dummy bits */ int N_cb = 3*nrows*NCOLS; - int k0 = nrows*(2*(uint32_t) ceilf((float) N_cb/(float) (8*nrows))*rv_idx+2); + int k0 = nrows*(2*(uint16_t) ceilf((float) N_cb/(float) (8*nrows))*rv_idx+2); int kidx; int K_p = nrows * NCOLS; @@ -214,7 +223,7 @@ void srslte_rm_turbo_gentables() { } for (int i=0;i<4;i++) { - k0_vec[cb_idx][i][0] = nrows * (2 * (uint32_t) ceilf((float) (3*K_p) / (float) (8 * nrows)) * i + 2); + k0_vec[cb_idx][i][0] = nrows * (2 * (uint16_t) ceilf((float) (3*K_p) / (float) (8 * nrows)) * i + 2); k0_vec[cb_idx][i][1] = -1; } srslte_rm_turbo_gentable_systematic(interleaver_systematic_bits[cb_idx], k0_vec[cb_idx], nrows, ndummy); @@ -241,10 +250,11 @@ int srslte_rm_turbo_tx_lut(uint8_t *w_buff, uint8_t *systematic, uint8_t *parity /* Sub-block interleaver (5.1.4.1.1) and bit collection */ if (rv_idx == 0) { - + // Systematic bits srslte_bit_interleave(systematic, w_buff, interleaver_systematic_bits[cb_idx], in_len/3); + // Parity bits srslte_bit_interleave_w_offset(parity, &w_buff[in_len/24], interleaver_parity_bits[cb_idx], 2*in_len/3, 4); } @@ -252,7 +262,6 @@ int srslte_rm_turbo_tx_lut(uint8_t *w_buff, uint8_t *systematic, uint8_t *parity /* Bit selection and transmission 5.1.4.1.2 */ int w_len = 0; int r_ptr = k0_vec[cb_idx][rv_idx][1]; - while (w_len < out_len) { int cp_len = out_len - w_len; if (cp_len + r_ptr >= in_len) { @@ -274,13 +283,84 @@ 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) { +#ifndef HAVE_SIMD if (rv_idx < 4 && cb_idx < SRSLTE_NOF_TC_CB_SIZES) { uint32_t out_len = 3*srslte_cbsegm_cbsize(cb_idx)+12; - uint32_t *deinter = deinterleaver[cb_idx][rv_idx]; + uint16_t *deinter = deinterleaver[cb_idx][rv_idx]; for (int i=0;i= out_len) { + /* Copy last elements */ + for (int j=nwrapps*out_len+intCnt-8;j<(nwrapps+1)*out_len;j++) { + printf("coping element %d (in=%d)\n", j, input[j]); + output[deinter[j]] += input[j]; + } + /* And wrap pointers */ + nwrapps++; + printf("--- Wrapping: intCnt=%d, nwrap=%d\n",intCnt, nwrapps); + intCnt = 8; + xPtr = (const __m128i*) &input[nwrapps*out_len]; + lutPtr = (const __m128i*) deinter; + } + + } + + for (int i=8*(in_len/8-1)+(((8*(in_len/8))%out_len)%8);i w_buff_len) { fprintf(stderr, @@ -385,7 +468,7 @@ int srslte_rm_turbo_tx(uint8_t *w_buff, uint32_t w_buff_len, uint8_t *input, uin N_cb = 3 * K_p; // TODO: Soft buffer size limitation k0 = nrows - * (2 * (uint32_t) ceilf((float) N_cb / (float) (8 * nrows)) * rv_idx + 2); + * (2 * (uint16_t) ceilf((float) N_cb / (float) (8 * nrows)) * rv_idx + 2); k = 0; j = 0; @@ -414,7 +497,7 @@ int srslte_rm_turbo_rx(float *w_buff, uint32_t w_buff_len, float *input, uint32_ - nrows = (uint32_t) (out_len / 3 - 1) / NCOLS + 1; + nrows = (uint16_t) (out_len / 3 - 1) / NCOLS + 1; K_p = nrows * NCOLS; if (3 * K_p > w_buff_len) { fprintf(stderr, @@ -437,7 +520,7 @@ int srslte_rm_turbo_rx(float *w_buff, uint32_t w_buff_len, float *input, uint32_ /* Undo bit collection. Account for dummy bits */ N_cb = 3 * K_p; // TODO: Soft buffer size limitation k0 = nrows - * (2 * (uint32_t) ceilf((float) N_cb / (float) (8 * nrows)) * rv_idx + 2); + * (2 * (uint16_t) ceilf((float) N_cb / (float) (8 * nrows)) * rv_idx + 2); k = 0; j = 0; @@ -462,7 +545,7 @@ int srslte_rm_turbo_rx(float *w_buff, uint32_t w_buff_len, float *input, uint32_ } } else { - uint32_t jpp = (jp - K_p - 1) / 2; + uint16_t jpp = (jp - K_p - 1) / 2; kidx = (RM_PERM_TC[jpp / nrows] + NCOLS * (jpp % nrows) + 1) % K_p; if ((kidx - ndummy) < 0) { isdummy = true; diff --git a/srslte/lib/fec/src/softbuffer.c b/srslte/lib/fec/src/softbuffer.c index 9ebb9433a..9277167df 100644 --- a/srslte/lib/fec/src/softbuffer.c +++ b/srslte/lib/fec/src/softbuffer.c @@ -56,7 +56,7 @@ int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, uint32_t nof_prb) { if (ret != SRSLTE_ERROR) { q->max_cb = (uint32_t) ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1; - q->buffer_f = srslte_vec_malloc(sizeof(float*) * q->max_cb); + q->buffer_f = srslte_vec_malloc(sizeof(int16_t*) * q->max_cb); if (!q->buffer_f) { perror("malloc"); return SRSLTE_ERROR; @@ -64,7 +64,7 @@ int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, uint32_t nof_prb) { // FIXME: Use HARQ buffer limitation based on UE category for (uint32_t i=0;imax_cb;i++) { - q->buffer_f[i] = srslte_vec_malloc(sizeof(float) * SOFTBUFFER_SIZE); + q->buffer_f[i] = srslte_vec_malloc(sizeof(int16_t) * SOFTBUFFER_SIZE); if (!q->buffer_f[i]) { perror("malloc"); return SRSLTE_ERROR; @@ -107,7 +107,7 @@ void srslte_softbuffer_rx_reset_cb(srslte_softbuffer_rx_t *q, uint32_t nof_cb) { } for (uint32_t i=0;ibuffer_f[i]) { - bzero(q->buffer_f[i], SOFTBUFFER_SIZE*sizeof(float)); + bzero(q->buffer_f[i], SOFTBUFFER_SIZE*sizeof(int16_t)); } } } diff --git a/srslte/lib/fec/src/turbocoder.c b/srslte/lib/fec/src/turbocoder.c index 5456c6ad4..ddf507dea 100644 --- a/srslte/lib/fec/src/turbocoder.c +++ b/srslte/lib/fec/src/turbocoder.c @@ -43,7 +43,7 @@ uint8_t tcod_lut_next_state[188][8][256]; uint8_t tcod_lut_output[188][8][256]; -uint32_t tcod_per_fw[188][6144]; +uint16_t tcod_per_fw[188][6144]; static bool table_initiated = false; @@ -74,7 +74,7 @@ int srslte_tcod_encode(srslte_tcod_t *h, uint8_t *input, uint8_t *output, uint32 uint32_t i, k = 0, j; uint8_t bit; uint8_t in, out; - uint32_t *per; + uint16_t *per; if (long_cb > h->max_long_cb) { fprintf(stderr, "Turbo coder initiated for max_long_cb=%d\n", diff --git a/srslte/lib/fec/src/turbodecoder_gen.c b/srslte/lib/fec/src/turbodecoder_gen.c index 610e94794..1896594ff 100644 --- a/srslte/lib/fec/src/turbodecoder_gen.c +++ b/srslte/lib/fec/src/turbodecoder_gen.c @@ -318,6 +318,10 @@ void srslte_tdec_gen_iteration(srslte_tdec_gen_t * h, float * input, uint32_t lo // Run MAP DEC #2 map_gen_dec(&h->dec, h->syst, h->parity, h->llr2, long_cb); + //printf("llr2="); + //srslte_vec_fprint_f(stdout, h->llr2, long_cb); + + // Update a-priori LLR from the last iteration for (i = 0; i < long_cb; i++) { h->w[i] += h->llr2[deinter[i]] - h->llr1[i]; diff --git a/srslte/lib/fec/src/turbodecoder_sse.c b/srslte/lib/fec/src/turbodecoder_sse.c index c99c8afe9..8b240954d 100644 --- a/srslte/lib/fec/src/turbodecoder_sse.c +++ b/srslte/lib/fec/src/turbodecoder_sse.c @@ -125,7 +125,7 @@ void srslte_map_gen_beta(srslte_map_gen_t * s, int16_t * output, uint32_t long_c BETA_STEP(g); } - + __m128i norm; for (; k >= 0; k-=8) { gv = _mm_load_si128(gPtr); gPtr--; @@ -133,13 +133,15 @@ void srslte_map_gen_beta(srslte_map_gen_t * s, int16_t * output, uint32_t long_c BETA_STEP_CNT(1,1); BETA_STEP_CNT(2,2); BETA_STEP_CNT(3,3); + norm = _mm_shuffle_epi8(beta_k, shuf_norm); + beta_k = _mm_sub_epi16(beta_k, norm); gv = _mm_load_si128(gPtr); gPtr--; BETA_STEP_CNT(0,4); BETA_STEP_CNT(1,5); BETA_STEP_CNT(2,6); BETA_STEP_CNT(3,7); - __m128i norm = _mm_shuffle_epi8(beta_k, shuf_norm); + norm = _mm_shuffle_epi8(beta_k, shuf_norm); beta_k = _mm_sub_epi16(beta_k, norm); } } @@ -203,6 +205,7 @@ void srslte_map_gen_alpha(srslte_map_gen_t * s, uint32_t long_cb) _mm_store_si128(alphaPtr, alpha_k);\ alphaPtr++; \ + __m128i norm; for (k = 0; k < long_cb/8; k++) { gv = _mm_load_si128(gPtr); gPtr++; @@ -210,13 +213,15 @@ void srslte_map_gen_alpha(srslte_map_gen_t * s, uint32_t long_cb) ALPHA_STEP(1); ALPHA_STEP(2); ALPHA_STEP(3); + norm = _mm_shuffle_epi8(alpha_k, shuf_norm); + alpha_k = _mm_sub_epi16(alpha_k, norm); gv = _mm_load_si128(gPtr); gPtr++; ALPHA_STEP(0); ALPHA_STEP(1); ALPHA_STEP(2); ALPHA_STEP(3); - __m128i norm = _mm_shuffle_epi8(alpha_k, shuf_norm); + norm = _mm_shuffle_epi8(alpha_k, shuf_norm); alpha_k = _mm_sub_epi16(alpha_k, norm); } } @@ -569,7 +574,7 @@ void srslte_tdec_sse_decision(srslte_tdec_sse_t * h, uint8_t *output, uint32_t l __m128i *appPtr = (__m128i*) h->app1; __m128i *outPtr = (__m128i*) output; __m128i ap, out, out0, out1; - + for (uint32_t i = 0; i < long_cb/16; i++) { ap = _mm_load_si128(appPtr); appPtr++; out0 = _mm_and_si128(_mm_cmpgt_epi16(ap, zero), lsb_mask); diff --git a/srslte/lib/fec/test/rm_turbo_test.c b/srslte/lib/fec/test/rm_turbo_test.c index 775efa3eb..beae24e8f 100644 --- a/srslte/lib/fec/test/rm_turbo_test.c +++ b/srslte/lib/fec/test/rm_turbo_test.c @@ -165,7 +165,7 @@ int main(int argc, char **argv) { } srslte_bit_unpack_vector(rm_bits2_bytes, rm_bits2, nof_e_bits); - + for (int i=0;isf_idx, rnti, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs, cfg->nbits.nof_re, - cfg->nbits.nof_bits, cfg->rv); + cfg->nbits.nof_bits, cfg->rv, cfg->grant.nof_prb); /* number of layers equals number of ports */ for (i = 0; i < q->cell.nof_ports; i++) { diff --git a/srslte/lib/phch/src/sch.c b/srslte/lib/phch/src/sch.c index f46c2fd9d..8a87b36d1 100644 --- a/srslte/lib/phch/src/sch.c +++ b/srslte/lib/phch/src/sch.c @@ -43,6 +43,8 @@ #include "srslte/utils/debug.h" #include "srslte/utils/vector.h" +#define SRSLTE_PDSCH_MAX_TDEC_ITERS 4 + /* 36.213 Table 8.6.3-1: Mapping of HARQ-ACK offset values and the index signalled by higher layers */ float beta_harq_offset[16] = {2.0, 2.5, 3.125, 4.0, 5.0, 6.250, 8.0, 10.0, 12.625, 15.875, 20.0, 31.0, 50.0, 80.0, 126.0, -1.0}; @@ -322,6 +324,8 @@ static int encode_tb(srslte_sch_t *q, return encode_tb_off(q, soft_buffer, cb_segm, Qm, rv, nof_e_bits, data, e_bits, 0); } + + /* Decode a transport block according to 36.212 5.3.2 * @@ -334,7 +338,7 @@ static int decode_tb(srslte_sch_t *q, uint8_t parity[3] = {0, 0, 0}; uint32_t par_rx, par_tx; uint32_t i; - uint32_t cb_len, rp, wp, rlen, F, n_e; + uint32_t cb_len, rp, wp, rlen, n_e; if (q != NULL && data != NULL && @@ -385,11 +389,6 @@ static int decode_tb(srslte_sch_t *q, } else { rlen = cb_len - 24; } - if (i == 0) { - F = cb_segm->F; - } else { - F = 0; - } if (i <= cb_segm->C - gamma - 1) { n_e = Qm * (Gp/cb_segm->C); @@ -397,9 +396,6 @@ static int decode_tb(srslte_sch_t *q, n_e = Qm * ((uint32_t) ceilf((float) Gp/cb_segm->C)); } - INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, F: %d, E: %d\n", i, - cb_len, rlen - F, wp, rp, F, n_e); - /* 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"); @@ -414,7 +410,6 @@ static int decode_tb(srslte_sch_t *q, /* Turbo Decoding with CRC-based early stopping */ q->nof_iterations = 0; uint32_t len_crc; - uint8_t *cb_in_ptr; srslte_crc_t *crc_ptr; early_stop = false; @@ -426,25 +421,29 @@ static int decode_tb(srslte_sch_t *q, if (cb_segm->C > 1) { len_crc = cb_len; - cb_in_ptr = q->cb_in; crc_ptr = &q->crc_cb; } else { len_crc = cb_segm->tbs+24; - cb_in_ptr = &q->cb_in[F/8]; crc_ptr = &q->crc_tb; } srslte_tdec_sse_decision_byte(&q->decoder, q->cb_in, cb_len); - + + if (i == 9) { + srslte_tdec_sse_decision(&q->decoder, q->temp_data, cb_len); + } /* Check Codeblock CRC and stop early if incorrect */ - if (!srslte_crc_checksum_byte(crc_ptr, cb_in_ptr, len_crc)) { + if (!srslte_crc_checksum_byte(crc_ptr, q->cb_in, len_crc)) { early_stop = true; } - - + } while (q->nof_iterations < SRSLTE_PDSCH_MAX_TDEC_ITERS && !early_stop); q->average_nof_iterations = SRSLTE_VEC_EMA((float) q->nof_iterations, q->average_nof_iterations, 0.2); + INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, E: %d, n_iters=%d\n", i, + cb_len, rlen, wp, rp, n_e, q->nof_iterations); + + if (SRSLTE_VERBOSE_ISDEBUG()) { DEBUG("CB#%d IN: ", i); srslte_vec_fprint_byte(stdout, q->cb_in, cb_len/8); @@ -452,24 +451,17 @@ static int decode_tb(srslte_sch_t *q, // If CB CRC is not correct, early_stop will be false and wont continue with rest of CBs - if (F%8) { - fprintf(stderr, "Fatal Error: Number of filler bits %d is not byte aligned\n", F); - } - /* Copy data to another buffer, removing the Codeblock CRC */ if (i < cb_segm->C - 1) { - memcpy(&data[wp/8], &q->cb_in[F/8], (rlen - F) * sizeof(uint8_t)/8); - } else { - DEBUG("Last CB, appending parity: %d to %d from %d and 24 from %d\n", - rlen - F - 24, wp, F, rlen - 24); - + memcpy(&data[wp/8], q->cb_in, rlen/8 * sizeof(uint8_t)); + } else { /* Append Transport Block parity bits to the last CB */ - memcpy(&data[wp/8], &q->cb_in[F/8], (rlen - F - 24) * sizeof(uint8_t)/8); - memcpy(parity, &q->cb_in[(rlen - 24)/8], 24 * sizeof(uint8_t)/8); + memcpy(&data[wp/8], q->cb_in, (rlen - 24)/8 * sizeof(uint8_t)); + memcpy(parity, &q->cb_in[(rlen - 24)/8], 3 * sizeof(uint8_t)); } /* Set read/write pointers */ - wp += (rlen - F); + wp += rlen; rp += n_e; } diff --git a/srslte/lib/phch/test/dlsch_encode_test_mex.c b/srslte/lib/phch/test/dlsch_encode_test_mex.c index 1ad44b34d..ca84218e5 100644 --- a/srslte/lib/phch/test/dlsch_encode_test_mex.c +++ b/srslte/lib/phch/test/dlsch_encode_test_mex.c @@ -113,15 +113,20 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Error encoding TB\n"); return; } - + uint8_t *e_bits_unpacked = srslte_vec_malloc(cfg.nbits.nof_bits * sizeof(uint8_t)); + if (!e_bits_unpacked) { + return; + } + srslte_bit_unpack_vector(e_bits, e_bits_unpacked, cfg.nbits.nof_bits); if (nlhs >= 1) { - mexutils_write_uint8(e_bits, &plhs[0], cfg.nbits.nof_bits, 1); + mexutils_write_uint8(e_bits_unpacked, &plhs[0], cfg.nbits.nof_bits, 1); } srslte_sch_free(&dlsch); free(trblkin); free(e_bits); + free(e_bits_unpacked); return; } diff --git a/srslte/lib/phch/test/pdsch_test_mex.c b/srslte/lib/phch/test/pdsch_test_mex.c index e81ac90d3..e9a80763c 100644 --- a/srslte/lib/phch/test/pdsch_test_mex.c +++ b/srslte/lib/phch/test/pdsch_test_mex.c @@ -65,6 +65,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) return; } + srslte_verbose = SRSLTE_VERBOSE_INFO; bzero(&cfg, sizeof(srslte_pdsch_cfg_t)); if (mexutils_read_cell(ENBCFG, &cell)) { @@ -196,7 +197,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) if (nrhs > NOF_INPUTS + 1) { noise_power = mxGetScalar(prhs[NOF_INPUTS+1]); } else { - noise_power = srslte_chest_dl_get_noise_estimate(&chest); + noise_power = 0; } uint8_t *data_bytes = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs.tbs/8); @@ -224,7 +225,13 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexutils_write_cf(pdsch.d, &plhs[3], cfg.nbits.nof_re, 1); } if (nlhs >= 5) { - mexutils_write_f(pdsch.e, &plhs[4], cfg.nbits.nof_bits, 1); + mexutils_write_s(pdsch.e, &plhs[4], cfg.nbits.nof_bits, 1); + } + if (nlhs >= 6) { + mexutils_write_s(softbuffer.buffer_f[9], &plhs[5], 16908, 1); + } + if (nlhs >= 7) { + mexutils_write_uint8(pdsch.dl_sch.temp_data, &plhs[6], 5632, 1); } srslte_chest_dl_free(&chest); diff --git a/srslte/lib/phch/test/prach_test_mex.c b/srslte/lib/phch/test/prach_test_mex.c index b2b51d18f..3dab23e9c 100644 --- a/srslte/lib/phch/test/prach_test_mex.c +++ b/srslte/lib/phch/test/prach_test_mex.c @@ -26,6 +26,7 @@ */ #include +#define FORCE_POWER2_FFT #include "srslte/srslte.h" #include "srslte/mex/mexutils.h" diff --git a/srslte/lib/sync/test/pss_file.c b/srslte/lib/sync/test/pss_file.c index 51fbdb839..656a2f6f5 100644 --- a/srslte/lib/sync/test/pss_file.c +++ b/srslte/lib/sync/test/pss_file.c @@ -54,14 +54,16 @@ uint32_t fft_size=64; float threshold = 0.4; int N_id_2_sync = -1; srslte_cp_t cp=SRSLTE_CP_NORM; +int file_offset = 0; void usage(char *prog) { - printf("Usage: %s [nlestdv] -i cell_id -f input_file_name\n", prog); + printf("Usage: %s [nlestodv] -i cell_id -f input_file_name\n", prog); printf("\t-n nof_frames [Default %d]\n", nof_frames); printf("\t-l N_id_2 to sync [Default use cell_id]\n"); printf("\t-e Extended CP [Default Normal]\n", fft_size); printf("\t-s symbol_sz [Default %d]\n", fft_size); printf("\t-t threshold [Default %.2f]\n", threshold); + printf("\t-o file read offset [Default %d]\n", file_offset); #ifndef DISABLE_GRAPHICS printf("\t-d disable plots [Default enabled]\n"); #else @@ -72,7 +74,7 @@ void usage(char *prog) { void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "nlestdvif")) != -1) { + while ((opt = getopt(argc, argv, "nlestdvoif")) != -1) { switch (opt) { case 'f': input_file_name = argv[optind]; @@ -86,6 +88,9 @@ void parse_args(int argc, char **argv) { case 'i': cell_id = atoi(argv[optind]); break; + case 'o': + file_offset = atoi(argv[optind]); + break; case 'l': N_id_2_sync = atoi(argv[optind]); break; @@ -193,6 +198,8 @@ int main(int argc, char **argv) { bzero(&ssync, sizeof(srslte_sync_t)); ssync.fft_size = fft_size; + n = srslte_filesource_read(&fsrc, buffer, file_offset); + while(frame_cnt < nof_frames || nof_frames == -1) { n = srslte_filesource_read(&fsrc, buffer, flen - peak_offset); if (n < 0) { @@ -237,6 +244,7 @@ int main(int argc, char **argv) { if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { sss_error2++; } + printf("sf_idx = %d\n", srslte_sss_synch_subframe(m0, m1)); INFO("Partial N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); srslte_sss_synch_m0m1_diff(&sss, &buffer[sss_idx], &m0, &m0_value, &m1, &m1_value); if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { diff --git a/srslte/lib/ue/src/ue_mib.c b/srslte/lib/ue/src/ue_mib.c index 0e8acd330..f2e7faa94 100644 --- a/srslte/lib/ue/src/ue_mib.c +++ b/srslte/lib/ue/src/ue_mib.c @@ -140,11 +140,13 @@ int srslte_ue_mib_decode(srslte_ue_mib_t * q, cf_t *input, for (int i=0;ice[i][SRSLTE_SLOT_LEN_RE(q->chest.cell.nof_prb, q->chest.cell.cp)]; } - + /* Decode PBCH */ ret = srslte_pbch_decode(&q->pbch, &q->sf_symbols[SRSLTE_SLOT_LEN_RE(q->chest.cell.nof_prb, q->chest.cell.cp)], ce_slot1, 0, bch_payload, nof_tx_ports, sfn_offset); + + if (ret < 0) { fprintf(stderr, "Error decoding PBCH (%d)\n", ret); } else if (ret == 1) { diff --git a/srslte/lib/ue/src/ue_sync.c b/srslte/lib/ue/src/ue_sync.c index bc34a9c78..f08b75a29 100644 --- a/srslte/lib/ue/src/ue_sync.c +++ b/srslte/lib/ue/src/ue_sync.c @@ -46,7 +46,9 @@ cf_t dummy[MAX_TIME_OFFSET]; #define TRACK_FRAME_SIZE 32 #define FIND_NOF_AVG_FRAMES 2 -int srslte_ue_sync_init_file(srslte_ue_sync_t *q, uint32_t nof_prb, char *file_name) { +cf_t kk[1024*1024]; + +int srslte_ue_sync_init_file(srslte_ue_sync_t *q, uint32_t nof_prb, char *file_name, int offset) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && @@ -69,6 +71,9 @@ int srslte_ue_sync_init_file(srslte_ue_sync_t *q, uint32_t nof_prb, char *file_n goto clean_exit; } + INFO("Offseting input file by %d samples\n", offset); + + srslte_filesource_read(&q->file_source, kk, offset); srslte_ue_sync_reset(q); ret = SRSLTE_SUCCESS; diff --git a/srslte/lib/utils/src/bit.c b/srslte/lib/utils/src/bit.c index 5dfe9bf44..67a524eff 100644 --- a/srslte/lib/utils/src/bit.c +++ b/srslte/lib/utils/src/bit.c @@ -34,18 +34,18 @@ #include "srslte/utils/bit.h" -void srslte_bit_interleave(uint8_t *input, uint8_t *output, uint32_t *interleaver, uint32_t nof_bits) { +void srslte_bit_interleave(uint8_t *input, uint8_t *output, uint16_t *interleaver, uint32_t nof_bits) { srslte_bit_interleave_w_offset(input, output, interleaver, nof_bits, 0); } -void srslte_bit_interleave_w_offset(uint8_t *input, uint8_t *output, uint32_t *interleaver, uint32_t nof_bits, uint32_t w_offset) { +void srslte_bit_interleave_w_offset(uint8_t *input, uint8_t *output, uint16_t *interleaver, uint32_t nof_bits, uint32_t w_offset) { uint32_t st=0, w_offset_p=0; static const uint8_t mask[] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 }; if (w_offset < 8 && w_offset > 0) { st=1; for (uint32_t j=0;j<8-w_offset;j++) { - uint32_t i_p = interleaver[j]; + uint16_t i_p = interleaver[j]; if (input[i_p/8] & mask[i_p%8]) { output[0] |= mask[j+w_offset]; } else { @@ -56,14 +56,14 @@ void srslte_bit_interleave_w_offset(uint8_t *input, uint8_t *output, uint32_t *i } for (uint32_t i=st;i