dlsch_scrambling.c 6.69 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
                      int mbsfn_flag,
                      LTE_eNB_DLSCH_t *dlsch,
74
		      int harq_pid,
75
76
77
78
                      int G,
                      uint8_t q,
                      uint8_t Ns)
{
79

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

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

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

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

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

103
#ifdef DEBUG_SCRAMBLING
knopp's avatar
knopp committed
104
    printf("scrambling %d : %d => ",k,e[k]);
105
#endif
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
139

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

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

155
156
157
}

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

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

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

178
179
180
#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
181
  s = lte_gold_scram(&x1, &x2, 1);
182

183
  for (i=0; i<(1+(G>>5)); i++) {
184
    for (j=0; j<32; j++,k++) {
185
186
187
188
189
190
191
192
#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
    }
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
218
    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);
    }
219
  }
220
}