Added "nr_ulsch_unscrambling" + Tested scrambling and unscrambling chain in "ulsim.c" (works)
- Added "nr_ulsch.c" file in NR_TRANSPORT - Renamed "nr_ulsch.c" in NR_UE_TRANSPORT to "nr_ulsch_ue.c" - Added "nr_ulsch_unscrambling" declaration to "nr_ulsch.h" - Added "nr_ulsch_unscrambling" definition to "nr_ulsch.c" - Added new test in "ulsim.c" to test encoding/decoding + scrambling/unscrambling
This commit is contained in:
committed by
Thomas Schlichter
parent
54c96644ae
commit
ef3c6add13
@@ -1282,6 +1282,7 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_tools.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_coding.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
|
||||
@@ -1324,7 +1325,7 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_tools_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pucch_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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/nr_ulsch.c
|
||||
* \brief Top-level routines for the reception of the PUSCH TS 38.211 v 15.4.0
|
||||
* \author Ahmed Hussein
|
||||
* \date 2019
|
||||
* \version 0.1
|
||||
* \company Fraunhofer IIS
|
||||
* \email: ahmed.hussein@iis.fraunhofer.de
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
||||
|
||||
void nr_ulsch_unscrambling(int16_t* llr,
|
||||
uint32_t size,
|
||||
uint8_t q,
|
||||
uint32_t Nid,
|
||||
uint32_t n_RNTI)
|
||||
{
|
||||
uint8_t reset;
|
||||
uint32_t x1, x2, s=0;
|
||||
|
||||
reset = 1;
|
||||
x2 = (n_RNTI<<15) + Nid;
|
||||
|
||||
for (uint32_t i=0; i<size; i++) {
|
||||
if ((i&0x1f)==0) {
|
||||
s = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
if (((s>>(i&0x1f))&1)==1)
|
||||
llr[i] = -llr[i];
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,19 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
|
||||
|
||||
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag);
|
||||
|
||||
|
||||
/*! \brief Perform PUSCH decoding. TS 38.212 V15.4.0 subclause 6.2
|
||||
@param phy_vars_gNB, Pointer to PHY data structure for gNB
|
||||
@param UE_id, ID of UE transmitting this PUSCH
|
||||
@param ulsch_llr, Pointer to received llr in ulsch
|
||||
@param frame_parms, Pointer to frame descriptor structure
|
||||
@param nb_symb_sch, number of symbols used in the uplink shared channel
|
||||
@param nr_tti_rx, current received TTI
|
||||
@param harq_pid, harq process id
|
||||
@param is_crnti
|
||||
@param llr8_flag If 1, indicate that the 8-bit decoder should be used
|
||||
*/
|
||||
|
||||
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
uint8_t UE_id,
|
||||
short *ulsch_llr,
|
||||
@@ -47,3 +60,18 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
uint8_t is_crnti,
|
||||
uint8_t llr8_flag);
|
||||
|
||||
|
||||
/*! \brief Perform PUSCH unscrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
|
||||
@param llr, Pointer to llr bits
|
||||
@param size, length of llr bits
|
||||
@param q, codeword index (0,1)
|
||||
@param Nid, cell id
|
||||
@param n_RNTI, CRNTI
|
||||
*/
|
||||
|
||||
void nr_ulsch_unscrambling(int16_t* llr,
|
||||
uint32_t size,
|
||||
uint8_t q,
|
||||
uint32_t Nid,
|
||||
uint32_t n_RNTI);
|
||||
|
||||
|
||||
+1
-1
@@ -65,4 +65,4 @@ void nr_pusch_codeword_scrambling(uint8_t *in,
|
||||
//printf("i %d b_idx %d in %d s 0x%08x out 0x%08x\n", i, b_idx, in[i], s, *out);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -141,15 +141,13 @@ int main(int argc, char **argv) {
|
||||
channel_desc_t *gNB2UE;
|
||||
uint8_t extended_prefix_flag = 0;
|
||||
//int8_t interf1 = -21, interf2 = -21;
|
||||
FILE *input_fd = NULL, *pbch_file_fd = NULL;
|
||||
FILE *input_fd = NULL;
|
||||
SCM_t channel_model = AWGN; //Rayleigh1_anticorr;
|
||||
uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
|
||||
//unsigned char frame_type = 0;
|
||||
unsigned char pbch_phase = 0;
|
||||
int frame = 0, subframe = 0, slot = 1;
|
||||
int frame = 0, subframe = 0;
|
||||
int frame_length_complex_samples;
|
||||
NR_DL_FRAME_PARMS *frame_parms;
|
||||
uint32_t Nsoft = 0;
|
||||
double sigma;
|
||||
unsigned char qbits = 8;
|
||||
int ret;
|
||||
@@ -159,12 +157,6 @@ int main(int argc, char **argv) {
|
||||
uint16_t nb_symb_sch = 12;
|
||||
uint16_t nb_rb = 50;
|
||||
uint8_t Imcs = 9;
|
||||
uint16_t n_dmrs;
|
||||
uint8_t dmrs_TypeA_Position;
|
||||
int l0;
|
||||
uint32_t ***pusch_dmrs;
|
||||
|
||||
PUSCH_TimeDomainResourceAllocation_t pusch_time_alloc;
|
||||
|
||||
cpuf = get_cpu_freq_GHz();
|
||||
|
||||
@@ -441,12 +433,12 @@ int main(int argc, char **argv) {
|
||||
uint8_t is_crnti = 0, llr8_flag = 0;
|
||||
unsigned int TBS = 8424;
|
||||
unsigned int available_bits;
|
||||
uint8_t nb_re_dmrs = 6;
|
||||
uint8_t nb_re_dmrs = 6;
|
||||
uint16_t length_dmrs = 1;
|
||||
uint8_t N_PRB_oh;
|
||||
uint8_t N_PRB_oh;
|
||||
uint16_t N_RE_prime;
|
||||
unsigned char mod_order;
|
||||
uint8_t Nl = 1;
|
||||
uint8_t Nl = 1;
|
||||
uint8_t rvidx = 0;
|
||||
uint8_t UE_id = 1;
|
||||
|
||||
@@ -455,17 +447,12 @@ int main(int argc, char **argv) {
|
||||
|
||||
NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0];
|
||||
|
||||
mod_order = nr_get_Qm(Imcs, 1);
|
||||
mod_order = nr_get_Qm(Imcs, 1);
|
||||
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
|
||||
TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl);
|
||||
TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl);
|
||||
|
||||
printf("available bits %d TBS %d mod_order %d\n", available_bits, TBS, mod_order);
|
||||
|
||||
/////////// setting PUSCH_TimeDomainResourceAllocation_t parameters ///////////
|
||||
|
||||
pusch_time_alloc.mappingType = typeA;
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
/////////// setting rel15_ul parameters ///////////
|
||||
rel15_ul->number_rbs = nb_rb;
|
||||
rel15_ul->number_symbols = nb_symb_sch;
|
||||
@@ -475,26 +462,30 @@ int main(int argc, char **argv) {
|
||||
rel15_ul->n_layers = Nl;
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc
|
||||
short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384);
|
||||
short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384);
|
||||
unsigned int errors_bit_uncoded = 0;
|
||||
// unsigned char *estimated_output;
|
||||
|
||||
double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc
|
||||
short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384);
|
||||
short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384);
|
||||
|
||||
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
|
||||
unsigned char *estimated_output_bit;
|
||||
unsigned char *test_input_bit;
|
||||
unsigned int errors_bit = 0;
|
||||
|
||||
test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
|
||||
// estimated_output = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
|
||||
estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
|
||||
|
||||
unsigned char *test_input;
|
||||
test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8);
|
||||
unsigned int errors_bit_uncoded;
|
||||
unsigned int errors_bit;
|
||||
uint8_t bit_index;
|
||||
uint32_t errors_scrambling;
|
||||
uint32_t scrambling_index;
|
||||
|
||||
|
||||
test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8);
|
||||
test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
|
||||
estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
|
||||
|
||||
|
||||
for (i = 0; i < TBS / 8; i++)
|
||||
test_input[i] = (unsigned char) rand();
|
||||
test_input[i] = 1;//(unsigned char) rand();
|
||||
|
||||
// estimated_output = ulsch_gNB->harq_processes[harq_pid]->b;
|
||||
|
||||
/////////////////////////[adk] preparing NR_UE_ULSCH_t parameters///////////////////////// A HOT FIX until creating nfapi_nr_ul_config_ulsch_pdu_rel15_t
|
||||
///////////
|
||||
@@ -504,6 +495,7 @@ int main(int argc, char **argv) {
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////[adk] preparing UL harq_process parameters/////////////////////////
|
||||
///////////
|
||||
NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
|
||||
@@ -530,11 +522,6 @@ int main(int argc, char **argv) {
|
||||
for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%d \n",test_input[i]);
|
||||
#endif
|
||||
|
||||
/*for (int i=0; i<TBS/8; i++)
|
||||
printf("test input[%d]=%d \n",i,test_input[i]);*/
|
||||
|
||||
//printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32));
|
||||
// generate signal
|
||||
|
||||
/////////////////////////ULSCH coding/////////////////////////
|
||||
///////////
|
||||
@@ -546,23 +533,20 @@ int main(int argc, char **argv) {
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////ULSCH scrambling/////////////////////////
|
||||
///////////
|
||||
|
||||
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
|
||||
uint16_t encoded_length;
|
||||
|
||||
encoded_length = harq_process_ul_ue->num_of_mod_symbols*mod_order;
|
||||
|
||||
for (int q=0; q<nb_codewords; q++){
|
||||
memset((void*)scrambled_output[q], 0, (encoded_length>>5)*sizeof(uint32_t));
|
||||
memset(scrambled_output[q], 0, ((available_bits>>5)+1)*sizeof(uint32_t));
|
||||
}
|
||||
|
||||
|
||||
nr_pusch_codeword_scrambling(ulsch_ue->g,
|
||||
encoded_length,
|
||||
available_bits,
|
||||
Nid_cell,
|
||||
ulsch_ue->rnti,
|
||||
scrambled_output[0]); // assume one codeword for the moment
|
||||
|
||||
|
||||
/////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -571,34 +555,25 @@ int main(int argc, char **argv) {
|
||||
///////////
|
||||
|
||||
nr_modulation(scrambled_output[0], // assume one codeword for the moment
|
||||
encoded_length,
|
||||
available_bits,
|
||||
mod_order,
|
||||
ulsch_ue->d);
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////PUSCH DMRS/////////////////////////
|
||||
///////////
|
||||
|
||||
pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
|
||||
dmrs_TypeA_Position = 2; // This parameter is given by dmrs_TypeA_Position which is located in MIB.
|
||||
n_dmrs = nb_re_dmrs<<1;
|
||||
int16_t mod_dmrs[n_dmrs<<1];
|
||||
|
||||
l0 = get_l0(pusch_time_alloc.mappingType, dmrs_TypeA_Position);//config.pdsch_config.dmrs_typeA_position.value);
|
||||
nr_modulation(pusch_dmrs[l0][0], n_dmrs, MOD_QPSK, mod_dmrs); // currently only codeword 0 is modulated
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
|
||||
n_errors = 0;
|
||||
n_false_positive = 0;
|
||||
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
|
||||
|
||||
n_errors = 0;
|
||||
n_false_positive = 0;
|
||||
|
||||
for (trial = 0; trial < n_trials; trial++) {
|
||||
|
||||
errors_bit_uncoded = 0;
|
||||
errors_scrambling = 0;
|
||||
errors_bit = 0;
|
||||
scrambling_index = 0;
|
||||
|
||||
for (i = 0; i < available_bits; i++) {
|
||||
|
||||
@@ -606,22 +581,27 @@ int main(int argc, char **argv) {
|
||||
if ((i&0xf)==0)
|
||||
printf("\ne %d..%d: ",i,i+15);
|
||||
#endif
|
||||
/*
|
||||
if (i<16){
|
||||
printf("ulsch_encoder output f[%d] = %d\n",i,ulsch_ue->harq_processes[0]->f[i]);
|
||||
}
|
||||
*/
|
||||
|
||||
if (ulsch_ue->harq_processes[0]->f[i] == 0)
|
||||
modulated_input[i] = 1.0; ///sqrt(2); //QPSK
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Modulate bit-wise the scrambled output //
|
||||
////////////////////////////////////////////
|
||||
|
||||
bit_index = i & 0x1f;
|
||||
|
||||
if ((bit_index == 0) && (i != 0)) {
|
||||
scrambling_index++;
|
||||
}
|
||||
|
||||
if(((scrambled_output[0][scrambling_index] >> bit_index) & 1) == 0)
|
||||
modulated_input[i] = 1.0; ///sqrt(2); //QPSK
|
||||
else
|
||||
modulated_input[i] = -1.0; ///sqrt(2);
|
||||
|
||||
//if (i<16) printf("modulated_input[%d] = %d\n",i,modulated_input[i]);
|
||||
//SNR =10;
|
||||
modulated_input[i] = -1.0; ///sqrt(2);
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
SNR_lin = pow(10, SNR / 10.0);
|
||||
sigma = 1.0 / sqrt(2 * SNR_lin);
|
||||
sigma = 1.0 / sqrt(2 * SNR_lin);
|
||||
#if 1
|
||||
channel_output_fixed[i] = (short) quantize(sigma / 4.0 / 4.0,
|
||||
modulated_input[i] + sigma * gaussdouble(0.0, 1.0),
|
||||
@@ -634,39 +614,70 @@ int main(int argc, char **argv) {
|
||||
|
||||
//Uncoded BER
|
||||
if (channel_output_fixed[i] < 0)
|
||||
channel_output_uncoded[i] = 1; //QPSK demod
|
||||
channel_output_uncoded[i] = 1; //QPSK demod
|
||||
else
|
||||
channel_output_uncoded[i] = 0;
|
||||
channel_output_uncoded[i] = 0;
|
||||
|
||||
if (channel_output_uncoded[i] != ulsch_ue->harq_processes[harq_pid]->f[i])
|
||||
errors_bit_uncoded = errors_bit_uncoded + 1;
|
||||
if (channel_output_uncoded[i] != ((scrambled_output[0][scrambling_index] >> bit_index) & 1)) {
|
||||
errors_bit_uncoded = errors_bit_uncoded + 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("errors bits uncoded %u\n", errors_bit_uncoded);
|
||||
printf("errors bits uncoded = %u\n", errors_bit_uncoded);
|
||||
|
||||
|
||||
#ifdef DEBUG_CODER
|
||||
printf("\n");
|
||||
exit(-1);
|
||||
#endif
|
||||
|
||||
|
||||
ret = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms,
|
||||
frame, nb_symb_sch, subframe, harq_pid, is_crnti, llr8_flag);
|
||||
////////////////////////////////////////////////////////////
|
||||
//////////////////// ULSCH unscrambling ////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
nr_ulsch_unscrambling(channel_output_fixed, available_bits, 0, Nid_cell, n_rnti);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////// ULSCH decoding //////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
ret = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, frame,
|
||||
nb_symb_sch, subframe, harq_pid, is_crnti, llr8_flag);
|
||||
|
||||
if (ret > ulsch_gNB->max_ldpc_iterations)
|
||||
n_errors++;
|
||||
|
||||
//count errors
|
||||
errors_bit = 0;
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/////////////////////// count errors ///////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
for (i = 0; i < TBS; i++) {
|
||||
|
||||
if(((ulsch_ue->g[i] == 0) && (channel_output_fixed[i] < 0)) || ((ulsch_ue->g[i] == 1) && (channel_output_fixed[i] >= 0))) {
|
||||
errors_scrambling++;
|
||||
}
|
||||
|
||||
estimated_output_bit[i] = (ulsch_gNB->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7);
|
||||
test_input_bit[i] = (test_input[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
|
||||
test_input_bit[i] = (test_input[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
|
||||
|
||||
if (estimated_output_bit[i] != test_input_bit[i]) {
|
||||
errors_bit++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
if (errors_bit > 0) {
|
||||
n_false_positive++;
|
||||
if (n_trials == 1)
|
||||
|
||||
Reference in New Issue
Block a user