dlsch_scrambling.c 8.06 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
37
#include "PHY/defs_eNB.h"
#include "PHY/defs_UE.h"
#include "PHY/CODING/coding_extern.h"
38
#include "PHY/CODING/lte_interleaver_inline.h"
39
40
#include "transport_eNB.h"
#include "PHY/phy_extern.h"
41
42
#include "UTIL/LOG/vcd_signal_dumper.h"

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
static inline unsigned int lte_gold_scram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline));
static inline unsigned int lte_gold_scram(unsigned int *x1, unsigned int *x2, unsigned char reset)
{
  int n;

  if (reset) {
    *x1 = 1+ (1<<31);
    *x2=*x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31);

    // skip first 50 double words (1600 bits)
    //      printf("n=0 : x1 %x, x2 %x\n",x1,x2);
    for (n=1; n<50; n++) {
      *x1 = (*x1>>1) ^ (*x1>>4);
      *x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
      *x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
      *x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
    }
  }

  *x1 = (*x1>>1) ^ (*x1>>4);
  *x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
  *x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
  *x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
  return(*x1^*x2);
  //  printf("n=%d : c %x\n",n,x1^x2);

}

71
void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
72
73
                      int mbsfn_flag,
                      LTE_eNB_DLSCH_t *dlsch,
74
		      int harq_pid,
75
76
                      int G,
                      uint8_t q,
77
		      uint16_t frame,
78
79
                      uint8_t Ns)
{
80

81
82
  int n;

gauthier's avatar
gauthier committed
83
84
  //  uint8_t reset;
  uint32_t x1, x2, s=0;
85
  uint8_t *dlsch_e=dlsch->harq_processes[harq_pid]->e;
knopp's avatar
knopp committed
86
  uint8_t *e=dlsch_e;
87

gauthier's avatar
gauthier committed
88
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING, VCD_FUNCTION_IN);
89

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#ifdef Rel14
  // 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);
  uint16_t i0 = dlsch->i0;

  if (dlsch->sib1_br_flag==1)                              Nacc=1;
  else if (dlsch->rnti == 0xFFFF || dlsch->rnti == 0xFFFE) Nacc = (frame_parms->frame_type == TDD) ? 10 : 4;
  // 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;

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

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

110
111
112
  //  reset = 1;
  // x1 is set in lte_gold_generic
  if (mbsfn_flag == 0) {
113
114
115
116
117
118
119
120
121
#ifdef Rel14
    if (dlsch->i0 != 0xFFFF) {
      // 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
122
  } else {
123
    x2 = ((Ns>>1)<<9) + frame_parms->Nid_cell_mbsfn; //this is c_init in 36.211 Sec 6.3.1 for PMCH
124
  }
125

126
#ifdef DEBUG_SCRAMBLING
knopp's avatar
knopp committed
127
#ifdef Rel14
128
  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
129
130
131
#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
132
#endif
133
  s = lte_gold_scram(&x1, &x2, 1);
134

135
  for (n=0; n<(1+(G>>5)); n++) {
136

137
#ifdef DEBUG_SCRAMBLING
knopp's avatar
knopp committed
138
    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));
139
#endif
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
165
166
167
168
169
170
171
172
173

                
    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
174
    
175
176
177
    // 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
178
179


knopp's avatar
knopp committed
180
181
    
    
182
    s = lte_gold_scram(&x1, &x2, 0);
knopp's avatar
knopp committed
183
    e += 32;
184
185
  }

gauthier's avatar
gauthier committed
186
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING, VCD_FUNCTION_OUT);
187

188
189
}

190
191
192
193
194
195
196
197
198
199
200
201
202
203


void init_scrambling_lut() {

  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);
    }
  }
}

204
void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
205
206
207
208
209
210
211
                        int mbsfn_flag,
                        LTE_UE_DLSCH_t *dlsch,
                        int G,
                        int16_t* llr,
                        uint8_t q,
                        uint8_t Ns)
{
212
213

  int i,j,k=0;
gauthier's avatar
gauthier committed
214
215
  //  uint8_t reset;
  uint32_t x1, x2, s=0;
216

217
218
219
220
221
222
223
  //  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
224

225
#ifdef DEBUG_SCRAMBLING
226
    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);
227
#endif
228
  s = lte_gold_scram(&x1, &x2, 1);
229

230
  for (i=0; i<(1+(G>>5)); i++) {
231
    for (j=0; j<32; j++,k++) {
232
#ifdef DEBUG_SCRAMBLING
knopp's avatar
knopp committed
233
    printf("unscrambling %d : %d xor %d =",k,llr[k],(s>>j)&1);
234
235
236
237
238
239
#endif
      llr[k] = ((2*((s>>j)&1))-1)*llr[k];
#ifdef DEBUG_SCRAMBLING
      printf("%d\n",llr[k]);
#endif
    }
240

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
    s = lte_gold_scram(&x1, &x2, 0);
  }
}

void init_unscrambling_lut() {

  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);
    }
  }
}