Initial NR DL DCI Packing/Unpacking

This commit is contained in:
Xavier Arteaga 2020-11-13 19:21:27 +01:00 committed by Andre Puschmann
parent fdec451a9d
commit a6ac80cfbf
2 changed files with 449 additions and 0 deletions

View File

@ -0,0 +1,87 @@
/*
* 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_DCI_NR_H
#define SRSLTE_DCI_NR_H
#include "srslte/phy/common/phy_common_nr.h"
#include "srslte/phy/phch/pdsch_cfg_nr.h"
typedef enum SRSLTE_API {
srslte_rnti_type_c = 0,
srslte_rnti_type_p,
srslte_rnti_type_si,
srslte_rnti_type_ra,
srslte_rnti_type_tc,
} srslte_rnti_type_t;
typedef struct SRSLTE_API {
uint8_t payload[32];
srslte_rnti_type_t rnti_type;
uint32_t nof_bits;
srslte_dci_format_nr_t format;
uint16_t rnti;
} srslte_dci_msg_nr_t;
typedef struct SRSLTE_API {
srslte_rnti_type_t rnti_type;
// Common fields
uint32_t freq_domain_assigment; ///< Frequency domain resource assignment
uint32_t time_domain_assigment; ///< Time domain resource assignment
uint32_t vrb_to_prb_mapping; ///< VRB-to-PRB mapping
uint32_t mcs; ///< Modulation and coding scheme
uint32_t rv; ///< Redundancy version
uint32_t reserved; ///< Reserved bits
// C-RNTI/TC-RNTI specific fields
uint32_t ndi; ///< New data indicator
uint32_t pid; ///< HARQ process number
uint32_t dai; ///< Downlink assignment index
uint32_t tpc; ///< TPC command for scheduled PUCCH
uint32_t pucch_resource; ///< PUCCH resource indicator
uint32_t harq_feedback; ///< PDSCH-to-HARQ_feedback timing indicator
// P-RNTI specific fields
uint32_t smi; ///< Short Messages Indicator
uint32_t sm; ///< Short Messages
uint32_t tb_scaling; ///< TB scaling
// SI-RNTI specific fields
uint32_t sii; ///< System information indicator
} srslte_dci_dl_t;
SRSLTE_API SRSLTE_API int srslte_dci_nr_format_1_0_sizeof(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset,
srslte_rnti_type_t rnti_type);
SRSLTE_API int srslte_dci_nr_format_1_0_pack(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset,
const srslte_dci_dl_t* dci,
srslte_dci_msg_nr_t* msg);
SRSLTE_API int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset,
srslte_dci_msg_nr_t* msg,
srslte_dci_dl_t* dci);
#endif // SRSLTE_DCI_NR_H

362
lib/src/phy/phch/dci_nr.c Normal file
View File

@ -0,0 +1,362 @@
/*
* 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/dci_nr.h"
#include "srslte/phy/utils/bit.h"
#include "srslte/phy/utils/debug.h"
static int dci_nr_format_1_0_freq_resource_size(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset0,
srslte_rnti_type_t rnti_type)
{
if (carrier == NULL) {
return SRSLTE_ERROR;
}
uint32_t N_DL_BWP_RB = carrier->nof_prb;
if (rnti_type == srslte_rnti_type_ra && coreset0 != NULL) {
N_DL_BWP_RB = srslte_coreset_get_bw(coreset0);
} else if (rnti_type == srslte_rnti_type_p || rnti_type == srslte_rnti_type_si) {
if (coreset0 == NULL) {
return SRSLTE_ERROR;
}
N_DL_BWP_RB = srslte_coreset_get_bw(coreset0);
}
return (int)ceil(log2(N_DL_BWP_RB * (N_DL_BWP_RB + 1) / 2.0));
}
int srslte_dci_nr_format_1_0_pack(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset,
const srslte_dci_dl_t* dci,
srslte_dci_msg_nr_t* msg)
{
uint8_t* y = msg->payload;
srslte_rnti_type_t rnti_type = msg->rnti_type;
if (carrier == NULL) {
return SRSLTE_ERROR;
}
// Identifier for DCI formats 1 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
*y = 1;
y++;
}
if (rnti_type == srslte_rnti_type_p) {
// Short Messages Indicator 2 bits
srslte_bit_unpack(dci->smi, &y, 2);
// Short Messages 8 bits
srslte_bit_unpack(dci->sm, &y, 8);
}
// Frequency domain resource assignment
int N = dci_nr_format_1_0_freq_resource_size(carrier, coreset, rnti_type);
if (N < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
srslte_bit_unpack(dci->freq_domain_assigment, &y, N);
// Time domain resource assignment 4 bits
srslte_bit_unpack(dci->time_domain_assigment, &y, 4);
// VRB-to-PRB mapping 1 bit
srslte_bit_unpack(dci->vrb_to_prb_mapping, &y, 1);
// Modulation and coding scheme 5 bits
srslte_bit_unpack(dci->mcs, &y, 5);
// TB scaling 2 bits
if (rnti_type == srslte_rnti_type_p || rnti_type == srslte_rnti_type_ra) {
srslte_bit_unpack(dci->tb_scaling, &y, 2);
}
// New data indicator 1 bit
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
srslte_bit_unpack(dci->ndi, &y, 1);
}
// Redundancy version 2 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_si || rnti_type == srslte_rnti_type_tc) {
srslte_bit_unpack(dci->rv, &y, 2);
}
// HARQ process number 4 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
srslte_bit_unpack(dci->pid, &y, 4);
}
// System information indicator 1 bit
if (rnti_type == srslte_rnti_type_si) {
srslte_bit_unpack(dci->sii, &y, 1);
}
// Downlink assignment index 2 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
srslte_bit_unpack(dci->dai, &y, 2);
}
// TPC command for scheduled PUCCH 2 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
srslte_bit_unpack(dci->tpc, &y, 2);
}
// PUCCH resource indicator 3 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
srslte_bit_unpack(dci->pucch_resource, &y, 3);
}
// PDSCH-to-HARQ_feedback timing indicator 3 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
srslte_bit_unpack(dci->harq_feedback, &y, 3);
}
// Reserved bits ...
if (rnti_type == srslte_rnti_type_p) {
// ... 6 bits
srslte_bit_unpack(dci->reserved, &y, 6);
} else if (rnti_type == srslte_rnti_type_si) {
// ... 15 bits
srslte_bit_unpack(dci->reserved, &y, 15);
} else if (rnti_type == srslte_rnti_type_ra) {
// ... 16 bits
srslte_bit_unpack(dci->reserved, &y, 16);
}
msg->nof_bits = srslte_dci_nr_format_1_0_sizeof(carrier, coreset, rnti_type);
if (msg->nof_bits != y - msg->payload) {
ERROR("Unpacked bits readed (%d) do NOT match payload size (%d)\n", msg->nof_bits, (int)(y - msg->payload));
return SRSLTE_ERROR;
}
return SRSLTE_ERROR;
}
int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset,
srslte_dci_msg_nr_t* msg,
srslte_dci_dl_t* dci)
{
uint8_t* y = msg->payload;
srslte_rnti_type_t rnti_type = msg->rnti_type;
if (msg->nof_bits != srslte_dci_nr_format_1_0_sizeof(carrier, coreset, rnti_type)) {
ERROR("Invalid number of bits %d, expected %d\n",
msg->nof_bits,
srslte_dci_nr_format_1_0_sizeof(carrier, coreset, rnti_type));
return SRSLTE_ERROR;
}
// Identifier for DCI formats 1 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
// The value of this bit field is always set to 1, indicating a DL DCI format
if (*y != 1) {
ERROR("Wrond DCI format\n");
return SRSLTE_ERROR;
}
y++;
}
if (rnti_type == srslte_rnti_type_p) {
// Short Messages Indicator 2 bits
dci->smi = srslte_bit_pack(&y, 2);
// Short Messages 8 bits
dci->sm = srslte_bit_pack(&y, 8);
}
// Frequency domain resource assignment
int N = dci_nr_format_1_0_freq_resource_size(carrier, coreset, rnti_type);
if (N < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
dci->freq_domain_assigment = srslte_bit_pack(&y, N);
// Time domain resource assignment 4 bits
dci->time_domain_assigment = srslte_bit_pack(&y, 4);
// VRB-to-PRB mapping 1 bit
dci->vrb_to_prb_mapping = srslte_bit_pack(&y, 1);
// Modulation and coding scheme 5 bits
dci->mcs = srslte_bit_pack(&y, 5);
// TB scaling 2 bits
if (rnti_type == srslte_rnti_type_p || rnti_type == srslte_rnti_type_ra) {
dci->tb_scaling = srslte_bit_pack(&y, 2);
}
// New data indicator 1 bit
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
dci->ndi = srslte_bit_pack(&y, 1);
}
// Redundancy version 2 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_si || rnti_type == srslte_rnti_type_tc) {
dci->rv = srslte_bit_pack(&y, 2);
}
// HARQ process number 4 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
dci->pid = srslte_bit_pack(&y, 4);
}
// System information indicator 1 bit
if (rnti_type == srslte_rnti_type_si) {
dci->sii = srslte_bit_pack(&y, 1);
}
// Downlink assignment index 2 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
dci->dai = srslte_bit_pack(&y, 2);
}
// TPC command for scheduled PUCCH 2 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
dci->tpc = srslte_bit_pack(&y, 2);
}
// PUCCH resource indicator 3 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
dci->pucch_resource = srslte_bit_pack(&y, 3);
}
// PDSCH-to-HARQ_feedback timing indicator 3 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
dci->harq_feedback = srslte_bit_pack(&y, 3);
}
// Reserved bits ...
if (rnti_type == srslte_rnti_type_p) {
// ... 6 bits
dci->reserved = srslte_bit_pack(&y, 6);
} else if (rnti_type == srslte_rnti_type_si) {
// ... 15 bits
dci->reserved = srslte_bit_pack(&y, 15);
} else if (rnti_type == srslte_rnti_type_ra) {
// ... 16 bits
dci->reserved = srslte_bit_pack(&y, 16);
}
if (msg->nof_bits != y - msg->payload) {
ERROR("Unpacked bits readed (%d) do NOT match payload size (%d)\n", msg->nof_bits, (int)(y - msg->payload));
return SRSLTE_ERROR;
}
return SRSLTE_ERROR;
}
int srslte_dci_nr_format_1_0_sizeof(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset,
srslte_rnti_type_t rnti_type)
{
uint32_t count = 0;
// Identifier for DCI formats 1 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
count += 1;
}
if (rnti_type == srslte_rnti_type_p) {
// Short Messages Indicator 2 bits
count += 2;
// Short Messages 8 bits
count += 8;
}
// Frequency domain resource assignment
int N = dci_nr_format_1_0_freq_resource_size(carrier, coreset, rnti_type);
if (N < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
count += N;
// Time domain resource assignment 4 bits
count += 4;
// VRB-to-PRB mapping 1 bit
count += 1;
// Modulation and coding scheme 5 bits
count += 5;
// TB scaling 2 bits
if (rnti_type == srslte_rnti_type_p || rnti_type == srslte_rnti_type_ra) {
count += 2;
}
// New data indicator 1 bit
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
count += 1;
}
// Redundancy version 2 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_si || rnti_type == srslte_rnti_type_tc) {
count += 2;
}
// HARQ process number 4 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
count += 4;
}
// System information indicator 1 bit
if (rnti_type == srslte_rnti_type_si) {
count += 1;
}
// Downlink assignment index 2 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
count += 2;
}
// TPC command for scheduled PUCCH 2 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
count += 2;
}
// PUCCH resource indicator 3 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
count += 3;
}
// PDSCH-to-HARQ_feedback timing indicator 3 bits
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
count += 3;
}
// Reserved bits ...
if (rnti_type == srslte_rnti_type_p) {
// ... 6 bits
count += 2;
} else if (rnti_type == srslte_rnti_type_si) {
// ... 15 bits
count += 15;
} else if (rnti_type == srslte_rnti_type_ra) {
// ... 16 bits
count += 16;
}
return count;
}