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