Commit 6237ba37 authored by Francesco Mani's avatar Francesco Mani

Merge branch 'nr_pucch' into NR_RRC_harq

parents 9e8e7de1 786be881
...@@ -1177,21 +1177,18 @@ ...@@ -1177,21 +1177,18 @@
<testCase id="015109"> <testCase id="015109">
<class>execution</class> <class>execution</class>
<desc>nr_pucchsim Test cases. (Test1: Format 0 ACK miss 106 PRB), <desc>nr_pucchsim Test cases. (Test1: Format 0 1-bit ACK miss 106 PRB),
(Test2: Format 1 ACK miss 106 PRB), (Test2: Format 0 2-bit ACK miss 106 PRB)</desc>
(Test3: Format 1 ACK miss 273 PRB),
(Test4: Format 1 NACKtoACK 106 PRB)</desc>
<pre_compile_prog></pre_compile_prog> <pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog> <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args> <compile_prog_args> --phy_simulators -c </compile_prog_args>
<pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec> <pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
<pre_exec_args></pre_exec_args> <pre_exec_args></pre_exec_args>
<main_exec> $OPENAIR_DIR/targets/bin/nr_pucchsim.Rel15</main_exec> <main_exec> $OPENAIR_DIR/targets/bin/nr_pucchsim.Rel15</main_exec>
<main_exec_args>-R 106 -i 1 -P 0 -b 1 -s3 -n100 <main_exec_args>-R 106 -i 1 -P 0 -b 1 -s-7 -n1000
-R 106 -i 14 -P 1 -b 1 -s-6 -n100 -R 106 -i 1 -P 0 -b 2 -s-7 -n1000
-R 273 -i 14 -P 1 -b 1 -s-6 -n100 </main_exec_args>
-R 106 -i 14 -P 1 -b 1 -s-6 -T 0.001 -n1000</main_exec_args> <tags>nr_pucchsim.test1 nr_pucchsim.test2 </tags>
<tags>nr_pucchsim.test1 nr_pucchsim.test2 nr_pucchsim.test3 nr_pucchsim.test4</tags>
<search_expr_true>PUCCH test OK</search_expr_true> <search_expr_true>PUCCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns> <nruns>3</nruns>
......
...@@ -633,7 +633,7 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) { ...@@ -633,7 +633,7 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) {
return 0; return 0;
} }
inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) { static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
if (fp->numerology_index == 0) if (fp->numerology_index == 0)
return fp->nb_prefix_samples0 + fp->ofdm_symbol_size; return fp->nb_prefix_samples0 + fp->ofdm_symbol_size;
int num_samples = (slot%(fp->slots_per_subframe/2)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0; int num_samples = (slot%(fp->slots_per_subframe/2)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0;
...@@ -641,7 +641,7 @@ inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) { ...@@ -641,7 +641,7 @@ inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
return num_samples; return num_samples;
} }
inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) { static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
int rem_samples = fp->get_samples_per_slot(slot, fp) - get_firstSymSamp(slot, fp); int rem_samples = fp->get_samples_per_slot(slot, fp) - get_firstSymSamp(slot, fp);
int next_slot_first_symbol = 0; int next_slot_first_symbol = 0;
if (slot < (fp->slots_per_frame-1)) if (slot < (fp->slots_per_frame-1))
......
...@@ -138,9 +138,8 @@ void nr_decode_pucch1(int32_t **rxdataF, ...@@ -138,9 +138,8 @@ void nr_decode_pucch1(int32_t **rxdataF,
uint8_t timeDomainOCC, uint8_t timeDomainOCC,
uint8_t nr_bit); uint8_t nr_bit);
void nr_decode_pucch0(int32_t **rxdataF, void nr_decode_pucch0(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *frame_parms, int slot,
int slot,
nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu, nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu,
nfapi_nr_pucch_pdu_t* pucch_pdu); nfapi_nr_pucch_pdu_t* pucch_pdu);
......
...@@ -17,19 +17,92 @@ ...@@ -17,19 +17,92 @@
#include "T.h" #include "T.h"
//#define DEBUG_NR_PUCCH_RX 1
void nr_decode_pucch0(int32_t **rxdataF, int get_pucch0_cs_lut_index(PHY_VARS_gNB *gNB,nfapi_nr_pucch_pdu_t* pucch_pdu) {
NR_DL_FRAME_PARMS *frame_parms,
int i=0;
#ifdef DEBUG_NR_PUCCH_RX
printf("getting index for LUT with %d entries, Nid %d\n",gNB->pucch0_lut.nb_id, pucch_pdu->hopping_id);
#endif
for (i=0;i<gNB->pucch0_lut.nb_id;i++) {
if (gNB->pucch0_lut.Nid[i] == pucch_pdu->hopping_id) break;
}
#ifdef DEBUG_NR_PUCCH_RX
printf("found index %d\n",i);
#endif
if (i<gNB->pucch0_lut.nb_id) return(i);
#ifdef DEBUG_NR_PUCCH_RX
printf("Initializing PUCCH0 LUT index %i with Nid %d\n",i, pucch_pdu->hopping_id);
#endif
// initialize
gNB->pucch0_lut.Nid[gNB->pucch0_lut.nb_id]=pucch_pdu->hopping_id;
for (int slot=0;slot<10<<pucch_pdu->subcarrier_spacing;slot++)
for (int symbol=0;symbol<14;symbol++)
gNB->pucch0_lut.lut[gNB->pucch0_lut.nb_id][slot][symbol] = (int)floor(nr_cyclic_shift_hopping(pucch_pdu->hopping_id,0,0,symbol,0,slot)/0.5235987756);
gNB->pucch0_lut.nb_id++;
return(gNB->pucch0_lut.nb_id-1);
}
int16_t idft12_re[12][12] = {
{23170,23170,23170,23170,23170,23170,23170,23170,23170,23170,23170,23170},
{23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585,0,11585,20066},
{23170,11585,-11585,-23170,-11585,11585,23170,11585,-11585,-23170,-11585,11585},
{23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170,0},
{23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585},
{23170,-20066,11585,0,-11585,20066,-23170,20066,-11585,0,11585,-20066},
{23170,-23170,23170,-23170,23170,-23170,23170,-23170,23170,-23170,23170,-23170},
{23170,-20066,11585,0,-11585,20066,-23170,20066,-11585,0,11585,-20066},
{23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585},
{23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170,0},
{23170,11585,-11585,-23170,-11585,11585,23170,11585,-11585,-23170,-11585,11585},
{23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585,0,11585,20066}
};
int16_t idft12_im[12][12] = {
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,11585,20066,23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585},
{0,20066,20066,0,-20066,-20066,0,20066,20066,0,-20066,-20066},
{0,23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170},
{0,20066,-20066,0,20066,-20066,0,20066,-20066,0,20066,-20066},
{0,11585,-20066,23170,-20066,11585,0,-11585,20066,-23170,20066,-11585},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,-11585,20066,-23170,20066,-11585,0,11585,-20066,23170,-20066,11585},
{0,-20066,20066,0,-20066,20066,0,-20066,20066,0,-20066,20066},
{0,-23170,0,23170,0,-23170,0,23170,0,-23170,0,23170},
{0,-20066,-20066,0,20066,20066,0,-20066,-20066,0,20066,20066},
{0,-11585,-20066,-23170,-20066,-11585,0,11585,20066,23170,20066,11585}
};
void nr_decode_pucch0(PHY_VARS_gNB *gNB,
int slot, int slot,
nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu, nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu,
nfapi_nr_pucch_pdu_t* pucch_pdu) { nfapi_nr_pucch_pdu_t* pucch_pdu) {
int32_t **rxdataF = gNB->common_vars.rxdataF;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
int nr_sequences; int nr_sequences;
const uint8_t *mcs; const uint8_t *mcs;
pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1); pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1);
if(pucch_pdu->bit_len_harq==1){ AssertFatal(pucch_pdu->bit_len_harq > 0 || pucch_pdu->sr_flag > 0,
"Either bit_len_harq (%d) or sr_flag (%d) must be > 0\n",
pucch_pdu->bit_len_harq,pucch_pdu->sr_flag);
if(pucch_pdu->bit_len_harq==0){
mcs=table1_mcs;
nr_sequences=1;
}
else if(pucch_pdu->bit_len_harq==1){
mcs=table1_mcs; mcs=table1_mcs;
nr_sequences=4>>(1-pucch_pdu->sr_flag); nr_sequences=4>>(1-pucch_pdu->sr_flag);
} }
...@@ -37,6 +110,8 @@ void nr_decode_pucch0(int32_t **rxdataF, ...@@ -37,6 +110,8 @@ void nr_decode_pucch0(int32_t **rxdataF,
mcs=table2_mcs; mcs=table2_mcs;
nr_sequences=8>>(1-pucch_pdu->sr_flag); nr_sequences=8>>(1-pucch_pdu->sr_flag);
} }
int cs_ind = get_pucch0_cs_lut_index(gNB,pucch_pdu);
/* /*
* Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation * Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation
* *
...@@ -71,35 +146,44 @@ void nr_decode_pucch0(int32_t **rxdataF, ...@@ -71,35 +146,44 @@ void nr_decode_pucch0(int32_t **rxdataF,
uint8_t n_hop = 0; // Frequnecy hopping not implemented FIXME!! uint8_t n_hop = 0; // Frequnecy hopping not implemented FIXME!!
// x_n contains the sequence r_u_v_alpha_delta(n) // x_n contains the sequence r_u_v_alpha_delta(n)
int16_t x_n_re[nr_sequences][24],x_n_im[nr_sequences][24];
int n,i,l; int n,i,l;
nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,n_hop,slot,&u,&v); // calculating u and v value
uint32_t re_offset=0;
uint8_t l2;
#ifdef OLD_IMPL
int16_t x_n_re[nr_sequences][24],x_n_im[nr_sequences][24];
for(i=0;i<nr_sequences;i++){ for(i=0;i<nr_sequences;i++){
// we proceed to calculate alpha according to TS 38.211 Subclause 6.3.2.2.2 // we proceed to calculate alpha according to TS 38.211 Subclause 6.3.2.2.2
for (l=0; l<pucch_pdu->nr_of_symbols; l++){ for (l=0; l<pucch_pdu->nr_of_symbols; l++){
nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,n_hop,slot,&u,&v); // calculating u and v value
alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id,pucch_pdu->initial_cyclic_shift,mcs[i],l,pucch_pdu->start_symbol_index,slot); alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id,pucch_pdu->initial_cyclic_shift,mcs[i],l,pucch_pdu->start_symbol_index,slot);
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d)\n",u,v,alpha,l); printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d/%d,mcs %d)\n",u,v,alpha,l,l+pucch_pdu->start_symbol_index,mcs[i]);
#endif printf("lut output %d\n",gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index]);
#endif
alpha=0.0;
for (n=0; n<12; n++){ for (n=0; n<12; n++){
x_n_re[i][(12*l)+n] = (int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) x_n_re[i][(12*l)+n] = (int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
- (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)))>>15); // Re part of base sequence shifted by alpha - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)))); // Re part of base sequence shifted by alpha
x_n_im[i][(12*l)+n] =(int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) x_n_im[i][(12*l)+n] =(int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
+ (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)))>>15); // Im part of base sequence shifted by alpha + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)))); // Im part of base sequence shifted by alpha
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d)\n", printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d) %d,%d\n",
u,v,alpha,l,n,x_n_re[(12*l)+n],x_n_im[(12*l)+n]); u,v,alpha,l,n,x_n_re[i][(12*l)+n],x_n_im[i][(12*l)+n],
#endif (int32_t)(round(32767*cos(alpha*n))),
(int32_t)(round(32767*sin(alpha*n))));
#endif
} }
} }
} }
int16_t r_re[24],r_im[24];
/* /*
* Implementing TS 38.211 Subclause 6.3.2.3.2 Mapping to physical resources * Implementing TS 38.211 Subclause 6.3.2.3.2 Mapping to physical resources
*/ */
uint32_t re_offset=0;
uint8_t l2; int16_t r_re[24],r_im[24];
for (l=0; l<pucch_pdu->nr_of_symbols; l++) { for (l=0; l<pucch_pdu->nr_of_symbols; l++) {
...@@ -122,7 +206,7 @@ void nr_decode_pucch0(int32_t **rxdataF, ...@@ -122,7 +206,7 @@ void nr_decode_pucch0(int32_t **rxdataF,
if (re_offset>= frame_parms->ofdm_symbol_size) if (re_offset>= frame_parms->ofdm_symbol_size)
re_offset-=frame_parms->ofdm_symbol_size; re_offset-=frame_parms->ofdm_symbol_size;
} }
} }
double corr[nr_sequences],corr_re[nr_sequences],corr_im[nr_sequences]; double corr[nr_sequences],corr_re[nr_sequences],corr_im[nr_sequences];
memset(corr,0,nr_sequences*sizeof(double)); memset(corr,0,nr_sequences*sizeof(double));
memset(corr_re,0,nr_sequences*sizeof(double)); memset(corr_re,0,nr_sequences*sizeof(double));
...@@ -144,28 +228,115 @@ void nr_decode_pucch0(int32_t **rxdataF, ...@@ -144,28 +228,115 @@ void nr_decode_pucch0(int32_t **rxdataF,
max_corr=corr[i]; max_corr=corr[i];
} }
} }
#else
int16_t *x_re = table_5_2_2_2_2_Re[u],*x_im = table_5_2_2_2_2_Im[u];
int16_t xr[24] __attribute__((aligned(32)));
int16_t xrt[24] __attribute__((aligned(32)));
int32_t xrtmag=0;
int maxpos=0;
int n2=0;
uint8_t index=0;
memset((void*)xr,0,24*sizeof(int16_t));
for (l=0; l<pucch_pdu->nr_of_symbols; l++) {
l2 = l+pucch_pdu->start_symbol_index;
re_offset = (12*pucch_pdu->prb_start) + frame_parms->first_carrier_offset;
if (re_offset>= frame_parms->ofdm_symbol_size)
re_offset-=frame_parms->ofdm_symbol_size;
AssertFatal(re_offset+12 < frame_parms->ofdm_symbol_size,"pucch straddles DC carrier, handle this!\n");
int16_t *r=(int16_t*)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size+re_offset)];
for (n=0;n<12;n++,n2+=2) {
xr[n2] =(int16_t)(((int32_t)x_re[n]*r[n2]+(int32_t)x_im[n]*r[n2+1])>>15);
xr[n2+1]=(int16_t)(((int32_t)x_re[n]*r[n2+1]-(int32_t)x_im[n]*r[n2])>>15);
#ifdef DEBUG_NR_PUCCH_RX
printf("x (%d,%d), r (%d,%d), xr (%d,%d)\n",
x_re[n],x_im[n],r[n2],r[n2+1],xr[n2],xr[n2+1]);
#endif
}
}
int32_t corr_re,corr_im,temp;
int seq_index;
for(i=0;i<nr_sequences;i++){
corr_re=0;corr_im=0;
n2=0;
for (l=0;l<pucch_pdu->nr_of_symbols;l++) {
seq_index = (pucch_pdu->initial_cyclic_shift+
mcs[i]+
gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12;
for (n=0;n<12;n++,n2+=2) {
corr_re+=(xr[n2]*idft12_re[seq_index][n]+xr[n2+1]*idft12_im[seq_index][n])>>15;
corr_im+=(xr[n2]*idft12_im[seq_index][n]-xr[n2+1]*idft12_re[seq_index][n])>>15;
}
}
#ifdef DEBUG_NR_PUCCH_RX
printf("PUCCH IDFT[%d/%d] = (%d,%d)=>%f\n",mcs[i],seq_index,corr_re,corr_im,10*log10(corr_re*corr_re + corr_im*corr_im));
#endif
if ((temp=corr_re*corr_re + corr_im*corr_im)>xrtmag) {
xrtmag=temp;
maxpos=i;
}
}
uint8_t xrtmag_dB = dB_fixed(xrtmag);
#ifdef DEBUG_NR_PUCCH_RX
printf("PUCCH 0 : maxpos %d\n",maxpos);
#endif
index=maxpos;
#endif
// first bit of bitmap for sr presence and second bit for acknack presence // first bit of bitmap for sr presence and second bit for acknack presence
uci_pdu->pdu_bit_map = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1); uci_pdu->pdu_bit_map = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1);
uci_pdu->pucch_format = 0; // format 0 uci_pdu->pucch_format = 0; // format 0
uci_pdu->ul_cqi = 0xff; // currently not valid uci_pdu->ul_cqi = 0xff; // currently not valid
uci_pdu->timing_advance = 0xffff; // currently not valid uci_pdu->timing_advance = 0xffff; // currently not valid
uci_pdu->rssi = 0xffff; // currently not valid uci_pdu->rssi = 0xffff; // currently not valid
if (pucch_pdu->sr_flag) {
//currently not supported if (pucch_pdu->bit_len_harq==0) {
uci_pdu->harq = NULL;
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
if (xrtmag_dB>(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres)) {
uci_pdu->sr->sr_indication = 1;
uci_pdu->sr->sr_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
} else {
uci_pdu->sr->sr_indication = 0;
uci_pdu->sr->sr_confidence_level = (gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres)-xrtmag_dB;
}
} }
else else if (pucch_pdu->bit_len_harq==1) {
uci_pdu->sr = NULL;
if (pucch_pdu->bit_len_harq>0) {
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq)); uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
uci_pdu->harq->num_harq = pucch_pdu->bit_len_harq; uci_pdu->harq->num_harq = 1;
uci_pdu->harq->harq_confidence_level = 0xff; // currently not valid uci_pdu->harq->harq_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(uci_pdu->harq->num_harq); uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1);
for (i=0; i<uci_pdu->harq->num_harq; i++) // FIXME for non present uci_pdu->harq->harq_list[0].harq_value = index&0x01;
uci_pdu->harq->harq_list[i].harq_value = (index>>i)&0x01; if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_indication = (index>1) ? 1 : 0;
uci_pdu->sr->sr_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
}
}
else {
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
uci_pdu->harq->num_harq = 2;
uci_pdu->harq->harq_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2);
uci_pdu->harq->harq_list[0].harq_value = index&0x01;
uci_pdu->harq->harq_list[1].harq_value = (index>>1)&0x01;
if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_indication = (index>3) ? 1 : 0;
uci_pdu->sr->sr_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
}
} }
else
uci_pdu->harq = NULL;
} }
...@@ -281,7 +452,6 @@ void nr_decode_pucch1( int32_t **rxdataF, ...@@ -281,7 +452,6 @@ void nr_decode_pucch1( int32_t **rxdataF,
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
} }
//txptr = &txdataF[0][re_offset];
for (int n=0; n<12; n++) { for (int n=0; n<12; n++) {
if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) {
// if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB)
...@@ -294,7 +464,7 @@ void nr_decode_pucch1( int32_t **rxdataF, ...@@ -294,7 +464,7 @@ void nr_decode_pucch1( int32_t **rxdataF,
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset,
l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); l,n,((int16_t *)&rxdataF[0][re_offset])[0],((int16_t *)&rxdataF[0][re_offset])[1]);
#endif #endif
} }
...@@ -305,7 +475,7 @@ void nr_decode_pucch1( int32_t **rxdataF, ...@@ -305,7 +475,7 @@ void nr_decode_pucch1( int32_t **rxdataF,
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset,
l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); l,n,((int16_t *)&rxdataF[0][re_offset])[0],((int16_t *)&rxdataF[0][re_offset])[1]);
#endif #endif
// printf("l=%d\ti=%d\tre_offset=%d\treceived dmrs re=%d\tim=%d\n",l,i,re_offset,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]); // printf("l=%d\ti=%d\tre_offset=%d\treceived dmrs re=%d\tim=%d\n",l,i,re_offset,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]);
} }
...@@ -416,7 +586,7 @@ void nr_decode_pucch1( int32_t **rxdataF, ...@@ -416,7 +586,7 @@ void nr_decode_pucch1( int32_t **rxdataF,
mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],
z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#endif #endif
// multiplying with conjugate of low papr sequence // multiplying with conjugate of low papr sequence
z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
...@@ -450,7 +620,7 @@ void nr_decode_pucch1( int32_t **rxdataF, ...@@ -450,7 +620,7 @@ void nr_decode_pucch1( int32_t **rxdataF,
mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],
z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#endif #endif
//finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays //finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays
z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
...@@ -501,7 +671,7 @@ void nr_decode_pucch1( int32_t **rxdataF, ...@@ -501,7 +671,7 @@ void nr_decode_pucch1( int32_t **rxdataF,
mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],
z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#endif #endif
z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
+ (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
...@@ -529,7 +699,7 @@ void nr_decode_pucch1( int32_t **rxdataF, ...@@ -529,7 +699,7 @@ void nr_decode_pucch1( int32_t **rxdataF,
mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],
z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#endif #endif
//finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays //finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays
z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
......
...@@ -194,7 +194,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, ...@@ -194,7 +194,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
} }
} }
//Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
else if (!IS_SOFTMODEM_NOS1 || !data_existing) { if (!IS_SOFTMODEM_NOS1 || !data_existing) {
//Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
//and block this traffic from being forwarded to the upper layers at the gNB //and block this traffic from being forwarded to the upper layers at the gNB
uint16_t payload_offset = 5; uint16_t payload_offset = 5;
......
...@@ -2437,6 +2437,10 @@ static inline void idft16(int16_t *x,int16_t *y) ...@@ -2437,6 +2437,10 @@ static inline void idft16(int16_t *x,int16_t *y)
#endif #endif
} }
void idft16f(int16_t *x,int16_t *y) {
idft16(x,y);
}
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__ #ifdef __AVX2__
// Does two 16-point IDFTS (x[0 .. 15] is 128 LSBs of input vector, x[16..31] is in 128 MSBs) // Does two 16-point IDFTS (x[0 .. 15] is 128 LSBs of input vector, x[16..31] is in 128 MSBs)
......
...@@ -179,6 +179,8 @@ This function performs optimized fixed-point radix-2 FFT/IFFT. ...@@ -179,6 +179,8 @@ This function performs optimized fixed-point radix-2 FFT/IFFT.
); );
*/ */
void idft16f(int16_t *x,int16_t *y);
void idft1536(int16_t *sigF,int16_t *sig,int scale); void idft1536(int16_t *sigF,int16_t *sig,int scale);
void idft6144(int16_t *sigF,int16_t *sig,int scale); void idft6144(int16_t *sigF,int16_t *sig,int scale);
......
...@@ -44,6 +44,13 @@ ...@@ -44,6 +44,13 @@
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" #include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB #define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
#define MAX_PUCCH0_NID 8
typedef struct {
int nb_id;
int Nid[MAX_PUCCH0_NID];
int lut[MAX_PUCCH0_NID][160][14];
} NR_gNB_PUCCH0_LUT_t;
typedef struct { typedef struct {
uint32_t pbch_a; uint32_t pbch_a;
...@@ -561,13 +568,13 @@ typedef struct { ...@@ -561,13 +568,13 @@ typedef struct {
//! estimated avg noise power (dB) //! estimated avg noise power (dB)
short n0_power_tot_dBm; short n0_power_tot_dBm;
//! estimated avg noise power per RB per RX ant (lin) //! estimated avg noise power per RB per RX ant (lin)
unsigned short n0_subband_power[MAX_NUM_RU_PER_gNB][100]; unsigned short n0_subband_power[MAX_NUM_RU_PER_gNB][275];
//! estimated avg noise power per RB per RX ant (dB) //! estimated avg noise power per RB per RX ant (dB)
unsigned short n0_subband_power_dB[MAX_NUM_RU_PER_gNB][100]; unsigned short n0_subband_power_dB[MAX_NUM_RU_PER_gNB][275];
//! estimated avg noise power per RB (dB) //! estimated avg noise power per RB (dB)
short n0_subband_power_tot_dB[100]; short n0_subband_power_tot_dB[275];
//! estimated avg noise power per RB (dBm) //! estimated avg noise power per RB (dBm)
short n0_subband_power_tot_dBm[100]; short n0_subband_power_tot_dBm[275];
// gNB measurements (per user) // gNB measurements (per user)
//! estimated received spatial signal power (linear) //! estimated received spatial signal power (linear)
unsigned int rx_spatial_power[NUMBER_OF_NR_DLSCH_MAX][2][2]; unsigned int rx_spatial_power[NUMBER_OF_NR_DLSCH_MAX][2][2];
...@@ -587,13 +594,13 @@ typedef struct { ...@@ -587,13 +594,13 @@ typedef struct {
/// Wideband CQI (sum of all RX antennas, in dB) /// Wideband CQI (sum of all RX antennas, in dB)
char wideband_cqi_tot[NUMBER_OF_NR_DLSCH_MAX]; char wideband_cqi_tot[NUMBER_OF_NR_DLSCH_MAX];
/// Subband CQI per RX antenna and RB (= SINR) /// Subband CQI per RX antenna and RB (= SINR)
int subband_cqi[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][100]; int subband_cqi[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][275];
/// Total Subband CQI and RB (= SINR) /// Total Subband CQI and RB (= SINR)
int subband_cqi_tot[NUMBER_OF_NR_DLSCH_MAX][100]; int subband_cqi_tot[NUMBER_OF_NR_DLSCH_MAX][275];
/// Subband CQI in dB and RB (= SINR dB) /// Subband CQI in dB and RB (= SINR dB)
int subband_cqi_dB[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][100]; int subband_cqi_dB[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][275];
/// Total Subband CQI and RB /// Total Subband CQI and RB
int subband_cqi_tot_dB[NUMBER_OF_NR_DLSCH_MAX][100]; int subband_cqi_tot_dB[NUMBER_OF_NR_DLSCH_MAX][275];
/// PRACH background noise level /// PRACH background noise level
int prach_I0; int prach_I0;
} PHY_MEASUREMENTS_gNB; } PHY_MEASUREMENTS_gNB;
...@@ -647,6 +654,8 @@ typedef struct PHY_VARS_gNB_s { ...@@ -647,6 +654,8 @@ typedef struct PHY_VARS_gNB_s {
uint8_t pbch_configured; uint8_t pbch_configured;
char gNB_generate_rar; char gNB_generate_rar;
// PUCCH0 Look-up table for cyclic-shifts
NR_gNB_PUCCH0_LUT_t pucch0_lut;
/// NR synchronization sequences /// NR synchronization sequences
int16_t d_pss[NR_PSS_LENGTH]; int16_t d_pss[NR_PSS_LENGTH];
int16_t d_sss[NR_SSS_LENGTH]; int16_t d_sss[NR_SSS_LENGTH];
...@@ -698,6 +707,7 @@ typedef struct PHY_VARS_gNB_s { ...@@ -698,6 +707,7 @@ typedef struct PHY_VARS_gNB_s {
/// counter to average prach energh over first 100 prach opportunities /// counter to average prach energh over first 100 prach opportunities
int prach_energy_counter; int prach_energy_counter;
int pucch0_thres;
/* /*
time_stats_t phy_proc; time_stats_t phy_proc;
*/ */
......
...@@ -286,7 +286,6 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_ ...@@ -286,7 +286,6 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_
nfapi_rx_indication_pdu_t *pdu; nfapi_rx_indication_pdu_t *pdu;
int timing_advance_update; int timing_advance_update;
int sync_pos; int sync_pos;
...@@ -299,7 +298,7 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_ ...@@ -299,7 +298,7 @@ void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_
gNB->UL_INFO.rx_ind.sfn_sf = frame<<4| slot_rx; gNB->UL_INFO.rx_ind.sfn_sf = frame<<4| slot_rx;
gNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; gNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG;
gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list->rx_indication_rel8.length = gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->TBS>>3; gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list->rx_indication_rel8.length = gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->TBS;
pdu = &gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus]; pdu = &gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus];
...@@ -406,52 +405,52 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) ...@@ -406,52 +405,52 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
uci_indication->num_ucis = 0; uci_indication->num_ucis = 0;
LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d, num_pdus %d\n",frame_rx,slot_rx,num_pdus); LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d, num_pdus %d\n",frame_rx,slot_rx,num_pdus);
gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0;
for (int i = 0; i < num_pdus; i++) { for (int i = 0; i < num_pdus; i++) {
switch (UL_tti_req->pdus_list[i].pdu_type) { switch (UL_tti_req->pdus_list[i].pdu_type) {
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx); LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx);
nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[i].pusch_pdu; nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;
nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu); nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu);
uint8_t ULSCH_id = find_nr_ulsch(pusch_pdu->rnti,gNB,SEARCH_EXIST); uint8_t ULSCH_id = find_nr_ulsch(pusch_pdu->rnti,gNB,SEARCH_EXIST);
uint8_t harq_pid = pusch_pdu->pusch_data.harq_process_id; uint8_t harq_pid = pusch_pdu->pusch_data.harq_process_id;
uint8_t symbol_start = pusch_pdu->start_symbol_index; uint8_t symbol_start = pusch_pdu->start_symbol_index;
uint8_t symbol_end = symbol_start + pusch_pdu->nr_of_symbols; uint8_t symbol_end = symbol_start + pusch_pdu->nr_of_symbols;
for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) {
nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid); nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid);
} }
//LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1); //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1);
//LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1); //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid);
nr_fill_rx_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); // indicate SDU to MAC nr_fill_rx_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); // indicate SDU to MAC
break; nr_fill_crc_indication(gNB, frame_rx, slot_rx, ULSCH_id, 0);
break;
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE\n",frame_rx,slot_rx); LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE\n",frame_rx,slot_rx);
nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[i].pucch_pdu; nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[i].pucch_pdu;
switch (pucch_pdu->format_type) { switch (pucch_pdu->format_type) {
case 0: case 0:
uci_indication->uci_list[uci_indication->num_ucis].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE; uci_indication->uci_list[uci_indication->num_ucis].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE;
uci_indication->uci_list[uci_indication->num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t); uci_indication->uci_list[uci_indication->num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t);
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &uci_indication->uci_list[uci_indication->num_ucis].pucch_pdu_format_0_1; nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &uci_indication->uci_list[uci_indication->num_ucis].pucch_pdu_format_0_1;
nr_decode_pucch0(gNB->common_vars.rxdataF, nr_decode_pucch0(gNB,
&gNB->frame_parms, slot_rx,
slot_rx, uci_pdu_format0,
uci_pdu_format0, pucch_pdu);
pucch_pdu);
uci_indication->num_ucis += 1;
uci_indication->num_ucis += 1; break;
break; case 1:
case 1: break;
break; default:
default: AssertFatal(1==0,"Only PUCCH format 0 and 1 are currently supported\n");
AssertFatal(1==0,"Only PUCCH format 0 and 1 are currently supported\n");
}
break;
} }
} }
} }
...@@ -171,6 +171,7 @@ int main(int argc, char **argv) ...@@ -171,6 +171,7 @@ int main(int argc, char **argv)
//int pbch_tx_ant; //int pbch_tx_ant;
int N_RB_DL=106,mu=1; int N_RB_DL=106,mu=1;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t dlsch_config; nfapi_nr_dl_tti_pdsch_pdu_rel15_t dlsch_config;
NR_sched_pucch pucch_sched;
//unsigned char frame_type = 0; //unsigned char frame_type = 0;
...@@ -706,7 +707,7 @@ int main(int argc, char **argv) ...@@ -706,7 +707,7 @@ int main(int argc, char **argv)
memset(RC.nrmac[0]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int)); memset(RC.nrmac[0]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int));
clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot); clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot,&dlsch_config); if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot,&pucch_sched,&dlsch_config);
else nr_schedule_css_dlsch_phytest(0,frame,slot); else nr_schedule_css_dlsch_phytest(0,frame,slot);
......
...@@ -66,7 +66,7 @@ int main(int argc, char **argv) ...@@ -66,7 +66,7 @@ int main(int argc, char **argv)
double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0; double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0;
double cfo=0; double cfo=0;
uint8_t snr1set=0; uint8_t snr1set=0;
int **txdata; int **txdataF,**rxdataF;
double **s_re,**s_im,**r_re,**r_im; double **s_re,**s_im,**r_re,**r_im;
//int sync_pos, sync_pos_slot; //int sync_pos, sync_pos_slot;
//FILE *rx_frame_file; //FILE *rx_frame_file;
...@@ -93,7 +93,6 @@ int main(int argc, char **argv) ...@@ -93,7 +93,6 @@ int main(int argc, char **argv)
uint8_t nrofSymbols=1; //number of OFDM symbols can be 1-2 for format 1 uint8_t nrofSymbols=1; //number of OFDM symbols can be 1-2 for format 1
uint8_t startingSymbolIndex=0; // resource allocated see 9.2.1, 38.213 for more info.should be actually present in the resource set provided uint8_t startingSymbolIndex=0; // resource allocated see 9.2.1, 38.213 for more info.should be actually present in the resource set provided
uint16_t startingPRB=0,startingPRB_intraSlotHopping=0; //PRB number not sure see 9.2.1, 38.213 for more info. Should be actually present in the resource set provided uint16_t startingPRB=0,startingPRB_intraSlotHopping=0; //PRB number not sure see 9.2.1, 38.213 for more info. Should be actually present in the resource set provided
uint32_t hoppingId=40;
uint8_t timeDomainOCC=0; uint8_t timeDomainOCC=0;
SCM_t channel_model=AWGN;//Rayleigh1_anticorr; SCM_t channel_model=AWGN;//Rayleigh1_anticorr;
...@@ -335,7 +334,7 @@ int main(int argc, char **argv) ...@@ -335,7 +334,7 @@ int main(int argc, char **argv)
RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *)); RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *));
RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB)); RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB));
gNB = RC.gNB[0]; gNB = RC.gNB[0];
memset((void*)gNB,0,sizeof(*gNB));
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
frame_parms->nb_antennas_tx = n_tx; frame_parms->nb_antennas_tx = n_tx;
frame_parms->nb_antennas_rx = n_rx; frame_parms->nb_antennas_rx = n_rx;
...@@ -401,8 +400,10 @@ int main(int argc, char **argv) ...@@ -401,8 +400,10 @@ int main(int argc, char **argv)
s_im = malloc(2*sizeof(double*)); s_im = malloc(2*sizeof(double*));
r_re = malloc(2*sizeof(double*)); r_re = malloc(2*sizeof(double*));
r_im = malloc(2*sizeof(double*)); r_im = malloc(2*sizeof(double*));
txdata = malloc(2*sizeof(int*)); txdataF = malloc(2*sizeof(int*));
rxdataF = malloc(2*sizeof(int*));
gNB->common_vars.rxdataF=rxdataF;
memcpy((void*)&gNB->frame_parms,(void*)frame_parms,sizeof(frame_parms));
for (i=0; i<2; i++) { for (i=0; i<2; i++) {
s_re[i] = malloc(frame_length_complex_samples*sizeof(double)); s_re[i] = malloc(frame_length_complex_samples*sizeof(double));
...@@ -415,17 +416,18 @@ int main(int argc, char **argv) ...@@ -415,17 +416,18 @@ int main(int argc, char **argv)
r_im[i] = malloc(frame_length_complex_samples*sizeof(double)); r_im[i] = malloc(frame_length_complex_samples*sizeof(double));
bzero(r_im[i],frame_length_complex_samples*sizeof(double)); bzero(r_im[i],frame_length_complex_samples*sizeof(double));
printf("Allocating %d samples for txdata\n",frame_length_complex_samples); printf("Allocating %d samples for txdataF/rxdataF\n",14*frame_parms->ofdm_symbol_size);
txdata[i] = malloc(frame_length_complex_samples*sizeof(int)); txdataF[i] = malloc(14*frame_parms->ofdm_symbol_size*sizeof(int));
bzero(r_re[i],frame_length_complex_samples*sizeof(int)); bzero(txdataF[i],14*frame_parms->ofdm_symbol_size*sizeof(int));
rxdataF[i] = malloc(14*frame_parms->ofdm_symbol_size*sizeof(int));
bzero(rxdataF[i],14*frame_parms->ofdm_symbol_size*sizeof(int));
} }
//configure UE //configure UE
UE = malloc(sizeof(PHY_VARS_NR_UE)); UE = malloc(sizeof(PHY_VARS_NR_UE));
memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
UE->pucch_config_common_nr->hoppingId = hoppingId; UE->pucch_config_common_nr->hoppingId = Nid_cell;
//phy_init_nr_top(UE); //called from init_nr_ue_signal //phy_init_nr_top(UE); //called from init_nr_ue_signal
UE->perfect_ce = 0; UE->perfect_ce = 0;
...@@ -454,41 +456,53 @@ int main(int argc, char **argv) ...@@ -454,41 +456,53 @@ int main(int argc, char **argv)
for(SNR=snr0;SNR<=snr1;SNR=SNR+1){ for(SNR=snr0;SNR<=snr1;SNR=SNR+1){
ack_nack_errors=0; ack_nack_errors=0;
n_errors = 0; n_errors = 0;
sigma2_dB = 20*log10((double)amp/32767)-SNR;
sigma2 = pow(10,sigma2_dB/10);
for (trial=0; trial<n_trials; trial++) { for (trial=0; trial<n_trials; trial++) {
bzero(txdata[0],frame_length_complex_samples*sizeof(int)); bzero(txdataF[aa],frame_parms->ofdm_symbol_size*sizeof(int));
if(format==0){ if(format==0){
nr_generate_pucch0(UE,txdata,frame_parms,UE->pucch_config_dedicated,amp,nr_tti_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB); nr_generate_pucch0(UE,txdataF,frame_parms,UE->pucch_config_dedicated,amp,nr_tti_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB);
} }
else{ else{
nr_generate_pucch1(UE,txdata,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,0,nr_bit); nr_generate_pucch1(UE,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,0,nr_bit);
} }
for(i=0; i<frame_length_complex_samples; i++) {
r_re[aa][i]=((double)(((int16_t *)txdata[0])[(i<<1)])/32767 + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); int txlev = signal_energy(&txdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size],
r_im[aa][i]=((double)(((int16_t *)txdata[0])[(i<<1)+1])/32767+ sqrt(sigma2/2)*gaussdouble(0.0,1.0)); frame_parms->ofdm_symbol_size);
r_re[aa][i]=r_re[0][i]/(sqrt(sigma2/2)+1); // printf("txlev %d (%d dB), offset %d\n",txlev,dB_fixed(txlev),startingSymbolIndex*frame_parms->ofdm_symbol_size);
r_im[aa][i]=r_im[0][i]/(sqrt(sigma2/2)+1);
if(r_re[aa][i]<-1) // note : this scaling is for 1 PRB, to be updated for PUCCH 2
r_re[aa][i]=-1; sigma2_dB = 10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12)-SNR;
else if(r_re[aa][i]>1) sigma2 = pow(10,sigma2_dB/10);
r_re[aa][i]=1;
if(r_im[aa][i]<-1) for(i=startingSymbolIndex*frame_parms->ofdm_symbol_size; i<(startingSymbolIndex+1)*frame_parms->ofdm_symbol_size; i++) {
r_im[aa][i]=-1; ((int16_t*)rxdataF[aa])[i<<1] = (int16_t)(100.0*((double)(((int16_t *)txdataF[aa])[(i<<1)]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))/sqrt((double)txlev));
else if(r_im[aa][i]>1) ((int16_t*)rxdataF[aa])[1+(i<<1)]=(int16_t)(100.0*((double)(((int16_t *)txdataF[aa])[(i<<1)+1])+ sqrt(sigma2/2)*gaussdouble(0.0,1.0))/sqrt((double)txlev));
r_im[aa][i]=1;
((int16_t *)txdata[aa])[(i<<1)] = (int16_t)round(r_re[aa][i]*32767);
((int16_t *)txdata[aa])[(i<<1)+1] =(int16_t)round(r_im[aa][i]*32767);
} }
int rxlev = signal_energy(&rxdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size);
// printf("rxlev %d (%d dB), sigma2 %f dB, SNR %f, TX %f\n",rxlev,dB_fixed(rxlev),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12));
if(format==0){ if(format==0){
nr_decode_pucch0(txdata,PUCCH_GroupHopping,n_id,&(payload_received),frame_parms,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,nr_bit); nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu;
nfapi_nr_pucch_pdu_t pucch_pdu;
pucch_pdu.subcarrier_spacing = 1;
pucch_pdu.group_hop_flag = PUCCH_GroupHopping&1;
pucch_pdu.sequence_hop_flag = (PUCCH_GroupHopping>>1)&1;
pucch_pdu.bit_len_harq = nr_bit;
pucch_pdu.sr_flag = 0;
pucch_pdu.nr_of_symbols = nrofSymbols;
pucch_pdu.hopping_id = n_id;
pucch_pdu.initial_cyclic_shift = 0;
pucch_pdu.start_symbol_index = startingSymbolIndex;
pucch_pdu.prb_start = startingPRB;
nr_decode_pucch0(gNB,nr_tti_tx,&uci_pdu,&pucch_pdu);
if(nr_bit==1) if(nr_bit==1)
ack_nack_errors+=(((actual_payload^payload_received)&2)>>1); ack_nack_errors+=(actual_payload^uci_pdu.harq->harq_list[0].harq_value);
else else
ack_nack_errors+=(((actual_payload^payload_received)&2)>>1) + (((actual_payload^payload_received)&4)>>2); ack_nack_errors+=((actual_payload^uci_pdu.harq->harq_list[0].harq_value)+((actual_payload>>1)^uci_pdu.harq->harq_list[1].harq_value));
free(uci_pdu.harq->harq_list);
} }
else{ else{
nr_decode_pucch1(txdata,PUCCH_GroupHopping,n_id,&(payload_received),frame_parms,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
nr_decode_pucch1(rxdataF,PUCCH_GroupHopping,n_id,&(payload_received),frame_parms,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
if(nr_bit==1) if(nr_bit==1)
ack_nack_errors+=((actual_payload^payload_received)&1); ack_nack_errors+=((actual_payload^payload_received)&1);
else else
...@@ -496,8 +510,7 @@ int main(int argc, char **argv) ...@@ -496,8 +510,7 @@ int main(int argc, char **argv)
} }
n_errors=((actual_payload^payload_received)&1)+(((actual_payload^payload_received)&2)>>1)+(((actual_payload^payload_received)&4)>>2)+n_errors; n_errors=((actual_payload^payload_received)&1)+(((actual_payload^payload_received)&2)>>1)+(((actual_payload^payload_received)&4)>>2)+n_errors;
} }
printf("Decoded payload is %ld\n",payload_received); printf("SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,ack_nack_errors);
printf("SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,n_errors);
if((float)ack_nack_errors/(float)(nr_bit*n_trials)<=target_error_rate){ if((float)ack_nack_errors/(float)(nr_bit*n_trials)<=target_error_rate){
printf("PUCCH test OK\n"); printf("PUCCH test OK\n");
break; break;
...@@ -509,13 +522,15 @@ int main(int argc, char **argv) ...@@ -509,13 +522,15 @@ int main(int argc, char **argv)
free(s_im[i]); free(s_im[i]);
free(r_re[i]); free(r_re[i]);
free(r_im[i]); free(r_im[i]);
free(txdata[i]); free(txdataF[i]);
free(rxdataF[i]);
} }
free(s_re); free(s_re);
free(s_im); free(s_im);
free(r_re); free(r_re);
free(r_im); free(r_im);
free(txdata); free(txdataF);
free(rxdataF);
if (output_fd) fclose(output_fd); if (output_fd) fclose(output_fd);
if (input_fd) fclose(input_fd); if (input_fd) fclose(input_fd);
......
...@@ -371,7 +371,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, ...@@ -371,7 +371,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
//printf("gNB_dlsch_ulsch_scheduler frameRX %d slotRX %d frameTX %d slotTX %d\n",frame_rxP,slot_rxP,frame_txP,slot_txP); //printf("gNB_dlsch_ulsch_scheduler frameRX %d slotRX %d frameTX %d slotTX %d\n",frame_rxP,slot_rxP,frame_txP,slot_txP);
protocol_ctxt_t ctxt; protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame_txP, slot_txP,module_idP);
int CC_id; int CC_id;
int UE_id; int UE_id;
uint64_t *dlsch_in_slot_bitmap=NULL; uint64_t *dlsch_in_slot_bitmap=NULL;
...@@ -387,9 +388,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, ...@@ -387,9 +388,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
int num_slots_per_tdd = (nr_slots_per_frame[*scc->ssbSubcarrierSpacing])>>(7-scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); int num_slots_per_tdd = (nr_slots_per_frame[*scc->ssbSubcarrierSpacing])>>(7-scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
//nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = NULL;
start_meas(&RC.nrmac[module_idP]->eNB_scheduler); start_meas(&RC.nrmac[module_idP]->eNB_scheduler);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
...@@ -448,7 +446,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, ...@@ -448,7 +446,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
} //END if (UE_list->active[i]) } //END if (UE_list->active[i])
} //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++) } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++)
*/ */
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES,NOT_A_RNTI, frame_txP, slot_txP,module_idP);
// This schedules MIB // This schedules MIB
if((slot_txP == 0) && (frame_txP & 7) == 0){ if((slot_txP == 0) && (frame_txP & 7) == 0){
......
...@@ -249,10 +249,11 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, ...@@ -249,10 +249,11 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
} }
} }
int configure_fapi_dl_pdu(int Mod_idP, int configure_fapi_dl_pdu(int Mod_idP,
int *CCEIndex, int *CCEIndex,
nfapi_nr_dl_tti_request_body_t *dl_req, nfapi_nr_dl_tti_request_body_t *dl_req,
NR_sched_pucch *pucch_sched, NR_sched_pucch *pucch_sched,
uint8_t *mcsIndex, uint8_t *mcsIndex,
uint16_t *rbSize, uint16_t *rbSize,
uint16_t *rbStart) { uint16_t *rbStart) {
...@@ -557,7 +558,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, ...@@ -557,7 +558,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
TBS_bytes = configure_fapi_dl_pdu(module_idP, TBS_bytes = configure_fapi_dl_pdu(module_idP,
CCEIndices, CCEIndices,
dl_req, dl_req,
pucch_sched, pucch_sched,
dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL,
dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, dlsch_config!=NULL ? &dlsch_config->rbSize : NULL,
dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); dlsch_config!=NULL ? &dlsch_config->rbStart : NULL);
......
...@@ -1468,7 +1468,7 @@ void nr_update_pucch_scheduling(int Mod_idP, ...@@ -1468,7 +1468,7 @@ void nr_update_pucch_scheduling(int Mod_idP,
} }
else { // to be tested else { // to be tested
curr_pucch = UE_list->UE_sched_ctrl[UE_id].sched_pucch; curr_pucch = UE_list->UE_sched_ctrl[UE_id].sched_pucch;
if (curr_pucch->dai_c<11) { // we are scheduling at most 11 harq-ack in the same pucch if (curr_pucch->dai_c<MAX_ACK_BITS) { // we are scheduling at most MAX_UCI_BITS harq-ack in the same pucch
while (i<8 && found == 0) { // look if timing indicator is among allowed values for current pucch while (i<8 && found == 0) { // look if timing indicator is among allowed values for current pucch
if (pdsch_to_harq_feedback[i]==(curr_pucch->ul_slot % slots_per_tdd)-(slotP % slots_per_tdd)) if (pdsch_to_harq_feedback[i]==(curr_pucch->ul_slot % slots_per_tdd)-(slotP % slots_per_tdd))
found = 1; found = 1;
...@@ -1480,7 +1480,7 @@ void nr_update_pucch_scheduling(int Mod_idP, ...@@ -1480,7 +1480,7 @@ void nr_update_pucch_scheduling(int Mod_idP,
sched_pucch->timing_indicator = pdsch_to_harq_feedback[i]; sched_pucch->timing_indicator = pdsch_to_harq_feedback[i];
} }
} }
if (curr_pucch->dai_c==11 || found == 0) { // if current pucch is full or no timing indicator allowed if (curr_pucch->dai_c==MAX_ACK_BITS || found == 0) { // if current pucch is full or no timing indicator allowed
// look for pucch occasions in other UL of mixed slots // look for pucch occasions in other UL of mixed slots
for (k=scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots; k<slots_per_tdd; k++) { // for each possible UL or mixed slot for (k=scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots; k<slots_per_tdd; k++) { // for each possible UL or mixed slot
if (k!=(curr_pucch->ul_slot % slots_per_tdd)) { // skip current scheduled slot (already checked) if (k!=(curr_pucch->ul_slot % slots_per_tdd)) { // skip current scheduled slot (already checked)
...@@ -1514,7 +1514,7 @@ void nr_update_pucch_scheduling(int Mod_idP, ...@@ -1514,7 +1514,7 @@ void nr_update_pucch_scheduling(int Mod_idP,
curr_pucch->next_sched_pucch = sched_pucch; curr_pucch->next_sched_pucch = sched_pucch;
} }
else { else {
if (curr_pucch->dai_c==11) if (curr_pucch->dai_c==MAX_ACK_BITS)
found = 0; // if pucch at index k is already full we have to find a new one in a following occasion found = 0; // if pucch at index k is already full we have to find a new one in a following occasion
else { // scheduling this harq-ack in current pucch else { // scheduling this harq-ack in current pucch
sched_pucch = curr_pucch; sched_pucch = curr_pucch;
......
...@@ -222,7 +222,10 @@ void nr_process_mac_pdu( ...@@ -222,7 +222,10 @@ void nr_process_mac_pdu(
pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
AssertFatal(pdu_len >= 0, "[MAC] nr_process_mac_pdu, residual mac pdu length < 0!\n"); if (pdu_len < 0) {
LOG_E(MAC, "%s() residual mac pdu length < 0!\n", __func__);
return;
}
} }
} }
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#include "PHY/defs_gNB.h" #include "PHY/defs_gNB.h"
#include "NR_TAG-Id.h" #include "NR_TAG-Id.h"
#define MAX_ACK_BITS 2 //only format 0 is available for now
void set_cset_offset(uint16_t); void set_cset_offset(uint16_t);
void mac_top_init_gNB(void); void mac_top_init_gNB(void);
...@@ -80,7 +82,6 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, ...@@ -80,7 +82,6 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
frame_t frameP, frame_t frameP,
sub_frame_t subframeP); sub_frame_t subframeP);
int configure_fapi_dl_pdu(int Mod_id, int configure_fapi_dl_pdu(int Mod_id,
int *CCEIndeces, int *CCEIndeces,
nfapi_nr_dl_tti_request_body_t *dl_req, nfapi_nr_dl_tti_request_body_t *dl_req,
...@@ -89,7 +90,6 @@ int configure_fapi_dl_pdu(int Mod_id, ...@@ -89,7 +90,6 @@ int configure_fapi_dl_pdu(int Mod_id,
uint16_t *rbSize, uint16_t *rbSize,
uint16_t *rbStart); uint16_t *rbStart);
void config_uldci(NR_BWP_Uplink_t *ubwp,nfapi_nr_pusch_pdu_t *pusch_pdu,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types); void config_uldci(NR_BWP_Uplink_t *ubwp,nfapi_nr_pusch_pdu_t *pusch_pdu,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types);
void configure_fapi_dl_Tx(module_id_t Mod_idP, void configure_fapi_dl_Tx(module_id_t Mod_idP,
...@@ -140,13 +140,24 @@ int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space, ...@@ -140,13 +140,24 @@ int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space,
uint16_t slot, uint16_t slot,
nfapi_nr_config_request_scf_t cfg); nfapi_nr_config_request_scf_t cfg);
*/ */
<<<<<<< HEAD
=======
void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
NR_ServingCellConfigCommon_t *scc,
NR_BWP_Uplink_t *bwp,
uint8_t pucch_resource,
uint16_t O_uci,
uint16_t O_ack,
uint8_t SR_flag);
>>>>>>> nr_pucch
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
int ss_type, int ss_type,
NR_ServingCellConfigCommon_t *scc, NR_ServingCellConfigCommon_t *scc,
NR_BWP_Downlink_t *bwp); NR_BWP_Downlink_t *bwp);
<<<<<<< HEAD
void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup, void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
dci_pdu_rel15_t *dci_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15,
...@@ -168,6 +179,12 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, ...@@ -168,6 +179,12 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
uint8_t SR_flag); uint8_t SR_flag);
=======
void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
dci_pdu_rel15_t *dci_pdu_rel15,
int *dci_formats,
int *rnti_types);
>>>>>>> nr_pucch
int get_spf(nfapi_nr_config_request_scf_t *cfg); int get_spf(nfapi_nr_config_request_scf_t *cfg);
int to_absslot(nfapi_nr_config_request_scf_t *cfg,int frame,int slot); int to_absslot(nfapi_nr_config_request_scf_t *cfg,int frame,int slot);
......
...@@ -203,4 +203,5 @@ typedef struct gNB_MAC_INST_s { ...@@ -203,4 +203,5 @@ typedef struct gNB_MAC_INST_s {
int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE]; int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE];
} gNB_MAC_INST; } gNB_MAC_INST;
#endif /*__LAYER2_NR_MAC_GNB_H__ */ #endif /*__LAYER2_NR_MAC_GNB_H__ */
...@@ -329,6 +329,11 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ ...@@ -329,6 +329,11 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
sprintf(filename,"reconfig.raw"); sprintf(filename,"reconfig.raw");
fd = fopen(filename,"r"); fd = fopen(filename,"r");
char buffer[1024]; char buffer[1024];
AssertFatal(fd,
"cannot read file %s: errno %d, %s\n",
filename,
errno,
strerror(errno));
int msg_len=fread(buffer,1,1024,fd); int msg_len=fread(buffer,1,1024,fd);
fclose(fd); fclose(fd);
process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len); process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len);
...@@ -337,6 +342,11 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ ...@@ -337,6 +342,11 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
else else
sprintf(filename,"rbconfig.raw"); sprintf(filename,"rbconfig.raw");
fd = fopen(filename,"r"); fd = fopen(filename,"r");
AssertFatal(fd,
"cannot read file %s: errno %d, %s\n",
filename,
errno,
strerror(errno));
msg_len=fread(buffer,1,1024,fd); msg_len=fread(buffer,1,1024,fd);
fclose(fd); fclose(fd);
process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len); process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len);
......
...@@ -3,6 +3,12 @@ This is an RF simulator that allows to test OAI without an RF board. It replaces ...@@ -3,6 +3,12 @@ This is an RF simulator that allows to test OAI without an RF board. It replaces
As much as possible, it works like an RF board, but not in real-time: It can run faster than real-time if there is enough CPU, or slower (it is CPU-bound instead of real-time RF sampling-bound). As much as possible, it works like an RF board, but not in real-time: It can run faster than real-time if there is enough CPU, or slower (it is CPU-bound instead of real-time RF sampling-bound).
It can be run either in:
- "noS1" mode: the generated IP traffic is sent and received between gNB and UE IP tunnel interfaces ("oaitun") by applications like ping and iperf
- "phy-test" mode: random UL and DL traffic is generated at every scheduling opportunity
# build # build
## From [build_oai](../../../doc/BUILD.md) script ## From [build_oai](../../../doc/BUILD.md) script
...@@ -84,19 +90,40 @@ make rfsimulator ...@@ -84,19 +90,40 @@ make rfsimulator
### Launch gNB in one window ### Launch gNB in one window
```bash ```bash
sudo RFSIMULATOR=server ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD sudo RFSIMULATOR=server ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD --rfsim --phy-test
``` ```
### Launch UE in another window ### Launch UE in another window
```bash ```bash
sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000 sudo RFSIMULATOR=<TARGET_GNB_INTERFACE_ADDRESS> ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path ../../../ci-scripts/rrc-files
``` ```
Note:
1. <TARGET_GNB_INTERFACE_ADDRESS> can be 127.0.0.1 if both gNB and nrUE executables run on the same host, OR the IP interface address of the remote host running the gNB executable, if the gNB and nrUE run on separate hosts
2. the --rrc_config_path parameter can be omitted (but not necessarily) if the gNB and nrUE run on the same host, in which case the gNB provides the nrUE with the necessary rrc configuration
3. to enable the noS1 mode --noS1 and --nokrnmod 1 options should be added to the command line
Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine.
In the UE, you can add `-d` option to get the softscope. In the UE, you can add `-d` option to get the softscope.
### Testing IP traffic (ping and iperf)
```
ping -I oaitun_enb1 10.0.1.2 (from gNB mchine)
ping -I oaitun_ue1 10.0.1.1 (from nrUE mchine)
```
```iperf (Downlink):
Server nrUE machine: iperf -s -i 1 -u -B 10.0.1.2
Client gNB machine: iperf -c 10.0.1.2 -u -b 0.1M --bind 10.0.1.1
```
```iperf (Uplink):
Server gNB machine: iperf -s -i 1 -u -B 10.0.1.1
Client nrUE machine: iperf -c 10.0.1.1 -u -b 0.1M --bind 10.0.1.2
Note: iperf tests can be performed only when running gNB and nrUE on separate hosts.
```
### Store and replay ### Store and replay
You can store emitted I/Q samples. If you set the option `saviq`, the simulator will write all the I/Q samples into this file. Then, you can replay with the executable `replay_node`. You can store emitted I/Q samples. If you set the option `saviq`, the simulator will write all the I/Q samples into this file. Then, you can replay with the executable `replay_node`.
......
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