Commit e7768b34 authored by hardy's avatar hardy

Merge remote-tracking branch 'origin/nr_ul_scfdma' into integration_2021_wk04

parents b1d98c04 1cb657ac
......@@ -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
......
......@@ -1289,7 +1289,10 @@
(Test5: MCS 9 273 PRBs),
(Test6: DMRS Type A, 3 DMRS, 4 PTRS, 5 Interpolated Symbols),
(Test7: DMRS Type B, 3 DMRS, 2 PTRS, 7 Interpolated Symbols),
(Test8: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols)</desc>
(Test8: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols),
(Test9: SC-FDMA, 50 PRBs),
(Test10: SC-FDMA, 75 PRBs),
(Test11: SC-FDMA, 3 DMRS)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
......@@ -1303,8 +1306,11 @@
-n100 -m9 -R273 -r273 -s5
-n100 -s5 -T 2 1 2 -U 2 0 2
-n100 -s5 -T 2 2 2 -U 2 1 2
-n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3</main_exec_args>
<tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8</tags>
-n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3
-n100 -s20 -Z
-n100 -s20 -Z -r75
-n100 -s20 -Z -U 2 0 2</main_exec_args>
<tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11</tags>
<search_expr_true>PUSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
......
......@@ -264,6 +264,7 @@ The following features are valid for the gNB and the 5G-NR UE.
* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 supported)
* Highly efficient 3GPP compliant polar encoder and decoder
* Encoder and decoder for short blocks
* Support for UL transform precoding (SC-FDMA)
## gNB PHY Layer ##
......
......@@ -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];
......@@ -195,6 +197,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
......@@ -389,6 +395,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
......
......@@ -212,7 +212,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
\param z Pointer to input in frequnecy domain, and it is also the output in time domain
\param Msc_PUSCH number of allocated data subcarriers
*/
void nr_idft(uint32_t *z, uint32_t Msc_PUSCH);
void nr_idft(int32_t *z, uint32_t Msc_PUSCH);
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
@param rxdataF_comp Compensated channel output
......
......@@ -12,7 +12,7 @@
//#define DEBUG_RB_EXT
//#define DEBUG_CH_MAG
void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
{
#if defined(__x86_64__) || defined(__i386__)
......@@ -38,7 +38,7 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
}
for (i=0,ip=0; i<Msc_PUSCH; i++, ip+=4) {
((uint32_t*)idft_in0)[ip+0] = z[i];
((int32_t*)idft_in0)[ip+0] = z[i];
}
......@@ -203,7 +203,7 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
z[i] = ((uint32_t*)idft_out0)[ip];
z[i] = ((int32_t*)idft_out0)[ip];
}
// conjugate output
......@@ -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(&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))
{
/*---------------------------------------------------------------------------------------------------- */
/*-------------------- 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;
int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
#else
int off = 0;
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
}
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);
}
......@@ -181,9 +181,9 @@ typedef struct {
/// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
uint8_t b_tilde[MAX_NUM_NR_CHANNEL_BITS];
/// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
uint32_t d_mod[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
int32_t d_mod[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
/// Transform-coded "y"-sequences (for definition see 38-211 V15.3.0 2018-09, subsection 6.3.1.4)
uint32_t y[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
int32_t y[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
/*
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
uint8_t q[MAX_CQI_PAYLOAD];
......
......@@ -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);
// 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];
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");
nb_re_pusch = nb_rb * (NR_NB_SC_PER_RB - nb_re_dmrs_per_rb);
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
}
nr_dft(&ulsch_ue->y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch);
#ifdef DEBUG_DFT_IDFT
int32_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,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",
......
......@@ -112,7 +112,7 @@ static inline void cmac_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32)
{
__m256i cmac_tmp,cmac_tmp_re32,cmac_tmp_im32;
__m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,19,18,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
__m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
cmac_tmp = _mm256_sign_epi16(b,*(__m256i*)reflip);
cmac_tmp_re32 = _mm256_madd_epi16(a,cmac_tmp);
......@@ -129,7 +129,7 @@ static inline void cmacc_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32)
{
__m256i cmac_tmp,cmac_tmp_re32,cmac_tmp_im32;
__m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,19,18,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
__m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
cmac_tmp_re32 = _mm256_madd_epi16(a,b);
......
......@@ -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;
......@@ -205,6 +207,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;
......@@ -225,7 +231,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) {
......@@ -458,9 +464,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");
......@@ -490,6 +506,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;
......@@ -685,13 +702,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
......@@ -721,9 +738,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: %u, l_prime_mask: %u number_dmrs_symbols: %u, mapping_type: %u add_pos: %d \n", length_dmrs, l_prime_mask, number_dmrs_symbols, mapping_type, add_pos);
printf("[ULSIM]: CDM groups: %u, dmrs_config_type: %d, num_rbs: %u, nb_symb_sch: %u\n", num_dmrs_cdm_grps_no_data, dmrs_config_type, nb_rb, nb_symb_sch);
printf("[ULSIM]: MCS: %d, mod order: %u, code_rate: %u\n", Imcs, mod_order, code_rate);
printf("[ULSIM]: VALUE OF G: %u, TBS: %u\n", available_bits, TBS);
uint8_t ulsch_input_buffer[TBS/8];
ulsch_input_buffer[0] = 0x31;
......@@ -878,7 +918,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;
......@@ -904,6 +944,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);
......@@ -955,6 +1002,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;
......
......@@ -1259,6 +1259,44 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
ulcfg_pdu->pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
}
/* TRANSFORM PRECODING ------------------------------------------------------------------------------------------*/
if (ulcfg_pdu->pusch_config_pdu.transform_precoding == transform_precoder_enabled) {
uint32_t n_RS_Id = 0;
NR_PUSCH_Config_t *pusch_config=mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup;
NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = NULL;
ulcfg_pdu->pusch_config_pdu.num_dmrs_cdm_grps_no_data = 2;
if(pusch_config->dmrs_UplinkForPUSCH_MappingTypeA != NULL)
NR_DMRS_ulconfig = pusch_config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup;
else
NR_DMRS_ulconfig = pusch_config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
if (NR_DMRS_ulconfig->transformPrecodingEnabled->nPUSCH_Identity != NULL)
n_RS_Id = *NR_DMRS_ulconfig->transformPrecodingEnabled->nPUSCH_Identity;
else
n_RS_Id = *mac->scc->physCellId;
// U as specified in section 6.4.1.1.1.2 in 38.211, if sequence hopping and group hopping are disabled
ulcfg_pdu->pusch_config_pdu.dfts_ofdm.low_papr_group_number = n_RS_Id % 30;
// V as specified in section 6.4.1.1.1.2 in 38.211 V = 0 if sequence hopping and group hopping are disabled
if ((NR_DMRS_ulconfig->transformPrecodingEnabled->sequenceGroupHopping == NULL) &&
(NR_DMRS_ulconfig->transformPrecodingEnabled->sequenceHopping == NULL))
ulcfg_pdu->pusch_config_pdu.dfts_ofdm.low_papr_sequence_number = 0;
else
AssertFatal(1==0,"SequenceGroupHopping or sequenceHopping are NOT Supported\n");
LOG_D(MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d \n", ulcfg_pdu->pusch_config_pdu.num_dmrs_cdm_grps_no_data,
ulcfg_pdu->pusch_config_pdu.dfts_ofdm.low_papr_group_number);
}
/* TRANSFORM PRECODING --------------------------------------------------------------------------------------------------------*/
get_num_re_dmrs(&ulcfg_pdu->pusch_config_pdu,
&nb_dmrs_re_per_rb,
&number_dmrs_symbols);
......@@ -2908,9 +2946,9 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
/* MCS TABLE */
if (mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
pusch_config_pdu_0_0->transform_precoding = 1;
pusch_config_pdu_0_0->transform_precoding = transform_precoder_disabled;
else
pusch_config_pdu_0_0->transform_precoding = 0;
pusch_config_pdu_0_0->transform_precoding = transform_precoder_enabled;
if (pusch_config_pdu_0_0->transform_precoding == transform_precoder_disabled)
pusch_config_pdu_0_0->mcs_table = get_pusch_mcs_table(pusch_config->mcs_Table, 0,
......@@ -3028,9 +3066,9 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
/* MCS TABLE */
if (pusch_config->transformPrecoder == NULL) {
if (mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
pusch_config_pdu_0_1->transform_precoding = 1;
pusch_config_pdu_0_1->transform_precoding = transform_precoder_disabled;
else
pusch_config_pdu_0_1->transform_precoding = 0;
pusch_config_pdu_0_1->transform_precoding = transform_precoder_enabled;
}
else
pusch_config_pdu_0_1->transform_precoding = *pusch_config->transformPrecoder;
......@@ -3144,14 +3182,58 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
}
}
}
/*-------------------- Changed to enable Transform precoding in RF SIM------------------------------------------------*/
NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = NULL;
if (pusch_config_pdu_0_1->transform_precoding == transform_precoder_enabled) {
mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder = transform_precoder_enabled;
if(pusch_config->dmrs_UplinkForPUSCH_MappingTypeA != NULL) {
NR_DMRS_ulconfig = pusch_config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup;
if (NR_DMRS_ulconfig->dmrs_Type == NULL)
mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.dmrs_type = 1;
if (NR_DMRS_ulconfig->maxLength == NULL)
mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.max_length = 1;
} else if(pusch_config->dmrs_UplinkForPUSCH_MappingTypeB != NULL) {
NR_DMRS_ulconfig = pusch_config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
if (NR_DMRS_ulconfig->dmrs_Type == NULL)
mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_b.dmrs_type = 1;
if (NR_DMRS_ulconfig->maxLength == NULL)
mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_b.max_length = 1;
}
} else
mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder = transform_precoder_disabled;
// mapping type b configured from RRC. TBD: Mapping type b is not handled in this function.
if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_enabled) &&
(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_b.dmrs_type == 1) &&
(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_b.max_length == 1)) { // tables 7.3.1.1.2-6
pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2;
pusch_config_pdu_0_1->dmrs_ports = dci->antenna_ports.val;
}
/*-------------------- ---------------------------------------------------------------------------------------------------------------*/
/* ANTENNA_PORTS */
uint8_t rank=0; // We need to initialize rank FIXME!!!
if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_enabled) &&
(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-6
pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2; //TBC
pusch_config_pdu_0_1->dmrs_ports = dci->antenna_ports.val; //TBC
}
if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_enabled) &&
(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) &&
(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-7
......
......@@ -221,7 +221,6 @@ void nr_save_pusch_fields(const NR_ServingCellConfigCommon_t *scc,
{
ps->dci_format = dci_format;
ps->time_domain_allocation = tda;
ps->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
......@@ -243,13 +242,17 @@ void nr_save_pusch_fields(const NR_ServingCellConfigCommon_t *scc,
NR_RNTI_C,
target_ss,
false);
else
else {
ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config->mcs_TableTransformPrecoder,
1,
ps->dci_format,
NR_RNTI_C,
target_ss,
false);
num_dmrs_cdm_grps_no_data = 2; // in case of transform precoding - no Data sent in DMRS symbol
}
ps->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
/* DMRS calculations */
ps->mapping_type = tdaList->list.array[tda]->mappingType;
......
......@@ -742,6 +742,25 @@ void nr_schedule_ulsch(module_id_t module_id,
pusch_pdu->pusch_data.tb_size = sched_pusch->tb_size;
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
/* TRANSFORM PRECODING --------------------------------------------------------*/
if (pusch_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled){
// U as specified in section 6.4.1.1.1.2 in 38.211, if sequence hopping and group hopping are disabled
pusch_pdu->dfts_ofdm.low_papr_group_number = pusch_pdu->pusch_identity % 30;
// V as specified in section 6.4.1.1.1.2 in 38.211 V = 0 if sequence hopping and group hopping are disabled
if ((ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceGroupHopping == NULL) &&
(ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceHopping == NULL))
pusch_pdu->dfts_ofdm.low_papr_sequence_number = 0;
else
AssertFatal(1==0,"SequenceGroupHopping or sequenceHopping are NOT Supported\n");
LOG_D(NR_MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d MCS table: %d\n", pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dfts_ofdm.low_papr_group_number, ps->mcs_table);
}
/*-----------------------------------------------------------------------------*/
/* PUSCH PTRS */
if (ps->NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) {
// TODO to be fixed from RRC config
......
......@@ -888,8 +888,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
pusch_Config->pusch_AggregationFactor=NULL;
pusch_Config->mcs_Table=NULL;
pusch_Config->mcs_TableTransformPrecoder=NULL;
pusch_Config->transformPrecoder=calloc(1,sizeof(*pusch_Config->transformPrecoder));
*pusch_Config->transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled;
pusch_Config->transformPrecoder= NULL;
/* if msg3_transformprecoding is set in conf file - pusch config should not disable it */
if (servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) {
pusch_Config->transformPrecoder=calloc(1,sizeof(*pusch_Config->transformPrecoder));
*pusch_Config->transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled;
}
pusch_Config->codebookSubset=calloc(1,sizeof(*pusch_Config->codebookSubset));
*pusch_Config->codebookSubset = NR_PUSCH_Config__codebookSubset_nonCoherent;
pusch_Config->maxRank=calloc(1,sizeof(*pusch_Config->maxRank));
......@@ -898,6 +902,39 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
pusch_Config->uci_OnPUSCH=NULL;
pusch_Config->tp_pi2BPSK=NULL;
/*------------------------------TRANSFORM PRECODING- -----------------------------------------------------------------------*/
uint8_t transform_precoding = NR_PUSCH_Config__transformPrecoder_disabled;
// TBD: configure this from .conf file, Dedicated params cannot yet be configured in .conf file.
// Enable this to test transform precoding enabled from dedicated config.
/*if (pusch_Config->transformPrecoder == NULL)
pusch_Config->transformPrecoder=calloc(1,sizeof(*pusch_Config->transformPrecoder));
*pusch_Config->transformPrecoder = NR_PUSCH_Config__transformPrecoder_enabled; */
// END -------
if (pusch_Config->transformPrecoder == NULL) {
if (servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder != NULL)
transform_precoding = NR_PUSCH_Config__transformPrecoder_enabled;
}
else
transform_precoding = *pusch_Config->transformPrecoder;
if (transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled ) {
/* Enable DMRS uplink config for transform precoding enabled */
NR_DMRS_UplinkConfig->transformPrecodingEnabled = calloc(1,sizeof(*NR_DMRS_UplinkConfig->transformPrecodingEnabled));
NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity = NULL;
NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceGroupHopping = NULL;
NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceHopping = NULL;
NR_DMRS_UplinkConfig->transformPrecodingEnabled->ext1 = NULL;
LOG_I(RRC,"TRANSFORM PRECODING ENABLED......\n");
}
/*----------------------------------------------------------------------------------------------------------------------------*/
initialUplinkBWP->srs_Config = calloc(1,sizeof(*initialUplinkBWP->srs_Config));
initialUplinkBWP->srs_Config->present = NR_SetupRelease_SRS_Config_PR_setup;
NR_SRS_Config_t *srs_Config = calloc(1,sizeof(*srs_Config));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment