putting phy procedures into compact functions (UE side)
implementing: - generate_ue_ulsch_params (customized for ulsim only) - nr_ue_ulsch_procedures - nr_ue_pusch_common_procedures
This commit is contained in:
committed by
Thomas Schlichter
parent
4a841aa83d
commit
749bb66988
@@ -1073,6 +1073,28 @@ void pusch_transform_precoding(NR_UE_ULSCH_t *ulsch,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int harq_pid);
|
||||
|
||||
/** \brief Perform the following functionalities:
|
||||
- encoding
|
||||
- scrambling
|
||||
- modulation
|
||||
- transform precoding
|
||||
*/
|
||||
|
||||
uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
unsigned char harq_pid,
|
||||
uint8_t slot,
|
||||
uint8_t thread_id,
|
||||
int eNB_id);
|
||||
|
||||
|
||||
/** \brief This function does IFFT for PUSCH
|
||||
*/
|
||||
|
||||
uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
uint8_t slot,
|
||||
uint8_t Nl,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
|
||||
|
||||
uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
|
||||
@@ -232,6 +232,8 @@ typedef struct {
|
||||
uint16_t rnti;
|
||||
/// RNTI type
|
||||
uint8_t rnti_type;
|
||||
/// Cell ID
|
||||
int Nid_cell;
|
||||
/// f_PUSCH parameter for PUSCH power control
|
||||
int16_t f_pusch;
|
||||
/// Po_PUSCH - target output power for PUSCH
|
||||
|
||||
@@ -30,7 +30,10 @@
|
||||
* \warning
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
#include "common/utils/assertions.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#include "PHY/defs_nr_common.h"
|
||||
@@ -181,3 +184,233 @@ void pusch_transform_precoding(NR_UE_ULSCH_t *ulsch, NR_DL_FRAME_PARMS *frame_pa
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
unsigned char harq_pid,
|
||||
uint8_t slot,
|
||||
uint8_t thread_id,
|
||||
int eNB_id) {
|
||||
|
||||
unsigned int available_bits;
|
||||
uint8_t mod_order, cwd_index, num_of_codewords;
|
||||
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
|
||||
int32_t *mod_symbols[MAX_NUM_NR_RE];
|
||||
uint32_t ***pusch_dmrs;
|
||||
int16_t **tx_layers;
|
||||
int32_t **txdataF;
|
||||
uint16_t start_sc, start_rb;
|
||||
int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
|
||||
uint16_t n_dmrs;
|
||||
uint8_t dmrs_type;
|
||||
uint8_t mapping_type;
|
||||
int ap, start_symbol, i;
|
||||
int sample_offsetF;
|
||||
|
||||
NR_UE_ULSCH_t *ulsch_ue;
|
||||
NR_UL_UE_HARQ_t *harq_process_ul_ue;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
|
||||
NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][eNB_id];
|
||||
|
||||
num_of_codewords = 1; // tmp assumption
|
||||
|
||||
for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) {
|
||||
|
||||
ulsch_ue = UE->ulsch[thread_id][eNB_id][cwd_index];
|
||||
harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
|
||||
|
||||
/////////////////////////ULSCH coding/////////////////////////
|
||||
///////////
|
||||
|
||||
nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid);
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////ULSCH scrambling/////////////////////////
|
||||
///////////
|
||||
|
||||
mod_order = nr_get_Qm(harq_process_ul_ue->mcs, 1);
|
||||
|
||||
available_bits = nr_get_G(harq_process_ul_ue->nb_rb,
|
||||
ulsch_ue->Nsymb_pusch,
|
||||
ulsch_ue->nb_re_dmrs,
|
||||
ulsch_ue->length_dmrs,
|
||||
mod_order,
|
||||
1);
|
||||
|
||||
memset(scrambled_output[cwd_index], 0, ((available_bits>>5)+1)*sizeof(uint32_t));
|
||||
|
||||
nr_pusch_codeword_scrambling(ulsch_ue->g,
|
||||
available_bits,
|
||||
ulsch_ue->Nid_cell,
|
||||
ulsch_ue->rnti,
|
||||
scrambled_output[cwd_index]); // assume one codeword for the moment
|
||||
|
||||
|
||||
/////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////ULSCH modulation/////////////////////////
|
||||
///////////
|
||||
|
||||
nr_modulation(scrambled_output[cwd_index], // assume one codeword for the moment
|
||||
available_bits,
|
||||
mod_order,
|
||||
(int16_t *)ulsch_ue->d_mod);
|
||||
|
||||
pusch_transform_precoding(ulsch_ue, frame_parms, harq_pid);
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
mod_symbols[cwd_index] = (int32_t *)malloc16((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t*));
|
||||
|
||||
memcpy(mod_symbols[cwd_index],ulsch_ue->d_mod,(available_bits/mod_order)*sizeof(int32_t));
|
||||
|
||||
}
|
||||
|
||||
start_symbol = 14 - ulsch_ue->Nsymb_pusch;
|
||||
|
||||
/////////////////////////DMRS Modulation/////////////////////////
|
||||
///////////
|
||||
|
||||
pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
|
||||
n_dmrs = (harq_process_ul_ue->nb_rb*ulsch_ue->nb_re_dmrs);
|
||||
int16_t mod_dmrs[n_dmrs<<1];
|
||||
dmrs_type = UE->dmrs_UplinkConfig.pusch_dmrs_type;
|
||||
mapping_type = UE->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
|
||||
|
||||
l0 = get_l0_ul(mapping_type, 2);
|
||||
nr_modulation(pusch_dmrs[l0][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////ULSCH layer mapping/////////////////////////
|
||||
///////////
|
||||
|
||||
tx_layers = (int16_t **)pusch_ue->txdataF_layers;
|
||||
|
||||
nr_layer_mapping((int16_t **)mod_symbols,
|
||||
harq_process_ul_ue->Nl,
|
||||
available_bits/mod_order,
|
||||
tx_layers);
|
||||
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////ULSCH RE mapping/////////////////////////
|
||||
///////////
|
||||
|
||||
txdataF = UE->common_vars.txdataF;
|
||||
|
||||
start_rb = harq_process_ul_ue->first_rb;
|
||||
start_sc = frame_parms->first_carrier_offset + start_rb*NR_NB_SC_PER_RB;
|
||||
|
||||
if (start_sc >= frame_parms->ofdm_symbol_size)
|
||||
start_sc -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
for (ap=0; ap<harq_process_ul_ue->Nl; ap++) {
|
||||
|
||||
// DMRS params for this ap
|
||||
get_Wt(Wt, ap, dmrs_type);
|
||||
get_Wf(Wf, ap, dmrs_type);
|
||||
delta = get_delta(ap, dmrs_type);
|
||||
l_prime[0] = 0; // single symbol ap 0
|
||||
uint8_t dmrs_symbol = l0+l_prime[0]; // Assuming dmrs-AdditionalPosition = 0
|
||||
|
||||
uint8_t k_prime=0, l;
|
||||
uint16_t m=0, n=0, dmrs_idx=0, k=0;
|
||||
|
||||
for (l=start_symbol; l<start_symbol+ulsch_ue->Nsymb_pusch; l++) {
|
||||
|
||||
k = start_sc;
|
||||
|
||||
for (i=0; i<harq_process_ul_ue->nb_rb*NR_NB_SC_PER_RB; i++) {
|
||||
|
||||
sample_offsetF = l*frame_parms->ofdm_symbol_size + k;
|
||||
|
||||
if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%(frame_parms->ofdm_symbol_size)))) {
|
||||
|
||||
((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 txdataF: %d %d\n",
|
||||
dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1],
|
||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]);
|
||||
#endif
|
||||
|
||||
dmrs_idx++;
|
||||
k_prime++;
|
||||
k_prime&=1;
|
||||
n+=(k_prime)?0:1;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (AMP * tx_layers[ap][m<<1]) >> 15;
|
||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (AMP * tx_layers[ap][(m<<1) + 1]) >> 15;
|
||||
|
||||
#ifdef DEBUG_PUSCH_MAPPING
|
||||
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
|
||||
m, l, k, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1],
|
||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]);
|
||||
#endif
|
||||
|
||||
m++;
|
||||
}
|
||||
|
||||
if (++k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
uint8_t slot,
|
||||
uint8_t Nl,
|
||||
NR_DL_FRAME_PARMS *frame_parms) {
|
||||
|
||||
int tx_offset, ap;
|
||||
int32_t **txdata;
|
||||
int32_t **txdataF;
|
||||
|
||||
/////////////////////////IFFT///////////////////////
|
||||
///////////
|
||||
|
||||
tx_offset = slot*frame_parms->samples_per_slot;
|
||||
txdata = UE->common_vars.txdata;
|
||||
txdataF = UE->common_vars.txdataF;
|
||||
|
||||
for (ap = 0; ap < Nl; ap++) {
|
||||
if (frame_parms->Ncp == 1) { // extended cyclic prefix
|
||||
PHY_ofdm_mod(txdataF[ap],
|
||||
&txdata[ap][tx_offset],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
12,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
} else { // normal cyclic prefix
|
||||
nr_normal_prefix_mod(txdataF[ap],
|
||||
&txdata[ap][tx_offset],
|
||||
14,
|
||||
frame_parms);
|
||||
}
|
||||
}
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user