mirror of https://github.com/PentHertz/srsLTE.git
Added ZC sequence LUT object
This commit is contained in:
parent
d100919561
commit
e7562e5b3f
|
@ -17,6 +17,16 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the maximum number of ZC sequence groups (u)
|
||||||
|
*/
|
||||||
|
#define SRSLTE_ZC_SEQUENCE_NOF_GROUPS 30
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the maximum number of base sequences (v)
|
||||||
|
*/
|
||||||
|
#define SRSLTE_ZC_SEQUENCE_NOF_BASE 2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generates ZC sequences given the required parameters used in the TS 36 series (LTE)
|
* @brief Generates ZC sequences given the required parameters used in the TS 36 series (LTE)
|
||||||
*
|
*
|
||||||
|
@ -35,7 +45,7 @@ SRSLTE_API int srslte_zc_sequence_generate_lte(uint32_t u, uint32_t v, float alp
|
||||||
* @brief Generates ZC sequences given the required parameters used in the TS 38 series (NR)
|
* @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
|
* @remark Implemented as defined in TS 38.211 section 5.2.2 Low-PAPR sequence generation
|
||||||
|
*
|
||||||
* @param u Group number {0,1,...29}
|
* @param u Group number {0,1,...29}
|
||||||
* @param v base sequence
|
* @param v base sequence
|
||||||
* @param alpha Phase shift
|
* @param alpha Phase shift
|
||||||
|
@ -47,4 +57,46 @@ SRSLTE_API int srslte_zc_sequence_generate_lte(uint32_t u, uint32_t v, float alp
|
||||||
SRSLTE_API int
|
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);
|
srslte_zc_sequence_generate_nr(uint32_t u, uint32_t v, float alpha, uint32_t m, uint32_t delta, cf_t* sequence);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Low-PAPR ZC sequence look-up-table
|
||||||
|
*/
|
||||||
|
typedef struct SRSLTE_API {
|
||||||
|
uint32_t M_zc;
|
||||||
|
uint32_t nof_alphas;
|
||||||
|
cf_t* sequence[SRSLTE_ZC_SEQUENCE_NOF_GROUPS][SRSLTE_ZC_SEQUENCE_NOF_BASE];
|
||||||
|
} srslte_zc_sequence_lut_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialises a Low-PAPR sequence look-up-table object using NR tables
|
||||||
|
*
|
||||||
|
* @param q Object pointer
|
||||||
|
* @param m Number of PRB
|
||||||
|
* @param delta Delta parameter described in specification
|
||||||
|
* @param alphas Vector with the alpha shift parameters
|
||||||
|
* @param nof_alphas Number alpha shifts to generate
|
||||||
|
* @return SRSLTE_SUCCESS if the initialization is successful, SRSLTE_ERROR code otherwise
|
||||||
|
*/
|
||||||
|
SRSLTE_API int srslte_zc_sequence_lut_init_nr(srslte_zc_sequence_lut_t* q,
|
||||||
|
uint32_t m,
|
||||||
|
uint32_t delta,
|
||||||
|
float* alphas,
|
||||||
|
uint32_t nof_alphas);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deallocates a Low-PAPR sequence look-up-table object
|
||||||
|
* @param q Object pointer
|
||||||
|
*/
|
||||||
|
SRSLTE_API void srslte_zc_sequence_lut_free(srslte_zc_sequence_lut_t* q);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a Low-PAPR sequence from the LUT
|
||||||
|
* @param q Object pointer
|
||||||
|
* @param u Group number {0,1,...29}
|
||||||
|
* @param v base sequence
|
||||||
|
* @param alpha_idx Phase shift index
|
||||||
|
* @return SRSLTE_SUCCESS if the generation is successful, SRSLTE_ERROR code otherwise
|
||||||
|
*/
|
||||||
|
SRSLTE_API const cf_t*
|
||||||
|
srslte_zc_sequence_lut_get(const srslte_zc_sequence_lut_t* q, uint32_t u, uint32_t v, uint32_t alpha_idx);
|
||||||
|
|
||||||
#endif // SRSLTE_ZC_SEQUENCE_H
|
#endif // SRSLTE_ZC_SEQUENCE_H
|
||||||
|
|
|
@ -267,11 +267,17 @@ static void zc_sequence_generate(uint32_t M_zc, float alpha, const cf_t* tmp_arg
|
||||||
|
|
||||||
int srslte_zc_sequence_generate_lte(uint32_t u, uint32_t v, float alpha, uint32_t nof_prb, cf_t* sequence)
|
int srslte_zc_sequence_generate_lte(uint32_t u, uint32_t v, float alpha, uint32_t nof_prb, cf_t* sequence)
|
||||||
{
|
{
|
||||||
|
// Check inputs
|
||||||
if (sequence == NULL) {
|
if (sequence == NULL) {
|
||||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check U and V
|
||||||
|
if (u >= SRSLTE_ZC_SEQUENCE_NOF_GROUPS || v >= SRSLTE_ZC_SEQUENCE_NOF_BASE) {
|
||||||
|
ERROR("Invalid u (%d) or v (%d)\n", u, v);
|
||||||
|
return SRSLTE_ERROR_OUT_OF_BOUNDS;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate number of samples
|
// Calculate number of samples
|
||||||
uint32_t M_zc = nof_prb * SRSLTE_NRE;
|
uint32_t M_zc = nof_prb * SRSLTE_NRE;
|
||||||
|
|
||||||
|
@ -293,6 +299,12 @@ int srslte_zc_sequence_generate_nr(uint32_t u, uint32_t v, float alpha, uint32_t
|
||||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check U and V
|
||||||
|
if (u >= SRSLTE_ZC_SEQUENCE_NOF_GROUPS || v >= SRSLTE_ZC_SEQUENCE_NOF_BASE) {
|
||||||
|
ERROR("Invalid u (%d) or v (%d)\n", u, v);
|
||||||
|
return SRSLTE_ERROR_OUT_OF_BOUNDS;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate number of samples
|
// Calculate number of samples
|
||||||
uint32_t M_zc = (m * SRSLTE_NRE) >> delta;
|
uint32_t M_zc = (m * SRSLTE_NRE) >> delta;
|
||||||
|
|
||||||
|
@ -305,4 +317,73 @@ int srslte_zc_sequence_generate_nr(uint32_t u, uint32_t v, float alpha, uint32_t
|
||||||
zc_sequence_generate(M_zc, alpha, sequence, sequence);
|
zc_sequence_generate(M_zc, alpha, sequence, sequence);
|
||||||
|
|
||||||
return SRSLTE_SUCCESS;
|
return SRSLTE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int srslte_zc_sequence_lut_init_nr(srslte_zc_sequence_lut_t* q,
|
||||||
|
uint32_t m,
|
||||||
|
uint32_t delta,
|
||||||
|
float* alphas,
|
||||||
|
uint32_t nof_alphas)
|
||||||
|
{
|
||||||
|
if (q == NULL || alphas == NULL) {
|
||||||
|
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set all structure to zero
|
||||||
|
SRSLTE_MEM_ZERO(q, srslte_zc_sequence_lut_t, 1);
|
||||||
|
|
||||||
|
// Calculate number of samples
|
||||||
|
q->M_zc = (m * SRSLTE_NRE) >> delta;
|
||||||
|
q->nof_alphas = nof_alphas;
|
||||||
|
|
||||||
|
for (uint32_t u = 0; u < SRSLTE_ZC_SEQUENCE_NOF_GROUPS; u++) {
|
||||||
|
for (uint32_t v = 0; v < SRSLTE_ZC_SEQUENCE_NOF_BASE; v++) {
|
||||||
|
// Allocate sequence
|
||||||
|
q->sequence[u][v] = srslte_vec_cf_malloc(nof_alphas * q->M_zc);
|
||||||
|
if (q->sequence[u][v] == NULL) {
|
||||||
|
ERROR("Malloc\n");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a sequence for each alpha
|
||||||
|
for (uint32_t alpha_idx = 0; alpha_idx < nof_alphas; alpha_idx++) {
|
||||||
|
if (srslte_zc_sequence_generate_nr(u, v, alphas[alpha_idx], m, delta, &q->sequence[u][v][alpha_idx * q->M_zc]) <
|
||||||
|
SRSLTE_SUCCESS) {
|
||||||
|
ERROR("Generating sequence\n");
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srslte_zc_sequence_lut_free(srslte_zc_sequence_lut_t* q)
|
||||||
|
{
|
||||||
|
for (uint32_t u = 0; u < SRSLTE_ZC_SEQUENCE_NOF_GROUPS; u++) {
|
||||||
|
for (uint32_t v = 0; v < SRSLTE_ZC_SEQUENCE_NOF_BASE; v++) {
|
||||||
|
if (q->sequence[u][v] != NULL) {
|
||||||
|
free(q->sequence[u][v]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SRSLTE_MEM_ZERO(q, srslte_zc_sequence_lut_t, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cf_t* srslte_zc_sequence_lut_get(const srslte_zc_sequence_lut_t* q, uint32_t u, uint32_t v, uint32_t alpha_idx)
|
||||||
|
{
|
||||||
|
if (q == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u >= SRSLTE_ZC_SEQUENCE_NOF_GROUPS) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v >= SRSLTE_ZC_SEQUENCE_NOF_BASE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &q->sequence[u][v][alpha_idx * q->M_zc];
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue