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
promise
OpenXG-RAN
Commits
edfef131
Commit
edfef131
authored
Jan 31, 2018
by
laurent
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add counters for non turbo-codec part
parent
fe5058ed
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1757 additions
and
1756 deletions
+1757
-1756
openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+465
-464
openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+1230
-1228
openair1/SCHED/phy_procedures_lte_eNb.c
openair1/SCHED/phy_procedures_lte_eNb.c
+27
-28
targets/tcri/measurement_display.c
targets/tcri/measurement_display.c
+29
-28
targets/tcri/thread-pool.c
targets/tcri/thread-pool.c
+2
-6
targets/tcri/thread-pool.h
targets/tcri/thread-pool.h
+4
-2
No files found.
openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
View file @
edfef131
...
...
@@ -56,45 +56,45 @@
void
free_eNB_dlsch
(
LTE_eNB_DLSCH_t
*
dlsch
)
{
int
i
;
int
r
;
int
i
;
int
r
;
if
(
dlsch
)
{
if
(
dlsch
)
{
#ifdef DEBUG_DLSCH_FREE
printf
(
"Freeing dlsch %p
\n
"
,
dlsch
);
printf
(
"Freeing dlsch %p
\n
"
,
dlsch
);
#endif
for
(
i
=
0
;
i
<
dlsch
->
Mdlharq
;
i
++
)
{
for
(
i
=
0
;
i
<
dlsch
->
Mdlharq
;
i
++
)
{
#ifdef DEBUG_DLSCH_FREE
printf
(
"Freeing dlsch process %d
\n
"
,
i
);
printf
(
"Freeing dlsch process %d
\n
"
,
i
);
#endif
if
(
dlsch
->
harq_processes
[
i
])
{
if
(
dlsch
->
harq_processes
[
i
])
{
#ifdef DEBUG_DLSCH_FREE
printf
(
"Freeing dlsch process %d (%p)
\n
"
,
i
,
dlsch
->
harq_processes
[
i
]);
printf
(
"Freeing dlsch process %d (%p)
\n
"
,
i
,
dlsch
->
harq_processes
[
i
]);
#endif
if
(
dlsch
->
harq_processes
[
i
]
->
b
)
{
free16
(
dlsch
->
harq_processes
[
i
]
->
b
,
MAX_DLSCH_PAYLOAD_BYTES
);
dlsch
->
harq_processes
[
i
]
->
b
=
NULL
;
if
(
dlsch
->
harq_processes
[
i
]
->
b
)
{
free16
(
dlsch
->
harq_processes
[
i
]
->
b
,
MAX_DLSCH_PAYLOAD_BYTES
);
dlsch
->
harq_processes
[
i
]
->
b
=
NULL
;
#ifdef DEBUG_DLSCH_FREE
printf
(
"Freeing dlsch process %d b (%p)
\n
"
,
i
,
dlsch
->
harq_processes
[
i
]
->
b
);
printf
(
"Freeing dlsch process %d b (%p)
\n
"
,
i
,
dlsch
->
harq_processes
[
i
]
->
b
);
#endif
}
}
#ifdef DEBUG_DLSCH_FREE
printf
(
"Freeing dlsch process %d c (%p)
\n
"
,
i
,
dlsch
->
harq_processes
[
i
]
->
c
);
printf
(
"Freeing dlsch process %d c (%p)
\n
"
,
i
,
dlsch
->
harq_processes
[
i
]
->
c
);
#endif
for
(
r
=
0
;
r
<
MAX_NUM_DLSCH_SEGMENTS
;
r
++
)
{
for
(
r
=
0
;
r
<
MAX_NUM_DLSCH_SEGMENTS
;
r
++
)
{
#ifdef DEBUG_DLSCH_FREE
printf
(
"Freeing dlsch process %d c[%d] (%p)
\n
"
,
i
,
r
,
dlsch
->
harq_processes
[
i
]
->
c
[
r
]);
printf
(
"Freeing dlsch process %d c[%d] (%p)
\n
"
,
i
,
r
,
dlsch
->
harq_processes
[
i
]
->
c
[
r
]);
#endif
if
(
dlsch
->
harq_processes
[
i
]
->
c
[
r
])
{
free16
(
dlsch
->
harq_processes
[
i
]
->
c
[
r
],((
r
==
0
)
?
8
:
0
)
+
3
+
768
);
dlsch
->
harq_processes
[
i
]
->
c
[
r
]
=
NULL
;
if
(
dlsch
->
harq_processes
[
i
]
->
c
[
r
])
{
free16
(
dlsch
->
harq_processes
[
i
]
->
c
[
r
],((
r
==
0
)
?
8
:
0
)
+
3
+
768
);
dlsch
->
harq_processes
[
i
]
->
c
[
r
]
=
NULL
;
}
}
free16
(
dlsch
->
harq_processes
[
i
],
sizeof
(
LTE_DL_eNB_HARQ_t
));
...
...
@@ -114,78 +114,78 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_
LTE_eNB_DLSCH_t
*
dlsch
;
unsigned
char
exit_flag
=
0
,
i
,
r
,
aa
,
layer
;
int
re
;
unsigned
char
bw_scaling
=
1
;
switch
(
N_RB_DL
)
{
case
6
:
bw_scaling
=
16
;
break
;
case
25
:
bw_scaling
=
4
;
break
;
case
50
:
bw_scaling
=
2
;
break
;
default:
bw_scaling
=
1
;
break
;
}
dlsch
=
(
LTE_eNB_DLSCH_t
*
)
malloc16
(
sizeof
(
LTE_eNB_DLSCH_t
));
if
(
dlsch
)
{
bzero
(
dlsch
,
sizeof
(
LTE_eNB_DLSCH_t
));
dlsch
->
Kmimo
=
Kmimo
;
dlsch
->
Mdlharq
=
Mdlharq
;
dlsch
->
Mlimit
=
8
;
dlsch
->
Nsoft
=
Nsoft
;
for
(
layer
=
0
;
layer
<
4
;
layer
++
)
{
dlsch
->
ue_spec_bf_weights
[
layer
]
=
(
int32_t
**
)
malloc16
(
64
*
sizeof
(
int32_t
*
));
for
(
aa
=
0
;
aa
<
64
;
aa
++
)
{
dlsch
->
ue_spec_bf_weights
[
layer
][
aa
]
=
(
int32_t
*
)
malloc16
(
OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES
*
sizeof
(
int32_t
));
for
(
re
=
0
;
re
<
OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES
;
re
++
)
{
dlsch
->
ue_spec_bf_weights
[
layer
][
aa
][
re
]
=
0x00007fff
;
}
}
}
unsigned
char
bw_scaling
=
1
;
switch
(
N_RB_DL
)
{
case
6
:
bw_scaling
=
16
;
break
;
// NOTE: THIS HAS TO BE REVISED FOR RU, commenting to remove memory leak !!!!!
/*
dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
case
25
:
bw_scaling
=
4
;
break
;
}*/
case
50
:
bw_scaling
=
2
;
break
;
for
(
i
=
0
;
i
<
10
;
i
++
)
dlsch
->
harq_ids
[
i
]
=
Mdlharq
;
default:
bw_scaling
=
1
;
break
;
}
for
(
i
=
0
;
i
<
Mdlharq
;
i
++
)
{
dlsch
->
harq_processes
[
i
]
=
(
LTE_DL_eNB_HARQ_t
*
)
malloc16
(
sizeof
(
LTE_DL_eNB_HARQ_t
));
LOG_T
(
PHY
,
"Required mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p
\n
"
,
MAX_DLSCH_PAYLOAD_BYTES
/
bw_scaling
,
bw_scaling
,
i
,
dlsch
->
harq_processes
[
i
]);
dlsch
=
(
LTE_eNB_DLSCH_t
*
)
malloc16
(
sizeof
(
LTE_eNB_DLSCH_t
));
if
(
dlsch
->
harq_processes
[
i
])
{
bzero
(
dlsch
->
harq_processes
[
i
],
sizeof
(
LTE_DL_eNB_HARQ_t
));
// dlsch->harq_processes[i]->first_tx=1;
dlsch
->
harq_processes
[
i
]
->
b
=
(
unsigned
char
*
)
malloc16
(
MAX_DLSCH_PAYLOAD_BYTES
/
bw_scaling
);
if
(
dlsch
)
{
bzero
(
dlsch
,
sizeof
(
LTE_eNB_DLSCH_t
));
dlsch
->
Kmimo
=
Kmimo
;
dlsch
->
Mdlharq
=
Mdlharq
;
dlsch
->
Mlimit
=
8
;
dlsch
->
Nsoft
=
Nsoft
;
if
(
dlsch
->
harq_processes
[
i
]
->
b
)
{
bzero
(
dlsch
->
harq_processes
[
i
]
->
b
,
MAX_DLSCH_PAYLOAD_BYTES
/
bw_scaling
);
}
else
{
printf
(
"Can't get b
\n
"
);
exit_flag
=
1
;
for
(
layer
=
0
;
layer
<
4
;
layer
++
)
{
dlsch
->
ue_spec_bf_weights
[
layer
]
=
(
int32_t
**
)
malloc16
(
64
*
sizeof
(
int32_t
*
));
for
(
aa
=
0
;
aa
<
64
;
aa
++
)
{
dlsch
->
ue_spec_bf_weights
[
layer
][
aa
]
=
(
int32_t
*
)
malloc16
(
OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES
*
sizeof
(
int32_t
));
for
(
re
=
0
;
re
<
OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES
;
re
++
)
{
dlsch
->
ue_spec_bf_weights
[
layer
][
aa
][
re
]
=
0x00007fff
;
}
}
}
if
(
abstraction_flag
==
0
)
{
for
(
r
=
0
;
r
<
MAX_NUM_DLSCH_SEGMENTS
/
bw_scaling
;
r
++
)
{
// account for filler in first segment and CRCs for multiple segment case
dlsch
->
harq_processes
[
i
]
->
c
[
r
]
=
(
uint8_t
*
)
malloc16
(((
r
==
0
)
?
8
:
0
)
+
3
+
768
);
// NOTE: THIS HAS TO BE REVISED FOR RU, commenting to remove memory leak !!!!!
/*
dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
}*/
for
(
i
=
0
;
i
<
10
;
i
++
)
dlsch
->
harq_ids
[
i
]
=
Mdlharq
;
for
(
i
=
0
;
i
<
Mdlharq
;
i
++
)
{
dlsch
->
harq_processes
[
i
]
=
(
LTE_DL_eNB_HARQ_t
*
)
malloc16
(
sizeof
(
LTE_DL_eNB_HARQ_t
));
LOG_T
(
PHY
,
"Required mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p
\n
"
,
MAX_DLSCH_PAYLOAD_BYTES
/
bw_scaling
,
bw_scaling
,
i
,
dlsch
->
harq_processes
[
i
]);
if
(
dlsch
->
harq_processes
[
i
])
{
bzero
(
dlsch
->
harq_processes
[
i
],
sizeof
(
LTE_DL_eNB_HARQ_t
));
// dlsch->harq_processes[i]->first_tx=1;
dlsch
->
harq_processes
[
i
]
->
b
=
(
unsigned
char
*
)
malloc16
(
MAX_DLSCH_PAYLOAD_BYTES
/
bw_scaling
);
if
(
dlsch
->
harq_processes
[
i
]
->
b
)
{
bzero
(
dlsch
->
harq_processes
[
i
]
->
b
,
MAX_DLSCH_PAYLOAD_BYTES
/
bw_scaling
);
}
else
{
printf
(
"Can't get b
\n
"
);
exit_flag
=
1
;
}
if
(
abstraction_flag
==
0
)
{
for
(
r
=
0
;
r
<
MAX_NUM_DLSCH_SEGMENTS
/
bw_scaling
;
r
++
)
{
// account for filler in first segment and CRCs for multiple segment case
dlsch
->
harq_processes
[
i
]
->
c
[
r
]
=
(
uint8_t
*
)
malloc16
(((
r
==
0
)
?
8
:
0
)
+
3
+
768
);
if
(
dlsch
->
harq_processes
[
i
]
->
c
[
r
])
{
bzero
(
dlsch
->
harq_processes
[
i
]
->
c
[
r
],((
r
==
0
)
?
8
:
0
)
+
3
+
768
);
}
else
{
...
...
@@ -205,14 +205,14 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_
dlsch
->
harq_processes
[
i
]
->
round
=
0
;
}
return
(
dlsch
);
return
(
dlsch
);
}
}
}
LOG_D
(
PHY
,
"new_eNB_dlsch exit flag %d, size of %ld
\n
"
,
exit_flag
,
sizeof
(
LTE_eNB_DLSCH_t
));
free_eNB_dlsch
(
dlsch
);
return
(
NULL
);
LOG_D
(
PHY
,
"new_eNB_dlsch exit flag %d, size of %ld
\n
"
,
exit_flag
,
sizeof
(
LTE_eNB_DLSCH_t
));
free_eNB_dlsch
(
dlsch
);
return
(
NULL
);
}
...
...
@@ -222,10 +222,10 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch)
unsigned
char
Mdlharq
;
if
(
dlsch
)
{
Mdlharq
=
dlsch
->
Mdlharq
;
dlsch
->
rnti
=
0
;
dlsch
->
active
=
0
;
if
(
dlsch
)
{
Mdlharq
=
dlsch
->
Mdlharq
;
dlsch
->
rnti
=
0
;
dlsch
->
active
=
0
;
for
(
int
i
=
0
;
i
<
10
;
i
++
)
dlsch
->
harq_ids
[
i
]
=
Mdlharq
;
...
...
@@ -239,49 +239,49 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch)
}
}
}
}
}
int
dlsch_encoding_2threads0
(
te_params
*
tep
)
{
LTE_eNB_DLSCH_t
*
dlsch
=
tep
->
dlsch
;
unsigned
int
G
=
tep
->
G
;
unsigned
char
harq_pid
=
tep
->
harq_pid
;
LTE_eNB_DLSCH_t
*
dlsch
=
tep
->
dlsch
;
unsigned
int
G
=
tep
->
G
;
unsigned
char
harq_pid
=
tep
->
harq_pid
;
unsigned
short
iind
;
unsigned
short
iind
;
unsigned
short
nb_rb
=
dlsch
->
harq_processes
[
harq_pid
]
->
nb_rb
;
unsigned
int
Kr
=
0
,
Kr_bytes
,
r
,
r_offset
=
0
;
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
unsigned
short
nb_rb
=
dlsch
->
harq_processes
[
harq_pid
]
->
nb_rb
;
unsigned
int
Kr
=
0
,
Kr_bytes
,
r
,
r_offset
=
0
;
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W
,
VCD_FUNCTION_IN
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W
,
VCD_FUNCTION_IN
);
if
(
dlsch
->
harq_processes
[
harq_pid
]
->
round
==
0
)
{
// this is a new packet
if
(
dlsch
->
harq_processes
[
harq_pid
]
->
round
==
0
)
{
// this is a new packet
for
(
r
=
0
;
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
C
>>
1
;
r
++
)
{
for
(
r
=
0
;
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
C
>>
1
;
r
++
)
{
if
(
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
Cminus
)
Kr
=
dlsch
->
harq_processes
[
harq_pid
]
->
Kminus
;
else
Kr
=
dlsch
->
harq_processes
[
harq_pid
]
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
// get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
printf
(
"dlsch_coding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
}
if
(
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
Cminus
)
Kr
=
dlsch
->
harq_processes
[
harq_pid
]
->
Kminus
;
else
Kr
=
dlsch
->
harq_processes
[
harq_pid
]
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
// get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
printf
(
"dlsch_coding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
}
uint8_t
tmp
[
96
+
12
+
3
+
3
*
6144
]
=
{
0
};
...
...
@@ -299,164 +299,164 @@ int dlsch_encoding_2threads0(te_params *tep) {
sub_block_interleaving_turbo
(
4
+
(
Kr_bytes
*
8
),
tmp
+
96
,
//&dlsch->harq_processes[harq_pid]->d[r][96],
dlsch
->
harq_processes
[
harq_pid
]
->
w
[
r
]);
}
}
}
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
// outputs for each code segment, see Section 5.1.5 p.20
for
(
r
=
0
;
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
C
>>
1
;
r
++
)
{
r_offset
+=
lte_rate_matching_turbo
(
dlsch
->
harq_processes
[
harq_pid
]
->
RTC
[
r
],
G
,
//G
dlsch
->
harq_processes
[
harq_pid
]
->
w
[
r
],
dlsch
->
harq_processes
[
harq_pid
]
->
e
+
r_offset
,
dlsch
->
harq_processes
[
harq_pid
]
->
C
,
// C
dlsch
->
Nsoft
,
// Nsoft,
dlsch
->
Mdlharq
,
dlsch
->
Kmimo
,
dlsch
->
harq_processes
[
harq_pid
]
->
rvidx
,
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
,
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
,
r
,
nb_rb
);
// m); // r
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W
,
VCD_FUNCTION_OUT
);
return
(
0
);
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
// outputs for each code segment, see Section 5.1.5 p.20
for
(
r
=
0
;
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
C
>>
1
;
r
++
)
{
r_offset
+=
lte_rate_matching_turbo
(
dlsch
->
harq_processes
[
harq_pid
]
->
RTC
[
r
],
G
,
//G
dlsch
->
harq_processes
[
harq_pid
]
->
w
[
r
],
dlsch
->
harq_processes
[
harq_pid
]
->
e
+
r_offset
,
dlsch
->
harq_processes
[
harq_pid
]
->
C
,
// C
dlsch
->
Nsoft
,
// Nsoft,
dlsch
->
Mdlharq
,
dlsch
->
Kmimo
,
dlsch
->
harq_processes
[
harq_pid
]
->
rvidx
,
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
,
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
,
r
,
nb_rb
);
// m); // r
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W
,
VCD_FUNCTION_OUT
);
return
(
0
);
}
extern
int
oai_exit
;
void
*
te_thread
(
void
*
param
)
{
pthread_setname_np
(
pthread_self
(),
"te processing"
);
LOG_I
(
PHY
,
"thread te created id=%ld"
,
syscall
(
__NR_gettid
));
pthread_setname_np
(
pthread_self
(),
"te processing"
);
LOG_I
(
PHY
,
"thread te created id=%ld"
,
syscall
(
__NR_gettid
));
eNB_proc_t
*
proc
=
&
((
te_params
*
)
param
)
->
eNB
->
proc
;
while
(
!
oai_exit
)
{
eNB_proc_t
*
proc
=
&
((
te_params
*
)
param
)
->
eNB
->
proc
;
while
(
!
oai_exit
)
{
if
(
wait_on_condition
(
&
proc
->
mutex_te
,
&
proc
->
cond_te
,
&
proc
->
instance_cnt_te
,
"te thread"
)
<
0
)
break
;
if
(
wait_on_condition
(
&
proc
->
mutex_te
,
&
proc
->
cond_te
,
&
proc
->
instance_cnt_te
,
"te thread"
)
<
0
)
break
;
dlsch_encoding_2threads0
((
te_params
*
)
param
);
dlsch_encoding_2threads0
((
te_params
*
)
param
);
if
(
release_thread
(
&
proc
->
mutex_te
,
&
proc
->
instance_cnt_te
,
"te thread"
)
<
0
)
break
;
if
(
release_thread
(
&
proc
->
mutex_te
,
&
proc
->
instance_cnt_te
,
"te thread"
)
<
0
)
break
;
if
(
pthread_cond_signal
(
&
proc
->
cond_te
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_cond_signal for te thread exit
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
(
NULL
);
if
(
pthread_cond_signal
(
&
proc
->
cond_te
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_cond_signal for te thread exit
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
(
NULL
);
}
}
}
return
(
NULL
);
return
(
NULL
);
}
int
dlsch_encoding_2threads
(
PHY_VARS_eNB
*
eNB
,
unsigned
char
*
a
,
uint8_t
num_pdcch_symbols
,
LTE_eNB_DLSCH_t
*
dlsch
,
int
frame
,
uint8_t
subframe
,
time_stats_t
*
rm_stats
,
time_stats_t
*
te_stats
,
time_stats_t
*
i_stats
)
unsigned
char
*
a
,
uint8_t
num_pdcch_symbols
,
LTE_eNB_DLSCH_t
*
dlsch
,
int
frame
,
uint8_t
subframe
,
time_stats_t
*
rm_stats
,
time_stats_t
*
te_stats
,
time_stats_t
*
i_stats
)
{
LTE_DL_FRAME_PARMS
*
frame_parms
=
&
eNB
->
frame_parms
;
eNB_proc_t
*
proc
=
&
eNB
->
proc
;
unsigned
int
G
;
unsigned
int
crc
=
1
;
unsigned
short
iind
;
LTE_DL_FRAME_PARMS
*
frame_parms
=
&
eNB
->
frame_parms
;
eNB_proc_t
*
proc
=
&
eNB
->
proc
;
unsigned
int
G
;
unsigned
int
crc
=
1
;
unsigned
short
iind
;
unsigned
char
harq_pid
=
dlsch
->
harq_ids
[
subframe
];
unsigned
short
nb_rb
=
dlsch
->
harq_processes
[
harq_pid
]
->
nb_rb
;
unsigned
int
A
;
unsigned
char
mod_order
;
unsigned
int
Kr
=
0
,
Kr_bytes
,
r
,
r_offset
=
0
;
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
unsigned
char
harq_pid
=
dlsch
->
harq_ids
[
subframe
];
unsigned
short
nb_rb
=
dlsch
->
harq_processes
[
harq_pid
]
->
nb_rb
;
unsigned
int
A
;
unsigned
char
mod_order
;
unsigned
int
Kr
=
0
,
Kr_bytes
,
r
,
r_offset
=
0
;
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_IN
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_IN
);
A
=
dlsch
->
harq_processes
[
harq_pid
]
->
TBS
;
//6228
mod_order
=
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
;
G
=
get_G
(
frame_parms
,
nb_rb
,
dlsch
->
harq_processes
[
harq_pid
]
->
rb_alloc
,
mod_order
,
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
,
num_pdcch_symbols
,
frame
,
subframe
,
dlsch
->
harq_processes
[
harq_pid
]
->
mimo_mode
==
TM7
?
7
:
0
);
A
=
dlsch
->
harq_processes
[
harq_pid
]
->
TBS
;
//6228
mod_order
=
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
;
G
=
get_G
(
frame_parms
,
nb_rb
,
dlsch
->
harq_processes
[
harq_pid
]
->
rb_alloc
,
mod_order
,
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
,
num_pdcch_symbols
,
frame
,
subframe
,
dlsch
->
harq_processes
[
harq_pid
]
->
mimo_mode
==
TM7
?
7
:
0
);
if
(
dlsch
->
harq_processes
[
harq_pid
]
->
round
==
0
)
{
// this is a new packet
if
(
dlsch
->
harq_processes
[
harq_pid
]
->
round
==
0
)
{
// this is a new packet
// Add 24-bit crc (polynomial A) to payload
crc
=
crc24a
(
a
,
A
)
>>
8
;
a
[
A
>>
3
]
=
((
uint8_t
*
)
&
crc
)[
2
];
a
[
1
+
(
A
>>
3
)]
=
((
uint8_t
*
)
&
crc
)[
1
];
a
[
2
+
(
A
>>
3
)]
=
((
uint8_t
*
)
&
crc
)[
0
];
// Add 24-bit crc (polynomial A) to payload
crc
=
crc24a
(
a
,
A
)
>>
8
;
a
[
A
>>
3
]
=
((
uint8_t
*
)
&
crc
)[
2
];
a
[
1
+
(
A
>>
3
)]
=
((
uint8_t
*
)
&
crc
)[
1
];
a
[
2
+
(
A
>>
3
)]
=
((
uint8_t
*
)
&
crc
)[
0
];
dlsch
->
harq_processes
[
harq_pid
]
->
B
=
A
+
24
;
memcpy
(
dlsch
->
harq_processes
[
harq_pid
]
->
b
,
a
,(
A
/
8
)
+
4
);
dlsch
->
harq_processes
[
harq_pid
]
->
B
=
A
+
24
;
memcpy
(
dlsch
->
harq_processes
[
harq_pid
]
->
b
,
a
,(
A
/
8
)
+
4
);
if
(
lte_segmentation
(
dlsch
->
harq_processes
[
harq_pid
]
->
b
,
dlsch
->
harq_processes
[
harq_pid
]
->
c
,
dlsch
->
harq_processes
[
harq_pid
]
->
B
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
C
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Cplus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Cminus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Kplus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Kminus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
F
)
<
0
)
return
(
-
1
);
if
(
lte_segmentation
(
dlsch
->
harq_processes
[
harq_pid
]
->
b
,
dlsch
->
harq_processes
[
harq_pid
]
->
c
,
dlsch
->
harq_processes
[
harq_pid
]
->
B
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
C
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Cplus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Cminus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Kplus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Kminus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
F
)
<
0
)
return
(
-
1
);
if
(
proc
->
instance_cnt_te
==
0
)
{
printf
(
"[eNB] TE thread busy
\n
"
);
exit_fun
(
"TE thread busy"
);
pthread_mutex_unlock
(
&
proc
->
mutex_te
);
return
(
-
1
);
}
if
(
proc
->
instance_cnt_te
==
0
)
{
printf
(
"[eNB] TE thread busy
\n
"
);
exit_fun
(
"TE thread busy"
);
pthread_mutex_unlock
(
&
proc
->
mutex_te
);
return
(
-
1
);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_OUT
);
++
proc
->
instance_cnt_te
;
proc
->
tep
.
eNB
=
eNB
;
proc
->
tep
.
dlsch
=
dlsch
;
proc
->
tep
.
G
=
G
;
proc
->
tep
.
harq_pid
=
harq_pid
;
// wakeup worker to do second half segments
if
(
pthread_cond_signal
(
&
proc
->
cond_te
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_cond_signal for te thread exit
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
(
-
1
);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_OUT
);
++
proc
->
instance_cnt_te
;
pthread_mutex_unlock
(
&
proc
->
mutex_te
);
proc
->
tep
.
eNB
=
eNB
;
proc
->
tep
.
dlsch
=
dlsch
;
proc
->
tep
.
G
=
G
;
proc
->
tep
.
harq_pid
=
harq_pid
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_IN
);
for
(
r
=
dlsch
->
harq_processes
[
harq_pid
]
->
C
>>
1
;
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
C
;
r
++
)
{
if
(
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
Cminus
)
Kr
=
dlsch
->
harq_processes
[
harq_pid
]
->
Kminus
;
else
Kr
=
dlsch
->
harq_processes
[
harq_pid
]
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
// get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
printf
(
"dlsch_coding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
}
// wakeup worker to do second half segments
if
(
pthread_cond_signal
(
&
proc
->
cond_te
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_cond_signal for te thread exit
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
(
-
1
);
}
pthread_mutex_unlock
(
&
proc
->
mutex_te
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_IN
);
for
(
r
=
dlsch
->
harq_processes
[
harq_pid
]
->
C
>>
1
;
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
C
;
r
++
)
{
if
(
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
Cminus
)
Kr
=
dlsch
->
harq_processes
[
harq_pid
]
->
Kminus
;
else
Kr
=
dlsch
->
harq_processes
[
harq_pid
]
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
// get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
printf
(
"dlsch_coding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
}
start_meas
(
te_stats
);
...
...
@@ -480,70 +480,70 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
stop_meas
(
i_stats
);
}
}
else
{
}
else
{
proc
->
tep
.
eNB
=
eNB
;
proc
->
tep
.
dlsch
=
dlsch
;
proc
->
tep
.
G
=
G
;
proc
->
tep
.
eNB
=
eNB
;
proc
->
tep
.
dlsch
=
dlsch
;
proc
->
tep
.
G
=
G
;
// wakeup worker to do second half segments
if
(
pthread_cond_signal
(
&
proc
->
cond_te
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_cond_signal for te thread exit
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
(
-
1
);
}
}
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
// outputs for each code segment, see Section 5.1.5 p.20
for
(
r
=
0
,
r_offset
=
0
;
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
C
;
r
++
)
{
// get information for E for the segments that are handled by the worker thread
if
(
r
<
(
dlsch
->
harq_processes
[
harq_pid
]
->
C
>>
1
))
{
int
Nl
=
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
;
int
Qm
=
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
;
int
C
=
dlsch
->
harq_processes
[
harq_pid
]
->
C
;
int
Gp
=
G
/
Nl
/
Qm
;
int
GpmodC
=
Gp
%
C
;
if
(
r
<
(
C
-
(
GpmodC
)))
r_offset
+=
Nl
*
Qm
*
(
Gp
/
C
);
else
r_offset
+=
Nl
*
Qm
*
((
GpmodC
==
0
?
0
:
1
)
+
(
Gp
/
C
));
// wakeup worker to do second half segments
if
(
pthread_cond_signal
(
&
proc
->
cond_te
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_cond_signal for te thread exit
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
(
-
1
);
}
}
else
{
start_meas
(
rm_stats
);
r_offset
+=
lte_rate_matching_turbo
(
dlsch
->
harq_processes
[
harq_pid
]
->
RTC
[
r
],
G
,
//G
dlsch
->
harq_processes
[
harq_pid
]
->
w
[
r
],
dlsch
->
harq_processes
[
harq_pid
]
->
e
+
r_offset
,
dlsch
->
harq_processes
[
harq_pid
]
->
C
,
// C
dlsch
->
Nsoft
,
// Nsoft,
dlsch
->
Mdlharq
,
dlsch
->
Kmimo
,
dlsch
->
harq_processes
[
harq_pid
]
->
rvidx
,
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
,
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
,
r
,
nb_rb
);
// m); // r
stop_meas
(
rm_stats
);
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
// outputs for each code segment, see Section 5.1.5 p.20
for
(
r
=
0
,
r_offset
=
0
;
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
C
;
r
++
)
{
// get information for E for the segments that are handled by the worker thread
if
(
r
<
(
dlsch
->
harq_processes
[
harq_pid
]
->
C
>>
1
))
{
int
Nl
=
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
;
int
Qm
=
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
;
int
C
=
dlsch
->
harq_processes
[
harq_pid
]
->
C
;
int
Gp
=
G
/
Nl
/
Qm
;
int
GpmodC
=
Gp
%
C
;
if
(
r
<
(
C
-
(
GpmodC
)))
r_offset
+=
Nl
*
Qm
*
(
Gp
/
C
);
else
r_offset
+=
Nl
*
Qm
*
((
GpmodC
==
0
?
0
:
1
)
+
(
Gp
/
C
));
}
else
{
start_meas
(
rm_stats
);
r_offset
+=
lte_rate_matching_turbo
(
dlsch
->
harq_processes
[
harq_pid
]
->
RTC
[
r
],
G
,
//G
dlsch
->
harq_processes
[
harq_pid
]
->
w
[
r
],
dlsch
->
harq_processes
[
harq_pid
]
->
e
+
r_offset
,
dlsch
->
harq_processes
[
harq_pid
]
->
C
,
// C
dlsch
->
Nsoft
,
// Nsoft,
dlsch
->
Mdlharq
,
dlsch
->
Kmimo
,
dlsch
->
harq_processes
[
harq_pid
]
->
rvidx
,
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
,
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
,
r
,
nb_rb
);
// m); // r
stop_meas
(
rm_stats
);
}
}
}
// wait for worker to finish
// wait for worker to finish
wait_on_busy_condition
(
&
proc
->
mutex_te
,
&
proc
->
cond_te
,
&
proc
->
instance_cnt_te
,
"te thread"
);
wait_on_busy_condition
(
&
proc
->
mutex_te
,
&
proc
->
cond_te
,
&
proc
->
instance_cnt_te
,
"te thread"
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_OUT
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_OUT
);
return
(
0
);
return
(
0
);
}
int
dlsch_encoding
(
PHY_VARS_eNB
*
eNB
,
unsigned
char
*
a
,
unsigned
char
*
a
,
uint8_t
num_pdcch_symbols
,
LTE_eNB_DLSCH_t
*
dlsch
,
int
frame
,
...
...
@@ -565,7 +565,6 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
a
[
1
+
(
A
>>
3
)]
=
((
uint8_t
*
)
&
crc
)[
1
];
a
[
2
+
(
A
>>
3
)]
=
((
uint8_t
*
)
&
crc
)[
0
];
// printf("CRC %x (A %d)\n",crc,A);
dlsch
->
harq_processes
[
harq_pid
]
->
B
=
A
+
24
;
// dlsch->harq_processes[harq_pid]->b = a;
memcpy
(
dlsch
->
harq_processes
[
harq_pid
]
->
b
,
a
,(
A
/
8
)
+
4
);
...
...
@@ -606,9 +605,10 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
return
(
-
1
);
}
request_t
*
req
=
createRequest
(
ENCODE
,
sizeof
(
turboEncode_t
));
union
turboReqUnion
id
=
{.
s
=
{
dlsch
->
rnti
,
frame
,
subframe
,
r
,
0
}};
req
->
id
=
id
.
p
;
req
->
decodeIterations
=
0
;
union
turboReqUnion
id
=
{.
s
=
{
dlsch
->
rnti
,
frame
,
subframe
,
r
,
0
}};
req
->
id
=
id
.
p
;
req
->
decodeIterations
=
0
;
req
->
startUELoop
=
eNB
->
proc
.
threadPool
.
startProcessingUE
;
turboEncode_t
*
rdata
=
(
turboEncode_t
*
)
req
->
data
;
rdata
->
input
=
dlsch
->
harq_processes
[
harq_pid
]
->
c
[
r
];
rdata
->
Kr_bytes
=
Kr
>>
3
;
...
...
@@ -622,7 +622,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
}
else
{
memset
(
rdata
->
output
,
LTE_NULL
,
TURBO_SIMD_SOFTBITS
);
start_meas
(
te_stats
);
req
->
creationTime
=
req
->
startProcessingTime
=
rdtsc
();
req
->
startProcessingTime
=
rdtsc
();
threegpplte_turbo_encoder
(
rdata
->
input
,
rdata
->
Kr_bytes
,
rdata
->
output
+
96
,
//&dlsch->harq_processes[harq_pid]->d[r][96],
...
...
@@ -635,11 +635,12 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
req
->
decodeIterations
=
0
;
req
->
coreId
=
0
;
req
->
processedBy
[
0
]
=
0
;
req
->
decodeIterations
=
0
;
req
->
next
=
eNB
->
proc
.
threadPool
.
doneRequests
;
eNB
->
proc
.
threadPool
.
doneRequests
=
req
;
req
->
decodeIterations
=
0
;
req
->
next
=
eNB
->
proc
.
threadPool
.
doneRequests
;
eNB
->
proc
.
threadPool
.
doneRequests
=
req
;
stop_meas
(
i_stats
);
}
eNB
->
proc
.
threadPool
.
startProcessingUE
=
rdtsc
();
}
return
0
;
}
...
...
@@ -677,157 +678,157 @@ int dlsch_encoding2(PHY_VARS_eNB *eNB,
for
(
int
r
=
0
;
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
C
;
r
++
)
{
#ifdef DEBUG_DLSCH_CODING
printf
(
"Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...
\n
"
,
r
,
G
,
Kr
*
3
,
mod_order
,
nb_rb
);
printf
(
"Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...
\n
"
,
r
,
G
,
Kr
*
3
,
mod_order
,
nb_rb
);
#endif
start_meas
(
rm_stats
);
start_meas
(
rm_stats
);
#ifdef DEBUG_DLSCH_CODING
printf
(
"rvidx in encoding = %d
\n
"
,
dlsch
->
harq_processes
[
harq_pid
]
->
rvidx
);
printf
(
"rvidx in encoding = %d
\n
"
,
dlsch
->
harq_processes
[
harq_pid
]
->
rvidx
);
#endif
r_offset
+=
lte_rate_matching_turbo
(
dlsch
->
harq_processes
[
harq_pid
]
->
RTC
[
r
],
G
,
//G
dlsch
->
harq_processes
[
harq_pid
]
->
w
[
r
],
dlsch
->
harq_processes
[
harq_pid
]
->
e
+
r_offset
,
dlsch
->
harq_processes
[
harq_pid
]
->
C
,
// C
dlsch
->
Nsoft
,
// Nsoft,
dlsch
->
Mdlharq
,
dlsch
->
Kmimo
,
dlsch
->
harq_processes
[
harq_pid
]
->
rvidx
,
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
,
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
,
r
,
nb_rb
);
// m); // r
stop_meas
(
rm_stats
);
r_offset
+=
lte_rate_matching_turbo
(
dlsch
->
harq_processes
[
harq_pid
]
->
RTC
[
r
],
G
,
//G
dlsch
->
harq_processes
[
harq_pid
]
->
w
[
r
],
dlsch
->
harq_processes
[
harq_pid
]
->
e
+
r_offset
,
dlsch
->
harq_processes
[
harq_pid
]
->
C
,
// C
dlsch
->
Nsoft
,
// Nsoft,
dlsch
->
Mdlharq
,
dlsch
->
Kmimo
,
dlsch
->
harq_processes
[
harq_pid
]
->
rvidx
,
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
,
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
,
r
,
nb_rb
);
// m); // r
stop_meas
(
rm_stats
);
#ifdef DEBUG_DLSCH_CODING
if
(
r
==
dlsch
->
harq_processes
[
harq_pid
]
->
C
-
1
)
write_output
(
"enc_output.m"
,
"enc"
,
dlsch
->
harq_processes
[
harq_pid
]
->
e
,
r_offset
,
1
,
4
);
if
(
r
==
dlsch
->
harq_processes
[
harq_pid
]
->
C
-
1
)
write_output
(
"enc_output.m"
,
"enc"
,
dlsch
->
harq_processes
[
harq_pid
]
->
e
,
r_offset
,
1
,
4
);
#endif
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_OUT
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_OUT
);
return
(
0
);
return
(
0
);
}
int
dlsch_encoding_SIC
(
PHY_VARS_UE
*
ue
,
unsigned
char
*
a
,
uint8_t
num_pdcch_symbols
,
LTE_eNB_DLSCH_t
*
dlsch
,
int
frame
,
uint8_t
subframe
,
time_stats_t
*
rm_stats
,
time_stats_t
*
te_stats
,
time_stats_t
*
i_stats
)
unsigned
char
*
a
,
uint8_t
num_pdcch_symbols
,
LTE_eNB_DLSCH_t
*
dlsch
,
int
frame
,
uint8_t
subframe
,
time_stats_t
*
rm_stats
,
time_stats_t
*
te_stats
,
time_stats_t
*
i_stats
)
{
unsigned
int
G
;
unsigned
int
crc
=
1
;
unsigned
short
iind
;
LTE_DL_FRAME_PARMS
*
frame_parms
=
&
ue
->
frame_parms
;
unsigned
char
harq_pid
=
ue
->
dlsch
[
subframe
&
2
][
0
][
0
]
->
rnti
;
unsigned
short
nb_rb
=
dlsch
->
harq_processes
[
harq_pid
]
->
nb_rb
;
unsigned
int
A
;
unsigned
char
mod_order
;
unsigned
int
Kr
=
0
,
Kr_bytes
,
r
,
r_offset
=
0
;
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
uint8_t
beamforming_mode
=
0
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_IN
);
A
=
dlsch
->
harq_processes
[
harq_pid
]
->
TBS
;
//6228
// printf("Encoder: A: %d\n",A);
mod_order
=
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
;
if
(
dlsch
->
harq_processes
[
harq_pid
]
->
mimo_mode
==
TM7
)
beamforming_mode
=
7
;
else
if
(
dlsch
->
harq_processes
[
harq_pid
]
->
mimo_mode
==
TM8
)
beamforming_mode
=
8
;
else
if
(
dlsch
->
harq_processes
[
harq_pid
]
->
mimo_mode
==
TM9_10
)
beamforming_mode
=
9
;
G
=
get_G
(
frame_parms
,
nb_rb
,
dlsch
->
harq_processes
[
harq_pid
]
->
rb_alloc
,
mod_order
,
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
,
num_pdcch_symbols
,
frame
,
subframe
,
beamforming_mode
);
// if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet
if
(
dlsch
->
harq_processes
[
harq_pid
]
->
round
==
0
)
{
// this is a new packet
#ifdef DEBUG_DLSCH_CODING
printf
(
"SIC encoding thinks this is a new packet
\n
"
);
#endif
/*
int i;
printf("dlsch (tx): \n");
for (i=0;i<(A>>3);i++)
printf("%02x.",a[i]);
printf("\n");
*/
// Add 24-bit crc (polynomial A) to payload
crc
=
crc24a
(
a
,
A
)
>>
8
;
a
[
A
>>
3
]
=
((
uint8_t
*
)
&
crc
)[
2
];
a
[
1
+
(
A
>>
3
)]
=
((
uint8_t
*
)
&
crc
)[
1
];
a
[
2
+
(
A
>>
3
)]
=
((
uint8_t
*
)
&
crc
)[
0
];
// printf("CRC %x (A %d)\n",crc,A);
dlsch
->
harq_processes
[
harq_pid
]
->
B
=
A
+
24
;
// dlsch->harq_processes[harq_pid]->b = a
;
memcpy
(
dlsch
->
harq_processes
[
harq_pid
]
->
b
,
a
,(
A
/
8
)
+
4
)
;
unsigned
int
G
;
unsigned
int
crc
=
1
;
unsigned
short
iind
;
if
(
lte_segmentation
(
dlsch
->
harq_processes
[
harq_pid
]
->
b
,
dlsch
->
harq_processes
[
harq_pid
]
->
c
,
dlsch
->
harq_processes
[
harq_pid
]
->
B
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
C
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Cplus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Cminus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Kplus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Kminus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
F
)
<
0
)
return
(
-
1
);
LTE_DL_FRAME_PARMS
*
frame_parms
=
&
ue
->
frame_parms
;
unsigned
char
harq_pid
=
ue
->
dlsch
[
subframe
&
2
][
0
][
0
]
->
rnti
;
unsigned
short
nb_rb
=
dlsch
->
harq_processes
[
harq_pid
]
->
nb_rb
;
unsigned
int
A
;
unsigned
char
mod_order
;
unsigned
int
Kr
=
0
,
Kr_bytes
,
r
,
r_offset
=
0
;
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
uint8_t
beamforming_mode
=
0
;
for
(
r
=
0
;
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
C
;
r
++
)
{
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_IN
);
if
(
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
Cminus
)
Kr
=
dlsch
->
harq_processes
[
harq_pid
]
->
Kminus
;
else
Kr
=
dlsch
->
harq_processes
[
harq_pid
]
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
// get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
printf
(
"dlsch_coding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
}
A
=
dlsch
->
harq_processes
[
harq_pid
]
->
TBS
;
//6228
// printf("Encoder: A: %d\n",A);
mod_order
=
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
;
if
(
dlsch
->
harq_processes
[
harq_pid
]
->
mimo_mode
==
TM7
)
beamforming_mode
=
7
;
else
if
(
dlsch
->
harq_processes
[
harq_pid
]
->
mimo_mode
==
TM8
)
beamforming_mode
=
8
;
else
if
(
dlsch
->
harq_processes
[
harq_pid
]
->
mimo_mode
==
TM9_10
)
beamforming_mode
=
9
;
G
=
get_G
(
frame_parms
,
nb_rb
,
dlsch
->
harq_processes
[
harq_pid
]
->
rb_alloc
,
mod_order
,
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
,
num_pdcch_symbols
,
frame
,
subframe
,
beamforming_mode
);
// if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet
if
(
dlsch
->
harq_processes
[
harq_pid
]
->
round
==
0
)
{
// this is a new packet
#ifdef DEBUG_DLSCH_CODING
printf
(
"Generating Code Segment %d (%d bits)
\n
"
,
r
,
Kr
);
// generate codewords
printf
(
"SIC encoding thinks this is a new packet
\n
"
);
#endif
/*
int i;
printf("dlsch (tx): \n");
for (i=0;i<(A>>3);i++)
printf("%02x.",a[i]);
printf("\n");
*/
// Add 24-bit crc (polynomial A) to payload
crc
=
crc24a
(
a
,
A
)
>>
8
;
a
[
A
>>
3
]
=
((
uint8_t
*
)
&
crc
)[
2
];
a
[
1
+
(
A
>>
3
)]
=
((
uint8_t
*
)
&
crc
)[
1
];
a
[
2
+
(
A
>>
3
)]
=
((
uint8_t
*
)
&
crc
)[
0
];
// printf("CRC %x (A %d)\n",crc,A);
dlsch
->
harq_processes
[
harq_pid
]
->
B
=
A
+
24
;
// dlsch->harq_processes[harq_pid]->b = a;
memcpy
(
dlsch
->
harq_processes
[
harq_pid
]
->
b
,
a
,(
A
/
8
)
+
4
);
if
(
lte_segmentation
(
dlsch
->
harq_processes
[
harq_pid
]
->
b
,
dlsch
->
harq_processes
[
harq_pid
]
->
c
,
dlsch
->
harq_processes
[
harq_pid
]
->
B
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
C
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Cplus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Cminus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Kplus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
Kminus
,
&
dlsch
->
harq_processes
[
harq_pid
]
->
F
)
<
0
)
return
(
-
1
);
for
(
r
=
0
;
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
C
;
r
++
)
{
if
(
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
Cminus
)
Kr
=
dlsch
->
harq_processes
[
harq_pid
]
->
Kminus
;
else
Kr
=
dlsch
->
harq_processes
[
harq_pid
]
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
// get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
printf
(
"dlsch_coding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
}
printf
(
"bits_per_codeword (Kr)= %d, A %d
\n
"
,
Kr
,
A
);
printf
(
"N_RB = %d
\n
"
,
nb_rb
);
printf
(
"Ncp %d
\n
"
,
frame_parms
->
Ncp
);
printf
(
"mod_order %d
\n
"
,
mod_order
);
#ifdef DEBUG_DLSCH_CODING
printf
(
"Generating Code Segment %d (%d bits)
\n
"
,
r
,
Kr
);
// generate codewords
printf
(
"bits_per_codeword (Kr)= %d, A %d
\n
"
,
Kr
,
A
);
printf
(
"N_RB = %d
\n
"
,
nb_rb
);
printf
(
"Ncp %d
\n
"
,
frame_parms
->
Ncp
);
printf
(
"mod_order %d
\n
"
,
mod_order
);
#endif
#ifdef DEBUG_DLSCH_CODING
printf
(
"Encoding ... iind %d f1 %d, f2 %d
\n
"
,
iind
,
f1f2mat_old
[
iind
*
2
],
f1f2mat_old
[(
iind
*
2
)
+
1
]);
printf
(
"Encoding ... iind %d f1 %d, f2 %d
\n
"
,
iind
,
f1f2mat_old
[
iind
*
2
],
f1f2mat_old
[(
iind
*
2
)
+
1
]);
#endif
start_meas
(
te_stats
);
uint8_t
tmp
[
96
+
12
+
3
+
3
*
6144
]
=
{
0
};
...
...
@@ -853,52 +854,52 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue,
tmp
+
96
,
//&dlsch->harq_processes[harq_pid]->d[r][96],
dlsch
->
harq_processes
[
harq_pid
]
->
w
[
r
]);
stop_meas
(
i_stats
);
}
}
}
}
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
// outputs for each code segment, see Section 5.1.5 p.20
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
// outputs for each code segment, see Section 5.1.5 p.20
for
(
r
=
0
;
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
C
;
r
++
)
{
for
(
r
=
0
;
r
<
dlsch
->
harq_processes
[
harq_pid
]
->
C
;
r
++
)
{
#ifdef DEBUG_DLSCH_CODING
printf
(
"Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...
\n
"
,
r
,
G
,
Kr
*
3
,
mod_order
,
nb_rb
);
printf
(
"Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...
\n
"
,
r
,
G
,
Kr
*
3
,
mod_order
,
nb_rb
);
#endif
start_meas
(
rm_stats
);
start_meas
(
rm_stats
);
#ifdef DEBUG_DLSCH_CODING
printf
(
"rvidx in SIC encoding = %d
\n
"
,
dlsch
->
harq_processes
[
harq_pid
]
->
rvidx
);
printf
(
"rvidx in SIC encoding = %d
\n
"
,
dlsch
->
harq_processes
[
harq_pid
]
->
rvidx
);
#endif
r_offset
+=
lte_rate_matching_turbo
(
dlsch
->
harq_processes
[
harq_pid
]
->
RTC
[
r
],
G
,
//G
dlsch
->
harq_processes
[
harq_pid
]
->
w
[
r
],
dlsch
->
harq_processes
[
harq_pid
]
->
e
+
r_offset
,
dlsch
->
harq_processes
[
harq_pid
]
->
C
,
// C
dlsch
->
Nsoft
,
// Nsoft,
dlsch
->
Mdlharq
,
dlsch
->
Kmimo
,
dlsch
->
harq_processes
[
harq_pid
]
->
rvidx
,
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
,
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
,
r
,
nb_rb
);
// m); // r
stop_meas
(
rm_stats
);
r_offset
+=
lte_rate_matching_turbo
(
dlsch
->
harq_processes
[
harq_pid
]
->
RTC
[
r
],
G
,
//G
dlsch
->
harq_processes
[
harq_pid
]
->
w
[
r
],
dlsch
->
harq_processes
[
harq_pid
]
->
e
+
r_offset
,
dlsch
->
harq_processes
[
harq_pid
]
->
C
,
// C
dlsch
->
Nsoft
,
// Nsoft,
dlsch
->
Mdlharq
,
dlsch
->
Kmimo
,
dlsch
->
harq_processes
[
harq_pid
]
->
rvidx
,
dlsch
->
harq_processes
[
harq_pid
]
->
Qm
,
dlsch
->
harq_processes
[
harq_pid
]
->
Nl
,
r
,
nb_rb
);
// m); // r
stop_meas
(
rm_stats
);
#ifdef DEBUG_DLSCH_CODING
if
(
r
==
dlsch
->
harq_processes
[
harq_pid
]
->
C
-
1
)
write_output
(
"enc_output.m"
,
"enc"
,
dlsch
->
harq_processes
[
harq_pid
]
->
e
,
r_offset
,
1
,
4
);
if
(
r
==
dlsch
->
harq_processes
[
harq_pid
]
->
C
-
1
)
write_output
(
"enc_output.m"
,
"enc"
,
dlsch
->
harq_processes
[
harq_pid
]
->
e
,
r_offset
,
1
,
4
);
#endif
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_OUT
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING
,
VCD_FUNCTION_OUT
);
return
(
0
);
return
(
0
);
}
...
...
openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
View file @
edfef131
...
...
@@ -80,29 +80,29 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin
uint8_t
exit_flag
=
0
;
unsigned
char
bw_scaling
;
switch
(
N_RB_UL
)
{
case
6
:
bw_scaling
=
16
;
break
;
switch
(
N_RB_UL
)
{
case
6
:
bw_scaling
=
16
;
break
;
case
25
:
bw_scaling
=
4
;
break
;
case
25
:
bw_scaling
=
4
;
break
;
case
50
:
bw_scaling
=
2
;
break
;
case
50
:
bw_scaling
=
2
;
break
;
default:
bw_scaling
=
1
;
break
;
}
default:
bw_scaling
=
1
;
break
;
}
ulsch
=
(
LTE_eNB_ULSCH_t
*
)
malloc16
(
sizeof
(
LTE_eNB_ULSCH_t
));
ulsch
=
(
LTE_eNB_ULSCH_t
*
)
malloc16
(
sizeof
(
LTE_eNB_ULSCH_t
));
if
(
ulsch
)
{
memset
(
ulsch
,
0
,
sizeof
(
LTE_eNB_ULSCH_t
));
ulsch
->
max_turbo_iterations
=
max_turbo_iterations
;
if
(
ulsch
)
{
memset
(
ulsch
,
0
,
sizeof
(
LTE_eNB_ULSCH_t
));
ulsch
->
max_turbo_iterations
=
max_turbo_iterations
;
ulsch
->
Mlimit
=
4
;
for
(
int
i
=
0
;
i
<
8
;
i
++
)
{
...
...
@@ -126,69 +126,69 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin
return
(
ulsch
);
}
LOG_E
(
PHY
,
"new_ue_ulsch: exit_flag = %d
\n
"
,
exit_flag
);
free_eNB_ulsch
(
ulsch
);
LOG_E
(
PHY
,
"new_ue_ulsch: exit_flag = %d
\n
"
,
exit_flag
);
free_eNB_ulsch
(
ulsch
);
return
(
NULL
);
return
(
NULL
);
}
void
clean_eNb_ulsch
(
LTE_eNB_ULSCH_t
*
ulsch
)
{
unsigned
char
i
;
//ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t));
if
(
ulsch
)
{
ulsch
->
rnti
=
0
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
if
(
ulsch
->
harq_processes
[
i
])
{
// ulsch->harq_processes[i]->Ndi = 0;
ulsch
->
harq_processes
[
i
]
->
status
=
0
;
//ulsch->harq_processes[i]->phich_active = 0; //this will be done later after transmission of PHICH
ulsch
->
harq_processes
[
i
]
->
phich_ACK
=
0
;
ulsch
->
harq_processes
[
i
]
->
round
=
0
;
ulsch
->
harq_processes
[
i
]
->
rar_alloc
=
0
;
ulsch
->
harq_processes
[
i
]
->
first_rb
=
0
;
ulsch
->
harq_processes
[
i
]
->
nb_rb
=
0
;
ulsch
->
harq_processes
[
i
]
->
TBS
=
0
;
ulsch
->
harq_processes
[
i
]
->
Or1
=
0
;
ulsch
->
harq_processes
[
i
]
->
Or2
=
0
;
for
(
int
j
=
0
;
j
<
2
;
j
++
)
{
ulsch
->
harq_processes
[
i
]
->
o_RI
[
j
]
=
0
;
unsigned
char
i
;
//ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t));
if
(
ulsch
)
{
ulsch
->
rnti
=
0
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
if
(
ulsch
->
harq_processes
[
i
])
{
// ulsch->harq_processes[i]->Ndi = 0;
ulsch
->
harq_processes
[
i
]
->
status
=
0
;
//ulsch->harq_processes[i]->phich_active = 0; //this will be done later after transmission of PHICH
ulsch
->
harq_processes
[
i
]
->
phich_ACK
=
0
;
ulsch
->
harq_processes
[
i
]
->
round
=
0
;
ulsch
->
harq_processes
[
i
]
->
rar_alloc
=
0
;
ulsch
->
harq_processes
[
i
]
->
first_rb
=
0
;
ulsch
->
harq_processes
[
i
]
->
nb_rb
=
0
;
ulsch
->
harq_processes
[
i
]
->
TBS
=
0
;
ulsch
->
harq_processes
[
i
]
->
Or1
=
0
;
ulsch
->
harq_processes
[
i
]
->
Or2
=
0
;
for
(
int
j
=
0
;
j
<
2
;
j
++
)
{
ulsch
->
harq_processes
[
i
]
->
o_RI
[
j
]
=
0
;
}
ulsch
->
harq_processes
[
i
]
->
O_ACK
=
0
;
ulsch
->
harq_processes
[
i
]
->
srs_active
=
0
;
ulsch
->
harq_processes
[
i
]
->
rvidx
=
0
;
ulsch
->
harq_processes
[
i
]
->
Msc_initial
=
0
;
ulsch
->
harq_processes
[
i
]
->
Nsymb_initial
=
0
;
}
}
ulsch
->
harq_processes
[
i
]
->
O_ACK
=
0
;
ulsch
->
harq_processes
[
i
]
->
srs_active
=
0
;
ulsch
->
harq_processes
[
i
]
->
rvidx
=
0
;
ulsch
->
harq_processes
[
i
]
->
Msc_initial
=
0
;
ulsch
->
harq_processes
[
i
]
->
Nsymb_initial
=
0
;
}
ulsch
->
beta_offset_cqi_times8
=
0
;
ulsch
->
beta_offset_ri_times8
=
0
;
ulsch
->
beta_offset_harqack_times8
=
0
;
ulsch
->
Msg3_active
=
0
;
}
ulsch
->
beta_offset_cqi_times8
=
0
;
ulsch
->
beta_offset_ri_times8
=
0
;
ulsch
->
beta_offset_harqack_times8
=
0
;
ulsch
->
Msg3_active
=
0
;
}
}
uint8_t
extract_cqi_crc
(
uint8_t
*
cqi
,
uint8_t
CQI_LENGTH
)
{
uint8_t
crc
;
uint8_t
crc
;
crc
=
cqi
[
CQI_LENGTH
>>
3
];
// printf("crc1: %x, shift %d\n",crc,CQI_LENGTH&0x7);
crc
=
(
crc
<<
(
CQI_LENGTH
&
0x7
));
// clear crc bits
// ((char *)cqi)[CQI_LENGTH>>3] &= 0xff>>(8-(CQI_LENGTH&0x7));
// printf("crc2: %x, cqi0 %x\n",crc,cqi[1+(CQI_LENGTH>>3)]);
crc
|=
(
cqi
[
1
+
(
CQI_LENGTH
>>
3
)])
>>
(
8
-
(
CQI_LENGTH
&
0x7
));
// clear crc bits
//(((char *)cqi)[1+(CQI_LENGTH>>3)]) = 0;
crc
=
cqi
[
CQI_LENGTH
>>
3
];
// printf("crc1: %x, shift %d\n",crc,CQI_LENGTH&0x7);
crc
=
(
crc
<<
(
CQI_LENGTH
&
0x7
));
// clear crc bits
// ((char *)cqi)[CQI_LENGTH>>3] &= 0xff>>(8-(CQI_LENGTH&0x7));
// printf("crc2: %x, cqi0 %x\n",crc,cqi[1+(CQI_LENGTH>>3)]);
crc
|=
(
cqi
[
1
+
(
CQI_LENGTH
>>
3
)])
>>
(
8
-
(
CQI_LENGTH
&
0x7
));
// clear crc bits
//(((char *)cqi)[1+(CQI_LENGTH>>3)]) = 0;
// printf("crc : %x\n",crc);
return
(
crc
);
// printf("crc : %x\n",crc);
return
(
crc
);
}
...
...
@@ -199,135 +199,135 @@ uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH)
int
ulsch_decoding_data_2thread0
(
td_params
*
tdp
)
{
PHY_VARS_eNB
*
eNB
=
tdp
->
eNB
;
int
UE_id
=
tdp
->
UE_id
;
int
harq_pid
=
tdp
->
harq_pid
;
int
llr8_flag
=
tdp
->
llr8_flag
;
unsigned
int
r
,
r_offset
=
0
,
Kr
,
Kr_bytes
,
iind
;
uint8_t
crc_type
;
int
offset
=
0
;
int
ret
=
1
;
int16_t
dummy_w
[
MAX_NUM_ULSCH_SEGMENTS
][
3
*
(
6144
+
64
)];
LTE_eNB_ULSCH_t
*
ulsch
=
eNB
->
ulsch
[
UE_id
];
LTE_UL_eNB_HARQ_t
*
ulsch_harq
=
ulsch
->
harq_processes
[
harq_pid
];
int
Q_m
=
ulsch_harq
->
Qm
;
int
G
=
ulsch_harq
->
G
;
uint32_t
E
=
0
;
uint32_t
Gp
,
GpmodC
,
Nl
=
1
;
uint32_t
C
=
ulsch_harq
->
C
;
PHY_VARS_eNB
*
eNB
=
tdp
->
eNB
;
int
UE_id
=
tdp
->
UE_id
;
int
harq_pid
=
tdp
->
harq_pid
;
int
llr8_flag
=
tdp
->
llr8_flag
;
unsigned
int
r
,
r_offset
=
0
,
Kr
,
Kr_bytes
,
iind
;
uint8_t
crc_type
;
int
offset
=
0
;
int
ret
=
1
;
int16_t
dummy_w
[
MAX_NUM_ULSCH_SEGMENTS
][
3
*
(
6144
+
64
)];
LTE_eNB_ULSCH_t
*
ulsch
=
eNB
->
ulsch
[
UE_id
];
LTE_UL_eNB_HARQ_t
*
ulsch_harq
=
ulsch
->
harq_processes
[
harq_pid
];
int
Q_m
=
ulsch_harq
->
Qm
;
int
G
=
ulsch_harq
->
G
;
uint32_t
E
=
0
;
uint32_t
Gp
,
GpmodC
,
Nl
=
1
;
uint32_t
C
=
ulsch_harq
->
C
;
turboDecoder
*
tc
=
llr8_flag
?
phy_threegpplte_turbo_decoder8:
phy_threegpplte_turbo_decoder16
;
// go through first half of segments to get r_offset
for
(
r
=
0
;
r
<
(
ulsch_harq
->
C
/
2
);
r
++
)
{
// go through first half of segments to get r_offset
for
(
r
=
0
;
r
<
(
ulsch_harq
->
C
/
2
);
r
++
)
{
// Get Turbo interleaver parameters
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
AssertFatal
(
1
==
0
,
"ulsch_decoding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
}
// Get Turbo interleaver parameters
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
// This is stolen from rate-matching algorithm to get the value of E
Gp
=
G
/
Nl
/
Q_m
;
GpmodC
=
Gp
%
C
;
if
(
r
<
(
C
-
(
GpmodC
)))
E
=
Nl
*
Q_m
*
(
Gp
/
C
);
else
E
=
Nl
*
Q_m
*
((
GpmodC
==
0
?
0
:
1
)
+
(
Gp
/
C
));
r_offset
+=
E
;
Kr_bytes
=
Kr
>>
3
;
if
(
r
==
0
)
{
offset
=
Kr_bytes
-
(
ulsch_harq
->
F
>>
3
)
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
);
}
else
{
offset
+=
(
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
}
}
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
AssertFatal
(
1
==
0
,
"ulsch_decoding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
}
// go through second half of segments
for
(;
r
<
(
ulsch_harq
->
C
);
r
++
)
{
// This is stolen from rate-matching algorithm to get the value of E
Gp
=
G
/
Nl
/
Q_m
;
GpmodC
=
Gp
%
C
;
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
LOG_E
(
PHY
,
"ulsch_decoding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
if
(
r
<
(
C
-
(
GpmodC
)))
E
=
Nl
*
Q_m
*
(
Gp
/
C
);
else
E
=
Nl
*
Q_m
*
((
GpmodC
==
0
?
0
:
1
)
+
(
Gp
/
C
));
r_offset
+=
E
;
if
(
r
==
0
)
{
offset
=
Kr_bytes
-
(
ulsch_harq
->
F
>>
3
)
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
);
}
else
{
offset
+=
(
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
}
}
// go through second half of segments
for
(;
r
<
(
ulsch_harq
->
C
);
r
++
)
{
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
LOG_E
(
PHY
,
"ulsch_decoding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
}
#ifdef DEBUG_ULSCH_DECODING
printf
(
"f1 %d, f2 %d, F %d
\n
"
,
f1f2mat_old
[
2
*
iind
],
f1f2mat_old
[
1
+
(
2
*
iind
)],(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
printf
(
"f1 %d, f2 %d, F %d
\n
"
,
f1f2mat_old
[
2
*
iind
],
f1f2mat_old
[
1
+
(
2
*
iind
)],(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
#endif
memset
(
&
dummy_w
[
r
][
0
],
0
,
3
*
(
6144
+
64
)
*
sizeof
(
short
));
ulsch_harq
->
RTC
[
r
]
=
generate_dummy_w
(
4
+
(
Kr_bytes
*
8
),
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
memset
(
&
dummy_w
[
r
][
0
],
0
,
3
*
(
6144
+
64
)
*
sizeof
(
short
));
ulsch_harq
->
RTC
[
r
]
=
generate_dummy_w
(
4
+
(
Kr_bytes
*
8
),
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
#ifdef DEBUG_ULSCH_DECODING
printf
(
"Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...
\n
"
,
r
,
G
,
Kr
*
3
,
Q_m
,
nb_rb
,
ulsch_harq
->
Nl
);
printf
(
"Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...
\n
"
,
r
,
G
,
Kr
*
3
,
Q_m
,
nb_rb
,
ulsch_harq
->
Nl
);
#endif
if
(
lte_rate_matching_turbo_rx
(
ulsch_harq
->
RTC
[
r
],
G
,
ulsch_harq
->
w
[
r
],
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
ulsch_harq
->
e
+
r_offset
,
ulsch_harq
->
C
,
NSOFT
,
0
,
//Uplink
1
,
ulsch_harq
->
rvidx
,
(
ulsch_harq
->
round
==
0
)
?
1
:
0
,
// clear
ulsch_harq
->
Qm
,
1
,
r
,
&
E
)
==-
1
)
{
LOG_E
(
PHY
,
"ulsch_decoding.c: Problem in rate matching
\n
"
);
return
(
-
1
);
}
if
(
lte_rate_matching_turbo_rx
(
ulsch_harq
->
RTC
[
r
],
G
,
ulsch_harq
->
w
[
r
],
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
ulsch_harq
->
e
+
r_offset
,
ulsch_harq
->
C
,
NSOFT
,
0
,
//Uplink
1
,
ulsch_harq
->
rvidx
,
(
ulsch_harq
->
round
==
0
)
?
1
:
0
,
// clear
ulsch_harq
->
Qm
,
1
,
r
,
&
E
)
==-
1
)
{
LOG_E
(
PHY
,
"ulsch_decoding.c: Problem in rate matching
\n
"
);
return
(
-
1
);
}
r_offset
+=
E
;
r_offset
+=
E
;
int16_t
soft_bits
[
3
*
8
*
6144
+
12
+
96
]
__attribute__
((
aligned
(
32
)));
sub_block_deinterleaving_turbo
(
4
+
Kr
,
...
...
@@ -343,83 +343,83 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
uint8_t
decoded_bytes
[
3
+
768
]
__attribute__
((
aligned
(
32
)));
ret
=
tc
(
soft_bits
+
96
,
decoded_bytes
,
Kr
,
f1f2mat_old
[
iind
*
2
],
f1f2mat_old
[(
iind
*
2
)
+
1
],
ulsch
->
max_turbo_iterations
,
//MAX_TURBO_ITERATIONS,
crc_type
,
(
r
==
0
)
?
ulsch_harq
->
F
:
0
,
&
eNB
->
ulsch_tc_init_stats
,
&
eNB
->
ulsch_tc_alpha_stats
,
&
eNB
->
ulsch_tc_beta_stats
,
&
eNB
->
ulsch_tc_gamma_stats
,
&
eNB
->
ulsch_tc_ext_stats
,
&
eNB
->
ulsch_tc_intl1_stats
,
&
eNB
->
ulsch_tc_intl2_stats
);
// Reassembly of Transport block here
if
(
ret
!=
(
1
+
ulsch
->
max_turbo_iterations
))
{
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
memcpy
(
ulsch_harq
->
b
+
offset
,
Kr
,
f1f2mat_old
[
iind
*
2
],
f1f2mat_old
[(
iind
*
2
)
+
1
],
ulsch
->
max_turbo_iterations
,
//MAX_TURBO_ITERATIONS,
crc_type
,
(
r
==
0
)
?
ulsch_harq
->
F
:
0
,
&
eNB
->
ulsch_tc_init_stats
,
&
eNB
->
ulsch_tc_alpha_stats
,
&
eNB
->
ulsch_tc_beta_stats
,
&
eNB
->
ulsch_tc_gamma_stats
,
&
eNB
->
ulsch_tc_ext_stats
,
&
eNB
->
ulsch_tc_intl1_stats
,
&
eNB
->
ulsch_tc_intl2_stats
);
// Reassembly of Transport block here
if
(
ret
!=
(
1
+
ulsch
->
max_turbo_iterations
))
{
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
memcpy
(
ulsch_harq
->
b
+
offset
,
decoded_bytes
,
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
offset
+=
(
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
}
else
{
break
;
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
offset
+=
(
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
}
else
{
break
;
}
}
}
return
(
ret
);
return
(
ret
);
}
extern
int
oai_exit
;
void
*
td_thread
(
void
*
param
)
{
pthread_setname_np
(
pthread_self
(),
"td processing"
);
PHY_VARS_eNB
*
eNB
=
((
td_params
*
)
param
)
->
eNB
;
eNB_proc_t
*
proc
=
&
eNB
->
proc
;
pthread_setname_np
(
pthread_self
(),
"td processing"
);
PHY_VARS_eNB
*
eNB
=
((
td_params
*
)
param
)
->
eNB
;
eNB_proc_t
*
proc
=
&
eNB
->
proc
;
while
(
!
oai_exit
)
{
while
(
!
oai_exit
)
{
if
(
wait_on_condition
(
&
proc
->
mutex_td
,
&
proc
->
cond_td
,
&
proc
->
instance_cnt_td
,
"td thread"
)
<
0
)
break
;
if
(
wait_on_condition
(
&
proc
->
mutex_td
,
&
proc
->
cond_td
,
&
proc
->
instance_cnt_td
,
"td thread"
)
<
0
)
break
;
((
td_params
*
)
param
)
->
ret
=
ulsch_decoding_data_2thread0
((
td_params
*
)
param
);
((
td_params
*
)
param
)
->
ret
=
ulsch_decoding_data_2thread0
((
td_params
*
)
param
);
if
(
release_thread
(
&
proc
->
mutex_td
,
&
proc
->
instance_cnt_td
,
"td thread"
)
<
0
)
break
;
if
(
release_thread
(
&
proc
->
mutex_td
,
&
proc
->
instance_cnt_td
,
"td thread"
)
<
0
)
break
;
if
(
pthread_cond_signal
(
&
proc
->
cond_td
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_cond_signal for td thread exit
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
(
NULL
);
if
(
pthread_cond_signal
(
&
proc
->
cond_td
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_cond_signal for td thread exit
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
(
NULL
);
}
}
}
return
(
NULL
);
return
(
NULL
);
}
int
ulsch_decoding_data_2thread
(
PHY_VARS_eNB
*
eNB
,
int
UE_id
,
int
harq_pid
,
int
llr8_flag
)
{
eNB_proc_t
*
proc
=
&
eNB
->
proc
;
unsigned
int
r
,
r_offset
=
0
,
Kr
,
Kr_bytes
,
iind
;
uint8_t
crc_type
;
int
offset
=
0
;
int
ret
=
1
;
int16_t
dummy_w
[
MAX_NUM_ULSCH_SEGMENTS
][
3
*
(
6144
+
64
)];
LTE_eNB_ULSCH_t
*
ulsch
=
eNB
->
ulsch
[
UE_id
];
LTE_UL_eNB_HARQ_t
*
ulsch_harq
=
ulsch
->
harq_processes
[
harq_pid
];
eNB_proc_t
*
proc
=
&
eNB
->
proc
;
unsigned
int
r
,
r_offset
=
0
,
Kr
,
Kr_bytes
,
iind
;
uint8_t
crc_type
;
int
offset
=
0
;
int
ret
=
1
;
int16_t
dummy_w
[
MAX_NUM_ULSCH_SEGMENTS
][
3
*
(
6144
+
64
)];
LTE_eNB_ULSCH_t
*
ulsch
=
eNB
->
ulsch
[
UE_id
];
LTE_UL_eNB_HARQ_t
*
ulsch_harq
=
ulsch
->
harq_processes
[
harq_pid
];
int
G
=
ulsch_harq
->
G
;
unsigned
int
E
;
int
Cby2
;
int
G
=
ulsch_harq
->
G
;
unsigned
int
E
;
int
Cby2
;
struct
timespec
wait
;
...
...
@@ -429,107 +429,107 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
phy_threegpplte_turbo_decoder8:
phy_threegpplte_turbo_decoder16
;
if
(
ulsch_harq
->
C
>
1
)
{
// wakeup worker if more than 1 segment
if
(
pthread_mutex_timedlock
(
&
proc
->
mutex_td
,
&
wait
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_mutex_lock for TD thread (IC %d)
\n
"
,
proc
->
instance_cnt_td
);
exit_fun
(
"error locking mutex_fep"
);
return
-
1
;
}
if
(
proc
->
instance_cnt_td
==
0
)
{
printf
(
"[eNB] TD thread busy
\n
"
);
exit_fun
(
"TD thread busy"
);
pthread_mutex_unlock
(
&
proc
->
mutex_td
);
return
-
1
;
}
++
proc
->
instance_cnt_td
;
proc
->
tdp
.
eNB
=
eNB
;
proc
->
tdp
.
UE_id
=
UE_id
;
proc
->
tdp
.
harq_pid
=
harq_pid
;
proc
->
tdp
.
llr8_flag
=
llr8_flag
;
// wakeup worker to do second half segments
if
(
pthread_cond_signal
(
&
proc
->
cond_td
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_cond_signal for td thread exit
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
(
1
+
ulsch
->
max_turbo_iterations
);
}
if
(
ulsch_harq
->
C
>
1
)
{
// wakeup worker if more than 1 segment
if
(
pthread_mutex_timedlock
(
&
proc
->
mutex_td
,
&
wait
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_mutex_lock for TD thread (IC %d)
\n
"
,
proc
->
instance_cnt_td
);
exit_fun
(
"error locking mutex_fep"
);
return
-
1
;
}
pthread_mutex_unlock
(
&
proc
->
mutex_td
);
Cby2
=
ulsch_harq
->
C
/
2
;
}
else
{
Cby2
=
1
;
}
if
(
proc
->
instance_cnt_td
==
0
)
{
printf
(
"[eNB] TD thread busy
\n
"
)
;
exit_fun
(
"TD thread busy"
);
pthread_mutex_unlock
(
&
proc
->
mutex_td
);
return
-
1
;
}
// go through first half of segments in main thread
for
(
r
=
0
;
r
<
Cby2
;
r
++
)
{
++
proc
->
instance_cnt_td
;
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
proc
->
tdp
.
eNB
=
eNB
;
proc
->
tdp
.
UE_id
=
UE_id
;
proc
->
tdp
.
harq_pid
=
harq_pid
;
proc
->
tdp
.
llr8_flag
=
llr8_flag
;
// wakeup worker to do second half segments
if
(
pthread_cond_signal
(
&
proc
->
cond_td
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_cond_signal for td thread exit
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
(
1
+
ulsch
->
max_turbo_iterations
);
}
pthread_mutex_unlock
(
&
proc
->
mutex_td
);
Cby2
=
ulsch_harq
->
C
/
2
;
}
else
{
LOG_E
(
PHY
,
"ulsch_decoding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
Cby2
=
1
;
}
// go through first half of segments in main thread
for
(
r
=
0
;
r
<
Cby2
;
r
++
)
{
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
LOG_E
(
PHY
,
"ulsch_decoding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
}
#ifdef DEBUG_ULSCH_DECODING
printf
(
"f1 %d, f2 %d, F %d
\n
"
,
f1f2mat_old
[
2
*
iind
],
f1f2mat_old
[
1
+
(
2
*
iind
)],(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
printf
(
"f1 %d, f2 %d, F %d
\n
"
,
f1f2mat_old
[
2
*
iind
],
f1f2mat_old
[
1
+
(
2
*
iind
)],(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
#endif
memset
(
&
dummy_w
[
r
][
0
],
0
,
3
*
(
6144
+
64
)
*
sizeof
(
short
));
ulsch_harq
->
RTC
[
r
]
=
generate_dummy_w
(
4
+
(
Kr_bytes
*
8
),
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
memset
(
&
dummy_w
[
r
][
0
],
0
,
3
*
(
6144
+
64
)
*
sizeof
(
short
));
ulsch_harq
->
RTC
[
r
]
=
generate_dummy_w
(
4
+
(
Kr_bytes
*
8
),
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
#ifdef DEBUG_ULSCH_DECODING
printf
(
"Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...
\n
"
,
r
,
G
,
Kr
*
3
,
Q_m
,
nb_rb
,
ulsch_harq
->
Nl
);
printf
(
"Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...
\n
"
,
r
,
G
,
Kr
*
3
,
Q_m
,
nb_rb
,
ulsch_harq
->
Nl
);
#endif
start_meas
(
&
eNB
->
ulsch_rate_unmatching_stats
);
if
(
lte_rate_matching_turbo_rx
(
ulsch_harq
->
RTC
[
r
],
G
,
ulsch_harq
->
w
[
r
],
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
ulsch_harq
->
e
+
r_offset
,
ulsch_harq
->
C
,
NSOFT
,
0
,
//Uplink
1
,
ulsch_harq
->
rvidx
,
(
ulsch_harq
->
round
==
0
)
?
1
:
0
,
// clear
ulsch_harq
->
Qm
,
1
,
r
,
&
E
)
==-
1
)
{
LOG_E
(
PHY
,
"ulsch_decoding.c: Problem in rate matching
\n
"
);
return
(
-
1
);
}
start_meas
(
&
eNB
->
ulsch_rate_unmatching_stats
);
stop_meas
(
&
eNB
->
ulsch_rate_unmatching_stats
);
if
(
lte_rate_matching_turbo_rx
(
ulsch_harq
->
RTC
[
r
],
G
,
ulsch_harq
->
w
[
r
],
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
ulsch_harq
->
e
+
r_offset
,
ulsch_harq
->
C
,
NSOFT
,
0
,
//Uplink
1
,
ulsch_harq
->
rvidx
,
(
ulsch_harq
->
round
==
0
)
?
1
:
0
,
// clear
ulsch_harq
->
Qm
,
1
,
r
,
&
E
)
==-
1
)
{
LOG_E
(
PHY
,
"ulsch_decoding.c: Problem in rate matching
\n
"
);
return
(
-
1
);
}
stop_meas
(
&
eNB
->
ulsch_rate_unmatching_stats
);
r_offset
+=
E
;
int16_t
soft_bits
[
3
*
8
*
6144
+
12
+
96
]
__attribute__
((
aligned
(
32
)));
...
...
@@ -577,25 +577,25 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
memcpy
(
ulsch_harq
->
b
,
decoded_bytes
+
(
ulsch_harq
->
F
>>
3
),
Kr_bytes
-
(
ulsch_harq
->
F
>>
3
)
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
offset
=
Kr_bytes
-
(
ulsch_harq
->
F
>>
3
)
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
);
}
else
{
memcpy
(
ulsch_harq
->
b
+
offset
,
offset
=
Kr_bytes
-
(
ulsch_harq
->
F
>>
3
)
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
);
}
else
{
memcpy
(
ulsch_harq
->
b
+
offset
,
decoded_bytes
,
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
offset
+=
(
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
}
}
else
{
break
;
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
offset
+=
(
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
}
}
else
{
break
;
}
stop_meas
(
&
eNB
->
ulsch_turbo_decoding_stats
);
}
stop_meas
(
&
eNB
->
ulsch_turbo_decoding_stats
);
}
// wait for worker to finish
// wait for worker to finish
wait_on_busy_condition
(
&
proc
->
mutex_td
,
&
proc
->
cond_td
,
&
proc
->
instance_cnt_td
,
"td thread"
);
wait_on_busy_condition
(
&
proc
->
mutex_td
,
&
proc
->
cond_td
,
&
proc
->
instance_cnt_td
,
"td thread"
);
return
(
(
ret
>
proc
->
tdp
.
ret
)
?
ret
:
proc
->
tdp
.
ret
);
return
(
(
ret
>
proc
->
tdp
.
ret
)
?
ret
:
proc
->
tdp
.
ret
);
}
request_t
*
ulsch_decoding_data
(
PHY_VARS_eNB
*
eNB
,
int
UE_id
,
int
harq_pid
,
int
llr8_flag
,
int
frame
,
int
subframe
)
{
...
...
@@ -642,6 +642,7 @@ request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
r_offset
+=
E
;
start_meas
(
&
eNB
->
ulsch_deinterleaving_stats
);
req
=
createRequest
(
DECODE
,
sizeof
(
turboDecode_t
));
req
->
startUELoop
=
eNB
->
proc
.
threadPool
.
startProcessingUE
;
union
turboReqUnion
id
=
{.
s
=
{
eNB
->
ulsch
[
UE_id
]
->
rnti
,
frame
,
subframe
,
r
,
0
}};
req
->
id
=
id
.
p
;
turboDecode_t
*
rdata
=
(
turboDecode_t
*
)
req
->
data
;
...
...
@@ -682,7 +683,7 @@ request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
add_request
(
req
,
&
eNB
->
proc
.
threadPool
);
req
=
NULL
;
}
else
{
req
->
creationTime
=
req
->
startProcessingTime
=
rdtsc
();
req
->
startProcessingTime
=
rdtsc
();
rdata
->
decodeIterations
=
td
(
rdata
->
soft_bits
+
96
,
rdata
->
decoded_bytes
,
rdata
->
Kr
,
...
...
@@ -704,14 +705,15 @@ request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
req
->
decodeIterations
=
rdata
->
decodeIterations
;
req
->
coreId
=
0
;
req
->
processedBy
[
0
]
=
0
;
req
->
next
=
eNB
->
proc
.
threadPool
.
doneRequests
;
eNB
->
proc
.
threadPool
.
doneRequests
=
req
;
if
(
rdata
->
decodeIterations
>
eNB
->
ulsch
[
UE_id
]
->
max_turbo_iterations
)
req
->
next
=
eNB
->
proc
.
threadPool
.
doneRequests
;
eNB
->
proc
.
threadPool
.
doneRequests
=
req
;
if
(
rdata
->
decodeIterations
>
eNB
->
ulsch
[
UE_id
]
->
max_turbo_iterations
)
// Entire TPU need retransmission
break
;
}
offset
+=
blockSize
;
eNB
->
proc
.
threadPool
.
startProcessingUE
=
rdtsc
();
}
return
NULL
;
}
...
...
@@ -719,28 +721,28 @@ request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
static
inline
unsigned
int
lte_gold_unscram
(
unsigned
int
*
x1
,
unsigned
int
*
x2
,
unsigned
char
reset
)
__attribute__
((
always_inline
));
static
inline
unsigned
int
lte_gold_unscram
(
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
);
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);
*
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);
}
...
...
@@ -790,389 +792,389 @@ request_t* ulsch_decoding(PHY_VARS_eNB *eNB,
harq_pid
=
subframe2harq_pid
(
frame_parms
,
proc
->
frame_rx
,
subframe
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0
+
harq_pid
,
1
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0
+
harq_pid
,
1
);
// x1 is set in lte_gold_generic
x2
=
((
uint32_t
)
ulsch
->
rnti
<<
14
)
+
((
uint32_t
)
subframe
<<
9
)
+
frame_parms
->
Nid_cell
;
//this is c_init in 36.211 Sec 6.3.1
ulsch_harq
=
ulsch
->
harq_processes
[
harq_pid
];
// x1 is set in lte_gold_generic
x2
=
((
uint32_t
)
ulsch
->
rnti
<<
14
)
+
((
uint32_t
)
subframe
<<
9
)
+
frame_parms
->
Nid_cell
;
//this is c_init in 36.211 Sec 6.3.1
ulsch_harq
=
ulsch
->
harq_processes
[
harq_pid
];
AssertFatal
(
harq_pid
<
8
,
"FATAL ERROR: illegal harq_pid, returning
\n
"
);
AssertFatal
(
ulsch_harq
->
Nsymb_pusch
!=
0
,
"FATAL ERROR: harq_pid %d, Nsymb 0!
\n
"
,
harq_pid
);
nb_rb
=
ulsch_harq
->
nb_rb
;
A
=
ulsch_harq
->
TBS
;
Q_m
=
ulsch_harq
->
Qm
;
G
=
nb_rb
*
(
12
*
Q_m
)
*
ulsch_harq
->
Nsymb_pusch
;
//#ifdef DEBUG_ULSCH_DECODING
LOG_D
(
PHY
,
"[PUSCH %d] Frame %d, Subframe %d: ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): A %d, round %d, RV %d, O_r1 %d, O_RI %d, O_ACK %d, G %d, Q_m %d Nsymb_pusch %d nb_rb %d
\n
"
,
harq_pid
,
proc
->
frame_rx
,
subframe
,
frame_parms
->
Nid_cell
,
ulsch
->
rnti
,
x2
,
A
,
ulsch_harq
->
round
,
ulsch_harq
->
rvidx
,
ulsch_harq
->
Or1
,
ulsch_harq
->
O_RI
,
ulsch_harq
->
O_ACK
,
G
,
ulsch_harq
->
Qm
,
ulsch_harq
->
Nsymb_pusch
,
nb_rb
);
//#endif
if
(
ulsch_harq
->
round
==
0
)
{
// This is a new packet, so compute quantities regarding segmentation
ulsch_harq
->
B
=
A
+
24
;
lte_segmentation
(
NULL
,
NULL
,
ulsch_harq
->
B
,
&
ulsch_harq
->
C
,
&
ulsch_harq
->
Cplus
,
&
ulsch_harq
->
Cminus
,
&
ulsch_harq
->
Kplus
,
&
ulsch_harq
->
Kminus
,
&
ulsch_harq
->
F
);
// CLEAR LLR's HERE for first packet in process
}
// printf("after segmentation c[%d] = %p\n",0,ulsch_harq->c[0]);
sumKr
=
0
;
for
(
r
=
0
;
r
<
ulsch_harq
->
C
;
r
++
)
{
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
"FATAL ERROR: illegal harq_pid, returning
\n
"
);
AssertFatal
(
ulsch_harq
->
Nsymb_pusch
!=
0
,
"FATAL ERROR: harq_pid %d, Nsymb 0!
\n
"
,
harq_pid
);
nb_rb
=
ulsch_harq
->
nb_rb
;
A
=
ulsch_harq
->
TBS
;
Q_m
=
ulsch_harq
->
Qm
;
G
=
nb_rb
*
(
12
*
Q_m
)
*
ulsch_harq
->
Nsymb_pusch
;
//#ifdef DEBUG_ULSCH_DECODING
LOG_D
(
PHY
,
"[PUSCH %d] Frame %d, Subframe %d: ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): A %d, round %d, RV %d, O_r1 %d, O_RI %d, O_ACK %d, G %d, Q_m %d Nsymb_pusch %d nb_rb %d
\n
"
,
harq_pid
,
proc
->
frame_rx
,
subframe
,
frame_parms
->
Nid_cell
,
ulsch
->
rnti
,
x2
,
A
,
ulsch_harq
->
round
,
ulsch_harq
->
rvidx
,
ulsch_harq
->
Or1
,
ulsch_harq
->
O_RI
,
ulsch_harq
->
O_ACK
,
G
,
ulsch_harq
->
Qm
,
ulsch_harq
->
Nsymb_pusch
,
nb_rb
);
//#endif
if
(
ulsch_harq
->
round
==
0
)
{
// This is a new packet, so compute quantities regarding segmentation
ulsch_harq
->
B
=
A
+
24
;
lte_segmentation
(
NULL
,
NULL
,
ulsch_harq
->
B
,
&
ulsch_harq
->
C
,
&
ulsch_harq
->
Cplus
,
&
ulsch_harq
->
Cminus
,
&
ulsch_harq
->
Kplus
,
&
ulsch_harq
->
Kminus
,
&
ulsch_harq
->
F
);
// CLEAR LLR's HERE for first packet in process
}
sumKr
+=
Kr
;
}
// printf("after segmentation c[%d] = %p\n",0,ulsch_harq->c[0]);
AssertFatal
(
sumKr
>
0
,
"[eNB] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, O_RI %d, O_ACK %d, G %d, subframe %d
\n
"
,
frame_parms
->
Nid_cell
,
ulsch
->
rnti
,
x2
,
harq_pid
,
ulsch_harq
->
round
,
ulsch_harq
->
rvidx
,
ulsch_harq
->
O_RI
,
ulsch_harq
->
O_ACK
,
G
,
subframe
);
sumKr
=
0
;
for
(
r
=
0
;
r
<
ulsch_harq
->
C
;
r
++
)
{
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
// Compute Q_ri
Qprime
=
ulsch_harq
->
O_RI
*
ulsch_harq
->
Msc_initial
*
ulsch_harq
->
Nsymb_initial
*
ulsch
->
beta_offset_ri_times8
;
sumKr
+=
Kr
;
}
if
(
Qprime
>
0
)
{
if
((
Qprime
%
(
8
*
sumKr
))
>
0
)
Qprime
=
1
+
(
Qprime
/
(
8
*
sumKr
));
else
Qprime
=
Qprime
/
(
8
*
sumKr
);
AssertFatal
(
sumKr
>
0
,
"[eNB] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, O_RI %d, O_ACK %d, G %d, subframe %d
\n
"
,
frame_parms
->
Nid_cell
,
ulsch
->
rnti
,
x2
,
harq_pid
,
ulsch_harq
->
round
,
ulsch_harq
->
rvidx
,
ulsch_harq
->
O_RI
,
ulsch_harq
->
O_ACK
,
G
,
subframe
);
if
(
Qprime
>
4
*
nb_rb
*
12
)
Qprime
=
4
*
nb_rb
*
12
;
}
Q_RI
=
Q_m
*
Qprime
;
Qprime_RI
=
Qprime
;
// Compute Q_ri
Qprime
=
ulsch_harq
->
O_RI
*
ulsch_harq
->
Msc_initial
*
ulsch_harq
->
Nsymb_initial
*
ulsch
->
beta_offset_ri_times8
;
if
(
Qprime
>
0
)
{
if
((
Qprime
%
(
8
*
sumKr
))
>
0
)
Qprime
=
1
+
(
Qprime
/
(
8
*
sumKr
));
else
Qprime
=
Qprime
/
(
8
*
sumKr
);
if
(
Qprime
>
4
*
nb_rb
*
12
)
Qprime
=
4
*
nb_rb
*
12
;
}
// Compute Q_ack
Q_RI
=
Q_m
*
Qprime
;
Qprime_RI
=
Qprime
;
Qprime
=
ulsch_harq
->
O_ACK
*
ulsch_harq
->
Msc_initial
*
ulsch_harq
->
Nsymb_initial
*
ulsch
->
beta_offset_harqack_times8
;
if
(
Qprime
>
0
)
{
if
((
Qprime
%
(
8
*
sumKr
))
>
0
)
Qprime
=
1
+
(
Qprime
/
(
8
*
sumKr
));
else
Qprime
=
Qprime
/
(
8
*
sumKr
);
// Compute Q_ack
Qprime
=
ulsch_harq
->
O_ACK
*
ulsch_harq
->
Msc_initial
*
ulsch_harq
->
Nsymb_initial
*
ulsch
->
beta_offset_harqack_times8
;
if
(
Qprime
>
0
)
{
if
((
Qprime
%
(
8
*
sumKr
))
>
0
)
Qprime
=
1
+
(
Qprime
/
(
8
*
sumKr
));
else
Qprime
=
Qprime
/
(
8
*
sumKr
);
if
(
Qprime
>
(
4
*
nb_rb
*
12
))
Qprime
=
4
*
nb_rb
*
12
;
}
if
(
Qprime
>
(
4
*
nb_rb
*
12
))
Qprime
=
4
*
nb_rb
*
12
;
}
// Q_ACK = Qprime * Q_m;
Qprime_ACK
=
Qprime
;
// Q_ACK = Qprime * Q_m;
Qprime_ACK
=
Qprime
;
#ifdef DEBUG_ULSCH_DECODING
printf
(
"ulsch_decoding.c: Qprime_ACK %d, Msc_initial %d, Nsymb_initial %d, sumKr %d
\n
"
,
Qprime_ACK
,
ulsch_harq
->
Msc_initial
,
ulsch_harq
->
Nsymb_initial
,
sumKr
);
printf
(
"ulsch_decoding.c: Qprime_ACK %d, Msc_initial %d, Nsymb_initial %d, sumKr %d
\n
"
,
Qprime_ACK
,
ulsch_harq
->
Msc_initial
,
ulsch_harq
->
Nsymb_initial
,
sumKr
);
#endif
// Compute Q_cqi
if
(
ulsch_harq
->
Or1
<
12
)
L
=
0
;
else
L
=
8
;
// NOTE: we have to handle the case where we have a very small number of bits (condition on pg. 26 36.212)
if
(
ulsch_harq
->
Or1
>
0
)
Qprime
=
(
ulsch_harq
->
Or1
+
L
)
*
ulsch_harq
->
Msc_initial
*
ulsch_harq
->
Nsymb_initial
*
ulsch
->
beta_offset_cqi_times8
;
else
Qprime
=
0
;
if
(
Qprime
>
0
)
{
// check if ceiling is larger than floor in Q' expression
if
((
Qprime
%
(
8
*
sumKr
))
>
0
)
Qprime
=
1
+
(
Qprime
/
(
8
*
sumKr
));
// Compute Q_cqi
if
(
ulsch_harq
->
Or1
<
12
)
L
=
0
;
else
Qprime
=
Qprime
/
(
8
*
sumKr
);
}
L
=
8
;
G
=
nb_rb
*
(
12
*
Q_m
)
*
(
ulsch_harq
->
Nsymb_pusch
);
// NOTE: we have to handle the case where we have a very small number of bits (condition on pg. 26 36.212)
if
(
ulsch_harq
->
Or1
>
0
)
Qprime
=
(
ulsch_harq
->
Or1
+
L
)
*
ulsch_harq
->
Msc_initial
*
ulsch_harq
->
Nsymb_initial
*
ulsch
->
beta_offset_cqi_times8
;
else
Qprime
=
0
;
if
(
Qprime
>
0
)
{
// check if ceiling is larger than floor in Q' expression
if
((
Qprime
%
(
8
*
sumKr
))
>
0
)
Qprime
=
1
+
(
Qprime
/
(
8
*
sumKr
));
else
Qprime
=
Qprime
/
(
8
*
sumKr
);
}
G
=
nb_rb
*
(
12
*
Q_m
)
*
(
ulsch_harq
->
Nsymb_pusch
);
Q_CQI
=
Q_m
*
Qprime
;
Q_CQI
=
Q_m
*
Qprime
;
#ifdef DEBUG_ULSCH_DECODING
printf
(
"ulsch_decoding: G %d, Q_RI %d, Q_CQI %d (L %d, Or1 %d) O_ACK %d
\n
"
,
G
,
Q_RI
,
Q_CQI
,
L
,
ulsch_harq
->
Or1
,
ulsch_harq
->
O_ACK
);
printf
(
"ulsch_decoding: G %d, Q_RI %d, Q_CQI %d (L %d, Or1 %d) O_ACK %d
\n
"
,
G
,
Q_RI
,
Q_CQI
,
L
,
ulsch_harq
->
Or1
,
ulsch_harq
->
O_ACK
);
#endif
G
=
G
-
Q_RI
-
Q_CQI
;
ulsch_harq
->
G
=
G
;
G
=
G
-
Q_RI
-
Q_CQI
;
ulsch_harq
->
G
=
G
;
AssertFatal
((
int
)
G
>
0
,
"FATAL: ulsch_decoding.c G < 0 (%d) : Q_RI %d, Q_CQI %d
\n
"
,
G
,
Q_RI
,
Q_CQI
);
AssertFatal
((
int
)
G
>
0
,
"FATAL: ulsch_decoding.c G < 0 (%d) : Q_RI %d, Q_CQI %d
\n
"
,
G
,
Q_RI
,
Q_CQI
);
H
=
G
+
Q_CQI
;
Hprime
=
H
/
Q_m
;
H
=
G
+
Q_CQI
;
Hprime
=
H
/
Q_m
;
// Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI
start_meas
(
&
eNB
->
ulsch_demultiplexing_stats
);
Hpp
=
Hprime
+
Qprime_RI
;
// Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI
start_meas
(
&
eNB
->
ulsch_demultiplexing_stats
);
Hpp
=
Hprime
+
Qprime_RI
;
Cmux
=
ulsch_harq
->
Nsymb_pusch
;
Rmux_prime
=
Hpp
/
Cmux
;
Cmux
=
ulsch_harq
->
Nsymb_pusch
;
Rmux_prime
=
Hpp
/
Cmux
;
// Clear "tag" interleaving matrix to allow for CQI/DATA identification
memset
(
ytag
,
0
,
Cmux
*
Rmux_prime
);
// Clear "tag" interleaving matrix to allow for CQI/DATA identification
memset
(
ytag
,
0
,
Cmux
*
Rmux_prime
);
i
=
0
;
memset
(
y
,
LTE_NULL
,
Q_m
*
Hpp
);
i
=
0
;
memset
(
y
,
LTE_NULL
,
Q_m
*
Hpp
);
// read in buffer and unscramble llrs for everything but placeholder bits
// llrs stored per symbol correspond to columns of interleaving matrix
// read in buffer and unscramble llrs for everything but placeholder bits
// llrs stored per symbol correspond to columns of interleaving matrix
s
=
lte_gold_unscram
(
&
x1
,
&
x2
,
1
);
i2
=
0
;
s
=
lte_gold_unscram
(
&
x1
,
&
x2
,
1
);
i2
=
0
;
for
(
i
=
0
;
i
<
((
Hpp
*
Q_m
)
>>
5
);
i
++
)
{
/*
for (j=0; j<32; j++) {
cseq[i2++] = (int16_t)((((s>>j)&1)<<1)-1);
}
*/
for
(
i
=
0
;
i
<
((
Hpp
*
Q_m
)
>>
5
);
i
++
)
{
/*
for (j=0; j<32; j++) {
cseq[i2++] = (int16_t)((((s>>j)&1)<<1)-1);
}
*/
#if defined(__x86_64__) || defined(__i386__)
#ifndef __AVX2__
((
__m128i
*
)
cseq
)[
i2
++
]
=
((
__m128i
*
)
unscrambling_lut
)[(
s
&
65535
)
<<
1
];
((
__m128i
*
)
cseq
)[
i2
++
]
=
((
__m128i
*
)
unscrambling_lut
)[
1
+
((
s
&
65535
)
<<
1
)];
s
>>=
16
;
((
__m128i
*
)
cseq
)[
i2
++
]
=
((
__m128i
*
)
unscrambling_lut
)[(
s
&
65535
)
<<
1
];
((
__m128i
*
)
cseq
)[
i2
++
]
=
((
__m128i
*
)
unscrambling_lut
)[
1
+
((
s
&
65535
)
<<
1
)];
((
__m128i
*
)
cseq
)[
i2
++
]
=
((
__m128i
*
)
unscrambling_lut
)[(
s
&
65535
)
<<
1
];
((
__m128i
*
)
cseq
)[
i2
++
]
=
((
__m128i
*
)
unscrambling_lut
)[
1
+
((
s
&
65535
)
<<
1
)];
s
>>=
16
;
((
__m128i
*
)
cseq
)[
i2
++
]
=
((
__m128i
*
)
unscrambling_lut
)[(
s
&
65535
)
<<
1
];
((
__m128i
*
)
cseq
)[
i2
++
]
=
((
__m128i
*
)
unscrambling_lut
)[
1
+
((
s
&
65535
)
<<
1
)];
#else
((
__m256i
*
)
cseq
)[
i2
++
]
=
((
__m256i
*
)
unscrambling_lut
)[
s
&
65535
];
((
__m256i
*
)
cseq
)[
i2
++
]
=
((
__m256i
*
)
unscrambling_lut
)[(
s
>>
16
)
&
65535
];
((
__m256i
*
)
cseq
)[
i2
++
]
=
((
__m256i
*
)
unscrambling_lut
)[
s
&
65535
];
((
__m256i
*
)
cseq
)[
i2
++
]
=
((
__m256i
*
)
unscrambling_lut
)[(
s
>>
16
)
&
65535
];
#endif
#elif defined(__arm__)
((
int16x8_t
*
)
cseq
)[
i2
++
]
=
((
int16x8_t
*
)
unscrambling_lut
)[(
s
&
65535
)
<<
1
];
((
int16x8_t
*
)
cseq
)[
i2
++
]
=
((
int16x8_t
*
)
unscrambling_lut
)[
1
+
((
s
&
65535
)
<<
1
)];
s
>>=
16
;
((
int16x8_t
*
)
cseq
)[
i2
++
]
=
((
int16x8_t
*
)
unscrambling_lut
)[(
s
&
65535
)
<<
1
];
((
int16x8_t
*
)
cseq
)[
i2
++
]
=
((
int16x8_t
*
)
unscrambling_lut
)[
1
+
((
s
&
65535
)
<<
1
)];
((
int16x8_t
*
)
cseq
)[
i2
++
]
=
((
int16x8_t
*
)
unscrambling_lut
)[(
s
&
65535
)
<<
1
];
((
int16x8_t
*
)
cseq
)[
i2
++
]
=
((
int16x8_t
*
)
unscrambling_lut
)[
1
+
((
s
&
65535
)
<<
1
)];
s
>>=
16
;
((
int16x8_t
*
)
cseq
)[
i2
++
]
=
((
int16x8_t
*
)
unscrambling_lut
)[(
s
&
65535
)
<<
1
];
((
int16x8_t
*
)
cseq
)[
i2
++
]
=
((
int16x8_t
*
)
unscrambling_lut
)[
1
+
((
s
&
65535
)
<<
1
)];
#endif
s
=
lte_gold_unscram
(
&
x1
,
&
x2
,
0
);
}
// printf("after unscrambling c[%d] = %p\n",0,ulsch_harq->c[0]);
s
=
lte_gold_unscram
(
&
x1
,
&
x2
,
0
);
}
if
(
frame_parms
->
Ncp
==
0
)
columnset
=
cs_ri_normal
;
else
columnset
=
cs_ri_extended
;
j
=
0
;
// printf("after unscrambling c[%d] = %p\n",0,ulsch_harq->c[0])
;
for
(
i
=
0
;
i
<
Qprime_RI
;
i
++
)
{
r
=
Rmux_prime
-
1
-
(
i
>>
2
);
/*
for (q=0;q<Q_m;q++)
ytag2[q+(Q_m*((r*Cmux) + columnset[j]))] = q_RI[(q+(Q_m*i))%len_RI];
*/
off
=
((
Rmux_prime
*
Q_m
*
columnset
[
j
])
+
(
r
*
Q_m
));
cseq
[
off
+
1
]
=
cseq
[
off
];
// PUSCH_y
if
(
frame_parms
->
Ncp
==
0
)
columnset
=
cs_ri_normal
;
else
columnset
=
cs_ri_extended
;
for
(
q
=
2
;
q
<
Q_m
;
q
++
)
cseq
[
off
+
q
]
=
-
1
;
// PUSCH_x
j
=
0
;
j
=
(
j
+
3
)
&
3
;
for
(
i
=
0
;
i
<
Qprime_RI
;
i
++
)
{
r
=
Rmux_prime
-
1
-
(
i
>>
2
);
/*
for (q=0;q<Q_m;q++)
ytag2[q+(Q_m*((r*Cmux) + columnset[j]))] = q_RI[(q+(Q_m*i))%len_RI];
*/
off
=
((
Rmux_prime
*
Q_m
*
columnset
[
j
])
+
(
r
*
Q_m
));
cseq
[
off
+
1
]
=
cseq
[
off
];
// PUSCH_y
}
for
(
q
=
2
;
q
<
Q_m
;
q
++
)
cseq
[
off
+
q
]
=
-
1
;
// PUSCH_x
// printf("after RI c[%d] = %p\n",0,ulsch_harq->c[0])
;
j
=
(
j
+
3
)
&
3
;
// HARQ-ACK Bits (Note these overwrite some bits)
if
(
frame_parms
->
Ncp
==
0
)
columnset
=
cs_ack_normal
;
else
columnset
=
cs_ack_extended
;
}
j
=
0
;
// printf("after RI c[%d] = %p\n",0,ulsch_harq->c[0])
;
for
(
i
=
0
;
i
<
Qprime_ACK
;
i
++
)
{
r
=
Rmux_prime
-
1
-
(
i
>>
2
);
off
=
((
Rmux_prime
*
Q_m
*
columnset
[
j
])
+
(
r
*
Q_m
));
// HARQ-ACK Bits (Note these overwrite some bits)
if
(
frame_parms
->
Ncp
==
0
)
columnset
=
cs_ack_normal
;
else
columnset
=
cs_ack_extended
;
if
(
ulsch_harq
->
O_ACK
==
1
)
{
if
(
ulsch
->
bundling
==
0
)
cseq
[
off
+
1
]
=
cseq
[
off
];
// PUSCH_y
j
=
0
;
for
(
q
=
2
;
q
<
Q_m
;
q
++
)
cseq
[
off
+
q
]
=
-
1
;
// PUSCH_x
}
else
if
(
ulsch_harq
->
O_ACK
==
2
)
{
for
(
q
=
2
;
q
<
Q_m
;
q
++
)
cseq
[
off
+
q
]
=
-
1
;
// PUSCH_x
}
for
(
i
=
0
;
i
<
Qprime_ACK
;
i
++
)
{
r
=
Rmux_prime
-
1
-
(
i
>>
2
);
off
=
((
Rmux_prime
*
Q_m
*
columnset
[
j
])
+
(
r
*
Q_m
));
if
(
ulsch_harq
->
O_ACK
==
1
)
{
if
(
ulsch
->
bundling
==
0
)
cseq
[
off
+
1
]
=
cseq
[
off
];
// PUSCH_y
for
(
q
=
2
;
q
<
Q_m
;
q
++
)
cseq
[
off
+
q
]
=
-
1
;
// PUSCH_x
}
else
if
(
ulsch_harq
->
O_ACK
==
2
)
{
for
(
q
=
2
;
q
<
Q_m
;
q
++
)
cseq
[
off
+
q
]
=
-
1
;
// PUSCH_x
}
#ifdef DEBUG_ULSCH_DECODING
printf
(
"ulsch_decoding.c: ACK i %d, r %d, j %d, ColumnSet[j] %d
\n
"
,
i
,
r
,
j
,
columnset
[
j
]);
printf
(
"ulsch_decoding.c: ACK i %d, r %d, j %d, ColumnSet[j] %d
\n
"
,
i
,
r
,
j
,
columnset
[
j
]);
#endif
j
=
(
j
+
3
)
&
3
;
}
j
=
(
j
+
3
)
&
3
;
}
i
=
0
;
i
=
0
;
switch
(
Q_m
)
{
case
2
:
for
(
j
=
0
;
j
<
Cmux
;
j
++
)
{
i2
=
j
<<
1
;
switch
(
Q_m
)
{
case
2
:
for
(
j
=
0
;
j
<
Cmux
;
j
++
)
{
i2
=
j
<<
1
;
for
(
r
=
0
;
r
<
Rmux_prime
;
r
++
)
{
c
=
cseq
[
i
];
// printf("ulsch %d: %d * ",i,c);
y
[
i2
++
]
=
c
*
ulsch_llr
[
i
++
];
// printf("%d\n",ulsch_llr[i-1]);
c
=
cseq
[
i
];
// printf("ulsch %d: %d * ",i,c);
y
[
i2
]
=
c
*
ulsch_llr
[
i
++
];
// printf("%d\n",ulsch_llr[i-1]);
i2
=
(
i2
+
(
Cmux
<<
1
)
-
1
);
}
}
for
(
r
=
0
;
r
<
Rmux_prime
;
r
++
)
{
c
=
cseq
[
i
];
// printf("ulsch %d: %d * ",i,c);
y
[
i2
++
]
=
c
*
ulsch_llr
[
i
++
];
// printf("%d\n",ulsch_llr[i-1]);
c
=
cseq
[
i
];
// printf("ulsch %d: %d * ",i,c);
y
[
i2
]
=
c
*
ulsch_llr
[
i
++
];
// printf("%d\n",ulsch_llr[i-1]);
i2
=
(
i2
+
(
Cmux
<<
1
)
-
1
);
}
}
break
;
break
;
case
4
:
for
(
j
=
0
;
j
<
Cmux
;
j
++
)
{
i2
=
j
<<
2
;
for
(
r
=
0
;
r
<
Rmux_prime
;
r
++
)
{
/*
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2] = c*ulsch_llr[i++];
i2=(i2+(Cmux<<2)-3);
*/
case
4
:
for
(
j
=
0
;
j
<
Cmux
;
j
++
)
{
i2
=
j
<<
2
;
for
(
r
=
0
;
r
<
Rmux_prime
;
r
++
)
{
/*
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2] = c*ulsch_llr[i++];
i2=(i2+(Cmux<<2)-3);
*/
// slightly more optimized version (equivalent to above) for 16QAM to improve computational performance
*
(
__m64
*
)
&
y
[
i2
]
=
_mm_sign_pi16
(
*
(
__m64
*
)
&
ulsch_llr
[
i
],
*
(
__m64
*
)
&
cseq
[
i
]);
i
+=
4
;
i2
+=
(
Cmux
<<
2
);
}
}
}
}
break
;
case
6
:
for
(
j
=
0
;
j
<
Cmux
;
j
++
)
{
i2
=
j
*
6
;
for
(
r
=
0
;
r
<
Rmux_prime
;
r
++
)
{
c
=
cseq
[
i
];
y
[
i2
++
]
=
c
*
ulsch_llr
[
i
++
];
c
=
cseq
[
i
];
y
[
i2
++
]
=
c
*
ulsch_llr
[
i
++
];
c
=
cseq
[
i
];
y
[
i2
++
]
=
c
*
ulsch_llr
[
i
++
];
c
=
cseq
[
i
];
y
[
i2
++
]
=
c
*
ulsch_llr
[
i
++
];
c
=
cseq
[
i
];
y
[
i2
++
]
=
c
*
ulsch_llr
[
i
++
];
c
=
cseq
[
i
];
y
[
i2
]
=
c
*
ulsch_llr
[
i
++
];
i2
=
(
i2
+
(
Cmux
*
6
)
-
5
);
}
}
break
;
break
;
}
case
6
:
for
(
j
=
0
;
j
<
Cmux
;
j
++
)
{
i2
=
j
*
6
;
for
(
r
=
0
;
r
<
Rmux_prime
;
r
++
)
{
c
=
cseq
[
i
];
y
[
i2
++
]
=
c
*
ulsch_llr
[
i
++
];
c
=
cseq
[
i
];
y
[
i2
++
]
=
c
*
ulsch_llr
[
i
++
];
c
=
cseq
[
i
];
y
[
i2
++
]
=
c
*
ulsch_llr
[
i
++
];
c
=
cseq
[
i
];
y
[
i2
++
]
=
c
*
ulsch_llr
[
i
++
];
c
=
cseq
[
i
];
y
[
i2
++
]
=
c
*
ulsch_llr
[
i
++
];
c
=
cseq
[
i
];
y
[
i2
]
=
c
*
ulsch_llr
[
i
++
];
i2
=
(
i2
+
(
Cmux
*
6
)
-
5
);
}
}
break
;
}
if
(
i
!=
(
H
+
Q_RI
))
LOG_D
(
PHY
,
"ulsch_decoding.c: Error in input buffer length (j %d, H+Q_RI %d)
\n
"
,
i
,
H
+
Q_RI
);
if
(
i
!=
(
H
+
Q_RI
))
LOG_D
(
PHY
,
"ulsch_decoding.c: Error in input buffer length (j %d, H+Q_RI %d)
\n
"
,
i
,
H
+
Q_RI
);
// HARQ-ACK Bits (LLRs are nulled in overwritten bits after copying HARQ-ACK LLR)
// HARQ-ACK Bits (LLRs are nulled in overwritten bits after copying HARQ-ACK LLR)
if
(
frame_parms
->
Ncp
==
0
)
columnset
=
cs_ack_normal
;
else
columnset
=
cs_ack_extended
;
if
(
frame_parms
->
Ncp
==
0
)
columnset
=
cs_ack_normal
;
else
columnset
=
cs_ack_extended
;
j
=
0
;
j
=
0
;
if
(
ulsch_harq
->
O_ACK
==
1
)
{
switch
(
Q_m
)
{
case
2
:
len_ACK
=
2
;
break
;
if
(
ulsch_harq
->
O_ACK
==
1
)
{
switch
(
Q_m
)
{
case
2
:
len_ACK
=
2
;
break
;
case
4
:
len_ACK
=
4
;
break
;
case
4
:
len_ACK
=
4
;
break
;
case
6
:
len_ACK
=
6
;
break
;
case
6
:
len_ACK
=
6
;
break
;
}
}
}
if
(
ulsch_harq
->
O_ACK
==
2
)
{
switch
(
Q_m
)
{
case
2
:
len_ACK
=
6
;
break
;
if
(
ulsch_harq
->
O_ACK
==
2
)
{
switch
(
Q_m
)
{
case
2
:
len_ACK
=
6
;
break
;
case
4
:
len_ACK
=
12
;
break
;
case
4
:
len_ACK
=
12
;
break
;
case
6
:
len_ACK
=
18
;
break
;
case
6
:
len_ACK
=
18
;
break
;
}
}
}
if
(
ulsch_harq
->
O_ACK
>
2
)
{
LOG_E
(
PHY
,
"ulsch_decoding: FATAL, ACK cannot be more than 2 bits yet
\n
"
);
...
...
@@ -1220,282 +1222,282 @@ request_t* ulsch_decoding(PHY_VARS_eNB *eNB,
return
NULL
;
}
for
(
i
=
0
;
i
<
len_RI
;
i
++
)
ulsch_harq
->
q_RI
[
i
]
=
0
;
if
(
frame_parms
->
Ncp
==
0
)
columnset
=
cs_ri_normal
;
else
columnset
=
cs_ri_extended
;
j
=
0
;
for
(
i
=
0
;
i
<
Qprime_RI
;
i
++
)
{
r
=
Rmux_prime
-
1
-
(
i
>>
2
);
for
(
q
=
0
;
q
<
Q_m
;
q
++
)
ulsch_harq
->
q_RI
[(
q
+
(
Q_m
*
i
))
%
len_RI
]
+=
y
[
q
+
(
Q_m
*
((
r
*
Cmux
)
+
columnset
[
j
]))];
ytag
[(
r
*
Cmux
)
+
columnset
[
j
]]
=
LTE_NULL
;
j
=
(
j
+
3
)
&
3
;
}
// printf("after RI2 c[%d] = %p\n",0,ulsch_harq->c[0]);
// CQI and Data bits
j
=
0
;
j2
=
0
;
// r=0;
if
(
Q_RI
>
0
)
{
for
(
i
=
0
;
i
<
(
Q_CQI
/
Q_m
);
i
++
)
{
while
(
ytag
[
j
]
==
LTE_NULL
)
{
j
++
;
j2
+=
Q_m
;
}
for
(
q
=
0
;
q
<
Q_m
;
q
++
)
{
// ys = y[q+(Q_m*((r*Cmux)+j))];
ys
=
y
[
q
+
j2
];
if
(
ys
>
127
)
ulsch_harq
->
q
[
q
+
(
Q_m
*
i
)]
=
127
;
else
if
(
ys
<-
128
)
ulsch_harq
->
q
[
q
+
(
Q_m
*
i
)]
=
-
128
;
else
ulsch_harq
->
q
[
q
+
(
Q_m
*
i
)]
=
ys
;
}
j2
+=
Q_m
;
}
switch
(
Q_m
)
{
case
2
:
for
(
iprime
=
0
;
iprime
<
G
;)
{
while
(
ytag
[
j
]
==
LTE_NULL
)
{
j
++
;
j2
+=
2
;
}
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
}
break
;
case
4
:
for
(
iprime
=
0
;
iprime
<
G
;)
{
while
(
ytag
[
j
]
==
LTE_NULL
)
{
j
++
;
j2
+=
4
;
}
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
}
break
;
case
6
:
for
(
iprime
=
0
;
iprime
<
G
;)
{
while
(
ytag
[
j
]
==
LTE_NULL
)
{
j
++
;
j2
+=
6
;
}
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
}
break
;
for
(
i
=
0
;
i
<
len_RI
;
i
++
)
ulsch_harq
->
q_RI
[
i
]
=
0
;
if
(
frame_parms
->
Ncp
==
0
)
columnset
=
cs_ri_normal
;
else
columnset
=
cs_ri_extended
;
j
=
0
;
for
(
i
=
0
;
i
<
Qprime_RI
;
i
++
)
{
r
=
Rmux_prime
-
1
-
(
i
>>
2
);
for
(
q
=
0
;
q
<
Q_m
;
q
++
)
ulsch_harq
->
q_RI
[(
q
+
(
Q_m
*
i
))
%
len_RI
]
+=
y
[
q
+
(
Q_m
*
((
r
*
Cmux
)
+
columnset
[
j
]))];
ytag
[(
r
*
Cmux
)
+
columnset
[
j
]]
=
LTE_NULL
;
j
=
(
j
+
3
)
&
3
;
}
}
// Q_RI>0
else
{
for
(
i
=
0
;
i
<
(
Q_CQI
/
Q_m
);
i
++
)
{
for
(
q
=
0
;
q
<
Q_m
;
q
++
)
{
ys
=
y
[
q
+
j2
];
if
(
ys
>
127
)
ulsch_harq
->
q
[
q
+
(
Q_m
*
i
)]
=
127
;
else
if
(
ys
<-
128
)
ulsch_harq
->
q
[
q
+
(
Q_m
*
i
)]
=
-
128
;
else
ulsch_harq
->
q
[
q
+
(
Q_m
*
i
)]
=
ys
;
}
j2
+=
Q_m
;
}
/* To be improved according to alignment of j2
#if defined(__x86_64__)||defined(__i386__)
#ifndef __AVX2__
for (iprime=0; iprime<G;iprime+=8,j2+=8)
*((__m128i *)&ulsch_harq->e[iprime]) = *((__m128i *)&y[j2]);
#else
for (iprime=0; iprime<G;iprime+=16,j2+=16)
*((__m256i *)&ulsch_harq->e[iprime]) = *((__m256i *)&y[j2]);
#endif
#elif defined(__arm__)
for (iprime=0; iprime<G;iprime+=8,j2+=8)
*((int16x8_t *)&ulsch_harq->e[iprime]) = *((int16x8_t *)&y[j2]);
#endif
*/
int16_t
*
yp
,
*
ep
;
for
(
iprime
=
0
,
yp
=&
y
[
j2
],
ep
=&
ulsch_harq
->
e
[
0
];
iprime
<
G
;
iprime
+=
8
,
j2
+=
8
,
ep
+=
8
,
yp
+=
8
)
{
ep
[
0
]
=
yp
[
0
];
ep
[
1
]
=
yp
[
1
];
ep
[
2
]
=
yp
[
2
];
ep
[
3
]
=
yp
[
3
];
ep
[
4
]
=
yp
[
4
];
ep
[
5
]
=
yp
[
5
];
ep
[
6
]
=
yp
[
6
];
ep
[
7
]
=
yp
[
7
];
}
}
stop_meas
(
&
eNB
->
ulsch_demultiplexing_stats
);
// printf("after ACKNAK2 c[%d] = %p (iprime %d, G %d)\n",0,ulsch_harq->c[0],iprime,G
);
// printf("after RI2 c[%d] = %p\n",0,ulsch_harq->c[0]
);
// Do CQI/RI/HARQ-ACK Decoding first and pass to MAC
// CQI and Data bits
j
=
0
;
j2
=
0
;
// HARQ-ACK
wACK_idx
=
(
ulsch
->
bundling
==
0
)
?
4
:
((
Nbundled
-
1
)
&
3
);
// r=0;
if
(
Q_RI
>
0
)
{
for
(
i
=
0
;
i
<
(
Q_CQI
/
Q_m
);
i
++
)
{
if
(
ulsch_harq
->
O_ACK
==
1
)
{
ulsch_harq
->
q_ACK
[
0
]
*=
wACK_RX
[
wACK_idx
][
0
];
ulsch_harq
->
q_ACK
[
0
]
+=
(
ulsch
->
bundling
==
0
)
?
ulsch_harq
->
q_ACK
[
1
]
*
wACK_RX
[
wACK_idx
][
0
]
:
ulsch_harq
->
q_ACK
[
1
]
*
wACK_RX
[
wACK_idx
][
1
];
while
(
ytag
[
j
]
==
LTE_NULL
)
{
j
++
;
j2
+=
Q_m
;
}
if
(
ulsch_harq
->
q_ACK
[
0
]
<
0
)
ulsch_harq
->
o_ACK
[
0
]
=
0
;
else
ulsch_harq
->
o_ACK
[
0
]
=
1
;
}
for
(
q
=
0
;
q
<
Q_m
;
q
++
)
{
// ys = y[q+(Q_m*((r*Cmux)+j))];
ys
=
y
[
q
+
j2
];
if
(
ulsch_harq
->
O_ACK
==
2
)
{
switch
(
Q_m
)
{
if
(
ys
>
127
)
ulsch_harq
->
q
[
q
+
(
Q_m
*
i
)]
=
127
;
else
if
(
ys
<-
128
)
ulsch_harq
->
q
[
q
+
(
Q_m
*
i
)]
=
-
128
;
else
ulsch_harq
->
q
[
q
+
(
Q_m
*
i
)]
=
ys
;
}
case
2
:
ulsch_harq
->
q_ACK
[
0
]
=
ulsch_harq
->
q_ACK
[
0
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
3
]
*
wACK_RX
[
wACK_idx
][
1
];
ulsch_harq
->
q_ACK
[
1
]
=
ulsch_harq
->
q_ACK
[
1
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
4
]
*
wACK_RX
[
wACK_idx
][
1
];
ulsch_harq
->
q_ACK
[
2
]
=
ulsch_harq
->
q_ACK
[
2
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
5
]
*
wACK_RX
[
wACK_idx
][
1
];
break
;
case
4
:
ulsch_harq
->
q_ACK
[
0
]
=
ulsch_harq
->
q_ACK
[
0
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
5
]
*
wACK_RX
[
wACK_idx
][
1
];
ulsch_harq
->
q_ACK
[
1
]
=
ulsch_harq
->
q_ACK
[
1
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
8
]
*
wACK_RX
[
wACK_idx
][
1
];
ulsch_harq
->
q_ACK
[
2
]
=
ulsch_harq
->
q_ACK
[
4
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
9
]
*
wACK_RX
[
wACK_idx
][
1
];
break
;
case
6
:
ulsch_harq
->
q_ACK
[
0
]
=
ulsch_harq
->
q_ACK
[
0
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
7
]
*
wACK_RX
[
wACK_idx
][
1
];
ulsch_harq
->
q_ACK
[
1
]
=
ulsch_harq
->
q_ACK
[
1
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
12
]
*
wACK_RX
[
wACK_idx
][
1
];
ulsch_harq
->
q_ACK
[
2
]
=
ulsch_harq
->
q_ACK
[
6
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
13
]
*
wACK_RX
[
wACK_idx
][
1
];
break
;
}
j2
+=
Q_m
;
}
ulsch_harq
->
o_ACK
[
0
]
=
1
;
ulsch_harq
->
o_ACK
[
1
]
=
1
;
metric
=
ulsch_harq
->
q_ACK
[
0
]
+
ulsch_harq
->
q_ACK
[
1
]
-
ulsch_harq
->
q_ACK
[
2
];
metric_new
=
-
ulsch_harq
->
q_ACK
[
0
]
+
ulsch_harq
->
q_ACK
[
1
]
+
ulsch_harq
->
q_ACK
[
2
];
if
(
metric_new
>
metric
)
{
ulsch_harq
->
o_ACK
[
0
]
=
0
;
ulsch_harq
->
o_ACK
[
1
]
=
1
;
metric
=
metric_new
;
switch
(
Q_m
)
{
case
2
:
for
(
iprime
=
0
;
iprime
<
G
;)
{
while
(
ytag
[
j
]
==
LTE_NULL
)
{
j
++
;
j2
+=
2
;
}
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
}
break
;
case
4
:
for
(
iprime
=
0
;
iprime
<
G
;)
{
while
(
ytag
[
j
]
==
LTE_NULL
)
{
j
++
;
j2
+=
4
;
}
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
}
break
;
case
6
:
for
(
iprime
=
0
;
iprime
<
G
;)
{
while
(
ytag
[
j
]
==
LTE_NULL
)
{
j
++
;
j2
+=
6
;
}
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
}
break
;
}
}
// Q_RI>0
else
{
for
(
i
=
0
;
i
<
(
Q_CQI
/
Q_m
);
i
++
)
{
for
(
q
=
0
;
q
<
Q_m
;
q
++
)
{
ys
=
y
[
q
+
j2
];
if
(
ys
>
127
)
ulsch_harq
->
q
[
q
+
(
Q_m
*
i
)]
=
127
;
else
if
(
ys
<-
128
)
ulsch_harq
->
q
[
q
+
(
Q_m
*
i
)]
=
-
128
;
else
ulsch_harq
->
q
[
q
+
(
Q_m
*
i
)]
=
ys
;
}
j2
+=
Q_m
;
}
/* To be improved according to alignment of j2
#if defined(__x86_64__)||defined(__i386__)
#ifndef __AVX2__
for (iprime=0; iprime<G;iprime+=8,j2+=8)
*((__m128i *)&ulsch_harq->e[iprime]) = *((__m128i *)&y[j2]);
#else
for (iprime=0; iprime<G;iprime+=16,j2+=16)
*((__m256i *)&ulsch_harq->e[iprime]) = *((__m256i *)&y[j2]);
#endif
#elif defined(__arm__)
for (iprime=0; iprime<G;iprime+=8,j2+=8)
*((int16x8_t *)&ulsch_harq->e[iprime]) = *((int16x8_t *)&y[j2]);
#endif
*/
int16_t
*
yp
,
*
ep
;
for
(
iprime
=
0
,
yp
=&
y
[
j2
],
ep
=&
ulsch_harq
->
e
[
0
];
iprime
<
G
;
iprime
+=
8
,
j2
+=
8
,
ep
+=
8
,
yp
+=
8
)
{
ep
[
0
]
=
yp
[
0
];
ep
[
1
]
=
yp
[
1
];
ep
[
2
]
=
yp
[
2
];
ep
[
3
]
=
yp
[
3
];
ep
[
4
]
=
yp
[
4
];
ep
[
5
]
=
yp
[
5
];
ep
[
6
]
=
yp
[
6
];
ep
[
7
]
=
yp
[
7
];
}
}
metric_new
=
ulsch_harq
->
q_ACK
[
0
]
-
ulsch_harq
->
q_ACK
[
1
]
+
ulsch_harq
->
q_ACK
[
2
];
stop_meas
(
&
eNB
->
ulsch_demultiplexing_stats
);
// printf("after ACKNAK2 c[%d] = %p (iprime %d, G %d)\n",0,ulsch_harq->c[0],iprime,G);
// Do CQI/RI/HARQ-ACK Decoding first and pass to MAC
// HARQ-ACK
wACK_idx
=
(
ulsch
->
bundling
==
0
)
?
4
:
((
Nbundled
-
1
)
&
3
);
if
(
metric_new
>
metric
)
{
ulsch_harq
->
o_ACK
[
0
]
=
1
;
ulsch_harq
->
o_ACK
[
1
]
=
0
;
metric
=
metric_new
;
if
(
ulsch_harq
->
O_ACK
==
1
)
{
ulsch_harq
->
q_ACK
[
0
]
*=
wACK_RX
[
wACK_idx
][
0
];
ulsch_harq
->
q_ACK
[
0
]
+=
(
ulsch
->
bundling
==
0
)
?
ulsch_harq
->
q_ACK
[
1
]
*
wACK_RX
[
wACK_idx
][
0
]
:
ulsch_harq
->
q_ACK
[
1
]
*
wACK_RX
[
wACK_idx
][
1
];
if
(
ulsch_harq
->
q_ACK
[
0
]
<
0
)
ulsch_harq
->
o_ACK
[
0
]
=
0
;
else
ulsch_harq
->
o_ACK
[
0
]
=
1
;
}
metric_new
=
-
ulsch_harq
->
q_ACK
[
0
]
-
ulsch_harq
->
q_ACK
[
1
]
-
ulsch_harq
->
q_ACK
[
2
];
if
(
ulsch_harq
->
O_ACK
==
2
)
{
switch
(
Q_m
)
{
case
2
:
ulsch_harq
->
q_ACK
[
0
]
=
ulsch_harq
->
q_ACK
[
0
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
3
]
*
wACK_RX
[
wACK_idx
][
1
];
ulsch_harq
->
q_ACK
[
1
]
=
ulsch_harq
->
q_ACK
[
1
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
4
]
*
wACK_RX
[
wACK_idx
][
1
];
ulsch_harq
->
q_ACK
[
2
]
=
ulsch_harq
->
q_ACK
[
2
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
5
]
*
wACK_RX
[
wACK_idx
][
1
];
break
;
case
4
:
ulsch_harq
->
q_ACK
[
0
]
=
ulsch_harq
->
q_ACK
[
0
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
5
]
*
wACK_RX
[
wACK_idx
][
1
];
ulsch_harq
->
q_ACK
[
1
]
=
ulsch_harq
->
q_ACK
[
1
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
8
]
*
wACK_RX
[
wACK_idx
][
1
];
ulsch_harq
->
q_ACK
[
2
]
=
ulsch_harq
->
q_ACK
[
4
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
9
]
*
wACK_RX
[
wACK_idx
][
1
];
break
;
case
6
:
ulsch_harq
->
q_ACK
[
0
]
=
ulsch_harq
->
q_ACK
[
0
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
7
]
*
wACK_RX
[
wACK_idx
][
1
];
ulsch_harq
->
q_ACK
[
1
]
=
ulsch_harq
->
q_ACK
[
1
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
12
]
*
wACK_RX
[
wACK_idx
][
1
];
ulsch_harq
->
q_ACK
[
2
]
=
ulsch_harq
->
q_ACK
[
6
]
*
wACK_RX
[
wACK_idx
][
0
]
+
ulsch_harq
->
q_ACK
[
13
]
*
wACK_RX
[
wACK_idx
][
1
];
break
;
}
ulsch_harq
->
o_ACK
[
0
]
=
1
;
ulsch_harq
->
o_ACK
[
1
]
=
1
;
metric
=
ulsch_harq
->
q_ACK
[
0
]
+
ulsch_harq
->
q_ACK
[
1
]
-
ulsch_harq
->
q_ACK
[
2
];
metric_new
=
-
ulsch_harq
->
q_ACK
[
0
]
+
ulsch_harq
->
q_ACK
[
1
]
+
ulsch_harq
->
q_ACK
[
2
];
if
(
metric_new
>
metric
)
{
ulsch_harq
->
o_ACK
[
0
]
=
0
;
ulsch_harq
->
o_ACK
[
1
]
=
1
;
metric
=
metric_new
;
}
metric_new
=
ulsch_harq
->
q_ACK
[
0
]
-
ulsch_harq
->
q_ACK
[
1
]
+
ulsch_harq
->
q_ACK
[
2
];
if
(
metric_new
>
metric
)
{
ulsch_harq
->
o_ACK
[
0
]
=
0
;
ulsch_harq
->
o_ACK
[
1
]
=
0
;
metric
=
metric_new
;
if
(
metric_new
>
metric
)
{
ulsch_harq
->
o_ACK
[
0
]
=
1
;
ulsch_harq
->
o_ACK
[
1
]
=
0
;
metric
=
metric_new
;
}
metric_new
=
-
ulsch_harq
->
q_ACK
[
0
]
-
ulsch_harq
->
q_ACK
[
1
]
-
ulsch_harq
->
q_ACK
[
2
];
if
(
metric_new
>
metric
)
{
ulsch_harq
->
o_ACK
[
0
]
=
0
;
ulsch_harq
->
o_ACK
[
1
]
=
0
;
metric
=
metric_new
;
}
}
}
// RI
// RI
// rank 1
if
((
ulsch_harq
->
O_RI
==
1
)
&&
(
Qprime_RI
>
0
))
{
ulsch_harq
->
o_RI
[
0
]
=
((
ulsch_harq
->
q_RI
[
0
]
+
ulsch_harq
->
q_RI
[
Q_m
/
2
])
>
0
)
?
0
:
1
;
}
// rank 1
if
((
ulsch_harq
->
O_RI
==
1
)
&&
(
Qprime_RI
>
0
))
{
ulsch_harq
->
o_RI
[
0
]
=
((
ulsch_harq
->
q_RI
[
0
]
+
ulsch_harq
->
q_RI
[
Q_m
/
2
])
>
0
)
?
0
:
1
;
}
// CQI
// CQI
// printf("before cqi c[%d] = %p\n",0,ulsch_harq->c[0]);
ulsch_harq
->
cqi_crc_status
=
0
;
if
(
Q_CQI
>
0
)
{
memset
((
void
*
)
&
dummy_w_cc
[
0
],
0
,
3
*
(
ulsch_harq
->
Or1
+
8
+
32
));
// printf("before cqi c[%d] = %p\n",0,ulsch_harq->c[0]);
ulsch_harq
->
cqi_crc_status
=
0
;
if
(
Q_CQI
>
0
)
{
memset
((
void
*
)
&
dummy_w_cc
[
0
],
0
,
3
*
(
ulsch_harq
->
Or1
+
8
+
32
));
O_RCC
=
generate_dummy_w_cc
(
ulsch_harq
->
Or1
+
8
,
&
dummy_w_cc
[
0
]);
O_RCC
=
generate_dummy_w_cc
(
ulsch_harq
->
Or1
+
8
,
&
dummy_w_cc
[
0
]);
lte_rate_matching_cc_rx
(
O_RCC
,
Q_CQI
,
ulsch_harq
->
o_w
,
dummy_w_cc
,
ulsch_harq
->
q
);
lte_rate_matching_cc_rx
(
O_RCC
,
Q_CQI
,
ulsch_harq
->
o_w
,
dummy_w_cc
,
ulsch_harq
->
q
);
sub_block_deinterleaving_cc
((
unsigned
int
)(
ulsch_harq
->
Or1
+
8
),
&
ulsch_harq
->
o_d
[
96
],
&
ulsch_harq
->
o_w
[
0
]);
sub_block_deinterleaving_cc
((
unsigned
int
)(
ulsch_harq
->
Or1
+
8
),
&
ulsch_harq
->
o_d
[
96
],
&
ulsch_harq
->
o_w
[
0
]);
memset
(
ulsch_harq
->
o
,
0
,(
7
+
8
+
ulsch_harq
->
Or1
)
/
8
);
phy_viterbi_lte_sse2
(
ulsch_harq
->
o_d
+
96
,
ulsch_harq
->
o
,
8
+
ulsch_harq
->
Or1
);
memset
(
ulsch_harq
->
o
,
0
,(
7
+
8
+
ulsch_harq
->
Or1
)
/
8
);
phy_viterbi_lte_sse2
(
ulsch_harq
->
o_d
+
96
,
ulsch_harq
->
o
,
8
+
ulsch_harq
->
Or1
);
if
(
extract_cqi_crc
(
ulsch_harq
->
o
,
ulsch_harq
->
Or1
)
==
(
crc8
(
ulsch_harq
->
o
,
ulsch_harq
->
Or1
)
>>
24
))
ulsch_harq
->
cqi_crc_status
=
1
;
if
(
extract_cqi_crc
(
ulsch_harq
->
o
,
ulsch_harq
->
Or1
)
==
(
crc8
(
ulsch_harq
->
o
,
ulsch_harq
->
Or1
)
>>
24
))
ulsch_harq
->
cqi_crc_status
=
1
;
#ifdef DEBUG_ULSCH_DECODING
printf
(
"ulsch_decoding: Or1=%d
\n
"
,
ulsch_harq
->
Or1
);
printf
(
"ulsch_decoding: Or1=%d
\n
"
,
ulsch_harq
->
Or1
);
for
(
i
=
0
;
i
<
1
+
((
8
+
ulsch_harq
->
Or1
)
/
8
);
i
++
)
printf
(
"ulsch_decoding: O[%d] %d
\n
"
,
i
,
ulsch_harq
->
o
[
i
]);
for
(
i
=
0
;
i
<
1
+
((
8
+
ulsch_harq
->
Or1
)
/
8
);
i
++
)
printf
(
"ulsch_decoding: O[%d] %d
\n
"
,
i
,
ulsch_harq
->
o
[
i
]);
if
(
ulsch_harq
->
cqi_crc_status
==
1
)
printf
(
"RX CQI CRC OK (%x)
\n
"
,
extract_cqi_crc
(
ulsch_harq
->
o
,
ulsch_harq
->
Or1
));
else
printf
(
"RX CQI CRC NOT OK (%x)
\n
"
,
extract_cqi_crc
(
ulsch_harq
->
o
,
ulsch_harq
->
Or1
));
if
(
ulsch_harq
->
cqi_crc_status
==
1
)
printf
(
"RX CQI CRC OK (%x)
\n
"
,
extract_cqi_crc
(
ulsch_harq
->
o
,
ulsch_harq
->
Or1
));
else
printf
(
"RX CQI CRC NOT OK (%x)
\n
"
,
extract_cqi_crc
(
ulsch_harq
->
o
,
ulsch_harq
->
Or1
));
#endif
}
}
LOG_D
(
PHY
,
"frame %d subframe %d O_ACK:%d o_ACK[]=%d:%d:%d:%d
\n
"
,
frame
,
subframe
,
ulsch_harq
->
O_ACK
,
ulsch_harq
->
o_ACK
[
0
],
ulsch_harq
->
o_ACK
[
1
],
ulsch_harq
->
o_ACK
[
2
],
ulsch_harq
->
o_ACK
[
3
]);
LOG_D
(
PHY
,
"frame %d subframe %d O_ACK:%d o_ACK[]=%d:%d:%d:%d
\n
"
,
frame
,
subframe
,
ulsch_harq
->
O_ACK
,
ulsch_harq
->
o_ACK
[
0
],
ulsch_harq
->
o_ACK
[
1
],
ulsch_harq
->
o_ACK
[
2
],
ulsch_harq
->
o_ACK
[
3
]);
// Do ULSCH Decoding for data portion
// Do ULSCH Decoding for data portion
request_t
*
ret
=
eNB
->
td
(
eNB
,
UE_id
,
harq_pid
,
llr8_flag
,
frame
,
subframe
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0
+
harq_pid
,
0
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0
+
harq_pid
,
0
);
return
(
ret
);
return
(
ret
);
}
#ifdef PHY_ABSTRACTION
...
...
@@ -1504,43 +1506,43 @@ request_t* ulsch_decoding(PHY_VARS_eNB *eNB,
int
ulsch_abstraction
(
double
*
sinr_dB
,
uint8_t
TM
,
uint8_t
mcs
,
uint16_t
nrb
,
uint16_t
frb
)
{
int
index
,
ii
;
double
sinr_eff
=
0
;
int
rb_count
=
0
;
int
offset
;
double
bler
=
0
;
TM
=
TM
-
1
;
sinr_eff
=
sinr_dB
[
frb
];
//the single sinr_eff value we calculated with MMSE FDE formula in init_snr_up function
int
index
,
ii
;
double
sinr_eff
=
0
;
int
rb_count
=
0
;
int
offset
;
double
bler
=
0
;
TM
=
TM
-
1
;
sinr_eff
=
sinr_dB
[
frb
];
//the single sinr_eff value we calculated with MMSE FDE formula in init_snr_up function
sinr_eff
*=
10
;
sinr_eff
=
floor
(
sinr_eff
);
sinr_eff
/=
10
;
sinr_eff
*=
10
;
sinr_eff
=
floor
(
sinr_eff
);
sinr_eff
/=
10
;
LOG_D
(
PHY
,
"[ABSTRACTION] sinr_eff after rounding = %f
\n
"
,
sinr_eff
);
LOG_D
(
PHY
,
"[ABSTRACTION] sinr_eff after rounding = %f
\n
"
,
sinr_eff
);
for
(
index
=
0
;
index
<
16
;
index
++
)
{
if
(
index
==
0
)
{
if
(
sinr_eff
<
sinr_bler_map_up
[
mcs
][
0
][
index
])
{
bler
=
1
;
break
;
}
}
for
(
index
=
0
;
index
<
16
;
index
++
)
{
if
(
index
==
0
)
{
if
(
sinr_eff
<
sinr_bler_map_up
[
mcs
][
0
][
index
])
{
bler
=
1
;
break
;
}
}
if
(
sinr_eff
==
sinr_bler_map_up
[
mcs
][
0
][
index
])
{
bler
=
sinr_bler_map_up
[
mcs
][
1
][
index
];
if
(
sinr_eff
==
sinr_bler_map_up
[
mcs
][
0
][
index
])
{
bler
=
sinr_bler_map_up
[
mcs
][
1
][
index
];
}
}
}
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
if
(
uniformrandom
()
<
bler
)
{
LOG_I
(
OCM
,
"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)
\n
"
,
mcs
,
sinr_eff
,
bler
);
return
(
0
);
}
else
{
LOG_I
(
OCM
,
"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)
\n
"
,
mcs
,
sinr_eff
,
bler
);
return
(
1
);
}
if
(
uniformrandom
()
<
bler
)
{
LOG_I
(
OCM
,
"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)
\n
"
,
mcs
,
sinr_eff
,
bler
);
return
(
0
);
}
else
{
LOG_I
(
OCM
,
"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)
\n
"
,
mcs
,
sinr_eff
,
bler
);
return
(
1
);
}
#endif
}
...
...
@@ -1553,313 +1555,313 @@ int ulsch_abstraction(double* sinr_dB, uint8_t TM, uint8_t mcs,uint16_t nrb, uin
int
ulsch_abstraction_MIESM
(
double
*
sinr_dB
,
uint8_t
TM
,
uint8_t
mcs
,
uint16_t
nrb
,
uint16_t
frb
)
{
int
index
;
double
sinr_eff
=
0
;
double
sinr_db1
=
0
;
double
sinr_db2
=
0
;
double
SI
=
0
;
double
RBIR
=
0
;
int
rb_count
=
0
;
int
offset
,
M
=
0
;
double
bler
=
0
;
int
start
,
middle
,
end
;
TM
=
TM
-
1
;
int
index
;
double
sinr_eff
=
0
;
double
sinr_db1
=
0
;
double
sinr_db2
=
0
;
double
SI
=
0
;
double
RBIR
=
0
;
int
rb_count
=
0
;
int
offset
,
M
=
0
;
double
bler
=
0
;
int
start
,
middle
,
end
;
TM
=
TM
-
1
;
for
(
offset
=
frb
;
offset
<=
(
frb
+
nrb
-
1
);
offset
++
)
{
for
(
offset
=
frb
;
offset
<=
(
frb
+
nrb
-
1
);
offset
++
)
{
rb_count
++
;
rb_count
++
;
//we need to do the table lookups here for the mutual information corresponding to the certain sinr_dB.
//we need to do the table lookups here for the mutual information corresponding to the certain sinr_dB.
sinr_db1
=
sinr_dB
[
offset
*
2
];
sinr_db2
=
sinr_dB
[
offset
*
2
+
1
];
sinr_db1
=
sinr_dB
[
offset
*
2
];
sinr_db2
=
sinr_dB
[
offset
*
2
+
1
];
printf
(
"sinr_db1=%f
\n
,sinr_db2=%f
\n
"
,
sinr_db1
,
sinr_db2
);
printf
(
"sinr_db1=%f
\n
,sinr_db2=%f
\n
"
,
sinr_db1
,
sinr_db2
);
//rounding up for the table lookup
sinr_db1
*=
10
;
sinr_db2
*=
10
;
//rounding up for the table lookup
sinr_db1
*=
10
;
sinr_db2
*=
10
;
sinr_db1
=
floor
(
sinr_db1
);
sinr_db2
=
floor
(
sinr_db2
);
sinr_db1
=
floor
(
sinr_db1
);
sinr_db2
=
floor
(
sinr_db2
);
if
((
int
)
sinr_db1
%
2
)
{
sinr_db1
+=
1
;
}
if
((
int
)
sinr_db1
%
2
)
{
sinr_db1
+=
1
;
}
if
((
int
)
sinr_db2
%
2
)
{
sinr_db2
+=
1
;
}
if
((
int
)
sinr_db2
%
2
)
{
sinr_db2
+=
1
;
}
sinr_db1
/=
10
;
sinr_db2
/=
10
;
sinr_db1
/=
10
;
sinr_db2
/=
10
;
if
(
mcs
<
10
)
{
//for sinr_db1
for
(
index
=
0
;
index
<
162
;
index
++
)
{
if
(
sinr_db1
<
MI_map_4qam
[
0
][
0
])
{
SI
+=
(
MI_map_4qam
[
1
][
0
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
2
;
break
;
}
if
(
mcs
<
10
)
{
//for sinr_db1
for
(
index
=
0
;
index
<
162
;
index
++
)
{
if
(
sinr_db1
<
MI_map_4qam
[
0
][
0
])
{
SI
+=
(
MI_map_4qam
[
1
][
0
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
2
;
break
;
}
if
(
sinr_db1
>
MI_map_4qam
[
0
][
161
])
{
SI
+=
(
MI_map_4qam
[
1
][
161
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
2
;
break
;
}
if
(
sinr_db1
>
MI_map_4qam
[
0
][
161
])
{
SI
+=
(
MI_map_4qam
[
1
][
161
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
2
;
break
;
}
if
(
sinr_db1
==
MI_map_4qam
[
0
][
index
])
{
SI
+=
(
MI_map_4qam
[
1
][
index
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
2
;
break
;
}
}
//for sinr_db2
for
(
index
=
0
;
index
<
162
;
index
++
)
{
if
(
sinr_db2
<
MI_map_4qam
[
0
][
0
])
{
SI
+=
(
MI_map_4qam
[
1
][
0
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
2
;
break
;
}
if
(
sinr_db1
==
MI_map_4qam
[
0
][
index
])
{
SI
+=
(
MI_map_4qam
[
1
][
index
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
2
;
break
;
}
}
if
(
sinr_db2
>
MI_map_4qam
[
0
][
161
])
{
SI
+=
(
MI_map_4qam
[
1
][
161
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
2
;
break
;
}
//for sinr_db2
for
(
index
=
0
;
index
<
162
;
index
++
)
{
if
(
sinr_db2
<
MI_map_4qam
[
0
][
0
])
{
SI
+=
(
MI_map_4qam
[
1
][
0
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
2
;
break
;
}
if
(
sinr_db2
==
MI_map_4qam
[
0
][
index
])
{
SI
+=
(
MI_map_4qam
[
1
][
index
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
2
;
break
;
}
}
}
else
if
(
mcs
>
9
&&
mcs
<
17
)
{
//for sinr_db1
for
(
index
=
0
;
index
<
197
;
index
++
)
{
if
(
sinr_db1
<
MI_map_16qam
[
0
][
0
])
{
SI
+=
(
MI_map_16qam
[
1
][
0
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
4
;
break
;
}
if
(
sinr_db2
>
MI_map_4qam
[
0
][
161
])
{
SI
+=
(
MI_map_4qam
[
1
][
161
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
2
;
break
;
}
if
(
sinr_db1
>
MI_map_16qam
[
0
][
196
])
{
SI
+=
(
MI_map_16qam
[
1
][
196
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
4
;
break
;
}
if
(
sinr_db2
==
MI_map_4qam
[
0
][
index
])
{
SI
+=
(
MI_map_4qam
[
1
][
index
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
2
;
break
;
}
}
if
(
sinr_db1
==
MI_map_16qam
[
0
][
index
])
{
SI
+=
(
MI_map_16qam
[
1
][
index
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
4
;
break
;
}
}
//for sinr_db2
for
(
index
=
0
;
index
<
197
;
index
++
)
{
if
(
sinr_db2
<
MI_map_16qam
[
0
][
0
])
{
SI
+=
(
MI_map_16qam
[
1
][
0
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
4
;
break
;
}
}
else
if
(
mcs
>
9
&&
mcs
<
17
)
{
//for sinr_db1
for
(
index
=
0
;
index
<
197
;
index
++
)
{
if
(
sinr_db1
<
MI_map_16qam
[
0
][
0
])
{
SI
+=
(
MI_map_16qam
[
1
][
0
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
4
;
break
;
}
if
(
sinr_db2
>
MI_map_16qam
[
0
][
196
])
{
SI
+=
(
MI_map_16qam
[
1
][
196
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
4
;
break
;
}
if
(
sinr_db1
>
MI_map_16qam
[
0
][
196
])
{
SI
+=
(
MI_map_16qam
[
1
][
196
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
4
;
break
;
}
if
(
sinr_db2
==
MI_map_16qam
[
0
][
index
])
{
SI
+=
(
MI_map_16qam
[
1
][
index
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
4
;
break
;
}
}
}
else
if
(
mcs
>
16
&&
mcs
<
22
)
{
//for sinr_db1
for
(
index
=
0
;
index
<
227
;
index
++
)
{
if
(
sinr_db1
<
MI_map_64qam
[
0
][
0
])
{
SI
+=
(
MI_map_64qam
[
1
][
0
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
6
;
break
;
}
if
(
sinr_db1
==
MI_map_16qam
[
0
][
index
])
{
SI
+=
(
MI_map_16qam
[
1
][
index
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
4
;
break
;
}
}
if
(
sinr_db1
>
MI_map_64qam
[
0
][
226
])
{
SI
+=
(
MI_map_64qam
[
1
][
226
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
6
;
break
;
}
//for sinr_db2
for
(
index
=
0
;
index
<
197
;
index
++
)
{
if
(
sinr_db2
<
MI_map_16qam
[
0
][
0
])
{
SI
+=
(
MI_map_16qam
[
1
][
0
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
4
;
break
;
}
if
(
sinr_db1
==
MI_map_64qam
[
0
][
index
])
{
SI
+=
(
MI_map_64qam
[
1
][
index
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
6
;
break
;
}
}
//for sinr_db2
for
(
index
=
0
;
index
<
227
;
index
++
)
{
if
(
sinr_db2
<
MI_map_64qam
[
0
][
0
])
{
SI
+=
(
MI_map_64qam
[
1
][
0
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
6
;
break
;
}
if
(
sinr_db2
>
MI_map_16qam
[
0
][
196
])
{
SI
+=
(
MI_map_16qam
[
1
][
196
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
4
;
break
;
}
if
(
sinr_db2
>
MI_map_64qam
[
0
][
226
])
{
SI
+=
(
MI_map_64qam
[
1
][
226
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
6
;
break
;
}
if
(
sinr_db2
==
MI_map_16qam
[
0
][
index
])
{
SI
+=
(
MI_map_16qam
[
1
][
index
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
4
;
break
;
}
}
if
(
sinr_db2
==
MI_map_64qam
[
0
][
index
])
{
SI
+=
(
MI_map_64qam
[
1
][
index
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
6
;
break
;
}
else
if
(
mcs
>
16
&&
mcs
<
22
)
{
//for sinr_db1
for
(
index
=
0
;
index
<
227
;
index
++
)
{
if
(
sinr_db1
<
MI_map_64qam
[
0
][
0
])
{
SI
+=
(
MI_map_64qam
[
1
][
0
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
6
;
break
;
}
if
(
sinr_db1
>
MI_map_64qam
[
0
][
226
])
{
SI
+=
(
MI_map_64qam
[
1
][
226
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
6
;
break
;
}
if
(
sinr_db1
==
MI_map_64qam
[
0
][
index
])
{
SI
+=
(
MI_map_64qam
[
1
][
index
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
6
;
break
;
}
}
//for sinr_db2
for
(
index
=
0
;
index
<
227
;
index
++
)
{
if
(
sinr_db2
<
MI_map_64qam
[
0
][
0
])
{
SI
+=
(
MI_map_64qam
[
1
][
0
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
6
;
break
;
}
if
(
sinr_db2
>
MI_map_64qam
[
0
][
226
])
{
SI
+=
(
MI_map_64qam
[
1
][
226
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
6
;
break
;
}
if
(
sinr_db2
==
MI_map_64qam
[
0
][
index
])
{
SI
+=
(
MI_map_64qam
[
1
][
index
]
/
beta1_dlsch_MI
[
TM
][
mcs
]);
M
+=
6
;
break
;
}
}
}
}
}
}
// }
// }
RBIR
=
SI
/
M
;
RBIR
=
SI
/
M
;
//Now RBIR->SINR_effective Mapping
//binary search method is performed here
if
(
mcs
<
10
)
{
start
=
0
;
end
=
161
;
middle
=
end
/
2
;
//Now RBIR->SINR_effective Mapping
//binary search method is performed here
if
(
mcs
<
10
)
{
start
=
0
;
end
=
161
;
middle
=
end
/
2
;
if
(
RBIR
<=
MI_map_4qam
[
2
][
start
])
{
sinr_eff
=
MI_map_4qam
[
0
][
start
];
}
else
{
if
(
RBIR
>=
MI_map_4qam
[
2
][
end
])
sinr_eff
=
MI_map_4qam
[
0
][
end
];
else
{
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if
(
RBIR
<
MI_map_4qam
[
2
][
middle
])
{
end
=
middle
;
middle
=
end
/
2
;
if
(
RBIR
<=
MI_map_4qam
[
2
][
start
])
{
sinr_eff
=
MI_map_4qam
[
0
][
start
];
}
else
{
start
=
middle
;
middle
=
(
end
-
middle
)
/
2
;
}
}
if
(
RBIR
>=
MI_map_4qam
[
2
][
end
])
sinr_eff
=
MI_map_4qam
[
0
][
end
];
else
{
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if
(
RBIR
<
MI_map_4qam
[
2
][
middle
])
{
end
=
middle
;
middle
=
end
/
2
;
}
else
{
start
=
middle
;
middle
=
(
end
-
middle
)
/
2
;
}
}
for
(;
end
>
start
;
end
--
)
{
if
((
RBIR
<
MI_map_4qam
[
2
][
end
])
&&
(
RBIR
>
MI_map_4qam
[
2
][
end
-
2
]))
{
sinr_eff
=
MI_map_4qam
[
0
][
end
-
1
];
break
;
for
(;
end
>
start
;
end
--
)
{
if
((
RBIR
<
MI_map_4qam
[
2
][
end
])
&&
(
RBIR
>
MI_map_4qam
[
2
][
end
-
2
]))
{
sinr_eff
=
MI_map_4qam
[
0
][
end
-
1
];
break
;
}
}
}
}
}
sinr_eff
=
sinr_eff
*
beta2_dlsch_MI
[
TM
][
mcs
];
}
sinr_eff
=
sinr_eff
*
beta2_dlsch_MI
[
TM
][
mcs
];
}
else
if
(
mcs
>
9
&&
mcs
<
17
)
{
else
if
(
mcs
>
9
&&
mcs
<
17
)
{
start
=
0
;
end
=
196
;
middle
=
end
/
2
;
start
=
0
;
end
=
196
;
middle
=
end
/
2
;
if
(
RBIR
<=
MI_map_16qam
[
2
][
start
])
{
sinr_eff
=
MI_map_16qam
[
0
][
start
];
}
else
{
if
(
RBIR
>=
MI_map_16qam
[
2
][
end
])
sinr_eff
=
MI_map_16qam
[
0
][
end
];
else
{
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if
(
RBIR
<
MI_map_16qam
[
2
][
middle
])
{
end
=
middle
;
middle
=
end
/
2
;
if
(
RBIR
<=
MI_map_16qam
[
2
][
start
])
{
sinr_eff
=
MI_map_16qam
[
0
][
start
];
}
else
{
start
=
middle
;
middle
=
(
end
-
middle
)
/
2
;
}
}
if
(
RBIR
>=
MI_map_16qam
[
2
][
end
])
sinr_eff
=
MI_map_16qam
[
0
][
end
];
else
{
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if
(
RBIR
<
MI_map_16qam
[
2
][
middle
])
{
end
=
middle
;
middle
=
end
/
2
;
}
else
{
start
=
middle
;
middle
=
(
end
-
middle
)
/
2
;
}
}
for
(;
end
>
start
;
end
--
)
{
if
((
RBIR
<
MI_map_16qam
[
2
][
end
])
&&
(
RBIR
>
MI_map_16qam
[
2
][
end
-
2
]))
{
sinr_eff
=
MI_map_16qam
[
0
][
end
-
1
];
break
;
for
(;
end
>
start
;
end
--
)
{
if
((
RBIR
<
MI_map_16qam
[
2
][
end
])
&&
(
RBIR
>
MI_map_16qam
[
2
][
end
-
2
]))
{
sinr_eff
=
MI_map_16qam
[
0
][
end
-
1
];
break
;
}
}
}
}
}
sinr_eff
=
sinr_eff
*
beta2_dlsch_MI
[
TM
][
mcs
];
}
else
if
(
mcs
>
16
)
{
start
=
0
;
end
=
226
;
middle
=
end
/
2
;
sinr_eff
=
sinr_eff
*
beta2_dlsch_MI
[
TM
][
mcs
];
}
else
if
(
mcs
>
16
)
{
start
=
0
;
end
=
226
;
middle
=
end
/
2
;
if
(
RBIR
<=
MI_map_64qam
[
2
][
start
])
{
sinr_eff
=
MI_map_64qam
[
0
][
start
];
}
else
{
if
(
RBIR
>=
MI_map_64qam
[
2
][
end
])
sinr_eff
=
MI_map_64qam
[
0
][
end
];
else
{
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if
(
RBIR
<
MI_map_64qam
[
2
][
middle
])
{
end
=
middle
;
middle
=
end
/
2
;
if
(
RBIR
<=
MI_map_64qam
[
2
][
start
])
{
sinr_eff
=
MI_map_64qam
[
0
][
start
];
}
else
{
start
=
middle
;
middle
=
(
end
-
middle
)
/
2
;
}
}
if
(
RBIR
>=
MI_map_64qam
[
2
][
end
])
sinr_eff
=
MI_map_64qam
[
0
][
end
];
else
{
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if
(
RBIR
<
MI_map_64qam
[
2
][
middle
])
{
end
=
middle
;
middle
=
end
/
2
;
}
else
{
start
=
middle
;
middle
=
(
end
-
middle
)
/
2
;
}
}
for
(;
end
>
start
;
end
--
)
{
if
((
RBIR
<
MI_map_64qam
[
2
][
end
])
&&
(
RBIR
>
MI_map_64qam
[
2
][
end
-
2
]))
{
sinr_eff
=
MI_map_64qam
[
0
][
end
-
1
];
break
;
for
(;
end
>
start
;
end
--
)
{
if
((
RBIR
<
MI_map_64qam
[
2
][
end
])
&&
(
RBIR
>
MI_map_64qam
[
2
][
end
-
2
]))
{
sinr_eff
=
MI_map_64qam
[
0
][
end
-
1
];
break
;
}
}
}
}
}
sinr_eff
=
sinr_eff
*
beta2_dlsch_MI
[
TM
][
mcs
];
}
sinr_eff
=
sinr_eff
*
beta2_dlsch_MI
[
TM
][
mcs
];
}
printf
(
"SINR_Eff = %e
\n
"
,
sinr_eff
);
printf
(
"SINR_Eff = %e
\n
"
,
sinr_eff
);
sinr_eff
*=
10
;
sinr_eff
=
floor
(
sinr_eff
);
// if ((int)sinr_eff%2) {
// sinr_eff += 1;
// }
sinr_eff
/=
10
;
printf
(
"sinr_eff after rounding = %f
\n
"
,
sinr_eff
);
sinr_eff
*=
10
;
sinr_eff
=
floor
(
sinr_eff
);
// if ((int)sinr_eff%2) {
// sinr_eff += 1;
// }
sinr_eff
/=
10
;
printf
(
"sinr_eff after rounding = %f
\n
"
,
sinr_eff
);
for
(
index
=
0
;
index
<
16
;
index
++
)
{
if
(
index
==
0
)
{
if
(
sinr_eff
<
sinr_bler_map_up
[
mcs
][
0
][
index
])
{
bler
=
1
;
break
;
}
}
for
(
index
=
0
;
index
<
16
;
index
++
)
{
if
(
index
==
0
)
{
if
(
sinr_eff
<
sinr_bler_map_up
[
mcs
][
0
][
index
])
{
bler
=
1
;
break
;
}
}
if
(
sinr_eff
==
sinr_bler_map_up
[
mcs
][
0
][
index
])
{
bler
=
sinr_bler_map_up
[
mcs
][
1
][
index
];
if
(
sinr_eff
==
sinr_bler_map_up
[
mcs
][
0
][
index
])
{
bler
=
sinr_bler_map_up
[
mcs
][
1
][
index
];
}
}
}
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
if
(
uniformrandom
()
<
bler
)
{
printf
(
"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)
\n
"
,
mcs
,
sinr_eff
,
bler
);
return
(
0
);
}
else
{
printf
(
"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)
\n
"
,
mcs
,
sinr_eff
,
bler
);
return
(
1
);
}
if
(
uniformrandom
()
<
bler
)
{
printf
(
"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)
\n
"
,
mcs
,
sinr_eff
,
bler
);
return
(
0
);
}
else
{
printf
(
"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)
\n
"
,
mcs
,
sinr_eff
,
bler
);
return
(
1
);
}
#endif
...
...
@@ -1872,85 +1874,85 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
uint16_t
*
crnti
)
{
uint8_t
UE_id
;
uint16_t
rnti
;
int
subframe
=
proc
->
subframe_rx
;
uint8_t
harq_pid
;
uint8_t
CC_id
=
eNB
->
CC_id
;
uint8_t
UE_id
;
uint16_t
rnti
;
int
subframe
=
proc
->
subframe_rx
;
uint8_t
harq_pid
;
uint8_t
CC_id
=
eNB
->
CC_id
;
harq_pid
=
subframe2harq_pid
(
&
eNB
->
frame_parms
,
proc
->
frame_rx
,
subframe
);
harq_pid
=
subframe2harq_pid
(
&
eNB
->
frame_parms
,
proc
->
frame_rx
,
subframe
);
rnti
=
eNB
->
ulsch
[
UE_index
]
->
rnti
;
rnti
=
eNB
->
ulsch
[
UE_index
]
->
rnti
;
#ifdef DEBUG_PHY
LOG_D
(
PHY
,
"[eNB %d] ulsch_decoding_emul : subframe %d UE_index %d harq_pid %d rnti %x
\n
"
,
eNB
->
Mod_id
,
subframe
,
UE_index
,
harq_pid
,
rnti
);
LOG_D
(
PHY
,
"[eNB %d] ulsch_decoding_emul : subframe %d UE_index %d harq_pid %d rnti %x
\n
"
,
eNB
->
Mod_id
,
subframe
,
UE_index
,
harq_pid
,
rnti
);
#endif
for
(
UE_id
=
0
;
UE_id
<
NB_UE_INST
;
UE_id
++
)
{
if
(
rnti
==
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
pdcch_vars
[
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
current_thread_id
[
subframe
]][
0
]
->
crnti
)
break
;
}
if
(
UE_id
==
NB_UE_INST
)
{
LOG_W
(
PHY
,
"[eNB %d] ulsch_decoding_emul: FATAL, didn't find UE with rnti %x (UE index %d)
\n
"
,
eNB
->
Mod_id
,
rnti
,
UE_index
);
return
(
1
+
eNB
->
ulsch
[
UE_id
]
->
max_turbo_iterations
);
}
else
{
LOG_D
(
PHY
,
"[eNB %d] Found UE with rnti %x => UE_id %d
\n
"
,
eNB
->
Mod_id
,
rnti
,
UE_id
);
}
if
(
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
harq_processes
[
harq_pid
]
->
status
==
CBA_ACTIVE
)
{
*
crnti
=
rnti
;
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
harq_processes
[
harq_pid
]
->
status
=
IDLE
;
}
else
*
crnti
=
0x0
;
if
(
1
)
{
LOG_D
(
PHY
,
"ulsch_decoding_emul abstraction successful
\n
"
);
memcpy
(
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
b
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
harq_processes
[
harq_pid
]
->
b
,
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
TBS
>>
3
);
// get local ue's ack
if
((
UE_index
>=
oai_emulation
.
info
.
first_ue_local
)
||
(
UE_index
<
(
oai_emulation
.
info
.
first_ue_local
+
oai_emulation
.
info
.
nb_ue_local
)))
{
get_ack
(
&
eNB
->
frame_parms
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
dlsch
[
0
][
0
][
0
]
->
harq_ack
,
proc
->
subframe_tx
,
proc
->
subframe_rx
,
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
,
0
);
}
else
{
// get remote UEs' ack
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
0
]
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o_ACK
[
0
];
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
1
]
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o_ACK
[
1
];
for
(
UE_id
=
0
;
UE_id
<
NB_UE_INST
;
UE_id
++
)
{
if
(
rnti
==
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
pdcch_vars
[
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
current_thread_id
[
subframe
]][
0
]
->
crnti
)
break
;
}
// Do abstraction of PUSCH feedback
if
(
UE_id
==
NB_UE_INST
)
{
LOG_W
(
PHY
,
"[eNB %d] ulsch_decoding_emul: FATAL, didn't find UE with rnti %x (UE index %d)
\n
"
,
eNB
->
Mod_id
,
rnti
,
UE_index
);
return
(
1
+
eNB
->
ulsch
[
UE_id
]
->
max_turbo_iterations
);
}
else
{
LOG_D
(
PHY
,
"[eNB %d] Found UE with rnti %x => UE_id %d
\n
"
,
eNB
->
Mod_id
,
rnti
,
UE_id
);
}
if
(
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
harq_processes
[
harq_pid
]
->
status
==
CBA_ACTIVE
)
{
*
crnti
=
rnti
;
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
harq_processes
[
harq_pid
]
->
status
=
IDLE
;
}
else
*
crnti
=
0x0
;
if
(
1
)
{
LOG_D
(
PHY
,
"ulsch_decoding_emul abstraction successful
\n
"
);
memcpy
(
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
b
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
harq_processes
[
harq_pid
]
->
b
,
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
TBS
>>
3
);
// get local ue's ack
if
((
UE_index
>=
oai_emulation
.
info
.
first_ue_local
)
||
(
UE_index
<
(
oai_emulation
.
info
.
first_ue_local
+
oai_emulation
.
info
.
nb_ue_local
)))
{
get_ack
(
&
eNB
->
frame_parms
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
dlsch
[
0
][
0
][
0
]
->
harq_ack
,
proc
->
subframe_tx
,
proc
->
subframe_rx
,
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
,
0
);
}
else
{
// get remote UEs' ack
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
0
]
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o_ACK
[
0
];
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
1
]
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o_ACK
[
1
];
}
// Do abstraction of PUSCH feedback
#ifdef DEBUG_PHY
LOG_D
(
PHY
,
"[eNB %d][EMUL] ue index %d UE_id %d: subframe %d : o_ACK (%d %d), cqi (val %d, len %d)
\n
"
,
eNB
->
Mod_id
,
UE_index
,
UE_id
,
subframe
,
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
0
],
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
1
],
((
HLC_subband_cqi_rank1_2A_5MHz
*
)
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o
)
->
cqi1
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
O
);
LOG_D
(
PHY
,
"[eNB %d][EMUL] ue index %d UE_id %d: subframe %d : o_ACK (%d %d), cqi (val %d, len %d)
\n
"
,
eNB
->
Mod_id
,
UE_index
,
UE_id
,
subframe
,
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
0
],
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
1
],
((
HLC_subband_cqi_rank1_2A_5MHz
*
)
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o
)
->
cqi1
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
O
);
#endif
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
Or1
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
O
;
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
Or2
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
O
;
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
Or1
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
O
;
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
Or2
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
O
;
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
uci_format
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
uci_format
;
memcpy
(
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o
,
MAX_CQI_BYTES
);
memcpy
(
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_RI
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o_RI
,
2
);
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
uci_format
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
uci_format
;
memcpy
(
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o
,
MAX_CQI_BYTES
);
memcpy
(
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_RI
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o_RI
,
2
);
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
cqi_crc_status
=
1
;
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
cqi_crc_status
=
1
;
return
(
1
);
}
else
{
LOG_W
(
PHY
,
"[eNB %d] ulsch_decoding_emul abstraction failed for UE %d
\n
"
,
eNB
->
Mod_id
,
UE_index
);
return
(
1
);
}
else
{
LOG_W
(
PHY
,
"[eNB %d] ulsch_decoding_emul abstraction failed for UE %d
\n
"
,
eNB
->
Mod_id
,
UE_index
);
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
cqi_crc_status
=
0
;
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
cqi_crc_status
=
0
;
// retransmission
return
(
1
+
eNB
->
ulsch
[
UE_index
]
->
max_turbo_iterations
);
}
// retransmission
return
(
1
+
eNB
->
ulsch
[
UE_index
]
->
max_turbo_iterations
);
}
}
#endif
...
...
openair1/SCHED/phy_procedures_lte_eNb.c
View file @
edfef131
...
...
@@ -555,6 +555,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
uint64_t
startTime
=
rdtsc
();
for
(
UE_id
=
0
;
UE_id
<
NUMBER_OF_UE_MAX
;
UE_id
++
)
{
eNB
->
proc
.
threadPool
.
startProcessingUE
=
rdtsc
();
dlsch0
=
eNB
->
dlsch
[(
uint8_t
)
UE_id
][
0
];
dlsch1
=
eNB
->
dlsch
[(
uint8_t
)
UE_id
][
1
];
...
...
@@ -567,11 +568,9 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
AssertFatal
(
harq_pid
>=
0
,
"harq_pid is negative
\n
"
);
if
(
harq_pid
>=
8
)
{
LOG_E
(
PHY
,
"harq_pid:%d corrupt must be 0-7 UE_id:%d frame:%d subframe:%d rnti:%x
\n
"
,
harq_pid
,
UE_id
,
frame
,
subframe
,
dlsch0
->
rnti
);
}
LOG_E
(
PHY
,
"harq_pid:%d corrupt must be 0-7 UE_id:%d frame:%d subframe:%d rnti:%x
\n
"
,
harq_pid
,
UE_id
,
frame
,
subframe
,
dlsch0
->
rnti
);
else
{
// generate pdsch
pdsch_procedures
(
eNB
,
proc
,
...
...
@@ -580,7 +579,6 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
dlsch1
,
&
eNB
->
UE_stats
[(
uint32_t
)
UE_id
],
0
);
}
}
}
...
...
@@ -615,19 +613,19 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
}
request_t
*
tmp
;
while
((
tmp
=
eNB
->
proc
.
threadPool
.
doneRequests
)
!=
NULL
)
{
tmp
->
returnTime
=
rdtsc
();
tmp
->
cumulSubframe
=
tmp
->
returnTime
-
startTime
;
// Ignore write error (if no trace listner)
if
(
write
(
eNB
->
proc
.
threadPool
.
traceFd
,
tmp
,
sizeof
(
request_t
)
-
2
*
sizeof
(
void
*
)))
{};
eNB
->
proc
.
threadPool
.
doneRequests
=
tmp
->
next
;
start_meas
(
&
eNB
->
dlsch_interleaving_stats
);
turboEncode_t
*
rdata
=
(
turboEncode_t
*
)
tmp
->
data
;
rdata
->
dlsch
->
harq_processes
[
rdata
->
harq_pid
]
->
RTC
[
rdata
->
r
]
=
sub_block_interleaving_turbo
(
4
+
(
rdata
->
Kr_bytes
*
8
),
rdata
->
output
+
96
,
//&dlsch->harq_processes[harq_pid]->d[r][96],
rdata
->
dlsch
->
harq_processes
[
rdata
->
harq_pid
]
->
w
[
rdata
->
r
]);
freeRequest
(
tmp
);
stop_meas
(
&
eNB
->
dlsch_interleaving_stats
);
tmp
->
returnTime
=
rdtsc
();
tmp
->
cumulSubframe
=
tmp
->
returnTime
-
startTime
;
// Ignore write error (if no trace listner)
if
(
write
(
eNB
->
proc
.
threadPool
.
traceFd
,
tmp
,
sizeof
(
request_t
)
-
2
*
sizeof
(
void
*
)))
{};
eNB
->
proc
.
threadPool
.
doneRequests
=
tmp
->
next
;
start_meas
(
&
eNB
->
dlsch_interleaving_stats
);
turboEncode_t
*
rdata
=
(
turboEncode_t
*
)
tmp
->
data
;
rdata
->
dlsch
->
harq_processes
[
rdata
->
harq_pid
]
->
RTC
[
rdata
->
r
]
=
sub_block_interleaving_turbo
(
4
+
(
rdata
->
Kr_bytes
*
8
),
rdata
->
output
+
96
,
//&dlsch->harq_processes[harq_pid]->d[r][96],
rdata
->
dlsch
->
harq_processes
[
rdata
->
harq_pid
]
->
w
[
rdata
->
r
]);
freeRequest
(
tmp
);
stop_meas
(
&
eNB
->
dlsch_interleaving_stats
);
}
for
(
UE_id
=
0
;
UE_id
<
NUMBER_OF_UE_MAX
;
UE_id
++
)
{
...
...
@@ -1506,9 +1504,10 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
eNB
->
proc
.
threadPool
.
newestRequests
!=
NULL
||
eNB
->
proc
.
threadPool
.
doneRequests
!=
NULL
)
LOG_E
(
PHY
,
"no finished = %d
\n
"
,
eNB
->
proc
.
threadPool
.
notFinishedJobs
);
LOG_E
(
PHY
,
"no finished = %d
\n
"
,
eNB
->
proc
.
threadPool
.
notFinishedJobs
);
uint64_t
startTime
=
rdtsc
();
for
(
int
i
=
0
;
i
<
NUMBER_OF_UE_MAX
;
i
++
)
{
eNB
->
proc
.
threadPool
.
startProcessingUE
=
rdtsc
();
LTE_eNB_ULSCH_t
*
ulsch
=
eNB
->
ulsch
[
i
];
LTE_UL_eNB_HARQ_t
*
ulsch_harq
=
ulsch
->
harq_processes
[
harq_pid
];
...
...
@@ -1590,15 +1589,15 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
request_t
*
tmp
;
while
((
tmp
=
eNB
->
proc
.
threadPool
.
doneRequests
)
!=
NULL
)
{
turboDecode_t
*
rdata
=
(
turboDecode_t
*
)
tmp
->
data
;
tmp
->
decodeIterations
=
rdata
->
decodeIterations
;
post_decode
(
tmp
);
tmp
->
returnTime
=
rdtsc
();
tmp
->
cumulSubframe
=
tmp
->
returnTime
-
startTime
;
// Ignore write error (if no trace listner)
if
(
write
(
eNB
->
proc
.
threadPool
.
traceFd
,
tmp
,
sizeof
(
request_t
)
-
2
*
sizeof
(
void
*
)))
{};
eNB
->
proc
.
threadPool
.
doneRequests
=
tmp
->
next
;
freeRequest
(
tmp
);
turboDecode_t
*
rdata
=
(
turboDecode_t
*
)
tmp
->
data
;
tmp
->
decodeIterations
=
rdata
->
decodeIterations
;
post_decode
(
tmp
);
tmp
->
returnTime
=
rdtsc
();
tmp
->
cumulSubframe
=
tmp
->
returnTime
-
startTime
;
// Ignore write error (if no trace listner)
if
(
write
(
eNB
->
proc
.
threadPool
.
traceFd
,
tmp
,
sizeof
(
request_t
)
-
2
*
sizeof
(
void
*
)))
{};
eNB
->
proc
.
threadPool
.
doneRequests
=
tmp
->
next
;
freeRequest
(
tmp
);
}
}
...
...
targets/tcri/measurement_display.c
View file @
edfef131
...
...
@@ -18,9 +18,9 @@
uint64_t
cpuCyclesMicroSec
;
static
__inline__
uint64_t
rdtsc
(
void
)
{
uint64_t
a
,
d
;
__asm__
volatile
(
"rdtsc"
:
"=a"
(
a
),
"=d"
(
d
));
return
(
d
<<
32
)
|
a
;
uint64_t
a
,
d
;
__asm__
volatile
(
"rdtsc"
:
"=a"
(
a
),
"=d"
(
d
));
return
(
d
<<
32
)
|
a
;
}
#include "thread-pool.h"
...
...
@@ -30,10 +30,10 @@ int main(int argc, char* argv[]) {
usleep
(
100000
);
cpuCyclesMicroSec
=
(
rdtsc
()
-
deb
)
/
100000
;
printf
(
"Cycles per µs: %lu
\n
"
,
cpuCyclesMicroSec
);
#define SEP "\t"
#define SEP "\t"
printf
(
"Frame"
SEP
"SubFrame"
SEP
"CodeBlock"
SEP
"RNTI"
SEP
"Iterations"
SEP
"StartTime"
SEP
"RunTime"
SEP
"ReturnTime"
SEP
"CumulSubFrame"
SEP
"CPUcore"
SEP
"ThreadID"
"
\n
"
);
"PreparationTime"
SEP
"StartTime"
SEP
"RunTime"
SEP
"ReturnTime"
SEP
"CumulSubFrame"
SEP
"CPUcore"
SEP
"ThreadID"
"
\n
"
);
mkfifo
(
"/tmp/test-tcri"
,
0666
);
int
fd
=
open
(
"/tmp/test-tcri"
,
O_RDONLY
);
...
...
@@ -44,27 +44,28 @@ int main(int argc, char* argv[]) {
request_t
doneRequest
;
int
s
=
sizeof
(
request_t
)
-
2
*
sizeof
(
void
*
);
while
(
1
)
{
if
(
read
(
fd
,
&
doneRequest
,
s
)
==
s
)
{
union
turboReqUnion
id
=
{.
p
=
doneRequest
.
id
};
doneRequest
.
processedBy
[
15
]
=
'\0'
;
printf
(
"%u"
SEP
"%u"
SEP
"%u"
SEP
"%u"
SEP
"%lu"
SEP
"%lu"
SEP
"%lu"
SEP
"%lu"
SEP
"%lu"
SEP
"%u"
SEP
"%s"
"
\n
"
,
id
.
s
.
frame
,
id
.
s
.
subframe
,
id
.
s
.
codeblock
,
id
.
s
.
rnti
,
doneRequest
.
decodeIterations
,
(
doneRequest
.
startProcessingTime
-
doneRequest
.
creationTime
)
/
cpuCyclesMicroSec
,
(
doneRequest
.
endProcessingTime
-
doneRequest
.
startProcessingTime
)
/
cpuCyclesMicroSec
,
(
doneRequest
.
returnTime
-
doneRequest
.
endProcessingTime
)
/
cpuCyclesMicroSec
,
doneRequest
.
cumulSubframe
/
cpuCyclesMicroSec
,
doneRequest
.
coreId
,
doneRequest
.
processedBy
);
}
else
{
printf
(
"no measurements
\n
"
);
sleep
(
1
);
}
if
(
read
(
fd
,
&
doneRequest
,
s
)
==
s
)
{
union
turboReqUnion
id
=
{.
p
=
doneRequest
.
id
};
doneRequest
.
processedBy
[
15
]
=
'\0'
;
printf
(
"%u"
SEP
"%u"
SEP
"%u"
SEP
"%u"
SEP
"%lu"
SEP
"%lu"
SEP
"%lu"
SEP
"%lu"
SEP
"%lu"
SEP
"%lu"
SEP
"%u"
SEP
"%s"
"
\n
"
,
id
.
s
.
frame
,
id
.
s
.
subframe
,
id
.
s
.
codeblock
,
id
.
s
.
rnti
,
doneRequest
.
decodeIterations
,
(
doneRequest
.
creationTime
-
doneRequest
.
startUELoop
)
/
cpuCyclesMicroSec
,
(
doneRequest
.
startProcessingTime
-
doneRequest
.
creationTime
)
/
cpuCyclesMicroSec
,
(
doneRequest
.
endProcessingTime
-
doneRequest
.
startProcessingTime
)
/
cpuCyclesMicroSec
,
(
doneRequest
.
returnTime
-
doneRequest
.
endProcessingTime
)
/
cpuCyclesMicroSec
,
doneRequest
.
cumulSubframe
/
cpuCyclesMicroSec
,
doneRequest
.
coreId
,
doneRequest
.
processedBy
);
}
else
{
printf
(
"no measurements
\n
"
);
sleep
(
1
);
}
}
}
targets/tcri/thread-pool.c
View file @
edfef131
...
...
@@ -29,6 +29,7 @@
request_t
*
createRequest
(
enum
request_t
type
,
int
size
)
{
request_t
*
request
;
AssertFatal
(
(
request
=
(
request_t
*
)
aligned_alloc
(
32
,
sizeof
(
request_t
)
+
size
))
!=
NULL
,
""
);
memset
(
request
,
0
,
sizeof
(
request_t
));
request
->
id
=
0
;
request
->
type
=
type
;
request
->
next
=
NULL
;
...
...
@@ -200,12 +201,7 @@ void handle_request(tpool_t * tp, request_t* request) {
tp
->
doneRequests
=
request
;
condsignal
(
tp
->
notifDone
);
mutexunlock
(
tp
->
lockReportDone
);
/*
printf("Thread '%ld' handled request '%d' delay in µs:%ld\n",
syscall( SYS_gettid ),
request->id,
(rdtsc() - request->creationTime)/tp->cpuCyclesMicroSec);
*/
}
void
*
one_thread
(
void
*
data
)
{
...
...
targets/tcri/thread-pool.h
View file @
edfef131
...
...
@@ -25,11 +25,12 @@ union turboReqUnion {
typedef
struct
request
{
uint64_t
id
;
enum
request_t
type
;
uint64_t
startUELoop
;
uint64_t
creationTime
;
uint64_t
startProcessingTime
;
uint64_t
endProcessingTime
;
uint64_t
returnTime
;
uint64_t
cumulSubframe
;
uint64_t
returnTime
;
uint64_t
cumulSubframe
;
uint64_t
decodeIterations
;
int
coreId
;
char
processedBy
[
16
];
...
...
@@ -60,6 +61,7 @@ typedef struct thread_pool {
int
traceFd
;
int
dummyTraceFd
;
uint64_t
cpuCyclesMicroSec
;
uint64_t
startProcessingUE
;
int
nbThreads
;
bool
restrictRNTI
;
struct
one_thread
*
allthreads
;
...
...
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