srsLTE/lib/src/phy/phch/pdsch_nr.c

217 lines
7.6 KiB
C
Raw Normal View History

2020-10-20 02:59:59 -07:00
/*
* 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/phch/pdsch_nr.h"
/**
* @brief copies a number of countiguous Resource Elements
* @param sf_symbols slot symbols in frequency domain
* @param symbols resource elements
* @param count number of resource elements to copy
* @param put Direction, symbols are copied into sf_symbols if put is true, otherwise sf_symbols are copied into symbols
*/
static void srslte_pdsch_re_cp(cf_t* sf_symbols, cf_t* symbols, uint32_t count, bool put)
{
if (put) {
srslte_vec_cf_copy(sf_symbols, symbols, count);
} else {
srslte_vec_cf_copy(symbols, sf_symbols, count);
}
}
2020-11-03 07:06:47 -08:00
static uint32_t srslte_pdsch_nr_cp_dmrs_type1(const srslte_pdsch_nr_t* q,
const srslte_pdsch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols,
bool put)
2020-10-20 02:59:59 -07:00
{
uint32_t count = 0;
uint32_t delta = 0;
for (uint32_t i = 0; i < q->carrier.nof_prb; i++) {
2020-11-03 07:06:47 -08:00
if (grant->prb_idx[i]) {
2020-10-20 02:59:59 -07:00
for (uint32_t j = 0; j < SRSLTE_NRE; j += 2) {
if (put) {
sf_symbols[i * SRSLTE_NRE + delta + j] = symbols[count++];
} else {
symbols[count++] = sf_symbols[i * SRSLTE_NRE + delta + j];
}
}
}
}
return count;
}
2020-11-03 07:06:47 -08:00
static uint32_t srslte_pdsch_nr_cp_dmrs_type2(const srslte_pdsch_nr_t* q,
const srslte_pdsch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols,
bool put)
2020-10-20 02:59:59 -07:00
{
uint32_t count = 0;
uint32_t delta = 0;
for (uint32_t i = 0; i < q->carrier.nof_prb; i++) {
2020-11-03 07:06:47 -08:00
if (grant->prb_idx[i]) {
2020-10-20 02:59:59 -07:00
// Copy RE before first pilot pair
if (delta > 0) {
srslte_pdsch_re_cp(&sf_symbols[i * SRSLTE_NRE], &symbols[count], delta, put);
count += delta;
}
// Copy RE between pilot pairs
srslte_pdsch_re_cp(&sf_symbols[i * SRSLTE_NRE + delta + 2], &symbols[count], 4, put);
count += 4;
// Copy RE after second pilot
srslte_pdsch_re_cp(&sf_symbols[(i + 1) * SRSLTE_NRE - 4 + delta], &symbols[count], 4 - delta, put);
count += 4 - delta;
}
}
return count;
}
2020-11-03 07:06:47 -08:00
static uint32_t srslte_pdsch_nr_cp_dmrs(const srslte_pdsch_nr_t* q,
const srslte_pdsch_cfg_nr_t* cfg,
const srslte_pdsch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols,
bool put)
2020-10-20 02:59:59 -07:00
{
uint32_t count = 0;
2020-11-03 07:06:47 -08:00
const srslte_pdsch_dmrs_cfg_t* dmrs_cfg =
grant->mapping == srslte_pdsch_mapping_type_A ? &cfg->dmrs_cfg_typeA : &cfg->dmrs_cfg_typeB;
switch (dmrs_cfg->type) {
2020-10-20 02:59:59 -07:00
case srslte_dmrs_pdsch_type_1:
2020-11-03 07:06:47 -08:00
count = srslte_pdsch_nr_cp_dmrs_type1(q, grant, symbols, sf_symbols, put);
2020-10-20 02:59:59 -07:00
break;
case srslte_dmrs_pdsch_type_2:
2020-11-03 07:06:47 -08:00
count = srslte_pdsch_nr_cp_dmrs_type2(q, grant, symbols, sf_symbols, put);
2020-10-20 02:59:59 -07:00
break;
}
return count;
}
2020-11-03 07:06:47 -08:00
static uint32_t srslte_pdsch_nr_cp_clean(const srslte_pdsch_nr_t* q,
const srslte_pdsch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols,
bool put)
2020-10-20 02:59:59 -07:00
{
uint32_t count = 0;
uint32_t start = 0; // Index of the start of continuous data
uint32_t length = 0; // End of continuous RE
for (uint32_t i = 0; i < q->carrier.nof_prb; i++) {
2020-11-03 07:06:47 -08:00
if (grant->prb_idx[i]) {
2020-10-20 02:59:59 -07:00
// If fist continuous block, save start
if (length == 0) {
start = i * SRSLTE_NRE;
}
length += SRSLTE_NRE;
} else {
// Consecutive block is finished
if (put) {
srslte_vec_cf_copy(&sf_symbols[start], &symbols[count], length);
} else {
srslte_vec_cf_copy(&symbols[count], &sf_symbols[start], length);
}
// Increase RE count
count += length;
// Reset consecutive block
length = 0;
}
}
// Copy last contiguous block
if (length > 0) {
if (put) {
srslte_vec_cf_copy(&sf_symbols[start], &symbols[count], length);
} else {
srslte_vec_cf_copy(&symbols[count], &sf_symbols[start], length);
}
count += length;
}
return count;
}
2020-11-03 07:06:47 -08:00
static int srslte_pdsch_nr_cp(const srslte_pdsch_nr_t* q,
const srslte_pdsch_cfg_nr_t* cfg,
const srslte_pdsch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols,
bool put)
2020-10-20 02:59:59 -07:00
{
uint32_t count = 0;
uint32_t dmrs_l_idx[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS] = {};
uint32_t dmrs_l_count = 0;
// Get symbol indexes carrying DMRS
2020-11-03 07:06:47 -08:00
int32_t nof_dmrs_symbols = srslte_dmrs_pdsch_get_symbols_idx(cfg, grant, dmrs_l_idx);
2020-10-20 02:59:59 -07:00
if (nof_dmrs_symbols < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
2020-11-03 07:06:47 -08:00
for (uint32_t l = grant->S; l < grant->L; l++) {
2020-10-20 02:59:59 -07:00
// Advance DMRS symbol counter until:
// - the current DMRS symbol index is greater or equal than current symbol l
// - no more DMRS symbols
while (dmrs_l_idx[dmrs_l_count] < l && dmrs_l_count < nof_dmrs_symbols) {
dmrs_l_count++;
}
if (l == dmrs_l_idx[dmrs_l_count]) {
2020-11-03 07:06:47 -08:00
count += srslte_pdsch_nr_cp_dmrs(
q, cfg, grant, &symbols[count], &sf_symbols[l * q->carrier.nof_prb * SRSLTE_NRE], put);
2020-10-20 02:59:59 -07:00
} else {
2020-11-03 07:06:47 -08:00
count +=
srslte_pdsch_nr_cp_clean(q, grant, &symbols[count], &sf_symbols[l * q->carrier.nof_prb * SRSLTE_NRE], put);
2020-10-20 02:59:59 -07:00
}
}
return count;
}
2020-11-03 07:06:47 -08:00
int srslte_pdsch_nr_put(const srslte_pdsch_nr_t* q,
const srslte_pdsch_cfg_nr_t* cfg,
const srslte_pdsch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols)
2020-10-20 02:59:59 -07:00
{
2020-11-03 07:06:47 -08:00
return srslte_pdsch_nr_cp(q, cfg, grant, symbols, sf_symbols, true);
2020-10-20 02:59:59 -07:00
}
int srslte_pdsch_nr_encode(srslte_pdsch_nr_t* q,
2020-10-20 03:00:37 -07:00
uint32_t slot_idx,
2020-10-20 02:59:59 -07:00
srslte_pdsch_cfg_nr_t* cfg,
uint8_t* data[SRSLTE_MAX_CODEWORDS],
2020-10-20 03:00:37 -07:00
cf_t* sf_symbols[SRSLTE_MAX_PORTS])
{
2020-10-20 02:59:59 -07:00
return SRSLTE_SUCCESS;
}