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
zzha zzha
OpenXG-RAN
Commits
d62de356
Commit
d62de356
authored
Mar 14, 2019
by
Javier Morgade
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
FeMBMS preliminary PMCH procedures (de-mapper)
parent
b052dbb9
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
700 additions
and
5 deletions
+700
-5
openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c
openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c
+700
-5
No files found.
openair1/PHY/LTE_UE_TRANSPORT/pmch_ue.c
View file @
d62de356
...
...
@@ -132,6 +132,38 @@ void fill_UE_dlsch_MCH(PHY_VARS_UE *ue,int mcs,int ndi,int rvidx,int eNB_id)
}
}
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
void
mch_extract_rbs_khz_1dot25
(
int
**
rxdataF
,
int
**
dl_ch_estimates
,
int
**
rxdataF_ext
,
int
**
dl_ch_estimates_ext
,
/*unsigned char symbol,*/
unsigned
char
subframe
,
LTE_DL_FRAME_PARMS
*
frame_parms
)
{
int
i
,
j
,
offset
,
aarx
,
numext
;
if
(
(
subframe
&
0x1
)
==
0
){
offset
=
0
;
}
else
{
offset
=
3
;
}
numext
=
0
;
for
(
aarx
=
0
;
aarx
<
frame_parms
->
nb_antennas_rx
;
aarx
++
)
{
for
(
i
=
0
,
j
=
0
;
i
<
frame_parms
->
N_RB_DL
*
72
;
i
++
)
{
if
(
(
i
%
6
)
!=
0
){
rxdataF_ext
[
aarx
][
j
+
0
]
=
rxdataF
[
aarx
][
i
+
4344
+
0
];
rxdataF_ext
[
aarx
][(
frame_parms
->
N_RB_DL
*
60
)
+
j
+
0
]
=
rxdataF
[
aarx
][
i
+
1
+
0
];
//DC
dl_ch_estimates_ext
[
aarx
][
j
+
0
]
=
dl_ch_estimates
[
aarx
][
i
+
0
];
dl_ch_estimates_ext
[
aarx
][(
frame_parms
->
N_RB_DL
*
60
)
+
j
+
0
]
=
dl_ch_estimates
[
aarx
][
i
+
(
frame_parms
->
N_RB_DL
*
72
)
+
0
];
numext
+=
2
;
j
++
;
}
}
}
}
#endif
void
mch_extract_rbs
(
int
**
rxdataF
,
...
...
@@ -145,7 +177,6 @@ void mch_extract_rbs(int **rxdataF,
int
pilots
=
0
,
i
,
j
,
offset
,
aarx
;
// printf("Extracting PMCH: symbol %d\n",symbol);
if
((
symbol
==
2
)
||
(
symbol
==
10
))
{
pilots
=
1
;
...
...
@@ -240,6 +271,62 @@ void mch_channel_level(int **dl_ch_estimates_ext,
#endif
}
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
void
mch_channel_level_khz_1dot25
(
int
**
dl_ch_estimates_ext
,
LTE_DL_FRAME_PARMS
*
frame_parms
,
int
*
avg
,
/*uint8_t symbol,*/
unsigned
short
nb_rb
)
{
int
i
,
aarx
,
nre
;
#if defined(__x86_64__) || defined(__i386__)
__m128i
*
dl_ch128
,
avg128
;
#elif defined(__arm__)
int32x4_t
avg128
;
#endif
for
(
aarx
=
0
;
aarx
<
frame_parms
->
nb_antennas_rx
;
aarx
++
)
{
#if defined(__x86_64__) || defined(__i386__)
//clear average level
avg128
=
_mm_setzero_si128
();
// 5 is always a symbol with no pilots for both normal and extended prefix
dl_ch128
=
(
__m128i
*
)
&
dl_ch_estimates_ext
[
aarx
][
0
/*symbol*frame_parms->N_RB_DL*12*/
];
#elif defined(__arm__)
#endif
/*if ((symbol == 2) || (symbol == 6) || (symbol == 10))
nre = (frame_parms->N_RB_DL*6);
else
nre = (frame_parms->N_RB_DL*12);*/
nre
=
frame_parms
->
N_RB_DL
*
12
*
10
;
//nre = frame_parms->N_RB_DL*12;
for
(
i
=
0
;
i
<
(
nre
>>
2
);
i
++
)
{
#if defined(__x86_64__) || defined(__i386__)
avg128
=
_mm_add_epi32
(
avg128
,
_mm_madd_epi16
(
dl_ch128
[
0
],
dl_ch128
[
0
]));
#elif defined(__arm__)
#endif
}
avg
[
aarx
]
=
(((
int
*
)
&
avg128
)[
0
]
+
((
int
*
)
&
avg128
)[
1
]
+
((
int
*
)
&
avg128
)[
2
]
+
((
int
*
)
&
avg128
)[
3
])
/
nre
;
//printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty
();
_m_empty
();
#endif
}
#endif
void
mch_channel_compensation
(
int
**
rxdataF_ext
,
int
**
dl_ch_estimates_ext
,
int
**
dl_ch_mag
,
...
...
@@ -389,6 +476,164 @@ void mch_channel_compensation(int **rxdataF_ext,
}
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
void
mch_channel_compensation_khz_1dot25
(
int
**
rxdataF_ext
,
int
**
dl_ch_estimates_ext
,
int
**
dl_ch_mag
,
int
**
dl_ch_magb
,
int
**
rxdataF_comp
,
LTE_DL_FRAME_PARMS
*
frame_parms
,
/*unsigned char symbol,*/
unsigned
char
mod_order
,
unsigned
char
output_shift
)
{
int
aarx
,
nre
,
i
;
#if defined(__x86_64__) || defined(__i386__)
__m128i
*
dl_ch128
,
*
dl_ch_mag128
,
*
dl_ch_mag128b
,
*
rxdataF128
,
*
rxdataF_comp128
;
__m128i
mmtmpD0
,
mmtmpD1
,
mmtmpD2
,
mmtmpD3
,
QAM_amp128
,
QAM_amp128b
;
#elif defined(__arm__)
#endif
/*if ((symbol == 2) || (symbol == 6) || (symbol == 10))
nre = frame_parms->N_RB_DL*6;
else
nre = frame_parms->N_RB_DL*12;*/
nre
=
frame_parms
->
N_RB_DL
*
12
*
10
;
#if defined(__x86_64__) || defined(__i386__)
if
(
mod_order
==
4
)
{
QAM_amp128
=
_mm_set1_epi16
(
QAM16_n1
);
// 2/sqrt(10)
QAM_amp128b
=
_mm_setzero_si128
();
}
else
if
(
mod_order
==
6
)
{
QAM_amp128
=
_mm_set1_epi16
(
QAM64_n1
);
//
QAM_amp128b
=
_mm_set1_epi16
(
QAM64_n2
);
}
#elif defined(__arm__)
#endif
for
(
aarx
=
0
;
aarx
<
frame_parms
->
nb_antennas_rx
;
aarx
++
)
{
#if defined(__x86_64__) || defined(__i386__)
dl_ch128
=
(
__m128i
*
)
&
dl_ch_estimates_ext
[
aarx
][
0
];
dl_ch_mag128
=
(
__m128i
*
)
&
dl_ch_mag
[
aarx
][
0
];
dl_ch_mag128b
=
(
__m128i
*
)
&
dl_ch_magb
[
aarx
][
0
];
rxdataF128
=
(
__m128i
*
)
&
rxdataF_ext
[
aarx
][
0
];
rxdataF_comp128
=
(
__m128i
*
)
&
rxdataF_comp
[
aarx
][
0
];
#elif defined(__arm__)
#endif
for
(
i
=
0
;
i
<
(
nre
>>
2
);
i
+=
2
)
{
if
(
mod_order
>
2
)
{
// get channel amplitude if not QPSK
#if defined(__x86_64__) || defined(__i386__)
mmtmpD0
=
_mm_madd_epi16
(
dl_ch128
[
0
],
dl_ch128
[
0
]);
mmtmpD0
=
_mm_srai_epi32
(
mmtmpD0
,
output_shift
);
mmtmpD1
=
_mm_madd_epi16
(
dl_ch128
[
1
],
dl_ch128
[
1
]);
mmtmpD1
=
_mm_srai_epi32
(
mmtmpD1
,
output_shift
);
mmtmpD0
=
_mm_packs_epi32
(
mmtmpD0
,
mmtmpD1
);
// store channel magnitude here in a new field of dlsch
dl_ch_mag128
[
0
]
=
_mm_unpacklo_epi16
(
mmtmpD0
,
mmtmpD0
);
dl_ch_mag128b
[
0
]
=
dl_ch_mag128
[
0
];
dl_ch_mag128
[
0
]
=
_mm_mulhi_epi16
(
dl_ch_mag128
[
0
],
QAM_amp128
);
dl_ch_mag128
[
0
]
=
_mm_slli_epi16
(
dl_ch_mag128
[
0
],
1
);
dl_ch_mag128
[
1
]
=
_mm_unpackhi_epi16
(
mmtmpD0
,
mmtmpD0
);
dl_ch_mag128b
[
1
]
=
dl_ch_mag128
[
1
];
dl_ch_mag128
[
1
]
=
_mm_mulhi_epi16
(
dl_ch_mag128
[
1
],
QAM_amp128
);
dl_ch_mag128
[
1
]
=
_mm_slli_epi16
(
dl_ch_mag128
[
1
],
1
);
dl_ch_mag128b
[
0
]
=
_mm_mulhi_epi16
(
dl_ch_mag128b
[
0
],
QAM_amp128b
);
dl_ch_mag128b
[
0
]
=
_mm_slli_epi16
(
dl_ch_mag128b
[
0
],
1
);
dl_ch_mag128b
[
1
]
=
_mm_mulhi_epi16
(
dl_ch_mag128b
[
1
],
QAM_amp128b
);
dl_ch_mag128b
[
1
]
=
_mm_slli_epi16
(
dl_ch_mag128b
[
1
],
1
);
#elif defined(__arm__)
#endif
}
#if defined(__x86_64__) || defined(__i386__)
// multiply by conjugated channel
mmtmpD0
=
_mm_madd_epi16
(
dl_ch128
[
0
],
rxdataF128
[
0
]);
// print_ints("re",&mmtmpD0);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
mmtmpD1
=
_mm_shufflelo_epi16
(
dl_ch128
[
0
],
_MM_SHUFFLE
(
2
,
3
,
0
,
1
));
mmtmpD1
=
_mm_shufflehi_epi16
(
mmtmpD1
,
_MM_SHUFFLE
(
2
,
3
,
0
,
1
));
mmtmpD1
=
_mm_sign_epi16
(
mmtmpD1
,
*
(
__m128i
*
)
&
conjugate
[
0
]);
// print_ints("im",&mmtmpD1);
mmtmpD1
=
_mm_madd_epi16
(
mmtmpD1
,
rxdataF128
[
0
]);
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpD0
=
_mm_srai_epi32
(
mmtmpD0
,
output_shift
);
// print_ints("re(shift)",&mmtmpD0);
mmtmpD1
=
_mm_srai_epi32
(
mmtmpD1
,
output_shift
);
// print_ints("im(shift)",&mmtmpD1);
mmtmpD2
=
_mm_unpacklo_epi32
(
mmtmpD0
,
mmtmpD1
);
mmtmpD3
=
_mm_unpackhi_epi32
(
mmtmpD0
,
mmtmpD1
);
// print_ints("c0",&mmtmpD2);
// print_ints("c1",&mmtmpD3);
rxdataF_comp128
[
0
]
=
_mm_packs_epi32
(
mmtmpD2
,
mmtmpD3
);
// print_shorts("rx:",rxdataF128);
// print_shorts("ch:",dl_ch128);
// print_shorts("pack:",rxdataF_comp128);
// multiply by conjugated channel
mmtmpD0
=
_mm_madd_epi16
(
dl_ch128
[
1
],
rxdataF128
[
1
]);
// mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
mmtmpD1
=
_mm_shufflelo_epi16
(
dl_ch128
[
1
],
_MM_SHUFFLE
(
2
,
3
,
0
,
1
));
mmtmpD1
=
_mm_shufflehi_epi16
(
mmtmpD1
,
_MM_SHUFFLE
(
2
,
3
,
0
,
1
));
mmtmpD1
=
_mm_sign_epi16
(
mmtmpD1
,
*
(
__m128i
*
)
conjugate
);
mmtmpD1
=
_mm_madd_epi16
(
mmtmpD1
,
rxdataF128
[
1
]);
// mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpD0
=
_mm_srai_epi32
(
mmtmpD0
,
output_shift
);
mmtmpD1
=
_mm_srai_epi32
(
mmtmpD1
,
output_shift
);
mmtmpD2
=
_mm_unpacklo_epi32
(
mmtmpD0
,
mmtmpD1
);
mmtmpD3
=
_mm_unpackhi_epi32
(
mmtmpD0
,
mmtmpD1
);
rxdataF_comp128
[
1
]
=
_mm_packs_epi32
(
mmtmpD2
,
mmtmpD3
);
// print_shorts("rx:",rxdataF128+1);
// print_shorts("ch:",dl_ch128+1);
// print_shorts("pack:",rxdataF_comp128+1);
dl_ch128
+=
2
;
dl_ch_mag128
+=
2
;
dl_ch_mag128b
+=
2
;
rxdataF128
+=
2
;
rxdataF_comp128
+=
2
;
#elif defined(__arm__)
#endif
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty
();
_m_empty
();
#endif
}
#endif
void
mch_detection_mrc
(
LTE_DL_FRAME_PARMS
*
frame_parms
,
int
**
rxdataF_comp
,
int
**
dl_ch_mag
,
...
...
@@ -442,6 +687,65 @@ void mch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
#endif
}
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
void
mch_detection_mrc_khz_1dot25
(
LTE_DL_FRAME_PARMS
*
frame_parms
,
int
**
rxdataF_comp
,
int
**
dl_ch_mag
,
int
**
dl_ch_magb
/*,
unsigned char symbol*/
)
{
int
i
;
#if defined(__x86_64__) || defined(__i386__)
__m128i
*
rxdataF_comp128_0
,
*
rxdataF_comp128_1
,
*
dl_ch_mag128_0
,
*
dl_ch_mag128_1
,
*
dl_ch_mag128_0b
,
*
dl_ch_mag128_1b
;
#elif defined(__arm__)
int16x8_t
*
rxdataF_comp128_0
,
*
rxdataF_comp128_1
,
*
dl_ch_mag128_0
,
*
dl_ch_mag128_1
,
*
dl_ch_mag128_0b
,
*
dl_ch_mag128_1b
;
#endif
if
(
frame_parms
->
nb_antennas_rx
>
1
)
{
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0
=
(
__m128i
*
)
&
rxdataF_comp
[
0
][
0
];
rxdataF_comp128_1
=
(
__m128i
*
)
&
rxdataF_comp
[
1
][
0
];
dl_ch_mag128_0
=
(
__m128i
*
)
&
dl_ch_mag
[
0
][
0
];
dl_ch_mag128_1
=
(
__m128i
*
)
&
dl_ch_mag
[
1
][
0
];
dl_ch_mag128_0b
=
(
__m128i
*
)
&
dl_ch_magb
[
0
][
0
];
dl_ch_mag128_1b
=
(
__m128i
*
)
&
dl_ch_magb
[
1
][
0
];
#elif defined(__arm__)
rxdataF_comp128_0
=
(
int16x8_t
*
)
&
rxdataF_comp
[
0
][
0
];
rxdataF_comp128_1
=
(
int16x8_t
*
)
&
rxdataF_comp
[
1
][
0
];
dl_ch_mag128_0
=
(
int16x8_t
*
)
&
dl_ch_mag
[
0
][
0
];
dl_ch_mag128_1
=
(
int16x8_t
*
)
&
dl_ch_mag
[
1
][
0
];
dl_ch_mag128_0b
=
(
int16x8_t
*
)
&
dl_ch_magb
[
0
][
0
];
dl_ch_mag128_1b
=
(
int16x8_t
*
)
&
dl_ch_magb
[
1
][
0
];
#endif
// MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
for
(
i
=
0
;
i
<
frame_parms
->
N_RB_DL
*
30
;
i
++
)
{
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0
[
i
]
=
_mm_adds_epi16
(
_mm_srai_epi16
(
rxdataF_comp128_0
[
i
],
1
),
_mm_srai_epi16
(
rxdataF_comp128_1
[
i
],
1
));
dl_ch_mag128_0
[
i
]
=
_mm_adds_epi16
(
_mm_srai_epi16
(
dl_ch_mag128_0
[
i
],
1
),
_mm_srai_epi16
(
dl_ch_mag128_1
[
i
],
1
));
dl_ch_mag128_0b
[
i
]
=
_mm_adds_epi16
(
_mm_srai_epi16
(
dl_ch_mag128_0b
[
i
],
1
),
_mm_srai_epi16
(
dl_ch_mag128_1b
[
i
],
1
));
#elif defined(__arm__)
rxdataF_comp128_0
[
i
]
=
vhaddq_s16
(
rxdataF_comp128_0
[
i
],
rxdataF_comp128_1
[
i
]);
dl_ch_mag128_0
[
i
]
=
vhaddq_s16
(
dl_ch_mag128_0
[
i
],
dl_ch_mag128_1
[
i
]);
dl_ch_mag128_0b
[
i
]
=
vhaddq_s16
(
dl_ch_mag128_0b
[
i
],
dl_ch_mag128_1b
[
i
]);
#endif
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty
();
_m_empty
();
#endif
}
#endif
int
mch_qpsk_llr
(
LTE_DL_FRAME_PARMS
*
frame_parms
,
int
**
rxdataF_comp
,
short
*
dlsch_llr
,
...
...
@@ -468,7 +772,6 @@ int mch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
len
=
frame_parms
->
N_RB_DL
*
12
;
}
// printf("dlsch_qpsk_llr: symbol %d,len %d,pbch_pss_sss_adjust %d\n",symbol,len,pbch_pss_sss_adjust);
for
(
i
=
0
;
i
<
len
;
i
++
)
{
*
llr32
=
*
rxF
;
rxF
++
;
...
...
@@ -485,14 +788,56 @@ int mch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
return
(
0
);
}
//----------------------------------------------------------------------------------------------
// 16-QAM
//----------------------------------------------------------------------------------------------
void
mch_16qam_llr
(
LTE_DL_FRAME_PARMS
*
frame_parms
,
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
int
mch_qpsk_llr_khz_1dot25
(
LTE_DL_FRAME_PARMS
*
frame_parms
,
int
**
rxdataF_comp
,
short
*
dlsch_llr
,
int
**
dl_ch_mag
,
/*unsigned char symbol,*/
short
**
llr32p
)
{
uint32_t
*
rxF
=
(
uint32_t
*
)
&
rxdataF_comp
[
0
][
0
/*(symbol*frame_parms->N_RB_DL*12)*/
];
//uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
uint32_t
*
llr32
;
int
i
,
len
;
//if (symbol==0) {
llr32
=
(
uint32_t
*
)
dlsch_llr
;
//} else {
//llr32 = (uint32_t*)(*llr32p);
//}
//AssertFatal(llr32!=NULL,"dlsch_qpsk_llr: llr is null, symbol %d, llr32=%p\n",symbol, llr32);
AssertFatal
(
llr32
!=
NULL
,
"dlsch_qpsk_llr: llr is null, llr32=%p
\n
"
,
llr32
);
len
=
frame_parms
->
N_RB_DL
*
12
*
10
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
*
llr32
=
*
rxF
;
rxF
++
;
llr32
++
;
}
*
llr32p
=
(
short
*
)
llr32
;
#if defined(__x86_64__) || defined(__i386__)
_mm_empty
();
_m_empty
();
#endif
return
(
0
);
}
#endif
//----------------------------------------------------------------------------------------------
// 16-QAM
//----------------------------------------------------------------------------------------------
void
mch_16qam_llr
(
LTE_DL_FRAME_PARMS
*
frame_parms
,
int
**
rxdataF_comp
,
short
*
dlsch_llr
,
int
**
dl_ch_mag
,
unsigned
char
symbol
,
int16_t
**
llr32p
)
{
...
...
@@ -599,6 +944,114 @@ void mch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
#endif
}
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
void
mch_16qam_llr_khz_1dot25
(
LTE_DL_FRAME_PARMS
*
frame_parms
,
int
**
rxdataF_comp
,
short
*
dlsch_llr
,
int
**
dl_ch_mag
,
/*unsigned char symbol,*/
int16_t
**
llr32p
)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i
*
rxF
=
(
__m128i
*
)
&
rxdataF_comp
[
0
][
0
];
__m128i
*
ch_mag
;
__m128i
llr128
[
2
],
xmm0
;
uint32_t
*
llr32
;
#elif defined(__arm__)
int16x8_t
*
rxF
=
(
int16x8_t
*
)
&
rxdataF_comp
[
0
][
0
];
int16x8_t
*
ch_mag
;
int16x8_t
llr128
[
2
],
xmm0
;
int16_t
*
llr16
;
#endif
int
i
,
len
;
unsigned
char
len_mod4
=
0
;
#if defined(__x86_64__) || defined(__i386__)
//if (symbol==2) {
llr32
=
(
uint32_t
*
)
dlsch_llr
;
//} else {
//llr32 = (uint32_t*)*llr32p;
//}
#elif defined(__arm__)
//if (symbol==2) {
llr16
=
(
int16_t
*
)
dlsch_llr
;
//} else {
// llr16 = (int16_t*)*llr32p;
//}
#endif
#if defined(__x86_64__) || defined(__i386__)
ch_mag
=
(
__m128i
*
)
&
dl_ch_mag
[
0
][
0
];
#elif defined(__arm__)
ch_mag
=
(
int16x8_t
*
)
&
dl_ch_mag
[
0
][
0
];
#endif
len
=
frame_parms
->
N_RB_DL
*
12
*
10
;
// update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE)
//if (symbol==2)
*
llr32p
=
dlsch_llr
+
(
len
<<
2
);
//else
//*llr32p += (len<<2);
len_mod4
=
len
&
3
;
len
>>=
2
;
// length in quad words (4 REs)
len
+=
(
len_mod4
==
0
?
0
:
1
);
for
(
i
=
0
;
i
<
len
;
i
++
)
{
#if defined(__x86_64__) || defined(__i386__)
xmm0
=
_mm_abs_epi16
(
rxF
[
i
]);
xmm0
=
_mm_subs_epi16
(
ch_mag
[
i
],
xmm0
);
// lambda_1=y_R, lambda_2=|y_R|-|h|^2, lamda_3=y_I, lambda_4=|y_I|-|h|^2
llr128
[
0
]
=
_mm_unpacklo_epi32
(
rxF
[
i
],
xmm0
);
llr128
[
1
]
=
_mm_unpackhi_epi32
(
rxF
[
i
],
xmm0
);
llr32
[
0
]
=
((
uint32_t
*
)
&
llr128
[
0
])[
0
];
llr32
[
1
]
=
((
uint32_t
*
)
&
llr128
[
0
])[
1
];
llr32
[
2
]
=
((
uint32_t
*
)
&
llr128
[
0
])[
2
];
llr32
[
3
]
=
((
uint32_t
*
)
&
llr128
[
0
])[
3
];
llr32
[
4
]
=
((
uint32_t
*
)
&
llr128
[
1
])[
0
];
llr32
[
5
]
=
((
uint32_t
*
)
&
llr128
[
1
])[
1
];
llr32
[
6
]
=
((
uint32_t
*
)
&
llr128
[
1
])[
2
];
llr32
[
7
]
=
((
uint32_t
*
)
&
llr128
[
1
])[
3
];
llr32
+=
8
;
#elif defined(__arm__)
xmm0
=
vabsq_s16
(
rxF
[
i
]);
xmm0
=
vsubq_s16
(
ch_mag
[
i
],
xmm0
);
// lambda_1=y_R, lambda_2=|y_R|-|h|^2, lamda_3=y_I, lambda_4=|y_I|-|h|^2
llr16
[
0
]
=
vgetq_lane_s16
(
rxF
[
i
],
0
);
llr16
[
1
]
=
vgetq_lane_s16
(
xmm0
,
0
);
llr16
[
2
]
=
vgetq_lane_s16
(
rxF
[
i
],
1
);
llr16
[
3
]
=
vgetq_lane_s16
(
xmm0
,
1
);
llr16
[
4
]
=
vgetq_lane_s16
(
rxF
[
i
],
2
);
llr16
[
5
]
=
vgetq_lane_s16
(
xmm0
,
2
);
llr16
[
6
]
=
vgetq_lane_s16
(
rxF
[
i
],
2
);
llr16
[
7
]
=
vgetq_lane_s16
(
xmm0
,
3
);
llr16
[
8
]
=
vgetq_lane_s16
(
rxF
[
i
],
4
);
llr16
[
9
]
=
vgetq_lane_s16
(
xmm0
,
4
);
llr16
[
10
]
=
vgetq_lane_s16
(
rxF
[
i
],
5
);
llr16
[
11
]
=
vgetq_lane_s16
(
xmm0
,
5
);
llr16
[
12
]
=
vgetq_lane_s16
(
rxF
[
i
],
6
);
llr16
[
13
]
=
vgetq_lane_s16
(
xmm0
,
6
);
llr16
[
14
]
=
vgetq_lane_s16
(
rxF
[
i
],
7
);
llr16
[
15
]
=
vgetq_lane_s16
(
xmm0
,
7
);
llr16
+=
16
;
#endif
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty
();
_m_empty
();
#endif
}
#endif
//----------------------------------------------------------------------------------------------
// 64-QAM
//----------------------------------------------------------------------------------------------
...
...
@@ -666,10 +1119,147 @@ void mch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
xmm2
=
vsubq_s16
(
ch_magb
[
i
],
xmm2
);
#endif
// loop over all LLRs in quad word (24 coded bits)
/*
printf("pmch i: %d => mag (%d,%d) (%d,%d)\n",i,((short *)&ch_mag[i])[0],((short *)&ch_magb[i])[0],
((short *)&rxF[i])[0],((short *)&rxF[i])[1]);
for (j=0;j<8;j+=2) {
llr2[0] = ((short *)&rxF[i])[j];
llr2[1] = ((short *)&rxF[i])[j+1];
llr2[2] = _mm_extract_epi16(xmm1,j);
llr2[3] = _mm_extract_epi16(xmm1,j+1);//((short *)&xmm1)[j+1];
llr2[4] = _mm_extract_epi16(xmm2,j);//((short *)&xmm2)[j];
llr2[5] = _mm_extract_epi16(xmm2,j+1);//((short *)&xmm2)[j+1];
llr2+=6;
}
*/
llr2
[
0
]
=
((
short
*
)
&
rxF
[
i
])[
0
];
llr2
[
1
]
=
((
short
*
)
&
rxF
[
i
])[
1
];
#if defined(__x86_64__) || defined(__i386__)
llr2
[
2
]
=
_mm_extract_epi16
(
xmm1
,
0
);
llr2
[
3
]
=
_mm_extract_epi16
(
xmm1
,
1
);
//((short *)&xmm1)[j+1];
llr2
[
4
]
=
_mm_extract_epi16
(
xmm2
,
0
);
//((short *)&xmm2)[j];
llr2
[
5
]
=
_mm_extract_epi16
(
xmm2
,
1
);
//((short *)&xmm2)[j+1];
#elif defined(__arm__)
llr2
[
2
]
=
vgetq_lane_s16
(
xmm1
,
0
);
llr2
[
3
]
=
vgetq_lane_s16
(
xmm1
,
1
);
//((short *)&xmm1)[j+1];
llr2
[
4
]
=
vgetq_lane_s16
(
xmm2
,
0
);
//((short *)&xmm2)[j];
llr2
[
5
]
=
vgetq_lane_s16
(
xmm2
,
1
);
//((short *)&xmm2)[j+1];
#endif
llr2
+=
6
;
llr2
[
0
]
=
((
short
*
)
&
rxF
[
i
])[
2
];
llr2
[
1
]
=
((
short
*
)
&
rxF
[
i
])[
3
];
#if defined(__x86_64__) || defined(__i386__)
llr2
[
2
]
=
_mm_extract_epi16
(
xmm1
,
2
);
llr2
[
3
]
=
_mm_extract_epi16
(
xmm1
,
3
);
//((short *)&xmm1)[j+1];
llr2
[
4
]
=
_mm_extract_epi16
(
xmm2
,
2
);
//((short *)&xmm2)[j];
llr2
[
5
]
=
_mm_extract_epi16
(
xmm2
,
3
);
//((short *)&xmm2)[j+1];
#elif defined(__arm__)
llr2
[
2
]
=
vgetq_lane_s16
(
xmm1
,
2
);
llr2
[
3
]
=
vgetq_lane_s16
(
xmm1
,
3
);
//((short *)&xmm1)[j+1];
llr2
[
4
]
=
vgetq_lane_s16
(
xmm2
,
2
);
//((short *)&xmm2)[j];
llr2
[
5
]
=
vgetq_lane_s16
(
xmm2
,
3
);
//((short *)&xmm2)[j+1];
#endif
llr2
+=
6
;
llr2
[
0
]
=
((
short
*
)
&
rxF
[
i
])[
4
];
llr2
[
1
]
=
((
short
*
)
&
rxF
[
i
])[
5
];
#if defined(__x86_64__) || defined(__i386__)
llr2
[
2
]
=
_mm_extract_epi16
(
xmm1
,
4
);
llr2
[
3
]
=
_mm_extract_epi16
(
xmm1
,
5
);
//((short *)&xmm1)[j+1];
llr2
[
4
]
=
_mm_extract_epi16
(
xmm2
,
4
);
//((short *)&xmm2)[j];
llr2
[
5
]
=
_mm_extract_epi16
(
xmm2
,
5
);
//((short *)&xmm2)[j+1];
#elif defined(__arm__)
llr2
[
2
]
=
vgetq_lane_s16
(
xmm1
,
4
);
llr2
[
3
]
=
vgetq_lane_s16
(
xmm1
,
5
);
//((short *)&xmm1)[j+1];
llr2
[
4
]
=
vgetq_lane_s16
(
xmm2
,
4
);
//((short *)&xmm2)[j];
llr2
[
5
]
=
vgetq_lane_s16
(
xmm2
,
5
);
//((short *)&xmm2)[j+1];
#endif
llr2
+=
6
;
llr2
[
0
]
=
((
short
*
)
&
rxF
[
i
])[
6
];
llr2
[
1
]
=
((
short
*
)
&
rxF
[
i
])[
7
];
#if defined(__x86_64__) || defined(__i386__)
llr2
[
2
]
=
_mm_extract_epi16
(
xmm1
,
6
);
llr2
[
3
]
=
_mm_extract_epi16
(
xmm1
,
7
);
//((short *)&xmm1)[j+1];
llr2
[
4
]
=
_mm_extract_epi16
(
xmm2
,
6
);
//((short *)&xmm2)[j];
llr2
[
5
]
=
_mm_extract_epi16
(
xmm2
,
7
);
//((short *)&xmm2)[j+1];
#elif defined(__arm__)
llr2
[
2
]
=
vgetq_lane_s16
(
xmm1
,
6
);
llr2
[
3
]
=
vgetq_lane_s16
(
xmm1
,
7
);
//((short *)&xmm1)[j+1];
llr2
[
4
]
=
vgetq_lane_s16
(
xmm2
,
6
);
//((short *)&xmm2)[j];
llr2
[
5
]
=
vgetq_lane_s16
(
xmm2
,
7
);
//((short *)&xmm2)[j+1];
#endif
llr2
+=
6
;
}
*
llr_save
=
llr
;
#if defined(__x86_64__) || defined(__i386__)
_mm_empty
();
_m_empty
();
#endif
}
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
void
mch_64qam_llr_khz_1dot25
(
LTE_DL_FRAME_PARMS
*
frame_parms
,
int
**
rxdataF_comp
,
short
*
dlsch_llr
,
int
**
dl_ch_mag
,
int
**
dl_ch_magb
,
/*unsigned char symbol,*/
short
**
llr_save
)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i
xmm1
,
xmm2
,
*
ch_mag
,
*
ch_magb
;
__m128i
*
rxF
=
(
__m128i
*
)
&
rxdataF_comp
[
0
][
0
];
#elif defined(__arm__)
int16x8_t
xmm1
,
xmm2
,
*
ch_mag
,
*
ch_magb
;
int16x8_t
*
rxF
=
(
int16x8_t
*
)
&
rxdataF_comp
[
0
][
0
];
#endif
int
i
,
len
,
len2
;
// int j=0;
unsigned
char
len_mod4
;
short
*
llr
;
int16_t
*
llr2
;
//if (symbol==2)
llr
=
dlsch_llr
;
//else
//llr = *llr_save;
#if defined(__x86_64__) || defined(__i386__)
ch_mag
=
(
__m128i
*
)
&
dl_ch_mag
[
0
][
0
];
ch_magb
=
(
__m128i
*
)
&
dl_ch_magb
[
0
][
0
];
#elif defined(__arm__)
ch_mag
=
(
int16x8_t
*
)
&
dl_ch_mag
[
0
][
0
];
ch_magb
=
(
int16x8_t
*
)
&
dl_ch_magb
[
0
][
0
];
#endif
len
=
frame_parms
->
N_RB_DL
*
12
*
10
;
llr2
=
llr
;
llr
+=
(
len
*
6
);
len_mod4
=
len
&
3
;
len2
=
len
>>
2
;
// length in quad words (4 REs)
len2
+=
(
len_mod4
?
0
:
1
);
for
(
i
=
0
;
i
<
len2
;
i
++
)
{
#if defined(__x86_64__) || defined(__i386__)
xmm1
=
_mm_abs_epi16
(
rxF
[
i
]);
xmm1
=
_mm_subs_epi16
(
ch_mag
[
i
],
xmm1
);
xmm2
=
_mm_abs_epi16
(
xmm1
);
xmm2
=
_mm_subs_epi16
(
ch_magb
[
i
],
xmm2
);
#elif defined(__arm__)
xmm1
=
vabsq_s16
(
rxF
[
i
]);
xmm1
=
vsubq_s16
(
ch_mag
[
i
],
xmm1
);
xmm2
=
vabsq_s16
(
xmm1
);
xmm2
=
vsubq_s16
(
ch_magb
[
i
],
xmm2
);
#endif
// loop over all LLRs in quad word (24 coded bits)
/*
for (j=0;j<8;j+=2) {
...
...
@@ -748,6 +1338,8 @@ void mch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
_m_empty
();
#endif
}
#endif
int
avg_pmch
[
4
];
int
rx_pmch
(
PHY_VARS_UE
*
ue
,
...
...
@@ -762,7 +1354,6 @@ int rx_pmch(PHY_VARS_UE *ue,
LTE_UE_DLSCH_t
**
dlsch
=
&
ue
->
dlsch_MCH
[
eNB_id
];
int
avgs
,
aarx
;
//printf("*********************mch: symbol %d\n",symbol);
mch_extract_rbs
(
common_vars
->
common_vars_rx_data_per_thread
[
ue
->
current_thread_id
[
subframe
]].
rxdataF
,
common_vars
->
common_vars_rx_data_per_thread
[
ue
->
current_thread_id
[
subframe
]].
dl_ch_estimates
[
eNB_id
],
...
...
@@ -839,4 +1430,108 @@ int rx_pmch(PHY_VARS_UE *ue,
return
(
0
);
}
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
int
rx_pmch_khz_1dot25
(
PHY_VARS_UE
*
ue
,
unsigned
char
eNB_id
,
uint8_t
subframe
/*,
unsigned char symbol*/
,
int
mcs
)
// currently work around TOFIX
{
unsigned
int
symbol
;
LTE_UE_COMMON
*
common_vars
=
&
ue
->
common_vars
;
LTE_UE_PDSCH
**
pdsch_vars
=
&
ue
->
pdsch_vars_MCH
[
eNB_id
];
LTE_DL_FRAME_PARMS
*
frame_parms
=
&
ue
->
frame_parms
;
LTE_UE_DLSCH_t
**
dlsch
=
&
ue
->
dlsch_MCH
[
eNB_id
];
int
avgs
,
aarx
;
//int mcs=2;
uint32_t
Nsoft
=
1827072
;
ue
->
dlsch_MCH
[
0
]
=
new_ue_dlsch
(
1
,
8
,
Nsoft
,
MAX_TURBO_ITERATIONS_MBSFN
,
25
,
0
);
mch_extract_rbs_khz_1dot25
(
common_vars
->
common_vars_rx_data_per_thread
[
ue
->
current_thread_id
[
subframe
]].
rxdataF
,
common_vars
->
common_vars_rx_data_per_thread
[
ue
->
current_thread_id
[
subframe
]].
dl_ch_estimates
[
eNB_id
],
pdsch_vars
[
eNB_id
]
->
rxdataF_ext
,
pdsch_vars
[
eNB_id
]
->
dl_ch_estimates_ext
,
/*symbol,*/
subframe
,
frame_parms
);
//if((subframe&0x1)==0){
mch_channel_level_khz_1dot25
(
pdsch_vars
[
eNB_id
]
->
dl_ch_estimates_ext
,
frame_parms
,
avg_pmch
,
/*symbol,*/
frame_parms
->
N_RB_DL
);
//}
avgs
=
0
;
for
(
aarx
=
0
;
aarx
<
frame_parms
->
nb_antennas_rx
;
aarx
++
){
avgs
=
cmax
(
avgs
,
avg_pmch
[
aarx
]);
}
if
(
get_Qm
(
mcs
/*dlsch[0]->harq_processes[0]->mcs)==2*/
)
==
2
)
pdsch_vars
[
eNB_id
]
->
log2_maxh
=
(
log2_approx
(
avgs
)
/
2
)
;
// + 2
else
pdsch_vars
[
eNB_id
]
->
log2_maxh
=
(
log2_approx
(
avgs
)
/
2
);
// + 5;// + 2*/
mch_channel_compensation_khz_1dot25
(
pdsch_vars
[
eNB_id
]
->
rxdataF_ext
,
pdsch_vars
[
eNB_id
]
->
dl_ch_estimates_ext
,
pdsch_vars
[
eNB_id
]
->
dl_ch_mag0
,
pdsch_vars
[
eNB_id
]
->
dl_ch_magb0
,
pdsch_vars
[
eNB_id
]
->
rxdataF_comp0
,
frame_parms
,
/*symbol,*/
get_Qm
(
mcs
/*dlsch[0]->harq_processes[0]->mcs*/
),
pdsch_vars
[
eNB_id
]
->
log2_maxh
);
if
(
frame_parms
->
nb_antennas_rx
>
1
){
getchar
();
mch_detection_mrc_khz_1dot25
(
frame_parms
,
pdsch_vars
[
eNB_id
]
->
rxdataF_comp0
,
pdsch_vars
[
eNB_id
]
->
dl_ch_mag0
,
pdsch_vars
[
eNB_id
]
->
dl_ch_magb0
/*,
symbol*/
);
}
switch
(
get_Qm
(
mcs
/*dlsch[0]->harq_processes[0]->mcs*/
))
{
case
2
:
mch_qpsk_llr_khz_1dot25
(
frame_parms
,
pdsch_vars
[
eNB_id
]
->
rxdataF_comp0
,
pdsch_vars
[
eNB_id
]
->
llr
[
0
],
/*symbol,*/
pdsch_vars
[
eNB_id
]
->
llr128
);
break
;
case
4
:
mch_16qam_llr_khz_1dot25
(
frame_parms
,
pdsch_vars
[
eNB_id
]
->
rxdataF_comp0
,
pdsch_vars
[
eNB_id
]
->
llr
[
0
],
pdsch_vars
[
eNB_id
]
->
dl_ch_mag0
,
/*symbol,*/
pdsch_vars
[
eNB_id
]
->
llr128
);
break
;
case
6
:
mch_64qam_llr_khz_1dot25
(
frame_parms
,
pdsch_vars
[
eNB_id
]
->
rxdataF_comp0
,
pdsch_vars
[
eNB_id
]
->
llr
[
0
],
pdsch_vars
[
eNB_id
]
->
dl_ch_mag0
,
pdsch_vars
[
eNB_id
]
->
dl_ch_magb0
,
/*symbol,*/
pdsch_vars
[
eNB_id
]
->
llr128
);
break
;
}
return
(
0
);
}
#endif
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