Commit 23ade3ad authored by Khalid Ahmed's avatar Khalid Ahmed Committed by Thomas Schlichter

PUSCH Rx channel estimation supporting DMRS type 2

- nr_ulsim supports multiple DMRS configurations
parent 935c2ce7
......@@ -45,7 +45,8 @@
unsigned short p,
unsigned char symbol,
unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pusch);
unsigned short nb_rb_pusch,
dmrs_UplinkConfig_t *dmrs_UplinkConfig);
int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
......
......@@ -56,9 +56,10 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
int32_t *output,
unsigned short p,
unsigned char lp,
unsigned short nb_pusch_rb)
unsigned short nb_pusch_rb,
uint8_t dmrs_type)
{
int8_t w,config_type;
int8_t w;
short *mod_table;
unsigned char idx=0;
......@@ -66,18 +67,16 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
array_of_w *wf;
array_of_w *wt;
config_type = 0; //to be updated by higher layer
wf = (dmrs_type==pusch_dmrs_type1) ? wf1 : wf2;
wt = (dmrs_type==pusch_dmrs_type1) ? wt1 : wt2;
wf = (config_type==0) ? wf1 : wf2;
wt = (config_type==0) ? wt1 : wt2;
if (dmrs_type > 2)
LOG_E(PHY,"Bad PUSCH DMRS config type %d\n", dmrs_type);
if (config_type > 1)
LOG_E(PHY,"Bad PUSCH DMRS config type %d\n", config_type);
if ((p>=1000) && (p<((config_type==0) ? 1008 : 1012))) {
if ((p>=1000) && (p<((dmrs_type==pusch_dmrs_type1) ? 1008 : 1012))) {
if (gNB->frame_parms.Ncp == NORMAL) {
for (int i=0; i<nb_pusch_rb*((config_type==0) ? 6:4); i++) {
for (int i=0; i<nb_pusch_rb*((dmrs_type==pusch_dmrs_type1) ? 6:4); i++) {
w = (wf[p-1000][i&1])*(wt[p-1000][lp]);
mod_table = (w==1) ? nr_rx_mod_table : nr_rx_nmod_table;
......@@ -86,7 +85,7 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
((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];
#ifdef DEBUG_PUSCH
printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", config_type, p, nb_pusch_rb);
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)[i<<1], ((int16_t*)output)[(i<<1)+1]);
......
......@@ -47,5 +47,6 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
int32_t *output,
unsigned short p,
unsigned char lp,
unsigned short nb_pusch_rb);
unsigned short nb_pusch_rb,
uint8_t dmrs_type);
#endif
......@@ -75,15 +75,18 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
unsigned short start_rb,
unsigned short nb_rb_pusch,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t is_dmrs_symbol,
uint8_t dmrs_symbol);
uint8_t dmrs_symbol,
uint16_t number_symbols,
uint8_t mapping_type,
dmrs_UplinkConfig_t *dmrs_UplinkConfig);
void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms,
NR_gNB_ULSCH_t **ulsch_gNB,
uint8_t symbol,
uint8_t start_symbol,
uint16_t nb_rb);
uint16_t nb_rb,
pusch_dmrs_type_t pusch_dmrs_type);
/** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal
......
......@@ -231,21 +231,25 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
unsigned short start_rb,
unsigned short nb_rb_pusch,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t is_dmrs_symbol,
uint8_t dmrs_symbol)
uint8_t dmrs_symbol,
uint16_t number_symbols,
uint8_t mapping_type,
dmrs_UplinkConfig_t *dmrs_UplinkConfig)
{
unsigned short start_re, re, nb_re_pusch;
unsigned char aarx;
uint32_t rxF_ext_index = 0;
uint32_t ul_ch0_ext_index = 0;
uint32_t ul_ch0_index = 0;
uint8_t is_dmrs_symbol_flag, k_prime;
uint16_t n=0;
int16_t *rxF,*rxF_ext;
int *ul_ch0,*ul_ch0_ext;
#ifdef DEBUG_RB_EXT
printf("--------------------symbol = %d, is_dmrs_symbol = %u-----------------------\n", symbol, is_dmrs_symbol);
printf("--------------------symbol = %d-----------------------\n", symbol);
printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * nb_rb_pusch);
#endif
......@@ -253,6 +257,7 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
start_re = (frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size;
nb_re_pusch = NR_NB_SC_PER_RB * nb_rb_pusch;
is_dmrs_symbol_flag = 0;
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
......@@ -263,26 +268,44 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
ul_ch0_ext = &ul_ch_estimates_ext[aarx][symbol*nb_re_pusch];
n = 0;
k_prime = 0;
for (re = 0; re < nb_re_pusch; re++) {
if ( (is_dmrs_symbol && ((re&1) != 0)) || (is_dmrs_symbol == 0) ) { // [hna] (re&1) != frame_parms->nushift) assuming only dmrs type 1 and mapping type A
// frame_parms->nushift should be initialized with 0
is_dmrs_symbol_flag = is_dmrs_symbol(symbol,
(start_re + re)%frame_parms->ofdm_symbol_size,
start_re,
k_prime,
n,
0,
number_symbols,
dmrs_UplinkConfig,
mapping_type,
frame_parms->ofdm_symbol_size);
#ifdef DEBUG_RB_EXT
printf("re = %d, is_dmrs_symbol_flag = %d, symbol = %d\n", re, is_dmrs_symbol_flag, symbol);
#endif
if ( is_dmrs_symbol_flag == 0 ) {
rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index];
ul_ch0_ext_index++;
rxF_ext_index = rxF_ext_index + 2;
}
ul_ch0_index++;
#ifdef DEBUG_RB_EXT
printf("rxF_ext[%d] = %d\n", rxF_ext_index, rxF_ext[rxF_ext_index]);
printf("rxF_ext[%d] = %d\n", rxF_ext_index+1, rxF_ext[rxF_ext_index+1]);
printf("ul_ch0_ext[%d] = %d\n", 2*rxF_ext_index, ((int16_t *)ul_ch0_ext)[2*rxF_ext_index]);
printf("ul_ch0_ext[%d] = %d\n", 2*rxF_ext_index + 1, ((int16_t *)ul_ch0_ext)[2*rxF_ext_index + 1]);
#endif
ul_ch0_ext_index++;
rxF_ext_index +=2;
} else {
k_prime++;
k_prime&=1;
n+=(k_prime)?0:1;
}
ul_ch0_index++;
}
}
}
......@@ -292,7 +315,8 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
NR_gNB_ULSCH_t **ulsch_gNB,
uint8_t symbol,
uint8_t is_dmrs_symbol,
unsigned short nb_rb)
unsigned short nb_rb,
pusch_dmrs_type_t pusch_dmrs_type)
{
#if defined(__x86_64__)||defined(__i386__)
......@@ -316,7 +340,10 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*nb_rb*NR_NB_SC_PER_RB];
if (is_dmrs_symbol==1){
nb_rb = nb_rb>>1;
if (pusch_dmrs_type == pusch_dmrs_type1)
nb_rb = nb_rb>>1;
else
nb_rb = (2*nb_rb)/3;
}
......@@ -367,7 +394,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
ul_ch128=(__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12];
for (rb = 0; rb < nb_rb; rb++) {
for (rb = 0; rb < len/12; rb++) {
avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x));
avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[1], ul_ch128[1]), x));
avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[2], ul_ch128[2]), x));
......@@ -997,18 +1024,18 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
bwp_start_subcarrier = (rel15_ul->start_rb*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
dmrs_symbol_flag = is_dmrs_symbol(symbol,
0,
0,
0,
0,
0,
rel15_ul->number_symbols,
&gNB->dmrs_UplinkConfig,
mapping_type,
frame_parms->ofdm_symbol_size);
0,
0,
0,
0,
0,
rel15_ul->number_symbols,
&gNB->dmrs_UplinkConfig,
mapping_type,
frame_parms->ofdm_symbol_size);
if (dmrs_symbol_flag == 1){
nb_re_pusch = rel15_ul->number_rbs * 6;
nb_re_pusch = rel15_ul->number_rbs * ((gNB->dmrs_UplinkConfig.pusch_dmrs_type==pusch_dmrs_type1)?6:8);
gNB->pusch_vars[UE_id]->dmrs_symbol = symbol;
} else {
nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB;
......@@ -1026,7 +1053,8 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
0, // p
symbol,
bwp_start_subcarrier,
rel15_ul->number_rbs);
rel15_ul->number_rbs,
&gNB->dmrs_UplinkConfig);
//----------------------------------------------------------
//--------------------- RBs extraction ---------------------
......@@ -1042,15 +1070,18 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
rel15_ul->start_rb,
rel15_ul->number_rbs,
frame_parms,
dmrs_symbol_flag,
gNB->pusch_vars[UE_id]->dmrs_symbol);
gNB->pusch_vars[UE_id]->dmrs_symbol,
rel15_ul->number_symbols,
mapping_type,
&gNB->dmrs_UplinkConfig);
nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
frame_parms,
gNB->ulsch[UE_id],
symbol,
dmrs_symbol_flag,
rel15_ul->number_rbs);
rel15_ul->number_rbs,
gNB->dmrs_UplinkConfig.pusch_dmrs_type);
if (first_symbol_flag==1) {
......
......@@ -173,3 +173,15 @@ short filt8_dcl1_h[8]= {
short filt8_dcr1_h[8]= {
0,0,4096,8192,12288,16384,0,0};
short filt8_ml2[8] = {
13107,9830,6554,3277,0,0,0,0};
short filt8_mr2[8] = {
3277,6554,9830,13107,0,0,0,0};
short filt8_rr1[8] = {
8192,12288,16384,20480,0,0,0,0};
short filt8_rr2[8] = {
-4096,-8192,-12288,-16384,0,0,0,0};
......@@ -124,4 +124,13 @@ extern short filt8_dcr1[8];
extern short filt8_dcl1_h[8];
extern short filt8_dcr1_h[8];
#endif
extern short filt8_ml2[8];
extern short filt8_mr2[8];
extern short filt8_rr1[8];
extern short filt8_rr2[8];
#endif
\ No newline at end of file
......@@ -91,13 +91,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
int gNB_id) {
uint32_t available_bits;
uint8_t mod_order, cwd_index, num_of_codewords;
uint8_t mod_order, cwd_index, num_of_codewords, l;
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
uint32_t ***pusch_dmrs;
int16_t **tx_layers;
int32_t **txdataF;
uint16_t start_sc, start_rb;
int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
int8_t Wf[2], Wt[2], l_prime[2], delta;
uint16_t n_dmrs, code_rate, number_dmrs_symbols;
uint8_t dmrs_type;
uint8_t mapping_type;
......@@ -135,8 +135,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
mapping_type,
frame_parms->ofdm_symbol_size);
printf("number_dmrs_symbols = %u\n", number_dmrs_symbols);
ulsch_ue->length_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength;
ulsch_ue->rnti = n_rnti;
ulsch_ue->Nid_cell = Nid_cell;
......@@ -229,8 +227,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
n_dmrs = (harq_process_ul_ue->nb_rb*ulsch_ue->nb_re_dmrs);
int16_t mod_dmrs[n_dmrs<<1];
dmrs_type = UE->dmrs_UplinkConfig.pusch_dmrs_type;
l0 = get_l0_ul(mapping_type, 2);
///////////
////////////////////////////////////////////////////////////////////////
......@@ -252,7 +248,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
///////////
l_prime[0] = 0; // single symbol ap 0
uint8_t dmrs_symbol = l0+l_prime[0], l; // Assuming dmrs-AdditionalPosition = 0
#ifdef NR_SC_FDMA
uint32_t nb_re_pusch, nb_re_dmrs_per_rb;
......@@ -260,8 +255,19 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
for (l = start_symbol; l < start_symbol + harq_process_ul_ue->number_of_symbols; l++) {
if(l == dmrs_symbol)
nb_re_dmrs_per_rb = ulsch_ue->nb_re_dmrs; // [hna] ulsch_ue->nb_re_dmrs = 6 in this configuration
is_dmrs = is_dmrs_symbol(l,
0,
0,
0,
0,
0,
harq_process_ul_ue->number_of_symbols,
&UE->dmrs_UplinkConfig,
mapping_type,
frame_parms->ofdm_symbol_size);
if (is_dmrs == 1)
nb_re_dmrs_per_rb = ulsch_ue->nb_re_dmrs;
else
nb_re_dmrs_per_rb = 0;
......@@ -328,8 +334,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
if (is_dmrs == 1) {
printf("DMRS l = %u\n", l);
nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15;
......
......@@ -119,6 +119,32 @@ void multadd_real_vector_complex_scalar(int16_t *x,
}
void multadd_real_four_symbols_vector_complex_scalar(int16_t *x,
int16_t *alpha,
int16_t *y)
{
// do 8 multiplications at a time
simd_q15_t alpha_r_128,alpha_i_128,yr,yi,*x_128=(simd_q15_t*)x;
simd_q15_t y_128;
y_128 = _mm_loadu_si128((simd_q15_t*)y);
alpha_r_128 = set1_int16(alpha[0]);
alpha_i_128 = set1_int16(alpha[1]);
yr = mulhi_s1_int16(alpha_r_128,x_128[0]);
yi = mulhi_s1_int16(alpha_i_128,x_128[0]);
y_128 = _mm_adds_epi16(y_128,_mm_unpacklo_epi16(yr,yi));
y_128 = _mm_adds_epi16(y_128,_mm_unpackhi_epi16(yr,yi));
_mm_storeu_si128((simd_q15_t*)y, y_128);
_mm_empty();
_m_empty();
}
/*
int rotate_cpx_vector(int16_t *x,
int16_t *alpha,
......
......@@ -71,6 +71,10 @@ void multadd_real_vector_complex_scalar(int16_t *x,
int16_t *y,
uint32_t N);
void multadd_real_four_symbols_vector_complex_scalar(int16_t *x,
int16_t *alpha,
int16_t *y);
/*!\fn void multadd_complex_vector_real_scalar(int16_t *x,int16_t alpha,int16_t *y,uint8_t zero_flag,uint32_t N)
This function performs componentwise multiplication and accumulation of a real scalar and a complex vector.
@param x Vector input (Q1.15) in the format |Re0 Im0|Re1 Im 1| ...
......
......@@ -22,6 +22,7 @@
#include "PHY/phy_extern.h"
#include "PHY/defs_gNB.h"
#include "sched_nr.h"
#include "PHY/NR_REFSIG/dmrs_nr.h"
#include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
......
......@@ -400,7 +400,6 @@ int main(int argc, char **argv)
rel15_ul->mcs = Imcs;
rel15_ul->rv = rvidx;
rel15_ul->n_layers = Nl;
rel15_ul->nb_re_dmrs = nb_re_dmrs;
rel15_ul->length_dmrs = length_dmrs;
rel15_ul->R = code_rate;
///////////////////////////////////////////////////
......
......@@ -150,8 +150,8 @@ int main(int argc, char **argv)
NR_DL_FRAME_PARMS *frame_parms;
int loglvl = OAILOG_WARNING;
uint64_t SSB_positions=0x01;
uint16_t nb_symb_sch = 12;
int start_symbol = NR_SYMBOLS_PER_SLOT - nb_symb_sch;
uint16_t nb_symb_sch = 14;
int start_symbol = 0;
uint16_t nb_rb = 50;
uint8_t Imcs = 9;
uint8_t precod_nbr_layers = 1;
......@@ -453,13 +453,14 @@ int main(int argc, char **argv)
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, precod_nbr_layers);
NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0];
//nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu;
nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req;
nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;
NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0];
unsigned char *estimated_output_bit;
unsigned char *test_input_bit;
uint32_t errors_decoding = 0;
......@@ -471,7 +472,33 @@ int main(int argc, char **argv)
nr_scheduled_response_t scheduled_response;
fapi_nr_ul_config_request_t ul_config;
unsigned int TBS;
uint16_t number_dmrs_symbols = 0;
unsigned int available_bits;
uint8_t nb_re_dmrs;
uint8_t length_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength;
unsigned char mod_order;
uint16_t code_rate;
for (i = 0; i < NR_SYMBOLS_PER_SLOT; i++)
number_dmrs_symbols += is_dmrs_symbol(i,
0,
0,
0,
0,
0,
nb_symb_sch,
&UE->dmrs_UplinkConfig,
UE->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType,
frame_parms->ofdm_symbol_size);
mod_order = nr_get_Qm_ul(Imcs, 0);
nb_re_dmrs = ((UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1) ? 6 : 4) * number_dmrs_symbols;
code_rate = nr_get_code_rate_ul(Imcs, 0);
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, precod_nbr_layers);
printf("\n");
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
......@@ -493,7 +520,6 @@ int main(int argc, char **argv)
rel15_ul->ulsch_pdu_rel15.number_rbs = nb_rb;
rel15_ul->ulsch_pdu_rel15.start_symbol = start_symbol;
rel15_ul->ulsch_pdu_rel15.number_symbols = nb_symb_sch;
rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = nb_re_dmrs;
rel15_ul->ulsch_pdu_rel15.length_dmrs = length_dmrs;
rel15_ul->ulsch_pdu_rel15.Qm = mod_order;
rel15_ul->ulsch_pdu_rel15.mcs = Imcs;
......
This diff is collapsed.
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