Initial EVM calculation commit and other easthetic changes

master
Xavier Arteaga 5 years ago committed by Xavier Arteaga
parent 4739f3084f
commit f261365c91

@ -250,9 +250,11 @@ typedef enum SRSLTE_API {
SRSLTE_MOD_QPSK, SRSLTE_MOD_QPSK,
SRSLTE_MOD_16QAM, SRSLTE_MOD_16QAM,
SRSLTE_MOD_64QAM, SRSLTE_MOD_64QAM,
SRSLTE_MOD_256QAM, SRSLTE_MOD_256QAM
} srslte_mod_t; } srslte_mod_t;
#define SRSLTE_NOF_MODULATIONS (SRSLTE_MOD_256QAM + 1)
typedef enum { typedef enum {
SRSLTE_DCI_FORMAT0 = 0, SRSLTE_DCI_FORMAT0 = 0,
SRSLTE_DCI_FORMAT1, SRSLTE_DCI_FORMAT1,

@ -36,8 +36,6 @@
#include "modem_table.h" #include "modem_table.h"
#include "srslte/config.h" #include "srslte/config.h"
typedef _Complex float cf_t;
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
srslte_mod_t mod; /* In this implementation, mapping table is hard-coded */ srslte_mod_t mod; /* In this implementation, mapping table is hard-coded */
} srslte_demod_hard_t; } srslte_demod_hard_t;

@ -0,0 +1,247 @@
/*
* Copyright 2013-2019 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef SRSLTE_EVM_H_
#define SRSLTE_EVM_H_
#include <srslte/config.h>
#include <srslte/phy/phch/ra.h>
#include <srslte/phy/utils/debug.h>
/** @struct srslte_evm_buffer_t
* This structure carries the necessary temporary data required for calculating the EVM.
*
* @var max_bits maximum of bits which can support
* @var hard_bits vector that stores hard bits after decision
* @var symbols vector that stores the modulated symbols from the hard bits
*/
typedef struct {
uint32_t max_bits;
uint8_t* hard_bits;
cf_t* symbols;
} srslte_evm_buffer_t;
/**
* Allocates the EVM calculation buffer
* @param nof_prb that provides the maximum number of bits
* @return EVM buffer pointer
*/
static inline srslte_evm_buffer_t* srslte_evm_buffer_alloc(uint32_t nof_prb)
{
srslte_evm_buffer_t* q = (srslte_evm_buffer_t*)srslte_vec_malloc(sizeof(srslte_evm_buffer_t));
// Check allocation result and number of PRB
if (!q || !nof_prb) {
ERROR("Malloc");
return q;
}
// Zero memory the buffer fields
memset(q, 0, sizeof(srslte_evm_buffer_t));
// Set max number of bits
q->max_bits = srslte_ra_tbs_from_idx(SRSLTE_RA_NOF_TBS_IDX - 1, nof_prb);
// Allocate hard bits
q->hard_bits = srslte_vec_u8_malloc(q->max_bits);
if (!q->hard_bits) {
ERROR("Malloc");
return q;
}
// Allocate symbols assuming BPSK
q->symbols = srslte_vec_cf_malloc(q->max_bits);
if (!q->symbols) {
ERROR("Malloc");
return q;
}
return q;
}
/**
* Allocates the EVM calculation buffer
* @param nof_prb that provides the maximum number of bits
* @return EVM buffer pointer
*/
static inline void srslte_evm_buffer_resize(srslte_evm_buffer_t* q, uint32_t nof_prb)
{
// Assert pointer and number of PRB
if (!q || !nof_prb) {
ERROR("Invalid inputs");
return;
}
// Get new number of max bits
uint32_t new_max_bits = srslte_ra_tbs_from_idx(SRSLTE_RA_NOF_TBS_IDX - 1, nof_prb);
// Return if no resize is required
if (q->max_bits >= new_max_bits) {
return;
}
// Update with greater value
q->max_bits = new_max_bits;
// Free hard bits if it was allocated
if (q->hard_bits) {
free(q->hard_bits);
}
// Allocate hard bits again
q->hard_bits = srslte_vec_u8_malloc(q->max_bits);
if (!q->hard_bits) {
ERROR("Malloc");
return;
}
// Free symbols if it was allocated
if (q->symbols) {
free(q->symbols);
}
// Allocate symbols again
q->symbols = srslte_vec_cf_malloc(q->max_bits);
if (!q->symbols) {
ERROR("Malloc");
return;
}
}
/**
* Template for hard decision taking
*/
#define HARD_DECISION(SOFTBITS, HARDBITS, NOF_SOFTBITS) \
do { \
for (uint32_t i = 0, k = 0; k < NOF_SOFTBITS; i++) { \
uint8_t w = 0; \
for (int j = 0; j < 8 && k < NOF_SOFTBITS; j++, k++) { \
w |= (SOFTBITS[k] > 0) ? ((uint32_t)1 << (uint32_t)(7 - j)) : 0; \
} \
HARDBITS[i] = w; \
} \
} while (false)
/**
* Template RMS EVM calculation for different LLR
*/
#define EVM_RUN_TEMPLATE(LLR_T, SUFFIX) \
static inline float srslte_evm_run_##SUFFIX(srslte_evm_buffer_t* q, \
const srslte_modem_table_t* modem_table, \
const cf_t* symbols, \
const LLR_T* llr, \
uint32_t nof_bits) \
{ \
float evm_rms = NAN; \
\
/* Return NAN if EVM buffers, modem table, LLR, symbols or bits missing*/ \
if (!q || !modem_table || !modem_table->nbits_x_symbol || !llr || !symbols || !nof_bits) { \
ERROR("Invalid inputs %p %p %p %p %d\n", q, modem_table, llr, symbols, nof_bits); \
return evm_rms; \
} \
\
/* Limit number of bits to the one supported by the buffer */ \
nof_bits = SRSLTE_MIN(q->max_bits, nof_bits); \
\
/* Calculate number of symbols */ \
uint32_t nsymbols = nof_bits / modem_table->nbits_x_symbol; \
\
/* Hard decision */ \
HARD_DECISION(llr, q->hard_bits, nof_bits); \
\
/* Modulate */ \
srslte_mod_modulate_bytes(modem_table, q->hard_bits, q->symbols, nof_bits); \
\
/* Compute symbol difference */ \
srslte_vec_sub_ccc(symbols, q->symbols, q->symbols, nsymbols); \
\
/* Average squares */ \
float evm_pow = srslte_vec_avg_power_cf(q->symbols, nsymbols); \
\
/* Convert measure to RMS */ \
evm_rms = sqrtf(evm_pow); \
\
return evm_rms; \
}
/** @function srslte_evm_run_f
* Calculates the Root Mean Squared EVM given a modulation table, complex symbols, floating point LLR (soft bits) and
* the number of bits.
*
* @param q is the EVM buffers, need to be preallocated
* @param modem_table points at the modulator table
* @param symbols vector carrying the modulated complex symbols
* @param llr softbits
* @param nof_bits number of bits
* @return the measured RMS EVM if no error occurs, otherwise it returns NAN
*/
EVM_RUN_TEMPLATE(float, f)
/** @function srslte_evm_run_s
* Calculates the Root Mean Squared EVM given a modulation table, complex symbols, fixed integer 16 bit LLR (soft bits)
* and the number of bits.
*
* @param q is the EVM buffers, need to be preallocated
* @param modem_table points at the modulator table
* @param symbols vector carrying the modulated complex symbols
* @param llr softbits
* @param nof_bits number of bits
* @return the measured RMS EVM if no error occurs, otherwise it returns NAN
*/
EVM_RUN_TEMPLATE(int16_t, s)
/** @function srslte_evm_run_b
* Calculates the Root Mean Squared EVM given a modulation table, complex symbols, fixed integer 8 bit LLR (soft bits)
* and the number of bits.
*
* @param q is the EVM buffers, need to be preallocated
* @param modem_table points at the modulator table
* @param symbols vector carrying the modulated complex symbols
* @param llr softbits
* @param nof_bits number of bits
* @return the measured RMS EVM if no error occurs, otherwise it returns NAN
*/
EVM_RUN_TEMPLATE(int8_t, b)
#undef EVM_RUN_TEMPLATE
#undef HARD_DECISION
static inline void srslte_evm_free(srslte_evm_buffer_t* q)
{
// Check EVM buffer object exist
if (q) {
// Check hard bits were allocated
if (q->hard_bits) {
free(q->hard_bits);
}
// Check symbols were allocated
if (q->symbols) {
free(q->symbols);
}
// Free buffer object
free(q);
}
}
#endif // SRSLTE_EVM_H_

@ -23,7 +23,7 @@
* File: mod.h * File: mod.h
* *
* Description: Modulation. * Description: Modulation.
* Supports BPSK, QPSK, 16QAM and 64QAM. * Supports BPSK, QPSK, 16QAM, 64QAM and 256QAM.
* *
* Reference: 3GPP TS 36.211 version 10.0.0 Release 10 Sec. 7.1 * Reference: 3GPP TS 36.211 version 10.0.0 Release 10 Sec. 7.1
*****************************************************************************/ *****************************************************************************/
@ -36,8 +36,9 @@
#include "modem_table.h" #include "modem_table.h"
#include "srslte/config.h" #include "srslte/config.h"
SRSLTE_API int srslte_mod_modulate(srslte_modem_table_t* table, uint8_t* bits, cf_t* symbols, uint32_t nbits); SRSLTE_API int srslte_mod_modulate(const srslte_modem_table_t* table, uint8_t* bits, cf_t* symbols, uint32_t nbits);
SRSLTE_API int srslte_mod_modulate_bytes(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uint32_t nbits); SRSLTE_API int
srslte_mod_modulate_bytes(const srslte_modem_table_t* q, const uint8_t* bits, cf_t* symbols, uint32_t nbits);
#endif // SRSLTE_MOD_H #endif // SRSLTE_MOD_H

@ -62,7 +62,6 @@ typedef struct SRSLTE_API {
bpsk_packed_t* symbol_table_bpsk; bpsk_packed_t* symbol_table_bpsk;
qpsk_packed_t* symbol_table_qpsk; qpsk_packed_t* symbol_table_qpsk;
qam16_packed_t* symbol_table_16qam; qam16_packed_t* symbol_table_16qam;
qam256_packed_t* symbol_table_256qam;
} srslte_modem_table_t; } srslte_modem_table_t;
SRSLTE_API void srslte_modem_table_init(srslte_modem_table_t* q); SRSLTE_API void srslte_modem_table_init(srslte_modem_table_t* q);

@ -36,6 +36,7 @@
#include "srslte/phy/mimo/layermap.h" #include "srslte/phy/mimo/layermap.h"
#include "srslte/phy/mimo/precoding.h" #include "srslte/phy/mimo/precoding.h"
#include "srslte/phy/modem/demod_soft.h" #include "srslte/phy/modem/demod_soft.h"
#include "srslte/phy/modem/evm.h"
#include "srslte/phy/modem/mod.h" #include "srslte/phy/modem/mod.h"
#include "srslte/phy/phch/dci.h" #include "srslte/phy/phch/dci.h"
#include "srslte/phy/phch/pdsch_cfg.h" #include "srslte/phy/phch/pdsch_cfg.h"
@ -72,7 +73,10 @@ typedef struct SRSLTE_API {
float* csi[SRSLTE_MAX_CODEWORDS]; /* Channel Strengh Indicator */ float* csi[SRSLTE_MAX_CODEWORDS]; /* Channel Strengh Indicator */
/* tx & rx objects */ /* tx & rx objects */
srslte_modem_table_t mod[5]; srslte_modem_table_t mod[SRSLTE_NOF_MODULATIONS];
// EVM buffers, one for each codeword (avoid concurrency issue with coworker)
srslte_evm_buffer_t* evm_buffer[SRSLTE_MAX_CODEWORDS];
// This is to generate the scrambling seq for multiple CRNTIs // This is to generate the scrambling seq for multiple CRNTIs
srslte_pdsch_user_t** users; srslte_pdsch_user_t** users;
@ -89,6 +93,7 @@ typedef struct {
uint8_t* payload; uint8_t* payload;
bool crc; bool crc;
float avg_iterations_block; float avg_iterations_block;
float evm;
} srslte_pdsch_res_t; } srslte_pdsch_res_t;
SRSLTE_API int srslte_pdsch_init_ue(srslte_pdsch_t* q, uint32_t max_prb, uint32_t nof_rx_antennas); SRSLTE_API int srslte_pdsch_init_ue(srslte_pdsch_t* q, uint32_t max_prb, uint32_t nof_rx_antennas);

@ -67,9 +67,9 @@ typedef struct SRSLTE_API {
srslte_softbuffer_rx_t* rx[SRSLTE_MAX_CODEWORDS]; srslte_softbuffer_rx_t* rx[SRSLTE_MAX_CODEWORDS];
} softbuffers; } softbuffers;
bool meas_evm_en;
bool meas_time_en; bool meas_time_en;
uint32_t meas_time_value; uint32_t meas_time_value;
} srslte_pdsch_cfg_t; } srslte_pdsch_cfg_t;
#endif // SRSLTE_PDSCH_CFG_H #endif // SRSLTE_PDSCH_CFG_H

@ -75,6 +75,8 @@ typedef struct SRSLTE_API {
enum { SRSLTE_RA_TYPE2_LOC = 0, SRSLTE_RA_TYPE2_DIST = 1 } mode; enum { SRSLTE_RA_TYPE2_LOC = 0, SRSLTE_RA_TYPE2_DIST = 1 } mode;
} srslte_ra_type2_t; } srslte_ra_type2_t;
#define SRSLTE_RA_NOF_TBS_IDX 34
SRSLTE_API uint32_t srslte_ra_type0_P(uint32_t nof_prb); SRSLTE_API uint32_t srslte_ra_type0_P(uint32_t nof_prb);
SRSLTE_API uint32_t srslte_ra_type2_n_vrb_dl(uint32_t nof_prb, bool ngap_is_1); SRSLTE_API uint32_t srslte_ra_type2_n_vrb_dl(uint32_t nof_prb, bool ngap_is_1);

@ -95,13 +95,13 @@ SRSLTE_API void srslte_vec_cf_zero(cf_t* ptr, uint32_t nsamples);
SRSLTE_API void srslte_vec_f_zero(float* ptr, uint32_t nsamples); SRSLTE_API void srslte_vec_f_zero(float* ptr, uint32_t nsamples);
/* print vectors */ /* print vectors */
SRSLTE_API void srslte_vec_fprint_c(FILE* stream, cf_t* x, const uint32_t len); SRSLTE_API void srslte_vec_fprint_c(FILE* stream, const cf_t* x, const uint32_t len);
SRSLTE_API void srslte_vec_fprint_f(FILE* stream, float* x, const uint32_t len); SRSLTE_API void srslte_vec_fprint_f(FILE* stream, const float* x, const uint32_t len);
SRSLTE_API void srslte_vec_fprint_b(FILE* stream, uint8_t* x, const uint32_t len); SRSLTE_API void srslte_vec_fprint_b(FILE* stream, const uint8_t* x, const uint32_t len);
SRSLTE_API void srslte_vec_fprint_bs(FILE* stream, int8_t* x, const uint32_t len); SRSLTE_API void srslte_vec_fprint_bs(FILE* stream, const int8_t* x, const uint32_t len);
SRSLTE_API void srslte_vec_fprint_byte(FILE* stream, uint8_t* x, const uint32_t len); SRSLTE_API void srslte_vec_fprint_byte(FILE* stream, const uint8_t* x, const uint32_t len);
SRSLTE_API void srslte_vec_fprint_i(FILE* stream, int* x, const uint32_t len); SRSLTE_API void srslte_vec_fprint_i(FILE* stream, const int* x, const uint32_t len);
SRSLTE_API void srslte_vec_fprint_s(FILE* stream, short* x, const uint32_t len); SRSLTE_API void srslte_vec_fprint_s(FILE* stream, const int16_t* x, const uint32_t len);
SRSLTE_API void srslte_vec_fprint_hex(FILE* stream, uint8_t* x, const uint32_t len); SRSLTE_API void srslte_vec_fprint_hex(FILE* stream, uint8_t* x, const uint32_t len);
SRSLTE_API void srslte_vec_sprint_hex(char* str, const uint32_t max_str_len, uint8_t* x, const uint32_t len); SRSLTE_API void srslte_vec_sprint_hex(char* str, const uint32_t max_str_len, uint8_t* x, const uint32_t len);

@ -45,7 +45,7 @@ int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t* q, uint32_t nof_prb)
if (q != NULL) { if (q != NULL) {
bzero(q, sizeof(srslte_softbuffer_rx_t)); bzero(q, sizeof(srslte_softbuffer_rx_t));
ret = srslte_ra_tbs_from_idx(33, nof_prb); ret = srslte_ra_tbs_from_idx(SRSLTE_RA_NOF_TBS_IDX - 1, nof_prb);
if (ret != SRSLTE_ERROR) { if (ret != SRSLTE_ERROR) {
q->max_cb = (uint32_t)ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1; q->max_cb = (uint32_t)ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1;
ret = SRSLTE_ERROR; ret = SRSLTE_ERROR;
@ -163,7 +163,7 @@ int srslte_softbuffer_tx_init(srslte_softbuffer_tx_t* q, uint32_t nof_prb)
bzero(q, sizeof(srslte_softbuffer_tx_t)); bzero(q, sizeof(srslte_softbuffer_tx_t));
ret = srslte_ra_tbs_from_idx(33, nof_prb); ret = srslte_ra_tbs_from_idx(SRSLTE_RA_NOF_TBS_IDX - 1, nof_prb);
if (ret != SRSLTE_ERROR) { if (ret != SRSLTE_ERROR) {
q->max_cb = (uint32_t)ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1; q->max_cb = (uint32_t)ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1;

@ -19,7 +19,7 @@
* *
*/ */
typedef _Complex float cf_t; #include <srslte/config.h>
#define BPSK_LEVEL M_SQRT1_2 #define BPSK_LEVEL M_SQRT1_2

@ -30,7 +30,7 @@
/** Low-level API */ /** Low-level API */
int srslte_mod_modulate(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uint32_t nbits) int srslte_mod_modulate(const srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uint32_t nbits)
{ {
uint32_t i, j, idx; uint32_t i, j, idx;
uint8_t* b_ptr = (uint8_t*)bits; uint8_t* b_ptr = (uint8_t*)bits;
@ -47,7 +47,7 @@ int srslte_mod_modulate(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, u
return j; return j;
} }
void mod_bpsk_bytes(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uint32_t nbits) static void mod_bpsk_bytes(const srslte_modem_table_t* q, const uint8_t* bits, cf_t* symbols, uint32_t nbits)
{ {
uint8_t mask_bpsk[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; uint8_t mask_bpsk[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
uint8_t shift_bpsk[8] = {7, 6, 5, 4, 3, 2, 1, 0}; uint8_t shift_bpsk[8] = {7, 6, 5, 4, 3, 2, 1, 0};
@ -60,7 +60,7 @@ void mod_bpsk_bytes(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uint3
} }
} }
void mod_qpsk_bytes(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uint32_t nbits) static void mod_qpsk_bytes(const srslte_modem_table_t* q, const uint8_t* bits, cf_t* symbols, uint32_t nbits)
{ {
uint8_t mask_qpsk[4] = {0xc0, 0x30, 0x0c, 0x03}; uint8_t mask_qpsk[4] = {0xc0, 0x30, 0x0c, 0x03};
uint8_t shift_qpsk[4] = {6, 4, 2, 0}; uint8_t shift_qpsk[4] = {6, 4, 2, 0};
@ -73,7 +73,7 @@ void mod_qpsk_bytes(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uint3
} }
} }
void mod_16qam_bytes(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uint32_t nbits) static void mod_16qam_bytes(const srslte_modem_table_t* q, const uint8_t* bits, cf_t* symbols, uint32_t nbits)
{ {
for (int i = 0; i < nbits / 8; i++) { for (int i = 0; i < nbits / 8; i++) {
memcpy(&symbols[2 * i], &q->symbol_table_16qam[bits[i]], sizeof(qam16_packed_t)); memcpy(&symbols[2 * i], &q->symbol_table_16qam[bits[i]], sizeof(qam16_packed_t));
@ -84,7 +84,7 @@ void mod_16qam_bytes(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uint
} }
} }
void mod_64qam_bytes(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uint32_t nbits) static void mod_64qam_bytes(const srslte_modem_table_t* q, const uint8_t* bits, cf_t* symbols, uint32_t nbits)
{ {
uint8_t in0, in1, in2, in3; uint8_t in0, in1, in2, in3;
uint32_t in80, in81, in82; uint32_t in80, in81, in82;
@ -124,7 +124,7 @@ void mod_64qam_bytes(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uint
} }
} }
void mod_256qam_bytes(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uint32_t nbits) static void mod_256qam_bytes(const srslte_modem_table_t* q, const uint8_t* bits, cf_t* symbols, uint32_t nbits)
{ {
for (int i = 0; i < nbits / 8; i++) { for (int i = 0; i < nbits / 8; i++) {
symbols[i] = q->symbol_table[bits[i]]; symbols[i] = q->symbol_table[bits[i]];
@ -132,12 +132,12 @@ void mod_256qam_bytes(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uin
} }
/* Assumes packet bits as input */ /* Assumes packet bits as input */
int srslte_mod_modulate_bytes(srslte_modem_table_t* q, uint8_t* bits, cf_t* symbols, uint32_t nbits) int srslte_mod_modulate_bytes(const srslte_modem_table_t* q, const uint8_t* bits, cf_t* symbols, uint32_t nbits)
{ {
if (!q->byte_tables_init) { if (!q->byte_tables_init) {
ERROR("Error need to initiated modem tables for packeted bits before calling srslte_mod_modulate_bytes()\n"); ERROR("Error need to initiated modem tables for packeted bits before calling srslte_mod_modulate_bytes()\n");
return -1; return SRSLTE_ERROR;
} }
if (nbits % q->nbits_x_symbol) { if (nbits % q->nbits_x_symbol) {
ERROR("Error modulator expects number of bits (%d) to be multiple of %d\n", nbits, q->nbits_x_symbol); ERROR("Error modulator expects number of bits (%d) to be multiple of %d\n", nbits, q->nbits_x_symbol);
@ -161,7 +161,7 @@ int srslte_mod_modulate_bytes(srslte_modem_table_t* q, uint8_t* bits, cf_t* symb
break; break;
default: default:
ERROR("srslte_mod_modulate_bytes() accepts QPSK/16QAM/64QAM modulations only\n"); ERROR("srslte_mod_modulate_bytes() accepts QPSK/16QAM/64QAM modulations only\n");
return -1; return SRSLTE_ERROR;
} }
return nbits / q->nbits_x_symbol; return nbits / q->nbits_x_symbol;
} }

@ -56,9 +56,6 @@ void srslte_modem_table_free(srslte_modem_table_t* q)
if (q->symbol_table_16qam) { if (q->symbol_table_16qam) {
free(q->symbol_table_16qam); free(q->symbol_table_16qam);
} }
if (q->symbol_table_256qam) {
free(q->symbol_table_256qam);
}
bzero(q, sizeof(srslte_modem_table_t)); bzero(q, sizeof(srslte_modem_table_t));
} }
void srslte_modem_table_reset(srslte_modem_table_t* q) void srslte_modem_table_reset(srslte_modem_table_t* q)

@ -64,7 +64,7 @@ typedef struct {
srslte_sch_t dl_sch; srslte_sch_t dl_sch;
/* Encoder/Decoder data pointers: they must be set before posting start semaphore */ /* Encoder/Decoder data pointers: they must be set before posting start semaphore */
uint8_t* data; srslte_pdsch_res_t* data;
/* Execution status */ /* Execution status */
int ret_status; int ret_status;
@ -254,7 +254,7 @@ static int pdsch_init(srslte_pdsch_t* q, uint32_t max_prb, bool is_ue, uint32_t
INFO("Init PDSCH: %d PRBs, max_symbols: %d\n", max_prb, q->max_re); INFO("Init PDSCH: %d PRBs, max_symbols: %d\n", max_prb, q->max_re);
for (int i = 0; i < 5; i++) { for (int i = 0; i < SRSLTE_NOF_MODULATIONS; i++) {
if (srslte_modem_table_lte(&q->mod[i], modulations[i])) { if (srslte_modem_table_lte(&q->mod[i], modulations[i])) {
goto clean; goto clean;
} }
@ -268,29 +268,38 @@ static int pdsch_init(srslte_pdsch_t* q, uint32_t max_prb, bool is_ue, uint32_t
for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
// Allocate int16_t for reception (LLRs) // Allocate int16_t for reception (LLRs)
q->e[i] = srslte_vec_malloc(sizeof(int16_t) * q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_256QAM)); q->e[i] = srslte_vec_i16_malloc(q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_256QAM));
if (!q->e[i]) { if (!q->e[i]) {
goto clean; goto clean;
} }
q->d[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); q->d[i] = srslte_vec_cf_malloc(q->max_re);
if (!q->d[i]) { if (!q->d[i]) {
goto clean; goto clean;
} }
// If it is the UE, allocate EVM buffer, for only minimum PRB
if (is_ue) {
q->evm_buffer[i] = srslte_evm_buffer_alloc(6);
if (!q->evm_buffer[i]) {
ERROR("Allocating EVM buffer\n");
goto clean;
}
}
} }
for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { for (int i = 0; i < SRSLTE_MAX_PORTS; i++) {
q->x[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); q->x[i] = srslte_vec_cf_malloc(q->max_re);
if (!q->x[i]) { if (!q->x[i]) {
goto clean; goto clean;
} }
q->symbols[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); q->symbols[i] = srslte_vec_cf_malloc(q->max_re);
if (!q->symbols[i]) { if (!q->symbols[i]) {
goto clean; goto clean;
} }
if (q->is_ue) { if (q->is_ue) {
for (int j = 0; j < SRSLTE_MAX_PORTS; j++) { for (int j = 0; j < SRSLTE_MAX_PORTS; j++) {
q->ce[i][j] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); q->ce[i][j] = srslte_vec_cf_malloc(q->max_re);
if (!q->ce[i][j]) { if (!q->ce[i][j]) {
goto clean; goto clean;
} }
@ -310,7 +319,7 @@ static int pdsch_init(srslte_pdsch_t* q, uint32_t max_prb, bool is_ue, uint32_t
for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
if (!q->csi[i]) { if (!q->csi[i]) {
q->csi[i] = srslte_vec_malloc(sizeof(float) * q->max_re * 2); q->csi[i] = srslte_vec_f_malloc(q->max_re * 2);
if (!q->csi[i]) { if (!q->csi[i]) {
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -413,6 +422,10 @@ void srslte_pdsch_free(srslte_pdsch_t* q)
if (q->csi[i]) { if (q->csi[i]) {
free(q->csi[i]); free(q->csi[i]);
} }
if (q->evm_buffer[i]) {
srslte_evm_free(q->evm_buffer[i]);
}
} }
/* Free sch objects */ /* Free sch objects */
@ -448,7 +461,7 @@ void srslte_pdsch_free(srslte_pdsch_t* q)
srslte_sequence_free(&q->tmp_seq); srslte_sequence_free(&q->tmp_seq);
for (int i = 0; i < 5; i++) { for (int i = 0; i < SRSLTE_NOF_MODULATIONS; i++) {
srslte_modem_table_free(&q->mod[i]); srslte_modem_table_free(&q->mod[i]);
} }
@ -463,6 +476,13 @@ int srslte_pdsch_set_cell(srslte_pdsch_t* q, srslte_cell_t cell)
q->cell = cell; q->cell = cell;
q->max_re = q->cell.nof_prb * MAX_PDSCH_RE(q->cell.cp); q->max_re = q->cell.nof_prb * MAX_PDSCH_RE(q->cell.cp);
// Resize EVM buffer, only for UE
if (q->is_ue) {
for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
srslte_evm_buffer_resize(q->evm_buffer[i], cell.nof_prb);
}
}
INFO("PDSCH: Cell config PCI=%d, %d ports, %d PRBs, max_symbols: %d\n", INFO("PDSCH: Cell config PCI=%d, %d ports, %d PRBs, max_symbols: %d\n",
q->cell.id, q->cell.id,
q->cell.nof_ports, q->cell.nof_ports,
@ -740,7 +760,7 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t* q,
srslte_dl_sf_cfg_t* sf, srslte_dl_sf_cfg_t* sf,
srslte_pdsch_cfg_t* cfg, srslte_pdsch_cfg_t* cfg,
srslte_sch_t* dl_sch, srslte_sch_t* dl_sch,
uint8_t* data, srslte_pdsch_res_t* data,
uint32_t tb_idx, uint32_t tb_idx,
bool* ack) bool* ack)
{ {
@ -772,6 +792,23 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t* q,
} else { } else {
srslte_demod_soft_demodulate_s(mcs->mod, q->d[codeword_idx], q->e[codeword_idx], cfg->grant.nof_re); srslte_demod_soft_demodulate_s(mcs->mod, q->d[codeword_idx], q->e[codeword_idx], cfg->grant.nof_re);
} }
if (cfg->meas_evm_en && q->evm_buffer[codeword_idx]) {
if (q->llr_is_8bit) {
data[tb_idx].evm = srslte_evm_run_b(q->evm_buffer[codeword_idx],
&q->mod[mcs->mod],
q->d[codeword_idx],
q->e[codeword_idx],
cfg->grant.tb[tb_idx].nof_bits);
} else {
data[tb_idx].evm = srslte_evm_run_s(q->evm_buffer[codeword_idx],
&q->mod[mcs->mod],
q->d[codeword_idx],
q->e[codeword_idx],
cfg->grant.tb[tb_idx].nof_bits);
}
} else {
data[tb_idx].evm = NAN;
}
/* Select scrambling sequence */ /* Select scrambling sequence */
srslte_sequence_t* seq = srslte_sequence_t* seq =
@ -793,7 +830,7 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t* q,
} }
/* Return */ /* Return */
ret = srslte_dlsch_decode2(dl_sch, cfg, q->e[codeword_idx], data, tb_idx, nof_layers); ret = srslte_dlsch_decode2(dl_sch, cfg, q->e[codeword_idx], data[tb_idx].payload, tb_idx, nof_layers);
if (ret == SRSLTE_SUCCESS) { if (ret == SRSLTE_SUCCESS) {
*ack = true; *ack = true;
@ -957,7 +994,7 @@ int srslte_pdsch_decode(srslte_pdsch_t* q,
h->pdsch_ptr = q; h->pdsch_ptr = q;
h->cfg = cfg; h->cfg = cfg;
h->sf = sf; h->sf = sf;
h->data = data[tb_idx].payload; h->data = &data[tb_idx];
h->tb_idx = tb_idx; h->tb_idx = tb_idx;
h->ack = &data[tb_idx].crc; h->ack = &data[tb_idx].crc;
h->dl_sch.max_iterations = q->dl_sch.max_iterations; h->dl_sch.max_iterations = q->dl_sch.max_iterations;
@ -965,7 +1002,7 @@ int srslte_pdsch_decode(srslte_pdsch_t* q,
sem_post(&h->start); sem_post(&h->start);
} else { } else {
ret = srslte_pdsch_codeword_decode(q, sf, cfg, &q->dl_sch, data[tb_idx].payload, tb_idx, &data[tb_idx].crc); ret = srslte_pdsch_codeword_decode(q, sf, cfg, &q->dl_sch, data, tb_idx, &data[tb_idx].crc);
data[tb_idx].avg_iterations_block = srslte_sch_last_noi(&q->dl_sch); data[tb_idx].avg_iterations_block = srslte_sch_last_noi(&q->dl_sch);
} }
@ -1100,7 +1137,7 @@ int srslte_pdsch_encode(srslte_pdsch_t* q,
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
} }
if (cfg->grant.nof_re > q->max_re || cfg->grant.nof_re > q->max_re) { if (cfg->grant.nof_re > q->max_re) {
ERROR("Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n", ERROR("Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n",
cfg->grant.nof_re, cfg->grant.nof_re,
q->max_re, q->max_re,
@ -1255,6 +1292,21 @@ srslte_pdsch_rx_info(srslte_pdsch_cfg_t* cfg, srslte_pdsch_res_t res[SRSLTE_MAX_
uint32_t len = srslte_print_check(str, str_len, 0, "rnti=0x%x", cfg->rnti); uint32_t len = srslte_print_check(str, str_len, 0, "rnti=0x%x", cfg->rnti);
len += srslte_pdsch_grant_rx_info(&cfg->grant, res, &str[len], str_len - len); len += srslte_pdsch_grant_rx_info(&cfg->grant, res, &str[len], str_len - len);
if (cfg->meas_evm_en) {
len = srslte_print_check(str, str_len, len, ", evm={", 0);
for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
if (cfg->grant.tb[i].enabled && !isnan(res[i].evm)) {
len = srslte_print_check(str, str_len, len, "%.2f", res[i].evm);
if (i < SRSLTE_MAX_CODEWORDS - 1) {
if (cfg->grant.tb[i + 1].enabled) {
len = srslte_print_check(str, str_len, len, "/", 0);
}
}
}
}
len = srslte_print_check(str, str_len, len, "}", 0);
}
if (cfg->meas_time_en) { if (cfg->meas_time_en) {
len = srslte_print_check(str, str_len, len, ", t=%d us\n", cfg->meas_time_value); len = srslte_print_check(str, str_len, len, ", t=%d us\n", cfg->meas_time_value);
} }

@ -33,8 +33,6 @@
#include "tbs_tables.h" #include "tbs_tables.h"
#define min(a, b) (a < b ? a : b)
/* Convert Type2 scheduling L_crb and RB_start to RIV value */ /* Convert Type2 scheduling L_crb and RB_start to RIV value */
uint32_t srslte_ra_type2_to_riv(uint32_t L_crb, uint32_t RB_start, uint32_t nof_prb) uint32_t srslte_ra_type2_to_riv(uint32_t L_crb, uint32_t RB_start, uint32_t nof_prb)
{ {
@ -201,7 +199,7 @@ int srslte_ra_mcs_from_tbs_idx(uint32_t tbs_idx, bool is_ul)
/* Table 7.1.7.2.1-1: Transport block size table on 36.213 */ /* Table 7.1.7.2.1-1: Transport block size table on 36.213 */
int srslte_ra_tbs_from_idx(uint32_t tbs_idx, uint32_t n_prb) int srslte_ra_tbs_from_idx(uint32_t tbs_idx, uint32_t n_prb)
{ {
if (tbs_idx < 34 && n_prb > 0 && n_prb <= SRSLTE_MAX_PRB) { if (tbs_idx < SRSLTE_RA_NOF_TBS_IDX && n_prb > 0 && n_prb <= SRSLTE_MAX_PRB) {
return tbs_table[tbs_idx][n_prb - 1]; return tbs_table[tbs_idx][n_prb - 1];
} else { } else {
return SRSLTE_ERROR; return SRSLTE_ERROR;

@ -32,7 +32,7 @@ static const int ul_mcs_tbs_idx_table[29] = {0, 1, 2, 3, 4, 5, 6, 7, 8,
14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26}; 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26};
/* Transport Block Size from 3GPP TS 36.213 v12.13.0 table 7.1.7.2.1-1 */ /* Transport Block Size from 3GPP TS 36.213 v12.13.0 table 7.1.7.2.1-1 */
static const int tbs_table[34][110] = { static const int tbs_table[SRSLTE_RA_NOF_TBS_IDX][110] = {
/* The matrix below is automatically generated from ETSI TS 136 213 V12.13.0 (2019-03) */ /* The matrix below is automatically generated from ETSI TS 136 213 V12.13.0 (2019-03) */
{16, 32, 56, 88, 120, 152, 176, 208, 224, 256, 288, 328, 344, 376, 392, 424, 456, 488, 504, {16, 32, 56, 88, 120, 152, 176, 208, 224, 256, 288, 328, 344, 376, 392, 424, 456, 488, 504,
536, 568, 600, 616, 648, 680, 712, 744, 776, 776, 808, 840, 872, 904, 936, 968, 1000, 1032, 1032, 536, 568, 600, 616, 648, 680, 712, 744, 776, 776, 808, 840, 872, 904, 936, 968, 1000, 1032, 1032,

@ -200,7 +200,7 @@ void* srslte_vec_realloc(void* ptr, uint32_t old_size, uint32_t new_size)
#endif #endif
} }
void srslte_vec_fprint_c(FILE* stream, cf_t* x, const uint32_t len) void srslte_vec_fprint_c(FILE* stream, const cf_t* x, const uint32_t len)
{ {
int i; int i;
fprintf(stream, "["); fprintf(stream, "[");
@ -210,7 +210,7 @@ void srslte_vec_fprint_c(FILE* stream, cf_t* x, const uint32_t len)
fprintf(stream, "];\n"); fprintf(stream, "];\n");
} }
void srslte_vec_fprint_f(FILE* stream, float* x, const uint32_t len) void srslte_vec_fprint_f(FILE* stream, const float* x, const uint32_t len)
{ {
int i; int i;
fprintf(stream, "["); fprintf(stream, "[");
@ -220,7 +220,7 @@ void srslte_vec_fprint_f(FILE* stream, float* x, const uint32_t len)
fprintf(stream, "];\n"); fprintf(stream, "];\n");
} }
void srslte_vec_fprint_b(FILE* stream, uint8_t* x, const uint32_t len) void srslte_vec_fprint_b(FILE* stream, const uint8_t* x, const uint32_t len)
{ {
int i; int i;
fprintf(stream, "["); fprintf(stream, "[");
@ -230,7 +230,7 @@ void srslte_vec_fprint_b(FILE* stream, uint8_t* x, const uint32_t len)
fprintf(stream, "];\n"); fprintf(stream, "];\n");
} }
void srslte_vec_fprint_bs(FILE* stream, int8_t* x, const uint32_t len) void srslte_vec_fprint_bs(FILE* stream, const int8_t* x, const uint32_t len)
{ {
int i; int i;
fprintf(stream, "["); fprintf(stream, "[");
@ -240,7 +240,7 @@ void srslte_vec_fprint_bs(FILE* stream, int8_t* x, const uint32_t len)
fprintf(stream, "];\n"); fprintf(stream, "];\n");
} }
void srslte_vec_fprint_byte(FILE* stream, uint8_t* x, const uint32_t len) void srslte_vec_fprint_byte(FILE* stream, const uint8_t* x, const uint32_t len)
{ {
int i; int i;
fprintf(stream, "["); fprintf(stream, "[");
@ -250,7 +250,7 @@ void srslte_vec_fprint_byte(FILE* stream, uint8_t* x, const uint32_t len)
fprintf(stream, "];\n"); fprintf(stream, "];\n");
} }
void srslte_vec_fprint_i(FILE* stream, int* x, const uint32_t len) void srslte_vec_fprint_i(FILE* stream, const int* x, const uint32_t len)
{ {
int i; int i;
fprintf(stream, "["); fprintf(stream, "[");
@ -260,7 +260,7 @@ void srslte_vec_fprint_i(FILE* stream, int* x, const uint32_t len)
fprintf(stream, "];\n"); fprintf(stream, "];\n");
} }
void srslte_vec_fprint_s(FILE* stream, short* x, const uint32_t len) void srslte_vec_fprint_s(FILE* stream, const int16_t* x, const uint32_t len)
{ {
int i; int i;
fprintf(stream, "["); fprintf(stream, "[");

@ -140,9 +140,6 @@ void parse_args(int argc, char** argv)
} }
} }
int prbset_num = 1, last_prbset_num = 1;
int prbset_orig = 0;
int work_enb(srslte_enb_dl_t* enb_dl, int work_enb(srslte_enb_dl_t* enb_dl,
srslte_dl_sf_cfg_t* dl_sf, srslte_dl_sf_cfg_t* dl_sf,
srslte_dci_cfg_t* dci_cfg, srslte_dci_cfg_t* dci_cfg,
@ -203,16 +200,16 @@ int work_ue(srslte_ue_dl_t* ue_dl,
{ {
if (srslte_ue_dl_decode_fft_estimate(ue_dl, sf_cfg_dl, ue_dl_cfg) < 0) { if (srslte_ue_dl_decode_fft_estimate(ue_dl, sf_cfg_dl, ue_dl_cfg) < 0) {
ERROR("Getting PDCCH FFT estimate sf_idx=%d\n", sf_idx); ERROR("Getting PDCCH FFT estimate sf_idx=%d\n", sf_idx);
return -1; return SRSLTE_ERROR;
} }
int nof_grants = srslte_ue_dl_find_dl_dci(ue_dl, sf_cfg_dl, ue_dl_cfg, rnti, dci_dl); int nof_grants = srslte_ue_dl_find_dl_dci(ue_dl, sf_cfg_dl, ue_dl_cfg, rnti, dci_dl);
if (nof_grants < 0) { if (nof_grants < 0) {
ERROR("Looking for DL grants sf_idx=%d\n", sf_idx); ERROR("Looking for DL grants sf_idx=%d\n", sf_idx);
return -1; return SRSLTE_ERROR;
} else if (nof_grants == 0) { } else if (nof_grants == 0) {
ERROR("Failed to find DCI in sf_idx=%d\n", sf_idx); ERROR("Failed to find DCI in sf_idx=%d\n", sf_idx);
return -1; return SRSLTE_ERROR;
} }
// Enable power allocation // Enable power allocation
@ -221,15 +218,18 @@ int work_ue(srslte_ue_dl_t* ue_dl,
ue_dl_cfg->cfg.pdsch.p_b = (transmission_mode > SRSLTE_TM1) ? 1 : 0; // 0 dB ue_dl_cfg->cfg.pdsch.p_b = (transmission_mode > SRSLTE_TM1) ? 1 : 0; // 0 dB
ue_dl_cfg->cfg.pdsch.rnti = dci_dl->rnti; ue_dl_cfg->cfg.pdsch.rnti = dci_dl->rnti;
ue_dl_cfg->cfg.pdsch.csi_enable = false; ue_dl_cfg->cfg.pdsch.csi_enable = false;
ue_dl_cfg->cfg.pdsch.meas_evm_en = true;
if (srslte_verbose >= SRSLTE_VERBOSE_INFO) {
char str[512]; char str[512];
srslte_dci_dl_info(&dci_dl[0], str, 512); srslte_dci_dl_info(&dci_dl[0], str, 512);
INFO("UE PDCCH: rnti=0x%x, %s\n", rnti, str); INFO("UE PDCCH: rnti=0x%x, %s\n", rnti, str);
}
if (srslte_ra_dl_dci_to_grant( if (srslte_ra_dl_dci_to_grant(
&cell, sf_cfg_dl, transmission_mode, enable_256qam, &dci_dl[0], &ue_dl_cfg->cfg.pdsch.grant)) { &cell, sf_cfg_dl, transmission_mode, enable_256qam, &dci_dl[0], &ue_dl_cfg->cfg.pdsch.grant)) {
ERROR("Computing DL grant sf_idx=%d\n", sf_idx); ERROR("Computing DL grant sf_idx=%d\n", sf_idx);
return -1; return SRSLTE_ERROR;
} }
// Reset softbuffer // Reset softbuffer
@ -241,34 +241,16 @@ int work_ue(srslte_ue_dl_t* ue_dl,
if (srslte_ue_dl_decode_pdsch(ue_dl, sf_cfg_dl, &ue_dl_cfg->cfg.pdsch, pdsch_res)) { if (srslte_ue_dl_decode_pdsch(ue_dl, sf_cfg_dl, &ue_dl_cfg->cfg.pdsch, pdsch_res)) {
ERROR("ERROR: Decoding PDSCH sf_idx=%d\n", sf_idx); ERROR("ERROR: Decoding PDSCH sf_idx=%d\n", sf_idx);
return -1; return SRSLTE_ERROR;
} }
srslte_pdsch_tx_info(&ue_dl_cfg->cfg.pdsch, str, 512); if (srslte_verbose >= SRSLTE_VERBOSE_INFO) {
INFO("UE PDSCH: rnti=0x%x, %s\n", rnti, str); char str[512];
srslte_pdsch_rx_info(&ue_dl_cfg->cfg.pdsch, pdsch_res, str, 512);
return 0; INFO("eNb PDSCH: rnti=0x%x, %s\n", rnti, str);
}
unsigned int reverse(register unsigned int x)
{
x = (((x & (uint32_t)0xaaaaaaaa) >> (uint32_t)1) | ((x & (uint32_t)0x55555555) << (uint32_t)1));
x = (((x & (uint32_t)0xcccccccc) >> (uint32_t)2) | ((x & (uint32_t)0x33333333) << (uint32_t)2));
x = (((x & (uint32_t)0xf0f0f0f0) >> (uint32_t)4) | ((x & (uint32_t)0x0f0f0f0f) << (uint32_t)4));
x = (((x & (uint32_t)0xff00ff00) >> (uint32_t)8) | ((x & (uint32_t)0x00ff00ff) << (uint32_t)8));
return ((x >> (uint32_t)16) | (x << (uint32_t)16));
}
uint32_t prbset_to_bitmask()
{
uint32_t mask = 0;
uint32_t nb = (uint32_t)ceilf((float)cell.nof_prb / srslte_ra_type0_P(cell.nof_prb));
for (uint32_t i = 0; i < nb; i++) {
if (i >= prbset_orig && i < prbset_orig + prbset_num) {
mask = mask | ((uint32_t)0x1 << i);
}
} }
return reverse(mask) >> (uint32_t)(32 - nb);
return SRSLTE_SUCCESS;
} }
static int static int
@ -448,8 +430,8 @@ int main(int argc, char** argv)
/* /*
* DCI Configuration * DCI Configuration
*/ */
srslte_dci_dl_t dci; srslte_dci_dl_t dci = {};
srslte_dci_cfg_t dci_cfg; srslte_dci_cfg_t dci_cfg = {};
dci_cfg.srs_request_enabled = false; dci_cfg.srs_request_enabled = false;
dci_cfg.ra_format_enabled = false; dci_cfg.ra_format_enabled = false;
dci_cfg.multiple_csi_request_enabled = false; dci_cfg.multiple_csi_request_enabled = false;
@ -480,14 +462,19 @@ int main(int argc, char** argv)
} }
// Set PRB Allocation type // Set PRB Allocation type
#if 0
dci.alloc_type = SRSLTE_RA_ALLOC_TYPE2;
uint32_t n_prb = 1; ///< Number of PRB
uint32_t s_prb = 0; ///< Start
dci.type2_alloc.riv = srslte_ra_type2_to_riv(n_prb, s_prb, cell.nof_prb);
#else
dci.alloc_type = SRSLTE_RA_ALLOC_TYPE0; dci.alloc_type = SRSLTE_RA_ALLOC_TYPE0;
prbset_num = (int)ceilf((float)cell.nof_prb / srslte_ra_type0_P(cell.nof_prb)); dci.type0_alloc.rbg_bitmask = 0xffffffff; // All PRB
last_prbset_num = prbset_num; #endif
dci.type0_alloc.rbg_bitmask = prbset_to_bitmask();
// Set TB // Set TB
if (transmission_mode < SRSLTE_TM3) { if (transmission_mode < SRSLTE_TM3) {
dci.format = SRSLTE_DCI_FORMAT1; dci.format = (dci.alloc_type == SRSLTE_RA_ALLOC_TYPE2) ? SRSLTE_DCI_FORMAT1A : SRSLTE_DCI_FORMAT1;
dci.tb[0].mcs_idx = mcs; dci.tb[0].mcs_idx = mcs;
dci.tb[0].rv = 0; dci.tb[0].rv = 0;
dci.tb[0].ndi = 0; dci.tb[0].ndi = 0;
@ -530,7 +517,7 @@ int main(int argc, char** argv)
/* /*
* Run eNodeB * Run eNodeB
*/ */
srslte_dl_sf_cfg_t sf_cfg_dl; srslte_dl_sf_cfg_t sf_cfg_dl = {};
sf_cfg_dl.tti = sf_idx % 10; sf_cfg_dl.tti = sf_idx % 10;
sf_cfg_dl.cfi = cfi; sf_cfg_dl.cfi = cfi;
sf_cfg_dl.sf_type = SRSLTE_SF_NORM; sf_cfg_dl.sf_type = SRSLTE_SF_NORM;

Loading…
Cancel
Save