NR_SC_FDMA changes
- CDM groups used, multiple DMRS locations tested - REMOVED compiler define NR_SC_FDMA - enabled -Z option in ulsim for testing NR SC-FDMA - Gnb UL Processing of LLRS even if last symbol allocated has no data - transform precoding Enumerations used
This commit is contained in:
@@ -1758,6 +1758,7 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_csi_rs.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
#include "SCHED_NR/fapi_nr_l1.h"
|
||||
#include "nfapi_nr_interface.h"
|
||||
|
||||
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
|
||||
|
||||
/*
|
||||
extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn);
|
||||
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
@@ -194,6 +196,10 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate low PAPR type 1 sequences for PUSCH DMRS, these are used if transform precoding is enabled. */
|
||||
generate_lowpapr_typ1_refsig_sequences(SHRT_MAX);
|
||||
|
||||
|
||||
nr_init_csi_rs(gNB, 0); // TODO scramblingID currently hardcoded to 0, to be taken from higher layer parameter scramblingID when implemented
|
||||
|
||||
/// Transport init necessary for NR synchro
|
||||
@@ -388,6 +394,11 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
/*
|
||||
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) gNB->UE_stats_ptr[UE_id] = NULL;
|
||||
*/
|
||||
|
||||
|
||||
free_gnb_lowpapr_sequences();
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
void install_schedule_handlers(IF_Module_t *if_inst)
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
|
||||
|
||||
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
|
||||
|
||||
|
||||
//#define DEBUG_CH
|
||||
//#define DEBUG_PUSCH
|
||||
|
||||
@@ -119,15 +122,36 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//------------------generate DMRS------------------//
|
||||
|
||||
if (pusch_pdu->transform_precoding==1) // if transform precoding is disabled
|
||||
if (pusch_pdu->transform_precoding == transform_precoder_disabled)
|
||||
nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->rb_start*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type);
|
||||
else
|
||||
nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type);
|
||||
|
||||
else { // if transform precoding or SC-FDMA is enabled in Uplink
|
||||
|
||||
// NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible
|
||||
uint16_t index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB/2));
|
||||
uint8_t u = pusch_pdu->dfts_ofdm.low_papr_group_number;
|
||||
uint8_t v = pusch_pdu->dfts_ofdm.low_papr_sequence_number;
|
||||
int16_t *dmrs_seq = gNB_dmrs_lowpaprtype1_sequence[u][v][index];
|
||||
|
||||
AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n");
|
||||
AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated");
|
||||
|
||||
LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index);
|
||||
|
||||
nr_pusch_lowpaprtype1_dmrs_rx(gNB, Ns, dmrs_seq, &pilot[0], 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type);
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf ("NR_UL_CHANNEL_EST: index %d, u %d,v %d\n", index, u, v);
|
||||
LOG_M("gNb_DMRS_SEQ.m","gNb_DMRS_SEQ", dmrs_seq,6*nb_rb_pusch,1,1);
|
||||
#endif
|
||||
|
||||
}
|
||||
//------------------------------------------------//
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
for (int i=0;i<(6*nb_rb_pusch);i++)
|
||||
printf("%d+j*(%d)\n",((int16_t*)pilot)[2*i],((int16_t*)pilot)[1+(2*i)]);
|
||||
|
||||
@@ -247,3 +247,51 @@ void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uin
|
||||
output[(i<<1)+1] = nr_rx_mod_table[((offset+idx)<<1)+1];
|
||||
}
|
||||
}
|
||||
|
||||
int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
unsigned int Ns,
|
||||
int16_t *dmrs_seq,
|
||||
int32_t *output,
|
||||
unsigned short p,
|
||||
unsigned char lp,
|
||||
unsigned short nb_pusch_rb,
|
||||
uint32_t re_offset,
|
||||
uint8_t dmrs_type)
|
||||
{
|
||||
int8_t w, nb_dmrs;
|
||||
int k;
|
||||
|
||||
int dmrs_offset = re_offset/((dmrs_type==pusch_dmrs_type1)?2:3);
|
||||
|
||||
if (dmrs_type != pusch_dmrs_type1)
|
||||
LOG_E(PHY,"PUSCH DMRS config type %d not valid\n", dmrs_type);
|
||||
|
||||
if ((p>=1000) && (p<1008)) {
|
||||
if (gNB->frame_parms.Ncp == NORMAL) {
|
||||
nb_dmrs = NR_NB_SC_PER_RB/2; // for DMRS TYPE 1 - 6 DMRS REs present per RB
|
||||
for (int i=dmrs_offset; i<dmrs_offset+(nb_pusch_rb*nb_dmrs); i++) {
|
||||
k = i-dmrs_offset;
|
||||
w = (wf1[p-1000][i&1])*(wt1[p-1000][lp]);
|
||||
|
||||
((int16_t*)output)[2*k] = w*dmrs_seq[2*i];
|
||||
((int16_t*)output)[(2*k)+1] = -(w*dmrs_seq[(2*i)+1]);// conjugate
|
||||
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("NR_DMRS_RX: nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d nb_dmrs %d\n", dmrs_type, p, nb_pusch_rb, nb_dmrs);
|
||||
printf("NR_DMRS_RX: wf[%d] = %d wt[%d]= %d\n", i&1, wf1[p-1000][i&1], lp, wt1[p-1000][lp]);
|
||||
printf("NR_DMRS_RX: i %d dmrs_offset %d k %d pusch dmrsseq[i<<1] %d, dmrsseq[(i<<1)+1] %d pilots[k<<1] %d pilots[(k<<1)+1] %d\n", i, dmrs_offset, k,
|
||||
dmrs_seq[i<<1], dmrs_seq[(i<<1)+1], ((int16_t*)output)[k<<1], ((int16_t*)output)[(k<<1)+1]);
|
||||
#endif
|
||||
|
||||
}
|
||||
} else {
|
||||
LOG_E(PHY,"extended cp not supported for PUSCH DMRS yet\n");
|
||||
}
|
||||
} else {
|
||||
LOG_E(PHY,"Illegal p %d PUSCH DMRS port\n",p);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,4 +59,18 @@ extern __m64 byte2m64_re[256];
|
||||
extern __m64 byte2m64_im[256];
|
||||
extern __m128i byte2m128i[256];
|
||||
|
||||
|
||||
|
||||
int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
unsigned int Ns,
|
||||
int16_t *dmrs_seq,
|
||||
int32_t *output,
|
||||
unsigned short p,
|
||||
unsigned char lp,
|
||||
unsigned short nb_pusch_rb,
|
||||
uint32_t re_offset,
|
||||
uint8_t dmrs_type);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -108,6 +108,39 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC,
|
||||
return rv_overbar;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : get_index_for_dmrs_lowpapr_seq
|
||||
*
|
||||
* PARAMETERS : num_dmrs_res - Total number of DMRS RES possible in allocated RBs
|
||||
*
|
||||
*
|
||||
* RETURN : returns index of array dmrs_ul_allocated_res
|
||||
*
|
||||
* DESCRIPTION : finds the index which in turn is used to index into dmrs low papr sequences
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res) {
|
||||
|
||||
int16_t index = -1;
|
||||
|
||||
if (num_dmrs_res >= dmrs_ul_allocated_res[(MAX_INDEX_DMRS_UL_ALLOCATED_REs-1)])
|
||||
index = MAX_INDEX_DMRS_UL_ALLOCATED_REs-1;
|
||||
else
|
||||
index = (num_dmrs_res/6) -1;
|
||||
|
||||
for (;index >= 0; index--) {
|
||||
if (dmrs_ul_allocated_res[index] == num_dmrs_res)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
LOG_D(PHY, "num_dmrs_res: %d INDEX RETURNED: %d", num_dmrs_res, index);
|
||||
return index;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : base_sequence_36_or_larger
|
||||
@@ -126,13 +159,19 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC,
|
||||
int16_t *base_sequence_36_or_larger(unsigned int Msc_RS,
|
||||
unsigned int u,
|
||||
unsigned int v,
|
||||
unsigned int scaling)
|
||||
unsigned int scaling, unsigned int if_dmrs_seq)
|
||||
{
|
||||
int16_t *rv_overbar;
|
||||
unsigned int N_ZC;
|
||||
unsigned int N_ZC, M_ZC;
|
||||
double q_overbar, x;
|
||||
unsigned int q,m,n;
|
||||
unsigned int M_ZC = ul_allocated_re[Msc_RS];
|
||||
|
||||
|
||||
if (if_dmrs_seq)
|
||||
M_ZC = dmrs_ul_allocated_res[Msc_RS];
|
||||
else
|
||||
M_ZC = ul_allocated_re[Msc_RS];
|
||||
|
||||
|
||||
rv_overbar = malloc16(IQ_SIZE*M_ZC);
|
||||
if (rv_overbar == NULL) {
|
||||
@@ -140,7 +179,11 @@ int16_t *base_sequence_36_or_larger(unsigned int Msc_RS,
|
||||
assert(0);
|
||||
}
|
||||
|
||||
N_ZC = ref_ul_primes[Msc_RS]; /* The length N_ZC is given by the largest prime number such that N_ZC < M_ZC */
|
||||
if (if_dmrs_seq)
|
||||
N_ZC = dmrs_ref_ul_primes[Msc_RS];
|
||||
else
|
||||
N_ZC = ref_ul_primes[Msc_RS]; /* The length N_ZC is given by the largest prime number such that N_ZC < M_ZC */
|
||||
|
||||
|
||||
q_overbar = N_ZC * (u+1)/(double)31;
|
||||
|
||||
@@ -159,19 +202,24 @@ int16_t *base_sequence_36_or_larger(unsigned int Msc_RS,
|
||||
return rv_overbar;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : generate_ul_srs_sequences
|
||||
*
|
||||
* PARAMETERS : scaling to apply
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : uplink reference signal sequences generation
|
||||
* which are Low-PAPR base sequences
|
||||
* see TS 38.211 5.2.2 Low-PAPR sequence generation
|
||||
*
|
||||
*********************************************************************/
|
||||
void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling)
|
||||
{
|
||||
unsigned int u,Msc_RS;
|
||||
unsigned int v = 0; // sequence hopping and group hopping are not supported yet
|
||||
|
||||
for (Msc_RS=0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) {
|
||||
for (u=0; u < U_GROUP_NUMBER; u++) {
|
||||
gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling);
|
||||
}
|
||||
}
|
||||
|
||||
for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) {
|
||||
for (u=0; u < U_GROUP_NUMBER; u++) {
|
||||
gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void generate_ul_reference_signal_sequences(unsigned int scaling)
|
||||
{
|
||||
@@ -184,10 +232,13 @@ void generate_ul_reference_signal_sequences(unsigned int scaling)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
for (Msc_RS=0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) {
|
||||
v = 0;
|
||||
v = 0;
|
||||
for (u=0; u < U_GROUP_NUMBER; u++) {
|
||||
rv_ul_ref_sig[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling);
|
||||
dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling);
|
||||
|
||||
#if 0
|
||||
sprintf(output_file, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
|
||||
sprintf(sequence_name, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
|
||||
@@ -198,10 +249,19 @@ void generate_ul_reference_signal_sequences(unsigned int scaling)
|
||||
}
|
||||
}
|
||||
|
||||
for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) {
|
||||
v = 0; // neither group hopping or sequnce hopping is supported for PUSCH DMRS hence v = 0
|
||||
for (u=0; u < U_GROUP_NUMBER; u++) {
|
||||
dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < SRS_SB_CONF; Msc_RS++) {
|
||||
for (u=0; u < U_GROUP_NUMBER; u++) {
|
||||
for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) {
|
||||
rv_ul_ref_sig[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling);
|
||||
for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) {
|
||||
rv_ul_ref_sig[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 0);
|
||||
|
||||
#if 0
|
||||
sprintf(output_file, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
|
||||
sprintf(sequence_name, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
|
||||
@@ -212,8 +272,11 @@ void generate_ul_reference_signal_sequences(unsigned int scaling)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : free_ul_reference_signal_sequences
|
||||
@@ -233,7 +296,33 @@ void free_ul_reference_signal_sequences(void)
|
||||
for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) {
|
||||
if (rv_ul_ref_sig[u][v][Msc_RS])
|
||||
free16(rv_ul_ref_sig[u][v][Msc_RS],2*sizeof(int16_t)*ul_allocated_re[Msc_RS]);
|
||||
if ((v==0) && (Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs))
|
||||
if (dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS])
|
||||
free16(dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS],2*sizeof(int16_t)*dmrs_ul_allocated_res[Msc_RS]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : free_gnb_lowpapr_sequences
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : free of uplink reference signal sequences
|
||||
*
|
||||
*********************************************************************/
|
||||
void free_gnb_lowpapr_sequences(void)
|
||||
{
|
||||
unsigned int u,v,Msc_RS;
|
||||
for (Msc_RS=0; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) {
|
||||
v=0;
|
||||
for (u=0; u < U_GROUP_NUMBER; u++) {
|
||||
if (gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS])
|
||||
free16(gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS],2*sizeof(int16_t)*dmrs_ul_allocated_res[Msc_RS]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
|
||||
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
|
||||
|
||||
#include "PHY/defs_nr_common.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
|
||||
|
||||
#ifdef DEFINE_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
#define EXTERN
|
||||
#define INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
@@ -255,7 +259,10 @@ const char phi_M_ZC_24[24*U_GROUP_NUMBER]
|
||||
;
|
||||
/************** FUNCTION ******************************************/
|
||||
|
||||
int16_t *base_sequence_36_or_larger(unsigned int M_ZC, unsigned int u, unsigned int v, unsigned int scaling);
|
||||
|
||||
int16_t *base_sequence_36_or_larger(unsigned int M_ZC, unsigned int u, unsigned int v, unsigned int scaling, unsigned int if_dmrs_seq);
|
||||
|
||||
|
||||
int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling);
|
||||
/*!
|
||||
\brief This function generate the sounding reference symbol (SRS) for the uplink.
|
||||
@@ -265,6 +272,72 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned
|
||||
void generate_ul_reference_signal_sequences(unsigned int scaling);
|
||||
void free_ul_reference_signal_sequences(void);
|
||||
|
||||
|
||||
|
||||
// Supported for 100Mhz configuration - which has max 273 RBs
|
||||
#define MAX_INDEX_DMRS_UL_ALLOCATED_REs 53
|
||||
|
||||
|
||||
const uint16_t dmrs_ul_allocated_res[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
|
||||
/* Number of possible DMRS REs based on PRBs allocated for PUSCH. Array has values until 273 RBs (100Mhz BW)
|
||||
Number of PUSCH RBs allocated should be able to be expressed as 2topowerofn*3topowerofn*5tothepowerofn
|
||||
According to 3GPP spec 38.211 section 6.3.1.4
|
||||
Table used in calculating DMRS low papr type1 sequence for transform precoding */
|
||||
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
= {
|
||||
/*RBs 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, */
|
||||
6, 12, 18, 24, 30, 36, 48, 54, 60, 72, 90, 96,
|
||||
|
||||
/*RBs 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48, 50, */
|
||||
108, 120, 144, 150, 162, 180, 192, 216, 240, 270, 288, 300,
|
||||
|
||||
/*RBs 54, 60, 64, 72 75, 80, 81, 90, 96, 100, (Bw 40Mhz) */
|
||||
324, 360, 384, 432, 450, 480, 486, 540, 576, 600,
|
||||
|
||||
/*RBs 108, 120 125 128 135 144 150 160 162 180 192 200 */
|
||||
648, 720, 750, 768, 810, 864, 900, 960, 972, 1080, 1152, 1200,
|
||||
|
||||
/*RBs 216 225 240 243 250 256 270 supported until 100Mhz */
|
||||
1296, 1350, 1440, 1458, 1500, 1536, 1620
|
||||
|
||||
}
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Table of largest prime number N_ZC < possible DMRS REs M_ZC, this array has values until 100Mhz
|
||||
According to 3GPP spec 38.211 section 5.2.2.1
|
||||
Table used in calculating DMRS low papr type1 sequence for transform precoding */
|
||||
const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
|
||||
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
= {
|
||||
/*DMRS REs 6, 12, 18, 24, 30, 36, 48, 54, 60, 72, 90, 96, */
|
||||
5, 11, 17, 23, 29, 31, 47, 53, 59, 71, 89, 89,
|
||||
|
||||
/*DMRS REs 108, 120, 144, 150, 162, 180, 192, 216, 240, 270, 288, 300, */
|
||||
107, 113, 139, 149, 157, 179, 191, 211, 239, 269, 283, 293,
|
||||
|
||||
/*DMRS REs 324, 360, 384, 432, 450, 480, 486, 540, 576, 600, */
|
||||
317, 359, 383, 431, 449, 479, 479, 523, 571, 599,
|
||||
|
||||
/*DMRS REs 648, 720, 750, 768, 810, 864, 900, 960, 972, 1080, 1152, 1200, */
|
||||
647, 719, 743, 761, 809, 863, 887, 953, 971, 1069, 1151, 1193,
|
||||
|
||||
/*DMRS REs 1296, 1350, 1440, 1458, 1500, 1536 1620 supported until 100Mhz */
|
||||
1291, 1327, 1439, 1453, 1499, 1531, 1619
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
;
|
||||
|
||||
/// PUSCH DMRS for transform precoding
|
||||
int16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
|
||||
int16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
|
||||
int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res);
|
||||
void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling);
|
||||
void free_gnb_lowpapr_sequences(void);
|
||||
|
||||
|
||||
#undef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
#undef EXTERN
|
||||
|
||||
|
||||
@@ -1118,6 +1118,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
LOG_D(PHY,"dmrs_symbol: nb_re_pusch %d\n",nb_re_pusch);
|
||||
gNB->pusch_vars[ulsch_id]->dmrs_symbol = symbol;
|
||||
|
||||
} else {
|
||||
nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
|
||||
}
|
||||
@@ -1219,9 +1220,21 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
symbol,
|
||||
rel15_ul->rb_size);
|
||||
stop_meas(&gNB->ulsch_mrc_stats);
|
||||
#ifdef NR_SC_FDMA
|
||||
nr_idft(&((uint32_t*)gNB->pusch_vars[ulsch_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch);
|
||||
#endif
|
||||
|
||||
|
||||
if (rel15_ul->transform_precoding == transform_precoder_enabled) {
|
||||
|
||||
#ifdef __AVX2__
|
||||
// For odd number of resource blocks need byte alignment to multiple of 8
|
||||
int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7);
|
||||
#else
|
||||
int nb_re_pusch2 = nb_re_pusch;
|
||||
#endif
|
||||
|
||||
// perform IDFT operation on the compensated rxdata if transform precoding is enabled
|
||||
nr_idft(&((uint32_t*)gNB->pusch_vars[ulsch_id]->rxdataF_comp[0])[symbol * nb_re_pusch2], nb_re_pusch);
|
||||
LOG_D(PHY,"Transform precoding being done on data- symbol: %d, nb_re_pusch: %d\n", symbol, nb_re_pusch);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
@@ -1245,32 +1258,33 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
/* Subtract total PTRS RE's in the symbol from PUSCH RE's */
|
||||
gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] -= gNB->pusch_vars[ulsch_id]->ptrs_re_per_slot;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------- */
|
||||
/*-------------------- LLRs computation -------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------------------------------------*/
|
||||
if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1))
|
||||
{
|
||||
#ifdef __AVX2__
|
||||
int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
|
||||
#else
|
||||
int off = 0;
|
||||
#endif
|
||||
uint32_t rxdataF_ext_offset = 0;
|
||||
for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++) {
|
||||
start_meas(&gNB->ulsch_llr_stats);
|
||||
nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][i * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)],
|
||||
gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
|
||||
gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
|
||||
&gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order],
|
||||
rel15_ul->rb_size,
|
||||
gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i],
|
||||
i,
|
||||
rel15_ul->qam_mod_order);
|
||||
stop_meas(&gNB->ulsch_llr_stats);
|
||||
rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i];
|
||||
}// symbol loop
|
||||
}// last symbol check
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------- */
|
||||
/*-------------------- LLRs computation -------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------------------------------------*/
|
||||
if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1)) {
|
||||
|
||||
#ifdef __AVX2__
|
||||
int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
|
||||
#else
|
||||
int off = 0;
|
||||
#endif
|
||||
uint32_t rxdataF_ext_offset = 0;
|
||||
for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++) {
|
||||
start_meas(&gNB->ulsch_llr_stats);
|
||||
nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][i * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)],
|
||||
gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
|
||||
gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
|
||||
&gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order],
|
||||
rel15_ul->rb_size,
|
||||
gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i],
|
||||
i,
|
||||
rel15_ul->qam_mod_order);
|
||||
stop_meas(&gNB->ulsch_llr_stats);
|
||||
rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i];
|
||||
}// symbol loop
|
||||
}// last symbol check
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "LAYER2/NR_MAC_UE/mac_proto.h"
|
||||
|
||||
//#define DEBUG_SCFDMA
|
||||
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
|
||||
|
||||
//#define DEBUG_PUSCH_MAPPING
|
||||
//#define DEBUG_MAC_PDU
|
||||
//#define DEBUG_DFT_IDFT
|
||||
|
||||
//extern int32_t uplink_counter;
|
||||
|
||||
@@ -153,6 +155,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
unsigned int G = nr_get_G(nb_rb, number_of_symbols,
|
||||
nb_dmrs_re_per_rb, number_dmrs_symbols, mod_order, Nl);
|
||||
|
||||
|
||||
nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid, G);
|
||||
|
||||
///////////
|
||||
@@ -184,8 +188,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
(int16_t *)ulsch_ue->d_mod);
|
||||
|
||||
|
||||
// pusch_transform_precoding(ulsch_ue, frame_parms, harq_pid);
|
||||
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -243,26 +246,72 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
l_prime[0] = 0; // single symbol ap 0
|
||||
|
||||
#ifdef NR_SC_FDMA
|
||||
uint32_t nb_re_pusch, nb_re_dmrs_per_rb;
|
||||
uint32_t y_offset = 0;
|
||||
uint16_t index;
|
||||
uint8_t u = 0, v = 0;
|
||||
int16_t *dmrs_seq = NULL;
|
||||
|
||||
for (l = start_symbol; l < start_symbol + number_of_symbols; l++) {
|
||||
if (pusch_pdu->transform_precoding == transform_precoder_enabled) {
|
||||
|
||||
if((ul_dmrs_symb_pos >> l) & 0x01)
|
||||
nb_re_dmrs_per_rb = nb_dmrs_re_per_rb;
|
||||
else
|
||||
nb_re_dmrs_per_rb = 0;
|
||||
uint32_t nb_re_pusch=nb_rb * NR_NB_SC_PER_RB;
|
||||
uint32_t y_offset = 0;
|
||||
uint16_t num_dmrs_res_per_symbol = nb_rb*(NR_NB_SC_PER_RB/2);
|
||||
|
||||
nb_re_pusch = nb_rb * (NR_NB_SC_PER_RB - nb_re_dmrs_per_rb);
|
||||
// Calculate index to dmrs seq array based on number of DMRS Subcarriers on this symbol
|
||||
index = get_index_for_dmrs_lowpapr_seq(num_dmrs_res_per_symbol);
|
||||
u = pusch_pdu->dfts_ofdm.low_papr_group_number;
|
||||
v = pusch_pdu->dfts_ofdm.low_papr_sequence_number;
|
||||
dmrs_seq = dmrs_lowpaprtype1_ul_ref_sig[u][v][index];
|
||||
|
||||
nr_dft(&ulsch_ue->y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch);
|
||||
AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n");
|
||||
AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated");
|
||||
|
||||
LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index);
|
||||
|
||||
for (l = start_symbol; l < start_symbol + number_of_symbols; l++) {
|
||||
|
||||
if((ul_dmrs_symb_pos >> l) & 0x01)
|
||||
/* In the symbol with DMRS no data would be transmitted CDM groups is 2*/
|
||||
continue;
|
||||
|
||||
nr_dft(&ulsch_ue->y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch);
|
||||
|
||||
y_offset = y_offset + nb_re_pusch;
|
||||
|
||||
LOG_D(PHY,"Transform precoding being done on data- symbol: %d, nb_re_pusch: %d, y_offset: %d\n", l, nb_re_pusch, y_offset);
|
||||
|
||||
#ifdef DEBUG_PUSCH_MAPPING
|
||||
printf("NR_ULSCH_UE: y_offset %d\t nb_re_pusch %d \t Symbol %d \t nb_rb %d \n",
|
||||
y_offset, nb_re_pusch, l, nb_rb);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DFT_IDFT
|
||||
uint32_t debug_symbols[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
|
||||
int offset = 0;
|
||||
printf("NR_ULSCH_UE: available_bits: %d, mod_order: %d", available_bits,mod_order);
|
||||
|
||||
for (int ll = 0; ll < (available_bits/mod_order); ll++) {
|
||||
debug_symbols[ll] = ulsch_ue->y[ll];
|
||||
}
|
||||
|
||||
printf("NR_ULSCH_UE: numSym: %d, num_dmrs_sym: %d", number_of_symbols,number_dmrs_symbols);
|
||||
for (int ll = 0; ll < (number_of_symbols-number_dmrs_symbols); ll++) {
|
||||
|
||||
nr_idft(&debug_symbols[offset], nb_re_pusch);
|
||||
|
||||
offset = offset + nb_re_pusch;
|
||||
|
||||
}
|
||||
LOG_M("preDFT_all_symbols.m","UE_preDFT", tx_layers[0],number_of_symbols*nb_re_pusch,1,1);
|
||||
LOG_M("postDFT_all_symbols.m","UE_postDFT", &(ulsch_ue->y[0]),number_of_symbols*nb_re_pusch,1,1);
|
||||
LOG_M("DEBUG_IDFT_SYMBOLS.m","UE_Debug_IDFT", debug_symbols,number_of_symbols*nb_re_pusch,1,1);
|
||||
LOG_M("UE_DMRS_SEQ.m","UE_DMRS_SEQ", dmrs_seq,nb_re_pusch,1,1);
|
||||
#endif
|
||||
|
||||
y_offset = y_offset + nb_re_pusch;
|
||||
}
|
||||
#else
|
||||
memcpy(ulsch_ue->y, tx_layers[0], (available_bits/mod_order)*sizeof(int32_t));
|
||||
#endif
|
||||
else
|
||||
memcpy(ulsch_ue->y, tx_layers[0], (available_bits/mod_order)*sizeof(int32_t));
|
||||
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -279,6 +328,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
uint8_t k_prime = 0;
|
||||
uint16_t m = 0;
|
||||
|
||||
|
||||
#ifdef DEBUG_PUSCH_MAPPING
|
||||
printf("NR_ULSCH_UE: Value of CELL ID %d /t, u %d \n", frame_parms->Nid_cell, u);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// DMRS params for this ap
|
||||
get_Wt(Wt, ap, dmrs_type);
|
||||
get_Wf(Wf, ap, dmrs_type);
|
||||
@@ -295,18 +351,25 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
if ((ul_dmrs_symb_pos >> l) & 0x01) {
|
||||
is_dmrs_sym = 1;
|
||||
|
||||
if (pusch_pdu->transform_precoding == 1){ // if transform precoding is disabled
|
||||
|
||||
if (pusch_pdu->transform_precoding == transform_precoder_disabled){
|
||||
|
||||
if (dmrs_type == pusch_dmrs_type1)
|
||||
dmrs_idx = start_rb*6;
|
||||
else
|
||||
dmrs_idx = start_rb*4;
|
||||
|
||||
// Perform this on gold sequence, not required when SC FDMA operation is done,
|
||||
nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
} else {
|
||||
dmrs_idx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
|
||||
nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
} else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
AssertFatal(pusch_pdu->transform_precoding == transform_precoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n");
|
||||
|
||||
if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) {
|
||||
is_ptrs_sym = 1;
|
||||
@@ -338,8 +401,17 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
if (is_dmrs == 1) {
|
||||
|
||||
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15;
|
||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
|
||||
if (pusch_pdu->transform_precoding == transform_precoder_enabled) {
|
||||
|
||||
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15;
|
||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15;
|
||||
|
||||
} else {
|
||||
|
||||
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15;
|
||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PUSCH_MAPPING
|
||||
printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n",
|
||||
|
||||
@@ -42,11 +42,6 @@
|
||||
#define nr_subframe_t lte_subframe_t
|
||||
#define nr_slot_t lte_subframe_t
|
||||
|
||||
// [hna] This enables SC-FDMA transmission in Uplink. If disabled, then OFDMA is used in UPLINK.
|
||||
#ifndef NR_SC_FDMA
|
||||
// #define NR_SC_FDMA
|
||||
#endif
|
||||
|
||||
#define MAX_NUM_SUBCARRIER_SPACING 5
|
||||
|
||||
#define NR_MAX_NB_RB 275
|
||||
|
||||
@@ -601,9 +601,11 @@ typedef enum{
|
||||
ul_rgb_config1 = 1,
|
||||
ul_rgb_config2 = 2
|
||||
} ul_rgb_Size_t;
|
||||
typedef enum {
|
||||
transformPrecoder_enabled = 1,
|
||||
transformPrecoder_disabled = 2
|
||||
/* Aligned values of this enum to other tranform precoder enums
|
||||
* eg: as defined in fapi_nr_ue_interface.h for transform_precoder_t*/
|
||||
typedef enum {
|
||||
transformPrecoder_enabled = 0,
|
||||
transformPrecoder_disabled = 1
|
||||
} transformPrecoder_t;
|
||||
typedef enum {
|
||||
codebookSubset_fullyAndPartialAndNonCoherent = 1,
|
||||
|
||||
@@ -63,6 +63,8 @@
|
||||
#include <openair2/LAYER2/MAC/mac_vars.h>
|
||||
#include <openair2/RRC/LTE/rrc_vars.h>
|
||||
|
||||
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
|
||||
|
||||
//#define DEBUG_ULSIM
|
||||
|
||||
LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC;
|
||||
@@ -201,6 +203,10 @@ int main(int argc, char **argv)
|
||||
uint16_t ptrsSymbPerSlot = 0;
|
||||
uint16_t ptrsRePerSymb = 0;
|
||||
|
||||
uint8_t transform_precoding = transform_precoder_disabled; // 0 - ENABLE, 1 - DISABLE
|
||||
uint8_t num_dmrs_cdm_grps_no_data = 1;
|
||||
uint8_t mcs_table = 0;
|
||||
|
||||
UE_nr_rxtx_proc_t UE_proc;
|
||||
FILE *scg_fd=NULL;
|
||||
int file_offset = 0;
|
||||
@@ -221,7 +227,7 @@ int main(int argc, char **argv)
|
||||
/* initialize the sin-cos table */
|
||||
InitSinLUT();
|
||||
|
||||
while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:G:H:M:N:PR:S:T:U:L:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:G:H:M:N:PR:S:T:U:L:Z")) != -1) {
|
||||
printf("handling optarg %c\n",c);
|
||||
switch (c) {
|
||||
|
||||
@@ -454,9 +460,19 @@ int main(int argc, char **argv)
|
||||
params_from_file = 1;
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
|
||||
transform_precoding = transform_precoder_enabled;
|
||||
num_dmrs_cdm_grps_no_data = 2;
|
||||
mcs_table = 3;
|
||||
|
||||
printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n", transform_precoding);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'h':
|
||||
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]);
|
||||
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId -Z Enable SC-FDMA in Uplink \n", argv[0]);
|
||||
//printf("-d Use TDD\n");
|
||||
printf("-d Introduce delay in terms of number of samples\n");
|
||||
printf("-f Number of frames to simulate\n");
|
||||
@@ -486,6 +502,7 @@ int main(int argc, char **argv)
|
||||
printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
|
||||
printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n");
|
||||
printf("-Q If -F used, read parameters from file\n");
|
||||
printf("-Z If -Z is used, SC-FDMA or transform precoding is enabled in Uplink \n");
|
||||
exit(-1);
|
||||
break;
|
||||
|
||||
@@ -681,13 +698,13 @@ int main(int argc, char **argv)
|
||||
uint8_t ptrs_mcs3 = 10;
|
||||
uint16_t n_rb0 = 25;
|
||||
uint16_t n_rb1 = 75;
|
||||
uint8_t mcs_table = 0;
|
||||
|
||||
uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; // | PUSCH_PDU_BITMAP_PUSCH_PTRS;
|
||||
uint8_t max_rounds = 4;
|
||||
uint8_t crc_status = 0;
|
||||
|
||||
unsigned char mod_order = nr_get_Qm_ul(Imcs, 0);
|
||||
uint16_t code_rate = nr_get_code_rate_ul(Imcs, 0);
|
||||
unsigned char mod_order = nr_get_Qm_ul(Imcs, mcs_table);
|
||||
uint16_t code_rate = nr_get_code_rate_ul(Imcs, mcs_table);
|
||||
|
||||
uint8_t mapping_type = typeB; // Default Values
|
||||
pusch_dmrs_type_t dmrs_config_type = pusch_dmrs_type1; // Default Values
|
||||
@@ -717,9 +734,32 @@ int main(int argc, char **argv)
|
||||
uint16_t l_prime_mask = get_l_prime(nb_symb_sch, mapping_type, add_pos, length_dmrs);
|
||||
uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch);
|
||||
uint8_t nb_re_dmrs = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4;
|
||||
|
||||
if (transform_precoding == transform_precoder_enabled) {
|
||||
|
||||
AssertFatal(enable_ptrs == 0, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n");
|
||||
|
||||
int8_t index = get_index_for_dmrs_lowpapr_seq((NR_NB_SC_PER_RB/2) * nb_rb);
|
||||
AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n");
|
||||
|
||||
dmrs_config_type = pusch_dmrs_type1;
|
||||
nb_re_dmrs = nb_re_dmrs * num_dmrs_cdm_grps_no_data;
|
||||
|
||||
printf("[ULSIM]: TRANSFORM PRECODING ENABLED. Num RBs: %d, index for DMRS_SEQ: %d\n", nb_rb, index);
|
||||
}
|
||||
|
||||
|
||||
unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1);
|
||||
unsigned int TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers);
|
||||
|
||||
|
||||
printf("[ULSIM]: length_dmrs: %d, l_prime_mask: %d number_dmrs_symbols: %d, mapping_type: %d add_pos: %d \n", length_dmrs, l_prime_mask, number_dmrs_symbols, mapping_type,add_pos);
|
||||
printf("[ULSIM]: CDM groups: %d, dmrs_config_type: %d, num_rbs: %d, nb_symb_sch: %d\n", num_dmrs_cdm_grps_no_data, dmrs_config_type, nb_rb, nb_symb_sch);
|
||||
printf("[ULSIM]: MCS: %d, mod order: %d, code_rate: %d\n", Imcs, mod_order, code_rate);
|
||||
printf("[ULSIM]: VALUE OF G: %d, TBS: %d\n", available_bits, TBS);
|
||||
|
||||
|
||||
|
||||
uint8_t ulsch_input_buffer[TBS/8];
|
||||
|
||||
ulsch_input_buffer[0] = 0x31;
|
||||
@@ -874,7 +914,7 @@ int main(int argc, char **argv)
|
||||
pusch_pdu->mcs_table = mcs_table;
|
||||
pusch_pdu->target_code_rate = code_rate;
|
||||
pusch_pdu->qam_mod_order = mod_order;
|
||||
pusch_pdu->transform_precoding = 1;
|
||||
pusch_pdu->transform_precoding = transform_precoding;
|
||||
pusch_pdu->data_scrambling_id = *scc->physCellId;
|
||||
pusch_pdu->nrOfLayers = 1;
|
||||
pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << start_symbol;
|
||||
@@ -900,6 +940,13 @@ int main(int argc, char **argv)
|
||||
pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
|
||||
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
|
||||
|
||||
if (transform_precoding == transform_precoder_enabled) {
|
||||
|
||||
pusch_pdu->dfts_ofdm.low_papr_group_number = *scc->physCellId % 30; // U as defined in 38.211 section 6.4.1.1.1.2
|
||||
pusch_pdu->dfts_ofdm.low_papr_sequence_number = 0; // V as defined in 38.211 section 6.4.1.1.1.2
|
||||
pusch_pdu->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
|
||||
}
|
||||
|
||||
// prepare ULSCH/PUSCH reception
|
||||
nr_schedule_response(Sched_INFO);
|
||||
|
||||
@@ -951,6 +998,18 @@ int main(int argc, char **argv)
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
|
||||
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.transform_precoding = transform_precoding;
|
||||
|
||||
if (transform_precoding == transform_precoder_enabled) {
|
||||
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_group_number = *scc->physCellId % 30;// U as defined in 38.211 section 6.4.1.1.1.2
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_sequence_number = 0;// V as defined in 38.211 section 6.4.1.1.1.2
|
||||
//ul_config.ul_config_list[0].pusch_config_pdu.pdu_bit_map |= PUSCH_PDU_BITMAP_DFTS_OFDM;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
|
||||
|
||||
}
|
||||
|
||||
|
||||
nr_fill_ulsch(gNB,frame,slot,pusch_pdu);
|
||||
|
||||
for (int i=0;i<(TBS/8);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff;
|
||||
|
||||
Reference in New Issue
Block a user