From 830bf07933a21bccb3273177aa2fe93b7b1c0305 Mon Sep 17 00:00:00 2001
From: Khalid Ahmed <ahmedkd@iis.fraunhofer.de>
Date: Tue, 26 Feb 2019 12:54:29 +0100
Subject: [PATCH] pusch scrambling

---
 cmake_targets/CMakeLists.txt                  |  1 +
 .../NR_TRANSPORT/nr_transport_common_proto.h  |  3 +
 .../PHY/NR_UE_TRANSPORT/nr_transport_ue.h     | 11 ++--
 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch.c       | 66 +++++++++++++++++++
 .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c     |  2 +-
 openair1/SCHED_NR_UE/fapi_nr_ue_l1.c          |  2 +-
 openair1/SIMULATION/NR_PHY/ulschsim.c         | 41 ++++++++++--
 openair1/SIMULATION/NR_PHY/ulsim.c            |  2 +-
 8 files changed, 117 insertions(+), 11 deletions(-)
 create mode 100644 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch.c

diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 3d701f5b98..815c1a04cc 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1322,6 +1322,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_REFSIG/ul_ref_seq_nr.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
index 14ba3de923..7b74d1b970 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
@@ -43,6 +43,9 @@
 #define MAX_NUM_NR_CHANNEL_BITS (14*273*12*6)  // 14 symbols, 273 RB
 #define MAX_NUM_NR_RE (14*273*12)
 
+#define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1
+#define NR_PUSCH_y 3 // UCI placeholder bit 
+
 // Functions below implement minor procedures from 38-214
 
 /** \brief Computes Q based on I_MCS PDSCH and when 'MCS-Table-PDSCH' is set to "256QAM". Implements Table 5.1.3.1-2 from 38.214.
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index fc303716e9..9a14e7c661 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -152,11 +152,12 @@ typedef struct {
   //  int calibration_flag;
   /// Number of soft channel bits
   uint32_t G;
-  // number of symbols
-  uint8_t nb_symbols;
-  // first symbol in the slot
+  // Number of modulated symbols carrying data
+  uint8_t num_of_mod_symbols;
+  // This is "L" in  TS 38.214 V15.4.0 subclause 6.1.2.1
+  uint8_t number_of_symbols;
+  // This is "S" in  TS 38.214 V15.4.0 subclause 6.1.2.1
   uint8_t start_symbol;
-
   // decode phich
   uint8_t decode_phich;
 } NR_UL_UE_HARQ_t;
@@ -166,6 +167,8 @@ typedef struct {
   uint8_t Nsymb_pusch;
   /// number of DMRS resource elements
   uint8_t nb_re_dmrs;
+  /// DMRS length
+  uint8_t length_dmrs;
   /// SRS active flag
   uint8_t srs_active; 
 //#if defined(UPGRADE_RAT_NR)
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch.c
new file mode 100644
index 0000000000..574e19eb5f
--- /dev/null
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch.c
@@ -0,0 +1,66 @@
+/*
+ * 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_UE_TRANSPORT/nr_ulsch.c
+* \brief Top-level routines for transmission of the PUSCH TS 38.211 v 15.4.0
+* \author Khalid Ahmed
+* \date 2019
+* \version 0.1
+* \company Fraunhofer IIS
+* \email: khalid.ahmed@iis.fraunhofer.de
+* \note
+* \warning
+*/
+#include <stdint.h>
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
+
+
+
+void nr_pusch_codeword_scrambling(uint8_t *in,
+                         uint16_t size,
+                         uint32_t Nid,
+                         uint32_t n_RNTI,
+                         uint32_t* out) {
+
+  uint8_t reset, b_idx;
+  uint32_t x1, x2, s=0;
+
+  reset = 1;
+  x2 = (n_RNTI<<15) + Nid;
+
+  for (int i=0; i<size; i++) {
+    b_idx = i&0x1f;
+    if (b_idx==0) {
+      s = lte_gold_generic(&x1, &x2, reset);
+      reset = 0;
+      if (i)
+        out++;
+    }
+    if (in[i]==NR_PUSCH_x)
+      *out ^= 1<<b_idx;
+    else if (in[i]==NR_PUSCH_y)
+      *out ^= (*out & (1<<b_idx-1))<<b_idx;
+    else
+      *out ^= (((in[i])&1) ^ ((s>>b_idx)&1))<<b_idx;
+    //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
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index 95ca86959f..64c49b32f7 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -224,7 +224,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
   crc = 1;
   harq_process = ulsch->harq_processes[harq_pid];
   nb_rb = harq_process->nb_rb;
-  nb_symb_sch = harq_process->nb_symbols;
+  nb_symb_sch = harq_process->number_of_symbols;
   A = harq_process->TBS;
   pz = &Z;
   mod_order = nr_get_Qm(harq_process->mcs,1);
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 0432ded427..6ee8fbfaa6 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -142,7 +142,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
 	  uint8_t current_harq_pid = pusch_config_pdu->harq_process_nbr;
 	  ulsch0->harq_processes[current_harq_pid]->nb_rb = pusch_config_pdu->number_rbs;
 	  ulsch0->harq_processes[current_harq_pid]->first_rb = pusch_config_pdu->start_rb;
-	  ulsch0->harq_processes[current_harq_pid]->nb_symbols = pusch_config_pdu->number_symbols;
+	  ulsch0->harq_processes[current_harq_pid]->number_of_symbols = pusch_config_pdu->number_symbols;
 	  ulsch0->harq_processes[current_harq_pid]->start_symbol = pusch_config_pdu->start_symbol;
 	  ulsch0->harq_processes[current_harq_pid]->mcs = pusch_config_pdu->mcs;
 	  ulsch0->harq_processes[current_harq_pid]->DCINdi = pusch_config_pdu->ndi;
diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c
index e021683a43..7c557e6134 100644
--- a/openair1/SIMULATION/NR_PHY/ulschsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulschsim.c
@@ -138,7 +138,7 @@ int main(int argc, char **argv) {
   //  int subframe_offset;
   //  char fname[40], vname[40];
   int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
-  uint8_t n_tx = 1, n_rx = 1;
+  uint8_t n_tx = 1, n_rx = 1, nb_codewords = 1;
   //uint8_t transmission_mode = 1;
   uint16_t Nid_cell = 0;
   channel_desc_t *gNB2UE;
@@ -475,6 +475,8 @@ int main(int argc, char **argv) {
   unsigned int available_bits;
   uint8_t nb_re_dmrs = 6;
   uint16_t length_dmrs = 1;
+  uint8_t N_PRB_oh;
+  uint16_t N_RE_prime;
   unsigned char mod_order;
   uint8_t Nl = 1;
   uint8_t rvidx = 0;
@@ -485,8 +487,6 @@ int main(int argc, char **argv) {
 
   NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0];
 
-  ulsch_ue->nb_re_dmrs = nb_re_dmrs; //[adk] A HOT FIX until cearting nfapi_nr_ul_config_ulsch_pdu_rel15_t
-
   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);
@@ -522,16 +522,28 @@ int main(int argc, char **argv) {
 
   // 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
+  ///////////
+  ulsch_ue->nb_re_dmrs = nb_re_dmrs;
+  ulsch_ue->length_dmrs =  length_dmrs;
+  ulsch_ue->rnti = n_rnti;
+  ///////////
+  ////////////////////////////////////////////////////////////////////////////////////////////
+
   /////////////////////////[adk] preparing UL harq_process parameters/////////////////////////
   ///////////
   NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
 
+  N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
+  N_RE_prime = NR_NB_SC_PER_RB*nb_symb_sch - nb_re_dmrs - N_PRB_oh;
+
   if (harq_process_ul_ue) {
 
     harq_process_ul_ue->mcs = Imcs;
     harq_process_ul_ue->Nl = Nl;
     harq_process_ul_ue->nb_rb = nb_rb;
-    harq_process_ul_ue->nb_symbols = nb_symb_sch;
+    harq_process_ul_ue->number_of_symbols = nb_symb_sch;
+    harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*nb_codewords;
     harq_process_ul_ue->rvidx = rvidx;
     harq_process_ul_ue->TBS = TBS;
     harq_process_ul_ue->a = &test_input[0];
@@ -560,6 +572,27 @@ int main(int argc, char **argv) {
   ///////////
   ////////////////////////////////////////////////////////////////////
 
+  /////////////////////////[adk] 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));
+  }
+
+  nr_pusch_codeword_scrambling(ulsch_ue->g,
+                               encoded_length,
+                               Nid_cell,
+                               ulsch_ue->rnti,
+                               scrambled_output[0]); // assume one codeword for the moment
+
+
+  /////////////
+  //////////////////////////////////////////////////////////////////////////
 
   for (SNR = snr0; SNR < snr1; SNR += snr_step) {
     n_errors = 0;
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index e021683a43..4e6fc52a0a 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -531,7 +531,7 @@ int main(int argc, char **argv) {
     harq_process_ul_ue->mcs = Imcs;
     harq_process_ul_ue->Nl = Nl;
     harq_process_ul_ue->nb_rb = nb_rb;
-    harq_process_ul_ue->nb_symbols = nb_symb_sch;
+    harq_process_ul_ue->number_of_symbols = nb_symb_sch;
     harq_process_ul_ue->rvidx = rvidx;
     harq_process_ul_ue->TBS = TBS;
     harq_process_ul_ue->a = &test_input[0];
-- 
2.26.2