mirror of https://github.com/pvnis/srsRAN_4G.git
Initial implementation of the 5G NR PDCCH DMRS encoding
parent
579526f1fe
commit
29ad2427d9
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 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_DMRS_PDCCH_H
|
||||||
|
#define SRSLTE_DMRS_PDCCH_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "srslte/phy/common/phy_common_nr.h"
|
||||||
|
#include "srslte/srslte.h"
|
||||||
|
|
||||||
|
SRSLTE_API int
|
||||||
|
srslte_dmrs_pdcch_put(const srslte_nr_pdcch_cfg_t* cfg, const srslte_dl_sf_cfg_t* dl_sf, cf_t* sf_symbols);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SRSLTE_DMRS_PDCCH_H
|
@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 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_PHY_COMMON_NR_H
|
||||||
|
#define SRSLTE_PHY_COMMON_NR_H
|
||||||
|
|
||||||
|
#include "phy_common.h"
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the number of symbols per slot. Defined by TS 38.211 v15.8.0 Table 4.3.2-1.
|
||||||
|
*/
|
||||||
|
#define SRSLTE_NR_NSYMB_PER_SLOT 14
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the maximum numerology supported. Defined by TS 38.211 v15.8.0 Table 4.3.2-1.
|
||||||
|
*/
|
||||||
|
#define SRSLTE_NR_MAX_NUMEROLOGY 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the number of slots per SF. Defined by TS 38.211 v15.8.0 Table 4.3.2-1.
|
||||||
|
*/
|
||||||
|
#define SRSLTE_NR_NSLOTS_PER_SF(NUM) (1U << (NUM))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the number of slots per frame. Defined by TS 38.211 v15.8.0 Table 4.3.2-1.
|
||||||
|
*/
|
||||||
|
#define SRSLTE_NR_NSLOTS_PER_FRAME(NUM) (SRSLTE_NR_NSLOTS_PER_SF(NUM) * SRSLTE_NOF_SF_X_FRAME)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum Carrier identification value. Defined by TS 38.331 v15.10.0 as PhysCellId from 0 to 1007.
|
||||||
|
*/
|
||||||
|
#define SRSLTE_NR_MAX_ID 1007
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum number of physical resource blocks (PRB) that a 5G NR can have. This is defined by TS 38.331 v15.10.0
|
||||||
|
* as maxNrofPhysicalResourceBlocks
|
||||||
|
*/
|
||||||
|
#define SRSLTE_NR_MAX_PRB 275
|
||||||
|
|
||||||
|
#define SRSLTE_NR_MAX_START 2199
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common carrier parameters
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t numerology;
|
||||||
|
uint32_t nof_prb;
|
||||||
|
uint32_t start;
|
||||||
|
} srslte_nr_carrier_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CORESET related constants
|
||||||
|
*/
|
||||||
|
#define SRSLTE_CORESET_DURATION_MIN 1
|
||||||
|
#define SRSLTE_CORESET_DURATION_MAX 3
|
||||||
|
#define SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE 45
|
||||||
|
#define SRSLTE_CORESET_SHIFT_INDEX_MAX (SRSLTE_CORESET_NOF_PRB_MAX - 1)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
srslte_coreset_mapping_type_interleaved = 0,
|
||||||
|
srslte_coreset_mapping_type_non_interleaved,
|
||||||
|
} srslte_coreset_mapping_type_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
srslte_coreset_bundle_size_n2 = 0,
|
||||||
|
srslte_coreset_bundle_size_n3,
|
||||||
|
srslte_coreset_bundle_size_n6,
|
||||||
|
} srslte_coreset_bundle_size_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
srslte_coreset_precoder_granularity_contiguous = 0,
|
||||||
|
srslte_coreset_precoder_granularity_reg_bundle
|
||||||
|
} srslte_coreset_precoder_granularity_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CORESET structure
|
||||||
|
*
|
||||||
|
* Fields follow the same order than described in 3GPP 38.331 R15 - ControlResourceSet
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
srslte_coreset_mapping_type_t mapping_type;
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t duration;
|
||||||
|
bool freq_domain_resources[SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE];
|
||||||
|
srslte_coreset_bundle_size_t interleaver_size;
|
||||||
|
|
||||||
|
bool dmrs_scrambling_id_present;
|
||||||
|
uint32_t dmrs_scrambling_id;
|
||||||
|
srslte_coreset_precoder_granularity_t precoder_granularity;
|
||||||
|
srslte_coreset_bundle_size_t reg_bundle_size;
|
||||||
|
uint32_t shift_index;
|
||||||
|
/** Missing TCI parameters */
|
||||||
|
} srslte_coreset_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
srslte_search_space_type_common = 0,
|
||||||
|
srslte_search_space_type_ue,
|
||||||
|
} srslte_search_space_type_t;
|
||||||
|
|
||||||
|
#define SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS 5
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t start; // start symbol within slot
|
||||||
|
uint32_t duration; // in slots
|
||||||
|
srslte_search_space_type_t type;
|
||||||
|
uint32_t nof_candidates[SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS];
|
||||||
|
} srslte_search_space_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
srslte_nr_carrier_t carrier;
|
||||||
|
uint16_t rnti;
|
||||||
|
srslte_coreset_t coreset;
|
||||||
|
srslte_search_space_t search_space;
|
||||||
|
uint32_t candidate;
|
||||||
|
uint32_t aggregation_level;
|
||||||
|
} srslte_nr_pdcch_cfg_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SRSLTE_PHY_COMMON_NR_H
|
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 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/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "srslte/phy/ch_estimation/dmrs_pdcch.h"
|
||||||
|
|
||||||
|
uint32_t srslte_pdcch_calculate_Y_p_n(uint32_t coreset_id, uint16_t rnti, int n)
|
||||||
|
{
|
||||||
|
const uint32_t A_p[3] = {39827, 39829, 39839};
|
||||||
|
const uint32_t D = 65537;
|
||||||
|
|
||||||
|
if (n < 0) {
|
||||||
|
return rnti;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (A_p[coreset_id % 3] * srslte_pdcch_calculate_Y_p_n(coreset_id, rnti, n - 1)) % D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the Control Channnel Element As described in 3GPP 38.213 R15 10.1 UE procedure for determining physical
|
||||||
|
* downlink control channel assignment
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int srslte_pdcch_get_ncce(const srslte_nr_pdcch_cfg_t* cfg, const srslte_dl_sf_cfg_t* dl_sf)
|
||||||
|
{
|
||||||
|
if (cfg->aggregation_level >= SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS) {
|
||||||
|
ERROR("Invalid aggregation level %d;\n", cfg->aggregation_level);
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t L = 1U << cfg->aggregation_level; // Aggregation level
|
||||||
|
uint32_t n_ci = 0; // Carrier indicator field
|
||||||
|
uint32_t m = cfg->candidate; // Selected PDDCH candidate
|
||||||
|
uint32_t M = cfg->search_space.nof_candidates[cfg->aggregation_level]; // Number of aggregation levels
|
||||||
|
|
||||||
|
if (M == 0) {
|
||||||
|
ERROR("Invalid number of candidates %d for aggregation level %d\n", M, cfg->aggregation_level);
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count number of REG
|
||||||
|
uint32_t N_cce = 0;
|
||||||
|
for (uint32_t i = 0; i < SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE; i++) {
|
||||||
|
N_cce += cfg->coreset.freq_domain_resources[i] ? cfg->coreset.duration : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (N_cce < L) {
|
||||||
|
ERROR("Error number of CCE %d is lower than the aggregation level %d\n", N_cce, L);
|
||||||
|
return SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate Y_p_n
|
||||||
|
uint32_t Y_p_n = 0;
|
||||||
|
if (cfg->search_space.type == srslte_search_space_type_ue) {
|
||||||
|
Y_p_n = srslte_pdcch_calculate_Y_p_n(
|
||||||
|
cfg->coreset.id, cfg->rnti, dl_sf->tti % SRSLTE_NR_NSLOTS_PER_FRAME(cfg->carrier.numerology));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)(L * ((Y_p_n + (m * N_cce) / (L * M) + n_ci) % (N_cce / L)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t dmrs_pdcch_get_cinit(uint32_t slot_idx, uint32_t symbol_idx, uint32_t n_id)
|
||||||
|
{
|
||||||
|
return (uint32_t)((((SRSLTE_NR_NSYMB_PER_SLOT * slot_idx + symbol_idx + 1UL) << 17UL) * (2 * n_id + 1) + 2 * n_id) &
|
||||||
|
(uint64_t)INT32_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dmrs_pdcch_put_symbol_noninterleaved(const srslte_nr_pdcch_cfg_t* cfg, uint32_t cinit, uint32_t ncce, cf_t* sf_symbol)
|
||||||
|
{
|
||||||
|
uint32_t L = 1U << cfg->aggregation_level;
|
||||||
|
uint32_t nof_freq_res = SRSLTE_MIN(cfg->carrier.nof_prb / 6, SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE);
|
||||||
|
|
||||||
|
// Initialise sequence for this symbol
|
||||||
|
srslte_sequence_state_t sequence_state = {};
|
||||||
|
srslte_sequence_state_init(&sequence_state, cinit);
|
||||||
|
uint32_t sequence_skip = 0; // Accumulates pilot locations to skip
|
||||||
|
|
||||||
|
// Calculate Resource block indexes range, every CCE is 6 REG, 1 REG is 6 RE in resource blocks
|
||||||
|
uint32_t rb_coreset_idx_begin = (ncce * 6) / cfg->coreset.duration;
|
||||||
|
uint32_t rb_coreset_idx_end = ((ncce + L) * 6) / cfg->coreset.duration;
|
||||||
|
|
||||||
|
// CORESET Resource Block counter
|
||||||
|
uint32_t rb_coreset_idx = 0;
|
||||||
|
for (uint32_t i = 0; i < nof_freq_res; i++) {
|
||||||
|
// Every frequency resource is 6 Resource blocks, every resource block carries 3 pilots. So 18 possible pilots per
|
||||||
|
// frequency resource.
|
||||||
|
const uint32_t nof_pilots_x_resource = 18;
|
||||||
|
|
||||||
|
// Skip frequency resource if outside of the CORESET
|
||||||
|
if (!cfg->coreset.freq_domain_resources[i]) {
|
||||||
|
// Skip possible DMRS locations in this region
|
||||||
|
sequence_skip += nof_pilots_x_resource;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip if the frequency resource highest RB is lower than the first CCE resource block.
|
||||||
|
if ((rb_coreset_idx + 6) <= rb_coreset_idx_begin) {
|
||||||
|
// Skip possible DMRS locations in this region
|
||||||
|
sequence_skip += nof_pilots_x_resource;
|
||||||
|
|
||||||
|
// Since this is part of the CORESET, count the RB as CORESET
|
||||||
|
rb_coreset_idx += 6;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return if the first RB of the frequency resource is greater than the last CCE resource block
|
||||||
|
if (rb_coreset_idx > rb_coreset_idx_end) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip all discarded possible pilot locations
|
||||||
|
srslte_sequence_state_advance(&sequence_state, 2 * sequence_skip);
|
||||||
|
sequence_skip = 0;
|
||||||
|
|
||||||
|
// Generate pilots
|
||||||
|
cf_t rl[nof_pilots_x_resource];
|
||||||
|
srslte_sequence_state_gen_f(&sequence_state, M_SQRT1_2, (float*)rl, nof_pilots_x_resource * 2);
|
||||||
|
|
||||||
|
// For each RB in the frequency resource
|
||||||
|
for (uint32_t j = 0; j < 6; j++) {
|
||||||
|
// Calculate absolute RB index
|
||||||
|
uint32_t n = i * 6 + j;
|
||||||
|
|
||||||
|
// Skip if lower than begin
|
||||||
|
if (rb_coreset_idx < rb_coreset_idx_begin) {
|
||||||
|
rb_coreset_idx++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return if greater than end
|
||||||
|
if (rb_coreset_idx >= rb_coreset_idx_end) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write pilots in the symbol
|
||||||
|
for (uint32_t k_prime = 0; k_prime < 3; k_prime++) {
|
||||||
|
// Calculate sub-carrier index
|
||||||
|
uint32_t k = n * SRSLTE_NRE + 4 * k_prime + 1;
|
||||||
|
|
||||||
|
sf_symbol[k] = rl[(3 * n + k_prime) % nof_pilots_x_resource];
|
||||||
|
}
|
||||||
|
rb_coreset_idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 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/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "srslte/common/test_common.h"
|
||||||
|
#include "srslte/srslte.h"
|
||||||
|
#include <complex.h>
|
||||||
|
#include <srslte/phy/ch_estimation/dmrs_pdcch.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static srslte_nr_carrier_t carrier = {
|
||||||
|
.nof_prb = 50,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t rnti = 0x1234;
|
||||||
|
|
||||||
|
void usage(char* prog)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [recov]\n", prog);
|
||||||
|
|
||||||
|
printf("\t-r nof_prb [Default %d]\n", carrier.nof_prb);
|
||||||
|
printf("\t-e extended cyclic prefix [Default normal]\n");
|
||||||
|
|
||||||
|
printf("\t-c cell_id [Default %d]\n", carrier.id);
|
||||||
|
|
||||||
|
printf("\t-v increase verbosity\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void parse_args(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int opt;
|
||||||
|
while ((opt = getopt(argc, argv, "recov")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'r':
|
||||||
|
carrier.nof_prb = (uint32_t)strtol(argv[optind], NULL, 10);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
carrier.id = (uint32_t)strtol(argv[optind], NULL, 10);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
srslte_verbose++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage(argv[0]);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int run_test(const srslte_nr_pdcch_cfg_t* cfg, cf_t* sf_symbols, cf_t* h)
|
||||||
|
{
|
||||||
|
srslte_dl_sf_cfg_t dl_sf = {};
|
||||||
|
for (dl_sf.tti = 0; dl_sf.tti < SRSLTE_NOF_SF_X_FRAME; dl_sf.tti++) {
|
||||||
|
TESTASSERT(srslte_dmrs_pdcch_put(cfg, &dl_sf, sf_symbols) == SRSLTE_SUCCESS);
|
||||||
|
|
||||||
|
/*srslte_dmrs_pdsch_get_sf(cfg, &dl_sf, sf_symbols, h);
|
||||||
|
|
||||||
|
float mse = 0.0f;
|
||||||
|
for (uint32_t i = 0; i < dmrs_pdsch->nof_symbols * dmrs_pdsch->nof_sc * SRSLTE_NRE; i++) {
|
||||||
|
cf_t err = h[i] - 1.0f;
|
||||||
|
mse += cabsf(err);
|
||||||
|
}
|
||||||
|
mse /= (float)dmrs_pdsch->nof_symbols * dmrs_pdsch->nof_sc;
|
||||||
|
|
||||||
|
TESTASSERT(!isnan(mse));
|
||||||
|
TESTASSERT(mse < 1e-6f);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int ret = SRSLTE_ERROR;
|
||||||
|
|
||||||
|
parse_args(argc, argv);
|
||||||
|
|
||||||
|
srslte_nr_pdcch_cfg_t cfg = {};
|
||||||
|
|
||||||
|
uint32_t nof_re = carrier.nof_prb * SRSLTE_NRE * SRSLTE_NOF_SLOTS_PER_SF * SRSLTE_MAX_NSYMB;
|
||||||
|
cf_t* sf_symbols = srslte_vec_cf_malloc(nof_re);
|
||||||
|
cf_t* h = srslte_vec_cf_malloc(nof_re);
|
||||||
|
|
||||||
|
uint32_t test_counter = 0;
|
||||||
|
uint32_t test_passed = 0;
|
||||||
|
|
||||||
|
cfg.carrier = carrier;
|
||||||
|
cfg.rnti = rnti;
|
||||||
|
cfg.coreset.mapping_type = srslte_coreset_mapping_type_non_interleaved;
|
||||||
|
|
||||||
|
uint32_t nof_frequency_resource = SRSLTE_MIN(SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE, carrier.nof_prb / 6);
|
||||||
|
for (uint32_t frequency_resources = 1; frequency_resources < (1U << nof_frequency_resource); frequency_resources++) {
|
||||||
|
uint32_t nof_freq_resources = 0;
|
||||||
|
for (uint32_t i = 0; i < nof_frequency_resource; i++) {
|
||||||
|
uint32_t mask = ((frequency_resources >> i) & 1U);
|
||||||
|
cfg.coreset.freq_domain_resources[i] = (mask == 1);
|
||||||
|
nof_freq_resources += mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cfg.coreset.duration = 1; cfg.coreset.duration <= 3; cfg.coreset.duration++) {
|
||||||
|
|
||||||
|
for (cfg.search_space.type = srslte_search_space_type_common;
|
||||||
|
cfg.search_space.type <= srslte_search_space_type_ue;
|
||||||
|
cfg.search_space.type++) {
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS; i++) {
|
||||||
|
uint32_t L = 1 << i;
|
||||||
|
uint32_t nof_reg = cfg.coreset.duration * nof_freq_resources * 6;
|
||||||
|
uint32_t nof_cce = nof_reg / 6;
|
||||||
|
cfg.search_space.nof_candidates[i] = nof_cce / L;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cfg.aggregation_level = 0; cfg.aggregation_level < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS;
|
||||||
|
cfg.aggregation_level++) {
|
||||||
|
|
||||||
|
for (cfg.candidate = 0; cfg.candidate < cfg.search_space.nof_candidates[cfg.aggregation_level];
|
||||||
|
cfg.candidate++) {
|
||||||
|
|
||||||
|
if (run_test(&cfg, sf_symbols, h)) {
|
||||||
|
ERROR("Test %d failed\n", test_counter);
|
||||||
|
} else {
|
||||||
|
test_passed++;
|
||||||
|
}
|
||||||
|
test_counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sf_symbols) {
|
||||||
|
free(sf_symbols);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h) {
|
||||||
|
free(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = test_passed == test_counter ? SRSLTE_SUCCESS : SRSLTE_ERROR;
|
||||||
|
printf("%s, %d of %d test passed successfully.\n", ret ? "Failed" : "Passed", test_passed, test_counter);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
Loading…
Reference in New Issue