Unified low-PAPR Ruv sequence generation

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent aa8b69e9a7
commit 732a220d42

@ -59,12 +59,6 @@ typedef struct SRSLTE_API {
// Group Hopping Flag
uint32_t* f_gh_pattern;
int32_t q[SRSLTE_SL_MAX_DMRS_SYMB];
float* r[SRSLTE_SL_MAX_DMRS_SYMB];
cf_t* r_uv[SRSLTE_SL_MAX_DMRS_SYMB];
cf_t* r_sequence[SRSLTE_SL_MAX_DMRS_SYMB][SRSLTE_SL_MAX_PSCCH_NOF_DMRS_CYCLIC_SHIFTS];
cf_t* r_sequence_rx[SRSLTE_SL_MAX_DMRS_SYMB];

@ -26,8 +26,6 @@
#include "srslte/phy/phch/pucch_cfg.h"
#include "srslte/phy/phch/pusch_cfg.h"
#include "srslte/phy/ch_estimation/ul_rs_tables.h"
#define SRSLTE_NOF_GROUPS_U 30
#define SRSLTE_NOF_SEQUENCES_U 2
#define SRSLTE_NOF_DELTA_SS 30
@ -66,8 +64,6 @@ typedef struct SRSLTE_API {
typedef struct SRSLTE_API {
srslte_cell_t cell;
float* tmp_arg;
uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB];
uint32_t n_prs_pusch[SRSLTE_NOF_DELTA_SS][SRSLTE_NSLOTS_X_FRAME]; // We precompute n_prs needed for cyclic shift alpha
// at srslte_refsignal_dl_init()
@ -85,14 +81,8 @@ typedef struct {
cf_t* r[SRSLTE_NOF_SF_X_FRAME];
} srslte_refsignal_srs_pregen_t;
SRSLTE_API int srslte_refsignal_ul_init(srslte_refsignal_ul_t* q, uint32_t max_prb);
SRSLTE_API int srslte_refsignal_ul_set_cell(srslte_refsignal_ul_t* q, srslte_cell_t cell);
SRSLTE_API void srslte_refsignal_ul_free(srslte_refsignal_ul_t* q);
SRSLTE_API void srslte_refsignal_r_uv_arg_1prb(float* arg, uint32_t u);
SRSLTE_API uint32_t srslte_refsignal_dmrs_N_rs(srslte_pucch_format_t format, srslte_cp_t cp);
SRSLTE_API uint32_t srslte_refsignal_dmrs_pucch_symbol(uint32_t m, srslte_pucch_format_t format, srslte_cp_t cp);
@ -191,6 +181,4 @@ SRSLTE_API uint32_t srslte_refsignal_srs_rb_L_cs(uint32_t bw_cfg, uint32_t nof_p
SRSLTE_API uint32_t srslte_refsignal_srs_M_sc(srslte_refsignal_ul_t* q, srslte_refsignal_srs_cfg_t* cfg);
SRSLTE_API uint32_t srslte_refsignal_get_q(uint32_t u, uint32_t v, uint32_t N_sz);
#endif // SRSLTE_REFSIGNAL_UL_H

@ -1,69 +0,0 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2020 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#ifndef SRSLTE_UL_RS_TABLES_H
#define SRSLTE_UL_RS_TABLES_H
#include <stdint.h>
// Phi values for M_sc=12 Table 5.5.1.2-1 in 36.211
static const int phi_M_sc_12[30][12] = {
{-1, 1, 3, -3, 3, 3, 1, 1, 3, 1, -3, 3}, {1, 1, 3, 3, 3, -1, 1, -3, -3, 1, -3, 3},
{1, 1, -3, -3, -3, -1, -3, -3, 1, -3, 1, -1}, {-1, 1, 1, 1, 1, -1, -3, -3, 1, -3, 3, -1},
{-1, 3, 1, -1, 1, -1, -3, -1, 1, -1, 1, 3}, {1, -3, 3, -1, -1, 1, 1, -1, -1, 3, -3, 1},
{-1, 3, -3, -3, -3, 3, 1, -1, 3, 3, -3, 1}, {-3, -1, -1, -1, 1, -3, 3, -1, 1, -3, 3, 1},
{1, -3, 3, 1, -1, -1, -1, 1, 1, 3, -1, 1}, {1, -3, -1, 3, 3, -1, -3, 1, 1, 1, 1, 1},
{-1, 3, -1, 1, 1, -3, -3, -1, -3, -3, 3, -1}, {3, 1, -1, -1, 3, 3, -3, 1, 3, 1, 3, 3},
{1, -3, 1, 1, -3, 1, 1, 1, -3, -3, -3, 1}, {3, 3, -3, 3, -3, 1, 1, 3, -1, -3, 3, 3},
{-3, 1, -1, -3, -1, 3, 1, 3, 3, 3, -1, 1}, {3, -1, 1, -3, -1, -1, 1, 1, 3, 1, -1, -3},
{1, 3, 1, -1, 1, 3, 3, 3, -1, -1, 3, -1}, {-3, 1, 1, 3, -3, 3, -3, -3, 3, 1, 3, -1},
{-3, 3, 1, 1, -3, 1, -3, -3, -1, -1, 1, -3}, {-1, 3, 1, 3, 1, -1, -1, 3, -3, -1, -3, -1},
{-1, -3, 1, 1, 1, 1, 3, 1, -1, 1, -3, -1}, {-1, 3, -1, 1, -3, -3, -3, -3, -3, 1, -1, -3},
{1, 1, -3, -3, -3, -3, -1, 3, -3, 1, -3, 3}, {1, 1, -1, -3, -1, -3, 1, -1, 1, 3, -1, 1},
{1, 1, 3, 1, 3, 3, -1, 1, -1, -3, -3, 1}, {1, -3, 3, 3, 1, 3, 3, 1, -3, -1, -1, 3},
{1, 3, -3, -3, 3, -3, 1, -1, -1, 3, -1, -3}, {-3, -1, -3, -1, -3, 3, 1, -1, 1, 3, -3, -3},
{-1, 3, -3, 3, -1, 3, 3, -3, 3, 3, -1, -1}, {3, -3, -3, -1, -1, -3, -1, 3, -3, 3, 1, -1}};
// Phi values for M_sc=24 Table 5.5.1.2-2 in 36.211
static const int phi_M_sc_24[30][24] = {
{-1, 3, 1, -3, 3, -1, 1, 3, -3, 3, 1, 3, -3, 3, 1, 1, -1, 1, 3, -3, 3, -3, -1, -3},
{-3, 3, -3, -3, -3, 1, -3, -3, 3, -1, 1, 1, 1, 3, 1, -1, 3, -3, -3, 1, 3, 1, 1, -3},
{3, -1, 3, 3, 1, 1, -3, 3, 3, 3, 3, 1, -1, 3, -1, 1, 1, -1, -3, -1, -1, 1, 3, 3},
{-1, -3, 1, 1, 3, -3, 1, 1, -3, -1, -1, 1, 3, 1, 3, 1, -1, 3, 1, 1, -3, -1, -3, -1},
{-1, -1, -1, -3, -3, -1, 1, 1, 3, 3, -1, 3, -1, 1, -1, -3, 1, -1, -3, -3, 1, -3, -1, -1},
{-3, 1, 1, 3, -1, 1, 3, 1, -3, 1, -3, 1, 1, -1, -1, 3, -1, -3, 3, -3, -3, -3, 1, 1},
{1, 1, -1, -1, 3, -3, -3, 3, -3, 1, -1, -1, 1, -1, 1, 1, -1, -3, -1, 1, -1, 3, -1, -3},
{-3, 3, 3, -1, -1, -3, -1, 3, 1, 3, 1, 3, 1, 1, -1, 3, 1, -1, 1, 3, -3, -1, -1, 1},
{-3, 1, 3, -3, 1, -1, -3, 3, -3, 3, -1, -1, -1, -1, 1, -3, -3, -3, 1, -3, -3, -3, 1, -3},
{1, 1, -3, 3, 3, -1, -3, -1, 3, -3, 3, 3, 3, -1, 1, 1, -3, 1, -1, 1, 1, -3, 1, 1},
{-1, 1, -3, -3, 3, -1, 3, -1, -1, -3, -3, -3, -1, -3, -3, 1, -1, 1, 3, 3, -1, 1, -1, 3},
{1, 3, 3, -3, -3, 1, 3, 1, -1, -3, -3, -3, 3, 3, -3, 3, 3, -1, -3, 3, -1, 1, -3, 1},
{1, 3, 3, 1, 1, 1, -1, -1, 1, -3, 3, -1, 1, 1, -3, 3, 3, -1, -3, 3, -3, -1, -3, -1},
{3, -1, -1, -1, -1, -3, -1, 3, 3, 1, -1, 1, 3, 3, 3, -1, 1, 1, -3, 1, 3, -1, -3, 3},
{-3, -3, 3, 1, 3, 1, -3, 3, 1, 3, 1, 1, 3, 3, -1, -1, -3, 1, -3, -1, 3, 1, 1, 3},
{-1, -1, 1, -3, 1, 3, -3, 1, -1, -3, -1, 3, 1, 3, 1, -1, -3, -3, -1, -1, -3, -3, -3, -1},
{-1, -3, 3, -1, -1, -1, -1, 1, 1, -3, 3, 1, 3, 3, 1, -1, 1, -3, 1, -3, 1, 1, -3, -1},
{1, 3, -1, 3, 3, -1, -3, 1, -1, -3, 3, 3, 3, -1, 1, 1, 3, -1, -3, -1, 3, -1, -1, -1},
{1, 1, 1, 1, 1, -1, 3, -1, -3, 1, 1, 3, -3, 1, -3, -1, 1, 1, -3, -3, 3, 1, 1, -3},
{1, 3, 3, 1, -1, -3, 3, -1, 3, 3, 3, -3, 1, -1, 1, -1, -3, -1, 1, 3, -1, 3, -3, -3},
{-1, -3, 3, -3, -3, -3, -1, -1, -3, -1, -3, 3, 1, 3, -3, -1, 3, -1, 1, -1, 3, -3, 1, -1},
{-3, -3, 1, 1, -1, 1, -1, 1, -1, 3, 1, -3, -1, 1, -1, 1, -1, -1, 3, 3, -3, -1, 1, -3},
{-3, -1, -3, 3, 1, -1, -3, -1, -3, -3, 3, -3, 3, -3, -1, 1, 3, 1, -3, 1, 3, 3, -1, -3},
{-1, -1, -1, -1, 3, 3, 3, 1, 3, 3, -3, 1, 3, -1, 3, -1, 3, 3, -3, 3, 1, -1, 3, 3},
{1, -1, 3, 3, -1, -3, 3, -3, -1, -1, 3, -1, 3, -1, -1, 1, 1, 1, 1, -1, -1, -3, -1, 3},
{1, -1, 1, -1, 3, -1, 3, 1, 1, -1, -1, -3, 1, 1, -3, 1, 3, -3, 1, 1, -3, -3, -1, -1},
{-3, -1, 1, 3, 1, 1, -3, -1, -1, -3, 3, -3, 3, 1, -3, 3, -3, 1, -1, 1, -3, 1, 1, 1},
{-1, -3, 3, 3, 1, 1, 3, -1, -3, -1, -1, -1, 3, 1, -3, -3, -1, 3, -3, -1, -3, -1, -3, -1},
{-1, -3, -1, -1, 1, -3, -1, -1, 1, -1, -3, 1, 1, -3, 1, -3, -3, 3, 1, 1, -1, 3, -1, -1},
{1, 1, -1, -1, -3, -1, 3, -1, 3, -1, 1, 3, 1, -1, 3, 1, 3, -3, -3, 1, -1, -1, 1, 3}};
#endif

@ -0,0 +1,50 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2020 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#ifndef SRSLTE_ZC_SEQUENCE_H
#define SRSLTE_ZC_SEQUENCE_H
#include "srslte/config.h"
#include <stdbool.h>
#include <stdint.h>
/**
* @brief Generates ZC sequences given the required parameters used in the TS 36 series (LTE)
*
* @remark Implemented as defined in TS 36.211 section 5.5.1 Generation of the reference signal sequence
*
* @param[in] u Group number {0,1,...29}
* @param[in] v Base sequence
* @param[in] alpha Phase shift
* @param[in] nof_prb Number of PRB
* @param[out] sequence Output sequence
* @return SRSLTE_SUCCESS if the generation is successful, SRSLTE_ERROR code otherwise
*/
SRSLTE_API int srslte_zc_sequence_generate_lte(uint32_t u, uint32_t v, float alpha, uint32_t nof_prb, cf_t* sequence);
/**
* @brief Generates ZC sequences given the required parameters used in the TS 38 series (NR)
*
* @remark Implemented as defined in TS 38.211 section 5.2.2 Low-PAPR sequence generation
* @param u Group number {0,1,...29}
* @param v base sequence
* @param alpha Phase shift
* @param m Number of PRB
* @param delta Delta parameter described in specification
* @param sequence Output sequence
* @return SRSLTE_SUCCESS if the generation is successful, SRSLTE_ERROR code otherwise
*/
SRSLTE_API int
srslte_zc_sequence_generate_nr(uint32_t u, uint32_t v, float alpha, uint32_t m, uint32_t delta, cf_t* sequence);
#endif // SRSLTE_ZC_SEQUENCE_H

@ -72,7 +72,6 @@ typedef struct SRSLTE_API {
cf_t d[SRSLTE_PUCCH_MAX_BITS / 2];
uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB];
uint32_t f_gh[SRSLTE_NSLOTS_X_FRAME];
float tmp_arg[SRSLTE_PUCCH_N_SEQ];
cf_t* z;
cf_t* z_tmp;

@ -17,10 +17,9 @@
#include <string.h>
#include "srslte/phy/ch_estimation/chest_sl.h"
#include "srslte/phy/ch_estimation/refsignal_ul.h"
#include "srslte/phy/common/zc_sequence.h"
#include "srslte/phy/mimo/precoding.h"
#include "srslte/phy/utils/debug.h"
#include "srslte/phy/utils/primes.h"
#include "srslte/phy/utils/vector.h"
static int chest_sl_init(srslte_chest_sl_t* q, uint32_t nof_cyclic_shift_seq)
@ -30,18 +29,6 @@ static int chest_sl_init(srslte_chest_sl_t* q, uint32_t nof_cyclic_shift_seq)
srslte_interp_linear_vector_init(&q->lin_vec_sl, SRSLTE_MAX_PRB * SRSLTE_NRE);
for (int i = 0; i < SRSLTE_SL_MAX_DMRS_SYMB; i++) {
q->r[i] = srslte_vec_f_malloc(SRSLTE_MAX_PRB * SRSLTE_NRE);
if (!q->r[i]) {
ERROR("Error allocating memory");
return SRSLTE_ERROR;
}
q->r_uv[i] = srslte_vec_cf_malloc(SRSLTE_MAX_PRB * SRSLTE_NRE);
if (!q->r_uv[i]) {
ERROR("Error allocating memory");
return SRSLTE_ERROR;
}
for (int j = 0; j < nof_cyclic_shift_seq; j++) {
q->r_sequence[i][j] = srslte_vec_cf_malloc(SRSLTE_MAX_PRB * SRSLTE_NRE);
if (!q->r_sequence[i][j]) {
@ -121,28 +108,6 @@ static int chest_sl_psbch_gen(srslte_chest_sl_t* q)
u[ns] = (f_gh + f_ss) % SRSLTE_SL_N_RU_SEQ;
}
int32_t N_zc = srslte_prime_lower_than(q->M_sc_rs); // N_zc - Zadoff Chu Sequence Length
if (N_zc < SRSLTE_SUCCESS) {
ERROR("Could not find prime number\n");
return SRSLTE_ERROR;
}
for (int j = 0; j < q->nof_dmrs_symbols; ++j) {
q->q[j] = srslte_refsignal_get_q(u[j], SRSLTE_SL_BASE_SEQUENCE_NUMBER, N_zc);
float n_sz = (float)N_zc;
for (uint32_t i = 0; i < q->M_sc_rs; i++) {
float m = (float)(i % N_zc);
q->r[j][i] = -M_PI * q->q[j] * m * (m + 1) / n_sz;
}
}
// Do complex exponential and adjust amplitude, 36.211 Section 5.5.1
for (int j = 0; j < q->nof_dmrs_symbols; ++j) {
for (int i = 0; i < q->M_sc_rs; i++) {
q->r_uv[j][i] = cexpf(I * (q->r[j][i] + q->alpha[0] * i));
}
}
// w - Orthogonal Sequence, 36.211 Section 9.8
if (q->cell.tm <= SRSLTE_SIDELINK_TM2) {
if (q->cell.N_sl_id % 2) {
@ -166,9 +131,13 @@ static int chest_sl_psbch_gen(srslte_chest_sl_t* q)
}
for (int j = 0; j < q->nof_dmrs_symbols; j++) {
for (int i = 0; i < q->M_sc_rs; i++) {
q->r_sequence[j][0][i] = q->w[j] * q->r_uv[j][i];
}
cf_t* seq = q->r_sequence[j][0];
// Generate R_uv sequences
srslte_zc_sequence_generate_lte(u[j], SRSLTE_SL_BASE_SEQUENCE_NUMBER, q->alpha[0], q->M_sc_rs / SRSLTE_NRE, seq);
// Apply w
srslte_vec_sc_prod_ccc(seq, q->w[j], seq, q->M_sc_rs);
}
return SRSLTE_SUCCESS;
@ -341,46 +310,6 @@ static int chest_sl_pscch_gen(srslte_chest_sl_t* q, uint32_t cyclic_shift)
u[ns] = (f_gh + f_ss) % SRSLTE_SL_N_RU_SEQ;
}
int32_t N_zc = 0; // N_zc - Zadoff Chu Sequence Length
switch (q->M_sc_rs / SRSLTE_NRE) {
case 1:
for (int j = 0; j < q->nof_dmrs_symbols; ++j) {
for (int i = 0; i < SRSLTE_NRE; i++) {
q->r[j][i] = phi_M_sc_12[u[j]][i] * M_PI / 4;
}
}
break;
case 2:
for (int j = 0; j < q->nof_dmrs_symbols; ++j) {
for (int i = 0; i < q->M_sc_rs; i++) {
q->r[j][i] = phi_M_sc_24[u[j]][i] * M_PI / 4;
}
}
break;
default:
N_zc = srslte_prime_lower_than(q->M_sc_rs); // N_zc - Zadoff Chu Sequence Length
if (N_zc < SRSLTE_SUCCESS) {
ERROR("Could not find prime number\n");
return SRSLTE_ERROR;
}
for (int j = 0; j < q->nof_dmrs_symbols; ++j) {
q->q[j] = srslte_refsignal_get_q(u[j], SRSLTE_SL_BASE_SEQUENCE_NUMBER, N_zc);
float n_sz = (float)N_zc;
for (uint32_t i = 0; i < q->M_sc_rs; i++) {
float m = (float)(i % N_zc);
q->r[j][i] = -M_PI * q->q[j] * m * (m + 1) / n_sz;
}
}
break;
}
// Do complex exponential and adjust amplitude, 36.211 Section 5.5.1
for (int j = 0; j < q->nof_dmrs_symbols; ++j) {
for (int i = 0; i < q->M_sc_rs; i++) {
q->r_uv[j][i] = cexpf(I * (q->r[j][i] + q->alpha[0] * i));
}
}
// w - Orthogonal Sequence, 36.211 Section 9.8
if (q->cell.tm <= SRSLTE_SIDELINK_TM2) {
q->w[0] = 1;
@ -393,9 +322,13 @@ static int chest_sl_pscch_gen(srslte_chest_sl_t* q, uint32_t cyclic_shift)
}
for (int j = 0; j < q->nof_dmrs_symbols; j++) {
for (int i = 0; i < q->M_sc_rs; i++) {
q->r_sequence[j][cyclic_shift / 3][i] = q->w[j] * q->r_uv[j][i];
}
cf_t* seq = q->r_sequence[j][cyclic_shift / 3];
// Generate R_uv sequences
srslte_zc_sequence_generate_lte(u[j], SRSLTE_SL_BASE_SEQUENCE_NUMBER, q->alpha[0], q->M_sc_rs / SRSLTE_NRE, seq);
// Apply w
srslte_vec_sc_prod_ccc(seq, q->w[j], seq, q->M_sc_rs);
}
return SRSLTE_SUCCESS;
@ -567,46 +500,6 @@ static int chest_sl_pssch_gen(srslte_chest_sl_t* q)
}
}
int32_t N_zc = 0; // N_zc - Zadoff Chu Sequence Length
switch (q->M_sc_rs / SRSLTE_NRE) {
case 1:
for (int j = 0; j < q->nof_dmrs_symbols; ++j) {
for (int i = 0; i < SRSLTE_NRE; i++) {
q->r[j][i] = phi_M_sc_12[u[j]][i] * M_PI / 4;
}
}
break;
case 2:
for (int j = 0; j < q->nof_dmrs_symbols; ++j) {
for (int i = 0; i < q->M_sc_rs; i++) {
q->r[j][i] = phi_M_sc_24[u[j]][i] * M_PI / 4;
}
}
break;
default:
N_zc = srslte_prime_lower_than(q->M_sc_rs); // N_zc - Zadoff Chu Sequence Length
if (N_zc < SRSLTE_SUCCESS) {
ERROR("Could not find prime number\n");
return SRSLTE_ERROR;
}
for (int j = 0; j < q->nof_dmrs_symbols; ++j) {
q->q[j] = srslte_refsignal_get_q(u[j], SRSLTE_SL_BASE_SEQUENCE_NUMBER, N_zc);
float n_sz = (float)N_zc;
for (uint32_t i = 0; i < q->M_sc_rs; i++) {
float m = (float)(i % N_zc);
q->r[j][i] = -M_PI * q->q[j] * m * (m + 1) / n_sz;
}
}
break;
}
// Do complex exponential and adjust amplitude, 36.211 Section 5.5.1
for (int j = 0; j < q->nof_dmrs_symbols; ++j) {
for (int i = 0; i < q->M_sc_rs; i++) {
q->r_uv[j][i] = cexpf(I * (q->r[j][i] + q->alpha[0] * i));
}
}
// w - Orthogonal Sequence, 36.211 Section 9.8
if (q->cell.tm <= SRSLTE_SIDELINK_TM2) {
if (q->chest_sl_cfg.N_x_id % 2 == 0) {
@ -632,9 +525,13 @@ static int chest_sl_pssch_gen(srslte_chest_sl_t* q)
}
for (int j = 0; j < q->nof_dmrs_symbols; j++) {
for (int i = 0; i < q->M_sc_rs; i++) {
q->r_sequence[j][0][i] = q->w[j] * q->r_uv[j][i];
}
cf_t* seq = q->r_sequence[j][0];
// Generate R_uv sequences
srslte_zc_sequence_generate_lte(u[j], SRSLTE_SL_BASE_SEQUENCE_NUMBER, q->alpha[0], q->M_sc_rs / SRSLTE_NRE, seq);
// Apply w
srslte_vec_sc_prod_ccc(seq, q->w[j], seq, q->M_sc_rs);
}
return SRSLTE_SUCCESS;
@ -1247,12 +1144,6 @@ void srslte_chest_sl_free(srslte_chest_sl_t* q)
srslte_interp_linear_vector_free(&q->lin_vec_sl);
for (int i = 0; i < SRSLTE_SL_MAX_DMRS_SYMB; i++) {
if (q->r[i]) {
free(q->r[i]);
}
if (q->r_uv[i]) {
free(q->r_uv[i]);
}
for (int j = 0; j < SRSLTE_SL_MAX_PSCCH_NOF_DMRS_CYCLIC_SHIFTS; j++) {
if (q->r_sequence[i][j]) {
free(q->r_sequence[i][j]);

@ -46,12 +46,6 @@ int srslte_chest_ul_init(srslte_chest_ul_t* q, uint32_t max_prb)
if (q != NULL) {
bzero(q, sizeof(srslte_chest_ul_t));
ret = srslte_refsignal_ul_init(&q->dmrs_signal, max_prb);
if (ret != SRSLTE_SUCCESS) {
ERROR("Error initializing CSR signal (%d)\n", ret);
goto clean_exit;
}
q->tmp_noise = srslte_vec_cf_malloc(MAX_REFS_SF);
if (!q->tmp_noise) {
perror("malloc");
@ -110,7 +104,6 @@ void srslte_chest_ul_free(srslte_chest_ul_t* q)
{
srslte_refsignal_dmrs_pusch_pregen_free(&q->dmrs_signal, &q->dmrs_pregen);
srslte_refsignal_ul_free(&q->dmrs_signal);
if (q->tmp_noise) {
free(q->tmp_noise);
}

@ -19,6 +19,7 @@
#include "srslte/phy/ch_estimation/refsignal_ul.h"
#include "srslte/phy/common/phy_common.h"
#include "srslte/phy/common/sequence.h"
#include "srslte/phy/common/zc_sequence.h"
#include "srslte/phy/dft/dft_precoding.h"
#include "srslte/phy/phch/pucch.h"
#include "srslte/phy/utils/debug.h"
@ -106,13 +107,6 @@ static int generate_n_prs(srslte_refsignal_ul_t* q)
return SRSLTE_SUCCESS;
}
void srslte_refsignal_r_uv_arg_1prb(float* arg, uint32_t u)
{
for (int i = 0; i < SRSLTE_NRE; i++) {
arg[i] = phi_M_sc_12[u][i] * M_PI / 4;
}
}
static int generate_srslte_sequence_hopping_v(srslte_refsignal_ul_t* q)
{
srslte_sequence_t seq;
@ -130,44 +124,6 @@ static int generate_srslte_sequence_hopping_v(srslte_refsignal_ul_t* q)
return SRSLTE_SUCCESS;
}
/** Initializes srslte_refsignal_ul_t object according to 3GPP 36.211 5.5
*
*/
int srslte_refsignal_ul_init(srslte_refsignal_ul_t* q, uint32_t max_prb)
{
int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (q != NULL) {
ret = SRSLTE_ERROR;
bzero(q, sizeof(srslte_refsignal_ul_t));
// Allocate temporal buffer for computing signal argument
q->tmp_arg = srslte_vec_f_malloc(SRSLTE_NRE * max_prb);
if (!q->tmp_arg) {
perror("malloc");
goto free_and_exit;
}
ret = SRSLTE_SUCCESS;
}
free_and_exit:
if (ret == SRSLTE_ERROR) {
srslte_refsignal_ul_free(q);
}
return ret;
}
void srslte_refsignal_ul_free(srslte_refsignal_ul_t* q)
{
if (q->tmp_arg) {
free(q->tmp_arg);
}
bzero(q, sizeof(srslte_refsignal_ul_t));
}
/** Initializes srslte_refsignal_ul_t object according to 3GPP 36.211 5.5
*
*/
@ -205,53 +161,6 @@ int srslte_refsignal_ul_set_cell(srslte_refsignal_ul_t* q, srslte_cell_t cell)
return ret;
}
static void arg_r_uv_2prb(float* arg, uint32_t u)
{
for (int i = 0; i < 2 * SRSLTE_NRE; i++) {
arg[i] = phi_M_sc_24[u][i] * M_PI / 4;
}
}
uint32_t srslte_refsignal_get_q(uint32_t u, uint32_t v, uint32_t N_sz)
{
float q;
float q_hat;
float n_sz = (float)N_sz;
q_hat = n_sz * (u + 1) / 31;
if ((((uint32_t)(2 * q_hat)) % 2) == 0) {
q = q_hat + 0.5 + v;
} else {
q = q_hat + 0.5 - v;
}
return (uint32_t)q;
}
static void arg_r_uv_mprb(float* arg, uint32_t M_sc, uint32_t u, uint32_t v)
{
int32_t N_sz = srslte_prime_lower_than(M_sc); // N_zc - Zadoff Chu Sequence Length
if (N_sz > 0) {
float q = srslte_refsignal_get_q(u, v, N_sz);
float n_sz = (float)N_sz;
for (uint32_t i = 0; i < M_sc; i++) {
float m = (float)(i % N_sz);
arg[i] = -M_PI * q * m * (m + 1) / n_sz;
}
}
}
/* Computes argument of r_u_v signal */
static void compute_r_uv_arg(srslte_refsignal_ul_t* q, uint32_t nof_prb, uint32_t u, uint32_t v)
{
if (nof_prb == 1) {
srslte_refsignal_r_uv_arg_1prb(q->tmp_arg, u);
} else if (nof_prb == 2) {
arg_r_uv_2prb(q->tmp_arg, u);
} else {
arg_r_uv_mprb(q->tmp_arg, SRSLTE_NRE * nof_prb, u, v);
}
}
/* Calculates alpha according to 5.5.2.1.1 of 36.211 */
static float pusch_alpha(srslte_refsignal_ul_t* q,
srslte_refsignal_dmrs_pusch_cfg_t* cfg,
@ -312,7 +221,9 @@ static void compute_r(srslte_refsignal_ul_t* q,
srslte_refsignal_dmrs_pusch_cfg_t* cfg,
uint32_t nof_prb,
uint32_t ns,
uint32_t delta_ss)
uint32_t delta_ss,
float alpha,
cf_t* sequence)
{
// Get group hopping number u
uint32_t f_gh = 0;
@ -328,7 +239,7 @@ static void compute_r(srslte_refsignal_ul_t* q,
}
// Compute signal argument
compute_r_uv_arg(q, nof_prb, u, v);
srslte_zc_sequence_generate_lte(u, v, alpha, nof_prb, sequence);
}
int srslte_refsignal_dmrs_pusch_pregen_init(srslte_refsignal_ul_dmrs_pregen_t* pregen, uint32_t max_prb)
@ -429,16 +340,10 @@ int srslte_refsignal_dmrs_pusch_gen(srslte_refsignal_ul_t* q,
ret = SRSLTE_ERROR;
for (uint32_t ns = 2 * sf_idx; ns < 2 * (sf_idx + 1); ns++) {
compute_r(q, cfg, nof_prb, ns, cfg->delta_ss);
// Add cyclic prefix alpha
float alpha = pusch_alpha(q, cfg, cyclic_shift_for_dmrs, ns);
// Do complex exponential and adjust amplitude
for (int i = 0; i < SRSLTE_NRE * nof_prb; i++) {
r_pusch[(ns % 2) * SRSLTE_NRE * nof_prb + i] = cexpf(I * (q->tmp_arg[i] + alpha * i));
}
compute_r(q, cfg, nof_prb, ns, cfg->delta_ss, alpha, &r_pusch[(ns % 2) * SRSLTE_NRE * nof_prb]);
}
ret = 0;
}
@ -543,8 +448,6 @@ int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t* q,
}
uint32_t u = (f_gh + (q->cell.id % 30)) % 30;
srslte_refsignal_r_uv_arg_1prb(q->tmp_arg, u);
for (uint32_t m = 0; m < N_rs; m++) {
uint32_t n_oc = 0;
@ -585,14 +488,15 @@ int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t* q,
ERROR("DMRS Generator: Unsupported format %d\n", cfg->format);
return SRSLTE_ERROR;
}
cf_t z_m = 1.0;
cf_t* r_sequence = &r_pucch[(ns % 2) * SRSLTE_NRE * N_rs + m * SRSLTE_NRE];
srslte_zc_sequence_generate_lte(u, 0, alpha, 1, r_sequence);
cf_t z_m = cexpf(I * w[m]);
if (m == 1) {
z_m = z_m_1;
}
for (uint32_t n = 0; n < SRSLTE_NRE; n++) {
r_pucch[(ns % 2) * SRSLTE_NRE * N_rs + m * SRSLTE_NRE + n] =
z_m * cexpf(I * (w[m] + q->tmp_arg[n] + alpha * n));
z_m *= z_m_1;
}
srslte_vec_sc_prod_ccc(r_sequence, z_m, r_sequence, SRSLTE_NRE);
}
}
ret = SRSLTE_SUCCESS;
@ -972,13 +876,8 @@ int srslte_refsignal_srs_gen(srslte_refsignal_ul_t* q,
uint32_t M_sc = srslte_refsignal_srs_M_sc(q, cfg);
for (uint32_t ns = 2 * sf_idx; ns < 2 * (sf_idx + 1); ns++) {
compute_r(q, pusch_cfg, M_sc / SRSLTE_NRE, ns, 0);
float alpha = 2 * M_PI * cfg->n_srs / 8;
// Do complex exponential and adjust amplitude
for (int i = 0; i < M_sc; i++) {
r_srs[(ns % 2) * M_sc + i] = cexpf(I * (q->tmp_arg[i] + alpha * i));
}
compute_r(q, pusch_cfg, M_sc / SRSLTE_NRE, ns, 0, alpha, &r_srs[(ns % 2) * M_sc]);
}
ret = SRSLTE_SUCCESS;
}

@ -70,11 +70,6 @@ int srs_test_context_init(srs_test_context_t* q)
{
q->sf_size = SRSLTE_SF_LEN_RE(SRSLTE_MAX_PRB, cell.cp);
// Initiate UL ref signals
if (srslte_refsignal_ul_init(&q->refsignal_ul, SRSLTE_MAX_PRB) != SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
// Set cell
if (srslte_refsignal_ul_set_cell(&q->refsignal_ul, cell) != SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
@ -111,7 +106,6 @@ int srs_test_context_init(srs_test_context_t* q)
void srs_test_context_free(srs_test_context_t* q)
{
srslte_refsignal_ul_free(&q->refsignal_ul);
srslte_refsignal_srs_pregen_free(&q->refsignal_ul, &q->srs_pregen);
srslte_chest_ul_free(&q->chest_ul);
srslte_chest_ul_res_free(&q->chest_ul_res);

@ -68,18 +68,13 @@ void parse_args(int argc, char** argv)
int main(int argc, char** argv)
{
srslte_refsignal_ul_t refs;
srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg;
srslte_refsignal_ul_t refs = {};
srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg = {};
cf_t* signal = NULL;
int ret = -1;
parse_args(argc, argv);
if (srslte_refsignal_ul_init(&refs, cell.nof_prb)) {
ERROR("Error initializing UL reference signal\n");
goto do_exit;
}
if (srslte_refsignal_ul_set_cell(&refs, cell)) {
ERROR("Error initializing UL reference signal\n");
goto do_exit;
@ -155,8 +150,6 @@ do_exit:
free(signal);
}
srslte_refsignal_ul_free(&refs);
if (!ret) {
printf("OK\n");
}

@ -6,7 +6,7 @@
# the distribution.
#
set(SOURCES phy_common.c phy_common_sl.c phy_common_nr.c sequence.c timestamp.c)
set(SOURCES phy_common.c phy_common_sl.c phy_common_nr.c sequence.c timestamp.c zc_sequence.c)
add_library(srslte_phy_common OBJECT ${SOURCES})
add_subdirectory(test)

@ -0,0 +1,308 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2020 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#include "srslte/phy/common/zc_sequence.h"
#include "srslte/phy/common/phy_common.h"
#include "srslte/phy/utils/debug.h"
#include "srslte/phy/utils/primes.h"
#include "srslte/phy/utils/vector.h"
#include <complex.h>
// Phi values for M_sc=12 Table 5.5.1.2-1 in TS 36.211
static const float zc_sequence_lte_phi_M_sc_12[30][12] = {
{-1, 1, 3, -3, 3, 3, 1, 1, 3, 1, -3, 3}, {1, 1, 3, 3, 3, -1, 1, -3, -3, 1, -3, 3},
{1, 1, -3, -3, -3, -1, -3, -3, 1, -3, 1, -1}, {-1, 1, 1, 1, 1, -1, -3, -3, 1, -3, 3, -1},
{-1, 3, 1, -1, 1, -1, -3, -1, 1, -1, 1, 3}, {1, -3, 3, -1, -1, 1, 1, -1, -1, 3, -3, 1},
{-1, 3, -3, -3, -3, 3, 1, -1, 3, 3, -3, 1}, {-3, -1, -1, -1, 1, -3, 3, -1, 1, -3, 3, 1},
{1, -3, 3, 1, -1, -1, -1, 1, 1, 3, -1, 1}, {1, -3, -1, 3, 3, -1, -3, 1, 1, 1, 1, 1},
{-1, 3, -1, 1, 1, -3, -3, -1, -3, -3, 3, -1}, {3, 1, -1, -1, 3, 3, -3, 1, 3, 1, 3, 3},
{1, -3, 1, 1, -3, 1, 1, 1, -3, -3, -3, 1}, {3, 3, -3, 3, -3, 1, 1, 3, -1, -3, 3, 3},
{-3, 1, -1, -3, -1, 3, 1, 3, 3, 3, -1, 1}, {3, -1, 1, -3, -1, -1, 1, 1, 3, 1, -1, -3},
{1, 3, 1, -1, 1, 3, 3, 3, -1, -1, 3, -1}, {-3, 1, 1, 3, -3, 3, -3, -3, 3, 1, 3, -1},
{-3, 3, 1, 1, -3, 1, -3, -3, -1, -1, 1, -3}, {-1, 3, 1, 3, 1, -1, -1, 3, -3, -1, -3, -1},
{-1, -3, 1, 1, 1, 1, 3, 1, -1, 1, -3, -1}, {-1, 3, -1, 1, -3, -3, -3, -3, -3, 1, -1, -3},
{1, 1, -3, -3, -3, -3, -1, 3, -3, 1, -3, 3}, {1, 1, -1, -3, -1, -3, 1, -1, 1, 3, -1, 1},
{1, 1, 3, 1, 3, 3, -1, 1, -1, -3, -3, 1}, {1, -3, 3, 3, 1, 3, 3, 1, -3, -1, -1, 3},
{1, 3, -3, -3, 3, -3, 1, -1, -1, 3, -1, -3}, {-3, -1, -3, -1, -3, 3, 1, -1, 1, 3, -3, -3},
{-1, 3, -3, 3, -1, 3, 3, -3, 3, 3, -1, -1}, {3, -3, -3, -1, -1, -3, -1, 3, -3, 3, 1, -1}};
// Phi values for M_sc=24 Table 5.5.1.2-2 in TS 36.211
static const float zc_sequence_lte_phi_M_sc_24[30][24] = {
{-1, 3, 1, -3, 3, -1, 1, 3, -3, 3, 1, 3, -3, 3, 1, 1, -1, 1, 3, -3, 3, -3, -1, -3},
{-3, 3, -3, -3, -3, 1, -3, -3, 3, -1, 1, 1, 1, 3, 1, -1, 3, -3, -3, 1, 3, 1, 1, -3},
{3, -1, 3, 3, 1, 1, -3, 3, 3, 3, 3, 1, -1, 3, -1, 1, 1, -1, -3, -1, -1, 1, 3, 3},
{-1, -3, 1, 1, 3, -3, 1, 1, -3, -1, -1, 1, 3, 1, 3, 1, -1, 3, 1, 1, -3, -1, -3, -1},
{-1, -1, -1, -3, -3, -1, 1, 1, 3, 3, -1, 3, -1, 1, -1, -3, 1, -1, -3, -3, 1, -3, -1, -1},
{-3, 1, 1, 3, -1, 1, 3, 1, -3, 1, -3, 1, 1, -1, -1, 3, -1, -3, 3, -3, -3, -3, 1, 1},
{1, 1, -1, -1, 3, -3, -3, 3, -3, 1, -1, -1, 1, -1, 1, 1, -1, -3, -1, 1, -1, 3, -1, -3},
{-3, 3, 3, -1, -1, -3, -1, 3, 1, 3, 1, 3, 1, 1, -1, 3, 1, -1, 1, 3, -3, -1, -1, 1},
{-3, 1, 3, -3, 1, -1, -3, 3, -3, 3, -1, -1, -1, -1, 1, -3, -3, -3, 1, -3, -3, -3, 1, -3},
{1, 1, -3, 3, 3, -1, -3, -1, 3, -3, 3, 3, 3, -1, 1, 1, -3, 1, -1, 1, 1, -3, 1, 1},
{-1, 1, -3, -3, 3, -1, 3, -1, -1, -3, -3, -3, -1, -3, -3, 1, -1, 1, 3, 3, -1, 1, -1, 3},
{1, 3, 3, -3, -3, 1, 3, 1, -1, -3, -3, -3, 3, 3, -3, 3, 3, -1, -3, 3, -1, 1, -3, 1},
{1, 3, 3, 1, 1, 1, -1, -1, 1, -3, 3, -1, 1, 1, -3, 3, 3, -1, -3, 3, -3, -1, -3, -1},
{3, -1, -1, -1, -1, -3, -1, 3, 3, 1, -1, 1, 3, 3, 3, -1, 1, 1, -3, 1, 3, -1, -3, 3},
{-3, -3, 3, 1, 3, 1, -3, 3, 1, 3, 1, 1, 3, 3, -1, -1, -3, 1, -3, -1, 3, 1, 1, 3},
{-1, -1, 1, -3, 1, 3, -3, 1, -1, -3, -1, 3, 1, 3, 1, -1, -3, -3, -1, -1, -3, -3, -3, -1},
{-1, -3, 3, -1, -1, -1, -1, 1, 1, -3, 3, 1, 3, 3, 1, -1, 1, -3, 1, -3, 1, 1, -3, -1},
{1, 3, -1, 3, 3, -1, -3, 1, -1, -3, 3, 3, 3, -1, 1, 1, 3, -1, -3, -1, 3, -1, -1, -1},
{1, 1, 1, 1, 1, -1, 3, -1, -3, 1, 1, 3, -3, 1, -3, -1, 1, 1, -3, -3, 3, 1, 1, -3},
{1, 3, 3, 1, -1, -3, 3, -1, 3, 3, 3, -3, 1, -1, 1, -1, -3, -1, 1, 3, -1, 3, -3, -3},
{-1, -3, 3, -3, -3, -3, -1, -1, -3, -1, -3, 3, 1, 3, -3, -1, 3, -1, 1, -1, 3, -3, 1, -1},
{-3, -3, 1, 1, -1, 1, -1, 1, -1, 3, 1, -3, -1, 1, -1, 1, -1, -1, 3, 3, -3, -1, 1, -3},
{-3, -1, -3, 3, 1, -1, -3, -1, -3, -3, 3, -3, 3, -3, -1, 1, 3, 1, -3, 1, 3, 3, -1, -3},
{-1, -1, -1, -1, 3, 3, 3, 1, 3, 3, -3, 1, 3, -1, 3, -1, 3, 3, -3, 3, 1, -1, 3, 3},
{1, -1, 3, 3, -1, -3, 3, -3, -1, -1, 3, -1, 3, -1, -1, 1, 1, 1, 1, -1, -1, -3, -1, 3},
{1, -1, 1, -1, 3, -1, 3, 1, 1, -1, -1, -3, 1, 1, -3, 1, 3, -3, 1, 1, -3, -3, -1, -1},
{-3, -1, 1, 3, 1, 1, -3, -1, -1, -3, 3, -3, 3, 1, -3, 3, -3, 1, -1, 1, -3, 1, 1, 1},
{-1, -3, 3, 3, 1, 1, 3, -1, -3, -1, -1, -1, 3, 1, -3, -3, -1, 3, -3, -1, -3, -1, -3, -1},
{-1, -3, -1, -1, 1, -3, -1, -1, 1, -1, -3, 1, 1, -3, 1, -3, -3, 3, 1, 1, -1, 3, -1, -1},
{1, 1, -1, -1, -3, -1, 3, -1, 3, -1, 1, 3, 1, -1, 3, 1, 3, -3, -3, 1, -1, -1, 1, 3}};
// Phi values for M_sc=12 Table 5.2.2.2-1 in TS 38.211
static const float zc_sequence_nr_phi_M_sc_6[30][6] = {
{-3, -1, 3, 3, -1, -3}, {-3, 3, -1, -1, 3, -3}, {-3, -3, -3, 3, 1, -3}, {1, 1, 1, 3, -1, -3},
{1, 1, 1, -3, -1, 3}, {-3, 1, -1, -3, -3, -3}, {-3, 1, 3, -3, -3, -3}, {-3, -1, 1, -3, 1, -1},
{-3, -1, -3, 1, -3, -3}, {-3, -3, 1, -3, 3, -3}, {-3, 1, 3, 1, -3, -3}, {-3, -1, -3, 1, 1, -3},
{1, 1, 3, -1, -3, 3}, {1, 1, 3, 3, -1, 3}, {1, 1, 1, -3, 3, -1}, {1, 1, 1, -1, 3, -3},
{-3, -1, -1, -1, 3, -1}, {-3, -3, -1, 1, -1, -3}, {-3, -3, -3, 1, -3, -1}, {-3, 1, 1, -3, -1, -3},
{-3, 3, -3, 1, 1, -3}, {-3, 1, -3, -3, -3, -1}, {1, 1, -3, 3, 1, 3}, {1, 1, -3, -3, 1, -3},
{1, 1, 3, -1, 3, 3}, {1, 1, -3, 1, 3, 3}, {1, 1, -1, -1, 3, -1}, {1, 1, -1, 3, -1, -1},
{1, 1, -1, 3, -3, -1}, {1, 1, -3, 1, -1, -1}};
// Phi values for M_sc=12 Table 5.2.2.2-2 in TS 38.211
static const float zc_sequence_nr_phi_M_sc_12[30][12] = {
{-3, 1, -3, -3, -3, 3, -3, -1, 1, 1, 1, -3}, {-3, 3, 1, -3, 1, 3, -1, -1, 1, 3, 3, 3},
{-3, 3, 3, 1, -3, 3, -1, 1, 3, -3, 3, -3}, {-3, -3, -1, 3, 3, 3, -3, 3, -3, 1, -1, -3},
{-3, -1, -1, 1, 3, 1, 1, -1, 1, -1, -3, 1}, {-3, -3, 3, 1, -3, -3, -3, -1, 3, -1, 1, 3},
{1, -1, 3, -1, -1, -1, -3, -1, 1, 1, 1, -3}, {-1, -3, 3, -1, -3, -3, -3, -1, 1, -1, 1, -3},
{-3, -1, 3, 1, -3, -1, -3, 3, 1, 3, 3, 1}, {-3, -1, -1, -3, -3, -1, -3, 3, 1, 3, -1, -3},
{-3, 3, -3, 3, 3, -3, -1, -1, 3, 3, 1, -3}, {-3, -1, -3, -1, -1, -3, 3, 3, -1, -1, 1, -3},
{-3, -1, 3, -3, -3, -1, -3, 1, -1, -3, 3, 3}, {-3, 1, -1, -1, 3, 3, -3, -1, -1, -3, -1, -3},
{1, 3, -3, 1, 3, 3, 3, 1, -1, 1, -1, 3}, {-3, 1, 3, -1, -1, -3, -3, -1, -1, 3, 1, -3},
{-1, -1, -1, -1, 1, -3, -1, 3, 3, -1, -3, 1}, {-1, 1, 1, -1, 1, 3, 3, -1, -1, -3, 1, -3},
{-3, 1, 3, 3, -1, -1, -3, 3, 3, -3, 3, -3}, {-3, -3, 3, -3, -1, 3, 3, 3, -1, -3, 1, -3},
{3, 1, 3, 1, 3, -3, -1, 1, 3, 1, -1, -3}, {-3, 3, 1, 3, -3, 1, 1, 1, 1, 3, -3, 3},
{-3, 3, 3, 3, -1, -3, -3, -1, -3, 1, 3, -3}, {3, -1, -3, 3, -3, -1, 3, 3, 3, -3, -1, -3},
{-3, -1, 1, -3, 1, 3, 3, 3, -1, -3, 3, 3}, {-3, 3, 1, -1, 3, 3, -3, 1, -1, 1, -1, 1},
{-1, 1, 3, -3, 1, -1, 1, -1, -1, -3, 1, -1}, {-3, -3, 3, 3, 3, -3, -1, 1, -3, 3, 1, -3},
{1, -1, 3, 1, 1, -1, -1, -1, 1, 3, -3, 1}, {-3, 3, -3, 3, -3, -3, 3, -1, -1, 1, 3, -3}};
// Phi values for M_sc=18 Table 5.2.2.2-3 in TS 38.211
static const float zc_sequence_nr_phi_M_sc_18[30][18] = {
{-1, 3, -1, -3, 3, 1, -3, -1, 3, -3, -1, -1, 1, 1, 1, -1, -1, -1},
{3, -3, 3, -1, 1, 3, -3, -1, -3, -3, -1, -3, 3, 1, -1, 3, -3, 3},
{-3, 3, 1, -1, -1, 3, -3, -1, 1, 1, 1, 1, 1, -1, 3, -1, -3, -1},
{-3, -3, 3, 3, 3, 1, -3, 1, 3, 3, 1, -3, -3, 3, -1, -3, -1, 1},
{1, 1, -1, -1, -3, -1, 1, -3, -3, -3, 1, -3, -1, -1, 1, -1, 3, 1},
{3, -3, 1, 1, 3, -1, 1, -1, -1, -3, 1, 1, -1, 3, 3, -3, 3, -1},
{-3, 3, -1, 1, 3, 1, -3, -1, 1, 1, -3, 1, 3, 3, -1, -3, -3, -3},
{1, 1, -3, 3, 3, 1, 3, -3, 3, -1, 1, 1, -1, 1, -3, -3, -1, 3},
{-3, 1, -3, -3, 1, -3, -3, 3, 1, -3, -1, -3, -3, -3, -1, 1, 1, 3},
{3, -1, 3, 1, -3, -3, -1, 1, -3, -3, 3, 3, 3, 1, 3, -3, 3, -3},
{-3, -3, -3, 1, -3, 3, 1, 1, 3, -3, -3, 1, 3, -1, 3, -3, -3, 3},
{-3, -3, 3, 3, 3, -1, -1, -3, -1, -1, -1, 3, 1, -3, -3, -1, 3, -1},
{-3, -1, -3, -3, 1, 1, -1, -3, -1, -3, -1, -1, 3, 3, -1, 3, 1, 3},
{1, 1, -3, -3, -3, -3, 1, 3, -3, 3, 3, 1, -3, -1, 3, -1, -3, 1},
{-3, 3, -1, -3, -1, -3, 1, 1, -3, -3, -1, -1, 3, -3, 1, 3, 1, 1},
{3, 1, -3, 1, -3, 3, 3, -1, -3, -3, -1, -3, -3, 3, -3, -1, 1, 3},
{-3, -1, -3, -1, -3, 1, 3, -3, -1, 3, 3, 3, 1, -1, -3, 3, -1, -3},
{-3, -1, 3, 3, -1, 3, -1, -3, -1, 1, -1, -3, -1, -1, -1, 3, 3, 1},
{-3, 1, -3, -1, -1, 3, 1, -3, -3, -3, -1, -3, -3, 1, 1, 1, -1, -1},
{3, 3, 3, -3, -1, -3, -1, 3, -1, 1, -1, -3, 1, -3, -3, -1, 3, 3},
{-3, 1, 1, -3, 1, 1, 3, -3, -1, -3, -1, 3, -3, 3, -1, -1, -1, -3},
{1, -3, -1, -3, 3, 3, -1, -3, 1, -3, -3, -1, -3, -1, 1, 3, 3, 3},
{-3, -3, 1, -1, -1, 1, 1, -3, -1, 3, 3, 3, 3, -1, 3, 1, 3, 1},
{3, -1, -3, 1, -3, -3, -3, 3, 3, -1, 1, -3, -1, 3, 1, 1, 3, 3},
{3, -1, -1, 1, -3, -1, -3, -1, -3, -3, -1, -3, 1, 1, 1, -3, -3, 3},
{-3, -3, 1, -3, 3, 3, 3, -1, 3, 1, 1, -3, -3, -3, 3, -3, -1, -1},
{-3, -1, -1, -3, 1, -3, 3, -1, -1, -3, 3, 3, -3, -1, 3, -1, -1, -1},
{-3, -3, 3, 3, -3, 1, 3, -1, -3, 1, -1, -3, 3, -3, -1, -1, -1, 3},
{-1, -3, 1, -3, -3, -3, 1, 1, 3, 3, -3, 3, 3, -3, -1, 3, -3, 1},
{-3, 3, 1, -1, -1, -1, -1, 1, -1, 3, 3, -3, -1, 1, 3, -1, 3, -1}};
// Phi values for M_sc=18 Table 5.2.2.2-3 in TS 38.211
static const float zc_sequence_nr_phi_M_sc_24[30][24] = {
{-1, -3, 3, -1, 3, 1, 3, -1, 1, -3, -1, -3, -1, 1, 3, -3, -1, -3, 3, 3, 3, -3, -3, -3},
{-1, -3, 3, 1, 1, -3, 1, -3, -3, 1, -3, -1, -1, 3, -3, 3, 3, 3, -3, 1, 3, 3, -3, -3},
{-1, -3, -3, 1, -1, -1, -3, 1, 3, -1, -3, -1, -1, -3, 1, 1, 3, 1, -3, -1, -1, 3, -3, -3},
{1, -3, 3, -1, -3, -1, 3, 3, 1, -1, 1, 1, 3, -3, -1, -3, -3, -3, -1, 3, -3, -1, -3, -3},
{-1, 3, -3, -3, -1, 3, -1, -1, 1, 3, 1, 3, -1, -1, -3, 1, 3, 1, -1, -3, 1, -1, -3, -3},
{-3, -1, 1, -3, -3, 1, 1, -3, 3, -1, -1, -3, 1, 3, 1, -1, -3, -1, -3, 1, -3, -3, -3, -3},
{-3, 3, 1, 3, -1, 1, -3, 1, -3, 1, -1, -3, -1, -3, -3, -3, -3, -1, -1, -1, 1, 1, -3, -3},
{-3, 1, 3, -1, 1, -1, 3, -3, 3, -1, -3, -1, -3, 3, -1, -1, -1, -3, -1, -1, -3, 3, 3, -3},
{-3, 1, -3, 3, -1, -1, -1, -3, 3, 1, -1, -3, -1, 1, 3, -1, 1, -1, 1, -3, -3, -3, -3, -3},
{1, 1, -1, -3, -1, 1, 1, -3, 1, -1, 1, -3, 3, -3, -3, 3, -1, -3, 1, 3, -3, 1, -3, -3},
{-3, -3, -3, -1, 3, -3, 3, 1, 3, 1, -3, -1, -1, -3, 1, 1, 3, 1, -1, -3, 3, 1, 3, -3},
{-3, 3, -1, 3, 1, -1, -1, -1, 3, 3, 1, 1, 1, 3, 3, 1, -3, -3, -1, 1, -3, 1, 3, -3},
{3, -3, 3, -1, -3, 1, 3, 1, -1, -1, -3, -1, 3, -3, 3, -1, -1, 3, 3, -3, -3, 3, -3, -3},
{-3, 3, -1, 3, -1, 3, 3, 1, 1, -3, 1, 3, -3, 3, -3, -3, -1, 1, 3, -3, -1, -1, -3, -3},
{-3, 1, -3, -1, -1, 3, 1, 3, -3, 1, -1, 3, 3, -1, -3, 3, -3, -1, -1, -3, -3, -3, 3, -3},
{-3, -1, -1, -3, 1, -3, -3, -1, -1, 3, -1, 1, -1, 3, 1, -3, -1, 3, 1, 1, -1, -1, -3, -3},
{-3, -3, 1, -1, 3, 3, -3, -1, 1, -1, -1, 1, 1, -1, -1, 3, -3, 1, -3, 1, -1, -1, -1, -3},
{3, -1, 3, -1, 1, -3, 1, 1, -3, -3, 3, -3, -1, -1, -1, -1, -1, -3, -3, -1, 1, 1, -3, -3},
{-3, 1, -3, 1, -3, -3, 1, -3, 1, -3, -3, -3, -3, -3, 1, -3, -3, 1, 1, -3, 1, 1, -3, -3},
{-3, -3, 3, 3, 1, -1, -1, -1, 1, -3, -1, 1, -1, 3, -3, -1, -3, -1, -1, 1, -3, 3, -1, -3},
{-3, -3, -1, -1, -1, -3, 1, -1, -3, -1, 3, -3, 1, -3, 3, -3, 3, 3, 1, -1, -1, 1, -3, -3},
{3, -1, 1, -1, 3, -3, 1, 1, 3, -1, -3, 3, 1, -3, 3, -1, -1, -1, -1, 1, -3, -3, -3, -3},
{-3, 1, -3, 3, -3, 1, -3, 3, 1, -1, -3, -1, -3, -3, -3, -3, 1, 3, -1, 1, 3, 3, 3, -3},
{-3, -1, 1, -3, -1, -1, 1, 1, 1, 3, 3, -1, 1, -1, 1, -1, -1, -3, -3, -3, 3, 1, -1, -3},
{-3, 3, -1, -3, -1, -1, -1, 3, -1, -1, 3, -3, -1, 3, -3, 3, -3, -1, 3, 1, 1, -1, -3, -3},
{-3, 1, -1, -3, -3, -1, 1, -3, -1, -3, 1, 1, -1, 1, 1, 3, 3, 3, -1, 1, -1, 1, -1, -3},
{-1, 3, -1, -1, 3, 3, -1, -1, -1, 3, -1, -3, 1, 3, 1, 1, -3, -3, -3, -1, -3, -1, -3, -3},
{3, -3, -3, -1, 3, 3, -3, -1, 3, 1, 1, 1, 3, -1, 3, -3, -1, 3, -1, 3, 1, -1, -3, -3},
{-3, 1, -3, 1, -3, 1, 1, 3, 1, -3, -3, -1, 1, 3, -1, -3, 3, 1, -1, -3, -3, -3, -3, -3},
{3, -3, -1, 1, 3, -1, -1, -3, -1, 3, -1, -3, -1, -3, 3, -1, 3, 1, 1, -3, 3, -3, -3, -3}};
static void zc_sequence_lte_r_uv_arg_1prb(uint32_t u, cf_t* tmp_arg)
{
srslte_vec_sc_prod_fcc(zc_sequence_lte_phi_M_sc_12[u], M_PI_4, tmp_arg, SRSLTE_NRE);
}
static void zc_sequence_lte_r_uv_arg_2prb(uint32_t u, cf_t* tmp_arg)
{
srslte_vec_sc_prod_fcc(zc_sequence_lte_phi_M_sc_24[u], M_PI_4, tmp_arg, 2 * SRSLTE_NRE);
}
static void zc_sequence_nr_r_uv_arg_0dot5prb(uint32_t u, cf_t* tmp_arg)
{
srslte_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_6[u], M_PI_4, tmp_arg, SRSLTE_NRE / 2);
}
static void zc_sequence_nr_r_uv_arg_1prb(uint32_t u, cf_t* tmp_arg)
{
srslte_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_12[u], M_PI_4, tmp_arg, SRSLTE_NRE);
}
static void zc_sequence_nr_r_uv_arg_1dot5prb(uint32_t u, cf_t* tmp_arg)
{
srslte_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_18[u], M_PI_4, tmp_arg, (3 * SRSLTE_NRE) / 2);
}
static void zc_sequence_nr_r_uv_arg_2prb(uint32_t u, cf_t* tmp_arg)
{
srslte_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_24[u], M_PI_4, tmp_arg, 2 * SRSLTE_NRE);
}
static uint32_t zc_sequence_q(uint32_t u, uint32_t v, uint32_t N_sz)
{
float q;
float q_hat;
float n_sz = (float)N_sz;
q_hat = n_sz * (u + 1) / 31;
if ((((uint32_t)(2 * q_hat)) % 2) == 0) {
q = q_hat + 0.5 + v;
} else {
q = q_hat + 0.5 - v;
}
return (uint32_t)q;
}
// Common for LTE and NR
static void zc_sequence_r_uv_arg_mprb(uint32_t M_zc, uint32_t u, uint32_t v, cf_t* tmp_arg)
{
int32_t N_sz = srslte_prime_lower_than(M_zc); // N_zc - Zadoff Chu Sequence Length
if (N_sz > 0) {
float q = zc_sequence_q(u, v, N_sz);
float n_sz = (float)N_sz;
for (uint32_t i = 0; i < M_zc; i++) {
float m = (float)(i % N_sz);
tmp_arg[i] = -M_PI * q * m * (m + 1) / n_sz;
}
}
}
static int zc_sequence_lte_r_uv_arg(uint32_t M_zc, uint32_t u, uint32_t v, cf_t* tmp_arg)
{
if (M_zc == 12) {
zc_sequence_lte_r_uv_arg_1prb(u, tmp_arg);
} else if (M_zc == 24) {
zc_sequence_lte_r_uv_arg_2prb(u, tmp_arg);
} else if (M_zc >= 36) {
zc_sequence_r_uv_arg_mprb(M_zc, u, v, tmp_arg);
} else {
ERROR("Invalid M_zc (%d)\n", M_zc);
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
static int zc_sequence_nr_r_uv_arg(uint32_t M_zc, uint32_t u, uint32_t v, cf_t* tmp_arg)
{
if (M_zc == 6) {
zc_sequence_nr_r_uv_arg_0dot5prb(u, tmp_arg);
} else if (M_zc == 12) {
zc_sequence_nr_r_uv_arg_1prb(u, tmp_arg);
} else if (M_zc == 18) {
zc_sequence_nr_r_uv_arg_1dot5prb(u, tmp_arg);
} else if (M_zc == 24) {
zc_sequence_nr_r_uv_arg_2prb(u, tmp_arg);
} else if (M_zc >= 36) {
zc_sequence_r_uv_arg_mprb(M_zc, u, v, tmp_arg);
} else {
ERROR("Invalid M_zc (%d)\n", M_zc);
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
static void zc_sequence_generate(uint32_t M_zc, float alpha, const cf_t* tmp_arg, cf_t* sequence)
{
for (uint32_t i = 0; i < M_zc; i++) {
sequence[i] = cexpf(I * (tmp_arg[i] + alpha * (float)i));
}
}
int srslte_zc_sequence_generate_lte(uint32_t u, uint32_t v, float alpha, uint32_t nof_prb, cf_t* sequence)
{
if (sequence == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
// Calculate number of samples
uint32_t M_zc = nof_prb * SRSLTE_NRE;
// Calculate argument
if (zc_sequence_lte_r_uv_arg(M_zc, u, v, sequence) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
// Do complex exponential and adjust amplitude
zc_sequence_generate(M_zc, alpha, sequence, sequence);
return SRSLTE_SUCCESS;
}
int srslte_zc_sequence_generate_nr(uint32_t u, uint32_t v, float alpha, uint32_t m, uint32_t delta, cf_t* sequence)
{
// Check inputs
if (sequence == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
// Calculate number of samples
uint32_t M_zc = (m * SRSLTE_NRE) >> delta;
// Calculate argument
if (zc_sequence_nr_r_uv_arg(M_zc, u, v, sequence) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
// Do complex exponential and adjust amplitude
zc_sequence_generate(M_zc, alpha, sequence, sequence);
return SRSLTE_SUCCESS;
}

@ -25,6 +25,7 @@
#include "srslte/phy/ch_estimation/refsignal_ul.h"
#include "srslte/phy/common/phy_common.h"
#include "srslte/phy/common/sequence.h"
#include "srslte/phy/common/zc_sequence.h"
#include "srslte/phy/mimo/precoding.h"
#include "srslte/phy/modem/demod_soft.h"
#include "srslte/phy/phch/pucch.h"
@ -289,9 +290,6 @@ uci_mod_bits(srslte_pucch_t* q, srslte_ul_sf_cfg_t* sf, srslte_pucch_cfg_t* cfg,
return SRSLTE_SUCCESS;
}
// Declare this here, since we can not include refsignal_ul.h
void srslte_refsignal_r_uv_arg_1prb(float* arg, uint32_t u);
/* 3GPP 36211 Table 5.5.2.2.2-1: Demodulation reference signal location for different PUCCH formats. */
static const uint32_t pucch_symbol_format1_cpnorm[4] = {0, 1, 5, 6};
static const uint32_t pucch_symbol_format1_cpext[4] = {0, 1, 4, 5};
@ -491,21 +489,22 @@ static int encode_signal_format12(srslte_pucch_t* q,
}
uint32_t u = (f_gh + (q->cell.id % 30)) % 30;
srslte_refsignal_r_uv_arg_1prb(q->tmp_arg, u);
uint32_t N_sf_widx = N_sf == 3 ? 1 : 0;
for (uint32_t m = 0; m < N_sf; m++) {
// Calculate sequence z pointer for this symbol m
cf_t* z_m = &z[(ns % 2) * N_sf_0 * SRSLTE_PUCCH_N_SEQ + m * SRSLTE_PUCCH_N_SEQ];
// Get symbol index
uint32_t l = get_pucch_symbol(m, cfg->format, q->cell.cp);
float alpha = 0;
cf_t w_m = 1.0;
if (cfg->format >= SRSLTE_PUCCH_FORMAT_2) {
alpha = srslte_pucch_alpha_format2(q->n_cs_cell, cfg, ns, l);
for (uint32_t n = 0; n < SRSLTE_PUCCH_N_SEQ; n++) {
z[(ns % 2) * N_sf * SRSLTE_PUCCH_N_SEQ + m * SRSLTE_PUCCH_N_SEQ + n] =
q->d[(ns % 2) * N_sf + m] * cexpf(I * (q->tmp_arg[n] + alpha * n));
}
float alpha = srslte_pucch_alpha_format2(q->n_cs_cell, cfg, ns, l);
srslte_zc_sequence_generate_lte(u, 0, alpha, SRSLTE_PUCCH_N_SEQ / SRSLTE_NRE, z_m);
w_m = q->d[(ns % 2) * N_sf + m];
} else {
uint32_t n_prime_ns = 0;
uint32_t n_oc = 0;
alpha = srslte_pucch_alpha_format1(q->n_cs_cell, cfg, q->cell.cp, true, ns, l, &n_oc, &n_prime_ns);
float alpha = srslte_pucch_alpha_format1(q->n_cs_cell, cfg, q->cell.cp, true, ns, l, &n_oc, &n_prime_ns);
float S_ns = 0;
if (n_prime_ns % 2) {
S_ns = M_PI / 2;
@ -517,12 +516,12 @@ static int encode_signal_format12(srslte_pucch_t* q,
n_oc,
n_prime_ns,
cfg->n_rb_2);
for (uint32_t n = 0; n < SRSLTE_PUCCH_N_SEQ; n++) {
z[(ns % 2) * N_sf_0 * SRSLTE_PUCCH_N_SEQ + m * SRSLTE_PUCCH_N_SEQ + n] =
q->d[0] * cexpf(I * (w_n_oc[N_sf_widx][n_oc % 3][m] + q->tmp_arg[n] + alpha * n + S_ns));
}
srslte_zc_sequence_generate_lte(u, 0, alpha, SRSLTE_PUCCH_N_SEQ / SRSLTE_NRE, z_m);
w_m = q->d[0] * cexpf(I * (w_n_oc[N_sf_widx][n_oc % 3][m] + S_ns));
}
// Apply w_m
srslte_vec_sc_prod_ccc(z_m, w_m, z_m, SRSLTE_PUCCH_N_SEQ);
}
}
return SRSLTE_SUCCESS;

@ -172,10 +172,6 @@ int main(int argc, char** argv)
ERROR("Error setting C-RNTI\n");
goto quit;
}
if (srslte_refsignal_ul_init(&dmrs, cell.nof_prb)) {
ERROR("Error creating PDSCH object\n");
exit(-1);
}
if (srslte_refsignal_ul_set_cell(&dmrs, cell)) {
ERROR("Error creating PDSCH object\n");
exit(-1);
@ -325,7 +321,6 @@ int main(int argc, char** argv)
quit:
srslte_pucch_free(&pucch_ue);
srslte_pucch_free(&pucch_enb);
srslte_refsignal_ul_free(&dmrs);
srslte_chest_ul_free(&chest);
srslte_chest_ul_res_free(&chest_res);
srslte_channel_awgn_free(&awgn);

@ -69,10 +69,6 @@ int srslte_ue_ul_init(srslte_ue_ul_t* q, cf_t* out_buffer, uint32_t max_prb)
ERROR("Error creating PUSCH object\n");
goto clean_exit;
}
if (srslte_refsignal_ul_init(&q->signals, max_prb)) {
ERROR("Error initiating srslte_refsignal_ul\n");
goto clean_exit;
}
q->refsignal = srslte_vec_cf_malloc(2 * SRSLTE_NRE * max_prb);
if (!q->refsignal) {
perror("malloc");
@ -106,7 +102,6 @@ void srslte_ue_ul_free(srslte_ue_ul_t* q)
srslte_pucch_free(&q->pucch);
srslte_cfo_free(&q->cfo);
srslte_refsignal_ul_free(&q->signals);
if (q->sf_symbols) {
free(q->sf_symbols);

Loading…
Cancel
Save