ULSCH decoding functionality at gNB side
Added the following structs and enums in "defs_gNB.h" - NR_UL_gNB_HARQ_t - NR_gNB_ULSCH_t - NR_SCH_status_t added the following structs in "nfapi_nr_interface.h" - nfapi_nr_ul_config_ulsch_pdu - nfapi_nr_ul_config_ulsch_pdu_rel15_t - nfapi_nr_ul_srs_config_t - nr_pusch_freq_hopping_t added nr_ulsch.h for the ulsch decoding function declarations - free_gNB_ulsch - new_gNB_ulsch - nr_ulsch_decoding added nr_ulsch_decoding.c for the implementation of the ulsch decoding functions - free_gNB_ulsch - new_gNB_ulsch - nr_ulsch_decoding
This commit is contained in:
@@ -1275,6 +1275,7 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_tools.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_coding.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
|
||||
|
||||
@@ -673,4 +673,45 @@ typedef struct {
|
||||
nfapi_vendor_extension_tlv_t vendor_extension;
|
||||
} nfapi_nr_dl_config_request_t;
|
||||
|
||||
|
||||
typedef enum {nr_pusch_freq_hopping_disabled = 0 ,
|
||||
nr_pusch_freq_hopping_enabled = 1
|
||||
} nr_pusch_freq_hopping_t;
|
||||
|
||||
typedef struct{
|
||||
uint8_t aperiodicSRS_ResourceTrigger;
|
||||
} nfapi_nr_ul_srs_config_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t bandwidth_part_ind;
|
||||
uint16_t number_rbs;
|
||||
uint16_t start_rb;
|
||||
uint8_t frame_offset;
|
||||
uint16_t number_symbols;
|
||||
uint16_t start_symbol;
|
||||
nr_pusch_freq_hopping_t pusch_freq_hopping;
|
||||
uint8_t mcs;
|
||||
uint8_t Qm;
|
||||
uint8_t ndi;
|
||||
uint8_t rv;
|
||||
uint8_t harq_process_nbr;
|
||||
int8_t accumulated_delta_PUSCH;
|
||||
int8_t absolute_delta_PUSCH;
|
||||
uint8_t n_layers;
|
||||
uint8_t tpmi;
|
||||
uint8_t n_dmrs_cdm_groups;
|
||||
uint8_t dmrs_ports[4];
|
||||
uint8_t n_front_load_symb;
|
||||
nfapi_nr_ul_srs_config_t srs_config;
|
||||
uint8_t csi_reportTriggerSize;
|
||||
uint8_t maxCodeBlockGroupsPerTransportBlock;
|
||||
uint8_t ptrs_dmrs_association_port;
|
||||
uint8_t beta_offset_ind;
|
||||
} nfapi_nr_ul_config_ulsch_pdu_rel15_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t rnti;
|
||||
nfapi_nr_ul_config_ulsch_pdu_rel15_t ulsch_pdu_rel15;
|
||||
} nfapi_nr_ul_config_ulsch_pdu;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_TRANSPORT/nr_ulsch.h
|
||||
* \brief functions used for PUSCH/ULSCH physical and transport channels for gNB
|
||||
* \author Ahmed Hussein
|
||||
* \date 2019
|
||||
* \version 0.1
|
||||
* \company Fraunhofer IIS
|
||||
* \email: ahmed.hussein@iis.fraunhofer.de
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
|
||||
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
|
||||
|
||||
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag);
|
||||
|
||||
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
uint8_t UE_id,
|
||||
short *ulsch_llr,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint32_t frame,
|
||||
uint16_t nb_symb_sch,
|
||||
uint8_t nr_tti_rx,
|
||||
uint8_t harq_pid,
|
||||
uint8_t is_crnti,
|
||||
uint8_t llr8_flag);
|
||||
|
||||
@@ -0,0 +1,583 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_TRANSPORT/nr_ulsch_decoding.c
|
||||
* \brief Top-level routines for decoding LDPC (ULSCH) transport channels from 38.212, V15.4.0 2018-12
|
||||
* \author Ahmed Hussein
|
||||
* \date 2019
|
||||
* \version 0.1
|
||||
* \company Fraunhofer IIS
|
||||
* \email: ahmed.hussein@iis.fraunhofer.de
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
|
||||
// [from gNB coding]
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/phy_extern.h"
|
||||
#include "PHY/CODING/coding_extern.h"
|
||||
#include "PHY/CODING/coding_defs.h"
|
||||
#include "PHY/CODING/lte_interleaver_inline.h"
|
||||
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
|
||||
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
|
||||
#include "SCHED_NR/sched_nr.h"
|
||||
#include "defs.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include <syscall.h>
|
||||
//#define DEBUG_ULSCH_DECODING
|
||||
|
||||
#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
|
||||
|
||||
static uint64_t nb_total_decod =0;
|
||||
static uint64_t nb_error_decod =0;
|
||||
|
||||
//extern double cpuf;
|
||||
|
||||
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
|
||||
{
|
||||
|
||||
int i,r;
|
||||
|
||||
if (ulsch) {
|
||||
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
|
||||
|
||||
if (ulsch->harq_processes[i]) {
|
||||
if (ulsch->harq_processes[i]->b) {
|
||||
free16(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES);
|
||||
ulsch->harq_processes[i]->b = NULL;
|
||||
}
|
||||
for (r=0; r<MAX_NUM_NR_ULSCH_SEGMENTS; r++) {
|
||||
free16(ulsch->harq_processes[i]->c[r],(8448)*sizeof(uint8_t));
|
||||
ulsch->harq_processes[i]->c[r] = NULL;
|
||||
}
|
||||
for (r=0; r<MAX_NUM_NR_ULSCH_SEGMENTS; r++) {
|
||||
if (ulsch->harq_processes[i]->d[r]) {
|
||||
free16(ulsch->harq_processes[i]->d[r],(68*384)*sizeof(int16_t));
|
||||
ulsch->harq_processes[i]->d[r] = NULL;
|
||||
}
|
||||
}
|
||||
for (r=0; r<(MAX_NUM_NR_ULSCH_SEGMENTS); r++) {
|
||||
if (ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]){
|
||||
nrLDPC_free_mem(ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]);
|
||||
ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL;
|
||||
}
|
||||
}
|
||||
free16(ulsch->harq_processes[i],sizeof(NR_UL_gNB_HARQ_t));
|
||||
ulsch->harq_processes[i] = NULL;
|
||||
}
|
||||
}
|
||||
free16(ulsch,sizeof(NR_gNB_ULSCH_t));
|
||||
ulsch = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag)
|
||||
{
|
||||
|
||||
NR_gNB_ULSCH_t *ulsch;
|
||||
uint8_t exit_flag = 0,i,r;
|
||||
unsigned char bw_scaling =1;
|
||||
|
||||
switch (N_RB_UL) {
|
||||
case 106:
|
||||
bw_scaling =2;
|
||||
break;
|
||||
|
||||
default:
|
||||
bw_scaling =1;
|
||||
break;
|
||||
}
|
||||
|
||||
ulsch = (NR_gNB_ULSCH_t *)malloc16(sizeof(NR_gNB_ULSCH_t));
|
||||
|
||||
if (ulsch) {
|
||||
|
||||
memset(ulsch,0,sizeof(NR_gNB_ULSCH_t));
|
||||
|
||||
ulsch->max_ldpc_iterations = max_ldpc_iterations;
|
||||
ulsch->Mlimit = 4;
|
||||
|
||||
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
|
||||
|
||||
ulsch->harq_processes[i] = (NR_UL_gNB_HARQ_t *)malloc16(sizeof(NR_UL_gNB_HARQ_t));
|
||||
|
||||
if (ulsch->harq_processes[i]) {
|
||||
|
||||
memset(ulsch->harq_processes[i],0,sizeof(NR_UL_gNB_HARQ_t));
|
||||
|
||||
ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
|
||||
|
||||
if (ulsch->harq_processes[i]->b)
|
||||
memset(ulsch->harq_processes[i]->b,0,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
|
||||
else
|
||||
exit_flag=3;
|
||||
|
||||
if (abstraction_flag == 0) {
|
||||
for (r=0; r<MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling; r++) {
|
||||
|
||||
ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
|
||||
|
||||
ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448*sizeof(uint8_t));
|
||||
|
||||
if (ulsch->harq_processes[i]->c[r])
|
||||
memset(ulsch->harq_processes[i]->c[r],0,8448*sizeof(uint8_t));
|
||||
else
|
||||
exit_flag=2;
|
||||
|
||||
ulsch->harq_processes[i]->d[r] = (int16_t*)malloc16((68*384)*sizeof(int16_t));
|
||||
|
||||
if (ulsch->harq_processes[i]->d[r])
|
||||
memset(ulsch->harq_processes[i]->d[r],0,(68*384)*sizeof(int16_t));
|
||||
else
|
||||
exit_flag=2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
exit_flag=1;
|
||||
}
|
||||
}
|
||||
|
||||
if (exit_flag==0)
|
||||
return(ulsch);
|
||||
}
|
||||
|
||||
printf("new_gNB_ulsch with size %zu: exit_flag = %u\n",sizeof(NR_UL_gNB_HARQ_t), exit_flag);
|
||||
free_gNB_ulsch(ulsch);
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
uint8_t UE_id,
|
||||
short *ulsch_llr,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint32_t frame,
|
||||
uint16_t nb_symb_sch,
|
||||
uint8_t nr_tti_rx,
|
||||
uint8_t harq_pid,
|
||||
uint8_t is_crnti,
|
||||
uint8_t llr8_flag)
|
||||
{
|
||||
|
||||
uint32_t A,E;
|
||||
uint32_t G;
|
||||
uint32_t ret,offset;
|
||||
int32_t no_iteration_ldpc;
|
||||
uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0;
|
||||
uint8_t crc_type;
|
||||
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
|
||||
|
||||
|
||||
NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0];
|
||||
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
|
||||
nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &harq_process->ulsch_pdu.ulsch_pdu_rel15;
|
||||
|
||||
t_nrLDPC_dec_params decParams;
|
||||
t_nrLDPC_dec_params* p_decParams = &decParams;
|
||||
t_nrLDPC_time_stats procTime;
|
||||
t_nrLDPC_time_stats* p_procTime = &procTime ;
|
||||
t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
|
||||
|
||||
int16_t z [68*384];
|
||||
int8_t l [68*384];
|
||||
int16_t inv_d [68*384];
|
||||
uint8_t kb, kc;
|
||||
uint8_t Ilbrm = 0;
|
||||
uint32_t Tbslbrm = 950984;
|
||||
uint16_t nb_rb = 30; //to update
|
||||
uint8_t nb_re_dmrs = 6;
|
||||
uint16_t length_dmrs = 1;
|
||||
|
||||
uint32_t i,j;
|
||||
|
||||
__m128i *pv = (__m128i*)&z;
|
||||
__m128i *pl = (__m128i*)&l;
|
||||
|
||||
|
||||
if (!ulsch_llr) {
|
||||
printf("ulsch_decoding.c: NULL ulsch_llr pointer\n");
|
||||
return(ulsch->max_ldpc_iterations);
|
||||
}
|
||||
|
||||
if (!harq_process) {
|
||||
printf("ulsch_decoding.c: NULL harq_process pointer\n");
|
||||
return(ulsch->max_ldpc_iterations);
|
||||
}
|
||||
|
||||
if (!frame_parms) {
|
||||
printf("ulsch_decoding.c: NULL frame_parms pointer\n");
|
||||
return(ulsch->max_ldpc_iterations);
|
||||
}
|
||||
|
||||
nb_rb = nfapi_ulsch_pdu_rel15->number_rbs;
|
||||
|
||||
// harq_process->trials[nfapi_ulsch_pdu_rel15->round]++;
|
||||
|
||||
harq_process->TBS = nr_compute_tbs(nfapi_ulsch_pdu_rel15->mcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->n_layers);
|
||||
|
||||
A = harq_process->TBS;
|
||||
ret = ulsch->max_ldpc_iterations;
|
||||
|
||||
harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->Qm,nfapi_ulsch_pdu_rel15->n_layers);
|
||||
G = harq_process->G;
|
||||
|
||||
LOG_I(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nfapi_ulsch_pdu_rel15->mcs, nfapi_ulsch_pdu_rel15->n_layers, nb_symb_sch,nb_rb);
|
||||
|
||||
if (harq_process->round == 0) {
|
||||
// This is a new packet, so compute quantities regarding segmentation
|
||||
harq_process->B = A+24;
|
||||
|
||||
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
|
||||
nr_segmentation(NULL,
|
||||
NULL,
|
||||
harq_process->B,
|
||||
&harq_process->C,
|
||||
&harq_process->K,
|
||||
&harq_process->Z, // [hna] Z is Zc
|
||||
&harq_process->F);
|
||||
|
||||
p_decParams->Z = harq_process->Z;
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
printf("ulsch decoding nr segmentation Z %d\n", p_decParams->Z);
|
||||
if (!frame%100)
|
||||
printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
|
||||
#endif
|
||||
}
|
||||
|
||||
kb = harq_process->K/harq_process->Z;
|
||||
|
||||
if ( kb==22) {
|
||||
p_decParams->BG = 1;
|
||||
p_decParams->R = 13;
|
||||
kc = 68;
|
||||
} else {
|
||||
p_decParams->BG = 2;
|
||||
p_decParams->R = 13;
|
||||
kc = 52;
|
||||
}
|
||||
|
||||
p_decParams->numMaxIter = ulsch->max_ldpc_iterations;
|
||||
Kr = p_decParams->Z*kb;
|
||||
p_decParams->outMode= 0;
|
||||
|
||||
err_flag = 0;
|
||||
r_offset = 0;
|
||||
|
||||
unsigned char bw_scaling =1;
|
||||
|
||||
switch (frame_parms->N_RB_UL) {
|
||||
|
||||
case 106:
|
||||
bw_scaling =2;
|
||||
break;
|
||||
|
||||
default:
|
||||
bw_scaling =1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (harq_process->C > MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling) {
|
||||
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling);
|
||||
return((1+ulsch->max_ldpc_iterations));
|
||||
}
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
|
||||
#endif
|
||||
|
||||
opp_enabled=1;
|
||||
|
||||
Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb"
|
||||
Kr_bytes = Kr>>3;
|
||||
|
||||
K_bytes_F = Kr_bytes-(harq_process->F>>3);
|
||||
|
||||
Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, nfapi_ulsch_pdu_rel15->n_layers);
|
||||
|
||||
for (r=0; r<harq_process->C; r++) {
|
||||
|
||||
E = nr_get_E(G, harq_process->C, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers, r);
|
||||
|
||||
#if gNB_TIMING_TRACE
|
||||
start_meas(ulsch_deinterleaving_stats);
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////// ulsch_llr =====> harq_process->e //////////////////////////////
|
||||
|
||||
nr_deinterleaving_ldpc(E,
|
||||
nfapi_ulsch_pdu_rel15->Qm,
|
||||
harq_process->e[r],
|
||||
ulsch_llr+r_offset);
|
||||
|
||||
//for (int i =0; i<16; i++)
|
||||
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
|
||||
|
||||
#if gNB_TIMING_TRACE
|
||||
stop_meas(ulsch_deinterleaving_stats);
|
||||
#endif
|
||||
|
||||
#if gNB_TIMING_TRACE
|
||||
start_meas(ulsch_rate_unmatching_stats);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
|
||||
harq_pid,r, G,
|
||||
Kr*3,
|
||||
harq_process->TBS,
|
||||
nfapi_ulsch_pdu_rel15->Qm,
|
||||
nfapi_ulsch_pdu_rel15->number_rbs,
|
||||
nfapi_ulsch_pdu_rel15->n_layers,
|
||||
nfapi_ulsch_pdu_rel15->rv,
|
||||
harq_process->round);
|
||||
#endif
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////// harq_process->e =====> harq_process->d /////////////////////////
|
||||
|
||||
if (nr_rate_matching_ldpc_rx(Ilbrm,
|
||||
Tbslbrm,
|
||||
p_decParams->BG,
|
||||
p_decParams->Z,
|
||||
harq_process->d[r],
|
||||
harq_process->e[r],
|
||||
harq_process->C,
|
||||
nfapi_ulsch_pdu_rel15->rv,
|
||||
(harq_process->round==0)?1:0,
|
||||
E)==-1) {
|
||||
#if gNB_TIMING_TRACE
|
||||
stop_meas(ulsch_rate_unmatching_stats);
|
||||
#endif
|
||||
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
|
||||
return(ulsch->max_ldpc_iterations);
|
||||
} else {
|
||||
#if gNB_TIMING_TRACE
|
||||
stop_meas(ulsch_rate_unmatching_stats);
|
||||
#endif
|
||||
}
|
||||
|
||||
r_offset += E;
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
if (r==0) {
|
||||
write_output("decoder_llr.m","decllr",ulsch_llr,G,1,0);
|
||||
write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0);
|
||||
}
|
||||
|
||||
printf("decoder input(segment %d) :",r);
|
||||
int i;
|
||||
for (i=0;i<(3*8*Kr_bytes)+12;i++)
|
||||
printf("%d : %d\n",i,harq_process->d[r][i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
|
||||
// printf("Clearing c, %p\n",harq_process->c[r]);
|
||||
memset(harq_process->c[r],0,Kr_bytes);
|
||||
|
||||
// printf("done\n");
|
||||
if (harq_process->C == 1)
|
||||
crc_type = CRC24_A;
|
||||
else
|
||||
crc_type = CRC24_B;
|
||||
|
||||
if (err_flag == 0) {
|
||||
|
||||
#if gNB_TIMING_TRACE
|
||||
start_meas(ulsch_turbo_decoding_stats);
|
||||
#endif
|
||||
|
||||
for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++) {
|
||||
inv_d[cnt] = (1)*harq_process->d[r][cnt];
|
||||
}
|
||||
|
||||
memset(pv,0,2*harq_process->Z*sizeof(int16_t));
|
||||
memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));
|
||||
|
||||
for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F+((2*p_decParams->Z)>>3); i++, j++) {
|
||||
pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j]));
|
||||
}
|
||||
|
||||
for (i=Kr_bytes+((2*p_decParams->Z)>>3),j=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) {
|
||||
pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j]));
|
||||
}
|
||||
|
||||
for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) {
|
||||
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////// nrLDPC_decoder /////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
|
||||
|
||||
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
|
||||
(int8_t*)&pl[0],
|
||||
llrProcBuf,
|
||||
p_nrLDPC_procBuf[r],
|
||||
p_procTime);
|
||||
|
||||
if (check_crc(llrProcBuf,harq_process->B,harq_process->F,crc_type)) {
|
||||
printf("CRC OK\n");
|
||||
ret = 2;
|
||||
} else {
|
||||
printf("CRC NOK\n");
|
||||
ret = 1+ulsch->max_ldpc_iterations;
|
||||
}
|
||||
|
||||
nb_total_decod++;
|
||||
if (no_iteration_ldpc > ulsch->max_ldpc_iterations){
|
||||
nb_error_decod++;
|
||||
}
|
||||
|
||||
ret=no_iteration_ldpc;
|
||||
|
||||
for (int m=0; m < Kr>>3; m ++) {
|
||||
harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
//printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
||||
for (int k=0;k<A>>3;k++)
|
||||
printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
|
||||
printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret);
|
||||
//write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
|
||||
#endif
|
||||
|
||||
#if gNB_TIMING_TRACE
|
||||
stop_meas(ulsch_turbo_decoding_stats);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((err_flag == 0) && (ret>=(1+ulsch->max_ldpc_iterations))) {
|
||||
// a Code segment is in error so break;
|
||||
LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
|
||||
err_flag = 1;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
int32_t frame_rx_prev = frame;
|
||||
int32_t tti_rx_prev = nr_tti_rx - 1;
|
||||
if (tti_rx_prev < 0) {
|
||||
frame_rx_prev--;
|
||||
tti_rx_prev += 10*frame_parms->ttis_per_subframe;
|
||||
}
|
||||
frame_rx_prev = frame_rx_prev%1024;
|
||||
|
||||
if (err_flag == 1) {
|
||||
|
||||
#if gNB_DEBUG_TRACE
|
||||
LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
|
||||
phy_vars_gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
|
||||
#endif
|
||||
|
||||
// harq_process->harq_ack.ack = 0;
|
||||
// harq_process->harq_ack.harq_id = harq_pid;
|
||||
// harq_process->harq_ack.send_harq_status = 1;
|
||||
// harq_process->errors[harq_process->round]++;
|
||||
harq_process->round++;
|
||||
|
||||
if (harq_process->round >= ulsch->Mlimit) {
|
||||
harq_process->status = SCH_IDLE;
|
||||
harq_process->round = 0;
|
||||
harq_process->handled = 0;
|
||||
ulsch->harq_mask &= ~(1 << harq_pid);
|
||||
}
|
||||
|
||||
if(is_crnti) {
|
||||
LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
|
||||
phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
|
||||
}
|
||||
|
||||
harq_process->handled = 1;
|
||||
return((1+ulsch->max_ldpc_iterations));
|
||||
|
||||
} else {
|
||||
|
||||
#if gNB_DEBUG_TRACE
|
||||
LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
|
||||
phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
|
||||
#endif
|
||||
|
||||
harq_process->status = SCH_IDLE;
|
||||
harq_process->round = 0;
|
||||
// harq_process->handled = 0;
|
||||
ulsch->harq_mask &= ~(1 << harq_pid);
|
||||
// harq_process->harq_ack.ack = 1;
|
||||
// harq_process->harq_ack.harq_id = harq_pid;
|
||||
// harq_process->harq_ack.send_harq_status = 1;
|
||||
|
||||
if(is_crnti)
|
||||
{
|
||||
LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
|
||||
}
|
||||
}
|
||||
|
||||
// Reassembly of Transport block here
|
||||
offset = 0;
|
||||
Kr = harq_process->K;
|
||||
Kr_bytes = Kr>>3;
|
||||
|
||||
for (r=0; r<harq_process->C; r++) {
|
||||
|
||||
memcpy(harq_process->b+offset,
|
||||
harq_process->c[r],
|
||||
Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
|
||||
|
||||
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes);
|
||||
printf("copied %d bytes to b sequence (harq_pid %d)\n",
|
||||
(Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
|
||||
printf("b[0] = %x,c[%d] = %x\n",
|
||||
harq_process->b[offset],
|
||||
harq_process->F>>3,
|
||||
harq_process->c[r]);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
ulsch->last_iteration_cnt = ret;
|
||||
|
||||
return(ret);
|
||||
}
|
||||
+186
-9
@@ -38,6 +38,10 @@
|
||||
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
||||
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#include "PHY/impl_defs_top.h"
|
||||
#include "PHY/defs_common.h"
|
||||
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
|
||||
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
|
||||
|
||||
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
|
||||
|
||||
@@ -72,6 +76,7 @@ typedef struct {
|
||||
uint64_t dci_pdu[2];
|
||||
} NR_gNB_DCI_ALLOC_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t num_dci;
|
||||
uint8_t num_pdsch_rnti;
|
||||
@@ -79,6 +84,14 @@ typedef struct {
|
||||
} NR_gNB_PDCCH;
|
||||
|
||||
|
||||
typedef enum {
|
||||
NR_SCH_IDLE,
|
||||
NR_ACTIVE,
|
||||
NR_CBA_ACTIVE,
|
||||
NR_DISABLED
|
||||
} NR_SCH_status_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// Nfapi DLSCH PDU
|
||||
nfapi_nr_dl_config_dlsch_pdu dlsch_pdu;
|
||||
@@ -114,7 +127,6 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
/// Pointers to 16 HARQ processes for the DLSCH
|
||||
NR_DL_gNB_HARQ_t *harq_processes[NR_MAX_NB_HARQ_PROCESSES];
|
||||
/// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding)
|
||||
@@ -160,6 +172,170 @@ typedef struct {
|
||||
} NR_gNB_DLSCH_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// Nfapi ULSCH PDU
|
||||
nfapi_nr_ul_config_ulsch_pdu ulsch_pdu;
|
||||
/// Frame where current HARQ round was sent
|
||||
uint32_t frame;
|
||||
/// Subframe where current HARQ round was sent
|
||||
uint32_t subframe;
|
||||
/// Index of current HARQ round for this DLSCH
|
||||
uint8_t round;
|
||||
/// Last TPC command
|
||||
uint8_t TPC;
|
||||
/// MIMO mode for this DLSCH
|
||||
MIMO_mode_t mimo_mode;
|
||||
/// Flag indicating that this ULSCH has been allocated by a DCI (otherwise it is a retransmission based on PHICH NAK)
|
||||
uint8_t dci_alloc;
|
||||
/// Flag indicating that this ULSCH has been allocated by a RAR (otherwise it is a retransmission based on PHICH NAK or DCI)
|
||||
uint8_t rar_alloc;
|
||||
/// Status Flag indicating for this ULSCH (idle,active,disabled)
|
||||
NR_SCH_status_t status;
|
||||
/// Subframe scheduling indicator (i.e. Transmission opportunity indicator)
|
||||
uint8_t subframe_scheduling_flag;
|
||||
/// Subframe cba scheduling indicator (i.e. CBA Transmission opportunity indicator)
|
||||
uint8_t subframe_cba_scheduling_flag;
|
||||
/// PHICH active flag
|
||||
uint8_t phich_active;
|
||||
/// PHICH ACK
|
||||
uint8_t phich_ACK;
|
||||
/// First Allocated RB - previous scheduling. This is needed for PHICH generation which is done after a new scheduling
|
||||
uint16_t previous_first_rb;
|
||||
/// Flag to indicate that the UL configuration has been handled. Used to remove a stale ULSCH when frame wraps around
|
||||
uint8_t handled;
|
||||
/// Flag to indicate that this ULSCH is for calibration information sent from UE (i.e. no MAC SDU to pass up)
|
||||
// int calibration_flag;
|
||||
/// delta_TF for power control
|
||||
int32_t delta_TF;
|
||||
|
||||
|
||||
/////////////////////// ulsch decoding ///////////////////////
|
||||
/// Transport block size (This is A from 38.212 V15.4.0 section 5.1)
|
||||
uint32_t TBS;
|
||||
/// Pointer to the payload (38.212 V15.4.0 section 5.1)
|
||||
uint8_t *b;
|
||||
/// The payload + CRC (24 bits) in bits (38.212 V15.4.0 section 5.1)
|
||||
uint32_t B;
|
||||
/// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2)
|
||||
uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS];
|
||||
/// Number of bits in each code block (38.212 V15.4.0 section 5.2.2)
|
||||
uint32_t K;
|
||||
/// Number of "Filler" bits added in the code block segmentation (38.212 V15.4.0 section 5.2.2)
|
||||
uint32_t F;
|
||||
/// Number of code blocks after code block segmentation (38.212 V15.4.0 section 5.2.2)
|
||||
uint32_t C;
|
||||
/// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2)
|
||||
int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS];
|
||||
/// LDPC processing buffer
|
||||
t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS];
|
||||
/// LDPC lifting size (38.212 V15.4.0 table 5.3.2-1)
|
||||
uint32_t Z;
|
||||
/// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
|
||||
int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
|
||||
/// Number of bits in each code block after rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
|
||||
uint32_t E;
|
||||
/// Number of soft channel bits after code block concatenation (38.212 V15.4.0 section 5.5)
|
||||
uint32_t G;
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////// DMRS /////////////////////////////
|
||||
/// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2)
|
||||
uint8_t n_DMRS;
|
||||
/// n_DMRS 2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1)
|
||||
uint8_t n_DMRS2;
|
||||
/// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) - previous scheduling
|
||||
/// This is needed for PHICH generation which
|
||||
/// is done after a new scheduling
|
||||
uint8_t previous_n_DMRS;
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////// UCI multiplexing ///////////////////////
|
||||
/// CQI CRC status
|
||||
uint8_t cqi_crc_status;
|
||||
/// Pointer to CQI data
|
||||
uint8_t o[MAX_CQI_BYTES];
|
||||
/// Format of CQI data
|
||||
UCI_format_t uci_format;
|
||||
/// Length of CQI data under RI=1 assumption(bits)
|
||||
uint8_t Or1;
|
||||
/// Length of CQI data under RI=2 assumption(bits)
|
||||
uint8_t Or2;
|
||||
/// Rank information
|
||||
uint8_t o_RI[2];
|
||||
/// Length of rank information (bits)
|
||||
uint8_t O_RI;
|
||||
/// Pointer to ACK
|
||||
uint8_t o_ACK[4];
|
||||
/// Length of ACK information (bits)
|
||||
uint8_t O_ACK;
|
||||
/// The value of DAI in DCI format 0
|
||||
uint8_t V_UL_DAI;
|
||||
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
|
||||
int8_t q[MAX_CQI_PAYLOAD];
|
||||
/// number of coded CQI bits after interleaving
|
||||
uint8_t o_RCC;
|
||||
/// coded and interleaved CQI bits
|
||||
int8_t o_w[(MAX_CQI_BITS+8)*3];
|
||||
/// coded CQI bits
|
||||
int8_t o_d[96+((MAX_CQI_BITS+8)*3)];
|
||||
/// coded ACK bits
|
||||
int16_t q_ACK[MAX_ACK_PAYLOAD];
|
||||
/// coded RI bits
|
||||
int16_t q_RI[MAX_RI_PAYLOAD];
|
||||
/// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
|
||||
uint8_t h[MAX_NUM_CHANNEL_BITS];
|
||||
/// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||
int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
|
||||
//////////////////////////////////////////////////////////////
|
||||
} NR_UL_gNB_HARQ_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// Pointers to 16 HARQ processes for the ULSCH
|
||||
NR_UL_gNB_HARQ_t *harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES];
|
||||
/// Current HARQ process id
|
||||
int harq_process_id[NR_MAX_SLOTS_PER_FRAME];
|
||||
/// HARQ process mask, indicates which processes are currently active
|
||||
uint16_t harq_mask;
|
||||
/// ACK/NAK Bundling flag
|
||||
uint8_t bundling;
|
||||
/// beta_offset_cqi times 8
|
||||
uint16_t beta_offset_cqi_times8;
|
||||
/// beta_offset_ri times 8
|
||||
uint16_t beta_offset_ri_times8;
|
||||
/// beta_offset_harqack times 8
|
||||
uint16_t beta_offset_harqack_times8;
|
||||
/// Flag to indicate that gNB awaits UE Msg3
|
||||
uint8_t Msg3_active;
|
||||
/// Flag to indicate that gNB should decode UE Msg3
|
||||
uint8_t Msg3_flag;
|
||||
/// Subframe for Msg3
|
||||
uint8_t Msg3_subframe;
|
||||
/// Frame for Msg3
|
||||
uint32_t Msg3_frame;
|
||||
/// Allocated RNTI for this ULSCH
|
||||
uint16_t rnti;
|
||||
/// RNTI type
|
||||
uint8_t rnti_type;
|
||||
/// cyclic shift for DM RS
|
||||
uint8_t cyclicShift;
|
||||
/// for cooperative communication
|
||||
uint8_t cooperation_flag;
|
||||
/// Maximum number of HARQ rounds
|
||||
uint8_t Mlimit;
|
||||
/// Maximum number of LDPC iterations
|
||||
uint8_t max_ldpc_iterations;
|
||||
/// number of iterations used in last LDPC decoding
|
||||
uint8_t last_iteration_cnt;
|
||||
/// num active cba group
|
||||
uint8_t num_active_cba_groups;
|
||||
/// num active cba group
|
||||
uint16_t cba_rnti[NUM_MAX_CBA_GROUP];
|
||||
} NR_gNB_ULSCH_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// \brief Pointers (dynamic) to the received data in the time domain.
|
||||
/// - first index: rx antenna [0..nb_antennas_rx[
|
||||
@@ -394,17 +570,18 @@ typedef struct PHY_VARS_gNB_s {
|
||||
LTE_eNB_PHICH phich_vars[2];
|
||||
|
||||
NR_gNB_COMMON common_vars;
|
||||
LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_PRACH prach_vars;
|
||||
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX][2]; // Nusers times two spatial streams
|
||||
LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA
|
||||
LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_PRACH prach_vars;
|
||||
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX][2]; // Nusers times two spatial streams
|
||||
NR_gNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1][2]; // [Nusers times + number of RA][2 codewords], index 0 in [NUMBER_OF_UE_MAX+1] is for RA
|
||||
// LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA
|
||||
NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p;
|
||||
NR_gNB_DLSCH_t *dlsch_MCH;
|
||||
NR_gNB_DLSCH_t *dlsch_PCH;
|
||||
LTE_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX];
|
||||
|
||||
uint8_t pbch_configured;
|
||||
uint8_t pbch_pdu[4]; //PBCH_PDU_SIZE
|
||||
|
||||
Reference in New Issue
Block a user