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
wangjie
OpenXG-RAN
Commits
ba0d2dae
Commit
ba0d2dae
authored
Jul 16, 2021
by
yihongzheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fpga_ldpc both decode and encode are OK
parent
3289c89f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
715 additions
and
1 deletion
+715
-1
openair1/PHY/NR_TRANSPORT/nr_dlsch.c
openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+487
-0
openair1/PHY/NR_TRANSPORT/nr_dlsch.h
openair1/PHY/NR_TRANSPORT/nr_dlsch.h
+30
-0
openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+194
-0
openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+2
-0
openair1/SCHED_NR/phy_procedures_nr_gNB.c
openair1/SCHED_NR/phy_procedures_nr_gNB.c
+2
-1
No files found.
openair1/PHY/NR_TRANSPORT/nr_dlsch.c
View file @
ba0d2dae
...
...
@@ -543,3 +543,490 @@ void clear_pdsch_stats(PHY_VARS_gNB *gNB) {
for
(
int
i
=
0
;
i
<
gNB
->
number_of_nr_dlsch_max
;
i
++
)
memset
((
void
*
)
&
gNB
->
dlsch_stats
[
i
],
0
,
sizeof
(
gNB
->
dlsch_stats
[
i
]));
}
void
nr_pdsch_codeword_scrambling_optim_fpga_ldpc
(
uint8_t
*
in
,
uint32_t
size
,
uint8_t
q
,
uint32_t
Nid
,
uint32_t
n_RNTI
,
uint32_t
*
out
)
{
uint32_t
x1
,
x2
,
s
=
0
;
uint32_t
*
pin32
;
uint32_t
byteSize
=
size
/
8
;
x2
=
(
n_RNTI
<<
15
)
+
(
q
<<
14
)
+
Nid
;
s
=
lte_gold_generic
(
&
x1
,
&
x2
,
1
);
#if defined(__AVX2__)
//让FPGA输出的每个BYTE中的高低位bit翻转
LOG_D
(
PHY
,
"in = %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x
\n
"
,
in
[
0
],
in
[
1
],
in
[
2
],
in
[
3
],
in
[
4
],
in
[
5
],
in
[
6
],
in
[
7
]);
Byte_Reverse_11
(
in
,
in
,
byteSize
);
pin32
=
(
uint32_t
*
)
in
;
for
(
int
j
=
0
;
j
<
(
byteSize
+
3
)
/
4
;
j
++
)
{
out
[
j
]
=
(
pin32
[
j
]
^
s
);
s
=
lte_gold_generic
(
&
x1
,
&
x2
,
0
);
}
#elif defined(__SSE4__)
uint32_t
in32
=
0
;
_m128i
*
in128
;
for
(
int
i
=
0
;
i
<
((
size
>>
5
)
+
((
size
&
0x1f
)
>
0
?
1
:
0
));
i
++
)
{
in128
=&
((
__m128i
*
)
in
)[
i
<<
1
];
((
uint16_t
*
)
&
in32
)[
0
]
=
_mm128_movemask_epi8
(
_mm256_slli_epi16
(
in128
[
0
],
7
));
((
uint16_t
*
)
&
in32
)[
1
]
=
_mm128_movemask_epi8
(
_mm256_slli_epi16
(
in128
[
1
],
7
));
out
[
i
]
=
(
in32
^
s
);
s
=
lte_gold_generic
(
&
x1
,
&
x2
,
0
);
}
//#elsif defined(__arm__) || defined(__aarch64)
#else
nr_pdsch_codeword_scrambling
(
in
,
size
,
q
,
Nid
,
n_RNTI
,
out
);
#endif
}
unsigned
char
Reverse8U
(
unsigned
char
x
)
{
x
=
(
x
&
0xaa
)
>>
1
|
(
x
&
0x55
)
<<
1
;
x
=
(
x
&
0xcc
)
>>
2
|
(
x
&
0x33
)
<<
2
;
x
=
(
x
&
0xf0
)
>>
4
|
(
x
&
0x0f
)
<<
4
;
return
x
;
}
void
Byte_Reverse_11
(
unsigned
char
*
Src
,
unsigned
char
*
Dest
,
int
Length
)
{
int
BlockSize
=
16
,
Block
=
Length
/
BlockSize
;
for
(
int
Y
=
0
;
Y
<
Block
*
BlockSize
;
Y
+=
BlockSize
)
{
__m128i
V
=
_mm_loadu_si128
((
__m128i
*
)(
Src
+
Y
));
V
=
_mm_or_si128
(
_mm_srli_epi16
(
_mm_and_si128
(
V
,
_mm_set1_epi8
(
0xaa
)),
1
),
_mm_slli_epi16
(
_mm_and_si128
(
V
,
_mm_set1_epi8
(
0x55
)),
1
));
V
=
_mm_or_si128
(
_mm_srli_epi16
(
_mm_and_si128
(
V
,
_mm_set1_epi8
(
0xcc
)),
2
),
_mm_slli_epi16
(
_mm_and_si128
(
V
,
_mm_set1_epi8
(
0x33
)),
2
));
V
=
_mm_or_si128
(
_mm_srli_epi16
(
_mm_and_si128
(
V
,
_mm_set1_epi8
(
0xf0
)),
4
),
_mm_slli_epi16
(
_mm_and_si128
(
V
,
_mm_set1_epi8
(
0x0f
)),
4
));
_mm_storeu_si128
((
__m128i
*
)(
Dest
+
Y
),
V
);
}
for
(
int
Y
=
Block
*
BlockSize
;
Y
<
Length
;
Y
++
)
{
Dest
[
Y
]
=
Reverse8U
(
Src
[
Y
]);
}
}
uint8_t
nr_generate_pdsch_fpga_ldpc
(
PHY_VARS_gNB
*
gNB
,
int
frame
,
int
slot
)
{
NR_gNB_DLSCH_t
*
dlsch
;
uint32_t
***
pdsch_dmrs
=
gNB
->
nr_gold_pdsch_dmrs
[
slot
];
int32_t
**
txdataF
=
gNB
->
common_vars
.
txdataF
;
int16_t
amp
=
AMP
;
int
xOverhead
=
0
;
NR_DL_FRAME_PARMS
*
frame_parms
=
&
gNB
->
frame_parms
;
time_stats_t
*
dlsch_encoding_stats
=&
gNB
->
dlsch_encoding_stats
;
time_stats_t
*
dlsch_scrambling_stats
=&
gNB
->
dlsch_scrambling_stats
;
time_stats_t
*
dlsch_modulation_stats
=&
gNB
->
dlsch_modulation_stats
;
time_stats_t
*
tinput
=&
gNB
->
tinput
;
time_stats_t
*
tprep
=&
gNB
->
tprep
;
time_stats_t
*
tparity
=&
gNB
->
tparity
;
time_stats_t
*
toutput
=&
gNB
->
toutput
;
time_stats_t
*
dlsch_rate_matching_stats
=&
gNB
->
dlsch_rate_matching_stats
;
time_stats_t
*
dlsch_interleaving_stats
=&
gNB
->
dlsch_interleaving_stats
;
time_stats_t
*
dlsch_segmentation_stats
=&
gNB
->
dlsch_segmentation_stats
;
for
(
int
dlsch_id
=
0
;
dlsch_id
<
gNB
->
number_of_nr_dlsch_max
;
dlsch_id
++
)
{
dlsch
=
gNB
->
dlsch
[
dlsch_id
][
0
];
if
(
dlsch
->
slot_tx
[
slot
]
==
0
)
continue
;
NR_DL_gNB_HARQ_t
*
harq
=
&
dlsch
->
harq_process
;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t
*
rel15
=
&
harq
->
pdsch_pdu
.
pdsch_pdu_rel15
;
uint32_t
scrambled_output
[
NR_MAX_NB_CODEWORDS
][
NR_MAX_PDSCH_ENCODED_LENGTH
>>
5
];
int16_t
**
mod_symbs
=
(
int16_t
**
)
dlsch
->
mod_symbs
;
int16_t
**
tx_layers
=
(
int16_t
**
)
dlsch
->
txdataF
;
int16_t
**
txdataF_precoding
=
(
int16_t
**
)
dlsch
->
txdataF_precoding
;
int8_t
Wf
[
2
],
Wt
[
2
],
l0
,
l_prime
,
l_overline
,
delta
;
uint8_t
dmrs_Type
=
rel15
->
dmrsConfigType
;
int
nb_re_dmrs
;
uint16_t
n_dmrs
;
if
(
rel15
->
dmrsConfigType
==
NFAPI_NR_DMRS_TYPE1
)
{
nb_re_dmrs
=
6
*
rel15
->
numDmrsCdmGrpsNoData
;
}
else
{
nb_re_dmrs
=
4
*
rel15
->
numDmrsCdmGrpsNoData
;
}
n_dmrs
=
(
rel15
->
BWPStart
+
rel15
->
rbStart
+
rel15
->
rbSize
)
*
nb_re_dmrs
;
uint16_t
dmrs_symbol_map
=
rel15
->
dlDmrsSymbPos
;
//single DMRS: 010000100 Double DMRS 110001100
uint8_t
dmrs_len
=
get_num_dmrs
(
rel15
->
dlDmrsSymbPos
);
uint16_t
nb_re
=
((
12
*
rel15
->
NrOfSymbols
)
-
nb_re_dmrs
*
dmrs_len
-
xOverhead
)
*
rel15
->
rbSize
*
rel15
->
nrOfLayers
;
uint8_t
Qm
=
rel15
->
qamModOrder
[
0
];
uint32_t
encoded_length
=
nb_re
*
Qm
;
int16_t
mod_dmrs
[
n_dmrs
<<
1
]
__attribute__
((
aligned
(
16
)));
/* PTRS */
uint16_t
beta_ptrs
=
1
;
uint8_t
ptrs_symbol
=
0
;
uint16_t
dlPtrsSymPos
=
0
;
uint16_t
n_ptrs
=
0
;
uint16_t
ptrs_idx
=
0
;
uint8_t
is_ptrs_re
=
0
;
if
(
rel15
->
pduBitmap
&
0x1
)
{
set_ptrs_symb_idx
(
&
dlPtrsSymPos
,
rel15
->
NrOfSymbols
,
rel15
->
StartSymbolIndex
,
1
<<
rel15
->
PTRSTimeDensity
,
rel15
->
dlDmrsSymbPos
);
n_ptrs
=
(
rel15
->
rbSize
+
rel15
->
PTRSFreqDensity
-
1
)
/
rel15
->
PTRSFreqDensity
;
}
int16_t
mod_ptrs
[
n_ptrs
<<
1
]
__attribute__
((
aligned
(
16
)));
/// CRC, coding, interleaving and rate matching
AssertFatal
(
harq
->
pdu
!=
NULL
,
"harq->pdu is null
\n
"
);
start_meas
(
dlsch_encoding_stats
);
nr_dlsch_encoding_fpga_ldpc
(
gNB
,
harq
->
pdu
,
frame
,
slot
,
dlsch
,
frame_parms
,
tinput
,
tprep
,
tparity
,
toutput
,
dlsch_rate_matching_stats
,
dlsch_interleaving_stats
,
dlsch_segmentation_stats
);
stop_meas
(
dlsch_encoding_stats
);
#ifdef DEBUG_DLSCH
printf
(
"PDSCH encoding:
\n
Payload:
\n
"
);
for
(
int
i
=
0
;
i
<
harq
->
B
>>
7
;
i
++
)
{
for
(
int
j
=
0
;
j
<
16
;
j
++
)
printf
(
"0x%02x
\t
"
,
harq
->
pdu
[(
i
<<
4
)
+
j
]);
printf
(
"
\n
"
);
}
printf
(
"
\n
Encoded payload:
\n
"
);
for
(
int
i
=
0
;
i
<
encoded_length
>>
3
;
i
++
)
{
for
(
int
j
=
0
;
j
<
8
;
j
++
)
printf
(
"%d"
,
harq
->
f
[(
i
<<
3
)
+
j
]);
printf
(
"
\t
"
);
}
printf
(
"
\n
"
);
#endif
/// scrambling
start_meas
(
dlsch_scrambling_stats
);
for
(
int
q
=
0
;
q
<
rel15
->
NrOfCodewords
;
q
++
)
memset
((
void
*
)
scrambled_output
[
q
],
0
,
(
encoded_length
>>
5
)
*
sizeof
(
uint32_t
));
for
(
int
q
=
0
;
q
<
rel15
->
NrOfCodewords
;
q
++
)
nr_pdsch_codeword_scrambling_optim_fpga_ldpc
(
harq
->
f
,
encoded_length
,
q
,
rel15
->
dlDmrsScramblingId
,
rel15
->
rnti
,
scrambled_output
[
q
]);
stop_meas
(
dlsch_scrambling_stats
);
#ifdef DEBUG_DLSCH
printf
(
"PDSCH scrambling:
\n
"
);
for
(
int
i
=
0
;
i
<
encoded_length
>>
8
;
i
++
)
{
for
(
int
j
=
0
;
j
<
8
;
j
++
)
printf
(
"0x%08x
\t
"
,
scrambled_output
[
0
][(
i
<<
3
)
+
j
]);
printf
(
"
\n
"
);
}
#endif
/// Modulation
start_meas
(
dlsch_modulation_stats
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION
,
1
);
for
(
int
q
=
0
;
q
<
rel15
->
NrOfCodewords
;
q
++
)
nr_modulation
(
scrambled_output
[
q
],
encoded_length
,
Qm
,
mod_symbs
[
q
]);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION
,
0
);
stop_meas
(
dlsch_modulation_stats
);
#ifdef DEBUG_DLSCH
printf
(
"PDSCH Modulation: Qm %d(%d)
\n
"
,
Qm
,
nb_re
);
for
(
int
i
=
0
;
i
<
nb_re
>>
3
;
i
++
)
{
for
(
int
j
=
0
;
j
<
8
;
j
++
)
{
printf
(
"%d %d
\t
"
,
mod_symbs
[
0
][((
i
<<
3
)
+
j
)
<<
1
],
mod_symbs
[
0
][(((
i
<<
3
)
+
j
)
<<
1
)
+
1
]);
}
printf
(
"
\n
"
);
}
#endif
/// Layer mapping
nr_layer_mapping
(
mod_symbs
,
rel15
->
nrOfLayers
,
nb_re
,
tx_layers
);
#ifdef DEBUG_DLSCH
printf
(
"Layer mapping (%d layers):
\n
"
,
rel15
->
nrOfLayers
);
for
(
int
l
=
0
;
l
<
rel15
->
nrOfLayers
;
l
++
)
for
(
int
i
=
0
;
i
<
(
nb_re
/
rel15
->
nrOfLayers
)
>>
3
;
i
++
)
{
printf
(
"layer %d, Re %d..%d : "
,
l
,
i
<<
3
,(
i
<<
3
)
+
7
);
for
(
int
j
=
0
;
j
<
8
;
j
++
)
{
printf
(
"l%d %d
\t
"
,
tx_layers
[
l
][((
i
<<
3
)
+
j
)
<<
1
],
tx_layers
[
l
][(((
i
<<
3
)
+
j
)
<<
1
)
+
1
]);
}
printf
(
"
\n
"
);
}
#endif
/// Resource mapping
// Non interleaved VRB to PRB mapping
uint16_t
start_sc
=
frame_parms
->
first_carrier_offset
+
(
rel15
->
rbStart
+
rel15
->
BWPStart
)
*
NR_NB_SC_PER_RB
;
if
(
start_sc
>=
frame_parms
->
ofdm_symbol_size
)
start_sc
-=
frame_parms
->
ofdm_symbol_size
;
int
txdataF_offset
=
(
slot
%
2
)
*
frame_parms
->
samples_per_slot_wCP
;
#ifdef DEBUG_DLSCH_MAPPING
printf
(
"PDSCH resource mapping started (start SC %d
\t
start symbol %d
\t
N_PRB %d
\t
nb_re %d,nb_layers %d)
\n
"
,
start_sc
,
rel15
->
StartSymbolIndex
,
rel15
->
rbSize
,
nb_re
,
rel15
->
nrOfLayers
);
#endif
for
(
int
ap
=
0
;
ap
<
rel15
->
nrOfLayers
;
ap
++
)
{
// DMRS params for this ap
get_Wt
(
Wt
,
ap
,
dmrs_Type
);
get_Wf
(
Wf
,
ap
,
dmrs_Type
);
delta
=
get_delta
(
ap
,
dmrs_Type
);
l_prime
=
0
;
// single symbol ap 0
l0
=
get_l0
(
rel15
->
dlDmrsSymbPos
);
l_overline
=
l0
;
#ifdef DEBUG_DLSCH_MAPPING
uint8_t
dmrs_symbol
=
l0
+
l_prime
;
printf
(
"DMRS Type %d params for ap %d: Wt %d %d
\t
Wf %d %d
\t
delta %d
\t
l_prime %d
\t
l0 %d
\t
DMRS symbol %d
\n
"
,
1
+
dmrs_Type
,
ap
,
Wt
[
0
],
Wt
[
1
],
Wf
[
0
],
Wf
[
1
],
delta
,
l_prime
,
l0
,
dmrs_symbol
);
#endif
uint16_t
m
=
0
,
dmrs_idx
=
0
;
// Loop Over OFDM symbols:
for
(
int
l
=
rel15
->
StartSymbolIndex
;
l
<
rel15
->
StartSymbolIndex
+
rel15
->
NrOfSymbols
;
l
++
)
{
/// DMRS QPSK modulation
uint8_t
k_prime
=
0
;
uint16_t
n
=
0
;
if
((
dmrs_symbol_map
&
(
1
<<
l
))){
// DMRS time occasion
// The reference point for is subcarrier 0 of the lowest-numbered resource block in CORESET 0 if the corresponding
// PDCCH is associated with CORESET 0 and Type0-PDCCH common search space and is addressed to SI-RNTI
// 3GPP TS 38.211 V15.8.0 Section 7.4.1.1.2 Mapping to physical resources
if
(
rel15
->
rnti
==
SI_RNTI
)
{
if
(
dmrs_Type
==
NFAPI_NR_DMRS_TYPE1
)
{
dmrs_idx
=
rel15
->
rbStart
*
6
;
}
else
{
dmrs_idx
=
rel15
->
rbStart
*
4
;
}
}
else
{
if
(
dmrs_Type
==
NFAPI_NR_DMRS_TYPE1
)
{
dmrs_idx
=
(
rel15
->
rbStart
+
rel15
->
BWPStart
)
*
6
;
}
else
{
dmrs_idx
=
(
rel15
->
rbStart
+
rel15
->
BWPStart
)
*
4
;
}
}
}
// Update l_prime in the case of double DMRS config
if
((
dmrs_symbol_map
&
(
1
<<
l
))){
//DMRS time occasion
if
(
l
==
(
l_overline
+
1
))
//take into account the double DMRS symbols
l_prime
=
1
;
else
if
(
l
>
(
l_overline
+
1
))
{
//new DMRS pair
l_overline
=
l
;
l_prime
=
0
;
}
}
/// DMRS QPSK modulation
if
(
rel15
->
dlDmrsSymbPos
&
(
1
<<
l
))
{
nr_modulation
(
pdsch_dmrs
[
l
][
0
],
n_dmrs
*
2
,
DMRS_MOD_ORDER
,
mod_dmrs
);
// currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
#ifdef DEBUG_DLSCH
printf
(
"DMRS modulation (symbol %d, %d symbols, type %d):
\n
"
,
l
,
n_dmrs
,
dmrs_Type
);
for
(
int
i
=
0
;
i
<
n_dmrs
>>
4
;
i
++
)
{
for
(
int
j
=
0
;
j
<
8
;
j
++
)
{
printf
(
"%d %d
\t
"
,
mod_dmrs
[((
i
<<
3
)
+
j
)
<<
1
],
mod_dmrs
[(((
i
<<
3
)
+
j
)
<<
1
)
+
1
]);
}
printf
(
"
\n
"
);
}
#endif
}
/* calculate if current symbol is PTRS symbols */
ptrs_idx
=
0
;
if
(
rel15
->
pduBitmap
&
0x1
)
{
ptrs_symbol
=
is_ptrs_symbol
(
l
,
dlPtrsSymPos
);
if
(
ptrs_symbol
)
{
/* PTRS QPSK Modulation for each OFDM symbol in a slot */
nr_modulation
(
pdsch_dmrs
[
l
][
0
],
(
n_ptrs
<<
1
),
DMRS_MOD_ORDER
,
mod_ptrs
);
}
}
uint16_t
k
=
start_sc
;
// Loop Over SCs:
for
(
int
i
=
0
;
i
<
rel15
->
rbSize
*
NR_NB_SC_PER_RB
;
i
++
)
{
/* check if cuurent RE is PTRS RE*/
is_ptrs_re
=
0
;
/* check for PTRS symbol and set flag for PTRS RE */
if
(
ptrs_symbol
){
is_ptrs_re
=
is_ptrs_subcarrier
(
k
,
rel15
->
rnti
,
ap
,
rel15
->
dmrsConfigType
,
rel15
->
PTRSFreqDensity
,
rel15
->
rbSize
,
rel15
->
PTRSReOffset
,
start_sc
,
frame_parms
->
ofdm_symbol_size
);
}
/* Map DMRS Symbol */
if
(
(
dmrs_symbol_map
&
(
1
<<
l
)
)
&&
(
k
==
((
start_sc
+
get_dmrs_freq_idx
(
n
,
k_prime
,
delta
,
dmrs_Type
))
%
(
frame_parms
->
ofdm_symbol_size
))))
{
txdataF_precoding
[
ap
][((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
(
2
*
txdataF_offset
)]
=
(
Wt
[
l_prime
]
*
Wf
[
k_prime
]
*
amp
*
mod_dmrs
[
dmrs_idx
<<
1
])
>>
15
;
txdataF_precoding
[
ap
][((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
1
+
(
2
*
txdataF_offset
)]
=
(
Wt
[
l_prime
]
*
Wf
[
k_prime
]
*
amp
*
mod_dmrs
[(
dmrs_idx
<<
1
)
+
1
])
>>
15
;
#ifdef DEBUG_DLSCH_MAPPING
printf
(
"dmrs_idx %d
\t
l %d
\t
k %d
\t
k_prime %d
\t
n %d
\t
txdataF: %d %d
\n
"
,
dmrs_idx
,
l
,
k
,
k_prime
,
n
,
txdataF_precoding
[
ap
][((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
(
2
*
txdataF_offset
)],
txdataF_precoding
[
ap
][((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
1
+
(
2
*
txdataF_offset
)]);
#endif
dmrs_idx
++
;
k_prime
++
;
k_prime
&=
1
;
n
+=
(
k_prime
)
?
0
:
1
;
}
/* Map PTRS Symbol */
else
if
(
is_ptrs_re
){
txdataF_precoding
[
ap
][((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
(
2
*
txdataF_offset
)]
=
(
beta_ptrs
*
amp
*
mod_ptrs
[
ptrs_idx
<<
1
])
>>
15
;
txdataF_precoding
[
ap
][((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
1
+
(
2
*
txdataF_offset
)]
=
(
beta_ptrs
*
amp
*
mod_ptrs
[(
ptrs_idx
<<
1
)
+
1
])
>>
15
;
#ifdef DEBUG_DLSCH_MAPPING
printf
(
"ptrs_idx %d
\t
l %d
\t
k %d
\t
k_prime %d
\t
n %d
\t
txdataF: %d %d
\n
"
,
ptrs_idx
,
l
,
k
,
k_prime
,
n
,
((
int16_t
*
)
txdataF
[
ap
])[((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
(
2
*
txdataF_offset
)],
((
int16_t
*
)
txdataF
[
ap
])[((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
1
+
(
2
*
txdataF_offset
)]);
#endif
ptrs_idx
++
;
}
/* Map DATA Symbol */
else
if
(
(
!
(
dmrs_symbol_map
&
(
1
<<
l
)))
||
allowed_xlsch_re_in_dmrs_symbol
(
k
,
start_sc
,
frame_parms
->
ofdm_symbol_size
,
rel15
->
numDmrsCdmGrpsNoData
,
dmrs_Type
))
{
txdataF_precoding
[
ap
][((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
(
2
*
txdataF_offset
)]
=
(
amp
*
tx_layers
[
ap
][
m
<<
1
])
>>
15
;
txdataF_precoding
[
ap
][((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
1
+
(
2
*
txdataF_offset
)]
=
(
amp
*
tx_layers
[
ap
][(
m
<<
1
)
+
1
])
>>
15
;
#ifdef DEBUG_DLSCH_MAPPING
printf
(
"m %d
\t
l %d
\t
k %d
\t
txdataF: %d %d
\n
"
,
m
,
l
,
k
,
txdataF_precoding
[
ap
][((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
(
2
*
txdataF_offset
)],
txdataF_precoding
[
ap
][((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
1
+
(
2
*
txdataF_offset
)]);
#endif
m
++
;
}
/* mute RE */
else
{
txdataF_precoding
[
ap
][((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
(
2
*
txdataF_offset
)]
=
0
;
txdataF_precoding
[
ap
][((
l
*
frame_parms
->
ofdm_symbol_size
+
k
)
<<
1
)
+
1
+
(
2
*
txdataF_offset
)]
=
0
;
}
if
(
++
k
>=
frame_parms
->
ofdm_symbol_size
)
k
-=
frame_parms
->
ofdm_symbol_size
;
}
//RE loop
}
// symbol loop
}
// layer loop
///Layer Precoding and Antenna port mapping
// tx_layers 1-8 are mapped on antenna ports 1000-1007
// The precoding info is supported by nfapi such as num_prgs, prg_size, prgs_list and pm_idx
// The same precoding matrix is applied on prg_size RBs, Thus
// pmi = prgs_list[rbidx/prg_size].pm_idx, rbidx =0,...,rbSize-1
// The Precoding matrix:
// The Codebook Type I and Type II are not supported yet.
// We adopt the precoding matrices of PUSCH for 4 layers.
for
(
int
ap
=
0
;
ap
<
frame_parms
->
nb_antennas_tx
;
ap
++
)
{
for
(
int
l
=
rel15
->
StartSymbolIndex
;
l
<
rel15
->
StartSymbolIndex
+
rel15
->
NrOfSymbols
;
l
++
)
{
uint16_t
k
=
start_sc
;
for
(
int
rb
=
0
;
rb
<
rel15
->
rbSize
;
rb
++
)
{
//get pmi info
uint8_t
pmi
;
if
(
rel15
->
precodingAndBeamforming
.
prg_size
>
0
)
pmi
=
rel15
->
precodingAndBeamforming
.
prgs_list
[(
int
)
rb
/
rel15
->
precodingAndBeamforming
.
prg_size
].
pm_idx
;
else
pmi
=
0
;
//no precoding
if
(
pmi
==
0
)
{
//unitary Precoding
if
(
ap
<
rel15
->
nrOfLayers
)
memcpy
((
void
*
)
&
txdataF
[
ap
][
l
*
frame_parms
->
ofdm_symbol_size
+
txdataF_offset
+
k
],
(
void
*
)
&
txdataF_precoding
[
ap
][
2
*
(
l
*
frame_parms
->
ofdm_symbol_size
+
txdataF_offset
+
k
)],
NR_NB_SC_PER_RB
*
sizeof
(
int32_t
));
else
memset
((
void
*
)
&
txdataF
[
ap
][
rel15
->
StartSymbolIndex
*
frame_parms
->
ofdm_symbol_size
+
txdataF_offset
+
k
],
0
,
NR_NB_SC_PER_RB
*
sizeof
(
int32_t
));
k
+=
NR_NB_SC_PER_RB
;
if
(
k
>=
frame_parms
->
ofdm_symbol_size
)
{
k
-=
frame_parms
->
ofdm_symbol_size
;
}
}
else
{
//get the precoding matrix weights:
char
*
W_prec
;
switch
(
frame_parms
->
nb_antennas_tx
)
{
case
1
:
//1 antenna port
W_prec
=
nr_W_1l_2p
[
pmi
][
ap
];
break
;
case
2
:
//2 antenna ports
if
(
rel15
->
nrOfLayers
==
1
)
//1 layer
W_prec
=
nr_W_1l_2p
[
pmi
][
ap
];
else
//2 layers
W_prec
=
nr_W_2l_2p
[
pmi
][
ap
];
break
;
case
4
:
//4 antenna ports
if
(
rel15
->
nrOfLayers
==
1
)
//1 layer
W_prec
=
nr_W_1l_4p
[
pmi
][
ap
];
else
if
(
rel15
->
nrOfLayers
==
2
)
//2 layers
W_prec
=
nr_W_2l_4p
[
pmi
][
ap
];
else
if
(
rel15
->
nrOfLayers
==
3
)
//3 layers
W_prec
=
nr_W_3l_4p
[
pmi
][
ap
];
else
//4 layers
W_prec
=
nr_W_4l_4p
[
pmi
][
ap
];
break
;
default:
LOG_D
(
PHY
,
"Precoding 1,2, or 4 antenna ports are currently supported
\n
"
);
W_prec
=
nr_W_1l_2p
[
pmi
][
ap
];
break
;
}
for
(
int
i
=
0
;
i
<
NR_NB_SC_PER_RB
;
i
++
)
{
int32_t
re_offset
=
l
*
frame_parms
->
ofdm_symbol_size
+
k
;
int32_t
precodatatx_F
=
nr_layer_precoder
(
txdataF_precoding
,
W_prec
,
rel15
->
nrOfLayers
,
re_offset
+
txdataF_offset
);
((
int16_t
*
)
txdataF
[
ap
])[(
re_offset
<<
1
)
+
(
2
*
txdataF_offset
)]
=
((
int16_t
*
)
&
precodatatx_F
)[
0
];
((
int16_t
*
)
txdataF
[
ap
])[(
re_offset
<<
1
)
+
1
+
(
2
*
txdataF_offset
)]
=
((
int16_t
*
)
&
precodatatx_F
)[
1
];
#ifdef DEBUG_DLSCH_MAPPING
printf
(
"antenna %d
\t
l %d
\t
k %d
\t
txdataF: %d %d
\n
"
,
ap
,
l
,
k
,
((
int16_t
*
)
txdataF
[
ap
])[(
re_offset
<<
1
)
+
(
2
*
txdataF_offset
)],
((
int16_t
*
)
txdataF
[
ap
])[(
re_offset
<<
1
)
+
1
+
(
2
*
txdataF_offset
)]);
#endif
if
(
++
k
>=
frame_parms
->
ofdm_symbol_size
)
{
k
-=
frame_parms
->
ofdm_symbol_size
;
}
}
}
}
//RB loop
}
// symbol loop
}
// port loop
dlsch
->
slot_tx
[
slot
]
=
0
;
// TODO: handle precoding
// this maps the layers onto antenna ports
// handle beamforming ID
// each antenna port is assigned a beam_index
// since PHY can only handle BF on slot basis we set the whole slot
// first check if this slot has not already been allocated to another beam
if
(
gNB
->
common_vars
.
beam_id
[
0
][
slot
*
frame_parms
->
symbols_per_slot
]
==
255
)
{
for
(
int
j
=
0
;
j
<
frame_parms
->
symbols_per_slot
;
j
++
)
gNB
->
common_vars
.
beam_id
[
0
][
slot
*
frame_parms
->
symbols_per_slot
+
j
]
=
rel15
->
precodingAndBeamforming
.
prgs_list
[
0
].
dig_bf_interface_list
[
0
].
beam_idx
;
}
else
{
LOG_D
(
PHY
,
"beam index for PDSCH allocation already taken
\n
"
);
}
}
// dlsch loop
return
0
;
}
\ No newline at end of file
openair1/PHY/NR_TRANSPORT/nr_dlsch.h
View file @
ba0d2dae
...
...
@@ -102,4 +102,34 @@ void dump_pdsch_stats(PHY_VARS_gNB *gNB);
void
clear_pdsch_stats
(
PHY_VARS_gNB
*
gNB
);
int
nr_dlsch_encoding_fpga_ldpc
(
PHY_VARS_gNB
*
gNB
,
unsigned
char
*
a
,
int
frame
,
uint8_t
slot
,
NR_gNB_DLSCH_t
*
dlsch
,
NR_DL_FRAME_PARMS
*
frame_parms
,
time_stats_t
*
tinput
,
time_stats_t
*
tprep
,
time_stats_t
*
tparity
,
time_stats_t
*
toutput
,
time_stats_t
*
dlsch_rate_matching_stats
,
time_stats_t
*
dlsch_interleaving_stats
,
time_stats_t
*
dlsch_segmentation_stats
);
void
dl_find_iLS_lsIndex
(
unsigned
int
*
LDPC_lifting_size
,
uint32_t
*
iLS_out
,
uint32_t
*
lsIndex_out
);
void
nr_pdsch_codeword_scrambling_optim_fpga_ldpc
(
uint8_t
*
in
,
uint32_t
size
,
uint8_t
q
,
uint32_t
Nid
,
uint32_t
n_RNTI
,
uint32_t
*
out
);
unsigned
char
Reverse8U
(
unsigned
char
x
);
void
Byte_Reverse_11
(
unsigned
char
*
Src
,
unsigned
char
*
Dest
,
int
Length
);
uint8_t
nr_generate_pdsch_fpga_ldpc
(
PHY_VARS_gNB
*
gNB
,
int
frame
,
int
slot
);
#endif
openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
View file @
ba0d2dae
...
...
@@ -462,3 +462,197 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
return
0
;
}
//FPGA加速,删除了部分OAI中的encode函数
int
nr_dlsch_encoding_fpga_ldpc
(
PHY_VARS_gNB
*
gNB
,
unsigned
char
*
a
,
int
frame
,
uint8_t
slot
,
NR_gNB_DLSCH_t
*
dlsch
,
NR_DL_FRAME_PARMS
*
frame_parms
,
time_stats_t
*
tinput
,
time_stats_t
*
tprep
,
time_stats_t
*
tparity
,
time_stats_t
*
toutput
,
time_stats_t
*
dlsch_rate_matching_stats
,
time_stats_t
*
dlsch_interleaving_stats
,
time_stats_t
*
dlsch_segmentation_stats
)
{
unsigned
int
G
;
NR_DL_gNB_HARQ_t
*
harq
=
&
dlsch
->
harq_process
;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t
*
rel15
=
&
harq
->
pdsch_pdu
.
pdsch_pdu_rel15
;
uint16_t
nb_rb
=
rel15
->
rbSize
;
uint8_t
nb_symb_sch
=
rel15
->
NrOfSymbols
;
uint32_t
A
=
0
;
uint32_t
*
Zc
=
&
dlsch
->
harq_process
.
Z
;
uint8_t
mod_order
=
rel15
->
qamModOrder
[
0
];
uint16_t
r
=
0
;
uint8_t
nb_re_dmrs
=
0
;
if
(
rel15
->
dmrsConfigType
==
NFAPI_NR_DMRS_TYPE1
)
nb_re_dmrs
=
6
*
rel15
->
numDmrsCdmGrpsNoData
;
else
nb_re_dmrs
=
4
*
rel15
->
numDmrsCdmGrpsNoData
;
uint16_t
length_dmrs
=
get_num_dmrs
(
rel15
->
dlDmrsSymbPos
);
uint16_t
R
=
rel15
->
targetCodeRate
[
0
];
float
Coderate
=
0
.
0
;
EncodeInHeadStruct
EncodeHead
;
uint8_t
*
pEnDataIn
=
NULL
;
uint8_t
*
pEnDataOut
=
NULL
;
uint32_t
iLS
=
0
;
uint32_t
lsIndex
=
0
;
uint32_t
dl_E0
=
0
,
dl_E1
=
0
;
pEnDataIn
=
a
;
pEnDataOut
=
harq
->
f
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING
,
VCD_FUNCTION_IN
);
A
=
rel15
->
TBSize
[
0
]
<<
3
;
NR_gNB_SCH_STATS_t
*
stats
=
NULL
;
int
first_free
=-
1
;
for
(
int
i
=
0
;
i
<
NUMBER_OF_NR_SCH_STATS_MAX
;
i
++
)
{
if
(
gNB
->
dlsch_stats
[
i
].
rnti
==
0
&&
first_free
==
-
1
)
{
first_free
=
i
;
stats
=&
gNB
->
dlsch_stats
[
i
];
}
if
(
gNB
->
dlsch_stats
[
i
].
rnti
==
dlsch
->
rnti
)
{
stats
=&
gNB
->
dlsch_stats
[
i
];
break
;
}
}
if
(
stats
)
{
stats
->
rnti
=
dlsch
->
rnti
;
stats
->
total_bytes_tx
+=
rel15
->
TBSize
[
0
];
stats
->
current_RI
=
rel15
->
nrOfLayers
;
stats
->
current_Qm
=
rel15
->
qamModOrder
[
0
];
}
G
=
nr_get_G
(
nb_rb
,
nb_symb_sch
,
nb_re_dmrs
,
length_dmrs
,
mod_order
,
rel15
->
nrOfLayers
);
LOG_D
(
PHY
,
"dlsch coding A %d G %d (nb_rb %d, nb_symb_sch %d, nb_re_dmrs %d, length_dmrs %d, mod_order %d)
\n
"
,
A
,
G
,
nb_rb
,
nb_symb_sch
,
nb_re_dmrs
,
length_dmrs
,
mod_order
);
if
(
A
>
3824
)
{
harq
->
B
=
A
+
24
;
}
else
{
harq
->
B
=
A
+
16
;
}
if
(
R
<
1000
)
Coderate
=
(
float
)
R
/
(
float
)
1024
;
else
// to scale for mcs 20 and 26 in table 5.1.3.1-2 which are decimal and input 2* in nr_tbs_tools
Coderate
=
(
float
)
R
/
(
float
)
2048
;
if
((
A
<=
292
)
||
((
A
<=
3824
)
&&
(
Coderate
<=
0
.
6667
))
||
Coderate
<=
0
.
25
)
harq
->
BG
=
2
;
else
harq
->
BG
=
1
;
start_meas
(
dlsch_segmentation_stats
);
nr_segmentation
(
NULL
,
NULL
,
harq
->
B
,
&
harq
->
C
,
&
harq
->
K
,
Zc
,
&
harq
->
F
,
harq
->
BG
);
stop_meas
(
dlsch_segmentation_stats
);
//FPGA加速的头部
//word 0
EncodeHead
.
pktType
=
0x12
;
EncodeHead
.
rsv0
=
0x00
;
EncodeHead
.
chkCode
=
0xFAFA
;
//word 1
EncodeHead
.
rsv1
=
0x0000
;
//word 2
EncodeHead
.
rsv2
=
0x0
;
EncodeHead
.
sectorId
=
0x0
;
//=0表示单小区
EncodeHead
.
rsv3
=
0x0
;
//word 3
EncodeHead
.
sfn
=
frame
;
EncodeHead
.
rsv4
=
0x0
;
EncodeHead
.
slotNum
=
slot
;
EncodeHead
.
subfn
=
EncodeHead
.
slotNum
/
2
;
EncodeHead
.
pduIdx
=
0x0
;
//=0表示第一个码字,总共一个码字
EncodeHead
.
rev5
=
0x0
;
//word 4
EncodeHead
.
tbSizeB
=
rel15
->
TBSize
[
0
];
EncodeHead
.
pktLen
=
32
+
((
EncodeHead
.
tbSizeB
+
32
-
1
)
/
32
)
*
32
;
//Byte,pktLen=encoder header(32byte)+ tbszie (byte),并且32Byte对齐,是32的整数倍
EncodeHead
.
rev6
=
0x0
;
EncodeHead
.
lastTb
=
0x1
;
EncodeHead
.
firstTb
=
0x1
;
//=1表示本slot只有一个TB
EncodeHead
.
rev7
=
0x0
;
EncodeHead
.
cbNum
=
harq
->
C
;
//word 5
EncodeHead
.
qm
=
rel15
->
qamModOrder
[
0
]
/
2
;
//规定是BPSK qm=0,QPSK qm=1,其他floor(调制阶数/2);OAI的Qm为2/4/6/8
EncodeHead
.
rev8
=
0x0
;
EncodeHead
.
fillbit
=
harq
->
F
;
EncodeHead
.
rev9
=
0x0
;
if
(
EncodeHead
.
cbNum
==
1
){
EncodeHead
.
kpInByte
=
((
harq
->
B
)
/
EncodeHead
.
cbNum
)
>>
3
;
}
else
{
EncodeHead
.
kpInByte
=
((
harq
->
B
+
((
EncodeHead
.
cbNum
)
*
24
))
/
EncodeHead
.
cbNum
)
>>
3
;
}
EncodeHead
.
rev10
=
0x0
;
//word 6
EncodeHead
.
gamma
=
EncodeHead
.
cbNum
-
(
G
/
(
rel15
->
nrOfLayers
*
(
2
*
EncodeHead
.
qm
)))
%
EncodeHead
.
cbNum
;
//=1表示本slot只有一个TB
EncodeHead
.
rev11
=
0x0
;
EncodeHead
.
rvIdx
=
rel15
->
rvIndex
[
0
];
EncodeHead
.
rev12
=
0x0
;
//查找iLS和lfSizeIx
dl_find_iLS_lsIndex
(
Zc
,
&
iLS
,
&
lsIndex
);
EncodeHead
.
iLs
=
iLS
;
EncodeHead
.
lfSizeIx
=
lsIndex
;
EncodeHead
.
rev13
=
0x0
;
// EncodeHead.iLs = *iLS_out;
EncodeHead
.
bg
=
harq
->
BG
-
1
;
//规定选择协议base grape1 bg=0; base grape2 bg=1;OAI的BG大了1
if
(
EncodeHead
.
bg
==
0
){
EncodeHead
.
codeRate
=
46
;
}
else
{
EncodeHead
.
codeRate
=
42
;
}
//word 7
//计算并获得e0和e1
nr_get_E0_E1
(
G
,
harq
->
C
,
mod_order
,
rel15
->
nrOfLayers
,
r
,
&
dl_E0
,
&
dl_E1
);
EncodeHead
.
e0
=
dl_E0
;
EncodeHead
.
e1
=
dl_E1
;
//调用FPGA的.so中的编码函数
encoder_load
(
&
EncodeHead
,
pEnDataIn
,
pEnDataOut
);
LOG_D
(
PHY
,
"encoder_load_OK!
\n
"
);
//LOG_M("pEnDataOut.m","pEnDataOut", pEnDataOut, G+32, 1, 9);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING
,
VCD_FUNCTION_OUT
);
return
0
;
}
void
dl_find_iLS_lsIndex
(
unsigned
int
*
LDPC_lifting_size
,
uint32_t
*
iLS_out
,
uint32_t
*
lsIndex_out
)
{
unsigned
int
Set_of_LDPC_lifting_size
[
8
][
8
]
=
{
{
2
,
4
,
8
,
16
,
32
,
64
,
128
,
256
},
{
3
,
6
,
12
,
24
,
48
,
96
,
192
,
384
},
{
5
,
10
,
20
,
40
,
80
,
160
,
320
},
{
7
,
14
,
28
,
56
,
112
,
224
},
{
9
,
18
,
36
,
72
,
144
,
288
},
{
11
,
22
,
44
,
88
,
176
,
352
},
{
13
,
26
,
52
,
104
,
208
},
{
15
,
30
,
60
,
120
,
240
}};
uint32_t
iLS
,
lsIndex
;
for
(
iLS
=
0
;
iLS
<
8
;
iLS
++
)
{
for
(
lsIndex
=
0
;
lsIndex
<
8
;
lsIndex
++
){
if
(
*
LDPC_lifting_size
==
Set_of_LDPC_lifting_size
[
iLS
][
lsIndex
]){
*
iLS_out
=
iLS
;
*
lsIndex_out
=
lsIndex
;
}
}
}
}
\ No newline at end of file
openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
View file @
ba0d2dae
...
...
@@ -815,6 +815,7 @@ uint32_t nr_ulsch_decoding_fpga_ldpc(PHY_VARS_gNB *phy_vars_gNB,
//调用FPGA的decode,并输出CRC
// clock_gettime( CLOCK_REALTIME, &decode_start );
decoder_load
(
&
DecodeHead
,
pDeDataIn
,
pDeDataOut
,
pcrc
);
LOG_D
(
PHY
,
" decoder_load_OK
\n
"
);
// clock_gettime( CLOCK_REALTIME, &decode_stop );
if
(
*
pcrc
==
1
)
{
LOG_D
(
PHY
,
"[gNB %d] ULSCH: Setting ACK for slot %d TBS %d
\n
"
,
...
...
@@ -825,6 +826,7 @@ uint32_t nr_ulsch_decoding_fpga_ldpc(PHY_VARS_gNB *phy_vars_gNB,
LOG_D
(
PHY
,
"ULSCH received ok
\n
"
);
nr_fill_indication
(
phy_vars_gNB
,
harq_process
->
frame
,
harq_process
->
slot
,
ULSCH_id
,
harq_pid
,
0
);
LOG_D
(
PHY
,
"crc = 1!
\n
"
);
}
else
{
LOG_D
(
PHY
,
"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) r %d
\n
"
,
...
...
openair1/SCHED_NR/phy_procedures_nr_gNB.c
View file @
ba0d2dae
...
...
@@ -194,6 +194,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH
,
1
);
LOG_D
(
PHY
,
"PDSCH generation started (%d) in frame %d.%d
\n
"
,
gNB
->
num_pdsch_rnti
[
slot
],
frame
,
slot
);
nr_generate_pdsch
(
gNB
,
frame
,
slot
);
// nr_generate_pdsch_fpga_ldpc(gNB,frame, slot); //上面是OAI的代码,fpga_ldpc的encode切换到该行即可
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH
,
0
);
}
...
...
@@ -699,7 +700,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
//LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX
,
1
);
nr_ulsch_procedures
(
gNB
,
frame_rx
,
slot_rx
,
ULSCH_id
,
harq_pid
);
// nr_ulsch_procedures_fpga_ldpc(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); //上面是OAI的代码,pga_ldpc的decode切换到该行即可
// nr_ulsch_procedures_fpga_ldpc(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); //上面是OAI的代码,
f
pga_ldpc的decode切换到该行即可
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX
,
0
);
break
;
}
...
...
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