Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
canghaiwuhen
OpenXG-RAN
Commits
637ab8cb
Commit
637ab8cb
authored
Jul 06, 2017
by
Michele Paffetti
Browse files
Options
Browse Files
Download
Plain Diff
conflicts correction and reordering of files
parents
a9f91a9c
849e9312
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
998 additions
and
0 deletions
+998
-0
openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.c
openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.c
+585
-0
openair1/PHY/LTE_TRANSPORT/dci_nb_iot.c
openair1/PHY/LTE_TRANSPORT/dci_nb_iot.c
+413
-0
No files found.
openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.c
0 → 100755
View file @
637ab8cb
/*******************************************************************************
*******************************************************************************/
/*! \file PHY/LTE_TRANSPORT/dci_NB_IoT.c
* \brief Top-level routines for implementing Tail-biting convolutional coding for transport channels (NPDCCH) for NB_IoT, TS 36-212, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
#ifdef USER_MODE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#include "SIMULATION/TOOLS/defs.h"
#include "PHY/sse_intrin.h"
#include "assertions.h"
#include "T.h"
static
uint8_t
d
[
2
][
3
*
(
MAX_DCI_SIZE_BITS_NB_IOT
+
16
)
+
96
];
static
uint8_t
w
[
2
][
3
*
3
*
(
MAX_DCI_SIZE_BITS_NB_IOT
+
16
)];
void
dci_encoding_NB_IoT
(
uint8_t
*
a
[
2
],
// Table of two DCI, even if one DCI is to transmit , the number of DCI is indicated in dci_number
uint8_t
A
,
// Length of table a
uint16_t
E
,
// E should equals to G (number of available bits in one RB)
uint8_t
*
e
[
2
],
// *e should be e[2][G]
uint16_t
rnti
[
2
],
// RNTI for UE specific or common search space
uint8_t
dci_number
,
// This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t
agr_level
)
// Aggregation level
{
uint8_t
D
=
(
A
+
16
);
uint32_t
RCC
;
uint8_t
occupation_size
=
1
;
// encode dci
if
(
dci_number
==
1
)
{
if
(
agr_level
==
2
)
{
occupation_size
=
1
;
}
else
{
occupation_size
=
2
;
}
memset
((
void
*
)
d
[
0
],
LTE_NULL
,
96
);
ccode_encode_NB_IoT
(
A
,
2
,
a
[
0
],
d
[
0
]
+
96
,
rnti
[
0
]);
// CRC attachement & Tail-biting convolutional coding
RCC
=
sub_block_interleaving_cc_NB_IoT
(
D
,
d
[
0
]
+
96
,
w
[
0
]);
// Interleaving
lte_rate_matching_cc_NB_IoT
(
RCC
,(
E
/
occupation_size
),
w
[
0
],
e
[
0
]);
// Rate Matching
}
else
if
(
dci_number
==
2
)
{
memset
((
void
*
)
d
[
0
],
LTE_NULL
,
96
);
memset
((
void
*
)
d
[
1
],
LTE_NULL
,
96
);
// first DCI encoding
ccode_encode_NB_IoT
(
A
,
2
,
a
[
0
],
d
[
0
]
+
96
,
rnti
[
0
]);
// CRC attachement & Tail-biting convolutional coding
RCC
=
sub_block_interleaving_cc_NB_IoT
(
D
,
d
[
0
]
+
96
,
w
[
0
]);
// interleaving
lte_rate_matching_cc_NB_IoT
(
RCC
,
E
/
2
,
w
[
0
],
e
[
0
]);
// Rate Matching , E/2 , NCCE0
// second DCI encoding
ccode_encode_NB_IoT
(
A
,
2
,
a
[
1
],
d
[
1
]
+
96
,
rnti
[
1
]);
// CRC attachement & Tail-biting convolutional coding
RCC
=
sub_block_interleaving_cc_NB_IoT
(
D
,
d
[
1
]
+
96
,
w
[
1
]);
// Interleaving
lte_rate_matching_cc_NB_IoT
(
RCC
,
E
/
2
,
w
[
1
],
e
[
1
]);
// Rate Matching, E/2 , NCCE1
}
}
///The scrambling sequence shall be initialised at the start of the search space and after every 4th NPDCCH subframes.
///
///
void
npdcch_scrambling_NB_IoT
(
NB_IOT_DL_FRAME_PARMS
*
frame_parms
,
uint8_t
*
e
[
2
],
// Input data
int
length
,
// Total number of bits to transmit in one subframe(case of DCI = G)
uint8_t
Ns
,
// Slot number (0..19)
uint8_t
dci_number
,
// This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t
agr_level
)
// Aggregation level
{
int
i
,
j
,
k
=
0
;
uint32_t
x1
,
x2
,
s
=
0
;
uint8_t
reset
;
reset
=
1
;
uint8_t
occupation_size
=
1
;
if
(
agr_level
==
2
)
{
occupation_size
=
1
;
}
else
{
occupation_size
=
2
;
}
if
(
dci_number
==
1
)
// Case of one DCI
{
x2
=
((
Ns
>>
1
)
<<
9
)
+
frame_parms
->
Nid_cell
;
// This is c_init in 36.211 Sec 10.2.3.1
for
(
i
=
0
;
i
<
length
/
occupation_size
;
i
++
)
{
if
((
i
&
0x1f
)
==
0
)
{
s
=
lte_gold_generic_NB_IoT
(
&
x1
,
&
x2
,
reset
);
reset
=
0
;
}
e
[
0
][
k
]
=
(
e
[
0
][
k
]
&
1
)
^
((
s
>>
(
i
&
0x1f
))
&
1
);
}
}
else
if
(
dci_number
==
2
&&
occupation_size
==
2
)
{
// Case of two DCI
// Scrambling the first DCI
//
x2
=
((
Ns
>>
1
)
<<
9
)
+
frame_parms
->
Nid_cell
;
// This is c_init in 36.211 Sec 10.2.3.1
for
(
i
=
0
;
i
<
length
/
occupation_size
;
i
++
)
{
if
((
i
&
0x1f
)
==
0
)
{
s
=
lte_gold_generic_NB_IoT
(
&
x1
,
&
x2
,
reset
);
reset
=
0
;
}
e
[
0
][
k
]
=
(
e
[
0
][
k
]
&
1
)
^
((
s
>>
(
i
&
0x1f
))
&
1
);
}
// reset of the scrambling function
reset
=
1
;
// Scrambling the second DCI
//
x2
=
((
Ns
>>
1
)
<<
9
)
+
frame_parms
->
Nid_cell
;
//this is c_init in 36.211 Sec 10.2.3.1
for
(
i
=
0
;
i
<
length
/
occupation_size
;
i
++
)
{
if
((
i
&
0x1f
)
==
0
)
{
s
=
lte_gold_generic_NB_IoT
(
&
x1
,
&
x2
,
reset
);
reset
=
0
;
}
e
[
1
][
k
]
=
(
e
[
1
][
k
]
&
1
)
^
((
s
>>
(
i
&
0x1f
))
&
1
);
}
}
}
int
dci_allocate_REs_in_RB_NB_IoT
(
NB_IOT_DL_FRAME_PARMS
*
frame_parms
,
int32_t
**
txdataF
,
uint32_t
*
jj
,
uint32_t
symbol_offset
,
uint8_t
*
x0
[
2
],
uint8_t
pilots
,
int16_t
amp
,
unsigned
short
id_offset
,
uint32_t
*
re_allocated
,
// not used variable ??!!
uint8_t
dci_number
,
// This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t
agr_level
)
{
MIMO_mode_t
mimo_mode
=
(
frame_parms
->
mode1_flag
==
1
)
?
SISO
:
ALAMOUTI
;
uint32_t
tti_offset
,
aa
;
uint8_t
re
,
diff_re
;
int16_t
gain_lin_QPSK
;
uint8_t
first_re
,
last_re
;
int32_t
tmp_sample1
,
tmp_sample2
,
tmp_sample3
,
tmp_sample4
;
gain_lin_QPSK
=
(
int16_t
)((
amp
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
first_re
=
0
;
last_re
=
12
;
if
(
agr_level
==
2
&&
dci_number
==
1
)
{
for
(
re
=
first_re
;
re
<
last_re
;
re
++
)
{
// re varies between 0 and 12 sub-carriers
tti_offset
=
symbol_offset
+
re
;
// symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if
(
pilots
!=
1
||
re
%
3
!=
id_offset
)
// if re is not a pilot
{
// diff_re = re%3 - id_offset;
if
(
mimo_mode
==
SISO
)
{
//SISO mapping
*
re_allocated
=
*
re_allocated
+
1
;
// variable incremented but never used
for
(
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_tx
;
aa
++
)
{
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
])[
0
]
+=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//I //b_i
}
*
jj
=
*
jj
+
1
;
for
(
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_tx
;
aa
++
)
{
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
])[
1
]
+=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//Q //b_{i+1}
}
*
jj
=
*
jj
+
1
;
}
else
if
(
mimo_mode
==
ALAMOUTI
)
{
*
re_allocated
=
*
re_allocated
+
1
;
((
int16_t
*
)
&
tmp_sample1
)[
0
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
((
int16_t
*
)
&
tmp_sample1
)[
1
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
// second antenna position n -> -x1*
((
int16_t
*
)
&
tmp_sample2
)[
0
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
gain_lin_QPSK
)
:
-
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
((
int16_t
*
)
&
tmp_sample2
)[
1
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
// normalization for 2 tx antennas
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample1
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample1
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample2
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample2
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
// fill in the rest of the ALAMOUTI precoding
if
(
pilots
!=
1
||
(
re
+
1
)
%
3
!=
id_offset
)
{
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
1
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
1
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
1
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
1
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
];
}
else
{
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
2
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
2
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
2
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
2
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
];
re
++
;
// skip pilots
*
re_allocated
=
*
re_allocated
+
1
;
}
re
++
;
// adjacent carriers are taken care of by precoding
*
re_allocated
=
*
re_allocated
+
1
;
// incremented variable but never used
}
}
}
}
else
if
(
agr_level
==
1
&&
dci_number
==
1
){
for
(
re
=
first_re
;
re
<
6
;
re
++
)
{
// re varies between 0 and 6 sub-carriers
tti_offset
=
symbol_offset
+
re
;
// symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if
(
pilots
!=
1
||
re
%
3
!=
id_offset
)
// if re is not a pilot
{
// diff_re = re%3 - id_offset;
if
(
mimo_mode
==
SISO
)
{
//SISO mapping
*
re_allocated
=
*
re_allocated
+
1
;
// variable incremented but never used
for
(
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_tx
;
aa
++
)
{
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
])[
0
]
+=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//I //b_i
}
*
jj
=
*
jj
+
1
;
for
(
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_tx
;
aa
++
)
{
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
])[
1
]
+=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//Q //b_{i+1}
}
*
jj
=
*
jj
+
1
;
}
else
if
(
mimo_mode
==
ALAMOUTI
)
{
*
re_allocated
=
*
re_allocated
+
1
;
((
int16_t
*
)
&
tmp_sample1
)[
0
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
((
int16_t
*
)
&
tmp_sample1
)[
1
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
// second antenna position n -> -x1*
((
int16_t
*
)
&
tmp_sample2
)[
0
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
gain_lin_QPSK
)
:
-
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
((
int16_t
*
)
&
tmp_sample2
)[
1
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
// normalization for 2 tx antennas
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample1
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample1
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample2
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample2
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
// fill in the rest of the ALAMOUTI precoding
if
(
pilots
!=
1
||
(
re
+
1
)
%
3
!=
id_offset
)
{
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
1
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
1
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
1
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
1
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
];
}
else
{
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
2
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
2
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
2
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
2
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
];
re
++
;
// skip pilots
*
re_allocated
=
*
re_allocated
+
1
;
}
re
++
;
// adjacent carriers are taken care of by precoding
*
re_allocated
=
*
re_allocated
+
1
;
// incremented variable but never used
}
}
}
}
else
{
// allocate first DCI
for
(
re
=
first_re
;
re
<
6
;
re
++
)
{
// re varies between 0 and 12 sub-carriers
tti_offset
=
symbol_offset
+
re
;
// symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if
(
pilots
!=
1
||
re
%
3
!=
id_offset
)
// if re is not a pilot
{
// diff_re = re%3 - id_offset;
if
(
mimo_mode
==
SISO
)
{
//SISO mapping
*
re_allocated
=
*
re_allocated
+
1
;
// variable incremented but never used
for
(
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_tx
;
aa
++
)
{
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
])[
0
]
+=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//I //b_i
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
+
6
])[
0
]
+=
(
x0
[
1
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//I //b_i
}
*
jj
=
*
jj
+
1
;
for
(
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_tx
;
aa
++
)
{
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
])[
1
]
+=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//Q //b_{i+1}
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
+
6
])[
1
]
+=
(
x0
[
1
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//Q //b_{i+1}
}
*
jj
=
*
jj
+
1
;
}
else
if
(
mimo_mode
==
ALAMOUTI
)
{
*
re_allocated
=
*
re_allocated
+
1
;
((
int16_t
*
)
&
tmp_sample1
)[
0
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
((
int16_t
*
)
&
tmp_sample3
)[
0
]
=
(
x0
[
1
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
((
int16_t
*
)
&
tmp_sample1
)[
1
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
((
int16_t
*
)
&
tmp_sample3
)[
1
]
=
(
x0
[
1
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
// second antenna position n -> -x1*
((
int16_t
*
)
&
tmp_sample2
)[
0
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
gain_lin_QPSK
)
:
-
gain_lin_QPSK
;
((
int16_t
*
)
&
tmp_sample4
)[
0
]
=
(
x0
[
1
][
*
jj
]
==
1
)
?
(
gain_lin_QPSK
)
:
-
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
((
int16_t
*
)
&
tmp_sample2
)[
1
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
((
int16_t
*
)
&
tmp_sample4
)[
1
]
=
(
x0
[
1
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
// normalization for 2 tx antennas
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample1
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample1
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample2
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample2
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample3
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample3
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample4
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample4
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
// fill in the rest of the ALAMOUTI precoding
if
(
pilots
!=
1
||
(
re
+
1
)
%
3
!=
id_offset
)
{
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
1
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
1
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
1
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
1
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
+
1
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
+
1
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
+
1
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
+
1
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
])[
1
];
}
else
{
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
2
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
2
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
2
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
2
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
+
2
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
+
2
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
+
2
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
+
2
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
])[
1
];
re
++
;
// skip pilots
*
re_allocated
=
*
re_allocated
+
1
;
}
re
++
;
// adjacent carriers are taken care of by precoding
*
re_allocated
=
*
re_allocated
+
1
;
// incremented variable but never used
}
}
}
}
return
(
0
);
}
int
dci_modulation_NB_IoT
(
int32_t
**
txdataF
,
int16_t
amp
,
NB_IOT_DL_FRAME_PARMS
*
frame_parms
,
uint8_t
control_region_size
,
// control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
uint8_t
*
e
[
2
],
// Input data
int
G
,
// number of bits per subframe
unsigned
short
NB_IoT_RB_ID
uint8_t
dci_number
,
// This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t
agr_level
)
// Aggregation level
{
uint32_t
jj
=
0
;
uint32_t
re_allocated
,
symbol_offset
;
uint16_t
l
;
uint8_t
id_offset
,
pilots
=
0
;
unsigned
short
bandwidth_even_odd
;
unsigned
short
NB_IoT_start
,
RB_IoT_ID
;
re_allocated
=
0
;
id_offset
=
0
;
// testing if the total number of RBs is even or odd
bandwidth_even_odd
=
frame_parms
->
N_RB_DL
%
2
;
// 0 even, 1 odd
RB_IoT_ID
=
NB_IoT_RB_ID
;
// step 5, 6, 7 // modulation and mapping (slot 1, symbols 0..3)
for
(
l
=
control_region_size
;
l
<
14
;
l
++
)
{
// loop on OFDM symbols
if
((
l
>=
4
&&
l
<=
8
)
||
(
l
>=
11
&&
l
<=
13
))
{
pilots
=
1
;
}
else
{
pilots
=
0
;
}
id_offset
=
frame_parms
->
Nid_cell
%
3
;
// Cell_ID_NB_IoT % 3
if
(
RB_IoT_ID
<
(
frame_parms
->
N_RB_DL
/
2
))
{
NB_IoT_start
=
frame_parms
->
ofdm_symbol_size
-
12
*
(
frame_parms
->
N_RB_DL
/
2
)
-
(
bandwidth_even_odd
*
6
)
+
12
*
(
RB_IoT_ID
%
(
ceil
(
frame_parms
->
N_RB_DL
/
(
float
)
2
)));
}
else
{
NB_IoT_start
=
(
bandwidth_even_odd
*
6
)
+
12
*
(
RB_IoT_ID
%
(
ceil
(
frame_parms
->
N_RB_DL
/
(
float
)
2
)));
}
symbol_offset
=
frame_parms
->
ofdm_symbol_size
*
l
+
NB_IoT_start
;
// symbol_offset = 512 * L + NB_IOT_RB start
dci_allocate_REs_in_RB_NB_IoT
(
frame_parms
,
txdataF
,
&
jj
,
symbol_offset
,
&
e
,
pilots
,
amp
,
id_offset
,
&
re_allocated
,
dci_number
,
agr_level
);
}
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT);
return
(
re_allocated
);
}
//*******************************************************************************************************
//*******************************************************************************************************
//********************************** Michele code *******************************************************
//*******************************************************************************************************
//*******************************************************************************************************
//*******************************************************************************************************
uint8_t
generate_dci_top_NB
(
uint8_t
Num_dci
,
DCI_ALLOC_NB_t
*
dci_alloc
,
int16_t
amp
,
NB_DL_FRAME_PARMS
*
fp
,
//NB_IoT_eNB_NPDCCH_t npdcch,
int32_t
**
txdataF
,
uint32_t
subframe
)
{
int
i
,
L
,
G
;
int
npdcch_start_index
;
/* PARAMETERS may not needed
**e_ptr : store the encoding result, and as a input to modulation
*num_pdcch_symbols : to calculate the resource allocation for pdcch
*L = aggregation level (there is 2 (at most) in NB-IoT) (Note this is not the real value but the index)
*lprime,kprime,kprime_mod12,mprime,nsymb,symbol_offset,tti_offset,re_offset : used in the REG allocation
*gain_lin_QPSK,yseq0[Msymb],yseq1[Msymb],*y[2] : used in the modulation
*mi = used in interleaving
*e = used to store the taus sequence (taus sequence is used to generate the first sequence for DCI) Turbo coding
*wbar used in the interleaving and also REG allocation
*/
//num_pdcch_symbols = get_num_pdcch_symbols(num_ue_spec_dci+num_common_dci,dci_alloc,frame_parms,subframe);
// generate DCIs in order of decreasing aggregation level, then common/ue spec
// MAC is assumed to have ordered the UE spec DCI according to the RNTI-based randomization???
// Value of aggregation level (FAPI/NFAPI specs v.9.0 pag 221 value 1,2)
for
(
L
=
2
;
L
>=
1
;
L
--
)
{
for
(
i
=
0
;
i
<
Num_dci
;
i
++
)
{
//XXX should be checked how the scheduler store the aggregation level for NB-IoT (value 1-2 or 0-1)
if
(
dci_alloc
[
i
].
L
==
(
uint8_t
)
L
)
{
if
(
dci_alloc
[
i
].
firstCCE
>=
0
)
{
//NB-IoT encoding
/*npdcch_encoding_NB_IoT(dci_alloc[i].dci_pdu,
frame_parms,
npdcch, //see when function dci_top is called
//no frame
subframe
//rm_stats, te_stats, i_stats
);*/
}
}
}
}
//NB-IoT scrambling
/*
*
* TS 36.213 ch 16.6.1
* npdcch_start_index indicate the starting OFDM symbol for NPDCCH in the first slot of a subframe k ad is determined as follow:
* - if eutracontrolregionsize is present (defined for in-band operating mode (mode 0,1 for FAPI specs))
* npdcch_start_index = eutracontrolregionsize (value 1,2,3) [units in number of OFDM symbol]
* -otherwise
* npdcch_start_index = 0
*
*Depending on npddch_start_index then we define different values for G
*/
//XXX the setting of this npdcch_start_index parameter should be done in the MAC
// if(fp->operating_mode == 0 || fp->operating_mode == 1) //in-band operating mode
// {
// npdcch_start_index = fp->control_region_size;
// }
// else
// {
// npdcch_start_index = 0;
// }
for
(
int
i
=
0
;
i
<
Num_dci
;
i
++
)
{
switch
(
dci_alloc
[
i
].
npdcch_start_symbol
)
//mail Bcom matthieu
{
case
0
:
G
=
304
;
break
;
case
1
:
G
=
240
;
break
;
case
2
:
G
=
224
;
break
;
case
3
:
G
=
200
;
break
;
default:
LOG_E
(
PHY
,
"npdcch_start_index has unwanted value
\n
"
);
break
;
}
// // NB-IoT scrambling
// npdcch_scrambling_NB_IoT(
// frame_parms,
// npdcch,
// //G,
// //q = nf mod 2 (TS 36.211 ch 10.2.3.1) with nf = number of frame
// //slot_id
// );
}
// //NB-IoT modulation
// npdcch_modulation_NB_IoT(
// txdataF,
// AMP,
// frame_parms,
// //no symbol
// //npdcch0???
// //RB_ID --> statically get from the higher layer (may included in the dl_frame params)
// );
//in NB-IoT the interleaving is done directly with the encoding procedure
//there is no interleaving because we don't apply turbo coding
// This is the REG allocation algorithm from 36-211
//already done in the modulation in our NB-IoT implementaiton??
//*******************************************************************************************************
//*******************************************************************************************************
//*******************************************************************************************************
//*******************************************************************************************************
//*******************************************************************************************************
return
0
;
}
openair1/PHY/LTE_TRANSPORT/dci_nb_iot.c
View file @
637ab8cb
...
...
@@ -43,6 +43,419 @@
#include "assertions.h"
#include "T.h"
//------------------------------------------------
// BCOM code functions npdcch start
//------------------------------------------------
static
uint8_t
d
[
2
][
3
*
(
MAX_DCI_SIZE_BITS_NB_IOT
+
16
)
+
96
];
static
uint8_t
w
[
2
][
3
*
3
*
(
MAX_DCI_SIZE_BITS_NB_IOT
+
16
)];
void
dci_encoding_NB_IoT
(
uint8_t
*
a
[
2
],
// Table of two DCI, even if one DCI is to transmit , the number of DCI is indicated in dci_number
uint8_t
A
,
// Length of table a
uint16_t
E
,
// E should equals to G (number of available bits in one RB)
uint8_t
*
e
[
2
],
// *e should be e[2][G]
uint16_t
rnti
[
2
],
// RNTI for UE specific or common search space
uint8_t
dci_number
,
// This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t
agr_level
)
// Aggregation level
{
uint8_t
D
=
(
A
+
16
);
uint32_t
RCC
;
uint8_t
occupation_size
=
1
;
// encode dci
if
(
dci_number
==
1
)
{
if
(
agr_level
==
2
)
{
occupation_size
=
1
;
}
else
{
occupation_size
=
2
;
}
memset
((
void
*
)
d
[
0
],
LTE_NULL
,
96
);
ccode_encode_NB_IoT
(
A
,
2
,
a
[
0
],
d
[
0
]
+
96
,
rnti
[
0
]);
// CRC attachement & Tail-biting convolutional coding
RCC
=
sub_block_interleaving_cc_NB_IoT
(
D
,
d
[
0
]
+
96
,
w
[
0
]);
// Interleaving
lte_rate_matching_cc_NB_IoT
(
RCC
,(
E
/
occupation_size
),
w
[
0
],
e
[
0
]);
// Rate Matching
}
else
if
(
dci_number
==
2
)
{
memset
((
void
*
)
d
[
0
],
LTE_NULL
,
96
);
memset
((
void
*
)
d
[
1
],
LTE_NULL
,
96
);
// first DCI encoding
ccode_encode_NB_IoT
(
A
,
2
,
a
[
0
],
d
[
0
]
+
96
,
rnti
[
0
]);
// CRC attachement & Tail-biting convolutional coding
RCC
=
sub_block_interleaving_cc_NB_IoT
(
D
,
d
[
0
]
+
96
,
w
[
0
]);
// interleaving
lte_rate_matching_cc_NB_IoT
(
RCC
,
E
/
2
,
w
[
0
],
e
[
0
]);
// Rate Matching , E/2 , NCCE0
// second DCI encoding
ccode_encode_NB_IoT
(
A
,
2
,
a
[
1
],
d
[
1
]
+
96
,
rnti
[
1
]);
// CRC attachement & Tail-biting convolutional coding
RCC
=
sub_block_interleaving_cc_NB_IoT
(
D
,
d
[
1
]
+
96
,
w
[
1
]);
// Interleaving
lte_rate_matching_cc_NB_IoT
(
RCC
,
E
/
2
,
w
[
1
],
e
[
1
]);
// Rate Matching, E/2 , NCCE1
}
}
///The scrambling sequence shall be initialised at the start of the search space and after every 4th NPDCCH subframes.
///
///
void
npdcch_scrambling_NB_IoT
(
NB_IOT_DL_FRAME_PARMS
*
frame_parms
,
uint8_t
*
e
[
2
],
// Input data
int
length
,
// Total number of bits to transmit in one subframe(case of DCI = G)
uint8_t
Ns
,
// Slot number (0..19)
uint8_t
dci_number
,
// This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t
agr_level
)
// Aggregation level
{
int
i
,
j
,
k
=
0
;
uint32_t
x1
,
x2
,
s
=
0
;
uint8_t
reset
;
reset
=
1
;
uint8_t
occupation_size
=
1
;
if
(
agr_level
==
2
)
{
occupation_size
=
1
;
}
else
{
occupation_size
=
2
;
}
if
(
dci_number
==
1
)
// Case of one DCI
{
x2
=
((
Ns
>>
1
)
<<
9
)
+
frame_parms
->
Nid_cell
;
// This is c_init in 36.211 Sec 10.2.3.1
for
(
i
=
0
;
i
<
length
/
occupation_size
;
i
++
)
{
if
((
i
&
0x1f
)
==
0
)
{
s
=
lte_gold_generic_NB_IoT
(
&
x1
,
&
x2
,
reset
);
reset
=
0
;
}
e
[
0
][
k
]
=
(
e
[
0
][
k
]
&
1
)
^
((
s
>>
(
i
&
0x1f
))
&
1
);
}
}
else
if
(
dci_number
==
2
&&
occupation_size
==
2
)
{
// Case of two DCI
// Scrambling the first DCI
//
x2
=
((
Ns
>>
1
)
<<
9
)
+
frame_parms
->
Nid_cell
;
// This is c_init in 36.211 Sec 10.2.3.1
for
(
i
=
0
;
i
<
length
/
occupation_size
;
i
++
)
{
if
((
i
&
0x1f
)
==
0
)
{
s
=
lte_gold_generic_NB_IoT
(
&
x1
,
&
x2
,
reset
);
reset
=
0
;
}
e
[
0
][
k
]
=
(
e
[
0
][
k
]
&
1
)
^
((
s
>>
(
i
&
0x1f
))
&
1
);
}
// reset of the scrambling function
reset
=
1
;
// Scrambling the second DCI
//
x2
=
((
Ns
>>
1
)
<<
9
)
+
frame_parms
->
Nid_cell
;
//this is c_init in 36.211 Sec 10.2.3.1
for
(
i
=
0
;
i
<
length
/
occupation_size
;
i
++
)
{
if
((
i
&
0x1f
)
==
0
)
{
s
=
lte_gold_generic_NB_IoT
(
&
x1
,
&
x2
,
reset
);
reset
=
0
;
}
e
[
1
][
k
]
=
(
e
[
1
][
k
]
&
1
)
^
((
s
>>
(
i
&
0x1f
))
&
1
);
}
}
}
int
dci_allocate_REs_in_RB_NB_IoT
(
NB_IOT_DL_FRAME_PARMS
*
frame_parms
,
int32_t
**
txdataF
,
uint32_t
*
jj
,
uint32_t
symbol_offset
,
uint8_t
*
x0
[
2
],
uint8_t
pilots
,
int16_t
amp
,
unsigned
short
id_offset
,
uint32_t
*
re_allocated
,
// not used variable ??!!
uint8_t
dci_number
,
// This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t
agr_level
)
{
MIMO_mode_t
mimo_mode
=
(
frame_parms
->
mode1_flag
==
1
)
?
SISO
:
ALAMOUTI
;
uint32_t
tti_offset
,
aa
;
uint8_t
re
,
diff_re
;
int16_t
gain_lin_QPSK
;
uint8_t
first_re
,
last_re
;
int32_t
tmp_sample1
,
tmp_sample2
,
tmp_sample3
,
tmp_sample4
;
gain_lin_QPSK
=
(
int16_t
)((
amp
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
first_re
=
0
;
last_re
=
12
;
if
(
agr_level
==
2
&&
dci_number
==
1
)
{
for
(
re
=
first_re
;
re
<
last_re
;
re
++
)
{
// re varies between 0 and 12 sub-carriers
tti_offset
=
symbol_offset
+
re
;
// symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if
(
pilots
!=
1
||
re
%
3
!=
id_offset
)
// if re is not a pilot
{
// diff_re = re%3 - id_offset;
if
(
mimo_mode
==
SISO
)
{
//SISO mapping
*
re_allocated
=
*
re_allocated
+
1
;
// variable incremented but never used
for
(
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_tx
;
aa
++
)
{
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
])[
0
]
+=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//I //b_i
}
*
jj
=
*
jj
+
1
;
for
(
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_tx
;
aa
++
)
{
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
])[
1
]
+=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//Q //b_{i+1}
}
*
jj
=
*
jj
+
1
;
}
else
if
(
mimo_mode
==
ALAMOUTI
)
{
*
re_allocated
=
*
re_allocated
+
1
;
((
int16_t
*
)
&
tmp_sample1
)[
0
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
((
int16_t
*
)
&
tmp_sample1
)[
1
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
// second antenna position n -> -x1*
((
int16_t
*
)
&
tmp_sample2
)[
0
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
gain_lin_QPSK
)
:
-
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
((
int16_t
*
)
&
tmp_sample2
)[
1
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
// normalization for 2 tx antennas
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample1
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample1
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample2
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample2
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
// fill in the rest of the ALAMOUTI precoding
if
(
pilots
!=
1
||
(
re
+
1
)
%
3
!=
id_offset
)
{
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
1
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
1
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
1
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
1
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
];
}
else
{
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
2
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
2
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
2
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
2
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
];
re
++
;
// skip pilots
*
re_allocated
=
*
re_allocated
+
1
;
}
re
++
;
// adjacent carriers are taken care of by precoding
*
re_allocated
=
*
re_allocated
+
1
;
// incremented variable but never used
}
}
}
}
else
if
(
agr_level
==
1
&&
dci_number
==
1
){
for
(
re
=
first_re
;
re
<
6
;
re
++
)
{
// re varies between 0 and 6 sub-carriers
tti_offset
=
symbol_offset
+
re
;
// symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if
(
pilots
!=
1
||
re
%
3
!=
id_offset
)
// if re is not a pilot
{
// diff_re = re%3 - id_offset;
if
(
mimo_mode
==
SISO
)
{
//SISO mapping
*
re_allocated
=
*
re_allocated
+
1
;
// variable incremented but never used
for
(
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_tx
;
aa
++
)
{
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
])[
0
]
+=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//I //b_i
}
*
jj
=
*
jj
+
1
;
for
(
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_tx
;
aa
++
)
{
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
])[
1
]
+=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//Q //b_{i+1}
}
*
jj
=
*
jj
+
1
;
}
else
if
(
mimo_mode
==
ALAMOUTI
)
{
*
re_allocated
=
*
re_allocated
+
1
;
((
int16_t
*
)
&
tmp_sample1
)[
0
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
((
int16_t
*
)
&
tmp_sample1
)[
1
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
// second antenna position n -> -x1*
((
int16_t
*
)
&
tmp_sample2
)[
0
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
gain_lin_QPSK
)
:
-
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
((
int16_t
*
)
&
tmp_sample2
)[
1
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
// normalization for 2 tx antennas
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample1
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample1
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample2
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample2
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
// fill in the rest of the ALAMOUTI precoding
if
(
pilots
!=
1
||
(
re
+
1
)
%
3
!=
id_offset
)
{
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
1
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
1
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
1
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
1
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
];
}
else
{
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
2
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
2
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
2
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
2
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
];
re
++
;
// skip pilots
*
re_allocated
=
*
re_allocated
+
1
;
}
re
++
;
// adjacent carriers are taken care of by precoding
*
re_allocated
=
*
re_allocated
+
1
;
// incremented variable but never used
}
}
}
}
else
{
// allocate first DCI
for
(
re
=
first_re
;
re
<
6
;
re
++
)
{
// re varies between 0 and 12 sub-carriers
tti_offset
=
symbol_offset
+
re
;
// symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if
(
pilots
!=
1
||
re
%
3
!=
id_offset
)
// if re is not a pilot
{
// diff_re = re%3 - id_offset;
if
(
mimo_mode
==
SISO
)
{
//SISO mapping
*
re_allocated
=
*
re_allocated
+
1
;
// variable incremented but never used
for
(
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_tx
;
aa
++
)
{
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
])[
0
]
+=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//I //b_i
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
+
6
])[
0
]
+=
(
x0
[
1
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//I //b_i
}
*
jj
=
*
jj
+
1
;
for
(
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_tx
;
aa
++
)
{
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
])[
1
]
+=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//Q //b_{i+1}
((
int16_t
*
)
&
txdataF
[
aa
][
tti_offset
+
6
])[
1
]
+=
(
x0
[
1
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
//Q //b_{i+1}
}
*
jj
=
*
jj
+
1
;
}
else
if
(
mimo_mode
==
ALAMOUTI
)
{
*
re_allocated
=
*
re_allocated
+
1
;
((
int16_t
*
)
&
tmp_sample1
)[
0
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
((
int16_t
*
)
&
tmp_sample3
)[
0
]
=
(
x0
[
1
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
((
int16_t
*
)
&
tmp_sample1
)[
1
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
((
int16_t
*
)
&
tmp_sample3
)[
1
]
=
(
x0
[
1
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
// second antenna position n -> -x1*
((
int16_t
*
)
&
tmp_sample2
)[
0
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
gain_lin_QPSK
)
:
-
gain_lin_QPSK
;
((
int16_t
*
)
&
tmp_sample4
)[
0
]
=
(
x0
[
1
][
*
jj
]
==
1
)
?
(
gain_lin_QPSK
)
:
-
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
((
int16_t
*
)
&
tmp_sample2
)[
1
]
=
(
x0
[
0
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
((
int16_t
*
)
&
tmp_sample4
)[
1
]
=
(
x0
[
1
][
*
jj
]
==
1
)
?
(
-
gain_lin_QPSK
)
:
gain_lin_QPSK
;
*
jj
=*
jj
+
1
;
// normalization for 2 tx antennas
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample1
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample1
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample2
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample2
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample3
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample3
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
])[
0
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample4
)[
0
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
])[
1
]
+=
(
int16_t
)((((
int16_t
*
)
&
tmp_sample4
)[
1
]
*
ONE_OVER_SQRT2_Q15
)
>>
15
);
// fill in the rest of the ALAMOUTI precoding
if
(
pilots
!=
1
||
(
re
+
1
)
%
3
!=
id_offset
)
{
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
1
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
1
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
1
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
1
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
+
1
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
+
1
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
+
1
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
+
1
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
])[
1
];
}
else
{
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
2
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
2
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
2
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
2
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
])[
1
];
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
+
2
])[
0
]
+=
-
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
])[
0
];
//x1
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
+
2
])[
1
]
+=
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
])[
1
];
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
+
2
])[
0
]
+=
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
])[
0
];
//x0*
((
int16_t
*
)
&
txdataF
[
1
][
tti_offset
+
6
+
2
])[
1
]
+=
-
((
int16_t
*
)
&
txdataF
[
0
][
tti_offset
+
6
])[
1
];
re
++
;
// skip pilots
*
re_allocated
=
*
re_allocated
+
1
;
}
re
++
;
// adjacent carriers are taken care of by precoding
*
re_allocated
=
*
re_allocated
+
1
;
// incremented variable but never used
}
}
}
}
return
(
0
);
}
int
dci_modulation_NB_IoT
(
int32_t
**
txdataF
,
int16_t
amp
,
NB_IOT_DL_FRAME_PARMS
*
frame_parms
,
uint8_t
control_region_size
,
// control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
uint8_t
*
e
[
2
],
// Input data
int
G
,
// number of bits per subframe
unsigned
short
NB_IoT_RB_ID
,
uint8_t
dci_number
,
// This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t
agr_level
)
// Aggregation level
{
uint32_t
jj
=
0
;
uint32_t
re_allocated
,
symbol_offset
;
uint16_t
l
;
uint8_t
id_offset
,
pilots
=
0
;
unsigned
short
bandwidth_even_odd
;
unsigned
short
NB_IoT_start
,
RB_IoT_ID
;
re_allocated
=
0
;
id_offset
=
0
;
// testing if the total number of RBs is even or odd
bandwidth_even_odd
=
frame_parms
->
N_RB_DL
%
2
;
// 0 even, 1 odd
RB_IoT_ID
=
NB_IoT_RB_ID
;
// step 5, 6, 7 // modulation and mapping (slot 1, symbols 0..3)
for
(
l
=
control_region_size
;
l
<
14
;
l
++
)
{
// loop on OFDM symbols
if
((
l
>=
4
&&
l
<=
8
)
||
(
l
>=
11
&&
l
<=
13
))
{
pilots
=
1
;
}
else
{
pilots
=
0
;
}
id_offset
=
frame_parms
->
Nid_cell
%
3
;
// Cell_ID_NB_IoT % 3
if
(
RB_IoT_ID
<
(
frame_parms
->
N_RB_DL
/
2
))
{
NB_IoT_start
=
frame_parms
->
ofdm_symbol_size
-
12
*
(
frame_parms
->
N_RB_DL
/
2
)
-
(
bandwidth_even_odd
*
6
)
+
12
*
(
RB_IoT_ID
%
(
ceil
(
frame_parms
->
N_RB_DL
/
(
float
)
2
)));
}
else
{
NB_IoT_start
=
(
bandwidth_even_odd
*
6
)
+
12
*
(
RB_IoT_ID
%
(
ceil
(
frame_parms
->
N_RB_DL
/
(
float
)
2
)));
}
symbol_offset
=
frame_parms
->
ofdm_symbol_size
*
l
+
NB_IoT_start
;
// symbol_offset = 512 * L + NB_IOT_RB start
dci_allocate_REs_in_RB_NB_IoT
(
frame_parms
,
txdataF
,
&
jj
,
symbol_offset
,
&
e
,
pilots
,
amp
,
id_offset
,
&
re_allocated
,
dci_number
,
agr_level
);
}
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT);
return
(
re_allocated
);
}
//------------------------------------------------
// BCOM code functions npdcch end
//------------------------------------------------
uint8_t
generate_dci_top_NB
(
uint8_t
Num_dci
,
DCI_ALLOC_NB_t
*
dci_alloc
,
int16_t
amp
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment