Commit c5bc4424 authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/better-log-ue-sync' into integration_2024_w13

parents c9265000 f4ac4fee
......@@ -1127,15 +1127,15 @@ class OaiCiTest():
mib_found = True
except Exception as e:
logging.error(f'\033[91m MIB marker was not found \033[0m')
result = re.search("Measured Carrier Frequency (?P<measured_carrier_frequency>\d{1,15}) Hz", str(line))
result = re.search("Initial sync: pbch decoded sucessfully", str(line))
if result is not None and (not frequency_found):
try:
mibMsg = f"Measured Carrier Frequency = {result.group('measured_carrier_frequency')} Hz"
mibMsg = f"UE decoded PBCH successfully"
HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n'
logging.debug(f'\033[94m{mibMsg}\033[0m')
frequency_found = True
except Exception as e:
logging.error(f'\033[91m Measured Carrier Frequency not found \033[0m')
logging.error(f'\033[91m UE did not find PBCH\033[0m')
result = re.search("PLMN MCC (?P<mcc>\d{1,3}), MNC (?P<mnc>\d{1,3}), TAC", str(line))
if result is not None and (not plmn_found):
try:
......
......@@ -254,9 +254,10 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
gNB->nr_srs_info = (nr_srs_info_t **)malloc16_clear(gNB->max_nb_srs * sizeof(nr_srs_info_t*));
for (int id = 0; id < gNB->max_nb_srs; id++) {
gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
gNB->nr_srs_info[id]->srs_generated_signal = (int32_t**)malloc16_clear(MAX_NUM_NR_SRS_AP*sizeof(int32_t*));
gNB->nr_srs_info[id]->srs_generated_signal = malloc16_clear(MAX_NUM_NR_SRS_AP * sizeof(c16_t *));
for(int ap=0; ap<MAX_NUM_NR_SRS_AP; ap++) {
gNB->nr_srs_info[id]->srs_generated_signal[ap] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t));
gNB->nr_srs_info[id]->srs_generated_signal[ap] =
malloc16_clear(fp->ofdm_symbol_size * MAX_NUM_NR_SRS_SYMBOLS * sizeof(c16_t));
}
}
......
......@@ -318,24 +318,19 @@ void nr_layer_mapping(int nbCodes,
}
}
void nr_ue_layer_mapping(int16_t *mod_symbs,
uint8_t n_layers,
uint32_t n_symbs,
int16_t **tx_layers) {
void nr_ue_layer_mapping(const c16_t *mod_symbs, const int n_layers, const int n_symbs, int sz, c16_t tx_layers[][sz])
{
for (int i=0; i<n_symbs/n_layers; i++) {
for (int l=0; l<n_layers; l++) {
tx_layers[l][i<<1] = (mod_symbs[(n_layers*i+l)<<1]*AMP)>>15;
tx_layers[l][(i<<1)+1] = (mod_symbs[((n_layers*i+l)<<1)+1]*AMP)>>15;
tx_layers[l][i] = c16mulRealShift(mod_symbs[n_layers * i + l], AMP, 15);
}
}
}
void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
void nr_dft(c16_t *z, c16_t *d, uint32_t Msc_PUSCH)
{
simde__m128i dft_in128[1][3240], dft_out128[1][3240];
uint32_t *dft_in0 = (uint32_t*)dft_in128[0], *dft_out0 = (uint32_t*)dft_out128[0];
simde__m128i dft_in128[3240], dft_out128[3240];
c16_t *dft_in0 = (c16_t *)dft_in128, *dft_out0 = (c16_t *)dft_out128;
uint32_t i, ip;
......@@ -659,36 +654,32 @@ void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp)
}
}
int nr_layer_precoder(int16_t **datatx_F_precoding, const char *prec_matrix, uint8_t n_layers, int32_t re_offset)
c16_t nr_layer_precoder(int sz, c16_t datatx_F_precoding[][sz], const char *prec_matrix, uint8_t n_layers, int32_t re_offset)
{
int32_t precodatatx_F = 0;
c16_t precodatatx_F = {0};
for (int al = 0; al<n_layers; al++) {
int16_t antenna_re = datatx_F_precoding[al][re_offset<<1];
int16_t antenna_im = datatx_F_precoding[al][(re_offset<<1) +1];
c16_t antenna = datatx_F_precoding[al][re_offset];
switch (prec_matrix[al]) {
case '0': //multiply by zero
break;
case '1': //multiply by 1
((int16_t *) &precodatatx_F)[0] += antenna_re;
((int16_t *) &precodatatx_F)[1] += antenna_im;
precodatatx_F = c16add(precodatatx_F, antenna);
break;
case 'n': // multiply by -1
((int16_t *) &precodatatx_F)[0] -= antenna_re;
((int16_t *) &precodatatx_F)[1] -= antenna_im;
precodatatx_F = c16sub(precodatatx_F, antenna);
break;
case 'j': //
((int16_t *) &precodatatx_F)[0] -= antenna_im;
((int16_t *) &precodatatx_F)[1] += antenna_re;
precodatatx_F.r -= antenna.i;
precodatatx_F.i += antenna.r;
break;
case 'o': // -j
((int16_t *) &precodatatx_F)[0] += antenna_im;
((int16_t *) &precodatatx_F)[1] -= antenna_re;
precodatatx_F.r += antenna.i;
precodatatx_F.i -= antenna.r;
break;
}
}
......
......@@ -68,13 +68,7 @@ void nr_layer_mapping(int nbCodes,
@param[in] n_symbs, number of modulated symbols
@param[out] tx_layers, modulated symbols for each layer
*/
void nr_ue_layer_mapping(int16_t *mod_symbs,
uint8_t n_layers,
uint32_t n_symbs,
int16_t **tx_layers);
void nr_ue_layer_mapping(const c16_t *mod_symbs, const int n_layers, const int n_symbs, int sz, c16_t tx_layers[][sz]);
/*!
\brief This function implements the OFDM front end processor on reception (FEP)
\param frame_parms Pointer to frame parameters
......@@ -98,7 +92,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
\param d Pointer to input in time domain
\param Msc_PUSCH number of allocated data subcarriers
*/
void nr_dft(int32_t *z,int32_t *d, uint32_t Msc_PUSCH);
void nr_dft(c16_t *z, c16_t *d, uint32_t Msc_PUSCH);
int nr_beam_precoding(c16_t **txdataF,
c16_t **txdataF_BF,
......@@ -137,7 +131,7 @@ void apply_nr_rotation_RX(NR_DL_FRAME_PARMS *frame_parms,
@param[in] prec_matrix, Pointer to precoding matrix
@param[in] n_layers, number of DLSCH layers
*/
int nr_layer_precoder(int16_t **datatx_F_precoding, const char *prec_matrix, uint8_t n_layers, int32_t re_offset);
c16_t nr_layer_precoder(int sz, c16_t datatx_F_precoding[][sz], const char *prec_matrix, uint8_t n_layers, int32_t re_offset);
c16_t nr_layer_precoder_cm(int n_layers,
int n_symbols,
......
......@@ -114,7 +114,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
nr_pusch_dmrs_rx(gNB,
Ns,
gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol],
(int32_t *)pilot,
pilot,
(1000 + p),
0,
nb_rb_pusch,
......@@ -122,14 +122,14 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
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
const uint16_t index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB/2));
const int index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB / 2));
const uint8_t u = pusch_pdu->dfts_ofdm.low_papr_group_number;
const uint8_t v = pusch_pdu->dfts_ofdm.low_papr_sequence_number;
int16_t *dmrs_seq = gNB_dmrs_lowpaprtype1_sequence[u][v][index];
c16_t *dmrs_seq = gNB_dmrs_lowpaprtype1_sequence[u][v][index];
LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", 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");
nr_pusch_lowpaprtype1_dmrs_rx(gNB, Ns, dmrs_seq, (int32_t *)pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type);
nr_pusch_lowpaprtype1_dmrs_rx(gNB, Ns, dmrs_seq, pilot, 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);
......@@ -611,19 +611,21 @@ uint32_t calc_power(const int16_t *x, const uint32_t size) {
return sum_x2/size - (sum_x/size)*(sum_x/size);
}
int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
const int frame,
const int slot,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
const int32_t **srs_generated_signal,
int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_estimated_channel_freq[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_estimated_channel_time[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
int32_t srs_estimated_channel_time_shifted[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
int8_t *snr_per_rb,
int8_t *snr) {
int nr_srs_channel_estimation(
const PHY_VARS_gNB *gNB,
const int frame,
const int slot,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
const c16_t **srs_generated_signal,
int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
int32_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports]
[gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
int32_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
int32_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
int8_t *snr_per_rb,
int8_t *snr)
{
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__);
#endif
......@@ -694,9 +696,8 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
uint16_t subcarrier_cdm = subcarrier;
for (int cdm_idx = 0; cdm_idx < fd_cdm; cdm_idx++) {
int16_t generated_real = ((c16_t*)srs_generated_signal[p_index])[subcarrier_cdm].r;
int16_t generated_imag = ((c16_t*)srs_generated_signal[p_index])[subcarrier_cdm].i;
int16_t generated_real = srs_generated_signal[p_index][subcarrier_cdm].r;
int16_t generated_imag = srs_generated_signal[p_index][subcarrier_cdm].i;
int16_t received_real = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].r;
int16_t received_imag = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].i;
......
......@@ -72,18 +72,20 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
unsigned char symbol,
uint32_t nb_re_pusch);
int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
const int frame,
const int slot,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
const int32_t **srs_generated_signal,
int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_estimated_channel_freq[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_estimated_channel_time[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
int32_t srs_estimated_channel_time_shifted[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
int8_t *snr_per_rb,
int8_t *snr);
int nr_srs_channel_estimation(
const PHY_VARS_gNB *gNB,
const int frame,
const int slot,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
const c16_t **srs_generated_signal,
int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
int32_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports]
[gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
int32_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
int32_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
int8_t *snr_per_rb,
int8_t *snr);
void nr_freq_equalization(NR_DL_FRAME_PARMS *frame_parms,
int *rxdataF_comp,
......
......@@ -51,10 +51,10 @@ static const int wt2[12][2] =
{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}};
// complex conjugate of mod table
static const short nr_rx_mod_table[14] =
{0, 0, 23170, -23170, -23170, 23170, 23170, -23170, 23170, 23170, -23170, -23170, -23170, 23170};
static const short nr_rx_nmod_table[14] =
{0, 0, -23170, 23170, 23170, -23170, -23170, 23170, -23170, -23170, 23170, 23170, 23170, -23170};
static const c16_t nr_rx_mod_table[7] =
{{0, 0}, {23170, -23170}, {-23170, 23170}, {23170, -23170}, {23170, 23170}, {-23170, -23170}, {-23170, 23170}};
static const c16_t nr_rx_nmod_table[7] =
{{0, 0}, {-23170, 23170}, {23170, -23170}, {-23170, 23170}, {-23170, -23170}, {23170, 23170}, {23170, -23170}};
int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p) {
if (dmrs_config_type == pusch_dmrs_type1) {
......@@ -67,7 +67,7 @@ int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p) {
int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
unsigned int Ns,
unsigned int *nr_gold_pusch,
int32_t *output,
c16_t *output,
unsigned short p,
unsigned char lp,
unsigned short nb_pusch_rb,
......@@ -92,16 +92,21 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
for (int i=dmrs_offset; i<dmrs_offset+(nb_pusch_rb*nb_dmrs); i++) {
k = i-dmrs_offset;
w = (wf[p-1000][i&1])*(wt[p-1000][lp]);
const short *mod_table = (w == 1) ? nr_rx_mod_table : nr_rx_nmod_table;
const c16_t *mod_table = (w == 1) ? nr_rx_mod_table : nr_rx_nmod_table;
idx = ((((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
((int16_t*)output)[k<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
((int16_t*)output)[(k<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
output[k] = mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx];
#ifdef DEBUG_PUSCH
printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", dmrs_type, p, nb_pusch_rb);
printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]);
printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pusch[(i<<1)>>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1),
(((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[k<<1], ((int16_t*)output)[(k<<1)+1]);
printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n",
i,
idx,
nr_gold_pusch[(i << 1) >> 5],
(((nr_gold_pusch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1),
(((nr_gold_pusch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1),
output[k].r,
output[k].i);
#endif
}
......@@ -115,11 +120,10 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
return(0);
}
int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
unsigned int Ns,
unsigned int *nr_gold_pdsch,
int32_t *output,
c16_t *output,
unsigned short p,
unsigned char lp,
unsigned short nb_pdsch_rb,
......@@ -139,11 +143,10 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
if (ue->frame_parms.Ncp == NORMAL) {
for (int i = 0; i < nb_pdsch_rb * ((config_type == NFAPI_NR_DMRS_TYPE1) ? 6 : 4); i++) {
w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]);
const short *mod_table = (w == 1) ? nr_rx_mod_table : nr_rx_nmod_table;
const c16_t *mod_table = (w == 1) ? nr_rx_mod_table : nr_rx_nmod_table;
idx = ((((nr_gold_pdsch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1) << 1) ^ (((nr_gold_pdsch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1);
((int16_t *)output)[i << 1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx) << 1];
((int16_t *)output)[(i << 1) + 1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx) << 1) + 1];
output[i] = mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx];
#ifdef DEBUG_PDSCH
printf("nr_pdsch_dmrs_rx dmrs config type %d port %d nb_pdsch_rb %d\n", config_type, p, nb_pdsch_rb);
printf("wf[%d] = %d wt[%d]= %d\n", i & 1, wf[p - 1000][i & 1], lp, wt[p - 1000][lp]);
......@@ -153,8 +156,8 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
nr_gold_pdsch[(i << 1) >> 5],
(((nr_gold_pdsch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1),
(((nr_gold_pdsch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1),
((int16_t *)output)[i << 1],
((int16_t *)output)[(i << 1) + 1]);
output[i].r,
output[i].i);
#endif
}
} else {
......@@ -167,11 +170,10 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
return(0);
}
int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
unsigned int Ns,
unsigned int *nr_gold_pdcch,
int32_t *output,
c16_t *output,
unsigned short p,
unsigned short nb_rb_coreset)
{
......@@ -182,12 +184,17 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
if (p==2000) {
for (int i=0; i<((nb_rb_coreset*6)>>1); i++) {
idx = ((((nr_gold_pdcch[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pdcch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
((int16_t*)output)[i<<1] = nr_rx_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
((int16_t*)output)[(i<<1)+1] = nr_rx_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
output[i] = nr_rx_mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx];
#ifdef DEBUG_PDCCH
if (i<8)
printf("i %d idx %d pdcch gold %u b0-b1 %d-%d mod_dmrs %d %d addr %p\n", i, idx, nr_gold_pdcch[(i<<1)>>5], (((nr_gold_pdcch[(i<<1)>>5])>>((i<<1)&0x1f))&1),
(((nr_gold_pdcch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1],&output[0]);
printf("i %d idx %d pdcch gold %u b0-b1 %d-%d mod_dmrs %d %d\n",
i,
idx,
nr_gold_pdcch[(i << 1) >> 5],
(((nr_gold_pdcch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1),
(((nr_gold_pdcch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1),
output[i].r,
output[i].i);
#endif
}
}
......@@ -195,8 +202,7 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
return(0);
}
int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, int32_t *output)
void nr_pbch_dmrs_rx(const int symbol, const unsigned int *nr_gold_pbch, c16_t *output)
{
int m,m0,m1;
uint8_t idx=0;
......@@ -217,18 +223,15 @@ int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, int32_t *output)
/// QPSK modulation
for (m=m0; m<m1; m++) {
idx = ((((nr_gold_pbch[(m<<1)>>5])>>((m<<1)&0x1f))&1)<<1) ^ (((nr_gold_pbch[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1);
((int16_t*)output)[(m-m0)<<1] = nr_rx_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
((int16_t*)output)[((m-m0)<<1)+1] = nr_rx_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
output[m - m0] = nr_rx_mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx];
#ifdef DEBUG_PBCH
if (m<16)
{printf("nr_gold_pbch[(m<<1)>>5] %x\n",nr_gold_pbch[(m<<1)>>5]);
printf("m %d output %d %d addr %p\n", m, ((int16_t*)output)[m<<1], ((int16_t*)output)[(m<<1)+1],&output[0]);
printf("m %d output %d %d\n", m, output[m].r, output[m].i);
}
#endif
}
return(0);
}
/*!
......@@ -237,7 +240,7 @@ int nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, int32_t *output)
\param length is number of RE in a OFDM symbol
\param *output pointer to all ptrs RE in a OFDM symbol
*/
void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order)
void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, c16_t *output, uint16_t offset, int mod_order)
{
uint8_t idx, b_idx;
for (int i=0; i<length/mod_order; i++)
......@@ -250,15 +253,14 @@ void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uin
in++;
idx ^= (((*in)>>b_idx)&1)<<(mod_order-j-1);
}
output[i<<1] = nr_rx_mod_table[(offset+idx)<<1];
output[(i<<1)+1] = nr_rx_mod_table[((offset+idx)<<1)+1];
output[i] = nr_rx_mod_table[offset + idx];
}
}
int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB,
unsigned int Ns,
int16_t *dmrs_seq,
int32_t *output,
c16_t *dmrs_seq,
c16_t *output,
unsigned short p,
unsigned char lp,
unsigned short nb_pusch_rb,
......@@ -278,19 +280,21 @@ int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB,
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
w = (wf1[p - 1000][i & 1]) * (wt1[p - 1000][lp]);
#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
output[k].r = w * dmrs_seq[i].r;
output[k].i = -w * dmrs_seq[i].i; // 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].r, dmrs_seq[i].i, output[k].r, output[(k].i);
#endif
}
} else {
LOG_E(PHY,"extended cp not supported for PUSCH DMRS yet\n");
......
......@@ -54,7 +54,7 @@ int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p);
int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
unsigned int Ns,
unsigned int *nr_gold_pusch,
int32_t *output,
c16_t *output,
unsigned short p,
unsigned char lp,
unsigned short nb_pusch_rb,
......@@ -68,18 +68,14 @@ extern simde__m64 byte2m64_re[256];
extern simde__m64 byte2m64_im[256];
extern simde__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);
unsigned int Ns,
c16_t *dmrs_seq,
c16_t *output,
unsigned short p,
unsigned char lp,
unsigned short nb_pusch_rb,
uint32_t re_offset,
uint8_t dmrs_type);
#endif
......@@ -27,13 +27,10 @@
#include "PHY/defs_nr_UE.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
*/
int nr_pbch_dmrs_rx(int dmrss,
unsigned int *nr_gold_pbch,
int32_t *output);
void nr_pbch_dmrs_rx(const int dmrss, const unsigned int *nr_gold_pbch, c16_t *output);
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
......@@ -41,14 +38,14 @@ int nr_pbch_dmrs_rx(int dmrss,
int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
unsigned int Ns,
unsigned int *nr_gold_pdcch,
int32_t *output,
c16_t *output,
unsigned short p,
unsigned short nb_rb_corset);
int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
unsigned int Ns,
unsigned int *nr_gold_pdsch,
int32_t *output,
c16_t *output,
unsigned short p,
unsigned char lp,
unsigned short nb_pdsch_rb,
......
......@@ -52,53 +52,44 @@
*
*********************************************************************/
static int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling)
static c16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling)
{
char *phi_table;
int16_t *rv_overbar;
double x;
unsigned int n;
const char *phi_table;
switch(M_ZC) {
case 6:
phi_table = (char *)phi_M_ZC_6;
phi_table = phi_M_ZC_6;
break;
case 12:
phi_table = (char *)phi_M_ZC_12;
phi_table = phi_M_ZC_12;
break;
case 18:
phi_table = (char *)phi_M_ZC_18;
phi_table = phi_M_ZC_18;
break;
case 24:
phi_table = (char *)phi_M_ZC_24;
phi_table = phi_M_ZC_24;
break;
case 30:
break;
default:
printf("function base_sequence_less_than 36_: unsupported base sequence size : %u \n", M_ZC);
assert(0);
AssertFatal(false, "function base_sequence_less_than 36_: unsupported base sequence size : %u \n", M_ZC);
break;
}
rv_overbar = malloc16(IQ_SIZE*M_ZC);
if (rv_overbar == NULL) {
msg("Fatal memory allocation problem \n");
assert(0);
}
c16_t *rv_overbar = malloc16(IQ_SIZE * M_ZC);
AssertFatal(rv_overbar, "Fatal memory allocation problem \n");
if (M_ZC == 30) {
for (n=0; n<M_ZC; n++) {
x = -(M_PI * (u + 1) * (n + 1) * (n + 2))/(double)31;
rv_overbar[2*n] =(int16_t)(floor(scaling*cos(x)));
rv_overbar[2*n+1] =(int16_t)(floor(scaling*sin(x)));
for (unsigned int n = 0; n < M_ZC; n++) {
const double x = -(M_PI * (u + 1) * (n + 1) * (n + 2)) / (double)31;
rv_overbar[n].r = (int16_t)(floor(scaling * cos(x)));
rv_overbar[n].i = (int16_t)(floor(scaling * sin(x)));
}
}
else {
for (n=0; n<M_ZC; n++) {
x = (double)phi_table[n + u*M_ZC] * (M_PI/4);
rv_overbar[2*n] = (int16_t)(floor(scaling*cos(x)));
rv_overbar[2*n+1] = (int16_t)(floor(scaling*sin(x)));
for (unsigned int n = 0; n < M_ZC; n++) {
const double x = (double)phi_table[n + u * M_ZC] * (M_PI / 4);
rv_overbar[n].r = (int16_t)(floor(scaling * cos(x)));
rv_overbar[n].i = (int16_t)(floor(scaling * sin(x)));
}
}
return rv_overbar;
......@@ -117,9 +108,9 @@ static int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, un
*
*********************************************************************/
int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res) {
int16_t index = num_dmrs_res/6 - 1;
int get_index_for_dmrs_lowpapr_seq(int num_dmrs_res)
{
int index = num_dmrs_res / 6 - 1;
if (index >= MAX_INDEX_DMRS_UL_ALLOCATED_REs)
index = MAX_INDEX_DMRS_UL_ALLOCATED_REs-1;
......@@ -149,79 +140,63 @@ int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res) {
*
*********************************************************************/
static int16_t *base_sequence_36_or_larger(unsigned int Msc_RS,
unsigned int u,
unsigned int v,
unsigned int scaling,
unsigned int if_dmrs_seq)
static c16_t *base_sequence_36_or_larger(unsigned int Msc_RS,
unsigned int u,
unsigned int v,
unsigned int scaling,
unsigned int if_dmrs_seq)
{
int16_t *rv_overbar;
unsigned int N_ZC, M_ZC;
double q_overbar, x;
unsigned int q,m,n;
const unsigned int M_ZC = if_dmrs_seq ? dmrs_ul_allocated_res[Msc_RS] : 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];
c16_t *rv_overbar = malloc16(IQ_SIZE * M_ZC);
AssertFatal(rv_overbar, "Fatal memory allocation problem \n");
rv_overbar = malloc16(IQ_SIZE*M_ZC);
if (rv_overbar == NULL) {
msg("Fatal memory allocation problem \n");
assert(0);
}
/* The length N_ZC is given by the largest prime number such that N_ZC < M_ZC */
const unsigned int N_ZC = if_dmrs_seq ? dmrs_ref_ul_primes[Msc_RS] : ref_ul_primes[Msc_RS];
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;
const double q_overbar = N_ZC * (u + 1) / (double)31;
/* q = (q_overbar + 1/2) + v.(-1)^(2q_overbar) */
double q;
if ((((int)floor(2*q_overbar))&1) == 0)
q = (int)(floor(q_overbar+.5)) - v;
q = floor(q_overbar + .5) - v;
else
q = (int)(floor(q_overbar+.5)) + v;
q = floor(q_overbar + .5) + v;
for (n = 0; n < M_ZC; n++) {
m=n%N_ZC;
x = (double)q * m * (m+1)/N_ZC;
rv_overbar[2*n] = (int16_t)(floor(scaling*cos(M_PI*x))); /* cos(-x) = cos(x) */
rv_overbar[2*n+1] = -(int16_t)(floor(scaling*sin(M_PI*x))); /* sin(-x) = -sin(x) */
for (int n = 0; n < M_ZC; n++) {
const int m = n % N_ZC;
const double x = q * m * (m + 1) / N_ZC;
rv_overbar[n].r = (int16_t)(floor(scaling * cos(M_PI * x))); /* cos(-x) = cos(x) */
rv_overbar[n].i = -(int16_t)(floor(scaling * sin(M_PI * x))); /* sin(-x) = -sin(x) */
}
return rv_overbar;
}
int16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF];
int16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
c16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF];
c16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling)
{
/* prevent multiple calls, relevant when both UE & gNB initialize this */
static bool already_called = false;
if (already_called) return;
if (already_called)
return;
already_called = true;
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++) {
for (unsigned int Msc_RS = 0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) {
for (unsigned int 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);
}
}
for (unsigned int Msc_RS = INDEX_SB_LESS_32 + 1; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) {
for (unsigned int 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);
}
}
}
int16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
c16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
void generate_ul_reference_signal_sequences(unsigned int scaling)
{
/* prevent multiple calls, relevant when both UE & gNB initialize this */
......
......@@ -228,7 +228,7 @@ static const uint16_t ref_ul_primes[SRS_SB_CONF] = {
};
/* Low-PAPR base sequence; see TS 38.211 clause 5.2.2 */
extern int16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF];
extern c16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF];
/* 38.211 table Table 5.2.2.2-1: Definition of phi(n) for M_ZC = 6 */
static const char phi_M_ZC_6[6 * U_GROUP_NUMBER] = {
......@@ -524,9 +524,9 @@ static const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs] = {
};
/// PUSCH DMRS for transform precoding
extern int16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
extern 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);
extern c16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
extern c16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
int get_index_for_dmrs_lowpapr_seq(int num_dmrs_res);
void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling);
void free_gnb_lowpapr_sequences(void);
......
......@@ -20,15 +20,16 @@
*/
#ifndef __FILT16A_H__
#define __FILT16A_H__
static const short filt16a_l0[16] = {16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const c16_t filt16a_l0[8] = {{16384, 12288}, {8192, 4096}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}};
static const short filt16a_mm0[16] = {0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0};
static const short filt16a_r0[16] = {0, 0, 0, 0, 0, 4096, 8192, 12288, 16384, 20480, 24576, 28672, 0, 0, 0, 0};
static const c16_t filt16a_r0[8] = {{0, 0}, {0, 0}, {0, 4096}, {8192, 12288}, {16384, 20480}, {24576, 28672}, {0, 0}, {0, 0}};
static const short filt16a_m0[16] = {0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, -8192, -12288, 0, 0, 0, 0};
static const c16_t filt16a_m0[8] =
{{0, 4096}, {8192, 12288}, {16384, 12288}, {8192, 4096}, {0, -4096}, {-8192, -12288}, {0, 0}, {0, 0}};
static const short filt16a_l1[16] = {20480, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const c16_t filt16a_l1[8] = {{20480, 16384}, {12288, 8192}, {4096, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}};
static const short filt16a_mm1[16] = {0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0};
......@@ -36,11 +37,12 @@ static const short filt16a_ml1[16] = {-4096, 0, 4096, 8192, 12288, 16384, 12288,
static const short filt16a_mr1[16] = {0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, -8192, 0, 0, 0, 0};
static const short filt16a_r1[16] = {0, 0, 0, 0, 0, 0, 4096, 8192, 12288, 16384, 20480, 24576, 0, 0, 0, 0};
static const c16_t filt16a_r1[8] = {{0, 0}, {0, 0}, {0, 0}, {4096, 8192}, {12288, 16384}, {20480, 24576}, {0, 0}, {0, 0}};
static const short filt16a_m1[16] = {-4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, -8192, 0, 0, 0, 0};
static const c16_t filt16a_m1[8] =
{{-4096, 0}, {4096, 8192}, {12288, 16384}, {12288, 8192}, {4096, 0}, {-4096, -8192}, {0, 0}, {0, 0}};
static const short filt16a_l2[16] = {24576, 20480, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const c16_t filt16a_l2[8] = {{24576, 20480}, {16384, 12288}, {8192, 4096}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}};
static const short filt16a_mm2[16] = {0, 0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0};
......@@ -48,19 +50,21 @@ static const short filt16a_ml2[16] = {-8192, -4096, 0, 4096, 8192, 12288, 16384,
static const short filt16a_mr2[16] = {0, 0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, 0, 0, 0, 0};
static const short filt16a_r2[16] = {0, 0, 0, 0, 0, 0, 0, 4096, 8192, 12288, 16384, 20480, 0, 0, 0, 0};
static const c16_t filt16a_r2[8] = {{0, 0}, {0, 0}, {0, 0}, {0, 4096}, {8192, 12288}, {16384, 20480}, {0, 0}, {0, 0}};
static const short filt16a_m2[16] = {-8192, -4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, -4096, 0, 0, 0, 0};
static const c16_t filt16a_m2[8] =
{{-8192, -4096}, {0, 4096}, {8192, 12288}, {16384, 12288}, {8192, 4096}, {0, -4096}, {0, 0}, {0, 0}};
static const short filt16a_l3[16] = {28672, 24576, 20480, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const c16_t filt16a_l3[8] = {{28672, 24576}, {20480, 16384}, {12288, 8192}, {4096, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}};
static const short filt16a_mm3[16] = {0, 0, 0, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0};
static const short filt16a_ml3[16] = {-12288, -8192, -4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0};
static const short filt16a_r3[16] = {0, 0, 0, 0, 0, 0, 0, 0, 4096, 8192, 12288, 16384, 0, 0, 0, 0};
static const c16_t filt16a_r3[8] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {4096, 8192}, {12288, 16384}, {0, 0}, {0, 0}};
static const short filt16a_m3[16] = {-12288, -8192, -4096, 0, 4096, 8192, 12288, 16384, 12288, 8192, 4096, 0, 0, 0, 0, 0};
static const c16_t filt16a_m3[8] =
{{-12288, -8192}, {-4096, 0}, {4096, 8192}, {12288, 16384}, {12288, 8192}, {4096, 0}, {0, 0}, {0, 0}};
static const short filt16a_l0_dc[16] = {16384, 12288, 8192, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
......
......@@ -37,9 +37,10 @@
extern openair0_config_t openair0_cfg[];
//#define DEBUG_PDSCH
//#define DEBUG_PDCCH
//#define DEBUG_PBCH
// #define DEBUG_PDSCH
// #define DEBUG_PDCCH
// #define DEBUG_PBCH(a...) printf(a)
#define DEBUG_PBCH(a...)
//#define DEBUG_PRS_CHEST // To enable PRS Matlab dumps
//#define DEBUG_PRS_PRINTS // To enable PRS channel estimation debug logs
......@@ -295,39 +296,39 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
// Choose the interpolation filters
switch (k_prime) {
case 0:
fl = filt16a_l0;
fl = (short int *)filt16a_l0;
fml = filt16a_mm0;
fmm = filt16a_mm0;
fmr = filt16a_m0;
fm = filt16a_m0;
fr = filt16a_r0;
fmr = (short int *)filt16a_m0;
fm = (short int *)filt16a_m0;
fr = (short int *)filt16a_r0;
break;
case 1:
fl = filt16a_l1;
fl = (short int *)filt16a_l1;
fml = filt16a_ml1;
fmm = filt16a_mm1;
fmr = filt16a_mr1;
fm = filt16a_m1;
fr = filt16a_r1;
fm = (short int *)filt16a_m1;
fr = (short int *)filt16a_r1;
break;
case 2:
fl = filt16a_l2;
fl = (short int *)filt16a_l2;
fml = filt16a_ml2;
fmm = filt16a_mm2;
fmr = filt16a_mr2;
fm = filt16a_m2;
fr = filt16a_r2;
fm = (short int *)filt16a_m2;
fr = (short int *)filt16a_r2;
break;
case 3:
fl = filt16a_l3;
fl = (short int *)filt16a_l3;
fml = filt16a_ml3;
fmm = filt16a_mm3;
fmr = filt16a_mm3;
fm = filt16a_m3;
fr = filt16a_r3;
fm = (short int *)filt16a_m3;
fr = (short int *)filt16a_r3;
break;
default:
......@@ -630,156 +631,89 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
return(0);
}
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
int dmrss,
NR_UE_SSB *current_ssb,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
const int symbol,
const int dmrss,
const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD],
const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{
int pilot[200] __attribute__((aligned(16)));
unsigned int pilot_cnt;
int16_t ch[2],*pil,*rxF;
int symbol_offset;
uint8_t ssb_index=current_ssb->i_ssb;
uint8_t n_hf=current_ssb->n_hf;
AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss);
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
AssertFatal(dmrss >= 0 && dmrss < 3,
"symbol %d is illegal for PBCH DM-RS \n",
dmrss);
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol;
unsigned int k = ue->frame_parms.Nid_cell % 4;
#ifdef DEBUG_PBCH
printf("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", proc->gNB_id, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol);
#endif
DEBUG_PBCH("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, k=%d symbol %d\n",
proc->gNB_id,
ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,
k,
symbol);
// generate pilot
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
c16_t pilot[200] __attribute__((aligned(16)));
nr_pbch_dmrs_rx(dmrss, nr_gold_pbch, pilot);
c32_t computed_val = {0};
for (int aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
int re_offset = ssb_offset;
pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
c16_t *pil = pilot;
const c16_t *rxF = &rxdataF[aarx][symbol_offset + k];
#ifdef DEBUG_PBCH
printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
printf("rxF addr %p\n", rxF);
#endif
//if ((ue->frame_parms.N_RB_DL&1)==0) {
DEBUG_PBCH("pbch ch est pilot RB_DL %d\n", ue->frame_parms.N_RB_DL);
DEBUG_PBCH("k %d, first_carrier %d\n", k, ue->frame_parms.first_carrier_offset);
// Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re += ch[0];
current_ssb->c_im += ch[1];
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
#ifdef DEBUG_PBCH
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
DEBUG_PBCH("ch 0 %d\n", pil->r * rxF[re_offset].r - pil->i * rxF[re_offset].i);
DEBUG_PBCH("pilot 0 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re += ch[0];
current_ssb->c_im += ch[1];
#ifdef DEBUG_PBCH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
pil += 2;
pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
current_ssb->c_re += ch[0];
current_ssb->c_im += ch[1];
DEBUG_PBCH("pilot 1 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
#ifdef DEBUG_PBCH
printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
pil += 2;
pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt += 3) {
DEBUG_PBCH("pilot 2 : rxF - > (%d,%d), pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
// if (pilot_cnt == 30)
// rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)];
pil++;
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size;
for (int pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) {
// in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS)
if (dmrss == 1 && pilot_cnt == 12) {
pilot_cnt=48;
re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
re_offset = (re_offset + 144) % ue->frame_parms.ofdm_symbol_size;
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re += ch[0];
current_ssb->c_im += ch[1];
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
#ifdef DEBUG_PBCH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re += ch[0];
current_ssb->c_im += ch[1];
#ifdef DEBUG_PBCH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
pil += 2;
pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
current_ssb->c_re += ch[0];
current_ssb->c_im += ch[1];
#ifdef DEBUG_PBCH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
pil += 2;
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 1, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 2, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size;
}
//}
}
return(0);
return computed_val;
}
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
......@@ -794,33 +728,31 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{
int Ns = proc->nr_slot_rx;
int pilot[200] __attribute__((aligned(16)));
unsigned short k;
unsigned int pilot_cnt;
int16_t *pil, *rxF, *dl_ch;
const int16_t *fl, *fm, *fr;
int ch_offset,symbol_offset;
c16_t pilot[200] __attribute__((aligned(16)));
//int slot_pbch;
uint8_t nushift;
nushift = ue->frame_parms.Nid_cell % 4;
const int nushift = ue->frame_parms.Nid_cell % 4;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol;
const int ch_offset = ue->frame_parms.ofdm_symbol_size * symbol;
AssertFatal(dmrss >= 0 && dmrss < 3,
"symbol %d is illegal for PBCH DM-RS \n",
dmrss);
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
k = nushift;
const int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol;
#ifdef DEBUG_PBCH
printf("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", proc->gNB_id, ch_offset, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol);
#endif
const int k = nushift;
const c16_t *fl, *fm, *fr;
DEBUG_PBCH("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",
proc->gNB_id,
ch_offset,
ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,
Ns,
k,
symbol);
switch (k) {
case 0:
......@@ -903,136 +835,91 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
// generate pilot
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
nr_pbch_dmrs_rx(dmrss, ue->nr_gold_pbch[n_hf][ssb_index], pilot);
for (int aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
int re_offset = ssb_offset;
pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
c16_t *pil = pilot;
c16_t *rxF = &rxdataF[aarx][symbol_offset + k];
c16_t *dl_ch = &dl_ch_estimates[aarx][ch_offset];
memset(dl_ch,0,sizeof(struct complex16)*(ue->frame_parms.ofdm_symbol_size));
memset(dl_ch, 0, sizeof(c16_t) * ue->frame_parms.ofdm_symbol_size);
#ifdef DEBUG_PBCH
printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
printf("rxF addr %p\n", rxF);
printf("dl_ch addr %p\n",dl_ch);
#endif
DEBUG_PBCH("pbch ch est pilot RB_DL %d\n", ue->frame_parms.N_RB_DL);
DEBUG_PBCH("k %d, first_carrier %d\n", k, ue->frame_parms.first_carrier_offset);
// Treat first 2 pilots specially (left edge)
int16_t ch[2];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PBCH
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fl,
ch,
dl_ch,
16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
//for (int i= 0; i<8; i++)
//printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i));
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
c16_t ch;
ch = c16mulShift(*pil, rxF[re_offset], 15);
DEBUG_PBCH("pilot 0: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i);
multaddRealVectorComplexScalar(fl, ch, dl_ch, 16);
pil++;
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size;
#ifdef DEBUG_PBCH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fm,
ch,
dl_ch,
16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch = c16mulShift(*pil, rxF[re_offset], 15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
DEBUG_PBCH("pilot 1: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i);
multaddRealVectorComplexScalar(fm, ch, dl_ch, 16);
pil++;
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size;
#ifdef DEBUG_PBCH
printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
ch = c16mulShift(*pil, rxF[re_offset], 15);
multadd_real_vector_complex_scalar(fr,
ch,
dl_ch,
16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
DEBUG_PBCH("pilot 2: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n", rxF[re_offset].r, rxF[re_offset].i, ch.r, ch.i, pil->r, pil->i);
multaddRealVectorComplexScalar(fr, ch, dl_ch, 16);
pil++;
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size;
dl_ch += 24;
for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt += 3) {
for (int pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) {
// if (pilot_cnt == 30)
// rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)];
// in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS)
if (dmrss == 1 && pilot_cnt == 12) {
pilot_cnt=48;
re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
re_offset = (re_offset + 144) % ue->frame_parms.ofdm_symbol_size;
dl_ch += 288;
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PBCH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fl,
ch,
dl_ch,
16);
//for (int i= 0; i<8; i++)
// printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i));
ch = c16mulShift(*pil, rxF[re_offset], 15);
DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n",
pilot_cnt,
rxF[re_offset].r,
rxF[re_offset].i,
ch.r,
ch.i,
pil->r,
pil->i);
multaddRealVectorComplexScalar(fl, ch, dl_ch, 16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PBCH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fm,
ch,
dl_ch,
16);
pil += 2;
pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PBCH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fr,
ch,
dl_ch,
16);
pil += 2;
ch = c16mulShift(*pil, rxF[re_offset], 15);
DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n",
pilot_cnt + 1,
rxF[re_offset].r,
rxF[re_offset].i,
ch.r,
ch.i,
pil->r,
pil->i);
multaddRealVectorComplexScalar(fm, ch, dl_ch, 16);
pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch += 24;
ch = c16mulShift(*pil, rxF[re_offset], 15);
DEBUG_PBCH("pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)\n",
pilot_cnt + 2,
rxF[re_offset].r,
rxF[re_offset].i,
ch.r,
ch.i,
pil->r,
pil->i);
multaddRealVectorComplexScalar(fr, ch, dl_ch, 16);
pil++;
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size;
dl_ch += 12;
}
if( dmrss == 2) // update time statistics for last PBCH symbol
......@@ -1117,7 +1004,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
// generate pilot
int pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16)));
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
nr_pdcch_dmrs_rx(ue, Ns, ue->nr_gold_pdcch[gNB_id][Ns][symbol], &pilot[0], 2000, (nb_rb_coreset + dmrs_ref));
nr_pdcch_dmrs_rx(ue, Ns, ue->nr_gold_pdcch[gNB_id][Ns][symbol], (c16_t *)pilot, 2000, (nb_rb_coreset + dmrs_ref));
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
......@@ -1655,14 +1542,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
c16_t pilot[3280] __attribute__((aligned(16)));
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
nr_pdsch_dmrs_rx(ue,
Ns,
ue->nr_gold_pdsch[gNB_id][Ns][symbol][nscid],
(int32_t *)pilot,
1000 + p,
0,
nb_rb_pdsch + rb_offset,
config_type);
nr_pdsch_dmrs_rx(ue, Ns, ue->nr_gold_pdsch[gNB_id][Ns][symbol][nscid], pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type);
uint8_t nushift = 0;
if (config_type == NFAPI_NR_DMRS_TYPE1) {
......
......@@ -57,12 +57,12 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
int dmrss,
NR_UE_SSB *current_ssb,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
const int symbol,
const int dmrss,
const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD],
const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
int estimateSz,
......
......@@ -92,15 +92,15 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
int,
ue->measurements.rx_spatial_power,
NUMBER_OF_CONNECTED_gNB_MAX,
frame_parms->nb_antenna_ports_gNB,
frame_parms->nb_antennas_rx,
cmax(frame_parms->nb_antenna_ports_gNB, 1),
cmax(frame_parms->nb_antennas_rx, 1),
false);
allocCast3D(rx_spatial_power_dB,
unsigned short,
ue->measurements.rx_spatial_power_dB,
NUMBER_OF_CONNECTED_gNB_MAX,
frame_parms->nb_antenna_ports_gNB,
frame_parms->nb_antennas_rx,
cmax(frame_parms->nb_antenna_ports_gNB, 1),
cmax(frame_parms->nb_antennas_rx, 1),
false);
// signal measurements
......
......@@ -44,8 +44,8 @@
#include "PHY/NR_REFSIG/pss_nr.h"
#include "PHY/NR_REFSIG/sss_nr.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/TOOLS/tools_defs.h"
extern openair0_config_t openair0_cfg[];
//static nfapi_nr_config_request_t config_t;
//static nfapi_nr_config_request_t* config =&config_t;
int cnt=0;
......@@ -53,51 +53,16 @@ int cnt=0;
// #define DEBUG_INITIAL_SYNCH
#define DUMP_PBCH_CH_ESTIMATES 0
// create a new node of SSB structure
NR_UE_SSB* create_ssb_node(uint8_t i, uint8_t h) {
// structure used for multiple SSB detection
typedef struct NR_UE_SSB {
uint i_ssb; // i_ssb between 0 and 7 (it corresponds to ssb_index only for Lmax=4,8)
uint n_hf; // n_hf = 0,1 for Lmax =4 or n_hf = 0 for Lmax =8,64
double metric; // metric to order SSB hypothesis
} NR_UE_SSB;
NR_UE_SSB *new_node = (NR_UE_SSB*)malloc(sizeof(NR_UE_SSB));
new_node->i_ssb = i;
new_node->n_hf = h;
new_node->c_re = 0;
new_node->c_im = 0;
new_node->metric = 0;
new_node->next_ssb = NULL;
return new_node;
}
// insertion of the structure in the ordered list (highest metric first)
NR_UE_SSB* insert_into_list(NR_UE_SSB *head, NR_UE_SSB *node) {
if (node->metric > head->metric) {
node->next_ssb = head;
head = node;
return head;
}
NR_UE_SSB *current = head;
while (current->next_ssb !=NULL) {
NR_UE_SSB *temp=current->next_ssb;
if(node->metric > temp->metric) {
node->next_ssb = temp;
current->next_ssb = node;
return head;
}
else
current = temp;
}
current->next_ssb = node;
return head;
}
void free_list(NR_UE_SSB *node) {
if (node->next_ssb != NULL)
free_list(node->next_ssb);
free(node);
static int ssb_sort(const void *a, const void *b)
{
return ((NR_UE_SSB *)b)->metric - ((NR_UE_SSB *)a)->metric;
}
static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
......@@ -107,76 +72,66 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
NR_UE_SSB *best_ssb = NULL;
NR_UE_SSB *current_ssb;
uint8_t N_L = (frame_parms->Lmax == 4)? 4:8;
uint8_t N_hf = (frame_parms->Lmax == 4)? 2:1;
// loops over possible pbch dmrs cases to retrive best estimated i_ssb (and n_hf for Lmax=4) for multiple ssb detection
const int N_L = (frame_parms->Lmax == 4) ? 4 : 8;
const int N_hf = (frame_parms->Lmax == 4) ? 2 : 1;
NR_UE_SSB best_ssb[N_L * N_hf];
NR_UE_SSB *current_ssb = best_ssb;
// loops over possible pbch dmrs cases to retrieve best estimated i_ssb (and n_hf for Lmax=4) for multiple ssb detection
start_meas(&ue->dlsch_channel_estimation_stats);
for (int hf = 0; hf < N_hf; hf++) {
for (int l = 0; l < N_L ; l++) {
// initialization of structure
current_ssb = create_ssb_node(l,hf);
start_meas(&ue->dlsch_channel_estimation_stats);
for (int l = 0; l < N_L; l++) {
// computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
nr_pbch_dmrs_correlation(ue, proc, i, i - pbch_initial_symbol, current_ssb, rxdataF);
stop_meas(&ue->dlsch_channel_estimation_stats);
current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im*current_ssb->c_im;
// generate a list of SSB structures
if (best_ssb == NULL)
best_ssb = current_ssb;
else
best_ssb = insert_into_list(best_ssb,current_ssb);
cd_t cumul = {0};
for (int i = pbch_initial_symbol; i < pbch_initial_symbol + 3; i++) {
c32_t meas = nr_pbch_dmrs_correlation(ue, proc, i, i - pbch_initial_symbol, ue->nr_gold_pbch[hf][l], rxdataF);
csum(cumul, cumul, meas);
}
*current_ssb = (NR_UE_SSB){.i_ssb = l, .n_hf = hf, .metric = squaredMod(cumul)};
current_ssb++;
}
}
qsort(best_ssb, N_L * N_hf, sizeof(NR_UE_SSB), ssb_sort);
stop_meas(&ue->dlsch_channel_estimation_stats);
NR_UE_SSB *temp_ptr = best_ssb;
bool ret = false;
while (!ret && temp_ptr != NULL) {
const int nb_ant = frame_parms->nb_antennas_rx;
for (NR_UE_SSB *ssb = best_ssb; ssb < best_ssb + N_L * N_hf; ssb++) {
start_meas(&ue->dlsch_channel_estimation_stats);
// computing channel estimation for selected best ssb
const int estimateSz = frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates[frame_parms->nb_antennas_rx][estimateSz];
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
__attribute__((aligned(32))) c16_t dl_ch_estimates[nb_ant][estimateSz];
__attribute__((aligned(32))) c16_t dl_ch_estimates_time[nb_ant][frame_parms->ofdm_symbol_size];
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
nr_pbch_channel_estimation(ue,estimateSz, dl_ch_estimates, dl_ch_estimates_time,
proc,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf,rxdataF);
nr_pbch_channel_estimation(ue,
estimateSz,
dl_ch_estimates,
dl_ch_estimates_time,
proc,
i,
i - pbch_initial_symbol,
ssb->i_ssb,
ssb->n_hf,
rxdataF);
stop_meas(&ue->dlsch_channel_estimation_stats);
fapiPbch_t result = {0};
int pbch_res = nr_rx_pbch(ue, proc, estimateSz, dl_ch_estimates, frame_parms, temp_ptr->i_ssb, &result, rxdataF);
ret = pbch_res == 0;
if (DUMP_PBCH_CH_ESTIMATES && ret) {
write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, frame_parms->nb_antennas_rx*estimateSz, 1, 1);
write_output("pbch_ch_estimates_time.m",
"pbch_ch_estimates_time",
dl_ch_estimates_time,
frame_parms->nb_antennas_rx * frame_parms->ofdm_symbol_size,
1,
1);
if (0 == nr_rx_pbch(ue, proc, estimateSz, dl_ch_estimates, frame_parms, ssb->i_ssb, &result, rxdataF)) {
if (DUMP_PBCH_CH_ESTIMATES) {
write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, nb_ant * estimateSz, 1, 1);
write_output("pbch_ch_estimates_time.m",
"pbch_ch_estimates_time",
dl_ch_estimates_time,
nb_ant * frame_parms->ofdm_symbol_size,
1,
1);
}
LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
return true;
}
temp_ptr=temp_ptr->next_ssb;
}
free_list(best_ssb);
if (ret) {
frame_parms->nb_antenna_ports_gNB = 1; // pbch_tx_ant;
LOG_I(PHY, "[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
}
return ret;
LOG_W(PHY, "[UE%d] Initial sync: pbch not decoded, ssb index %d\n", ue->Mod_id, frame_parms->ssb_index);
return false;
}
nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, int sa)
......@@ -394,11 +349,7 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, i
// send sync status to higher layers later when timing offset converge to target timing
}
LOG_I(PHY,
"[UE %d] Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
ue->Mod_id,
openair0_cfg[0].rx_freq[0] + ue->common_vars.freq_offset,
ue->common_vars.freq_offset);
LOG_I(PHY, "[UE %d] Measured Carrier Frequency offset %d Hz\n", ue->Mod_id, ue->common_vars.freq_offset);
} else {
#ifdef DEBUG_INITIAL_SYNC
LOG_I(PHY,"[UE%d] Initial sync : PBCH not ok\n",ue->Mod_id);
......
......@@ -224,7 +224,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
///////////
int max_num_re = Nl*number_of_symbols*nb_rb*NR_NB_SC_PER_RB;
int32_t d_mod[max_num_re] __attribute__ ((aligned(16)));
c16_t d_mod[max_num_re] __attribute__((aligned(16)));
nr_modulation(scrambled_output, // assume one codeword for the moment
available_bits,
......@@ -245,7 +245,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4);
int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16)));
c16_t mod_dmrs[n_dmrs] __attribute((aligned(16)));
///////////
////////////////////////////////////////////////////////////////////////
......@@ -253,15 +253,11 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
/////////////////////////ULSCH layer mapping/////////////////////////
///////////
const int sz = available_bits / mod_order;
c16_t tx_layers[Nl][sz];
memset(tx_layers, 0, sizeof(tx_layers));
int16_t **tx_layers = (int16_t **)malloc16_clear(Nl*sizeof(int16_t *));
for (int nl=0; nl<Nl; nl++)
tx_layers[nl] = (int16_t *)malloc16_clear((available_bits<<1)/mod_order*sizeof(int16_t));
nr_ue_layer_mapping((int16_t *)d_mod,
Nl,
available_bits/mod_order,
tx_layers);
nr_ue_layer_mapping(d_mod, Nl, available_bits / mod_order, sz, tx_layers);
///////////
////////////////////////////////////////////////////////////////////////
......@@ -272,13 +268,11 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
l_prime[0] = 0; // single symbol ap 0
uint16_t index;
uint8_t u = 0, v = 0;
int16_t *dmrs_seq = NULL;
c16_t *dmrs_seq = NULL;
/// Transform-coded "y"-sequences (for definition see 38-211 V15.3.0 2018-09, subsection 6.3.1.4)
int32_t y[max_num_re] __attribute__ ((aligned(16)));
memset(y, 0, max_num_re*sizeof(int32_t));
c16_t y[max_num_re] __attribute__((aligned(16)));
memset(y, 0, sizeof(y));
if (pusch_pdu->transform_precoding == transformPrecoder_enabled) {
......@@ -287,7 +281,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
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);
int 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];
......@@ -303,7 +297,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
/* In the symbol with DMRS no data would be transmitted CDM groups is 2*/
continue;
nr_dft(&y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch);
nr_dft(&y[y_offset], &tx_layers[0][y_offset], nb_re_pusch);
y_offset = y_offset + nb_re_pusch;
......@@ -321,7 +315,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
printf("NR_ULSCH_UE: available_bits: %u, mod_order: %d", available_bits,mod_order);
for (int ll = 0; ll < (available_bits/mod_order); ll++) {
debug_symbols[ll] = ulsch_ue->y[ll];
debug_symbols[ll] = ulsch_ue->y[ll];
}
printf("NR_ULSCH_UE: numSym: %d, num_dmrs_sym: %d", number_of_symbols,number_dmrs_symbols);
......@@ -345,10 +339,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
/////////////////////////ULSCH RE mapping/////////////////////////
///////////
int encoded_length = frame_parms->N_RB_UL*14*NR_NB_SC_PER_RB*mod_order*Nl;
int16_t **tx_precoding = (int16_t **)malloc16_clear(Nl*sizeof(int16_t *));
for (int nl=0; nl<Nl; nl++)
tx_precoding[nl] = (int16_t *)malloc16_clear((encoded_length<<1)*sizeof(int16_t));
const int encoded_length = frame_parms->N_RB_UL * 14 * NR_NB_SC_PER_RB * mod_order * Nl;
c16_t tx_precoding[Nl][encoded_length];
memset(tx_precoding, 0, sizeof(tx_precoding));
for (int nl=0; nl < Nl; nl++) {
uint8_t k_prime = 0;
......@@ -372,7 +365,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint8_t is_ptrs_sym = 0;
uint16_t dmrs_idx = 0, ptrs_idx = 0;
int16_t mod_ptrs[nb_rb] __attribute((aligned(16))); // assume maximum number of PTRS per pusch allocation
c16_t mod_ptrs[nb_rb] __attribute((aligned(16))); // assume maximum number of PTRS per pusch allocation
if ((ul_dmrs_symb_pos >> l) & 0x01) {
is_dmrs_sym = 1;
......@@ -387,7 +380,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
// TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part
// Perform this on gold sequence, not required when SC FDMA operation is done,
LOG_D(PHY,"DMRS in symbol %d\n",l);
nr_modulation(pusch_dmrs[l][pusch_pdu->scid], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
nr_modulation(pusch_dmrs[l][pusch_pdu->scid],
n_dmrs * 2,
DMRS_MOD_ORDER,
(int16_t *)mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
} else {
dmrs_idx = 0;
}
......@@ -397,7 +393,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) {
is_ptrs_sym = 1;
nr_modulation(pusch_dmrs[l][pusch_pdu->scid], nb_rb, DMRS_MOD_ORDER, mod_ptrs);
nr_modulation(pusch_dmrs[l][pusch_pdu->scid], nb_rb, DMRS_MOD_ORDER, (int16_t *)mod_ptrs);
}
}
......@@ -422,166 +418,149 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
if (is_dmrs == 1) {
// if transform precoding is enabled
if (pusch_pdu->transform_precoding == transformPrecoder_enabled) {
((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15;
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15;
} else {
((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15;
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
}
const int tmp = Wt[l_prime[0]] * Wf[k_prime] * AMP;
if (pusch_pdu->transform_precoding == transformPrecoder_enabled)
tx_precoding[nl][sample_offsetF] = c16mulRealShift(dmrs_seq[dmrs_idx], tmp, 15);
else
tx_precoding[nl][sample_offsetF] = c16mulRealShift(mod_dmrs[dmrs_idx], tmp, 15);
#ifdef DEBUG_PUSCH_MAPPING
printf("DMRS: Layer: %d\t, dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n",
nl, dmrs_idx, l, k, k_prime, n, ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1],
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1]);
nl,
dmrs_idx,
l,
k,
k_prime,
n,
tx_precoding[nl][sample_offsetF].r,
tx_precoding[nl][sample_offsetF].i);
#endif
dmrs_idx++;
k_prime++;
k_prime&=1;
n+=(k_prime)?0:1;
} else if (is_ptrs == 1) {
k_prime &= 1;
n += (k_prime) ? 0 : 1;
} else if (is_ptrs == 1) {
uint16_t beta_ptrs = 1; // temp value until power control is implemented
((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15;
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15;
tx_precoding[nl][sample_offsetF] = c16mulRealShift(mod_ptrs[ptrs_idx], beta_ptrs * AMP, 15);
ptrs_idx++;
} else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) {
if (pusch_pdu->transform_precoding == transformPrecoder_disabled) {
((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = ((int16_t *)tx_layers[nl])[m<<1];
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = ((int16_t *)tx_layers[nl])[(m<<1) + 1];
}
else {
((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = ((int16_t *) y)[m<<1];
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = ((int16_t *) y)[(m<<1) + 1];
}
} else if (!is_dmrs_sym
|| allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) {
if (pusch_pdu->transform_precoding == transformPrecoder_disabled)
tx_precoding[nl][sample_offsetF] = tx_layers[nl][m];
else
tx_precoding[nl][sample_offsetF] = y[m];
#ifdef DEBUG_PUSCH_MAPPING
printf("DATA: layer %d\t m %d\t l %d \t k %d \t tx_precoding: %d %d\n",
nl, m, l, k, ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1],
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1]);
nl,
m,
l,
k,
tx_precoding[nl][sample_offsetF].r,
tx_precoding[nl][sample_offsetF].i);
#endif
m++;
} else {
((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = 0;
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = 0;
tx_precoding[nl][sample_offsetF] = (c16_t){0};
}
if (++k >= frame_parms->ofdm_symbol_size)
k -= frame_parms->ofdm_symbol_size;
} //for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++)
}//for (l=start_symbol; l<start_symbol+number_of_symbols; l++)
}//for (nl=0; nl < Nl; nl++)
} // for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++)
} // for (l=start_symbol; l<start_symbol+number_of_symbols; l++)
} // for (nl=0; nl < Nl; nl++)
/////////////////////////ULSCH precoding/////////////////////////
///////////
///Layer Precoding and Antenna port mapping
/// Layer Precoding and Antenna port mapping
// tx_layers 0-3 are mapped on antenna ports
// The precoding info is supported by nfapi such as num_prgs, prg_size, prgs_list and pm_idx
// The same precoding matrix is applied on prg_size RBs, Thus
// pmi = prgs_list[rbidx/prg_size].pm_idx, rbidx =0,...,rbSize-1
// The Precoding matrix:
for (int ap=0; ap<frame_parms->nb_antennas_tx; ap++) {
for (int l=start_symbol; l<start_symbol+number_of_symbols; l++) {
for (int ap = 0; ap < frame_parms->nb_antennas_tx; ap++) {
for (int l = start_symbol; l < start_symbol + number_of_symbols; l++) {
uint16_t k = start_sc;
for (int rb=0; rb<nb_rb; rb++) {
//get pmi info
uint8_t pmi=pusch_pdu->Tpmi;
if (pmi == 0) {//unitary Precoding
for (int rb = 0; rb < nb_rb; rb++) {
// get pmi info
uint8_t pmi = pusch_pdu->Tpmi;
if (pmi == 0) { // unitary Precoding
if (k + NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { // RB does not cross DC
if (ap<pusch_pdu->nrOfLayers)
memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
NR_NB_SC_PER_RB*sizeof(int32_t));
if (ap < pusch_pdu->nrOfLayers)
memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k],
&tx_precoding[ap][l * frame_parms->ofdm_symbol_size + k],
NR_NB_SC_PER_RB * sizeof(c16_t));
else
memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
0,
NR_NB_SC_PER_RB*sizeof(int32_t));
memset(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k], 0, NR_NB_SC_PER_RB * sizeof(int32_t));
} else { // RB does cross DC
int neg_length = frame_parms->ofdm_symbol_size - k;
int pos_length = NR_NB_SC_PER_RB - neg_length;
if (ap<pusch_pdu->nrOfLayers) {
memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
neg_length*sizeof(int32_t));
memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size],
&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size)],
pos_length*sizeof(int32_t));
if (ap < pusch_pdu->nrOfLayers) {
memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k],
&tx_precoding[ap][l * frame_parms->ofdm_symbol_size + k],
neg_length * sizeof(c16_t));
memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size],
&tx_precoding[ap][l * frame_parms->ofdm_symbol_size],
pos_length * sizeof(int32_t));
} else {
memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
0,
neg_length*sizeof(int32_t));
memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size],
0,
pos_length*sizeof(int32_t));
memset(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k], 0, neg_length * sizeof(int32_t));
memset(&txdataF[ap][l * frame_parms->ofdm_symbol_size], 0, pos_length * sizeof(int32_t));
}
}
k += NR_NB_SC_PER_RB;
if (k >= frame_parms->ofdm_symbol_size) {
k -= frame_parms->ofdm_symbol_size;
}
}
else {
//get the precoding matrix weights:
} else {
// get the precoding matrix weights:
const char *W_prec;
switch (frame_parms->nb_antennas_tx) {
case 1://1 antenna port
case 1: // 1 antenna port
W_prec = nr_W_1l_2p[pmi][ap];
break;
case 2://2 antenna ports
if (pusch_pdu->nrOfLayers == 1)//1 layer
case 2: // 2 antenna ports
if (pusch_pdu->nrOfLayers == 1) // 1 layer
W_prec = nr_W_1l_2p[pmi][ap];
else//2 layers
else // 2 layers
W_prec = nr_W_2l_2p[pmi][ap];
break;
case 4://4 antenna ports
if (pusch_pdu->nrOfLayers == 1)//1 layer
case 4: // 4 antenna ports
if (pusch_pdu->nrOfLayers == 1) // 1 layer
W_prec = nr_W_1l_4p[pmi][ap];
else if (pusch_pdu->nrOfLayers == 2)//2 layers
else if (pusch_pdu->nrOfLayers == 2) // 2 layers
W_prec = nr_W_2l_4p[pmi][ap];
else if (pusch_pdu->nrOfLayers == 3)//3 layers
else if (pusch_pdu->nrOfLayers == 3) // 3 layers
W_prec = nr_W_3l_4p[pmi][ap];
else//4 layers
else // 4 layers
W_prec = nr_W_4l_4p[pmi][ap];
break;
default:
LOG_D(PHY,"Precoding 1,2, or 4 antenna ports are currently supported\n");
LOG_D(PHY, "Precoding 1,2, or 4 antenna ports are currently supported\n");
W_prec = nr_W_1l_2p[pmi][ap];
break;
}
for (int i=0; i<NR_NB_SC_PER_RB; i++) {
int32_t re_offset = l*frame_parms->ofdm_symbol_size + k;
int32_t precodatatx_F = nr_layer_precoder(tx_precoding, W_prec, pusch_pdu->nrOfLayers, re_offset);
((int16_t*)txdataF[ap])[(re_offset<<1)] = ((int16_t *) &precodatatx_F)[0];
((int16_t*)txdataF[ap])[(re_offset<<1) + 1] = ((int16_t *) &precodatatx_F)[1];
for (int i = 0; i < NR_NB_SC_PER_RB; i++) {
int32_t re_offset = l * frame_parms->ofdm_symbol_size + k;
txdataF[ap][re_offset] = nr_layer_precoder(encoded_length, tx_precoding, W_prec, pusch_pdu->nrOfLayers, re_offset);
if (++k >= frame_parms->ofdm_symbol_size) {
k -= frame_parms->ofdm_symbol_size;
}
}
}
} //RB loop
} // RB loop
} // symbol loop
}// port loop
} // port loop
NR_UL_UE_HARQ_t *harq_process_ulsch=NULL;
NR_UL_UE_HARQ_t *harq_process_ulsch = NULL;
harq_process_ulsch = &UE->ul_harq_processes[harq_pid];
harq_process_ulsch->status = SCH_IDLE;
for (int nl = 0; nl < Nl; nl++) {
free_and_zero(tx_layers[nl]);
free_and_zero(tx_precoding[nl]);
}
free_and_zero(tx_layers);
free_and_zero(tx_precoding);
///////////
////////////////////////////////////////////////////////////////////////
}
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/**********************************************************************
*
* FILENAME : pbch_nr.c
*
* MODULE : broacast channel
*
* DESCRIPTION : generation of pbch
* 3GPP TS 38.211 7.3.3 Physical broadcast channel
*
************************************************************************/
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include "PHY/defs.h"
#define DEFINE_VARIABLES_PBCH_NR_H
#include "PHY/NR_REFSIG/pbch_nr.h"
#undef DEFINE_VARIABLES_PBCH_NR_H
/*******************************************************************
*
* NAME : pseudo_random_gold_sequence
*
* PARAMETERS :
*
* RETURN : generate pseudo-random sequence which is a length-31 Gold sequence
*
* DESCRIPTION : 3GPP TS 38.211 5.2.1 Pseudo-random sequence generation
* Sequence generation
*
*********************************************************************/
#define NC (1600)
#define GOLD_LENGTH (31)
uint32_t *pseudo_random_gold_sequence(length M_PN, uint32_t cinit)
{
int size = M_PN * sizeof(uint32_t);
int size_x = sizeof(int)*M_PN + size;
int *x1 = malloc(size_x);
int *x2 = malloc(size_x);
if ((x1 == NULL) || (x2 == NULL)) {
msg("Fatal memory allocation problem \n");
assert(0);
}
else {
bzero(x1, size_x);
bzero(x2, size_x);
}
x1[0] = 1;
for (n = 0; n < 31; n++) {
x2[n] = (cinit >> n) & 0x1;
}
for (int n = 0; n < (NC+M_PN); n++) {
x1(n+31) = (x1(n+3) + x1(n))%2;
x2(n+31) = (x2(n+3) + x2(n+2) + x2(n+1) + x2(n))%2;
}
int *c = calloc(size);
if (c != NULL) {
bzero(c, size);
}
else {
msg("Fatal memory allocation problem \n");
assert(0);
}
for (int n = 0; n < M_PN; n++) {
c(i) = (x1(n+NC) + x2(n+NC))%2;
}
return c;
}
......@@ -672,7 +672,15 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i
*nid2 = pss_source;
LOG_I(PHY,"[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB, ffo %lf\n", pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value),dB_fixed64(avg[pss_source]),ffo_est);
LOG_I(PHY,
"[UE] nr_synchro_time: Sync source (nid2) = %d, Peak found at pos %d, val = %ld (%d dB power over signal avg %d dB), ffo "
"%lf\n",
pss_source,
peak_position,
peak_value,
dB_fixed64(peak_value),
dB_fixed64(avg[pss_source]),
ffo_est);
if (peak_value < 5*avg[pss_source])
return(-1);
......
......@@ -179,13 +179,13 @@ uint16_t compute_n_b(frame_t frame_number,
***************************************************************************/
int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu,
NR_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
c16_t **txdataF,
uint16_t symbol_offset,
nr_srs_info_t *nr_srs_info,
int16_t amp,
frame_t frame_number,
slot_t slot_number) {
slot_t slot_number)
{
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__);
#endif
......@@ -371,20 +371,15 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu,
// For each port, and for each OFDM symbol, here it is computed and mapped an SRS sequence with M_sc_b_SRS symbols
for (int k = 0; k < M_sc_b_SRS; k++) {
double shift_real = cos(alpha_i * k);
double shift_imag = sin(alpha_i * k);
int16_t r_overbar_real = rv_ul_ref_sig[u][v][M_sc_b_SRS_index][k<<1];
int16_t r_overbar_imag = rv_ul_ref_sig[u][v][M_sc_b_SRS_index][(k<<1)+1];
cd_t shift = {cos(alpha_i * k), sin(alpha_i * k)};
const c16_t tmp = rv_ul_ref_sig[u][v][M_sc_b_SRS_index][k];
cd_t r_overbar = {tmp.r, tmp.i};
// cos(x+y) = cos(x)cos(y) - sin(x)sin(y)
double r_real = (shift_real*r_overbar_real - shift_imag*r_overbar_imag) / sqrt_N_ap;
// sin(x+y) = sin(x)cos(y) + cos(x)sin(y)
double r_imag = (shift_imag*r_overbar_real + shift_real*r_overbar_imag) / sqrt_N_ap;
cd_t r = cdMul(shift, r_overbar);
int32_t r_real_amp = ((int32_t) round((double) amp * r_real)) >> 15;
int32_t r_imag_amp = ((int32_t) round((double) amp * r_imag)) >> 15;
c16_t r_amp = {(((int32_t)round((double)amp * r.r / sqrt_N_ap)) >> 15),
(((int32_t)round((double)amp * r.i / sqrt_N_ap)) >> 15)};
#ifdef SRS_DEBUG
int subcarrier_log = subcarrier-subcarrier_offset;
......@@ -394,10 +389,10 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu,
if(subcarrier_log%12 == 0) {
LOG_I(NR_PHY,"------------ %d ------------\n", subcarrier_log/12);
}
LOG_I(NR_PHY,"(%d) \t%i\t%i\n", subcarrier_log, (int16_t)(r_real_amp&0xFFFF), (int16_t)(r_imag_amp&0xFFFF));
LOG_I(NR_PHY, "(%d) \t%i\t%i\n", subcarrier_log, r_amp.r, r_amp.i);
#endif
*(c16_t *)&txdataF[p_index][symbol_offset + l_line_offset + subcarrier] = (c16_t){r_real_amp, r_imag_amp};
txdataF[p_index][symbol_offset + l_line_offset + subcarrier] = r_amp;
// Subcarrier increment
subcarrier += K_TC;
......@@ -465,14 +460,7 @@ int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_
NR_DL_FRAME_PARMS *frame_parms = &(ue->frame_parms);
uint16_t symbol_offset = (frame_parms->symbols_per_slot - 1 - srs_config_pdu->time_start_position)*frame_parms->ofdm_symbol_size;
if (generate_srs_nr(srs_config_pdu,
frame_parms,
(int32_t **)txdataF,
symbol_offset,
ue->nr_srs_info,
AMP,
proc->frame_tx,
proc->nr_slot_tx)
if (generate_srs_nr(srs_config_pdu, frame_parms, txdataF, symbol_offset, ue->nr_srs_info, AMP, proc->frame_tx, proc->nr_slot_tx)
== 0) {
return 0;
} else {
......
......@@ -133,7 +133,7 @@ static const uint16_t srs_max_number_cs[3] = {8, 12, 6};
int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu,
NR_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
c16_t **txdataF,
uint16_t symbol_offset,
nr_srs_info_t *nr_srs_info,
int16_t amp,
......
......@@ -503,15 +503,15 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
Nid1 = GET_NID1(frame_parms->Nid_cell);
LOG_D(PHY,"Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max);
}
//#endif
if (Nid1==N_ID_1_NUMBER)
return false;
// #endif
int re = 0;
int im = 0;
if (Nid1 == N_ID_1_NUMBER) {
LOG_I(PHY,"Failed to detect SSS after PSS\n");
LOG_W(PHY,
"Failed to detect SSS after PSS, metric of SSS %d, threshold to consider SSS valid %d, detected PCI: %d\n",
*tot_metric,
SSS_METRIC_FLOOR_NR,
frame_parms->Nid_cell);
return false;
}
d = (int16_t *)&d_sss[Nid2][Nid1];
......@@ -524,7 +524,8 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
double ffo_pss = ((double)ue->common_vars.freq_offset)/frame_parms->subcarrier_spacing;
LOG_W(NR_PHY,
"ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz), nid1: %d, nid2: %d\n",
"SSS detected, PCI: %d, ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz), nid1: %d, nid2: %d\n",
frame_parms->Nid_cell,
ffo_pss,
(int)(ffo_pss * frame_parms->subcarrier_spacing),
ffo_sss,
......
......@@ -183,6 +183,11 @@ extern "C" {
return a.r * a.r + a.i * a.i;
}
__attribute__((always_inline)) inline c16_t c16add(const c16_t a, const c16_t b)
{
return (c16_t){.r = (int16_t)(a.r + b.r), .i = (int16_t)(a.i + b.i)};
}
__attribute__((always_inline)) inline c16_t c16sub(const c16_t a, const c16_t b) {
return (c16_t) {
.r = (int16_t) (a.r - b.r),
......@@ -309,6 +314,25 @@ The function implemented is : \f$\mathbf{y} = y + \alpha\mathbf{x}\f$
*/
void multadd_real_vector_complex_scalar(const int16_t *x, const int16_t *alpha, int16_t *y, uint32_t N);
// Same with correct types
static inline void multaddRealVectorComplexScalar(const c16_t *in, const c16_t alpha, c16_t *out, uint32_t N)
{
// do 8 multiplications at a time
simd_q15_t *x_128 = (simd_q15_t *)in, *y_128 = (simd_q15_t *)out;
// printf("alpha = %d,%d\n",alpha[0],alpha[1]);
const simd_q15_t alpha_r_128 = set1_int16(alpha.r);
const simd_q15_t alpha_i_128 = set1_int16(alpha.i);
for (unsigned int i = 0; i < N >> 3; i++) {
const simd_q15_t yr = mulhi_s1_int16(alpha_r_128, x_128[i]);
const simd_q15_t yi = mulhi_s1_int16(alpha_i_128, x_128[i]);
const simd_q15_t tmp = simde_mm_loadu_si128(y_128);
simde_mm_storeu_si128(y_128++, simde_mm_adds_epi16(tmp, simde_mm_unpacklo_epi16(yr, yi)));
const simd_q15_t tmp2 = simde_mm_loadu_si128(y_128);
simde_mm_storeu_si128(y_128++, simde_mm_adds_epi16(tmp2, simde_mm_unpackhi_epi16(yr, yi)));
}
}
static __attribute__((always_inline)) inline void multadd_real_four_symbols_vector_complex_scalar(const int16_t *x,
c16_t *alpha,
c16_t *y)
......
......@@ -307,16 +307,6 @@ typedef struct {
fapi_nr_ul_config_srs_pdu srs_config_pdu;
} NR_UE_SRS;
// structure used for multiple SSB detection
typedef struct NR_UE_SSB {
uint8_t i_ssb; // i_ssb between 0 and 7 (it corresponds to ssb_index only for Lmax=4,8)
uint8_t n_hf; // n_hf = 0,1 for Lmax =4 or n_hf = 0 for Lmax =8,64
uint32_t metric; // metric to order SSB hypothesis
uint32_t c_re;
uint32_t c_im;
struct NR_UE_SSB *next_ssb;
} NR_UE_SSB;
typedef struct UE_NR_SCAN_INFO_s {
/// 10 best amplitudes (linear) for each pss signals
int32_t amp[3][10];
......
......@@ -115,7 +115,7 @@ typedef enum{
typedef struct {
uint8_t k_0_p[MAX_NUM_NR_SRS_AP][MAX_NUM_NR_SRS_SYMBOLS];
uint8_t srs_generated_signal_bits;
int32_t **srs_generated_signal;
c16_t **srs_generated_signal;
nfapi_nr_srs_pdu_t srs_pdu;
} nr_srs_info_t;
......
......@@ -951,7 +951,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
slot_rx,
srs_pdu,
gNB->nr_srs_info[i],
(const int32_t **)gNB->nr_srs_info[i]->srs_generated_signal,
(const c16_t**)gNB->nr_srs_info[i]->srs_generated_signal,
srs_received_signal,
srs_estimated_channel_freq,
srs_estimated_channel_time,
......
......@@ -776,7 +776,7 @@ int main(int argc, char *argv[])
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);
int 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;
......
......@@ -78,8 +78,8 @@ void generate_reference_signals(void)
assert(0);
}
for (int n=0; n<ul_allocated_re[Msc_RS]; n++) {
if ((ul_ref_sigs[u][v][Msc_RS][2*n] != rv_ul_ref_sig[u][v][Msc_RS_index_nr][2*n])
|| (ul_ref_sigs[u][v][Msc_RS][2*n+1] != rv_ul_ref_sig[u][v][Msc_RS_index_nr][2*n+1])) {
if ((ul_ref_sigs[u][v][Msc_RS][n].r != rv_ul_ref_sig[u][v][Msc_RS_index_nr][n].r)
|| (ul_ref_sigs[u][v][Msc_RS][n].i != rv_ul_ref_sig[u][v][Msc_RS_index_nr][n].i)) {
number_differencies++;
}
}
......@@ -157,9 +157,7 @@ void default_srs_configuration(NR_DL_FRAME_PARMS *frame_parms)
* for various combinations of parameters
*
*********************************************************************/
int test_srs_single(NR_DL_FRAME_PARMS *frame_parms,
int32_t *txptr,
UE_nr_rxtx_proc_t *proc)
int test_srs_single(NR_DL_FRAME_PARMS *frame_parms, c16_t *txptr, UE_nr_rxtx_proc_t *proc)
{
SRS_Resource_t *p_SRS_Resource = frame_parms->srs_nr.p_SRS_ResourceSetList[0]->p_srs_ResourceList[0];
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* This is the interface module between PHY
* Provided the FAPI style interface structures for P7.
*/
/*! \file openair2/PHY_INTERFACE/IF_Module.h
* \brief data structures for PHY/MAC interface modules
* \author EURECOM/NTUST
* \date 2017
* \version 0.1
* \company Eurecom
* \email: raymond.knopp@eurecom.fr
* \note
* \warning
*/
#ifndef __UE_MAC_INTERFACE__H__
#define __UE_MAC_INTERFACE__H__
#include "nfapi_interface.h"
#include "openair1/PHY/defs_RU.h"
#include "common/openairinterface5g_limits.h"
#define MAX_NUM_DL_PDU 100
#define MAX_NUM_UL_PDU 100
#define MAX_NUM_HI_DCI0_PDU 100
#define MAX_NUM_TX_REQUEST_PDU 100
#define MAX_NUM_HARQ_IND 100
#define MAX_NUM_CRC_IND 100
#define MAX_NUM_SR_IND 100
#define MAX_NUM_CQI_IND 100
#define MAX_NUM_RACH_IND 100
#define MAX_NUM_SRS_IND 100
// UE_MAC enums
typedef enum {
UE_MAC_DL_IND_PDSCH_PDU_TYPE =0,
UE_MAC_DL_IND_SI_PDSCH_PDU_TYPE,
UE_MAC_DL_IND_P_PDSCH_PDU_TYPE,
UE_MAC_DL_IND_DLSCH_RAR_PDU_TYPE
} UE_MAC_dl_ind_pdu_type_e;
// UE_MAC enums
typedef enum {
UE_MAC_Tx_IND_Msg1_TYPE =0,
UE_MAC_Tx_IND_Msg3_TYPE
} UE_MAC_Tx_ind_type_e;
// *** UE_Tx.request related structures
typedef struct {
uint16_t pdu_length;
uint16_t pdu_index;
uint8_t num_segments;
struct {
uint32_t segment_length;
uint8_t* segment_data;
} segments[NFAPI_TX_MAX_SEGMENTS];
} UE_MAC_tx_request_pdu_t;
typedef struct {
nfapi_tl_t tl;
uint16_t number_of_pdus;
UE_MAC_tx_request_pdu_t* ue_tx_pdu_list;
} UE_MAC_tx_request_body_t;
typedef struct {
//nfapi_p7_message_header_t header;
uint16_t sfn_sf;
UE_MAC_tx_request_body_t ue_tx_request_body;
} UE_MAC_tx_request_t;
typedef struct{
}UE_MAC_sl_config_request_Tx_t;
typedef struct{
}UE_MAC_sl_config_request_Rx_t;
typedef struct{
}UE_MAC_sl_tx_request_t;
// *** UE_DL.indication related structures
typedef struct{
unsigned char eNB_index;
uint8_t first_sync; //boolean 0 or 1
uint8_t sync; // boolean 0 or 1 to indicate whether rrc_out_of_sync_ind() or dl_phy_sync_success()
// should be called from the handler function of the interface respectively.
}UE_MAC_bch_indication_pdu_t;
typedef struct{
nfapi_tl_t tl;
UE_MAC_bch_indication_pdu_t* bch_ind_list;
}UE_MAC_BCH_indication_body_t;
// Corresponding to inputs of MAC functions: ue_send_sdu(), ue_decode_si(), ue_decode_p().
typedef struct{
uint8_t* data;
uint16_t data_len;
}UE_MAC_dlsch_pdu;
// Corresponding to inputs of MAC function: process_rar().
typedef struct{
rnti_t ra_rnti;
uint8_t* rar_input_buffer; // Originating from PHY
rnti_t* t_crnti;
uint8_t preamble_index;
uint8_t* rar_output_buffer; //should be returned to PHY: dlsch0->harq_processes[0]->b
}UE_MAC_dlsch_rar_pdu;
typedef struct{
uint8_t pdu_type;
uint8_t eNB_index;
union{
UE_MAC_dlsch_pdu dlsch_pdu_ind;
UE_MAC_dlsch_rar_pdu dlsch_rar_pdu_ind;
};
}UE_MAC_dlsch_indication_pdu_t;
typedef struct{
nfapi_tl_t tl;
uint16_t number_of_pdus;
UE_MAC_dlsch_indication_pdu_t* dlsch_ind_list;
}UE_MAC_DLSCH_indication_body_t;
// *** UE_SL.indication related structures
typedef struct{
}ue_sci_indication_body_t;
typedef struct{
}ue_SLSCH_indication_body_t;
typedef struct{
}ue_SLDCH_indication_body_t;
typedef struct{
}ue_SLBCH_indication_body_t;
// *** UE_Config_common.request related structures
typedef struct {
uint8_t subframeAssignment;
uint8_t specialSubframePatterns;
}UE_PHY_tdd_frame_structure_t;
typedef struct {
uint16_t rootSequenceIndex;
uint8_t prach_Config_enabled;
uint8_t prach_ConfigIndex;
uint8_t highSpeedFlag;
uint8_t zeroCorrelationZoneConfig;
uint8_t prach_FreqOffset;
}UE_PHY_prach_config_t;
typedef struct {
uint8_t deltaPUCCH_Shift;
uint8_t nRB_CQI;
uint8_t nCS_AN;
uint16_t n1PUCCH_AN;
}UE_PHY_pucch_config_t;
typedef struct {
int8_t referenceSignalPower;
uint8_t p_b;
}UE_PHY_pdsch_config_t;
typedef struct {
uint8_t n_SB;
PUSCH_HOPPING_t hoppingMode;
uint8_t pusch_HoppingOffset;
uint8_t enable64QAM;
uint8_t groupHoppingEnabled;
uint8_t groupAssignmentPUSCH;
uint8_t sequenceHoppingEnabled;
uint8_t cyclicShift;
}UE_PHY_pusch_config_t;
typedef struct{
uint8_t enabled_flag;
uint8_t srs_BandwidthConfig;
uint8_t srs_SubframeConfig;
uint8_t ackNackSRS_SimultaneousTransmission;
uint8_t srs_MaxUpPts;
}UE_PHY_SRS_config_t;
typedef struct{
int8_t p0_NominalPUSCH;
PUSCH_alpha_t alpha;
int8_t p0_NominalPUCCH;
int8_t deltaPreambleMsg3;
long deltaF_PUCCH_Format1;
long deltaF_PUCCH_Format1b;
long deltaF_PUCCH_Format2;
long deltaF_PUCCH_Format2a;
long deltaF_PUCCH_Format2b;
}UE_PHY_UL_power_control_config_t;
typedef struct{
uint8_t maxHARQ_Msg3Tx;
}UE_PHY_HARQ_Msg3_config_t;
typedef struct{
uint8_t nb_antennas_tx;
}UE_PHY_antenna_config_t;
typedef struct{
PHICH_RESOURCE_t phich_resource;
PHICH_DURATION_t phich_duration;
}UE_PHY_phich_config_t;
typedef struct {
UE_PHY_tdd_frame_structure_t ue_tdd_frame_structure_config;
UE_PHY_prach_config_t ue_prach_config;
UE_PHY_pucch_config_t ue_pucch_config;
UE_PHY_pdsch_config_t ue_pdsch_config;
UE_PHY_pusch_config_t ue_pusch_config;
UE_PHY_SRS_config_t ue_srs_config;
UE_PHY_UL_power_control_config_t ue_ul_pow_cntl_config;
UE_PHY_HARQ_Msg3_config_t ue_harq_msg3_config;
/* Where can we find the types and values of the configuration for the PCH?
UE_MAC_pusch_config_t ue_pch_config
radioResourceConfigCommon->pcch_Config.defaultPagingCycle, radioResourceConfigCommon->pcch_Config.nB*/
UE_PHY_antenna_config_t ue_ant_config;
UE_PHY_phich_config_t ue_phich_config;
/* MBSFN?*/
}UE_PHY_config_common_request_t;
// *** UE_Config_dedicated. request related structures
typedef struct{
PA_t p_a;
}UE_PHY_pdsch_config_dedicated_t;
typedef struct{
uint8_t ackNackRepetition;
ANFBmode_t tdd_AckNackFeedbackMode;
//ACKNAKREP_t repetitionFactor;
//uint16_t n1PUCCH_AN_Rep;
}UE_PHY_pucch_config_dedicated_t;
typedef struct{
uint16_t betaOffset_ACK_Index;
uint16_t betaOffset_RI_Index;
uint16_t betaOffset_CQI_Index;
}UE_PHY_pusch_config_dedicated_t;
typedef struct{
int8_t p0_UE_PUSCH;
uint8_t deltaMCS_Enabled;
uint8_t accumulationEnabled;
int8_t p0_UE_PUCCH;
int8_t pSRS_Offset;
uint8_t filterCoefficient;
}UE_PHY_ul_power_control_config_dedicated_t;
typedef struct{
uint16_t sr_PUCCH_ResourceIndex;
uint8_t sr_ConfigIndex;
DSR_TRANSMAX_t dsr_TransMax;
}UE_PHY_SR_config_dedicated_t;
typedef struct{
uint8_t srsConfigDedicatedSetup;
uint8_t duration;
uint8_t cyclicShift;
uint8_t freqDomainPosition;
uint8_t srs_Bandwidth;
uint16_t srs_ConfigIndex;
uint8_t srs_HoppingBandwidth;
uint8_t transmissionComb;
//uint8_t srsCellSubframe;
//uint8_t srsUeSubframe;
}UE_PHY_srs_ul_config_dedicated_t;
typedef struct{
CQI_REPORTMODEAPERIODIC cqi_ReportModeAperiodic;
CQI_REPORTPERIODIC CQI_ReportPeriodic;
//int8_t nomPDSCH_RS_EPRE_Offset;
}UE_PHY_cqi_report_config_dedicated_t;
typedef struct{
uint8_t transmission_mode [NUMBER_OF_CONNECTED_eNB_MAX];
UE_PHY_pdsch_config_dedicated_t ue_pdsch_config;
UE_PHY_pucch_config_dedicated_t ue_pucch_config;
UE_PHY_pusch_config_dedicated_t ue_pusch_config;
UE_PHY_ul_power_control_config_dedicated_t ue_ul_pow_cntrl_config;
UE_PHY_SR_config_dedicated_t ue_SR_config;
UE_PHY_srs_ul_config_dedicated_t ue_srs_ul_config;
UE_PHY_cqi_report_config_dedicated_t ue_cqi_report_config;
}UE_PHY_config_dedicated_request_t;
#endif
/*
typedef struct {
nfapi_p4_p5_message_header_t header;
uint8_t num_tlv;
nfapi_subframe_config_t subframe_config;
nfapi_rf_config_t rf_config;
nfapi_phich_config_t phich_config;
nfapi_sch_config_t sch_config;
nfapi_prach_config_t prach_config;
nfapi_pusch_config_t pusch_config;
nfapi_pucch_config_t pucch_config;
nfapi_srs_config_t srs_config;
nfapi_uplink_reference_signal_config_t uplink_reference_signal_config;
nfapi_laa_config_t laa_config;
nfapi_emtc_config_t emtc_config;
nfapi_tdd_frame_structure_t tdd_frame_structure_config;
nfapi_l23_config_t l23_config;
nfapi_nb_iot_config_t nb_iot_config;
// addition nfapi tlvs as per table 2-16 in idle or configure
nfapi_nfapi_t nfapi_config;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_config_request_t;
typedef struct {
nfapi_tl_t tl;
uint8_t dci_format;
uint8_t cce_index;
uint8_t aggregation_level;
uint16_t rnti;
uint8_t resource_block_start;
uint8_t number_of_resource_block;
uint8_t mcs_1;
uint8_t cyclic_shift_2_for_drms;
uint8_t frequency_hopping_enabled_flag;
uint8_t frequency_hopping_bits;
uint8_t new_data_indication_1;
uint8_t ue_tx_antenna_seleciton;
uint8_t tpc;
uint8_t cqi_csi_request;
uint8_t ul_index;
uint8_t dl_assignment_index;
uint32_t tpc_bitmap;
uint16_t transmission_power;
} nfapi_hi_dci0_dci_pdu_rel8_t;
*/
......@@ -459,7 +459,9 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc,
LOG_E(NR_RRC, "NR_BCCH_BCH decode error\n");
return;
}
if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout, &asn_DEF_NR_BCCH_BCH_Message, (void *)bcch_message);
// Actions following cell selection while T311 is running
NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants;
if (is_nr_timer_active(timers->T311)) {
......@@ -717,10 +719,6 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc,
(const void *)Sdu,
Sdu_len);
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message);
}
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(NR_RRC, "[UE %ld] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", rrc->ue_id, dec_rval.consumed);
log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n");
......@@ -730,6 +728,10 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc,
return -1;
}
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message);
}
if (bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1) {
switch (bcch_message->message.choice.c1->present) {
case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1:
......
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