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
spbro
OpenXG-RAN
Commits
d017afad
Commit
d017afad
authored
Sep 20, 2024
by
Jaroslava Fiedlerova
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/NR_UE_pusch_optimization' into integration_2024_w38b
parents
05bb40d7
321a20ea
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
477 additions
and
198 deletions
+477
-198
openair1/PHY/MODULATION/nr_modulation.c
openair1/PHY/MODULATION/nr_modulation.c
+3
-3
openair1/PHY/MODULATION/nr_modulation.h
openair1/PHY/MODULATION/nr_modulation.h
+1
-1
openair1/PHY/NR_REFSIG/ptrs_nr.c
openair1/PHY/NR_REFSIG/ptrs_nr.c
+7
-0
openair1/PHY/NR_REFSIG/ptrs_nr.h
openair1/PHY/NR_REFSIG/ptrs_nr.h
+2
-0
openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+5
-3
openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+431
-165
openair1/PHY/TOOLS/cmult_sv.c
openair1/PHY/TOOLS/cmult_sv.c
+15
-12
openair1/PHY/TOOLS/tools_defs.h
openair1/PHY/TOOLS/tools_defs.h
+3
-0
openair1/PHY/nr_phy_common/inc/nr_ue_phy_meas.h
openair1/PHY/nr_phy_common/inc/nr_ue_phy_meas.h
+3
-1
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+7
-2
openair1/SIMULATION/NR_PHY/ulsim.c
openair1/SIMULATION/NR_PHY/ulsim.c
+0
-11
No files found.
openair1/PHY/MODULATION/nr_modulation.c
View file @
d017afad
...
...
@@ -318,10 +318,10 @@ void nr_layer_mapping(int nbCodes,
}
}
void
nr_ue_layer_mapping
(
const
c16_t
*
mod_symbs
,
const
int
n_layers
,
const
int
n_symbs
,
int
sz
,
c16_t
tx_layers
[][
sz
])
void
nr_ue_layer_mapping
(
const
c16_t
*
mod_symbs
,
const
int
n_layers
,
const
int
n_symbs
,
c16_t
tx_layers
[][
n_symbs
])
{
for
(
int
i
=
0
;
i
<
n_symbs
/
n_layers
;
i
++
)
{
for
(
int
l
=
0
;
l
<
n_layers
;
l
++
)
{
for
(
int
l
=
0
;
l
<
n_layers
;
l
++
)
{
for
(
int
i
=
0
;
i
<
n_symbs
;
i
++
)
{
tx_layers
[
l
][
i
]
=
c16mulRealShift
(
mod_symbs
[
n_layers
*
i
+
l
],
AMP
,
15
);
}
}
...
...
openair1/PHY/MODULATION/nr_modulation.h
View file @
d017afad
...
...
@@ -69,7 +69,7 @@ void nr_layer_mapping(int nbCodes,
@param[in] n_symbs, number of modulated symbols
@param[out] tx_layers, modulated symbols for each layer
*/
void
nr_ue_layer_mapping
(
const
c16_t
*
mod_symbs
,
const
int
n_layers
,
const
int
n_symbs
,
int
sz
,
c16_t
tx_layers
[][
sz
]);
void
nr_ue_layer_mapping
(
const
c16_t
*
mod_symbs
,
const
int
n_layers
,
const
int
n_symbs
,
c16_t
tx_layers
[][
n_symbs
]);
/*!
\brief This function implements the OFDM front end processor on reception (FEP)
\param frame_parms Pointer to frame parameters
...
...
openair1/PHY/NR_REFSIG/ptrs_nr.c
View file @
d017afad
...
...
@@ -85,6 +85,13 @@ void set_ptrs_symb_idx(uint16_t *ptrs_symbols,
}
}
unsigned
int
get_first_ptrs_re
(
const
rnti_t
rnti
,
const
uint8_t
K_ptrs
,
const
uint16_t
nRB
,
const
uint8_t
k_RE_ref
)
{
const
uint16_t
nRB_Kptrs
=
nRB
%
K_ptrs
;
const
uint16_t
k_RB_ref
=
nRB_Kptrs
?
(
rnti
%
nRB_Kptrs
)
:
(
rnti
%
K_ptrs
);
return
(
k_RE_ref
+
k_RB_ref
*
NR_NB_SC_PER_RB
);
}
/*******************************************************************
*
* NAME : is_ptrs_subcarrier
...
...
openair1/PHY/NR_REFSIG/ptrs_nr.h
View file @
d017afad
...
...
@@ -53,6 +53,8 @@ void set_ptrs_symb_idx(uint16_t *ptrs_symbols,
uint8_t
L_ptrs
,
uint16_t
dmrs_symb_pos
);
unsigned
int
get_first_ptrs_re
(
const
rnti_t
rnti
,
const
uint8_t
K_ptrs
,
const
uint16_t
nRB
,
const
uint8_t
k_RE_ref
);
uint8_t
is_ptrs_subcarrier
(
uint16_t
k
,
uint16_t
n_rnti
,
uint8_t
K_ptrs
,
...
...
openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
View file @
d017afad
...
...
@@ -116,6 +116,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
&
harq_process
->
Z
,
&
harq_process
->
F
,
harq_process
->
BG
);
stop_meas_nr_ue_phy
(
ue
,
ULSCH_SEGMENTATION_STATS
);
impp
.
n_segments
=
harq_process
->
C
;
impp
.
K
=
harq_process
->
K
;
impp
.
Kr
=
impp
.
K
;
...
...
@@ -126,7 +127,6 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
LOG_E
(
PHY
,
"nr_segmentation.c: too many segments %d, B %d
\n
"
,
impp
.
n_segments
,
B
);
return
(
-
1
);
}
stop_meas_nr_ue_phy
(
ue
,
ULSCH_SEGMENTATION_STATS
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION
,
VCD_FUNCTION_OUT
);
#ifdef DEBUG_ULSCH_CODING
...
...
@@ -149,19 +149,22 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM
,
VCD_FUNCTION_IN
);
}
start_meas_nr_ue_phy
(
ue
,
ULSCH_LDPC_ENCODING_STATS
);
if
(
ldpc_interface_offload
.
LDPCencoder
)
{
for
(
int
j
=
0
;
j
<
impp
.
n_segments
;
j
++
)
{
impp
.
perCB
[
j
].
E_cb
=
nr_get_E
(
G
,
impp
.
n_segments
,
impp
.
Qm
,
ulsch
->
pusch_pdu
.
nrOfLayers
,
j
);
}
start_meas_nr_ue_phy
(
ue
,
ULSCH_LDPC_ENCODING_STATS
);
ldpc_interface_offload
.
LDPCencoder
(
harq_process
->
c
,
&
harq_process
->
f
,
&
impp
);
stop_meas_nr_ue_phy
(
ue
,
ULSCH_LDPC_ENCODING_STATS
);
}
else
{
if
(
ulsch
->
pusch_pdu
.
pusch_data
.
new_data_indicator
)
{
start_meas_nr_ue_phy
(
ue
,
ULSCH_LDPC_ENCODING_STATS
);
for
(
int
j
=
0
;
j
<
(
impp
.
n_segments
/
8
+
1
);
j
++
)
{
impp
.
macro_num
=
j
;
impp
.
Kr
=
impp
.
K
;
ldpc_interface
.
LDPCencoder
(
harq_process
->
c
,
harq_process
->
d
,
&
impp
);
}
stop_meas_nr_ue_phy
(
ue
,
ULSCH_LDPC_ENCODING_STATS
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM
,
VCD_FUNCTION_OUT
);
#ifdef DEBUG_ULSCH_CODING
...
...
@@ -169,7 +172,6 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
write_output
(
"ulsch_enc_output0.m"
,
"enc0"
,
&
harq_process
->
d
[
0
][
0
],
(
3
*
8
*
Kr_bytes
)
+
12
,
1
,
4
);
#endif
}
stop_meas_nr_ue_phy
(
ue
,
ULSCH_LDPC_ENCODING_STATS
);
///////////////////////////////////////////////////////////////////////////////
for
(
int
r
=
0
;
r
<
impp
.
n_segments
;
r
++
)
{
// looping over C segments
if
(
impp
.
F
>
0
)
{
...
...
openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
View file @
d017afad
...
...
@@ -85,6 +85,382 @@ void nr_pusch_codeword_scrambling(uint8_t *in, uint32_t size, uint32_t Nid, uint
nr_codeword_scrambling
(
in
,
size
,
0
,
Nid
,
n_RNTI
,
out
);
}
/*
The function pointers are set once before calling the mapping funcion for
all symbols based on different parameters. Then the mapping is done for
each symbol by calling the function pointers.
*/
static
void
(
*
map_dmrs_ptr
)(
const
unsigned
int
,
const
c16_t
*
,
c16_t
*
);
static
void
(
*
map_data_dmrs_ptr
)(
const
unsigned
int
num_cdm_no_data
,
const
c16_t
*
,
c16_t
*
);
/*
The following set of functions map dmrs and/or data REs in one RB based on
configuration of DMRS type, number of CDM groups with no data and delta.
For all other combinations of the parameters not present below is not
applicable.
*/
/*
DMRS mapping in a RB for Type 1.
Mapping as in TS 38.211 6.4.1.1.3 k = 4n + 2k^prime + delta
*/
static
void
map_dmrs_type1_cdm1_rb
(
const
unsigned
int
delta
,
const
c16_t
*
dmrs
,
c16_t
*
out
)
{
*
(
out
+
delta
)
=
*
dmrs
++
;
*
(
out
+
delta
+
2
)
=
*
dmrs
++
;
*
(
out
+
delta
+
4
)
=
*
dmrs
++
;
*
(
out
+
delta
+
6
)
=
*
dmrs
++
;
*
(
out
+
delta
+
8
)
=
*
dmrs
++
;
*
(
out
+
delta
+
10
)
=
*
dmrs
++
;
}
/*
Data in DMRS symbol for Type 1, NumCDMGroupNoData = 1 and delta 0 (antenna port 0 and 1).
There is no data in DMRS symbol for other scenarios in type 1.
*/
static
void
map_data_dmrs_type1_cdm1_rb
(
const
unsigned
int
num_cdm_no_data
,
const
c16_t
*
data
,
c16_t
*
out
)
{
*
(
out
+
1
)
=
*
data
++
;
*
(
out
+
3
)
=
*
data
++
;
*
(
out
+
5
)
=
*
data
++
;
*
(
out
+
7
)
=
*
data
++
;
*
(
out
+
9
)
=
*
data
++
;
*
(
out
+
11
)
=
*
data
++
;
}
#define NR_DMRS_TYPE2_CDM_GRP_SIZE 2
#define NR_DMRS_TYPE2_NUM_CDM_GRP 3
/*
Map DMRS for type 2
Mapping as in TS 38.211 6.4.1.1.3 k = 6n + k^prime + delta
*/
static
void
map_dmrs_type2_rb
(
const
unsigned
int
delta
,
const
c16_t
*
dmrs
,
c16_t
*
out
)
{
memcpy
(
out
+
delta
,
dmrs
,
sizeof
(
c16_t
)
*
NR_DMRS_TYPE2_CDM_GRP_SIZE
);
out
+=
(
NR_DMRS_TYPE2_CDM_GRP_SIZE
*
NR_DMRS_TYPE2_NUM_CDM_GRP
);
dmrs
+=
NR_DMRS_TYPE2_CDM_GRP_SIZE
;
memcpy
(
out
+
delta
,
dmrs
,
sizeof
(
c16_t
)
*
NR_DMRS_TYPE2_CDM_GRP_SIZE
);
}
/*
Map data for type 2 DMRS
*/
static
void
map_data_dmrs_type2_rb
(
const
unsigned
int
num_cdm_no_data
,
const
c16_t
*
data
,
c16_t
*
out
)
{
unsigned
int
offset
=
num_cdm_no_data
*
NR_DMRS_TYPE2_CDM_GRP_SIZE
;
const
unsigned
int
size
=
(
NR_DMRS_TYPE2_NUM_CDM_GRP
-
num_cdm_no_data
)
*
NR_DMRS_TYPE2_CDM_GRP_SIZE
;
memcpy
(
out
+
offset
,
data
,
sizeof
(
c16_t
)
*
size
);
offset
+=
NR_DMRS_TYPE2_CDM_GRP_SIZE
*
NR_DMRS_TYPE2_NUM_CDM_GRP
;
data
+=
size
;
memcpy
(
out
+
offset
,
data
,
sizeof
(
c16_t
)
*
size
);
}
/*
Map data and PTRS in RB
*/
static
void
map_data_ptrs
(
const
unsigned
int
ptrsIdx
,
const
c16_t
*
data
,
const
c16_t
*
ptrs
,
c16_t
*
out
)
{
memcpy
(
out
,
data
,
sizeof
(
c16_t
)
*
ptrsIdx
);
data
+=
ptrsIdx
;
*
(
out
+
ptrsIdx
)
=
*
ptrs
;
memcpy
(
out
+
ptrsIdx
+
1
,
data
,
sizeof
(
c16_t
)
*
NR_NB_SC_PER_RB
-
ptrsIdx
-
1
);
}
/*
Map data only in RB
*/
static
void
map_data_rb
(
const
c16_t
*
data
,
c16_t
*
out
)
{
memcpy
(
out
,
data
,
sizeof
(
c16_t
)
*
NR_NB_SC_PER_RB
);
}
/*
This function is used when a PRB is on both sides of DC.
The destination buffer in this case in not contiguous so REs are mapped on to a temporary buffer
so that we can reuse the existing functions. Then it is copied to the destination buffer.
*/
static
void
map_over_dc
(
const
unsigned
int
right_dc
,
const
unsigned
int
num_cdm_no_data
,
const
unsigned
int
fft_size
,
const
unsigned
int
dmrs_per_rb
,
const
unsigned
int
data_per_rb
,
const
unsigned
int
delta
,
const
unsigned
int
ptrsIdx
,
const
c16_t
**
ptrs
,
const
c16_t
**
dmrs
,
const
c16_t
**
data
,
c16_t
**
out
)
{
// if first RE is DC no need to map in this function
if
(
right_dc
==
0
)
return
;
c16_t
*
out_tmp
=
*
out
;
c16_t
tmp_out_buf
[
NR_NB_SC_PER_RB
];
const
unsigned
int
left_dc
=
NR_NB_SC_PER_RB
-
right_dc
;
/* copy out to temp buffer. incase we want to preserve the REs in the out buffer
as we call mapping of data in DMRS symbol after mapping DMRS REs
*/
memcpy
(
tmp_out_buf
,
out_tmp
,
sizeof
(
c16_t
)
*
left_dc
);
out_tmp
-=
(
fft_size
-
left_dc
);
memcpy
(
tmp_out_buf
+
left_dc
,
out_tmp
,
sizeof
(
c16_t
)
*
right_dc
);
/* map on to temp buffer */
if
(
dmrs
&&
data
)
{
map_data_dmrs_ptr
(
num_cdm_no_data
,
*
data
,
tmp_out_buf
);
*
data
+=
data_per_rb
;
}
else
if
(
dmrs
)
{
map_dmrs_ptr
(
delta
,
*
dmrs
,
tmp_out_buf
);
*
dmrs
+=
dmrs_per_rb
;
}
else
if
(
ptrs
)
{
map_data_ptrs
(
ptrsIdx
,
*
data
,
*
ptrs
,
tmp_out_buf
);
*
data
+=
(
NR_NB_SC_PER_RB
-
1
);
*
ptrs
+=
1
;
}
else
if
(
data
)
{
map_data_rb
(
*
data
,
tmp_out_buf
);
*
data
+=
NR_NB_SC_PER_RB
;
}
else
{
DevAssert
(
false
);
}
/* copy back to out buffer */
out_tmp
=
*
out
;
memcpy
(
out_tmp
,
tmp_out_buf
,
sizeof
(
c16_t
)
*
left_dc
);
out_tmp
-=
(
fft_size
-
left_dc
);
memcpy
(
out_tmp
,
tmp_out_buf
+
left_dc
,
sizeof
(
c16_t
)
*
right_dc
);
out_tmp
+=
right_dc
;
*
out
=
out_tmp
;
}
/*
Holds params needed for PUSCH resoruce mapping
*/
typedef
struct
{
rnti_t
rnti
;
unsigned
int
K_ptrs
;
unsigned
int
k_RE_ref
;
unsigned
int
first_sc_offset
;
unsigned
int
fft_size
;
unsigned
int
num_rb_max
;
unsigned
int
symbols_per_slot
;
unsigned
int
slot
;
unsigned
int
dmrs_scrambling_id
;
unsigned
int
scid
;
unsigned
int
dmrs_port
;
int
Wt
;
int
*
Wf
;
unsigned
int
dmrs_symb_pos
;
unsigned
int
ptrs_symb_pos
;
unsigned
int
pdu_bit_map
;
transformPrecoder_t
transform_precoding
;
unsigned
int
bwp_start
;
unsigned
int
start_rb
;
unsigned
int
nb_rb
;
unsigned
int
start_symbol
;
unsigned
int
num_symbols
;
pusch_dmrs_type_t
dmrs_type
;
unsigned
int
delta
;
unsigned
int
num_cdm_no_data
;
}
nr_phy_pxsch_params_t
;
/*
Map all REs in one OFDM symbol
This function operation is as follows:
mapping is done on RB basis. if RB contains DC and if DC is in middle
of the RB, then the mapping is done via map_over_dc().
*/
static
void
map_current_symbol
(
const
nr_phy_pxsch_params_t
p
,
const
bool
dmrs_symbol
,
const
bool
ptrs_symbol
,
const
c16_t
*
dmrs_seq
,
const
c16_t
*
ptrs_seq
,
const
c16_t
**
data
,
c16_t
*
out
)
{
const
unsigned
int
abs_start_rb
=
p
.
bwp_start
+
p
.
start_rb
;
const
unsigned
int
start_sc
=
(
p
.
first_sc_offset
+
abs_start_rb
*
NR_NB_SC_PER_RB
)
%
p
.
fft_size
;
const
unsigned
int
dc_rb
=
(
p
.
fft_size
-
start_sc
)
/
NR_NB_SC_PER_RB
;
const
unsigned
int
rb_over_dc
=
(
p
.
fft_size
-
start_sc
)
%
NR_NB_SC_PER_RB
;
const
unsigned
int
n_cdm
=
p
.
num_cdm_no_data
;
const
c16_t
*
data_tmp
=
*
data
;
/* If current symbol is DMRS symbol */
if
(
dmrs_symbol
)
{
const
unsigned
int
dmrs_per_rb
=
(
p
.
dmrs_type
==
pusch_dmrs_type1
)
?
6
:
4
;
const
unsigned
int
data_per_rb
=
NR_NB_SC_PER_RB
-
dmrs_per_rb
;
const
c16_t
*
p_mod_dmrs
=
dmrs_seq
+
abs_start_rb
*
dmrs_per_rb
;
c16_t
*
out_tmp
=
out
+
start_sc
;
for
(
unsigned
int
rb
=
0
;
rb
<
p
.
nb_rb
;
rb
++
)
{
if
(
rb
==
dc_rb
)
{
// map RB at DC
if
(
rb_over_dc
)
{
// if DC is in middle of RB, the following function handles it.
map_over_dc
(
rb_over_dc
,
n_cdm
,
p
.
fft_size
,
dmrs_per_rb
,
data_per_rb
,
p
.
delta
,
0
,
NULL
,
&
p_mod_dmrs
,
NULL
,
&
out_tmp
);
continue
;
}
else
{
// else just move the pointer and following function will map the rb
out_tmp
-=
p
.
fft_size
;
}
}
map_dmrs_ptr
(
p
.
delta
,
p_mod_dmrs
,
out_tmp
);
p_mod_dmrs
+=
dmrs_per_rb
;
out_tmp
+=
NR_NB_SC_PER_RB
;
}
/* if there is data in current DMRS symbol, we map it here. */
if
(
map_data_dmrs_ptr
)
{
c16_t
*
out_tmp
=
out
+
start_sc
;
for
(
unsigned
int
rb
=
0
;
rb
<
p
.
nb_rb
;
rb
++
)
{
if
(
rb
==
dc_rb
)
{
if
(
rb_over_dc
)
{
map_over_dc
(
rb_over_dc
,
n_cdm
,
p
.
fft_size
,
dmrs_per_rb
,
data_per_rb
,
p
.
delta
,
0
,
NULL
,
&
p_mod_dmrs
,
&
data_tmp
,
&
out_tmp
);
continue
;
}
else
{
out_tmp
-=
p
.
fft_size
;
}
}
map_data_dmrs_ptr
(
n_cdm
,
data_tmp
,
out_tmp
);
data_tmp
+=
data_per_rb
;
out_tmp
+=
NR_NB_SC_PER_RB
;
}
}
/* If current symbol is a PTRS symbol */
}
else
if
(
ptrs_symbol
)
{
const
unsigned
int
first_ptrs_re
=
get_first_ptrs_re
(
p
.
rnti
,
p
.
K_ptrs
,
p
.
nb_rb
,
p
.
k_RE_ref
)
+
start_sc
;
const
unsigned
int
ptrs_idx_re
=
(
start_sc
-
first_ptrs_re
)
%
NR_NB_SC_PER_RB
;
// PTRS RE index within RB
unsigned
int
non_ptrs_rb
=
(
start_sc
-
first_ptrs_re
)
/
NR_NB_SC_PER_RB
;
// number of RBs before the first PTRS RB
int
ptrs_idx_rb
=
-
non_ptrs_rb
;
// RB count to check for PTRS RB
c16_t
*
out_tmp
=
out
+
start_sc
;
const
c16_t
*
p_mod_ptrs
=
ptrs_seq
;
/* map data to RBs before the first PTRS RB or if current RB has no PTRS */
for
(
unsigned
int
rb
=
0
;
rb
<
p
.
nb_rb
;
rb
++
)
{
if
(
rb
<
non_ptrs_rb
||
ptrs_idx_rb
%
p
.
K_ptrs
)
{
if
(
rb
==
dc_rb
)
{
if
(
rb_over_dc
)
{
map_over_dc
(
rb_over_dc
,
n_cdm
,
p
.
fft_size
,
0
,
0
,
p
.
delta
,
0
,
NULL
,
NULL
,
&
data_tmp
,
&
out_tmp
);
continue
;
}
else
{
out_tmp
-=
p
.
fft_size
;
}
}
map_data_rb
(
data_tmp
,
out_tmp
);
data_tmp
+=
NR_NB_SC_PER_RB
;
out_tmp
+=
NR_NB_SC_PER_RB
;
}
else
{
if
(
rb
==
dc_rb
)
{
if
(
rb_over_dc
)
{
map_over_dc
(
rb_over_dc
,
n_cdm
,
p
.
fft_size
,
0
,
0
,
p
.
delta
,
ptrs_idx_re
,
&
p_mod_ptrs
,
NULL
,
&
data_tmp
,
&
out_tmp
);
continue
;
}
else
{
out_tmp
-=
p
.
fft_size
;
}
}
map_data_ptrs
(
ptrs_idx_re
,
data_tmp
,
p_mod_ptrs
,
out_tmp
);
p_mod_ptrs
++
;
// increament once as only one PTRS RE per RB
data_tmp
+=
(
NR_NB_SC_PER_RB
-
1
);
out_tmp
+=
NR_NB_SC_PER_RB
;
}
ptrs_idx_rb
++
;
}
}
else
{
/* only data in this symbol */
c16_t
*
out_tmp
=
out
+
start_sc
;
for
(
unsigned
int
rb
=
0
;
rb
<
p
.
nb_rb
;
rb
++
)
{
if
(
rb
==
dc_rb
)
{
if
(
rb_over_dc
)
{
map_over_dc
(
rb_over_dc
,
n_cdm
,
p
.
fft_size
,
0
,
0
,
p
.
delta
,
0
,
NULL
,
NULL
,
&
data_tmp
,
&
out_tmp
);
continue
;
}
else
{
out_tmp
-=
p
.
fft_size
;
}
}
map_data_rb
(
data_tmp
,
out_tmp
);
data_tmp
+=
NR_NB_SC_PER_RB
;
out_tmp
+=
NR_NB_SC_PER_RB
;
}
}
*
data
=
data_tmp
;
}
/*
TS 38.211 table 6.4.1.1.3-1 and 2
*/
static
void
dmrs_amp_mult
(
const
uint32_t
dmrs_port
,
const
int
Wt
,
const
int
Wf
[
2
],
const
c16_t
*
mod_dmrs
,
c16_t
*
mod_dmrs_out
,
const
uint32_t
n_dmrs
,
const
pusch_dmrs_type_t
dmrs_type
)
{
/* short array that hold amplitude for k_prime = 0 and k_prime = 1 */
int32_t
alpha_dmrs
[
2
]
__attribute
((
aligned
(
16
)));
for
(
int_fast8_t
i
=
0
;
i
<
sizeofArray
(
alpha_dmrs
);
i
++
)
{
const
int32_t
a
=
Wf
[
i
]
*
Wt
*
AMP
;
alpha_dmrs
[
i
]
=
a
;
}
/* multiply amplitude with complex DMRS vector */
for
(
int_fast16_t
i
=
0
;
i
<
n_dmrs
;
i
++
)
{
mod_dmrs_out
[
i
]
=
c16mulRealShift
(
mod_dmrs
[
i
],
alpha_dmrs
[
i
%
2
],
15
);
}
}
/*
Map ULSCH data and DMRS in all of the scheduled symbols and PRBs
*/
static
void
map_symbols
(
const
nr_phy_pxsch_params_t
p
,
const
unsigned
int
slot
,
const
c16_t
*
dmrs_seq
,
const
c16_t
*
data
,
c16_t
*
out
)
{
// asign the function pointers
if
(
p
.
dmrs_type
==
pusch_dmrs_type1
)
{
map_dmrs_ptr
=
map_dmrs_type1_cdm1_rb
;
map_data_dmrs_ptr
=
(
p
.
num_cdm_no_data
==
1
)
?
map_data_dmrs_type1_cdm1_rb
:
NULL
;
}
else
{
map_dmrs_ptr
=
map_dmrs_type2_rb
;
map_data_dmrs_ptr
=
(
p
.
num_cdm_no_data
<
3
)
?
map_data_dmrs_type2_rb
:
NULL
;
}
// for all symbols
const
unsigned
int
n_dmrs
=
(
p
.
bwp_start
+
p
.
start_rb
+
p
.
nb_rb
)
*
((
p
.
dmrs_type
==
pusch_dmrs_type1
)
?
6
:
4
);
const
c16_t
*
cur_data
=
data
;
for
(
int
l
=
p
.
start_symbol
;
l
<
p
.
start_symbol
+
p
.
num_symbols
;
l
++
)
{
const
bool
dmrs_symbol
=
is_dmrs_symbol
(
l
,
p
.
dmrs_symb_pos
);
const
bool
ptrs_symbol
=
is_ptrs_symbol
(
l
,
p
.
ptrs_symb_pos
);
c16_t
mod_dmrs_amp
[
ALNARS_16_4
(
n_dmrs
)]
__attribute
((
aligned
(
16
)));
c16_t
mod_ptrs_amp
[
ALNARS_16_4
(
p
.
nb_rb
)]
__attribute
((
aligned
(
16
)));
const
uint32_t
*
gold
=
NULL
;
if
(
dmrs_symbol
||
ptrs_symbol
)
{
gold
=
nr_gold_pusch
(
p
.
num_rb_max
,
p
.
symbols_per_slot
,
p
.
dmrs_scrambling_id
,
p
.
scid
,
slot
,
l
);
}
if
(
dmrs_symbol
)
{
c16_t
mod_dmrs
[
ALNARS_16_4
(
n_dmrs
)]
__attribute
((
aligned
(
16
)));
if
(
p
.
transform_precoding
==
transformPrecoder_disabled
)
{
nr_modulation
(
gold
,
n_dmrs
*
2
,
DMRS_MOD_ORDER
,
(
int16_t
*
)
mod_dmrs
);
dmrs_amp_mult
(
p
.
dmrs_port
,
p
.
Wt
,
p
.
Wf
,
mod_dmrs
,
mod_dmrs_amp
,
n_dmrs
,
p
.
dmrs_type
);
}
else
{
dmrs_amp_mult
(
p
.
dmrs_port
,
p
.
Wt
,
p
.
Wf
,
dmrs_seq
,
mod_dmrs_amp
,
n_dmrs
,
p
.
dmrs_type
);
}
}
else
if
((
p
.
pdu_bit_map
&
PUSCH_PDU_BITMAP_PUSCH_PTRS
)
&&
ptrs_symbol
)
{
AssertFatal
(
p
.
transform_precoding
==
transformPrecoder_disabled
,
"PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED
\n
"
);
c16_t
mod_ptrs
[
ALNARS_16_4
(
p
.
nb_rb
)]
__attribute
((
aligned
(
16
)));
nr_modulation
(
gold
,
p
.
nb_rb
,
DMRS_MOD_ORDER
,
(
int16_t
*
)
mod_ptrs
);
const
unsigned
int
beta_ptrs
=
1
;
// temp value until power control is implemented
multadd_complex_vector_real_scalar
((
int16_t
*
)
mod_ptrs
,
beta_ptrs
*
AMP
,
(
int16_t
*
)
mod_ptrs_amp
,
1
,
p
.
nb_rb
);
}
map_current_symbol
(
p
,
dmrs_symbol
,
ptrs_symbol
,
mod_dmrs_amp
,
mod_ptrs_amp
,
&
cur_data
,
// increments every symbol
out
+
l
*
p
.
fft_size
);
}
}
void
nr_ue_ulsch_procedures
(
PHY_VARS_NR_UE
*
UE
,
const
unsigned
char
harq_pid
,
const
uint32_t
frame
,
...
...
@@ -95,11 +471,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
{
LOG_D
(
PHY
,
"nr_ue_ulsch_procedures hard_id %d %d.%d
\n
"
,
harq_pid
,
frame
,
slot
);
int
Wf
[
2
],
Wt
[
2
];
int
l_prime
[
2
],
delta
;
int
l_prime
[
2
];
uint8_t
nb_dmrs_re_per_rb
;
int
i
;
int
sample_offsetF
,
N_RE_prime
;
NR_DL_FRAME_PARMS
*
frame_parms
=
&
UE
->
frame_parms
;
...
...
@@ -143,17 +516,18 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
LOG_D
(
PHY
,
"ulsch TX %x : start_rb %d nb_rb %d mod_order %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d
\n
"
,
rnti
,
start_rb
,
nb_rb
,
mod_order
,
Nl
,
pusch_pdu
->
Tpmi
,
pusch_pdu
->
bwp_start
,
start_sc
,
start_symbol
,
number_of_symbols
,
cdm_grps_no_data
,
number_dmrs_symbols
,
nb_dmrs_re_per_rb
);
// TbD num_of_mod_symbols is set but never used
N_RE_prime
=
NR_NB_SC_PER_RB
*
number_of_symbols
-
nb_dmrs_re_per_rb
*
number_dmrs_symbols
-
N_PRB_oh
;
const
uint32_t
N_RE_prime
=
NR_NB_SC_PER_RB
*
number_of_symbols
-
nb_dmrs_re_per_rb
*
number_dmrs_symbols
-
N_PRB_oh
;
harq_process_ul_ue
->
num_of_mod_symbols
=
N_RE_prime
*
nb_rb
;
/////////////////////////PTRS parameters' initialization/////////////////////////
///////////
u
int8_t
L_ptrs
,
K_ptrs
=
0
;
u
nsigned
int
K_ptrs
=
0
,
k_RE_ref
=
0
;
uint32_t
unav_res
=
0
;
if
(
pusch_pdu
->
pdu_bit_map
&
PUSCH_PDU_BITMAP_PUSCH_PTRS
)
{
K_ptrs
=
pusch_pdu
->
pusch_ptrs
.
ptrs_freq_density
;
L_ptrs
=
1
<<
pusch_pdu
->
pusch_ptrs
.
ptrs_time_density
;
k_RE_ref
=
pusch_pdu
->
pusch_ptrs
.
ptrs_ports_list
[
0
].
ptrs_re_offset
;
uint8_t
L_ptrs
=
1
<<
pusch_pdu
->
pusch_ptrs
.
ptrs_time_density
;
ulsch_ue
->
ptrs_symbols
=
0
;
...
...
@@ -197,8 +571,11 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
.
oob_event_value
=
0
};
trace_pdu
(
&
tmp
);
if
(
nr_ulsch_encoding
(
UE
,
ulsch_ue
,
frame_parms
,
harq_pid
,
tb_size
,
G
)
==
-
1
)
if
(
nr_ulsch_encoding
(
UE
,
ulsch_ue
,
frame_parms
,
harq_pid
,
tb_size
,
G
)
==
-
1
)
{
NR_UL_UE_HARQ_t
*
harq_process_ulsch
=
&
UE
->
ul_harq_processes
[
harq_pid
];
harq_process_ulsch
->
ULstatus
=
SCH_IDLE
;
return
;
}
///////////
////////////////////////////////////////////////////////////////////
...
...
@@ -236,23 +613,12 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
///////////
////////////////////////////////////////////////////////////////////////
/////////////////////////DMRS Modulation/////////////////////////
///////////
uint16_t
n_dmrs
=
(
pusch_pdu
->
bwp_start
+
start_rb
+
nb_rb
)
*
((
dmrs_type
==
pusch_dmrs_type1
)
?
6
:
4
);
c16_t
mod_dmrs
[
n_dmrs
]
__attribute
((
aligned
(
16
)));
///////////
////////////////////////////////////////////////////////////////////////
/////////////////////////ULSCH layer mapping/////////////////////////
///////////
const
int
sz
=
available_bits
/
mod_order
;
c16_t
tx_layers
[
Nl
][
sz
];
memset
(
tx_layers
,
0
,
sizeof
(
tx_layers
));
const
int
sz
=
available_bits
/
mod_order
/
Nl
;
c16_t
ulsch_mod
[
Nl
][
sz
];
nr_ue_layer_mapping
(
d_mod
,
Nl
,
available_bits
/
mod_order
,
sz
,
tx_layers
);
nr_ue_layer_mapping
(
d_mod
,
Nl
,
sz
,
ulsch_mod
);
///////////
////////////////////////////////////////////////////////////////////////
...
...
@@ -266,8 +632,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint8_t
u
=
0
,
v
=
0
;
c16_t
*
dmrs_seq
=
NULL
;
/// Transform-coded "y"-sequences (for definition see 38-211 V15.3.0 2018-09, subsection 6.3.1.4)
c16_t
y
[
max_num_re
]
__attribute__
((
aligned
(
16
)));
memset
(
y
,
0
,
sizeof
(
y
));
c16_t
ulsch_mod_tp
[
max_num_re
]
__attribute__
((
aligned
(
16
)));
memset
(
ulsch_mod_tp
,
0
,
sizeof
(
ulsch_mod_tp
));
if
(
pusch_pdu
->
transform_precoding
==
transformPrecoder_enabled
)
{
...
...
@@ -292,7 +658,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
/* In the symbol with DMRS no data would be transmitted CDM groups is 2*/
continue
;
nr_dft
(
&
y
[
y_offset
],
&
tx_layers
[
0
][
y_offset
],
nb_re_pusch
);
nr_dft
(
&
ulsch_mod_tp
[
y_offset
],
&
ulsch_mod
[
0
][
y_offset
],
nb_re_pusch
);
y_offset
=
y_offset
+
nb_re_pusch
;
...
...
@@ -310,7 +676,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
printf
(
"NR_ULSCH_UE: available_bits: %u, mod_order: %d"
,
available_bits
,
mod_order
);
for
(
int
ll
=
0
;
ll
<
(
available_bits
/
mod_order
);
ll
++
)
{
debug_symbols
[
ll
]
=
ulsch_ue
->
y
[
ll
];
debug_symbols
[
ll
]
=
ulsch_ue
->
ulsch_mod_tp
[
ll
];
}
printf
(
"NR_ULSCH_UE: numSym: %d, num_dmrs_sym: %d"
,
number_of_symbols
,
number_dmrs_symbols
);
...
...
@@ -318,8 +684,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
nr_idft
(
&
debug_symbols
[
offset
],
nb_re_pusch
);
offset
=
offset
+
nb_re_pusch
;
}
LOG_M
(
"preDFT_all_symbols.m"
,
"UE_preDFT"
,
tx_layers
[
0
],
number_of_symbols
*
nb_re_pusch
,
1
,
1
);
LOG_M
(
"postDFT_all_symbols.m"
,
"UE_postDFT"
,
y
,
number_of_symbols
*
nb_re_pusch
,
1
,
1
);
LOG_M
(
"preDFT_all_symbols.m"
,
"UE_preDFT"
,
ulsch_mod
[
0
],
number_of_symbols
*
nb_re_pusch
,
1
,
1
);
LOG_M
(
"postDFT_all_symbols.m"
,
"UE_postDFT"
,
ulsch_mod_tp
,
number_of_symbols
*
nb_re_pusch
,
1
,
1
);
LOG_M
(
"DEBUG_IDFT_SYMBOLS.m"
,
"UE_Debug_IDFT"
,
debug_symbols
,
number_of_symbols
*
nb_re_pusch
,
1
,
1
);
LOG_M
(
"UE_DMRS_SEQ.m"
,
"UE_DMRS_SEQ"
,
dmrs_seq
,
nb_re_pusch
,
1
,
1
);
#endif
...
...
@@ -334,157 +700,57 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
/////////////////////////ULSCH RE mapping/////////////////////////
///////////
const
int
encoded_length
=
frame_parms
->
N_RB_UL
*
14
*
NR_NB_SC_PER_RB
*
mod_order
*
Nl
;
c16_t
tx_precoding
[
Nl
][
encoded_length
];
const
int
slot_sz
=
frame_parms
->
ofdm_symbol_size
*
frame_parms
->
symbols_per_slot
;
c16_t
tx_precoding
[
Nl
][
slot_sz
];
memset
(
tx_precoding
,
0
,
sizeof
(
tx_precoding
));
for
(
int
nl
=
0
;
nl
<
Nl
;
nl
++
)
{
uint8_t
k_prime
=
0
;
uint16_t
m
=
0
;
for
(
int
nl
=
0
;
nl
<
Nl
;
nl
++
)
{
#ifdef DEBUG_PUSCH_MAPPING
printf
(
"NR_ULSCH_UE: Value of CELL ID %d /t, u %d
\n
"
,
frame_parms
->
Nid_cell
,
u
);
#endif
int
dmrs_port
=
get_dmrs_port
(
nl
,
pusch_pdu
->
dmrs_ports
);
// DMRS params for this dmrs port
const
uint8_t
dmrs_port
=
get_dmrs_port
(
nl
,
pusch_pdu
->
dmrs_ports
);
const
uint8_t
delta
=
get_delta
(
dmrs_port
,
dmrs_type
);
int
Wt
[
2
];
int
Wf
[
2
];
get_Wt
(
Wt
,
dmrs_port
,
dmrs_type
);
get_Wf
(
Wf
,
dmrs_port
,
dmrs_type
);
delta
=
get_delta
(
dmrs_port
,
dmrs_type
);
for
(
int
l
=
start_symbol
;
l
<
start_symbol
+
number_of_symbols
;
l
++
)
{
uint16_t
k
=
start_sc
;
uint16_t
n
=
0
;
uint8_t
is_dmrs_sym
=
0
;
uint8_t
is_ptrs_sym
=
0
;
uint16_t
dmrs_idx
=
0
,
ptrs_idx
=
0
;
c16_t
mod_ptrs
[
nb_rb
]
__attribute
((
aligned
(
16
)));
// assume maximum number of PTRS per pusch allocation
if
((
ul_dmrs_symb_pos
>>
l
)
&
0x01
)
{
is_dmrs_sym
=
1
;
if
(
pusch_pdu
->
transform_precoding
==
transformPrecoder_disabled
){
if
(
dmrs_type
==
pusch_dmrs_type1
)
dmrs_idx
=
(
pusch_pdu
->
bwp_start
+
start_rb
)
*
6
;
else
dmrs_idx
=
(
pusch_pdu
->
bwp_start
+
start_rb
)
*
4
;
// TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part
// Perform this on gold sequence, not required when SC FDMA operation is done,
LOG_D
(
PHY
,
"DMRS in symbol %d
\n
"
,
l
);
const
uint32_t
*
gold
=
nr_gold_pusch
(
frame_parms
->
N_RB_UL
,
frame_parms
->
symbols_per_slot
,
pusch_pdu
->
ul_dmrs_scrambling_id
,
pusch_pdu
->
scid
,
slot
,
l
);
nr_modulation
(
gold
,
n_dmrs
*
2
,
DMRS_MOD_ORDER
,
(
int16_t
*
)
mod_dmrs
);
// currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
}
else
{
dmrs_idx
=
0
;
}
}
else
if
(
pusch_pdu
->
pdu_bit_map
&
PUSCH_PDU_BITMAP_PUSCH_PTRS
)
{
AssertFatal
(
pusch_pdu
->
transform_precoding
==
transformPrecoder_disabled
,
"PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED
\n
"
);
if
(
is_ptrs_symbol
(
l
,
ulsch_ue
->
ptrs_symbols
))
{
is_ptrs_sym
=
1
;
const
uint32_t
*
gold
=
nr_gold_pusch
(
frame_parms
->
N_RB_UL
,
frame_parms
->
symbols_per_slot
,
pusch_pdu
->
ul_dmrs_scrambling_id
,
pusch_pdu
->
scid
,
slot
,
l
);
nr_modulation
(
gold
,
nb_rb
,
DMRS_MOD_ORDER
,
(
int16_t
*
)
mod_ptrs
);
}
}
for
(
i
=
0
;
i
<
nb_rb
*
NR_NB_SC_PER_RB
;
i
++
)
{
uint8_t
is_dmrs
=
0
;
uint8_t
is_ptrs
=
0
;
sample_offsetF
=
l
*
frame_parms
->
ofdm_symbol_size
+
k
;
if
(
is_dmrs_sym
)
{
if
(
k
==
((
start_sc
+
get_dmrs_freq_idx_ul
(
n
,
k_prime
,
delta
,
dmrs_type
))
%
frame_parms
->
ofdm_symbol_size
))
is_dmrs
=
1
;
}
else
if
(
is_ptrs_sym
)
{
is_ptrs
=
is_ptrs_subcarrier
(
k
,
rnti
,
K_ptrs
,
nb_rb
,
pusch_pdu
->
pusch_ptrs
.
ptrs_ports_list
[
0
].
ptrs_re_offset
,
start_sc
,
frame_parms
->
ofdm_symbol_size
);
}
if
(
is_dmrs
==
1
)
{
// if transform precoding is enabled
const
int
tmp
=
Wt
[
l_prime
[
0
]]
*
Wf
[
k_prime
]
*
AMP
;
if
(
pusch_pdu
->
transform_precoding
==
transformPrecoder_enabled
)
tx_precoding
[
nl
][
sample_offsetF
]
=
c16mulRealShift
(
dmrs_seq
[
dmrs_idx
],
tmp
,
15
);
else
tx_precoding
[
nl
][
sample_offsetF
]
=
c16mulRealShift
(
mod_dmrs
[
dmrs_idx
],
tmp
,
15
);
#ifdef DEBUG_PUSCH_MAPPING
printf
(
"DMRS: Layer: %d
\t
, dmrs_idx %d
\t
l %d
\t
k %d
\t
k_prime %d
\t
n %d
\t
dmrs: %d %d
\n
"
,
nl
,
dmrs_idx
,
l
,
k
,
k_prime
,
n
,
tx_precoding
[
nl
][
sample_offsetF
].
r
,
tx_precoding
[
nl
][
sample_offsetF
].
i
);
#endif
dmrs_idx
++
;
k_prime
++
;
k_prime
&=
1
;
n
+=
(
k_prime
)
?
0
:
1
;
}
else
if
(
is_ptrs
==
1
)
{
uint16_t
beta_ptrs
=
1
;
// temp value until power control is implemented
tx_precoding
[
nl
][
sample_offsetF
]
=
c16mulRealShift
(
mod_ptrs
[
ptrs_idx
],
beta_ptrs
*
AMP
,
15
);
ptrs_idx
++
;
}
else
if
(
!
is_dmrs_sym
||
allowed_xlsch_re_in_dmrs_symbol
(
k
,
start_sc
,
frame_parms
->
ofdm_symbol_size
,
cdm_grps_no_data
,
dmrs_type
))
{
if
(
pusch_pdu
->
transform_precoding
==
transformPrecoder_disabled
)
tx_precoding
[
nl
][
sample_offsetF
]
=
tx_layers
[
nl
][
m
];
else
tx_precoding
[
nl
][
sample_offsetF
]
=
y
[
m
];
#ifdef DEBUG_PUSCH_MAPPING
printf
(
"DATA: layer %d
\t
m %d
\t
l %d
\t
k %d
\t
tx_precoding: %d %d
\n
"
,
nl
,
m
,
l
,
k
,
tx_precoding
[
nl
][
sample_offsetF
].
r
,
tx_precoding
[
nl
][
sample_offsetF
].
i
);
#endif
m
++
;
}
else
{
tx_precoding
[
nl
][
sample_offsetF
]
=
(
c16_t
){
0
};
}
c16_t
*
data
=
(
pusch_pdu
->
transform_precoding
==
transformPrecoder_enabled
)
?
ulsch_mod_tp
:
ulsch_mod
[
nl
];
nr_phy_pxsch_params_t
params
=
{.
rnti
=
rnti
,
.
K_ptrs
=
K_ptrs
,
.
k_RE_ref
=
k_RE_ref
,
.
first_sc_offset
=
frame_parms
->
first_carrier_offset
,
.
fft_size
=
frame_parms
->
ofdm_symbol_size
,
.
num_rb_max
=
frame_parms
->
N_RB_UL
,
.
symbols_per_slot
=
frame_parms
->
symbols_per_slot
,
.
dmrs_scrambling_id
=
pusch_pdu
->
ul_dmrs_scrambling_id
,
.
scid
=
pusch_pdu
->
scid
,
.
dmrs_port
=
dmrs_port
,
.
Wt
=
Wt
[
l_prime
[
0
]],
.
Wf
=
Wf
,
.
dmrs_symb_pos
=
ul_dmrs_symb_pos
,
.
ptrs_symb_pos
=
ulsch_ue
->
ptrs_symbols
,
.
pdu_bit_map
=
pusch_pdu
->
pdu_bit_map
,
.
transform_precoding
=
pusch_pdu
->
transform_precoding
,
.
bwp_start
=
pusch_pdu
->
bwp_start
,
.
start_rb
=
start_rb
,
.
nb_rb
=
nb_rb
,
.
start_symbol
=
start_symbol
,
.
num_symbols
=
number_of_symbols
,
.
dmrs_type
=
dmrs_type
,
.
delta
=
delta
,
.
num_cdm_no_data
=
cdm_grps_no_data
};
map_symbols
(
params
,
slot
,
dmrs_seq
,
data
,
tx_precoding
[
nl
]);
if
(
++
k
>=
frame_parms
->
ofdm_symbol_size
)
k
-=
frame_parms
->
ofdm_symbol_size
;
}
// for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++)
}
// for (l=start_symbol; l<start_symbol+number_of_symbols; l++)
}
// for (nl=0; nl < Nl; nl++)
/////////////////////////ULSCH precoding/////////////////////////
///////////
/// Layer Precoding and Antenna port mapping
//
tx_layers
0-3 are mapped on antenna ports
//
ulsch_mod
0-3 are mapped on antenna ports
// 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
...
...
@@ -555,7 +821,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
for
(
int
i
=
0
;
i
<
NR_NB_SC_PER_RB
;
i
++
)
{
int32_t
re_offset
=
l
*
frame_parms
->
ofdm_symbol_size
+
k
;
txdataF
[
ap
][
re_offset
]
=
nr_layer_precoder
(
encoded_length
,
tx_precoding
,
W_prec
,
pusch_pdu
->
nrOfLayers
,
re_offset
);
txdataF
[
ap
][
re_offset
]
=
nr_layer_precoder
(
slot_sz
,
tx_precoding
,
W_prec
,
pusch_pdu
->
nrOfLayers
,
re_offset
);
if
(
++
k
>=
frame_parms
->
ofdm_symbol_size
)
{
k
-=
frame_parms
->
ofdm_symbol_size
;
}
...
...
openair1/PHY/TOOLS/cmult_sv.c
View file @
d017afad
...
...
@@ -30,27 +30,30 @@ void multadd_complex_vector_real_scalar(int16_t *x,
uint8_t
zero_flag
,
uint32_t
N
)
{
simd_q15_t
alpha_128
,
*
x_128
=
(
simd_q15_t
*
)
x
,
*
y_128
=
(
simd_q15_t
*
)
y
;
int
n
;
alpha_128
=
set1_int16
(
alpha
);
const
uint32_t
num_simd_adds
=
N
/
4
;
const
uint32_t
num_adds
=
N
%
4
;
if
(
zero_flag
==
1
)
for
(
n
=
0
;
n
<
N
>>
2
;
n
++
)
{
// print_shorts("x_128[n]=", &x_128[n]);
// print_shorts("alpha_128", &alpha_128);
if
(
zero_flag
==
1
)
{
for
(
n
=
0
;
n
<
num_simd_adds
;
n
++
)
{
y_128
[
n
]
=
mulhi_int16
(
x_128
[
n
],
alpha_128
);
// print_shorts("y_128[n]=", &y_128[n]);
}
else
for
(
n
=
0
;
n
<
N
>>
2
;
n
++
)
{
for
(
n
=
0
;
n
<
num_adds
;
n
++
)
{
const
uint32_t
offset
=
num_simd_adds
*
4
;
y
[
offset
+
n
]
=
(
x
[
offset
+
n
]
*
alpha
)
>>
16
;
}
}
else
{
for
(
n
=
0
;
n
<
num_simd_adds
;
n
++
)
{
y_128
[
n
]
=
adds_int16
(
y_128
[
n
],
mulhi_int16
(
x_128
[
n
],
alpha_128
));
}
simde_mm_empty
();
simde_m_empty
();
for
(
n
=
0
;
n
<
num_adds
;
n
++
)
{
const
uint32_t
offset
=
num_simd_adds
*
4
;
y
[
offset
+
n
]
+=
(
x
[
offset
+
n
]
*
alpha
)
>>
16
;
}
}
}
void
multadd_real_vector_complex_scalar
(
const
int16_t
*
x
,
const
int16_t
*
alpha
,
int16_t
*
y
,
uint32_t
N
)
...
...
openair1/PHY/TOOLS/tools_defs.h
View file @
d017afad
...
...
@@ -52,6 +52,9 @@
extern
"C"
{
#endif
#define ALIGNARRAYSIZE(a, b) (((a + b - 1) / b) * b)
#define ALNARS_16_4(a) ALIGNARRAYSIZE(a, 4)
typedef
struct
complexd
{
double
r
;
double
i
;
...
...
openair1/PHY/nr_phy_common/inc/nr_ue_phy_meas.h
View file @
d017afad
...
...
@@ -45,11 +45,13 @@
FN(PHY_RX_PDCCH_STATS),\
FN(DLSCH_PROCEDURES_STATS),\
FN(PHY_PROC_TX),\
FN(PUSCH_PROC_STATS),\
FN(ULSCH_SEGMENTATION_STATS),\
FN(ULSCH_LDPC_ENCODING_STATS),\
FN(ULSCH_RATE_MATCHING_STATS),\
FN(ULSCH_INTERLEAVING_STATS),\
FN(ULSCH_ENCODING_STATS)
FN(ULSCH_ENCODING_STATS),\
FN(OFDM_MOD_STATS)
typedef
enum
{
FOREACH_NR_PHY_CPU_MEAS
(
NOOP
),
...
...
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
View file @
d017afad
...
...
@@ -287,21 +287,26 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
start_meas_nr_ue_phy
(
ue
,
PHY_PROC_TX
);
int
harq_pid
=
phy_data
->
ulsch
.
pusch_pdu
.
pusch_data
.
harq_process_id
;
if
(
ue
->
ul_harq_processes
[
harq_pid
].
ULstatus
==
ACTIVE
)
const
int
harq_pid
=
phy_data
->
ulsch
.
pusch_pdu
.
pusch_data
.
harq_process_id
;
if
(
ue
->
ul_harq_processes
[
harq_pid
].
ULstatus
==
ACTIVE
)
{
start_meas_nr_ue_phy
(
ue
,
PUSCH_PROC_STATS
);
nr_ue_ulsch_procedures
(
ue
,
harq_pid
,
frame_tx
,
slot_tx
,
gNB_id
,
phy_data
,
(
c16_t
**
)
&
txdataF
);
stop_meas_nr_ue_phy
(
ue
,
PUSCH_PROC_STATS
);
}
ue_srs_procedures_nr
(
ue
,
proc
,
(
c16_t
**
)
&
txdataF
);
pucch_procedures_ue_nr
(
ue
,
proc
,
phy_data
,
(
c16_t
**
)
&
txdataF
);
LOG_D
(
PHY
,
"Sending Uplink data
\n
"
);
start_meas_nr_ue_phy
(
ue
,
OFDM_MOD_STATS
);
nr_ue_pusch_common_procedures
(
ue
,
proc
->
nr_slot_tx
,
&
ue
->
frame_parms
,
ue
->
frame_parms
.
nb_antennas_tx
,
(
c16_t
**
)
txdataF
,
link_type_ul
);
stop_meas_nr_ue_phy
(
ue
,
OFDM_MOD_STATS
);
nr_ue_prach_procedures
(
ue
,
proc
);
...
...
openair1/SIMULATION/NR_PHY/ulsim.c
View file @
d017afad
...
...
@@ -1421,17 +1421,6 @@ int main(int argc, char *argv[])
errors_decoding
++
;
}
}
if
(
n_trials
==
1
)
{
for
(
int
r
=
0
;
r
<
UE
->
ul_harq_processes
[
harq_pid
].
C
;
r
++
)
for
(
int
i
=
0
;
i
<
UE
->
ul_harq_processes
[
harq_pid
].
K
>>
3
;
i
++
)
{
if
((
UE
->
ul_harq_processes
[
harq_pid
].
c
[
r
][
i
]
^
ulsch_gNB
->
harq_process
->
c
[
r
][
i
])
!=
0
)
printf
(
"************"
);
/*printf("r %d: in[%d] %x, out[%d] %x (%x)\n",r,
i,UE->ul_harq_processes[harq_pid].c[r][i],
i,ulsch_gNB->harq_process->c[r][i],
UE->ul_harq_processes[harq_pid].c[r][i]^ulsch_gNB->harq_process->c[r][i]);*/
}
}
if
(
errors_decoding
>
0
&&
error_flag
==
0
)
{
n_false_positive
++
;
if
(
n_trials
==
1
)
...
...
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