Commit f35bf889 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 ca886866
......@@ -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
......
/*
* 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);
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);
......@@ -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);
}
}
\ No newline at end of file
}
......@@ -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,16 +447,11 @@ 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);
printf("available bits %d TBS %d mod_order %d\n", available_bits, TBS, mod_order);
TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl);
/////////// 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 ///////////
rel15_ul->number_rbs = nb_rb;
......@@ -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;
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_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);
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
////////////////////////////////////////////////////////////
//////////////////// ULSCH unscrambling ////////////////////
////////////////////////////////////////////////////////////
nr_ulsch_unscrambling(channel_output_fixed, available_bits, 0, Nid_cell, n_rnti);
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
ret = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms,
frame, nb_symb_sch, subframe, harq_pid, is_crnti, llr8_flag);
////////////////////////////////////////////////////////////
////////////////////// 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)
......
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