Commit 9890410a authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/l1_tx_thread' into integration_2024_w06

parents d01c1470 c33a308d
......@@ -437,13 +437,19 @@ class HTMLManagement():
for k in DataLog['Data']:
# TestRow
avg = DataLog['Data'][k][0]
maxval = DataLog['Data'][k][1]
count = DataLog['Data'][k][2]
valnorm = float(DataLog['Data'][k][3])
dev = DataLog['DeviationThreshold'][k]
ref = DataLog['Ref'][k]
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td colspan="3" bgcolor = "lightcyan" >' + k + ' </td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" >' + DataLog['Data'][k][0] + '; ' + DataLog['Data'][k][1] + '; ' + DataLog['Data'][k][2] + ' </td>\n')
if float(DataLog['Data'][k][3])> DataLog['Threshold'][k]:
self.htmlFile.write(' <th bgcolor = "red" >' + DataLog['Data'][k][3] + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = ' +str(DataLog['Threshold'][k])+') ' + '</th>\n')
self.htmlFile.write(f' <td colspan="2" bgcolor = "lightcyan" >{avg}; {maxval}; {count}</td>\n')
if valnorm > 1.0 + dev or valnorm < 1.0 - dev:
self.htmlFile.write(f' <th bgcolor = "red" >{valnorm} (Avg over Ref = {avg} over {ref}; max allowed deviation = {dev})</th>\n')
else:
self.htmlFile.write(' <th bgcolor = "green" ><font color="white">' + DataLog['Data'][k][3] + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = ' +str(DataLog['Threshold'][k])+') ' + '</th>\n')
self.htmlFile.write(f' <th bgcolor = "green" ><font color="white">{valnorm} (Avg over Ref = {avg} over {ref}; max allowed deviation = {dev})</font></th>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.close()
......
Active_gNBs = ( "gNB-Eurecom-5GNRBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
cell_type = "CELL_MACRO_GNB";
gNB_name = "gNB-Eurecom-5GNRBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
tr_s_preference = "local_mac"
////////// Physical parameters:
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;
min_rxtxtime = 6;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
absoluteFrequencySSB = 621312;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 620040;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 273;
#initialDownlinkBWP
#genericParameters
# this is RBstart=41,L=24 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 31624;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 273;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 31624;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -118;
#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 = 1;
#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 = 4;
#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 = 7;
rsrp_ThresholdSSB = 19;
#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,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# 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;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.26";
ipv6 = "192:168:30::17";
port = 36412 ;
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES : {
GNB_INTERFACE_NAME_FOR_S1_MME = "eth0";
GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24";
GNB_INTERFACE_NAME_FOR_S1U = "eth0";
GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = ({
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
});
L1s = ({
num_cc = 1;
tr_n_preference = "local_mac";
});
RUs = ({
local_rf = "yes"
nb_tx = 2
nb_rx = 2
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 50;
eNB_instances = [0];
bf_weights = [0x00007fff, 0x0000];
sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2";
});
THREAD_STRUCT = ({
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
});
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config : {
global_log_level = "info";
hw_log_level = "info";
phy_log_level = "info";
mac_log_level = "info";
rlc_log_level = "info";
pdcp_log_level = "info";
rrc_log_level = "info";
};
#this is a configuration file
#used to build real time processing statistics
#for 5G NR phy test (gNB terminate)
Title : Processing Time (us) from datalog_rt_stats.100.2x2.yaml
ColNames :
- Metric
- Average; Max; Count
- Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold)
Ref :
feprx : 150.0
feptx_prec : 0.0
feptx_ofdm : 65.0
feptx_total : 177.0
L1 Tx processing : 700.0
DLSCH encoding : 179.0
L1 Rx processing : 526.0
PUSCH inner-receiver : 400.0
Schedule Response : 3.0
DL & UL scheduling timing : 15.0
UL Indication : 3.0
Slot Indication : 17.0
DeviationThreshold :
feprx : 0.25
feptx_prec : 0.25
feptx_ofdm : 0.25
feptx_total : 0.25
L1 Tx processing : 0.25
DLSCH encoding : 0.25
L1 Rx processing : 0.25
PUSCH inner-receiver : 0.25
Schedule Response : 1.00
DL & UL scheduling timing : 0.25
UL Indication : 1.00
Slot Indication : 0.50
#this is a configuration file
#used to build real time processing statistics
#for 5G NR phy test (gNB terminate)
Title : Processing Time (us)
Title : Processing Time (us) from datalog_rt_stats.1x1.60.yaml
ColNames :
- Metric
- Average; Max; Count
- Average vs Reference Deviation (Reference Value; Acceptability Threshold)
- Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold)
Ref :
feprx : 46.0
feptx_prec : 15.0
......@@ -15,20 +15,20 @@ Ref :
DLSCH encoding : 137.0
L1 Rx processing : 345.0
PUSCH inner-receiver : 210.0
PUSCH decoding : 2200.0
Schedule Response : 48.0
DL & UL scheduling timing : 13.0
UL Indication : 60.0
Threshold :
feprx : 1.25
feptx_prec : 1.25
feptx_ofdm : 1.25
feptx_total : 1.25
L1 Tx processing : 1.25
DLSCH encoding : 1.25
L1 Rx processing : 1.25
PUSCH inner-receiver : 1.25
PUSCH decoding : 1.25
Schedule Response : 1.25
DL & UL scheduling timing : 1.25
UL Indication : 1.25
Schedule Response : 3.0
DL & UL scheduling timing : 8.0
UL Indication : 3.0
Slot Indication : 8.0
DeviationThreshold :
feprx : 0.25
feptx_prec : 0.25
feptx_ofdm : 0.25
feptx_total : 0.25
L1 Tx processing : 0.25
DLSCH encoding : 0.25
L1 Rx processing : 0.25
PUSCH inner-receiver : 0.25
Schedule Response : 1.00
DL & UL scheduling timing : 0.50
UL Indication : 1.00
Slot Indication : 0.50
#this is a configuration file
#used to build real time processing statistics
#for 5G NR phy test (gNB terminate)
Title : Processing Time (us)
Title : Processing Time (us) from datalog_rt_stats.2x2.yaml
ColNames :
- Metric
- Average; Max; Count
- Average vs Reference Deviation (Reference Value; Acceptability Threshold)
- Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold)
Ref :
feprx : 120.0
feptx_prec : 30.0
......@@ -15,18 +15,20 @@ Ref :
DLSCH encoding : 230.0
L1 Rx processing : 175.0
PUSCH inner-receiver : 100.0
PUSCH decoding : 180.0
DL & UL scheduling timing : 37.0
UL Indication : 38.0
Threshold :
feprx : 1.25
feptx_prec : 1.25
feptx_ofdm : 1.25
feptx_total : 1.25
L1 Tx processing : 1.25
DLSCH encoding : 1.25
L1 Rx processing : 1.25
PUSCH inner-receiver : 1.25
PUSCH decoding : 1.25
DL & UL scheduling timing : 1.25
UL Indication : 1.25
Schedule Response : 3.0
DL & UL scheduling timing : 11.0
UL Indication : 3.0
Slot Indication : 14.0
DeviationThreshold :
feprx : 0.25
feptx_prec : 0.25
feptx_ofdm : 0.25
feptx_total : 0.25
L1 Tx processing : 0.25
DLSCH encoding : 0.25
L1 Rx processing : 0.25
PUSCH inner-receiver : 0.25
Schedule Response : 1.00
DL & UL scheduling timing : 0.50
UL Indication : 1.00
Slot Indication : 0.25
#this is a configuration file
#used to build real time processing statistics
#for 5G NR phy test (gNB terminate)
Title : Processing Time (us)
Title : Processing Time (us) from datalog_rt_stats.60.2x2.yaml
ColNames :
- Metric
- Average; Max; Count
- Average vs Reference Deviation (Reference Value; Acceptability Threshold)
- Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold)
Ref :
feprx : 84.0
feptx_prec : 14.0
......@@ -15,20 +15,20 @@ Ref :
DLSCH encoding : 177.0
L1 Rx processing : 345.0
PUSCH inner-receiver : 210.0
PUSCH decoding : 2200.0
Schedule Response : 111.0
DL & UL scheduling timing : 20.0
UL Indication : 127.0
Threshold :
feprx : 1.25
feptx_prec : 1.25
feptx_ofdm : 1.25
feptx_total : 1.25
L1 Tx processing : 1.25
DLSCH encoding : 1.25
L1 Rx processing : 1.25
PUSCH inner-receiver : 1.25
PUSCH decoding : 1.25
Schedule Response : 48.0
DL & UL scheduling timing : 1.25
UL Indication : 1.25
Schedule Response : 3.0
DL & UL scheduling timing : 13.0
UL Indication : 3.0
Slot Indication : 15.0
DeviationThreshold :
feprx : 0.25
feptx_prec : 0.25
feptx_ofdm : 0.25
feptx_total : 0.25
L1 Tx processing : 0.25
DLSCH encoding : 0.25
L1 Rx processing : 0.25
PUSCH inner-receiver : 0.25
Schedule Response : 1.00
DL & UL scheduling timing : 0.35
UL Indication : 1.00
Slot Indication : 0.35
#this is a configuration file
#used to build real time processing statistics
#for 5G NR phy test (gNB terminate)
Title : Processing Time (us)
Title : Processing Time (us) from datalog_rt_stats.default.yaml
ColNames :
- Metric
- Average; Max; Count
- Average vs Reference Deviation (Reference Value; Acceptability Threshold)
- Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold)
Ref :
feprx : 43.0
feptx_prec : 13.0
......@@ -15,20 +15,20 @@ Ref :
DLSCH encoding : 118.0
L1 Rx processing : 305.0
PUSCH inner-receiver : 150.0
PUSCH decoding : 2200.0
Schedule Response : 30.0
DL & UL scheduling timing : 10.0
UL Indication : 40.0
Threshold :
feprx : 1.25
feptx_prec : 1.25
feptx_ofdm : 1.25
feptx_total : 1.25
L1 Tx processing : 1.25
DLSCH encoding : 1.25
L1 Rx processing : 1.25
PUSCH inner-receiver : 1.25
PUSCH decoding : 1.25
Schedule Response : 1.25
DL & UL scheduling timing : 1.25
UL Indication : 1.25
Schedule Response : 3.0
DL & UL scheduling timing : 6.0
UL Indication : 3.0
Slot Indication : 7.0
DeviationThreshold :
feprx : 0.25
feptx_prec : 0.25
feptx_ofdm : 0.25
feptx_total : 0.25
L1 Tx processing : 0.25
DLSCH encoding : 0.25
L1 Rx processing : 0.25
PUSCH inner-receiver : 0.25
Schedule Response : 1.00
DL & UL scheduling timing : 0.50
UL Indication : 1.00
Slot Indication : 0.50
......@@ -1179,8 +1179,10 @@ class RANManagement():
self.datalog_rt_stats=datalog_rt_stats
#check if there is a fail => will render the test as failed
for k in datalog_rt_stats['Data']:
if float(datalog_rt_stats['Data'][k][3])> datalog_rt_stats['Threshold'][k]: #condition for fail : avg/ref is greater than the fixed threshold
logging.debug('\u001B[1;30;43m datalog_rt_stats metric ' + k + '=' + datalog_rt_stats['Data'][k][3] + ' > threshold ' + str(datalog_rt_stats['Threshold'][k]) + ' \u001B[0m')
valnorm = float(datalog_rt_stats['Data'][k][3])
dev = datalog_rt_stats['DeviationThreshold'][k]
if valnorm > 1.0 + dev or valnorm < 1.0 - dev: # condition for fail : avg/ref deviates by more than "deviation threshold"
logging.debug(f'\u001B[1;30;43m normalized datalog_rt_stats metric {k}={valnorm} deviates by more than {dev}\u001B[0m')
RealTimeProcessingIssue = True
else:
statMsg = 'No real time stats found in the log file\n'
......
......@@ -24,9 +24,9 @@ gnb :
DLSCH encoding:
L1 Rx processing:
PUSCH inner-receiver:
PUSCH decoding:
DL & UL scheduling timing:
UL Indication:
Slot Indication:
graph :
page1:
dlsch_err:
......@@ -44,6 +44,6 @@ gnb :
rt.L1 Rx processing:
page4:
rt.PUSCH inner-receiver:
rt.PUSCH decoding:
rt.DL & UL scheduling timing:
rt.UL Indication:
rt.Slot Indication:
<!--
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
-->
<testCaseList>
<htmlTabRef>gNB-PHY-Test-100-2x2</htmlTabRef>
<htmlTabName>Timing phytest 100 MHz 2x2</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
100000 390101 000001 390109 200000
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="100000">
<class>Custom_Command</class>
<desc>Disable Sleep States</desc>
<node>caracal</node>
<command>sudo cpupower idle-set -D 0</command>
</testCase>
<testCase id="200000">
<class>Custom_Command</class>
<desc>Enable Sleep States</desc>
<node>caracal</node>
<command>sudo cpupower idle-set -E</command>
</testCase>
<testCase id="390101">
<class>Initialize_eNB</class>
<desc>Initialize gNB USRP</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.273prb.usrpn300.phytest-dora.conf --phy-test -q -U 787200 -T 273 -t 23 -D 130175 -m 23 -M 273 -l 2 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
<rt_stats_cfg>datalog_rt_stats.100.2x2.yaml</rt_stats_cfg>
<air_interface>NR</air_interface>
<USRP_IPAddress>192.168.20.2</USRP_IPAddress>
<cmd_prefix>numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0</cmd_prefix>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>60</idle_sleep_time_in_sec>
</testCase>
<testCase id="390109">
<class>Terminate_eNB</class>
<desc>Terminate gNB</desc>
<air_interface>NR</air_interface>
</testCase>
</testCaseList>
......@@ -52,6 +52,8 @@
#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
......@@ -109,42 +111,70 @@ time_stats_t softmodem_stats_rx_sf; // total rx time
#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
#define L1STATSSTRLEN 16384
void tx_func(void *param)
static void tx_func(void *param)
{
processingData_L1tx_t *info = (processingData_L1tx_t *) param;
PHY_VARS_gNB *gNB = info->gNB;
int frame_tx = info->frame;
int slot_tx = info->slot;
int cumul_samples = gNB->frame_parms.get_samples_per_slot(0, &gNB->frame_parms);
int i = 1;
for (; i < gNB->frame_parms.slots_per_subframe / 2; i++)
cumul_samples += gNB->frame_parms.get_samples_per_slot(i, &gNB->frame_parms);
int samples = cumul_samples / i;
int absslot_tx = info->timestamp_tx / samples;
int absslot_rx = absslot_tx - gNB->RU_list[0]->sl_ahead;
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
start_meas(&gNB->phy_proc_tx);
int frame_rx = info->frame_rx;
int slot_rx = info->slot_rx;
int absslot_tx = info->timestamp_tx / info->gNB->frame_parms.get_samples_per_slot(slot_tx, &info->gNB->frame_parms);
int absslot_rx = absslot_tx - info->gNB->RU_list[0]->sl_ahead;
clock_gettime(CLOCK_MONOTONIC, &gNB->rt_L1_profiling.start_L1_TX[rt_prof_idx]);
phy_procedures_gNB_TX(info,
frame_tx,
slot_tx,
1);
clock_gettime(CLOCK_MONOTONIC, &gNB->rt_L1_profiling.return_L1_TX[rt_prof_idx]);
LOG_D(NR_PHY, "%d.%d running tx_func\n", frame_tx, slot_tx);
PHY_VARS_gNB *gNB = info->gNB;
module_id_t module_id = gNB->Mod_id;
uint8_t CC_id = gNB->CC_id;
NR_IF_Module_t *ifi = gNB->if_inst;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
if (get_softmodem_params()->reorder_thread_disable) {
if (slot_rx == 0) {
reset_active_stats(gNB, frame_rx);
reset_active_ulsch(gNB, frame_rx);
}
start_meas(&gNB->slot_indication_stats);
ifi->NR_slot_indication(module_id, CC_id, frame_tx, slot_tx);
stop_meas(&gNB->slot_indication_stats);
gNB->msgDataTx->timestamp_tx = info->timestamp_tx;
info = gNB->msgDataTx;
info->gNB = gNB;
// At this point, MAC scheduler just ran, including scheduling
// PRACH/PUCCH/PUSCH, so trigger RX chain processing
LOG_D(NR_PHY, "%s() trigger RX for %d.%d\n", __func__, frame_rx, slot_rx);
notifiedFIFO_elt_t *res = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->resp_L1, NULL);
processingData_L1_t *syncMsg = NotifiedFifoData(res);
syncMsg->gNB = gNB;
syncMsg->frame_rx = frame_rx;
syncMsg->slot_rx = slot_rx;
syncMsg->timestamp_tx = info->timestamp_tx;
res->key = slot_rx;
pushNotifiedFIFO(&gNB->resp_L1, res);
int tx_slot_type = nr_slot_select(cfg, frame_tx, slot_tx);
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx) {
start_meas(&info->gNB->phy_proc_tx);
phy_procedures_gNB_TX(info, frame_tx, slot_tx, 1);
const int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
clock_gettime(CLOCK_MONOTONIC, &info->gNB->rt_L1_profiling.return_L1_TX[rt_prof_idx]);
PHY_VARS_gNB *gNB = info->gNB;
processingData_RU_t syncMsgRU;
syncMsgRU.frame_tx = frame_tx;
syncMsgRU.slot_tx = slot_tx;
syncMsgRU.ru = gNB->RU_list[0];
syncMsgRU.timestamp_tx = info->timestamp_tx;
LOG_D(PHY,"gNB: %d.%d : calling RU TX function\n",syncMsgRU.frame_tx,syncMsgRU.slot_tx);
ru_tx_func((void*)&syncMsgRU);
LOG_D(PHY, "gNB: %d.%d : calling RU TX function\n", syncMsgRU.frame_tx, syncMsgRU.slot_tx);
ru_tx_func((void *)&syncMsgRU);
stop_meas(&info->gNB->phy_proc_tx);
}
/* this thread is done with the sched_info, decrease the reference counter */
LOG_D(NR_PHY, "Calling deref_sched_response for id %d (tx_func) in %d.%d\n", info->sched_response_id, frame_tx, slot_tx);
deref_sched_response(info->sched_response_id);
stop_meas(&gNB->phy_proc_tx);
}
......@@ -162,27 +192,27 @@ void *L1_rx_thread(void *arg)
}
return NULL;
}
/* to be added for URLLC, requires MAC scheduling to be split from UL indication
// Added for URLLC, requires MAC scheduling to be split from UL indication
void *L1_tx_thread(void *arg) {
PHY_VARS_gNB *gNB = (PHY_VARS_gNB*)arg;
while (oai_exit == 0) {
notifiedFIFO_elt_t *res = pullNotifiedFIFO(&gNB->L1_tx_out);
if (res == NULL) // stopping condition, happens only when queue is freed
break;
processingData_L1tx_t *info = (processingData_L1tx_t *)NotifiedFifoData(res);
tx_func(info);
delNotifiedFIFO_elt(res);
}
return NULL;
}
*/
void rx_func(void *param)
{
processingData_L1_t *info = (processingData_L1_t *) param;
PHY_VARS_gNB *gNB = info->gNB;
int frame_rx = info->frame_rx;
int slot_rx = info->slot_rx;
int frame_tx = info->frame_tx;
int slot_tx = info->slot_tx;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
int cumul_samples = gNB->frame_parms.get_samples_per_slot(0, &gNB->frame_parms);
int i = 1;
......@@ -204,32 +234,14 @@ void rx_func(void *param)
handle_nr_slot_ind(frame_rx, slot_rx);
stop_meas(&nfapi_meas);
/*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs ||
gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs ||
gNB->UL_INFO.rach_ind.number_of_pdus ||
gNB->UL_INFO.cqi_ind.number_of_cqis
) {
LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d rach_pdus:%0d.%d:%d cqis:%d] RX:%04d%d TX:%04d%d \n",
NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus,
NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,
NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs,
gNB->UL_INFO.rach_ind.sfn, gNB->UL_INFO.rach_ind.slot,gNB->UL_INFO.rach_ind.number_of_pdus,
gNB->UL_INFO.cqi_ind.number_of_cqis,
frame_rx, slot_rx,
frame_tx, slot_tx);
}*/
}
// ****************************************
T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
reset_active_stats(gNB, frame_tx);
reset_active_ulsch(gNB, frame_tx);
// RX processing
int rx_slot_type = nr_slot_select(cfg, frame_rx, slot_rx);
if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) {
LOG_D(NR_PHY, "%d.%d Starting RX processing\n", frame_rx, slot_rx);
// UE-specific RX processing for subframe n
// TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT
......@@ -252,98 +264,30 @@ void rx_func(void *param)
}
}
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
}
stop_meas( &softmodem_stats_rxtx_sf );
LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.return_L1_RX[rt_prof_idx]);
// Call the scheduler
start_meas(&gNB->ul_indication_stats);
// pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.frame = frame_rx;
gNB->UL_INFO.slot = slot_rx;
gNB->UL_INFO.module_id = gNB->Mod_id;
gNB->UL_INFO.CC_id = gNB->CC_id;
gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
// pthread_mutex_unlock(&gNB->UL_INFO_mutex);
stop_meas(&gNB->ul_indication_stats);
int tx_slot_type = nr_slot_select(cfg,frame_tx,slot_tx);
if ((tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) && NFAPI_MODE != NFAPI_MODE_PNF) {
notifiedFIFO_elt_t *res;
processingData_L1tx_t *syncMsg;
// Its a FIFO so it maitains the order in which the MAC fills the messages
// so no need for checking for right slot
if (get_softmodem_params()->reorder_thread_disable) {
// call the TX function directly from this thread
syncMsg = gNB->msgDataTx;
syncMsg->gNB = gNB;
syncMsg->timestamp_tx = info->timestamp_tx;
tx_func(syncMsg);
} else {
res = pullTpool(&gNB->L1_tx_filled, &gNB->threadPool);
if (res == NULL)
return; // Tpool has been stopped
syncMsg = (processingData_L1tx_t *)NotifiedFifoData(res);
syncMsg->gNB = gNB;
syncMsg->timestamp_tx = info->timestamp_tx;
res->key = slot_tx;
pushTpool(&gNB->threadPool, res);
}
} else if (get_softmodem_params()->continuous_tx) {
notifiedFIFO_elt_t *res = pullNotifiedFIFO(&gNB->L1_tx_free);
if (res == NULL)
return; // Tpool has been stopped
processingData_L1tx_t *syncMsg = (processingData_L1tx_t *)NotifiedFifoData(res);
// Call the scheduler
start_meas(&gNB->ul_indication_stats);
gNB->UL_INFO.frame = frame_rx;
gNB->UL_INFO.slot = slot_rx;
gNB->UL_INFO.module_id = gNB->Mod_id;
gNB->UL_INFO.CC_id = gNB->CC_id;
gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
stop_meas(&gNB->ul_indication_stats);
notifiedFIFO_elt_t *res = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->L1_rx_out, NULL);
processingData_L1_t *syncMsg = NotifiedFifoData(res);
syncMsg->gNB = gNB;
syncMsg->timestamp_tx = info->timestamp_tx;
syncMsg->frame = frame_tx;
syncMsg->slot = slot_tx;
res->key = slot_tx;
pushNotifiedFIFO(&gNB->L1_tx_out, res);
syncMsg->frame_rx = frame_rx;
syncMsg->slot_rx = slot_rx;
res->key = slot_rx;
LOG_D(NR_PHY, "Signaling completion for %d.%d (mod_slot %d) on L1_rx_out\n", frame_rx, slot_rx, slot_rx % RU_RX_SLOT_DEPTH);
pushNotifiedFIFO(&gNB->L1_rx_out, res);
}
#if 0
LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ",
softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now,
TICK_TO_US(gNB->phy_proc),
TICK_TO_US(gNB->phy_proc_tx),
TICK_TO_US(gNB->phy_proc_rx),
TICK_TO_US(gNB->rx_prach),
TICK_TO_US(gNB->ofdm_mod_stats),
softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now);
LOG_D(PHY,
"dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ",
TICK_TO_US(gNB->dlsch_encoding_stats),
TICK_TO_US(gNB->dlsch_modulation_stats),
TICK_TO_US(gNB->dlsch_scrambling_stats),
TICK_TO_US(gNB->dlsch_rate_matching_stats),
TICK_TO_US(gNB->dlsch_turbo_encoding_stats),
TICK_TO_US(gNB->dlsch_interleaving_stats),
TICK_TO_US(gNB->rx_dft_stats));
LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ",
TICK_TO_US(gNB->ulsch_channel_estimation_stats),
TICK_TO_US(gNB->ulsch_freq_offset_estimation_stats),
TICK_TO_US(gNB->ulsch_decoding_stats),
TICK_TO_US(gNB->ulsch_demodulation_stats),
TICK_TO_US(gNB->ulsch_rate_unmatching_stats));
LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ",
TICK_TO_US(gNB->ulsch_turbo_decoding_stats),
TICK_TO_US(gNB->ulsch_deinterleaving_stats),
TICK_TO_US(gNB->ulsch_demultiplexing_stats),
TICK_TO_US(gNB->ulsch_llr_stats),
TICK_TO_US(gNB->ulsch_tc_init_stats));
LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n",
TICK_TO_US(gNB->ulsch_tc_alpha_stats),
TICK_TO_US(gNB->ulsch_tc_beta_stats),
TICK_TO_US(gNB->ulsch_tc_gamma_stats),
TICK_TO_US(gNB->ulsch_tc_ext_stats),
TICK_TO_US(gNB->ulsch_tc_intl1_stats),
TICK_TO_US(gNB->ulsch_tc_intl2_stats)
);
#endif
stop_meas(&softmodem_stats_rxtx_sf);
clock_gettime(CLOCK_MONOTONIC, &info->gNB->rt_L1_profiling.return_L1_RX[rt_prof_idx]);
}
static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size_t outputlen) {
const char *begin = output;
const char *end = output + outputlen;
......@@ -356,8 +300,8 @@ static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size
output += print_meas_log(&gNB->dlsch_precoding_stats, "DLSCH precoding", NULL, NULL, output,end-output);
output += print_meas_log(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->ul_indication_stats, "UL Indication", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->slot_indication_stats, "Slot Indication", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->ulsch_decoding_stats, "PUSCH decoding", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->schedule_response_stats, "Schedule Response", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->rx_prach, "PRACH RX", NULL, NULL, output, end - output);
if (ru->feprx)
......@@ -399,8 +343,8 @@ void *nrL1_stats_thread(void *param) {
reset_meas(&gNB->dlsch_encoding_stats);
reset_meas(&gNB->phy_proc_rx);
reset_meas(&gNB->ul_indication_stats);
reset_meas(&gNB->slot_indication_stats);
reset_meas(&gNB->rx_pusch_stats);
reset_meas(&gNB->ulsch_decoding_stats);
reset_meas(&gNB->schedule_response_stats);
reset_meas(&gNB->dlsch_scrambling_stats);
reset_meas(&gNB->dlsch_modulation_stats);
......@@ -421,60 +365,6 @@ void *nrL1_stats_thread(void *param) {
return(NULL);
}
// This thread reads the finished L1 tx jobs from threaPool
// and pushes RU tx thread in the right order. It works only
// two parallel L1 tx threads.
void *tx_reorder_thread(void* param) {
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
notifiedFIFO_elt_t *resL1Reserve = pullNotifiedFIFO(&gNB->L1_tx_out);
AssertFatal(resL1Reserve != NULL, "pullTpool() did not return start message in %s\n", __func__);
int next_tx_slot=((processingData_L1tx_t *)NotifiedFifoData(resL1Reserve))->slot;
LOG_I(PHY,"tx_reorder_thread started\n");
while (!oai_exit) {
notifiedFIFO_elt_t *resL1;
if (resL1Reserve) {
resL1=resL1Reserve;
if (((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot) {
LOG_E(PHY,"order mistake\n");
resL1Reserve = NULL;
resL1 = pullNotifiedFIFO(&gNB->L1_tx_out);
}
} else {
resL1 = pullNotifiedFIFO(&gNB->L1_tx_out);
if (resL1 != NULL && ((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot) {
if (resL1Reserve)
LOG_E(PHY,"error, have a stored packet, then a second one\n");
resL1Reserve = resL1;
resL1 = pullNotifiedFIFO(&gNB->L1_tx_out);
if (((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot)
LOG_E(PHY,"error, pull two msg, none is good\n");
}
}
if (resL1 == NULL)
break; // Tpool has been stopped
processingData_L1tx_t *syncMsgL1= (processingData_L1tx_t *)NotifiedFifoData(resL1);
processingData_RU_t syncMsgRU;
syncMsgRU.frame_tx = syncMsgL1->frame;
syncMsgRU.slot_tx = syncMsgL1->slot;
syncMsgRU.timestamp_tx = syncMsgL1->timestamp_tx;
syncMsgRU.ru = gNB->RU_list[0];
if (get_softmodem_params()->continuous_tx) {
int slots_per_frame = gNB->frame_parms.slots_per_frame;
next_tx_slot = (syncMsgRU.slot_tx + 1) % slots_per_frame;
} else
next_tx_slot = get_next_downlink_slot(gNB, &gNB->gNB_config, syncMsgRU.frame_tx, syncMsgRU.slot_tx);
pushNotifiedFIFO(&gNB->L1_tx_free, resL1);
if (resL1==resL1Reserve)
resL1Reserve=NULL;
LOG_D(PHY,"gNB: %d.%d : calling RU TX function\n",syncMsgL1->frame,syncMsgL1->slot);
ru_tx_func((void*)&syncMsgRU);
}
return(NULL);
}
void init_gNB_Tpool(int inst) {
PHY_VARS_gNB *gNB;
gNB = RC.gNB[inst];
......@@ -487,47 +377,26 @@ void init_gNB_Tpool(int inst) {
initNotifiedFIFO(&gNB->respPuschSymb);
initNotifiedFIFO(&gNB->respDecode);
// L1 RX result FIFO
// L1 RX result FIFO
initNotifiedFIFO(&gNB->resp_L1);
if (!get_softmodem_params()->reorder_thread_disable) {
notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->resp_L1, rx_func);
pushNotifiedFIFO(&gNB->resp_L1, msg); // to unblock the process in the beginning
}
// L1 TX result FIFO
initNotifiedFIFO(&gNB->L1_tx_free);
initNotifiedFIFO(&gNB->L1_tx_filled);
initNotifiedFIFO(&gNB->L1_tx_out);
if (get_softmodem_params()->reorder_thread_disable) {
// create the RX thread responsible for triggering RX processing and then TX processing if a single thread is used
threadCreate(&gNB->L1_rx_thread, L1_rx_thread, (void *)gNB, "L1_rx_thread",
gNB->L1_rx_thread_core, OAI_PRIORITY_RT_MAX);
// if separate threads are used for RX and TX, create the TX thread
// threadCreate(&gNB->L1_tx_thread, L1_tx_thread, (void *)gNB, "L1_tx_thread",
// gNB->L1_tx_thread_core, OAI_PRIORITY_RT_MAX);
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, tx_func);
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
memset(msgDataTx, 0, sizeof(processingData_L1tx_t));
init_DLSCH_struct(gNB, msgDataTx);
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
// this will be removed when the msgDataTx is not necessary anymore
gNB->msgDataTx = msgDataTx;
} else {
// we create 2 threads for L1 tx processing
for (int i=0; i < 2; i++) {
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, tx_func);
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
memset(msgDataTx, 0, sizeof(processingData_L1tx_t));
init_DLSCH_struct(gNB, msgDataTx);
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
pushNotifiedFIFO(&gNB->L1_tx_free, msgL1Tx); // to unblock the process in the beginning
}
LOG_I(PHY,"Creating thread for TX reordering and dispatching to RU\n");
threadCreate(&proc->pthread_tx_reorder, tx_reorder_thread, (void *)gNB, "thread_tx_reorder",
gNB->RU_list[0] ? gNB->RU_list[0]->tpcores[1] : -1, OAI_PRIORITY_RT_MAX);
}
initNotifiedFIFO(&gNB->L1_rx_out);
// create the RX thread responsible for RX processing start event (resp_L1 msg queue), then launch rx_func()
threadCreate(&gNB->L1_rx_thread, L1_rx_thread, (void *)gNB, "L1_rx_thread", gNB->L1_rx_thread_core, OAI_PRIORITY_RT_MAX);
// create the TX thread responsible for TX processing start event (L1_tx_out msg queue), then launch tx_func()
threadCreate(&gNB->L1_tx_thread, L1_tx_thread, (void *)gNB, "L1_tx_thread", gNB->L1_tx_thread_core, OAI_PRIORITY_RT_MAX);
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, tx_func);
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
memset(msgDataTx, 0, sizeof(processingData_L1tx_t));
init_DLSCH_struct(gNB, msgDataTx);
memset(msgDataTx->ssb, 0, 64 * sizeof(NR_gNB_SSB_t));
// this will be removed when the msgDataTx is not necessary anymore
gNB->msgDataTx = msgDataTx;
if ((!get_softmodem_params()->emulate_l1) && (!IS_SOFTMODEM_NOSTATS_BIT) && (NFAPI_MODE!=NFAPI_MODE_VNF))
threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW);
......@@ -543,25 +412,11 @@ void term_gNB_Tpool(int inst) {
abortNotifiedFIFO(&gNB->L1_tx_free);
abortNotifiedFIFO(&gNB->L1_tx_filled);
abortNotifiedFIFO(&gNB->L1_tx_out);
abortNotifiedFIFO(&gNB->L1_rx_out);
gNB_L1_proc_t *proc = &gNB->proc;
if (!get_softmodem_params()->emulate_l1)
pthread_join(proc->L1_stats_thread, NULL);
if (!get_softmodem_params()->reorder_thread_disable)
pthread_join(proc->pthread_tx_reorder, NULL);
}
/*!
* \brief Terminate gNB TX and RX threads.
*/
void kill_gNB_proc(int inst) {
PHY_VARS_gNB *gNB;
gNB=RC.gNB[inst];
LOG_I(PHY, "Destroying UL_INFO mutex\n");
pthread_mutex_destroy(&gNB->UL_INFO_mutex);
}
void reset_opp_meas(void) {
......@@ -601,7 +456,6 @@ void init_eNB_afterRU(void) {
gNB = RC.gNB[inst];
gNB->ldpc_offload_flag = get_softmodem_params()->ldpc_offload_flag;
gNB->reorder_thread_disable = get_softmodem_params()->reorder_thread_disable;
phy_init_nr_gNB(gNB);
......@@ -692,6 +546,5 @@ void stop_gNB(int nb_inst) {
for (int inst=0; inst<nb_inst; inst++) {
LOG_I(PHY,"Killing gNB %d processing threads\n",inst);
term_gNB_Tpool(inst);
kill_gNB_proc(inst);
}
}
......@@ -283,7 +283,7 @@ void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) {
for (int aid=0;aid<ru->nb_tx;aid++) buffs[aid] = (void*)&ru->common.txdata[aid][offset];
struct timespec txmeas;
clock_gettime(CLOCK_MONOTONIC, &txmeas);
LOG_D(PHY,"IF5 TX %d.%d, TS %llu, buffs[0] %p, buffs[1] %p ener0 %f dB, tx start %d\n",frame,slot,(unsigned long long)timestamp,buffs[0],buffs[1],
LOG_D(NR_PHY,"IF5 TX %d.%d, TS %llu, buffs[0] %p, buffs[1] %p ener0 %f dB, tx start %d\n",frame,slot,(unsigned long long)timestamp,buffs[0],buffs[1],
10*log10((double)signal_energy(buffs[0],ru->nr_frame_parms->get_samples_per_slot(slot,ru->nr_frame_parms))),(int)txmeas.tv_nsec);
ru->ifdevice.trx_write_func2(&ru->ifdevice,
timestamp,
......@@ -624,7 +624,8 @@ void *emulatedRF_thread(void *param) {
return 0;
}
void rx_rf(RU_t *ru,int *frame,int *slot) {
static void rx_rf(RU_t *ru, int *frame, int *slot)
{
RU_proc_t *proc = &ru->proc;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
openair0_config_t *cfg = &ru->openair0_cfg;
......@@ -662,13 +663,17 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
//AssertFatal(rxs == fp->samples_per_subframe,
//"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_subframe,rxs);
if (rxs != samples_per_slot) LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",samples_per_slot,rxs);
if (rxs != samples_per_slot)
LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n", samples_per_slot, rxs);
if (proc->first_rx != 1) {
samples_per_slot_prev = fp->get_samples_per_slot((*slot-1)%fp->slots_per_frame,fp);
if (proc->timestamp_rx - old_ts != samples_per_slot_prev) {
LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - samples_per_slot_prev,ru->ts_offset);
LOG_D(PHY,
"rx_rf: rfdevice timing drift of %" PRId64 " samples (ts_off %" PRId64 ")\n",
proc->timestamp_rx - old_ts - samples_per_slot_prev,
ru->ts_offset);
ru->ts_offset += (proc->timestamp_rx - old_ts - samples_per_slot_prev);
proc->timestamp_rx = ts-ru->ts_offset;
}
......@@ -705,8 +710,14 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
}
if (proc->frame_rx != *frame) {
LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, proc->tti_rx %d, slot %d)\n",(long long unsigned int)proc->timestamp_rx,proc->frame_rx,
*frame,proc->tti_rx,*slot);
LOG_E(PHY,
"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, proc->tti_rx %d, "
"slot %d)\n",
(long long unsigned int)proc->timestamp_rx,
proc->frame_rx,
*frame,
proc->tti_rx,
*slot);
exit_fun("Exiting");
}
} else {
......@@ -1169,6 +1180,7 @@ void *ru_thread( void *param ) {
int initial_wait=0;
int opp_enabled0 = opp_enabled;
bool rx_tti_busy[RU_RX_SLOT_DEPTH] = {false};
nfapi_nr_config_request_scf_t *cfg = &ru->config;
// set default return value
ru_thread_status = 0;
......@@ -1233,9 +1245,6 @@ void *ru_thread( void *param ) {
pthread_mutex_unlock(&RC.ru_mutex);
wait_sync("ru_thread");
processingData_L1_t *syncMsg;
notifiedFIFO_elt_t *res;
if(!emulate_rf) {
// Start RF device if any
if (ru->start_rf) {
......@@ -1299,14 +1308,13 @@ void *ru_thread( void *param ) {
if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot);
else AssertFatal(1==0, "No fronthaul interface at south port");
if (initial_wait == 1 && proc->frame_rx < 300 && ru->fh_south_in == rx_rf) {
if (proc->frame_rx>0 && ((proc->frame_rx % 100) == 0) && proc->tti_rx==0) {
LOG_I(PHY,"delay processing to let RX stream settle, frame %d (trials %d)\n",proc->frame_rx,ru->rx_fhaul.trials);
print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL);
reset_meas(&ru->rx_fhaul);
}
continue;
if (initial_wait == 1 && proc->frame_rx < 300) {
if (proc->frame_rx > 0 && ((proc->frame_rx % 100) == 0) && proc->tti_rx == 0) {
LOG_D(PHY, "delay processing to let RX stream settle, frame %d (trials %d)\n", proc->frame_rx, ru->rx_fhaul.trials);
print_meas(&ru->rx_fhaul, "rx_fhaul", NULL, NULL);
reset_meas(&ru->rx_fhaul);
}
continue;
}
if (proc->frame_rx>=300) {
initial_wait=0;
......@@ -1314,15 +1322,14 @@ void *ru_thread( void *param ) {
}
if (initial_wait == 0 && ru->rx_fhaul.trials > 1000) {
reset_meas(&ru->rx_fhaul);
/*if (ru->if_south == REMOTE_IF5) reset_meas(&ru->ifdevice.tx_fhaul);
else*/ reset_meas(&ru->tx_fhaul);
reset_meas(&ru->tx_fhaul);
}
proc->timestamp_tx = proc->timestamp_rx;
int sl=proc->tti_tx;
for (int slidx=0;slidx<ru->sl_ahead;slidx++)
proc->timestamp_tx += fp->get_samples_per_slot((sl+slidx)%fp->slots_per_frame,fp);
proc->frame_tx = (proc->tti_rx > (fp->slots_per_frame-1-(ru->sl_ahead))) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
proc->tti_tx = (proc->tti_rx + ru->sl_ahead)%fp->slots_per_frame;
proc->frame_tx = (proc->tti_rx > (fp->slots_per_frame - 1 - (ru->sl_ahead))) ? (proc->frame_rx + 1) & 1023 : proc->frame_rx;
proc->tti_tx = (proc->tti_rx + ru->sl_ahead) % fp->slots_per_frame;
int absslot_rx = proc->timestamp_rx/fp->get_samples_per_slot(proc->tti_rx,fp);
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_south_in[rt_prof_idx]);
......@@ -1333,14 +1340,62 @@ void *ru_thread( void *param ) {
RC.gNB[0]->proc.frame_rx,RC.gNB[0]->proc.slot_rx,
RC.gNB[0]->proc.frame_tx);
if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023;
if (ru->idx != 0)
proc->frame_tx = (proc->frame_tx + proc->frame_offset) & 1023;
LOG_D(NR_PHY, "In %d.%d: Checking L1 status\n", proc->frame_rx, proc->tti_rx);
for (int n = 0; n < RU_RX_SLOT_DEPTH; n++)
LOG_D(NR_PHY, "slot n %d => %d\n", n, rx_tti_busy[n]);
// handle potential race by blocking if rxdataF is being used by L1
// collect all pending msg in L1 return fifo to not down the memory is available (rx_tti_busy[slot] boolean array)
notifiedFIFO_elt_t *res = pollNotifiedFIFO(&gNB->L1_rx_out);
LOG_D(NR_PHY, "%d.%d Polling L1_rx_out %p\n", proc->frame_rx, proc->tti_rx, res);
while (res) {
processingData_L1_t *info = (processingData_L1_t *)NotifiedFifoData(res);
LOG_D(NR_PHY,
"%d.%d res %d.%d completed, clearing %d\n",
proc->frame_rx,
proc->tti_rx,
info->frame_rx,
info->slot_rx,
info->slot_rx % RU_RX_SLOT_DEPTH);
rx_tti_busy[info->slot_rx % RU_RX_SLOT_DEPTH] = false;
res = pollNotifiedFIFO(&gNB->L1_rx_out);
}
LOG_D(NR_PHY, "%d.%d Done polling\n", proc->frame_rx, proc->tti_rx);
// do RX front-end processing (frequency-shift, dft) if needed
int slot_type = nr_slot_select(cfg,proc->frame_rx,proc->tti_rx);
int slot_type = nr_slot_select(cfg, proc->frame_rx, proc->tti_rx);
if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
if (ru->feprx) {
if (rx_tti_busy[proc->tti_rx % RU_RX_SLOT_DEPTH]) {
bool not_done = true;
LOG_D(NR_PHY, "%d.%d Waiting to access RX slot %d\n", proc->frame_rx, proc->tti_rx, proc->tti_rx % RU_RX_SLOT_DEPTH);
// now we block and wait our slot memory zone is freed from previous slot processing
// as we can get other slots ending, we loop on the queue
while (not_done) {
res = pullNotifiedFIFO(&gNB->L1_rx_out);
if (!res)
break;
processingData_L1_t *info = (processingData_L1_t *)NotifiedFifoData(res);
LOG_D(NR_PHY,
"%d.%d Got access to RX slot %d.%d (%d)\n",
proc->frame_rx,
proc->tti_rx,
info->frame_rx,
info->slot_rx,
proc->tti_rx % RU_RX_SLOT_DEPTH);
rx_tti_busy[info->slot_rx % RU_RX_SLOT_DEPTH] = false;
if ((info->slot_rx % RU_RX_SLOT_DEPTH) == (proc->tti_rx % RU_RX_SLOT_DEPTH))
not_done = false;
}
if (!res)
break;
}
ru->feprx(ru,proc->tti_rx);
// set the tti that was generated to busy
LOG_D(NR_PHY, "Setting %d.%d (%d) to busy\n", proc->frame_rx, proc->tti_rx, proc->tti_rx % RU_RX_SLOT_DEPTH);
rx_tti_busy[proc->tti_rx % RU_RX_SLOT_DEPTH] = true;
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_feprx[rt_prof_idx]);
//LOG_M("rxdata.m","rxs",ru->common.rxdata[0],1228800,1,1);
LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx);
......@@ -1383,26 +1438,16 @@ void *ru_thread( void *param ) {
}
} // end if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
// At this point, all information for subframe has been received on FH interface
if (!get_softmodem_params()->reorder_thread_disable) {
res = pullTpool(&gNB->resp_L1, &gNB->threadPool);
if (res == NULL)
break; // Tpool has been stopped
} else {
res=newNotifiedFIFO_elt(sizeof(processingData_L1_t),0, &gNB->resp_L1,NULL);
}
syncMsg = (processingData_L1_t *)NotifiedFifoData(res);
syncMsg->gNB = gNB;
syncMsg->frame_rx = proc->frame_rx;
syncMsg->slot_rx = proc->tti_rx;
syncMsg->frame_tx = proc->frame_tx;
syncMsg->slot_tx = proc->tti_tx;
syncMsg->timestamp_tx = proc->timestamp_tx;
res->key = proc->tti_rx;
if (!get_softmodem_params()->reorder_thread_disable)
pushTpool(&gNB->threadPool, res);
else
pushNotifiedFIFO(&gNB->resp_L1, res);
notifiedFIFO_elt_t *resTx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, NULL);
processingData_L1tx_t *syncMsgTx = NotifiedFifoData(resTx);
syncMsgTx->gNB = gNB;
syncMsgTx->frame = proc->frame_tx;
syncMsgTx->slot = proc->tti_tx;
syncMsgTx->frame_rx = proc->frame_rx;
syncMsgTx->slot_rx = proc->tti_rx;
syncMsgTx->timestamp_tx = proc->timestamp_tx;
resTx->key = proc->tti_tx;
pushNotifiedFIFO(&gNB->L1_tx_out, resTx);
}
printf( "Exiting ru_thread \n");
......
......@@ -47,7 +47,6 @@ extern char *uecap_file;
// In nr-gnb.c
extern void init_gNB(int single_thread_flag,int wait_for_sync);
extern void stop_gNB(int);
extern void kill_gNB_proc(int inst);
// In nr-ru.c
extern void init_NR_RU(configmodule_interface_t *cfg, char *);
......
......@@ -44,7 +44,6 @@ extern "C"
example: -1,3 launches two working threads one floating, the second set on core 3\n\
default 8 floating threads\n\
use N for no pool (runs in calling thread) recommended with rfsim.\n"
#define CONFIG_HLP_REORDER "Disable reorder thread\n"
#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n"
#define CONFIG_HLP_CALUER "set UE RX calibration\n"
#define CONFIG_HLP_CALUERM ""
......@@ -143,7 +142,6 @@ extern "C"
#define SYNC_REF softmodem_params.sync_ref
#define LDPC_OFFLOAD_FLAG softmodem_params.ldpc_offload_flag
#define REORDER_THREAD_DISABLE softmodem_params.reorder_thread_disable
#define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat";
extern int usrp_tx_thread;
......@@ -151,7 +149,6 @@ extern int usrp_tx_thread;
#define CMDLINE_PARAMS_DESC { \
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, .strptr=&RF_CONFIG_FILE, .defstrval=NULL, TYPE_STRING, 0}, \
{"thread-pool", CONFIG_HLP_TPOOL, 0, .strptr=&TP_CONFIG, .defstrval="-1,-1,-1,-1,-1,-1,-1,-1", TYPE_STRING, 0}, \
{"reorder-thread-disable",CONFIG_HLP_REORDER, PARAMFLAG_BOOL, .iptr=&REORDER_THREAD_DISABLE, .defintval=0, TYPE_INT, 0}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, .iptr=&PHY_TEST, .defintval=0, TYPE_INT, 0}, \
{"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, .iptr=&DO_RA, .defintval=0, TYPE_INT, 0}, \
{"sa", CONFIG_HLP_SA, PARAMFLAG_BOOL, .iptr=&SA, .defintval=0, TYPE_INT, 0}, \
......@@ -227,7 +224,6 @@ extern int usrp_tx_thread;
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s3a = { config_checkstr_assign_integer, \
{"MONOLITHIC", "PNF", "VNF","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \
{NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \
......@@ -321,8 +317,7 @@ typedef struct {
uint64_t optmask;
//THREAD_STRUCT thread_struct;
char *rf_config_file;
char *threadPoolConfig;
int reorder_thread_disable;
char *threadPoolConfig;
int phy_test;
int do_ra;
int sa;
......@@ -368,7 +363,6 @@ extern uint16_t sl_ahead;
extern uint16_t sf_ahead;
extern int oai_exit;
void tx_func(void *param);
void rx_func(void *param);
void ru_tx_func(void *param);
extern uint8_t nfapi_mode;
......
......@@ -1244,7 +1244,6 @@ int phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind) {
int phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind) {
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.srs_ind = *ind;
......@@ -1260,8 +1259,6 @@ int phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind) {
);
}
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
return 1;
}
//end NR phy indication
......
......@@ -182,7 +182,6 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config)
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "This is the slot_ind queue size %ld in %s():%d\n",
gnb_slot_ind_queue.num_items, __FUNCTION__, __LINE__);
if (slot_ind) {
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.frame = slot_ind->sfn;
gNB->UL_INFO.slot = slot_ind->slot;
......@@ -198,7 +197,6 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config)
gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
prev_slot = gNB->UL_INFO.slot;
}
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
free(slot_ind);
slot_ind = NULL;
}
......
......@@ -76,11 +76,11 @@ void nr_fill_prach(PHY_VARS_gNB *gNB,
nfapi_nr_prach_pdu_t *prach_pdu) {
int prach_id = find_nr_prach(gNB,SFN,Slot,SEARCH_EXIST_OR_FREE);
AssertFatal( ((prach_id>=0) && (prach_id<NUMBER_OF_NR_PRACH_MAX)) || (prach_id < 0),
"illegal or no prach_id found!!! prach_id %d\n",prach_id);
AssertFatal(((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX)), "illegal or no prach_id found!!! prach_id %d\n", prach_id);
gNB->prach_vars.list[prach_id].frame=SFN;
gNB->prach_vars.list[prach_id].slot=Slot;
LOG_D(NR_PHY,"Copying prach pdu %d bytes to index %d\n",(int)sizeof(*prach_pdu),prach_id);
memcpy((void*)&gNB->prach_vars.list[prach_id].pdu,(void*)prach_pdu,sizeof(*prach_pdu));
}
......
......@@ -74,8 +74,8 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t
NR_UL_gNB_HARQ_t *harq = ulsch->harq_process;
if (ulsch_pdu->pusch_data.new_data_indicator)
harq->harq_to_be_cleared = true;
LOG_D(PHY,
"%d.%d RNTI %x HARQ PID %d new data indicator %d\n",
LOG_D(NR_PHY,
"NEW ULSCH %d.%d RNTI %x HARQ PID %d new data indicator %d\n",
frame,
slot,
ulsch_pdu->rnti,
......@@ -98,8 +98,17 @@ void reset_active_ulsch(PHY_VARS_gNB *gNB, int frame)
// assuming UE disconnected or some other error occurred
for (int i = 0; i < gNB->max_nb_pusch; i++) {
NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[i];
if (ulsch->active && (((frame - ulsch->frame + 1024) % 1024) > NUMBER_FRAMES_PHY_UE_INACTIVE))
int diff = (frame - ulsch->frame + 1024) & 1023;
if (ulsch->active && diff > NUMBER_FRAMES_PHY_UE_INACTIVE && diff < 100) {
ulsch->active = false;
LOG_D(NR_PHY,
"Frame %d: resetting ulsch %d harq %d (programmed in %d.%d)\n",
frame,
i,
ulsch->harq_pid,
ulsch->frame,
ulsch->slot);
}
}
}
......
......@@ -1409,7 +1409,7 @@ static void nr_pusch_symbol_processing(void *arg)
if (gNB->pusch_vars[ulsch_id].ul_valid_re_per_slot[symbol] == 0)
continue;
int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size;
int soffset = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
inner_rx(gNB,
ulsch_id,
slot,
......@@ -1591,7 +1591,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
// extract the first dmrs for the channel level computation
// extract the data in the OFDM frame, to the start of the array
int soffset = (slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size;
int soffset = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
nb_re_pusch = (nb_re_pusch + 15) & ~15;
......
......@@ -501,7 +501,7 @@ void nr_decode_pucch1(c16_t **rxdataF,
* Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation
*
*/
const int soffset = (nr_tti_tx & 3) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
const int soffset = (nr_tti_tx % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
// lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213]
const int lprime = startingSymbolIndex;
// mcs = 0 except for PUCCH format 0
......@@ -1021,14 +1021,10 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
//extract pucch and dmrs first
int l2 = pucch_pdu->start_symbol_index;
int soffset = (slot & 3) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
int soffset = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
int re_offset[2];
re_offset[0] =
(12 * (pucch_pdu->prb_start + pucch_pdu->bwp_start) + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
if (re_offset[0]>= frame_parms->ofdm_symbol_size)
re_offset[0]-=frame_parms->ofdm_symbol_size;
if (pucch_pdu->freq_hop_flag == 0)
re_offset[1] = re_offset[0];
else {
......
......@@ -34,6 +34,7 @@
#include "PHY/impl_defs_nr.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_gNB.h"
#include "PHY/defs_RU.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"
......@@ -75,7 +76,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
c16_t **rxdataF = gNB->common_vars.rxdataF;
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 uint16_t n_symbols = (slot % RU_RX_SLOT_DEPTH) * 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;
......
......@@ -197,7 +197,7 @@ typedef struct {
#define NUMBER_OF_NR_RU_PRACH_MAX 8
#define NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX 12
#define RU_RX_SLOT_DEPTH 4
typedef struct RU_proc_t_s {
/// Pointer to associated RU descriptor
struct RU_t_s *ru;
......
......@@ -562,7 +562,6 @@ typedef struct PHY_VARS_gNB_s {
PHY_MEASUREMENTS_gNB measurements;
NR_IF_Module_t *if_inst;
NR_UL_IND_t UL_INFO;
pthread_mutex_t UL_INFO_mutex;
/// NFAPI RX ULSCH information
nfapi_nr_rx_data_pdu_t rx_pdu_list[MAX_UL_PDUS_PER_SLOT];
......@@ -640,8 +639,6 @@ typedef struct PHY_VARS_gNB_s {
int ldpc_offload_flag;
int reorder_thread_disable;
int max_ldpc_iterations;
/// indicate the channel estimation technique in time domain
int chest_time;
......@@ -694,8 +691,8 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t rx_pusch_init_stats;
time_stats_t rx_pusch_symbol_processing_stats;
time_stats_t ul_indication_stats;
time_stats_t slot_indication_stats;
time_stats_t schedule_response_stats;
time_stats_t ulsch_decoding_stats;
time_stats_t ulsch_ldpc_decoding_stats;
time_stats_t ulsch_deinterleaving_stats;
time_stats_t ulsch_channel_estimation_stats;
......@@ -719,6 +716,7 @@ typedef struct PHY_VARS_gNB_s {
notifiedFIFO_t L1_tx_free;
notifiedFIFO_t L1_tx_filled;
notifiedFIFO_t L1_tx_out;
notifiedFIFO_t L1_rx_out;
notifiedFIFO_t resp_RU_tx;
tpool_t threadPool;
int nbSymb;
......@@ -796,9 +794,7 @@ union ldpcReqUnion {
typedef struct processingData_L1 {
int frame_rx;
int frame_tx;
int slot_rx;
int slot_tx;
openair0_timestamp timestamp_tx;
PHY_VARS_gNB *gNB;
} processingData_L1_t;
......@@ -812,6 +808,8 @@ typedef enum {
typedef struct processingData_L1tx {
int frame;
int slot;
int frame_rx;
int slot_rx;
openair0_timestamp timestamp_tx;
PHY_VARS_gNB *gNB;
nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu[NFAPI_NR_MAX_NB_CORESETS];
......@@ -826,4 +824,9 @@ typedef struct processingData_L1tx {
int sched_response_id;
} processingData_L1tx_t;
typedef struct processingData_L1rx {
int frame_rx;
int slot_rx;
PHY_VARS_gNB *gNB;
} processingData_L1rx_t;
#endif
......@@ -55,7 +55,7 @@ void handle_nr_nfapi_ssb_pdu(processingData_L1tx_t *msgTx,int frame,int slot,
uint8_t i_ssb = dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
LOG_D(PHY,"%d.%d : ssb index %d pbch_pdu: %x\n",frame,slot,i_ssb,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
LOG_D(NR_PHY,"%d.%d : ssb index %d pbch_pdu: %x\n",frame,slot,i_ssb,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
if (msgTx->ssb[i_ssb].active)
AssertFatal(1==0,"SSB PDU with index %d already active\n",i_ssb);
else {
......@@ -109,7 +109,7 @@ void handle_nfapi_nr_csirs_pdu(processingData_L1tx_t *msgTx, int frame, int slot
for (int id = 0; id < NR_SYMBOLS_PER_SLOT; id++) {
NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[id];
if (csirs->active == 0) {
LOG_D(PHY,"Frame %d Slot %d CSI_RS with ID %d is now active\n",frame,slot,id);
LOG_D(NR_PHY,"Frame %d Slot %d CSI_RS with ID %d is now active\n",frame,slot,id);
csirs->active = 1;
memcpy((void*)&csirs->csirs_pdu, (void*)csirs_pdu, sizeof(nfapi_nr_dl_tti_csi_rs_pdu));
found = 1;
......@@ -156,21 +156,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
uint8_t number_tx_data_pdu = (TX_req == NULL) ? 0 : TX_req->Number_of_PDUs;
if (NFAPI_MODE == NFAPI_MONOLITHIC){
if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT) {
notifiedFIFO_elt_t *res=NULL;
processingData_L1tx_t *msgTx=NULL;
if (!gNB->reorder_thread_disable) {
res = pullNotifiedFIFO(&gNB->L1_tx_free);
if (res == NULL)
return; // Tpool has been stopped, nothing to process
msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
} else {
msgTx = gNB->msgDataTx; //newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0, &gNB->L1_tx_out,NULL);
}
/*const time_stats_t ts = exec_time_stats_NotifiedFIFO(res);
merge_meas(&gNB->phy_proc_tx, &ts);
*/
msgTx = gNB->msgDataTx;
msgTx->num_pdsch_slot = 0;
msgTx->num_dl_pdcch = 0;
msgTx->num_ul_pdcch = number_ul_dci_pdu;
......@@ -181,7 +169,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
for (int i=0;i<number_dl_pdu;i++) {
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i];
LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType);
LOG_D(NR_PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType);
switch (dl_tti_pdu->PDUType) {
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
handle_nr_nfapi_ssb_pdu(msgTx,frame,slot,
......@@ -189,18 +177,18 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
break;
case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
LOG_D(NR_PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
msgTx->pdcch_pdu[msgTx->num_dl_pdcch] = dl_tti_pdu->pdcch_pdu;
msgTx->num_dl_pdcch++;
break;
case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
LOG_D(NR_PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
handle_nfapi_nr_csirs_pdu(msgTx,frame,slot,&dl_tti_pdu->csi_rs_pdu);
break;
case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
LOG_D(NR_PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15;
uint16_t pduIndex = pdsch_pdu_rel15->pduIndex;
AssertFatal(TX_req->pdu_list[pduIndex].num_TLV == 1, "TX_req->pdu_list[%d].num_TLV %d != 1\n",
......@@ -222,29 +210,27 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
* released only when both threads are done with it.
*/
inc_ref_sched_response(Sched_INFO->sched_response_id);
if (!gNB->reorder_thread_disable)
pushNotifiedFIFO(&gNB->L1_tx_filled,res);
}
for (int i = 0; i < number_ul_tti_pdu; i++) {
switch (UL_tti_req->pdus_list[i].pdu_type) {
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUSCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
LOG_D(NR_PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUSCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
nr_fill_ulsch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu);
break;
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
LOG_D(NR_PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
nr_fill_pucch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pucch_pdu);
break;
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
LOG_D(NR_PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu;
nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
if (gNB->RU_list[0]->if_south == LOCAL_RF ||
gNB->RU_list[0]->if_south == REMOTE_IF5) nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
break;
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
LOG_D(NR_PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
nr_fill_srs(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].srs_pdu);
break;
}
......@@ -267,7 +253,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
}
/* this thread is done with the sched_info, decrease the reference counter */
deref_sched_response(Sched_INFO->sched_response_id);
if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT) {
LOG_D(NR_PHY, "Calling dref_sched_response for id %d in %d.%d (sched_response)\n", Sched_INFO->sched_response_id, frame, slot);
deref_sched_response(Sched_INFO->sched_response_id);
}
stop_meas(&gNB->schedule_response_stats);
}
......@@ -120,6 +120,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) {
int prach_id=find_nr_prach(gNB,frame,slot,SEARCH_EXIST);
if (prach_id>=0) {
LOG_D(NR_PHY,"%d.%d Got prach entry id %d\n",frame,slot,prach_id);
nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_vars.list[prach_id].pdu;
uint8_t prachStartSymbol;
uint8_t N_dur = get_nr_prach_duration(prach_pdu->prach_format);
......@@ -140,9 +141,9 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) {
&max_preamble[0],
&max_preamble_energy[0],
&max_preamble_delay[0]);
LOG_D(NR_PHY,"Freeing PRACH entry %d\n",prach_id);
free_nr_prach_entry(gNB,prach_id);
LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d (prach_energy counter %d)\n",
LOG_D(NR_PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d (prach_energy counter %d)\n",
frame,slot,prach_oc,prachStartSymbol,
max_preamble[0],
max_preamble_energy[0]/10,
......
......@@ -242,7 +242,7 @@ void nr_fep_full(RU_t *ru, int slot) {
// remove_7_5_kHz(ru,proc->tti_rx<<1);
// remove_7_5_kHz(ru,1+(proc->tti_rx<<1));
int offset = (proc->tti_rx&3)*(fp->symbols_per_slot * fp->ofdm_symbol_size);
int offset = (proc->tti_rx % RU_RX_SLOT_DEPTH) * (fp->symbols_per_slot * fp->ofdm_symbol_size);
for (l = 0; l < fp->symbols_per_slot; l++) {
for (aa = 0; aa < fp->nb_antennas_rx; aa++) {
nr_slot_fep_ul(fp,
......@@ -378,7 +378,7 @@ void nr_fep(void* arg) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 1);
int offset = (tti_rx&3) * fp->symbols_per_slot * fp->ofdm_symbol_size;
int offset = (tti_rx % RU_RX_SLOT_DEPTH) * fp->symbols_per_slot * fp->ofdm_symbol_size;
for (int l = startSymbol; l <= endSymbol; l++)
nr_slot_fep_ul(fp,
ru->common.rxdata[aid],
......
......@@ -272,10 +272,11 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
}
if (crc_valid && !check_abort(&ulsch_harq->abort_decode) && !gNB->pusch_vars[rdata->ulsch_id].DTX) {
LOG_D(PHY,
"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (rnti %x, pid %d, ndi %d, status %d, round %d, TBS %d, Max interation "
LOG_D(NR_PHY,
"[gNB %d] ULSCH %d: Setting ACK for SFN/SF %d.%d (rnti %x, pid %d, ndi %d, status %d, round %d, TBS %d, Max interation "
"(all seg) %d)\n",
gNB->Mod_id,
rdata->ulsch_id,
ulsch->frame,
ulsch->slot,
ulsch->rnti,
......@@ -316,7 +317,7 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
if (ulsch_harq->ulsch_pdu.mcs_index == 0 && dumpsig==1) {
int off = ((ulsch_harq->ulsch_pdu.rb_size&1) == 1)? 4:0;
LOG_M("rxsigF0.m","rxsF0",&gNB->common_vars.rxdataF[0][(ulsch_harq->slot&3)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1);
LOG_M("rxsigF0.m","rxsF0",&gNB->common_vars.rxdataF[0][(ulsch_harq->slot%RU_RX_SLOT_DEPTH)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1);
LOG_M("rxsigF0_ext.m","rxsF0_ext",
&gNB->pusch_vars[0].rxdataF_ext[0][ulsch_harq->ulsch_pdu.start_symbol_index*NR_NB_SC_PER_RB *
ulsch_harq->ulsch_pdu.rb_size],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB *
......@@ -400,7 +401,6 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int
//--------------------- ULSCH decoding ---------------------
//----------------------------------------------------------
start_meas(&gNB->ulsch_decoding_stats);
int nbDecode =
nr_ulsch_decoding(gNB, ULSCH_id, gNB->pusch_vars[ULSCH_id].llr, frame_parms, pusch_pdu, frame_rx, slot_rx, harq_pid, G);
......@@ -410,9 +410,6 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int
void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, uint8_t harq_pid, uint8_t crc_flag, int dtx_flag)
{
if (!get_softmodem_params()->reorder_thread_disable)
pthread_mutex_lock(&gNB->UL_INFO_mutex);
NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
NR_gNB_PHY_STATS_t *stats = get_phy_stats(gNB, ulsch->rnti);
......@@ -467,7 +464,13 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
__attribute__((unused))
int off = ((pusch_pdu->rb_size&1) == 1)? 4:0;
LOG_M("rxsigF0.m","rxsF0",&gNB->common_vars.rxdataF[0][(slot_rx&3)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1);
LOG_M("rxsigF0.m",
"rxsF0",
&gNB->common_vars
.rxdataF[0][(slot_rx % RU_RX_SLOT_DEPTH) * gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot],
gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot,
1,
1);
LOG_M("chestF0.m",
"chF0",
&gNB->pusch_vars[0].ul_ch_estimates[0][pusch_pdu->start_symbol_index * gNB->frame_parms.ofdm_symbol_size],
......@@ -494,7 +497,14 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
1,
0);
if (gNB->frame_parms.nb_antennas_rx > 1) {
LOG_M("rxsigF1.m","rxsF1",&gNB->common_vars.rxdataF[1][(slot_rx&3)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1);
LOG_M(
"rxsigF1.m",
"rxsF1",
&gNB->common_vars
.rxdataF[1][(slot_rx % RU_RX_SLOT_DEPTH) * gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot],
gNB->frame_parms.ofdm_symbol_size * gNB->frame_parms.symbols_per_slot,
1,
1);
LOG_M("chestF1.m",
"chF1",
&gNB->pusch_vars[0].ul_ch_estimates[1][pusch_pdu->start_symbol_index * gNB->frame_parms.ofdm_symbol_size],
......@@ -557,9 +567,6 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
}
gNB->UL_INFO.rx_ind.number_of_pdus++;
if (!get_softmodem_params()->reorder_thread_disable)
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
}
// Function to fill UL RB mask to be used for N0 measurements
......@@ -834,9 +841,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id];
NR_UL_gNB_HARQ_t *ulsch_harq = ulsch->harq_process;
AssertFatal(ulsch_harq != NULL, "harq_pid %d is not allocated\n", ulsch->harq_pid);
if ((ulsch->active == true) && (ulsch->frame == frame_rx) && (ulsch->slot == slot_rx) && (ulsch->handled == 0)) {
LOG_D(PHY, "PUSCH ID %d with RNTI %x detection started in frame %d slot %d\n", ULSCH_id, ulsch->rnti, frame_rx, slot_rx);
int num_dmrs = 0;
for (int s = 0; s < NR_NUMBER_OF_SYMBOLS_PER_SLOT; s++)
num_dmrs += (ulsch_harq->ulsch_pdu.ul_dmrs_symb_pos >> s) & 1;
......@@ -941,7 +948,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
delNotifiedFIFO_elt(req);
totalDecode--;
}
stop_meas(&gNB->ulsch_decoding_stats);
for (int i = 0; i < gNB->max_nb_srs; i++) {
NR_gNB_SRS_t *srs = &gNB->srs[i];
if (srs) {
......
......@@ -895,6 +895,7 @@ int main(int argc, char **argv)
msgDataTx->slot = slot;
msgDataTx->frame = frame;
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
gNB->msgDataTx = msgDataTx;
// Buffers to store internal memory of slot process
int rx_size = (((14 * frame_parms->N_RB_DL * 12 * sizeof(int32_t)) + 15) >> 4) << 4;
......
......@@ -563,6 +563,7 @@ int main(int argc, char *argv[])
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_free, NULL);
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
msgDataTx->slot = -1;
gNB->msgDataTx = msgDataTx;
//gNB_config = &gNB->gNB_config;
//memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
......@@ -921,7 +922,6 @@ int main(int argc, char *argv[])
reset_meas(&gNB->rx_pusch_stats);
reset_meas(&gNB->rx_pusch_init_stats);
reset_meas(&gNB->rx_pusch_symbol_processing_stats);
reset_meas(&gNB->ulsch_decoding_stats);
reset_meas(&gNB->ulsch_channel_estimation_stats);
reset_meas(&UE->ulsch_ldpc_encoding_stats);
reset_meas(&UE->ulsch_rate_matching_stats);
......@@ -1546,7 +1546,6 @@ int main(int argc, char *argv[])
printStatIndent2(&gNB->ulsch_channel_estimation_stats, "ULSCH channel estimation time");
printStatIndent2(&gNB->rx_pusch_init_stats, "RX PUSCH Initialization time");
printStatIndent2(&gNB->rx_pusch_symbol_processing_stats, "RX PUSCH Symbol Processing time");
printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
printf("\nUE TX\n");
printStatIndent(&UE->ulsch_encoding_stats,"ULSCH total encoding time");
......
......@@ -385,12 +385,49 @@ static void match_crc_rx_pdu(nfapi_nr_rx_data_indication_t *rx_ind, nfapi_nr_crc
}
}
static void run_scheduler(module_id_t module_id, int CC_id, int frame, int slot)
{
NR_IF_Module_t *ifi = nr_if_inst[module_id];
// gNB_MAC_INST *mac = RC.nrmac[module_id];
NR_Sched_Rsp_t *sched_info;
LOG_D(NR_MAC, "Calling scheduler for %d.%d\n", frame, slot);
sched_info = allocate_sched_response();
// clear UL DCI prior to handling ULSCH
sched_info->UL_dci_req.numPdus = 0;
gNB_dlsch_ulsch_scheduler(module_id, frame, slot, sched_info);
ifi->CC_mask = 0;
sched_info->module_id = module_id;
sched_info->CC_id = CC_id;
sched_info->frame = frame;
sched_info->slot = slot;
/*
sched_info->DL_req = &mac->DL_req[CC_id];
sched_info->UL_dci_req = &mac->UL_dci_req[CC_id];
sched_info->UL_tti_req = mac->UL_tti_req[CC_id];
sched_info->TX_req = &mac->TX_req[CC_id];
*/
#ifdef DUMP_FAPI
dump_dl(sched_info);
#endif
AssertFatal(ifi->NR_Schedule_response != NULL, "nr_schedule_response is null (mod %d, cc %d)\n", module_id, CC_id);
ifi->NR_Schedule_response(sched_info);
LOG_D(NR_PHY,
"NR_Schedule_response: SFN SLOT:%d %d dl_pdus:%d\n",
sched_info->frame,
sched_info->slot,
sched_info->DL_req.dl_tti_request_body.nPDUs);
}
void NR_UL_indication(NR_UL_IND_t *UL_info) {
AssertFatal(UL_info!=NULL,"UL_info is null\n");
module_id_t module_id = UL_info->module_id;
int CC_id = UL_info->CC_id;
NR_Sched_Rsp_t *sched_info;
NR_IF_Module_t *ifi = nr_if_inst[module_id];
module_id_t module_id = UL_info->module_id;
int CC_id = UL_info->CC_id;
LOG_D(NR_PHY,"SFN/SLOT:%d.%d module_id:%d CC_id:%d UL_info[rach_pdus:%zu rx_ind:%zu crcs:%zu]\n",
UL_info->frame, UL_info->slot,
......@@ -449,57 +486,6 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
if (get_softmodem_params()->emulate_l1) {
free_unqueued_nfapi_indications(rach_ind, uci_ind, rx_ind, crc_ind);
}
if (NFAPI_MODE != NFAPI_MODE_PNF) {
gNB_MAC_INST *mac = RC.nrmac[module_id];
if (ifi->CC_mask==0) {
ifi->current_frame = UL_info->frame;
ifi->current_slot = UL_info->slot;
} else {
AssertFatal(UL_info->frame != ifi->current_frame,"CC_mask %x is not full and frame has changed\n",ifi->CC_mask);
AssertFatal(UL_info->slot != ifi->current_slot,"CC_mask %x is not full and slot has changed\n",ifi->CC_mask);
}
ifi->CC_mask |= (1<<CC_id);
if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) {
/*
eNB_dlsch_ulsch_scheduler(module_id,
(UL_info->frame+((UL_info->slot>(9-sl_ahead))?1:0)) % 1024,
(UL_info->slot+sl_ahead)%10);
*/
nfapi_nr_config_request_scf_t *cfg = &mac->config[CC_id];
int spf = get_spf(cfg);
sched_info = allocate_sched_response();
// clear UL DCI prior to handling ULSCH
sched_info->UL_dci_req.numPdus = 0;
gNB_dlsch_ulsch_scheduler(module_id,
(UL_info->frame + ((UL_info->slot > (spf - 1 - ifi->sl_ahead)) ? 1 : 0)) % 1024,
(UL_info->slot + ifi->sl_ahead) % spf,
sched_info);
ifi->CC_mask = 0;
sched_info->module_id = module_id;
sched_info->CC_id = CC_id;
sched_info->frame = (UL_info->frame + ((UL_info->slot>(spf-1-ifi->sl_ahead)) ? 1 : 0)) % 1024;
sched_info->slot = (UL_info->slot+ifi->sl_ahead)%spf;
#ifdef DUMP_FAPI
dump_dl(sched_info);
#endif
AssertFatal(ifi->NR_Schedule_response!=NULL,
"nr_schedule_response is null (mod %d, cc %d)\n",
module_id,
CC_id);
ifi->NR_Schedule_response(sched_info);
LOG_D(NR_PHY,
"NR_Schedule_response: SFN SLOT:%d %d dl_pdus:%d\n",
sched_info->frame,
sched_info->slot,
sched_info->DL_req.dl_tti_request_body.nPDUs);
}
}
}
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {
......@@ -514,6 +500,7 @@ NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {
nr_if_inst[Mod_id]->CC_mask=0;
nr_if_inst[Mod_id]->NR_UL_indication = NR_UL_indication;
nr_if_inst[Mod_id]->NR_slot_indication = run_scheduler;
AssertFatal(pthread_mutex_init(&nr_if_inst[Mod_id]->if_mutex,NULL)==0,
"allocation of nr_if_inst[%d]->if_mutex fails\n",Mod_id);
}
......
......@@ -113,6 +113,7 @@ typedef struct NR_IF_Module_s {
//define the function pointer
void (*NR_UL_indication)(NR_UL_IND_t *UL_INFO);
void (*NR_Schedule_response)(NR_Sched_Rsp_t *Sched_INFO);
void (*NR_slot_indication)(module_id_t module_idP, int CC_id, int frame, int slot);
void (*NR_PHY_config_req)(NR_PHY_Config_t *config_INFO);
uint32_t CC_mask;
uint16_t current_frame;
......
......@@ -105,6 +105,7 @@ NR_Sched_Rsp_t *allocate_sched_response(void)
static void release_sched_response(int sched_response_id)
{
LOG_D(NR_MAC,"Releasing sched_response %d\n",sched_response_id);
resp_freelist_next[sched_response_id] = resp_freelist_head;
resp_freelist_head = sched_response_id;
}
......@@ -124,6 +125,7 @@ void deref_sched_response(int sched_response_id)
AssertFatal(resp_freelist_inited, "sched_response used before init\n");
AssertFatal(resp_refcount[sched_response_id] > 0, "sched_reponse decreased too much\n");
LOG_D(NR_MAC,"resp_refcount[%d] %d\n",sched_response_id,resp_refcount[sched_response_id]);
resp_refcount[sched_response_id]--;
if (resp_refcount[sched_response_id] == 0)
release_sched_response(sched_response_id);
......@@ -141,6 +143,8 @@ void inc_ref_sched_response(int sched_response_id)
if (sched_response_id == -1)
return;
LOG_D(NR_MAC,"Incrementing sched_resp resp_refounct[%d] = %d\n",
sched_response_id,resp_refcount[sched_response_id]);
if (pthread_mutex_lock(&resp_mutex))
AssertFatal(0, "pthread_mutex_lock failed\n");
......
......@@ -337,7 +337,7 @@ void *trx_eth_write_udp_cmd(udpTXelem_t *udpTXelem) {
TS -= device->txrx_offset;
int TSinc = (6*256*device->sampling_rate_ratio_d)/device->sampling_rate_ratio_n;
int len=256;
LOG_D(PHY,"TS %llu (%llu),txrx_offset %d,d %d, n %d, buff[0] %p buff[1] %p\n",
LOG_D(NR_PHY,"in eth send: TS %llu (%llu),txrx_offset %d,d %d, n %d, buff[0] %p buff[1] %p\n",
(unsigned long long)TS,(unsigned long long)timestamp,device->txrx_offset,device->sampling_rate_ratio_d,device->sampling_rate_ratio_n,
buff[0],buff[1]);
for (int offset=0;offset<nsamps;offset+=256,TS+=TSinc) {
......@@ -349,7 +349,7 @@ void *trx_eth_write_udp_cmd(udpTXelem_t *udpTXelem) {
*(uint8_t *)(buff2 + 2) = len>>8;
*(uint8_t *)(buff2 + 3) = len&0xff;
for (int aid = 0; aid<nant; aid++) {
LOG_D(PHY,"TS %llu (TS0 %llu) aa %d : offset %d, len %d\n",(unsigned long long)TS,(unsigned long long)fhstate->TS0,aid,offset,len);
LOG_D(NR_PHY,"TS %llu (TS0 %llu) aa %d : offset %d, len %d\n",(unsigned long long)TS,(unsigned long long)fhstate->TS0,aid,offset,len);
// ECPRI PC_ID (2 bytes)
*(uint16_t *)(buff2 + 4) = aid;
// bring TX data into 12 MSBs
......@@ -383,6 +383,7 @@ void *trx_eth_write_udp_cmd(udpTXelem_t *udpTXelem) {
} // aid
} // offset
free(buff);
LOG_D(NR_PHY,"Returning from eth send\n");
return(NULL);
}
......
......@@ -11,7 +11,7 @@ gNBs =
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1 }) });
plmn_list = ({ mcc = 208; mnc = 98; mnc_length = 2; snssaiList = ({ sst = 1 }) });
nr_cellid = 12345678L;
......@@ -136,10 +136,10 @@ gNBs =
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
dl_UL_TransmissionPeriodicity = 5;
nrofDownlinkSlots = 3;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSlots = 1;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
......@@ -168,9 +168,9 @@ gNBs =
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
GNB_INTERFACE_NAME_FOR_NG_AMF = "internet";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24";
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
GNB_INTERFACE_NAME_FOR_NGU = "internet";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
......@@ -186,6 +186,10 @@ MACRLCs = (
pusch_TargetSNRx10 = 150;
pucch_TargetSNRx10 = 200;
ulsch_max_frame_inactivity = 0;
ul_max_mcs = 10;
min_grant_prb = 20;
min_grant_mcs = 16;
dl_max_mcs = 10;
}
);
......@@ -204,8 +208,8 @@ RUs = (
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 6;
att_rx = 6;
att_tx = 0;
att_rx = 0;
bands = [41];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
......@@ -213,6 +217,7 @@ RUs = (
#beamforming 1x4 matrix:
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
clock_src = "internal";
sl_ahead = 2;
}
);
......
......@@ -217,7 +217,7 @@ L1s = (
#thread_pool_size = 8;
tx_amp_backoff_dB = 3;
L1_rx_thread_core = 8;
L1_tx_thread_core = 10; # relevant after merge of l1_tx_thread
L1_tx_thread_core = 10;
phase_compensation = 0; # needs to match O-RU configuration
}
);
......
......@@ -214,7 +214,7 @@ L1s = (
max_ldpc_iterations = 10;
tx_amp_backoff_dB = 20; # needs to match O-RU configuration
L1_rx_thread_core = 8;
L1_tx_thread_core = 10; # relevant after merge of l1_tx_thread
L1_tx_thread_core = 10;
phase_compensation = 0; # needs to match O-RU configuration
}
);
......
......@@ -215,7 +215,7 @@ L1s = (
max_ldpc_iterations = 10;
tx_amp_backoff_dB = 20; # needs to match O-RU configuration
L1_rx_thread_core = 8;
L1_tx_thread_core = 10; # relevant after merge of l1_tx_thread
L1_tx_thread_core = 10;
phase_compensation = 1; # needs to match O-RU configuration
}
);
......
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