Commit cb3108f4 authored by Robert Schmidt's avatar Robert Schmidt

Merge branch 'integration_2022_wk35' into 'develop'

integration_2022_wk35

See merge request oai/openairinterface5g!1682

MR !1571 PHY procedures for SRS MIMO
MR !1666 gzip optim, links for size
MR !1668 Update core images to latest develop for CI
MR !1670 Fix initial_cyclic_shift for pucch-ConfigCommon
MR !1671 Fix unaligned channel processing with odd number of rb
MR !1672 Enable 2 Downlink layers MIMO and other minor improvements in default configuration files
MR !1680 Fix buffer overflow and division by 0 for SRS
parents e28fccc7 e2faa154
......@@ -579,9 +579,17 @@ class Containerize():
lUserName = self.eNB2UserName
lPassWord = self.eNB2Password
lSsh.open(lIpAddr, lUserName, lPassWord)
lSsh.command('docker save ' + self.imageToCopy + ':' + imageTag + ' | gzip > ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60)
lSsh.copyin(lIpAddr, lUserName, lPassWord, '~/' + self.imageToCopy + '-' + imageTag + '.tar.gz', '.')
lSsh.command('docker save ' + self.imageToCopy + ':' + imageTag + ' | gzip --fast > ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60)
ret = lSsh.copyin(lIpAddr, lUserName, lPassWord, '~/' + self.imageToCopy + '-' + imageTag + '.tar.gz', '.')
if ret != 0:
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK)
self.exitStatus = 1
return False
lSsh.command('rm ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60)
if lSsh.getBefore().count('cannot remove'):
HTML.CreateHtmlTestRow('file not created by docker save', 'KO', CONST.ALL_PROCESSES_OK)
self.exitStatus = 1
return False
lSsh.close()
# Going to the Test Server
......@@ -599,15 +607,26 @@ class Containerize():
lPassWord = self.eNB2Password
lSsh.open(lIpAddr, lUserName, lPassWord)
lSsh.copyout(lIpAddr, lUserName, lPassWord, './' + self.imageToCopy + '-' + imageTag + '.tar.gz', '~')
# copyout has no return code and will quit if something fails
lSsh.command('docker rmi ' + self.imageToCopy + ':' + imageTag, '\$', 10)
lSsh.command('docker load < ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60)
if lSsh.getBefore().count('o such file') or lSsh.getBefore().count('invalid tar header'):
logging.debug(lSsh.getBefore())
HTML.CreateHtmlTestRow('problem during docker load', 'KO', CONST.ALL_PROCESSES_OK)
self.exitStatus = 1
return False
lSsh.command('rm ' + self.imageToCopy + '-' + imageTag + '.tar.gz', '\$', 60)
if lSsh.getBefore().count('cannot remove'):
HTML.CreateHtmlTestRow('file not copied during scp?', 'KO', CONST.ALL_PROCESSES_OK)
self.exitStatus = 1
return False
lSsh.close()
if os.path.isfile('./' + self.imageToCopy + '-' + imageTag + '.tar.gz'):
os.remove('./' + self.imageToCopy + '-' + imageTag + '.tar.gz')
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
return True
def DeployObject(self, HTML, EPC):
if self.eNB_serverId[self.eNB_instance] == '0':
......@@ -683,6 +702,9 @@ class Containerize():
logging.debug(' -- ' + str(unhealthyNb) + ' unhealthy container(s)')
logging.debug(' -- ' + str(startingNb) + ' still starting container(s)')
self.testCase_id = HTML.testCase_id
self.eNB_logFile[self.eNB_instance] = 'enb_' + self.testCase_id + '.log'
status = False
if healthyNb == 1:
cnt = 0
......@@ -697,11 +719,12 @@ class Containerize():
status = True
logging.info('\u001B[1m Deploying OAI object Pass\u001B[0m')
time.sleep(10)
else:
# containers are unhealthy, so we won't start. However, logs are stored at the end
# in UndeployObject so we here store the logs of the unhealthy container to report it
mySSH.command('docker logs ' + containerName + ' > ' + lSourcePath + '/cmake_targets/' + self.eNB_logFile[self.eNB_instance], '\$', 30)
mySSH.close()
self.testCase_id = HTML.testCase_id
self.eNB_logFile[self.eNB_instance] = 'enb_' + self.testCase_id + '.log'
if status:
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
else:
......
......@@ -253,7 +253,7 @@ class EPCManagement():
logging.debug('Starting OAI CN5G')
mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5)
mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts', '\$', 5)
mySSH.command('cd /opt/oai-cn5g-fed-v1.3/docker-compose', '\$', 5)
mySSH.command('cd /opt/oai-cn5g-fed-v1.4/docker-compose', '\$', 5)
mySSH.command('python3 ./core-network.py '+self.cfgDeploy, '\$', 60)
if re.search('start-mini-as-ue', self.cfgDeploy):
dFile = 'docker-compose-mini-nrf-asue.yaml'
......@@ -537,7 +537,7 @@ class EPCManagement():
mySSH.command('docker logs ' + c + ' > ' + self.SourceCodePath + '/logs/' + c + '.log', '\$', 5)
logging.debug('Terminating OAI CN5G')
mySSH.command('cd /opt/oai-cn5g-fed-v1.3/docker-compose', '\$', 5)
mySSH.command('cd /opt/oai-cn5g-fed-v1.4/docker-compose', '\$', 5)
mySSH.command('python3 ./core-network.py '+self.cfgUnDeploy, '\$', 60)
mySSH.command('docker volume prune --force || true', '\$', 60)
time.sleep(2)
......
......@@ -921,7 +921,9 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
elif action == 'Build_Proxy':
CONTAINERS.BuildProxy(HTML)
elif action == 'Copy_Image_to_Test':
CONTAINERS.Copy_Image_to_Test_Server(HTML)
success = CONTAINERS.Copy_Image_to_Test_Server(HTML)
if not success:
RAN.prematureExit = True
elif action == 'Deploy_Object':
CONTAINERS.DeployObject(HTML, EPC)
if CONTAINERS.exitStatus==1:
......
......@@ -2,7 +2,7 @@ version: '3.8'
services:
oai-nrf:
container_name: "l2sim-oai-nrf"
image: oai-nrf:latest
image: oai-nrf:august-dev
environment:
- NRF_INTERFACE_NAME_FOR_SBI=eth0
- NRF_INTERFACE_PORT_FOR_SBI=80
......@@ -42,7 +42,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "l2sim-oai-amf"
image: oai-amf:latest
image: oai-amf:august-dev
environment:
- TZ=Europe/paris
- INSTANCE=0
......@@ -110,7 +110,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "l2sim-oai-smf"
image: oai-smf:latest
image: oai-smf:august-dev
environment:
- TZ=Europe/Paris
- INSTANCE=0
......@@ -156,7 +156,7 @@ services:
ipv4_address: 192.168.71.133
oai-spgwu:
container_name: "l2sim-oai-spgwu"
image: oai-spgwu-tiny:latest
image: oai-spgwu-tiny:august-dev
environment:
- TZ=Europe/Paris
- PID_DIRECTORY=/var/run
......
......@@ -2,7 +2,7 @@ version: '3.8'
services:
oai-nrf:
container_name: "rfsim5g-oai-nrf"
image: oai-nrf:latest
image: oai-nrf:august-dev
environment:
- NRF_INTERFACE_NAME_FOR_SBI=eth0
- NRF_INTERFACE_PORT_FOR_SBI=80
......@@ -42,7 +42,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oai-amf:latest
image: oai-amf:august-dev
environment:
- TZ=Europe/paris
- INSTANCE=0
......@@ -110,7 +110,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oai-smf:latest
image: oai-smf:august-dev
environment:
- TZ=Europe/Paris
- INSTANCE=0
......@@ -156,7 +156,7 @@ services:
ipv4_address: 192.168.71.133
oai-spgwu:
container_name: "rfsim5g-oai-spgwu"
image: oai-spgwu-tiny:latest
image: oai-spgwu-tiny:august-dev
environment:
- TZ=Europe/Paris
- PID_DIRECTORY=/var/run
......
......@@ -237,8 +237,9 @@ compilations() {
echo_error "$2 compilation failed"
exit 1
fi
if [ -s $3 ] ; then
cp $3 $4
if [ -s "$3" ] ; then
rm -f "$4"
ln -s "$PWD/$3" "$4"
echo_success "$2 compiled"
check_warnings "$dlog/$2.$REL.txt"
else
......
......@@ -43,6 +43,7 @@ RUN yum update -y && \
tzdata \
procps-ng \
atlas \
gdb \
python3 \
python3-pip \
net-tools \
......
......@@ -53,6 +53,7 @@ RUN apt-get update && \
iputils-ping \
iproute2 \
iperf \
gdb \
python \
python3 \
python3-six \
......
......@@ -46,6 +46,7 @@ RUN yum repolist --disablerepo=* && \
lksctp-tools \
nettle \
tzdata \
gdb \
python3 \
python3-pip \
net-tools \
......
......@@ -52,6 +52,7 @@ RUN apt-get update && \
net-tools \
iproute2 \
iputils-ping \
gdb \
python \
python3 \
python3-six \
......
......@@ -41,6 +41,7 @@ RUN yum update -y && \
tzdata \
procps-ng \
atlas \
gdb \
python3 \
python3-pip \
net-tools \
......
......@@ -47,6 +47,7 @@ RUN apt-get update && \
libatlas3-base \
libconfig9 \
net-tools \
gdb \
python \
python3 \
python3-six \
......
......@@ -44,6 +44,7 @@ RUN yum update -y && \
nettle \
tzdata \
atlas \
gdb \
python3 \
python3-pip \
iproute \
......
......@@ -46,6 +46,7 @@ RUN yum update -y && \
iputils \
iproute \
atlas \
gdb \
python3 \
python3-pip \
libXpm \
......
......@@ -50,6 +50,7 @@ RUN apt-get update && \
libconfig9 \
openssl \
net-tools \
gdb \
python \
python3 \
python3-six \
......
......@@ -51,9 +51,15 @@ for c in ${CONFIG_FILES}; do
# render template and inline replace config file
sed -i "${EXPRESSIONS}" ${c}
echo "=================================="
echo "== Configuration file: ${c}"
cat ${c}
done
# Load the USRP binaries
echo "=================================="
echo "== Load USRP binaries"
if [[ -v USE_B2XX ]]; then
$PREFIX/bin/uhd_images_downloader.py -t b2xx
elif [[ -v USE_X3XX ]]; then
......@@ -62,6 +68,9 @@ elif [[ -v USE_N3XX ]]; then
$PREFIX/bin/uhd_images_downloader.py -t n3xx
fi
# enable printing of stack traces on assert
export gdbStacks=1
echo "=================================="
echo "== Starting eNB soft modem"
if [[ -v USE_ADDITIONAL_OPTIONS ]]; then
......
......@@ -51,9 +51,15 @@ for c in ${CONFIG_FILES}; do
# render template and inline replace config file
sed -i "${EXPRESSIONS}" ${c}
echo "=================================="
echo "== Configuration file: ${c}"
cat ${c}
done
# Load the USRP binaries
echo "=================================="
echo "== Load USRP binaries"
if [[ -v USE_B2XX ]]; then
$PREFIX/bin/uhd_images_downloader.py -t b2xx
elif [[ -v USE_X3XX ]]; then
......@@ -62,6 +68,9 @@ elif [[ -v USE_N3XX ]]; then
$PREFIX/bin/uhd_images_downloader.py -t n3xx
fi
# enable printing of stack traces on assert
export gdbStacks=1
echo "=================================="
echo "== Starting gNB soft modem"
if [[ -v USE_ADDITIONAL_OPTIONS ]]; then
......
......@@ -31,9 +31,15 @@ for c in ${CONFIG_FILES}; do
# render template and inline replace config file
sed -i "${EXPRESSIONS}" ${c}
echo "=================================="
echo "== Configuration file: ${c}"
cat ${c}
done
# Load the USRP binaries
echo "=================================="
echo "== Load USRP binaries"
if [[ -v USE_B2XX ]]; then
$PREFIX/bin/uhd_images_downloader.py -t b2xx
elif [[ -v USE_X3XX ]]; then
......@@ -42,6 +48,9 @@ elif [[ -v USE_N3XX ]]; then
$PREFIX/bin/uhd_images_downloader.py -t n3xx
fi
# enable printing of stack traces on assert
export gdbStacks=1
echo "=================================="
echo "== Starting eNB soft modem"
if [[ -v USE_ADDITIONAL_OPTIONS ]]; then
......
......@@ -30,6 +30,10 @@ for c in ${CONFIG_FILES}; do
# render template and inline replace config file
sed -i "${EXPRESSIONS}" ${c}
echo "=================================="
echo "== Configuration file: ${c}"
cat ${c}
done
#now generate USIM files
......@@ -38,6 +42,8 @@ cd $PREFIX
$PREFIX/bin/conf2uedata -c $PREFIX/etc/ue_usim.conf -o $PREFIX
# Load the USRP binaries
echo "=================================="
echo "== Load USRP binaries"
if [[ -v USE_B2XX ]]; then
$PREFIX/bin/uhd_images_downloader.py -t b2xx
elif [[ -v USE_X3XX ]]; then
......@@ -57,6 +63,9 @@ if [[ -v USE_NFAPI ]]; then
new_args+=("$PREFIX/etc/ue.conf")
fi
# enable printing of stack traces on assert
export gdbStacks=1
echo "=================================="
echo "== Starting LTE UE soft modem"
if [[ -v USE_ADDITIONAL_OPTIONS ]]; then
......
......@@ -40,9 +40,15 @@ for c in ${CONFIG_FILES}; do
# render template and inline replace config file
sed -i "${EXPRESSIONS}" ${c}
echo "=================================="
echo "== Configuration file: ${c}"
cat ${c}
done
# Load the USRP binaries
echo "=================================="
echo "== Load USRP binaries"
if [[ -v USE_B2XX ]]; then
$PREFIX/bin/uhd_images_downloader.py -t b2xx
elif [[ -v USE_X3XX ]]; then
......@@ -58,6 +64,9 @@ while [[ $# -gt 0 ]]; do
shift
done
# enable printing of stack traces on assert
export gdbStacks=1
echo "=================================="
echo "== Starting NR UE soft modem"
if [[ -v USE_ADDITIONAL_OPTIONS ]]; then
......
......@@ -1290,42 +1290,33 @@ typedef struct
} nfapi_nr_pucch_pdu_t;
//for srs_pdu:
typedef struct
{
uint16_t rnti;//UE RNTI
uint32_t handle;//An opaque handling returned in the SRS.indication
//BWP
uint16_t bwp_size;
uint16_t bwp_start;
uint8_t subcarrier_spacing;
uint8_t cyclic_prefix;
uint8_t num_ant_ports;
uint8_t num_symbols;
uint8_t num_repetitions;
uint8_t time_start_position;//Starting position in the time domain l0; Note: the MAC undertakes the translation from startPosition to 𝑙0
uint8_t config_index;
uint16_t sequence_id;
uint8_t bandwidth_index;
uint8_t comb_size;
uint8_t comb_offset;//Transmission comb offset 𝑘 ̄ TC [TS38.211, Sec 6.4.1.4.3] Value: 0 → 1 (combSize = 0) Value: 0 → 3 (combSize = 1)
uint8_t cyclic_shift;
uint8_t frequency_position;
uint16_t frequency_shift;
uint8_t frequency_hopping;
uint8_t group_or_sequence_hopping;//Group or sequence hopping configuration (RRC parameter groupOrSequenceHopping in SRS-Resource
uint8_t resource_type;//Type of SRS resource allocation
uint16_t t_srs;//SRS-Periodicity in slots [TS38.211 Sec 6.4.1.4.4] Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560
uint16_t t_offset;//Slot offset value [TS38.211, Sec 6.4.1.4.3] Value:0->2559
typedef struct {
uint16_t rnti; // UE RNTI, Value: 1->65535
uint32_t handle; // An opaque handling returned in the SRS.indication
uint16_t bwp_size; // Bandwidth part size [3GPP TS 38.213, sec 12]. Number of contiguous PRBs allocated to the BWP, Value: 1->275
uint16_t bwp_start; // Bandwidth part start RB index from reference CRB [3GPP TS 38.213, sec 12], Value: 0->274
uint8_t subcarrier_spacing; // subcarrierSpacing [3GPP TS 38.211, sec 4.2], Value:0->4
uint8_t cyclic_prefix; // Cyclic prefix type [3GPP TS 38.211, sec 4.2], 0: Normal; 1: Extended
uint8_t num_ant_ports; // Number of antenna ports N_SRS_ap [3GPP TS 38.211, Sec 6.4.1.4.1], Value: 0 = 1 port, 1 = 2 ports, 2 = 4 ports
uint8_t num_symbols; // Number of symbols N_SRS_symb [3GPP TS 38.211, Sec 6.4.1.4.1], Value: 0 = 1 symbol, 1 = 2 symbols, 2 = 4 symbols
uint8_t num_repetitions; // Repetition factor R [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 = 1, 1 = 2, 2 = 4
uint8_t time_start_position; // Starting position in the time domain l_0 [3GPP TS 38.211, Sec 6.4.1.4.1], Note: the MAC undertakes the translation from startPosition to l_0, Value: 0 --> 13
uint8_t config_index; // SRS bandwidth config index C_SRS [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 63
uint16_t sequence_id; // SRS sequence ID n_SRS_ID [3GPP TS 38.211, Sec 6.4.1.4.2], Value: 0 --> 1023
uint8_t bandwidth_index; // SRS bandwidth index B_SRS [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 3
uint8_t comb_size; // Transmission comb size K_TC [3GPP TS 38.211, Sec 6.4.1.4.2], Value: 0 = comb size 2, 1 = comb size 4, 2 = comb size 8 (Rel16)
uint8_t comb_offset; // Transmission comb offset K'_TC[3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 1 (combSize = 0), Value: 0 --> 3 (combSize = 1), Value: 0 --> 7 (combSize = 2)
uint8_t cyclic_shift; // Cyclic shift n_CS_SRS [3GPP TS 38.211, Sec 6.4.1.4.2], Value: 0 --> 7 (combSize = 0), Value: 0 --> 11 (combSize = 1), Value: 0 --> 5 (combSize = 2)
uint8_t frequency_position; // Frequency domain position n_RRC [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 67
uint16_t frequency_shift; // Frequency domain shift n_shift [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 268
uint8_t frequency_hopping; // Frequency hopping b_hop [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 3
uint8_t group_or_sequence_hopping; // Group or sequence hopping configuration (RRC parameter groupOrSequenceHopping in SRSResource IE), Value: 0 = No hopping, 1 = Group hopping groupOrSequenceHopping, 2 = Sequence hopping
uint8_t resource_type; // Type of SRS resource allocation [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0: aperiodic, 1: semi-persistent, 2: periodic
uint16_t t_srs; // SRS-Periodicity in slots [3GPP TS 38.211, Sec 6.4.1.4.4], Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560
uint16_t t_offset; // Slot offset value [3GPP TS 38.211, Sec 6.4.1.4.3], Value:0->2559
nfapi_nr_ul_beamforming_t beamforming;
} nfapi_nr_srs_pdu_t;
//
typedef enum {
NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE = 0,
NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE = 1,
......
......@@ -613,6 +613,10 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
for (int id=0; id<NUMBER_OF_NR_SRS_MAX; id++) {
gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
gNB->nr_srs_info[id]->srs_generated_signal = (int32_t**)malloc16_clear(MAX_NUM_NR_SRS_AP*sizeof(int32_t*));
for(int ap=0; ap<MAX_NUM_NR_SRS_AP; ap++) {
gNB->nr_srs_info[id]->srs_generated_signal[ap] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t));
}
}
generate_ul_reference_signal_sequences(SHRT_MAX);
......@@ -767,6 +771,10 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(gNB->nr_csi_info);
for (int id = 0; id < NUMBER_OF_NR_SRS_MAX; id++) {
for(int i=0; i<MAX_NUM_NR_SRS_AP; i++) {
free_and_zero(gNB->nr_srs_info[id]->srs_generated_signal[i]);
}
free_and_zero(gNB->nr_srs_info[id]->srs_generated_signal);
free_and_zero(gNB->nr_srs_info[id]);
}
......
......@@ -28,6 +28,7 @@
#include "PHY/NR_REFSIG/dmrs_nr.h"
#include "PHY/NR_REFSIG/ptrs_nr.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_TRANSPORT/srs_modulation_nr.h"
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
......@@ -964,153 +965,238 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
const int slot,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
const int32_t *srs_generated_signal,
const int32_t **srs_generated_signal,
int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_ls_estimated_channel[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_estimated_channel_freq[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_estimated_channel_time[][gNB->frame_parms.ofdm_symbol_size],
int32_t srs_estimated_channel_time_shifted[][gNB->frame_parms.ofdm_symbol_size],
int32_t srs_ls_estimated_channel[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_estimated_channel_freq[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_estimated_channel_time[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
int32_t srs_estimated_channel_time_shifted[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
uint32_t *signal_power,
uint32_t *noise_power_per_rb,
uint32_t *noise_power,
int8_t *snr_per_rb,
int8_t *snr) {
if(nr_srs_info->sc_list_length == 0) {
LOG_E(NR_PHY, "(%d.%d) nr_srs_info was not generated yet!\n", frame, slot);
return -1;
}
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__);
#endif
const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB;
const uint8_t N_ap = 1<<srs_pdu->num_ant_ports;
const uint8_t K_TC = 2<<srs_pdu->comb_size;
const uint16_t m_SRS_b = srs_bandwidth_config[srs_pdu->config_index][srs_pdu->bandwidth_index][0];
const uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB/K_TC;
uint8_t fd_cdm = N_ap;
if (N_ap == 4 && ((K_TC == 2 && srs_pdu->cyclic_shift >= 4) || (K_TC == 4 && srs_pdu->cyclic_shift >= 6))) {
fd_cdm = 2;
}
int16_t ch_real[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length];
int16_t ch_imag[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length];
int16_t noise_real[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length];
int16_t noise_imag[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length];
int16_t ch_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS];
int16_t ch_imag[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS];
int16_t noise_real[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS];
int16_t noise_imag[frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS];
int16_t ls_estimated[2];
uint8_t mem_offset = 0;
while(((long)&srs_estimated_channel_freq[0][nr_srs_info->sc_list[0] + mem_offset] & 0xF) != 0) {
mem_offset++;
}
int32_t srs_est[frame_parms->ofdm_symbol_size*(1<<srs_pdu->num_symbols) + mem_offset] __attribute__ ((aligned(32)));
uint8_t mem_offset = ((16 - ((long)&srs_estimated_channel_freq[0][0][subcarrier_offset + nr_srs_info->k_0_p[0][0]])) & 0xF) >> 2; // >> 2 <=> /sizeof(int32_t)
// filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0}
// The End of OFDM symbol corresponds to the position of last 16384 in the filter
// The multadd_real_vector_complex_scalar applies the remaining 8 zeros of filter, therefore, to avoid a buffer overflow,
// we added 8 in the array size
int32_t srs_est[frame_parms->ofdm_symbol_size*(1<<srs_pdu->num_symbols) + mem_offset + 8] __attribute__ ((aligned(32)));
for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) {
memset(srs_ls_estimated_channel[ant], 0, frame_parms->ofdm_symbol_size*(1<<srs_pdu->num_symbols)*sizeof(int32_t));
for (int p_index = 0; p_index < N_ap; p_index++) {
memset(srs_ls_estimated_channel[ant][p_index], 0, frame_parms->ofdm_symbol_size*(1<<srs_pdu->num_symbols)*sizeof(int32_t));
memset(srs_est, 0, (frame_parms->ofdm_symbol_size*(1<<srs_pdu->num_symbols) + mem_offset)*sizeof(int32_t));
int16_t *srs_estimated_channel16 = (int16_t *)&srs_est[nr_srs_info->sc_list[0] + mem_offset];
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant);
#endif
uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
if (subcarrier>frame_parms->ofdm_symbol_size) {
subcarrier -= frame_parms->ofdm_symbol_size;
}
int16_t *srs_estimated_channel16 = (int16_t *)&srs_est[subcarrier + mem_offset];
for (int k = 0; k < M_sc_b_SRS; k++) {
if (k%fd_cdm==0) {
ls_estimated[0] = 0;
ls_estimated[1] = 0;
uint16_t subcarrier_cdm = subcarrier;
for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) {
for (int cdm_idx = 0; cdm_idx < fd_cdm; cdm_idx++) {
int16_t generated_real = ((c16_t*)srs_generated_signal)[nr_srs_info->sc_list[sc_idx]].r;
int16_t generated_imag = ((c16_t*)srs_generated_signal)[nr_srs_info->sc_list[sc_idx]].i;
int16_t generated_real = ((c16_t*)srs_generated_signal[p_index])[subcarrier_cdm].r;
int16_t generated_imag = ((c16_t*)srs_generated_signal[p_index])[subcarrier_cdm].i;
int16_t received_real = ((c16_t*)srs_received_signal[ant])[nr_srs_info->sc_list[sc_idx]].r;
int16_t received_imag = ((c16_t*)srs_received_signal[ant])[nr_srs_info->sc_list[sc_idx]].i;
int16_t received_real = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].r;
int16_t received_imag = ((c16_t*)srs_received_signal[ant])[subcarrier_cdm].i;
// We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the generated_real and generated_imag.
// So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16 bits.
ls_estimated[0] = (int16_t)(((int32_t)generated_real*received_real + (int32_t)generated_imag*received_imag)>>nr_srs_info->srs_generated_signal_bits);
ls_estimated[1] = (int16_t)(((int32_t)generated_real*received_imag - (int32_t)generated_imag*received_real)>>nr_srs_info->srs_generated_signal_bits);
srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]] = ls_estimated[0] + (((int32_t)ls_estimated[1] << 16) & 0xFFFF0000);
ls_estimated[0] += (int16_t)(((int32_t)generated_real*received_real + (int32_t)generated_imag*received_imag)>>nr_srs_info->srs_generated_signal_bits);
ls_estimated[1] += (int16_t)(((int32_t)generated_real*received_imag - (int32_t)generated_imag*received_real)>>nr_srs_info->srs_generated_signal_bits);
// Subcarrier increment
subcarrier_cdm += K_TC;
if (subcarrier_cdm >= frame_parms->ofdm_symbol_size) {
subcarrier_cdm=subcarrier_cdm-frame_parms->ofdm_symbol_size;
}
}
}
srs_ls_estimated_channel[ant][p_index][subcarrier] = ls_estimated[0] + (((int32_t)ls_estimated[1] << 16) & 0xFFFF0000);
const uint16_t sc_idx_offset = nr_srs_info->sc_list[sc_idx] + mem_offset;
#ifdef SRS_DEBUG
int subcarrier_log = subcarrier-subcarrier_offset;
if(subcarrier_log < 0) {
subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size;
}
if(subcarrier_log%12 == 0) {
LOG_I(NR_PHY,"------------------------------------ %d ------------------------------------\n", subcarrier_log/12);
LOG_I(NR_PHY,"\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n");
}
LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n",
subcarrier_log,
(int16_t)(srs_generated_signal[p_index][subcarrier] & 0xFFFF), (int16_t)((srs_generated_signal[p_index][subcarrier] >> 16) & 0xFFFF),
(int16_t)(srs_received_signal[ant][subcarrier] & 0xFFFF), (int16_t)((srs_received_signal[ant][subcarrier] >> 16) & 0xFFFF),
ls_estimated[0], ls_estimated[1]);
#endif
const uint16_t sc_offset = subcarrier + mem_offset;
// Channel interpolation
if(srs_pdu->comb_size == 0) {
if(sc_idx == 0) { // First subcarrier case
if(k == 0) { // First subcarrier case
// filt8_start is {12288,8192,4096,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt8_start, ls_estimated, srs_estimated_channel16, 8);
} else if(nr_srs_info->sc_list[sc_idx] < nr_srs_info->sc_list[sc_idx - 1]) { // Start of OFDM symbol case
} else if(subcarrier < K_TC) { // Start of OFDM symbol case
// filt8_start is {12288,8192,4096,0,0,0,0,0}
srs_estimated_channel16 = (int16_t *)&srs_est[nr_srs_info->sc_list[sc_idx]];
srs_estimated_channel16 = (int16_t *)&srs_est[subcarrier];
short *filter = mem_offset==0 ? filt8_start:filt8_start_shift2;
multadd_real_vector_complex_scalar(filter, ls_estimated, srs_estimated_channel16, 8);
} else if((sc_idx < (nr_srs_info->sc_list_length - 1) && nr_srs_info->sc_list[sc_idx + 1] < nr_srs_info->sc_list[sc_idx])
|| (sc_idx == (nr_srs_info->sc_list_length - 1))) { // End of OFDM symbol or last subcarrier cases
} else if((subcarrier+K_TC)>=frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS-1)) { // End of OFDM symbol or last subcarrier cases
// filt8_end is {4096,8192,12288,16384,0,0,0,0}
short *filter = mem_offset==0 || sc_idx == (nr_srs_info->sc_list_length - 1) ? filt8_end:filt8_end_shift2;
short *filter = mem_offset==0 || k == (M_sc_b_SRS-1) ? filt8_end:filt8_end_shift2;
multadd_real_vector_complex_scalar(filter, ls_estimated, srs_estimated_channel16, 8);
} else if(sc_idx%2 == 1) { // 1st middle case
} else if(k%2 == 1) { // 1st middle case
// filt8_middle2 is {4096,8192,8192,8192,4096,0,0,0}
multadd_real_vector_complex_scalar(filt8_middle2, ls_estimated, srs_estimated_channel16, 8);
} else if(sc_idx%2 == 0) { // 2nd middle case
} else if(k%2 == 0) { // 2nd middle case
// filt8_middle4 is {0,0,4096,8192,8192,8192,4096,0}
multadd_real_vector_complex_scalar(filt8_middle4, ls_estimated, srs_estimated_channel16, 8);
srs_estimated_channel16 = (int16_t *)&srs_est[sc_idx_offset];
srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset];
}
} else {
if(sc_idx == 0) { // First subcarrier case
if(k == 0) { // First subcarrier case
// filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16);
} else if(nr_srs_info->sc_list[sc_idx] < nr_srs_info->sc_list[sc_idx - 1]) { // Start of OFDM symbol case
srs_estimated_channel16 = (int16_t *)&srs_est[sc_idx_offset];
} else if(subcarrier < K_TC) { // Start of OFDM symbol case
srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset];
// filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16);
} else if((sc_idx < (nr_srs_info->sc_list_length - 1) && nr_srs_info->sc_list[sc_idx + 1] < nr_srs_info->sc_list[sc_idx])
|| (sc_idx == (nr_srs_info->sc_list_length - 1))) { // End of OFDM symbol or last subcarrier cases
} else if((subcarrier+K_TC)>=frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS-1)) { // End of OFDM symbol or last subcarrier cases
// filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt16_end, ls_estimated, srs_estimated_channel16, 16);
} else { // Middle case
// filt16_middle4 is {4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0}
multadd_real_vector_complex_scalar(filt16_middle4, ls_estimated, srs_estimated_channel16, 16);
srs_estimated_channel16 = (int16_t *)&srs_est[sc_idx_offset];
srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset];
}
}
// Subcarrier increment
subcarrier += K_TC;
if (subcarrier >= frame_parms->ofdm_symbol_size) {
subcarrier=subcarrier-frame_parms->ofdm_symbol_size;
}
} // for (int k = 0; k < M_sc_b_SRS; k++)
memcpy(&srs_estimated_channel_freq[ant][p_index][0],
&srs_est[mem_offset],
(frame_parms->ofdm_symbol_size*(1<<srs_pdu->num_symbols))*sizeof(int32_t));
// Compute noise
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
if (subcarrier>frame_parms->ofdm_symbol_size) {
subcarrier -= frame_parms->ofdm_symbol_size;
}
uint16_t base_idx = ant*N_ap*M_sc_b_SRS + p_index*M_sc_b_SRS;
for (int k = 0; k < M_sc_b_SRS; k++) {
ch_real[base_idx+k] = ((c16_t*)srs_estimated_channel_freq[ant][p_index])[subcarrier].r;
ch_imag[base_idx+k] = ((c16_t*)srs_estimated_channel_freq[ant][p_index])[subcarrier].i;
noise_real[base_idx+k] = abs(((c16_t*)srs_ls_estimated_channel[ant][p_index])[subcarrier].r - ch_real[base_idx+k]);
noise_imag[base_idx+k] = abs(((c16_t*)srs_ls_estimated_channel[ant][p_index])[subcarrier].i - ch_imag[base_idx+k]);
subcarrier += K_TC;
if (subcarrier >= frame_parms->ofdm_symbol_size) {
subcarrier=subcarrier-frame_parms->ofdm_symbol_size;
}
}
#ifdef SRS_DEBUG
uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12;
int subcarrier_log = nr_srs_info->sc_list[sc_idx]-subcarrier_offset;
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
if (subcarrier>frame_parms->ofdm_symbol_size) {
subcarrier -= frame_parms->ofdm_symbol_size;
}
for (int k = 0; k < K_TC*M_sc_b_SRS; k++) {
int subcarrier_log = subcarrier-subcarrier_offset;
if(subcarrier_log < 0) {
subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size;
}
if(sc_idx == 0) {
LOG_I(NR_PHY,"______________________________ Rx antenna %i _______________________________\n", ant);
}
if(subcarrier_log%12 == 0) {
LOG_I(NR_PHY,":::::::::::::::::::::::::::::::::::: %i ::::::::::::::::::::::::::::::::::::\n", subcarrier_log/12);
LOG_I(NR_PHY,"\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n");
LOG_I(NR_PHY,"------------------------------------- %d -------------------------------------\n", subcarrier_log/12);
LOG_I(NR_PHY,"\t __lsRe__________lsIm__|____intRe_______intIm__|____noiRe_______noiIm__\n");
}
LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n",
subcarrier_log,
generated_real, generated_imag,
received_real, received_imag,
ls_estimated[0], ls_estimated[1]);
#endif
(int16_t)(srs_ls_estimated_channel[ant][p_index][subcarrier]&0xFFFF),
(int16_t)((srs_ls_estimated_channel[ant][p_index][subcarrier]>>16)&0xFFFF),
(int16_t)(srs_estimated_channel_freq[ant][p_index][subcarrier]&0xFFFF),
(int16_t)((srs_estimated_channel_freq[ant][p_index][subcarrier]>>16)&0xFFFF),
noise_real[base_idx+(k/K_TC)], noise_imag[base_idx+(k/K_TC)]);
// Subcarrier increment
subcarrier++;
if (subcarrier >= frame_parms->ofdm_symbol_size) {
subcarrier=subcarrier-frame_parms->ofdm_symbol_size;
}
memcpy(&srs_estimated_channel_freq[ant][0],
&srs_est[mem_offset],
(frame_parms->ofdm_symbol_size*(1<<srs_pdu->num_symbols))*sizeof(int32_t));
// Compute noise
for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) {
ch_real[ant*nr_srs_info->sc_list_length + sc_idx] = ((c16_t*)srs_estimated_channel_freq[ant])[nr_srs_info->sc_list[sc_idx]].r;
ch_imag[ant*nr_srs_info->sc_list_length + sc_idx] = ((c16_t*)srs_estimated_channel_freq[ant])[nr_srs_info->sc_list[sc_idx]].i;
noise_real[ant*nr_srs_info->sc_list_length + sc_idx] = abs(((c16_t*)srs_ls_estimated_channel[ant])[nr_srs_info->sc_list[sc_idx]].r - ch_real[ant*nr_srs_info->sc_list_length + sc_idx]);
noise_imag[ant*nr_srs_info->sc_list_length + sc_idx] = abs(((c16_t*)srs_ls_estimated_channel[ant])[nr_srs_info->sc_list[sc_idx]].i - ch_imag[ant*nr_srs_info->sc_list_length + sc_idx]);
}
#endif
// Convert to time domain
freq2time(gNB->frame_parms.ofdm_symbol_size,
(int16_t*) srs_estimated_channel_freq[ant],
(int16_t*) srs_estimated_channel_time[ant]);
(int16_t*) srs_estimated_channel_freq[ant][p_index],
(int16_t*) srs_estimated_channel_time[ant][p_index]);
memcpy(&srs_estimated_channel_time_shifted[ant][0],
&srs_estimated_channel_time[ant][gNB->frame_parms.ofdm_symbol_size>>1],
memcpy(&srs_estimated_channel_time_shifted[ant][p_index][0],
&srs_estimated_channel_time[ant][p_index][gNB->frame_parms.ofdm_symbol_size>>1],
(gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t));
memcpy(&srs_estimated_channel_time_shifted[ant][gNB->frame_parms.ofdm_symbol_size>>1],
&srs_estimated_channel_time[ant][0],
memcpy(&srs_estimated_channel_time_shifted[ant][p_index][gNB->frame_parms.ofdm_symbol_size>>1],
&srs_estimated_channel_time[ant][p_index][0],
(gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t));
}
} // for (int p_index = 0; p_index < N_ap; p_index++)
} // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++)
// Compute signal power
*signal_power = calc_power(ch_real,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length)
+ calc_power(ch_imag,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length);
*signal_power = calc_power(ch_real,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS)
+ calc_power(ch_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS);
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"signal_power = %u\n", *signal_power);
......@@ -1127,84 +1213,48 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
const uint8_t factor_bits = signal_power_bits < 32 ? 32 - signal_power_bits : 0; // 32 due to input of dB_fixed(uint32_t x)
const int32_t factor_dB = dB_fixed(1<<factor_bits);
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12;
const uint8_t srs_symbols_per_rb = srs_pdu->comb_size == 0 ? 6 : 3;
const uint8_t n_noise_est = frame_parms->nb_antennas_rx * srs_symbols_per_rb;
uint8_t count_estimates = 0;
const uint8_t n_noise_est = frame_parms->nb_antennas_rx*N_ap*srs_symbols_per_rb;
uint64_t sum_re = 0;
uint64_t sum_re2 = 0;
uint64_t sum_im = 0;
uint64_t sum_im2 = 0;
for (int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) {
for (int rb = 0; rb < m_SRS_b; rb++) {
int subcarrier0 = nr_srs_info->sc_list[sc_idx]-subcarrier_offset;
if(subcarrier0 < 0) {
subcarrier0 = subcarrier0 + frame_parms->ofdm_symbol_size;
}
int rb = subcarrier0/NR_NB_SC_PER_RB;
sum_re = 0;
sum_re2 = 0;
sum_im = 0;
sum_im2 = 0;
for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) {
for (int p_index = 0; p_index < N_ap; p_index++) {
uint16_t base_idx = ant*N_ap*M_sc_b_SRS + p_index*M_sc_b_SRS + rb*srs_symbols_per_rb;
for (int srs_symb = 0; srs_symb < srs_symbols_per_rb; srs_symb++) {
sum_re = sum_re + noise_real[base_idx+srs_symb];
sum_re2 = sum_re2 + noise_real[base_idx+srs_symb]*noise_real[base_idx+srs_symb];
sum_im = sum_im + noise_imag[base_idx+srs_symb];
sum_im2 = sum_im2 + noise_imag[base_idx+srs_symb]*noise_imag[base_idx+srs_symb];
} // for (int srs_symb = 0; srs_symb < srs_symbols_per_rb; srs_symb++)
} // for (int p_index = 0; p_index < N_ap; p_index++)
} // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++)
sum_re = sum_re + noise_real[ant*nr_srs_info->sc_list_length+sc_idx];
sum_re2 = sum_re2 + noise_real[ant*nr_srs_info->sc_list_length+sc_idx]*noise_real[ant*nr_srs_info->sc_list_length+sc_idx];
sum_im = sum_im + noise_imag[ant*nr_srs_info->sc_list_length+sc_idx];
sum_im2 = sum_im2 + noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]*noise_imag[ant*nr_srs_info->sc_list_length+sc_idx];
count_estimates++;
if (count_estimates == n_noise_est) {
noise_power_per_rb[rb] = max(sum_re2 / n_noise_est - (sum_re / n_noise_est) * (sum_re / n_noise_est) +
sum_im2 / n_noise_est - (sum_im / n_noise_est) * (sum_im / n_noise_est), 1);
snr_per_rb[rb] = dB_fixed((int32_t)((*signal_power<<factor_bits)/noise_power_per_rb[rb])) - factor_dB;
count_estimates = 0;
sum_re = 0;
sum_re2 = 0;
sum_im = 0;
sum_im2 = 0;
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"noise_power_per_rb[%i] = %i, snr_per_rb[%i] = %i dB\n", rb, noise_power_per_rb[rb], rb, snr_per_rb[rb]);
#endif
}
}
}
} // for (int rb = 0; rb < m_SRS_b; rb++)
*noise_power = calc_power(noise_real,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length)
+ calc_power(noise_imag,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length);
*noise_power = max(calc_power(noise_real,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS)
+ calc_power(noise_imag,frame_parms->nb_antennas_rx*N_ap*M_sc_b_SRS), 1);
*snr = dB_fixed((int32_t)((*signal_power<<factor_bits)/(*noise_power))) - factor_dB;
#ifdef SRS_DEBUG
uint8_t R = srs_pdu->comb_size == 0 ? 2 : 4;
for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) {
for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) {
int subcarrier_log = nr_srs_info->sc_list[sc_idx]-subcarrier_offset;
if(subcarrier_log < 0) {
subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size;
}
if(sc_idx == 0) {
LOG_I(NR_PHY,"______________________________ Rx antenna %i _______________________________\n", ant);
}
if(subcarrier_log%12 == 0) {
LOG_I(NR_PHY,":::::::::::::::::::::::::::::::::::: %i ::::::::::::::::::::::::::::::::::::\n", subcarrier_log/12);
LOG_I(NR_PHY,"\t __lsRe__________lsIm__|____intRe_______intIm__|____noiRe_______noiIm_\n");
}
for(int r = 0; r<R; r++) {
if (nr_srs_info->sc_list[sc_idx] + r >= frame_parms->ofdm_symbol_size)
continue;
LOG_I(NR_PHY,"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n",
subcarrier_log+r,
(int16_t)(srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]+r]&0xFFFF),
(int16_t)((srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]+r]>>16)&0xFFFF),
(int16_t)(srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]+r]&0xFFFF),
(int16_t)((srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]+r]>>16)&0xFFFF),
noise_real[ant*nr_srs_info->sc_list_length+sc_idx],
noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]);
}
}
}
LOG_I(NR_PHY,"noise_power = %u, SNR = %i dB\n", *noise_power, *snr);
#endif
......
......@@ -71,12 +71,12 @@ int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB,
const int slot,
const nfapi_nr_srs_pdu_t *srs_pdu,
const nr_srs_info_t *nr_srs_info,
const int32_t *srs_generated_signal,
const int32_t **srs_generated_signal,
int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_ls_estimated_channel[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_estimated_channel_freq[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_estimated_channel_time[][gNB->frame_parms.ofdm_symbol_size],
int32_t srs_estimated_channel_time_shifted[][gNB->frame_parms.ofdm_symbol_size],
int32_t srs_ls_estimated_channel[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_estimated_channel_freq[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)],
int32_t srs_estimated_channel_time[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
int32_t srs_estimated_channel_time_shifted[][1<<srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
uint32_t *signal_power,
uint32_t *noise_power_per_rb,
uint32_t *noise_power,
......
......@@ -315,19 +315,19 @@ int nr_find_pucch(uint16_t rnti,
NR_gNB_SRS_t *new_gNB_srs(void);
void free_gNB_srs(NR_gNB_SRS_t *srs);
int nr_find_srs(uint16_t rnti,
int frame,
int slot,
int nr_find_srs(rnti_t rnti,
frame_t frame,
slot_t slot,
PHY_VARS_gNB *gNB);
void nr_fill_srs(PHY_VARS_gNB *gNB,
int frame,
int slot,
frame_t frame,
slot_t slot,
nfapi_nr_srs_pdu_t *srs_pdu);
int nr_get_srs_signal(PHY_VARS_gNB *gNB,
int frame,
int slot,
frame_t frame,
slot_t slot,
nfapi_nr_srs_pdu_t *srs_pdu,
nr_srs_info_t *nr_srs_info,
int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)]);
......
......@@ -30,10 +30,12 @@
#include <unistd.h>
#include <fcntl.h>
#include "PHY/INIT/phy_init.h"
#include "PHY/impl_defs_nr.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_gNB.h"
#include <openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h>
#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h"
#include "PHY/NR_UE_TRANSPORT/srs_modulation_nr.h"
#include "common/utils/LOG/log.h"
#include "nfapi/oai_integration/vendor_ext.h"
......@@ -54,9 +56,9 @@ void free_gNB_srs(NR_gNB_SRS_t *srs)
free_and_zero(srs);
}
int nr_find_srs(uint16_t rnti,
int frame,
int slot,
int nr_find_srs(rnti_t rnti,
frame_t frame,
slot_t slot,
PHY_VARS_gNB *gNB) {
AssertFatal(gNB!=NULL,"gNB is null\n");
......@@ -78,8 +80,8 @@ int nr_find_srs(uint16_t rnti,
}
void nr_fill_srs(PHY_VARS_gNB *gNB,
int frame,
int slot,
frame_t frame,
slot_t slot,
nfapi_nr_srs_pdu_t *srs_pdu) {
int id = nr_find_srs(srs_pdu->rnti,frame,slot,gNB);
......@@ -94,23 +96,28 @@ void nr_fill_srs(PHY_VARS_gNB *gNB,
}
int nr_get_srs_signal(PHY_VARS_gNB *gNB,
int frame,
int slot,
frame_t frame,
slot_t slot,
nfapi_nr_srs_pdu_t *srs_pdu,
nr_srs_info_t *nr_srs_info,
int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)]) {
if(nr_srs_info->sc_list_length == 0) {
LOG_E(NR_PHY, "(%d.%d) nr_srs_info was not generated yet!\n", frame, slot);
return -1;
}
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__);
#endif
int32_t **rxdataF = gNB->common_vars.rxdataF;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
const uint16_t n_symbols = (slot&3)*frame_parms->symbols_per_slot; // number of symbols until this slot
const uint8_t l0 = frame_parms->symbols_per_slot - 1 - srs_pdu->time_start_position; // starting symbol in this slot
const uint64_t symbol_offset = (n_symbols+l0)*frame_parms->ofdm_symbol_size;
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB;
uint16_t n_symbols = (slot&3)*frame_parms->symbols_per_slot; // number of symbols until this slot
uint8_t l0 = frame_parms->symbols_per_slot - 1 - srs_pdu->time_start_position; // starting symbol in this slot
uint64_t symbol_offset = (n_symbols+l0)*frame_parms->ofdm_symbol_size;
const uint8_t N_ap = 1<<srs_pdu->num_ant_ports;
const uint8_t N_symb_SRS = 1<<srs_pdu->num_symbols;
const uint8_t K_TC = 2<<srs_pdu->comb_size;
const uint16_t M_sc_b_SRS = srs_bandwidth_config[srs_pdu->config_index][srs_pdu->bandwidth_index][0] * NR_NB_SC_PER_RB/K_TC;
int32_t *rx_signal;
bool no_srs_signal = true;
......@@ -119,32 +126,56 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
memset(srs_received_signal[ant], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
rx_signal = &rxdataF[ant][symbol_offset];
for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) {
srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]] = rx_signal[nr_srs_info->sc_list[sc_idx]];
for (int p_index = 0; p_index < N_ap; p_index++) {
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"===== UE port %d --> gNB Rx antenna %i =====\n", p_index, ant);
#endif
for (int l_line = 0; l_line < N_symb_SRS; l_line++) {
#ifdef SRS_DEBUG
LOG_I(NR_PHY,":::::::: OFDM symbol %d ::::::::\n", l0+l_line);
#endif
uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][l_line];
if (subcarrier>frame_parms->ofdm_symbol_size) {
subcarrier -= frame_parms->ofdm_symbol_size;
}
uint16_t l_line_offset = l_line*frame_parms->ofdm_symbol_size;
for (int k = 0; k < M_sc_b_SRS; k++) {
if (rx_signal[nr_srs_info->sc_list[sc_idx]] != 0) {
srs_received_signal[ant][l_line_offset+subcarrier] = rx_signal[l_line_offset+subcarrier];
if (rx_signal[l_line_offset+subcarrier] != 0) {
no_srs_signal = false;
}
#ifdef SRS_DEBUG
uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12;
int subcarrier_log = nr_srs_info->sc_list[sc_idx]-subcarrier_offset;
int subcarrier_log = subcarrier-subcarrier_offset;
if(subcarrier_log < 0) {
subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size;
}
if(sc_idx == 0) {
LOG_I(NR_PHY,"________ Rx antenna %i ________\n", ant);
}
if(subcarrier_log%12 == 0) {
LOG_I(NR_PHY,"::::::::::::: %i :::::::::::::\n", subcarrier_log/12);
LOG_I(NR_PHY,"------------ %d ------------\n", subcarrier_log/12);
}
LOG_I(NR_PHY,"(%i) \t%i\t%i\n",
subcarrier_log,
(int16_t)(srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]]&0xFFFF),
(int16_t)((srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]]>>16)&0xFFFF));
(int16_t)(srs_received_signal[ant][l_line_offset+subcarrier]&0xFFFF),
(int16_t)((srs_received_signal[ant][l_line_offset+subcarrier]>>16)&0xFFFF));
#endif
// Subcarrier increment
subcarrier += K_TC;
if (subcarrier >= frame_parms->ofdm_symbol_size) {
subcarrier=subcarrier-frame_parms->ofdm_symbol_size;
}
}
} // for (int k = 0; k < M_sc_b_SRS; k++)
} // for (int l_line = 0; l_line < N_symb_SRS; l_line++)
} // for (int p_index = 0; p_index < N_ap; p_index++)
} // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++)
if (no_srs_signal) {
LOG_W(NR_PHY, "No SRS signal\n");
......
......@@ -48,9 +48,129 @@
//#define SRS_DEBUG
/*******************************************************************
uint16_t group_number_hopping(int slot_number,
uint8_t n_ID_SRS,
uint8_t l0,
uint8_t l_line) {
// Pseudo-random sequence c(i) defined by TS 38.211 - Section 5.2.1
uint32_t cinit = n_ID_SRS;
uint8_t c_last_index = 8 * (slot_number * N_SYMB_SLOT + l0 + l_line) + 7;
uint32_t *c_sequence = calloc(c_last_index+1, sizeof(uint32_t));
pseudo_random_sequence(c_last_index+1, c_sequence, cinit);
// TS 38.211 - 6.4.1.4.2 Sequence generation
uint32_t f_gh = 0;
for (int m = 0; m <= 7; m++) {
f_gh += c_sequence[8 * (slot_number * N_SYMB_SLOT + l0 + l_line) + m] << m;
}
f_gh = f_gh%30;
uint8_t u = (f_gh + n_ID_SRS)%U_GROUP_NUMBER;
free(c_sequence);
return u;
}
uint16_t sequence_number_hopping(int slot_number,
uint8_t n_ID_SRS,
uint16_t M_sc_b_SRS,
uint8_t l0,
uint8_t l_line) {
uint16_t v = 0;
if (M_sc_b_SRS > 6 * NR_NB_SC_PER_RB) {
// Pseudo-random sequence c(i) defined by TS 38.211 - Section 5.2.1
uint32_t cinit = n_ID_SRS;
uint8_t c_last_index = (slot_number * N_SYMB_SLOT + l0 + l_line);
uint32_t *c_sequence = calloc(c_last_index+1, sizeof(uint32_t));
pseudo_random_sequence(c_last_index+1, c_sequence, cinit);
// TS 38.211 - 6.4.1.4.2 Sequence generation
v = c_sequence[c_last_index];
free(c_sequence);
}
return v;
}
uint16_t compute_F_b(frame_t frame_number,
slot_t slot_number,
uint16_t slots_per_frame,
uint8_t N_symb_SRS,
uint8_t B_SRS,
uint8_t C_SRS,
uint8_t b_hop,
uint8_t R,
uint16_t T_offset,
uint16_t T_SRS,
resourceType_t resource_type,
uint8_t l_line,
uint8_t b) {
// Compute the number of SRS transmissions
uint16_t n_SRS = 0;
if (resource_type == aperiodic) {
n_SRS = l_line / R;
} else {
n_SRS = ((slots_per_frame*frame_number + slot_number - T_offset)/T_SRS)*(N_symb_SRS/R)+(l_line / R);
}
uint16_t product_N_b = 1;
for (unsigned int b_prime = b_hop; b_prime < B_SRS; b_prime++) {
if (b_prime != b_hop) {
product_N_b *= srs_bandwidth_config[C_SRS][b_prime][1];
}
}
uint16_t F_b = 0;
uint8_t N_b = srs_bandwidth_config[C_SRS][b][1];
if (N_b & 1) { // Nb odd
F_b = (N_b/2)*(n_SRS/product_N_b);
} else { // Nb even
uint16_t product_N_b_B_SRS = product_N_b;
product_N_b_B_SRS *= srs_bandwidth_config[C_SRS][B_SRS][1]; /* product for b_hop to b */
F_b = (N_b/2)*((n_SRS%product_N_b_B_SRS)/product_N_b) + ((n_SRS%product_N_b_B_SRS)/2*product_N_b);
}
return F_b;
}
uint16_t compute_n_b(frame_t frame_number,
slot_t slot_number,
uint16_t slots_per_frame,
uint8_t N_symb_SRS,
uint8_t B_SRS,
uint8_t C_SRS,
uint8_t b_hop,
uint8_t n_RRC,
uint8_t R,
uint16_t T_offset,
uint16_t T_SRS,
resourceType_t resource_type,
uint8_t l_line,
uint8_t b) {
uint8_t N_b = srs_bandwidth_config[C_SRS][b][1];
uint16_t m_SRS_b = srs_bandwidth_config[C_SRS][B_SRS][0];
uint16_t n_b = 0;
if (b_hop >= B_SRS) {
n_b = (4 * n_RRC/m_SRS_b)%N_b;
} else {
if (b <= b_hop) {
n_b = (4 * n_RRC/m_SRS_b)%N_b;
} else {
// Compute the hopping offset Fb
uint16_t F_b = compute_F_b(frame_number, slot_number, slots_per_frame, N_symb_SRS, B_SRS, C_SRS, b_hop, R,
T_offset, T_SRS, resource_type, l_line, b);
n_b = (F_b + (4 * n_RRC/m_SRS_b))%N_b;
}
}
return n_b;
}
/*************************************************************************
*
* NAME : generate_srs
* NAME : generate_srs_nr
*
* PARAMETERS : pointer to srs config pdu
* pointer to transmit buffer
......@@ -60,68 +180,43 @@
* -1 if sequence can not be properly generated
*
* DESCRIPTION : generate/map srs symbol into transmit buffer
* see TS 38211 6.4.1.4 Sounding reference signal
*
* FFS_TODO_NR
* Current supported configuration:
* - single resource per resource set
* - single port antenna
* - 1 symbol for SRS
* - no symbol offset
* - periodic mode
* - no hopping
* - no carrier switching
* - no antenna switching*
* See TS 38.211 - Section 6.4.1.4 Sounding reference signal
*
*********************************************************************/
***************************************************************************/
int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu,
NR_DL_FRAME_PARMS *frame_parms,
int32_t *txptr,
int32_t **txdataF,
uint16_t symbol_offset,
nr_srs_info_t *nr_srs_info,
int16_t amp,
int frame_number,
int slot_number)
{
uint8_t n_SRS_cs_max;
uint8_t u;
uint8_t v_nu;
uint32_t f_gh = 0;
uint16_t n_SRS;
uint16_t n_SRS_cs_i;
double alpha_i;
uint8_t K_TC_p;
uint16_t n_b[B_SRS_NUMBER];
uint16_t F_b;
uint16_t subcarrier;
uint8_t N_b;
uint8_t k_0_overbar_p;
frame_t frame_number,
slot_t slot_number) {
// get parameters from srs_config_pdu
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"Calling %s function\n", __FUNCTION__);
#endif
// SRS config parameters
uint8_t B_SRS = srs_config_pdu->bandwidth_index;
uint8_t C_SRS = srs_config_pdu->config_index;
uint8_t b_hop = srs_config_pdu->frequency_hopping;
uint8_t K_TC = 2<<srs_config_pdu->comb_size;
uint8_t K_TC_overbar = srs_config_pdu->comb_offset; // FFS_TODO_NR is this parameter for K_TC_overbar ??
uint8_t K_TC_overbar = srs_config_pdu->comb_offset;
uint8_t n_SRS_cs = srs_config_pdu->cyclic_shift;
uint8_t n_ID_SRS = srs_config_pdu->sequence_id;
uint8_t n_shift = srs_config_pdu->frequency_position; // it adjusts the SRS allocation to align with the common resource block grid in multiples of four
uint8_t n_shift = srs_config_pdu->frequency_position; // It adjusts the SRS allocation to align with the common resource block grid in multiples of four
uint8_t n_RRC = srs_config_pdu->frequency_shift;
uint8_t groupOrSequenceHopping = srs_config_pdu->group_or_sequence_hopping;
uint8_t l_offset = srs_config_pdu->time_start_position;
uint16_t T_SRS = srs_config_pdu->t_srs;
uint16_t T_offset = srs_config_pdu->t_offset; // FFS_TODO_NR to check interface with RRC
uint16_t T_offset = srs_config_pdu->t_offset;
uint8_t R = 1<<srs_config_pdu->num_repetitions;
uint8_t N_ap = 1<<srs_config_pdu->num_ant_ports; // antenna port for transmission
uint8_t N_symb_SRS = 1<<srs_config_pdu->num_symbols; // consecutive OFDM symbols
uint8_t l0 = frame_parms->symbols_per_slot - 1 - l_offset; // starting position in the time domain
uint8_t k_0_p; // frequency domain starting position
uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_config_pdu->bwp_start*N_SC_RB;
if(nr_srs_info) {
nr_srs_info->sc_list_length = 0;
nr_srs_info->srs_generated_signal_bits = log2_approx(amp);
}
uint8_t N_ap = 1<<srs_config_pdu->num_ant_ports; // Number of antenna port for transmission
uint8_t N_symb_SRS = 1<<srs_config_pdu->num_symbols; // Number of consecutive OFDM symbols
uint8_t l0 = frame_parms->symbols_per_slot - 1 - l_offset; // Starting symbol position in the time domain
uint8_t n_SRS_cs_max = srs_max_number_cs[srs_config_pdu->comb_size];
uint16_t m_SRS_b = srs_bandwidth_config[C_SRS][B_SRS][0]; // Number of resource blocks
uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB/K_TC; // Length of the SRS sequence
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"Frame = %i, slot = %i\n", frame_number, slot_number);
......@@ -142,265 +237,185 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu,
LOG_I(NR_PHY,"N_ap = %i\n", N_ap);
LOG_I(NR_PHY,"N_symb_SRS = %i\n", N_symb_SRS);
LOG_I(NR_PHY,"l0 = %i\n", l0);
LOG_I(NR_PHY,"n_SRS_cs_max = %i\n", n_SRS_cs_max);
LOG_I(NR_PHY,"m_SRS_b = %i\n", m_SRS_b);
LOG_I(NR_PHY,"M_sc_b_SRS = %i\n", M_sc_b_SRS);
#endif
if (N_ap != port1) {
LOG_E(NR_PHY, "generate_srs: this number of antenna ports %d is not yet supported!\n", N_ap);
return (-1);
}
if (N_symb_SRS != 1) {
LOG_E(NR_PHY, "generate_srs: this number of srs symbol %d is not yet supported!\n", N_symb_SRS);
return (-1);
}
if (groupOrSequenceHopping != neitherHopping) {
LOG_E(NR_PHY, "generate_srs: sequence hopping is not yet supported!\n");
return (-1);
}
// Validation of SRS config parameters
if (R == 0) {
LOG_E(NR_PHY, "generate_srs: this parameter repetition factor %d is not consistent !\n", R);
return (-1);
}
else if (R > N_symb_SRS) {
return -1;
} else if (R > N_symb_SRS) {
LOG_E(NR_PHY, "generate_srs: R %d can not be greater than N_symb_SRS %d !\n", R, N_symb_SRS);
return (-1);
}
/* see 38211 6.4.1.4.2 Sequence generation */
if (K_TC == 4) {
n_SRS_cs_max = 12;
// delta = 2; /* delta = log2(K_TC) */
}
else if (K_TC == 2) {
n_SRS_cs_max = 8;
// delta = 1; /* delta = log2(K_TC) */
}
else {
LOG_E(NR_PHY, "generate_srs: SRS unknown value for K_TC %d !\n", K_TC);
return (-1);
return -1;
}
if (n_SRS_cs >= n_SRS_cs_max) {
LOG_E(NR_PHY, "generate_srs: inconsistent parameter n_SRS_cs %d >= n_SRS_cs_max %d !\n", n_SRS_cs, n_SRS_cs_max);
return (-1);
return -1;
}
if (T_SRS == 0) {
LOG_E(NR_PHY, "generate_srs: inconsistent parameter T_SRS %d can not be equal to zero !\n", T_SRS);
return (-1);
}
else
{
return -1;
} else {
int index = 0;
while (srs_periodicity[index] != T_SRS) {
index++;
if (index == SRS_PERIODICITY) {
LOG_E(NR_PHY, "generate_srs: inconsistent parameter T_SRS %d not specified !\n", T_SRS);
return (-1);
return -1;
}
}
}
uint16_t m_SRS_b = srs_bandwidth_config[C_SRS][B_SRS][0]; /* m_SRS_b is given by TS 38211 clause 6.4.1.4.3 */
uint16_t M_sc_b_SRS = m_SRS_b * N_SC_RB/K_TC; /* length of the sounding reference signal sequence */
// Variable initialization
if(nr_srs_info) {
nr_srs_info->srs_generated_signal_bits = log2_approx(amp);
}
uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_config_pdu->bwp_start*NR_NB_SC_PER_RB;
double sqrt_N_ap = sqrt(N_ap);
uint16_t n_b[B_SRS_NUMBER];
// Find index of table which is for this SRS length
uint16_t M_sc_b_SRS_index = 0;
while((ul_allocated_re[M_sc_b_SRS_index] != M_sc_b_SRS) && (M_sc_b_SRS_index < SRS_SB_CONF)){
M_sc_b_SRS_index++;
}
/* for each antenna ports for transmission */
// SRS sequence generation and mapping, TS 38.211 - Section 6.4.1.4
for (int p_index = 0; p_index < N_ap; p_index++) {
/* see TS 38.211 6.4.1.4.2 Sequence generation */
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"============ port %d ============\n", p_index);
#endif
n_SRS_cs_i = (n_SRS_cs + (n_SRS_cs_max * (SRS_antenna_port[p_index] - 1000)/N_ap))%n_SRS_cs_max;
alpha_i = 2 * M_PI * ((double)n_SRS_cs_i / (double)n_SRS_cs_max);
uint16_t n_SRS_cs_i = (n_SRS_cs + (n_SRS_cs_max * (SRS_antenna_port[p_index] - 1000)/N_ap))%n_SRS_cs_max;
double alpha_i = 2 * M_PI * ((double)n_SRS_cs_i / (double)n_SRS_cs_max);
/* for each SRS symbol which should be managed by SRS configuration */
/* from TS 38.214 6.2.1.1 UE SRS frequency hopping procedure */
/* A UE may be configured to transmit an SRS resource on adjacent symbols within the last six symbols of a slot, */
/* where all antenna ports of the SRS resource are mapped to each symbol of the resource */
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"n_SRS_cs_i = %i\n", n_SRS_cs_i);
LOG_I(NR_PHY,"alpha_i = %f\n", alpha_i);
#endif
uint8_t l = p_index;
if (l >= N_symb_SRS) {
LOG_E(NR_PHY, "generate_srs: number of antenna ports %d and number of srs symbols %d are different !\n", N_ap, N_symb_SRS);
}
for (int l_line = 0; l_line < N_symb_SRS; l_line++) {
#ifdef SRS_DEBUG
LOG_I(NR_PHY,":::::::: OFDM symbol %d ::::::::\n", l0+l_line);
#endif
// Set group and sequence numbers (u,v) per OFDM symbol
uint16_t u = 0;
uint16_t v = 0;
switch(groupOrSequenceHopping) {
case neitherHopping:
{
f_gh = 0;
v_nu = 0;
u = n_ID_SRS%U_GROUP_NUMBER;
v = 0;
break;
}
case groupHopping:
{
uint8_t c_last_index = 8 * (slot_number * N_SYMB_SLOT + l0 + l) + 7; /* compute maximum value of the random sequence */
uint32_t *c_sequence = calloc(c_last_index+1, sizeof(uint32_t));
uint32_t cinit = n_ID_SRS/30;
pseudo_random_sequence(c_last_index+1, c_sequence, cinit);
for (int m = 0; m < 8; m++) {
f_gh += c_sequence[8 * (slot_number * N_SYMB_SLOT + l0 + l) + m]<<m;
}
free(c_sequence);
f_gh = f_gh%30;
v_nu = 0;
u = group_number_hopping(slot_number, n_ID_SRS, l0, l_line);
v = 0;
break;
}
case sequenceHopping:
{
f_gh = 0;
if (M_sc_b_SRS > 6 * N_SC_RB) {
uint8_t c_last_index = (slot_number * N_SYMB_SLOT + l0 + l); /* compute maximum value of the random sequence */
uint32_t *c_sequence = calloc(c_last_index+1, sizeof(uint32_t));
uint32_t cinit = n_ID_SRS;
pseudo_random_sequence(c_last_index+1, c_sequence, cinit);
v_nu = c_sequence[c_last_index];
free(c_sequence);
}
else {
v_nu = 0;
}
u = n_ID_SRS%U_GROUP_NUMBER;
v = sequence_number_hopping(slot_number, n_ID_SRS, M_sc_b_SRS, l0, l_line);
break;
}
default:
{
LOG_E(NR_PHY, "generate_srs: unknown hopping setting %d !\n", groupOrSequenceHopping);
return (-1);
}
return -1;
}
/* u is the sequence-group number defined in section 6.4.1.4.1 */
u = (f_gh + n_ID_SRS)%U_GROUP_NUMBER; /* 30 */
/* TS 38.211 6.4.1.4.3 Mapping to physical resources */
if((n_SRS_cs >= n_SRS_cs_max/2)&&(n_SRS_cs < n_SRS_cs_max)&&(N_ap == 4) && ((SRS_antenna_port[p_index] == 1001) || (SRS_antenna_port[p_index] == 1003))) {
K_TC_p = (K_TC_overbar + K_TC/2)%K_TC;
}
else {
K_TC_p = K_TC_overbar;
}
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"u = %i\n", u);
LOG_I(NR_PHY,"v = %i\n", v);
#endif
// Compute the frequency position index n_b
uint16_t sum_n_b = 0;
for (int b = 0; b <= B_SRS; b++) {
N_b = srs_bandwidth_config[C_SRS][b][1];
if (b_hop >= B_SRS) {
n_b[b] = (4 * n_RRC/m_SRS_b)%N_b; /* frequency hopping is disabled and the frequency position index n_b remains constant */
}
else {
if (b == b_hop) {
N_b = 1;
}
/* periodicity and offset */
if (srs_config_pdu->resource_type == aperiodic) {
n_SRS = l/R;
}
else {
int8_t N_slot_frame = frame_parms->slots_per_frame;
n_SRS = ((N_slot_frame*frame_number + slot_number - T_offset)/T_SRS)*(N_symb_SRS/R)+(l/R);
}
n_b[b] = compute_n_b(frame_number, slot_number, frame_parms->slots_per_frame, N_symb_SRS, B_SRS,
C_SRS, b_hop, n_RRC, R, T_offset, T_SRS, srs_config_pdu->resource_type, l_line, b);
uint16_t product_N_b = 1; /* for b_hop to b-1 */
for (unsigned int b_prime = b_hop; b_prime < B_SRS; b_prime++) { /* product for b_hop to b-1 */
if (b_prime != b_hop) {
product_N_b *= srs_bandwidth_config[C_SRS][b_prime][1];
}
}
sum_n_b += n_b[b];
if (N_b & 1) { /* Nb odd */
F_b = (N_b/2)*(n_SRS/product_N_b);
}
else { /* Nb even */
uint16_t product_N_b_B_SRS = product_N_b;
product_N_b_B_SRS *= srs_bandwidth_config[C_SRS][B_SRS][1]; /* product for b_hop to b */
F_b = (N_b/2)*((n_SRS%product_N_b_B_SRS)/product_N_b) + ((n_SRS%product_N_b_B_SRS)/2*product_N_b);
}
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"n_b[%i] = %i\n", b, n_b[b]);
#endif
if (b <= b_hop) {
n_b[b] = (4 * n_RRC/m_SRS_b)%N_b;
}
else {
n_b[b] = (F_b + (4 * n_RRC/m_SRS_b))%N_b;
}
}
}
k_0_overbar_p = n_shift * N_SC_RB + K_TC_p;
k_0_p = k_0_overbar_p; /* it is the frequency-domain starting position */
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"sum_n_b = %i\n", sum_n_b);
#endif
for (int b = 0; b <= B_SRS; b++) {
k_0_p += K_TC * M_sc_b_SRS * n_b[b];
// Compute the frequency-domain starting position
uint8_t K_TC_p = 0;
if((n_SRS_cs >= n_SRS_cs_max/2)&&(n_SRS_cs < n_SRS_cs_max)&&(N_ap == 4) && ((SRS_antenna_port[p_index] == 1001) || (SRS_antenna_port[p_index] == 1003))) {
K_TC_p = (K_TC_overbar + K_TC/2)%K_TC;
} else {
K_TC_p = K_TC_overbar;
}
uint8_t k_l_offset = 0; // If the SRS is configured by the IE SRS-PosResource-r16, the quantity k_l_offset is
// given by TS 38.211 - Table 6.4.1.4.3-2, otherwise k_l_offset = 0.
uint8_t k_0_overbar_p = (n_shift*NR_NB_SC_PER_RB + (K_TC_p+k_l_offset))%K_TC;
uint8_t k_0_p = k_0_overbar_p + K_TC*M_sc_b_SRS*sum_n_b;
nr_srs_info->k_0_p[p_index][l_line] = k_0_p;
subcarrier = subcarrier_offset + k_0_p;
#ifdef SRS_DEBUG
LOG_I(NR_PHY,"K_TC_p = %i\n", K_TC_p);
LOG_I(NR_PHY,"k_0_overbar_p = %i\n", k_0_overbar_p);
LOG_I(NR_PHY,"k_0_p = %i\n", k_0_p);
#endif
uint16_t subcarrier = subcarrier_offset + k_0_p;
if (subcarrier>frame_parms->ofdm_symbol_size) {
subcarrier -= frame_parms->ofdm_symbol_size;
}
uint16_t l_line_offset = l_line*frame_parms->ofdm_symbol_size;
/* find index of table which is for this srs length */
unsigned int M_sc_b_SRS_index = 0;
while((ul_allocated_re[M_sc_b_SRS_index] != M_sc_b_SRS) && (M_sc_b_SRS_index < SRS_SB_CONF)){
M_sc_b_SRS_index++;
}
// For each port, and for each OFDM symbol, here it is computed and mapped an SRS sequence with M_sc_b_SRS symbols
for (int k = 0; k < M_sc_b_SRS; k++) {
if (ul_allocated_re[M_sc_b_SRS_index] != M_sc_b_SRS) {
LOG_E(NR_PHY, "generate_srs: srs uplink allocation %d can not be found! \n", M_sc_b_SRS);
return (-1);
}
#if 0
char output_file[255];
char sequence_name[255];
sprintf(output_file, "rv_seq_%d_%d_%d.m", u, v_nu, ul_allocated_re[M_sc_b_SRS_index]);
sprintf(sequence_name, "rv_seq_%d_%d_%d", u, v_nu, ul_allocated_re[M_sc_b_SRS_index]);
write_output(output_file, sequence_name, rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index], ul_allocated_re[M_sc_b_SRS_index], 1, 1);
#endif
double shift_real = cos(alpha_i * k);
double shift_imag = sin(alpha_i * k);
int16_t r_overbar_real = rv_ul_ref_sig[u][v][M_sc_b_SRS_index][k<<1];
int16_t r_overbar_imag = rv_ul_ref_sig[u][v][M_sc_b_SRS_index][(k<<1)+1];
for (int k=0; k < M_sc_b_SRS; k++) {
// cos(x+y) = cos(x)cos(y) - sin(x)sin(y)
double r_real = (shift_real*r_overbar_real - shift_imag*r_overbar_imag) / sqrt_N_ap;
double real_shift = cos(alpha_i*k);
double imag_shift = sin(alpha_i*k);
// sin(x+y) = sin(x)cos(y) + cos(x)sin(y)
double r_imag = (shift_imag*r_overbar_real + shift_real*r_overbar_imag) / sqrt_N_ap;
/* cos(x + y) = cos(x)cos(y) - sin(x)sin(y) */
double real = ((real_shift*rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k]) - (imag_shift*rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k+1]))/sqrt(N_ap);
/* sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */
double imag = ((imag_shift*rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k]) + (real_shift*rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k+1]))/sqrt(N_ap);
int32_t real_amp = ((int32_t)round((double) amp * real)) >> 15;
int32_t imag_amp = ((int32_t)round((double) amp * imag)) >> 15;
#if 0
printf("subcarrier %5d srs[%3d] r: %4d i: %4d reference[%d][%d][%d] r: %6d i: %6d\n", subcarrier, k, real_amp, imag_amp,
u, v_nu, M_sc_b_SRS_index,
rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k],
rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k+1]);
#endif
txptr[subcarrier] = (real_amp & 0xFFFF) + ((imag_amp<<16)&0xFFFF0000);
if(nr_srs_info) {
nr_srs_info->sc_list[nr_srs_info->sc_list_length] = subcarrier;
nr_srs_info->sc_list_length++;
}
int32_t r_real_amp = ((int32_t) round((double) amp * r_real)) >> 15;
int32_t r_imag_amp = ((int32_t) round((double) amp * r_imag)) >> 15;
#ifdef SRS_DEBUG
int subcarrier_log = subcarrier-subcarrier_offset;
if(subcarrier_log < 0) {
subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size;
}
if( subcarrier_log%12 == 0 ) {
if(subcarrier_log%12 == 0) {
LOG_I(NR_PHY,"------------ %d ------------\n", subcarrier_log/12);
}
LOG_I(NR_PHY,"(%d) \t%i\t%i\n", subcarrier_log, (int16_t)(real_amp&0xFFFF), (int16_t)(imag_amp&0xFFFF));
LOG_I(NR_PHY,"(%d) \t%i\t%i\n", subcarrier_log, (int16_t)(r_real_amp&0xFFFF), (int16_t)(r_imag_amp&0xFFFF));
#endif
subcarrier += (K_TC); /* subcarrier increment */
txdataF[p_index][symbol_offset+l_line_offset+subcarrier] = (r_real_amp & 0xFFFF) + ((r_imag_amp<<16)&0xFFFF0000);
// Subcarrier increment
subcarrier += K_TC;
if (subcarrier >= frame_parms->ofdm_symbol_size) {
subcarrier=subcarrier-frame_parms->ofdm_symbol_size;
}
}
/* process next symbol */
//txptr = txptr + frame_parms->ofdm_symbol_size;
}
} // for (int k = 0; k < M_sc_b_SRS; k++)
} // for (int l_line = 0; l_line < N_symb_SRS; l_line++)
} // for (int p_index = 0; p_index < N_ap; p_index++)
return (0);
return 0;
}
/*******************************************************************
......@@ -457,7 +472,7 @@ int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gN
NR_DL_FRAME_PARMS *frame_parms = &(ue->frame_parms);
uint16_t symbol_offset = (frame_parms->symbols_per_slot - 1 - srs_config_pdu->time_start_position)*frame_parms->ofdm_symbol_size;
if (generate_srs_nr(srs_config_pdu, frame_parms, &ue->common_vars.txdataF[gNB_id][symbol_offset], ue->nr_srs_info,
if (generate_srs_nr(srs_config_pdu, frame_parms, ue->common_vars.txdataF, symbol_offset, ue->nr_srs_info,
AMP, proc->frame_tx, proc->nr_slot_tx) == 0) {
return 0;
} else {
......
......@@ -131,11 +131,19 @@ EXTERN const uint16_t srs_periodicity[SRS_PERIODICITY]
#endif
;
// TS 38.211 - Table 6.4.1.4.2-1
EXTERN const uint16_t srs_max_number_cs[3]
#ifdef INIT_VARIABLES_SRS_MODULATION_NR_H
= {8, 12, 6}
#endif
;
/*************** FUNCTIONS *****************************************/
/** \brief This function generates the sounding reference symbol (SRS) for the uplink according to 38.211 6.4.1.4 Sounding reference signal
@param frame_parms NR DL Frame parameters
@param txdataF pointer to the frequency domain TX signal
@param symbol_offset symbol offset added in txdataF
@param nr_srs_info pointer to the srs info structure
@param amp amplitude of generated signal
@param frame_number frame number
......@@ -144,11 +152,12 @@ EXTERN const uint16_t srs_periodicity[SRS_PERIODICITY]
int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu,
NR_DL_FRAME_PARMS *frame_parms,
int32_t *txptr,
int32_t **txdataF,
uint16_t symbol_offset,
nr_srs_info_t *nr_srs_info,
int16_t amp,
int frame_number,
int slot_number);
frame_t frame_number,
slot_t slot_number);
/** \brief This function checks for periodic srs if srs should be transmitted in this slot
* @param p_SRS_Resource pointer to active resource
......
......@@ -85,38 +85,30 @@ void multadd_real_vector_complex_scalar(int16_t *x,
uint32_t i;
// do 8 multiplications at a time
simd_q15_t alpha_r_128,alpha_i_128,yr,yi,*x_128=(simd_q15_t*)x,*y_128=(simd_q15_t*)y;
int j;
simd_q15_t alpha_r_128, alpha_i_128, yr, yi, *x_128 = (simd_q15_t *)x, *y_128 = (simd_q15_t *)y;
// printf("alpha = %d,%d\n",alpha[0],alpha[1]);
alpha_r_128 = set1_int16(alpha[0]);
alpha_i_128 = set1_int16(alpha[1]);
j=0;
for (i=0; i<N>>3; i++) {
yr = mulhi_s1_int16(alpha_r_128,x_128[i]);
yi = mulhi_s1_int16(alpha_i_128,x_128[i]);
#if defined(__x86_64__) || defined(__i386__)
y_128[j] = _mm_adds_epi16(y_128[j],_mm_unpacklo_epi16(yr,yi));
j++;
y_128[j] = _mm_adds_epi16(y_128[j],_mm_unpackhi_epi16(yr,yi));
j++;
const simd_q15_t tmp = _mm_loadu_si128(y_128);
_mm_storeu_si128(y_128++, _mm_adds_epi16(tmp, _mm_unpacklo_epi16(yr, yi)));
const simd_q15_t tmp2 = _mm_loadu_si128(y_128);
_mm_storeu_si128(y_128++, _mm_adds_epi16(tmp2, _mm_unpackhi_epi16(yr, yi)));
#elif defined(__arm__)
int16x8x2_t yint;
yint = vzipq_s16(yr,yi);
y_128[j] = adds_int16(y_128[j],yint.val[0]);
*y_128 = adds_int16(*y_128, yint.val[0]);
j++;
y_128[j] = adds_int16(y_128[j],yint.val[1]);
*y_128 = adds_int16(*y_128, yint.val[1]);
j++;
#endif
}
_mm_empty();
_m_empty();
}
void multadd_real_four_symbols_vector_complex_scalar(int16_t *x,
......
......@@ -97,6 +97,7 @@
#define MAX_NUM_NR_RE (4*14*273*12)
#define MAX_NUM_NR_SRS_SYMBOLS 4
#define MAX_NUM_NR_SRS_AP 4
#define NR_RX_NB_TH 1
#define NR_NB_TH_SLOT 2
......@@ -241,10 +242,9 @@ typedef struct {
} NR_PRACH_RESOURCES_t;
typedef struct {
uint16_t sc_list_length;
uint16_t sc_list[6*273];
uint8_t k_0_p[MAX_NUM_NR_SRS_AP][MAX_NUM_NR_SRS_SYMBOLS];
uint8_t srs_generated_signal_bits;
int32_t srs_generated_signal[OFDM_SYMBOL_SIZE_SAMPLES_MAX * MAX_NUM_NR_SRS_SYMBOLS];
int32_t **srs_generated_signal;
} nr_srs_info_t;
typedef struct {
......
......@@ -807,10 +807,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu;
uint8_t N_symb_SRS = 1<<srs_pdu->num_symbols;
int32_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS];
int32_t srs_ls_estimated_channel[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS];
int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS] __attribute__ ((aligned(32)));
int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size] __attribute__ ((aligned(32)));
int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
int32_t srs_ls_estimated_channel[frame_parms->nb_antennas_rx][1<<srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size*N_symb_SRS];
int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][1<<srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size*N_symb_SRS] __attribute__ ((aligned(32)));
int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][1<<srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size] __attribute__ ((aligned(32)));
int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][1<<srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size];
uint32_t noise_power_per_rb[srs_pdu->bwp_size];
int8_t snr_per_rb[srs_pdu->bwp_size];
uint32_t signal_power;
......@@ -818,8 +818,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
int8_t snr;
// At least currently, the configuration is constant, so it is enough to generate the sequence just once.
if(gNB->nr_srs_info[i]->sc_list_length == 0) {
generate_srs_nr(srs_pdu, frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx);
if(gNB->nr_srs_info[i]->srs_generated_signal_bits == 0) {
generate_srs_nr(srs_pdu, frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, 0, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx);
}
const int srs_est = nr_get_srs_signal(gNB,frame_rx,slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal);
......@@ -830,7 +830,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
slot_rx,
srs_pdu,
gNB->nr_srs_info[i],
gNB->nr_srs_info[i]->srs_generated_signal,
(const int32_t **) gNB->nr_srs_info[i]->srs_generated_signal,
srs_received_signal,
srs_ls_estimated_channel,
srs_estimated_channel_freq,
......@@ -844,10 +844,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
}
T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(0), T_INT(0),
T_BUFFER(srs_estimated_channel_freq[0], frame_parms->ofdm_symbol_size*sizeof(int32_t)));
T_BUFFER(srs_estimated_channel_freq[0][0], frame_parms->ofdm_symbol_size*sizeof(int32_t)));
T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(0), T_INT(0),
T_BUFFER(srs_estimated_channel_time_shifted[0], frame_parms->ofdm_symbol_size*sizeof(int32_t)));
T_BUFFER(srs_estimated_channel_time_shifted[0][0], frame_parms->ofdm_symbol_size*sizeof(int32_t)));
const uint16_t num_srs = gNB->UL_INFO.srs_ind.number_of_pdus;
gNB->UL_INFO.srs_ind.pdu_list = &gNB->srs_pdu_list[0];
......@@ -856,7 +856,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
gNB->srs_pdu_list[num_srs].handle = srs_pdu->handle;
gNB->srs_pdu_list[num_srs].rnti = srs_pdu->rnti;
gNB->srs_pdu_list[num_srs].timing_advance = srs_est >= 0 ? nr_est_timing_advance_srs(frame_parms,
srs_estimated_channel_time) : 0xFFFF;
srs_estimated_channel_time[0]) : 0xFFFF;
gNB->srs_pdu_list[num_srs].num_symbols = 1<<srs_pdu->num_symbols;
gNB->srs_pdu_list[num_srs].wide_band_snr = srs_est >= 0 ? (snr + 64)<<1 : 0xFF; // 0xFF will be set if this field is invalid
gNB->srs_pdu_list[num_srs].num_reported_symbols = 1<<srs_pdu->num_symbols;
......
......@@ -65,6 +65,8 @@
#include "common/ran_context.h"
//#define DEBUG_DCI
extern RAN_CONTEXT_t RC;
// Note the 2 scs values in the table names represent resp. scs_common and pdcch_scs
......@@ -1247,8 +1249,8 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
pucch_pdu->format_type = default_pucch_fmt[rsetindex];
pucch_pdu->initial_cyclic_shift = r_pucch%default_pucch_csset[rsetindex];
if (rsetindex==3||rsetindex==7||rsetindex==11) pucch_pdu->initial_cyclic_shift*=6;
else if (rsetindex==1||rsetindex==2) pucch_pdu->initial_cyclic_shift*=3;
else pucch_pdu->initial_cyclic_shift*=4;
else if (rsetindex==1||rsetindex==2) pucch_pdu->initial_cyclic_shift*=4;
else pucch_pdu->initial_cyclic_shift*=3;
pucch_pdu->nr_of_symbols = nr_of_symb;
pucch_pdu->start_symbol_index = start_symb;
if (pucch_pdu->format_type == 1) pucch_pdu->time_domain_occ_idx = 0; // check this!!
......@@ -1827,6 +1829,36 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
// UL-SCH indicator
pos += 1;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->ulsch_indicator & 0x1) << (dci_size - pos);
#ifdef DEBUG_DCI
LOG_I(NR_MAC,"============= NR_UL_DCI_FORMAT_0_1 =============\n");
LOG_I(NR_MAC,"dci_size = %i\n", dci_size);
LOG_I(NR_MAC,"dci_pdu_rel15->format_indicator = %i\n", dci_pdu_rel15->format_indicator);
LOG_I(NR_MAC,"dci_pdu_rel15->carrier_indicator.val = %i\n", dci_pdu_rel15->carrier_indicator.val);
LOG_I(NR_MAC,"dci_pdu_rel15->ul_sul_indicator.val = %i\n", dci_pdu_rel15->ul_sul_indicator.val);
LOG_I(NR_MAC,"dci_pdu_rel15->bwp_indicator.val = %i\n", dci_pdu_rel15->bwp_indicator.val);
LOG_I(NR_MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val);
LOG_I(NR_MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val);
LOG_I(NR_MAC,"dci_pdu_rel15->frequency_hopping_flag.val = %i\n", dci_pdu_rel15->frequency_hopping_flag.val);
LOG_I(NR_MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs);
LOG_I(NR_MAC,"dci_pdu_rel15->ndi = %i\n", dci_pdu_rel15->ndi);
LOG_I(NR_MAC,"dci_pdu_rel15->rv= %i\n", dci_pdu_rel15->rv);
LOG_I(NR_MAC,"dci_pdu_rel15->harq_pid = %i\n", dci_pdu_rel15->harq_pid);
LOG_I(NR_MAC,"dci_pdu_rel15->dai[0].val = %i\n", dci_pdu_rel15->dai[0].val);
LOG_I(NR_MAC,"dci_pdu_rel15->dai[1].val = %i\n", dci_pdu_rel15->dai[1].val);
LOG_I(NR_MAC,"dci_pdu_rel15->tpc = %i\n", dci_pdu_rel15->tpc);
LOG_I(NR_MAC,"dci_pdu_rel15->srs_resource_indicator.val = %i\n", dci_pdu_rel15->srs_resource_indicator.val);
LOG_I(NR_MAC,"dci_pdu_rel15->precoding_information.val = %i\n", dci_pdu_rel15->precoding_information.val);
LOG_I(NR_MAC,"dci_pdu_rel15->antenna_ports.val = %i\n", dci_pdu_rel15->antenna_ports.val);
LOG_I(NR_MAC,"dci_pdu_rel15->srs_request.val = %i\n", dci_pdu_rel15->srs_request.val);
LOG_I(NR_MAC,"dci_pdu_rel15->csi_request.val = %i\n", dci_pdu_rel15->csi_request.val);
LOG_I(NR_MAC,"dci_pdu_rel15->cbgti.val = %i\n", dci_pdu_rel15->cbgti.val);
LOG_I(NR_MAC,"dci_pdu_rel15->ptrs_dmrs_association.val = %i\n", dci_pdu_rel15->ptrs_dmrs_association.val);
LOG_I(NR_MAC,"dci_pdu_rel15->beta_offset_indicator.val = %i\n", dci_pdu_rel15->beta_offset_indicator.val);
LOG_I(NR_MAC,"dci_pdu_rel15->dmrs_sequence_initialization.val = %i\n", dci_pdu_rel15->dmrs_sequence_initialization.val);
LOG_I(NR_MAC,"dci_pdu_rel15->ulsch_indicator = %i\n", dci_pdu_rel15->ulsch_indicator);
#endif
break;
}
break;
......
......@@ -1092,7 +1092,7 @@ void fill_initial_SpCellConfig(int uid,
// We are using do_srs = 0 here because the periodic SRS will only be enabled in update_cellGroupConfig() if do_srs == 1
initialUplinkBWP->srs_Config = calloc(1,sizeof(*initialUplinkBWP->srs_Config));
config_srs(initialUplinkBWP->srs_Config, curr_bwp, uid, 0, 0);
config_srs(initialUplinkBWP->srs_Config, NULL, curr_bwp, uid, 0, 0);
scheduling_request_config(scc, pucch_Config);
......@@ -1596,6 +1596,7 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config));
}
config_srs(SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config,
uecap,
curr_bwp,
uid,
0,
......@@ -1620,6 +1621,7 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
NR_BWP_Uplink_t *ul_bwp = UL_BWP_list->list.array[i];
int bwp_size = NRRIV2BW(ul_bwp->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
config_srs(ul_bwp->bwp_Dedicated->srs_Config,
uecap,
bwp_size,
uid,
i+1,
......
......@@ -352,6 +352,7 @@ long rrc_get_max_nr_csrs(const uint8_t max_rbs, const long b_SRS) {
}
void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config,
const NR_UE_NR_Capability_t *uecap,
const int curr_bwp,
const int uid,
const int res_id,
......@@ -418,6 +419,26 @@ void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config,
NR_SRS_Resource_t *srs_res0=calloc(1,sizeof(*srs_res0));
srs_res0->srs_ResourceId = res_id;
srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_port1;
// if (uecap &&
// uecap->featureSets &&
// uecap->featureSets->featureSetsUplink &&
// uecap->featureSets->featureSetsUplink->list.count > 0) {
// NR_FeatureSetUplink_t *ul_feature_setup = uecap->featureSets->featureSetsUplink->list.array[0];
// switch (ul_feature_setup->supportedSRS_Resources->maxNumberSRS_Ports_PerResource) {
// case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n1:
// srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_port1;
// break;
// case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n2:
// srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_ports2;
// break;
// case NR_SRS_Resources__maxNumberSRS_Ports_PerResource_n4:
// srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_ports4;
// break;
// default:
// LOG_E(NR_RRC, "Max Number of SRS Ports Per Resource %ld is invalid!\n",
// ul_feature_setup->supportedSRS_Resources->maxNumberSRS_Ports_PerResource);
// }
// }
srs_res0->ptrs_PortIndex = NULL;
srs_res0->transmissionComb.present = NR_SRS_Resource__transmissionComb_PR_n2;
srs_res0->transmissionComb.choice.n2 = calloc(1,sizeof(*srs_res0->transmissionComb.choice.n2));
......@@ -1116,6 +1137,7 @@ void config_uplinkBWP(NR_BWP_Uplink_t *ubwp,
ubwp->bwp_Dedicated->srs_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->srs_Config));
config_srs(ubwp->bwp_Dedicated->srs_Config,
NULL,
curr_bwp,
uid,
bwp_loop+1,
......
......@@ -145,6 +145,7 @@ void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigcommon,
void config_csiim(int do_csirs, int dl_antenna_ports, int curr_bwp,
NR_CSI_MeasConfig_t *csi_MeasConfig, int id);
void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config,
const NR_UE_NR_Capability_t *uecap,
const int curr_bwp,
const int uid,
const int res_id,
......
......@@ -489,7 +489,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
int curr_bwp = NRRIV2BW(servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
initialUplinkBWP->srs_Config = calloc(1,sizeof(*initialUplinkBWP->srs_Config));
config_srs(initialUplinkBWP->srs_Config, curr_bwp, uid, 0, configuration->do_SRS);
config_srs(initialUplinkBWP->srs_Config, NULL, curr_bwp, uid, 0, configuration->do_SRS);
// Downlink BWPs
int n_dl_bwp = 1;
......
......@@ -2,157 +2,156 @@ Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
gNBs = (
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({
plmn_list = (
{
mcc = 208;
mnc = 99;
mnc_length = 2;
snssaiList = (
{
snssaiList = ({
sst = 1;
sd = 0x1; // 0 false, else true
});
}
);
});
nr_cellid = 12345678L;
////////// Physical parameters:
pdsch_AntennaPorts_XP = 1;
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;
do_CSIRS = 0;
do_CSIRS = 1;
do_SRS = 0;
ul_prbblacklist = "135,136,137,138"
pdcch_ConfigSIB1 = (
{
pdcch_ConfigSIB1 = ({
controlResourceSetZero = 12;
searchSpaceZero = 10;
}
);
searchSpaceZero = 0;
});
servingCellConfigCommon = (
{
#spCellConfigCommon
# spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3300.24 + 134*12*30e3 = 3348.48 MHz (5G NR GSCN: 7741)
absoluteFrequencySSB = 623232;
dl_frequencyBand = 78;
# this is 3300.24 MHz
dl_absoluteFrequencyPointA = 620016;
#scs-SpecificCarrierList
# downlinkConfigCommon
# frequencyInfoDL
# this is 3900.60 MHz + (134 PRBs + 4 SCs)@30kHz SCS (GSCN: 8158)
absoluteFrequencySSB = 663264;
dl_frequencyBand = 77;
# this is 3900.60 MHz
dl_absoluteFrequencyPointA = 660040;
# scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 273;
#initialDownlinkBWP
#genericParameters
# initialDownlinkBWP
# genericParameters
# this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart))
initialDLBWPlocationAndBandwidth = 31624;
#
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
# pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 10;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
# uplinkConfigCommon
# frequencyInfoUL
ul_frequencyBand = 77;
# scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 273;
pMax = 20;
#initialUplinkBWP
#genericParameters
# initialUplinkBWP
# genericParameters
initialULBWPlocationAndBandwidth = 31624;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
# rach-ConfigCommon
# rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
# prach_msg1_FDM
# 0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 12;
preambleReceivedTargetPower = -90;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
# preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
# powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
# ra_ReponseWindow
# 1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
# ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
# 1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
#oneHalf (0..15) 4,8,12,16,...60,64
# oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
# ra_ContentionResolutionTimer
# (0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
# prach-RootSequenceIndex_PR
# 1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
# pucch-ConfigCommon
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -70;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
......@@ -165,12 +164,12 @@ gNBs =
ssPBCH_BlockPower = -25;
}
);
# Dedicated Serving Cell Configuration
servingCellConfigDedicated = ({
# Dedicated Serving Cell Configuration
servingCellConfigDedicated = (
{
# BWP-Downlink
# BWP 1 Configuration
dl_bwp-Id_1 = 1;
......@@ -198,7 +197,7 @@ servingCellConfigDedicated = ({
firstActiveUplinkBWP-Id = 1; #BWP-Id
}
);
);
......@@ -212,14 +211,15 @@ servingCellConfigDedicated = ({
////////// AMF parameters:
amf_ip_address = ( { ipv4 = "192.168.70.132";
amf_ip_address = (
{
ipv4 = "192.168.70.132";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
......@@ -227,9 +227,9 @@ servingCellConfigDedicated = ({
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
}
);
MACRLCs = (
......@@ -237,10 +237,11 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 150;
pusch_TargetSNRx10 = 300;
pucch_TargetSNRx10 = 200;
pusch_FailureThres = 1000;
ulsch_max_frame_inactivity = 0;
ul_max_mcs = 28;
}
);
......@@ -260,7 +261,7 @@ RUs = (
nb_rx = 2;
att_tx = 0;
att_rx = 0;
bands = [78];
bands = [77];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
eNB_instances = [0];
......
......@@ -28,7 +28,6 @@ gNBs =
////////// Physical parameters:
min_rxtxtime = 2;
do_CSIRS = 1;
do_SRS = 1;
......@@ -283,8 +282,8 @@ RUs = (
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 6;
att_rx = 6;
att_tx = 12;
att_rx = 12;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
......
......@@ -27,15 +27,14 @@ gNBs =
////////// Physical parameters:
pdsch_AntennaPorts_XP = 1;
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;
do_CSIRS = 0;
ul_prbblacklist = "79,80,81,82"
do_CSIRS = 1;
pdcch_ConfigSIB1 = (
{
controlResourceSetZero = 12;
searchSpaceZero = 10;
searchSpaceZero = 0;
}
);
......@@ -67,7 +66,7 @@ gNBs =
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 10;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
......@@ -203,9 +202,11 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 150;
pusch_TargetSNRx10 = 300;
pucch_TargetSNRx10 = 200;
pusch_FailureThres = 1000;
ulsch_max_frame_inactivity = 0;
ul_max_mcs = 28;
}
);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment