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
3c1405f6
Commit
3c1405f6
authored
Jan 19, 2024
by
Jaroslava Fiedlerova
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/NR_precoding_marix_at_MAC' into integration_2024_w03
parents
4aa5f3d6
c8afb25d
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
640 additions
and
742 deletions
+640
-742
common/utils/nr/nr_common.h
common/utils/nr/nr_common.h
+2
-0
nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+44
-43
openair1/PHY/INIT/nr_init.c
openair1/PHY/INIT/nr_init.c
+3
-415
openair1/PHY/MODULATION/nr_modulation.c
openair1/PHY/MODULATION/nr_modulation.c
+53
-41
openair1/PHY/MODULATION/nr_modulation.h
openair1/PHY/MODULATION/nr_modulation.h
+5
-2
openair1/PHY/NR_TRANSPORT/nr_dlsch.c
openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+41
-47
openair1/PHY/defs_gNB.h
openair1/PHY/defs_gNB.h
+0
-7
openair1/PHY/defs_nr_common.h
openair1/PHY/defs_nr_common.h
+0
-1
openair1/SIMULATION/NR_PHY/dlsim.c
openair1/SIMULATION/NR_PHY/dlsim.c
+11
-25
openair2/LAYER2/NR_MAC_gNB/config.c
openair2/LAYER2/NR_MAC_gNB/config.c
+460
-148
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+1
-2
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+17
-10
openair2/LAYER2/NR_MAC_gNB/mac_proto.h
openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+2
-1
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+1
-0
No files found.
common/utils/nr/nr_common.h
View file @
3c1405f6
...
...
@@ -76,6 +76,8 @@ static inline const char *rnti_types(nr_rnti_type_t rr)
}
#undef R
#define NR_MAX_NB_LAYERS 4 // 8
typedef
enum
{
nr_FR1
=
0
,
nr_FR2
...
...
nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
View file @
3c1405f6
...
...
@@ -449,6 +449,26 @@ typedef struct
}
nfapi_nr_measurement_config_t
;
// Table 3–62 Precoding matrix (PM) PDU (v.222.10.04)
typedef
struct
{
int16_t
precoder_weight_Re
;
int16_t
precoder_weight_Im
;
}
nfapi_nr_pm_weights_t
;
typedef
struct
{
uint16_t
pm_idx
;
uint16_t
numLayers
;
uint16_t
num_ant_ports
;
nfapi_nr_pm_weights_t
weights
[
4
][
4
];
// TODO temporary hardcoding
}
nfapi_nr_pm_pdu_t
;
typedef
struct
{
uint16_t
num_pm_idx
;
nfapi_nr_pm_pdu_t
*
pmi_pdu
;
}
nfapi_nr_pm_list_t
;
// ERROR enums
typedef
enum
{
// Table 2-22
NFAPI_NR_PARAM_MSG_OK
=
0
,
...
...
@@ -560,6 +580,7 @@ typedef struct {
nfapi_nr_tdd_table_t
tdd_table
;
nfapi_nr_measurement_config_t
measurement_config
;
nfapi_nr_nfapi_t
nfapi_config
;
nfapi_nr_pm_list_t
pmi_list
;
}
nfapi_nr_config_request_scf_t
;
...
...
@@ -648,26 +669,6 @@ typedef struct {
}
nfapi_nr_dbt_pdu_t
;
//table 3-33
//?
typedef
struct
{
uint16_t
num_ant_ports
;
int16_t
precoder_weight_Re
;
int16_t
precoder_weight_Im
;
}
nfapi_nr_num_ant_ports_t
;
typedef
struct
{
uint16_t
numLayers
;
//0~65535
nfapi_nr_num_ant_ports_t
*
num_ant_ports_list
;
}
nfapi_nr_num_layers_t
;
typedef
struct
{
uint16_t
pm_idx
;
//0~65535
nfapi_nr_num_layers_t
*
num_layers_list
;
//0~65535
//nfapi_nr_num_ant_ports_t* num_ant_ports_list;
}
nfapi_nr_pm_pdu_t
;
// Section 3.4
// Section 3.4.1 slot indication
...
...
openair1/PHY/INIT/nr_init.c
View file @
3c1405f6
...
...
@@ -99,408 +99,6 @@ void reset_active_stats(PHY_VARS_gNB *gNB, int frame)
}
}
int
init_codebook_gNB
(
PHY_VARS_gNB
*
gNB
)
{
if
(
gNB
->
frame_parms
.
nb_antennas_tx
>
1
){
int
CSI_RS_antenna_ports
=
gNB
->
frame_parms
.
nb_antennas_tx
;
//NR Codebook Generation for codebook type1 SinglePanel
int
N1
=
gNB
->
ap_N1
;
int
N2
=
gNB
->
ap_N2
;
//Uniform Planner Array: UPA
// X X X X ... X
// X X X X ... X
// N2 . . . . ... .
// X X X X ... X
// |<-----N1---->|
int
x_polarization
=
gNB
->
ap_XP
;
//Get the uniform planar array parameters
// To be confirmed
int
O2
=
N2
>
1
?
4
:
1
;
//Vertical beam oversampling (1 or 4)
int
O1
=
CSI_RS_antenna_ports
>
2
?
4
:
1
;
//Horizontal beam oversampling (1 or 4)
AssertFatal
(
CSI_RS_antenna_ports
==
N1
*
N2
*
x_polarization
,
"Nb of antenna ports at PHY %d does not correspond to what passed down with fapi %d
\n
"
,
N1
*
N2
*
x_polarization
,
CSI_RS_antenna_ports
);
// Generation of codebook Type1 with codebookMode 1 (CSI_RS_antenna_ports < 16)
if
(
CSI_RS_antenna_ports
<
16
)
{
//Generate DFT vertical beams
//ll: index of a vertical beams vector (represented by i1_1 in TS 38.214)
double
complex
v
[
N1
*
O1
][
N1
];
for
(
int
ll
=
0
;
ll
<
N1
*
O1
;
ll
++
)
{
//i1_1
for
(
int
nn
=
0
;
nn
<
N1
;
nn
++
)
{
v
[
ll
][
nn
]
=
cexp
(
I
*
(
2
*
M_PI
*
nn
*
ll
)
/
(
N1
*
O1
));
//printf("v[%d][%d] = %f +j %f\n", ll,nn, creal(v[ll][nn]),cimag(v[ll][nn]));
}
}
//Generate DFT Horizontal beams
//mm: index of a Horizontal beams vector (represented by i1_2 in TS 38.214)
double
complex
u
[
N2
*
O2
][
N2
];
for
(
int
mm
=
0
;
mm
<
N2
*
O2
;
mm
++
)
{
//i1_2
for
(
int
nn
=
0
;
nn
<
N2
;
nn
++
)
{
u
[
mm
][
nn
]
=
cexp
(
I
*
(
2
*
M_PI
*
nn
*
mm
)
/
(
N2
*
O2
));
//printf("u[%d][%d] = %f +j %f\n", mm,nn, creal(u[mm][nn]),cimag(u[mm][nn]));
}
}
//Generate co-phasing angles
//i_2: index of a co-phasing vector
//i1_1, i1_2, and i_2 are reported from UEs
double
complex
theta_n
[
4
];
for
(
int
nn
=
0
;
nn
<
4
;
nn
++
)
{
theta_n
[
nn
]
=
cexp
(
I
*
M_PI
*
nn
/
2
);
//printf("theta_n[%d] = %f +j %f\n", nn, creal(theta_n[nn]),cimag(theta_n[nn]));
}
//Kronecker product v_lm
double
complex
v_lm
[
N1
*
O1
][
N2
*
O2
][
N2
*
N1
];
//v_ll_mm_codebook denotes the elements of a precoding matrix W_i1,1_i_1,2
for
(
int
ll
=
0
;
ll
<
N1
*
O1
;
ll
++
)
{
//i_1_1
for
(
int
mm
=
0
;
mm
<
N2
*
O2
;
mm
++
)
{
//i_1_2
for
(
int
nn1
=
0
;
nn1
<
N1
;
nn1
++
)
{
for
(
int
nn2
=
0
;
nn2
<
N2
;
nn2
++
)
{
//printf("indx %d \n",nn1*N2+nn2);
v_lm
[
ll
][
mm
][
nn1
*
N2
+
nn2
]
=
v
[
ll
][
nn1
]
*
u
[
mm
][
nn2
];
//printf("v_lm[%d][%d][%d] = %f +j %f\n",ll,mm, nn1*N2+nn2, creal(v_lm[ll][mm][nn1*N2+nn2]),cimag(v_lm[ll][mm][nn1*N2+nn2]));
}
}
}
}
int
max_mimo_layers
=
(
CSI_RS_antenna_ports
<
NR_MAX_NB_LAYERS
)
?
CSI_RS_antenna_ports
:
NR_MAX_NB_LAYERS
;
gNB
->
nr_mimo_precoding_matrix
=
(
int32_t
***
)
malloc16
(
max_mimo_layers
*
sizeof
(
int32_t
**
));
int32_t
***
mat
=
gNB
->
nr_mimo_precoding_matrix
;
double
complex
res_code
;
//Table 5.2.2.2.1-5:
//Codebook for 1-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
gNB
->
pmiq_size
[
0
]
=
N1
*
O1
*
N2
*
O2
*
4
+
1
;
mat
[
0
]
=
(
int32_t
**
)
malloc16
(
gNB
->
pmiq_size
[
0
]
*
sizeof
(
int32_t
*
));
//pmi=0 corresponds to unit matrix
mat
[
0
][
0
]
=
(
int32_t
*
)
calloc
(
2
*
N1
*
N2
,
sizeof
(
int32_t
));
for
(
int
j_col
=
0
;
j_col
<
1
;
j_col
++
)
{
//1 layer
for
(
int
i_rows
=
0
;
i_rows
<
2
*
N1
*
N2
;
i_rows
++
)
{
//2-x polarized antenna
if
(
j_col
==
i_rows
)
{
mat
[
0
][
0
][
i_rows
+
j_col
]
=
0x7fff
;
}
}
}
for
(
int
ll
=
0
;
ll
<
N1
*
O1
;
ll
++
)
{
//i_1_1
for
(
int
mm
=
0
;
mm
<
N2
*
O2
;
mm
++
)
{
//i_1_2
for
(
int
nn
=
0
;
nn
<
4
;
nn
++
)
{
int
pmiq
=
1
+
ll
*
N2
*
O2
*
4
+
mm
*
4
+
nn
;
mat
[
0
][
pmiq
]
=
(
int32_t
*
)
malloc16
((
2
*
N1
*
N2
)
*
1
*
sizeof
(
int32_t
));
LOG_D
(
PHY
,
"layer 1 Codebook pmiq = %d
\n
"
,
pmiq
);
for
(
int
len
=
0
;
len
<
N1
*
N2
;
len
++
)
{
res_code
=
sqrt
(
1
/
(
double
)
CSI_RS_antenna_ports
)
*
v_lm
[
ll
][
mm
][
len
];
if
(
creal
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
0
][
pmiq
][
len
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
0
][
pmiq
][
len
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
if
(
cimag
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
0
][
pmiq
][
len
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
0
][
pmiq
][
len
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
LOG_D
(
PHY
,
"1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
len
,
creal
(
res_code
),
cimag
(
res_code
),((
short
*
)
&
mat
[
0
][
pmiq
][
len
])[
0
],((
short
*
)
&
mat
[
0
][
pmiq
][
len
])[
1
]);
}
for
(
int
len
=
N1
*
N2
;
len
<
2
*
N1
*
N2
;
len
++
)
{
res_code
=
sqrt
(
1
/
(
double
)
CSI_RS_antenna_ports
)
*
theta_n
[
nn
]
*
v_lm
[
ll
][
mm
][
len
-
N1
*
N2
];
if
(
creal
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
0
][
pmiq
][
len
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
0
][
pmiq
][
len
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
if
(
cimag
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
0
][
pmiq
][
len
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
0
][
pmiq
][
len
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
LOG_D
(
PHY
,
"1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
len
,
creal
(
res_code
),
cimag
(
res_code
),((
short
*
)
&
mat
[
0
][
pmiq
][
len
])[
0
],((
short
*
)
&
mat
[
0
][
pmiq
][
len
])[
1
]);
}
}
}
}
int
llc
=
0
;
int
mmc
=
0
;
double
complex
phase_sign
=
0
;
//Table 5.2.2.2.1-6:
//Codebook for 2-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
//Compute the code book size for generating 2 layers out of Tx antenna ports
//pmi_size is computed as follows
gNB
->
pmiq_size
[
1
]
=
1
;
//1 for unity matrix
for
(
int
llb
=
0
;
llb
<
N1
*
O1
;
llb
++
)
{
//i_1_1
for
(
int
mmb
=
0
;
mmb
<
N2
*
O2
;
mmb
++
)
{
//i_1_2
for
(
int
ll
=
0
;
ll
<
N1
*
O1
;
ll
++
)
{
//i_1_1
for
(
int
mm
=
0
;
mm
<
N2
*
O2
;
mm
++
)
{
//i_1_2
for
(
int
nn
=
0
;
nn
<
2
;
nn
++
)
{
if
((
llb
!=
ll
)
||
(
mmb
!=
mm
)
||
((
N1
==
1
)
&&
(
N2
==
1
)))
gNB
->
pmiq_size
[
1
]
+=
1
;
}
}
}
}
}
mat
[
1
]
=
(
int32_t
**
)
malloc16
(
gNB
->
pmiq_size
[
1
]
*
sizeof
(
int32_t
*
));
//pmi=0 corresponds to unit matrix
mat
[
1
][
0
]
=
(
int32_t
*
)
calloc
((
2
*
N1
*
N2
)
*
(
2
),
sizeof
(
int32_t
));
for
(
int
j_col
=
0
;
j_col
<
2
;
j_col
++
)
{
//2 layers
for
(
int
i_rows
=
0
;
i_rows
<
2
*
N1
*
N2
;
i_rows
++
)
{
//2-x polarized antenna
if
(
j_col
==
i_rows
)
{
mat
[
1
][
0
][
i_rows
*
2
+
j_col
]
=
0x7fff
;
}
}
}
//pmi=1,...,pmi_size, we construct
int
pmiq
=
0
;
for
(
int
llb
=
0
;
llb
<
N1
*
O1
;
llb
++
)
{
//i_1_1
for
(
int
mmb
=
0
;
mmb
<
N2
*
O2
;
mmb
++
)
{
//i_1_2
for
(
int
ll
=
0
;
ll
<
N1
*
O1
;
ll
++
)
{
//i_1_1
for
(
int
mm
=
0
;
mm
<
N2
*
O2
;
mm
++
)
{
//i_1_2
for
(
int
nn
=
0
;
nn
<
2
;
nn
++
)
{
if
((
llb
!=
ll
)
||
(
mmb
!=
mm
)
||
((
N1
==
1
)
&&
(
N2
==
1
))){
pmiq
+=
1
;
mat
[
1
][
pmiq
]
=
(
int32_t
*
)
malloc16
((
2
*
N1
*
N2
)
*
(
2
)
*
sizeof
(
int32_t
));
LOG_D
(
PHY
,
"layer 2 Codebook pmiq = %d
\n
"
,
pmiq
);
for
(
int
j_col
=
0
;
j_col
<
2
;
j_col
++
)
{
if
(
j_col
==
0
)
{
llc
=
llb
;
mmc
=
mmb
;
phase_sign
=
1
;
}
if
(
j_col
==
1
)
{
llc
=
ll
;
mmc
=
mm
;
phase_sign
=
-
1
;
}
for
(
int
i_rows
=
0
;
i_rows
<
N1
*
N2
;
i_rows
++
)
{
res_code
=
sqrt
(
1
/
(
double
)(
2
*
CSI_RS_antenna_ports
))
*
v_lm
[
llc
][
mmc
][
i_rows
];
if
(
creal
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
1
][
pmiq
][
i_rows
*
2
+
j_col
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
1
][
pmiq
][
i_rows
*
2
+
j_col
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
if
(
cimag
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
1
][
pmiq
][
i_rows
*
2
+
j_col
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
1
][
pmiq
][
i_rows
*
2
+
j_col
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
LOG_D
(
PHY
,
"2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
i_rows
,
j_col
,
creal
(
res_code
),
cimag
(
res_code
),((
short
*
)
&
mat
[
1
][
pmiq
][
i_rows
*
2
+
j_col
])[
0
],((
short
*
)
&
mat
[
1
][
pmiq
][
i_rows
*
2
+
j_col
])[
1
]);
}
for
(
int
i_rows
=
N1
*
N2
;
i_rows
<
2
*
N1
*
N2
;
i_rows
++
)
{
res_code
=
sqrt
(
1
/
(
double
)(
2
*
CSI_RS_antenna_ports
))
*
(
phase_sign
)
*
theta_n
[
nn
]
*
v_lm
[
llc
][
mmc
][
i_rows
-
N1
*
N2
];
if
(
creal
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
1
][
pmiq
][
i_rows
*
2
+
j_col
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
1
][
pmiq
][
i_rows
*
2
+
j_col
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
if
(
cimag
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
1
][
pmiq
][
i_rows
*
2
+
j_col
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
1
][
pmiq
][
i_rows
*
2
+
j_col
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
LOG_D
(
PHY
,
"2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
i_rows
,
j_col
,
creal
(
res_code
),
cimag
(
res_code
),((
short
*
)
&
mat
[
1
][
pmiq
][
i_rows
*
2
+
j_col
])[
0
],((
short
*
)
&
mat
[
1
][
pmiq
][
i_rows
*
2
+
j_col
])[
1
]);
}
}
}
}
}
}
}
}
//Table 5.2.2.2.1-7:
//Codebook for 3-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
if
(
max_mimo_layers
>=
3
)
{
//pmi_size is computed as follows
gNB
->
pmiq_size
[
2
]
=
1
;
//unity matrix
for
(
int
llb
=
0
;
llb
<
N1
*
O1
;
llb
++
)
{
//i_1_1
for
(
int
mmb
=
0
;
mmb
<
N2
*
O2
;
mmb
++
)
{
//i_1_2
for
(
int
ll
=
0
;
ll
<
N1
*
O1
;
ll
++
)
{
//i_1_1
for
(
int
mm
=
0
;
mm
<
N2
*
O2
;
mm
++
)
{
//i_1_2
for
(
int
nn
=
0
;
nn
<
2
;
nn
++
)
{
if
((
llb
!=
ll
)
||
(
mmb
!=
mm
))
gNB
->
pmiq_size
[
2
]
+=
1
;
}
}
}
}
}
mat
[
2
]
=
(
int32_t
**
)
malloc16
(
gNB
->
pmiq_size
[
2
]
*
sizeof
(
int32_t
*
));
//pmi=0 corresponds to unit matrix
mat
[
2
][
0
]
=
(
int32_t
*
)
calloc
((
2
*
N1
*
N2
)
*
(
3
),
sizeof
(
int32_t
));
for
(
int
j_col
=
0
;
j_col
<
3
;
j_col
++
)
{
//3 layers
for
(
int
i_rows
=
0
;
i_rows
<
2
*
N1
*
N2
;
i_rows
++
)
{
//2-x polarized antenna
if
(
j_col
==
i_rows
)
{
mat
[
2
][
0
][
i_rows
*
3
+
j_col
]
=
0x7fff
;
}
}
}
pmiq
=
0
;
//pmi=1,...,pmi_size are computed as follows
for
(
int
llb
=
0
;
llb
<
N1
*
O1
;
llb
++
)
{
//i_1_1
for
(
int
mmb
=
0
;
mmb
<
N2
*
O2
;
mmb
++
)
{
//i_1_2
for
(
int
ll
=
0
;
ll
<
N1
*
O1
;
ll
++
)
{
//i_1_1
for
(
int
mm
=
0
;
mm
<
N2
*
O2
;
mm
++
)
{
//i_1_2
for
(
int
nn
=
0
;
nn
<
2
;
nn
++
)
{
if
((
llb
!=
ll
)
||
(
mmb
!=
mm
)){
pmiq
+=
1
;
mat
[
2
][
pmiq
]
=
(
int32_t
*
)
malloc16
((
2
*
N1
*
N2
)
*
(
3
)
*
sizeof
(
int32_t
));
LOG_D
(
PHY
,
"layer 3 Codebook pmiq = %d
\n
"
,
pmiq
);
for
(
int
j_col
=
0
;
j_col
<
3
;
j_col
++
)
{
if
(
j_col
==
0
)
{
llc
=
llb
;
mmc
=
mmb
;
phase_sign
=
1
;
}
if
(
j_col
==
1
)
{
llc
=
ll
;
mmc
=
mm
;
phase_sign
=
1
;
}
if
(
j_col
==
2
)
{
llc
=
ll
;
mmc
=
mm
;
phase_sign
=
-
1
;
}
for
(
int
i_rows
=
0
;
i_rows
<
N1
*
N2
;
i_rows
++
)
{
res_code
=
sqrt
(
1
/
(
double
)(
3
*
CSI_RS_antenna_ports
))
*
v_lm
[
llc
][
mmc
][
i_rows
];
if
(
creal
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
2
][
pmiq
][
i_rows
*
3
+
j_col
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
2
][
pmiq
][
i_rows
*
3
+
j_col
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
if
(
cimag
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
2
][
pmiq
][
i_rows
*
3
+
j_col
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
2
][
pmiq
][
i_rows
*
3
+
j_col
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
LOG_D
(
PHY
,
"3 Layer Precoding Matrix[2][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
i_rows
,
j_col
,
creal
(
res_code
),
cimag
(
res_code
),((
short
*
)
&
mat
[
2
][
pmiq
][
i_rows
*
3
+
j_col
])[
0
],((
short
*
)
&
mat
[
2
][
pmiq
][
i_rows
*
3
+
j_col
])[
1
]);
}
for
(
int
i_rows
=
N1
*
N2
;
i_rows
<
2
*
N1
*
N2
;
i_rows
++
)
{
res_code
=
sqrt
(
1
/
(
double
)(
3
*
CSI_RS_antenna_ports
))
*
(
phase_sign
)
*
theta_n
[
nn
]
*
v_lm
[
llc
][
mmc
][
i_rows
-
N1
*
N2
];
if
(
creal
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
2
][
pmiq
][
i_rows
*
3
+
j_col
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
2
][
pmiq
][
i_rows
*
3
+
j_col
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
if
(
cimag
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
2
][
pmiq
][
i_rows
*
3
+
j_col
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
2
][
pmiq
][
i_rows
*
3
+
j_col
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
LOG_D
(
PHY
,
"3 Layer Precoding Matrix[2][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
i_rows
,
j_col
,
creal
(
res_code
),
cimag
(
res_code
),((
short
*
)
&
mat
[
2
][
pmiq
][
i_rows
*
3
+
j_col
])[
0
],((
short
*
)
&
mat
[
2
][
pmiq
][
i_rows
*
3
+
j_col
])[
1
]);
}
}
}
}
}
}
}
}
}
//Table 5.2.2.2.1-8:
//Codebook for 4-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
if
(
max_mimo_layers
>=
4
)
{
//pmi_size is computed as follows
gNB
->
pmiq_size
[
3
]
=
1
;
//unity matrix
for
(
int
llb
=
0
;
llb
<
N1
*
O1
;
llb
++
)
{
//i_1_1
for
(
int
mmb
=
0
;
mmb
<
N2
*
O2
;
mmb
++
)
{
//i_1_2
for
(
int
ll
=
0
;
ll
<
N1
*
O1
;
ll
++
)
{
//i_1_1
for
(
int
mm
=
0
;
mm
<
N2
*
O2
;
mm
++
)
{
//i_1_2
for
(
int
nn
=
0
;
nn
<
2
;
nn
++
)
{
if
((
llb
!=
ll
)
||
(
mmb
!=
mm
))
gNB
->
pmiq_size
[
3
]
+=
1
;
}
}
}
}
}
mat
[
3
]
=
(
int32_t
**
)
malloc16
(
gNB
->
pmiq_size
[
3
]
*
sizeof
(
int32_t
*
));
//pmi=0 corresponds to unit matrix
mat
[
3
][
0
]
=
(
int32_t
*
)
calloc
((
2
*
N1
*
N2
)
*
(
4
),
sizeof
(
int32_t
));
for
(
int
j_col
=
0
;
j_col
<
4
;
j_col
++
)
{
//4 layers
for
(
int
i_rows
=
0
;
i_rows
<
2
*
N1
*
N2
;
i_rows
++
)
{
//2-x polarized antenna
if
(
j_col
==
i_rows
)
{
mat
[
3
][
0
][
i_rows
*
4
+
j_col
]
=
0x7fff
;
}
}
}
pmiq
=
0
;
//pmi=1,...,pmi_size are computed as follows
for
(
int
llb
=
0
;
llb
<
N1
*
O1
;
llb
++
)
{
//i_1_1
for
(
int
mmb
=
0
;
mmb
<
N2
*
O2
;
mmb
++
)
{
//i_1_2
for
(
int
ll
=
0
;
ll
<
N1
*
O1
;
ll
++
)
{
//i_1_1
for
(
int
mm
=
0
;
mm
<
N2
*
O2
;
mm
++
)
{
//i_1_2
for
(
int
nn
=
0
;
nn
<
2
;
nn
++
)
{
if
((
llb
!=
ll
)
||
(
mmb
!=
mm
)){
pmiq
+=
1
;
mat
[
3
][
pmiq
]
=
(
int32_t
*
)
malloc16
((
2
*
N1
*
N2
)
*
4
*
sizeof
(
int32_t
));
LOG_D
(
PHY
,
"layer 4 pmiq = %d
\n
"
,
pmiq
);
for
(
int
j_col
=
0
;
j_col
<
4
;
j_col
++
)
{
if
(
j_col
==
0
)
{
llc
=
llb
;
mmc
=
mmb
;
phase_sign
=
1
;
}
if
(
j_col
==
1
)
{
llc
=
ll
;
mmc
=
mm
;
phase_sign
=
1
;
}
if
(
j_col
==
2
)
{
llc
=
llb
;
mmc
=
mmb
;
phase_sign
=
-
1
;
}
if
(
j_col
==
3
)
{
llc
=
ll
;
mmc
=
mm
;
phase_sign
=
-
1
;
}
for
(
int
i_rows
=
0
;
i_rows
<
N1
*
N2
;
i_rows
++
)
{
res_code
=
sqrt
(
1
/
(
double
)(
4
*
CSI_RS_antenna_ports
))
*
v_lm
[
llc
][
mmc
][
i_rows
];
if
(
creal
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
3
][
pmiq
][
i_rows
*
4
+
j_col
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
3
][
pmiq
][
i_rows
*
4
+
j_col
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
if
(
cimag
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
3
][
pmiq
][
i_rows
*
4
+
j_col
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
3
][
pmiq
][
i_rows
*
4
+
j_col
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
LOG_D
(
PHY
,
"4 Layer Precoding Matrix[3][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
i_rows
,
j_col
,
creal
(
res_code
),
cimag
(
res_code
),((
short
*
)
&
mat
[
3
][
pmiq
][
i_rows
*
4
+
j_col
])[
0
],((
short
*
)
&
mat
[
3
][
pmiq
][
i_rows
*
4
+
j_col
])[
1
]);
}
for
(
int
i_rows
=
N1
*
N2
;
i_rows
<
2
*
N1
*
N2
;
i_rows
++
)
{
res_code
=
sqrt
(
1
/
(
double
)(
4
*
CSI_RS_antenna_ports
))
*
(
phase_sign
)
*
theta_n
[
nn
]
*
v_lm
[
llc
][
mmc
][
i_rows
-
N1
*
N2
];
if
(
creal
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
3
][
pmiq
][
i_rows
*
4
+
j_col
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
3
][
pmiq
][
i_rows
*
4
+
j_col
])[
0
]
=
(
short
)
((
creal
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
if
(
cimag
(
res_code
)
>
0
)
((
short
*
)
&
mat
[
3
][
pmiq
][
i_rows
*
4
+
j_col
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
+
0
.
5
);
//convert to Q15
else
((
short
*
)
&
mat
[
3
][
pmiq
][
i_rows
*
4
+
j_col
])[
1
]
=
(
short
)
((
cimag
(
res_code
)
*
32768
)
-
0
.
5
);
//convert to Q15
LOG_D
(
PHY
,
"4 Layer Precoding Matrix[3][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
i_rows
,
j_col
,
creal
(
res_code
),
cimag
(
res_code
),((
short
*
)
&
mat
[
3
][
pmiq
][
i_rows
*
4
+
j_col
])[
0
],((
short
*
)
&
mat
[
3
][
pmiq
][
i_rows
*
4
+
j_col
])[
1
]);
}
}
}
}
}
}
}
}
}
}
}
return
0
;
}
// A global var to reduce the changes size
ldpc_interface_t
ldpc_interface
=
{
0
},
ldpc_interface_offload
=
{
0
};
...
...
@@ -536,8 +134,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
if
(
gNB
->
ldpc_offload_flag
)
load_LDPClib
(
"_t2"
,
&
ldpc_interface_offload
);
gNB
->
max_nb_pdsch
=
MAX_MOBILES_PER_GNB
;
init_codebook_gNB
(
gNB
);
init_delay_table
(
fp
->
ofdm_symbol_size
,
MAX_DELAY_COMP
,
NR_MAX_OFDM_SYMBOL_SIZE
,
fp
->
delay_table
);
// PBCH DMRS gold sequences generation
...
...
@@ -730,18 +326,10 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
const
int
Prx
=
gNB
->
gNB_config
.
carrier_config
.
num_rx_ant
.
value
;
const
int
max_ul_mimo_layers
=
4
;
// taken from phy_init_nr_gNB()
const
int
n_buf
=
Prx
*
max_ul_mimo_layers
;
PHY_MEASUREMENTS_gNB
*
meas
=&
gNB
->
measurements
;
PHY_MEASUREMENTS_gNB
*
meas
=
&
gNB
->
measurements
;
free_and_zero
(
meas
->
n0_subband_power
);
free_and_zero
(
meas
->
n0_subband_power_dB
);
int
max_dl_mimo_layers
=
(
fp
->
nb_antennas_tx
<
NR_MAX_NB_LAYERS
)
?
fp
->
nb_antennas_tx
:
NR_MAX_NB_LAYERS
;
if
(
fp
->
nb_antennas_tx
>
1
)
{
for
(
int
nl
=
0
;
nl
<
max_dl_mimo_layers
;
nl
++
)
{
for
(
int
size
=
0
;
size
<
gNB
->
pmiq_size
[
nl
];
size
++
)
free_and_zero
(
gNB
->
nr_mimo_precoding_matrix
[
nl
][
size
]);
free_and_zero
(
gNB
->
nr_mimo_precoding_matrix
[
nl
]);
}
free_and_zero
(
gNB
->
nr_mimo_precoding_matrix
);
}
uint32_t
***
pdcch_dmrs
=
gNB
->
nr_gold_pdcch_dmrs
;
for
(
int
slot
=
0
;
slot
<
fp
->
slots_per_frame
;
slot
++
)
{
...
...
openair1/PHY/MODULATION/nr_modulation.c
View file @
3c1405f6
...
...
@@ -703,13 +703,17 @@ c16_t nr_layer_precoder_cm(int n_layers,
int
n_symbols
,
int
symSz
,
c16_t
datatx_F_precoding
[
n_layers
][
n_symbols
][
symSz
],
c16_t
*
prec_matrix
,
int
ap
,
nfapi_nr_pm_pdu_t
*
pmi_pdu
,
int
symbol
,
int
offset
)
{
c16_t
precodatatx_F
=
{
0
};
for
(
int
al
=
0
;
al
<
n_layers
;
al
++
)
precodatatx_F
=
c16maddShift
(
datatx_F_precoding
[
al
][
symbol
][
offset
],
prec_matrix
[
al
],
precodatatx_F
,
15
);
for
(
int
al
=
0
;
al
<
n_layers
;
al
++
)
{
nfapi_nr_pm_weights_t
*
w
=
&
pmi_pdu
->
weights
[
al
][
ap
];
c16_t
prec_weight
=
{.
r
=
w
->
precoder_weight_Re
,
.
i
=
w
->
precoder_weight_Im
};
precodatatx_F
=
c16maddShift
(
datatx_F_precoding
[
al
][
symbol
][
offset
],
prec_weight
,
precodatatx_F
,
15
);
}
return
precodatatx_F
;
}
...
...
@@ -717,29 +721,33 @@ void nr_layer_precoder_simd(const int n_layers,
const
int
n_symbols
,
const
int
symSz
,
const
c16_t
txdataF_res_mapped
[
n_layers
][
n_symbols
][
symSz
],
const
c16_t
prec_matrix
[
n_layers
],
const
int
ant
,
const
nfapi_nr_pm_pdu_t
*
pmi_pdu
,
const
int
symbol
,
const
int
sc_offset
,
const
int
re_cnt
,
c16_t
*
txdataF_precoded
)
{
uint32_t
sc
=
sc_offset
;
c16_t
prec_weight
=
{
0
};
// For x86, use 256 SIMD for every 8 RE and 128 SIMD for last 4 RE
// For aarch64, use 128 SIMD for every 4 RE
// 256 SIMD: Do 8 RE in one iteration, 3 iterations for 2 RB
#ifdef __AVX2__
#ifdef __AVX2__
const
uint32_t
re_cnt_align8
=
re_cnt
&
~
7
;
for
(;
sc
<
sc_offset
+
(
re_cnt_align8
);
sc
+=
sizeof
(
simde__m256i
)
/
sizeof
(
*
prec_matrix
))
{
for
(;
sc
<
sc_offset
+
(
re_cnt_align8
);
sc
+=
sizeof
(
simde__m256i
)
/
sizeof
(
prec_weight
))
{
// Matrix multiplication for 4 elements of the result (sizeof(simde__m256i) / sizeof(*prec_matrix) = 8)
simde__m256i
y
=
simde_mm256_set1_epi16
(
0
);
// Y = W[0]*X[0] + W[1]*X[1] + ... + W[nrOfLayers-1]*X[nrOfLayers-1]
for
(
int
nl
=
0
;
nl
<
n_layers
;
nl
++
){
for
(
int
nl
=
0
;
nl
<
n_layers
;
nl
++
)
{
prec_weight
.
r
=
pmi_pdu
->
weights
[
nl
][
ant
].
precoder_weight_Re
;
prec_weight
.
i
=
pmi_pdu
->
weights
[
nl
][
ant
].
precoder_weight_Im
;
const
simde__m256i
x
=
simde_mm256_loadu_epi32
(
&
txdataF_res_mapped
[
nl
][
symbol
][
sc
]);
// Rearrange precoding matrix weight to match complex multiplication and broadcast it to match SIMD size
const
simde__m256i
w_c
=
simde_mm256_set1_epi32
(
c16toI32
(
c16conj
(
prec_matrix
[
nl
]
)));
// broadcast conjugate of w
const
simde__m256i
w_s
=
simde_mm256_set1_epi32
(
c16toI32
(
c16swap
(
prec_matrix
[
nl
]
)));
// broadcast swapped real and img of w
const
simde__m256i
w_c
=
simde_mm256_set1_epi32
(
c16toI32
(
c16conj
(
prec_weight
)));
// broadcast conjugate of w
const
simde__m256i
w_s
=
simde_mm256_set1_epi32
(
c16toI32
(
c16swap
(
prec_weight
)));
// broadcast swapped real and img of w
// Multiplication and shift
const
simde__m256i
reals
=
simde_mm256_srai_epi32
(
simde_mm256_madd_epi16
(
x
,
w_c
),
15
);
// (int32_t) .r = (x.r * w.r - x.i * w.i) >> 15
...
...
@@ -754,19 +762,20 @@ void nr_layer_precoder_simd(const int n_layers,
// Store the result to txdataF
simde_mm256_storeu_si256
(
&
txdataF_precoded
[
sc
],
y
);
}
#endif
#endif
// 128 SIMD: Do 4 RE in one iteration, 3 iterations for 1 RB
const
uint32_t
re_cnt_align4
=
re_cnt
&
~
3
;
for
(;
sc
<
sc_offset
+
re_cnt_align4
;
sc
+=
sizeof
(
simde__m128i
)
/
sizeof
(
*
prec_matrix
))
{
for
(;
sc
<
sc_offset
+
re_cnt_align4
;
sc
+=
sizeof
(
simde__m128i
)
/
sizeof
(
prec_weight
))
{
#ifdef DEBUG_DLSCH_PRECODING_PRINT_WITH_TRIVIAL // Get result with trivial solution, TODO: To be removed
c16_t
y_triv
[
4
];
for
(
int
i
=
0
;
i
<
4
;
i
++
)
for
(
int
i
=
0
;
i
<
4
;
i
++
)
y_triv
[
i
]
=
nr_layer_precoder_cm
(
n_layers
,
NR_SYMBOLS_PER_SLOT
,
symSz
,
txdataF_res_mapped
,
prec_matrix
,
ant
,
pmi_pdu
,
symbol
,
sc
+
i
);
memcpy
(
&
txdataF_precoded
[
sc
],
y_triv
,
sizeof
(
y_triv
));
...
...
@@ -774,12 +783,15 @@ void nr_layer_precoder_simd(const int n_layers,
// Matrix multiplication for 4 elements of the result (sizeof(simde__m128i) / sizeof(c16_t) = 4)
simde__m128i
y
=
simde_mm_set1_epi16
(
0
);
// Y = W[0]*X[0] + W[1]*X[1] + ... + W[nrOfLayers-1]*X[nrOfLayers-1]
for
(
int
nl
=
0
;
nl
<
n_layers
;
nl
++
){
for
(
int
nl
=
0
;
nl
<
n_layers
;
nl
++
)
{
prec_weight
.
r
=
pmi_pdu
->
weights
[
nl
][
ant
].
precoder_weight_Re
;
prec_weight
.
i
=
pmi_pdu
->
weights
[
nl
][
ant
].
precoder_weight_Im
;
const
simde__m128i
x
=
simde_mm_loadu_epi32
(
&
txdataF_res_mapped
[
nl
][
symbol
][
sc
]);
// Rearrange precoding matrix weight to match complex multiplication and broadcast it to match SIMD size
const
simde__m128i
w_c
=
simde_mm_set1_epi32
(
c16toI32
(
c16conj
(
prec_
matrix
[
nl
]
)));
// broadcast conjugate of w
const
simde__m128i
w_s
=
simde_mm_set1_epi32
(
c16toI32
(
c16swap
(
prec_
matrix
[
nl
]
)));
// broadcast swapped real and img of w
const
simde__m128i
w_c
=
simde_mm_set1_epi32
(
c16toI32
(
c16conj
(
prec_
weight
)));
// broadcast conjugate of w
const
simde__m128i
w_s
=
simde_mm_set1_epi32
(
c16toI32
(
c16swap
(
prec_
weight
)));
// broadcast swapped real and img of w
// Multiplication and shift
const
simde__m128i
reals
=
simde_mm_srai_epi32
(
simde_mm_madd_epi16
(
x
,
w_c
),
15
);
// (int32_t) .r = (x.r * w.r - x.i * w.i) >> 15
...
...
openair1/PHY/MODULATION/nr_modulation.h
View file @
3c1405f6
...
...
@@ -138,11 +138,13 @@ void apply_nr_rotation_RX(NR_DL_FRAME_PARMS *frame_parms,
@param[in] n_layers, number of DLSCH layers
*/
int
nr_layer_precoder
(
int16_t
**
datatx_F_precoding
,
const
char
*
prec_matrix
,
uint8_t
n_layers
,
int32_t
re_offset
);
c16_t
nr_layer_precoder_cm
(
int
n_layers
,
int
n_symbols
,
int
symSz
,
c16_t
datatx_F_precoding
[
n_layers
][
n_symbols
][
symSz
],
c16_t
*
prec_matrix
,
int
ap
,
nfapi_nr_pm_pdu_t
*
pmi_pdu
,
int
symbol
,
int
offset
);
...
...
@@ -156,7 +158,8 @@ void nr_layer_precoder_simd(const int n_layers,
const
int
n_symbols
,
const
int
symSz
,
const
c16_t
txdataF_res_mapped
[
n_layers
][
n_symbols
][
symSz
],
const
c16_t
prec_matrix
[
n_layers
],
const
int
ant
,
const
nfapi_nr_pm_pdu_t
*
pmi_pdu
,
const
int
symbol
,
const
int
sc_offset
,
const
int
re_cnt
,
...
...
openair1/PHY/NR_TRANSPORT/nr_dlsch.c
View file @
3c1405f6
...
...
@@ -535,28 +535,22 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
}
}
else
{
// non-unitary Precoding
if
(
frame_parms
->
nb_antennas_tx
==
1
){
// no precoding matrix defined
memcpy
(
&
txdataF
[
ant
][
txdataF_offset_per_symbol
+
subCarrier
],
&
txdataF_precoding
[
ant
][
l_symbol
][
subCarrier
],
re_cnt
*
sizeof
(
**
txdataF
));
subCarrier
+=
re_cnt
;
if
(
subCarrier
>=
frame_parms
->
ofdm_symbol_size
)
{
subCarrier
-=
frame_parms
->
ofdm_symbol_size
;
}
}
else
{
// precoding with more than 1 tx
AssertFatal
(
frame_parms
->
nb_antennas_tx
>
1
,
"No precoding can be done with a single antenna port
\n
"
);
//get the precoding matrix weights:
c16_t
**
mat
=
(
c16_t
**
)
gNB
->
nr_mimo_precoding_matrix
[
rel15
->
nrOfLayers
-
1
];
//i_row =0,...,dl_antenna_port
//j_col =0,...,nrOfLayers
//mat[pmi][i_rows*2+j_col]
c16_t
*
W_prec
=
&
mat
[
pmi
][
ant
*
rel15
->
nrOfLayers
];
nfapi_nr_pm_pdu_t
*
pmi_pdu
=
&
gNB
->
gNB_config
.
pmi_list
.
pmi_pdu
[
pmi
-
1
];
// pmi 0 is identity matrix
AssertFatal
(
pmi
==
pmi_pdu
->
pm_idx
,
"PMI %d doesn't match to the one in precoding matrix %d
\n
"
,
pmi
,
pmi_pdu
->
pm_idx
);
AssertFatal
(
ant
<
pmi_pdu
->
num_ant_ports
,
"Antenna port index %d exceeds precoding matrix AP size %d
\n
"
,
ant
,
pmi_pdu
->
num_ant_ports
);
AssertFatal
(
rel15
->
nrOfLayers
==
pmi_pdu
->
numLayers
,
"Number of layers %d doesn't match to the one in precoding matrix %d
\n
"
,
rel15
->
nrOfLayers
,
pmi_pdu
->
numLayers
);
if
((
subCarrier
+
re_cnt
)
<
frame_parms
->
ofdm_symbol_size
){
// within ofdm_symbol_size, use SIMDe
nr_layer_precoder_simd
(
rel15
->
nrOfLayers
,
NR_SYMBOLS_PER_SLOT
,
frame_parms
->
ofdm_symbol_size
,
txdataF_precoding
,
W_prec
,
ant
,
pmi_pdu
,
l_symbol
,
subCarrier
,
re_cnt
,
...
...
@@ -570,7 +564,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
NR_SYMBOLS_PER_SLOT
,
frame_parms
->
ofdm_symbol_size
,
txdataF_precoding
,
W_prec
,
ant
,
pmi_pdu
,
l_symbol
,
subCarrier
);
#ifdef DEBUG_DLSCH_MAPPING
...
...
@@ -586,7 +581,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
}
}
}
// else{ // crossing ofdm_symbol_size, use simple arithmetic operations
}
// else { // precoding with more than 1 tx
}
// else { // non-unitary Precoding
rb
+=
rb_step
;
...
...
openair1/PHY/defs_gNB.h
View file @
3c1405f6
...
...
@@ -619,13 +619,6 @@ typedef struct PHY_VARS_gNB_s {
/// PDSCH DMRS sequence
uint32_t
****
nr_gold_pdsch_dmrs
;
/// PDSCH codebook I precoding LUTs
/// first dimension: Rank number [0,...,noOfLayers-1[
/// second dimension: PMI [0,...,CodeSize-1[
/// third dimension: [i_rows*noOfLayers+j_col], i_rows=0,...pdsch_AntennaPorts-1 and j_col=0,...,noOfLayers-1
int32_t
***
nr_mimo_precoding_matrix
;
int
pmiq_size
[
NR_MAX_NB_LAYERS
];
/// PUSCH DMRS
uint32_t
****
nr_gold_pusch_dmrs
;
...
...
openair1/PHY/defs_nr_common.h
View file @
3c1405f6
...
...
@@ -79,7 +79,6 @@
#define NR_MAX_PDCCH_AGG_LEVEL 16 // 3GPP TS 38.211 V15.8 Section 7.3.2 Table 7.3.2.1-1: Supported PDCCH aggregation levels
#define NR_MAX_NB_LAYERS 4 // 8
#define NR_MAX_NB_PORTS 32
#define NR_MAX_PDSCH_TBS 3824
...
...
openair1/SIMULATION/NR_PHY/dlsim.c
View file @
3c1405f6
...
...
@@ -223,35 +223,21 @@ nrUE_params_t *get_nrUE_params(void) {
}
void
validate_input_pmi
(
nr_pdsch_AntennaPorts_t
pdsch_AntennaPorts
,
int
nrOfLayers
,
int
pmi
)
void
validate_input_pmi
(
nfapi_nr_config_request_scf_t
*
gNB_config
,
nr_pdsch_AntennaPorts_t
pdsch_AntennaPorts
,
int
nrOfLayers
,
int
pmi
)
{
if
(
pmi
==
0
)
return
;
nfapi_nr_pm_pdu_t
*
pmi_pdu
=
&
gNB_config
->
pmi_list
.
pmi_pdu
[
pmi
-
1
];
// pmi 0 is identity matrix
AssertFatal
(
pmi
==
pmi_pdu
->
pm_idx
,
"PMI %d doesn't match to the one in precoding matrix %d
\n
"
,
pmi
,
pmi_pdu
->
pm_idx
);
AssertFatal
(
nrOfLayers
==
pmi_pdu
->
numLayers
,
"Number of layers %d doesn't match to the one in precoding matrix %d for PMI %d
\n
"
,
nrOfLayers
,
pmi_pdu
->
numLayers
,
pmi
);
int
num_antenna_ports
=
pdsch_AntennaPorts
.
N1
*
pdsch_AntennaPorts
.
N2
*
pdsch_AntennaPorts
.
XP
;
int
N1
=
pdsch_AntennaPorts
.
N1
;
int
N2
=
pdsch_AntennaPorts
.
N2
;
int
O1
=
N1
>
1
?
4
:
1
;
int
O2
=
N2
>
1
?
4
:
1
;
int
K1
,
K2
;
if
(
num_antenna_ports
>
2
)
get_K1_K2
(
N1
,
N2
,
&
K1
,
&
K2
);
else
{
K1
=
1
;
K2
=
1
;
}
int
num_pmi
=
1
;
// pmi = 0 is the identity matrix
switch
(
nrOfLayers
)
{
case
1
:
num_pmi
+=
N1
*
O1
*
N2
*
O2
*
4
;
AssertFatal
(
pmi
<
num_pmi
,
"Input PMI index %d exceeds the limit of configured matrices %d for %d layers
\n
"
,
pmi
,
num_pmi
,
nrOfLayers
);
return
;
case
2
:
num_pmi
+=
N1
*
O1
*
N2
*
O2
*
K1
*
K2
*
2
;
AssertFatal
(
pmi
<
num_pmi
,
"Input PMI index %d exceeds the limit of conigured matrices %d for %d layers
\n
"
,
pmi
,
num_pmi
,
nrOfLayers
);
break
;
default
:
AssertFatal
(
false
,
"Precoding with more than 2 nrOfLayers not yet supported
\n
"
);
}
AssertFatal
(
num_antenna_ports
==
pmi_pdu
->
num_ant_ports
,
"Configured antenna ports %d does not match precoding matrix AP size %d for PMI %d
\n
"
,
num_antenna_ports
,
pmi_pdu
->
num_ant_ports
,
pmi
);
}
...
...
@@ -709,7 +695,7 @@ int main(int argc, char **argv)
gNB
->
ap_N2
=
pdsch_AntennaPorts
.
N2
;
gNB
->
ap_XP
=
pdsch_AntennaPorts
.
XP
;
validate_input_pmi
(
pdsch_AntennaPorts
,
g_nrOfLayers
,
g_pmi
);
validate_input_pmi
(
&
gNB_mac
->
config
[
0
],
pdsch_AntennaPorts
,
g_nrOfLayers
,
g_pmi
);
NR_UE_NR_Capability_t
*
UE_Capability_nr
=
CALLOC
(
1
,
sizeof
(
NR_UE_NR_Capability_t
));
prepare_sim_uecap
(
UE_Capability_nr
,
scc
,
mu
,
...
...
openair2/LAYER2/NR_MAC_gNB/config.c
View file @
3c1405f6
...
...
@@ -50,11 +50,319 @@
#include "../../../../nfapi/oai_integration/vendor_ext.h"
/* Softmodem params */
#include "executables/softmodem-common.h"
#include <complex.h>
extern
RAN_CONTEXT_t
RC
;
//extern int l2_init_gNB(void);
extern
uint8_t
nfapi_mode
;
c16_t
convert_precoder_weight
(
double
complex
c_in
)
{
double
cr
=
creal
(
c_in
)
*
32768
+
0
.
5
;
if
(
cr
<
0
)
cr
-=
1
;
double
ci
=
cimag
(
c_in
)
*
32768
+
0
.
5
;
if
(
ci
<
0
)
ci
-=
1
;
return
(
c16_t
)
{.
r
=
(
short
)
cr
,
.
i
=
(
short
)
ci
};
}
nfapi_nr_pm_list_t
init_DL_MIMO_codebook
(
gNB_MAC_INST
*
gNB
,
nr_pdsch_AntennaPorts_t
antenna_ports
)
{
int
num_antenna_ports
=
antenna_ports
.
N1
*
antenna_ports
.
N2
*
antenna_ports
.
XP
;
if
(
num_antenna_ports
<
2
)
return
(
nfapi_nr_pm_list_t
)
{
0
};
//NR Codebook Generation for codebook type1 SinglePanel
int
N1
=
antenna_ports
.
N1
;
int
N2
=
antenna_ports
.
N2
;
//Uniform Planner Array: UPA
// X X X X ... X
// X X X X ... X
// N2 . . . . ... .
// X X X X ... X
// |<-----N1---->|
//Get the uniform planar array parameters
// To be confirmed
int
O2
=
N2
>
1
?
4
:
1
;
//Vertical beam oversampling (1 or 4)
int
O1
=
num_antenna_ports
>
2
?
4
:
1
;
//Horizontal beam oversampling (1 or 4)
int
K1
,
K2
;
get_K1_K2
(
N1
,
N2
,
&
K1
,
&
K2
);
int
max_mimo_layers
=
(
num_antenna_ports
<
NR_MAX_NB_LAYERS
)
?
num_antenna_ports
:
NR_MAX_NB_LAYERS
;
AssertFatal
(
max_mimo_layers
<=
4
,
"Max number of layers supported is 4
\n
"
);
gNB
->
precoding_matrix_size
[
0
]
=
N1
*
O1
*
N2
*
O2
*
4
;
nfapi_nr_pm_list_t
mat
=
{.
num_pm_idx
=
gNB
->
precoding_matrix_size
[
0
]};
for
(
int
i
=
1
;
i
<
max_mimo_layers
;
i
++
)
{
gNB
->
precoding_matrix_size
[
i
]
=
2
*
N1
*
O1
*
N2
*
O2
*
K1
*
K2
;
mat
.
num_pm_idx
+=
gNB
->
precoding_matrix_size
[
i
];
}
nfapi_nr_pm_pdu_t
*
pmi_pdu
=
malloc16
(
mat
.
num_pm_idx
*
sizeof
(
*
pmi_pdu
));
AssertFatal
(
pmi_pdu
!=
NULL
,
"out of memory
\n
"
);
mat
.
pmi_pdu
=
pmi_pdu
;
// Generation of codebook Type1 with codebookMode 1 (num_antenna_ports < 16)
if
(
num_antenna_ports
<
16
)
{
//Generate DFT vertical beams
//ll: index of a vertical beams vector (represented by i1_1 in TS 38.214)
const
int
max_l
=
N1
*
O1
+
(
K1
-
1
)
*
O1
;
double
complex
v
[
max_l
][
N1
];
for
(
int
ll
=
0
;
ll
<
max_l
;
ll
++
)
{
//i1_1
for
(
int
nn
=
0
;
nn
<
N1
;
nn
++
)
{
v
[
ll
][
nn
]
=
cexp
(
I
*
(
2
*
M_PI
*
nn
*
ll
)
/
(
N1
*
O1
));
LOG_D
(
PHY
,
"v[%d][%d] = %f +j %f
\n
"
,
ll
,
nn
,
creal
(
v
[
ll
][
nn
]),
cimag
(
v
[
ll
][
nn
]));
}
}
//Generate DFT Horizontal beams
//mm: index of a Horizontal beams vector (represented by i1_2 in TS 38.214)
const
int
max_m
=
N2
*
O2
+
(
K2
-
1
)
*
O2
;
double
complex
u
[
max_m
][
N2
];
for
(
int
mm
=
0
;
mm
<
max_m
;
mm
++
)
{
//i1_2
for
(
int
nn
=
0
;
nn
<
N2
;
nn
++
)
{
u
[
mm
][
nn
]
=
cexp
(
I
*
(
2
*
M_PI
*
nn
*
mm
)
/
(
N2
*
O2
));
LOG_D
(
PHY
,
"u[%d][%d] = %f +j %f
\n
"
,
mm
,
nn
,
creal
(
u
[
mm
][
nn
]),
cimag
(
u
[
mm
][
nn
]));
}
}
//Generate co-phasing angles
//i_2: index of a co-phasing vector
//i1_1, i1_2, and i_2 are reported from UEs
double
complex
theta_n
[
4
];
for
(
int
nn
=
0
;
nn
<
4
;
nn
++
)
{
theta_n
[
nn
]
=
cexp
(
I
*
M_PI
*
nn
/
2
);
LOG_D
(
PHY
,
"theta_n[%d] = %f +j %f
\n
"
,
nn
,
creal
(
theta_n
[
nn
]),
cimag
(
theta_n
[
nn
]));
}
//Kronecker product v_lm
double
complex
v_lm
[
max_l
][
max_m
][
N2
*
N1
];
//v_ll_mm_codebook denotes the elements of a precoding matrix W_i1,1_i_1,2
for
(
int
ll
=
0
;
ll
<
max_l
;
ll
++
)
{
//i_1_1
for
(
int
mm
=
0
;
mm
<
max_m
;
mm
++
)
{
//i_1_2
for
(
int
nn1
=
0
;
nn1
<
N1
;
nn1
++
)
{
for
(
int
nn2
=
0
;
nn2
<
N2
;
nn2
++
)
{
v_lm
[
ll
][
mm
][
nn1
*
N2
+
nn2
]
=
v
[
ll
][
nn1
]
*
u
[
mm
][
nn2
];
LOG_D
(
PHY
,
"v_lm[%d][%d][%d] = %f +j %f
\n
"
,
ll
,
mm
,
nn1
*
N2
+
nn2
,
creal
(
v_lm
[
ll
][
mm
][
nn1
*
N2
+
nn2
]),
cimag
(
v_lm
[
ll
][
mm
][
nn1
*
N2
+
nn2
]));
}
}
}
}
double
complex
res_code
;
//Table 5.2.2.2.1-5:
int
pmiq
=
0
;
//Codebook for 1-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
for
(
int
ll
=
0
;
ll
<
N1
*
O1
;
ll
++
)
{
//i_1_1
for
(
int
mm
=
0
;
mm
<
N2
*
O2
;
mm
++
)
{
//i_1_2
for
(
int
nn
=
0
;
nn
<
4
;
nn
++
)
{
pmiq
=
ll
*
N2
*
O2
*
4
+
mm
*
4
+
nn
;
pmi_pdu
[
pmiq
].
pm_idx
=
pmiq
+
1
;
// index 0 is the identity matrix
pmi_pdu
[
pmiq
].
numLayers
=
1
;
pmi_pdu
[
pmiq
].
num_ant_ports
=
num_antenna_ports
;
LOG_D
(
PHY
,
"layer 1 Codebook pmiq = %d
\n
"
,
pmiq
);
for
(
int
len
=
0
;
len
<
N1
*
N2
;
len
++
)
{
nfapi_nr_pm_weights_t
*
weights
=
&
pmi_pdu
[
pmiq
].
weights
[
0
][
len
];
res_code
=
sqrt
(
1
/
(
double
)
num_antenna_ports
)
*
v_lm
[
ll
][
mm
][
len
];
c16_t
precoder_weight
=
convert_precoder_weight
(
res_code
);
weights
->
precoder_weight_Re
=
precoder_weight
.
r
;
weights
->
precoder_weight_Im
=
precoder_weight
.
i
;
LOG_D
(
PHY
,
"1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
len
,
creal
(
res_code
),
cimag
(
res_code
),
weights
->
precoder_weight_Re
,
weights
->
precoder_weight_Im
);
}
for
(
int
len
=
N1
*
N2
;
len
<
2
*
N1
*
N2
;
len
++
)
{
nfapi_nr_pm_weights_t
*
weights
=
&
pmi_pdu
[
pmiq
].
weights
[
0
][
len
];
res_code
=
sqrt
(
1
/
(
double
)
num_antenna_ports
)
*
theta_n
[
nn
]
*
v_lm
[
ll
][
mm
][
len
-
N1
*
N2
];
c16_t
precoder_weight
=
convert_precoder_weight
(
res_code
);
weights
->
precoder_weight_Re
=
precoder_weight
.
r
;
weights
->
precoder_weight_Im
=
precoder_weight
.
i
;
LOG_D
(
PHY
,
"1 Layer Precoding Matrix[0][pmi %d][antPort %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
len
,
creal
(
res_code
),
cimag
(
res_code
),
weights
->
precoder_weight_Re
,
weights
->
precoder_weight_Im
);
}
}
}
}
int
llc
=
0
;
int
mmc
=
0
;
double
complex
phase_sign
=
0
;
//Table 5.2.2.2.1-6:
//Codebook for 2-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
//Compute the code book size for generating 2 layers out of Tx antenna ports
//pmi=1,...,pmi_size, we construct
for
(
int
ll
=
0
;
ll
<
N1
*
O1
;
ll
++
)
{
//i_1_1
for
(
int
mm
=
0
;
mm
<
N2
*
O2
;
mm
++
)
{
// i_1_2
for
(
int
k1
=
0
;
k1
<
K1
;
k1
++
)
{
for
(
int
k2
=
0
;
k2
<
K2
;
k2
++
)
{
for
(
int
nn
=
0
;
nn
<
2
;
nn
++
)
{
// i_2
pmiq
++
;
pmi_pdu
[
pmiq
].
pm_idx
=
pmiq
+
1
;
// index 0 is the identity matrix
pmi_pdu
[
pmiq
].
numLayers
=
2
;
pmi_pdu
[
pmiq
].
num_ant_ports
=
num_antenna_ports
;
LOG_D
(
PHY
,
"layer 2 Codebook pmiq = %d
\n
"
,
pmiq
);
for
(
int
j_col
=
0
;
j_col
<
2
;
j_col
++
)
{
if
(
j_col
==
0
)
{
llc
=
ll
;
mmc
=
mm
;
phase_sign
=
1
;
}
if
(
j_col
==
1
)
{
llc
=
ll
+
k1
*
O1
;
mmc
=
mm
+
k2
*
O2
;
phase_sign
=
-
1
;
}
for
(
int
i_rows
=
0
;
i_rows
<
N1
*
N2
;
i_rows
++
)
{
nfapi_nr_pm_weights_t
*
weights
=
&
pmi_pdu
[
pmiq
].
weights
[
j_col
][
i_rows
];
res_code
=
sqrt
(
1
/
(
double
)(
2
*
num_antenna_ports
))
*
v_lm
[
llc
][
mmc
][
i_rows
];
c16_t
precoder_weight
=
convert_precoder_weight
(
res_code
);
weights
->
precoder_weight_Re
=
precoder_weight
.
r
;
weights
->
precoder_weight_Im
=
precoder_weight
.
i
;
LOG_D
(
PHY
,
"2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
i_rows
,
j_col
,
creal
(
res_code
),
cimag
(
res_code
),
weights
->
precoder_weight_Re
,
weights
->
precoder_weight_Im
);
}
for
(
int
i_rows
=
N1
*
N2
;
i_rows
<
2
*
N1
*
N2
;
i_rows
++
)
{
nfapi_nr_pm_weights_t
*
weights
=
&
pmi_pdu
[
pmiq
].
weights
[
j_col
][
i_rows
];
res_code
=
sqrt
(
1
/
(
double
)(
2
*
num_antenna_ports
))
*
(
phase_sign
)
*
theta_n
[
nn
]
*
v_lm
[
llc
][
mmc
][
i_rows
-
N1
*
N2
];
c16_t
precoder_weight
=
convert_precoder_weight
(
res_code
);
weights
->
precoder_weight_Re
=
precoder_weight
.
r
;
weights
->
precoder_weight_Im
=
precoder_weight
.
i
;
LOG_D
(
PHY
,
"2 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
i_rows
,
j_col
,
creal
(
res_code
),
cimag
(
res_code
),
weights
->
precoder_weight_Re
,
weights
->
precoder_weight_Im
);
}
}
}
}
}
}
}
if
(
max_mimo_layers
<
3
)
return
mat
;
//Table 5.2.2.2.1-7:
//Codebook for 3-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
//pmi=1,...,pmi_size are computed as follows
for
(
int
ll
=
0
;
ll
<
N1
*
O1
;
ll
++
)
{
//i_1_1
for
(
int
mm
=
0
;
mm
<
N2
*
O2
;
mm
++
)
{
// i_1_2
for
(
int
k1
=
0
;
k1
<
K1
;
k1
++
)
{
for
(
int
k2
=
0
;
k2
<
K2
;
k2
++
)
{
for
(
int
nn
=
0
;
nn
<
2
;
nn
++
)
{
// i_2
pmiq
++
;
pmi_pdu
[
pmiq
].
pm_idx
=
pmiq
+
1
;
// index 0 is the identity matrix
pmi_pdu
[
pmiq
].
numLayers
=
3
;
pmi_pdu
[
pmiq
].
num_ant_ports
=
num_antenna_ports
;
LOG_D
(
PHY
,
"layer 3 Codebook pmiq = %d
\n
"
,
pmiq
);
for
(
int
j_col
=
0
;
j_col
<
3
;
j_col
++
)
{
if
(
j_col
==
0
)
{
llc
=
ll
;
mmc
=
mm
;
phase_sign
=
1
;
}
if
(
j_col
==
1
)
{
llc
=
ll
+
k1
*
O1
;
mmc
=
mm
+
k2
*
O2
;
phase_sign
=
1
;
}
if
(
j_col
==
2
)
{
llc
=
ll
;
mmc
=
mm
;
phase_sign
=
-
1
;
}
for
(
int
i_rows
=
0
;
i_rows
<
N1
*
N2
;
i_rows
++
)
{
nfapi_nr_pm_weights_t
*
weights
=
&
pmi_pdu
[
pmiq
].
weights
[
j_col
][
i_rows
];
res_code
=
sqrt
(
1
/
(
double
)(
3
*
num_antenna_ports
))
*
v_lm
[
llc
][
mmc
][
i_rows
];
c16_t
precoder_weight
=
convert_precoder_weight
(
res_code
);
weights
->
precoder_weight_Re
=
precoder_weight
.
r
;
weights
->
precoder_weight_Im
=
precoder_weight
.
i
;
LOG_D
(
PHY
,
"3 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
i_rows
,
j_col
,
creal
(
res_code
),
cimag
(
res_code
),
weights
->
precoder_weight_Re
,
weights
->
precoder_weight_Im
);
}
for
(
int
i_rows
=
N1
*
N2
;
i_rows
<
2
*
N1
*
N2
;
i_rows
++
)
{
nfapi_nr_pm_weights_t
*
weights
=
&
pmi_pdu
[
pmiq
].
weights
[
j_col
][
i_rows
];
res_code
=
sqrt
(
1
/
(
double
)(
3
*
num_antenna_ports
))
*
(
phase_sign
)
*
theta_n
[
nn
]
*
v_lm
[
llc
][
mmc
][
i_rows
-
N1
*
N2
];
c16_t
precoder_weight
=
convert_precoder_weight
(
res_code
);
weights
->
precoder_weight_Re
=
precoder_weight
.
r
;
weights
->
precoder_weight_Im
=
precoder_weight
.
i
;
LOG_D
(
PHY
,
"3 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
i_rows
,
j_col
,
creal
(
res_code
),
cimag
(
res_code
),
weights
->
precoder_weight_Re
,
weights
->
precoder_weight_Im
);
}
}
}
}
}
}
}
if
(
max_mimo_layers
<
4
)
return
mat
;
//Table 5.2.2.2.1-8:
//Codebook for 4-layer CSI reporting using antenna ports 3000 to 2999+PCSI-RS
for
(
int
ll
=
0
;
ll
<
N1
*
O1
;
ll
++
)
{
//i_1_1
for
(
int
mm
=
0
;
mm
<
N2
*
O2
;
mm
++
)
{
// i_1_2
for
(
int
k1
=
0
;
k1
<
K1
;
k1
++
)
{
for
(
int
k2
=
0
;
k2
<
K2
;
k2
++
)
{
for
(
int
nn
=
0
;
nn
<
2
;
nn
++
)
{
// i_2
pmiq
++
;
pmi_pdu
[
pmiq
].
pm_idx
=
pmiq
+
1
;
// index 0 is the identity matrix
pmi_pdu
[
pmiq
].
numLayers
=
4
;
pmi_pdu
[
pmiq
].
num_ant_ports
=
num_antenna_ports
;
LOG_D
(
PHY
,
"layer 4 pmiq = %d
\n
"
,
pmiq
);
for
(
int
j_col
=
0
;
j_col
<
4
;
j_col
++
)
{
if
(
j_col
==
0
)
{
llc
=
ll
;
mmc
=
mm
;
phase_sign
=
1
;
}
if
(
j_col
==
1
)
{
llc
=
ll
+
k1
*
O1
;
mmc
=
mm
+
k2
*
O2
;
phase_sign
=
1
;
}
if
(
j_col
==
2
)
{
llc
=
ll
;
mmc
=
mm
;
phase_sign
=
-
1
;
}
if
(
j_col
==
3
)
{
llc
=
ll
+
k1
*
O1
;
mmc
=
mm
+
k2
*
O2
;
phase_sign
=
-
1
;
}
for
(
int
i_rows
=
0
;
i_rows
<
N1
*
N2
;
i_rows
++
)
{
nfapi_nr_pm_weights_t
*
weights
=
&
pmi_pdu
[
pmiq
].
weights
[
j_col
][
i_rows
];
res_code
=
sqrt
(
1
/
(
double
)(
4
*
num_antenna_ports
))
*
v_lm
[
llc
][
mmc
][
i_rows
];
c16_t
precoder_weight
=
convert_precoder_weight
(
res_code
);
weights
->
precoder_weight_Re
=
precoder_weight
.
r
;
weights
->
precoder_weight_Im
=
precoder_weight
.
i
;
LOG_D
(
PHY
,
"4 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
i_rows
,
j_col
,
creal
(
res_code
),
cimag
(
res_code
),
weights
->
precoder_weight_Re
,
weights
->
precoder_weight_Im
);
}
for
(
int
i_rows
=
N1
*
N2
;
i_rows
<
2
*
N1
*
N2
;
i_rows
++
)
{
nfapi_nr_pm_weights_t
*
weights
=
&
pmi_pdu
[
pmiq
].
weights
[
j_col
][
i_rows
];
res_code
=
sqrt
(
1
/
(
double
)(
4
*
num_antenna_ports
))
*
(
phase_sign
)
*
theta_n
[
nn
]
*
v_lm
[
llc
][
mmc
][
i_rows
-
N1
*
N2
];
c16_t
precoder_weight
=
convert_precoder_weight
(
res_code
);
weights
->
precoder_weight_Re
=
precoder_weight
.
r
;
weights
->
precoder_weight_Im
=
precoder_weight
.
i
;
LOG_D
(
PHY
,
"4 Layer Precoding Matrix[1][pmi %d][antPort %d][layerIdx %d]= %f+j %f -> Fixed Point %d+j %d
\n
"
,
pmiq
,
i_rows
,
j_col
,
creal
(
res_code
),
cimag
(
res_code
),
weights
->
precoder_weight_Re
,
weights
->
precoder_weight_Im
);
}
}
}
}
}
}
}
return
mat
;
}
else
AssertFatal
(
false
,
"Max number of antenna ports supported is currently 16
\n
"
);
}
static
void
process_rlcBearerConfig
(
struct
NR_CellGroupConfig__rlc_BearerToAddModList
*
rlc_bearer2add_list
,
struct
NR_CellGroupConfig__rlc_BearerToReleaseList
*
rlc_bearer2release_list
,
NR_UE_sched_ctrl_t
*
sched_ctrl
)
...
...
@@ -122,7 +430,7 @@ void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_info_t *UE)
process_rlcBearerConfig
(
CellGroup
->
rlc_BearerToAddModList
,
CellGroup
->
rlc_BearerToReleaseList
,
&
UE
->
UE_sched_ctrl
);
}
static
void
config_common
(
gNB_MAC_INST
*
nrmac
,
in
t
pdsch_AntennaPorts
,
int
pusch_AntennaPorts
,
NR_ServingCellConfigCommon_t
*
scc
)
static
void
config_common
(
gNB_MAC_INST
*
nrmac
,
nr_pdsch_AntennaPorts_
t
pdsch_AntennaPorts
,
int
pusch_AntennaPorts
,
NR_ServingCellConfigCommon_t
*
scc
)
{
nfapi_nr_config_request_scf_t
*
cfg
=
&
nrmac
->
config
[
0
];
nrmac
->
common_channels
[
0
].
ServingCellConfigCommon
=
scc
;
...
...
@@ -136,7 +444,7 @@ static void config_common(gNB_MAC_INST *nrmac, int pdsch_AntennaPorts, int pusch
get_supported_bw_mhz
(
*
frequencyInfoDL
->
frequencyBandList
.
list
.
array
[
0
]
>
256
?
FR2
:
FR1
,
bw_index
);
cfg
->
carrier_config
.
dl_bandwidth
.
tl
.
tag
=
NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG
;
// temporary
cfg
->
num_tlv
++
;
LOG_I
(
NR_MAC
,
"%s() dl_BandwidthP:%d
\n
"
,
__FUNCTION__
,
cfg
->
carrier_config
.
dl_bandwidth
.
value
);
LOG_I
(
NR_MAC
,
"DL_Bandwidth:%d
\n
"
,
cfg
->
carrier_config
.
dl_bandwidth
.
value
);
cfg
->
carrier_config
.
dl_frequency
.
value
=
from_nrarfcn
(
*
frequencyInfoDL
->
frequencyBandList
.
list
.
array
[
0
],
*
scc
->
ssbSubcarrierSpacing
,
...
...
@@ -166,7 +474,7 @@ static void config_common(gNB_MAC_INST *nrmac, int pdsch_AntennaPorts, int pusch
get_supported_bw_mhz
(
*
frequencyInfoUL
->
frequencyBandList
->
list
.
array
[
0
]
>
256
?
FR2
:
FR1
,
bw_index
);
cfg
->
carrier_config
.
uplink_bandwidth
.
tl
.
tag
=
NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG
;
// temporary
cfg
->
num_tlv
++
;
LOG_I
(
NR_MAC
,
"%s() dl_BandwidthP:%d
\n
"
,
__FUNCTION__
,
cfg
->
carrier_config
.
uplink_bandwidth
.
value
);
LOG_I
(
NR_MAC
,
"DL_Bandwidth:%d
\n
"
,
cfg
->
carrier_config
.
uplink_bandwidth
.
value
);
int
UL_pointA
;
if
(
frequencyInfoUL
->
absoluteFrequencyPointA
==
NULL
)
...
...
@@ -332,6 +640,7 @@ static void config_common(gNB_MAC_INST *nrmac, int pdsch_AntennaPorts, int pusch
cfg
->
ssb_table
.
ssb_subcarrier_offset
.
value
=
get_ssb_subcarrier_offset
(
*
scc
->
downlinkConfigCommon
->
frequencyInfoDL
->
absoluteFrequencySSB
,
scc
->
downlinkConfigCommon
->
frequencyInfoDL
->
absoluteFrequencyPointA
);
AssertFatal
(
cfg
->
ssb_table
.
ssb_subcarrier_offset
.
value
<
16
,
"cannot handle ssb_subcarrier_offset %d resulting from Point A %ld SSB %ld: please increase dl_absoluteFrequencyPointA "
"in the config by 16
\n
"
,
...
...
@@ -376,8 +685,9 @@ static void config_common(gNB_MAC_INST *nrmac, int pdsch_AntennaPorts, int pusch
cfg
->
num_tlv
+=
2
;
// logical antenna ports
cfg
->
carrier_config
.
num_tx_ant
.
value
=
pdsch_AntennaPorts
;
AssertFatal
(
pdsch_AntennaPorts
>
0
&&
pdsch_AntennaPorts
<
33
,
"pdsch_AntennaPorts in 1...32
\n
"
);
int
num_pdsch_antenna_ports
=
pdsch_AntennaPorts
.
N1
*
pdsch_AntennaPorts
.
N2
*
pdsch_AntennaPorts
.
XP
;
cfg
->
carrier_config
.
num_tx_ant
.
value
=
num_pdsch_antenna_ports
;
AssertFatal
(
num_pdsch_antenna_ports
>
0
&&
num_pdsch_antenna_ports
<
33
,
"pdsch_AntennaPorts in 1...32
\n
"
);
cfg
->
carrier_config
.
num_tx_ant
.
tl
.
tag
=
NFAPI_NR_CONFIG_NUM_TX_ANT_TAG
;
int
num_ssb
=
0
;
...
...
@@ -441,6 +751,9 @@ static void config_common(gNB_MAC_INST *nrmac, int pdsch_AntennaPorts, int pusch
nrmac
->
tdd_beam_association
=
(
int16_t
*
)
malloc16
(
periods_per_frame
*
sizeof
(
int16_t
));
}
}
// precoding matrix configuration (to be improved)
cfg
->
pmi_list
=
init_DL_MIMO_codebook
(
nrmac
,
pdsch_AntennaPorts
);
}
void
nr_mac_config_scc
(
gNB_MAC_INST
*
nrmac
,
NR_ServingCellConfigCommon_t
*
scc
,
const
nr_mac_config_t
*
config
)
...
...
@@ -464,8 +777,7 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
LOG_I
(
NR_MAC
,
"Configuring common parameters from NR ServingCellConfig
\n
"
);
int
num_pdsch_antenna_ports
=
config
->
pdsch_AntennaPorts
.
N1
*
config
->
pdsch_AntennaPorts
.
N2
*
config
->
pdsch_AntennaPorts
.
XP
;
config_common
(
nrmac
,
num_pdsch_antenna_ports
,
config
->
pusch_AntennaPorts
,
scc
);
config_common
(
nrmac
,
config
->
pdsch_AntennaPorts
,
config
->
pusch_AntennaPorts
,
scc
);
if
(
NFAPI_MODE
==
NFAPI_MODE_PNF
||
NFAPI_MODE
==
NFAPI_MODE_VNF
)
{
// fake that the gNB is configured in nFAPI mode, which would normally be
...
...
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
View file @
3c1405f6
...
...
@@ -668,8 +668,7 @@ static void pf_dl(module_id_t module_id,
else
sched_pdsch
->
mcs
=
get_mcs_from_bler
(
bo
,
stats
,
&
sched_ctrl
->
dl_bler_stats
,
max_mcs
,
frame
);
sched_pdsch
->
nrOfLayers
=
get_dl_nrOfLayers
(
sched_ctrl
,
current_BWP
->
dci_format
);
sched_pdsch
->
pm_index
=
mac
->
identity_pm
?
0
:
get_pm_index
(
UE
,
sched_pdsch
->
nrOfLayers
,
mac
->
radio_config
.
pdsch_AntennaPorts
.
XP
);
sched_pdsch
->
pm_index
=
mac
->
identity_pm
?
0
:
get_pm_index
(
mac
,
UE
,
sched_pdsch
->
nrOfLayers
,
mac
->
radio_config
.
pdsch_AntennaPorts
.
XP
);
const
uint8_t
Qm
=
nr_get_Qm_dl
(
sched_pdsch
->
mcs
,
current_BWP
->
mcsTableIdx
);
const
uint16_t
R
=
nr_get_code_rate_dl
(
sched_pdsch
->
mcs
,
current_BWP
->
mcsTableIdx
);
uint32_t
tbs
=
nr_compute_tbs
(
Qm
,
...
...
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
View file @
3c1405f6
...
...
@@ -129,29 +129,36 @@ uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl,
}
uint16_t
get_pm_index
(
const
NR_UE_info_t
*
UE
,
uint16_t
get_pm_index
(
const
gNB_MAC_INST
*
nrmac
,
const
NR_UE_info_t
*
UE
,
int
layers
,
int
xp_pdsch_antenna_ports
)
{
if
(
layers
==
1
)
return
0
;
int
xp_pdsch_antenna_ports
)
{
const
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
UE
->
UE_sched_ctrl
;
const
int
report_id
=
sched_ctrl
->
CSI_report
.
cri_ri_li_pmi_cqi_report
.
csi_report_id
;
const
nr_csi_report_t
*
csi_report
=
&
UE
->
csi_report_template
[
report_id
];
const
int
N1
=
csi_report
->
N1
;
const
int
N2
=
csi_report
->
N2
;
const
int
antenna_ports
=
(
N1
*
N2
)
<<
1
;
const
int
antenna_ports
=
(
N1
*
N2
)
<<
1
;
if
(
xp_pdsch_antenna_ports
==
1
&&
antenna_ports
>
1
)
if
(
xp_pdsch_antenna_ports
==
1
)
return
0
;
//identity matrix (basic 5G configuration handled by PMI report is with XP antennas)
const
int
x1
=
sched_ctrl
->
CSI_report
.
cri_ri_li_pmi_cqi_report
.
pmi_x1
;
const
int
x2
=
sched_ctrl
->
CSI_report
.
cri_ri_li_pmi_cqi_report
.
pmi_x2
;
LOG_D
(
NR_MAC
,
"PMI report: x1 %d x2 %d
\n
"
,
x1
,
x2
);
LOG_D
(
NR_MAC
,
"PMI report: x1 %d x2 %d layers: %d
\n
"
,
x1
,
x2
,
layers
);
int
prev_layers_size
=
0
;
for
(
int
i
=
1
;
i
<
layers
;
i
++
)
prev_layers_size
+=
nrmac
->
precoding_matrix_size
[
i
-
1
];
// need to return PM index to matrix initialized in init_DL_MIMO_codebook
// index 0 is for identity matrix
// order of matrices depends on layers to be transmitted
// elements from 1 to n for 1 layer
// elements from n+1 to m for 2 layers etc.
if
(
antenna_ports
==
2
)
return
x2
;
return
1
+
prev_layers_size
+
x2
;
// 0 for identity matrix
else
AssertFatal
(
1
==
0
,
"More than 2 antenna ports not yet supported
\n
"
);
}
...
...
openair2/LAYER2/NR_MAC_gNB/mac_proto.h
View file @
3c1405f6
...
...
@@ -377,7 +377,8 @@ NR_pdsch_dmrs_t get_dl_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
const
NR_tda_info_t
*
tda_info
,
const
int
Layers
);
uint16_t
get_pm_index
(
const
NR_UE_info_t
*
UE
,
uint16_t
get_pm_index
(
const
gNB_MAC_INST
*
nrmac
,
const
NR_UE_info_t
*
UE
,
int
layers
,
int
xp_pdsch_antenna_ports
);
...
...
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
View file @
3c1405f6
...
...
@@ -852,6 +852,7 @@ typedef struct gNB_MAC_INST_s {
uint8_t
min_grant_prb
;
uint8_t
min_grant_mcs
;
bool
identity_pm
;
int
precoding_matrix_size
[
NR_MAX_NB_LAYERS
];
nr_mac_rrc_ul_if_t
mac_rrc
;
f1_config_t
f1_config
;
...
...
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