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
ebeb2652
Commit
ebeb2652
authored
Apr 15, 2024
by
Robert Schmidt
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/NR_PSBCH_MERGE1' into integration_2024_w15
parents
3011b706
d7a27954
Changes
42
Show whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
3245 additions
and
154 deletions
+3245
-154
CMakeLists.txt
CMakeLists.txt
+20
-0
charts/physims/charts/nr-psbchsim/Chart.yaml
charts/physims/charts/nr-psbchsim/Chart.yaml
+36
-0
charts/physims/charts/nr-psbchsim/templates/_helpers.tpl
charts/physims/charts/nr-psbchsim/templates/_helpers.tpl
+63
-0
charts/physims/charts/nr-psbchsim/templates/job.yaml
charts/physims/charts/nr-psbchsim/templates/job.yaml
+42
-0
charts/physims/charts/nr-psbchsim/values.yaml
charts/physims/charts/nr-psbchsim/values.yaml
+48
-0
charts/physims/values.yaml
charts/physims/values.yaml
+1
-0
ci-scripts/cls_physim1.py
ci-scripts/cls_physim1.py
+1
-1
cmake_targets/autotests/test_case_list.xml
cmake_targets/autotests/test_case_list.xml
+12
-0
cmake_targets/build_oai
cmake_targets/build_oai
+1
-1
docker/Dockerfile.phySim.rhel9
docker/Dockerfile.phySim.rhel9
+1
-0
openair1/PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h
openair1/PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h
+57
-0
openair1/PHY/CODING/nr_polar_init.c
openair1/PHY/CODING/nr_polar_init.c
+17
-1
openair1/PHY/INIT/nr_init_ue.c
openair1/PHY/INIT/nr_init_ue.c
+79
-1
openair1/PHY/INIT/nr_parms.c
openair1/PHY/INIT/nr_parms.c
+3
-3
openair1/PHY/INIT/nr_phy_init.h
openair1/PHY/INIT/nr_phy_init.h
+1
-0
openair1/PHY/MODULATION/modulation_UE.h
openair1/PHY/MODULATION/modulation_UE.h
+9
-1
openair1/PHY/MODULATION/slot_fep_nr.c
openair1/PHY/MODULATION/slot_fep_nr.c
+100
-10
openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
+18
-13
openair1/PHY/NR_REFSIG/nr_gold_ue.c
openair1/PHY/NR_REFSIG/nr_gold_ue.c
+25
-0
openair1/PHY/NR_REFSIG/refsig_defs_ue.h
openair1/PHY/NR_REFSIG/refsig_defs_ue.h
+5
-2
openair1/PHY/NR_REFSIG/sss_nr.h
openair1/PHY/NR_REFSIG/sss_nr.h
+20
-0
openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+53
-38
openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+10
-2
openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
+48
-0
openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+4
-1
openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c
openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c
+552
-0
openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+19
-22
openair1/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c
openair1/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c
+239
-0
openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c
openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c
+384
-0
openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+34
-0
openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+90
-0
openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
+49
-8
openair1/PHY/TOOLS/tools_defs.h
openair1/PHY/TOOLS/tools_defs.h
+5
-0
openair1/PHY/defs_nr_UE.h
openair1/PHY/defs_nr_UE.h
+14
-0
openair1/PHY/defs_nr_common.h
openair1/PHY/defs_nr_common.h
+2
-2
openair1/PHY/defs_nr_sl_UE.h
openair1/PHY/defs_nr_sl_UE.h
+152
-0
openair1/SCHED_NR_UE/defs.h
openair1/SCHED_NR_UE/defs.h
+18
-0
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+16
-20
openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c
openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c
+305
-0
openair1/SIMULATION/NR_PHY/pbchsim.c
openair1/SIMULATION/NR_PHY/pbchsim.c
+36
-27
openair1/SIMULATION/NR_PHY/psbchsim.c
openair1/SIMULATION/NR_PHY/psbchsim.c
+655
-0
openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
+1
-1
No files found.
CMakeLists.txt
View file @
ebeb2652
...
...
@@ -717,6 +717,7 @@ target_link_libraries(SCHED_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
set
(
SCHED_SRC_NR_UE
${
OPENAIR1_DIR
}
/SCHED_NR_UE/phy_procedures_nr_ue.c
${
OPENAIR1_DIR
}
/SCHED_NR_UE/phy_procedures_nr_ue_sl.c
${
OPENAIR1_DIR
}
/SCHED_NR_UE/fapi_nr_ue_l1.c
${
OPENAIR1_DIR
}
/SCHED_NR_UE/phy_frame_config_nr_ue.c
${
OPENAIR1_DIR
}
/SCHED_NR_UE/harq_nr.c
...
...
@@ -1084,8 +1085,11 @@ set(PHY_SRC_UE
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/sss_nr.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/cic_filter_nr.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_pbch.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
...
...
@@ -2237,6 +2241,22 @@ target_link_libraries(nr_pbchsim PRIVATE
)
target_link_libraries
(
nr_pbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs
)
add_executable
(
nr_psbchsim
${
OPENAIR1_DIR
}
/SIMULATION/NR_PHY/psbchsim.c
${
OPENAIR1_DIR
}
/SIMULATION/NR_PHY/nr_dummy_functions.c
${
OPENAIR_DIR
}
/common/utils/nr/nr_common.c
${
OPENAIR_DIR
}
/executables/softmodem-common.c
${
OPENAIR2_DIR
}
/RRC/NAS/nas_config.c
${
NR_UE_RRC_DIR
}
/rrc_nsa.c
${
NFAPI_USER_DIR
}
/nfapi.c
${
NFAPI_USER_DIR
}
/gnb_ind_vars.c
${
PHY_INTERFACE_DIR
}
/queue_t.c
)
target_link_libraries
(
nr_psbchsim PRIVATE
-Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB L2_NR -lz -Wl,--end-group
m pthread
${
T_LIB
}
ITTI dl shlib_loader
)
target_link_libraries
(
nr_psbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs
)
#PUCCH ---> Prashanth
add_executable
(
nr_pucchsim
...
...
charts/physims/charts/nr-psbchsim/Chart.yaml
0 → 100644
View file @
ebeb2652
apiVersion
:
v1
name
:
oai-nr-psbchsim
description
:
A Helm subchart for nr-psbchsim network function
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type
:
application
icon
:
http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version
:
0.1.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion
:
v1
keywords
:
-
Physical Simulator
-
nr-psbchsim
-
RAN
-
5G
sources
:
-
https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers
:
-
name
:
OPENAIRINTERFACE
email
:
contact@openairinterface.org
charts/physims/charts/nr-psbchsim/templates/_helpers.tpl
0 → 100644
View file @
ebeb2652
{{
/*
vim
:
set
filetype
=
mustache
:
*/
}}
{
{
/*
Expand
the
name
of
the
chart
.
*/
}
}
{{- define "oai-nr-psbchsim.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{
{
/*
Create
a
default
fully
qualified
app
name
.
We
truncate
at
63
chars
because
some
Kubernetes
name
fields
are
limited
to
this
(
by
the
DNS
naming
spec
).
If
release
name
contains
chart
name
it
will
be
used
as
a
full
name
.
*/
}
}
{{- define "oai-nr-psbchsim.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{
{
/*
Create
chart
name
and
version
as
used
by
the
chart
label
.
*/
}
}
{{- define "oai-nr-psbchsim.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{
{
/*
Common
labels
*/
}
}
{{- define "oai-nr-psbchsim.labels" -}}
helm.sh/chart: {{ include "oai-nr-psbchsim.chart" . }}
{{ include "oai-nr-psbchsim.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{
{
/*
Selector
labels
*/
}
}
{{- define "oai-nr-psbchsim.selectorLabels" -}}
app.kubernetes.io/name: {{ include "oai-nr-psbchsim.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{
{
/*
Create
the
name
of
the
service
account
to
use
*/
}
}
{{- define "oai-nr-psbchsim.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "oai-nr-psbchsim.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
charts/physims/charts/nr-psbchsim/templates/job.yaml
0 → 100644
View file @
ebeb2652
apiVersion
:
batch/v1
kind
:
Job
metadata
:
name
:
{{
.Chart.Name
}}
spec
:
template
:
metadata
:
labels
:
app
:
physim
spec
:
securityContext
:
{{
- toYaml .Values.podSecurityContext | nindent 8
}}
{{
- if .Values.imagePullSecrets
}}
imagePullSecrets
:
{{
- toYaml . | nindent 8
}}
{{
- end
}}
containers
:
-
name
:
physim
image
:
"
{{
.Values.global.image.repository
}}:{{
.Values.global.image.version
}}"
imagePullPolicy
:
{{
.Values.image.pullPolicy
}}
securityContext
:
{{
- toYaml .Values.securityContext | nindent 12
}}
env
:
-
name
:
OPENAIR_DIR
value
:
/opt/oai-physim
command
:
[
"
/bin/sh"
,
"
-c"
]
args
:
-
>
cmake_targets/autotests/run_exec_autotests.bash -g "nr_psbchsim" -d bin/ &&
echo "FINISHED" && sleep infinity
dnsPolicy
:
ClusterFirst
restartPolicy
:
Never
schedulerName
:
default-scheduler
serviceAccountName
:
{{
.Values.global.serviceAccountName
}}
terminationGracePeriodSeconds
:
30
{{
- if .Values.global.nodeSelector
}}
nodeSelector
:
{{
- toYaml .Values.global.nodeSelector | nindent 12
}}
{{
- end
}}
{{
- if .Values.global.nodeName.nrpsbchsim
}}
nodeName
:
{{
.Values.global.nodeName.nrpsbchsim
}}
{{
- end
}}
charts/physims/charts/nr-psbchsim/values.yaml
0 → 100644
View file @
ebeb2652
# Default values for oai-nr-psbchsim
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount
:
1
image
:
# pullPolicy: IfNotPresent or Never or Always
pullPolicy
:
Always
imagePullSecrets
:
[]
nameOverride
:
"
"
fullnameOverride
:
"
"
serviceAccount
:
# Specifies whether a service account should be created
create
:
true
# Annotations to add to the service account
annotations
:
{}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name
:
"
oai-nr-psbchsim"
podSecurityContext
:
runAsUser
:
0
runAsGroup
:
0
securityContext
:
privileged
:
false
resources
:
{}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector
:
{}
tolerations
:
[]
affinity
:
{}
charts/physims/values.yaml
View file @
ebeb2652
...
...
@@ -27,6 +27,7 @@ global:
nrpbschsim106rb
:
dedale
nrpbchsim217rb
:
dedale
nrpbchsim273rb
:
dedale
nrpsbchsim
:
dedale
nrprachsim
:
dedale
nrpucchsim
:
dedale
nrulschsim
:
theseus
...
...
ci-scripts/cls_physim1.py
View file @
ebeb2652
...
...
@@ -166,7 +166,7 @@ class PhySim:
mySSH
.
command
(
'oc get pods -o wide -l app=physim | tee -a cmake_targets/log/physim_pods_summary.txt'
,
'\$'
,
30
,
resync
=
True
)
running_count
=
mySSH
.
getBefore
().
count
(
'Running'
)
completed_count
=
mySSH
.
getBefore
().
count
(
'Completed'
)
if
(
running_count
+
completed_count
)
==
2
1
:
if
(
running_count
+
completed_count
)
==
2
2
:
logging
.
debug
(
'
\u001B
[1m Running the physim test Scenarios
\u001B
[0m'
)
isRunning
=
True
podNames
=
re
.
findall
(
'oai-[\S\d\w]+'
,
mySSH
.
getBefore
())
...
...
cmake_targets/autotests/test_case_list.xml
View file @
ebeb2652
...
...
@@ -529,4 +529,16 @@
<search_expr_false>
segmentation fault|assertion|exiting|fatal
</search_expr_false>
<nruns>
3
</nruns>
</testCase>
<testCase
id=
"nr_psbchsim"
>
<desc>
NR-Sidelink PSBCH test cases. (Test1: SLSS Search),
(Test2: PSBCH TxRx)
</desc>
<main_exec>
nr_psbchsim
</main_exec>
<main_exec_args>
-I
-n 10
</main_exec_args>
<tags>
test1 test2
</tags>
<search_expr_true>
PSBCH test OK
</search_expr_true>
<search_expr_false>
segmentation fault|assertion|exiting|fatal
</search_expr_false>
<nruns>
3
</nruns>
</testCase>
</testCaseList>
cmake_targets/build_oai
View file @
ebeb2652
...
...
@@ -324,7 +324,7 @@ function main() {
-P
|
--phy_simulators
)
SIMUS_PHY
=
1
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
TARGET_LIST
=
"
$TARGET_LIST
dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim"
TARGET_LIST
=
"
$TARGET_LIST
dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim
nr_psbchsim
"
echo_info
"Will compile dlsim, ulsim, ..."
shift
;;
-s
|
--check
)
...
...
docker/Dockerfile.phySim.rhel9
View file @
ebeb2652
...
...
@@ -69,6 +69,7 @@ COPY --from=phy-sim-build \
/oai-ran/cmake_targets/ran_build/build/ldpctest \
/oai-ran/cmake_targets/ran_build/build/nr_dlschsim \
/oai-ran/cmake_targets/ran_build/build/nr_pbchsim \
/oai-ran/cmake_targets/ran_build/build/nr_psbchsim \
/oai-ran/cmake_targets/ran_build/build/nr_pucchsim \
/oai-ran/cmake_targets/ran_build/build/nr_ulsim \
/oai-ran/cmake_targets/ran_build/build/smallblocktest \
...
...
openair1/PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h
0 → 100644
View file @
ebeb2652
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file /PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h
\brief Polar definitions required for Sidelink PSBCH
\author
\date
\version
\company: Fraunhofer
\email:
\note
\warning
*/
#ifndef __NR_POLAR_PSBCH_DEFS__H__
#define __NR_POLAR_PSBCH_DEFS__H__
// PSBCH related polar parameters.
// PSBCH symbols sent in 11RBS, 9 symbols. 11*9*(12-3(for DMRS))*2bits = 1782 bits
#define SL_NR_POLAR_PSBCH_E_NORMAL_CP 1782
// PSBCH symbols sent in 11RBS, 7 symbols. 11*7*(12-3(for DMRS))*2bits = 1386 bits
#define SL_NR_POLAR_PSBCH_E_EXT_CP 1386
// SL_NR_POLAR_PSBCH_E_NORMAL_CP/32
#define SL_NR_POLAR_PSBCH_E_DWORD 56
#define SL_NR_POLAR_PSBCH_MESSAGE_TYPE (NR_POLAR_UCI_PUCCH_MESSAGE_TYPE + 1)
#define SL_NR_POLAR_PSBCH_PAYLOAD_BITS 32
#define SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL 0
#define SL_NR_POLAR_PSBCH_N_MAX 9
#define SL_NR_POLAR_PSBCH_I_IL 1
#define SL_NR_POLAR_PSBCH_I_SEG 0
#define SL_NR_POLAR_PSBCH_N_PC 0
#define SL_NR_POLAR_PSBCH_N_PC_WM 0
#define SL_NR_POLAR_PSBCH_I_BIL 0
#define SL_NR_POLAR_PSBCH_CRC_PARITY_BITS 24
#define SL_NR_POLAR_PSBCH_CRC_ERROR_CORRECTION_BITS 3
#endif
openair1/PHY/CODING/nr_polar_init.c
View file @
ebeb2652
...
...
@@ -32,6 +32,7 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
#include "nrPolar_tools/nr_polar_psbch_defs.h"
#define PolarKey ((messageType<<24)|(messageLength<<8)|aggregation_level)
static
t_nrPolar_params
*
PolarList
=
NULL
;
...
...
@@ -190,7 +191,22 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
newPolarInitNode
->
payloadBits
=
messageLength
;
newPolarInitNode
->
crcCorrectionBits
=
NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS
;
//LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level);
}
else
if
(
messageType
==
SL_NR_POLAR_PSBCH_MESSAGE_TYPE
)
{
// PSBCH
newPolarInitNode
->
n_max
=
SL_NR_POLAR_PSBCH_N_MAX
;
newPolarInitNode
->
i_il
=
SL_NR_POLAR_PSBCH_I_IL
;
newPolarInitNode
->
i_seg
=
SL_NR_POLAR_PSBCH_I_SEG
;
newPolarInitNode
->
n_pc
=
SL_NR_POLAR_PSBCH_N_PC
;
newPolarInitNode
->
n_pc_wm
=
SL_NR_POLAR_PSBCH_N_PC_WM
;
newPolarInitNode
->
i_bil
=
SL_NR_POLAR_PSBCH_I_BIL
;
newPolarInitNode
->
crcParityBits
=
SL_NR_POLAR_PSBCH_CRC_PARITY_BITS
;
newPolarInitNode
->
payloadBits
=
SL_NR_POLAR_PSBCH_PAYLOAD_BITS
;
newPolarInitNode
->
encoderLength
=
SL_NR_POLAR_PSBCH_E_NORMAL_CP
+
2
;
newPolarInitNode
->
crcCorrectionBits
=
SL_NR_POLAR_PSBCH_CRC_ERROR_CORRECTION_BITS
;
newPolarInitNode
->
crc_generator_matrix
=
crc24c_generator_matrix
(
newPolarInitNode
->
payloadBits
);
// G_P
LOG_D
(
PHY
,
"SIDELINK: Initializing polar parameters for PSBCH (K %d, E %d)
\n
"
,
newPolarInitNode
->
payloadBits
,
newPolarInitNode
->
encoderLength
);
}
else
{
AssertFatal
(
1
==
0
,
"[nr_polar_init] Incorrect Message Type(%d)"
,
messageType
);
}
...
...
openair1/PHY/INIT/nr_init_ue.c
View file @
ebeb2652
...
...
@@ -32,7 +32,7 @@
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/
MODULATION/nr_modulation
.h"
#include "PHY/
NR_REFSIG/nr_mod_table
.h"
#include "openair2/COMMON/prs_nr_paramdef.h"
#include "SCHED_NR_UE/harq_nr.h"
...
...
@@ -384,6 +384,15 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
return
0
;
}
static
void
sl_ue_free
(
PHY_VARS_NR_UE
*
UE
)
{
if
(
UE
->
SL_UE_PHY_PARAMS
.
init_params
.
sl_pss_for_correlation
)
{
free_and_zero
(
UE
->
SL_UE_PHY_PARAMS
.
init_params
.
sl_pss_for_correlation
[
0
]);
free_and_zero
(
UE
->
SL_UE_PHY_PARAMS
.
init_params
.
sl_pss_for_correlation
[
1
]);
free_and_zero
(
UE
->
SL_UE_PHY_PARAMS
.
init_params
.
sl_pss_for_correlation
);
}
}
void
term_nr_ue_signal
(
PHY_VARS_NR_UE
*
ue
,
int
nb_connected_gNB
)
{
const
NR_DL_FRAME_PARMS
*
fp
=
&
ue
->
frame_parms
;
...
...
@@ -489,6 +498,8 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
free_and_zero
(
ue
->
prs_vars
[
idx
]);
}
sl_ue_free
(
ue
);
}
void
free_nr_ue_dl_harq
(
NR_DL_UE_HARQ_t
harq_list
[
2
][
NR_MAX_DLSCH_HARQ_PROCESSES
],
int
number_of_processes
,
int
num_rb
)
{
...
...
@@ -702,3 +713,70 @@ void phy_term_nr_top(void)
free_ul_reference_signal_sequences
();
free_context_synchro_nr
();
}
static
void
sl_generate_psbch_dmrs_qpsk_sequences
(
PHY_VARS_NR_UE
*
UE
,
struct
complex16
*
modulated_dmrs_sym
,
uint16_t
slss_id
)
{
uint8_t
idx
=
0
;
uint32_t
*
sl_dmrs_sequence
=
UE
->
SL_UE_PHY_PARAMS
.
init_params
.
psbch_dmrs_gold_sequences
[
slss_id
];
c16_t
*
mod_table
=
(
c16_t
*
)
nr_qpsk_mod_table
;
#ifdef SL_DEBUG_INIT
printf
(
"SIDELINK INIT: PSBCH DMRS Generation with slss_id:%d
\n
"
,
slss_id
);
#endif
/// QPSK modulation
for
(
int
m
=
0
;
m
<
SL_NR_NUM_PSBCH_DMRS_RE
;
m
++
)
{
idx
=
(((
sl_dmrs_sequence
[(
m
<<
1
)
>>
5
])
>>
((
m
<<
1
)
&
0x1f
))
&
3
);
modulated_dmrs_sym
[
m
].
r
=
mod_table
[
idx
].
r
;
modulated_dmrs_sym
[
m
].
i
=
mod_table
[
idx
].
i
;
#ifdef SL_DEBUG_INIT_DATA
printf
(
"m:%d gold seq: %d b0-b1: %d-%d DMRS Symbols: %d %d
\n
"
,
m
,
sl_dmrs_sequence
[(
m
<<
1
)
>>
5
],
(((
sl_dmrs_sequence
[(
m
<<
1
)
>>
5
])
>>
((
m
<<
1
)
&
0x1f
))
&
1
),
(((
sl_dmrs_sequence
[((
m
<<
1
)
+
1
)
>>
5
])
>>
(((
m
<<
1
)
+
1
)
&
0x1f
))
&
1
),
modulated_dmrs_sym
[
m
].
r
,
modulated_dmrs_sym
[
m
].
i
);
printf
(
"idx:%d, qpsk_table.r:%d, qpsk_table.i:%d
\n
"
,
idx
,
mod_table
[
idx
].
r
,
mod_table
[
idx
].
i
);
#endif
}
#ifdef SL_DUMP_INIT_SAMPLES
char
filename
[
40
],
varname
[
25
];
sprintf
(
filename
,
"sl_psbch_dmrs_slssid_%d.m"
,
slss_id
);
sprintf
(
varname
,
"sl_dmrs_id_%d.m"
,
slss_id
);
LOG_M
(
filename
,
varname
,
(
void
*
)
modulated_dmrs_sym
,
SL_NR_NUM_PSBCH_DMRS_RE
,
1
,
1
);
#endif
}
void
sl_ue_phy_init
(
PHY_VARS_NR_UE
*
UE
)
{
uint16_t
scaling_value
=
ONE_OVER_SQRT2_Q15
;
NR_DL_FRAME_PARMS
*
sl_fp
=
&
UE
->
SL_UE_PHY_PARAMS
.
sl_frame_params
;
if
(
!
UE
->
SL_UE_PHY_PARAMS
.
init_params
.
sl_pss_for_correlation
)
{
UE
->
SL_UE_PHY_PARAMS
.
init_params
.
sl_pss_for_correlation
=
malloc16_clear
(
SL_NR_NUM_IDs_IN_PSS
*
sizeof
(
int32_t
*
));
UE
->
SL_UE_PHY_PARAMS
.
init_params
.
sl_pss_for_correlation
[
0
]
=
malloc16_clear
(
sizeof
(
int32_t
)
*
sl_fp
->
ofdm_symbol_size
);
UE
->
SL_UE_PHY_PARAMS
.
init_params
.
sl_pss_for_correlation
[
1
]
=
malloc16_clear
(
sizeof
(
int32_t
)
*
sl_fp
->
ofdm_symbol_size
);
}
LOG_I
(
PHY
,
"SIDELINK INIT: GENERATE PSS, SSS, GOLD SEQUENCES AND PSBCH DMRS SEQUENCES FOR ALL possible SLSS IDs 0- 671
\n
"
);
// Generate PSS sequences for IDs 0,1 used in PSS
sl_generate_pss
(
&
UE
->
SL_UE_PHY_PARAMS
.
init_params
,
0
,
scaling_value
);
sl_generate_pss
(
&
UE
->
SL_UE_PHY_PARAMS
.
init_params
,
1
,
scaling_value
);
// Generate psbch dmrs Gold Sequences and modulated dmrs symbols
sl_init_psbch_dmrs_gold_sequences
(
UE
);
for
(
int
slss_id
=
0
;
slss_id
<
SL_NR_NUM_SLSS_IDs
;
slss_id
++
)
{
sl_generate_psbch_dmrs_qpsk_sequences
(
UE
,
UE
->
SL_UE_PHY_PARAMS
.
init_params
.
psbch_dmrs_modsym
[
slss_id
],
slss_id
);
sl_generate_sss
(
&
UE
->
SL_UE_PHY_PARAMS
.
init_params
,
slss_id
,
scaling_value
);
}
// Generate PSS time domain samples used for correlation during SLSS reception.
sl_generate_pss_ifft_samples
(
&
UE
->
SL_UE_PHY_PARAMS
,
&
UE
->
SL_UE_PHY_PARAMS
.
init_params
);
init_symbol_rotation
(
sl_fp
);
init_timeshift_rotation
(
sl_fp
);
}
openair1/PHY/INIT/nr_parms.c
View file @
ebeb2652
...
...
@@ -425,7 +425,7 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
LOG_I
(
PHY
,
"fp->samples_per_frame=%d
\n
"
,
fp
->
samples_per_frame
);
LOG_I
(
PHY
,
"fp->dl_CarrierFreq=%lu
\n
"
,
fp
->
dl_CarrierFreq
);
LOG_I
(
PHY
,
"fp->ul_CarrierFreq=%lu
\n
"
,
fp
->
ul_CarrierFreq
);
LOG_I
(
PHY
,
"fp->Nid_cell=%d
\n
"
,
fp
->
Nid_cell
);
LOG_I
(
PHY
,
"fp->first_carrier_offset=%d
\n
"
,
fp
->
first_carrier_offset
);
LOG_I
(
PHY
,
"fp->ssb_start_subcarrier=%d
\n
"
,
fp
->
ssb_start_subcarrier
);
}
openair1/PHY/INIT/nr_phy_init.h
View file @
ebeb2652
...
...
@@ -61,4 +61,5 @@ void init_delay_table(uint16_t ofdm_symbol_size,
int
max_ofdm_symbol_size
,
c16_t
delay_table
[][
max_ofdm_symbol_size
]);
void
sl_ue_phy_init
(
PHY_VARS_NR_UE
*
UE
);
#endif
openair1/PHY/MODULATION/modulation_UE.h
View file @
ebeb2652
...
...
@@ -49,9 +49,17 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue,
int
reset_freq_est
);
int
nr_slot_fep
(
PHY_VARS_NR_UE
*
ue
,
NR_DL_FRAME_PARMS
*
frame_parms
,
const
UE_nr_rxtx_proc_t
*
proc
,
unsigned
char
symbol
,
c16_t
rxdataF
[][
ue
->
frame_parms
.
samples_per_slot_wCP
]);
c16_t
rxdataF
[][
frame_parms
->
samples_per_slot_wCP
],
uint32_t
linktype
);
int
sl_nr_slot_fep
(
PHY_VARS_NR_UE
*
ue
,
UE_nr_rxtx_proc_t
*
proc
,
unsigned
char
symbol
,
unsigned
char
Ns
,
uint32_t
sample_offset
,
c16_t
rxdataF
[][
ue
->
SL_UE_PHY_PARAMS
.
sl_frame_params
.
samples_per_slot_wCP
]);
int
nr_slot_fep_init_sync
(
PHY_VARS_NR_UE
*
ue
,
const
UE_nr_rxtx_proc_t
*
proc
,
...
...
openair1/PHY/MODULATION/slot_fep_nr.c
View file @
ebeb2652
...
...
@@ -34,12 +34,109 @@
#define LOG_I(A,B...) printf(A)
#endif*/
int
sl_nr_slot_fep
(
PHY_VARS_NR_UE
*
ue
,
UE_nr_rxtx_proc_t
*
proc
,
unsigned
char
symbol
,
unsigned
char
Ns
,
uint32_t
sample_offset
,
c16_t
rxdataF
[][
ue
->
SL_UE_PHY_PARAMS
.
sl_frame_params
.
samples_per_slot_wCP
])
{
NR_DL_FRAME_PARMS
*
frame_params
=
&
ue
->
SL_UE_PHY_PARAMS
.
sl_frame_params
;
NR_UE_COMMON
*
common_vars
=
&
ue
->
common_vars
;
AssertFatal
(
symbol
<
frame_params
->
symbols_per_slot
,
"slot_fep: symbol must be between 0 and %d
\n
"
,
frame_params
->
symbols_per_slot
-
1
);
AssertFatal
(
Ns
<
frame_params
->
slots_per_frame
,
"slot_fep: Ns must be between 0 and %d
\n
"
,
frame_params
->
slots_per_frame
-
1
);
unsigned
int
nb_prefix_samples
=
frame_params
->
nb_prefix_samples
;
unsigned
int
nb_prefix_samples0
=
frame_params
->
nb_prefix_samples0
;
dft_size_idx_t
dftsize
=
get_dft
(
frame_params
->
ofdm_symbol_size
);
// This is for misalignment issues
int32_t
tmp_dft_in
[
8192
]
__attribute__
((
aligned
(
32
)));
unsigned
int
rx_offset
=
frame_params
->
get_samples_slot_timestamp
(
Ns
,
frame_params
,
0
);
unsigned
int
abs_symbol
=
Ns
*
frame_params
->
symbols_per_slot
+
symbol
;
rx_offset
+=
sample_offset
;
for
(
int
idx_symb
=
Ns
*
frame_params
->
symbols_per_slot
;
idx_symb
<=
abs_symbol
;
idx_symb
++
)
rx_offset
+=
(
idx_symb
%
(
0x7
<<
frame_params
->
numerology_index
))
?
nb_prefix_samples
:
nb_prefix_samples0
;
rx_offset
+=
frame_params
->
ofdm_symbol_size
*
symbol
;
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rx_offset
-=
(
nb_prefix_samples
/
frame_params
->
ofdm_offset_divisor
);
#ifdef SL_DEBUG_SLOT_FEP
// if (ue->frame <100)
LOG_I
(
PHY
,
"slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u
\n
"
,
Ns
,
symbol
,
nb_prefix_samples
,
nb_prefix_samples0
,
rx_offset
);
#endif
for
(
unsigned
char
aa
=
0
;
aa
<
frame_params
->
nb_antennas_rx
;
aa
++
)
{
memset
(
&
rxdataF
[
aa
][
frame_params
->
ofdm_symbol_size
*
symbol
],
0
,
frame_params
->
ofdm_symbol_size
*
sizeof
(
int32_t
));
int16_t
*
rxdata_ptr
=
(
int16_t
*
)
&
common_vars
->
rxdata
[
aa
][
rx_offset
];
// if input to dft is not 256-bit aligned
if
((
rx_offset
&
7
)
!=
0
)
{
memcpy
((
void
*
)
&
tmp_dft_in
[
0
],
(
void
*
)
&
common_vars
->
rxdata
[
aa
][
rx_offset
],
frame_params
->
ofdm_symbol_size
*
sizeof
(
int32_t
));
rxdata_ptr
=
(
int16_t
*
)
tmp_dft_in
;
}
dft
(
dftsize
,
rxdata_ptr
,
(
int16_t
*
)
&
rxdataF
[
aa
][
frame_params
->
ofdm_symbol_size
*
symbol
],
1
);
int
symb_offset
=
(
Ns
%
frame_params
->
slots_per_subframe
)
*
frame_params
->
symbols_per_slot
;
int32_t
rot2
=
((
uint32_t
*
)
frame_params
->
symbol_rotation
[
1
])[
symbol
+
symb_offset
];
((
int16_t
*
)
&
rot2
)[
1
]
=
-
((
int16_t
*
)
&
rot2
)[
1
];
#ifdef SL_DEBUG_SLOT_FEP
// if (ue->frame <100)
LOG_I
(
PHY
,
"slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d
\n
"
,
Ns
,
symbol
,
rx_offset
,
symbol
+
symb_offset
,
((
int16_t
*
)
&
rot2
)[
0
],
((
int16_t
*
)
&
rot2
)[
1
]);
#endif
rotate_cpx_vector
((
c16_t
*
)
&
rxdataF
[
aa
][
frame_params
->
ofdm_symbol_size
*
symbol
],
(
c16_t
*
)
&
rot2
,
(
c16_t
*
)
&
rxdataF
[
aa
][
frame_params
->
ofdm_symbol_size
*
symbol
],
frame_params
->
ofdm_symbol_size
,
15
);
int16_t
*
shift_rot
=
(
int16_t
*
)
frame_params
->
timeshift_symbol_rotation
;
multadd_cpx_vector
((
int16_t
*
)
&
rxdataF
[
aa
][
frame_params
->
ofdm_symbol_size
*
symbol
],
shift_rot
,
(
int16_t
*
)
&
rxdataF
[
aa
][
frame_params
->
ofdm_symbol_size
*
symbol
],
1
,
frame_params
->
ofdm_symbol_size
,
15
);
}
LOG_D
(
PHY
,
"SIDELINK RX: Slot FEP: done for symbol:%d
\n
"
,
symbol
);
return
0
;
}
int
nr_slot_fep
(
PHY_VARS_NR_UE
*
ue
,
NR_DL_FRAME_PARMS
*
frame_parms
,
const
UE_nr_rxtx_proc_t
*
proc
,
unsigned
char
symbol
,
c16_t
rxdataF
[][
ue
->
frame_parms
.
samples_per_slot_wCP
])
c16_t
rxdataF
[][
frame_parms
->
samples_per_slot_wCP
],
uint32_t
linktype
)
{
NR_DL_FRAME_PARMS
*
frame_parms
=
&
ue
->
frame_parms
;
NR_UE_COMMON
*
common_vars
=
&
ue
->
common_vars
;
int
Ns
=
proc
->
nr_slot_rx
;
...
...
@@ -96,14 +193,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
stop_meas
(
&
ue
->
rx_dft_stats
);
apply_nr_rotation_RX
(
frame_parms
,
rxdataF
[
aa
],
frame_parms
->
symbol_rotation
[
0
],
Ns
,
frame_parms
->
N_RB_DL
,
0
,
symbol
,
1
);
apply_nr_rotation_RX
(
frame_parms
,
rxdataF
[
aa
],
frame_parms
->
symbol_rotation
[
linktype
],
Ns
,
frame_parms
->
N_RB_DL
,
0
,
symbol
,
1
);
}
#ifdef DEBUG_FEP
...
...
openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
View file @
ebeb2652
...
...
@@ -202,22 +202,27 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
return
(
0
);
}
void
nr_pbch_dmrs_rx
(
const
int
symbol
,
const
unsigned
int
*
nr_gold_pbch
,
c16_t
*
output
)
void
nr_pbch_dmrs_rx
(
int
symbol
,
unsigned
int
*
nr_gold_pbch
,
c16_t
*
output
,
bool
sidelink
)
{
int
m
,
m0
,
m1
;
uint8_t
idx
=
0
;
AssertFatal
(
symbol
>=
0
&&
symbol
<
3
,
"illegal symbol %d
\n
"
,
symbol
);
if
(
sidelink
)
{
AssertFatal
(
symbol
==
0
||
(
symbol
>=
5
&&
symbol
<=
12
),
"illegal symbol %d
\n
"
,
symbol
);
m0
=
(
symbol
)
?
(
symbol
-
4
)
*
33
:
0
;
m1
=
(
symbol
)
?
(
symbol
-
3
)
*
33
:
33
;
}
else
{
AssertFatal
(
symbol
>=
0
&&
symbol
<
3
,
"illegal symbol %d
\n
"
,
symbol
);
if
(
symbol
==
0
)
{
m0
=
0
;
m1
=
60
;
}
else
if
(
symbol
==
1
)
{
m0
=
60
;
m1
=
84
;
m0
=
0
;
m1
=
60
;
}
else
if
(
symbol
==
1
)
{
m0
=
60
;
m1
=
84
;
}
else
{
m0
=
84
;
m1
=
144
;
}
else
{
m0
=
84
;
m1
=
144
;
}
// printf("Generating pilots symbol %d, m0 %d, m1 %d\n",symbol,m0,m1);
/// QPSK modulation
...
...
openair1/PHY/NR_REFSIG/nr_gold_ue.c
View file @
ebeb2652
...
...
@@ -148,3 +148,28 @@ void init_nr_gold_prs(PHY_VARS_NR_UE* ue)
}
// for rsc
}
// for gnb
}
void
sl_init_psbch_dmrs_gold_sequences
(
PHY_VARS_NR_UE
*
UE
)
{
unsigned
int
x1
,
x2
;
uint16_t
slss_id
;
uint8_t
reset
;
for
(
slss_id
=
0
;
slss_id
<
SL_NR_NUM_SLSS_IDs
;
slss_id
++
)
{
reset
=
1
;
x2
=
slss_id
;
#ifdef SL_DEBUG_INIT
printf
(
"
\n
PSBCH DMRS GOLD SEQ for SLSSID :%d :
\n
"
,
slss_id
);
#endif
for
(
uint8_t
n
=
0
;
n
<
SL_NR_NUM_PSBCH_DMRS_RE_DWORD
;
n
++
)
{
UE
->
SL_UE_PHY_PARAMS
.
init_params
.
psbch_dmrs_gold_sequences
[
slss_id
][
n
]
=
lte_gold_generic
(
&
x1
,
&
x2
,
reset
);
reset
=
0
;
#ifdef SL_DEBUG_INIT_DATA
printf
(
"%x
\n
"
,
SL_UE_INIT_PARAMS
.
sl_psbch_dmrs_gold_sequences
[
slss_id
][
n
]);
#endif
}
}
}
openair1/PHY/NR_REFSIG/refsig_defs_ue.h
View file @
ebeb2652
...
...
@@ -30,7 +30,7 @@
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
*/
void
nr_pbch_dmrs_rx
(
const
int
dmrss
,
const
unsigned
int
*
nr_gold_pbch
,
c16_t
*
output
);
void
nr_pbch_dmrs_rx
(
int
dmrss
,
unsigned
int
*
nr_gold_pbch
,
c16_t
*
output
,
bool
sidelink
);
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
...
...
@@ -66,5 +66,8 @@ void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
void
nr_init_csi_rs
(
const
NR_DL_FRAME_PARMS
*
fp
,
uint32_t
***
csi_rs
,
uint32_t
Nid
);
void
init_nr_gold_prs
(
PHY_VARS_NR_UE
*
ue
);
void
sl_generate_pss
(
SL_NR_UE_INIT_PARAMS_t
*
sl_init_params
,
uint8_t
n_sl_id2
,
uint16_t
scaling
);
void
sl_generate_pss_ifft_samples
(
sl_nr_ue_phy_params_t
*
sl_ue_params
,
SL_NR_UE_INIT_PARAMS_t
*
sl_init_params
);
void
sl_generate_sss
(
SL_NR_UE_INIT_PARAMS_t
*
sl_init_params
,
uint16_t
slss_id
,
uint16_t
scaling
);
void
sl_init_psbch_dmrs_gold_sequences
(
PHY_VARS_NR_UE
*
UE
);
#endif
openair1/PHY/NR_REFSIG/sss_nr.h
View file @
ebeb2652
...
...
@@ -67,8 +67,28 @@
#define PHASE_HYPOTHESIS_NUMBER (16)
#define INDEX_NO_PHASE_DIFFERENCE (3)
/* this is for no phase shift case */
/************** FUNCTION ******************************************/
static
const
c16_t
phase_nr
[
PHASE_HYPOTHESIS_NUMBER
]
=
{
// {pi/3 ---- pi/3, -pi/3 ---- pi/3}
{
16384
,
-
28377
},
{
20173
,
-
25821
},
{
23571
,
-
22762
},
{
26509
,
-
19260
},
{
28932
,
-
15383
},
{
30791
,
-
11207
},
{
32051
,
-
6813
},
{
32687
,
-
2286
},
{
32687
,
2286
},
{
32051
,
6813
},
{
30791
,
11207
},
{
28932
,
15383
},
{
26509
,
19260
},
{
23571
,
22762
},
{
20173
,
25821
},
{
16384
,
28377
}};
void
init_context_sss_nr
(
int
amp
);
void
free_context_sss_nr
(
void
);
...
...
openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
View file @
ebeb2652
...
...
@@ -581,7 +581,7 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
// generate pilot
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
c16_t
pilot
[
200
]
__attribute__
((
aligned
(
16
)));
nr_pbch_dmrs_rx
(
dmrss
,
nr_gold_pbch
,
pilot
);
nr_pbch_dmrs_rx
(
dmrss
,
(
uint32_t
*
)
nr_gold_pbch
,
pilot
,
false
);
c32_t
computed_val
=
{
0
};
for
(
int
aarx
=
0
;
aarx
<
ue
->
frame_parms
.
nb_antennas_rx
;
aarx
++
)
{
...
...
@@ -641,43 +641,66 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
}
int
nr_pbch_channel_estimation
(
PHY_VARS_NR_UE
*
ue
,
NR_DL_FRAME_PARMS
*
fp
,
int
estimateSz
,
struct
complex16
dl_ch_estimates
[][
estimateSz
],
struct
complex16
dl_ch_estimates_time
[][
ue
->
frame_parms
.
ofdm_symbol_size
],
struct
complex16
dl_ch_estimates_time
[][
fp
->
ofdm_symbol_size
],
const
UE_nr_rxtx_proc_t
*
proc
,
unsigned
char
symbol
,
int
dmrss
,
uint8_t
ssb_index
,
uint8_t
n_hf
,
c16_t
rxdataF
[][
ue
->
frame_parms
.
samples_per_slot_wCP
])
c16_t
rxdataF
[][
fp
->
samples_per_slot_wCP
],
bool
sidelink
,
uint16_t
Nid
)
{
int
Ns
=
proc
->
nr_slot_rx
;
c16_t
pilot
[
200
]
__attribute__
((
aligned
(
16
)));
//int slot_pbch;
const
int
nushift
=
ue
->
frame_parms
.
Nid_cell
%
4
;
unsigned
int
ssb_offset
=
ue
->
frame_parms
.
first_carrier_offset
+
ue
->
frame_parms
.
ssb_start_subcarrier
;
if
(
ssb_offset
>=
ue
->
frame_parms
.
ofdm_symbol_size
)
ssb_offset
-=
ue
->
frame_parms
.
ofdm_symbol_size
;
uint8_t
nushift
=
0
,
lastsymbol
=
0
,
num_rbs
=
0
;
uint32_t
*
gold_seq
=
NULL
;
const
int
ch_offset
=
ue
->
frame_parms
.
ofdm_symbol_size
*
symbol
;
if
(
sidelink
)
{
AssertFatal
(
dmrss
==
0
||
(
dmrss
>=
5
&&
dmrss
<=
12
),
"symbol %d is illegal for PSBCH DM-RS
\n
"
,
dmrss
);
AssertFatal
(
dmrss
>=
0
&&
dmrss
<
3
,
"symbol %d is illegal for PBCH DM-RS
\n
"
,
dmrss
);
sl_nr_ue_phy_params_t
*
sl_phy_params
=
&
ue
->
SL_UE_PHY_PARAMS
;
const
int
symbol_offset
=
ue
->
frame_parms
.
ofdm_symbol_size
*
symbol
;
LOG_D
(
PHY
,
"PSBCH Channel Estimation SLSSID:%d
\n
"
,
Nid
);
gold_seq
=
sl_phy_params
->
init_params
.
psbch_dmrs_gold_sequences
[
Nid
];
lastsymbol
=
12
;
num_rbs
=
SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL
;
}
else
{
nushift
=
fp
->
Nid_cell
%
4
;
AssertFatal
(
dmrss
>=
0
&&
dmrss
<
3
,
"symbol %d is illegal for PBCH DM-RS
\n
"
,
dmrss
);
gold_seq
=
ue
->
nr_gold_pbch
[
n_hf
][
ssb_index
];
lastsymbol
=
2
;
num_rbs
=
20
;
}
unsigned
int
ssb_offset
=
fp
->
first_carrier_offset
+
fp
->
ssb_start_subcarrier
;
if
(
ssb_offset
>=
fp
->
ofdm_symbol_size
)
ssb_offset
-=
fp
->
ofdm_symbol_size
;
const
int
ch_offset
=
fp
->
ofdm_symbol_size
*
symbol
;
const
int
symbol_offset
=
fp
->
ofdm_symbol_size
*
symbol
;
const
int
k
=
nushift
;
const
c16_t
*
fl
,
*
fm
,
*
fr
;
DEBUG_PBCH
(
"PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d
\n
"
,
proc
->
gNB_id
,
ch_offset
,
ue
->
frame_parms
.
ofdm_symbol_size
,
ue
->
frame_parms
.
Ncp
,
fp
->
ofdm_symbol_size
,
fp
->
Ncp
,
Ns
,
k
,
symbol
);
const
c16_t
*
fl
,
*
fm
,
*
fr
;
switch
(
k
)
{
case
0
:
fl
=
filt16a_l0
;
...
...
@@ -709,22 +732,20 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
break
;
}
// generate pilot
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
nr_pbch_dmrs_rx
(
dmrss
,
ue
->
nr_gold_pbch
[
n_hf
][
ssb_index
],
pilot
);
for
(
int
aarx
=
0
;
aarx
<
ue
->
frame_parms
.
nb_antennas_rx
;
aarx
++
)
{
nr_pbch_dmrs_rx
(
dmrss
,
gold_seq
,
&
pilot
[
0
],
sidelink
);
for
(
int
aarx
=
0
;
aarx
<
fp
->
nb_antennas_rx
;
aarx
++
)
{
int
re_offset
=
ssb_offset
;
c16_t
*
pil
=
pilot
;
c16_t
*
rxF
=
&
rxdataF
[
aarx
][
symbol_offset
+
k
];
c16_t
*
dl_ch
=
&
dl_ch_estimates
[
aarx
][
ch_offset
];
memset
(
dl_ch
,
0
,
sizeof
(
c16_t
)
*
ue
->
frame_parms
.
ofdm_symbol_size
);
memset
(
dl_ch
,
0
,
sizeof
(
c16_t
)
*
fp
->
ofdm_symbol_size
);
DEBUG_PBCH
(
"pbch ch est pilot RB_DL %d
\n
"
,
ue
->
frame_parms
.
N_RB_DL
);
DEBUG_PBCH
(
"k %d, first_carrier %d
\n
"
,
k
,
ue
->
frame_parms
.
first_carrier_offset
);
DEBUG_PBCH
(
"pbch ch est pilot RB_DL %d
\n
"
,
fp
->
N_RB_DL
);
DEBUG_PBCH
(
"k %d, first_carrier %d
\n
"
,
k
,
fp
->
first_carrier_offset
);
// Treat first 2 pilots specially (left edge)
c16_t
ch
;
...
...
@@ -732,31 +753,31 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
DEBUG_PBCH
(
"pilot 0: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)
\n
"
,
rxF
[
re_offset
].
r
,
rxF
[
re_offset
].
i
,
ch
.
r
,
ch
.
i
,
pil
->
r
,
pil
->
i
);
multaddRealVectorComplexScalar
(
fl
,
ch
,
dl_ch
,
16
);
pil
++
;
re_offset
=
(
re_offset
+
4
)
%
ue
->
frame_parms
.
ofdm_symbol_size
;
re_offset
=
(
re_offset
+
4
)
%
fp
->
ofdm_symbol_size
;
ch
=
c16mulShift
(
*
pil
,
rxF
[
re_offset
],
15
);
DEBUG_PBCH
(
"pilot 1: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)
\n
"
,
rxF
[
re_offset
].
r
,
rxF
[
re_offset
].
i
,
ch
.
r
,
ch
.
i
,
pil
->
r
,
pil
->
i
);
multaddRealVectorComplexScalar
(
fm
,
ch
,
dl_ch
,
16
);
pil
++
;
re_offset
=
(
re_offset
+
4
)
%
ue
->
frame_parms
.
ofdm_symbol_size
;
re_offset
=
(
re_offset
+
4
)
%
fp
->
ofdm_symbol_size
;
ch
=
c16mulShift
(
*
pil
,
rxF
[
re_offset
],
15
);
DEBUG_PBCH
(
"pilot 2: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)
\n
"
,
rxF
[
re_offset
].
r
,
rxF
[
re_offset
].
i
,
ch
.
r
,
ch
.
i
,
pil
->
r
,
pil
->
i
);
multaddRealVectorComplexScalar
(
fr
,
ch
,
dl_ch
,
16
);
pil
++
;
re_offset
=
(
re_offset
+
4
)
%
ue
->
frame_parms
.
ofdm_symbol_size
;
re_offset
=
(
re_offset
+
4
)
%
fp
->
ofdm_symbol_size
;
dl_ch
+=
24
;
for
(
int
pilot_cnt
=
3
;
pilot_cnt
<
(
3
*
20
);
pilot_cnt
+=
3
)
{
for
(
int
pilot_cnt
=
3
;
pilot_cnt
<
(
3
*
num_rbs
);
pilot_cnt
+=
3
)
{
// if (pilot_cnt == 30)
// rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)];
// in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS)
if
(
dmrss
==
1
&&
pilot_cnt
==
12
)
{
pilot_cnt
=
48
;
re_offset
=
(
re_offset
+
144
)
%
ue
->
frame_parms
.
ofdm_symbol_size
;
re_offset
=
(
re_offset
+
144
)
%
fp
->
ofdm_symbol_size
;
dl_ch
+=
288
;
}
ch
=
c16mulShift
(
*
pil
,
rxF
[
re_offset
],
15
);
...
...
@@ -771,7 +792,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
multaddRealVectorComplexScalar
(
fl
,
ch
,
dl_ch
,
16
);
pil
++
;
re_offset
=
(
re_offset
+
4
)
%
ue
->
frame_parms
.
ofdm_symbol_size
;
re_offset
=
(
re_offset
+
4
)
%
fp
->
ofdm_symbol_size
;
ch
=
c16mulShift
(
*
pil
,
rxF
[
re_offset
],
15
);
DEBUG_PBCH
(
"pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)
\n
"
,
pilot_cnt
+
1
,
...
...
@@ -783,7 +804,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
pil
->
i
);
multaddRealVectorComplexScalar
(
fm
,
ch
,
dl_ch
,
16
);
pil
++
;
re_offset
=
(
re_offset
+
4
)
%
ue
->
frame_parms
.
ofdm_symbol_size
;
re_offset
=
(
re_offset
+
4
)
%
fp
->
ofdm_symbol_size
;
ch
=
c16mulShift
(
*
pil
,
rxF
[
re_offset
],
15
);
DEBUG_PBCH
(
"pilot %u: rxF= (%d,%d), ch= (%d,%d), pil=(%d,%d)
\n
"
,
pilot_cnt
+
2
,
...
...
@@ -795,11 +816,11 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
pil
->
i
);
multaddRealVectorComplexScalar
(
fr
,
ch
,
dl_ch
,
16
);
pil
++
;
re_offset
=
(
re_offset
+
4
)
%
ue
->
frame_parms
.
ofdm_symbol_size
;
re_offset
=
(
re_offset
+
4
)
%
fp
->
ofdm_symbol_size
;
dl_ch
+=
12
;
}
if
(
dmrss
==
2
)
// update time statistics for last PBCH symbol
if
(
dmrss
==
lastsymbol
)
// update time statistics for last PBCH symbol
{
// do ifft of channel estimate
LOG_D
(
PHY
,
"Channel Impulse Computation Slot %d Symbol %d ch_offset %d
\n
"
,
Ns
,
symbol
,
ch_offset
);
...
...
@@ -809,14 +830,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
}
}
if
(
dmrss
==
2
)
UEscopeCopy
(
ue
,
pbchDlChEstimateTime
,
(
void
*
)
dl_ch_estimates_time
,
sizeof
(
c16_t
),
ue
->
frame_parms
.
nb_antennas_rx
,
ue
->
frame_parms
.
ofdm_symbol_size
,
0
);
if
(
!
sidelink
&&
dmrss
==
lastsymbol
)
UEscopeCopy
(
ue
,
pbchDlChEstimateTime
,
(
void
*
)
dl_ch_estimates_time
,
sizeof
(
c16_t
),
fp
->
nb_antennas_rx
,
fp
->
ofdm_symbol_size
,
0
);
return
(
0
);
}
...
...
openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
View file @
ebeb2652
...
...
@@ -65,15 +65,18 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
const
c16_t
rxdataF
[][
ue
->
frame_parms
.
samples_per_slot_wCP
]);
int
nr_pbch_channel_estimation
(
PHY_VARS_NR_UE
*
ue
,
NR_DL_FRAME_PARMS
*
fp
,
int
estimateSz
,
struct
complex16
dl_ch_estimates
[][
estimateSz
],
struct
complex16
dl_ch_estimates_time
[][
ue
->
frame_parms
.
ofdm_symbol_size
],
struct
complex16
dl_ch_estimates_time
[][
fp
->
ofdm_symbol_size
],
const
UE_nr_rxtx_proc_t
*
proc
,
unsigned
char
symbol
,
int
dmrss
,
uint8_t
ssb_index
,
uint8_t
n_hf
,
c16_t
rxdataF
[][
ue
->
frame_parms
.
samples_per_slot_wCP
]);
c16_t
rxdataF
[][
fp
->
samples_per_slot_wCP
],
bool
sidelink
,
uint16_t
Nid
);
int
nr_pdsch_channel_estimation
(
PHY_VARS_NR_UE
*
ue
,
const
UE_nr_rxtx_proc_t
*
proc
,
...
...
@@ -137,5 +140,10 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
NR_UE_DLSCH_t
dlsch
[
2
]);
float_t
get_nr_RSRP
(
module_id_t
Mod_id
,
uint8_t
CC_id
,
uint8_t
gNB_index
);
void
nr_sl_psbch_rsrp_measurements
(
sl_nr_ue_phy_params_t
*
sl_phy_params
,
NR_DL_FRAME_PARMS
*
fp
,
c16_t
rxdataF
[][
fp
->
samples_per_slot_wCP
],
bool
use_SSS
);
/** @}*/
#endif
openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
View file @
ebeb2652
...
...
@@ -309,3 +309,51 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
ue
->
measurements
.
n0_power_tot_dB
+
30
-
10
*
log10
(
pow
(
2
,
30
))
-
dB_fixed
(
ue
->
frame_parms
.
ofdm_symbol_size
)
-
((
int
)
rx_gain
-
(
int
)
rx_gain_offset
));
}
// PSBCH RSRP calculations according to 38.215 section 5.1.22
void
nr_sl_psbch_rsrp_measurements
(
sl_nr_ue_phy_params_t
*
sl_phy_params
,
NR_DL_FRAME_PARMS
*
fp
,
c16_t
rxdataF
[][
fp
->
samples_per_slot_wCP
],
bool
use_SSS
)
{
SL_NR_UE_PSBCH_t
*
psbch_rx
=
&
sl_phy_params
->
psbch
;
uint8_t
numsym
=
(
fp
->
Ncp
)
?
SL_NR_NUM_SYMBOLS_SSB_EXT_CP
:
SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP
;
uint32_t
re_offset
=
fp
->
first_carrier_offset
+
fp
->
ssb_start_subcarrier
;
uint32_t
rsrp
=
0
,
num_re
=
0
;
LOG_D
(
PHY
,
"PSBCH RSRP MEAS: numsym:%d, re_offset:%d
\n
"
,
numsym
,
re_offset
);
for
(
int
aarx
=
0
;
aarx
<
fp
->
nb_antennas_rx
;
aarx
++
)
{
// Calculate PSBCH RSRP based from DMRS REs
for
(
uint8_t
symbol
=
0
;
symbol
<
numsym
;)
{
struct
complex16
*
rxF
=
&
rxdataF
[
aarx
][
symbol
*
fp
->
ofdm_symbol_size
];
for
(
int
re
=
0
;
re
<
SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL
;
re
++
)
{
if
(
re
%
4
==
0
)
{
// DMRS RE
uint16_t
offset
=
(
re_offset
+
re
)
%
fp
->
ofdm_symbol_size
;
rsrp
+=
c16amp2
(
rxF
[
offset
]);
num_re
++
;
}
}
symbol
=
(
symbol
==
0
)
?
5
:
symbol
+
1
;
}
}
if
(
use_SSS
)
{
// TBD...
// UE can decide between using only PSBCH DMRS or PSBCH DMRS and SSS for PSBCH RSRP computation.
// If needed this can be implemented. Reference Spec 38.215
}
psbch_rx
->
rsrp_dB_per_RE
=
10
*
log10
(
rsrp
/
num_re
);
psbch_rx
->
rsrp_dBm_per_RE
=
psbch_rx
->
rsrp_dB_per_RE
+
30
-
10
*
log10
(
pow
(
2
,
30
))
-
((
int
)
openair0_cfg
[
0
].
rx_gain
[
0
]
-
(
int
)
openair0_cfg
[
0
].
rx_gain_offset
[
0
])
-
dB_fixed
(
fp
->
ofdm_symbol_size
);
LOG_I
(
PHY
,
"PSBCH RSRP (DMRS REs): numREs:%d RSRP :%d dB/RE ,RSRP:%d dBm/RE
\n
"
,
num_re
,
psbch_rx
->
rsrp_dB_per_RE
,
psbch_rx
->
rsrp_dBm_per_RE
);
}
openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
View file @
ebeb2652
...
...
@@ -101,6 +101,7 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
for
(
int
i
=
pbch_initial_symbol
;
i
<
pbch_initial_symbol
+
3
;
i
++
)
nr_pbch_channel_estimation
(
ue
,
&
ue
->
frame_parms
,
estimateSz
,
dl_ch_estimates
,
dl_ch_estimates_time
,
...
...
@@ -109,7 +110,9 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
i
-
pbch_initial_symbol
,
ssb
->
i_ssb
,
ssb
->
n_hf
,
rxdataF
);
rxdataF
,
false
,
frame_parms
->
Nid_cell
);
stop_meas
(
&
ue
->
dlsch_channel_estimation_stats
);
fapiPbch_t
result
=
{
0
};
...
...
openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c
0 → 100644
View file @
ebeb2652
#include "PHY/defs_nr_UE.h"
#include "PHY/TOOLS/tools_defs.h"
#include "PHY/NR_REFSIG/sss_nr.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "SCHED_NR_UE/defs.h"
// Number of symbols carrying SLSS signal - PSS+SSS+PSBCH
#define SL_NR_NUMSYM_SLSS_NORMAL_CP 14
#define SL_NR_MAX_RX_ANTENNA 1
#define SL_NR_FIRST_PSS_SYMBOL 1
#define SL_NR_FIRST_SSS_SYMBOL 3
#define SL_NR_NUM_PSS_SSS_SYMBOLS 4
// #define SL_DEBUG
static
int
sl_nr_pss_correlation
(
PHY_VARS_NR_UE
*
UE
,
int
frame_index
)
{
sl_nr_ue_phy_params_t
*
sl_ue
=
&
UE
->
SL_UE_PHY_PARAMS
;
SL_NR_SYNC_PARAMS_t
*
sync_params
=
&
sl_ue
->
sync_params
;
NR_DL_FRAME_PARMS
*
sl_fp
=
&
UE
->
SL_UE_PHY_PARAMS
.
sl_frame_params
;
int16_t
**
pss_for_correlation
=
(
int16_t
**
)
sl_ue
->
init_params
.
sl_pss_for_correlation
;
uint32_t
length
=
(
frame_index
==
0
)
?
sl_fp
->
samples_per_frame
+
(
2
*
sl_fp
->
ofdm_symbol_size
)
:
sl_fp
->
samples_per_frame
;
int32_t
**
rxdata
=
(
int32_t
**
)
UE
->
common_vars
.
rxdata
;
#ifdef SL_DEBUG
char
fname
[
50
],
sname
[
25
];
sprintf
(
fname
,
"rxdata_frame_%d.m"
,
frame_index
);
sprintf
(
sname
,
"rxd_frame%d"
,
frame_index
);
LOG_M
(
fname
,
sname
,
&
rxdata
[
0
][
frame_index
*
sl_fp
->
samples_per_frame
],
sl_fp
->
samples_per_frame
,
1
,
1
);
LOG_M
(
"pss_for_correlation0.m"
,
"pss_id0"
,
pss_for_correlation
[
0
],
2048
,
1
,
1
);
LOG_M
(
"pss_for_correlation1.m"
,
"pss_id1"
,
pss_for_correlation
[
1
],
2048
,
1
,
1
);
int64_t
*
pss_corr_debug_values
[
SL_NR_NUM_IDs_IN_PSS
];
#endif
int
maxval
=
0
;
for
(
int
i
=
0
;
i
<
2
*
(
sl_fp
->
ofdm_symbol_size
);
i
++
)
{
maxval
=
max
(
maxval
,
pss_for_correlation
[
0
][
i
]);
maxval
=
max
(
maxval
,
-
pss_for_correlation
[
0
][
i
]);
maxval
=
max
(
maxval
,
pss_for_correlation
[
1
][
i
]);
maxval
=
max
(
maxval
,
-
pss_for_correlation
[
1
][
i
]);
}
int
shift
=
log2_approx
(
maxval
);
//*(sl_fp->ofdm_symbol_size + sl_fp->nb_prefix_samples)*2);
#ifdef SL_DEBUG
LOG_I
(
PHY
,
"SIDELINK SLSS SEARCH: Function:%s
\n
"
,
__func__
);
LOG_I
(
PHY
,
"maxval:%d, shift:%d
\n
"
,
maxval
,
shift
);
#endif
int64_t
avg
[
SL_NR_NUM_IDs_IN_PSS
]
=
{
0
};
int64_t
peak_value
=
0
,
psss_corr_value
=
0
;
unsigned
int
peak_position
=
0
,
pss_source
=
0
;
for
(
int
pss_index
=
0
;
pss_index
<
SL_NR_NUM_IDs_IN_PSS
;
pss_index
++
)
avg
[
pss_index
]
=
0
;
#ifdef SL_DEBUG
int64_t
*
pss_corr_debug_values
[
SL_NR_NUM_IDs_IN_PSS
];
for
(
int
pss_index
=
0
;
pss_index
<
SL_NR_NUM_IDs_IN_PSS
;
pss_index
++
)
pss_corr_debug_values
[
pss_index
]
=
malloc16_clear
(
length
*
sizeof
(
int64_t
));
#endif
for
(
int
n
=
0
;
n
<
length
-
sl_fp
->
ofdm_symbol_size
;
n
+=
4
)
{
//
for
(
int
pss_index
=
0
;
pss_index
<
SL_NR_NUM_IDs_IN_PSS
;
pss_index
++
)
{
psss_corr_value
=
0
;
// calculate dot product of primary_synchro_time_nr and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n];
for
(
int
ar
=
0
;
ar
<
sl_fp
->
nb_antennas_rx
;
ar
++
)
{
/* perform correlation of rx data and pss sequence ie it is a dot product */
const
c32_t
result
=
dot_product
((
c16_t
*
)
pss_for_correlation
[
pss_index
],
(
c16_t
*
)
&
(
rxdata
[
ar
][
n
+
frame_index
*
sl_fp
->
samples_per_frame
]),
sl_fp
->
ofdm_symbol_size
,
shift
);
const
c64_t
r64
=
{.
r
=
result
.
r
,
.
i
=
result
.
i
};
psss_corr_value
+=
squaredMod
(
r64
);
#ifdef SL_DEBUG
pss_corr_debug_values
[
pss_index
][
n
]
=
psss_corr_value
;
printf
(
"frame:%d n:%d, pss_index:%d, pss_for_correlation[pss_index][0]:%x, rxdata[n]:%x
\n
"
,
frame_index
,
n
,
pss_index
,
pss_for_correlation
[
pss_index
][
0
],
rxdata
[
ar
][
n
+
frame_index
*
sl_fp
->
samples_per_frame
]);
printf
(
"result %lld, pss_corr_values[%d][%d]:%ld
\n
"
,
result
,
pss_index
,
n
,
pss_corr_debug_values
[
pss_index
][
n
]);
printf
(
"pss_index %d: n %6u peak_value %15llu
\n
"
,
pss_index
,
n
,
(
unsigned
long
long
)
pss_corr_debug_values
[
pss_index
][
n
]);
printf
(
"peak_value:%ld, peak_position:%d, pss_source:%d
\n
"
,
peak_value
,
peak_position
,
pss_source
);
#endif
}
// calculate the absolute value of sync_corr[n]
avg
[
pss_index
]
+=
psss_corr_value
;
if
(
psss_corr_value
>
peak_value
)
{
peak_value
=
psss_corr_value
;
peak_position
=
n
;
pss_source
=
pss_index
;
#ifdef SL_DEBUG
printf
(
"pss_index %d: n %6u peak_value %15llu
\n
"
,
pss_index
,
n
,
(
unsigned
long
long
)
psss_corr_value
);
#endif
}
}
}
#ifdef SL_DEBUG
LOG_M
(
"pss_corr_debug_values_0.m"
,
"pss_corr0"
,
&
pss_corr_debug_values
[
0
][
0
],
length
,
1
,
6
);
LOG_M
(
"pss_corr_debug_values_1.m"
,
"pss_corr1"
,
&
pss_corr_debug_values
[
1
][
0
],
length
,
1
,
6
);
for
(
int
pss_index
=
0
;
pss_index
<
SL_NR_NUM_IDs_IN_PSS
;
pss_index
++
)
{
free
(
pss_corr_debug_values
[
pss_index
]);
}
#endif
double
ffo_est
=
0
;
if
(
UE
->
UE_fo_compensation
)
{
// Not tested
// fractional frequency offset computation according to Cross-correlation Synchronization Algorithm Using PSS
// Shoujun Huang, Yongtao Su, Ying He and Shan Tang, "Joint time and frequency offset estimation in LTE downlink," 7th
// International Conference on Communications and Networking in China, 2012.
c16_t
*
pss
=
(
c16_t
*
)
pss_for_correlation
[
pss_source
];
c16_t
*
rxd
=
(
c16_t
*
)
&
(
rxdata
[
0
][
peak_position
+
frame_index
*
sl_fp
->
samples_per_frame
]);
int
half_symbol
=
sl_fp
->
ofdm_symbol_size
>>
1
;
// Computing cross-correlation at peak on half the symbol size for first half of data
c32_t
r1
=
dot_product
(
pss
,
rxd
,
half_symbol
,
shift
);
// Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size
// as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift
c32_t
r2
=
dot_product
(
pss
+
half_symbol
,
rxd
+
half_symbol
,
half_symbol
,
shift
);
cd_t
r1d
=
{
r1
.
r
,
r1
.
i
},
r2d
=
{
r2
.
r
,
r2
.
i
};
// estimation of fractional frequency offset: angle[(result1)'*(result2)]/pi
ffo_est
=
atan2
(
r1d
.
r
*
r2d
.
i
-
r2d
.
r
*
r1d
.
i
,
r1d
.
r
*
r2d
.
r
+
r1d
.
i
*
r2d
.
i
)
/
M_PI
;
#ifdef SL_DEBUG
printf
(
"ffo %lf
\n
"
,
ffo_est
);
#endif
}
// computing absolute value of frequency offset
sync_params
->
freq_offset
=
ffo_est
*
sl_fp
->
subcarrier_spacing
;
for
(
int
pss_index
=
0
;
pss_index
<
SL_NR_NUM_IDs_IN_PSS
;
pss_index
++
)
avg
[
pss_index
]
/=
(
length
/
4
);
sync_params
->
N_sl_id2
=
pss_source
;
LOG_I
(
PHY
,
"PSS Source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB, ffo %lf, freq offset:%d Hz
\n
"
,
pss_source
,
peak_position
,
(
unsigned
long
long
)
peak_value
,
dB_fixed64
(
peak_value
),
dB_fixed64
(
avg
[
pss_source
]),
ffo_est
,
sync_params
->
freq_offset
);
if
(
peak_value
<
5
*
avg
[
pss_source
])
return
(
-
1
);
return
peak_position
;
}
static
void
sl_nr_extract_sss
(
PHY_VARS_NR_UE
*
ue
,
UE_nr_rxtx_proc_t
*
proc
,
int32_t
*
tot_metric
,
uint8_t
*
phase_max
,
c16_t
rxdataF
[][
ue
->
SL_UE_PHY_PARAMS
.
sl_frame_params
.
samples_per_slot_wCP
])
{
c16_t
pss_ext
[
SL_NR_MAX_RX_ANTENNA
][
SL_NR_NUM_PSS_SYMBOLS
][
SL_NR_PSS_SEQUENCE_LENGTH
];
c16_t
sss_ext
[
SL_NR_MAX_RX_ANTENNA
][
SL_NR_NUM_SSS_SYMBOLS
][
SL_NR_PSS_SEQUENCE_LENGTH
];
uint8_t
Nid2
=
ue
->
SL_UE_PHY_PARAMS
.
sync_params
.
N_sl_id2
;
NR_DL_FRAME_PARMS
*
sl_fp
=
&
ue
->
SL_UE_PHY_PARAMS
.
sl_frame_params
;
int16_t
*
d
;
uint16_t
Nid1
=
0
;
uint8_t
phase
;
c16_t
*
rxF_ext
;
for
(
int
aarx
=
0
;
aarx
<
sl_fp
->
nb_antennas_rx
;
aarx
++
)
{
unsigned
int
ofdm_symbol_size
=
sl_fp
->
ofdm_symbol_size
;
// pss, sss extraction
for
(
int
sym
=
SL_NR_FIRST_PSS_SYMBOL
;
sym
<
SL_NR_FIRST_PSS_SYMBOL
+
SL_NR_NUM_PSS_SSS_SYMBOLS
;
sym
++
)
{
if
(
sym
<
SL_NR_FIRST_PSS_SYMBOL
+
SL_NR_NUM_PSS_SYMBOLS
)
{
rxF_ext
=
&
pss_ext
[
aarx
][
sym
-
SL_NR_FIRST_PSS_SYMBOL
][
0
];
}
else
{
rxF_ext
=
&
sss_ext
[
aarx
][
sym
-
SL_NR_FIRST_SSS_SYMBOL
][
0
];
}
unsigned
int
k
=
sl_fp
->
first_carrier_offset
+
sl_fp
->
ssb_start_subcarrier
+
2
;
if
(
k
>=
ofdm_symbol_size
)
k
-=
ofdm_symbol_size
;
LOG_D
(
PHY
,
"firstcarrieroffset:%d, ssb_sc:%d, k:%d, symbol:%d
\n
"
,
sl_fp
->
first_carrier_offset
,
sl_fp
->
ssb_start_subcarrier
,
k
,
sym
);
for
(
int
i
=
0
;
i
<
SL_NR_PSS_SEQUENCE_LENGTH
;
i
++
)
{
rxF_ext
[
i
]
=
rxdataF
[
aarx
][
sym
*
ofdm_symbol_size
+
k
];
k
++
;
if
(
k
==
ofdm_symbol_size
)
k
=
0
;
}
}
LOG_D
(
PHY
,
"SIDELINK SLSS SEARCH: EXTRACTION OF PSS, SSS done
\n
"
);
#ifdef SL_DEBUG
LOG_M
(
"pss_ext_sym1.m"
,
"pss_ext1"
,
&
pss_ext
[
aarx
][
0
][
0
],
SL_NR_PSS_SEQUENCE_LENGTH
,
1
,
1
);
LOG_M
(
"pss_ext_sym2.m"
,
"pss_ext2"
,
&
pss_ext
[
aarx
][
1
][
0
],
SL_NR_PSS_SEQUENCE_LENGTH
,
1
,
1
);
LOG_M
(
"sss_ext_sym3.m"
,
"sss_ext3"
,
&
sss_ext
[
aarx
][
0
][
0
],
SL_NR_PSS_SEQUENCE_LENGTH
,
1
,
1
);
LOG_M
(
"sss_ext_sym4.m"
,
"sss_ext4"
,
&
sss_ext
[
aarx
][
1
][
0
],
SL_NR_PSS_SEQUENCE_LENGTH
,
1
,
1
);
#endif
// get conjugated channel estimate from PSS, H* = R* \cdot PSS
// and do channel estimation and compensation based on PSS
int16_t
*
pss
=
ue
->
SL_UE_PHY_PARAMS
.
init_params
.
sl_pss_for_sync
[
Nid2
];
c16_t
*
pss_ext2
,
*
sss_ext2
;
// 2 Symbols each for PSS and SSS
for
(
int
j
=
0
;
j
<
SL_NR_NUM_PSS_OR_SSS_SYMBOLS
;
j
++
)
{
sss_ext2
=
&
sss_ext
[
aarx
][
j
][
0
];
pss_ext2
=
&
pss_ext
[
aarx
][
j
][
0
];
for
(
int
i
=
0
;
i
<
SL_NR_PSS_SEQUENCE_LENGTH
;
i
++
)
{
// This is H*(PSS) = R* \cdot PSS
c16_t
tmp
=
{.
r
=
(
pss_ext2
[
i
].
r
*
pss
[
i
]),
.
i
=
(
-
pss_ext2
[
i
].
i
*
pss
[
i
])};
int
amp
=
c16amp2
(
tmp
);
int
shift
=
log2_approx
(
amp
)
/
2
;
// This is R(SSS) \cdot H*(PSS)
c16_t
tmp2
=
c16mulShift
(
tmp
,
sss_ext2
[
i
],
shift
);
// MRC on RX antennas
// sss_ext now contains the compensated SSS
if
(
aarx
==
0
)
{
sss_ext2
[
i
].
r
=
tmp2
.
r
;
sss_ext2
[
i
].
i
=
tmp2
.
i
;
}
else
{
AssertFatal
(
1
==
0
,
"SIDELINK MORE THAN 1 RX ANTENNA NOT YET SUPPORTED
\n
"
);
}
}
}
LOG_D
(
PHY
,
"SIDELINK SLSS SEARCH: Ch. estimation SSS done
\n
"
);
}
/*
#ifdef SL_DEBUG
write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_subframe,1,1);
write_output("rxdataF0_pss.m","rxF0_pss",&ue->common_vars.rxdataF[0][0],frame_parms->ofdm_symbol_size,1,1);
write_output("rxdataF0_sss.m","rxF0_sss",&ue->common_vars.rxdataF[0][(SSS_SYMBOL_NB-PSS_SYMBOL_NB)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
write_output("pss_ext.m","pss_ext",pss_ext,LENGTH_PSS_NR,1,1);
#endif
*/
/* for phase evaluation, one uses an array of possible phase shifts */
/* then a correlation is done between received signal with a shift pĥase and the reference signal */
/* Computation of signal with shift phase is based on below formula */
/* cosinus cos(x + y) = cos(x)cos(y) - sin(x)sin(y) */
/* sinus sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */
// now do the SSS detection based on the pre computed SSS sequences
*
tot_metric
=
INT_MIN
;
c16_t
*
sss
=
&
sss_ext
[
0
][
0
][
0
];
for
(
uint16_t
id1
=
0
;
id1
<
SL_NR_NUM_IDs_IN_SSS
;
id1
++
)
{
// all possible SSS Nid1 values
for
(
phase
=
0
;
phase
<
PHASE_HYPOTHESIS_NUMBER
;
phase
++
)
{
// phase offset between PSS and SSS
int32_t
metric
=
0
,
metric_re
=
0
;
d
=
(
int16_t
*
)
&
ue
->
SL_UE_PHY_PARAMS
.
init_params
.
sl_sss_for_sync
[
Nid2
*
SL_NR_NUM_IDs_IN_SSS
+
id1
];
// This is the inner product using one particular value of each unknown parameter
for
(
int
i
=
0
;
i
<
SL_NR_SSS_SEQUENCE_LENGTH
;
i
++
)
{
metric_re
+=
d
[
i
]
*
(((
int64_t
)
phase_nr
[
phase
].
r
*
sss
[
i
].
r
-
phase_nr
[
phase
].
i
*
sss
[
i
].
i
)
>>
15
);
}
metric
=
metric_re
;
// if the current metric is better than the last save it
if
(
metric
>
*
tot_metric
)
{
*
tot_metric
=
metric
;
Nid1
=
id1
;
*
phase_max
=
phase
;
LOG_D
(
PHY
,
"(phase,Nid1) (%d,%d), metric_phase %d tot_metric %d, phase_max %d
\n
"
,
phase
,
Nid1
,
metric
,
*
tot_metric
,
*
phase_max
);
}
}
}
ue
->
SL_UE_PHY_PARAMS
.
sync_params
.
N_sl_id1
=
Nid1
;
ue
->
SL_UE_PHY_PARAMS
.
sync_params
.
N_sl_id
=
ue
->
SL_UE_PHY_PARAMS
.
sync_params
.
N_sl_id1
+
SL_NR_NUM_IDs_IN_SSS
*
ue
->
SL_UE_PHY_PARAMS
.
sync_params
.
N_sl_id2
;
LOG_I
(
PHY
,
"UE[%d]NR-SL SLSS SEARCH: SSS Processing over. id2 from SSS:%d, id1 from PSS:%d, SLSS id:%d
\n
"
,
ue
->
Mod_id
,
ue
->
SL_UE_PHY_PARAMS
.
sync_params
.
N_sl_id1
,
ue
->
SL_UE_PHY_PARAMS
.
sync_params
.
N_sl_id2
,
ue
->
SL_UE_PHY_PARAMS
.
sync_params
.
N_sl_id
);
#ifdef SL_DEBUG
#define SSS_METRIC_FLOOR_NR (30000)
if
(
*
tot_metric
>
SSS_METRIC_FLOOR_NR
)
{
Nid2
=
ue
->
SL_UE_PHY_PARAMS
.
sync_params
.
N_sl_id2
;
Nid1
=
ue
->
SL_UE_PHY_PARAMS
.
sync_params
.
N_sl_id1
;
printf
(
"Nid2 %d Nid1 %d tot_metric %d, phase_max %d
\n
"
,
Nid2
,
Nid1
,
*
tot_metric
,
*
phase_max
);
}
#endif
return
;
}
// Right now 2 frames worth of samples get processed for PSS in OAI.
// For PSS in Sidelink, worst case 1 SSB in 16 frames can be present
// Hence 16 frames worth of samples needs to be correlated to find the PSS.
nr_initial_sync_t
sl_nr_slss_search
(
PHY_VARS_NR_UE
*
UE
,
UE_nr_rxtx_proc_t
*
proc
,
int
num_frames
)
{
sl_nr_ue_phy_params_t
*
sl_ue
=
&
UE
->
SL_UE_PHY_PARAMS
;
SL_NR_SYNC_PARAMS_t
*
sync_params
=
&
sl_ue
->
sync_params
;
NR_DL_FRAME_PARMS
*
sl_fp
=
&
UE
->
SL_UE_PHY_PARAMS
.
sl_frame_params
;
int32_t
sync_pos
=
-
1
;
// sync_pos_frame = -1;
int32_t
metric_tdd_ncp
=
0
;
uint8_t
phase_tdd_ncp
;
double
im
,
re
;
int
ret
=
-
1
;
uint16_t
rx_slss_id
=
65535
;
nr_initial_sync_t
result
=
{
true
,
0
};
#ifdef SL_DEBUG_SEARCH_SLSS
LOG_D
(
PHY
,
"SIDELINK SEARCH SLSS: Function:%s
\n
"
,
__func__
);
#endif
/* Initial synchronisation
*
* 1 radio frame = 10 ms
* <--------------------------------------------------------------------------->
* | Received UE data buffer |
* ----------------------------------------------------------------------------
* <-------------->|psbch|pss|pss|sss|sss|psbch sym5-sym 12|sym13 - guard|
* sync_pos SS/PSBCH block
*/
// initial sync performed on 16 successive frames. Worst case - one PSBCH can be sent in 16 frames.
// If psbch passes on first frame, no need to process second frame
// Problem with the frame approach is that
// --------- SSB can be on the boundary between frames. In this case if only 1 SSB is sent we will miss it.
// rxdata will hold 16 frames + slot worth of samples. This needs to be processed to find the best SSB
for
(
int
frame_index
=
0
;
frame_index
<
num_frames
;
frame_index
++
)
{
/* process pss search on received buffer */
sync_pos
=
sl_nr_pss_correlation
(
UE
,
frame_index
);
if
(
sync_pos
==
-
1
)
{
LOG_I
(
PHY
,
"SIDELINK SEARCH SLSS: No PSSS found in this frame
\n
"
);
continue
;
}
sync_pos
+=
frame_index
*
sl_fp
->
samples_per_frame
;
// position in the num_frames frame samples
for
(
int
pss_sym
=
1
;
pss_sym
<
3
;
pss_sym
++
)
{
// Now Sync pos can point to PSS 1st symbol or 2nd symbol.
// Right now implemented the strategy to try both locations for FFT
// Think about a better correlation strategy
if
(
pss_sym
==
1
)
{
// Check if sync pos points to SYMBOL1 - first symbol of PSS location
if
(
sync_pos
>
sl_fp
->
nb_prefix_samples0
+
sl_fp
->
ofdm_symbol_size
+
sl_fp
->
nb_prefix_samples
)
sync_params
->
ssb_offset
=
sync_pos
-
(
sl_fp
->
nb_prefix_samples0
+
sl_fp
->
ofdm_symbol_size
+
sl_fp
->
nb_prefix_samples
);
else
sync_params
->
ssb_offset
=
sync_pos
+
sl_fp
->
samples_per_frame
-
(
sl_fp
->
nb_prefix_samples0
+
sl_fp
->
ofdm_symbol_size
+
sl_fp
->
nb_prefix_samples
);
}
else
{
// Check if sync pos points to SYMBOL2 - second symbol of PSS location
if
(
sync_pos
>=
sl_fp
->
nb_prefix_samples0
+
2
*
(
sl_fp
->
ofdm_symbol_size
+
sl_fp
->
nb_prefix_samples
))
sync_params
->
ssb_offset
=
sync_pos
-
(
sl_fp
->
nb_prefix_samples0
+
2
*
(
sl_fp
->
ofdm_symbol_size
+
sl_fp
->
nb_prefix_samples
));
else
sync_params
->
ssb_offset
=
sync_pos
+
sl_fp
->
samples_per_frame
-
(
sl_fp
->
nb_prefix_samples0
+
2
*
(
sl_fp
->
ofdm_symbol_size
+
sl_fp
->
nb_prefix_samples
));
}
LOG_I
(
PHY
,
"UE[%d]SIDELINK SEARCH SLSS: PSS Peak at %d, PSS sym:%d, Estimated PSS position %d
\n
"
,
UE
->
Mod_id
,
sync_pos
,
pss_sym
,
sync_params
->
ssb_offset
);
int
slss_block_samples
=
(
SL_NR_NUMSYM_SLSS_NORMAL_CP
*
sl_fp
->
ofdm_symbol_size
)
+
(
SL_NR_NUMSYM_SLSS_NORMAL_CP
-
1
)
*
sl_fp
->
nb_prefix_samples
+
sl_fp
->
nb_prefix_samples0
;
int
ssb_end_position
=
sync_params
->
ssb_offset
+
slss_block_samples
;
LOG_D
(
PHY
,
"ssb_end:%d ssb block samples:%d total samples: %d
\n
"
,
ssb_end_position
,
slss_block_samples
,
num_frames
*
sl_fp
->
samples_per_frame
);
/* check that SSS/PBCH block is continuous inside the received buffer */
if
(
ssb_end_position
<
num_frames
*
sl_fp
->
samples_per_frame
)
{
// digital compensation of FFO for SSB symbols
if
(
UE
->
UE_fo_compensation
)
{
// This code to be checked. Why do we do this before PSS detection is successful?
double
s_time
=
1
/
(
1.0e3
*
sl_fp
->
samples_per_subframe
);
// sampling time
double
off_angle
=
-
2
*
M_PI
*
s_time
*
(
sync_params
->
freq_offset
);
// offset rotation angle compensation per sample
int
start
=
sync_params
->
ssb_offset
;
// start for offset correction is at ssb_offset (pss time position)
// Adapt this for other numerologies number of symbols with larger cp increases TBD
int
end
=
ssb_end_position
;
// loop over samples in all symbols (ssb size), including prefix
LOG_I
(
PHY
,
"SLSS SEARCH: FREQ comp of SLSS samples. Freq_OFSET:%d, startpos:%d, end_pos:%d
\n
"
,
sync_params
->
freq_offset
,
start
,
end
);
for
(
int
n
=
start
;
n
<
end
;
n
++
)
{
for
(
int
ar
=
0
;
ar
<
sl_fp
->
nb_antennas_rx
;
ar
++
)
{
re
=
((
double
)(((
short
*
)
UE
->
common_vars
.
rxdata
[
ar
]))[
2
*
n
]);
im
=
((
double
)(((
short
*
)
UE
->
common_vars
.
rxdata
[
ar
]))[
2
*
n
+
1
]);
((
short
*
)
UE
->
common_vars
.
rxdata
[
ar
])[
2
*
n
]
=
(
short
)(
round
(
re
*
cos
(
n
*
off_angle
)
-
im
*
sin
(
n
*
off_angle
)));
((
short
*
)
UE
->
common_vars
.
rxdata
[
ar
])[
2
*
n
+
1
]
=
(
short
)(
round
(
re
*
sin
(
n
*
off_angle
)
+
im
*
cos
(
n
*
off_angle
)));
}
}
}
NR_DL_FRAME_PARMS
*
frame_parms
=
&
UE
->
SL_UE_PHY_PARAMS
.
sl_frame_params
;
const
uint32_t
rxdataF_sz
=
frame_parms
->
samples_per_slot_wCP
;
__attribute__
((
aligned
(
32
)))
c16_t
rxdataF
[
frame_parms
->
nb_antennas_rx
][
rxdataF_sz
];
/* In order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */
for
(
int
symbol
=
0
;
symbol
<
SL_NR_NUMSYM_SLSS_NORMAL_CP
;
symbol
++
)
{
sl_nr_slot_fep
(
UE
,
NULL
,
symbol
,
0
,
sync_params
->
ssb_offset
,
rxdataF
);
}
sl_nr_extract_sss
(
UE
,
NULL
,
&
metric_tdd_ncp
,
&
phase_tdd_ncp
,
rxdataF
);
// save detected cell id to psbch
rx_slss_id
=
UE
->
SL_UE_PHY_PARAMS
.
sync_params
.
N_sl_id
;
__attribute__
((
aligned
(
32
)))
struct
complex16
dl_ch_estimates
[
frame_parms
->
nb_antennas_rx
][
rxdataF_sz
];
__attribute__
((
aligned
(
32
)))
struct
complex16
dl_ch_estimates_time
[
frame_parms
->
nb_antennas_rx
][
frame_parms
->
ofdm_symbol_size
];
uint8_t
decoded_output
[
4
];
for
(
int
symbol
=
0
;
symbol
<
SL_NR_NUMSYM_SLSS_NORMAL_CP
-
1
;)
{
nr_pbch_channel_estimation
(
UE
,
frame_parms
,
rxdataF_sz
,
dl_ch_estimates
,
dl_ch_estimates_time
,
proc
,
symbol
,
symbol
,
0
,
0
,
rxdataF
,
1
,
rx_slss_id
);
symbol
=
(
symbol
==
0
)
?
5
:
symbol
+
1
;
}
ret
=
nr_rx_psbch
(
UE
,
proc
,
rxdataF_sz
,
dl_ch_estimates
,
frame_parms
,
decoded_output
,
rxdataF
,
rx_slss_id
);
result
.
cell_detected
=
(
ret
==
0
)
?
true
:
false
;
if
(
result
.
cell_detected
)
{
// Check this later TBD
// sync at symbol ue->symbol_offset
// computing the offset wrt the beginning of the frame
// SSB located at symbol 0
sync_params
->
remaining_frames
=
(
num_frames
*
sl_fp
->
samples_per_frame
-
sync_params
->
ssb_offset
)
/
sl_fp
->
samples_per_frame
;
// ssb_offset points to start of sl-ssb
// rx_offset points to remaining samples needed to fill a frame
sync_params
->
rx_offset
=
sync_params
->
ssb_offset
%
sl_fp
->
samples_per_frame
;
LOG_I
(
PHY
,
"UE[%d]SIDELINK SLSS SEARCH: PSBCH RX OK. Remainingframes:%d, rx_offset:%d
\n
"
,
UE
->
Mod_id
,
sync_params
->
remaining_frames
,
sync_params
->
rx_offset
);
uint32_t
psbch_payload
=
(
*
(
uint32_t
*
)
decoded_output
);
// retrieve DFN and slot number from SL-MIB
sync_params
->
DFN
=
(((
psbch_payload
&
0x0700
)
>>
1
)
|
((
psbch_payload
&
0xFE0000
)
>>
17
));
sync_params
->
slot_offset
=
(((
psbch_payload
&
0x010000
)
>>
10
)
|
((
psbch_payload
&
0xFC000000
)
>>
26
));
LOG_I
(
PHY
,
"UE[%d]SIDELINK SLSS SEARCH: SL-MIB: DFN:%d, slot:%d.
\n
"
,
UE
->
Mod_id
,
sync_params
->
DFN
,
sync_params
->
slot_offset
);
nr_sl_psbch_rsrp_measurements
(
sl_ue
,
frame_parms
,
rxdataF
,
false
);
UE
->
init_sync_frame
=
sync_params
->
remaining_frames
;
result
.
rx_offset
=
sync_params
->
rx_offset
;
nr_sidelink_indication_t
sl_indication
;
sl_nr_rx_indication_t
rx_ind
=
{
0
};
uint16_t
number_pdus
=
1
;
nr_fill_sl_indication
(
&
sl_indication
,
&
rx_ind
,
NULL
,
proc
,
UE
,
NULL
);
nr_fill_sl_rx_indication
(
&
rx_ind
,
SL_NR_RX_PDU_TYPE_SSB
,
UE
,
number_pdus
,
proc
,
(
void
*
)
decoded_output
,
rx_slss_id
);
LOG_D
(
PHY
,
"Sidelink SLSS SEARCH PSBCH RX OK. Send SL-SSB TO MAC
\n
"
);
if
(
UE
->
if_inst
&&
UE
->
if_inst
->
sl_indication
)
UE
->
if_inst
->
sl_indication
(
&
sl_indication
);
break
;
}
LOG_I
(
PHY
,
"SIDELINK SLSS SEARCH: SLSS ID: %d metric %d, phase %d, psbch CRC %s
\n
"
,
sl_ue
->
sync_params
.
N_sl_id
,
metric_tdd_ncp
,
phase_tdd_ncp
,
(
ret
==
0
)
?
"OK"
:
"NOT OK"
);
}
else
{
LOG_W
(
PHY
,
"SIDELINK SLSS SEARCH: Error: Not enough samples to process PSBCH. sync_pos %d
\n
"
,
sync_pos
);
}
}
if
(
result
.
cell_detected
)
break
;
}
if
(
!
result
.
cell_detected
)
{
// PSBCH not found so indicate sync to higher layers and configure frame parameters
LOG_E
(
PHY
,
"SIDELINK SLSS SEARCH: PSBCH not received. Estimated PSS position:%d
\n
"
,
sync_pos
);
}
return
result
;
}
openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
View file @
ebeb2652
...
...
@@ -43,7 +43,6 @@
//#define DEBUG_PBCH_ENCODING
#define PBCH_A 24
#define PBCH_MAX_RE_PER_SYMBOL (20*12)
#define PBCH_MAX_RE (PBCH_MAX_RE_PER_SYMBOL*4)
#define print_shorts(s,x) printf("%s : %d,%d,%d,%d,%d,%d,%d,%d\n",s,((int16_t*)x)[0],((int16_t*)x)[1],((int16_t*)x)[2],((int16_t*)x)[3],((int16_t*)x)[4],((int16_t*)x)[5],((int16_t*)x)[6],((int16_t*)x)[7])
...
...
@@ -241,20 +240,19 @@ int nr_pbch_channel_level(struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER
return
(
avg2
);
}
static
void
nr_pbch_channel_compensation
(
struct
complex16
rxdataF_ext
[][
PBCH_MAX_RE_PER_SYMBOL
],
void
nr_pbch_channel_compensation
(
struct
complex16
rxdataF_ext
[][
PBCH_MAX_RE_PER_SYMBOL
],
struct
complex16
dl_ch_estimates_ext
[][
PBCH_MAX_RE_PER_SYMBOL
],
int
nb_re
,
struct
complex16
rxdataF_comp
[][
PBCH_MAX_RE_PER_SYMBOL
],
NR_DL_FRAME_PARMS
*
frame_parms
,
uint8_t
output_shift
)
{
uint8_t
output_shift
)
{
for
(
int
aarx
=
0
;
aarx
<
frame_parms
->
nb_antennas_rx
;
aarx
++
)
{
simde__m128i
*
dl_ch128
=
(
simde__m128i
*
)
dl_ch_estimates_ext
[
aarx
];
simde__m128i
*
rxdataF128
=
(
simde__m128i
*
)
rxdataF_ext
[
aarx
];
simde__m128i
*
rxdataF_comp128
=
(
simde__m128i
*
)
rxdataF_comp
[
aarx
];
for
(
int
re
=
0
;
re
<
nb_re
;
re
+=
12
)
{
*
rxdataF_comp128
++
=
mulByConjugate128
(
rxdataF128
++
,
dl_ch128
++
,
output_shift
);
*
rxdataF_comp128
++
=
mulByConjugate128
(
rxdataF128
++
,
dl_ch128
++
,
output_shift
);
for
(
int
re
=
0
;
re
<
nb_re
;
re
+=
4
)
{
*
rxdataF_comp128
++
=
mulByConjugate128
(
rxdataF128
++
,
dl_ch128
++
,
output_shift
);
}
}
...
...
@@ -283,7 +281,7 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
simde_m_empty
();
}
static
void
nr_pbch_unscrambling
(
int16_t
*
demod_pbch_e
,
void
nr_pbch_unscrambling
(
int16_t
*
demod_pbch_e
,
uint16_t
Nid
,
uint8_t
nushift
,
uint16_t
M
,
...
...
@@ -345,9 +343,8 @@ static void nr_pbch_unscrambling(int16_t *demod_pbch_e,
}
}
static
void
nr_pbch_quantize
(
int16_t
*
pbch_llr8
,
int16_t
*
pbch_llr
,
uint16_t
len
)
{
void
nr_pbch_quantize
(
int16_t
*
pbch_llr8
,
int16_t
*
pbch_llr
,
uint16_t
len
)
{
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
if
(
pbch_llr
[
i
]
>
31
)
pbch_llr8
[
i
]
=
32
;
...
...
openair1/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c
0 → 100644
View file @
ebeb2652
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "PHY/defs_nr_UE.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "common/utils/LOG/log.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
// #define DEBUG_PSBCH
static
void
nr_psbch_extract
(
uint32_t
rxdataF_sz
,
c16_t
rxdataF
[][
rxdataF_sz
],
int
estimateSz
,
struct
complex16
dl_ch_estimates
[][
estimateSz
],
struct
complex16
rxdataF_ext
[][
SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL
],
struct
complex16
dl_ch_estimates_ext
[][
SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL
],
uint32_t
symbol
,
NR_DL_FRAME_PARMS
*
frame_params
)
{
uint16_t
rb
;
uint8_t
i
,
j
,
aarx
;
struct
complex16
*
dl_ch0
,
*
dl_ch0_ext
,
*
rxF
,
*
rxF_ext
;
const
uint8_t
nb_rb
=
SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL
;
AssertFatal
((
symbol
==
0
||
symbol
>=
5
),
"SIDELINK: PSBCH DMRS not contained in symbol %d
\n
"
,
symbol
);
for
(
aarx
=
0
;
aarx
<
frame_params
->
nb_antennas_rx
;
aarx
++
)
{
unsigned
int
rx_offset
=
frame_params
->
first_carrier_offset
+
frame_params
->
ssb_start_subcarrier
;
rx_offset
=
rx_offset
%
frame_params
->
ofdm_symbol_size
;
rxF
=
&
rxdataF
[
aarx
][
symbol
*
frame_params
->
ofdm_symbol_size
];
rxF_ext
=
&
rxdataF_ext
[
aarx
][
0
];
dl_ch0
=
&
dl_ch_estimates
[
aarx
][
symbol
*
frame_params
->
ofdm_symbol_size
];
dl_ch0_ext
=
&
dl_ch_estimates_ext
[
aarx
][
0
];
#ifdef DEBUG_PSBCH
LOG_I
(
PHY
,
"extract_rbs: rx_offset=%d, symbol %u
\n
"
,
(
rx_offset
+
(
symbol
*
frame_params
->
ofdm_symbol_size
)),
symbol
);
#endif
for
(
rb
=
0
;
rb
<
nb_rb
;
rb
++
)
{
j
=
0
;
for
(
i
=
0
;
i
<
NR_NB_SC_PER_RB
;
i
++
)
{
if
(
i
%
4
!=
0
)
{
rxF_ext
[
j
]
=
rxF
[
rx_offset
];
dl_ch0_ext
[
j
]
=
dl_ch0
[
i
];
#ifdef DEBUG_PSBCH
LOG_I
(
PHY
,
"rxF ext[%d] = (%d,%d) rxF [%u]= (%d,%d)
\n
"
,
(
9
*
rb
)
+
j
,
rxF_ext
[
j
].
r
,
rxF_ext
[
j
].
i
,
rx_offset
,
rxF
[
rx_offset
].
r
,
rxF
[
rx_offset
].
i
);
LOG_I
(
PHY
,
"dl ch0 ext[%d] = (%d,%d) dl_ch0 [%d]= (%d,%d)
\n
"
,
(
9
*
rb
)
+
j
,
dl_ch0_ext
[
j
].
r
,
dl_ch0_ext
[
j
].
i
,
i
,
dl_ch0
[
i
].
r
,
dl_ch0
[
i
].
i
);
#endif
j
++
;
}
rx_offset
=
(
rx_offset
+
1
)
%
(
frame_params
->
ofdm_symbol_size
);
}
rxF_ext
+=
SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_RB
;
dl_ch0_ext
+=
SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_RB
;
dl_ch0
+=
NR_NB_SC_PER_RB
;
}
#ifdef DEBUG_PSBCH
char
filename
[
40
],
varname
[
25
];
sprintf
(
filename
,
"psbch_dlch_sym_%d.m"
,
symbol
);
sprintf
(
varname
,
"psbch_dlch%d.m"
,
symbol
);
LOG_M
(
filename
,
varname
,
(
void
*
)
dl_ch0
,
frame_params
->
ofdm_symbol_size
,
1
,
1
);
sprintf
(
filename
,
"psbch_dlchext_sym_%d.m"
,
symbol
);
sprintf
(
varname
,
"psbch_dlchext%d.m"
,
symbol
);
LOG_M
(
filename
,
varname
,
(
void
*
)
&
dl_ch_estimates_ext
[
0
][
0
],
SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL
,
1
,
1
);
#endif
}
return
;
}
int
nr_rx_psbch
(
PHY_VARS_NR_UE
*
ue
,
UE_nr_rxtx_proc_t
*
proc
,
int
estimateSz
,
struct
complex16
dl_ch_estimates
[][
estimateSz
],
NR_DL_FRAME_PARMS
*
frame_parms
,
uint8_t
*
decoded_output
,
c16_t
rxdataF
[][
frame_parms
->
samples_per_slot_wCP
],
uint16_t
slss_id
)
{
uint32_t
decoderState
=
0
;
int
psbch_e_rx_idx
=
0
;
// Extra 2 bits needed as polar decoder expects a multiple of 4 as encoder length
// If these 2 bits are not added, runs compiled with --sanitize will fail.
int16_t
psbch_e_rx
[
SL_NR_POLAR_PSBCH_E_NORMAL_CP
+
2
]
=
{
0
};
#ifdef DEBUG_PSBCH
write_output
(
"psbch_rxdataF.m"
,
"psbchrxF"
,
&
rxdataF
[
0
][
0
],
frame_parms
->
ofdm_symbol_size
*
SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP
,
1
,
1
);
#endif
// symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot
double
log2_maxh
=
0
;
// 0 for Normal Cyclic Prefix and 1 for EXT CyclicPrefix
const
int
numsym
=
(
frame_parms
->
Ncp
)
?
SL_NR_NUM_SYMBOLS_SSB_EXT_CP
:
SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP
;
for
(
int
symbol
=
0
;
symbol
<
numsym
;)
{
const
uint16_t
nb_re
=
SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL
;
__attribute__
((
aligned
(
32
)))
struct
complex16
rxdataF_ext
[
frame_parms
->
nb_antennas_rx
][
nb_re
+
1
];
__attribute__
((
aligned
(
32
)))
struct
complex16
dl_ch_estimates_ext
[
frame_parms
->
nb_antennas_rx
][
nb_re
+
1
];
// memset(dl_ch_estimates_ext,0, sizeof dl_ch_estimates_ext);
nr_psbch_extract
(
frame_parms
->
samples_per_slot_wCP
,
rxdataF
,
estimateSz
,
dl_ch_estimates
,
rxdataF_ext
,
dl_ch_estimates_ext
,
symbol
,
frame_parms
);
#ifdef DEBUG_PSBCH
LOG_I
(
PHY
,
"PSBCH RX Symbol %d ofdm size %d
\n
"
,
symbol
,
frame_parms
->
ofdm_symbol_size
);
#endif
int
max_h
=
0
;
if
(
symbol
==
0
)
{
max_h
=
nr_pbch_channel_level
(
dl_ch_estimates_ext
,
frame_parms
,
nb_re
);
// log2_maxh = 3+(log2_approx(max_h)/2);
log2_maxh
=
5
+
(
log2_approx
(
max_h
)
/
2
);
// LLR32 crc error. LLR 16 CRC works
}
#ifdef DEBUG_PSBCH
LOG_I
(
PHY
,
"PSBCH RX log2_maxh = %f (%d)
\n
"
,
log2_maxh
,
max_h
);
#endif
__attribute__
((
aligned
(
32
)))
struct
complex16
rxdataF_comp
[
frame_parms
->
nb_antennas_rx
][
nb_re
+
1
];
nr_pbch_channel_compensation
(
rxdataF_ext
,
dl_ch_estimates_ext
,
nb_re
,
rxdataF_comp
,
frame_parms
,
log2_maxh
);
// log2_maxh+I0_shift
nr_pbch_quantize
(
psbch_e_rx
+
psbch_e_rx_idx
,
(
short
*
)
rxdataF_comp
[
0
],
SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL
);
psbch_e_rx_idx
+=
SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL
;
// SKIP 2 SL-PSS AND 2 SL-SSS symbols
// Symbols carrying PSBCH 0, 5-12
symbol
=
(
symbol
==
0
)
?
5
:
symbol
+
1
;
}
#if 0 // ENABLE SCOPE LATER
UEscopeCopy(ue, psbchRxdataF_comp, psbch_unClipped, sizeof(struct complex16), frame_parms->nb_antennas_rx, psbch_e_rx_idx/2);
UEscopeCopy(ue, psbchLlr, psbch_e_rx, sizeof(int16_t), frame_parms->nb_antennas_rx, psbch_e_rx_idx);
#endif
#ifdef DEBUG_PSBCH
write_output
(
"psbch_rxdataFcomp.m"
,
"psbch_rxFcomp"
,
psbch_unClipped
,
SL_NR_NUM_PSBCH_DATA_RE_IN_ALL_SYMBOLS
,
1
,
1
);
#endif
// un-scrambling
LOG_D
(
PHY
,
"PSBCH RX POLAR DECODING: total PSBCH bits:%d, rx_slss_id:%d
\n
"
,
psbch_e_rx_idx
,
slss_id
);
nr_pbch_unscrambling
(
psbch_e_rx
,
slss_id
,
0
,
0
,
psbch_e_rx_idx
,
0
,
0
,
0
,
NULL
);
// polar decoding de-rate matching
uint64_t
tmp
=
0
;
decoderState
=
polar_decoder_int16
(
psbch_e_rx
,
(
uint64_t
*
)
&
tmp
,
0
,
SL_NR_POLAR_PSBCH_MESSAGE_TYPE
,
SL_NR_POLAR_PSBCH_PAYLOAD_BITS
,
SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL
);
uint32_t
psbch_payload
=
tmp
;
if
(
decoderState
)
{
LOG_D
(
PHY
,
"%d:%d PSBCH RX: NOK
\n
"
,
proc
->
frame_rx
,
proc
->
nr_slot_rx
);
return
(
decoderState
);
}
// Decoder reversal
uint32_t
a_reversed
=
0
;
for
(
int
i
=
0
;
i
<
SL_NR_POLAR_PSBCH_PAYLOAD_BITS
;
i
++
)
a_reversed
|=
(((
uint64_t
)
psbch_payload
>>
i
)
&
1
)
<<
(
31
-
i
);
psbch_payload
=
a_reversed
;
*
((
uint32_t
*
)
decoded_output
)
=
psbch_payload
;
#ifdef DEBUG_PSBCH
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
LOG_I
(
PHY
,
"decoded_output[%d]:%x
\n
"
,
i
,
decoded_output
[
i
]);
}
#endif
ue
->
symbol_offset
=
0
;
// retrieve DFN and slot number from SL-MIB
uint32_t
DFN
=
0
,
slot_offset
=
0
;
DFN
=
(((
psbch_payload
&
0x0700
)
>>
1
)
|
((
psbch_payload
&
0xFE0000
)
>>
17
));
slot_offset
=
(((
psbch_payload
&
0x010000
)
>>
10
)
|
((
psbch_payload
&
0xFC000000
)
>>
26
));
LOG_D
(
PHY
,
"PSBCH RX SL-MIB:%x, decoded DFN:slot %d:%d, %x
\n
"
,
psbch_payload
,
DFN
,
slot_offset
,
*
(
uint32_t
*
)
decoded_output
);
return
0
;
}
openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c
0 → 100644
View file @
ebeb2652
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "PHY/defs_nr_UE.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h"
#include "PHY/MODULATION/nr_modulation.h"
// #define SL_DEBUG
/**
*This function performs PSBCH SCrambling as described in 38.211.
*Input parameter "output" is scrambled and the scrambled output is stored in this parameter.
*id - SLSS ID used for C_INIT
*length is the length of the buffer.
*/
void
sl_psbch_scrambling
(
uint32_t
*
output
,
uint32_t
id
,
uint16_t
length
)
{
uint32_t
x1
,
x2
,
s
=
0
;
// x1 is set in lte_gold_generic
x2
=
id
;
// C_INIT
#ifdef SL_DEBUG
printf
(
"SIDELINK: Function %s
\n
"
,
__func__
);
printf
(
"Scrambling params: length %d id %d
\n
"
,
length
,
id
);
#endif
#ifdef SL_DEBUG
for
(
int
i
=
0
;
i
<
56
;
i
++
)
{
printf
(
"
\n
BEFORE SCRAMBLING output[%d]:0x%x
\n
"
,
i
,
output
[
i
]);
}
#endif
// get initial 32 scrambing bits
s
=
lte_gold_generic
(
&
x1
,
&
x2
,
1
);
#ifdef SL_DEBUG
printf
(
"s: %04x
\t
"
,
s
);
#endif
// scramble in 32bit chunks
int
i
=
0
;
while
(
i
+
32
<=
length
)
{
output
[
i
>>
5
]
^=
s
;
i
+=
32
;
s
=
lte_gold_generic
(
&
x1
,
&
x2
,
0
);
#ifdef SL_DEBUG
printf
(
"s: %04x
\t
"
,
s
);
#endif
}
// scramble remaining bits
for
(;
i
<
length
;
++
i
)
{
output
[
i
>>
5
]
^=
((
s
>>
(
i
&
0x1f
)
&
1
)
<<
(
i
&
0x1f
));
}
#ifdef SL_DEBUG
for
(
int
i
=
0
;
i
<
56
;
i
++
)
{
printf
(
"
\n
AFTER SCRAMBLING output[%d]:0x%x
\n
"
,
i
,
output
[
i
]);
}
#endif
}
/**
*This function RE MAPS PSS, SSS sequences as described in 38.211.
*txF is the data in frequency domain, sync_seq = PSS or SSS seq
*startsym = 1 for PSS, 3 for SSS
*re_offset = sample which points to first RE + SSB start RE
*scaling factor = scaling factor used for PSS, SSS (determined according to PSBCH pwr)
*symbol size = OFDM symbol size used for RE Mapping
*/
void
sl_map_pss_or_sss
(
c16_t
*
txF
,
int16_t
*
sync_seq
,
uint16_t
startsym
,
uint16_t
re_offset
,
uint16_t
scaling_factor
,
uint16_t
symbol_size
)
{
#ifdef SL_DEBUG
printf
(
"%s. DEBUG PSBCH TX: RE MAPPING of PSS/SSS
\n
"
,
__func__
);
printf
(
"Input Params - StartSYM:%d, NUMSYM:%d, RE_OFFSET:%d, num_REs:%d, scaling_factor:%d, symbol_size:%d
\n
"
,
startsym
,
SL_NR_NUM_PSS_OR_SSS_SYMBOLS
,
re_offset
,
SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL
,
scaling_factor
,
symbol_size
);
#endif
// RE Mapping of SL-PSS, SL-SSS
for
(
int
l
=
startsym
;
l
<
(
startsym
+
SL_NR_NUM_PSS_OR_SSS_SYMBOLS
);
l
++
)
{
int
k
=
re_offset
%
symbol_size
;
int
index
=
0
,
offset
=
0
;
for
(
int
m
=
0
;
m
<
SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL
;
m
++
)
{
offset
=
l
*
symbol_size
+
k
;
if
((
m
<
2
)
||
(
m
>=
(
SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL
-
3
)))
{
txF
[
offset
].
r
=
0
;
// Set REs 0,1,129,130,131 = 0
#ifdef SL_DEBUG
printf
(
"sym:%d, RE:%d, txF[%d]:%d.%d
\n
"
,
l
,
m
,
offset
,
txF
[
offset
].
r
,
txF
[
offset
].
i
);
#endif
}
else
{
txF
[
offset
].
r
=
(
sync_seq
[
index
]
*
scaling_factor
)
>>
15
;
#ifdef SL_DEBUG
printf
(
"sym:%d, RE:%d, txF[%d]:%d.%d, syncseq[%d]:%d
\n
"
,
l
,
m
,
offset
,
txF
[
offset
].
r
,
txF
[
offset
].
i
,
index
,
sync_seq
[
index
]);
#endif
index
++
;
}
txF
[
offset
].
i
=
0
;
k
=
(
k
+
1
)
%
symbol_size
;
}
}
}
/**
* This function Generates the PSBCH DATA Modulation symbols and RE MAPS PSBCH Modulated symbols
* and PSBCH DMRS sequences as described in 38.211.
* txF is the data in frequency domain
* payload is the PSBCH payload (SL-MIB given by higher layers)
* id - SLSS ID used for knowing which DMRS sequence to be used.
* Cp - NORMAL of extended Cyclic prefix
* startsym = 0 and then PSBCH is mapped from symbols 5-13 if normal , 5-11 if extended
* re_offset = sample which points to first RE + SSB start RE
* scaling factor = scaling factor used for PSS, SSS (determined according to PSBCH pwr)
* symbol size = OFDM symbol size used for RE Mapping
*/
void
sl_generate_and_map_psbch
(
c16_t
*
txF
,
uint32_t
*
payload
,
uint16_t
id
,
uint16_t
cp
,
uint16_t
re_offset
,
uint16_t
scaling_factor
,
uint16_t
symbol_size
,
c16_t
*
psbch_dmrs
)
{
uint64_t
psbch_a_reversed
=
0
;
uint16_t
num_psbch_modsym
=
0
,
numsym
=
0
;
const
int
mod_order
=
2
;
// QPSK
uint32_t
encoder_output
[
SL_NR_POLAR_PSBCH_E_DWORD
];
struct
complex16
psbch_modsym
[
SL_NR_NUM_PSBCH_MODULATED_SYMBOLS
];
LOG_D
(
PHY
,
"PSBCH TX: Generation accg to 38.212, 38.211. SLSS id:%d
\n
"
,
id
);
// Encoder reversal
for
(
int
i
=
0
;
i
<
SL_NR_POLAR_PSBCH_PAYLOAD_BITS
;
i
++
)
psbch_a_reversed
|=
(((
uint64_t
)
*
payload
>>
i
)
&
1
)
<<
(
31
-
i
);
#ifdef SL_DEBUG
printf
(
"DEBUG PSBCH TX: 38.212 PSBCH CRC + Channel coding (POLAR) + Rate Matching:
\n
"
);
printf
(
"PSBCH payload:%x, Reversed Payload:%016lx
\n
"
,
*
payload
,
psbch_a_reversed
);
#endif
/// CRC, coding and rate matching
polar_encoder_fast
(
&
psbch_a_reversed
,
(
void
*
)
encoder_output
,
0
,
0
,
SL_NR_POLAR_PSBCH_MESSAGE_TYPE
,
SL_NR_POLAR_PSBCH_PAYLOAD_BITS
,
SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL
);
#ifdef SL_DEBUG
for
(
int
i
=
0
;
i
<
SL_NR_POLAR_PSBCH_E_DWORD
;
i
++
)
printf
(
"encoderoutput[%d]: 0x%08x
\t
"
,
i
,
encoder_output
[
i
]);
printf
(
"
\n
"
);
#endif
/// 38.211 Scrambling
if
(
cp
)
{
// EXT Cyclic prefix
sl_psbch_scrambling
(
encoder_output
,
id
,
SL_NR_POLAR_PSBCH_E_EXT_CP
);
// for Extended Cyclic prefix
num_psbch_modsym
=
SL_NR_POLAR_PSBCH_E_EXT_CP
/
mod_order
;
numsym
=
SL_NR_NUM_SYMBOLS_SSB_EXT_CP
;
AssertFatal
(
1
==
0
,
"EXT CP is not yet supported
\n
"
);
}
else
{
// Normal CP
sl_psbch_scrambling
(
encoder_output
,
id
,
SL_NR_POLAR_PSBCH_E_NORMAL_CP
);
// for Cyclic prefix
num_psbch_modsym
=
SL_NR_POLAR_PSBCH_E_NORMAL_CP
/
mod_order
;
numsym
=
SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP
;
}
LOG_D
(
PHY
,
"PSBCH TX: 38.211 Scrambling done. Number of bits:%d
\n
"
,
SL_NR_POLAR_PSBCH_E_NORMAL_CP
);
#ifdef SL_DEBUG
printf
(
"38211 STEP: PSBCH Scrambling
\n
"
);
for
(
int
i
=
0
;
i
<
SL_NR_POLAR_PSBCH_E_NORMAL_CP
/
32
;
i
++
)
printf
(
"Scrambleroutput[%d]: 0x%08x
\t
"
,
i
,
encoder_output
[
i
]);
printf
(
"
\n
"
);
#endif
#ifdef SL_DEBUG
printf
(
"SIDELINK PSBCH TX: 38211 STEP: QPSK Modulation of PSBCH symbols:%d, symbols in PSBCH:%d
\n
"
,
num_psbch_modsym
,
numsym
);
#endif
/// 38.211 QPSK modulation
nr_modulation
(
encoder_output
,
num_psbch_modsym
*
mod_order
,
mod_order
,
(
int16_t
*
)
psbch_modsym
);
// RE MApping of PSBCH and PSBCH DMRS
int
index
=
0
,
dmrs_index
=
0
;
const
int
numre
=
SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL
;
#ifdef SL_DEBUG
LOG_M
(
"sl_psbch_data_symbols.m"
,
"psbch_sym"
,
(
void
*
)
psbch_modsym
,
num_psbch_modsym
,
1
,
1
);
LOG_M
(
"sl_psbch_dmrs_symbols.m"
,
"psbch_dmrs"
,
(
void
*
)
psbch_dmrs
,
SL_NR_NUM_PSBCH_DMRS_RE
,
1
,
1
);
#endif
#ifdef SL_DEBUG
printf
(
"
\n
Mapping Sidelink PSBCH DMRS, PSBCH modulation symbols to 132 REs
\n
"
);
#endif
#ifdef SL_DEBUG
printf
(
"%s. DEBUG PSBCH TX: RE MAPPING of PSBCH DATA AND DMRS
\n
"
,
__func__
);
printf
(
"Input Params - StartSYM:%d, NUMSYM:%d, RE_OFFSET:%d, num_REs:%d, scaling_factor:%d, symbol_size:%d
\n
"
,
0
,
numsym
,
re_offset
,
numre
,
scaling_factor
,
symbol_size
);
#endif
for
(
int
l
=
0
;
l
<
numsym
;)
{
int
k
=
re_offset
%
symbol_size
;
int
symbol_offset
=
l
*
symbol_size
;
int
offset
=
0
;
for
(
int
m
=
0
;
m
<
numre
;
m
++
)
{
// Maps PSBCH DMRS in every 4th RE ex:0,4,....128
// Maps PSBCH in all other REs ex: 1,2,3,5,6,...127,129,130,131
offset
=
symbol_offset
+
k
;
#ifdef SL_DEBUG
printf
(
"symbol:%d, symbol_offset:%d, k:%d, re:%d, sampleoffset:%d "
,
l
,
symbol_offset
,
k
,
m
,
offset
);
#endif
if
(
m
%
4
==
0
)
{
txF
[
offset
]
=
c16xmulConstShift
(
psbch_dmrs
[
dmrs_index
],
scaling_factor
,
15
);
#ifdef SL_DEBUG
printf
(
"txF[%d]:%d,%d, psbch_dmrs[%d]:%d,%d "
,
offset
,
txF
[
offset
].
r
,
txF
[
offset
].
i
,
dmrs_index
,
psbch_dmrs
[
dmrs_index
].
r
,
psbch_dmrs
[
dmrs_index
].
i
);
#endif
dmrs_index
++
;
}
else
{
txF
[
offset
]
=
c16xmulConstShift
(
psbch_modsym
[
index
],
scaling_factor
,
15
);
#ifdef SL_DEBUG
printf
(
"txF[%d]:%d,%d, psbch_modsym[%d]:%d,%d
\n
"
,
offset
,
txF
[
offset
].
r
,
txF
[
offset
].
i
,
index
,
psbch_modsym
[
index
].
r
,
psbch_modsym
[
index
].
i
);
#endif
index
++
;
}
k
=
(
k
+
1
)
%
symbol_size
;
}
LOG_D
(
PHY
,
"PSBCH TX: 38211 STEP: RE MAPPING OF PSBCH, PSBCH DMRS DONE. symbol:%d, first RE offset:%d, Last RE offset:%d, Num PSBCH "
"DATA REs:%d, Num PSBCH DMRS REs:%d
\n
"
,
l
,
symbol_offset
+
re_offset
,
offset
,
index
,
dmrs_index
);
l
=
(
l
==
0
)
?
5
:
l
+
1
;
}
}
/**
*This function prepares the PSBCH block and RE MAPS PSS, SSS, PSBCH DATA, PSBCH DMRS into buffer txF.
*Called by the L1 Scheduler when MAC triggers PHY to send PSBCH
*UE is the UE context.
*frame, slot points to the TTI in which PSBCH TX will be transmitted
*/
void
nr_tx_psbch
(
PHY_VARS_NR_UE
*
UE
,
uint32_t
frame_tx
,
uint32_t
slot_tx
,
sl_nr_tx_config_psbch_pdu_t
*
psbch_vars
,
c16_t
**
txdataF
)
{
sl_nr_ue_phy_params_t
*
sl_ue_phy_params
=
&
UE
->
SL_UE_PHY_PARAMS
;
uint16_t
slss_id
=
psbch_vars
->
tx_slss_id
;
NR_DL_FRAME_PARMS
*
sl_fp
=
&
sl_ue_phy_params
->
sl_frame_params
;
uint32_t
psbch_payload
=
*
((
uint32_t
*
)
psbch_vars
->
psbch_payload
);
LOG_D
(
PHY
,
"PSBCH TX: slss-id %d, psbch payload %x
\n
"
,
slss_id
,
psbch_payload
);
// Insert FN and Slot number into SL-MIB
uint32_t
mask
=
~
(
0x700
|
0xFE0000
|
0x10000
|
0xFC000000
);
psbch_payload
&=
mask
;
psbch_payload
|=
((
frame_tx
%
1024
)
<<
1
)
&
0x700
;
psbch_payload
|=
((
frame_tx
%
1024
)
<<
17
)
&
0xFE0000
;
psbch_payload
|=
(
slot_tx
<<
10
)
&
0x10000
;
psbch_payload
|=
(
slot_tx
<<
26
)
&
0xFC000000
;
#ifdef SL_DEBUG
printf
(
"DEBUG PSBCH TX: DFN, SLOT included. psbch_a :0x%08x, frame:%d, slot:%d
\n
"
,
psbch_payload
,
frame_tx
,
slot_tx
);
#endif
LOG_D
(
PHY
,
"PSBCH TX: Frame.Slot %d.%d. Payload::0x%08x, slssid:%d
\n
"
,
frame_tx
,
slot_tx
,
psbch_payload
,
slss_id
);
// GENERATE Sidelink PSS,SSS Sequences, PSBCH DMRS Symbols, PSBCH Symbols
int16_t
*
sl_pss
=
&
sl_ue_phy_params
->
init_params
.
sl_pss
[
slss_id
/
336
][
0
];
int16_t
*
sl_sss
=
&
sl_ue_phy_params
->
init_params
.
sl_sss
[
slss_id
][
0
];
uint16_t
re_offset
=
sl_fp
->
first_carrier_offset
+
sl_fp
->
ssb_start_subcarrier
;
uint16_t
symbol_size
=
sl_fp
->
ofdm_symbol_size
;
// TBD: Need to be replaced by function which calculates scaling factor based on psbch tx power
uint16_t
scaling_factor
=
AMP
;
struct
complex16
*
txF
=
&
txdataF
[
0
][
0
];
uint16_t
startsym
=
SL_NR_PSS_START_SYMBOL
;
#ifdef SL_DEBUG
printf
(
"DEBUG PSBCH TX: MAP PSS. startsym:%d, PSS RE START:%d, scaling factor:%d
\n
"
,
startsym
,
re_offset
,
scaling_factor
);
#endif
sl_map_pss_or_sss
(
txF
,
sl_pss
,
startsym
,
re_offset
,
scaling_factor
,
symbol_size
);
// PSS
startsym
+=
SL_NR_NUM_PSS_SYMBOLS
;
#ifdef SL_DEBUG
printf
(
"DEBUG PSBCH TX: MAP SSS. startsym:%d, SSS RE START:%d, scaling factor:%d
\n
"
,
startsym
,
re_offset
,
scaling_factor
);
#endif
sl_map_pss_or_sss
(
txF
,
sl_sss
,
startsym
,
re_offset
,
scaling_factor
,
symbol_size
);
// SSS
#ifdef SL_DEBUG
printf
(
"DEBUG PSBCH TX: MAP PSBCH DATA AND DMRS. cyclicPrefix:%d, PSS RE START:%d, scaling factor:%d
\n
"
,
sl_fp
->
Ncp
,
re_offset
,
scaling_factor
);
#endif
struct
complex16
*
psbch_dmrs
=
&
sl_ue_phy_params
->
init_params
.
psbch_dmrs_modsym
[
slss_id
][
0
];
sl_generate_and_map_psbch
(
txF
,
&
psbch_payload
,
slss_id
,
sl_fp
->
Ncp
,
re_offset
,
scaling_factor
,
symbol_size
,
psbch_dmrs
);
#ifdef SL_DEBUG
printf
(
"DEBUG PSBCH TX: txdataF Prepared
\n
"
);
#endif
#ifdef SL_DEBUG
LOG_M
(
"sl_psbch_block.m"
,
"sl_txF"
,
(
void
*
)
txdataF
[
0
],
symbol_size
*
14
,
1
,
1
);
#endif
}
openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
View file @
ebeb2652
...
...
@@ -418,6 +418,40 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
void
dump_nrdlsch
(
PHY_VARS_NR_UE
*
ue
,
uint8_t
gNB_id
,
uint8_t
nr_slot_rx
,
unsigned
int
*
coded_bits_per_codeword
,
int
round
,
unsigned
char
harq_pid
);
void
nr_a_sum_b
(
c16_t
*
input_x
,
c16_t
*
input_y
,
unsigned
short
nb_rb
);
int
nr_rx_psbch
(
PHY_VARS_NR_UE
*
ue
,
UE_nr_rxtx_proc_t
*
proc
,
int
estimateSz
,
struct
complex16
dl_ch_estimates
[][
estimateSz
],
NR_DL_FRAME_PARMS
*
frame_parms
,
uint8_t
*
decoded_output
,
c16_t
rxdataF
[][
frame_parms
->
samples_per_slot_wCP
],
uint16_t
slss_id
);
void
nr_tx_psbch
(
PHY_VARS_NR_UE
*
UE
,
uint32_t
frame_tx
,
uint32_t
slot_tx
,
sl_nr_tx_config_psbch_pdu_t
*
psbch_vars
,
c16_t
**
txdataF
);
nr_initial_sync_t
sl_nr_slss_search
(
PHY_VARS_NR_UE
*
UE
,
UE_nr_rxtx_proc_t
*
proc
,
int
num_frames
);
// Reuse already existing PBCH functions
int
nr_pbch_channel_level
(
struct
complex16
dl_ch_estimates_ext
[][
PBCH_MAX_RE_PER_SYMBOL
],
NR_DL_FRAME_PARMS
*
frame_parms
,
int
nb_re
);
void
nr_pbch_channel_compensation
(
struct
complex16
rxdataF_ext
[][
PBCH_MAX_RE_PER_SYMBOL
],
struct
complex16
dl_ch_estimates_ext
[][
PBCH_MAX_RE_PER_SYMBOL
],
int
nb_re
,
struct
complex16
rxdataF_comp
[][
PBCH_MAX_RE_PER_SYMBOL
],
NR_DL_FRAME_PARMS
*
frame_parms
,
uint8_t
output_shift
);
void
nr_pbch_unscrambling
(
int16_t
*
demod_pbch_e
,
uint16_t
Nid
,
uint8_t
nushift
,
uint16_t
M
,
uint16_t
length
,
uint8_t
bitwise
,
uint32_t
unscrambling_mask
,
uint32_t
pbch_a_prime
,
uint32_t
*
pbch_a_interleaved
);
void
nr_pbch_quantize
(
int16_t
*
pbch_llr8
,
int16_t
*
pbch_llr
,
uint16_t
len
);
/**@}*/
#endif
openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
View file @
ebeb2652
...
...
@@ -704,3 +704,93 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i
return
peak_position
;
}
void
sl_generate_pss
(
SL_NR_UE_INIT_PARAMS_t
*
sl_init_params
,
uint8_t
n_sl_id2
,
uint16_t
scaling
)
{
int
i
=
0
,
m
=
0
;
int16_t
x
[
SL_NR_PSS_SEQUENCE_LENGTH
];
const
int
x_initial
[
7
]
=
{
0
,
1
,
1
,
0
,
1
,
1
,
1
};
int16_t
*
sl_pss
=
sl_init_params
->
sl_pss
[
n_sl_id2
];
int16_t
*
sl_pss_for_sync
=
sl_init_params
->
sl_pss_for_sync
[
n_sl_id2
];
LOG_D
(
PHY
,
"SIDELINK PSBCH INIT: PSS Generation with N_SL_id2:%d
\n
"
,
n_sl_id2
);
#ifdef SL_DEBUG_INIT
printf
(
"SIDELINK: PSS Generation with N_SL_id2:%d
\n
"
,
n_sl_id2
);
#endif
/// Sequence generation
for
(
i
=
0
;
i
<
7
;
i
++
)
x
[
i
]
=
x_initial
[
i
];
for
(
i
=
0
;
i
<
(
SL_NR_PSS_SEQUENCE_LENGTH
-
7
);
i
++
)
{
x
[
i
+
7
]
=
(
x
[
i
+
4
]
+
x
[
i
])
%
2
;
}
for
(
i
=
0
;
i
<
SL_NR_PSS_SEQUENCE_LENGTH
;
i
++
)
{
m
=
(
i
+
22
+
43
*
n_sl_id2
)
%
SL_NR_PSS_SEQUENCE_LENGTH
;
sl_pss_for_sync
[
i
]
=
(
1
-
2
*
x
[
m
]);
sl_pss
[
i
]
=
sl_pss_for_sync
[
i
]
*
scaling
;
#ifdef SL_DEBUG_INIT_DATA
printf
(
"m:%d, sl_pss[%d]:%d
\n
"
,
m
,
i
,
sl_pss
[
i
]);
#endif
}
#ifdef SL_DUMP_INIT_SAMPLES
LOG_M
(
"sl_pss_seq.m"
,
"sl_pss"
,
(
void
*
)
sl_pss
,
SL_NR_PSS_SEQUENCE_LENGTH
,
1
,
0
);
#endif
}
// This cannot be done at init time as ofdm symbol size, ssb start subcarrier depends on configuration
// done at SLSS read time.
void
sl_generate_pss_ifft_samples
(
sl_nr_ue_phy_params_t
*
sl_ue_params
,
SL_NR_UE_INIT_PARAMS_t
*
sl_init_params
)
{
uint8_t
id2
=
0
;
int16_t
*
sl_pss
=
NULL
;
NR_DL_FRAME_PARMS
*
sl_fp
=
&
sl_ue_params
->
sl_frame_params
;
int16_t
scaling_factor
=
AMP
;
int32_t
*
pss_T
=
NULL
;
uint16_t
k
=
0
;
c16_t
pss_F
[
sl_fp
->
ofdm_symbol_size
];
// IQ samples in freq domain
LOG_I
(
PHY
,
"SIDELINK INIT: Generation of PSS time domain samples. scaling_factor:%d
\n
"
,
scaling_factor
);
for
(
id2
=
0
;
id2
<
SL_NR_NUM_IDs_IN_PSS
;
id2
++
)
{
k
=
sl_fp
->
first_carrier_offset
+
sl_fp
->
ssb_start_subcarrier
+
2
;
// PSS in from REs 2-129
if
(
k
>=
sl_fp
->
ofdm_symbol_size
)
k
-=
sl_fp
->
ofdm_symbol_size
;
pss_T
=
&
sl_init_params
->
sl_pss_for_correlation
[
id2
][
0
];
sl_pss
=
sl_init_params
->
sl_pss
[
id2
];
memset
(
pss_T
,
0
,
sl_fp
->
ofdm_symbol_size
*
sizeof
(
pss_T
[
0
]));
memset
(
pss_F
,
0
,
sl_fp
->
ofdm_symbol_size
*
sizeof
(
c16_t
));
for
(
int
i
=
0
;
i
<
SL_NR_PSS_SEQUENCE_LENGTH
;
i
++
)
{
pss_F
[
k
].
r
=
(
sl_pss
[
i
]
*
scaling_factor
)
>>
15
;
// pss_F[2*k] = (sl_pss[i]/23170) * 4192;
// pss_F[2*k+1] = 0;
#ifdef SL_DEBUG_INIT_DATA
printf
(
"id:%d, k:%d, pss_F[%d]:%d, sl_pss[%d]:%d
\n
"
,
id2
,
k
,
2
*
k
,
pss_F
[
2
*
k
],
i
,
sl_pss
[
i
]);
#endif
k
++
;
if
(
k
==
sl_fp
->
ofdm_symbol_size
)
k
=
0
;
}
idft
((
int16_t
)
get_idft
(
sl_fp
->
ofdm_symbol_size
),
(
int16_t
*
)
&
pss_F
[
0
],
/* complex input */
(
int16_t
*
)
&
pss_T
[
0
],
/* complex output */
1
);
/* scaling factor */
}
#ifdef SL_DUMP_PSBCH_TX_SAMPLES
LOG_M
(
"sl_pss_TD_id0.m"
,
"pss_TD_0"
,
(
void
*
)
sl_init_params
->
sl_pss_for_correlation
[
0
],
sl_fp
->
ofdm_symbol_size
,
1
,
1
);
LOG_M
(
"sl_pss_TD_id1.m"
,
"pss_TD_1"
,
(
void
*
)
sl_init_params
->
sl_pss_for_correlation
[
1
],
sl_fp
->
ofdm_symbol_size
,
1
,
1
);
#endif
}
openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
View file @
ebeb2652
...
...
@@ -63,13 +63,6 @@
#define INITIAL_SSS_NR (7)
static
const
int16_t
phase_re_nr
[
PHASE_HYPOTHESIS_NUMBER
]
// -pi/3 ---- pi/3
=
{
16384
,
20173
,
23571
,
26509
,
28932
,
30791
,
32051
,
32687
,
32687
,
32051
,
30791
,
28932
,
26509
,
23571
,
20173
,
16384
};
static
const
int16_t
phase_im_nr
[
PHASE_HYPOTHESIS_NUMBER
]
// -pi/3 ---- pi/3
=
{
-
28377
,
-
25821
,
-
22762
,
-
19260
,
-
15383
,
-
11207
,
-
6813
,
-
2286
,
2286
,
6813
,
11207
,
15383
,
19260
,
22762
,
25821
,
28377
};
static
int16_t
d_sss
[
N_ID_2_NUMBER
][
N_ID_1_NUMBER
][
LENGTH_SSS_NR
];
void
init_context_sss_nr
(
int
amp
)
...
...
@@ -475,7 +468,7 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
// This is the inner product using one particular value of each unknown parameter
for
(
i
=
0
;
i
<
LENGTH_SSS_NR
;
i
++
)
{
metric_re
+=
d
[
i
]
*
((
phase_
re_nr
[
phase
]
*
sss
[
i
].
r
-
phase_im_nr
[
phase
]
*
sss
[
i
].
i
)
>>
SCALING_METRIC_SSS_NR
);
metric_re
+=
d
[
i
]
*
((
phase_
nr
[
phase
].
r
*
sss
[
i
].
r
-
phase_nr
[
phase
].
i
*
sss
[
i
].
i
)
>>
SCALING_METRIC_SSS_NR
);
}
metric
=
metric_re
;
...
...
@@ -537,3 +530,51 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
return
true
;
}
void
sl_generate_sss
(
SL_NR_UE_INIT_PARAMS_t
*
sl_init_params
,
uint16_t
slss_id
,
uint16_t
scaling
)
{
int
i
=
0
;
int
m0
,
m1
;
int
n_sl_id1
,
n_sl_id2
;
int16_t
*
sl_sss
=
sl_init_params
->
sl_sss
[
slss_id
];
int16_t
*
sl_sss_for_sync
=
sl_init_params
->
sl_sss_for_sync
[
slss_id
];
int16_t
x0
[
SL_NR_SSS_SEQUENCE_LENGTH
],
x1
[
SL_NR_SSS_SEQUENCE_LENGTH
];
const
int
x_initial
[
7
]
=
{
1
,
0
,
0
,
0
,
0
,
0
,
0
};
n_sl_id1
=
slss_id
%
336
;
n_sl_id2
=
slss_id
/
336
;
LOG_D
(
PHY
,
"SIDELINK INIT: SSS Generation with N_SL_id1:%d N_SL_id2:%d
\n
"
,
n_sl_id1
,
n_sl_id2
);
#ifdef SL_DEBUG_INIT
printf
(
"SIDELINK: SSS Generation with slss_id:%d, N_SL_id1:%d, N_SL_id2:%d
\n
"
,
slss_id
,
n_sl_id1
,
n_sl_id2
);
#endif
for
(
i
=
0
;
i
<
7
;
i
++
)
{
x0
[
i
]
=
x_initial
[
i
];
x1
[
i
]
=
x_initial
[
i
];
}
for
(
i
=
0
;
i
<
SL_NR_SSS_SEQUENCE_LENGTH
-
7
;
i
++
)
{
x0
[
i
+
7
]
=
(
x0
[
i
+
4
]
+
x0
[
i
])
%
2
;
x1
[
i
+
7
]
=
(
x1
[
i
+
1
]
+
x1
[
i
])
%
2
;
}
m0
=
15
*
(
n_sl_id1
/
112
)
+
(
5
*
n_sl_id2
);
m1
=
n_sl_id1
%
112
;
for
(
i
=
0
;
i
<
SL_NR_SSS_SEQUENCE_LENGTH
;
i
++
)
{
sl_sss_for_sync
[
i
]
=
(
1
-
2
*
x0
[(
i
+
m0
)
%
SL_NR_SSS_SEQUENCE_LENGTH
])
*
(
1
-
2
*
x1
[(
i
+
m1
)
%
SL_NR_SSS_SEQUENCE_LENGTH
]);
sl_sss
[
i
]
=
sl_sss_for_sync
[
i
]
*
scaling
;
#ifdef SL_DEBUG_INIT_DATA
printf
(
"m0:%d, m1:%d, sl_sss_for_sync[%d]:%d, sl_sss[%d]:%d
\n
"
,
m0
,
m1
,
i
,
sl_sss_for_sync
[
i
],
i
,
sl_sss
[
i
]);
#endif
}
#ifdef SL_DUMP_PSBCH_TX_SAMPLES
LOG_M
(
"sl_sss_seq.m"
,
"sl_sss"
,
(
void
*
)
sl_sss
,
SL_NR_SSS_SEQUENCE_LENGTH
,
1
,
0
);
LOG_M
(
"sl_sss_forsync_seq.m"
,
"sl_sss_for_sync"
,
(
void
*
)
sl_sss_for_sync
,
SL_NR_SSS_SEQUENCE_LENGTH
,
1
,
0
);
#endif
}
openair1/PHY/TOOLS/tools_defs.h
View file @
ebeb2652
...
...
@@ -242,6 +242,11 @@ extern "C" {
};
}
__attribute__
((
always_inline
))
inline
c16_t
c16xmulConstShift
(
const
c16_t
a
,
const
int
b
,
const
int
Shift
)
{
return
(
c16_t
){.
r
=
(
int16_t
)((
a
.
r
*
b
)
>>
Shift
),
.
i
=
(
int16_t
)((
a
.
i
*
b
)
>>
Shift
)};
}
__attribute__
((
always_inline
))
inline
c32_t
c32x16maddShift
(
const
c16_t
a
,
const
c16_t
b
,
const
c32_t
c
,
const
int
Shift
)
{
return
(
c32_t
)
{
.
r
=
((
a
.
r
*
b
.
r
-
a
.
i
*
b
.
i
)
>>
Shift
)
+
c
.
r
,
...
...
openair1/PHY/defs_nr_UE.h
View file @
ebeb2652
...
...
@@ -39,6 +39,7 @@
#include "defs_nr_common.h"
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "PHY/defs_nr_sl_UE.h"
#include <stdio.h>
#include <stdlib.h>
...
...
@@ -591,6 +592,10 @@ typedef struct PHY_VARS_NR_UE_s {
uint8_t
*
phy_sim_dlsch_b
;
notifiedFIFO_t
tx_resume_ind_fifo
[
NR_MAX_SLOTS_PER_FRAME
];
// Sidelink parameters
sl_nr_sidelink_mode_t
sl_mode
;
sl_nr_ue_phy_params_t
SL_UE_PHY_PARAMS
;
}
PHY_VARS_NR_UE
;
typedef
struct
{
...
...
@@ -612,11 +617,20 @@ typedef struct {
typedef
struct
nr_phy_data_tx_s
{
NR_UE_ULSCH_t
ulsch
;
NR_UE_PUCCH
pucch_vars
;
// Sidelink Rx action decided by MAC
sl_nr_tx_config_type_enum_t
sl_tx_action
;
sl_nr_tx_config_psbch_pdu_t
psbch_vars
;
}
nr_phy_data_tx_t
;
typedef
struct
nr_phy_data_s
{
NR_UE_PDCCH_CONFIG
phy_pdcch_config
;
NR_UE_DLSCH_t
dlsch
[
2
];
// Sidelink Rx action decided by MAC
sl_nr_rx_config_type_enum_t
sl_rx_action
;
}
nr_phy_data_t
;
/* this structure is used to pass both UE phy vars and
* proc to the function UE_thread_rxn_txnp4
...
...
openair1/PHY/defs_nr_common.h
View file @
ebeb2652
...
...
@@ -96,6 +96,8 @@
#define MAX_DELAY_COMP 20
#define PBCH_MAX_RE_PER_SYMBOL (20 * 12)
typedef
enum
{
NR_MU_0
=
0
,
NR_MU_1
,
...
...
@@ -168,8 +170,6 @@ struct NR_DL_FRAME_PARMS {
/// Frame type (0 FDD, 1 TDD)
frame_type_t
frame_type
;
uint8_t
tdd_config
;
/// Sidelink Cell ID
uint16_t
Nid_SL
;
/// Cell ID
uint16_t
Nid_cell
;
/// subcarrier spacing (15,30,60,120)
...
...
openair1/PHY/defs_nr_sl_UE.h
0 → 100644
View file @
ebeb2652
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/defs_nr_sl_UE.h
\brief Top-level defines and structure definitions
\author
\date
\version
\company Fraunhofer
\email:
\note
\warning
*/
#ifndef _DEFS_NR_SL_UE_H_
#define _DEFS_NR_SL_UE_H_
#include "PHY/types.h"
#include "PHY/defs_nr_common.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h"
#include "common/utils/time_meas.h"
// (33*(13-4))
// Normal CP - NUM_SSB_Symbols = 13. 4 symbols for PSS, SSS
#define SL_NR_NUM_PSBCH_DMRS_RE 297
// ceil(2(QPSK)*SL_NR_NUM_PSBCH_DMRS_RE/32)
#define SL_NR_NUM_PSBCH_DMRS_RE_DWORD 20
// 11 RBs for PSBCH in one symbol * 12 REs
#define SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL 132
// 3 DMRS REs per RB * 11 RBS in one symbol
#define SL_NR_NUM_PSBCH_DMRS_RE_IN_ONE_SYMBOL 33
// 9 PSBCH DATA REs * 11 RBS in one symbol
#define SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL 99
#define SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL 11
// SL_NR_POLAR_PSBCH_E_NORMAL_CP/2 bits because QPSK used for PSBCH.
// 11 * (12-3 DMRS REs) * 9 symbols for PSBCH
#define SL_NR_NUM_PSBCH_MODULATED_SYMBOLS 891
#define SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_RB 9
#define SL_NR_NUM_PSBCH_DMRS_RE_IN_ONE_RB 3
// 11 * (12-3 DMRS REs) * 9 symbols for PSBCH
#define SL_NR_NUM_PSBCH_DATA_RE_IN_ALL_SYMBOLS 891
#define SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP 13
#define SL_NR_NUM_SYMBOLS_SSB_EXT_CP 11
#define SL_NR_NUM_PSS_SYMBOLS 2
#define SL_NR_NUM_SSS_SYMBOLS 2
#define SL_NR_PSS_START_SYMBOL 1
#define SL_NR_SSS_START_SYMBOL 3
#define SL_NR_NUM_PSS_OR_SSS_SYMBOLS 2
#define SL_NR_PSS_SEQUENCE_LENGTH 127
#define SL_NR_SSS_SEQUENCE_LENGTH 127
#define SL_NR_NUM_IDs_IN_PSS 2
#define SL_NR_NUM_IDs_IN_SSS 336
#define SL_NR_NUM_SLSS_IDs 672
typedef
enum
sl_nr_sidelink_mode
{
SL_NOT_SUPPORTED
=
0
,
SL_MODE1_SUPPORTED
,
SL_MODE2_SUPPORTED
}
sl_nr_sidelink_mode_t
;
//(11*(12-3 DMRS REs) * 2 (QPSK used)
#define SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL 198
typedef
struct
SL_NR_UE_INIT_PARAMS
{
// gold sequences for PSBCH DMRS
uint32_t
psbch_dmrs_gold_sequences
[
SL_NR_NUM_SLSS_IDs
][
SL_NR_NUM_PSBCH_DMRS_RE_DWORD
];
// Gold sequences for PSBCH DMRS
// PSBCH DMRS QPSK modulated symbols for all possible SLSS Ids
struct
complex16
psbch_dmrs_modsym
[
SL_NR_NUM_SLSS_IDs
][
SL_NR_NUM_PSBCH_DMRS_RE
];
// Scaled values
int16_t
sl_pss
[
SL_NR_NUM_IDs_IN_PSS
][
SL_NR_PSS_SEQUENCE_LENGTH
];
int16_t
sl_sss
[
SL_NR_NUM_SLSS_IDs
][
SL_NR_SSS_SEQUENCE_LENGTH
];
// Contains Not scaled values just the simple generated sequence
int16_t
sl_pss_for_sync
[
SL_NR_NUM_IDs_IN_PSS
][
SL_NR_PSS_SEQUENCE_LENGTH
];
int16_t
sl_sss_for_sync
[
SL_NR_NUM_SLSS_IDs
][
SL_NR_SSS_SEQUENCE_LENGTH
];
int32_t
**
sl_pss_for_correlation
;
// IFFT samples for correlation
}
SL_NR_UE_INIT_PARAMS_t
;
typedef
struct
SL_NR_SYNC_PARAMS
{
// Indicating start of SSB block in the initial set of samples
uint32_t
ssb_offset
;
// Freq Offset calculated
int32_t
freq_offset
;
uint32_t
remaining_frames
;
uint32_t
rx_offset
;
uint32_t
slot_offset
;
uint16_t
N_sl_id2
;
// id2 determined from PSS during sync ref UE selection
uint16_t
N_sl_id1
;
// id2 determined from SSS during sync ref UE selection
uint16_t
N_sl_id
;
// ID calculated from ID1 and ID2
int32_t
psbch_rsrp
;
// rsrp of the decoded psbch during sync ref ue selection
uint32_t
DFN
;
// DFN calculated after sync ref UE search
}
SL_NR_SYNC_PARAMS_t
;
typedef
struct
SL_NR_UE_PSBCH
{
// AVG POWER OF PSBCH DMRS in dB/RE
int16_t
rsrp_dB_per_RE
;
// AVG POWER OF PSBCH DMRS in dBm/RE
int16_t
rsrp_dBm_per_RE
;
// STATS - CRC Errors observed during PSBCH reception
uint16_t
rx_errors
;
// STATS - Receptions with CRC OK
uint16_t
rx_ok
;
// STATS - transmissions of PSBCH by the UE
uint16_t
num_psbch_tx
;
}
SL_NR_UE_PSBCH_t
;
typedef
struct
sl_nr_ue_phy_params
{
SL_NR_UE_INIT_PARAMS_t
init_params
;
SL_NR_SYNC_PARAMS_t
sync_params
;
// Sidelink PHY PARAMETERS USED FOR PSBCH reception/Txn
SL_NR_UE_PSBCH_t
psbch
;
// Configuration parameters from MAC
sl_nr_phy_config_request_t
sl_config
;
NR_DL_FRAME_PARMS
sl_frame_params
;
time_stats_t
phy_proc_sl_tx
;
time_stats_t
phy_proc_sl_rx
;
time_stats_t
channel_estimation_stats
;
time_stats_t
ue_sl_indication_stats
;
}
sl_nr_ue_phy_params_t
;
#endif
\ No newline at end of file
openair1/SCHED_NR_UE/defs.h
View file @
ebeb2652
...
...
@@ -165,5 +165,23 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
const
UE_nr_rxtx_proc_t
*
proc
,
c16_t
rxdataF
[][
ue
->
frame_parms
.
samples_per_slot_wCP
]);
int
psbch_pscch_processing
(
PHY_VARS_NR_UE
*
ue
,
UE_nr_rxtx_proc_t
*
proc
,
nr_phy_data_t
*
phy_data
);
int
phy_procedures_nrUE_SL_TX
(
PHY_VARS_NR_UE
*
ue
,
UE_nr_rxtx_proc_t
*
proc
,
nr_phy_data_tx_t
*
phy_data
);
/*! \brief This function prepares the sl indication to pass to the MAC
*/
void
nr_fill_sl_indication
(
nr_sidelink_indication_t
*
sl_ind
,
sl_nr_rx_indication_t
*
rx_ind
,
sl_nr_sci_indication_t
*
sci_ind
,
UE_nr_rxtx_proc_t
*
proc
,
PHY_VARS_NR_UE
*
ue
,
void
*
phy_data
);
void
nr_fill_sl_rx_indication
(
sl_nr_rx_indication_t
*
rx_ind
,
uint8_t
pdu_type
,
PHY_VARS_NR_UE
*
ue
,
uint16_t
n_pdus
,
UE_nr_rxtx_proc_t
*
proc
,
void
*
typeSpecific
,
uint16_t
rx_slss_id
);
#endif
/** @}*/
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
View file @
ebeb2652
...
...
@@ -865,22 +865,22 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
__attribute__
((
aligned
(
32
)))
struct
complex16
dl_ch_estimates_time
[
fp
->
nb_antennas_rx
][
fp
->
ofdm_symbol_size
];
for
(
int
i
=
1
;
i
<
4
;
i
++
)
{
nr_slot_fep
(
ue
,
proc
,
(
ssb_start_symbol
+
i
)
%
(
fp
->
symbols_per_slot
),
rxdataF
);
nr_slot_fep
(
ue
,
fp
,
proc
,
(
ssb_start_symbol
+
i
)
%
(
fp
->
symbols_per_slot
),
rxdataF
,
link_type_dl
);
start_meas
(
&
ue
->
dlsch_channel_estimation_stats
);
nr_pbch_channel_estimation
(
ue
,
&
ue
->
frame_parms
,
estimateSz
,
dl_ch_estimates
,
dl_ch_estimates_time
,
proc
,
(
ssb_start_symbol
+
i
)
%
(
fp
->
symbols_per_slot
),
i
-
1
,
ssb_index
&
7
,
(
ssb_start_symbol
+
i
)
%
(
fp
->
symbols_per_slot
),
i
-
1
,
ssb_index
&
7
,
ssb_slot_2
==
nr_slot_rx
,
rxdataF
);
rxdataF
,
false
,
fp
->
Nid_cell
);
stop_meas
(
&
ue
->
dlsch_channel_estimation_stats
);
}
...
...
@@ -921,10 +921,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
{
for
(
int
j
=
prs_config
->
SymbolStart
;
j
<
(
prs_config
->
SymbolStart
+
prs_config
->
NumPRSSymbols
);
j
++
)
{
nr_slot_fep
(
ue
,
proc
,
(
j
%
fp
->
symbols_per_slot
),
rxdataF
);
nr_slot_fep
(
ue
,
fp
,
proc
,
(
j
%
fp
->
symbols_per_slot
),
rxdataF
,
link_type_dl
);
}
nr_prs_channel_estimation
(
gNB_id
,
rsc_id
,
i
,
ue
,
proc
,
fp
,
rxdataF
);
}
...
...
@@ -955,10 +952,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
for
(
uint16_t
l
=
0
;
l
<
nb_symb_pdcch
;
l
++
)
{
start_meas
(
&
ue
->
ofdm_demod_stats
);
nr_slot_fep
(
ue
,
proc
,
l
,
rxdataF
);
nr_slot_fep
(
ue
,
fp
,
proc
,
l
,
rxdataF
,
link_type_dl
);
}
// Hold the channel estimates in frequency domain.
...
...
@@ -1016,9 +1010,11 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
for
(
uint16_t
m
=
start_symb_sch
;
m
<
(
nb_symb_sch
+
start_symb_sch
)
;
m
++
){
nr_slot_fep
(
ue
,
&
ue
->
frame_parms
,
proc
,
m
,
//to be updated from higher layer
rxdataF
);
m
,
// to be updated from higher layer
rxdataF
,
link_type_dl
);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH
,
VCD_FUNCTION_OUT
);
...
...
@@ -1106,7 +1102,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
}
l_csiim
[
symb_idx
]
=
ue
->
csiim_vars
[
gNB_id
]
->
csiim_config_pdu
.
l_csiim
[
symb_idx
];
if
(
nr_slot_fep_done
==
false
)
{
nr_slot_fep
(
ue
,
proc
,
ue
->
csiim_vars
[
gNB_id
]
->
csiim_config_pdu
.
l_csiim
[
symb_idx
],
rxdataF
);
nr_slot_fep
(
ue
,
&
ue
->
frame_parms
,
proc
,
ue
->
csiim_vars
[
gNB_id
]
->
csiim_config_pdu
.
l_csiim
[
symb_idx
],
rxdataF
,
link_type_dl
);
}
}
nr_ue_csi_im_procedures
(
ue
,
proc
,
rxdataF
);
...
...
@@ -1117,7 +1113,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
if
((
ue
->
csirs_vars
[
gNB_id
])
&&
(
ue
->
csirs_vars
[
gNB_id
]
->
active
==
1
))
{
for
(
int
symb
=
0
;
symb
<
NR_SYMBOLS_PER_SLOT
;
symb
++
)
{
if
(
is_csi_rs_in_symbol
(
ue
->
csirs_vars
[
gNB_id
]
->
csirs_config_pdu
,
symb
))
{
nr_slot_fep
(
ue
,
proc
,
symb
,
rxdataF
);
nr_slot_fep
(
ue
,
&
ue
->
frame_parms
,
proc
,
symb
,
rxdataF
,
link_type_dl
);
}
}
nr_ue_csi_rs_procedures
(
ue
,
proc
,
rxdataF
);
...
...
openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c
0 → 100644
View file @
ebeb2652
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#define _GNU_SOURCE
#include "PHY/defs_nr_UE.h"
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "intertask_interface.h"
#include "T.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
void
nr_fill_sl_indication
(
nr_sidelink_indication_t
*
sl_ind
,
sl_nr_rx_indication_t
*
rx_ind
,
sl_nr_sci_indication_t
*
sci_ind
,
UE_nr_rxtx_proc_t
*
proc
,
PHY_VARS_NR_UE
*
ue
,
void
*
phy_data
)
{
memset
((
void
*
)
sl_ind
,
0
,
sizeof
(
nr_sidelink_indication_t
));
sl_ind
->
gNB_index
=
proc
->
gNB_id
;
sl_ind
->
module_id
=
ue
->
Mod_id
;
sl_ind
->
cc_id
=
ue
->
CC_id
;
sl_ind
->
frame_rx
=
proc
->
frame_rx
;
sl_ind
->
slot_rx
=
proc
->
nr_slot_rx
;
sl_ind
->
frame_tx
=
proc
->
frame_tx
;
sl_ind
->
slot_tx
=
proc
->
nr_slot_tx
;
sl_ind
->
phy_data
=
phy_data
;
if
(
rx_ind
)
{
sl_ind
->
rx_ind
=
rx_ind
;
// hang on rx_ind instance
sl_ind
->
sci_ind
=
NULL
;
}
if
(
sci_ind
)
{
sl_ind
->
rx_ind
=
NULL
;
sl_ind
->
sci_ind
=
sci_ind
;
}
}
void
nr_fill_sl_rx_indication
(
sl_nr_rx_indication_t
*
rx_ind
,
uint8_t
pdu_type
,
PHY_VARS_NR_UE
*
ue
,
uint16_t
n_pdus
,
UE_nr_rxtx_proc_t
*
proc
,
void
*
typeSpecific
,
uint16_t
rx_slss_id
)
{
if
(
n_pdus
>
1
)
{
LOG_E
(
PHY
,
"In %s: multiple number of SL PDUs not supported yet...
\n
"
,
__FUNCTION__
);
}
sl_nr_ue_phy_params_t
*
sl_phy_params
=
&
ue
->
SL_UE_PHY_PARAMS
;
switch
(
pdu_type
)
{
case
SL_NR_RX_PDU_TYPE_SLSCH
:
break
;
case
FAPI_NR_RX_PDU_TYPE_SSB
:
{
sl_nr_ssb_pdu_t
*
ssb_pdu
=
&
rx_ind
->
rx_indication_body
[
n_pdus
-
1
].
ssb_pdu
;
if
(
typeSpecific
)
{
uint8_t
*
psbch_decoded_output
=
(
uint8_t
*
)
typeSpecific
;
memcpy
(
ssb_pdu
->
psbch_payload
,
psbch_decoded_output
,
sizeof
(
4
));
// 4 bytes of PSBCH payload bytes
ssb_pdu
->
rsrp_dbm
=
sl_phy_params
->
psbch
.
rsrp_dBm_per_RE
;
ssb_pdu
->
rx_slss_id
=
rx_slss_id
;
ssb_pdu
->
decode_status
=
true
;
LOG_D
(
PHY
,
"SL-IND: SSB to MAC. rsrp:%d, slssid:%d, payload:%x
\n
"
,
ssb_pdu
->
rsrp_dbm
,
ssb_pdu
->
rx_slss_id
,
*
((
uint32_t
*
)(
ssb_pdu
->
psbch_payload
)));
}
else
ssb_pdu
->
decode_status
=
false
;
}
break
;
default:
break
;
}
rx_ind
->
rx_indication_body
[
n_pdus
-
1
].
pdu_type
=
pdu_type
;
rx_ind
->
number_pdus
=
n_pdus
;
}
static
int
nr_ue_psbch_procedures
(
PHY_VARS_NR_UE
*
ue
,
NR_DL_FRAME_PARMS
*
fp
,
UE_nr_rxtx_proc_t
*
proc
,
int
estimateSz
,
struct
complex16
dl_ch_estimates
[][
estimateSz
],
nr_phy_data_t
*
phy_data
,
c16_t
rxdataF
[][
fp
->
samples_per_slot_wCP
])
{
int
ret
=
0
;
DevAssert
(
ue
);
int
frame_rx
=
proc
->
frame_rx
;
int
nr_slot_rx
=
proc
->
nr_slot_rx
;
sl_nr_ue_phy_params_t
*
sl_phy_params
=
&
ue
->
SL_UE_PHY_PARAMS
;
uint16_t
rx_slss_id
=
sl_phy_params
->
sl_config
.
sl_sync_source
.
rx_slss_id
;
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PSBCH_PROCEDURES, VCD_FUNCTION_IN);
LOG_D
(
PHY
,
"[UE %d] Frame %d Slot %d, Trying PSBCH (SLSS ID %d)
\n
"
,
ue
->
Mod_id
,
frame_rx
,
nr_slot_rx
,
sl_phy_params
->
sl_config
.
sl_sync_source
.
rx_slss_id
);
uint8_t
decoded_pdu
[
4
]
=
{
0
};
ret
=
nr_rx_psbch
(
ue
,
proc
,
estimateSz
,
dl_ch_estimates
,
fp
,
decoded_pdu
,
rxdataF
,
sl_phy_params
->
sl_config
.
sl_sync_source
.
rx_slss_id
);
nr_sidelink_indication_t
sl_indication
;
sl_nr_rx_indication_t
rx_ind
=
{
0
};
uint16_t
number_pdus
=
1
;
uint8_t
*
result
=
NULL
;
if
(
ret
)
{
sl_phy_params
->
psbch
.
rx_errors
++
;
LOG_E
(
PHY
,
"%d:%d PSBCH RX: NOK
\n
"
,
proc
->
frame_rx
,
proc
->
nr_slot_rx
);
}
else
{
result
=
decoded_pdu
;
sl_phy_params
->
psbch
.
rx_ok
++
;
LOG_D
(
PHY
,
"%d:%d PSBCH RX: OK
\n
"
,
proc
->
frame_rx
,
proc
->
nr_slot_rx
);
}
nr_fill_sl_indication
(
&
sl_indication
,
&
rx_ind
,
NULL
,
proc
,
ue
,
phy_data
);
nr_fill_sl_rx_indication
(
&
rx_ind
,
SL_NR_RX_PDU_TYPE_SSB
,
ue
,
number_pdus
,
proc
,
(
void
*
)
result
,
rx_slss_id
);
if
(
ue
->
if_inst
&&
ue
->
if_inst
->
sl_indication
)
ue
->
if_inst
->
sl_indication
(
&
sl_indication
);
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PSBCH_PROCEDURES, VCD_FUNCTION_OUT);
return
ret
;
}
int
psbch_pscch_processing
(
PHY_VARS_NR_UE
*
ue
,
UE_nr_rxtx_proc_t
*
proc
,
nr_phy_data_t
*
phy_data
)
{
int
frame_rx
=
proc
->
frame_rx
;
int
nr_slot_rx
=
proc
->
nr_slot_rx
;
sl_nr_ue_phy_params_t
*
sl_phy_params
=
&
ue
->
SL_UE_PHY_PARAMS
;
NR_DL_FRAME_PARMS
*
fp
=
&
sl_phy_params
->
sl_frame_params
;
int
sampleShift
=
0
;
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX_SL, VCD_FUNCTION_IN);
start_meas
(
&
sl_phy_params
->
phy_proc_sl_rx
);
LOG_D
(
PHY
,
" ****** Sidelink RX-Chain for Frame.Slot %d.%d ******
\n
"
,
frame_rx
%
1024
,
nr_slot_rx
);
const
uint32_t
rxdataF_sz
=
fp
->
samples_per_slot_wCP
;
__attribute__
((
aligned
(
32
)))
c16_t
rxdataF
[
fp
->
nb_antennas_rx
][
rxdataF_sz
];
if
(
phy_data
->
sl_rx_action
==
SL_NR_CONFIG_TYPE_RX_PSBCH
)
{
const
int
estimateSz
=
fp
->
symbols_per_slot
*
fp
->
ofdm_symbol_size
;
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_IN);
LOG_D
(
PHY
,
" ----- PSBCH RX TTI: frame.slot %d.%d ------
\n
"
,
frame_rx
%
1024
,
nr_slot_rx
);
__attribute__
((
aligned
(
32
)))
struct
complex16
dl_ch_estimates
[
fp
->
nb_antennas_rx
][
estimateSz
];
__attribute__
((
aligned
(
32
)))
struct
complex16
dl_ch_estimates_time
[
fp
->
nb_antennas_rx
][
fp
->
ofdm_symbol_size
];
// 0 for Normal Cyclic Prefix and 1 for EXT CyclicPrefix
const
int
numsym
=
(
fp
->
Ncp
)
?
SL_NR_NUM_SYMBOLS_SSB_EXT_CP
:
SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP
;
for
(
int
sym
=
0
;
sym
<
numsym
;)
{
nr_slot_fep
(
ue
,
fp
,
proc
,
sym
,
rxdataF
,
link_type_ul
);
start_meas
(
&
sl_phy_params
->
channel_estimation_stats
);
nr_pbch_channel_estimation
(
ue
,
fp
,
estimateSz
,
dl_ch_estimates
,
dl_ch_estimates_time
,
proc
,
sym
,
sym
,
0
,
0
,
rxdataF
,
true
,
sl_phy_params
->
sl_config
.
sl_sync_source
.
rx_slss_id
);
stop_meas
(
&
sl_phy_params
->
channel_estimation_stats
);
// PSBCH present in symbols 0, 5-12 for normal cp
sym
=
(
sym
==
0
)
?
5
:
sym
+
1
;
}
nr_sl_psbch_rsrp_measurements
(
sl_phy_params
,
fp
,
rxdataF
,
false
);
LOG_D
(
PHY
,
" ------ Decode SL-MIB: frame.slot %d.%d ------
\n
"
,
frame_rx
%
1024
,
nr_slot_rx
);
const
int
psbchSuccess
=
nr_ue_psbch_procedures
(
ue
,
fp
,
proc
,
estimateSz
,
dl_ch_estimates
,
phy_data
,
rxdataF
);
if
(
ue
->
no_timing_correction
==
0
&&
psbchSuccess
==
0
)
{
LOG_D
(
PHY
,
"start adjust sync slot = %d no timing %d
\n
"
,
nr_slot_rx
,
ue
->
no_timing_correction
);
sampleShift
=
nr_adjust_synch_ue
(
fp
,
ue
,
proc
->
gNB_id
,
fp
->
ofdm_symbol_size
,
dl_ch_estimates_time
,
frame_rx
,
nr_slot_rx
,
16384
);
}
LOG_D
(
PHY
,
"Doing N0 measurements in %s
\n
"
,
__FUNCTION__
);
// nr_ue_rrc_measurements(ue, proc, rxdataF);
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_OUT);
if
(
frame_rx
%
64
==
0
)
{
LOG_I
(
NR_PHY
,
"============================================
\n
"
);
LOG_I
(
NR_PHY
,
"[UE%d] %d:%d PSBCH Stats: TX %d, RX ok %d, RX not ok %d
\n
"
,
ue
->
Mod_id
,
frame_rx
,
nr_slot_rx
,
sl_phy_params
->
psbch
.
num_psbch_tx
,
sl_phy_params
->
psbch
.
rx_ok
,
sl_phy_params
->
psbch
.
rx_errors
);
LOG_I
(
NR_PHY
,
"============================================
\n
"
);
}
}
return
sampleShift
;
}
int
phy_procedures_nrUE_SL_TX
(
PHY_VARS_NR_UE
*
ue
,
UE_nr_rxtx_proc_t
*
proc
,
nr_phy_data_tx_t
*
phy_data
)
{
int
slot_tx
=
proc
->
nr_slot_tx
;
int
frame_tx
=
proc
->
frame_tx
;
int
tx_action
=
0
;
sl_nr_ue_phy_params_t
*
sl_phy_params
=
&
ue
->
SL_UE_PHY_PARAMS
;
NR_DL_FRAME_PARMS
*
fp
=
&
sl_phy_params
->
sl_frame_params
;
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_SL,VCD_FUNCTION_IN);
const
int
samplesF_per_slot
=
NR_SYMBOLS_PER_SLOT
*
fp
->
ofdm_symbol_size
;
c16_t
txdataF_buf
[
fp
->
nb_antennas_tx
*
samplesF_per_slot
]
__attribute__
((
aligned
(
32
)));
memset
(
txdataF_buf
,
0
,
sizeof
(
txdataF_buf
));
c16_t
*
txdataF
[
fp
->
nb_antennas_tx
];
/* workaround to be compatible with current txdataF usage in all tx procedures. */
for
(
int
i
=
0
;
i
<
fp
->
nb_antennas_tx
;
++
i
)
txdataF
[
i
]
=
&
txdataF_buf
[
i
*
samplesF_per_slot
];
LOG_D
(
PHY
,
"****** start Sidelink TX-Chain for AbsSubframe %d.%d ******
\n
"
,
frame_tx
,
slot_tx
);
start_meas
(
&
sl_phy_params
->
phy_proc_sl_tx
);
if
(
phy_data
->
sl_tx_action
==
SL_NR_CONFIG_TYPE_TX_PSBCH
)
{
sl_nr_tx_config_psbch_pdu_t
*
psbch_vars
=
&
phy_data
->
psbch_vars
;
nr_tx_psbch
(
ue
,
frame_tx
,
slot_tx
,
psbch_vars
,
txdataF
);
sl_phy_params
->
psbch
.
num_psbch_tx
++
;
if
(
frame_tx
%
64
==
0
)
{
LOG_I
(
NR_PHY
,
"============================================
\n
"
);
LOG_I
(
NR_PHY
,
"[UE%d] %d:%d PSBCH Stats: TX %d, RX ok %d, RX not ok %d
\n
"
,
ue
->
Mod_id
,
frame_tx
,
slot_tx
,
sl_phy_params
->
psbch
.
num_psbch_tx
,
sl_phy_params
->
psbch
.
rx_ok
,
sl_phy_params
->
psbch
.
rx_errors
);
LOG_I
(
NR_PHY
,
"============================================
\n
"
);
}
tx_action
=
1
;
}
if
(
tx_action
)
{
LOG_D
(
PHY
,
"Sending Uplink data
\n
"
);
nr_ue_pusch_common_procedures
(
ue
,
proc
->
nr_slot_tx
,
fp
,
fp
->
nb_antennas_tx
,
txdataF
);
}
LOG_D
(
PHY
,
"****** end Sidelink TX-Chain for AbsSubframe %d.%d ******
\n
"
,
frame_tx
,
slot_tx
);
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_SL, VCD_FUNCTION_OUT);
stop_meas
(
&
sl_phy_params
->
phy_proc_sl_tx
);
return
tx_action
;
}
openair1/SIMULATION/NR_PHY/pbchsim.c
View file @
ebeb2652
...
...
@@ -786,36 +786,45 @@ int main(int argc, char **argv)
int
ssb_slot
=
(
UE
->
symbol_offset
/
14
)
+
(
n_hf
*
(
frame_parms
->
slots_per_frame
>>
1
));
proc
.
nr_slot_rx
=
ssb_slot
;
proc
.
gNB_id
=
0
;
for
(
int
i
=
UE
->
symbol_offset
+
1
;
i
<
UE
->
symbol_offset
+
4
;
i
++
)
{
nr_slot_fep
(
UE
,
for
(
int
i
=
UE
->
symbol_offset
+
1
;
i
<
UE
->
symbol_offset
+
4
;
i
++
)
{
nr_slot_fep
(
UE
,
frame_parms
,
&
proc
,
i
%
frame_parms
->
symbols_per_slot
,
rxdataF
,
link_type_dl
);
nr_pbch_channel_estimation
(
UE
,
&
UE
->
frame_parms
,
estimateSz
,
dl_ch_estimates
,
dl_ch_estimates_time
,
&
proc
,
i
%
frame_parms
->
symbols_per_slot
,
rxdataF
);
nr_pbch_channel_estimation
(
UE
,
estimateSz
,
dl_ch_estimates
,
dl_ch_estimates_time
,
&
proc
,
i
%
frame_parms
->
symbols_per_slot
,
i
-
(
UE
->
symbol_offset
+
1
),
ssb_index
%
8
,
n_hf
,
rxdataF
);
i
%
frame_parms
->
symbols_per_slot
,
i
-
(
UE
->
symbol_offset
+
1
),
ssb_index
%
8
,
n_hf
,
rxdataF
,
false
,
frame_parms
->
Nid_cell
);
}
fapiPbch_t
result
;
ret
=
nr_rx_pbch
(
UE
,
&
proc
,
estimateSz
,
dl_ch_estimates
,
frame_parms
,
ssb_index
%
8
,
&
result
,
rxdataF
);
if
(
ret
==
0
)
{
//
UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically
//
UE->rx_ind.rx_indication_body->mib_pdu.ssb_length; //Lmax, not yet detected automatically
uint8_t
gNB_xtra_byte
=
0
;
for
(
int
i
=
0
;
i
<
8
;
i
++
)
gNB_xtra_byte
|=
((
gNB
->
pbch
.
pbch_a
>>
(
31
-
i
))
&
1
)
<<
(
7
-
i
);
if
(
ret
==
0
)
{
//
UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically
//
UE->rx_ind.rx_indication_body->mib_pdu.ssb_length; //Lmax, not yet detected automatically
uint8_t
gNB_xtra_byte
=
0
;
for
(
int
i
=
0
;
i
<
8
;
i
++
)
gNB_xtra_byte
|=
((
gNB
->
pbch
.
pbch_a
>>
(
31
-
i
))
&
1
)
<<
(
7
-
i
);
payload_ret
=
(
result
.
xtra_byte
==
gNB_xtra_byte
);
for
(
i
=
0
;
i
<
3
;
i
++
){
payload_ret
+=
(
result
.
decoded_output
[
i
]
==
((
msgDataTx
.
ssb
[
ssb_index
].
ssb_pdu
.
ssb_pdu_rel15
.
bchPayload
>>
(
8
*
i
))
&
0xff
));
for
(
i
=
0
;
i
<
3
;
i
++
)
{
payload_ret
+=
(
result
.
decoded_output
[
i
]
==
((
msgDataTx
.
ssb
[
ssb_index
].
ssb_pdu
.
ssb_pdu_rel15
.
bchPayload
>>
(
8
*
i
))
&
0xff
));
}
//
printf("ret %d\n", payload_ret);
if
(
payload_ret
!=
4
)
//
printf("ret %d\n", payload_ret);
if
(
payload_ret
!=
4
)
n_errors_payload
++
;
}
if
(
ret
!=
0
)
n_errors
++
;
if
(
ret
!=
0
)
n_errors
++
;
}
}
//noise trials
printf
(
"SNR %f: trials %d, n_errors_crc = %d, n_errors_payload %d
\n
"
,
SNR
,
n_trials
,
n_errors
,
n_errors_payload
);
...
...
openair1/SIMULATION/NR_PHY/psbchsim.c
0 → 100644
View file @
ebeb2652
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include "common/config/config_userapi.h"
#include "common/ran_context.h"
#include "PHY/types.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/defs_gNB.h"
#include "PHY/phy_vars.h"
#include "NR_MasterInformationBlockSidelink.h"
#include "PHY/INIT/phy_init.h"
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "openair1/SIMULATION/TOOLS/sim.h"
#include "common/utils/nr/nr_common.h"
#include "openair2/RRC/NR/nr_rrc_extern.h"
#include "openair2/RRC/LTE/rrc_vars.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/INIT/nr_phy_init.h"
#include "SIMULATION/RF/rf.h"
#include "common/utils/load_module_shlib.h"
#include "PHY/MODULATION/nr_modulation.h"
#include "NR_SL-SSB-TimeAllocation-r16.h"
void
e1_bearer_context_setup
(
const
e1ap_bearer_setup_req_t
*
req
)
{
abort
();
}
void
e1_bearer_context_modif
(
const
e1ap_bearer_setup_req_t
*
req
)
{
abort
();
}
void
e1_bearer_release_cmd
(
const
e1ap_bearer_release_cmd_t
*
cmd
)
{
abort
();
}
void
exit_function
(
const
char
*
file
,
const
char
*
function
,
const
int
line
,
const
char
*
s
,
const
int
assert
)
{
const
char
*
msg
=
s
==
NULL
?
"no comment"
:
s
;
printf
(
"Exiting at: %s:%d %s(), %s
\n
"
,
file
,
line
,
function
,
msg
);
exit
(
-
1
);
}
int8_t
nr_rrc_RA_succeeded
(
const
module_id_t
mod_id
,
const
uint8_t
gNB_index
)
{
return
1
;
}
// to solve link errors
double
cpuf
;
// void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
void
get_num_re_dmrs
(
nfapi_nr_ue_pusch_pdu_t
*
pusch_pdu
,
uint8_t
*
nb_dmrs_re_per_rb
,
uint16_t
*
number_dmrs_symbols
)
{
}
uint64_t
downlink_frequency
[
1
][
1
];
int32_t
uplink_frequency_offset
[
1
][
1
];
THREAD_STRUCT
thread_struct
;
instance_t
DUuniqInstance
=
0
;
instance_t
CUuniqInstance
=
0
;
openair0_config_t
openair0_cfg
[
1
];
RAN_CONTEXT_t
RC
;
int
oai_exit
=
0
;
char
*
uecap_file
;
void
nr_rrc_ue_generate_RRCSetupRequest
(
module_id_t
module_id
,
const
uint8_t
gNB_index
)
{
return
;
}
int8_t
nr_mac_rrc_data_req_ue
(
const
module_id_t
Mod_idP
,
const
int
CC_id
,
const
uint8_t
gNB_id
,
const
frame_t
frameP
,
const
rb_id_t
Srb_id
,
uint8_t
*
buffer_pP
)
{
return
0
;
}
nr_bler_struct
nr_bler_data
[
NR_NUM_MCS
];
void
get_nrUE_params
(
void
)
{
return
;
}
uint8_t
check_if_ue_is_sl_syncsource
()
{
return
0
;
}
//////////////////////////////////////////////////////////////////////////
static
void
prepare_mib_bits
(
uint8_t
*
buf
,
uint32_t
frame_tx
,
uint32_t
slot_tx
)
{
NR_MasterInformationBlockSidelink_t
*
sl_mib
;
asn_enc_rval_t
enc_rval
;
void
*
buffer
=
(
void
*
)
buf
;
sl_mib
=
CALLOC
(
1
,
sizeof
(
NR_MasterInformationBlockSidelink_t
));
sl_mib
->
inCoverage_r16
=
0
;
// TRUE;
// allocate buffer for 7 bits slotnumber
sl_mib
->
slotIndex_r16
.
size
=
1
;
sl_mib
->
slotIndex_r16
.
buf
=
CALLOC
(
1
,
sl_mib
->
slotIndex_r16
.
size
);
sl_mib
->
slotIndex_r16
.
bits_unused
=
sl_mib
->
slotIndex_r16
.
size
*
8
-
7
;
sl_mib
->
slotIndex_r16
.
buf
[
0
]
=
slot_tx
<<
sl_mib
->
slotIndex_r16
.
bits_unused
;
sl_mib
->
directFrameNumber_r16
.
size
=
2
;
sl_mib
->
directFrameNumber_r16
.
buf
=
CALLOC
(
1
,
sl_mib
->
directFrameNumber_r16
.
size
);
sl_mib
->
directFrameNumber_r16
.
bits_unused
=
sl_mib
->
directFrameNumber_r16
.
size
*
8
-
10
;
sl_mib
->
directFrameNumber_r16
.
buf
[
0
]
=
frame_tx
>>
(
8
-
sl_mib
->
directFrameNumber_r16
.
bits_unused
);
sl_mib
->
directFrameNumber_r16
.
buf
[
1
]
=
frame_tx
<<
sl_mib
->
directFrameNumber_r16
.
bits_unused
;
enc_rval
=
uper_encode_to_buffer
(
&
asn_DEF_NR_MasterInformationBlockSidelink
,
NULL
,
(
void
*
)
sl_mib
,
buffer
,
100
);
AssertFatal
(
enc_rval
.
encoded
>
0
,
"ASN1 message encoding failed (%s, %lu)!
\n
"
,
enc_rval
.
failed_type
->
name
,
enc_rval
.
encoded
);
asn_DEF_NR_MasterInformationBlockSidelink
.
op
->
free_struct
(
&
asn_DEF_NR_MasterInformationBlockSidelink
,
sl_mib
,
ASFM_FREE_EVERYTHING
);
}
static
int
test_rx_mib
(
uint8_t
*
decoded_output
,
uint16_t
frame
,
uint16_t
slot
)
{
uint32_t
sl_mib
=
*
(
uint32_t
*
)
decoded_output
;
uint32_t
fn
=
0
,
sl
=
0
;
fn
=
(((
sl_mib
&
0x0700
)
>>
1
)
|
((
sl_mib
&
0xFE0000
)
>>
17
));
sl
=
(((
sl_mib
&
0x010000
)
>>
10
)
|
((
sl_mib
&
0xFC000000
)
>>
26
));
printf
(
"decoded output:%x, TX %d:%d, timing decoded from sl-MIB %d:%d
\n
"
,
*
(
uint32_t
*
)
decoded_output
,
frame
,
slot
,
fn
,
sl
);
if
(
frame
==
fn
&&
slot
==
sl
)
return
0
;
return
-
1
;
}
//////////////////////////////////////////////////////////////////////////
static
void
configure_NR_UE
(
PHY_VARS_NR_UE
*
UE
,
int
mu
,
int
N_RB
)
{
fapi_nr_config_request_t
config
;
NR_DL_FRAME_PARMS
*
fp
=
&
UE
->
frame_parms
;
config
.
ssb_config
.
scs_common
=
mu
;
config
.
cell_config
.
frame_duplex_type
=
TDD
;
config
.
carrier_config
.
dl_grid_size
[
mu
]
=
N_RB
;
config
.
carrier_config
.
ul_grid_size
[
mu
]
=
N_RB
;
config
.
carrier_config
.
dl_frequency
=
0
;
config
.
carrier_config
.
uplink_frequency
=
0
;
int
band
;
if
(
mu
==
1
)
band
=
78
;
if
(
mu
==
0
)
band
=
34
;
nr_init_frame_parms_ue
(
fp
,
&
config
,
band
);
fp
->
ofdm_offset_divisor
=
8
;
nr_dump_frame_parms
(
fp
);
if
(
init_nr_ue_signal
(
UE
,
1
)
!=
0
)
{
printf
(
"Error at UE NR initialisation
\n
"
);
exit
(
-
1
);
}
}
static
void
sl_init_frame_parameters
(
PHY_VARS_NR_UE
*
UE
)
{
NR_DL_FRAME_PARMS
*
nr_fp
=
&
UE
->
frame_parms
;
NR_DL_FRAME_PARMS
*
sl_fp
=
&
UE
->
SL_UE_PHY_PARAMS
.
sl_frame_params
;
memcpy
(
sl_fp
,
nr_fp
,
sizeof
(
NR_DL_FRAME_PARMS
));
sl_fp
->
ofdm_offset_divisor
=
8
;
// What is this used for?
sl_fp
->
att_tx
=
1
;
sl_fp
->
att_rx
=
1
;
// band47 //UL freq will be set to Sidelink freq
sl_fp
->
ul_CarrierFreq
=
5880000000
;
sl_fp
->
ssb_start_subcarrier
=
UE
->
SL_UE_PHY_PARAMS
.
sl_config
.
sl_bwp_config
.
sl_ssb_offset_point_a
;
sl_fp
->
Nid_cell
=
UE
->
SL_UE_PHY_PARAMS
.
sl_config
.
sl_sync_source
.
rx_slss_id
;
#ifdef DEBUG_INIT
LOG_I
(
PHY
,
"Dumping Sidelink Frame Parameters
\n
"
);
nr_dump_frame_parms
(
sl_fp
);
#endif
}
static
void
configure_SL_UE
(
PHY_VARS_NR_UE
*
UE
,
int
mu
,
int
N_RB
,
int
ssb_offset
,
int
slss_id
)
{
sl_nr_phy_config_request_t
*
config
=
&
UE
->
SL_UE_PHY_PARAMS
.
sl_config
;
NR_DL_FRAME_PARMS
*
fp
=
&
UE
->
SL_UE_PHY_PARAMS
.
sl_frame_params
;
config
->
sl_bwp_config
.
sl_scs
=
mu
;
config
->
sl_bwp_config
.
sl_ssb_offset_point_a
=
ssb_offset
;
config
->
sl_carrier_config
.
sl_bandwidth
=
N_RB
;
config
->
sl_carrier_config
.
sl_grid_size
=
106
;
config
->
sl_sync_source
.
rx_slss_id
=
slss_id
;
sl_init_frame_parameters
(
UE
);
sl_ue_phy_init
(
UE
);
init_symbol_rotation
(
fp
);
init_timeshift_rotation
(
fp
);
LOG_I
(
PHY
,
"Dumping Sidelink Frame Parameters
\n
"
);
nr_dump_frame_parms
(
fp
);
}
static
int
freq_domain_loopback
(
PHY_VARS_NR_UE
*
UE_tx
,
PHY_VARS_NR_UE
*
UE_rx
,
int
frame
,
int
slot
,
nr_phy_data_tx_t
*
phy_data
)
{
sl_nr_ue_phy_params_t
*
sl_ue1
=
&
UE_tx
->
SL_UE_PHY_PARAMS
;
sl_nr_ue_phy_params_t
*
sl_ue2
=
&
UE_rx
->
SL_UE_PHY_PARAMS
;
printf
(
"
\n
PSBCH SIM -F: %d:%d slss id TX UE:%d, RX UE:%d
\n
"
,
frame
,
slot
,
phy_data
->
psbch_vars
.
tx_slss_id
,
sl_ue2
->
sl_config
.
sl_sync_source
.
rx_slss_id
);
NR_DL_FRAME_PARMS
*
fp
=
&
sl_ue1
->
sl_frame_params
;
const
int
samplesF_per_slot
=
NR_SYMBOLS_PER_SLOT
*
fp
->
ofdm_symbol_size
;
c16_t
txdataF_buf
[
fp
->
nb_antennas_tx
*
samplesF_per_slot
]
__attribute__
((
aligned
(
32
)));
memset
(
txdataF_buf
,
0
,
sizeof
(
txdataF_buf
));
c16_t
*
txdataF
[
fp
->
nb_antennas_tx
];
/* workaround to be compatible with current txdataF usage in all tx procedures. */
for
(
int
i
=
0
;
i
<
fp
->
nb_antennas_tx
;
++
i
)
txdataF
[
i
]
=
&
txdataF_buf
[
i
*
samplesF_per_slot
];
nr_tx_psbch
(
UE_tx
,
frame
,
slot
,
&
phy_data
->
psbch_vars
,
txdataF
);
int
estimateSz
=
sl_ue2
->
sl_frame_params
.
samples_per_slot_wCP
;
__attribute__
((
aligned
(
32
)))
struct
complex16
rxdataF
[
1
][
estimateSz
];
for
(
int
i
=
0
;
i
<
sl_ue1
->
sl_frame_params
.
samples_per_slot_wCP
;
i
++
)
{
struct
complex16
*
txdataF_ptr
=
(
struct
complex16
*
)
&
txdataF
[
0
][
i
];
struct
complex16
*
rxdataF_ptr
=
(
struct
complex16
*
)
&
rxdataF
[
0
][
i
];
rxdataF_ptr
->
r
=
txdataF_ptr
->
r
;
rxdataF_ptr
->
i
=
txdataF_ptr
->
i
;
// printf("r,i TXDATAF[%d]- %d:%d, RXDATAF[%d]- %d:%d\n",
// i, txdataF_ptr->r, txdataF_ptr->i, i, txdataF_ptr->r, txdataF_ptr->i);
}
uint8_t
err_status
=
0
;
UE_nr_rxtx_proc_t
proc
;
proc
.
frame_rx
=
frame
;
proc
.
nr_slot_rx
=
slot
;
struct
complex16
dl_ch_estimates
[
1
][
estimateSz
];
uint8_t
decoded_output
[
4
]
=
{
0
};
LOG_I
(
PHY
,
"DEBUG: HIJACKING DL CHANNEL ESTIMATES.
\n
"
);
for
(
int
s
=
0
;
s
<
14
;
s
++
)
{
for
(
int
j
=
0
;
j
<
sl_ue2
->
sl_frame_params
.
ofdm_symbol_size
;
j
++
)
{
struct
complex16
*
dlch
=
(
struct
complex16
*
)(
&
dl_ch_estimates
[
0
][
s
*
sl_ue2
->
sl_frame_params
.
ofdm_symbol_size
]);
dlch
[
j
].
r
=
128
;
dlch
[
j
].
i
=
0
;
}
}
err_status
=
nr_rx_psbch
(
UE_rx
,
&
proc
,
estimateSz
,
dl_ch_estimates
,
&
sl_ue2
->
sl_frame_params
,
decoded_output
,
rxdataF
,
sl_ue2
->
sl_config
.
sl_sync_source
.
rx_slss_id
);
int
error_payload
=
0
;
error_payload
=
test_rx_mib
(
decoded_output
,
frame
,
slot
);
if
(
err_status
==
0
||
error_payload
==
0
)
{
LOG_I
(
PHY
,
"---------PSBCH -F TEST OK.
\n
"
);
return
0
;
}
LOG_E
(
PHY
,
"--------PSBCH -F TEST NOK. FAIL.
\n
"
);
return
-
1
;
}
PHY_VARS_NR_UE
*
UE_TX
;
// for tx
PHY_VARS_NR_UE
*
UE_RX
;
// for rx
double
cpuf
;
configmodule_interface_t
*
uniqCfg
=
NULL
;
int
main
(
int
argc
,
char
**
argv
)
{
char
c
;
int
test_freqdomain_loopback
=
0
,
test_slss_search
=
0
;
int
frame
=
5
,
slot
=
10
,
frame_tx
=
0
,
slot_tx
=
0
;
int
loglvl
=
OAILOG_INFO
;
uint16_t
slss_id
=
336
,
ssb_offset
=
0
;
double
snr1
=
2
.
0
,
snr0
=
2
.
0
,
SNR
;
double
sigma2
=
0
.
0
,
sigma2_dB
=
0
.
0
;
double
cfo
=
0
,
ip
=
0
.
0
;
SCM_t
channel_model
=
AWGN
;
// Rayleigh1_anticorr;
int
N_RB_DL
=
106
,
mu
=
1
;
uint16_t
errors
=
0
,
n_trials
=
1
;
int
frame_length_complex_samples
;
// int frame_length_complex_samples_no_prefix;
NR_DL_FRAME_PARMS
*
frame_parms
;
int
seed
=
0
;
cpuf
=
get_cpu_freq_GHz
();
if
((
uniqCfg
=
load_configmodule
(
argc
,
argv
,
CONFIG_ENABLECMDLINEONLY
))
==
0
)
{
exit_fun
(
"[NR_PSBCHSIM] Error, configuration module init failed
\n
"
);
}
randominit
(
0
);
while
((
c
=
getopt
(
argc
,
argv
,
"c:hn:o:s:FIL:N:R:S:T:"
))
!=
-
1
)
{
printf
(
"SIDELINK PSBCH SIM: handling optarg %c
\n
"
,
c
);
switch
(
c
)
{
case
'c'
:
cfo
=
atof
(
optarg
);
printf
(
"Setting CFO to %f Hz
\n
"
,
cfo
);
break
;
case
'g'
:
switch
((
char
)
*
optarg
)
{
case
'A'
:
channel_model
=
SCM_A
;
break
;
case
'B'
:
channel_model
=
SCM_B
;
break
;
case
'C'
:
channel_model
=
SCM_C
;
break
;
case
'D'
:
channel_model
=
SCM_D
;
break
;
case
'E'
:
channel_model
=
EPA
;
break
;
case
'F'
:
channel_model
=
EVA
;
break
;
case
'G'
:
channel_model
=
ETU
;
break
;
default:
printf
(
"Unsupported channel model! Exiting.
\n
"
);
exit
(
-
1
);
}
break
;
case
'n'
:
n_trials
=
atoi
(
optarg
);
break
;
case
'o'
:
ssb_offset
=
atoi
(
optarg
);
printf
(
"SIDELINK PSBCH SIM: ssb offset from pointA:%d
\n
"
,
ssb_offset
);
break
;
case
's'
:
slss_id
=
atoi
(
optarg
);
printf
(
"SIDELINK PSBCH SIM: slss_id from arg:%d
\n
"
,
slss_id
);
AssertFatal
(
slss_id
>=
0
&&
slss_id
<=
671
,
"SLSS ID not within Range 0-671
\n
"
);
break
;
case
'F'
:
test_freqdomain_loopback
=
1
;
break
;
case
'I'
:
test_slss_search
=
1
;
printf
(
"SIDELINK PSBCH SIM: SLSS search will be tested
\n
"
);
break
;
case
'L'
:
loglvl
=
atoi
(
optarg
);
break
;
case
'N'
:
snr0
=
atoi
(
optarg
);
snr1
=
snr0
;
printf
(
"Setting SNR0 to %f. Test uses this SNR as target SNR
\n
"
,
snr0
);
break
;
case
'R'
:
N_RB_DL
=
atoi
(
optarg
);
printf
(
"SIDELINK PSBCH SIM: N_RB_DL:%d
\n
"
,
N_RB_DL
);
break
;
case
'S'
:
snr1
=
atof
(
optarg
);
printf
(
"Setting SNR1 to %f. Test will run until this SNR as target SNR
\n
"
,
snr1
);
AssertFatal
(
snr1
<=
snr0
,
"Test runs SNR down, set snr1 to a lower value than %f
\n
"
,
snr0
);
break
;
case
'T'
:
frame
=
atoi
(
optarg
);
slot
=
atoi
(
argv
[
optind
]);
printf
(
"PSBCH SIM: frame timing- %d:%d
\n
"
,
frame
,
slot
);
break
;
case
'h'
:
default:
printf
(
"
\n\n
SIDELINK PSBCH SIM OPTIONS LIST - hus:FL:T:
\n
"
);
printf
(
"-h: HELP
\n
"
);
printf
(
"-c Carrier frequency offset in Hz
\n
"
);
printf
(
"-n Number of trials
\n
"
);
printf
(
"-o ssb offset from PointA - indicates ssb_start subcarrier
\n
"
);
printf
(
"-s: set Sidelink sync id slss_id. ex -s 100
\n
"
);
printf
(
"-F: Run PSBCH frequency domain loopback test of the samples
\n
"
);
printf
(
"-I: Sidelink SLSS search will be tested.
\n
"
);
printf
(
"-L: Set Log Level.
\n
"
);
printf
(
"-N: Test with Noise. target SNR0 eg -N 10
\n
"
);
printf
(
"-R N_RB_DL
\n
"
);
printf
(
"-S Ending SNR, runs from SNR0 to SNR1
\n
"
);
printf
(
"-T: Frame,Slot to be sent in sl-MIB eg -T 4 2
\n
"
);
return
1
;
}
}
randominit
(
seed
);
logInit
();
set_glog
(
loglvl
);
double
fs
=
0
,
eps
;
double
scs
=
30000
;
double
bw
=
100e6
;
switch
(
mu
)
{
case
1
:
scs
=
30000
;
if
(
N_RB_DL
==
217
)
{
fs
=
122.88e6
;
bw
=
80e6
;
}
else
if
(
N_RB_DL
==
245
)
{
fs
=
122.88e6
;
bw
=
90e6
;
}
else
if
(
N_RB_DL
==
273
)
{
fs
=
122.88e6
;
bw
=
100e6
;
}
else
if
(
N_RB_DL
==
106
)
{
fs
=
61.44e6
;
bw
=
40e6
;
}
else
AssertFatal
(
1
==
0
,
"Unsupported numerology for mu %d, N_RB %d
\n
"
,
mu
,
N_RB_DL
);
break
;
case
3
:
scs
=
120000
;
if
(
N_RB_DL
==
66
)
{
fs
=
122.88e6
;
bw
=
100e6
;
}
else
AssertFatal
(
1
==
0
,
"Unsupported numerology for mu %d, N_RB %d
\n
"
,
mu
,
N_RB_DL
);
break
;
}
// cfo with respect to sub-carrier spacing
eps
=
cfo
/
scs
;
// computation of integer and fractional FO to compare with estimation results
int
IFO
;
if
(
eps
!=
0
.
0
)
{
printf
(
"Introducing a CFO of %lf relative to SCS of %d kHz
\n
"
,
eps
,
(
int
)(
scs
/
1000
));
if
(
eps
>
0
)
IFO
=
(
int
)(
eps
+
0
.
5
);
else
IFO
=
(
int
)(
eps
-
0
.
5
);
printf
(
"FFO = %lf; IFO = %d
\n
"
,
eps
-
IFO
,
IFO
);
}
channel_desc_t
*
UE2UE
;
int
n_tx
=
1
,
n_rx
=
1
;
UE2UE
=
new_channel_desc_scm
(
n_tx
,
n_rx
,
channel_model
,
fs
,
0
,
bw
,
300e-9
,
0
.
0
,
CORR_LEVEL_LOW
,
0
,
0
,
0
,
0
);
if
(
UE2UE
==
NULL
)
{
printf
(
"Problem generating channel model. Exiting.
\n
"
);
exit
(
-
1
);
}
/*****configure UE *************************/
UE_TX
=
calloc
(
1
,
sizeof
(
PHY_VARS_NR_UE
));
UE_RX
=
calloc
(
1
,
sizeof
(
PHY_VARS_NR_UE
));
LOG_I
(
PHY
,
"Configure UE-TX and sidelink UE-TX.
\n
"
);
configure_NR_UE
(
UE_TX
,
mu
,
N_RB_DL
);
configure_SL_UE
(
UE_TX
,
mu
,
N_RB_DL
,
ssb_offset
,
0xFFFF
);
LOG_I
(
PHY
,
"Configure UE-RX and sidelink UE-RX.
\n
"
);
configure_NR_UE
(
UE_RX
,
mu
,
N_RB_DL
);
UE_RX
->
is_synchronized
=
(
test_slss_search
)
?
0
:
1
;
configure_SL_UE
(
UE_RX
,
mu
,
N_RB_DL
,
ssb_offset
,
slss_id
);
/*****************************************/
sl_nr_ue_phy_params_t
*
sl_uetx
=
&
UE_TX
->
SL_UE_PHY_PARAMS
;
sl_nr_ue_phy_params_t
*
sl_uerx
=
&
UE_RX
->
SL_UE_PHY_PARAMS
;
frame_parms
=
&
sl_uetx
->
sl_frame_params
;
frame_tx
=
frame
%
1024
;
slot_tx
=
slot
%
frame_parms
->
slots_per_frame
;
frame_length_complex_samples
=
frame_parms
->
samples_per_subframe
*
NR_NUMBER_OF_SUBFRAMES_PER_FRAME
;
// frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP;
double
**
s_re
,
**
s_im
,
**
r_re
,
**
r_im
;
s_re
=
malloc
(
2
*
sizeof
(
double
*
));
s_im
=
malloc
(
2
*
sizeof
(
double
*
));
r_re
=
malloc
(
2
*
sizeof
(
double
*
));
r_im
=
malloc
(
2
*
sizeof
(
double
*
));
s_re
[
0
]
=
malloc16_clear
(
frame_length_complex_samples
*
sizeof
(
double
));
s_im
[
0
]
=
malloc16_clear
(
frame_length_complex_samples
*
sizeof
(
double
));
r_re
[
0
]
=
malloc16_clear
(
frame_length_complex_samples
*
sizeof
(
double
));
r_im
[
0
]
=
malloc16_clear
(
frame_length_complex_samples
*
sizeof
(
double
));
if
(
eps
!=
0
.
0
)
UE_RX
->
UE_fo_compensation
=
1
;
// if a frequency offset is set then perform fo estimation and compensation
UE_nr_rxtx_proc_t
proc
;
proc
.
frame_tx
=
frame
;
proc
.
nr_slot_tx
=
slot
;
nr_phy_data_tx_t
phy_data_tx
;
phy_data_tx
.
psbch_vars
.
tx_slss_id
=
slss_id
;
uint8_t
sl_mib
[
4
]
=
{
0
};
prepare_mib_bits
(
sl_mib
,
frame
,
slot
);
memcpy
(
phy_data_tx
.
psbch_vars
.
psbch_payload
,
sl_mib
,
4
);
phy_data_tx
.
sl_tx_action
=
SL_NR_CONFIG_TYPE_TX_PSBCH
;
proc
.
frame_rx
=
frame
;
proc
.
nr_slot_rx
=
slot
;
nr_phy_data_t
phy_data_rx
;
phy_data_rx
.
sl_rx_action
=
SL_NR_CONFIG_TYPE_RX_PSBCH
;
if
(
test_freqdomain_loopback
)
{
errors
+=
freq_domain_loopback
(
UE_TX
,
UE_RX
,
frame_tx
,
slot_tx
,
&
phy_data_tx
);
}
printf
(
"
\n
Sidelink TX UE - Frame.Slot %d.%d SLSS id:%d
\n
"
,
frame
,
slot
,
phy_data_tx
.
psbch_vars
.
tx_slss_id
);
printf
(
"Sidelink RX UE - Frame.Slot %d.%d SLSS id:%d
\n
"
,
proc
.
frame_rx
,
proc
.
nr_slot_rx
,
sl_uerx
->
sl_config
.
sl_sync_source
.
rx_slss_id
);
phy_procedures_nrUE_SL_TX
(
UE_TX
,
&
proc
,
&
phy_data_tx
);
for
(
SNR
=
snr0
;
SNR
>=
snr1
;
SNR
-=
1
)
{
for
(
int
trial
=
0
;
trial
<
n_trials
;
trial
++
)
{
for
(
int
i
=
0
;
i
<
frame_length_complex_samples
;
i
++
)
{
for
(
int
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_tx
;
aa
++
)
{
struct
complex16
*
txdata_ptr
=
(
struct
complex16
*
)
&
UE_TX
->
common_vars
.
txData
[
aa
][
i
];
r_re
[
aa
][
i
]
=
(
double
)
txdata_ptr
->
r
;
r_im
[
aa
][
i
]
=
(
double
)
txdata_ptr
->
i
;
}
}
LOG_M
(
"txData0.m"
,
"txd0"
,
UE_TX
->
common_vars
.
txData
[
0
],
frame_parms
->
samples_per_frame
,
1
,
1
);
// AWGN
sigma2_dB
=
20
*
log10
((
double
)
AMP
/
4
)
-
SNR
;
sigma2
=
pow
(
10
,
sigma2_dB
/
10
);
// printf("sigma2 %f (%f dB), tx_lev %f (%f dB)\n",sigma2,sigma2_dB,txlev,10*log10((double)txlev));
if
(
eps
!=
0
.
0
)
{
rf_rx
(
r_re
,
// real part of txdata
r_im
,
// imag part of txdata
NULL
,
// interference real part
NULL
,
// interference imag part
0
,
// interference power
frame_parms
->
nb_antennas_rx
,
// number of rx antennas
frame_length_complex_samples
,
// number of samples in frame
1.0e9
/
fs
,
// sampling time (ns)
cfo
,
// frequency offset in Hz
0
.
0
,
// drift (not implemented)
0
.
0
,
// noise figure (not implemented)
0
.
0
,
// rx gain in dB ?
200
,
// 3rd order non-linearity in dB ?
&
ip
,
// initial phase
30.0e3
,
// phase noise cutoff in kHz
-
500
.
0
,
// phase noise amplitude in dBc
0
.
0
,
// IQ imbalance (dB),
0
.
0
);
// IQ phase imbalance (rad)
}
for
(
int
i
=
0
;
i
<
frame_length_complex_samples
;
i
++
)
{
for
(
int
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_rx
;
aa
++
)
{
UE_RX
->
common_vars
.
rxdata
[
aa
][
i
].
r
=
(
short
)(
r_re
[
aa
][
i
]
+
sqrt
(
sigma2
/
2
)
*
gaussdouble
(
0
.
0
,
1
.
0
));
UE_RX
->
common_vars
.
rxdata
[
aa
][
i
].
i
=
(
short
)(
r_im
[
aa
][
i
]
+
sqrt
(
sigma2
/
2
)
*
gaussdouble
(
0
.
0
,
1
.
0
));
}
}
if
(
UE_RX
->
is_synchronized
==
0
)
{
nr_initial_sync_t
ret
=
{
false
,
0
};
UE_nr_rxtx_proc_t
proc
=
{
0
};
// Should not have SLSS id configured. Search should find SLSS id from TX UE
UE_RX
->
SL_UE_PHY_PARAMS
.
sl_config
.
sl_sync_source
.
rx_slss_id
=
0xFFFF
;
ret
=
sl_nr_slss_search
(
UE_RX
,
&
proc
,
1
);
printf
(
"Sidelink SLSS search returns status:%d, rx_offset:%d
\n
"
,
ret
.
cell_detected
,
ret
.
rx_offset
);
if
(
!
ret
.
cell_detected
)
sl_uerx
->
psbch
.
rx_errors
=
1
;
else
{
AssertFatal
(
UE_RX
->
SL_UE_PHY_PARAMS
.
sync_params
.
N_sl_id
==
slss_id
,
"DETECTED INCORRECT SLSS ID in SEARCH.CHECK id:%d
\n
"
,
UE_RX
->
SL_UE_PHY_PARAMS
.
sync_params
.
N_sl_id
);
sl_uerx
->
psbch
.
rx_ok
=
1
;
}
}
else
psbch_pscch_processing
(
UE_RX
,
&
proc
,
&
phy_data_rx
);
}
// noise trials
printf
(
"Runs:%d SNR %f: SLSS Search:%d crc ERRORs = %d, OK = %d
\n
"
,
n_trials
,
SNR
,
!
UE_RX
->
is_synchronized
,
sl_uerx
->
psbch
.
rx_errors
,
sl_uerx
->
psbch
.
rx_ok
);
errors
+=
sl_uerx
->
psbch
.
rx_errors
;
sl_uerx
->
psbch
.
rx_errors
=
0
;
sl_uerx
->
psbch
.
rx_ok
=
0
;
}
// NSR
if
(
errors
==
0
)
LOG_I
(
PHY
,
"PSBCH test OK
\n
"
);
else
LOG_E
(
PHY
,
"PSBCH test NOT OK
\n
"
);
free_channel_desc_scm
(
UE2UE
);
free
(
s_re
[
0
]);
free
(
s_im
[
0
]);
free
(
r_re
[
0
]);
free
(
r_im
[
0
]);
free
(
s_re
);
free
(
s_im
);
free
(
r_re
);
free
(
r_im
);
term_nr_ue_signal
(
UE_TX
,
1
);
term_nr_ue_signal
(
UE_RX
,
1
);
free
(
UE_TX
);
free
(
UE_RX
);
logTerm
();
loader_reset
();
return
errors
;
}
openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
View file @
ebeb2652
...
...
@@ -98,7 +98,7 @@ typedef struct {
uint32_t
gNB_index
;
/// component carrier id
int
cc_id
;
/// frame
/// frame
rx
frame_t
frame_rx
;
/// slot rx
uint32_t
slot_rx
;
...
...
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