dlsch_scrambling.c 6.68 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * 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.0  (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
 */

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*! \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

#include "PHY/defs.h"
#include "PHY/CODING/extern.h"
#include "PHY/CODING/lte_interleaver_inline.h"
#include "defs.h"
#include "extern.h"
#include "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
74
75
76
77
                      int mbsfn_flag,
                      LTE_eNB_DLSCH_t *dlsch,
                      int G,
                      uint8_t q,
                      uint8_t Ns)
{
78

knopp's avatar
knopp committed
79
  int i;
gauthier's avatar
gauthier committed
80
81
  //  uint8_t reset;
  uint32_t x1, x2, s=0;
knopp's avatar
knopp committed
82
83
  uint8_t *dlsch_e=dlsch->harq_processes[dlsch->current_harq_pid]->e;
  uint8_t *e=dlsch_e;
84

gauthier's avatar
gauthier committed
85
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING, VCD_FUNCTION_IN);
86

87
88
89
90
  //  reset = 1;
  // x1 is set in 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
91
  } else {
92
93
    x2 = ((Ns>>1)<<9) + frame_parms->Nid_cell_mbsfn; //this is c_init in 36.211 Sec 6.3.1
  }
94

95
#ifdef DEBUG_SCRAMBLING
96
  printf("scrambling: rnti %x, q %d, Ns %d, Nid_cell %d, length %d\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell, G);
97
#endif
98
  s = lte_gold_scram(&x1, &x2, 1);
99

100
  for (i=0; i<(1+(G>>5)); i++) {
101

102
#ifdef DEBUG_SCRAMBLING
knopp's avatar
knopp committed
103
    printf("scrambling %d : %d => ",k,e[k]);
104
#endif
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

                
    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
139
    
140
141
142
    // 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]);
143
#ifdef DEBUG_SCRAMBLING
knopp's avatar
knopp committed
144
    printf("%d\n",e[k]);
145
#endif
knopp's avatar
knopp committed
146
147
    
    
148
    s = lte_gold_scram(&x1, &x2, 0);
knopp's avatar
knopp committed
149
    e += 32;
150
151
  }

gauthier's avatar
gauthier committed
152
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING, VCD_FUNCTION_OUT);
153

154
155
156
}

void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
157
158
159
160
161
162
163
                        int mbsfn_flag,
                        LTE_UE_DLSCH_t *dlsch,
                        int G,
                        int16_t* llr,
                        uint8_t q,
                        uint8_t Ns)
{
164
165

  int i,j,k=0;
gauthier's avatar
gauthier committed
166
167
  //  uint8_t reset;
  uint32_t x1, x2, s=0;
168

169
170
171
172
173
174
175
  //  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
176

177
178
179
#ifdef DEBUG_SCRAMBLING
  printf("unscrambling: rnti %x, q %d, Ns %d, Nid_cell %d length %d\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell,G);
#endif
180
  s = lte_gold_scram(&x1, &x2, 1);
181

182
  for (i=0; i<(1+(G>>5)); i++) {
183
    for (j=0; j<32; j++,k++) {
184
185
186
187
188
189
190
191
#ifdef DEBUG_SCRAMBLING
      printf("unscrambling %d : %d => ",k,llr[k]);
#endif
      llr[k] = ((2*((s>>j)&1))-1)*llr[k];
#ifdef DEBUG_SCRAMBLING
      printf("%d\n",llr[k]);
#endif
    }
192

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
    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);
    }
  }
}

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