dlsch_scrambling.c 7.99 KB
Newer Older
1 2 3 4 5
/*
 * 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
Cedric Roux's avatar
Cedric Roux committed
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * 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
 */

22 23 24 25 26 27 28 29 30 31 32 33 34
/*! \file PHY/LTE_TRANSPORT/dlsch_scrambling.c
* \brief Routines for the scrambling procedure of the PDSCH physical channel from 36-211, V8.6 2009-03
* \author R. Knopp
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
* \note
* \warning
*/

//#define DEBUG_SCRAMBLING 1

35 36
#include "PHY/defs_eNB.h"
#include "PHY/defs_UE.h"
37
#include "PHY/LTE_REFSIG/lte_refsig.h"
38
#include "PHY/CODING/coding_extern.h"
39
#include "PHY/CODING/lte_interleaver_inline.h"
40 41
#include "transport_eNB.h"
#include "PHY/phy_extern.h"
42
#include "common/utils/LOG/vcd_signal_dumper.h"
43

44
void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
45 46
                      int mbsfn_flag,
                      LTE_eNB_DLSCH_t *dlsch,
47
                      int harq_pid,
48 49
                      int G,
                      uint8_t q,
50
                      uint16_t frame,
51 52
                      uint8_t Ns)
{
53

54 55
  int n;

gauthier's avatar
gauthier committed
56 57
  //  uint8_t reset;
  uint32_t x1, x2, s=0;
58
  uint8_t *dlsch_e=dlsch->harq_processes[harq_pid]->e;
knopp's avatar
knopp committed
59
  uint8_t *e=dlsch_e;
60

gauthier's avatar
gauthier committed
61
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING, VCD_FUNCTION_IN);
62

63
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
64 65 66 67
  // Rule for accumulation of subframes for BL/CE UEs
  uint8_t Nacc=4;
  uint16_t j0,j,idelta;
  uint16_t i  = (Ns>>1) + (10*frame);
68
#ifdef PHY_TX_THREAD
69 70
  uint16_t i0 = dlsch->harq_processes[harq_pid]->i0;
#else
71
  uint16_t i0 = dlsch->i0;
72
#endif
73

74
#ifdef PHY_TX_THREAD
75 76
  if (dlsch->harq_processes[harq_pid]->sib1_br_flag==1)                              Nacc=1;
#else
77
  if (dlsch->sib1_br_flag==1)                              Nacc=1;
78
#endif
79
  else if (dlsch->rnti == 0xFFFF || dlsch->rnti == 0xFFFE) Nacc = (frame_parms->frame_type == TDD) ? 10 : 4;
80
#ifdef PHY_TX_THREAD
81 82 83 84
  // Note: above SC-RNTI will also have to be added when/if implemented
  else if (dlsch->harq_processes[harq_pid]->CEmode == CEmodeA)                       Nacc=1;
  else if (dlsch->harq_processes[harq_pid]->CEmode == CEmodeB)                       Nacc = (frame_parms->frame_type == TDD) ? 10 : 4;
#else
85 86 87
  // Note: above SC-RNTI will also have to be added when/if implemented
  else if (dlsch->CEmode == CEmodeA)                       Nacc=1;
  else if (dlsch->CEmode == CEmodeB)                       Nacc = (frame_parms->frame_type == TDD) ? 10 : 4;
88
#endif
89 90 91 92 93 94 95 96

  if (frame_parms->frame_type == FDD || Nacc == 1) idelta = 0;
  else                                             idelta = Nacc-2;

  j0 = (i0+idelta)/Nacc;
  j  = (i - i0)/Nacc; 
#endif

97 98 99
  //  reset = 1;
  // x1 is set in lte_gold_generic
  if (mbsfn_flag == 0) {
100
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
101
#ifdef PHY_TX_THREAD
102 103
    if (dlsch->harq_processes[harq_pid]->i0 != 0xFFFF) {
#else
104
    if (dlsch->i0 != 0xFFFF) {
105
#endif
106 107 108 109 110 111 112
      // rule for BL/CE UEs from Section 6.3.1 in 36.211
      x2=  (dlsch->rnti<<14) + (q<<13) + ((((j0+j)*Nacc)%10)<<9) + frame_parms->Nid_cell;
      if ((frame&1023) < 200) LOG_D(PHY,"Scrambling init for (i0 %d, i %d, j0 %d, j %d, Nacc %d) => x2 %d\n",i0,i,j0,j,Nacc,x2);
    }
    else
#endif
    x2 = (dlsch->rnti<<14) + (q<<13) + ((Ns>>1)<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1 for PDSCH
113
  } else {
114
    x2 = ((Ns>>1)<<9) + frame_parms->Nid_cell_mbsfn; //this is c_init in 36.211 Sec 6.3.1 for PMCH
115
  }
116

117
#ifdef DEBUG_SCRAMBLING
118
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
119
  printf("scrambling: i0 %d rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->i0,dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2);
knopp's avatar
knopp committed
120 121 122
#else
  printf("scrambling: rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2);
#endif
123
#endif
124
  s = lte_gold_generic(&x1, &x2, 1);
125

126
  for (n=0; n<(1+(G>>5)); n++) {
127

128
#ifdef DEBUG_SCRAMBLING
knopp's avatar
knopp committed
129
    for (int k=0;k<32;k++) printf("scrambling %d : %d xor %d = %d\n",k+(n<<5),e[k],(s>>k)&1,e[k]^((s>>k)&1));
130
#endif
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164

                
    e[0] = (e[0]) ^ (s&1);      
    e[1] = (e[1]) ^ ((s>>1)&1);      
    e[2] = (e[2]) ^ ((s>>2)&1);      
    e[3] = (e[3]) ^ ((s>>3)&1);      
    e[4] = (e[4]) ^ ((s>>4)&1);      
    e[5] = (e[5]) ^ ((s>>5)&1);      
    e[6] = (e[6]) ^ ((s>>6)&1);      
    e[7] = (e[7]) ^ ((s>>7)&1);      
    e[8] = (e[8]) ^ ((s>>8)&1);      
    e[9] = (e[9]) ^ ((s>>9)&1);      
    e[10] = (e[10]) ^ ((s>>10)&1);      
    e[11] = (e[11]) ^ ((s>>11)&1);      
    e[12] = (e[12]) ^ ((s>>12)&1);      
    e[13] = (e[13]) ^ ((s>>13)&1);      
    e[14] = (e[14]) ^ ((s>>14)&1);      
    e[15] = (e[15]) ^ ((s>>15)&1);      
    e[16] = (e[16]) ^ ((s>>16)&1);      
    e[17] = (e[17]) ^ ((s>>17)&1);      
    e[18] = (e[18]) ^ ((s>>18)&1);      
    e[19] = (e[19]) ^ ((s>>19)&1);      
    e[20] = (e[20]) ^ ((s>>20)&1);      
    e[21] = (e[21]) ^ ((s>>21)&1);      
    e[22] = (e[22]) ^ ((s>>22)&1);      
    e[23] = (e[23]) ^ ((s>>23)&1);      
    e[24] = (e[24]) ^ ((s>>24)&1);      
    e[25] = (e[25]) ^ ((s>>25)&1);      
    e[26] = (e[26]) ^ ((s>>26)&1);      
    e[27] = (e[27]) ^ ((s>>27)&1);      
    e[28] = (e[28]) ^ ((s>>28)&1);      
    e[29] = (e[29]) ^ ((s>>29)&1);      
    e[30] = (e[30]) ^ ((s>>30)&1);      
    e[31] = (e[31]) ^ ((s>>31)&1);      
knopp's avatar
knopp committed
165
    
166 167 168
    // This is not faster for some unknown reason
    //    ((__m128i *)e)[0] = _mm_xor_si128(((__m128i *)e)[0],((__m128i *)scrambling_lut)[s&65535]);
    //    ((__m128i *)e)[1] = _mm_xor_si128(((__m128i *)e)[1],((__m128i *)scrambling_lut)[s>>16]);
knopp's avatar
knopp committed
169 170


knopp's avatar
knopp committed
171 172
    
    
173
    s = lte_gold_generic(&x1, &x2, 0);
knopp's avatar
knopp committed
174
    e += 32;
175 176
  }

gauthier's avatar
gauthier committed
177
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING, VCD_FUNCTION_OUT);
178

179 180
}

181 182


knopp's avatar
knopp committed
183
void init_scrambling_lut(void) {
184 185 186 187 188 189 190 191 192 193 194

  uint32_t s;
  int i=0,j;

  for (s=0;s<=65535;s++) {
    for (j=0;j<16;j++) {
      scrambling_lut[i++] = (uint8_t)((s>>j)&1);
    }
  }
}

195
void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
196 197 198 199 200 201 202
                        int mbsfn_flag,
                        LTE_UE_DLSCH_t *dlsch,
                        int G,
                        int16_t* llr,
                        uint8_t q,
                        uint8_t Ns)
{
203 204

  int i,j,k=0;
gauthier's avatar
gauthier committed
205 206
  //  uint8_t reset;
  uint32_t x1, x2, s=0;
207

208 209 210 211 212 213 214
  //  reset = 1;
  // x1 is set in first call to lte_gold_generic

  if (mbsfn_flag == 0)
    x2 = (dlsch->rnti<<14) + (q<<13) + ((Ns>>1)<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1
  else
    x2 = ((Ns>>1)<<9) + frame_parms->Nid_cell_mbsfn; //this is c_init in 36.211 Sec 6.3.1
215

216
#ifdef DEBUG_SCRAMBLING
217
    printf("unscrambling: rnti %x, q %d, Ns %d, Nid_cell %d G %d, x2 %x\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell,G,x2);
218
#endif
219
  s = lte_gold_generic(&x1, &x2, 1);
220

221
  for (i=0; i<(1+(G>>5)); i++) {
222
    for (j=0; j<32; j++,k++) {
223
#ifdef DEBUG_SCRAMBLING
knopp's avatar
knopp committed
224
    printf("unscrambling %d : %d xor %d =",k,llr[k],(s>>j)&1);
225 226 227 228 229 230
#endif
      llr[k] = ((2*((s>>j)&1))-1)*llr[k];
#ifdef DEBUG_SCRAMBLING
      printf("%d\n",llr[k]);
#endif
    }
231

232
    s = lte_gold_generic(&x1, &x2, 0);
233 234 235
  }
}

knopp's avatar
knopp committed
236
void init_unscrambling_lut(void) {
237 238 239 240 241 242 243 244 245 246

  uint32_t s;
  int i=0,j;

  for (s=0;s<=65535;s++) {
    for (j=0;j<16;j++) {
      unscrambling_lut[i++] = (int16_t)((((s>>j)&1)<<1)-1);
    }
  }
}