Commit ef3c6add authored by Ahmed Hussein's avatar Ahmed Hussein Committed by Thomas Schlichter

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
parent 54c96644
...@@ -1282,6 +1282,7 @@ set(PHY_SRC_UE ...@@ -1282,6 +1282,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_tools.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_tools.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_coding.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_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_tbs_tools.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
...@@ -1324,7 +1325,7 @@ set(PHY_SRC_UE ...@@ -1324,7 +1325,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_nr.c ${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/dci_tools_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pucch_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/ul_ref_seq_nr.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c
......
/*
* 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];
}
}
\ No newline at end of file
...@@ -36,6 +36,19 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch); ...@@ -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); 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, uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t UE_id, uint8_t UE_id,
short *ulsch_llr, short *ulsch_llr,
...@@ -47,3 +60,18 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -47,3 +60,18 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t is_crnti, uint8_t is_crnti,
uint8_t llr8_flag); 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);
...@@ -141,15 +141,13 @@ int main(int argc, char **argv) { ...@@ -141,15 +141,13 @@ int main(int argc, char **argv) {
channel_desc_t *gNB2UE; channel_desc_t *gNB2UE;
uint8_t extended_prefix_flag = 0; uint8_t extended_prefix_flag = 0;
//int8_t interf1 = -21, interf2 = -21; //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; SCM_t channel_model = AWGN; //Rayleigh1_anticorr;
uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
//unsigned char frame_type = 0; //unsigned char frame_type = 0;
unsigned char pbch_phase = 0; int frame = 0, subframe = 0;
int frame = 0, subframe = 0, slot = 1;
int frame_length_complex_samples; int frame_length_complex_samples;
NR_DL_FRAME_PARMS *frame_parms; NR_DL_FRAME_PARMS *frame_parms;
uint32_t Nsoft = 0;
double sigma; double sigma;
unsigned char qbits = 8; unsigned char qbits = 8;
int ret; int ret;
...@@ -159,12 +157,6 @@ int main(int argc, char **argv) { ...@@ -159,12 +157,6 @@ int main(int argc, char **argv) {
uint16_t nb_symb_sch = 12; uint16_t nb_symb_sch = 12;
uint16_t nb_rb = 50; uint16_t nb_rb = 50;
uint8_t Imcs = 9; 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(); cpuf = get_cpu_freq_GHz();
...@@ -458,13 +450,8 @@ int main(int argc, char **argv) { ...@@ -458,13 +450,8 @@ int main(int argc, char **argv) {
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); 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;
/////////////////////////////////////////////////// printf("available bits %d TBS %d mod_order %d\n", available_bits, TBS, mod_order);
/////////// setting rel15_ul parameters /////////// /////////// setting rel15_ul parameters ///////////
rel15_ul->number_rbs = nb_rb; rel15_ul->number_rbs = nb_rb;
...@@ -475,26 +462,30 @@ int main(int argc, char **argv) { ...@@ -475,26 +462,30 @@ int main(int argc, char **argv) {
rel15_ul->n_layers = Nl; rel15_ul->n_layers = Nl;
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc 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_fixed = malloc16(sizeof(short) * 16 * 68 * 384);
short *channel_output_uncoded = malloc16(sizeof(unsigned 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; uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
unsigned char *estimated_output_bit; unsigned char *estimated_output_bit;
unsigned char *test_input_bit; unsigned char *test_input_bit;
unsigned int errors_bit = 0; unsigned char *test_input;
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); 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); 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);
for (i = 0; i < TBS / 8; i++) 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 /////////////////////////[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) { ...@@ -504,6 +495,7 @@ int main(int argc, char **argv) {
/////////// ///////////
//////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////[adk] preparing UL harq_process parameters///////////////////////// /////////////////////////[adk] preparing UL harq_process parameters/////////////////////////
/////////// ///////////
NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid]; 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) { ...@@ -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]); for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%d \n",test_input[i]);
#endif #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///////////////////////// /////////////////////////ULSCH coding/////////////////////////
/////////// ///////////
...@@ -546,24 +533,21 @@ int main(int argc, char **argv) { ...@@ -546,24 +533,21 @@ int main(int argc, char **argv) {
/////////// ///////////
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
/////////////////////////ULSCH scrambling///////////////////////// /////////////////////////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++){ 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, nr_pusch_codeword_scrambling(ulsch_ue->g,
encoded_length, available_bits,
Nid_cell, Nid_cell,
ulsch_ue->rnti, ulsch_ue->rnti,
scrambled_output[0]); // assume one codeword for the moment scrambled_output[0]); // assume one codeword for the moment
///////////// /////////////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
...@@ -571,34 +555,25 @@ int main(int argc, char **argv) { ...@@ -571,34 +555,25 @@ int main(int argc, char **argv) {
/////////// ///////////
nr_modulation(scrambled_output[0], // assume one codeword for the moment nr_modulation(scrambled_output[0], // assume one codeword for the moment
encoded_length, available_bits,
mod_order, mod_order,
ulsch_ue->d); 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) { for (SNR = snr0; SNR < snr1; SNR += snr_step) {
n_errors = 0; n_errors = 0;
n_false_positive = 0; n_false_positive = 0;
for (trial = 0; trial < n_trials; trial++) { for (trial = 0; trial < n_trials; trial++) {
errors_bit_uncoded = 0; errors_bit_uncoded = 0;
errors_scrambling = 0;
errors_bit = 0;
scrambling_index = 0;
for (i = 0; i < available_bits; i++) { for (i = 0; i < available_bits; i++) {
...@@ -606,19 +581,24 @@ int main(int argc, char **argv) { ...@@ -606,19 +581,24 @@ int main(int argc, char **argv) {
if ((i&0xf)==0) if ((i&0xf)==0)
printf("\ne %d..%d: ",i,i+15); printf("\ne %d..%d: ",i,i+15);
#endif #endif
/*
if (i<16){
printf("ulsch_encoder output f[%d] = %d\n",i,ulsch_ue->harq_processes[0]->f[i]); ////////////////////////////////////////////
// Modulate bit-wise the scrambled output //
////////////////////////////////////////////
bit_index = i & 0x1f;
if ((bit_index == 0) && (i != 0)) {
scrambling_index++;
} }
*/
if (ulsch_ue->harq_processes[0]->f[i] == 0) if(((scrambled_output[0][scrambling_index] >> bit_index) & 1) == 0)
modulated_input[i] = 1.0; ///sqrt(2); //QPSK modulated_input[i] = 1.0; ///sqrt(2); //QPSK
else else
modulated_input[i] = -1.0; ///sqrt(2); modulated_input[i] = -1.0; ///sqrt(2);
//if (i<16) printf("modulated_input[%d] = %d\n",i,modulated_input[i]); ////////////////////////////////////////////
//SNR =10;
SNR_lin = pow(10, SNR / 10.0); SNR_lin = pow(10, SNR / 10.0);
sigma = 1.0 / sqrt(2 * SNR_lin); sigma = 1.0 / sqrt(2 * SNR_lin);
...@@ -638,35 +618,66 @@ int main(int argc, char **argv) { ...@@ -638,35 +618,66 @@ int main(int argc, char **argv) {
else else
channel_output_uncoded[i] = 0; channel_output_uncoded[i] = 0;
if (channel_output_uncoded[i] != ulsch_ue->harq_processes[harq_pid]->f[i]) if (channel_output_uncoded[i] != ((scrambled_output[0][scrambling_index] >> bit_index) & 1)) {
errors_bit_uncoded = errors_bit_uncoded + 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 #ifdef DEBUG_CODER
printf("\n"); printf("\n");
exit(-1); exit(-1);
#endif #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) if (ret > ulsch_gNB->max_ldpc_iterations)
n_errors++; n_errors++;
//count errors ////////////////////////////////////////////////////////////
errors_bit = 0; ////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
/////////////////////// count errors ///////////////////////
////////////////////////////////////////////////////////////
for (i = 0; i < TBS; i++) { 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); 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]) { if (estimated_output_bit[i] != test_input_bit[i]) {
errors_bit++; errors_bit++;
} }
} }
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
if (errors_bit > 0) { if (errors_bit > 0) {
n_false_positive++; n_false_positive++;
if (n_trials == 1) if (n_trials == 1)
......
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