testing for pucch format 2, 3-11 bits. Configuration works for 2 PRBs, 1 symbol only. Assertion in gNB RX otherwise.
This commit is contained in:
@@ -1495,6 +1495,7 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/scrambling_luts.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c
|
||||
|
||||
@@ -96,7 +96,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
||||
|
||||
while(gNB->configured == 0) usleep(10000);
|
||||
|
||||
init_dfts();
|
||||
/*
|
||||
LOG_I(PHY,"[gNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d nb_antennas_tx:%u nb_antennas_rx:%u PRACH[rootSequenceIndex:%u prach_Config_enabled:%u configIndex:%u highSpeed:%u zeroCorrelationZoneConfig:%u freqOffset:%u]\n",
|
||||
gNB->Mod_id,
|
||||
@@ -113,6 +112,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
||||
LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id);
|
||||
crcTableInit();
|
||||
init_dfts();
|
||||
init_scrambling_luts();
|
||||
init_pucch2_luts();
|
||||
load_nrLDPClib();
|
||||
// PBCH DMRS gold sequences generation
|
||||
nr_init_pbch_dmrs(gNB);
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
||||
|
||||
#include "PHY/sse_intrin.h"
|
||||
|
||||
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
|
||||
@param PHY_VARS_gNB* gNB structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
|
||||
@@ -49,4 +49,10 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
unsigned char lp,
|
||||
unsigned short nb_pusch_rb,
|
||||
uint8_t dmrs_type);
|
||||
|
||||
void init_scrambling_luts(void);
|
||||
|
||||
extern __m64 byte2m64_re[256];
|
||||
extern __m64 byte2m64_im[256];
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,34 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_TRANSPORT/pucch_rx.c
|
||||
* \brief Top-level routines for decoding the PUCCH physical channel
|
||||
* \author A. Mico Pereperez, Padarthi Naga Prasanth, Francesco Mani, Raymond Knopp
|
||||
* \date 2020
|
||||
* \version 0.2
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#include<stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
@@ -8,10 +39,12 @@
|
||||
|
||||
#include "PHY/impl_defs_nr.h"
|
||||
#include "PHY/defs_nr_common.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
|
||||
@@ -188,7 +221,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
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;
|
||||
re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset;
|
||||
if (re_offset>= frame_parms->ofdm_symbol_size)
|
||||
re_offset-=frame_parms->ofdm_symbol_size;
|
||||
|
||||
@@ -818,3 +851,496 @@ void nr_decode_pucch1( int32_t **rxdataF,
|
||||
}
|
||||
}
|
||||
|
||||
__m256i pucch2_3bit[8*2];
|
||||
__m256i pucch2_4bit[16*2];
|
||||
__m256i pucch2_5bit[32*2];
|
||||
__m256i pucch2_6bit[64*2];
|
||||
__m256i pucch2_7bit[128*2];
|
||||
__m256i pucch2_8bit[256*2];
|
||||
__m256i pucch2_9bit[512*2];
|
||||
__m256i pucch2_10bit[1024*2];
|
||||
__m256i pucch2_11bit[2048*2];
|
||||
|
||||
__m256i *pucch2_lut[9]={pucch2_3bit,
|
||||
pucch2_4bit,
|
||||
pucch2_5bit,
|
||||
pucch2_6bit,
|
||||
pucch2_7bit,
|
||||
pucch2_8bit,
|
||||
pucch2_9bit,
|
||||
pucch2_10bit,
|
||||
pucch2_11bit};
|
||||
|
||||
void init_pucch2_luts() {
|
||||
|
||||
uint32_t out;
|
||||
int8_t bit;
|
||||
|
||||
for (int b=3;b<12;b++) {
|
||||
for (uint16_t i=0;i<(1<<b);i++) {
|
||||
out=encodeSmallBlock(&i,b);
|
||||
if (b==3) printf("in %d, out %x\n",i,out);
|
||||
__m256i *lut_i=&pucch2_lut[b-3][i<<1];
|
||||
__m256i *lut_ip1=&pucch2_lut[b-3][1+(i<<1)];
|
||||
bit = (out&0x1) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,0);
|
||||
bit = (out&0x2) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,0);
|
||||
bit = (out&0x4) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,1);
|
||||
bit = (out&0x8) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,1);
|
||||
bit = (out&0x10) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,2);
|
||||
bit = (out&0x20) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,2);
|
||||
bit = (out&0x40) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,3);
|
||||
bit = (out&0x80) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,3);
|
||||
bit = (out&0x100) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,4);
|
||||
bit = (out&0x200) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,4);
|
||||
bit = (out&0x400) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,5);
|
||||
bit = (out&0x800) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,5);
|
||||
bit = (out&0x1000) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,6);
|
||||
bit = (out&0x2000) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,6);
|
||||
bit = (out&0x4000) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,7);
|
||||
bit = (out&0x8000) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,7);
|
||||
bit = (out&0x10000) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,8);
|
||||
bit = (out&0x20000) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,8);
|
||||
bit = (out&0x40000) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,9);
|
||||
bit = (out&0x80000) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,9);
|
||||
bit = (out&0x100000) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,10);
|
||||
bit = (out&0x200000) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,10);
|
||||
bit = (out&0x400000) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,11);
|
||||
bit = (out&0x800000) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,11);
|
||||
bit = (out&0x1000000) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,12);
|
||||
bit = (out&0x2000000) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,12);
|
||||
bit = (out&0x4000000) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,13);
|
||||
bit = (out&0x8000000) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,13);
|
||||
bit = (out&0x10000000) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,14);
|
||||
bit = (out&0x20000000) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,14);
|
||||
bit = (out&0x40000000) > 0 ? -1 : 1;
|
||||
*lut_i = _mm256_insert_epi16(*lut_i,bit,15);
|
||||
bit = (out&0x80000000) > 0 ? -1 : 1;
|
||||
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
int slot,
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu,
|
||||
nfapi_nr_pucch_pdu_t* pucch_pdu) {
|
||||
|
||||
int32_t **rxdataF = gNB->common_vars.rxdataF;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1);
|
||||
|
||||
AssertFatal(pucch_pdu->nr_of_symbols==1 || pucch_pdu->nr_of_symbols==2,
|
||||
"Illegal number of symbols for PUCCH 2 %d\n",pucch_pdu->nr_of_symbols);
|
||||
|
||||
|
||||
//extract pucch and dmrs first
|
||||
|
||||
int l2;
|
||||
int re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset;
|
||||
if (re_offset>= frame_parms->ofdm_symbol_size)
|
||||
re_offset-=frame_parms->ofdm_symbol_size;
|
||||
|
||||
AssertFatal(pucch_pdu->prb_size*pucch_pdu->nr_of_symbols > 1,"number of PRB*SYMB (%d,%d)< 2",
|
||||
pucch_pdu->prb_size,pucch_pdu->nr_of_symbols);
|
||||
|
||||
int Prx = gNB->gNB_config.carrier_config.num_rx_ant.value;
|
||||
int Prx2 = (Prx==1)?2:Prx;
|
||||
// use 2 for Nb antennas in case of single antenna to allow the following allocations
|
||||
int16_t r_re_ext[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
|
||||
int16_t r_im_ext[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
|
||||
int16_t r_re_ext2[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
|
||||
int16_t r_im_ext2[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
|
||||
int16_t rd_re_ext[Prx2][4*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
|
||||
int16_t rd_im_ext[Prx2][4*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
|
||||
|
||||
int16_t *rp[Prx2];
|
||||
__m64 dmrs_re,dmrs_im;
|
||||
|
||||
for (int aa=0;aa<Prx;aa++) rp[aa] = ((int16_t *)&rxdataF[aa][(l2*frame_parms->ofdm_symbol_size)+re_offset]);
|
||||
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("Decoding pucch2 for %d symbols, %d PRB\n",pucch_pdu->nr_of_symbols,pucch_pdu->prb_size);
|
||||
#endif
|
||||
|
||||
int nc_group_size=1; // 2 PRB
|
||||
int ngroup = pucch_pdu->prb_size/nc_group_size/2;
|
||||
int32_t corr32_re[ngroup][Prx2],corr32_im[ngroup][Prx2];
|
||||
for (int aa=0;aa<Prx;aa++) for (int group=0;group<ngroup;group++) { corr32_re[group][aa]=0; corr32_im[group][aa]=0;}
|
||||
|
||||
if (pucch_pdu->nr_of_symbols == 1) {
|
||||
AssertFatal((pucch_pdu->prb_size&1) == 0,"prb_size %d is not a multiple of 2\n",pucch_pdu->prb_size);
|
||||
// 24 PRBs contains 48x16-bit, so 6x8x16-bit
|
||||
for (int prb=0;prb<pucch_pdu->prb_size;prb+=2) {
|
||||
for (int aa=0;aa<Prx;aa++) {
|
||||
|
||||
r_re_ext[aa][0]=rp[aa][0];
|
||||
r_im_ext[aa][0]=rp[aa][1];
|
||||
rd_re_ext[aa][0]=rp[aa][2];
|
||||
rd_im_ext[aa][0]=rp[aa][3];
|
||||
r_re_ext[aa][1]=rp[aa][4];
|
||||
r_im_ext[aa][1]=rp[aa][5];
|
||||
|
||||
r_re_ext[aa][2]=rp[aa][6];
|
||||
r_im_ext[aa][2]=rp[aa][7];
|
||||
rd_re_ext[aa][1]=rp[aa][8];
|
||||
rd_im_ext[aa][1]=rp[aa][9];
|
||||
r_re_ext[aa][3]=rp[aa][10];
|
||||
r_im_ext[aa][3]=rp[aa][11];
|
||||
|
||||
r_re_ext[aa][4]=rp[aa][12];
|
||||
r_im_ext[aa][4]=rp[aa][13];
|
||||
rd_re_ext[aa][2]=rp[aa][14];
|
||||
rd_im_ext[aa][2]=rp[aa][15];
|
||||
r_re_ext[aa][5]=rp[aa][16];
|
||||
r_im_ext[aa][5]=rp[aa][17];
|
||||
|
||||
r_re_ext[aa][6]=rp[aa][18];
|
||||
r_im_ext[aa][6]=rp[aa][19];
|
||||
rd_re_ext[aa][3]=rp[aa][20];
|
||||
rd_im_ext[aa][3]=rp[aa][21];
|
||||
r_re_ext[aa][7]=rp[aa][22];
|
||||
r_im_ext[aa][7]=rp[aa][23];
|
||||
|
||||
r_re_ext[aa][8]=rp[aa][24];
|
||||
r_im_ext[aa][8]=rp[aa][25];
|
||||
rd_re_ext[aa][4]=rp[aa][26];
|
||||
rd_im_ext[aa][4]=rp[aa][27];
|
||||
r_re_ext[aa][9]=rp[aa][28];
|
||||
r_im_ext[aa][9]=rp[aa][29];
|
||||
|
||||
r_re_ext[aa][10]=rp[aa][30];
|
||||
r_im_ext[aa][10]=rp[aa][31];
|
||||
rd_re_ext[aa][5]=rp[aa][32];
|
||||
rd_im_ext[aa][5]=rp[aa][33];
|
||||
r_re_ext[aa][11]=rp[aa][34];
|
||||
r_im_ext[aa][11]=rp[aa][35];
|
||||
|
||||
r_re_ext[aa][12]=rp[aa][36];
|
||||
r_im_ext[aa][12]=rp[aa][37];
|
||||
rd_re_ext[aa][6]=rp[aa][38];
|
||||
rd_im_ext[aa][6]=rp[aa][39];
|
||||
r_re_ext[aa][13]=rp[aa][40];
|
||||
r_im_ext[aa][13]=rp[aa][41];
|
||||
|
||||
r_re_ext[aa][14]=rp[aa][42];
|
||||
r_im_ext[aa][14]=rp[aa][43];
|
||||
rd_re_ext[aa][7]=rp[aa][44];
|
||||
rd_im_ext[aa][7]=rp[aa][45];
|
||||
r_re_ext[aa][15]=rp[aa][46];
|
||||
r_im_ext[aa][15]=rp[aa][47];
|
||||
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
for (int i=0;i<8;i++) printf("Ant %d PRB %d dmrs[%d] -> (%d,%d)\n",aa,prb+(i>>2),i,rd_re_ext[aa][i],rd_im_ext[aa],i);
|
||||
#endif
|
||||
} // aa
|
||||
} // prb
|
||||
|
||||
|
||||
// first compute DMRS component
|
||||
uint32_t x1, x2, s=0;
|
||||
x2 = (((1<<17)*((14*slot) + (pucch_pdu->start_symbol_index) + 1)*((2*pucch_pdu->dmrs_scrambling_id) + 1)) + (2*pucch_pdu->dmrs_scrambling_id))%(1U<<31); // c_init calculation according to TS38.211 subclause
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("slot %d, start_symbol_index %d, dmrs_scrambling_id %d\n",
|
||||
slot,pucch_pdu->start_symbol_index,pucch_pdu->dmrs_scrambling_id);
|
||||
#endif
|
||||
s = lte_gold_generic(&x1, &x2, 1);
|
||||
|
||||
|
||||
for (int group=0;group<ngroup;group++) {
|
||||
// each group has 8*nc_group_size elements, compute 1 complex correlation with DMRS per group
|
||||
// non-coherent combining across groups
|
||||
dmrs_re = byte2m64_re[((uint8_t*)&s)[(group&1)<<1]];
|
||||
dmrs_im = byte2m64_im[((uint8_t*)&s)[(group&1)<<1]];
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("Group %d: s %x x2 %x ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
|
||||
group,
|
||||
((uint16_t*)&s)[0],x2,
|
||||
((int16_t*)&dmrs_re)[0],((int16_t*)&dmrs_im)[0],
|
||||
((int16_t*)&dmrs_re)[1],((int16_t*)&dmrs_im)[1],
|
||||
((int16_t*)&dmrs_re)[2],((int16_t*)&dmrs_im)[2],
|
||||
((int16_t*)&dmrs_re)[3],((int16_t*)&dmrs_im)[3]);
|
||||
#endif
|
||||
for (int aa=0;aa<Prx;aa++) {
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("Group %d: rd ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
|
||||
group,
|
||||
rd_re_ext[aa][0],rd_im_ext[aa][0],
|
||||
rd_re_ext[aa][1],rd_im_ext[aa][1],
|
||||
rd_re_ext[aa][2],rd_im_ext[aa][2],
|
||||
rd_re_ext[aa][3],rd_im_ext[aa][3]);
|
||||
#endif
|
||||
corr32_re[group][aa]+=(rd_re_ext[aa][0]*((int16_t*)&dmrs_re)[0] + rd_im_ext[aa][0]*((int16_t*)&dmrs_im)[0]);
|
||||
corr32_im[group][aa]+=(-rd_re_ext[aa][0]*((int16_t*)&dmrs_im)[0] + rd_im_ext[aa][0]*((int16_t*)&dmrs_re)[0]);
|
||||
corr32_re[group][aa]+=(rd_re_ext[aa][1]*((int16_t*)&dmrs_re)[1] + rd_im_ext[aa][1]*((int16_t*)&dmrs_im)[1]);
|
||||
corr32_im[group][aa]+=(-rd_re_ext[aa][1]*((int16_t*)&dmrs_im)[1] + rd_im_ext[aa][1]*((int16_t*)&dmrs_re)[1]);
|
||||
corr32_re[group][aa]+=(rd_re_ext[aa][2]*((int16_t*)&dmrs_re)[2] + rd_im_ext[aa][2]*((int16_t*)&dmrs_im)[2]);
|
||||
corr32_im[group][aa]+=(-rd_re_ext[aa][2]*((int16_t*)&dmrs_im)[2] + rd_im_ext[aa][2]*((int16_t*)&dmrs_re)[2]);
|
||||
corr32_re[group][aa]+=(rd_re_ext[aa][3]*((int16_t*)&dmrs_re)[3] + rd_im_ext[aa][3]*((int16_t*)&dmrs_im)[3]);
|
||||
corr32_im[group][aa]+=(-rd_re_ext[aa][3]*((int16_t*)&dmrs_im)[3] + rd_im_ext[aa][3]*((int16_t*)&dmrs_re)[3]);
|
||||
}
|
||||
dmrs_re = byte2m64_re[((uint8_t*)&s)[1+((group&1)<<1)]];
|
||||
dmrs_im = byte2m64_im[((uint8_t*)&s)[1+((group&1)<<1)]];
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("Group %d: s %x ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
|
||||
group,
|
||||
((uint16_t*)&s)[1],
|
||||
((int16_t*)&dmrs_re)[0],((int16_t*)&dmrs_im)[0],
|
||||
((int16_t*)&dmrs_re)[1],((int16_t*)&dmrs_im)[1],
|
||||
((int16_t*)&dmrs_re)[2],((int16_t*)&dmrs_im)[2],
|
||||
((int16_t*)&dmrs_re)[3],((int16_t*)&dmrs_im)[3]);
|
||||
#endif
|
||||
for (int aa=0;aa<Prx;aa++) {
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("Group %d: rd ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
|
||||
group,
|
||||
rd_re_ext[aa][4],rd_im_ext[aa][4],
|
||||
rd_re_ext[aa][5],rd_im_ext[aa][5],
|
||||
rd_re_ext[aa][6],rd_im_ext[aa][6],
|
||||
rd_re_ext[aa][7],rd_im_ext[aa][7]);
|
||||
#endif
|
||||
corr32_re[group][aa]+=(rd_re_ext[aa][4]*((int16_t*)&dmrs_re)[0] + rd_im_ext[aa][4]*((int16_t*)&dmrs_im)[0]);
|
||||
corr32_im[group][aa]+=(-rd_re_ext[aa][4]*((int16_t*)&dmrs_im)[0] + rd_im_ext[aa][4]*((int16_t*)&dmrs_re)[0]);
|
||||
corr32_re[group][aa]+=(rd_re_ext[aa][5]*((int16_t*)&dmrs_re)[1] + rd_im_ext[aa][5]*((int16_t*)&dmrs_im)[1]);
|
||||
corr32_im[group][aa]+=(-rd_re_ext[aa][5]*((int16_t*)&dmrs_im)[1] + rd_im_ext[aa][5]*((int16_t*)&dmrs_re)[1]);
|
||||
corr32_re[group][aa]+=(rd_re_ext[aa][6]*((int16_t*)&dmrs_re)[2] + rd_im_ext[aa][6]*((int16_t*)&dmrs_im)[2]);
|
||||
corr32_im[group][aa]+=(-rd_re_ext[aa][6]*((int16_t*)&dmrs_im)[2] + rd_im_ext[aa][6]*((int16_t*)&dmrs_re)[2]);
|
||||
corr32_re[group][aa]+=(rd_re_ext[aa][7]*((int16_t*)&dmrs_re)[3] + rd_im_ext[aa][7]*((int16_t*)&dmrs_im)[3]);
|
||||
corr32_im[group][aa]+=(-rd_re_ext[aa][7]*((int16_t*)&dmrs_im)[3] + rd_im_ext[aa][7]*((int16_t*)&dmrs_re)[3]);
|
||||
corr32_re[group][aa]>>=5;
|
||||
corr32_im[group][aa]>>=5;
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("Group %d: corr32 (%d,%d)\n",group,corr32_re[group][aa],corr32_im[group][aa]);
|
||||
#endif
|
||||
} //aa
|
||||
|
||||
if ((group&3) == 3) s = lte_gold_generic(&x1, &x2, 0);
|
||||
} // group
|
||||
}
|
||||
else { // 2 symbol case
|
||||
AssertFatal(1==0, "Fill in 2 symbol PUCCH2 case\n");
|
||||
}
|
||||
|
||||
uint32_t x1, x2, s=0;
|
||||
// unscrambling
|
||||
x2 = ((pucch_pdu->rnti)<<15)+pucch_pdu->data_scrambling_id;
|
||||
s = lte_gold_generic(&x1, &x2, 1);
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("x2 %x, s %x\n",x2,s);
|
||||
#endif
|
||||
__m64 c_re0,c_im0,c_re1,c_im1,c_re2,c_im2,c_re3,c_im3;
|
||||
re_offset=0;
|
||||
for (int prb=0;prb<pucch_pdu->prb_size;prb+=2,re_offset+=16) {
|
||||
c_re0 = byte2m64_re[((uint8_t*)&s)[0]];
|
||||
c_im0 = byte2m64_im[((uint8_t*)&s)[0]];
|
||||
c_re1 = byte2m64_re[((uint8_t*)&s)[1]];
|
||||
c_im1 = byte2m64_im[((uint8_t*)&s)[1]];
|
||||
c_re2 = byte2m64_re[((uint8_t*)&s)[2]];
|
||||
c_im2 = byte2m64_im[((uint8_t*)&s)[2]];
|
||||
c_re3 = byte2m64_re[((uint8_t*)&s)[3]];
|
||||
c_im3 = byte2m64_im[((uint8_t*)&s)[3]];
|
||||
|
||||
for (int aa=0;aa<Prx;aa++) {
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("prb %d: rd ((%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
|
||||
prb,
|
||||
r_re_ext[aa][re_offset],r_im_ext[aa][re_offset],
|
||||
r_re_ext[aa][re_offset+1],r_im_ext[aa][re_offset+1],
|
||||
r_re_ext[aa][re_offset+2],r_im_ext[aa][re_offset+2],
|
||||
r_re_ext[aa][re_offset+3],r_im_ext[aa][re_offset+3],
|
||||
r_re_ext[aa][re_offset+4],r_im_ext[aa][re_offset+4],
|
||||
r_re_ext[aa][re_offset+5],r_im_ext[aa][re_offset+5],
|
||||
r_re_ext[aa][re_offset+6],r_im_ext[aa][re_offset+6],
|
||||
r_re_ext[aa][re_offset+7],r_im_ext[aa][re_offset+7]);
|
||||
printf("prb %d: c ((%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
|
||||
prb,
|
||||
((int16_t*)&c_re0)[0],((int16_t*)&c_im0)[0],
|
||||
((int16_t*)&c_re0)[1],((int16_t*)&c_im0)[1],
|
||||
((int16_t*)&c_re0)[2],((int16_t*)&c_im0)[2],
|
||||
((int16_t*)&c_re0)[3],((int16_t*)&c_im0)[3],
|
||||
((int16_t*)&c_re1)[0],((int16_t*)&c_im1)[0],
|
||||
((int16_t*)&c_re1)[1],((int16_t*)&c_im1)[1],
|
||||
((int16_t*)&c_re1)[2],((int16_t*)&c_im1)[2],
|
||||
((int16_t*)&c_re1)[3],((int16_t*)&c_im1)[3]
|
||||
);
|
||||
printf("prb %d: rd ((%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
|
||||
prb+1,
|
||||
r_re_ext[aa][re_offset+8],r_im_ext[aa][re_offset+8],
|
||||
r_re_ext[aa][re_offset+9],r_im_ext[aa][re_offset+9],
|
||||
r_re_ext[aa][re_offset+10],r_im_ext[aa][re_offset+10],
|
||||
r_re_ext[aa][re_offset+11],r_im_ext[aa][re_offset+11],
|
||||
r_re_ext[aa][re_offset+12],r_im_ext[aa][re_offset+12],
|
||||
r_re_ext[aa][re_offset+13],r_im_ext[aa][re_offset+13],
|
||||
r_re_ext[aa][re_offset+14],r_im_ext[aa][re_offset+14],
|
||||
r_re_ext[aa][re_offset+15],r_im_ext[aa][re_offset+15]);
|
||||
printf("prb %d: c ((%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
|
||||
prb+1,
|
||||
((int16_t*)&c_re2)[0],((int16_t*)&c_im2)[0],
|
||||
((int16_t*)&c_re2)[1],((int16_t*)&c_im2)[1],
|
||||
((int16_t*)&c_re2)[2],((int16_t*)&c_im2)[2],
|
||||
((int16_t*)&c_re2)[3],((int16_t*)&c_im2)[3],
|
||||
((int16_t*)&c_re3)[0],((int16_t*)&c_im3)[0],
|
||||
((int16_t*)&c_re3)[1],((int16_t*)&c_im3)[1],
|
||||
((int16_t*)&c_re3)[2],((int16_t*)&c_im3)[2],
|
||||
((int16_t*)&c_re3)[3],((int16_t*)&c_im3)[3]
|
||||
);
|
||||
#endif
|
||||
|
||||
((__m64*)&r_re_ext2[aa][re_offset])[0] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[0],c_im0);
|
||||
((__m64*)&r_re_ext[aa][re_offset])[0] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[0],c_re0);
|
||||
((__m64*)&r_im_ext2[aa][re_offset])[0] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[0],c_re0);
|
||||
((__m64*)&r_im_ext[aa][re_offset])[0] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[0],c_im0);
|
||||
|
||||
((__m64*)&r_re_ext2[aa][re_offset])[1] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[1],c_im1);
|
||||
((__m64*)&r_re_ext[aa][re_offset])[1] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[1],c_re1);
|
||||
((__m64*)&r_im_ext2[aa][re_offset])[1] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[1],c_re1);
|
||||
((__m64*)&r_im_ext[aa][re_offset])[1] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[1],c_im1);
|
||||
|
||||
((__m64*)&r_re_ext2[aa][re_offset])[2] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[2],c_im2);
|
||||
((__m64*)&r_re_ext[aa][re_offset])[2] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[2],c_re2);
|
||||
((__m64*)&r_im_ext2[aa][re_offset])[2] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[2],c_re2);
|
||||
((__m64*)&r_im_ext[aa][re_offset])[2] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[2],c_im2);
|
||||
|
||||
((__m64*)&r_re_ext2[aa][re_offset])[3] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[3],c_im3);
|
||||
((__m64*)&r_re_ext[aa][re_offset])[3] = _mm_mullo_pi16(((__m64*)&r_re_ext[aa][re_offset])[3],c_re3);
|
||||
((__m64*)&r_im_ext2[aa][re_offset])[3] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[3],c_re3);
|
||||
((__m64*)&r_im_ext[aa][re_offset])[3] = _mm_mullo_pi16(((__m64*)&r_im_ext[aa][re_offset])[3],c_im3);
|
||||
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("prb %d: r ((%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
|
||||
prb,
|
||||
r_re_ext[aa][re_offset],r_im_ext[aa][re_offset],
|
||||
r_re_ext[aa][re_offset+1],r_im_ext[aa][re_offset+1],
|
||||
r_re_ext[aa][re_offset+2],r_im_ext[aa][re_offset+2],
|
||||
r_re_ext[aa][re_offset+3],r_im_ext[aa][re_offset+3],
|
||||
r_re_ext[aa][re_offset+4],r_im_ext[aa][re_offset+4],
|
||||
r_re_ext[aa][re_offset+5],r_im_ext[aa][re_offset+5],
|
||||
r_re_ext[aa][re_offset+6],r_im_ext[aa][re_offset+6],
|
||||
r_re_ext[aa][re_offset+7],r_im_ext[aa][re_offset+7]);
|
||||
printf("prb %d: r ((%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
|
||||
prb+1,
|
||||
r_re_ext[aa][re_offset+8],r_im_ext[aa][re_offset+8],
|
||||
r_re_ext[aa][re_offset+9],r_im_ext[aa][re_offset+9],
|
||||
r_re_ext[aa][re_offset+10],r_im_ext[aa][re_offset+10],
|
||||
r_re_ext[aa][re_offset+11],r_im_ext[aa][re_offset+11],
|
||||
r_re_ext[aa][re_offset+12],r_im_ext[aa][re_offset+12],
|
||||
r_re_ext[aa][re_offset+13],r_im_ext[aa][re_offset+13],
|
||||
r_re_ext[aa][re_offset+14],r_im_ext[aa][re_offset+14],
|
||||
r_re_ext[aa][re_offset+15],r_im_ext[aa][re_offset+15]);
|
||||
#endif
|
||||
}
|
||||
s = lte_gold_generic(&x1, &x2, 0);
|
||||
}
|
||||
AssertFatal(pucch_pdu->bit_len_csi_part1 + pucch_pdu->bit_len_csi_part2 == 0,"no csi for now\n");
|
||||
AssertFatal((pucch_pdu->bit_len_harq+pucch_pdu->sr_flag > 2 ) && (pucch_pdu->bit_len_harq+pucch_pdu->sr_flag < 12),"illegal length (%d,%d)\n",pucch_pdu->bit_len_harq,pucch_pdu->sr_flag);
|
||||
int nb_bit = pucch_pdu->bit_len_harq+pucch_pdu->sr_flag;
|
||||
__m256i *rp_re[Prx2];
|
||||
__m256i *rp2_re[Prx2];
|
||||
__m256i *rp_im[Prx2];
|
||||
__m256i *rp2_im[Prx2];
|
||||
for (int aa=0;aa<Prx;aa++) {
|
||||
rp_re[aa] = (__m256i*)r_re_ext[aa];
|
||||
rp_im[aa] = (__m256i*)r_im_ext[aa];
|
||||
rp2_re[aa] = (__m256i*)r_re_ext2[aa];
|
||||
rp2_im[aa] = (__m256i*)r_im_ext2[aa];
|
||||
}
|
||||
__m256i prod_re[Prx2],prod_im[Prx2];
|
||||
int64_t corr=0;
|
||||
int cw_ML=0;
|
||||
|
||||
for (int cw=0;cw<1<<nb_bit;cw++) {
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("cw %d:",cw);
|
||||
for (int i=0;i<32;i+=2) {
|
||||
printf("%d,%d,",
|
||||
((int16_t*)&pucch2_lut[nb_bit-3][cw<<1])[i>>1],
|
||||
((int16_t*)&pucch2_lut[nb_bit-3][cw<<1])[1+(i>>1)]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
// do complex correlation
|
||||
for (int aa=0;aa<Prx;aa++) {
|
||||
prod_re[aa] = _mm256_srai_epi16(_mm256_adds_epi16(_mm256_mullo_epi16(pucch2_lut[nb_bit-3][cw<<1],rp_re[aa][0]),
|
||||
_mm256_mullo_epi16(pucch2_lut[nb_bit-3][(cw<<1)+1],rp_im[aa][0])),5);
|
||||
prod_im[aa] = _mm256_srai_epi16(_mm256_subs_epi16(_mm256_mullo_epi16(pucch2_lut[nb_bit-3][cw<<1],rp2_im[aa][0]),
|
||||
_mm256_mullo_epi16(pucch2_lut[nb_bit-3][(cw<<1)+1],rp2_re[aa][0])),5);
|
||||
prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1
|
||||
prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
|
||||
prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3
|
||||
prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
|
||||
prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7
|
||||
prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
|
||||
prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15
|
||||
prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
|
||||
}
|
||||
int64_t corr_re=0,corr_im=0;
|
||||
|
||||
for (int aa=0;aa<Prx;aa++) {
|
||||
LOG_D(PHY,"pucch2 cw %d aa %d: (%d,%d)+(%d,%d) = (%d,%d)\n",cw,aa,
|
||||
corr32_re[0][aa],corr32_im[0][aa],
|
||||
((int16_t*)(&prod_re[aa]))[0],
|
||||
((int16_t*)(&prod_im[aa]))[0],
|
||||
corr32_re[0][aa]+((int16_t*)(&prod_re[0]))[0],
|
||||
corr32_im[0][aa]+((int16_t*)(&prod_im[0]))[0]);
|
||||
|
||||
corr_re += ( corr32_re[0][aa]+((int16_t*)(&prod_re[0]))[0]);
|
||||
corr_im += ( corr32_im[0][aa]+((int16_t*)(&prod_im[0]))[0]);
|
||||
|
||||
}
|
||||
int64_t corr_tmp = corr_re*corr_re + corr_im*corr_im;
|
||||
if (corr_tmp > corr) {
|
||||
corr = corr_tmp;
|
||||
cw_ML=cw;
|
||||
}
|
||||
}
|
||||
uint8_t corr_dB = dB_fixed64((uint64_t)corr);
|
||||
LOG_D(PHY,"cw_ML %d, metric %d dB\n",cw_ML,corr_dB);
|
||||
uci_pdu->harq.harq_bit_len = pucch_pdu->bit_len_harq;
|
||||
|
||||
|
||||
int harq_bytes=pucch_pdu->bit_len_harq>>3;
|
||||
if ((pucch_pdu->bit_len_harq&7) > 0) harq_bytes++;
|
||||
uci_pdu->harq.harq_payload = (nfapi_nr_harq_t*)malloc(harq_bytes);
|
||||
uci_pdu->harq.harq_crc = 2;
|
||||
for (int i=0;i<harq_bytes;i++) {
|
||||
uci_pdu->harq.harq_payload[i] = cw_ML & 255;
|
||||
cw_ML>>=8;
|
||||
}
|
||||
|
||||
if (pucch_pdu->sr_flag == 1) {
|
||||
uci_pdu->sr.sr_bit_len = 1;
|
||||
uci_pdu->sr.sr_payload = malloc(1);
|
||||
uci_pdu->sr.sr_payload[0] = cw_ML;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
|
||||
#include "T.h"
|
||||
//#define NR_UNIT_TEST 1
|
||||
#ifdef NR_UNIT_TEST
|
||||
#define DEBUG_PUCCH_TX
|
||||
#define DEBUG_NR_PUCCH_TX
|
||||
@@ -905,7 +906,9 @@ void nr_uci_encoding(uint64_t payload,
|
||||
if (A<=11) {
|
||||
// procedure in subclause 6.3.1.2.2 (UCI encoded by channel coding of small block lengths -> subclause 6.3.1.3.2)
|
||||
// CRC bits are not attached, and coding small block lengths (subclause 5.3.3)
|
||||
b[0] = encodeSmallBlock((uint16_t*)&payload,A);
|
||||
} else if (A>=12) {
|
||||
AssertFatal(1==0,"Polar encoding not supported yet for UCI\n");
|
||||
// procedure in subclause 6.3.1.2.1 (UCI encoded by Polar code -> subclause 6.3.1.3.1)
|
||||
/*if ((A>=360 && E>=1088)||(A>=1013)) {
|
||||
I_seg = 1;
|
||||
@@ -924,10 +927,13 @@ void nr_uci_encoding(uint64_t payload,
|
||||
// code block segmentation and CRC attachment is performed according to subclause 5.2.1
|
||||
// polar coding subclause 5.3.1
|
||||
}
|
||||
|
||||
}
|
||||
//#if 0
|
||||
void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
|
||||
uint16_t crnti,
|
||||
uint32_t dmrs_scrambling_id,
|
||||
uint32_t data_scrambling_id,
|
||||
int32_t **txdataF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
|
||||
@@ -961,14 +967,14 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
|
||||
*/
|
||||
uint8_t *btilde = malloc(sizeof(int8_t)*M_bit);
|
||||
// rnti is given by the C-RNTI
|
||||
uint16_t rnti=crnti, n_id=0;
|
||||
uint16_t rnti=crnti;
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t [nr_generate_pucch2] rnti = %d ,\n",rnti);
|
||||
#endif
|
||||
/*
|
||||
* Implementing TS 38.211 Subclause 6.3.2.5.1 scrambling format 2
|
||||
*/
|
||||
nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,b,btilde);
|
||||
nr_pucch2_3_4_scrambling(M_bit,rnti,data_scrambling_id,b,btilde);
|
||||
/*
|
||||
* Implementing TS 38.211 Subclause 6.3.2.5.2 modulation format 2
|
||||
* btilde shall be modulated as described in subclause 5.1 using QPSK
|
||||
@@ -1016,10 +1022,10 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
|
||||
int m=0;
|
||||
|
||||
for (int l=0; l<nrofSymbols; l++) {
|
||||
x2 = (((1<<17)*((14*nr_tti_tx) + (l+startingSymbolIndex) + 1)*((2*n_id) + 1)) + (2*n_id))%(1U<<31); // c_init calculation according to TS38.211 subclause
|
||||
x2 = (((1<<17)*((14*nr_tti_tx) + (l+startingSymbolIndex) + 1)*((2*dmrs_scrambling_id) + 1)) + (2*dmrs_scrambling_id))%(1U<<31); // c_init calculation according to TS38.211 subclause
|
||||
|
||||
s = lte_gold_generic(&x1, &x2, 1);
|
||||
m = 0;
|
||||
|
||||
for (int rb=0; rb<nrofPRB; rb++) {
|
||||
//startingPRB = startingPRB + rb;
|
||||
if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_UE_TRANSPORT/pucch_nr.c
|
||||
* \brief Top-level routines for generating and decoding the PUCCH physical channel
|
||||
* \brief Top-level routines for generating the PUCCH physical channel
|
||||
* \author A. Mico Pereperez
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
@@ -70,6 +70,8 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
|
||||
uint8_t nr_bit);
|
||||
void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
|
||||
uint16_t crnti,
|
||||
uint32_t dmrs_scrambling_id,
|
||||
uint32_t data_scrambling_id,
|
||||
int32_t **txdataF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
|
||||
|
||||
@@ -93,11 +93,12 @@ int main(int argc, char **argv)
|
||||
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
|
||||
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 nrofPRB=2;
|
||||
uint8_t timeDomainOCC=0;
|
||||
SCM_t channel_model=AWGN;//Rayleigh1_anticorr;
|
||||
|
||||
int N_RB_DL=273,mu=1;
|
||||
float target_error_rate=0.01;
|
||||
float target_error_rate=0.001;
|
||||
int frame_length_complex_samples;
|
||||
//int frame_length_complex_samples_no_prefix;
|
||||
NR_DL_FRAME_PARMS *frame_parms;
|
||||
@@ -112,9 +113,8 @@ int main(int argc, char **argv)
|
||||
|
||||
randominit(0);
|
||||
logInit();
|
||||
set_glog(loglvl);
|
||||
|
||||
while ((c = getopt (argc, argv, "f:hA:f:g:i:I:P:B:b:T:m:n:r:o:s:S:x:y:z:N:F:GR:IL")) != -1) {
|
||||
while ((c = getopt (argc, argv, "f:hA:f:g:i:I:P:B:b:T:m:n:r:o:s:S:x:y:z:N:F:GR:IL:q:")) != -1) {
|
||||
switch (c) {
|
||||
case 'f':
|
||||
//write_output_file=1;
|
||||
@@ -263,6 +263,9 @@ int main(int argc, char **argv)
|
||||
case 'r':
|
||||
startingPRB=atoi(optarg);
|
||||
break;
|
||||
case 'q':
|
||||
nrofPRB=atoi(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
format=atoi(optarg);
|
||||
break;
|
||||
@@ -305,7 +308,8 @@ int main(int argc, char **argv)
|
||||
printf("-F Input filename (.txt format) for RX conformance testing\n");
|
||||
printf("-i Enter number of ofdm symbols for pucch\n");
|
||||
printf("-I Starting symbol index for pucch\n");
|
||||
printf("-r PUCCCH starting PRB\n");
|
||||
printf("-r PUCCH starting PRB\n");
|
||||
printf("-q PUCCH number of PRB\n");
|
||||
printf("-P Enter the format of PUCCH\n");
|
||||
printf("-b number of HARQ bits (1-2)\n");
|
||||
printf("-B payload to be transmitted on PUCCH\n");
|
||||
@@ -316,18 +320,22 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
set_glog(loglvl);
|
||||
|
||||
if (snr1set==0) snr1 = snr0+10;
|
||||
|
||||
printf("Initializing gNodeB for mu %d, N_RB_DL %d\n",mu,N_RB_DL);
|
||||
|
||||
if((format!=0) && (format!=1)){
|
||||
if((format!=0) && (format!=1) && (format!=2)){
|
||||
printf("PUCCH format %d not supported\n",format);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
AssertFatal((nr_bit<3)&&(actual_payload<4),"Only format 0 and 1 currently supported. 2 bits max supported");
|
||||
AssertFatal(((format < 2)&&(nr_bit<3)&&(actual_payload<4)) ||
|
||||
((format == 2)&&(nr_bit>2)&&(nr_bit<12)),"illegal combination format %d, nr_bit %d\n",
|
||||
format,nr_bit);
|
||||
|
||||
if (nr_bit==1) actual_payload = actual_payload&1;
|
||||
actual_payload &= ((1<<nr_bit)-1);
|
||||
|
||||
printf("Transmitted payload is %ld\n",actual_payload);
|
||||
|
||||
@@ -417,9 +425,9 @@ int main(int argc, char **argv)
|
||||
bzero(r_im[i],frame_length_complex_samples*sizeof(double));
|
||||
|
||||
printf("Allocating %d samples for txdataF/rxdataF\n",14*frame_parms->ofdm_symbol_size);
|
||||
txdataF[i] = malloc(14*frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
txdataF[i] = memalign(32,14*frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
bzero(txdataF[i],14*frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
rxdataF[i] = malloc(14*frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
rxdataF[i] = memalign(32,14*frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
bzero(rxdataF[i],14*frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
}
|
||||
|
||||
@@ -443,8 +451,8 @@ int main(int argc, char **argv)
|
||||
uint8_t mcs=0;
|
||||
startingPRB_intraSlotHopping=N_RB_DL-1;
|
||||
pucch_GroupHopping_t PUCCH_GroupHopping=UE->pucch_config_common_nr->pucch_GroupHopping;
|
||||
uint32_t n_id=UE->pucch_config_common_nr->hoppingId;
|
||||
|
||||
uint32_t hopping_id=UE->pucch_config_common_nr->hoppingId;
|
||||
uint32_t dmrs_scrambling_id = 0, data_scrambling_id=0;
|
||||
if(format==0){
|
||||
// for now we are not considering SR just HARQ-ACK
|
||||
if(nr_bit==1)
|
||||
@@ -461,9 +469,12 @@ int main(int argc, char **argv)
|
||||
if(format==0){
|
||||
nr_generate_pucch0(UE,txdataF,frame_parms,UE->pucch_config_dedicated,amp,nr_tti_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB);
|
||||
}
|
||||
else{
|
||||
else if (format == 1){
|
||||
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);
|
||||
}
|
||||
else {
|
||||
nr_generate_pucch2(UE,0x1234,dmrs_scrambling_id,data_scrambling_id,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_tti_tx,nrofSymbols,startingSymbolIndex,nrofPRB,startingPRB,nr_bit);
|
||||
}
|
||||
|
||||
int txlev = signal_energy(&txdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size],
|
||||
frame_parms->ofdm_symbol_size);
|
||||
@@ -489,7 +500,7 @@ int main(int argc, char **argv)
|
||||
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.hopping_id = hopping_id;
|
||||
pucch_pdu.initial_cyclic_shift = 0;
|
||||
pucch_pdu.start_symbol_index = startingSymbolIndex;
|
||||
pucch_pdu.prb_start = startingPRB;
|
||||
@@ -497,21 +508,49 @@ int main(int argc, char **argv)
|
||||
if(nr_bit==1)
|
||||
ack_nack_errors+=(actual_payload^uci_pdu.harq->harq_list[0].harq_value);
|
||||
else
|
||||
ack_nack_errors+=((actual_payload^uci_pdu.harq->harq_list[0].harq_value)+((actual_payload>>1)^uci_pdu.harq->harq_list[1].harq_value));
|
||||
ack_nack_errors+=(((actual_payload&1)^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 if (format==1) {
|
||||
|
||||
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);
|
||||
nr_decode_pucch1(rxdataF,PUCCH_GroupHopping,hopping_id,&(payload_received),frame_parms,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
|
||||
if(nr_bit==1)
|
||||
ack_nack_errors+=((actual_payload^payload_received)&1);
|
||||
else
|
||||
ack_nack_errors+=((actual_payload^payload_received)&1) + (((actual_payload^payload_received)&2)>>1);
|
||||
}
|
||||
else if (format==2) {
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t uci_pdu;
|
||||
nfapi_nr_pucch_pdu_t pucch_pdu;
|
||||
pucch_pdu.rnti = 0x1234;
|
||||
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 = hopping_id;
|
||||
pucch_pdu.initial_cyclic_shift = 0;
|
||||
pucch_pdu.start_symbol_index = startingSymbolIndex;
|
||||
pucch_pdu.prb_size = nrofPRB;
|
||||
pucch_pdu.prb_start = startingPRB;
|
||||
pucch_pdu.dmrs_scrambling_id = dmrs_scrambling_id;
|
||||
pucch_pdu.data_scrambling_id = data_scrambling_id;
|
||||
nr_decode_pucch2(gNB,nr_tti_tx,&uci_pdu,&pucch_pdu);
|
||||
int harq_bytes=pucch_pdu.bit_len_harq>>3;
|
||||
if ((pucch_pdu.bit_len_harq&7) > 0) harq_bytes++;
|
||||
for (int i=0;i<harq_bytes;i++)
|
||||
if (uci_pdu.harq.harq_payload[i] != ((int8_t*)&actual_payload)[i]) {
|
||||
ack_nack_errors++;
|
||||
break;
|
||||
}
|
||||
free(uci_pdu.harq.harq_payload);
|
||||
|
||||
}
|
||||
n_errors=((actual_payload^payload_received)&1)+(((actual_payload^payload_received)&2)>>1)+(((actual_payload^payload_received)&4)>>2)+n_errors;
|
||||
}
|
||||
printf("SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,ack_nack_errors);
|
||||
if((float)ack_nack_errors/(float)(nr_bit*n_trials)<=target_error_rate){
|
||||
if((float)ack_nack_errors/(float)(n_trials)<=target_error_rate){
|
||||
printf("PUCCH test OK\n");
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user