diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
index e71bb00ffb..d92804ae44 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -21,183 +21,166 @@ gNBs =
////////// Physical parameters:
- component_carriers = (
- {
- node_function = "3GPP_gNODEB";
- node_timing = "synch_to_ext_device";
- node_synch_ref = 0;
- frame_type = "TDD";
- DL_prefix_type = "NORMAL";
- UL_prefix_type = "NORMAL";
- eutra_band = 78;
- downlink_frequency = 3510000000L;
- uplink_frequency_offset = -120000000;
- Nid_cell = 0;
- N_RB_DL = 106;
- nb_antenna_ports = 1;
- nb_antennas_tx = 1;
- nb_antennas_rx = 1;
- tx_gain = 90;
- rx_gain = 125;
- MIB_subCarrierSpacingCommon = 30;
- MIB_ssb_SubcarrierOffset = 0;
- MIB_dmrs_TypeA_Position = 2;
- pdcch_ConfigSIB1 = 0;
- SIB1_frequencyOffsetSSB = "khz5";
- SIB1_ssb_PeriodicityServingCell = 5;
- SIB1_ss_PBCH_BlockPower = -60;
- absoluteFrequencySSB = 0;
- DL_FreqBandIndicatorNR = 15;
- DL_absoluteFrequencyPointA = 15;
- DL_offsetToCarrier = 15;
- DL_SCS_SubcarrierSpacing = "kHz30";
- DL_SCS_SpecificCarrier_k0 = 0;
- DL_carrierBandwidth = 15;
- DL_locationAndBandwidth = 15;
- DL_BWP_SubcarrierSpacing = "kHz30";
- DL_BWP_prefix_type = "NORMAL";
- UL_FreqBandIndicatorNR = 15;
- UL_absoluteFrequencyPointA = 13;
- UL_additionalSpectrumEmission = 3;
- UL_p_Max = -1;
- UL_frequencyShift7p5khz = "TRUE";
- UL_offsetToCarrier = 10;
- UL_SCS_SubcarrierSpacing = "kHz30";
- UL_SCS_SpecificCarrier_k0 = 0;
- UL_carrierBandwidth = 15;
- UL_locationAndBandwidth = 15;
- UL_BWP_SubcarrierSpacing = "kHz30";
- UL_BWP_prefix_type = "NORMAL";
- UL_timeAlignmentTimerCommon = "infinity";
- ServingCellConfigCommon_n_TimingAdvanceOffset = "n0"
- ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01;
- ServingCellConfigCommon_ssb_periodicityServingCell = 10;
- ServingCellConfigCommon_dmrs_TypeA_Position = 2;
- NIA_SubcarrierSpacing = "kHz15";
- ServingCellConfigCommon_ss_PBCH_BlockPower = -60;
- referenceSubcarrierSpacing = "kHz15";
- dl_UL_TransmissionPeriodicity = "ms0p5";
- nrofDownlinkSlots = 10;
- nrofDownlinkSymbols = 10;
- nrofUplinkSlots = 10;
- nrofUplinkSymbols = 10;
- rach_totalNumberOfRA_Preambles = 63;
- rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_choice = "oneEighth";
- rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneEighth = 4;
- rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneFourth = 8;
- rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneHalf = 16;
- rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_one = 24;
- rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_two = 32;
- rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_four = 8;
- rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_eight = 4;
- rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_sixteen = 2;
- rach_groupBconfigured = "ENABLE";
- rach_ra_Msg3SizeGroupA = 56;
- rach_messagePowerOffsetGroupB = "dB0";
- rach_numberOfRA_PreamblesGroupA = 32;
- rach_ra_ContentionResolutionTimer = 8;
- rsrp_ThresholdSSB = 64;
- rsrp_ThresholdSSB_SUL = 64;
- prach_RootSequenceIndex_choice = "l839";
- prach_RootSequenceIndex_l839 = 0;
- prach_RootSequenceIndex_l139 = 0;
- prach_msg1_SubcarrierSpacing = "kHz30";
- restrictedSetConfig = "unrestrictedSet";
- msg3_transformPrecoding = "ENABLE";
- prach_ConfigurationIndex = 10;
- prach_msg1_FDM = "one";
- prach_msg1_FrequencyStart = 10;
- zeroCorrelationZoneConfig = 10;
- preambleReceivedTargetPower = -150;
- preambleTransMax = 6;
- powerRampingStep = "dB0";
- ra_ResponseWindow = 8;
- groupHoppingEnabledTransformPrecoding = "ENABLE";
- msg3_DeltaPreamble = 0;
- p0_NominalWithGrant = 0;
- PUSCH_TimeDomainResourceAllocation_k2 = 0;
- PUSCH_TimeDomainResourceAllocation_mappingType = "typeA";
- PUSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0;
- pucch_ResourceCommon = 0;
- pucch_GroupHopping = "neither";
- hoppingId = 0;
- p0_nominal = -30;
- PDSCH_TimeDomainResourceAllocation_k0 = 2;
- PDSCH_TimeDomainResourceAllocation_mappingType = "typeA";
- PDSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0;
- rateMatchPatternId = 0;
- RateMatchPattern_patternType = "bitmaps";
- symbolsInResourceBlock = "oneSlot";
- periodicityAndPattern = 2;
- RateMatchPattern_controlResourceSet = 5;
- RateMatchPattern_subcarrierSpacing = "kHz30";
- RateMatchPattern_mode = "dynamic";
- controlResourceSetZero = 0;
- searchSpaceZero = 0;
- searchSpaceSIB1 = 10;
- searchSpaceOtherSystemInformation = 10;
- pagingSearchSpace = 10;
- ra_SearchSpace = 10;
- PDCCH_common_controlResourceSetId = 5;
- PDCCH_common_ControlResourceSet_duration = 2;
- PDCCH_cce_REG_MappingType = "nonInterleaved";
- PDCCH_reg_BundleSize = 3;
- PDCCH_interleaverSize = 3;
- PDCCH_shiftIndex = 10;
- PDCCH_precoderGranularity = "sameAsREG-bundle";
- PDCCH_TCI_StateId = 32;
- tci_PresentInDCI = "ENABLE";
- PDCCH_DMRS_ScramblingID = 0;
- SearchSpaceId = 10;
- commonSearchSpaces_controlResourceSetId = 5;
- SearchSpace_monitoringSlotPeriodicityAndOffset_choice = "sl1";
- SearchSpace_monitoringSlotPeriodicityAndOffset_value = 0;
- SearchSpace_duration = 2;
- SearchSpace_nrofCandidates_aggregationLevel1 = 0;
- SearchSpace_nrofCandidates_aggregationLevel2 = 0;
- SearchSpace_nrofCandidates_aggregationLevel4 = 0;
- SearchSpace_nrofCandidates_aggregationLevel8 = 0;
- SearchSpace_nrofCandidates_aggregationLevel16 = 0;
- SearchSpace_searchSpaceType = "common";
- Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel1 = 1;
- Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel2 = 1;
- Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel4 = 1;
- Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel8 = 1;
- Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel16 = 1;
- Common_dci_Format2_3_monitoringPeriodicity = 1;
- Common_dci_Format2_3_nrofPDCCH_Candidates = 1;
- ue_Specific__dci_Formats = "formats0-0-And-1-0";
- RateMatchPatternLTE_CRS_carrierFreqDL = 6;
- RateMatchPatternLTE_CRS_carrierBandwidthDL = 6;
- RateMatchPatternLTE_CRS_nrofCRS_Ports = 1;
- RateMatchPatternLTE_CRS_v_Shift = 0;
- RateMatchPatternLTE_CRS_radioframeAllocationPeriod = 1;
- RateMatchPatternLTE_CRS_radioframeAllocationOffset = 0;
- RateMatchPatternLTE_CRS_subframeAllocation_choice = "oneFrame";
- }
- );
-
-
- srb1_parameters :
+ ssb_SubcarrierOffset = 0;
+ pdsch_AntennaPorts = 1;
+
+ servingCellConfigCommon = (
{
- # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
- timer_poll_retransmit = 80;
+ #spCellConfigCommon
- # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
- timer_reordering = 35;
+ physCellId = 0;
- # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
- timer_status_prohibit = 0;
+# downlinkConfigCommon
+ #frequencyInfoDL
+ # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+ absoluteFrequencySSB = 641032;
+ dl_frequencyBand = 78;
+ # this is 3600 MHz
+ dl_absoluteFrequencyPointA = 640000;
+ #scs-SpecificCarrierList
+ dl_offstToCarrier = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+ dl_subcarrierSpacing = 1;
+ dl_carrierBandwidth = 106;
+ #initialDownlinkBWP
+ #genericParameters
+ # this is RBstart=0,L=50 (275*(L-1))+RBstart
+ initialDLBWPlocationAndBandwidth = 13475;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+ initialDLBWPsubcarrierSpacing = 1;
+ #pdcch-ConfigCommon
+ initialDLBWPcontrolResourceSetZero = 12;
+ initialDLBWPsearchSpaceZero = 0;
+ #pdsch-ConfigCommon
+ #pdschTimeDomainAllocationList (up to 16 entries)
+ initialDLBWPk0_0 = 0;
+ #initialULBWPmappingType
+ #0=typeA,1=typeB
+ initialDLBWPmappingType_0 = 0;
+ #this is SS=2,L=3
+ initialDLBWPstartSymbolAndLength_0 = 40;
- # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
- poll_pdu = 4;
+ initialDLBWPk0_1 = 0;
+ initialDLBWPmappingType_1 = 0;
+ #this is SS=2,L=12
+ initialDLBWPstartSymbolAndLength_1 = 53;
- # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
- poll_byte = 99999;
+ initialDLBWPk0_2 = 0;
+ initialDLBWPmappingType_2 = 0;
+ #this is SS=1,L=12
+ initialDLBWPstartSymbolAndLength_2 = 54;
+ #uplinkConfigCommon
+ #frequencyInfoUL
+ ul_frequencyBand = 78;
+ #scs-SpecificCarrierList
+ ul_offstToCarrier = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+ ul_subcarrierSpacing = 1;
+ ul_carrierBandwidth = 106;
+ pMax = 20;
+ #initialUplinkBWP
+ #genericParameters
+ initialULBWPlocationAndBandwidth = 13475;
+# 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
+#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
+ ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
+#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
+#0 = 839, 1 = 139
+ prach_RootSequenceIndex_PR = 1;
+ 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,
+ # pusch-ConfigCommon (up to 16 elements)
+ initialULBWPk2_0 = 2;
+ initialULBWPmappingType_0 = 1
+ # this is SS=0 L=11
+ initialULBWPstartSymbolAndLength_0 = 55;
+
+ initialULBWPk2_1 = 2;
+ initialULBWPmappingType_1 = 1;
+ # this is SS=0 L=12
+ initialULBWPstartSymbolAndLength_1 = 69;
+
+
+ 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 = 10;
+ }
+
+ );
- # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
- max_retx_threshold = 4;
- }
# ------- SCTP definitions
SCTP :
@@ -254,8 +237,8 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
- sdr_addrs = "addr=192.168.20.2,second_addr=192.168.10.2,mgmt_addr=192.168.20.2,clock_source=external,time_source=external";
-
+ sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2";
+ clock_src = "external";
}
);
@@ -268,16 +251,6 @@ THREAD_STRUCT = (
}
);
-NETWORK_CONTROLLER :
-{
- FLEXRAN_ENABLED = "no";
- FLEXRAN_INTERFACE_NAME = "lo";
- FLEXRAN_IPV4_ADDRESS = "127.0.0.1";
- FLEXRAN_PORT = 2210;
- FLEXRAN_CACHE = "/mnt/oai_agent_cache";
- FLEXRAN_AWAIT_RECONF = "no";
-};
-
log_config :
{
global_log_level ="info";
diff --git a/ci-scripts/conf_files/lte-fdd-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-basic-sim.conf
index 24a2b400e6..30b4beb94b 100644
--- a/ci-scripts/conf_files/lte-fdd-basic-sim.conf
+++ b/ci-scripts/conf_files/lte-fdd-basic-sim.conf
@@ -14,7 +14,7 @@ eNBs =
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
- plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
+ plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
tr_s_preference = "local_mac"
@@ -171,7 +171,7 @@ eNBs =
////////// MME parameters:
- mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR";
+ mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
@@ -188,12 +188,13 @@ eNBs =
NETWORK_INTERFACES :
{
- ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
- ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR";
- ENB_INTERFACE_NAME_FOR_S1U = "eth0";
- ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR";
+ ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
+ ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10";
+ ENB_INTERFACE_NAME_FOR_S1U = "lo";
+ ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
- ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR";
+
+ ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.1";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
@@ -244,8 +245,8 @@ THREAD_STRUCT = (
NETWORK_CONTROLLER :
{
FLEXRAN_ENABLED = "no";
- FLEXRAN_INTERFACE_NAME = "ens3";
- FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR";
+ FLEXRAN_INTERFACE_NAME = "lo";
+ FLEXRAN_IPV4_ADDRESS = "127.0.0.1";
FLEXRAN_PORT = 2210;
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index 95360cae8f..21d51105f8 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -1044,6 +1044,12 @@ class SSHConnection():
logging.debug('Found a N3xx device --> resetting it')
self.command('cd ' + self.UESourceCodePath, '\$', 5)
# Initialize_OAI_UE_args usually start with -C and followed by the location in repository
+ # in case of NR-UE, we may have rrc_config_path (Temporary?)
+ modifiedUeOptions = str(self.Initialize_OAI_UE_args)
+ if self.air_interface == 'nr':
+ result = re.search('--rrc_config_path ', modifiedUeOptions)
+ if result is not None:
+ modifiedUeOptions = modifiedUeOptions.replace('rrc_config_path ', 'rrc_config_path ' + self.UESourceCodePath + '/')
self.command('source oaienv', '\$', 5)
self.command('cd cmake_targets/ran_build/build', '\$', 5)
if self.air_interface == 'lte':
@@ -1058,7 +1064,7 @@ class SSHConnection():
self.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5)
self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5)
self.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5)
- self.command('echo "ulimit -c unlimited && ./'+ self.air_interface +'-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
+ self.command('echo "ulimit -c unlimited && ./'+ self.air_interface +'-uesoftmodem ' + modifiedUeOptions + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
self.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
self.UELogFile = 'ue_' + self.testCase_id + '.log'
@@ -1105,6 +1111,9 @@ class SSHConnection():
if result is not None:
self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT -r *-uesoftmodem', '\$', 4)
time.sleep(3)
+ outterLoopCounter = outterLoopCounter - 1
+ if (outterLoopCounter == 0):
+ doOutterLoop = False
continue
if self.air_interface == 'nr':
fullSyncStatus = True
diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool
index 485c22902e..9d6349077f 100755
--- a/ci-scripts/oai-ci-vm-tool
+++ b/ci-scripts/oai-ci-vm-tool
@@ -182,7 +182,7 @@ function variant__v2__basic_sim {
}
function variant__v3__phy_sim {
- NB_PATTERN_FILES=12
+ NB_PATTERN_FILES=13
BUILD_OPTIONS="--phy_simulators"
VM_MEMORY=8192
VM_DISK=20
diff --git a/ci-scripts/rrc-files/rbconfig.raw b/ci-scripts/rrc-files/rbconfig.raw
new file mode 100644
index 0000000000..b03f18d121
Binary files /dev/null and b/ci-scripts/rrc-files/rbconfig.raw differ
diff --git a/ci-scripts/rrc-files/reconfig.raw b/ci-scripts/rrc-files/reconfig.raw
new file mode 100644
index 0000000000..97b41d9b6b
Binary files /dev/null and b/ci-scripts/rrc-files/reconfig.raw differ
diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index 09859133cc..502c1a5d47 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -1199,7 +1199,7 @@ function start_rf_sim_gnb {
echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
if [ $LOC_S1_CONFIGURATION -eq 0 ]
then
- echo "echo \"RFSIMULATOR=server ./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --noS1 --nokrnmod 1 --rfsim\" > ./my-nr-softmodem-run.sh " >> $1
+ echo "echo \"RFSIMULATOR=server ./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --noS1 --nokrnmod 1 --rfsim --phy-test\" > ./my-nr-softmodem-run.sh " >> $1
fi
echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1
echo "cat ./my-nr-softmodem-run.sh" >> $1
@@ -1274,7 +1274,7 @@ function start_rf_sim_nr_ue {
echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
if [ $LOC_S1_CONFIGURATION -eq 0 ]
then
- echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --numerology 1 -C ${LOC_FREQUENCY}000000 -r $LOC_PRB --nokrnmod 1 --rfsim --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1
+ echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --nokrnmod 1 --rfsim --phy-test --rrc_config_path /home/ubuntu/tmp/ci-scripts/rrc-files --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1
fi
echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1
echo "cat ./my-nr-softmodem-run.sh" >> $1
@@ -1285,7 +1285,7 @@ function start_rf_sim_nr_ue {
rm $1
local i="0"
- echo "egrep -c \"rfsimulator: Success\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1
+ echo "egrep -c \"Initial sync: pbch decoded sucessfully\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1
while [ $i -lt 10 ]
do
sleep 5
diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
index 03220ec286..f3e80c576a 100644
--- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
+++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
@@ -24,7 +24,7 @@
run-oai-gnb-nr-ue
Run-gNB-and-NR-UE
tasks
- 4
+ 2
090101 000001 090102 000002 090108 090109
@@ -33,7 +33,7 @@
Initialize_eNB
Initialize gNB USRP
- -O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
+ -O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test
NR
@@ -52,7 +52,7 @@
Initialize_OAI_UE
Initialize NR UE USRP
- -C 3510000000 --numerology 1 -r 106 --phy-test --usrp-args "addr=192.168.30.2,clock_source=external,time_source=external" --threadoffset 16
+ --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --threadoffset 16 --rrc_config_path ci-scripts/rrc-files
NR
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index d7cba6a82e..613d00e70f 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -226,6 +226,7 @@ set (FIRMWARE_VERSION "No svn information")
add_definitions("-DFIRMWARE_VERSION=\"${FIRMWARE_VERSION}\"")
add_definitions("-DPACKAGE_VERSION=\"Branch: ${GIT_BRANCH} Abrev. Hash: ${GIT_COMMIT_HASH} Date: ${GIT_COMMIT_DATE}\"")
add_definitions("-DPACKAGE_BUGREPORT=\"openair4g-devel@lists.eurecom.fr\"")
+#add_definitions("-DEMIT_ASN_DEBUG=1")
# Debug related options
@@ -311,7 +312,7 @@ set (NR_RRC_ASN1_VERSION "NR_Rel15" )
make_version(NR_RRC_VERSION 15 6 0)
set (NR_RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-15.6.0.asn1)
add_definitions(-DNR_RRC_VERSION=${NR_RRC_VERSION})
-set (NR_RRC_FULL_DIR ${asn1_generated_dir}/${NR_RRC_ASN1_VERSION})
+set (NR_RRC_FULL_DIR ${asn1_generated_dir}/RRC_${NR_RRC_ASN1_VERSION})
# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${NR_RRC_FULL_DIR}" "${NR_RRC_GRAMMAR}" "NR_" "-findirect-choice"
@@ -1180,6 +1181,8 @@ set(SCHED_NR_SRC
${OPENAIR1_DIR}/SCHED_NR/fapi_nr_l1.c
${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c
${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_gNB.c
+ ${OPENAIR1_DIR}/SCHED_NR/nr_prach_procedures.c
+ ${OPENAIR1_DIR}/SCHED_NR/phy_frame_config_nr.c
)
add_library(SCHED_NR_LIB ${SCHED_NR_SRC})
@@ -1205,7 +1208,7 @@ set(SCHED_SRC_NR_UE
${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue.c
${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c
${OPENAIR1_DIR}/SCHED_NR_UE/fapi_nr_ue_l1.c
- ${OPENAIR1_DIR}/SCHED_NR_UE/phy_frame_config_nr.c
+ ${OPENAIR1_DIR}/SCHED_NR/phy_frame_config_nr.c
${OPENAIR1_DIR}/SCHED_NR_UE/harq_nr.c
${OPENAIR1_DIR}/SCHED_NR_UE/pucch_uci_ue_nr.c
${OPENAIR1_DIR}/SCHED_NR_UE/pucch_power_control_ue_nr.c
@@ -1354,7 +1357,6 @@ set(PHY_SRC_COMMON
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_ul_ref.c
${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c
${OPENAIR1_DIR}/PHY/CODING/nr_segmentation.c
- ${OPENAIR1_DIR}/PHY/CODING/nr_compute_tbs.c
${OPENAIR1_DIR}/PHY/CODING/nr_rate_matching.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c
@@ -1467,6 +1469,11 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/INIT/lte_init_ue.c
)
+ set(PHY_NR_SRC_COMMON
+ ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach_common.c
+ ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci_tools_common.c
+ )
+
set(PHY_NR_SRC
${OPENAIR1_DIR}/PHY/INIT/nr_init.c
${OPENAIR1_DIR}/PHY/INIT/nr_parms.c
@@ -1483,6 +1490,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
+ ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
@@ -1523,6 +1531,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
+ ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach_common.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_prach.c
@@ -1581,6 +1590,7 @@ add_library(PHY ${PHY_SRC})
add_dependencies(PHY rrc_flag)
add_library(PHY_UE ${PHY_SRC_UE})
add_dependencies(PHY_UE rrc_flag)
+add_library(PHY_NR_COMMON ${PHY_NR_SRC_COMMON})
add_library(PHY_NR ${PHY_NR_SRC})
add_library(PHY_NR_UE ${PHY_NR_UE_SRC})
@@ -1680,6 +1690,7 @@ set(L2_SRC
${PDCP_DIR}/pdcp_netlink.c
# ${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_eNB.c
+ ${RRC_DIR}/rrc_eNB_endc.c
${RRC_DIR}/rrc_eNB_S1AP.c
${RRC_DIR}/rrc_eNB_M2AP.c
${RRC_DIR}/rrc_eNB_UE_context.c
@@ -1699,6 +1710,10 @@ set(L2_NR_SRC
${NR_RRC_DIR}/nr_rrc_common.c
${NR_RRC_DIR}/L2_nr_interface.c
${NR_RRC_DIR}/nr_rrc_config.c
+ ${NR_RRC_DIR}/rrc_gNB_nsa.c
+ ${NR_RRC_DIR}/rrc_gNB_internode.c
+ ${NR_RRC_DIR}/rrc_gNB_reconfig.c
+ ${NR_RRC_DIR}/rrc_gNB_UE_context.c
)
set(L2_SRC_UE
@@ -1787,6 +1802,7 @@ set (MAC_NR_SRC_UE
${NR_UE_MAC_DIR}/mac_vars.c
${NR_UE_MAC_DIR}/main_ue_nr.c
${NR_UE_MAC_DIR}/nr_ue_procedures.c
+ ${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c
)
set (ENB_APP_SRC
@@ -1847,7 +1863,7 @@ add_dependencies(L2_UE rrc_flag s1ap_flag x2_flag)
add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} )
-add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c )
+add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c)
include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE")
include_directories("${OPENAIR2_DIR}/LAYER2/NR_MAC_UE")
@@ -2488,7 +2504,7 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer)
target_link_libraries (lte-softmodem
-Wl,--start-group
- RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
+ RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
-Wl,--end-group z dl)
@@ -2529,7 +2545,7 @@ add_dependencies(ocp-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer)
target_link_libraries (ocp-softmodem
-Wl,--start-group
- RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
+ RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
-Wl,--end-group z dl)
@@ -2629,6 +2645,7 @@ add_executable(nr-softmodem
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
+ ${OPENAIR_DIR}/common/utils/nr/nr_common.c
${GTPU_need_ITTI}
${XFORMS_SOURCE_NR}
${T_SOURCE}
@@ -2638,7 +2655,7 @@ add_executable(nr-softmodem
target_link_libraries (nr-softmodem
-Wl,--start-group
- UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA
+ UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB
S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB}
@@ -2665,11 +2682,13 @@ add_executable(nr-uesoftmodem
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
+ ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
+ ${OPENAIR_DIR}/common/utils/nr/nr_common.c
${XFORMS_SOURCE_NR}
${T_SOURCE}
${UTIL_SRC}
@@ -2681,7 +2700,7 @@ target_link_libraries (nr-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
- PHY_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS L2_UE NR_L2_UE MAC_NR_COMMON S1AP_LIB S1AP_ENB
+ PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS L2_UE NR_L2_UE MAC_NR_COMMON S1AP_LIB S1AP_ENB
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl)
@@ -2737,22 +2756,29 @@ target_link_libraries (dlsim_tm4
add_executable(polartest
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c
+ ${OPENAIR_DIR}/common/utils/backtrace.c
+ ${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/common/utils/system.c
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(polartest
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE CONFIG_LIB -Wl,--end-group
+ -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE CONFIG_LIB -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} dl
)
add_executable(smallblocktest
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/smallblocktest.c
+ ${OPENAIR_DIR}/common/utils/backtrace.c
+ ${OPENAIR_DIR}/common/utils/nr/nr_common.c
+ ${OPENAIR_DIR}/common/utils/system.c
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
- )
+)
+
+
target_link_libraries(smallblocktest
- -Wl,--start-group UTIL SIMU PHY_NR CONFIG_LIB -Wl,--end-group
+ -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} dl
)
@@ -2765,7 +2791,7 @@ add_executable(ldpctest
add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
target_link_libraries(ldpctest
- -Wl,--start-group UTIL SIMU PHY_NR CONFIG_LIB -Wl,--end-group
+ -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} dl
)
@@ -2777,7 +2803,7 @@ add_executable(nr_dlschsim
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_dlschsim
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
+ -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
)
@@ -2789,35 +2815,50 @@ add_executable(nr_pbchsim
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_pbchsim
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
+ -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
)
#PUCCH ---> Prashanth
add_executable(nr_pucchsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c
+ ${OPENAIR_DIR}/common/utils/backtrace.c
+ ${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/common/utils/system.c
${UTIL_SRC}
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_pucchsim
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
+ -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
)
-#PUCCH ---> Prashanth
add_executable(nr_dlsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c
${OPENAIR_DIR}/common/utils/system.c
+ ${OPENAIR_DIR}/common/utils/nr/nr_common.c
+ ${OPENAIR_DIR}/executables/softmodem-common.c
${UTIL_SRC}
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_dlsim
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group
+ -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
)
+target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR)
+
+add_executable(nr_prachsim
+ ${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c
+ ${OPENAIR_DIR}/common/utils/system.c
+ ${OPENAIR_DIR}/common/utils/nr/nr_common.c
+ ${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c
+ ${UTIL_SRC}
+ ${T_SOURCE}
+ ${SHLIB_LOADER_SOURCES})
+target_link_libraries(nr_prachsim
+ -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl)
add_executable(nr_ulschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
@@ -2827,22 +2868,24 @@ add_executable(nr_ulschsim
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_ulschsim
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
+ -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
)
add_executable(nr_ulsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulsim.c
${OPENAIR_DIR}/common/utils/system.c
+ ${OPENAIR_DIR}/common/utils/nr/nr_common.c
+ ${OPENAIR_DIR}/executables/softmodem-common.c
${UTIL_SRC}
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_ulsim
- -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group
+ -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
)
-
+target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR)
foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim)
@@ -2858,9 +2901,10 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
${NFAPI_USER_DIR}/nfapi.c
)
target_link_libraries (${myExe}
- -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY PHY_UE PHY_RU LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group
+ -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_NR_COMMON PHY PHY_UE PHY_RU LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group
pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl
)
+
endforeach(myExe)
add_executable(test_epc_generate_scenario
@@ -2891,7 +2935,7 @@ add_executable(test_epc_play_scenario
)
target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c)
target_link_libraries (test_epc_play_scenario
- -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIB}
+ -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIB}
)
@@ -2935,9 +2979,10 @@ if (${T_TRACER})
coding FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO
SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
- PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_UE PHY_RU PHY_MEX
+ PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX
L2 L2_LTE L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR
- CN_UTILS GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU SIMU_ETH OPENAIR0_LIB)
+ CN_UTILS GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU SIMU_ETH OPENAIR0_LIB
+ ldpc_orig ldpc_optim ldpc_optim8seg ldpc)
if (TARGET ${i})
add_dependencies(${i} generate_T)
endif()
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index c4f15c3a16..b3954db1fd 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1082,32 +1082,31 @@
nr_dlsim Test cases. (Test1: 106 PRB),
(Test2: 217 PRB),
(Test3: 273 PRB),
- (Test4: 106 PRB 12 CSET-Offset),
- (Test5: 217 PRB 48 CSET-Offset),
- (Test6: 106 PRB 25 PDSCH-Offset),
- (Test7: 106 PRB 51 PDSCH-Offset),
- (Test8: 217 PRB 100 PDSCH-PRBs),
- (Test9: 217 PRB 80 PDSCH-Offset),
- (Test10: 217 PRB 100 PDSCH-PRBs 110 PDSCH-Offset),
- (Test11: 106 PRBs 50 PDSCH-PRBs MCS Index 28
+ (Test4: 106 PRB 25 PDSCH-Offset),
+ (Test5: 106 PRB 51 PDSCH-Offset),
+ (Test6: 217 PRB 100 PDSCH-PRBs),
+ (Test7: 217 PRB 80 PDSCH-Offset),
+ (Test8: 217 PRB 100 PDSCH-PRBs 110 PDSCH-Offset),
+ (Test9: 106 PRBs 50 PDSCH-PRBs MCS Index 27)
+ (Test10: 106 PRBs 50 PDSCH-PRBs MCS Index 16)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash
$OPENAIR_DIR/targets/bin/nr_dlsim.Rel15
- -n100 -R106 -b106
- -n100 -R217 -b217
- -n100 -R273 -b273
- -n100 -R106 -o12
- -n100 -R217 -o48
- -n100 -R106 -a25
- -n100 -R106 -a51
- -n100 -R217 -b100
- -n100 -R217 -a80
- -n100 -R217 -a110 -b100
- -n100 -e28
- nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11
+ -n100 -R106 -b106 -s5
+ -n100 -R217 -b217 -s5
+ -n100 -R273 -b273 -s5
+ -n100 -R106 -a25 -s5
+ -n100 -R106 -a51 -s5
+ -n100 -R217 -b100 -s5
+ -n100 -R217 -a80 -s5
+ -n100 -R217 -a110 -s5 -b100
+ -n100 -e27 -s30
+ -n100 -e16 -s10
+
+ nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10
PDSCH test OK
segmentation fault|assertion|exiting|fatal
3
@@ -1249,11 +1248,11 @@
$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash
$OPENAIR_DIR/targets/bin/nr_ulsim.Rel15
- -f100 -m9 -r106 -s10
- -f100 -m16 -s20
- -f100 -m28 -s30
- -f100 -m9 -R217 -r217 -s10
- -f100 -m9 -R273 -r273 -s10
+ -n100 -m9 -r106 -s0
+ -n100 -m16 -s10
+ -n100 -m28 -s20
+ -n100 -m9 -R217 -r217 -s0
+ -n100 -m9 -R273 -r273 -s0
nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5
PUSCH test OK
segmentation fault|assertion|exiting|fatal
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index 6f4d5608f8..965dfaea3a 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -697,7 +697,7 @@ function main() {
if [ "$SIMUS_PHY" = "1" ] ; then
echo_info "Compiling physical unitary tests simulators"
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
- simlist="dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim"
+ simlist="dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim"
for f in $simlist ; do
compilations \
phy_simulators $f \
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 6ed17649cc..818b1fd79c 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -102,8 +102,8 @@ check_supported_distribution() {
"ubuntu14.04") return 0 ;;
"fedora24") return 0 ;;
"rhel7") return 0 ;;
- "rhel7.6") return 0 ;;
- "rhel7.7") return 0 ;;
+ "rhel7.6") return 0 ;;
+ "rhel7.7") return 0 ;;
"centos7") return 0 ;;
esac
return 1
diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c
index c951905101..33d6408828 100644
--- a/common/config/config_userapi.c
+++ b/common/config/config_userapi.c
@@ -224,7 +224,6 @@ int config_get(paramdef_t *params, int numparams, char *prefix) {
}
configmodule_interface_t *cfgif = config_get_if();
-
if (cfgif != NULL) {
ret = config_get_if()->get(params, numparams, prefix);
diff --git a/common/ran_context.h b/common/ran_context.h
index abe482c742..8262f5dd55 100644
--- a/common/ran_context.h
+++ b/common/ran_context.h
@@ -85,8 +85,6 @@ typedef struct {
int nb_nr_L1_inst;
/// Number of Component Carriers per instance in this node
int *nb_L1_CC;
- /// Number of NR Component Carriers per instance in this node
- int *nb_nr_L1_CC;
/// Number of RU instances in this node
int nb_RU;
/// FlexRAN context variables
@@ -94,7 +92,7 @@ typedef struct {
/// eNB context variables
struct PHY_VARS_eNB_s ***eNB;
/// gNB context variables
- struct PHY_VARS_gNB_s ***gNB;
+ struct PHY_VARS_gNB_s **gNB;
/// NB_IoT L1 context variables
struct PHY_VARS_eNB_NB_IoT_s **L1_NB_IoT;
/// RRC context variables
diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c
index 9327b6e77a..0043eb3238 100644
--- a/common/utils/LOG/vcd_signal_dumper.c
+++ b/common/utils/LOG/vcd_signal_dumper.c
@@ -514,7 +514,8 @@ const char* eurecomFunctionsNames[] = {
/*NR softmodem signal*/
"wakeup_txfh",
"gNB_thread_rxtx0",
- "gNB_thread_rxtx1"
+ "gNB_thread_rxtx1",
+ "ru_thread_tx_wait"
};
struct vcd_module_s vcd_modules[] = {
diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h
index 9383b39b1e..20588bb828 100644
--- a/common/utils/LOG/vcd_signal_dumper.h
+++ b/common/utils/LOG/vcd_signal_dumper.h
@@ -507,6 +507,7 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH,
VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0,
VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT,
VCD_SIGNAL_DUMPER_FUNCTIONS_END
} vcd_signal_dump_functions;
diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h
index b59fae2a0c..4cb4bf2bba 100644
--- a/common/utils/T/T_defs.h
+++ b/common/utils/T/T_defs.h
@@ -73,7 +73,7 @@ typedef struct {
} T_cache_t;
/* number of VCD functions (to be kept up to date! see in T_messages.txt) */
-#define VCD_NUM_FUNCTIONS (247)
+#define VCD_NUM_FUNCTIONS (248)
/* number of VCD variables (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_VARIABLES (186)
diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt
index 387257d145..f8b746669c 100644
--- a/common/utils/T/T_messages.txt
+++ b/common/utils/T/T_messages.txt
@@ -3378,3 +3378,8 @@ ID = VCD_FUNCTION_gNB_PROC_RXTX1
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = gNB_thread_rxtx1
+ID = VCD_FUNCTION_RU_TX_WAIT
+ DESC = VCD function RU_TX_WAIT
+ GROUP = ALL:VCD:ENB:VCD_FUNCTION
+ FORMAT = int,value
+ VCD_NAME = ru_thread_tx_wait
diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c
new file mode 100644
index 0000000000..8a236c49f9
--- /dev/null
+++ b/common/utils/nr/nr_common.c
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+/* \file config_ue.c
+ * \brief common utility functions for NR (gNB and UE)
+ * \author R. Knopp,
+ * \date 2019
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include
+#include "assertions.h"
+
+int NRRIV2BW(int locationAndBandwidth,int N_RB) {
+ int tmp = locationAndBandwidth/N_RB;
+ int tmp2 = locationAndBandwidth%N_RB;
+
+
+ if (tmp <= ((N_RB>>1)+1) && (tmp+tmp2)>1)+1) && (tmp+tmp2)0 && (NPRB + RBstart <= BWPsize),"Illegal NPRB/RBstart Configuration (%d,%d) for BWPsize %d\n",NPRB,RBstart,BWPsize);
+
+ if (NPRB <= 1+(BWPsize>>1)) return(BWPsize*(NPRB-1)+RBstart);
+ else return(BWPsize*(BWPsize+1-NPRB) + (BWPsize-1-RBstart));
+}
+
+int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart) {
+ return(PRBalloc_to_locationandbandwidth0(NPRB,RBstart,275));
+}
+/// Target code rate tables indexed by Imcs
+uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \
+ 616, 658, 438, 466, 517, 567, 616, 666, 719, 772, 822, 873, 910, 948};
+ // Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
+uint16_t nr_target_code_rate_table2[28] = {120, 193, 308, 449, 602, 378, 434, 490, 553, 616, 658, 466, 517, 567, \
+ 616, 666, 719, 772, 822, 873, 1365, 711, 754, 797, 841, 885, 1833, 948};
+uint16_t nr_target_code_rate_table3[29] = {30, 40, 50, 64, 78, 99, 120, 157, 193, 251, 308, 379, 449, 526, 602, 340, \
+ 378, 434, 490, 553, 616, 438, 466, 517, 567, 616, 666, 719, 772};
+uint16_t nr_tbs_table[93] = {24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 208, 224, 240, 256, 272, 288, 304, 320, \
+ 336, 352, 368, 384, 408, 432, 456, 480, 504, 528, 552, 576, 608, 640, 672, 704, 736, 768, 808, 848, 888, 928, 984, 1032, 1064, 1128, 1160, 1192, 1224, 1256, \
+ 1288, 1320, 1352, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, 2024, 2088, 2152, 2216, 2280, 2408, 2472, 2536, 2600, 2664, 2728, 2792, 2856, 2976, \
+ 3104, 3240, 3368, 3496, 3624, 3752, 3824};
+
+uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx) {
+ switch(table_idx) {
+ case 1:
+ return (((Imcs<10)||(Imcs==29))?2:((Imcs<17)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1);
+ break;
+
+ case 2:
+ return (((Imcs<5)||(Imcs==28))?2:((Imcs<11)||(Imcs==29))?4:((Imcs<20)||(Imcs==30))?6:((Imcs<28)||(Imcs==31))?8:-1);
+ break;
+
+ case 3:
+ return (((Imcs<15)||(Imcs==29))?2:((Imcs<21)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1);
+ break;
+
+ default:
+ AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx);
+ return(0);
+ break;
+ }
+}
+
+uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) {
+ switch(table_idx) {
+ case 1:
+ return (nr_target_code_rate_table1[Imcs]);
+ break;
+
+ case 2:
+ return (nr_target_code_rate_table2[Imcs]);
+ break;
+
+ case 3:
+ return (nr_target_code_rate_table3[Imcs]);
+ break;
+
+ default:
+ AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx);
+ return(0);
+ break;
+ }
+}
+
+int get_subband_size(int NPRB,int size) {
+ // implements table 5.2.1.4-2 from 36.214
+ //
+ //Bandwidth part (PRBs) Subband size (PRBs)
+ // < 24 N/A
+ //24 – 72 4, 8
+ //73 – 144 8, 16
+ //145 – 275 16, 32
+
+ if (NPRB<24) return(1);
+ if (NPRB<72) return (size==0 ? 4 : 8);
+ if (NPRB<144) return (size==0 ? 8 : 16);
+ if (NPRB<275) return (size==0 ? 16 : 32);
+ AssertFatal(1==0,"Shouldn't get here, NPRB %d\n",NPRB);
+
+}
+
+void SLIV2SL(int SLIV,int *S,int *L) {
+
+ int SLIVdiv14 = SLIV/14;
+ int SLIVmod14 = SLIV%14;
+ // Either SLIV = 14*(L-1) + S, or SLIV = 14*(14-L+1) + (14-1-S). Condition is 0 <= L <= 14-S
+ if ((SLIVdiv14 + 1) >= 0 && (SLIVdiv14 <= 13-SLIVmod14)) {
+ *L=SLIVdiv14+1;
+ *S=SLIVmod14;
+ } else {
+ *L=15-SLIVdiv14;
+ *S=13-SLIVmod14;
+ }
+
+}
diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h
new file mode 100644
index 0000000000..979cf86343
--- /dev/null
+++ b/common/utils/nr/nr_common.h
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+/* \file config_ue.c
+ * \brief common utility functions for NR (gNB and UE)
+ * \author R. Knopp,
+ * \date 2019
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include
+#include "assertions.h"
+
+int NRRIV2BW(int locationAndBandwidth,int N_RB);
+int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
+int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize);
+int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart);
+extern uint16_t nr_target_code_rate_table1[29];
+extern uint16_t nr_target_code_rate_table2[28];
+extern uint16_t nr_target_code_rate_table3[29];
+extern uint16_t nr_tbs_table[93];
+uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx);
+uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx);
+int get_subband_size(int NPRB,int size);
+void SLIV2SL(int SLIV,int *S,int *L);
+
+
+#define CEILIDIV(a,b) ((a+b-1)/b)
+#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
+
+#define cmax(a,b) ((a>b) ? (a) : (b))
+#define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c))
+#define cmin(a,b) ((aittiMsgHeader.messageId = message_id;
temp->ittiMsgHeader.originTaskId = origin_task_id;
temp->ittiMsgHeader.ittiMsgSize = size;
+ temp->ittiMsgHeader.destinationTaskId=TASK_UNKNOWN;
+ temp->ittiMsgHeader.instance=0;
+ temp->ittiMsgHeader.lte_time={0};
return temp;
//return itti_alloc_new_message_sized(origin_task_id, message_id, messages_info[message_id].size);
}
diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h
index 349d1add44..265a57ca63 100644
--- a/common/utils/ocp_itti/intertask_interface.h
+++ b/common/utils/ocp_itti/intertask_interface.h
@@ -275,7 +275,7 @@ typedef struct {
//TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL)
//TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)
//TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL)
-
+void * rrc_enb_process_msg(void*);
#define FOREACH_TASK(TASK_DEF) \
TASK_DEF(TASK_UNKNOWN, TASK_PRIORITY_MED, 50, NULL, NULL) \
TASK_DEF(TASK_TIMER, TASK_PRIORITY_MED, 10, NULL, NULL) \
@@ -288,7 +288,7 @@ typedef struct {
TASK_DEF(TASK_PDCP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_DATA_FORWARDING, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_END_MARKER, TASK_PRIORITY_MED, 200, NULL, NULL) \
- TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, rrc_enb_process_itti_msg,NULL)\
+ TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, rrc_enb_process_msg,NULL)\
TASK_DEF(TASK_RRC_GNB, TASK_PRIORITY_MED, 200, NULL,NULL)\
TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200, NULL, NULL) \
diff --git a/executables/main-ocp.c b/executables/main-ocp.c
index a68ee290d0..4d16b92464 100644
--- a/executables/main-ocp.c
+++ b/executables/main-ocp.c
@@ -53,7 +53,7 @@ volatile int oai_exit = 0;
double cpuf;
uint16_t sf_ahead=4;
int otg_enabled;
-uint32_t downlink_frequency[MAX_NUM_CCs][4];
+uint64_t downlink_frequency[MAX_NUM_CCs][4];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
int split73;
char * split73_config;
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index d8f119061e..660a2d3655 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -101,8 +101,8 @@ extern openair0_config_t openair0_cfg[MAX_CARDS];
extern int transmission_mode;
-uint16_t sl_ahead=6;
-uint16_t sf_ahead=6;
+extern uint16_t sf_ahead;
+extern uint16_t sl_ahead;
//pthread_t main_gNB_thread;
time_stats_t softmodem_stats_mt; // main thread
@@ -144,10 +144,14 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) {
+
+ sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe;
+ nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
+
start_meas(&softmodem_stats_rxtx_sf);
// *******************************************************************
-
+ // NFAPI not yet supported for NR - this code has to be revised
if (nfapi_mode == 1) {
// I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
//add_subframe(&frame, &subframe, 4);
@@ -173,19 +177,17 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
frame_tx, slot_tx);
}
}
-
- /// NR disabling
// ****************************************
- // Common RX procedures subframe n
- T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
- /*
- // if this is IF5 or 3GPP_gNB
- if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
- wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
- }
- // UE-specific RX processing for subframe n
- if (nfapi_mode == 0 || nfapi_mode == 1) */
+ T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
+
+ /*
+ // if this is IF5 or 3GPP_gNB
+ if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
+ wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
+ }
+ */
+ // Call the scheduler
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.frame = frame_rx;
@@ -194,22 +196,30 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
gNB->UL_INFO.CC_id = gNB->CC_id;
gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
+
+ // RX processing
+ int tx_slot_type = nr_slot_select(cfg,frame_tx,slot_tx);
+ int rx_slot_type = nr_slot_select(cfg,frame_rx,slot_rx);
- /// end
- // *****************************************
- // TX processing for subframe n+sl_ahead
- // run PHY TX procedures the one after the other for all CCs to avoid race conditions
- // (may be relaxed in the future for performance reasons)
- // *****************************************
- //if (wait_CCs(proc)<0) return(-1);
+ if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) {
+ // UE-specific RX processing for subframe n
+ // TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT
+ phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
+ }
if (oai_exit) return(-1);
- //if (slot_rx == NR_UPLINK_SLOT || gNB->frame_parms.frame_type == FDD)
- phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
+ // *****************************************
+ // TX processing for subframe n+sf_ahead
+ // run PHY TX procedures the one after the other for all CCs to avoid race conditions
+ // (may be relaxed in the future for performance reasons)
+ // *****************************************
+
+ if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
- if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) {
- phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
+ if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) {
+ phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
+ }
}
stop_meas( &softmodem_stats_rxtx_sf );
@@ -388,14 +398,15 @@ void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct
RU_proc_t *ru_proc=&ru->proc;
proc->frame_rx = frame_rx;
proc->slot_rx = slot_rx;
+ sl_ahead = sf_ahead*fp->slots_per_subframe;
if (!oai_exit) {
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->slot_rx));
- L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot);
+ L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe);
L1_proc->frame_rx = ru_proc->frame_rx;
L1_proc->slot_rx = ru_proc->tti_rx;
- L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
- L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame;
+ L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
+ L1_proc->slot_tx = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame;
if (rxtx(gNB,L1_proc->frame_rx,L1_proc->slot_rx,L1_proc->frame_tx,L1_proc->slot_tx,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id);
@@ -558,7 +569,7 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
abstime.tv_sec += 1;
}
- // wake up TX for subframe n+sl_ahead
+ // wake up TX for subframe n+sf_ahead
// lock the TX mutex and make sure the thread is ready
AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
@@ -572,17 +583,17 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
// We have just received and processed the common part of a subframe, say n.
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
// transmitted timestamp of the next TX slot (first).
- // The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
- // we want to generate subframe (n+sl_ahead), so TS_tx = TX_rx+sl_ahead*samples_per_tti,
- // and proc->slot_tx = proc->slot_rx+sl_ahead
- // and proc->slot_tx = proc->slot_rx+sl_ahead
- L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sl_ahead*fp->samples_per_slot);
+
+ // The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
+ // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti,
+ // and proc->slot_tx = proc->slot_rx+sf_ahead
+ L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe);
L1_proc->frame_rx = ru_proc->frame_rx;
L1_proc->slot_rx = ru_proc->tti_rx;
- L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-sl_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
- L1_proc->slot_tx = (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame;
+ L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
+ L1_proc->slot_tx = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame;
- LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sl_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sl_ahead);
+ LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sf_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sf_ahead);
pthread_mutex_unlock( &L1_proc->mutex );
@@ -719,64 +730,62 @@ static void *process_stats_thread(void *param) {
void init_gNB_proc(int inst) {
int i=0;
- int CC_id;
+ int CC_id = 0;
PHY_VARS_gNB *gNB;
gNB_L1_proc_t *proc;
gNB_L1_rxtx_proc_t *L1_proc,*L1_proc_tx;
- LOG_I(PHY,"%s(inst:%d) RC.nb_nr_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_nr_CC[inst]);
-
- for (CC_id=0; CC_idproc;
- L1_proc = &proc->L1_proc;
- L1_proc_tx = &proc->L1_proc_tx;
- L1_proc->instance_cnt = -1;
- L1_proc_tx->instance_cnt = -1;
- L1_proc->instance_cnt_RUs = 0;
- L1_proc_tx->instance_cnt_RUs = 0;
- proc->instance_cnt_prach = -1;
- proc->instance_cnt_asynch_rxtx = -1;
- proc->CC_id = CC_id;
- proc->first_rx =1;
- proc->first_tx =1;
- proc->RU_mask =0;
- proc->RU_mask_tx = (1<num_RU)-1;
- proc->RU_mask_prach =0;
- pthread_mutex_init( &gNB->UL_INFO_mutex, NULL);
- pthread_mutex_init( &L1_proc->mutex, NULL);
- pthread_mutex_init( &L1_proc_tx->mutex, NULL);
- pthread_cond_init( &L1_proc->cond, NULL);
- pthread_cond_init( &L1_proc_tx->cond, NULL);
- pthread_mutex_init( &proc->mutex_prach, NULL);
- pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
- pthread_mutex_init( &proc->mutex_RU,NULL);
- pthread_mutex_init( &proc->mutex_RU_tx,NULL);
- pthread_mutex_init( &proc->mutex_RU_PRACH,NULL);
- pthread_cond_init( &proc->cond_prach, NULL);
- pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
- LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag);
-
- if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
- threadCreate( &L1_proc->pthread, gNB_L1_thread, gNB, "L1_proc", -1, OAI_PRIORITY_RT );
- threadCreate( &L1_proc_tx->pthread, gNB_L1_thread_tx, gNB,"L1_proc_tx", -1, OAI_PRIORITY_RT);
- }
-
- if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW);
- //pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB );
- char name[16];
-
- if (gNB->single_thread_flag==0) {
- snprintf( name, sizeof(name), "L1 %d", i );
- pthread_setname_np( L1_proc->pthread, name );
- snprintf( name, sizeof(name), "L1TX %d", i );
- pthread_setname_np( L1_proc_tx->pthread, name );
- }
-
- AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach);
+
+ proc = &gNB->proc;
+ L1_proc = &proc->L1_proc;
+ L1_proc_tx = &proc->L1_proc_tx;
+ L1_proc->instance_cnt = -1;
+ L1_proc_tx->instance_cnt = -1;
+ L1_proc->instance_cnt_RUs = 0;
+ L1_proc_tx->instance_cnt_RUs = 0;
+ proc->instance_cnt_prach = -1;
+ proc->instance_cnt_asynch_rxtx = -1;
+ proc->CC_id = CC_id;
+ proc->first_rx =1;
+ proc->first_tx =1;
+ proc->RU_mask =0;
+ proc->RU_mask_tx = (1<num_RU)-1;
+ proc->RU_mask_prach =0;
+ pthread_mutex_init( &gNB->UL_INFO_mutex, NULL);
+ pthread_mutex_init( &L1_proc->mutex, NULL);
+ pthread_mutex_init( &L1_proc_tx->mutex, NULL);
+ pthread_cond_init( &L1_proc->cond, NULL);
+ pthread_cond_init( &L1_proc_tx->cond, NULL);
+ pthread_mutex_init( &proc->mutex_prach, NULL);
+ pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
+ pthread_mutex_init( &proc->mutex_RU,NULL);
+ pthread_mutex_init( &proc->mutex_RU_tx,NULL);
+ pthread_mutex_init( &proc->mutex_RU_PRACH,NULL);
+ pthread_cond_init( &proc->cond_prach, NULL);
+ pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
+ LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag);
+
+ if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
+ threadCreate( &L1_proc->pthread, gNB_L1_thread, gNB, "L1_proc", -1, OAI_PRIORITY_RT );
+ threadCreate( &L1_proc_tx->pthread, gNB_L1_thread_tx, gNB,"L1_proc_tx", -1, OAI_PRIORITY_RT);
}
+
+ if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW);
+ //pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB );
+ char name[16];
+
+ if (gNB->single_thread_flag==0) {
+ snprintf( name, sizeof(name), "L1 %d", i );
+ pthread_setname_np( L1_proc->pthread, name );
+ snprintf( name, sizeof(name), "L1TX %d", i );
+ pthread_setname_np( L1_proc_tx->pthread, name );
+ }
+
+ AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach);
/* setup PHY proc TX sync mechanism */
pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
@@ -795,52 +804,51 @@ void kill_gNB_proc(int inst) {
gNB_L1_proc_t *proc;
gNB_L1_rxtx_proc_t *L1_proc, *L1_proc_tx;
- for (int CC_id=0; CC_idproc;
- L1_proc = &proc->L1_proc;
- L1_proc_tx = &proc->L1_proc_tx;
- LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst );
-
- if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
- pthread_mutex_lock(&L1_proc->mutex);
- L1_proc->instance_cnt = 0;
- pthread_cond_signal(&L1_proc->cond);
- pthread_mutex_unlock(&L1_proc->mutex);
- pthread_mutex_lock(&L1_proc_tx->mutex);
- L1_proc_tx->instance_cnt = 0;
- pthread_cond_signal(&L1_proc_tx->cond);
- pthread_mutex_unlock(&L1_proc_tx->mutex);
- }
-
- proc->instance_cnt_prach = 0;
- pthread_cond_signal( &proc->cond_prach );
- pthread_cond_signal( &proc->cond_asynch_rxtx );
- pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
- // LOG_D(PHY, "joining pthread_prach\n");
- // pthread_join( proc->pthread_prach, (void**)&status );
- LOG_I(PHY, "Destroying prach mutex/cond\n");
- pthread_mutex_destroy( &proc->mutex_prach );
- pthread_cond_destroy( &proc->cond_prach );
- LOG_I(PHY, "Destroying UL_INFO mutex\n");
- pthread_mutex_destroy(&gNB->UL_INFO_mutex);
-
- if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
- LOG_I(PHY, "Joining L1_proc mutex/cond\n");
- pthread_join( L1_proc->pthread, (void **)&status );
- LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n");
- pthread_join( L1_proc_tx->pthread, (void **)&status );
- }
-
- LOG_I(PHY, "Destroying L1_proc mutex/cond\n");
- pthread_mutex_destroy( &L1_proc->mutex );
- pthread_cond_destroy( &L1_proc->cond );
- LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n");
- pthread_mutex_destroy( &L1_proc_tx->mutex );
- pthread_cond_destroy( &L1_proc_tx->cond );
- pthread_mutex_destroy( &proc->mutex_RU );
- pthread_mutex_destroy( &proc->mutex_RU_tx );
+ gNB=RC.gNB[inst];
+ proc = &gNB->proc;
+ L1_proc = &proc->L1_proc;
+ L1_proc_tx = &proc->L1_proc_tx;
+ LOG_I(PHY, "Killing TX inst %d\n",inst );
+
+ if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
+ pthread_mutex_lock(&L1_proc->mutex);
+ L1_proc->instance_cnt = 0;
+ pthread_cond_signal(&L1_proc->cond);
+ pthread_mutex_unlock(&L1_proc->mutex);
+ pthread_mutex_lock(&L1_proc_tx->mutex);
+ L1_proc_tx->instance_cnt = 0;
+ pthread_cond_signal(&L1_proc_tx->cond);
+ pthread_mutex_unlock(&L1_proc_tx->mutex);
}
+
+ proc->instance_cnt_prach = 0;
+ pthread_cond_signal( &proc->cond_prach );
+ pthread_cond_signal( &proc->cond_asynch_rxtx );
+ pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
+ // LOG_D(PHY, "joining pthread_prach\n");
+ // pthread_join( proc->pthread_prach, (void**)&status );
+ LOG_I(PHY, "Destroying prach mutex/cond\n");
+ pthread_mutex_destroy( &proc->mutex_prach );
+ pthread_cond_destroy( &proc->cond_prach );
+ LOG_I(PHY, "Destroying UL_INFO mutex\n");
+ pthread_mutex_destroy(&gNB->UL_INFO_mutex);
+
+ if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
+ LOG_I(PHY, "Joining L1_proc mutex/cond\n");
+ pthread_join( L1_proc->pthread, (void **)&status );
+ LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n");
+ pthread_join( L1_proc_tx->pthread, (void **)&status );
+ }
+
+ LOG_I(PHY, "Destroying L1_proc mutex/cond\n");
+ pthread_mutex_destroy( &L1_proc->mutex );
+ pthread_cond_destroy( &L1_proc->cond );
+ LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n");
+ pthread_mutex_destroy( &L1_proc_tx->mutex );
+ pthread_cond_destroy( &L1_proc_tx->cond );
+ pthread_mutex_destroy( &proc->mutex_RU );
+ pthread_mutex_destroy( &proc->mutex_RU_tx );
+
}
@@ -872,48 +880,41 @@ void print_opp_meas(void) {
/// eNB kept in function name for nffapi calls, TO FIX
void init_eNB_afterRU(void) {
- int inst,CC_id,ru_id,i,aa;
+ int inst,ru_id,i,aa;
PHY_VARS_gNB *gNB;
LOG_I(PHY,"%s() RC.nb_nr_inst:%d\n", __FUNCTION__, RC.nb_nr_inst);
for (inst=0; instnum_RU>0,"Number of RU attached to gNB %d is zero\n",gNB->Mod_id);
- // map antennas and PRACH signals to gNB RX
- if (0) AssertFatal(gNB->num_RU>0,"Number of RU attached to gNB %d is zero\n",gNB->Mod_id);
+ LOG_I(PHY,"Mapping RX ports from %d RUs to gNB %d\n",gNB->num_RU,gNB->Mod_id);
+ LOG_I(PHY,"gNB->num_RU:%d\n", gNB->num_RU);
- LOG_I(PHY,"Mapping RX ports from %d RUs to gNB %d\n",gNB->num_RU,gNB->Mod_id);
- //LOG_I(PHY,"Overwriting gNB->prach_vars.rxsigF[0]:%p\n", gNB->prach_vars.rxsigF[0]);
- // gNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *));
- LOG_I(PHY,"gNB->num_RU:%d\n", gNB->num_RU);
-
- for (ru_id=0,aa=0; ru_idnum_RU; ru_id++) {
- AssertFatal(gNB->RU_list[ru_id]->common.rxdataF!=NULL,
- "RU %d : common.rxdataF is NULL\n",
- gNB->RU_list[ru_id]->idx);
- AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF!=NULL,
- "RU %d : prach_rxsigF is NULL\n",
- gNB->RU_list[ru_id]->idx);
-
- for (i=0; iRU_list[ru_id]->nb_rx; aa++,i++) {
- LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa);
- // gNB->prach_vars.rxsigF[0][aa] = gNB->RU_list[ru_id]->prach_rxsigF[i];
- gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i];
- }
+ for (ru_id=0,aa=0; ru_idnum_RU; ru_id++) {
+ AssertFatal(gNB->RU_list[ru_id]->common.rxdataF!=NULL,
+ "RU %d : common.rxdataF is NULL\n",
+ gNB->RU_list[ru_id]->idx);
+ AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF!=NULL,
+ "RU %d : prach_rxsigF is NULL\n",
+ gNB->RU_list[ru_id]->idx);
+
+ for (i=0; iRU_list[ru_id]->nb_rx; aa++,i++) {
+ LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa);
+ gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[i];
+ gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i];
}
-
- /* TODO: review this code, there is something wrong.
- * In monolithic mode, we come here with nb_antennas_rx == 0
- * (not tested in other modes).
- */
- //init_precoding_weights(RC.gNB[inst][CC_id]);
}
+ /* TODO: review this code, there is something wrong.
+ * In monolithic mode, we come here with nb_antennas_rx == 0
+ * (not tested in other modes).
+ */
+ //init_precoding_weights(RC.gNB[inst]);
init_gNB_proc(inst);
}
@@ -926,51 +927,52 @@ void init_eNB_afterRU(void) {
}
void init_gNB(int single_thread_flag,int wait_for_sync) {
- int CC_id;
+
int inst;
PHY_VARS_gNB *gNB;
- LOG_I(PHY,"[nr-softmodem.c] gNB structure about to be allocated RC.nb_nr_L1_inst:%d RC.nb_nr_L1_CC[0]:%d\n",RC.nb_nr_L1_inst,RC.nb_nr_L1_CC[0]);
- if (RC.gNB == NULL) RC.gNB = (PHY_VARS_gNB ***) malloc(RC.nb_nr_L1_inst*sizeof(PHY_VARS_gNB **));
-
- LOG_I(PHY,"[lte-softmodem.c] gNB structure RC.gNB allocated\n");
-
- for (inst=0; instabstraction_flag = 0;
- gNB->single_thread_flag = single_thread_flag;
- /*nr_polar_init(&gNB->nrPolar_params,
- NR_POLAR_PBCH_MESSAGE_TYPE,
- NR_POLAR_PBCH_PAYLOAD_BITS,
- NR_POLAR_PBCH_AGGREGATION_LEVEL);*/
- LOG_I(PHY,"Initializing gNB %d CC_id %d single_thread_flag:%d\n",inst,CC_id,single_thread_flag);
-#ifndef OCP_FRAMEWORK
- LOG_I(PHY,"Initializing gNB %d CC_id %d\n",inst,CC_id);
-#endif
- LOG_I(PHY,"Registering with MAC interface module\n");
- AssertFatal((gNB->if_inst = NR_IF_Module_init(inst))!=NULL,"Cannot register interface");
- gNB->if_inst->NR_Schedule_response = nr_schedule_response;
- gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
- memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
- memset((void *)&gNB->UL_tti_req,0,sizeof(nfapi_nr_ul_tti_request_t));
- //memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO));
- LOG_I(PHY,"Setting indication lists\n");
- gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list;
- gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list;
- gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list;
- gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list;
- gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list;
- gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;
-
- gNB->prach_energy_counter = 0;
+ if (RC.gNB == NULL) {
+ RC.gNB = (PHY_VARS_gNB **) malloc((1+RC.nb_nr_L1_inst)*sizeof(PHY_VARS_gNB *));
+ for (inst=0; instabstraction_flag = 0;
+ gNB->single_thread_flag = single_thread_flag;
+ /*nr_polar_init(&gNB->nrPolar_params,
+ NR_POLAR_PBCH_MESSAGE_TYPE,
+ NR_POLAR_PBCH_PAYLOAD_BITS,
+ NR_POLAR_PBCH_AGGREGATION_LEVEL);*/
+ LOG_I(PHY,"Initializing gNB %d single_thread_flag:%d\n",inst,gNB->single_thread_flag);
+#ifndef OCP_FRAMEWORK
+ LOG_I(PHY,"Initializing gNB %d\n",inst);
+#endif
+
+ LOG_I(PHY,"Registering with MAC interface module (before %p)\n",gNB->if_inst);
+ AssertFatal((gNB->if_inst = NR_IF_Module_init(inst))!=NULL,"Cannot register interface");
+ LOG_I(PHY,"Registering with MAC interface module (after %p)\n",gNB->if_inst);
+ gNB->if_inst->NR_Schedule_response = nr_schedule_response;
+ gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
+ memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
+ LOG_I(PHY,"Setting indication lists\n");
+ gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list;
+ gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list;
+ gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list;
+ gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list;
+ gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list;
+ gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;
+ gNB->prach_energy_counter = 0;
+ }
+
+
LOG_I(PHY,"[nr-softmodem.c] gNB structure allocated\n");
}
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index 05ae216d00..30ed266ce4 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -50,6 +50,7 @@
#include
#include
#include
+#include
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
@@ -130,7 +131,8 @@ void configure_rru(int idx, void *arg);
int attach_rru(RU_t *ru);
int connect_rau(RU_t *ru);
-extern uint16_t sl_ahead;
+uint16_t sf_ahead;
+uint16_t sl_ahead;
extern int emulate_rf;
extern int numerology;
@@ -296,29 +298,24 @@ int connect_rau(RU_t *ru)
/* Southbound Fronthaul functions, RCC/RAU */
// southbound IF5 fronthaul for 16-bit OAI format
-static inline void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
+void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
{
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
send_IF5(ru, timestamp, slot, &ru->seqno, IF5_RRH_GW_DL);
}
-// southbound IF5 fronthaul for Mobipass packet format
-static inline void fh_if5_mobipass_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
-{
- if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
-
- send_IF5(ru, timestamp, slot, &ru->seqno, IF5_MOBIPASS);
-}
-
// southbound IF4p5 fronthaul
-static inline void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
+void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
{
+ nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx);
- if (nr_slot_select(&ru->gNB_list[0]->gNB_config,ru->proc.tti_tx,frame)!=SF_UL) send_IF4p5(ru,frame, slot, IF4p5_PDLFFT);
+
+ if ((nr_slot_select(cfg,ru->proc.frame_tx,ru->proc.tti_tx)&NR_DOWNLINK_SLOT) > 0)
+ send_IF4p5(ru,frame, slot, IF4p5_PDLFFT);
}
/*************************************************************/
@@ -332,8 +329,9 @@ void fh_if5_south_in(RU_t *ru,
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
RU_proc_t *proc = &ru->proc;
recv_IF5(ru, &proc->timestamp_rx, *tti, IF5_RRH_GW_UL);
- proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_slot*20))&1023;
- proc->tti_rx = (proc->timestamp_rx / fp->samples_per_slot)%20;
+ proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023;
+ uint32_t idx_sf = proc->timestamp_rx / fp->samples_per_subframe;
+ proc->tti_rx = (idx_sf * fp->slots_per_subframe + (int)round((float)(proc->timestamp_rx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame);
if (proc->first_rx == 0) {
if (proc->tti_rx != *tti) {
@@ -391,12 +389,12 @@ void fh_if4p5_south_in(RU_t *ru,
} while(proc->symbol_mask[sl] != symbol_mask_full);
//caculate timestamp_rx, timestamp_tx based on frame and subframe
- proc->tti_rx = sl;
- proc->frame_rx = f;
- proc->timestamp_rx = ((proc->frame_rx * fp->slots_per_frame) + proc->tti_rx ) * fp->samples_per_slot ;
+ proc->tti_rx = sl;
+ proc->frame_rx = f;
+ proc->timestamp_rx = (proc->frame_rx * fp->samples_per_subframe * 10) + fp->get_samples_slot_timestamp(proc->tti_rx, fp, 0);
// proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_subframe);
- proc->tti_tx = (sl+sl_ahead)%fp->slots_per_frame;
- proc->frame_tx = (sl>(fp->slots_per_frame-sl_ahead)) ? (f+1)&1023 : f;
+ proc->tti_tx = (sl+(fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame;
+ proc->frame_tx = (sl>(fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (f+1)&1023 : f;
if (proc->first_rx == 0) {
if (proc->tti_rx != *slot) {
@@ -503,8 +501,9 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
openair0_timestamp timestamp_tx;
recv_IF5(ru, ×tamp_tx, *slot, IF5_RRH_GW_DL);
// printf("Received subframe %d (TS %llu) from RCC\n",tti_tx,timestamp_tx);
- tti_tx = (timestamp_tx/fp->samples_per_slot)%fp->slots_per_frame;
- frame_tx = (timestamp_tx/(fp->samples_per_slot*fp->slots_per_frame))&1023;
+ frame_tx = (timestamp_tx / (fp->samples_per_subframe*10))&1023;
+ uint32_t idx_sf = timestamp_tx / fp->samples_per_subframe;
+ tti_tx = (idx_sf * fp->slots_per_subframe + (int)round((float)(timestamp_tx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame);
if (proc->first_tx != 0) {
*slot = tti_tx;
@@ -520,7 +519,7 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
- nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
RU_proc_t *proc = &ru->proc;
uint16_t packet_type;
uint32_t symbol_number,symbol_mask,symbol_mask_full=0;
@@ -533,10 +532,10 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
do {
recv_IF4p5(ru, &frame_tx, &slot_tx, &packet_type, &symbol_number);
- if ((nr_slot_select(cfg,slot_tx,frame_tx) == SF_DL) && (symbol_number == 0)) start_meas(&ru->rx_fhaul);
+ if (((nr_slot_select(cfg,frame_tx,slot_tx) & NR_DOWNLINK_SLOT) > 0) && (symbol_number == 0)) start_meas(&ru->rx_fhaul);
- LOG_D(PHY,"subframe %d (%d): frame %d, subframe %d, symbol %d\n",
- *slot,nr_slot_select(cfg,*slot,*frame),frame_tx,slot_tx,symbol_number);
+ LOG_D(PHY,"slot %d (%d): frame %d, slot %d, symbol %d\n",
+ *slot,nr_slot_select(cfg,frame_tx,*slot),frame_tx,slot_tx,symbol_number);
if (proc->first_tx != 0) {
*frame = frame_tx;
@@ -555,14 +554,14 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
} else AssertFatal(1==0,"Illegal IF4p5 packet type (should only be IF4p5_PDLFFT%d\n",packet_type);
} while (symbol_mask != symbol_mask_full);
- if (nr_slot_select(cfg,slot_tx,frame_tx) == SF_DL) stop_meas(&ru->rx_fhaul);
+ if ((nr_slot_select(cfg,frame_tx,slot_tx) & NR_DOWNLINK_SLOT)>0) stop_meas(&ru->rx_fhaul);
- proc->tti_tx = slot_tx;
- proc->frame_tx = frame_tx;
+ proc->tti_tx = slot_tx;
+ proc->frame_tx = frame_tx;
if ((frame_tx == 0)&&(slot_tx == 0)) proc->frame_tx_unwrap += 1024;
- proc->timestamp_tx = ((((uint64_t)frame_tx + (uint64_t)proc->frame_tx_unwrap) * fp->slots_per_frame) + (uint64_t)slot_tx) * (uint64_t)fp->samples_per_slot;
+ proc->timestamp_tx = (((uint64_t)frame_tx + (uint64_t)proc->frame_tx_unwrap) * fp->samples_per_subframe * 10) + fp->get_samples_slot_timestamp(slot_tx, fp, 0);
LOG_D(PHY,"RU %d/%d TST %llu, frame %d, subframe %d\n",ru->idx,0,(long long unsigned int)proc->timestamp_tx,frame_tx,slot_tx);
// dump VCD output for first RU in list
@@ -604,7 +603,7 @@ void fh_if4p5_north_out(RU_t *ru) {
stop_meas(&ru->tx_fhaul);
}
-static void *emulatedRF_thread(void *param) {
+void *emulatedRF_thread(void *param) {
RU_proc_t *proc = (RU_proc_t *) param;
int microsec = 500; // length of time to sleep, in miliseconds
struct timespec req = {0};
@@ -629,26 +628,27 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
void *rxp[ru->nb_rx];
unsigned int rxs;
int i;
+ uint32_t samples_per_slot = fp->get_samples_per_slot(*slot,fp);
openair0_timestamp ts,old_ts;
AssertFatal(*slotslots_per_frame && *slot>=0, "slot %d is illegal (%d)\n",*slot,fp->slots_per_frame);
for (i=0; inb_rx; i++)
- rxp[i] = (void *)&ru->common.rxdata[i][*slot*fp->samples_per_slot];
+ rxp[i] = (void *)&ru->common.rxdata[i][fp->get_samples_slot_timestamp(*slot,fp,0)];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
old_ts = proc->timestamp_rx;
- LOG_D(PHY,"Reading %d samples for slot %d (%p)\n",fp->samples_per_slot,*slot,rxp[0]);
+ LOG_D(PHY,"Reading %d samples for slot %d (%p)\n",samples_per_slot,*slot,rxp[0]);
if(emulate_rf) {
wait_on_condition(&proc->mutex_emulateRF,&proc->cond_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
release_thread(&proc->mutex_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
- rxs = fp->samples_per_slot;
+ rxs = samples_per_slot;
ts = old_ts + rxs;
} else {
rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
&ts,
rxp,
- fp->samples_per_slot,
+ samples_per_slot,
ru->nb_rx);
}
@@ -658,21 +658,22 @@ 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 != fp->samples_per_slot) LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",fp->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) {
ru->ts_offset = proc->timestamp_rx;
proc->timestamp_rx = 0;
} else {
- if (proc->timestamp_rx - old_ts != fp->samples_per_slot) {
- LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_slot,ru->ts_offset);
- ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_slot);
+ if (proc->timestamp_rx - old_ts != fp->get_samples_per_slot((*slot-1)%fp->slots_per_frame,fp)) {
+ LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - samples_per_slot,ru->ts_offset);
+ ru->ts_offset += (proc->timestamp_rx - old_ts - samples_per_slot);
proc->timestamp_rx = ts-ru->ts_offset;
}
}
- proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_slot*fp->slots_per_frame))&1023;
- proc->tti_rx = (proc->timestamp_rx / fp->samples_per_slot)%fp->slots_per_frame;
+ proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023;
+ uint32_t idx_sf = proc->timestamp_rx / fp->samples_per_subframe;
+ proc->tti_rx = (idx_sf * fp->slots_per_subframe + (int)round((float)(proc->timestamp_rx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame);
// synchronize first reception to frame 0 subframe 0
LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n",
ru->idx,
@@ -688,7 +689,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
if (proc->first_rx == 0) {
if (proc->tti_rx != *slot) {
- LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d)\n",(long long unsigned int)proc->timestamp_rx,proc->tti_rx,*slot);
+ LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->tti_rx %d, slot %d)\n",(long long unsigned int)proc->timestamp_rx,proc->tti_rx,*slot);
exit_fun("Exiting");
}
@@ -705,7 +706,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
//printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",ru->timestamp_rx,proc->frame_rx,frame,proc->tti_rx,subframe);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
- if (rxs != fp->samples_per_slot) {
+ if (rxs != samples_per_slot) {
//exit_fun( "problem receiving samples" );
LOG_E(PHY, "problem receiving samples\n");
}
@@ -715,69 +716,83 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
RU_proc_t *proc = &ru->proc;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
- //nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
void *txp[ru->nb_tx];
unsigned int txs;
- int i;
+ int i,txsymb;
T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot),
- T_INT(0), T_BUFFER(&ru->common.txdata[0][slot * fp->samples_per_slot], fp->samples_per_slot * 4));
- int sf_extension = 0;
- //nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame,frame);
+ T_INT(0), T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot,fp,0)], fp->samples_per_subframe * 4));
- if ((slot == 0) ||
- (slot == 1) || IS_SOFTMODEM_RFSIM ) {
- int siglen=fp->samples_per_slot;
- int flags;
- if (slot==0)
- flags = 2;
- else if (slot==1)
- flags=3;
- else
- flags=4;
+ int slot_type = nr_slot_select(cfg,frame,slot%fp->slots_per_frame);
+ int prevslot_type = nr_slot_select(cfg,frame,(slot+(fp->slots_per_frame-1))%fp->slots_per_frame);
+ int nextslot_type = nr_slot_select(cfg,frame,(slot+1)%fp->slots_per_frame);
+ int sf_extension = 0; //sf_extension = ru->sf_extension;
+ int siglen=fp->get_samples_per_slot(slot,fp);
+ int flags=1;
- /*
- if (SF_type == SF_S) {
- siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0);
- flags=3; // end of burst
- }
- if ((fp->frame_type == TDD) &&
- (SF_type == SF_DL)&&
- (prevSF_type == SF_UL) &&
- (nextSF_type == SF_DL)) {
- flags = 2; // start of burst
- sf_extension = ru->N_TA_offset<<1;
- }
+ //nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame);
+ if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT || IS_SOFTMODEM_RFSIM) {
- if ((cfg->subframe_config.duplex_mode == TDD) &&
- (SF_type == SF_DL)&&
- (prevSF_type == SF_UL) &&
- (nextSF_type == SF_UL)) {
- flags = 4; // start of burst and end of burst (only one DL SF between two UL)
- sf_extension = ru->N_TA_offset<<1;
- } */
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame );
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot );
-
- for (i=0; inb_tx; i++) {
- txp[i] = (void *)&ru->common.txdata[i][(slot*fp->samples_per_slot)-sf_extension];
+ if(slot_type == NR_MIXED_SLOT) {
+ txsymb = 0;
+ for(int symbol_count =0;symbol_counttdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0)
+ txsymb++;
+ }
+ AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb);
+ if(slot%(fp->slots_per_subframe/2))
+ siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
+ else
+ siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
+ //+ ru->end_of_burst_delay;
+ flags=3; // end of burst
}
+ if (cfg->cell_config.frame_duplex_type.value == TDD &&
+ slot_type == NR_DOWNLINK_SLOT &&
+ prevslot_type == NR_UPLINK_SLOT) {
+ flags = 2; // start of burst
+ }
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
- // prepare tx buffer pointers
- start_meas(&ru->tx_fhaul);
- txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
- timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
- txp,
- siglen+sf_extension,
- ru->nb_tx,
- flags);
- stop_meas(&ru->tx_fhaul);
- LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx,
- (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
- AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %u/%d)\n", txs, siglen);
+ if (cfg->cell_config.frame_duplex_type.value == TDD &&
+ slot_type == NR_DOWNLINK_SLOT &&
+ nextslot_type == NR_UPLINK_SLOT) {
+ flags = 3; // end of burst
+ }
+
+ if (fp->freq_range==nr_FR2) {
+ // the beam index is written in bits 8-10 of the flags
+ // bit 11 enables the gpio programming
+ int beam=0;
+ if (slot==0) beam = 11; //3 for boresight & 8 to enable
+ /*
+ if (slot==0 || slot==40) beam=0&8;
+ if (slot==10 || slot==50) beam=1&8;
+ if (slot==20 || slot==60) beam=2&8;
+ if (slot==30 || slot==70) beam=3&8;
+ */
+ flags |= beam<<8;
+ }
+
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags );
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame );
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot );
+ for (i=0; inb_tx; i++)
+ txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot,fp,0)-sf_extension];
+
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
+ // prepare tx buffer pointers
+ txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
+ timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension,
+ txp,
+ siglen+sf_extension,
+ ru->nb_tx,
+ flags);
+ LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, slot %d\n",ru->idx,
+ (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
+ AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %u/%d)\n", txs, siglen);
}
}
@@ -789,11 +804,12 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
* \param param is a \ref gNB_L1_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/
-static void *ru_thread_asynch_rxtx( void *param ) {
+void *ru_thread_asynch_rxtx( void *param ) {
static int ru_thread_asynch_rxtx_status;
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
- int subframe=0, frame=0;
+ nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
+ int slot=0, frame=0;
// wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
wait_sync("ru_thread_asynch_rxtx");
// wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
@@ -803,22 +819,20 @@ static void *ru_thread_asynch_rxtx( void *param ) {
while (!oai_exit) {
- if (subframe==9) {
- subframe=0;
+ if (slot==ru->nr_frame_parms->slots_per_frame) {
+ slot=0;
frame++;
frame&=1023;
} else {
- subframe++;
+ slot++;
}
LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n");
- // asynchronous receive from south (Mobipass)
- if (ru->fh_south_asynch_in) ru->fh_south_asynch_in(ru,&frame,&subframe);
// asynchronous receive from north (RRU IF4/IF5)
- else if (ru->fh_north_asynch_in) {
- if (nr_slot_select(&ru->gNB_list[0]->gNB_config,subframe,frame)!=SF_UL)
- ru->fh_north_asynch_in(ru,&frame,&subframe);
+ if (ru->fh_north_asynch_in) {
+ if ((nr_slot_select(cfg,frame,slot) & NR_DOWNLINK_SLOT)>0)
+ ru->fh_north_asynch_in(ru,&frame,&slot);
} else AssertFatal(1==0,"Unknown function in ru_thread_asynch_rxtx\n");
}
@@ -834,7 +848,7 @@ static void *ru_thread_asynch_rxtx( void *param ) {
* \param param is a \ref RU_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/
-static void *ru_thread_prach( void *param ) {
+void *ru_thread_prach( void *param ) {
static int ru_thread_prach_status;
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = (RU_proc_t *)&ru->proc;
@@ -1004,7 +1018,7 @@ void wakeup_gNB_L1s(RU_t *ru) {
}
}
-static inline int wakeup_prach_ru(RU_t *ru) {
+int wakeup_prach_ru(RU_t *ru) {
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
@@ -1039,10 +1053,10 @@ static inline int wakeup_prach_ru(RU_t *ru) {
void fill_rf_config(RU_t *ru, char *rf_config_file) {
int i;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
- nfapi_nr_config_request_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index
+ nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index
openair0_config_t *cfg = &ru->openair0_cfg;
- int N_RB = gNB_config->rf_config.dl_carrier_bandwidth.value;
- int mu = gNB_config->subframe_config.numerology_index_mu.value;
+ int mu = gNB_config->ssb_config.scs_common.value;
+ int N_RB = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;
if (mu == NR_MU_0) { //or if LTE
if(N_RB == 100) {
@@ -1111,11 +1125,23 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
} else {
AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu);
}
+ } else if (mu == NR_MU_3) {
+ if (N_RB == 66) {
+ cfg->sample_rate = 122.88e6;
+ cfg->samples_per_frame = 1228800;
+ cfg->tx_bw = 100e6;
+ cfg->rx_bw = 100e6;
+ } else if(N_RB == 32) {
+ cfg->sample_rate=61.44e6;
+ cfg->samples_per_frame = 614400;
+ cfg->tx_bw = 50e6;
+ cfg->rx_bw = 50e6;
+ }
} else {
AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu);
}
- if (gNB_config->subframe_config.duplex_mode.value==TDD)
+ if (gNB_config->cell_config.frame_duplex_type.value==TDD)
cfg->duplex_mode = duplex_mode_TDD;
else //FDD
cfg->duplex_mode = duplex_mode_FDD;
@@ -1126,8 +1152,14 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
cfg->rx_num_channels=ru->nb_rx;
for (i=0; inb_tx; i++) {
- cfg->tx_freq[i] = (double)fp->dl_CarrierFreq;
- cfg->rx_freq[i] = (double)fp->ul_CarrierFreq;
+ if (ru->if_frequency == 0) {
+ cfg->tx_freq[i] = (double)fp->dl_CarrierFreq;
+ cfg->rx_freq[i] = (double)fp->ul_CarrierFreq;
+ }
+ else {
+ cfg->tx_freq[i] = (double)ru->if_frequency;
+ cfg->rx_freq[i] = (double)(ru->if_frequency+fp->ul_CarrierFreq-fp->dl_CarrierFreq);
+ }
cfg->tx_gain[i] = ru->att_tx;
cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx;
cfg->configFilename = rf_config_file;
@@ -1199,7 +1231,7 @@ int setup_RU_buffers(RU_t *ru) {
return(0);
}
-static void *ru_stats_thread(void *param) {
+void *ru_stats_thread(void *param) {
RU_t *ru = (RU_t *)param;
wait_sync("ru_stats_thread");
@@ -1230,7 +1262,7 @@ static void *ru_stats_thread(void *param) {
return(NULL);
}
-static void *ru_thread_tx( void *param ) {
+void *ru_thread_tx( void *param ) {
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
@@ -1250,7 +1282,10 @@ static void *ru_thread_tx( void *param ) {
LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n");
// wait until eNBs are finished subframe RX n and TX n+4
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT, 1 );
wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx");
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT, 0 );
ret = pthread_mutex_lock(&proc->mutex_gNBs);
AssertFatal(ret == 0,"mutex_lock return %d\n",ret);
@@ -1345,12 +1380,12 @@ static void *ru_thread_tx( void *param ) {
// the thread can now be woken up
if (L1_proc->instance_cnt_RUs == -1) {
L1_proc->instance_cnt_RUs = 0;
+ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs);
AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0,
"ERROR pthread_cond_signal for gNB_L1_thread\n");
} //else AssertFatal(1==0,"gNB TX thread is not ready\n");
ret = pthread_mutex_unlock(&L1_proc->mutex_RUs_tx);
AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret);
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs);
}
}
}
@@ -1359,7 +1394,7 @@ static void *ru_thread_tx( void *param ) {
return 0;
}
-static void *ru_thread( void *param ) {
+void *ru_thread( void *param ) {
static int ru_thread_status;
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
@@ -1371,7 +1406,9 @@ static void *ru_thread( void *param ) {
int print_frame = 8;
int i = 0;
int aa;
- // set default return value
+
+ nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
+
// set default return value
ru_thread_status = 0;
// set default return value
@@ -1417,6 +1454,7 @@ static void *ru_thread( void *param ) {
}
}
+ sf_ahead = (uint16_t) ceil((float)6/(0x01<numerology_index));
LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx);
pthread_mutex_lock(&RC.ru_mutex);
RC.ru_mask &= ~(1<idx);
@@ -1468,12 +1506,12 @@ static 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");
- LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0][0]:[RX:%d%d TX(SFN):%d]\n",
+ LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0]:[RX:%d%d TX(SFN):%d]\n",
frame,slot,
proc->frame_rx,proc->tti_rx,
proc->frame_tx,proc->tti_tx,
- RC.gNB[0][0]->proc.frame_rx,RC.gNB[0][0]->proc.slot_rx,
- RC.gNB[0][0]->proc.frame_tx);
+ RC.gNB[0]->proc.frame_rx,RC.gNB[0]->proc.slot_rx,
+ RC.gNB[0]->proc.frame_tx);
/*
LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n",
ru->do_prach,
@@ -1490,19 +1528,21 @@ static void *ru_thread( void *param ) {
// do RX front-end processing (frequency-shift, dft) if needed
- if (proc->tti_rx == NR_UPLINK_SLOT || fp->frame_type == FDD) {
+ 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 (proc->tti_rx==8) {
if (ru->feprx) ru->feprx(ru,proc->tti_rx);
+ //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);
+ LOG_D(PHY,"Copying rxdataF from RU to gNB\n");
+
+ for (aa=0;aanb_rx;aa++)
+ memcpy((void*)RC.gNB[0]->common_vars.rxdataF[aa],
+ (void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
}
- LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx);
- LOG_D(PHY,"Copying rxdataF from RU to gNB\n");
-
- for (aa=0; aanb_rx; aa++)
- memcpy((void *)RC.gNB[0][0]->common_vars.rxdataF[aa],
- (void *)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
-
// At this point, all information for subframe has been received on FH interface
// wakeup all gNB processes waiting for this RU
@@ -1814,19 +1854,19 @@ int check_capabilities(RU_t *ru,RRU_capabilities_t *cap)
FH_fmt_options_t fmt = cap->FH_fmt;
int i;
int found_band=0;
- LOG_I(PHY,"RRU %d, num_bands %d, looking for band %d\n",ru->idx,cap->num_bands,ru->nr_frame_parms->eutra_band);
+ LOG_I(PHY,"RRU %d, num_bands %d, looking for band %d\n",ru->idx,cap->num_bands,ru->nr_frame_parms->nr_band);
for (i=0; inum_bands; i++) {
LOG_I(PHY,"band %d on RRU %d\n",cap->band_list[i],ru->idx);
- if (ru->nr_frame_parms->eutra_band == cap->band_list[i]) {
+ if (ru->nr_frame_parms->nr_band == cap->band_list[i]) {
found_band=1;
break;
}
}
if (found_band == 0) {
- LOG_I(PHY,"Couldn't find target EUTRA band %d on RRU %d\n",ru->nr_frame_parms->eutra_band,ru->idx);
+ LOG_I(PHY,"Couldn't find target NR band %d on RRU %d\n",ru->nr_frame_parms->nr_band,ru->idx);
return(-1);
}
@@ -1871,7 +1911,7 @@ void configure_ru(int idx,
RU_t *ru = RC.ru[idx];
RRU_config_t *config = (RRU_config_t *)arg;
RRU_capabilities_t *capabilities = (RRU_capabilities_t *)arg;
- nfapi_nr_config_request_t *gNB_config = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config;
int ret;
LOG_I(PHY, "Received capabilities from RRU %d\n",idx);
@@ -1883,19 +1923,19 @@ void configure_ru(int idx,
ru->nb_tx = capabilities->nb_tx[0];
ru->nb_rx = capabilities->nb_rx[0];
// Pass configuration to RRU
- LOG_I(PHY, "Using %s fronthaul (%d), band %d \n",ru_if_formats[ru->if_south],ru->if_south,ru->nr_frame_parms->eutra_band);
+ LOG_I(PHY, "Using %s fronthaul (%d), band %d \n",ru_if_formats[ru->if_south],ru->if_south,ru->nr_frame_parms->nr_band);
// wait for configuration
config->FH_fmt = ru->if_south;
config->num_bands = 1;
- config->band_list[0] = ru->nr_frame_parms->eutra_band;
+ config->band_list[0] = ru->nr_frame_parms->nr_band;
config->tx_freq[0] = ru->nr_frame_parms->dl_CarrierFreq;
config->rx_freq[0] = ru->nr_frame_parms->ul_CarrierFreq;
//config->tdd_config[0] = ru->nr_frame_parms->tdd_config;
//config->tdd_config_S[0] = ru->nr_frame_parms->tdd_config_S;
config->att_tx[0] = ru->att_tx;
config->att_rx[0] = ru->att_rx;
- config->N_RB_DL[0] = gNB_config->rf_config.dl_carrier_bandwidth.value;
- config->N_RB_UL[0] = gNB_config->rf_config.ul_carrier_bandwidth.value;
+ config->N_RB_DL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;
+ config->N_RB_UL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;
config->threequarter_fs[0] = ru->nr_frame_parms->threequarter_fs;
/* if (ru->if_south==REMOTE_IF4p5) {
config->prach_FreqOffset[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset;
@@ -1910,22 +1950,23 @@ void configure_rru(int idx,
void *arg) {
RRU_config_t *config = (RRU_config_t *)arg;
RU_t *ru = RC.ru[idx];
- nfapi_nr_config_request_t *gNB_config = &ru->gNB_list[0]->gNB_config;
- ru->nr_frame_parms->eutra_band = config->band_list[0];
+ nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config;
+ ru->nr_frame_parms->nr_band = config->band_list[0];
ru->nr_frame_parms->dl_CarrierFreq = config->tx_freq[0];
ru->nr_frame_parms->ul_CarrierFreq = config->rx_freq[0];
if (ru->nr_frame_parms->dl_CarrierFreq == ru->nr_frame_parms->ul_CarrierFreq) {
- gNB_config->subframe_config.duplex_mode.value = TDD;
+ gNB_config->cell_config.frame_duplex_type.value = TDD;
//ru->nr_frame_parms->tdd_config = config->tdd_config[0];
//ru->nr_frame_parms->tdd_config_S = config->tdd_config_S[0];
} else
- gNB_config->subframe_config.duplex_mode.value = FDD;
+ gNB_config->cell_config.frame_duplex_type.value = FDD;
ru->att_tx = config->att_tx[0];
ru->att_rx = config->att_rx[0];
- gNB_config->rf_config.dl_carrier_bandwidth.value = config->N_RB_DL[0];
- gNB_config->rf_config.ul_carrier_bandwidth.value = config->N_RB_UL[0];
+ int mu = gNB_config->ssb_config.scs_common.value;
+ gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0];
+ gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0];
ru->nr_frame_parms->threequarter_fs = config->threequarter_fs[0];
//ru->nr_frame_parms->pdsch_config_common.referenceSignalPower = ru->max_pdschReferenceSignalPower-config->att_tx[0];
@@ -2117,8 +2158,6 @@ void set_function_spec_param(RU_t *ru) {
} // switch on interface type
}
-extern void RCconfig_RU(void);
-
void init_NR_RU(char *rf_config_file)
{
int ru_id;
@@ -2137,10 +2176,6 @@ void init_NR_RU(char *rf_config_file)
RCconfig_RU();
LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_nr_L1_inst,RC.nb_RU,get_nprocs());
- if (RC.nb_nr_CC != 0)
- for (i=0; inum_RU=0;
-
LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU);
for (ru_id=0; ru_idnum_gNB > 0) {
- LOG_D(PHY, "%s() RC.ru[%d].num_gNB:%d ru->gNB_list[0]:%p RC.gNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_gNB, ru->gNB_list[0], RC.gNB[0][0], ru->rf_config_file);
+ LOG_D(PHY, "%s() RC.ru[%d].num_gNB:%d ru->gNB_list[0]:%p RC.gNB[0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_gNB, ru->gNB_list[0], RC.gNB[0], ru->rf_config_file);
if (ru->gNB_list[0] == 0) {
LOG_E(PHY,"%s() DJP - ru->gNB_list ru->num_gNB are not initialized - so do it manually\n", __FUNCTION__);
- ru->gNB_list[0] = RC.gNB[0][0];
+ ru->gNB_list[0] = RC.gNB[0];
ru->num_gNB=1;
//
// DJP - feptx_prec() / feptx_ofdm() parses the gNB_list (based on num_gNB) and copies the txdata_F to txdata in RU
@@ -2167,7 +2202,7 @@ void init_NR_RU(char *rf_config_file)
}
}
- gNB_RC = RC.gNB[0][0];
+ gNB_RC = RC.gNB[0];
gNB0 = ru->gNB_list[0];
fp = ru->nr_frame_parms;
LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south);
@@ -2239,7 +2274,7 @@ void RCconfig_RU(void)
else
RC.ru[j]->num_gNB = 0;
- for (i=0; inum_gNB; i++) RC.ru[j]->gNB_list[i] = RC.gNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0];
+ for (i=0; inum_gNB; i++) RC.ru[j]->gNB_list[i] = RC.gNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]];
if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) {
RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr));
@@ -2332,18 +2367,14 @@ void RCconfig_RU(void)
RC.ru[j]->if_south = REMOTE_IF4p5;
RC.ru[j]->function = NGFI_RAU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
- } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if5_mobipass") == 0) {
- RC.ru[j]->if_south = REMOTE_IF5;
- RC.ru[j]->function = NGFI_RAU_IF5;
- RC.ru[j]->if_timing = synch_to_other;
- RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF5_MOBIPASS;
- }
+ }
} /* strcmp(local_rf, "yes") != 0 */
RC.ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr);
RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr);
RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr);
RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr);
+ RC.ru[j]->if_frequency = *(RUParamList.paramarray[j][RU_IF_FREQUENCY].u64ptr);
if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) {
RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt;
@@ -2359,3 +2390,4 @@ void RCconfig_RU(void)
return;
}
+
diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h
index e6aafafeb9..ccb3f28d98 100644
--- a/executables/nr-softmodem-common.h
+++ b/executables/nr-softmodem-common.h
@@ -83,6 +83,7 @@
#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_DISABLETIMECORR "disable UE timing correction\n"
+#define CONFIG_HLP_RRC_CFG_PATH "path for RRC configuration\n"
#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n"
#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n"
@@ -126,7 +127,7 @@ extern pthread_mutex_t sync_mutex;
extern int sync_var;
-extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
+extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
extern int rx_input_level_dBm;
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index ed73aca4fe..cd222ac176 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -84,6 +84,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "executables/softmodem-common.h"
#include "executables/thread-common.h"
#include "NB_IoT_interface.h"
+#include "x2ap_eNB.h"
short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,16384,16384,-16384,-16384,16384,16384,16384,-16384,-16384,16384,-16384,-16384,7327,7327,7327,21981,21981,7327,21981,21981,7327,-7327,7327,-21981,21981,-7327,21981,-21981,-7327,7327,-7327,21981,-21981,7327,-21981,21981,-7327,-7327,-7327,-21981,-21981,-7327,-21981,-21981,10726,10726,10726,3576,3576,10726,3576,3576,10726,17876,10726,25027,3576,17876,3576,25027,17876,10726,17876,3576,25027,10726,25027,3576,17876,17876,17876,25027,25027,17876,25027,25027,10726,-10726,10726,-3576,3576,-10726,3576,-3576,10726,-17876,10726,-25027,3576,-17876,3576,-25027,17876,-10726,17876,-3576,25027,-10726,25027,-3576,17876,-17876,17876,-25027,25027,-17876,25027,-25027,-10726,10726,-10726,3576,-3576,10726,-3576,3576,-10726,17876,-10726,25027,-3576,17876,-3576,25027,-17876,10726,-17876,3576,-25027,10726,-25027,3576,-17876,17876,-17876,25027,-25027,17876,-25027,25027,-10726,-10726,-10726,-3576,-3576,-10726,-3576,-3576,-10726,-17876,-10726,-25027,-3576,-17876,-3576,-25027,-17876,-10726,-17876,-3576,-25027,-10726,-25027,-3576,-17876,-17876,-17876,-25027,-25027,-17876,-25027,-25027,8886,8886,8886,12439,12439,8886,12439,12439,8886,5332,8886,1778,12439,5332,12439,1778,5332,8886,5332,12439,1778,8886,1778,12439,5332,5332,5332,1778,1778,5332,1778,1778,8886,19547,8886,15993,12439,19547,12439,15993,8886,23101,8886,26655,12439,23101,12439,26655,5332,19547,5332,15993,1778,19547,1778,15993,5332,23101,5332,26655,1778,23101,1778,26655,19547,8886,19547,12439,15993,8886,15993,12439,19547,5332,19547,1778,15993,5332,15993,1778,23101,8886,23101,12439,26655,8886,26655,12439,23101,5332,23101,1778,26655,5332,26655,1778,19547,19547,19547,15993,15993,19547,15993,15993,19547,23101,19547,26655,15993,23101,15993,26655,23101,19547,23101,15993,26655,19547,26655,15993,23101,23101,23101,26655,26655,23101,26655,26655,8886,-8886,8886,-12439,12439,-8886,12439,-12439,8886,-5332,8886,-1778,12439,-5332,12439,-1778,5332,-8886,5332,-12439,1778,-8886,1778,-12439,5332,-5332,5332,-1778,1778,-5332,1778,-1778,8886,-19547,8886,-15993,12439,-19547,12439,-15993,8886,-23101,8886,-26655,12439,-23101,12439,-26655,5332,-19547,5332,-15993,1778,-19547,1778,-15993,5332,-23101,5332,-26655,1778,-23101,1778,-26655,19547,-8886,19547,-12439,15993,-8886,15993,-12439,19547,-5332,19547,-1778,15993,-5332,15993,-1778,23101,-8886,23101,-12439,26655,-8886,26655,-12439,23101,-5332,23101,-1778,26655,-5332,26655,-1778,19547,-19547,19547,-15993,15993,-19547,15993,-15993,19547,-23101,19547,-26655,15993,-23101,15993,-26655,23101,-19547,23101,-15993,26655,-19547,26655,-15993,23101,-23101,23101,-26655,26655,-23101,26655,-26655,-8886,8886,-8886,12439,-12439,8886,-12439,12439,-8886,5332,-8886,1778,-12439,5332,-12439,1778,-5332,8886,-5332,12439,-1778,8886,-1778,12439,-5332,5332,-5332,1778,-1778,5332,-1778,1778,-8886,19547,-8886,15993,-12439,19547,-12439,15993,-8886,23101,-8886,26655,-12439,23101,-12439,26655,-5332,19547,-5332,15993,-1778,19547,-1778,15993,-5332,23101,-5332,26655,-1778,23101,-1778,26655,-19547,8886,-19547,12439,-15993,8886,-15993,12439,-19547,5332,-19547,1778,-15993,5332,-15993,1778,-23101,8886,-23101,12439,-26655,8886,-26655,12439,-23101,5332,-23101,1778,-26655,5332,-26655,1778,-19547,19547,-19547,15993,-15993,19547,-15993,15993,-19547,23101,-19547,26655,-15993,23101,-15993,26655,-23101,19547,-23101,15993,-26655,19547,-26655,15993,-23101,23101,-23101,26655,-26655,23101,-26655,26655,-8886,-8886,-8886,-12439,-12439,-8886,-12439,-12439,-8886,-5332,-8886,-1778,-12439,-5332,-12439,-1778,-5332,-8886,-5332,-12439,-1778,-8886,-1778,-12439,-5332,-5332,-5332,-1778,-1778,-5332,-1778,-1778,-8886,-19547,-8886,-15993,-12439,-19547,-12439,-15993,-8886,-23101,-8886,-26655,-12439,-23101,-12439,-26655,-5332,-19547,-5332,-15993,-1778,-19547,-1778,-15993,-5332,-23101,-5332,-26655,-1778,-23101,-1778,-26655,-19547,-8886,-19547,-12439,-15993,-8886,-15993,-12439,-19547,-5332,-19547,-1778,-15993,-5332,-15993,-1778,-23101,-8886,-23101,-12439,-26655,-8886,-26655,-12439,-23101,-5332,-23101,-1778,-26655,-5332,-26655,-1778,-19547,-19547,-19547,-15993,-15993,-19547,-15993,-15993,-19547,-23101,-19547,-26655,-15993,-23101,-15993,-26655,-23101,-19547,-23101,-15993,-26655,-19547,-26655,-15993,-23101,-23101,-23101,-26655,-26655,-23101,-26655,-26655};
@@ -107,9 +108,9 @@ static int wait_for_sync = 0;
unsigned int mmapped_dma=0;
int single_thread_flag=1;
-static int8_t threequarter_fs=0;
+int8_t threequarter_fs=0;
-uint32_t downlink_frequency[MAX_NUM_CCs][4];
+uint64_t downlink_frequency[MAX_NUM_CCs][4];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
//Temp fix for inexistent NR upper layer
@@ -204,7 +205,7 @@ char uecap_xer_in=0;
uint8_t abstraction_flag=0;
/* forward declarations */
-void set_default_frame_parms(nfapi_nr_config_request_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
+void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
/*---------------------BMC: timespec helpers -----------------------------*/
@@ -389,6 +390,18 @@ int create_gNB_tasks(uint32_t gnb_nb) {
LOG_E(GNB_APP, "Create task for gNB APP failed\n");
return -1;
}
+ if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){
+ LOG_E(SCTP, "Create task for SCTP failed\n");
+ return -1;
+ }
+ if (is_x2ap_enabled()) {
+ if(itti_create_task(TASK_X2AP, x2ap_task, NULL) < 0){
+ LOG_E(X2AP, "Create task for X2AP failed\n");
+ }
+ }
+ else {
+ LOG_I(X2AP, "X2AP is disabled.\n");
+ }
}
/*
@@ -457,18 +470,18 @@ static void get_options(void) {
}
-void set_default_frame_parms(nfapi_nr_config_request_t *config[MAX_NUM_CCs],
- NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs])
+void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs],
+ NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs])
{
for (int CC_id=0; CC_idsubframe_config.numerology_index_mu.value =1;
- config[CC_id]->subframe_config.duplex_mode.value = 1; //FDD
- config[CC_id]->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL
- config[CC_id]->rf_config.dl_carrier_bandwidth.value = 106;
- config[CC_id]->rf_config.ul_carrier_bandwidth.value = 106;
- config[CC_id]->sch_config.physical_cell_id.value = 0;
+ config[CC_id] = (nfapi_nr_config_request_scf_t *) malloc(sizeof(nfapi_nr_config_request_scf_t));
+ config[CC_id]->ssb_config.scs_common.value = 1;
+ config[CC_id]->cell_config.frame_duplex_type.value = 1; //FDD
+ //config[CC_id]->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL
+ config[CC_id]->carrier_config.dl_grid_size[1].value = 106;
+ config[CC_id]->carrier_config.ul_grid_size[1].value = 106;
+ config[CC_id]->cell_config.phy_cell_id.value = 0;
///dl frequency to be filled in
/* //Set some default values that may be overwritten while reading options
frame_parms[CC_id]->frame_type = FDD;
@@ -480,7 +493,7 @@ void set_default_frame_parms(nfapi_nr_config_request_t *config[MAX_NUM_CCs],
frame_parms[CC_id]->Ncp_UL = NORMAL;
frame_parms[CC_id]->Nid_cell = 0;
frame_parms[CC_id]->num_MBSFN_config = 0;
- frame_parms[CC_id]->nb_antenna_ports_eNB = 1;
+ frame_parms[CC_id]->nb_antenna_ports_gNB = 1;
frame_parms[CC_id]->nb_antennas_tx = 1;
frame_parms[CC_id]->nb_antennas_rx = 1;
@@ -557,8 +570,8 @@ void init_openair0(void) {
openair0_cfg[card].duplex_mode = duplex_mode_FDD;
printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
- RC.gNB[0][0]->gNB_config.rf_config.tx_antenna_ports.value,
- RC.gNB[0][0]->gNB_config.rf_config.tx_antenna_ports.value );
+ RC.gNB[0]->gNB_config.rf_config.tx_antenna_ports.value,
+ RC.gNB[0]->gNB_config.rf_config.tx_antenna_ports.value );
openair0_cfg[card].Mod_id = 0;
openair0_cfg[card].num_rb_dl=config[0]->rf_config.dl_carrier_bandwidth.value;
@@ -566,8 +579,8 @@ void init_openair0(void) {
openair0_cfg[card].clock_source = clock_source;
- openair0_cfg[card].tx_num_channels=min(2,RC.gNB[0][0]->gNB_config.rf_config.tx_antenna_ports.value );
- openair0_cfg[card].rx_num_channels=min(2,RC.gNB[0][0]->gNB_config.rf_config.tx_antenna_ports.value );
+ openair0_cfg[card].tx_num_channels=min(2,RC.gNB[0]->gNB_config.rf_config.tx_antenna_ports.value );
+ openair0_cfg[card].rx_num_channels=min(2,RC.gNB[0]->gNB_config.rf_config.tx_antenna_ports.value );
for (i=0; i<4; i++) {
@@ -583,7 +596,7 @@ void init_openair0(void) {
openair0_cfg[card].autocal[i] = 1;
openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
- openair0_cfg[card].rx_gain[i] = RC.gNB[0][0]->rx_total_gain_dB;
+ openair0_cfg[card].rx_gain[i] = RC.gNB[0]->rx_total_gain_dB;
openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file;
@@ -612,7 +625,7 @@ void wait_RUs(void) {
}
void wait_gNBs(void) {
- int i,j;
+ int i;
int waiting=1;
while (waiting==1) {
@@ -621,13 +634,10 @@ void wait_gNBs(void) {
waiting=0;
for (i=0; iconfigured==0) {
- waiting=1;
- break;
- }
+ if (RC.gNB[i]->configured==0) {
+ waiting=1;
+ break;
}
}
}
@@ -686,10 +696,9 @@ int stop_L1L2(module_id_t gnb_id) {
kill_NR_RU_proc(gnb_id);
oai_exit = 0;
- for (int cc_id = 0; cc_id < RC.nb_nr_CC[gnb_id]; cc_id++) {
- //free_transport(RC.gNB[gnb_id][cc_id]);
- phy_free_nr_gNB(RC.gNB[gnb_id][cc_id]);
- }
+ //free_transport(RC.gNB[gnb_id]);
+ phy_free_nr_gNB(RC.gNB[gnb_id]);
+
nr_phy_free_RU(RC.ru[gnb_id]);
free_lte_top();
@@ -707,14 +716,13 @@ int restart_L1L2(module_id_t gnb_id) {
/* block threads */
sync_var = -1;
- for (cc_id = 0; cc_id < RC.nb_nr_L1_CC[gnb_id]; cc_id++) {
- RC.gNB[gnb_id][cc_id]->configured = 0;
- }
+ RC.gNB[gnb_id]->configured = 0;
+
RC.ru_mask |= (1 << ru->idx);
/* copy the changed frame parameters to the RU */
/* TODO this should be done for all RUs associated to this gNB */
- memcpy(&ru->nr_frame_parms, &RC.gNB[gnb_id][0]->frame_parms, sizeof(NR_DL_FRAME_PARMS));
+ memcpy(&ru->nr_frame_parms, &RC.gNB[gnb_id]->frame_parms, sizeof(NR_DL_FRAME_PARMS));
set_function_spec_param(RC.ru[gnb_id]);
LOG_I(GNB_APP, "attempting to create ITTI tasks\n");
// No more rrc thread, as many race conditions are hidden behind
@@ -784,9 +792,10 @@ void init_pdcp(void) {
}*/
}
+
int main( int argc, char **argv )
{
- int i, ru_id, CC_id = 0;
+ int ru_id, CC_id = 0;
start_background_system();
///static configuration for NR at the moment
@@ -859,11 +868,13 @@ if(!IS_SOFTMODEM_NOS1)
}
/* Start the agent. If it is turned off in the configuration, it won't start */
+ /*
RCconfig_nr_flexran();
for (i = 0; i < RC.nb_nr_L1_inst; i++) {
flexran_agent_start(i);
}
+*/
// init UE_PF_PO and mutex lock
pthread_mutex_init(&ue_pf_po_mutex, NULL);
@@ -871,38 +882,8 @@ if(!IS_SOFTMODEM_NOS1)
mlockall(MCL_CURRENT | MCL_FUTURE);
pthread_cond_init(&sync_cond,NULL);
pthread_mutex_init(&sync_mutex, NULL);
- /*#ifdef XFORMS
- int UE_id;
- if (do_forms==1) {
- fl_initialize (&argc, argv, NULL, 0, 0);
- form_stats_l2 = create_form_stats_form();
- fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats");
- form_stats = create_form_stats_form();
- fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
-
- for(UE_id=0; UE_idphy_scope_gnb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
-
- if (otg_enabled) {
- fl_set_button(form_gnb[CC_id][UE_id]->button_0,1);
- fl_set_object_label(form_gnb[CC_id][UE_id]->button_0,"DL Traffic ON");
- } else {
- fl_set_button(form_gnb[CC_id][UE_id]->button_0,0);
- fl_set_object_label(form_gnb[CC_id][UE_id]->button_0,"DL Traffic OFF");
- }
- } // CC_id
- } // UE_id
-
- threadCreate(&forms_thread, scope_thread, NULL, "scope", -1, OAI_PRIORITY_RT_LOW);
- printf("Scope thread created, ret=%d\n",ret);
- }
-
- #endif*/
- usleep(10*1000);
+ usleep(1000);
if (nfapi_mode) {
printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
@@ -972,6 +953,13 @@ if(!IS_SOFTMODEM_NOS1)
// once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration)
printf("ALL RUs ready - init gNBs\n");
+ if (do_forms==1) {
+ scopeParms_t p;
+ p.argc=&argc;
+ p.argv=argv;
+ startScope(&p);
+ }
+
if (nfapi_mode != 1 && nfapi_mode != 2) {
printf("Not NFAPI mode - call init_eNB_afterRU()\n");
init_eNB_afterRU();
@@ -1028,10 +1016,8 @@ if(!IS_SOFTMODEM_NOS1)
/* release memory used by the RU/gNB threads (incomplete), after all
* threads have been stopped (they partially use the same memory) */
for (int inst = 0; inst < NB_gNB_INST; inst++) {
- for (int cc_id = 0; cc_id < RC.nb_nr_CC[inst]; cc_id++) {
- //free_transport(RC.gNB[inst][cc_id]);
- phy_free_nr_gNB(RC.gNB[inst][cc_id]);
- }
+ //free_transport(RC.gNB[inst]);
+ phy_free_nr_gNB(RC.gNB[inst]);
}
for (int inst = 0; inst < NB_RU; inst++) {
diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h
index 20316bff2e..27e3ba1e3e 100644
--- a/executables/nr-softmodem.h
+++ b/executables/nr-softmodem.h
@@ -22,7 +22,7 @@
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
- {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT, 0}, \
+ {"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT64, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 767f258817..a0251b26df 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -136,14 +136,12 @@ typedef enum {
} sync_mode_t;
-PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms,
- uint8_t UE_id,
- uint8_t abstraction_flag)
-
+void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
+ NR_DL_FRAME_PARMS *frame_parms,
+ uint8_t UE_id,
+ uint8_t abstraction_flag)
{
- PHY_VARS_NR_UE *ue;
- ue = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE));
- memset(ue,0,sizeof(PHY_VARS_NR_UE));
+
memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS));
ue->Mod_id = UE_id;
@@ -153,7 +151,6 @@ PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms,
init_nr_ue_signal(ue,1,abstraction_flag);
// intialize transport
init_nr_ue_transport(ue,abstraction_flag);
- return(ue);
}
/*!
@@ -175,22 +172,19 @@ static void UE_synch(void *arg) {
int freq_offset=0;
UE->is_synchronized = 0;
-
if (UE->UE_scan == 0) {
- get_band(downlink_frequency[CC_id][0], &UE->frame_parms.eutra_band, &uplink_frequency_offset[CC_id][0], &UE->frame_parms.frame_type);
- LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n",
- downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],
+ LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu64", UL %"PRIu64" (oai_exit %d, rx_num_channels %d)\n",
+ UE->frame_parms.dl_CarrierFreq, UE->frame_parms.ul_CarrierFreq,
oai_exit, openair0_cfg[0].rx_num_channels);
for (i=0; irf_map.card].rx_num_channels; i++) {
- openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
- openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
- downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
+ openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = UE->frame_parms.dl_CarrierFreq;
+ openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = UE->frame_parms.ul_CarrierFreq;
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
- if (uplink_frequency_offset[CC_id][i] != 0) //
+ if (UE->frame_parms.frame_type == FDD)
openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD;
- else //FDD
+ else
openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD;
}
@@ -248,13 +242,14 @@ static void UE_synch(void *arg) {
if (nr_initial_sync( &syncD->proc, UE, UE->mode,2) == 0) {
freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
- hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_slot;
- LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
+ hw_slot_offset = ((UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe) +
+ round((float)((UE->rx_offset<<1) % UE->frame_parms.samples_per_subframe)/UE->frame_parms.samples_per_slot0);
+ LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %lu, UL %lu), UE_scan_carrier %d\n",
hw_slot_offset,
freq_offset,
UE->rx_total_gain_dB,
- downlink_frequency[0][0]+freq_offset,
- downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset,
+ UE->frame_parms.dl_CarrierFreq+freq_offset,
+ UE->frame_parms.ul_CarrierFreq+freq_offset,
UE->UE_scan_carrier );
// rerun with new cell parameters and frequency-offset
@@ -267,8 +262,8 @@ static void UE_synch(void *arg) {
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(freq_offset);
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
- openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i];
- downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
+ openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+(UE->frame_parms.ul_CarrierFreq-UE->frame_parms.dl_CarrierFreq);
+ UE->frame_parms.dl_CarrierFreq = openair0_cfg[CC_id].rx_freq[i];
}
// reconfigure for potentially different bandwidth
@@ -300,6 +295,12 @@ static void UE_synch(void *arg) {
openair0_cfg[UE->rf_map.card].tx_bw=10.0e6;
// openair0_cfg[0].rx_gain[0] -= 0;
break;
+
+ case 66:
+ openair0_cfg[UE->rf_map.card].sample_rate=122.88e6;
+ openair0_cfg[UE->rf_map.card].rx_bw=100.e6;
+ openair0_cfg[UE->rf_map.card].tx_bw=100.e6;
+ break;
}
if (UE->mode != loop_through_memory) {
@@ -327,15 +328,15 @@ static void UE_synch(void *arg) {
freq_offset += 100;
freq_offset *= -1;
- LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
+ LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %lu, UL %lu)\n",
freq_offset,
UE->rx_total_gain_dB,
- downlink_frequency[0][0]+freq_offset,
- downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
+ UE->frame_parms.dl_CarrierFreq+freq_offset,
+ UE->frame_parms.ul_CarrierFreq+freq_offset );
for (i=0; irf_map.card].rx_num_channels; i++) {
- openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset;
- openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset;
+ openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = UE->frame_parms.dl_CarrierFreq+freq_offset;
+ openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = UE->frame_parms.ul_CarrierFreq+freq_offset;
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
if (UE->UE_scan_carrier==1)
@@ -355,25 +356,24 @@ static void UE_synch(void *arg) {
}
}
-void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
-
- nr_dcireq_t dcireq;
- nr_scheduled_response_t scheduled_response;
+void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
uint32_t nb_rb, start_rb;
uint8_t nb_symb_sch, start_symbol, mcs, precod_nbr_layers, harq_pid, rvidx;
uint16_t n_rnti;
- // Process Rx data for one sub-frame
- if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) {
- //TODO: all of this has to be moved to the MAC!!!
+ nr_dcireq_t dcireq;
+ nr_scheduled_response_t scheduled_response;
+
+ // program PUSCH. this should actually be done by the MAC upon reception of an UL DCI
+ if (proc->nr_tti_tx == 8 || UE->frame_parms.frame_type == FDD){
+
dcireq.module_id = UE->Mod_id;
dcireq.gNB_index = 0;
dcireq.cc_id = 0;
dcireq.frame = proc->frame_rx;
dcireq.slot = proc->nr_tti_rx;
- nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
- scheduled_response.dl_config = &dcireq.dl_config_req;
+ scheduled_response.dl_config = NULL;
scheduled_response.ul_config = &dcireq.ul_config_req;
scheduled_response.tx_request = NULL;
scheduled_response.module_id = UE->Mod_id;
@@ -381,19 +381,18 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
scheduled_response.frame = proc->frame_rx;
scheduled_response.slot = proc->nr_tti_rx;
//--------------------------Temporary configuration-----------------------------//
- //--------------------------Temporary configuration-----------------------------//
n_rnti = 0x1234;
nb_rb = 50;
start_rb = 0;
nb_symb_sch = 12;
- start_symbol = 0;
+ start_symbol = 2;
precod_nbr_layers = 1;
mcs = 9;
harq_pid = 0;
rvidx = 0;
//------------------------------------------------------------------------------//
- scheduled_response.ul_config->sfn_slot = NR_UPLINK_SLOT;
+ scheduled_response.ul_config->slot = 8;
scheduled_response.ul_config->number_pdus = 1;
scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.rnti = n_rnti;
@@ -406,8 +405,53 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.rv = rvidx;
scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.n_layers = precod_nbr_layers;
scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid;
- nr_ue_scheduled_response(&scheduled_response);
+ nr_ue_scheduled_response(&scheduled_response);
+
+ if (UE->mode != loop_through_memory) {
+ uint8_t thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_tx];
+ phy_procedures_nrUE_TX(UE,proc,0,thread_id);
+ }
+ }
+}
+
+void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
+
+ nr_dcireq_t dcireq;
+ nr_scheduled_response_t scheduled_response;
+ uint8_t ssb_period = UE->nrUE_config.ssb_table.ssb_period;
+
+ //program DCI for slot 1
+ //TODO: all of this has to be moved to the MAC!!!
+ if (proc->nr_tti_rx == NR_DOWNLINK_SLOT || UE->frame_parms.frame_type == FDD){
+ dcireq.module_id = UE->Mod_id;
+ dcireq.gNB_index = 0;
+ dcireq.cc_id = 0;
+ dcireq.frame = proc->frame_rx;
+ dcireq.slot = proc->nr_tti_rx;
+ nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
+
+ // we should have received a DL DCI here, so configure DL accordingly
+ scheduled_response.dl_config = &dcireq.dl_config_req;
+ scheduled_response.ul_config = NULL;
+ scheduled_response.tx_request = NULL;
+ scheduled_response.module_id = UE->Mod_id;
+ scheduled_response.CC_id = 0;
+ if (!((proc->frame_rx)%(1<<(ssb_period-1)))) {
+ if(proc->frame_rx > dcireq.dl_config_req.sfn)
+ UE->frame_gap = proc->frame_rx - dcireq.dl_config_req.sfn;
+ if(proc->frame_rx < dcireq.dl_config_req.sfn)
+ UE->frame_gap = dcireq.dl_config_req.sfn - proc->frame_rx;
+ proc->frame_rx = dcireq.dl_config_req.sfn;
+ }
+ scheduled_response.frame = proc->frame_rx;
+ scheduled_response.slot = proc->nr_tti_rx;
+
+ nr_ue_scheduled_response(&scheduled_response);
+ }
+
+ // Process Rx data for one sub-frame
+ if ( proc->nr_tti_rx >=0 && proc->nr_tti_rx <= 1 ) {
#ifdef UE_SLOT_PARALLELISATION
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
#else
@@ -416,14 +460,15 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
LOG_D(PHY,"phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_tti_rx, (rdtsc()-a)/3500);
//printf(">>> nr_ue_pdcch_procedures ended\n");
#endif
- if(IS_SOFTMODEM_NOS1){ //&& proc->nr_tti_rx==1
- //Hardcoded rnti value
- protocol_ctxt_t ctxt;
- PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO,
- 0x1234, proc->frame_rx,
- proc->nr_tti_rx, 0);
- pdcp_run(&ctxt);
- }
+
+ if(IS_SOFTMODEM_NOS1){ //&& proc->nr_tti_rx==1
+ //Hardcoded rnti value
+ protocol_ctxt_t ctxt;
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO,
+ 0x1234, proc->frame_rx,
+ proc->nr_tti_rx, 0);
+ pdcp_run(&ctxt);
+ }
}
// no UL for now
@@ -458,11 +503,10 @@ typedef struct processingData_s {
} processingData_t;
void UE_processing(void *arg) {
- uint8_t thread_id;
processingData_t *rxtxD=(processingData_t *) arg;
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
PHY_VARS_NR_UE *UE = rxtxD->UE;
- processSlotRX(UE, proc);
+
uint8_t gNB_id = 0;
// params for UL time alignment procedure
// params for UL time alignment procedure
@@ -472,18 +516,6 @@ void UE_processing(void *arg) {
int slot_tx = proc->nr_tti_tx;
int frame_tx = proc->frame_tx;
- //printf(">>> mac ended\n");
- // Prepare the future Tx data
- /*
- #ifndef NO_RAT_NR
-
- if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_UPLINK_SLOT)
- #else
- if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
- (UE->frame_parms.frame_type == FDD) )
- #endif
- */
-
/* UL time alignment
// If the current tx frame and slot match the TA configuration in ul_time_alignment
// then timing advance is processed and set to be applied in the next UL transmission */
@@ -500,80 +532,60 @@ void UE_processing(void *arg) {
}
}
- if (proc->nr_tti_tx == NR_UPLINK_SLOT || UE->frame_parms.frame_type == FDD) {
+ processSlotRX(UE, proc);
- thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_tx];
+ processSlotTX(UE, proc);
-
- if (UE->mode != loop_through_memory)
- phy_procedures_nrUE_TX(UE,proc,gNB_id,thread_id);
-
- }
-
- //phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay);
-
-#if 0
-
- if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) &&
- (UE->frame_parms.frame_type == TDD))
- if (UE->mode != loop_through_memory)
- //phy_procedures_UE_S_TX(UE,0,0,no_relay);
- updateTimes(current, &t3, 10000, timing_proc_name);
-
-#endif
}
-void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
- void *rxp[NB_ANTENNAS_RX];
+void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) {
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
for (int i=0; iframe_parms.nb_antennas_tx; i++)
- dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
+ dummy_tx[i]=malloc16_clear(writeBlockSize*4);
- for(int x=0; x<20; x++) { // two frames for initial sync
- for (int i=0; iframe_parms.nb_antennas_rx; i++)
- rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) + 4*x*UE->frame_parms.samples_per_subframe;
-
- AssertFatal( UE->frame_parms.samples_per_subframe ==
- UE->rfdevice.trx_read_func(&UE->rfdevice,
- timestamp,
- rxp,
- UE->frame_parms.samples_per_subframe,
- UE->frame_parms.nb_antennas_rx), "");
- }
+ AssertFatal( writeBlockSize ==
+ UE->rfdevice.trx_write_func(&UE->rfdevice,
+ timestamp,
+ dummy_tx,
+ writeBlockSize,
+ UE->frame_parms.nb_antennas_tx,
+ 4),"");
for (int i=0; iframe_parms.nb_antennas_tx; i++)
free(dummy_tx[i]);
}
-void trashFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
- void *dummy_tx[UE->frame_parms.nb_antennas_tx];
+void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash) {
- for (int i=0; iframe_parms.nb_antennas_tx; i++)
- dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
+ void *rxp[NB_ANTENNAS_RX];
- void *dummy_rx[UE->frame_parms.nb_antennas_rx];
+ for(int x=0; x<20; x++) { // two frames for initial sync
+ for (int slot=0; slotframe_parms.slots_per_subframe; slot ++ ) {
+ for (int i=0; iframe_parms.nb_antennas_rx; i++) {
+ if (toTrash)
+ rxp[i]=malloc16(UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms)*4);
+ else
+ rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) +
+ 4*((x*UE->frame_parms.samples_per_subframe)+
+ UE->frame_parms.get_samples_slot_timestamp(slot,&UE->frame_parms,0));
+ }
+
+ AssertFatal( UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms) ==
+ UE->rfdevice.trx_read_func(&UE->rfdevice,
+ timestamp,
+ rxp,
+ UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms),
+ UE->frame_parms.nb_antennas_rx), "");
- for (int i=0; iframe_parms.nb_antennas_rx; i++)
- dummy_rx[i]=malloc16(UE->frame_parms.samples_per_subframe*4);
-
- for (int sf=0; sfrfdevice.trx_read_func(&UE->rfdevice,
- timestamp,
- dummy_rx,
- UE->frame_parms.samples_per_subframe,
- UE->frame_parms.nb_antennas_rx);
- if (IS_SOFTMODEM_RFSIM ) {
- usleep(1000); // slow down, as would do actual rf to let cpu for the synchro thread
+ if (IS_SOFTMODEM_RFSIM)
+ dummyWrite(UE,*timestamp, UE->frame_parms.get_samples_per_slot(slot,&UE->frame_parms));
+ if (toTrash)
+ for (int i=0; iframe_parms.nb_antennas_rx; i++)
+ free(rxp[i]);
}
}
- for (int i=0; iframe_parms.nb_antennas_tx; i++)
- free(dummy_tx[i]);
-
- for (int i=0; iframe_parms.nb_antennas_rx; i++)
- free(dummy_rx[i]);
}
void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
@@ -581,21 +593,20 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
void *dummy_tx[UE->frame_parms.nb_antennas_tx];
- for (int i=0; iframe_parms.nb_antennas_tx; i++)
- dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4);
-
- for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
- int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
- AssertFatal(unitTransfer ==
- UE->rfdevice.trx_read_func(&UE->rfdevice,
- timestamp,
- (void **)UE->common_vars.rxdata,
- unitTransfer,
- UE->frame_parms.nb_antennas_rx),"");
- }
-
- for (int i=0; iframe_parms.nb_antennas_tx; i++)
- free(dummy_tx[i]);
+ *timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms);
+ for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
+ int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
+ // we write before read becasue gNB waits for UE to write and both executions halt
+ // this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
+ if (IS_SOFTMODEM_RFSIM) dummyWrite(UE,*timestamp, unitTransfer);
+ AssertFatal(unitTransfer ==
+ UE->rfdevice.trx_read_func(&UE->rfdevice,
+ timestamp,
+ (void **)UE->common_vars.rxdata,
+ unitTransfer,
+ UE->frame_parms.nb_antennas_rx),"");
+ *timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write
+ }
}
@@ -622,6 +633,22 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) {
return 0;
}
+static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
+ if (fp->numerology_index == 0)
+ return fp->nb_prefix_samples0 + fp->ofdm_symbol_size;
+ int num_samples = (slot%(fp->slots_per_subframe/2)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0;
+ num_samples += fp->ofdm_symbol_size;
+ return num_samples;
+}
+
+static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
+ int rem_samples = fp->get_samples_per_slot(slot, fp) - get_firstSymSamp(slot, fp);
+ int next_slot_first_symbol = 0;
+ if (slot < (fp->slots_per_frame-1))
+ next_slot_first_symbol = get_firstSymSamp(slot+1, fp);
+ return rem_samples + next_slot_first_symbol;
+}
+
void *UE_thread(void *arg) {
//this thread should be over the processing thread to keep in real time
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
@@ -629,7 +656,6 @@ void *UE_thread(void *arg) {
openair0_timestamp timestamp;
void *rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX];
int start_rx_stream = 0;
- const uint16_t table_sf_slot[20] = {0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9};
AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), "");
UE->rfdevice.host_type = RAU_HOST;
AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n");
@@ -639,13 +665,14 @@ void *UE_thread(void *arg) {
int thread_idx=0;
notifiedFIFO_t freeBlocks;
initNotifiedFIFO_nothreadSafe(&freeBlocks);
+ NR_UE_MAC_INST_t *mac = get_mac_inst(0);
for (int i=0; iframe_parms.slots_per_subframe;
+ const int nb_slot_frame = UE->frame_parms.slots_per_frame;
int absolute_slot=0, decoded_frame_rx=INT_MAX, trashed_frames=0;
while (!oai_exit) {
@@ -656,11 +683,11 @@ void *UE_thread(void *arg) {
syncRunning=false;
syncData_t *tmp=(syncData_t *)NotifiedFifoData(res);
// shift the frame index with all the frames we trashed meanwhile we perform the synch search
- decoded_frame_rx=(tmp->proc.decoded_frame_rx+trashed_frames) % MAX_FRAME_NUMBER;
+ decoded_frame_rx=(tmp->proc.decoded_frame_rx + (!UE->init_sync_frame) + trashed_frames) % MAX_FRAME_NUMBER;
delNotifiedFIFO_elt(res);
} else {
- trashFrame(UE, ×tamp);
- trashed_frames++;
+ readFrame(UE, ×tamp, true);
+ trashed_frames+=2;
continue;
}
}
@@ -668,7 +695,7 @@ void *UE_thread(void *arg) {
AssertFatal( !syncRunning, "At this point synchronization can't be running\n");
if (!UE->is_synchronized) {
- readFrame(UE, ×tamp);
+ readFrame(UE, ×tamp, false);
notifiedFIFO_elt_t *Msg=newNotifiedFIFO_elt(sizeof(syncData_t),0,&nf,UE_synch);
syncData_t *syncMsg=(syncData_t *)NotifiedFifoData(Msg);
syncMsg->UE=UE;
@@ -695,7 +722,7 @@ void *UE_thread(void *arg) {
// and we shifted above to the first slot of next frame
decoded_frame_rx++;
// we do ++ first in the regular processing, so it will be begin of frame;
- absolute_slot=decoded_frame_rx*nb_slot_frame + nb_slot_frame -1;
+ absolute_slot=decoded_frame_rx*nb_slot_frame -1;
continue;
}
@@ -715,11 +742,11 @@ void *UE_thread(void *arg) {
curMsg->UE->current_thread_id[slot_nr] = thread_idx;
curMsg->proc.CC_id = 0;
curMsg->proc.nr_tti_rx= slot_nr;
- curMsg->proc.subframe_rx=table_sf_slot[slot_nr];
+ curMsg->proc.subframe_rx=slot_nr/(nb_slot_frame/10);
curMsg->proc.nr_tti_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame;
curMsg->proc.subframe_tx=curMsg->proc.nr_tti_rx;
- curMsg->proc.frame_rx = ( absolute_slot/nb_slot_frame ) % MAX_FRAME_NUMBER;
- curMsg->proc.frame_tx = ( (absolute_slot + DURATION_RX_TO_TX) /nb_slot_frame ) % MAX_FRAME_NUMBER;
+ curMsg->proc.frame_rx = ((absolute_slot/nb_slot_frame)+UE->frame_gap) % MAX_FRAME_NUMBER;
+ curMsg->proc.frame_tx = (((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame)+UE->frame_gap) % MAX_FRAME_NUMBER;
curMsg->proc.decoded_frame_rx=-1;
//LOG_I(PHY,"Process slot %d thread Idx %d total gain %d\n", slot_nr, thread_idx, UE->rx_total_gain_dB);
@@ -732,26 +759,25 @@ void *UE_thread(void *arg) {
}*/
#endif
+ int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms);
for (int i=0; iframe_parms.nb_antennas_rx; i++)
- rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+
- UE->frame_parms.nb_prefix_samples0+
- slot_nr*UE->frame_parms.samples_per_slot];
+ rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp+
+ UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,0)];
for (int i=0; iframe_parms.nb_antennas_tx; i++)
- txp[i] = (void *)&UE->common_vars.txdata[i][((curMsg->proc.nr_tti_rx + DURATION_RX_TO_TX)%nb_slot_frame)*UE->frame_parms.samples_per_slot];
+ txp[i] = (void *)&UE->common_vars.txdata[i][UE->frame_parms.get_samples_slot_timestamp(
+ ((curMsg->proc.nr_tti_rx + DURATION_RX_TO_TX)%nb_slot_frame),&UE->frame_parms,0)];
int readBlockSize, writeBlockSize;
if (slot_nr<(nb_slot_frame - 1)) {
- readBlockSize=UE->frame_parms.samples_per_slot;
- writeBlockSize=UE->frame_parms.samples_per_slot;
+ readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms);
+ writeBlockSize=UE->frame_parms.get_samples_per_slot(curMsg->proc.nr_tti_tx,&UE->frame_parms);
} else {
UE->rx_offset_diff = computeSamplesShift(UE);
- readBlockSize=UE->frame_parms.samples_per_slot -
- UE->frame_parms.ofdm_symbol_size -
- UE->frame_parms.nb_prefix_samples0 -
+ readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) -
UE->rx_offset_diff;
- writeBlockSize=UE->frame_parms.samples_per_slot -
+ writeBlockSize=UE->frame_parms.get_samples_per_slot(curMsg->proc.nr_tti_tx,&UE->frame_parms) -
UE->rx_offset_diff;
}
@@ -762,33 +788,20 @@ void *UE_thread(void *arg) {
readBlockSize,
UE->frame_parms.nb_antennas_rx),"");
- if (slot_nr == (20+NR_UPLINK_SLOT-DURATION_RX_TO_TX - 1)%20)
- AssertFatal( writeBlockSize ==
- UE->rfdevice.trx_write_func(&UE->rfdevice,
- timestamp+
- (DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot) -
- UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
- openair0_cfg[0].tx_sample_advance,
- txp,
- writeBlockSize,
- UE->frame_parms.nb_antennas_tx,
- 2),"");
-
- if (slot_nr == (20+NR_UPLINK_SLOT-DURATION_RX_TO_TX)%20)
- AssertFatal( writeBlockSize ==
- UE->rfdevice.trx_write_func(&UE->rfdevice,
- timestamp+
- (DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot) -
- UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
- openair0_cfg[0].tx_sample_advance,
- txp,
- writeBlockSize,
- UE->frame_parms.nb_antennas_tx,
- 3),"");
+ AssertFatal( writeBlockSize ==
+ UE->rfdevice.trx_write_func(&UE->rfdevice,
+ timestamp+
+ UE->frame_parms.get_samples_slot_timestamp(slot_nr,
+ &UE->frame_parms,DURATION_RX_TO_TX) - firstSymSamp -
+ openair0_cfg[0].tx_sample_advance,
+ txp,
+ writeBlockSize,
+ UE->frame_parms.nb_antennas_tx,
+ 1),"");
if( slot_nr==(nb_slot_frame-1)) {
// read in first symbol of next frame and adjust for timing drift
- int first_symbols=writeBlockSize-readBlockSize;
+ int first_symbols=UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0; // first symbol of every frames
if ( first_symbols > 0 )
AssertFatal(first_symbols ==
@@ -802,8 +815,9 @@ void *UE_thread(void *arg) {
}
curMsg->proc.timestamp_tx = timestamp+
- (DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot)-
- UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
+ UE->frame_parms.get_samples_slot_timestamp(slot_nr,
+ &UE->frame_parms,DURATION_RX_TO_TX) - firstSymSamp;
+
notifiedFIFO_elt_t *res;
while (nbSlotProcessing >= RX_NB_TH) {
@@ -812,7 +826,8 @@ void *UE_thread(void *arg) {
processingData_t *tmp=(processingData_t *)res->msgData;
if (tmp->proc.decoded_frame_rx != -1)
- decoded_frame_rx=tmp->proc.decoded_frame_rx;
+ decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
+ //decoded_frame_rx=tmp->proc.decoded_frame_rx;
pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
}
@@ -838,7 +853,8 @@ void *UE_thread(void *arg) {
processingData_t *tmp=(processingData_t *)res->msgData;
if (tmp->proc.decoded_frame_rx != -1)
- decoded_frame_rx=tmp->proc.decoded_frame_rx;
+ decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
+ //decoded_frame_rx=tmp->proc.decoded_frame_rx;
pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
}
@@ -847,30 +863,27 @@ void *UE_thread(void *arg) {
return NULL;
}
-void init_NR_UE(int nb_inst) {
+void init_NR_UE(int nb_inst, char* rrc_config_path) {
int inst;
NR_UE_MAC_INST_t *mac_inst;
+ NR_UE_RRC_INST_t* rrc_inst;
+
+ for (inst=0; inst < nb_inst; inst++) {
+ AssertFatal((rrc_inst = nr_l3_init_ue(rrc_config_path)) != NULL, "can not initialize RRC module\n");
+ AssertFatal((mac_inst = nr_l2_init_ue(rrc_inst)) != NULL, "can not initialize L2 module\n");
+ AssertFatal((mac_inst->if_module = nr_ue_if_module_init(inst)) != NULL, "can not initialize IF module\n");
+ }
+}
+
+void init_NR_UE_threads(int nb_inst) {
+ int inst;
+
pthread_t threads[nb_inst];
for (inst=0; inst < nb_inst; inst++) {
PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0];
- AssertFatal((UE->if_inst = nr_ue_if_module_init(inst)) != NULL, "can not initial IF module\n");
- nr_l3_init_ue();
- nr_l2_init_ue();
- mac_inst = get_mac_inst(inst);
- mac_inst->if_module = UE->if_inst;
- // Initial bandwidth part configuration -- full carrier bandwidth
- mac_inst->initial_bwp_dl.bwp_id = 0;
- mac_inst->initial_bwp_dl.location = 0;
- mac_inst->initial_bwp_dl.scs = UE->frame_parms.subcarrier_spacing;
- mac_inst->initial_bwp_dl.N_RB = UE->frame_parms.N_RB_DL;
- mac_inst->initial_bwp_dl.cyclic_prefix = UE->frame_parms.Ncp;
- mac_inst->initial_bwp_ul.bwp_id = 0;
- mac_inst->initial_bwp_ul.location = 0;
- mac_inst->initial_bwp_ul.scs = UE->frame_parms.subcarrier_spacing;
- mac_inst->initial_bwp_ul.N_RB = UE->frame_parms.N_RB_UL;
- mac_inst->initial_bwp_ul.cyclic_prefix = UE->frame_parms.Ncp;
- LOG_I(PHY,"Initializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
+
+ LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX);
#ifdef UE_DLSCH_PARALLELISATION
@@ -879,8 +892,6 @@ void init_NR_UE(int nb_inst) {
#endif
}
-
- printf("UE threads created by %ld\n", gettid());
}
/* HACK: this function is needed to compile the UE
@@ -895,4 +906,3 @@ int8_t find_dlsch(uint16_t rnti,
}
void multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP) {}
-
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 3efa8d098c..a269117ed8 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -133,7 +133,7 @@ static double snr_dB=20;
int threequarter_fs=0;
-uint32_t downlink_frequency[MAX_NUM_CCs][4];
+uint64_t downlink_frequency[MAX_NUM_CCs][4];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
//int32_t uplink_counter = 0;
@@ -221,6 +221,8 @@ tpool_t *Tpool;
char *usrp_args=NULL;
+char *rrc_config_path=NULL;
+
/* forward declarations */
void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
@@ -472,7 +474,7 @@ void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
for (CC_id=0; CC_ideutra_band = 78;
+ frame_parms[CC_id]->nr_band = 78;
frame_parms[CC_id]->frame_type = FDD;
frame_parms[CC_id]->tdd_config = 3;
//frame_parms[CC_id]->tdd_config_S = 0;
@@ -482,7 +484,7 @@ void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
//frame_parms[CC_id]->Ncp_UL = NORMAL;
frame_parms[CC_id]->Nid_cell = 0;
//frame_parms[CC_id]->num_MBSFN_config = 0;
- frame_parms[CC_id]->nb_antenna_ports_eNB = 1;
+ frame_parms[CC_id]->nb_antenna_ports_gNB = 1;
frame_parms[CC_id]->nb_antennas_tx = 1;
frame_parms[CC_id]->nb_antennas_rx = 1;
//frame_parms[CC_id]->nushift = 0;
@@ -500,8 +502,25 @@ void init_openair0(void) {
for (card=0; cardthreequarter_fs;
+ numerology = frame_parms[0]->numerology_index;
- if(frame_parms[0]->N_RB_DL == 217) {
+ if(frame_parms[0]->N_RB_DL == 66) {
+ if (numerology==3) {
+ openair0_cfg[card].sample_rate=122.88e6;
+ openair0_cfg[card].samples_per_frame = 1228800;
+ } else {
+ LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n");
+ exit(-1);
+ }
+ }else if(frame_parms[0]->N_RB_DL == 32) {
+ if (numerology==3) {
+ openair0_cfg[card].sample_rate=61.44e6;
+ openair0_cfg[card].samples_per_frame = 614400;
+ } else {
+ LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n");
+ exit(-1);
+ }
+ }else if(frame_parms[0]->N_RB_DL == 217) {
if (numerology==1) {
if (frame_parms[0]->threequarter_fs) {
openair0_cfg[card].sample_rate=92.16e6;
@@ -584,12 +603,12 @@ void init_openair0(void) {
for (i=0; i<4; i++) {
if (iul_CarrierFreq;
else
openair0_cfg[card].tx_freq[i]=0.0;
if (idl_CarrierFreq;
else
openair0_cfg[card].rx_freq[i]=0.0;
@@ -631,7 +650,7 @@ void init_pdcp(void) {
}
// Stupid function addition because UE itti messages queues definition is common with eNB
-void *rrc_enb_process_itti_msg(void *notUsed) {
+void *rrc_enb_process_msg(void *notUsed) {
return NULL;
}
@@ -674,35 +693,28 @@ int main( int argc, char **argv ) {
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
init_opt() ;
- if(IS_SOFTMODEM_NOS1)
- init_pdcp();
+ load_nrLDPClib();
if (ouput_vcd) {
vcd_signal_dumper_init("/tmp/openair_dump_nrUE.vcd");
}
- /*
- #ifdef PDCP_USE_NETLINK
- netlink_init();
- #if defined(PDCP_USE_NETLINK_QUEUES)
- pdcp_netlink_init();
- #endif
- #endif
- */
-#ifndef PACKAGE_VERSION
+ #ifndef PACKAGE_VERSION
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
#endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
- // init the parameters
- for (int CC_id=0; CC_idnb_antennas_tx = nb_antenna_tx;
- frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx;
- frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later
- frame_parms[CC_id]->threequarter_fs = threequarter_fs;
- LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx);
- get_band(downlink_frequency[CC_id][0], &frame_parms[CC_id]->eutra_band, &uplink_frequency_offset[CC_id][0], &frame_parms[CC_id]->frame_type);
- }
+ init_NR_UE(1,rrc_config_path);
+ if(IS_SOFTMODEM_NOS1)
+ init_pdcp();
+/*
+#ifdef PDCP_USE_NETLINK
+ netlink_init();
+#if defined(PDCP_USE_NETLINK_QUEUES)
+ pdcp_netlink_init();
+#endif
+#endif
+*/
NB_UE_INST=1;
NB_INST=1;
@@ -710,17 +722,38 @@ int main( int argc, char **argv ) {
PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE *)*MAX_NUM_CCs);
for (int CC_id=0; CC_idofdm_symbol_size);
- nr_init_frame_parms_ue(frame_parms[CC_id],numerology,NORMAL,frame_parms[CC_id]->N_RB_DL,(frame_parms[CC_id]->N_RB_DL-20)>>1,0);
- PHY_vars_UE_g[0][CC_id] = init_nr_ue_vars(frame_parms[CC_id], 0,abstraction_flag);
- UE[CC_id] = PHY_vars_UE_g[0][CC_id];
+ printf("frame_parms %d\n",frame_parms[CC_id]->ofdm_symbol_size);
+ frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx;
+ frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx;
+ frame_parms[CC_id]->nb_antenna_ports_gNB = 1; //initial value overwritten by initial sync later
+ frame_parms[CC_id]->threequarter_fs = threequarter_fs;
+ LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx);
+ PHY_vars_UE_g[0][CC_id] = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE));
+
+ UE[CC_id] = PHY_vars_UE_g[0][CC_id];
+ memset(UE[CC_id],0,sizeof(PHY_VARS_NR_UE));
+
+ NR_UE_MAC_INST_t *mac = get_mac_inst(0);
+ if(mac->if_module != NULL && mac->if_module->phy_config_request != NULL)
+ mac->if_module->phy_config_request(&mac->phy_config);
+
+ fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config;
+ nr_init_frame_parms_ue(frame_parms[CC_id],nrUE_config,NORMAL);
+
+ // Overwrite DL frequency (for FR2 testing)
+ if (downlink_frequency[0][0]!=0)
+ frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0];
+
+ init_nr_ue_vars(UE[CC_id],frame_parms[CC_id],0,abstraction_flag);
if (get_softmodem_params()->phy_test==1)
UE[CC_id]->mac_enabled = 0;
else
UE[CC_id]->mac_enabled = 1;
+ UE[CC_id]->mac_enabled = 1;
+ UE[CC_id]->if_inst = nr_ue_if_module_init(0);
UE[CC_id]->UE_scan = UE_scan;
UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
UE[CC_id]->UE_fo_compensation = UE_fo_compensation;
@@ -728,13 +761,6 @@ int main( int argc, char **argv ) {
UE[CC_id]->no_timing_correction = UE_no_timing_correction;
printf("UE[%d]->mode = %d\n",CC_id,mode);
- for (uint8_t i=0; imac_enabled == 1)
- UE[CC_id]->pdcch_vars[i][0]->crnti = 0x1234;
- else
- UE[CC_id]->pdcch_vars[i][0]->crnti = 0x1235;
- }
-
UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off;
UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
@@ -769,11 +795,14 @@ int main( int argc, char **argv ) {
#else
PHY_vars_UE_g[0][CC_id]->hw_timing_advance = 160;
#endif
+
}
+ init_NR_UE_threads(1);
+ printf("UE threads created by %ld\n", gettid());
+
// wait for end of program
printf("TYPE TO TERMINATE\n");
- init_NR_UE(1);
while(true)
sleep(3600);
diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h
index 38c4c1b607..7fad43e897 100644
--- a/executables/nr-uesoftmodem.h
+++ b/executables/nr-uesoftmodem.h
@@ -54,8 +54,6 @@
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0} \
}
-#define DEFAULT_DLF 2680000000
-
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters common to eNodeB and UE */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
@@ -65,7 +63,7 @@
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
- {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \
+ {"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:0,TYPE_UINT64, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:&do_forms, defintval:0, TYPE_INT, 0}, \
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \
@@ -74,13 +72,14 @@
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \
- {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \
+ {"numerology" , CONFIG_HLP_NUMEROLOGY, 0, iptr:&numerology, defintval:0, TYPE_INT, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0}, \
- {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&UE_no_timing_correction, defintval:0, TYPE_INT, 0} \
+ {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&UE_no_timing_correction, defintval:0, TYPE_INT, 0}, \
+ {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:(char **)&rrc_config_path, defstrval:"./", TYPE_STRING, 0} \
}
@@ -92,11 +91,12 @@ extern int T_dont_fork;
// In nr-ue.c
extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
extern void fill_ue_band_info(void);
-extern void init_NR_UE(int);
+extern void init_NR_UE(int, char*);
+extern void init_NR_UE_threads(int);
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
void *UE_thread(void *arg);
-PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag);
+void init_nr_ue_vars(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag);
extern tpool_t *Tpool;
extern tpool_t *Tpool_dl;
#endif
diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c
index 83380f8267..04a58413b5 100644
--- a/executables/softmodem-common.c
+++ b/executables/softmodem-common.c
@@ -144,7 +144,6 @@ void get_common_options(uint32_t execmask) {
if(worker_config != NULL) set_worker_conf(worker_config);
}
-
void softmodem_printresources(int sig, telnet_printfunc_t pf) {
struct rusage usage;
struct timespec stop;
@@ -204,3 +203,4 @@ void set_softmodem_sighandler(void) {
signal(SIGTERM, signal_handler);
signal(SIGABRT, signal_handler);
}
+
diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h
index a59b0f59b9..b16a14fc66 100644
--- a/executables/softmodem-common.h
+++ b/executables/softmodem-common.h
@@ -117,7 +117,7 @@ extern "C"
{"clock", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \
{"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG, defintval:0, TYPE_INT, 0}, \
- {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \
+ {"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:0, TYPE_UINT64, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
@@ -198,7 +198,7 @@ extern "C"
typedef struct {
uint64_t optmask;
- THREAD_STRUCT thread_struct;
+ //THREAD_STRUCT thread_struct;
char rf_config_file[1024];
char split73[1024];
char threadPoolConfig[1024];
@@ -223,7 +223,7 @@ extern void get_common_options(uint32_t execmask);
extern char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr);
#define SOFTMODEM_RTSIGNAL (SIGRTMIN+1)
extern void set_softmodem_sighandler(void);
-extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
+extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
#ifdef __cplusplus
}
#endif
diff --git a/executables/uecap.raw b/executables/uecap.raw
new file mode 100644
index 0000000000..01c03d225a
Binary files /dev/null and b/executables/uecap.raw differ
diff --git a/nfapi/oai_integration/nfapi_pnf.h b/nfapi/oai_integration/nfapi_pnf.h
index e213d785f1..2c8201737c 100644
--- a/nfapi/oai_integration/nfapi_pnf.h
+++ b/nfapi/oai_integration/nfapi_pnf.h
@@ -23,5 +23,5 @@
#define NFAPI_PNF_H__
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
-
+void oai_subframe_ind(uint16_t sfn, uint16_t sf);
#endif
diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c
index a0574221f5..7ab8be5746 100644
--- a/nfapi/oai_integration/nfapi_vnf.c
+++ b/nfapi/oai_integration/nfapi_vnf.c
@@ -31,7 +31,7 @@
#include
#include
-#include "nfapi_nr_interface.h"
+#include "nfapi_nr_interface_scf.h"
#include "nfapi_vnf_interface.h"
#include "nfapi.h"
#include "vendor_ext.h"
@@ -1169,7 +1169,7 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) {
return retval;
}
-int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req)
+int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_tti_request_t *dl_config_req)
{
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
@@ -1177,9 +1177,9 @@ int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req)
int retval = nfapi_vnf_p7_nr_dl_config_req(p7_config, dl_config_req);
- dl_config_req->dl_config_request_body.number_dci = 0;
- dl_config_req->dl_config_request_body.number_pdu = 0;
- dl_config_req->dl_config_request_body.number_pdsch_rnti = 0;
+ dl_config_req->dl_tti_request_body.nPDUs = 0;
+ dl_config_req->dl_tti_request_body.nGroup = 0;
+
if (retval!=0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
index babcc6404f..cbcd26c3e3 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
@@ -8,6 +8,9 @@
#define FAPI_NR_MAX_NUM_ZP_CSI_RS_RESOURCE_PER_SET 16
#define FAPI_NR_MAX_NUM_CANDIDATE_BEAMS 16
#define FAPI_NR_MAX_RA_OCCASION_PER_CSIRS 64
+// Constants Defined in 38.213
+#define FAPI_NR_MAX_CORESET_PER_BWP 3
+#define FAPI_NR_MAX_SS_PER_CORESET 10
/// RX_IND
@@ -41,8 +44,8 @@
#define FAPI_NR_DL_CONFIG_TYPE_DLSCH 0x02
-#define CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01
-#define CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02
+#define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01
+#define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02
#define PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE 0x01
#define PRECODER_GRANULARITY_ALL_CONTIGUOUS_RBS 0x02
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
index 838e52dada..576144e1df 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
@@ -1,5 +1,4 @@
-/*
- * Copyright 2017 Cisco Systems, Inc.
+/*Copyright 2017 Cisco Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,77 +31,7 @@
typedef signed char int8_t;
*/
-typedef struct {
- uint8_t identifier_dci_formats ; // 0 IDENTIFIER_DCI_FORMATS:
- uint8_t carrier_ind ; // 1 CARRIER_IND: 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213]
- uint8_t sul_ind_0_1 ; // 2 SUL_IND_0_1:
- uint8_t slot_format_ind ; // 3 SLOT_FORMAT_IND: size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213]
- uint8_t pre_emption_ind ; // 4 PRE_EMPTION_IND: size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits
- uint8_t block_number ; // 5 BLOCK_NUMBER: starting position of a block is determined by the parameter startingBitOfFormat2_3
- uint8_t close_loop_ind ; // 6 CLOSE_LOOP_IND:
- uint8_t bandwidth_part_ind ; // 7 BANDWIDTH_PART_IND:
- uint8_t short_message_ind ; // 8 SHORT_MESSAGE_IND:
- uint8_t short_messages ; // 9 SHORT_MESSAGES:
- uint16_t freq_dom_resource_assignment_UL; // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered
- // (NOTE 1) If DCI format 0_0 is monitored in common search space
- // and if the number of information bits in the DCI format 0_0 prior to padding
- // is larger than the payload size of the DCI format 1_0 monitored in common search space
- // the bitwidth of the frequency domain resource allocation field in the DCI format 0_0
- // is reduced such that the size of DCI format 0_0 equals to the size of the DCI format 1_0
- uint16_t freq_dom_resource_assignment_DL; // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL:
- uint8_t time_dom_resource_assignment ; // 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits,
- // where I the number of entries in the higher layer parameter pusch-AllocationList
- uint8_t vrb_to_prb_mapping ; // 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0
- uint8_t prb_bundling_size_ind ; // 14 PRB_BUNDLING_SIZE_IND:0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214]
- uint8_t rate_matching_ind ; // 15 RATE_MATCHING_IND: 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set
- uint8_t zp_csi_rs_trigger ; // 16 ZP_CSI_RS_TRIGGER:
- uint8_t freq_hopping_flag ; // 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0
- uint8_t tb1_mcs ; // 18 TB1_MCS:
- uint8_t tb1_ndi ; // 19 TB1_NDI:
- uint8_t tb1_rv ; // 20 TB1_RV:
- uint8_t tb2_mcs ; // 21 TB2_MCS:
- uint8_t tb2_ndi ; // 22 TB2_NDI:
- uint8_t tb2_rv ; // 23 TB2_RV:
- uint8_t mcs ; // 24 MCS:
- uint8_t ndi ; // 25 NDI:
- uint8_t rv ; // 26 RV:
- uint8_t harq_process_number ; // 27 HARQ_PROCESS_NUMBER:
- uint8_t dai ; // 28 DAI: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI
- // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI
- // 0 otherwise
- uint8_t first_dai ; // 29 FIRST_DAI: (1 or 2 bits) 1 bit for semi-static HARQ-ACK
- uint8_t second_dai ; // 30 SECOND_DAI: (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks
- uint8_t tb_scaling ; // 31 TB_SCALING:
- uint8_t tpc_pusch ; // 32 TPC_PUSCH:
- uint8_t tpc_pucch ; // 33 TPC_PUCCH:
- uint8_t pucch_resource_ind ; // 34 PUCCH_RESOURCE_IND:
- uint8_t pdsch_to_harq_feedback_time_ind ; // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND:
- uint8_t srs_resource_ind ; // 36 SRS_RESOURCE_IND:
- uint8_t precod_nbr_layers ; // 37 PRECOD_NBR_LAYERS:
- uint8_t antenna_ports ; // 38 ANTENNA_PORTS:
- uint8_t tci ; // 39 TCI: 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits
- uint8_t srs_request ; // 40 SRS_REQUEST:
- uint8_t tpc_cmd ; // 41 TPC_CMD:
- uint8_t csi_request ; // 42 CSI_REQUEST:
- uint8_t cbgti ; // 43 CBGTI: 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH
- uint8_t cbgfi ; // 44 CBGFI: 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator
- uint8_t ptrs_dmrs ; // 45 PTRS_DMRS:
- uint8_t beta_offset_ind ; // 46 BETA_OFFSET_IND:
- uint8_t dmrs_seq_ini ; // 47 DMRS_SEQ_INI: 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding
- // is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise
- uint8_t ul_sch_ind ; // 48 UL_SCH_IND: value of "1" indicates UL-SCH shall be transmitted on the PUSCH and a value of "0" indicates UL-SCH shall not be transmitted on the PUSCH
- uint16_t padding_nr_dci ; // 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space
- // and if the number of information bits in the DCI format 0_0 prior to padding
- // is less than the payload size of the DCI format 1_0 monitored in common search space
- // zeros shall be appended to the DCI format 0_0
- // until the payload size equals that of the DCI format 1_0
- uint8_t sul_ind_0_0 ; // 50 SUL_IND_0_0:
- uint8_t ra_preamble_index ; // 51 RA_PREAMBLE_INDEX:
- uint8_t sul_ind_1_0 ; // 52 SUL_IND_1_0:
- uint8_t ss_pbch_index ; // 53 SS_PBCH_INDEX
- uint8_t prach_mask_index ; // 54 PRACH_MASK_INDEX
- uint8_t reserved_nr_dci ; // 55 RESERVED_NR_DCI
-} fapi_nr_dci_pdu_rel15_t;
+
@@ -121,16 +50,14 @@ typedef struct {
typedef struct {
/// frequency_domain_resource;
- //uint32_t rb_start;
- //uint32_t rb_end;
- uint64_t frequency_domain_resource;
- uint16_t rb_offset;
-
+ uint8_t frequency_domain_resource[6];
+ uint8_t StartSymbolIndex;
uint8_t duration;
- uint8_t cce_reg_mapping_type; // interleaved or noninterleaved
- uint8_t cce_reg_interleaved_reg_bundle_size; // valid if CCE to REG mapping type is interleaved type
- uint8_t cce_reg_interleaved_interleaver_size; // valid if CCE to REG mapping type is interleaved type
- uint8_t cce_reg_interleaved_shift_index; // valid if CCE to REG mapping type is interleaved type
+ uint8_t CceRegMappingType; // interleaved or noninterleaved
+ uint8_t RegBundleSize; // valid if CCE to REG mapping type is interleaved type
+ uint8_t InterleaverSize; // valid if CCE to REG mapping type is interleaved type
+ uint8_t ShiftIndex; // valid if CCE to REG mapping type is interleaved type
+ uint8_t CoreSetType;
uint8_t precoder_granularity;
uint16_t pdcch_dmrs_scrambling_id;
@@ -155,13 +82,16 @@ typedef struct {
int n_CCE;
// N_CCE is L, or number of CCEs for DCI
int N_CCE;
- fapi_nr_dci_pdu_rel15_t dci;
+ uint8_t payloadSize;
+ uint8_t payloadBits[16];
+ //fapi_nr_dci_pdu_rel15_t dci;
} fapi_nr_dci_indication_pdu_t;
///
typedef struct {
- uint32_t sfn_slot;
+ uint16_t SFN;
+ uint8_t slot;
uint16_t number_of_dcis;
fapi_nr_dci_indication_pdu_t dci_list[10];
} fapi_nr_dci_indication_t;
@@ -199,7 +129,8 @@ typedef struct {
///
#define NFAPI_RX_IND_MAX_PDU 100
typedef struct {
- uint32_t sfn_slot;
+ uint16_t sfn;
+ uint16_t slot;
uint16_t number_pdus;
fapi_nr_rx_indication_body_t rx_indication_body[NFAPI_RX_IND_MAX_PDU];
} fapi_nr_rx_indication_t;
@@ -218,7 +149,8 @@ typedef struct {
///
typedef struct {
- uint32_t sfn_slot;
+ uint16_t sfn;
+ uint16_t slot;
fapi_nr_tx_config_t tx_config;
uint16_t number_of_pdus;
fapi_nr_tx_request_body_t *tx_request_body;
@@ -374,7 +306,8 @@ typedef struct {
} fapi_nr_ul_config_request_pdu_t;
typedef struct {
- uint32_t sfn_slot;
+ uint16_t sfn;
+ uint16_t slot;
uint8_t number_pdus;
fapi_nr_ul_config_request_pdu_t ul_config_list[FAPI_NR_UL_CONFIG_LIST_NUM];
} fapi_nr_ul_config_request_t;
@@ -382,16 +315,15 @@ typedef struct {
typedef struct {
uint16_t rnti;
-
+ uint16_t BWPSize;
+ uint16_t BWPStart;
+ uint8_t SubcarrierSpacing;
fapi_nr_coreset_t coreset;
- uint16_t N_RB_BWP;
- uint32_t duration;
- uint8_t number_of_candidates[5]; // aggregation level 1, 2, 4, 8, 16
- uint16_t monitoring_symbols_within_slot;
- // DCI foramt-specific
- uint8_t format_2_0_number_of_candidates[5]; // aggregation level 1, 2, 4, 8, 16
- uint8_t format_2_3_monitorying_periodicity;
- uint8_t format_2_3_number_of_candidates;
+ uint8_t number_of_candidates;
+ uint16_t CCE[64];
+ uint8_t L[64];
+ uint8_t dci_length;
+ uint8_t dci_format;
} fapi_nr_dl_config_dci_dl_pdu_rel15_t;
typedef struct {
@@ -404,12 +336,16 @@ typedef struct{
typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interleaved = 1} vrb_to_prb_mapping_t;
//typedef fapi_nr_dci_pdu_rel15_t fapi_nr_dl_config_dlsch_pdu_rel15_t;
typedef struct {
- uint8_t bandwidth_part_ind;
+ uint16_t BWPSize;
+ uint16_t BWPStart;
+ uint8_t SubcarrierSpacing;
uint16_t number_rbs;
uint16_t start_rb;
uint8_t frame_offset;
uint16_t number_symbols;
uint16_t start_symbol;
+ uint16_t dlDmrsSymbPos;
+ uint8_t dmrsConfigType;
uint8_t prb_bundling_size_ind;
uint8_t rate_matching_ind;
uint8_t zp_csi_rs_trigger;
@@ -450,7 +386,8 @@ typedef struct {
} fapi_nr_dl_config_request_pdu_t;
typedef struct {
- uint32_t sfn_slot;
+ uint16_t sfn;
+ uint16_t slot;
uint8_t number_pdus;
fapi_nr_dl_config_request_pdu_t dl_config_list[FAPI_NR_DL_CONFIG_LIST_NUM];
} fapi_nr_dl_config_request_t;
@@ -544,20 +481,6 @@ typedef struct {
uint8_t p0_nominal;
} fapi_nr_pucch_config_common_t;
-typedef struct {
-
- uint8_t subcarrier_spacing_common;
- uint8_t ssb_subcarrier_offset;
- uint8_t dmrs_type_a_position;
- uint8_t pdcch_config_sib1;
- uint8_t cell_barred;
- uint8_t intra_frequency_reselection;
-
- uint16_t system_frame_number;
- uint8_t ssb_index;
- uint8_t half_frame_bit;
-} fapi_nr_pbch_config_t;
-
typedef struct {
fapi_nr_pdcch_config_common_t pdcch_config_common;
@@ -907,10 +830,115 @@ typedef struct {
#define FAPI_NR_CONFIG_REQUEST_MASK_DL_BWP_DEDICATED 0x08
#define FAPI_NR_CONFIG_REQUEST_MASK_UL_BWP_DEDICATED 0x10
+typedef struct
+{
+ uint16_t dl_bandwidth;//Carrier bandwidth for DL in MHz [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400
+ uint32_t dl_frequency; //Absolute frequency of DL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000
+ uint16_t dl_k0[5];//𝑘_{0}^{𝜇} for each of the numerologies [38.211, sec 5.3.1] Value: 0 ->23699
+ uint16_t dl_grid_size[5];//Grid size 𝑁_{𝑔𝑟𝑖𝑑}^{𝑠𝑖𝑧𝑒,𝜇} for each of the numerologies [38.211, sec 4.4.2] Value: 0->275 0 = this numerology not used
+ uint16_t num_tx_ant;//Number of Tx antennas
+ uint16_t uplink_bandwidth;//Carrier bandwidth for UL in MHz. [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400
+ uint32_t uplink_frequency;//Absolute frequency of UL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000
+ uint16_t ul_k0[5];//𝑘0 𝜇 for each of the numerologies [38.211, sec 5.3.1] Value: : 0 ->23699
+ uint16_t ul_grid_size[5];//Grid size 𝑁𝑔𝑟𝑖𝑑 𝑠𝑖𝑧𝑒,𝜇 for each of the numerologies [38.211, sec 4.4.2]. Value: 0->275 0 = this numerology not used
+ uint16_t num_rx_ant;//
+ uint8_t frequency_shift_7p5khz;//Indicates presence of 7.5KHz frequency shift. Value: 0 = false 1 = true
+
+} fapi_nr_ue_carrier_config_t;
+
+typedef struct
+{
+ uint8_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007
+ uint8_t frame_duplex_type;//Frame duplex type Value: 0 = FDD 1 = TDD
+
+} fapi_nr_cell_config_t;
+
+typedef struct
+{
+ uint32_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
+ uint8_t bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload
+ uint8_t scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3
+
+} fapi_nr_ssb_config_t;
+
+typedef struct
+{
+ uint32_t ssb_mask;//Bitmap for actually transmitted SSB. MSB->LSB of first 32 bit number corresponds to SSB 0 to SSB 31 MSB->LSB of second 32 bit number corresponds to SSB 32 to SSB 63 Value for each bit: 0: not transmitted 1: transmitted
+
+} fapi_nr_ssb_mask_size_2_t;
+
+typedef struct
+{
+ int8_t beam_id[64];//BeamID for each SSB in SsbMask. For example, if SSB mask bit 26 is set to 1, then BeamId[26] will be used to indicate beam ID of SSB 26. Value: from 0 to 63
+
+} fapi_nr_ssb_mask_size_64_t;
+
+typedef struct
+{
+ uint16_t ssb_offset_point_a;//Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Given in PRB [38.211, section 4.4.4.2] Value: 0->2199
+ uint8_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block [38.213, sec 4.1] Values: 0 = 0dB
+ uint8_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160
+ uint8_t ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31
+ uint32_t MIB;//MIB payload, where the 24 MSB are used and represent the MIB in [38.331 MIB IE] and represent 0 1 2 3 1 , , , ,..., A− a a a a a [38.212, sec 7.1.1]
+ fapi_nr_ssb_mask_size_2_t ssb_mask_list[2];
+ fapi_nr_ssb_mask_size_64_t* ssb_beam_id_list;//64
+ uint8_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled
+ uint8_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled
+
+} fapi_nr_ssb_table_t;
+
+typedef struct
+{
+ uint8_t slot_config;//For each symbol in each slot a uint8_t value is provided indicating: 0: DL slot 1: UL slot 2: Guard slot
+
+} fapi_nr_max_num_of_symbol_per_slot_t;
+
+typedef struct
+{
+ fapi_nr_max_num_of_symbol_per_slot_t* max_num_of_symbol_per_slot_list;
+
+} fapi_nr_max_tdd_periodicity_t;
+
+typedef struct
+{
+ uint8_t tdd_period;//DL UL Transmission Periodicity. Value:0: ms0p5 1: ms0p625 2: ms1 3: ms1p25 4: ms2 5: ms2p5 6: ms5 7: ms10 8: ms3 9: ms4
+ fapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list;
+
+} fapi_nr_tdd_table_t;
+
+typedef struct
+{
+ uint8_t num_prach_fd_occasions;
+ uint16_t prach_root_sequence_index;//Starting logical root sequence index, 𝑖, equivalent to higher layer parameter prach-RootSequenceIndex [38.211, sec 6.3.3.1] Value: 0 -> 837
+ uint8_t num_root_sequences;//Number of root sequences for a particular FD occasion that are required to generate the necessary number of preambles
+ uint16_t k1;//Frequency offset (from UL bandwidth part) for each FD. [38.211, sec 6.3.3.2] Value: from 0 to 272
+ uint8_t prach_zero_corr_conf;//PRACH Zero CorrelationZone Config which is used to dervive 𝑁𝑐𝑠 [38.211, sec 6.3.3.1] Value: from 0 to 15
+ uint8_t num_unused_root_sequences;//Number of unused sequences available for noise estimation per FD occasion. At least one unused root sequence is required per FD occasion.
+ uint8_t* unused_root_sequences_list;//Unused root sequence or sequences per FD occasion. Required for noise estimation.
+
+} fapi_nr_num_prach_fd_occasions_t;
+
+typedef struct
+{
+ uint8_t prach_sequence_length;//RACH sequence length. Only short sequence length is supported for FR2. [38.211, sec 6.3.3.1] Value: 0 = Long sequence 1 = Short sequence
+ uint8_t prach_sub_c_spacing;//Subcarrier spacing of PRACH. [38.211 sec 4.2] Value:0->4
+ uint8_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B
+ uint8_t num_prach_fd_occasions;//Corresponds to the parameter 𝑀 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8
+ fapi_nr_num_prach_fd_occasions_t* num_prach_fd_occasions_list;
+ uint8_t ssb_per_rach;//SSB-per-RACH-occasion Value: 0: 1/8 1:1/4, 2:1/2 3:1 4:2 5:4, 6:8 7:16
+ uint8_t prach_multiple_carriers_in_a_band;//0 = disabled 1 = enabled
+
+} fapi_nr_prach_config_t;
+
typedef struct {
uint32_t config_mask;
- fapi_nr_pbch_config_t pbch_config; // MIB
+ fapi_nr_ue_carrier_config_t carrier_config;
+ fapi_nr_cell_config_t cell_config;
+ fapi_nr_ssb_config_t ssb_config;
+ fapi_nr_ssb_table_t ssb_table;
+ fapi_nr_tdd_table_t tdd_table;
+ fapi_nr_prach_config_t prach_config;
fapi_nr_dl_bwp_common_config_t dl_bwp_common;
fapi_nr_dl_bwp_dedicated_config_t dl_bwp_dedicated;
@@ -921,3 +949,4 @@ typedef struct {
} fapi_nr_config_request_t;
#endif
+
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
index a6cb7262a4..650bda4f78 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
@@ -10,44 +10,18 @@
#define _NFAPI_NR_INTERFACE_H_
#include "nfapi_interface.h"
-
+#include
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
#define NFAPI_NR_MAX_NB_CORESETS 12
#define NFAPI_NR_MAX_NB_SEARCH_SPACES 40
-// Extension to the generic structures for single tlv values
-typedef struct {
- nfapi_tl_t tl;
- int32_t value;
-} nfapi_int32_tlv_t;
-typedef struct {
- nfapi_tl_t tl;
- uint32_t value;
-} nfapi_uint32_tlv_t;
-
-/*typedef struct {
- nfapi_tl_t tl;
- int64_t value;
-} nfapi_int64_tlv_t;*/
-
-typedef struct {
- nfapi_tl_t tl;
- uint64_t value;
-} nfapi_uint64_tlv_t;
// nFAPI enums
-typedef enum {
- NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE = 0,
- NFAPI_NR_DL_CONFIG_BCH_PDU_TYPE,
- NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE,
- NFAPI_NR_DL_CONFIG_PCH_PDU_TYPE,
- NFAPI_NR_DL_CONFIG_NBCH_PDU_TYPE,
- NFAPI_NR_DL_CONFIG_NPDCCH_PDU_TYPE,
- NFAPI_NR_DL_CONFIG_NDLSCH_PDU_TYPE
-} nfapi_nr_dl_config_pdu_type_e;
+
+
//These TLVs are used exclusively by nFAPI
typedef struct
@@ -106,37 +80,6 @@ typedef struct
// P5 Message Structures
-typedef struct{
- nfapi_tl_t tl;
- uint16_t corset_ID; ///// L1 parameter 'CORESET-ID'
- uint16_t freq_dom; ///// L1 parameter 'CORESET-freq-dom'
- uint16_t duration; ///// L1 parameter 'CORESET-time-duration'
- uint16_t reg_type; ///// L1 parameter 'CORESET-CCE-REG-mapping-type'
- uint16_t reg_bundlesize; ///// L1 parameter 'CORESET-REG-bundle-size'
- uint16_t interleaversize; ///// L1 parameter 'CORESET-interleaver-size'
- uint16_t shiftindex; ///// L1 parameter 'CORESET-shift-index'
- uint16_t precodergranularity; ///// L1 parameter 'CORESET-precoder-granuality'
- uint16_t tci_stateId; ///// L1 parameter 'TCI-StatesPDCCH'
- uint16_t tci_present; ///// L1 parameter 'TCI-PresentInDCI'
- uint16_t dmrs_scramblingID; ///// L1 parameter 'PDCCH-DMRS-Scrambling-ID'
-} nfapi_nr_ControlResourcesSet_t;
-
-typedef struct{
- nfapi_tl_t tl;
- nfapi_nr_ControlResourcesSet_t coreset;
- uint16_t monitoringSlotPeriodicityAndOffset; ///// L1 parameters 'Montoring-periodicity-PDCCH-slot'
- uint16_t monitoringSymbolsWithinSlot; ///// L1 parameter 'Montoring-symbols-PDCCH-within-slot'
- uint16_t nrofCand_aggLevel1; ///// L1 parameter 'Aggregation-level-1'
- uint16_t nrofCand_aggLevel2; ///// L1 parameter 'Aggregation-level-2'
- uint16_t nrofCand_aggLevel4; ///// L1 parameter 'Aggregation-level-4'
- uint16_t nrofCand_aggLevel8; ///// L1 parameter 'Aggregation-level-8'
- uint16_t nrofCand_aggLevel16; ///// L1 parameter 'Aggregation-level-16'
- uint16_t sfi_agg_fmt2_0; ///// L1 parameters 'SFI-Num-PDCCH-cand' and 'SFI-Aggregation-Level'
- uint16_t monitoringperiodicity_fmt2_3; ///// L1 parameter 'SRS-monitoring-periodicity'
- uint16_t nrof_candidates_fmt_2_3; ///// L1 parameter 'SRS-Num-PDCCH-cand'
-} nfapi_nr_SearchSpace_t;
-
-
typedef struct {
nfapi_uint16_tlv_t numerology_index_mu;
nfapi_uint16_tlv_t duplex_mode;
@@ -154,10 +97,6 @@ typedef struct {
typedef struct {
nfapi_uint16_tlv_t dl_carrier_bandwidth;
nfapi_uint16_tlv_t ul_carrier_bandwidth;
- nfapi_uint16_tlv_t dl_bwp_subcarrierspacing;
- nfapi_uint16_tlv_t ul_bwp_subcarrierspacing;
- nfapi_uint16_tlv_t dl_locationandbandwidth;
- nfapi_uint16_tlv_t ul_locationandbandwidth;
nfapi_uint16_tlv_t dl_absolutefrequencypointA;
nfapi_uint16_tlv_t ul_absolutefrequencypointA;
nfapi_uint16_tlv_t dl_offsettocarrier;
@@ -173,6 +112,8 @@ typedef struct {
#define NFAPI_NR_RF_CONFIG_UL_CARRIER_BANDWIDTH_TAG 0x500B
#define NFAPI_NR_RF_CONFIG_DL_SUBCARRIERSPACING_TAG 0x500C
#define NFAPI_NR_RF_CONFIG_UL_SUBCARRIERSPACING_TAG 0x500D
+#define NFAPI_NR_RF_CONFIG_DL_OFFSETTOCARRIER_TAG 0x500E
+#define NFAPI_NR_RF_CONFIG_UL_OFFSETTOCARRIER_TAG 0x500F
typedef struct {
nfapi_uint16_tlv_t physical_cell_id;
@@ -183,9 +124,25 @@ typedef struct {
nfapi_uint16_tlv_t ssb_periodicity;
nfapi_uint16_tlv_t ss_pbch_block_power;
nfapi_uint16_tlv_t n_ssb_crb;
- nfapi_uint16_tlv_t rmsi_pdcch_config;
} nfapi_nr_sch_config_t;
+typedef struct {
+ nfapi_uint16_tlv_t dl_bandwidth;
+ nfapi_uint16_tlv_t ul_bandwidth;
+ nfapi_uint16_tlv_t dl_offset;
+ nfapi_uint16_tlv_t ul_offset;
+ nfapi_uint16_tlv_t dl_subcarrierSpacing;
+ nfapi_uint16_tlv_t ul_subcarrierSpacing;
+} nfapi_nr_initialBWP_config_t;
+
+#define NFAPI_INITIALBWP_DL_BANDWIDTH_TAG 0x5010
+#define NFAPI_INITIALBWP_DL_OFFSET_TAG 0x5011
+#define NFAPI_INITIALBWP_DL_SUBCARRIERSPACING_TAG 0x5012
+#define NFAPI_INITIALBWP_UL_BANDWIDTH_TAG 0x5013
+#define NFAPI_INITIALBWP_UL_OFFSET_TAG 0x5014
+#define NFAPI_INITIALBWP_UL_SUBCARRIERSPACING_TAG 0x5015
+
+
#define NFAPI_NR_SCH_CONFIG_PHYSICAL_CELL_ID_TAG 0x501E
#define NFAPI_NR_SCH_CONFIG_HALF_FRAME_INDEX_TAG 0x501F
#define NFAPI_NR_SCH_CONFIG_SSB_SUBCARRIER_OFFSET_TAG 0x5020
@@ -193,25 +150,15 @@ typedef struct {
#define NFAPI_NR_SCH_CONFIG_SSB_PERIODICITY 0x5022
#define NFAPI_NR_SCH_CONFIG_SS_PBCH_BLOCK_POWER 0x5023
#define NFAPI_NR_SCH_CONFIG_N_SSB_CRB 0x5024
+#define NFAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS 16
+#define NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS 16
typedef struct {
- nfapi_uint16_tlv_t data_scrambling_id;
- nfapi_uint16_tlv_t dmrs_typeA_position;
- nfapi_uint16_tlv_t dmrs_additional_position;
- nfapi_uint16_tlv_t dmrs_type;
- nfapi_uint16_tlv_t dmrs_max_length;
- nfapi_uint16_tlv_t mapping_type;
- nfapi_uint16_tlv_t resource_allocation;
- nfapi_uint16_tlv_t time_allocation_list;
- nfapi_uint16_tlv_t mcs_table;
- nfapi_uint16_tlv_t aggregation_factor;
- nfapi_uint16_tlv_t prb_bundling_type;
- nfapi_uint16_tlv_t rbg_size;
- nfapi_uint16_tlv_t vrb_to_prb_interleaver;
- nfapi_uint16_tlv_t code_block_groug_transmission;
- nfapi_uint16_tlv_t x_overhead;
- nfapi_uint16_tlv_t max_dci_codewords;
-
+ nfapi_uint16_tlv_t dmrs_TypeA_Position;
+ nfapi_uint16_tlv_t num_PDSCHTimeDomainResourceAllocations;
+ nfapi_uint16_tlv_t PDSCHTimeDomainResourceAllocation_k0[NFAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS];
+ nfapi_uint16_tlv_t PDSCHTimeDomainResourceAllocation_mappingType[NFAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS];
+ nfapi_uint16_tlv_t PDSCHTimeDomainResourceAllocation_startSymbolAndLength[NFAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS];
} nfapi_nr_pdsch_config_t;
#define NFAPI_NR_PDSCH_CONFIG_TAG
@@ -221,43 +168,64 @@ typedef struct {
nfapi_uint16_tlv_t prach_msg1_SubcarrierSpacing; ///// L1 parameter 'prach-Msg1SubcarrierSpacing'
nfapi_uint16_tlv_t restrictedSetConfig;
nfapi_uint16_tlv_t msg3_transformPrecoding; ///// L1 parameter 'msg3-tp'
+ nfapi_uint16_tlv_t ssb_perRACH_OccasionAndCB_PreamblesPerSSB;
+ nfapi_uint16_tlv_t ra_ContentionResolutionTimer;
+ nfapi_uint16_tlv_t rsrp_ThresholdSSB;
/////////////////--------------------NR RACH-ConfigGeneric--------------------/////////////////
nfapi_uint16_tlv_t prach_ConfigurationIndex; ///// L1 parameter 'PRACHConfigurationIndex'
nfapi_uint16_tlv_t prach_msg1_FDM; ///// L1 parameter 'prach-FDM'
nfapi_uint16_tlv_t prach_msg1_FrequencyStart; ///// L1 parameter 'prach-frequency-start'
nfapi_uint16_tlv_t zeroCorrelationZoneConfig;
nfapi_uint16_tlv_t preambleReceivedTargetPower;
+ nfapi_uint16_tlv_t preambleTransMax;
+ nfapi_uint16_tlv_t powerRampingStep;
+ nfapi_uint16_tlv_t ra_ResponseWindow;
} nfapi_nr_rach_config_t;
typedef struct {
nfapi_uint16_tlv_t groupHoppingEnabledTransformPrecoding; ///// L1 parameter 'Group-hopping-enabled-Transform-precoding'
nfapi_uint16_tlv_t msg3_DeltaPreamble; ///// L1 parameter 'Delta-preamble-msg3'
nfapi_uint16_tlv_t p0_NominalWithGrant; ///// L1 parameter 'p0-nominal-pusch-withgrant'
- nfapi_uint16_tlv_t TimeDomainResourceAllocation_k2; ///// L1 parameter 'K2'
- nfapi_uint16_tlv_t TimeDomainResourceAllocation_mappingType; ///// L1 parameter 'Mapping-type'
+ nfapi_uint16_tlv_t dmrs_TypeA_Position;
+ nfapi_uint16_tlv_t num_PUSCHTimeDomainResourceAllocations;
+ nfapi_uint16_tlv_t PUSCHTimeDomainResourceAllocation_k2[NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS]; ///// L1 parameter 'K2'
+ nfapi_uint16_tlv_t PUSCHTimeDomainResourceAllocation_mappingType[NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS]; ///// L1 parameter 'Mapping-type'
+ nfapi_uint16_tlv_t PUSCHTimeDomainResourceAllocation_startSymbolAndLength[NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS];
} nfapi_nr_pusch_config_t;
typedef struct {
+ uint8_t pucch_resource_common;
nfapi_uint16_tlv_t pucch_GroupHopping; ///// L1 parameter 'PUCCH-GroupHopping'
nfapi_uint16_tlv_t p0_nominal; ///// L1 parameter 'p0-nominal-pucch'
} nfapi_nr_pucch_config_t;
+
typedef struct {
nfapi_tl_t tl;
- nfapi_nr_SearchSpace_t sib1searchSpace;
- nfapi_nr_SearchSpace_t sibssearchSpace;
- nfapi_nr_SearchSpace_t ra_SearchSpace;
+
+ nfapi_uint16_tlv_t controlResourceSetZero;
+ nfapi_uint16_tlv_t searchSpaceZero;
+
+ // nfapi_nr_SearchSpace_t sib1searchSpace;
+ // nfapi_nr_SearchSpace_t sibssearchSpace;
+ // nfapi_nr_SearchSpace_t ra_SearchSpace;
}nfapi_nr_pdcch_config_t;
typedef struct {
//NR TDD-UL-DL-ConfigCommon ///// L1 parameter 'UL-DL-configuration-common'
- nfapi_uint16_tlv_t subcarrierspacing; ///// L1 parameter 'reference-SCS'
+ nfapi_uint16_tlv_t referenceSubcarrierSpacing; ///// L1 parameter 'reference-SCS'
nfapi_uint16_tlv_t dl_ul_periodicity; ///// L1 parameter 'DL-UL-transmission-periodicity'
nfapi_uint16_tlv_t nrofDownlinkSlots; ///// L1 parameter 'number-of-DL-slots'
nfapi_uint16_tlv_t nrofDownlinkSymbols; ///// L1 parameter 'number-of-DL-symbols-common'
nfapi_uint16_tlv_t nrofUplinkSlots; ///// L1 parameter 'number-of-UL-slots'
nfapi_uint16_tlv_t nrofUplinkSymbols; ///// L1 parameter 'number-of-UL-symbols-common'
+ nfapi_uint16_tlv_t Pattern2Present;
+ nfapi_uint16_tlv_t Pattern2_dl_ul_periodicity; ///// L1 parameter 'DL-UL-transmission-periodicity'
+ nfapi_uint16_tlv_t Pattern2_nrofDownlinkSlots; ///// L1 parameter 'number-of-DL-slots'
+ nfapi_uint16_tlv_t Pattern2_nrofDownlinkSymbols; ///// L1 parameter 'number-of-DL-symbols-common'
+ nfapi_uint16_tlv_t Pattern2_nrofUplinkSlots; ///// L1 parameter 'number-of-UL-slots'
+ nfapi_uint16_tlv_t Pattern2_nrofUplinkSymbols; ///// L1 parameter 'number-of-UL-symbols-common'
} nfapi_nr_tdd_ul_dl_config_t;
typedef struct {
@@ -287,6 +255,7 @@ typedef struct {
nfapi_nr_subframe_config_t subframe_config;
nfapi_nr_rf_config_t rf_config;
nfapi_nr_sch_config_t sch_config;
+ nfapi_nr_initialBWP_config_t initialBWP_config;
nfapi_nr_pdsch_config_t pdsch_config;
nfapi_nr_rach_config_t rach_config;
nfapi_nr_pusch_config_t pusch_config;
@@ -426,13 +395,9 @@ typedef enum {
NFAPI_NR_MCS_TABLE_QAM256
} nfapi_nr_pdsch_mcs_table_e;
-typedef enum {
- NFAPI_NR_DMRS_TYPE1=0,
- NFAPI_NR_DMRS_TYPE2
-} nfapi_nr_dmrs_type_e;
-
// P7 Sub Structures
+/*
typedef struct {
nfapi_tl_t tl;
@@ -495,9 +460,12 @@ uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16
uint16_t padding;
} nfapi_nr_dl_config_dci_dl_pdu_rel15_t;
-
+*/
//#define NFAPI_NR_DL_CONFIG_REQUEST_DCI_DL_PDU_REL15_TAG 0x????
+
+
+/*
typedef struct{
nfapi_tl_t tl;
uint8_t coreset_id;
@@ -532,11 +500,13 @@ typedef struct{
uint16_t number_of_candidates[NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS];
} nfapi_nr_search_space_t;
+
typedef struct {
nfapi_tl_t tl;
uint16_t rnti;
uint8_t rnti_type;
uint8_t dci_format;
+ uint16_t cce_index;
/// Number of CRB in BWP that this DCI configures
uint16_t n_RB_BWP;
uint8_t config_type;
@@ -561,118 +531,7 @@ typedef struct {
nfapi_bf_vector_t bf_vector;
} nfapi_nr_dl_config_pdcch_parameters_rel15_t;
-typedef struct {
- nfapi_tl_t tl;
- uint16_t length;
- int16_t pdu_index;
- uint16_t transmission_power;
-} nfapi_nr_dl_config_bch_pdu_rel15_t;
-#define NFAPI_NR_DL_CONFIG_REQUEST_BCH_PDU_REL15_TAG 0x5025
-
-typedef struct {
- nfapi_nr_dl_config_bch_pdu_rel15_t bch_pdu_rel15;
-} nfapi_nr_dl_config_bch_pdu;
-
-typedef struct {
- nfapi_tl_t tl;
- uint16_t length;
- uint8_t pdu_index;
- uint16_t rnti;
- uint16_t nb_mod_symbols;
- uint8_t time_allocation_type;
- uint8_t freq_allocation_type;
- uint16_t start_prb;
- uint16_t n_prb;
- uint8_t start_symbol;
- uint8_t nb_symbols;
- uint8_t mcs_idx;
- uint8_t mcs_table;
- uint8_t ndi;
- uint8_t nb_codewords;
- uint8_t nb_layers;
- uint16_t coding_rate;
- uint8_t modulation;
- uint8_t modulation_order;
- uint32_t transport_block_size;
- uint8_t nb_re_dmrs;
- uint8_t time_alloc_list_flag;
- uint8_t time_alloc_list;
- uint8_t rbg_list;
- uint8_t virtual_resource_block_assignment_flag;
- uint32_t resource_block_coding;
- uint8_t redundancy_version;
- uint8_t transport_blocks;
- uint8_t transmission_scheme;
- uint8_t number_of_subbands;
- uint8_t codebook_index[NFAPI_MAX_NUM_SUBBANDS];
- uint8_t ue_category_capacity;
- uint8_t pa;
- uint8_t delta_power_offset_index;
- uint8_t ngap;
- uint8_t transmission_mode;
- uint8_t num_bf_prb_per_subband;
- uint8_t num_bf_vector;
- nfapi_bf_vector_t bf_vector[NFAPI_MAX_BF_VECTORS];
-}nfapi_nr_dl_config_dlsch_pdu_rel15_t;
-#define NFAPI_NR_DL_CONFIG_REQUEST_DLSCH_PDU_REL15_TAG
-
-typedef struct {
- nfapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_pdu_rel15;
-} nfapi_nr_dl_config_dlsch_pdu;
-
-typedef struct {
- nfapi_tl_t tl;
- nfapi_nr_search_space_t pagingSearchSpace;
- nfapi_nr_coreset_t pagingControlResourceSets;
-}nfapi_nr_dl_config_pch_pdu_rel15_t;
-
-typedef struct {
-
-} nfapi_nr_dl_config_nbch_pdu_rel15_t;
-
-typedef struct {
-
-} nfapi_nr_dl_config_npdcch_pdu_rel15_t;
-
-typedef struct {
-
-} nfapi_nr_dl_config_ndlsch_pdu_rel15_t;
-
-typedef struct {
- nfapi_nr_dl_config_dci_dl_pdu_rel15_t dci_dl_pdu_rel15;
- nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params_rel15;
-} nfapi_nr_dl_config_dci_dl_pdu;
-
-
-typedef struct {
- uint8_t pdu_type;
- uint8_t pdu_size;
-
- union {
- nfapi_nr_dl_config_dci_dl_pdu dci_dl_pdu;
- nfapi_nr_dl_config_bch_pdu_rel15_t bch_pdu_rel15;
- nfapi_nr_dl_config_dlsch_pdu dlsch_pdu;
- nfapi_nr_dl_config_pch_pdu_rel15_t pch_pdu_rel15;
- nfapi_nr_dl_config_nbch_pdu_rel15_t nbch_pdu_rel15;
- nfapi_nr_dl_config_npdcch_pdu_rel15_t npdcch_pdu_rel15;
- nfapi_nr_dl_config_ndlsch_pdu_rel15_t ndlsch_pdu_rel15;
- };
-} nfapi_nr_dl_config_request_pdu_t;
-
-typedef struct {
- nfapi_tl_t tl;
- uint8_t number_dci;
- uint8_t number_pdu;
- uint8_t number_pdsch_rnti;
- nfapi_nr_dl_config_request_pdu_t *dl_config_pdu_list;
-} nfapi_nr_dl_config_request_body_t;
-
-typedef struct {
- nfapi_p7_message_header_t header;
- uint16_t sfn_sf;
- nfapi_nr_dl_config_request_body_t dl_config_request_body;
- nfapi_vendor_extension_tlv_t vendor_extension;
-} nfapi_nr_dl_config_request_t;
+*/
typedef enum {nr_pusch_freq_hopping_disabled = 0 ,
@@ -711,9 +570,37 @@ typedef struct {
uint8_t beta_offset_ind;
} nfapi_nr_ul_config_ulsch_pdu_rel15_t;
+
+
+
+
typedef struct {
uint16_t rnti;
nfapi_nr_ul_config_ulsch_pdu_rel15_t ulsch_pdu_rel15;
} nfapi_nr_ul_config_ulsch_pdu;
+typedef struct {
+ uint8_t pdu_type;
+ uint8_t pdu_size;
+
+ union {
+ // nfapi_nr_ul_config_uci_pdu uci_pdu;
+ nfapi_nr_ul_config_ulsch_pdu ulsch_pdu;
+ // nfapi_nr_ul_config_srs_pdu srs_pdu;
+ };
+} nfapi_nr_ul_config_request_pdu_t;
+
+typedef struct {
+ nfapi_tl_t tl;
+ uint8_t number_pdu;
+ nfapi_nr_ul_config_request_pdu_t *ul_config_pdu_list;
+} nfapi_nr_ul_config_request_body_t;
+
+typedef struct {
+ nfapi_p7_message_header_t header;
+ uint16_t sfn_sf;
+ nfapi_nr_ul_config_request_body_t ul_config_request_body;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_ul_config_request_t;
+
#endif
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
index 408da13718..f69c928ed2 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
@@ -11,7 +11,6 @@
#include "stddef.h"
#include "nfapi_interface.h"
-#include
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
@@ -23,7 +22,6 @@
#define NFAPI_MAX_NUM_GROUPS 8
#define NFAPI_MAX_NUM_CB 8
-/*
// Extension to the generic structures for single tlv values
typedef struct {
nfapi_tl_t tl;
@@ -34,7 +32,34 @@ typedef struct {
nfapi_tl_t tl;
uint32_t value;
} nfapi_uint32_tlv_t;
-*/
+
+typedef struct {
+ nfapi_tl_t tl;
+ int64_t value;
+} nfapi_int64_tlv_t;
+
+typedef struct {
+ nfapi_tl_t tl;
+ uint64_t value;
+} nfapi_uint64_tlv_t;
+
+typedef enum {
+ NFAPI_NR_DMRS_TYPE1=0,
+ NFAPI_NR_DMRS_TYPE2
+} nfapi_nr_dmrs_type_e;
+
+
+typedef struct {
+ /// Value: 0 -> 1, 0: Payload is carried directly in the value field, 1: Pointer to payload is in the value field
+ uint16_t tag;
+ /// Length of the actual payload in bytes, without the padding bytes Value: 0 → 65535
+ uint16_t length;
+ union {
+ uint32_t *ptr;
+ uint32_t direct[16384];
+ } value;
+} nfapi_nr_tx_data_request_tlv_t;
+
// 2019.8
// SCF222_5G-FAPI_PHY_SPI_Specificayion.pdf Section 3.2
@@ -68,12 +93,6 @@ typedef enum {
//3.3.1 PARAM
-typedef struct {
- nfapi_tl_t tl;
- uint16_t value;
-
-} nfapi_nr_param_tlv_t;
-
//same with nfapi_param_request_t
typedef struct {
nfapi_p4_p5_message_header_t header;
@@ -86,12 +105,12 @@ typedef enum {
} nfapi_nr_param_errors_e;
-typedef struct {
+/*typedef struct {
nfapi_nr_param_errors_e error_code;
//Number of TLVs contained in the message body.
uint8_t number_of_tlvs;
nfapi_nr_param_tlv_t TLV;
-} nfapi_nr_param_response_t;
+} nfapi_nr_param_response_t;*/
//PARAM and CONFIG TLVs are used in the PARAM and CONFIG message exchanges, respectively
@@ -101,7 +120,7 @@ typedef struct {
//table 3-9
-#define NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG 0x0001
+#define NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG 0x0001
#define NFAPI_NR_PARAM_TLV_PHY_STATE_TAG 0x0002
#define NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG 0x0003
#define NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG 0x0004
@@ -158,123 +177,113 @@ typedef struct {
typedef struct
{
- uint16_t release_capability; //TAG 0x0001
- uint16_t phy_state;
- uint8_t skip_blank_dl_config;
- uint8_t skip_blank_ul_config;
- uint16_t num_config_tlvs_to_report;
- nfapi_nr_param_tlv_t* config_tlvs_to_report_list;
+ nfapi_uint16_tlv_t release_capability; //TAG 0x0001
+ nfapi_uint16_tlv_t phy_state;
+ nfapi_uint8_tlv_t skip_blank_dl_config;
+ nfapi_uint8_tlv_t skip_blank_ul_config;
+ nfapi_uint16_tlv_t num_config_tlvs_to_report;
+ nfapi_uint8_tlv_t* config_tlvs_to_report_list;
} nfapi_nr_cell_param_t;
//table 3-10 Carrier parameters
typedef struct
{
- uint8_t cyclic_prefix;//TAG 0x0006
- uint8_t supported_subcarrier_spacings_dl;
- uint16_t supported_bandwidth_dl;
- uint8_t supported_subcarrier_spacings_ul;
- uint16_t supported_bandwidth_ul;
+ nfapi_uint8_tlv_t cyclic_prefix;//TAG 0x0006
+ nfapi_uint16_tlv_t supported_subcarrier_spacings_dl;
+ nfapi_uint16_tlv_t supported_bandwidth_dl;
+ nfapi_uint8_tlv_t supported_subcarrier_spacings_ul;
+ nfapi_uint16_tlv_t supported_bandwidth_ul;
} nfapi_nr_carrier_param_t;
//table 3-11 PDCCH parameters
typedef struct
{
- uint8_t cce_mapping_type;
- uint8_t coreset_outside_first_3_of_ofdm_syms_of_slot;
- uint8_t coreset_precoder_granularity_coreset;
- uint8_t pdcch_mu_mimo;
- uint8_t pdcch_precoder_cycling;
- uint8_t max_pdcch_per_slot;//TAG 0x0010
+ nfapi_uint8_tlv_t cce_mapping_type;
+ nfapi_uint8_tlv_t coreset_outside_first_3_of_ofdm_syms_of_slot;
+ nfapi_uint8_tlv_t coreset_precoder_granularity_coreset;
+ nfapi_uint8_tlv_t pdcch_mu_mimo;
+ nfapi_uint8_tlv_t pdcch_precoder_cycling;
+ nfapi_uint8_tlv_t max_pdcch_per_slot;//TAG 0x0010
} nfapi_nr_pdcch_param_t;
//table 3-12 PUCCH parameters
typedef struct
{
- uint8_t pucch_formats;
- uint8_t max_pucchs_per_slot;
+ nfapi_uint8_tlv_t pucch_formats;
+ nfapi_uint8_tlv_t max_pucchs_per_slot;
} nfapi_nr_pucch_param_t;
//table 3-13 PDSCH parameters
typedef struct
{
- uint8_t pdsch_mapping_type;
- uint8_t pdsch_allocation_types;
- uint8_t pdsch_vrb_to_prb_mapping;
- uint8_t pdsch_cbg;
- uint8_t pdsch_dmrs_config_types;
- uint8_t pdsch_dmrs_max_length;
- uint8_t pdsch_dmrs_additional_pos;
- uint8_t max_pdsch_tbs_per_slot;
- uint8_t max_number_mimo_layers_pdsch;
- uint8_t supported_max_modulation_order_dl;
- uint8_t max_mu_mimo_users_dl;
- uint8_t pdsch_data_in_dmrs_symbols;
- uint8_t premption_support;//TAG 0x001F
- uint8_t pdsch_non_slot_support;
+ nfapi_uint8_tlv_t pdsch_mapping_type;
+ nfapi_uint8_tlv_t pdsch_allocation_types;
+ nfapi_uint8_tlv_t pdsch_vrb_to_prb_mapping;
+ nfapi_uint8_tlv_t pdsch_cbg;
+ nfapi_uint8_tlv_t pdsch_dmrs_config_types;
+ nfapi_uint8_tlv_t pdsch_dmrs_max_length;
+ nfapi_uint8_tlv_t pdsch_dmrs_additional_pos;
+ nfapi_uint8_tlv_t max_pdsch_tbs_per_slot;
+ nfapi_uint8_tlv_t max_number_mimo_layers_pdsch;
+ nfapi_uint8_tlv_t supported_max_modulation_order_dl;
+ nfapi_uint8_tlv_t max_mu_mimo_users_dl;
+ nfapi_uint8_tlv_t pdsch_data_in_dmrs_symbols;
+ nfapi_uint8_tlv_t premption_support;//TAG 0x001F
+ nfapi_uint8_tlv_t pdsch_non_slot_support;
} nfapi_nr_pdsch_param_t;
//table 3-14
typedef struct
{
- uint8_t uci_mux_ulsch_in_pusch;
- uint8_t uci_only_pusch;
- uint8_t pusch_frequency_hopping;
- uint8_t pusch_dmrs_config_types;
- uint8_t pusch_dmrs_max_len;
- uint8_t pusch_dmrs_additional_pos;
- uint8_t pusch_cbg;
- uint8_t pusch_mapping_type;
- uint8_t pusch_allocation_types;
- uint8_t pusch_vrb_to_prb_mapping;
- //uint8 ? ↓ see table 3-14
- uint8_t pusch_max_ptrs_ports;
- uint8_t max_pduschs_tbs_per_slot;
- uint8_t max_number_mimo_layers_non_cb_pusch;
- uint8_t supported_modulation_order_ul;
- uint8_t max_mu_mimo_users_ul;
- uint8_t dfts_ofdm_support;
- uint8_t pusch_aggregation_factor;//TAG 0x0031
+ nfapi_uint8_tlv_t uci_mux_ulsch_in_pusch;
+ nfapi_uint8_tlv_t uci_only_pusch;
+ nfapi_uint8_tlv_t pusch_frequency_hopping;
+ nfapi_uint8_tlv_t pusch_dmrs_config_types;
+ nfapi_uint8_tlv_t pusch_dmrs_max_len;
+ nfapi_uint8_tlv_t pusch_dmrs_additional_pos;
+ nfapi_uint8_tlv_t pusch_cbg;
+ nfapi_uint8_tlv_t pusch_mapping_type;
+ nfapi_uint8_tlv_t pusch_allocation_types;
+ nfapi_uint8_tlv_t pusch_vrb_to_prb_mapping;
+ nfapi_uint8_tlv_t pusch_max_ptrs_ports;
+ nfapi_uint8_tlv_t max_pduschs_tbs_per_slot;
+ nfapi_uint8_tlv_t max_number_mimo_layers_non_cb_pusch;
+ nfapi_uint8_tlv_t supported_modulation_order_ul;
+ nfapi_uint8_tlv_t max_mu_mimo_users_ul;
+ nfapi_uint8_tlv_t dfts_ofdm_support;
+ nfapi_uint8_tlv_t pusch_aggregation_factor;//TAG 0x0031
} nfapi_nr_pusch_param_t;
//table 3-15
typedef struct
{
- uint8_t prach_long_formats;
- uint8_t prach_short_formats;
- uint8_t prach_restricted_sets;
- uint8_t max_prach_fd_occasions_in_a_slot;
-
+ nfapi_uint8_tlv_t prach_long_formats;
+ nfapi_uint8_tlv_t prach_short_formats;
+ nfapi_uint8_tlv_t prach_restricted_sets;
+ nfapi_uint8_tlv_t max_prach_fd_occasions_in_a_slot;
} nfapi_nr_prach_param_t;
//table 3-16
typedef struct
{
- uint8_t rssi_measurement_support;
+ nfapi_uint8_tlv_t rssi_measurement_support;
} nfapi_nr_measurement_param_t;
//-------------------------------------------//
//3.3.2 CONFIG
-typedef struct {
- nfapi_tl_t tl;
- uint16_t value;
-} nfapi_nr_config_tlv_t;
-typedef struct {
- uint8_t number_of_tlvs;
- nfapi_nr_config_tlv_t tlv;
-} nfapi_nr_config_request_scf_t;
typedef enum {
NFAPI_NR_CONFIG_MSG_OK = 0,
- NFAPI_NR_CONFIG_MSG_INVALID_CONFIG //The configuration provided has missing mandatory TLVs, or TLVs that are invalid or unsupported in this state.
+ NFAPI_NR_CONFIG_MSG_INVALID_CONFIG //The configuration provided has missing mandatory TLVs, or TLVs that are invalid or unsupported in this state.
} nfapi_nr_config_errors_e;
-typedef struct {
+/*typedef struct {
nfapi_nr_config_errors_e error_code;
uint8_t number_of_invalid_tlvs_that_can_only_be_configured_in_idle;
uint8_t unmber_of_missing_tlvs;
@@ -284,7 +293,7 @@ typedef struct {
nfapi_nr_config_tlv_t* tlv_invalid_running_list;
nfapi_nr_config_tlv_t* tlv_missing_list;
-} nfapi_nr_config_response_t;
+} nfapi_nr_config_response_t;*/
//nfapi_nr_config_tlv_format_t carrier config ~ precoding config:
@@ -337,34 +346,34 @@ typedef struct {
//table 3-21
typedef struct
{
- uint16_t dl_bandwidth;//Carrier bandwidth for DL in MHz [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400
- uint32_t dl_frequency; //Absolute frequency of DL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000
- uint16_t dl_k0[5];//𝑘_{0}^{𝜇} for each of the numerologies [38.211, sec 5.3.1] Value: 0 ->23699
- uint16_t dl_grid_size[5];//Grid size 𝑁_{𝑔𝑟𝑖𝑑}^{𝑠𝑖𝑧𝑒,𝜇} for each of the numerologies [38.211, sec 4.4.2] Value: 0->275 0 = this numerology not used
- uint16_t num_tx_ant;//Number of Tx antennas
- uint16_t uplink_bandwidth;//Carrier bandwidth for UL in MHz. [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400
- uint32_t uplink_frequency;//Absolute frequency of UL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000
- uint16_t ul_k0[5];//𝑘0 𝜇 for each of the numerologies [38.211, sec 5.3.1] Value: : 0 ->23699
- uint16_t ul_grid_size[5];//Grid size 𝑁𝑔𝑟𝑖𝑑 𝑠𝑖𝑧𝑒,𝜇 for each of the numerologies [38.211, sec 4.4.2]. Value: 0->275 0 = this numerology not used
- uint16_t num_rx_ant;//
- uint8_t frequency_shift_7p5khz;//Indicates presence of 7.5KHz frequency shift. Value: 0 = false 1 = true
+ nfapi_uint16_tlv_t dl_bandwidth;//Carrier bandwidth for DL in MHz [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400
+ nfapi_uint32_tlv_t dl_frequency; //Absolute frequency of DL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000
+ nfapi_uint16_tlv_t dl_k0[5];//𝑘_{0}^{𝜇} for each of the numerologies [38.211, sec 5.3.1] Value: 0 ->23699
+ nfapi_uint16_tlv_t dl_grid_size[5];//Grid size 𝑁_{𝑔𝑟𝑖𝑑}^{𝑠𝑖𝑧𝑒,𝜇} for each of the numerologies [38.211, sec 4.4.2] Value: 0->275 0 = this numerology not used
+ nfapi_uint16_tlv_t num_tx_ant;//Number of Tx antennas
+ nfapi_uint16_tlv_t uplink_bandwidth;//Carrier bandwidth for UL in MHz. [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400
+ nfapi_uint32_tlv_t uplink_frequency;//Absolute frequency of UL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000
+ nfapi_uint16_tlv_t ul_k0[5];//𝑘0 𝜇 for each of the numerologies [38.211, sec 5.3.1] Value: : 0 ->23699
+ nfapi_uint16_tlv_t ul_grid_size[5];//Grid size 𝑁𝑔𝑟𝑖𝑑 𝑠𝑖𝑧𝑒,𝜇 for each of the numerologies [38.211, sec 4.4.2]. Value: 0->275 0 = this numerology not used
+ nfapi_uint16_tlv_t num_rx_ant;//
+ nfapi_uint8_tlv_t frequency_shift_7p5khz;//Indicates presence of 7.5KHz frequency shift. Value: 0 = false 1 = true
} nfapi_nr_carrier_config_t;
//table 3-22
typedef struct
{
- uint8_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007
- uint8_t frame_duplex_type;//Frame duplex type Value: 0 = FDD 1 = TDD
+ nfapi_uint8_tlv_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007
+ nfapi_uint8_tlv_t frame_duplex_type;//Frame duplex type Value: 0 = FDD 1 = TDD
} nfapi_nr_cell_config_t;
//table 3-23
typedef struct
{
- uint32_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
- uint8_t bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload
- uint8_t scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3
+ nfapi_uint32_tlv_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
+ nfapi_uint8_tlv_t bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload
+ nfapi_uint8_tlv_t scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3
} nfapi_nr_ssb_config_t;
@@ -376,51 +385,51 @@ typedef struct
typedef struct
{
uint8_t num_prach_fd_occasions;
- uint16_t prach_root_sequence_index;//Starting logical root sequence index, 𝑖, equivalent to higher layer parameter prach-RootSequenceIndex [38.211, sec 6.3.3.1] Value: 0 -> 837
- uint8_t num_root_sequences;//Number of root sequences for a particular FD occasion that are required to generate the necessary number of preambles
- uint16_t k1;//Frequency offset (from UL bandwidth part) for each FD. [38.211, sec 6.3.3.2] Value: from 0 to 272
- uint8_t prach_zero_corr_conf;//PRACH Zero CorrelationZone Config which is used to dervive 𝑁𝑐𝑠 [38.211, sec 6.3.3.1] Value: from 0 to 15
- uint8_t num_unused_root_sequences;//Number of unused sequences available for noise estimation per FD occasion. At least one unused root sequence is required per FD occasion.
- uint8_t* unused_root_sequences_list;//Unused root sequence or sequences per FD occasion. Required for noise estimation.
+ nfapi_uint16_tlv_t prach_root_sequence_index;//Starting logical root sequence index, 𝑖, equivalent to higher layer parameter prach-RootSequenceIndex [38.211, sec 6.3.3.1] Value: 0 -> 837
+ nfapi_uint8_tlv_t num_root_sequences;//Number of root sequences for a particular FD occasion that are required to generate the necessary number of preambles
+ nfapi_uint16_tlv_t k1;//Frequency offset (from UL bandwidth part) for each FD. [38.211, sec 6.3.3.2] Value: from 0 to 272
+ nfapi_uint8_tlv_t prach_zero_corr_conf;//PRACH Zero CorrelationZone Config which is used to dervive 𝑁𝑐𝑠 [38.211, sec 6.3.3.1] Value: from 0 to 15
+ nfapi_uint8_tlv_t num_unused_root_sequences;//Number of unused sequences available for noise estimation per FD occasion. At least one unused root sequence is required per FD occasion.
+ nfapi_uint8_tlv_t* unused_root_sequences_list;//Unused root sequence or sequences per FD occasion. Required for noise estimation.
} nfapi_nr_num_prach_fd_occasions_t;
typedef struct
{
- uint8_t prach_sequence_length;//RACH sequence length. Long or Short sequence length. Only short sequence length is supported for FR2. [38.211, sec 6.3.3.1] Value: 0 = Long sequence 1 = Short sequence
- uint8_t prach_sub_c_spacing;//Subcarrier spacing of PRACH. [38.211 sec 4.2] Value:0->4
- uint8_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B
- uint8_t num_prach_fd_occasions;//Number of RACH frequency domain occasions. Corresponds to the parameter 𝑀 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8
+ nfapi_uint8_tlv_t prach_sequence_length;//RACH sequence length. Only short sequence length is supported for FR2. [38.211, sec 6.3.3.1] Value: 0 = Long sequence 1 = Short sequence
+ nfapi_uint8_tlv_t prach_sub_c_spacing;//Subcarrier spacing of PRACH. [38.211 sec 4.2] Value:0->4
+ nfapi_uint8_tlv_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B
+ nfapi_uint8_tlv_t num_prach_fd_occasions;//Corresponds to the parameter 𝑀 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8
nfapi_nr_num_prach_fd_occasions_t* num_prach_fd_occasions_list;
- uint8_t ssb_per_rach;//SSB-per-RACH-occasion Value: 0: 1/8 1:1/4, 2:1/2 3:1 4:2 5:4, 6:8 7:16
- uint8_t prach_multiple_carriers_in_a_band;//0 = disabled 1 = enabled
+ nfapi_uint8_tlv_t ssb_per_rach;//SSB-per-RACH-occasion Value: 0: 1/8 1:1/4, 2:1/2 3:1 4:2 5:4, 6:8 7:16
+ nfapi_uint8_tlv_t prach_multiple_carriers_in_a_band;//0 = disabled 1 = enabled
} nfapi_nr_prach_config_t;
//table 3-25
typedef struct
{
- uint32_t ssb_mask;//Bitmap for actually transmitted SSB. MSB->LSB of first 32 bit number corresponds to SSB 0 to SSB 31 MSB->LSB of second 32 bit number corresponds to SSB 32 to SSB 63 Value for each bit: 0: not transmitted 1: transmitted
+ nfapi_uint32_tlv_t ssb_mask;//Bitmap for actually transmitted SSB. MSB->LSB of first 32 bit number corresponds to SSB 0 to SSB 31 MSB->LSB of second 32 bit number corresponds to SSB 32 to SSB 63 Value for each bit: 0: not transmitted 1: transmitted
} nfapi_nr_ssb_mask_size_2_t;
typedef struct
{
- uint8_t beam_id[64];//BeamID for each SSB in SsbMask. For example, if SSB mask bit 26 is set to 1, then BeamId[26] will be used to indicate beam ID of SSB 26. Value: from 0 to 63
+ nfapi_uint8_tlv_t beam_id[64];//BeamID for each SSB in SsbMask. For example, if SSB mask bit 26 is set to 1, then BeamId[26] will be used to indicate beam ID of SSB 26. Value: from 0 to 63
} nfapi_nr_ssb_mask_size_64_t;
typedef struct
{
- uint16_t ssb_offset_point_a;//Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Given in PRB [38.211, section 4.4.4.2] Value: 0->2199
- uint8_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block [38.213, sec 4.1] Values: 0 = 0dB
- uint8_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160
- uint8_t ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31
- uint32_t MIB;//MIB payload, where the 24 MSB are used and represent the MIB in [38.331 MIB IE] and represent 0 1 2 3 1 , , , ,..., A− a a a a a [38.212, sec 7.1.1]
- nfapi_nr_ssb_mask_size_2_t* ssb_mask_size_2_list;//2
- nfapi_nr_ssb_mask_size_64_t* ssb_mask_size_64_list;//64
- uint8_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled
- uint8_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled
+ nfapi_uint16_tlv_t ssb_offset_point_a;//Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Given in PRB [38.211, section 4.4.4.2] Value: 0->2199
+ nfapi_uint8_tlv_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block [38.213, sec 4.1] Values: 0 = 0dB
+ nfapi_uint8_tlv_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160
+ nfapi_uint8_tlv_t ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31
+ nfapi_uint32_tlv_t MIB;//MIB payload, where the 24 MSB are used and represent the MIB in [38.331 MIB IE] and represent 0 1 2 3 1 , , , ,..., A− a a a a a [38.212, sec 7.1.1]
+ nfapi_nr_ssb_mask_size_2_t ssb_mask_list[2];
+ nfapi_nr_ssb_mask_size_64_t* ssb_beam_id_list;//64
+ nfapi_uint8_tlv_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled
+ nfapi_uint8_tlv_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled
} nfapi_nr_ssb_table_t;
@@ -429,7 +438,7 @@ typedef struct
//?
typedef struct
{
- uint8_t slot_config;//For each symbol in each slot a uint8_t value is provided indicating: 0: DL slot 1: UL slot 2: Guard slot
+ nfapi_uint8_tlv_t slot_config;//For each symbol in each slot a uint8_t value is provided indicating: 0: DL slot 1: UL slot 2: Guard slot
} nfapi_nr_max_num_of_symbol_per_slot_t;
@@ -441,7 +450,7 @@ typedef struct
typedef struct
{
- uint8_t tdd_period;//DL UL Transmission Periodicity. Value:0: ms0p5 1: ms0p625 2: ms1 3: ms1p25 4: ms2 5: ms2p5 6: ms5 7: ms10
+ nfapi_uint8_tlv_t tdd_period;//DL UL Transmission Periodicity. Value:0: ms0p5 1: ms0p625 2: ms1 3: ms1p25 4: ms2 5: ms2p5 6: ms5 7: ms10 8: ms3 9: ms4
nfapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list;
} nfapi_nr_tdd_table_t;
@@ -449,10 +458,23 @@ typedef struct
//table 3-27
typedef struct
{
- uint8_t rssi_measurement;//RSSI measurement unit. See Table 3-16 for RSSI definition. Value: 0: Do not report RSSI 1: dBm 2: dBFS
+ nfapi_uint8_tlv_t rssi_measurement;//RSSI measurement unit. See Table 3-16 for RSSI definition. Value: 0: Do not report RSSI 1: dBm 2: dBFS
} nfapi_nr_measurement_config_t;
+
+typedef struct {
+ uint8_t num_tlv;
+ nfapi_nr_carrier_config_t carrier_config;
+ nfapi_nr_cell_config_t cell_config;
+ nfapi_nr_ssb_config_t ssb_config;
+ nfapi_nr_prach_config_t prach_config;
+ nfapi_nr_ssb_table_t ssb_table;
+ nfapi_nr_tdd_table_t tdd_table;
+ nfapi_nr_measurement_config_t measurement_config;
+} nfapi_nr_config_request_scf_t;
+
+
//------------------------------//
//3.3.3 START
@@ -574,17 +596,29 @@ typedef struct
}nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t;
+/*
//table 3-43
typedef struct
{
- uint16_t num_prgs;/*Number of PRGs spanning this allocation.
-Value : 1->275 */
- uint16_t prg_size;/*Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275 */
+ uint16_t num_prgs;//Number of PRGs spanning this allocation. Value : 1->275
+ uint16_t prg_size;//Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275
//watchout: dig_bf_interfaces here, in table 3-53 it's dig_bf_interface
uint8_t dig_bf_interfaces;//Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255
nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t* prgs_list;//
}nfapi_nr_tx_precoding_and_beamforming_t;
+*/
+
+typedef struct {
+ /// Number of PRGs spanning this allocation. Value : 1->275
+ uint16_t numPRGs;
+ /// Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275
+ uint16_t prgSize;
+ /// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255
+ uint8_t digBFInterfaces;
+ uint16_t PMIdx[275];
+ uint16_t *beamIdx[275];
+} nfapi_nr_tx_precoding_and_beamforming_t;
//table 3-37
@@ -607,33 +641,154 @@ SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 */
} nfapi_nr_dl_dci_pdu_t;
-//table 3-36
-typedef struct
-{
- uint16_t bwp_size;//Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP Value: 1->275
- uint16_t bwp_start;//bandwidth part start RB index from reference CRB [TS38.213 sec 12] Value: 0->274
- uint8_t subcarrier_spacing;//subcarrierSpacing [TS38.211 sec 4.2] Value:0->4
- uint8_t cyclic_prefix;//Cyclic prefix type [TS38.211 sec 4.2] 0: Normal; 1: Extended
- //Coreset [TS38.211 sec 7.3.2.2]
- uint8_t start_symbol_index;//Starting OFDM symbol for the CORESET Value: 0->13
- uint8_t duration_symbols;/* Contiguous time duration of the CORESET in number of symbols. Corresponds to L1 parameter 𝑁𝑠𝑦𝑚𝑏 𝐶𝑂𝑅𝐸𝑆𝐸𝑇 [TS38.211 sec 7.3.2.2] Value: 1,2,3*/
- uint8_t freq_domain_resource[6];/* Frequency domain resources. This is a bitmap defining non-overlapping groups of 6 PRBs in ascending order. [TS38.213 10.1]. Also, corresponds to L1 parameter N^{CORESET}_{RB} [TS38.211 sec 7.3.2.2]
- Bitmap of uint8 array. 45 bits.*/
- uint8_t cce_reg_mapping_type;/*CORESET-CCE-to-REG-mapping-type [TS38.211 sec 7.3.2.2] 0: non-interleaved 1: interleaved */
- uint8_t reg_bundle_size;/*The number of REGs in a bundle. Must be 6 for
-cceRegMappingType = nonInterleaved. For cceRegMappingType = interleaved, must belong to {2,6} if duration = 1,2 and must belong to {3,6} if
-duration = 3. Corresponds to parameter L. [TS38.211 sec 7.3.2.2] Value: 2,3,6 */
- uint8_t interleaver_size;//The interleaver size. For interleaved mapping belongs to {2,3,6} and for non-interleaved mapping is NA. Corresponds to parameter R. [TS38.211 sec 7.3.2.2] Value: 2,3,6
- uint8_t core_set_type;//[TS38.211 sec 7.3.2.2 and sec 7.4.1.3.2] 0: CORESET is configured by the PBCH or SIB1 (subcarrier 0 of CRB0 for DMRS mapping) 1: otherwise (subcarrier 0 of CORESET)
- uint16_t shift_index;//[TS38.211 sec 7.3.2.2] Not applicable for non-interleaved mapping. For interleaved mapping and a PDCCH transmitted in a CORESET configured by the PBCH or SIB1 this should be set to phy cell ID. Value: 10 bits Otherwise, for interleaved mapping this is set to 0-> max num of PRBs. Value 0-> 275
- uint8_t precoder_granularity;//Granularity of precoding [TS38.211 sec 7.3.2.2] 0: sameAsRegBundle 1: allContiguousRBs
- uint16_t num_dl_dci;//Number of DCIs in this CORESET. Value: 0->MaxDciPerSlot
- nfapi_nr_dl_dci_pdu_t* dl_dci_list;
+typedef struct {
+ /// Number of PRGs spanning this allocation. Value : 1->275
+ uint16_t numPRGs;
+ /// Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275
+ uint16_t prgSize;
+ /// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255
+ uint8_t digBFInterfaces;
+ uint16_t PMIdx[275];
+ uint16_t *beamIdx[275];
+} nr_beamforming_t;
+
+#define MAX_DCI_CORESET 8
+#define DCI_PAYLOAD_BYTE_LEN 8
+
+typedef struct {
+ ///Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP,Value: 1->275
+ uint16_t BWPSize;
+ ///bandwidth part start RB index from reference CRB, [TS38.213 sec 12], Value: 0->274
+ uint16_t BWPStart;
+ ///subcarrierSpacing [TS38.211 sec 4.2], Value:0->4
+ uint8_t SubcarrierSpacing;
+ ///Cyclic prefix type [TS38.211 sec 4.2], 0: Normal; 1: Extended
+ uint8_t CyclicPrefix;
+ ///Starting OFDM symbol for the CORESET, Value: 0->13
+ uint8_t StartSymbolIndex;
+///Contiguous time duration of the CORESET in number of symbols. Corresponds to L1 parameter 𝑁𝑠𝑦𝑚𝑏_𝐶𝑂𝑅𝐸𝑆𝐸𝑇 [TS38.211 sec 7.3.2.2] Value: 1,2,3
+ uint8_t DurationSymbols;
+ ///Frequency domain resources. This is a bitmap defining non-overlapping groups of 6 PRBs in ascending order. [TS38.213 10.1]. Also, corresponds to L1 parameter CORE SET RB N [TS38.211 sec 7.3.2.2] Bitmap of uint8 array. 45 bits.
+ uint8_t FreqDomainResource[6];
+ ///CORESET-CCE-to-REG-mapping-type [TS38.211 sec 7.3.2.2] 0: non-interleaved 1: interleaved
+ uint8_t CceRegMappingType;
+ ///The number of REGs in a bundle. Must be 6 for cceRegMappingType = nonInterleaved. For cceRegMappingType = interleaved, must belong to {2,6} if duration = 1,2 and must belong to {3,6} if duration = 3. Corresponds to parameter L. [TS38.211 sec 7.3.2.2] Value: 2,3,6
+ uint8_t RegBundleSize;
+ ///The interleaver size. For interleaved mapping belongs to {2,3,6} and for non-interleaved mapping is NA. Corresponds to parameter R. [TS38.211 sec 7.3.2.2] Value: 2,3,6 CoreSetType
+ uint8_t InterleaverSize;
+ ///[TS38.211 sec 7.3.2.2 and sec 7.4.1.3.2] 0: CORESET is configured by the PBCH or SIB1 (subcarrier 0 of CRB0 for DMRS mapping) 1: otherwise (subcarrier 0 of CORESET)
+ uint8_t CoreSetType;
+ ///[TS38.211 sec 7.3.2.2] Not applicable for non-interleaved mapping. For interleaved mapping and a PDCCH transmitted in a CORESET configured by the PBCH or SIB1 this should be set to phy cell ID. Value: 10 bits Otherwise, for interleaved mapping this is set to 0-> max num of PRBs. Value 0-> 275
+ uint16_t ShiftIndex;
+ ///Granularity of precoding [TS38.211 sec 7.3.2.2] Field Type Description 0: sameAsRegBundle 1: allContiguousRBs
+ uint8_t precoderGranularity;
+ ///Number of DCIs in this CORESET.Value: 0->MaxDciPerSlot
+ uint16_t numDlDci;
+ ///The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535.
+ uint16_t RNTI[MAX_DCI_CORESET];
+ ///For a UE-specific search space it equals the higher-layer parameter PDCCH-DMRSScrambling-ID if configured, otherwise it should be set to the phy cell ID. [TS38.211, sec 7.3.2.3] Value: 0->65535
+ uint16_t ScramblingId[MAX_DCI_CORESET];
+ ///For a UE-specific search space where PDCCH-DMRSScrambling- ID is configured This param equals the CRNTI. Otherwise, it should be set to 0. [TS38.211, sec 7.3.2.3] Value: 0 -> 65535
+ uint16_t ScramblingRNTI[MAX_DCI_CORESET];
+ ///CCE start Index used to send the DCI Value: 0->135
+ uint8_t CceIndex[MAX_DCI_CORESET];
+ ///Aggregation level used [TS38.211, sec 7.3.2.1] Value: 1,2,4,8,16
+ uint8_t AggregationLevel[MAX_DCI_CORESET];
+ ///Precoding and Beamforming structure See Table 3-43
+ nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming[MAX_DCI_CORESET];
+ ///PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 Report title: 5G FAPI: PHY API Specification Issue date: 29 June 2019 Version: 222.10.17 68 Field Type Description representing -8 to 8 dB in 1dB steps
+ uint8_t beta_PDCCH_1_0[MAX_DCI_CORESET];
+ ///PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB,1: 0dB,2: 3dB,3: 6dB
+ uint8_t powerControlOffsetSS[MAX_DCI_CORESET];
+///The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BTYE_LEN*8
+ uint16_t PayloadSizeBits[MAX_DCI_CORESET];
+ ///DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
+ uint8_t Payload[MAX_DCI_CORESET][DCI_PAYLOAD_BYTE_LEN];
+} nfapi_nr_dl_tti_pdcch_pdu_rel15_t;
+
+typedef struct {
+ uint16_t pduBitmap;
+ uint16_t rnti;
+ uint16_t pduIndex;
+ // BWP [TS38.213 sec 12]
+ /// Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP, Value: 1->275
+ uint16_t BWPSize;
+ /// bandwidth part start RB index from reference CRB [TS38.213 sec 12],Value: 0->274
+ uint16_t BWPStart;
+ /// subcarrierSpacing [TS38.211 sec 4.2], Value:0->4
+ uint8_t SubcarrierSpacing;
+ /// Cyclic prefix type [TS38.211 sec 4.2], 0: Normal; 1: Extended
+ uint8_t CyclicPrefix;
+ // Codeword information
+ /// Number of code words for this RNTI (UE), Value: 1 -> 2
+ uint8_t NrOfCodewords;
+ /// Target coding rate [TS38.212 sec 5.4.2.1 and 38.214 sec 5.1.3.1]. This is the number of information bits per 1024 coded bits expressed in 0.1 bit units
+ uint16_t targetCodeRate[2];
+ /// QAM modulation [TS38.212 sec 5.4.2.1 and 38.214 sec 5.1.3.1], Value: 2,4,6,8
+ uint8_t qamModOrder[2];
+ /// MCS index [TS38.214, sec 5.1.3.1], should match value sent in DCI Value : 0->31
+ uint8_t mcsIndex[2];
+ /// MCS-Table-PDSCH [TS38.214, sec 5.1.3.1] 0: notqam256, 1: qam256, 2: qam64LowSE
+ uint8_t mcsTable[2];
+ /// Redundancy version index [TS38.212, Table 5.4.2.1-2 and 38.214, Table 5.1.2.1-2], should match value sent in DCI Value : 0->3
+ uint8_t rvIndex[2];
+ /// Transmit block size (in bytes) [TS38.214 sec 5.1.3.2], Value: 0->65535
+ uint32_t TBSize[2];
+ /// dataScramblingIdentityPdsch [TS38.211, sec 7.3.1.1], It equals the higher-layer parameter Datascrambling-Identity if configured and the RNTI equals the C-RNTI, otherwise L2 needs to set it to physical cell id. Value: 0->65535
+ uint16_t dataScramblingId;
+ /// Number of layers [TS38.211, sec 7.3.1.3]. Value : 1->8
+ uint8_t nrOfLayers;
+ /// PDSCH transmission schemes [TS38.214, sec5.1.1] 0: Up to 8 transmission layers
+ uint8_t transmissionScheme;
+ /// Reference point for PDSCH DMRS "k" - used for tone mapping [TS38.211, sec 7.4.1.1.2] Resource block bundles [TS38.211, sec 7.3.1.6] Value: 0 -> 1 If 0, the 0 reference point for PDSCH DMRS is at Point A [TS38.211 sec 4.4.4.2]. Resource block bundles generated per sub-bullets 2 and 3 in [TS38.211, sec 7.3.1.6]. For sub-bullet 2, the start of bandwidth part must be set to the start of actual bandwidth part +NstartCORESET and the bandwidth of the bandwidth part must be set to the bandwidth of the initial bandwidth part. If 1, the DMRS reference point is at the lowest VRB/PRB of the allocation. Resource block bundles generated per sub-bullets 1 [TS38.211, sec 7.3.1.6]
+ uint8_t refPoint;
+ // DMRS [TS38.211 sec 7.4.1.1]
+ /// DMRS symbol positions [TS38.211, sec 7.4.1.1.2 and Tables 7.4.1.1.2-3 and 7.4.1.1.2-4] Bitmap occupying the 14 LSBs with: bit 0: first symbol and for each bit 0: no DMRS 1: DMRS
+ uint16_t dlDmrsSymbPos;
+ /// DL DMRS config type [TS38.211, sec 7.4.1.1.2] 0: type 1, 1: type 2
+ uint8_t dmrsConfigType;
+ /// DL-DMRS-Scrambling-ID [TS38.211, sec 7.4.1.1.2 ] If provided by the higher-layer and the PDSCH is scheduled by PDCCH with CRC scrambled by CRNTI or CS-RNTI, otherwise, L2 should set this to physical cell id. Value: 0->65535
+ uint16_t dlDmrsScramblingId;
+ /// DMRS sequence initialization [TS38.211, sec 7.4.1.1.2]. Should match what is sent in DCI 1_1, otherwise set to 0. Value : 0->1
+ uint8_t SCID;
+ /// Number of DM-RS CDM groups without data [TS38.212 sec 7.3.1.2.2] [TS38.214 Table 4.1-1] it determines the ratio of PDSCH EPRE to DM-RS EPRE. Value: 1->3
+ uint8_t numDmrsCdmGrpsNoData;
+ /// DMRS ports. [TS38.212 7.3.1.2.2] provides description between DCI 1-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used
+ uint16_t dmrsPorts;
+ // Pdsch Allocation in frequency domain [TS38.214, sec 5.1.2.2]
+ /// Resource Allocation Type [TS38.214, sec 5.1.2.2] 0: Type 0, 1: Type 1
+ uint8_t resourceAlloc;
+ /// For resource alloc type 0. TS 38.212 V15.0.x, 7.3.1.2.2 bitmap of RBs, 273 rounded up to multiple of 32. This bitmap is in units of VRBs. LSB of byte 0 of the bitmap represents the first RB of the bwp
+ uint8_t rbBitmap[36];
+ /// For resource allocation type 1. [TS38.214, sec 5.1.2.2.2] The starting resource block within the BWP for this PDSCH. Value: 0->274
+ uint16_t rbStart;
+ /// For resource allocation type 1. [TS38.214, sec 5.1.2.2.2] The number of resource block within for this PDSCH. Value: 1->275
+ uint16_t rbSize;
+ /// VRB-to-PRB-mapping [TS38.211, sec 7.3.1.6] 0: non-interleaved 1: interleaved with RB size 2 2: Interleaved with RB size 4
+ uint8_t VRBtoPRBMapping;
+ // Resource Allocation in time domain [TS38.214, sec 5.1.2.1]
+ /// Start symbol index of PDSCH mapping from the start of the slot, S. [TS38.214, Table 5.1.2.1-1] Value: 0->13
+ uint8_t StartSymbolIndex;
+ /// PDSCH duration in symbols, L [TS38.214, Table 5.1.2.1-1] Value: 1->14
+ uint8_t NrOfSymbols;
+ // PTRS [TS38.214, sec 5.1.6.3]
+ /// PT-RS antenna ports [TS38.214, sec 5.1.6.3] [TS38.211, table 7.4.1.2.2-1] Bitmap occupying the 6 LSBs with: bit 0: antenna port 1000 bit 5: antenna port 1005 and for each bit 0: PTRS port not used 1: PTRS port used
+ uint8_t PTRSPortIndex ;
+ /// PT-RS time density [TS38.214, table 5.1.6.3-1] 0: 1 1: 2 2: 4
+ uint8_t PTRSTimeDensity;
+ /// PT-RS frequency density [TS38.214, table 5.1.6.3-2] 0: 2 1: 4
+ uint8_t PTRSFreqDensity;
+ /// PT-RS resource element offset [TS38.211, table 7.4.1.2.2-1] Value: 0->3
+ uint8_t PTRSReOffset;
+ /// PT-RS-to-PDSCH EPRE ratio [TS38.214, table 4.1-2] Value :0->3
+ uint8_t nEpreRatioOfPDSCHToPTRS;
+ // Beamforming
+ nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming;
+}nfapi_nr_dl_tti_pdsch_pdu_rel15_t;
-} nfapi_nr_pdcch_pdu_t;
//for pdsch_pdu:
-
+/*
typedef struct
{
uint16_t target_code_rate;//
@@ -693,31 +848,32 @@ typedef struct
uint32_t dl_tb_crc;//TB CRC: to be used in the last CB, applicable only if last CB is present
} nfapi_nr_dlsch_pdu_t;
+*/
//for csi-rs_pdu:
//table 3-39
typedef struct
{
-uint16_t bwp_size;//
-uint16_t bwp_start;//
-uint8_t subcarrier_spacing;//
-uint8_t cyclic_prefix;//
-uint16_t start_rb;
-uint16_t nr_of_rbs;
-uint8_t csi_type;//Value: 0:TRS 1:CSI-RS NZP 2:CSI-RS ZP
-uint8_t row;//Row entry into the CSI Resource location table. [TS38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1] Value: 1-18
-uint16_t freq_domain;//Value: Up to the 12 LSBs, actual size is determined by the Row parameter
-uint8_t symb_l0;//The time domain location l0 and firstOFDMSymbolInTimeDomain Value: 0->13
-uint8_t symb_l1;//
-uint8_t cdm_type;
-uint8_t freq_density;//The density field, p and comb offset (for dot5).0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three
-uint16_t scramb_id;//ScramblingID of the CSI-RS [TS38.214, sec 5.2.2.3.1] Value: 0->1023
-//tx power info
-uint8_t power_control_offset;//Ratio of PDSCH EPRE to NZP CSI-RSEPRE Value :0->23 representing -8 to 15 dB in 1dB steps
-uint8_t power_control_offset_ss;//Ratio of SSB/PBCH block EPRE to NZP CSI-RS EPRES 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB
+ uint16_t bwp_size;//
+ uint16_t bwp_start;//
+ uint8_t subcarrier_spacing;//
+ uint8_t cyclic_prefix;//
+ uint16_t start_rb;
+ uint16_t nr_of_rbs;
+ uint8_t csi_type;//Value: 0:TRS 1:CSI-RS NZP 2:CSI-RS ZP
+ uint8_t row;//Row entry into the CSI Resource location table. [TS38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1] Value: 1-18
+ uint16_t freq_domain;//Value: Up to the 12 LSBs, actual size is determined by the Row parameter
+ uint8_t symb_l0;//The time domain location l0 and firstOFDMSymbolInTimeDomain Value: 0->13
+ uint8_t symb_l1;//
+ uint8_t cdm_type;
+ uint8_t freq_density;//The density field, p and comb offset (for dot5).0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three
+ uint16_t scramb_id;//ScramblingID of the CSI-RS [TS38.214, sec 5.2.2.3.1] Value: 0->1023
+ //tx power info
+ uint8_t power_control_offset;//Ratio of PDSCH EPRE to NZP CSI-RSEPRE Value :0->23 representing -8 to 15 dB in 1dB steps
+ uint8_t power_control_offset_ss;//Ratio of SSB/PBCH block EPRE to NZP CSI-RS EPRES 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB
-} nfapi_nr_csi_rs_pdu_t;
+} nfapi_nr_dl_tti_csi_rs_pdu_rel15_t;
//for ssb_pdu:
@@ -744,27 +900,85 @@ typedef struct
} nfapi_nr_bch_payload_t;
-typedef struct
-{
- uint16_t phys_cell_id;//0~1007
- uint8_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block 0 = 0dB 1 = 3dB
- uint8_t ssb_block_index;//SS/PBCH block index within a SSB burst set. Required for PBCH DMRS scrambling. Value: 0->63 (Lmax)
- uint8_t ssb_subcarrier_offset;//
- uint16_t ssb_offset_point_a;//Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Value: 0->2199
- uint8_t bch_payload_flag;//A value indicating how the BCH payload is generated. This should match the PARAM/CONFIG TLVs. Value: 0: MAC generates the full PBCH payload, see Table 3-41, where bchPayload has 31 bits 1: PHY generates the timing PBCH bits, see Table 3-41, where the bchPayload has 24 bits 2: PHY generates the full PBCH payload
- nfapi_nr_bch_payload_t bch_payload;
+typedef struct {
+ /// Physical Cell ID Value 0~>1007
+ uint16_t PhysCellId;
+ ///PSS EPRE to SSS EPRE in a SS/PBCH block 0 = 0dB 1 = 3dB
+ uint8_t BetaPss;
+ ///SS/PBCH block index within a SSB burst set. Required for PBCH DMRS scrambling. Value: 0->63 (Lmax)
+ uint8_t SsbBlockIndex;
+ /// ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (TS38.211, section 7.4.3.1) Value: 0->31
+ uint8_t SsbSubcarrierOffset;
+ ///Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Value: 0->2199
+ uint16_t ssbOffsetPointA;
+ /// A value indicating how the BCH payload is generated. This should match the PARAM/CONFIG TLVs. Value: 0: MAC generates the full PBCH payload, see Table 3-41, where bchPayload has 31 bits 1: PHY generates the timing PBCH bits, see Table 3-41, where the bchPayload has 24 bits 2: PHY generates the full PBCH payload
+ uint8_t bchPayloadFlag;
+ uint32_t bchPayload;
nfapi_nr_tx_precoding_and_beamforming_t precoding_and_beamforming;
+} nfapi_nr_dl_tti_ssb_pdu_rel15_t;
-} nfapi_nr_ssb_pdu_t;
+typedef struct {
+ nfapi_nr_dl_tti_ssb_pdu_rel15_t ssb_pdu_rel15;
+} nfapi_nr_dl_tti_ssb_pdu;
+typedef struct {
+ nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_rs_pdu_rel15;
+} nfapi_nr_dl_tti_csi_rs_pdu;
+
+typedef struct {
+ nfapi_nr_dl_tti_pdsch_pdu_rel15_t pdsch_pdu_rel15;
+} nfapi_nr_dl_tti_pdsch_pdu;
+
+typedef struct {
+ nfapi_nr_dl_tti_pdcch_pdu_rel15_t pdcch_pdu_rel15;
+} nfapi_nr_dl_tti_pdcch_pdu;
+
+typedef struct {
+ uint16_t PDUType;
+ uint16_t PDUSize;
+
+ union {
+ nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu;
+ nfapi_nr_dl_tti_pdsch_pdu pdsch_pdu;
+ nfapi_nr_dl_tti_csi_rs_pdu csi_rs_pdu;
+ nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
+ };
+} nfapi_nr_dl_tti_request_pdu_t;
+
+#define NFAPI_NR_MAX_DL_TTI_PDUS 32
+typedef struct {
+ /// Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255
+ uint8_t nPDUs;
+ /// Number of UEs in the Group included in this message. Value 0 -> 255
+ uint8_t nGroup;
+ /// List containing PDUs
+ nfapi_nr_dl_tti_request_pdu_t dl_tti_pdu_list[NFAPI_NR_MAX_DL_TTI_PDUS];
+ /// Number of UE in this group. For SU-MIMO, one group includes one UE only. For MU-MIMO, one group includes up to 12 UEs. Value 1 -> 12
+ uint8_t nUe[256];
+ /// This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 255
+ uint8_t PduIdx[256][12];
+} nfapi_nr_dl_tti_request_body_t;
+
+typedef struct {
+ nfapi_p7_message_header_t header;
+ /// System Frame Number (0-1023)
+ uint16_t SFN;
+ /// Slot number (0-319)
+ uint16_t Slot;
+ nfapi_nr_dl_tti_request_body_t dl_tti_request_body;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_dl_tti_request_t;
+
+/*
typedef struct
{
- nfapi_nr_pdcch_pdu_t* pdcch_pdu;
- nfapi_nr_dlsch_pdu_t* dlsch_pdu;//pdsch_pdu;
- nfapi_nr_csi_rs_pdu_t* csi_rs_pdu;
- nfapi_nr_ssb_pdu_t* ssb_pdu;
+ nfapi_nr_dl_tti_pdcch_pdu* pdcch_pdu;
+ nfapi_nr_dl_tti_pdsch_pdu* pdsch_pdu;
+ nfapi_nr_dl_tti_csi_rs_pdu_t* csi_rs_pdu;
+ nfapi_nr_dl_tti_ssb_pdu_t* ssb_pdu;
} nfapi_nr_dl_pdu_configuration_t;
-
+*/
+ /*
typedef struct
{
uint16_t pdu_type;//0: PDCCH PDU 1: PDSCH PDU 2: CSI-RS PDU 3: SSB PDU,
@@ -772,6 +986,7 @@ typedef struct
nfapi_nr_dl_pdu_configuration_t* dl_pdu_configuration;
} nfapi_nr_dl_tti_request_number_of_pdus_t;
+
typedef struct
{
@@ -796,9 +1011,10 @@ typedef struct {
nfapi_nr_dl_tti_request_number_of_groups_t* groups_list;
} nfapi_nr_dl_tti_request_t;
+*/
// Section 3.4.3 ul_tti_request
-
+
//for prach_pdu:
typedef struct
{
@@ -906,10 +1122,10 @@ typedef struct
uint16_t data_scrambling_id;
uint8_t nrOfLayers;
//DMRS
- uint8_t ul_dmrs_symb_pos;
+ uint16_t ul_dmrs_symb_pos;
uint8_t dmrs_config_type;
uint16_t ul_dmrs_scrambling_id;
- uint8_t scid;//
+ uint8_t scid;
uint8_t num_dmrs_cdm_grps_no_data;
uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
@@ -1016,6 +1232,13 @@ typedef struct
//
+typedef enum {
+ NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE = 0,
+ NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE = 1,
+ NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE = 2,
+ NFAPI_NR_DL_TTI_SSB_PDU_TYPE = 3,
+} nfapi_nr_dl_tti_pdu_type_e;
+
typedef enum {
NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE=0,
NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE,
@@ -1051,8 +1274,8 @@ typedef struct
} nfapi_nr_ul_tti_request_number_of_groups_t;
typedef struct {
- uint16_t sfn; //0->1023
- uint16_t slot;//0->319
+ uint16_t SFN; //0->1023
+ uint16_t Slot;//0->319
uint8_t n_pdus;//Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255
uint8_t rach_present;//Indicates if a RACH PDU will be included in this message. 0: no RACH in this slot 1: RACH in this slot
uint8_t n_ulsch;//Number of ULSCH PDUs that are included in this message.
@@ -1060,13 +1283,13 @@ typedef struct {
uint8_t n_group;//Number of UE Groups included in this message. Value 0 -> 8
nfapi_nr_ul_tti_request_number_of_pdus_t pdus_list[NFAPI_MAX_NUM_UL_PDU];
nfapi_nr_ul_tti_request_number_of_groups_t groups_list[NFAPI_MAX_NUM_GROUPS];
-
} nfapi_nr_ul_tti_request_t;
//3.4.4 ul_dci_request
//table 3-54
+/*
typedef struct
{
uint16_t pdu_type;//0: PDCCH PDU
@@ -1083,6 +1306,25 @@ typedef struct
nfapi_nr_ul_dci_request_number_of_pdus_t* pdu_list;
} nfapi_nr_ul_dci_request_t;
+*/
+
+ // normally one PDU per coreset per BWP
+#define NFAPI_NR_MAX_UL_DCI_PDUS 4
+
+typedef struct {
+ /// only possible value 0: PDCCH PDU
+ uint16_t PDUType;
+ ///Size of the PDU control information (in bytes). This length value includes the 4 bytes required for the PDU type and PDU size parameters. Value 0 -> 65535
+ uint16_t PDUSize;
+ nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu;
+} nfapi_nr_ul_dci_request_pdus_t;
+
+typedef struct {
+ uint16_t SFN;
+ uint16_t Slot;
+ uint8_t numPdus;
+ nfapi_nr_ul_dci_request_pdus_t ul_dci_pdu_list[NFAPI_NR_MAX_UL_DCI_PDUS];
+} nfapi_nr_ul_dci_request_t;
//3.4.5 slot_errors
typedef enum {
@@ -1099,6 +1341,7 @@ typedef enum {
} nfapi_nr_slot_errors_dl_tti_e;
+
typedef enum {
NFAPI_NR_SLOT_UL_DCI_MSG_INVALID_STATE,
NFAPI_NR_SLOT_UL_DCI_MSG_INVALID_SFN,
@@ -1109,23 +1352,23 @@ typedef enum {
//3.4.6 tx_data_request
//table 3-58
-
+#define NFAPI_NR_MAX_TX_REQUEST_TLV 2
typedef struct
{
- uint16_t pdu_length;
- uint16_t pdu_index;
- uint32_t num_tlv;
- //! fixme
- nfapi_int32_tlv_t* tlvs; //nfapi_int32_tlv_t tlvs[num_tlv]
+ uint16_t PDU_length;
+ uint16_t PDU_index;
+ uint32_t num_TLV;
+ nfapi_nr_tx_data_request_tlv_t TLVs[NFAPI_NR_MAX_TX_REQUEST_TLV];
} nfapi_nr_pdu_t;
+#define NFAPI_NR_MAX_TX_REQUEST_PDUS 16
typedef struct
{
- uint16_t sfn;
- uint16_t slot;
- uint16_t number_of_pdus;
- nfapi_nr_pdu_t* pdu_list;
+ uint16_t SFN;
+ uint16_t Slot;
+ uint16_t Number_of_PDUs;
+ nfapi_nr_pdu_t pdu_list[NFAPI_NR_MAX_TX_REQUEST_PDUS];
} nfapi_nr_tx_data_request_t;
diff --git a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h
index 5d463afdae..5abf6b75c3 100644
--- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h
+++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h
@@ -18,7 +18,8 @@
#define _NFAPI_VNF_INTERFACE_H_
#include "nfapi_interface.h"
-#include "nfapi_nr_interface.h"
+#include "nfapi_nr_interface_scf.h"
+
#include "debug.h"
#include "netinet/in.h"
@@ -938,7 +939,7 @@ int nfapi_vnf_p7_del_pnf(nfapi_vnf_p7_config_t* config, int phy_id);
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_dl_config_request_t* req);
-int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_config_request_t* req);
+int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req);
/*! Send the UL_CONFIG.request
* \param config A pointer to the vnf p7 configuration
diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c
index b7adc808ca..a0efeeb5f4 100644
--- a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c
+++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c
@@ -482,7 +482,7 @@ int nfapi_vnf_p7_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_dl_config_re
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
-int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_config_request_t* req)
+int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req)
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(config:%p req:%p)\n", __FUNCTION__, config, req);
diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c
index 7fcaa0646c..806d8de28c 100644
--- a/openair1/PHY/CODING/TESTBENCH/polartest.c
+++ b/openair1/PHY/CODING/TESTBENCH/polartest.c
@@ -175,7 +175,7 @@ if (logFlag){
double channelOutput[coderLength]; //add noise
int16_t channelOutput_int16[coderLength];
- t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level);
+ t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level, 1, NULL);
#ifdef DEBUG_DCI_POLAR_PARAMS
uint32_t dci_pdu[4];
diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h
index 540fd3b263..9b111309cd 100644
--- a/openair1/PHY/CODING/coding_defs.h
+++ b/openair1/PHY/CODING/coding_defs.h
@@ -481,6 +481,8 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm,
uint8_t *w,
uint8_t *e,
uint8_t C,
+ uint32_t F,
+ uint32_t Foffset,
uint8_t rvidx,
uint32_t E);
@@ -493,7 +495,9 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
uint8_t C,
uint8_t rvidx,
uint8_t clear,
- uint32_t E);
+ uint32_t E,
+ uint32_t F,
+ uint32_t Foffset);
decoder_if_t phy_threegpplte_turbo_decoder;
decoder_if_t phy_threegpplte_turbo_decoder8;
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h
index a3d829883d..db9d6e4119 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h
@@ -88,23 +88,29 @@ static inline void nrLDPC_cnProc_BG2(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_pr
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
+ __m256i *pj0 = &p_cnProcBuf[lut_idxCnProcG3[j][0]];
+ __m256i *pj1 = &p_cnProcBuf[lut_idxCnProcG3[j][1]];
+
// Loop over CNs
for (i=0; i
+#include
+#include
+#include
+#include
+#include "assertions.h"
+#include "common/utils/LOG/log.h"
+#include "PHY/TOOLS/time_meas.h"
+#include "defs.h"
+
+//#define DEBUG_LDPC
+
+#include "ldpc384_byte.c"
+#include "ldpc352_byte.c"
+#include "ldpc320_byte.c"
+#include "ldpc288_byte.c"
+#include "ldpc256_byte.c"
+#include "ldpc240_byte.c"
+#include "ldpc224_byte.c"
+#include "ldpc208_byte.c"
+#include "ldpc192_byte.c"
+#include "ldpc176_byte.c"
+#include "ldpc_BG2_Zc384_byte.c"
+#include "ldpc_BG2_Zc352_byte.c"
+#include "ldpc_BG2_Zc320_byte.c"
+#include "ldpc_BG2_Zc288_byte.c"
+#include "ldpc_BG2_Zc256_byte.c"
+#include "ldpc_BG2_Zc240_byte.c"
+#include "ldpc_BG2_Zc224_byte.c"
+#include "ldpc_BG2_Zc208_byte.c"
+#include "ldpc_BG2_Zc192_byte.c"
+#include "ldpc_BG2_Zc176_byte.c"
+#include "ldpc_BG2_Zc160_byte.c"
+#include "ldpc_BG2_Zc144_byte.c"
+#include "ldpc_BG2_Zc128_byte.c"
+#include "ldpc_BG2_Zc120_byte.c"
+#include "ldpc_BG2_Zc112_byte.c"
+#include "ldpc_BG2_Zc104_byte.c"
+#include "ldpc_BG2_Zc96_byte.c"
+#include "ldpc_BG2_Zc88_byte.c"
+#include "ldpc_BG2_Zc80_byte.c"
+#include "ldpc_BG2_Zc72_byte.c"
+
+
+
+void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb)
+{
+
+ if (BG==1)
+ {
+ switch (Zc)
+ {
+ case 2: break;
+ case 3: break;
+ case 4: break;
+ case 5: break;
+ case 6: break;
+ case 7: break;
+ case 8: break;
+ case 9: break;
+ case 10: break;
+ case 11: break;
+ case 12: break;
+ case 13: break;
+ case 14: break;
+ case 15: break;
+ case 16: break;
+ case 18: break;
+ case 20: break;
+ case 22: break;
+ case 24: break;
+ case 26: break;
+ case 28: break;
+ case 30: break;
+ case 32: break;
+ case 36: break;
+ case 40: break;
+ case 44: break;
+ case 48: break;
+ case 52: break;
+ case 56: break;
+ case 60: break;
+ case 64: break;
+ case 72: break;
+ case 80: break;
+ case 88: break;
+ case 96: break;
+ case 104: break;
+ case 112: break;
+ case 120: break;
+ case 128: break;
+ case 144: break;
+ case 160: break;
+ case 176: ldpc176_byte(c,d); break;
+ case 192: ldpc192_byte(c,d); break;
+ case 208: ldpc208_byte(c,d); break;
+ case 224: ldpc224_byte(c,d); break;
+ case 240: ldpc240_byte(c,d); break;
+ case 256: ldpc256_byte(c,d); break;
+ case 288: ldpc288_byte(c,d); break;
+ case 320: ldpc320_byte(c,d); break;
+ case 352: ldpc352_byte(c,d); break;
+ case 384: ldpc384_byte(c,d); break;
+ default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break;
+ }
+ }
+ else if (BG==2) {
+ switch (Zc)
+ {
+ case 2: break;
+ case 3: break;
+ case 4: break;
+ case 5: break;
+ case 6: break;
+ case 7: break;
+ case 8: break;
+ case 9: break;
+ case 10: break;
+ case 11: break;
+ case 12: break;
+ case 13: break;
+ case 14: break;
+ case 15: break;
+ case 16: break;
+ case 18: break;
+ case 20: break;
+ case 22: break;
+ case 24: break;
+ case 26: break;
+ case 28: break;
+ case 30: break;
+ case 32: break;
+ case 36: break;
+ case 40: break;
+ case 44: break;
+ case 48: break;
+ case 52: break;
+ case 56: break;
+ case 60: break;
+ case 64: break;
+ case 72: ldpc_BG2_Zc72_byte(c,d); break;
+ case 80: ldpc_BG2_Zc80_byte(c,d); break;
+ case 88: ldpc_BG2_Zc88_byte(c,d); break;
+ case 96: ldpc_BG2_Zc96_byte(c,d); break;
+ case 104: ldpc_BG2_Zc104_byte(c,d); break;
+ case 112: ldpc_BG2_Zc112_byte(c,d); break;
+ case 120: ldpc_BG2_Zc120_byte(c,d); break;
+ case 128: ldpc_BG2_Zc128_byte(c,d); break;
+ case 144: ldpc_BG2_Zc144_byte(c,d); break;
+ case 160: ldpc_BG2_Zc160_byte(c,d); break;
+ case 176: ldpc_BG2_Zc176_byte(c,d); break;
+ case 192: ldpc_BG2_Zc192_byte(c,d); break;
+ case 208: ldpc_BG2_Zc208_byte(c,d); break;
+ case 224: ldpc_BG2_Zc224_byte(c,d); break;
+ case 240: ldpc_BG2_Zc240_byte(c,d); break;
+ case 256: ldpc_BG2_Zc256_byte(c,d); break;
+ case 288: ldpc_BG2_Zc288_byte(c,d); break;
+ case 320: ldpc_BG2_Zc320_byte(c,d); break;
+ case 352: ldpc_BG2_Zc352_byte(c,d); break;
+ case 384: ldpc_BG2_Zc384_byte(c,d); break;
+ default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break;
+ }
+ }
+ else {
+ AssertFatal(0,"BG %d is not supported yet\n",BG);
+ }
+
+}
+
+
+int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
+{
+
+ short nrows=0,ncols=0;
+ int i,i1,rate=3;
+ int no_punctured_columns,removed_bit;
+
+ int simd_size;
+
+ //determine number of bits in codeword
+ //if (block_length>3840)
+ if (BG==1)
+ {
+ //BG=1;
+ nrows=46; //parity check bits
+ ncols=22; //info bits
+ rate=3;
+ }
+ //else if (block_length<=3840)
+ else if (BG==2)
+ {
+ //BG=2;
+ nrows=42; //parity check bits
+ ncols=10; // info bits
+ rate=5;
+
+ }
+
+
+#ifdef DEBUG_LDPC
+ LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length);
+ LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU %x %x %x %x\n",test_input[0],test_input[1],test_input[2],test_input[3]);
+#endif
+
+ if ((Zc&31) > 0) simd_size = 16;
+ else simd_size = 32;
+
+ unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
+ unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
+
+ unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
+
+ // calculate number of punctured bits
+ no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
+ removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
+ // printf("%d\n",no_punctured_columns);
+ // printf("%d\n",removed_bit);
+ // unpack input
+ memset(c,0,sizeof(unsigned char) * ncols * Zc);
+ memset(d,0,sizeof(unsigned char) * nrows * Zc);
+
+ if(tinput != NULL) start_meas(tinput);
+ for (i=0; i>(i&7)))>>(7-(i&7));
+ //printf("c(%d,%d)=%d\n",j,i,temp);
+ }
+
+ if(tinput != NULL) stop_meas(tinput);
+
+ if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) {
+ // extend matrix
+ if(tprep != NULL) start_meas(tprep);
+ for (i1=0; i1 < ncols; i1++)
+ {
+ memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+ memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+ }
+ for (i1=1;i1 8 bytes, pattern repeats.
+ __m256i zero256 = _mm256_setzero_si256();
+ __m256i masks[8];
+ register __m256i c256;
+ masks[0] = _mm256_set1_epi8(0x1);
+ masks[1] = _mm256_set1_epi8(0x2);
+ masks[2] = _mm256_set1_epi8(0x4);
+ masks[3] = _mm256_set1_epi8(0x8);
+ masks[4] = _mm256_set1_epi8(0x10);
+ masks[5] = _mm256_set1_epi8(0x20);
+ masks[6] = _mm256_set1_epi8(0x40);
+ masks[7] = _mm256_set1_epi8(0x80);
+#endif
+
+ AssertFatal(n_segments>0&&n_segments<=8,"0 < n_segments %d <= 8\n",n_segments);
+
+ //determine number of bits in codeword
+ //if (block_length>3840)
+ if (BG==1)
+ {
+ nrows=46; //parity check bits
+ ncols=22; //info bits
+ rate=3;
+ }
+ //else if (block_length<=3840)
+ else if (BG==2)
+ {
+ //BG=2;
+ nrows=42; //parity check bits
+ ncols=10; // info bits
+ rate=5;
+
+ }
+
+#ifdef DEBUG_LDPC
+ LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
+ LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
+#endif
+
+ AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
+
+ if ((Zc&31) > 0) simd_size = 16;
+ else simd_size = 32;
+
+ unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
+ unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
+
+ unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
+
+ // calculate number of punctured bits
+ no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
+ removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
+ // printf("%d\n",no_punctured_columns);
+ // printf("%d\n",removed_bit);
+ // unpack input
+ memset(c,0,sizeof(unsigned char) * ncols * Zc);
+ memset(d,0,sizeof(unsigned char) * nrows * Zc);
+
+ if(tinput != NULL) start_meas(tinput);
+#if 0
+ for (i=0; i>(i&7)))>>(7-(i&7));
+ //printf("c(%d,%d)=%d\n",j,i,temp);
+ c[i] |= (temp << j);
+ }
+ }
+#else
+#ifdef __AVX2__
+ for (i=0; i>5; i++) {
+ c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[0])[i]), shufmask),andmask),zero256),masks[0]);
+ for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7));
+ //printf("c(%d,%d)=%d\n",j,i,temp);
+ c[i] |= (temp << j);
+ }
+ }
+#else
+ AssertFatal(1==0,"Need AVX2 for this\n");
+#endif
+#endif
+
+ if(tinput != NULL) stop_meas(tinput);
+
+ if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) {
+ // extend matrix
+ if(tprep != NULL) start_meas(tprep);
+ for (i1=0; i1 < ncols; i1++)
+ {
+ memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+ memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+ }
+ for (i1=1;i1>5;
+ uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5;
+ __m256i *c256p = (__m256i *)&c[2*Zc];
+ __m256i *d256p = (__m256i *)&d[0];
+ // if (((block_length-(2*Zc))&31)>0) l1++;
+
+ for (i=0;i0) l2++;
+
+ for (i1=0;i1>j)&1;
+ for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
+ for (j=0; j>j)&1;
+ }
+
+#else
+ AssertFatal(1==0,"Need AVX2 for now\n");
+#endif
+
+ if(toutput != NULL) stop_meas(toutput);
+ return 0;
+}
+
+int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
+{
+
+ short nrows=0,ncols=0;
+ int i,i1,j,rate=3;
+ int no_punctured_columns,removed_bit;
+ //Table of possible lifting sizes
+ char temp;
+ int simd_size;
+ unsigned int macro_segment, macro_segment_end;
+
+
+ macro_segment = 8*macro_num;
+ macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments;
+ //macro_segment_end = macro_segment + (n_segments > 8 ? 8 : n_segments);
+ //printf("macro_segment: %d\n", macro_segment);
+ //printf("macro_segment_end: %d\n", macro_segment_end );
+
+#ifdef __AVX2__
+ __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000);
+ __m256i andmask = _mm256_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats.
+ __m256i zero256 = _mm256_setzero_si256();
+ __m256i masks[8];
+ register __m256i c256;
+ masks[0] = _mm256_set1_epi8(0x1);
+ masks[1] = _mm256_set1_epi8(0x2);
+ masks[2] = _mm256_set1_epi8(0x4);
+ masks[3] = _mm256_set1_epi8(0x8);
+ masks[4] = _mm256_set1_epi8(0x10);
+ masks[5] = _mm256_set1_epi8(0x20);
+ masks[6] = _mm256_set1_epi8(0x40);
+ masks[7] = _mm256_set1_epi8(0x80);
+#endif
+
+
+
+ //determine number of bits in codeword
+ if (BG==1)
+ {
+ nrows=46; //parity check bits
+ ncols=22; //info bits
+ rate=3;
+ }
+ else if (BG==2)
+ {
+ nrows=42; //parity check bits
+ ncols=10; // info bits
+ rate=5;
+ }
+
+#ifdef DEBUG_LDPC
+ LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
+ LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
+#endif
+
+ AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
+
+ if ((Zc&31) > 0) simd_size = 16;
+ else simd_size = 32;
+
+ unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
+ unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
+
+ unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
+
+ // calculate number of punctured bits
+ no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
+ removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
+ //printf("%d\n",no_punctured_columns);
+ //printf("%d\n",removed_bit);
+ // unpack input
+ memset(c,0,sizeof(unsigned char) * ncols * Zc);
+ memset(d,0,sizeof(unsigned char) * nrows * Zc);
+
+ if(tinput != NULL) start_meas(tinput);
+#if 0
+ for (i=0; i>(i&7);
+ //printf("c(%d,%d)=%d\n",j,i,temp);
+ c[i] |= (temp << (j-macro_segment));
+ }
+ }
+#else
+#ifdef __AVX2__
+ for (i=0; i>5; i++) {
+ c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]);
+ //for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7));
+ //printf("c(%d,%d)=%d\n",j,i,temp);
+ c[i] |= (temp << (j-macro_segment));
+ }
+ }
+#else
+ AssertFatal(1==0,"Need AVX2 for this\n");
+#endif
+#endif
+
+ if(tinput != NULL) stop_meas(tinput);
+
+ if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) {
+ // extend matrix
+ if(tprep != NULL) start_meas(tprep);
+ for (i1=0; i1 < ncols; i1++)
+ {
+ memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+ memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
+ }
+ for (i1=1;i1>5;
+ uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5;
+ __m256i *c256p = (__m256i *)&c[2*Zc];
+ __m256i *d256p = (__m256i *)&d[0];
+ // if (((block_length-(2*Zc))&31)>0) l1++;
+
+ for (i=0;i0) l2++;
+
+ for (i1=0;i1>(j-macro_segment))&1;
+ for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
+ //for (j=0; j>(j-macro_segment))&1;
+ }
+
+#else
+ AssertFatal(1==0,"Need AVX2 for now\n");
+#endif
+
+ if(toutput != NULL) stop_meas(toutput);
+ return 0;
+}
+
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
index 28ab5b5029..b21f875b32 100644
--- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
@@ -58,8 +58,7 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
macro_segment = 8*impp->macro_num;
- // macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments;
- macro_segment_end = macro_segment + (impp->n_segments > 8 ? 8 : impp->n_segments);
+ macro_segment_end = (impp->n_segments > 8*(impp->macro_num+1)) ? 8*(impp->macro_num+1) : impp->n_segments;
///printf("macro_segment: %d\n", macro_segment);
///printf("macro_segment_end: %d\n", macro_segment_end );
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
index a130484c8e..6e01a05d0f 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h
@@ -187,7 +187,9 @@ void nr_polar_print_polarParams(t_nrPolar_params *polarParams);
t_nrPolar_params *nr_polar_params (int8_t messageType,
uint16_t messageLength,
- uint8_t aggregation_level);
+ uint8_t aggregation_level,
+ int decoder_flag,
+ t_nrPolar_params **polarList_ext);
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level);
diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c
index efc78d91fd..f6a06b3f7f 100644
--- a/openair1/PHY/CODING/nr_polar_init.c
+++ b/openair1/PHY/CODING/nr_polar_init.c
@@ -40,7 +40,8 @@ static int intcmp(const void *p1,const void *p2) {
static void nr_polar_init(t_nrPolar_params * *polarParams,
int8_t messageType,
uint16_t messageLength,
- uint8_t aggregation_level) {
+ uint8_t aggregation_level,
+ int decoder_flag) {
t_nrPolar_params *currentPtr = *polarParams;
uint16_t aggregation_prime = nr_polar_aggregation_prime(aggregation_level);
@@ -150,7 +151,7 @@ static void nr_polar_init(t_nrPolar_params * *polarParams,
newPolarInitNode->i_bil,
newPolarInitNode->encoderLength);
free(J);
- build_decoder_tree(newPolarInitNode);
+ if (decoder_flag == 1) build_decoder_tree(newPolarInitNode);
build_polar_tables(newPolarInitNode);
init_polar_deinterleaver_table(newPolarInitNode);
//printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes);
@@ -183,10 +184,13 @@ void nr_polar_print_polarParams(t_nrPolar_params *polarParams) {
t_nrPolar_params *nr_polar_params (int8_t messageType,
uint16_t messageLength,
- uint8_t aggregation_level) {
+ uint8_t aggregation_level,
+ int decoding_flag,
+ t_nrPolar_params **polarList_ext) {
static t_nrPolar_params *polarList = NULL;
- nr_polar_init(&polarList, messageType,messageLength,aggregation_level);
- t_nrPolar_params *polarParams=polarList;
+ nr_polar_init(polarList_ext != NULL ? polarList_ext : &polarList,
+ messageType,messageLength,aggregation_level,decoding_flag);
+ t_nrPolar_params *polarParams=polarList_ext != NULL ? *polarList_ext : polarList;
const int tag=messageType * messageLength * nr_polar_aggregation_prime(aggregation_level);
while (polarParams != NULL) {
diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c
index 9d50b4678b..0cffc2d852 100644
--- a/openair1/PHY/CODING/nr_rate_matching.c
+++ b/openair1/PHY/CODING/nr_rate_matching.c
@@ -32,23 +32,281 @@
uint8_t index_k0[2][4] = {{0,17,33,56},{0,13,25,43}};
-
void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f)
{
uint32_t EQm;
EQm = E/Qm;
memset(f,0,E*sizeof(uint8_t));
+ uint8_t *e0,*e1,*e2,*e3,*e4,*e5,*e6,*e7;
+ uint8_t *fp;
+#if 0 //def __AVX2__
+ __m256i tmp0,tmp1,tmp2,tmp0b,tmp1b,tmp3,tmp4,tmp5;
+ __m256i *e0_256,*e1_256,*e2_256,*e3_256,*e4_256,*e5_256,*e6_256,*e7_256;
- for (int j = 0; j< EQm; j++){
- for (int i = 0; i< Qm; i++){
- f[(i+j*Qm)] = e[(i*EQm + j)];
- }
+ __m256i *f_256=(__m256i *)f;
+
+ uint8_t *fp2;
+ switch(Qm) {
+ case 2:
+ e0=e;
+ e1=e0+EQm;
+ e0_256=(__m256i *)e0;
+ e1_256=(__m256i *)e1;
+ for (int k=0,j=0;j>5;j++,k+=2) {
+ f_256[k] = _mm256_unpacklo_epi8(e0_256[j],e1_256[j]);
+ f_256[k+1] = _mm256_unpackhi_epi8(e0_256[j],e1_256[j]);
+ }
+ break;
+ case 4:
+ e0=e;
+ e1=e0+EQm;
+ e2=e1+EQm;
+ e3=e2+EQm;
+ e0_256=(__m256i *)e0;
+ e1_256=(__m256i *)e1;
+ e2_256=(__m256i *)e2;
+ e3_256=(__m256i *)e3;
+ for (int k=0,j=0;j>5;j++,k+=4) {
+ tmp0 = _mm256_unpacklo_epi8(e0_256[j],e1_256[j]); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15)
+ tmp1 = _mm256_unpacklo_epi8(e2_256[j],e3_256[j]); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15)
+ f_256[k] = _mm256_unpacklo_epi8(tmp0,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7)
+ f_256[k+1] = _mm256_unpackhi_epi8(tmp0,tmp1); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15)
+ tmp0 = _mm256_unpackhi_epi8(e0_256[j],e1_256[j]); // e0(i+16) e1(i+16) e0(i+17) e1(i+17) .... e0(i+31) e1(i+31)
+ tmp1 = _mm256_unpackhi_epi8(e2_256[j],e3_256[j]); // e2(i+16) e3(i+16) e2(i+17) e3(i+17) .... e2(i+31) e3(i+31)
+ f_256[k+2] = _mm256_unpacklo_epi8(tmp0,tmp1);
+ f_256[k+3] = _mm256_unpackhi_epi8(tmp0,tmp1);
+ }
+ break;
+ case 6:
+ e0=e;
+ e1=e0+EQm;
+ e2=e1+EQm;
+ e3=e2+EQm;
+ e4=e3+EQm;
+ e5=e4+EQm;
+ e0_256=(__m256i *)e0;
+ e1_256=(__m256i *)e1;
+ e2_256=(__m256i *)e2;
+ e3_256=(__m256i *)e3;
+ e4_256=(__m256i *)e4;
+ e5_256=(__m256i *)e5;
+
+ for (int j=0,k=0;j>5;j++,k+=192) {
+ fp = f+k;
+ fp2 = fp+96;
+
+ tmp0 = _mm256_unpacklo_epi8(e0_256[j],e1_256[j]); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15)
+ tmp1 = _mm256_unpacklo_epi8(e2_256[j],e3_256[j]); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15)
+ tmp0b = _mm256_unpacklo_epi16(tmp0,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7)
+ tmp1b = _mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15)
+ tmp0 = _mm256_unpacklo_epi8(e4_256[j],e5_256[j]); // e4(i) e5(i) e4(i+1) e5(i+1) .... e4(i+15) e5(i+15)
+ *((uint32_t*)fp) = _mm256_extract_epi32(tmp0b,0);
+ *((uint16_t*)(fp+4)) = _mm256_extract_epi16(tmp0,0);
+ *((uint32_t*)(fp+6)) = _mm256_extract_epi32(tmp0b,1);
+ *((uint16_t*)(fp+10)) = _mm256_extract_epi16(tmp0,1);
+ *((uint32_t*)(fp+12)) = _mm256_extract_epi32(tmp0b,2);
+ *((uint16_t*)(fp+16)) = _mm256_extract_epi16(tmp0,2);
+ *((uint32_t*)(fp+18)) = _mm256_extract_epi32(tmp0b,3);
+ *((uint16_t*)(fp+22)) = _mm256_extract_epi16(tmp0,3);
+ *((uint32_t*)(fp+24)) = _mm256_extract_epi32(tmp0b,4);
+ *((uint16_t*)(fp+26)) = _mm256_extract_epi16(tmp0,4);
+ *((uint32_t*)(fp+30)) = _mm256_extract_epi32(tmp0b,5);
+ *((uint16_t*)(fp+34)) = _mm256_extract_epi16(tmp0,5);
+ *((uint32_t*)(fp+36)) = _mm256_extract_epi32(tmp0,6);
+ *((uint16_t*)(fp+40)) = _mm256_extract_epi16(tmp0,6);
+ *((uint32_t*)(fp+42)) = _mm256_extract_epi32(tmp0b,7);
+ *((uint16_t*)(fp+46)) = _mm256_extract_epi16(tmp0,7);
+
+ *((uint32_t*)(fp+48)) = _mm256_extract_epi32(tmp1b,0);
+ *((uint16_t*)(fp+52)) = _mm256_extract_epi16(tmp0,8);
+ *((uint32_t*)(fp+56)) = _mm256_extract_epi32(tmp1b,1);
+ *((uint16_t*)(fp+60)) = _mm256_extract_epi16(tmp0,9);
+ *((uint32_t*)(fp+62)) = _mm256_extract_epi32(tmp1b,2);
+ *((uint16_t*)(fp+66)) = _mm256_extract_epi16(tmp0,10);
+ *((uint32_t*)(fp+68)) = _mm256_extract_epi32(tmp1b,3);
+ *((uint16_t*)(fp+72)) = _mm256_extract_epi16(tmp0,11);
+ *((uint32_t*)(fp+74)) = _mm256_extract_epi32(tmp1b,4);
+ *((uint16_t*)(fp+76)) = _mm256_extract_epi16(tmp0,12);
+ *((uint32_t*)(fp+80)) = _mm256_extract_epi32(tmp1b,5);
+ *((uint16_t*)(fp+82)) = _mm256_extract_epi16(tmp0,13);
+ *((uint32_t*)(fp+86)) = _mm256_extract_epi32(tmp1b,6);
+ *((uint16_t*)(fp+90)) = _mm256_extract_epi16(tmp0,14);
+ *((uint32_t*)(fp+92)) = _mm256_extract_epi32(tmp1b,7);
+ *((uint16_t*)(fp+94)) = _mm256_extract_epi16(tmp0,15);
+
+ tmp0 = _mm256_unpackhi_epi8(e0_256[j],e1_256[j]); // e0(i+16) e1(i+16) e0(i+17) e1(i+17) .... e0(i+31) e1(i+31)
+ tmp1 = _mm256_unpackhi_epi8(e2_256[j],e3_256[j]); // e2(i+16) e3(i+16) e2(i+17) e3(i+17) .... e2(i+31) e3(i+31)
+ tmp0b = _mm256_unpacklo_epi16(tmp0,tmp1); // e0(i+16) e1(i+16) e2(i+16) e3(i+16) ... e0(i+23) e1(i+23) e2(i+23) e3(i+23)
+ tmp1b = _mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) ... e0(i+31) e1(i+31) e2(i+31) e3(i+31)
+ tmp0 = _mm256_unpackhi_epi8(e4_256[j],e5_256[j]); // e4(i+16) e5(i+16) e4(i+17) e5(i+17) .... e4(i+31) e5(i+31)
+ *((uint32_t*)fp2) = _mm256_extract_epi32(tmp0b,0);
+ *((uint16_t*)(fp2+4)) = _mm256_extract_epi16(tmp0,0);
+ *((uint32_t*)(fp2+6)) = _mm256_extract_epi32(tmp0b,1);
+ *((uint16_t*)(fp2+10)) = _mm256_extract_epi16(tmp0,1);
+ *((uint32_t*)(fp2+12)) = _mm256_extract_epi32(tmp0b,2);
+ *((uint16_t*)(fp2+16)) = _mm256_extract_epi16(tmp0,2);
+ *((uint32_t*)(fp2+18)) = _mm256_extract_epi32(tmp0b,3);
+ *((uint16_t*)(fp2+22)) = _mm256_extract_epi16(tmp0,3);
+ *((uint32_t*)(fp2+24)) = _mm256_extract_epi32(tmp0b,4);
+ *((uint16_t*)(fp2+26)) = _mm256_extract_epi16(tmp0,4);
+ *((uint32_t*)(fp2+30)) = _mm256_extract_epi32(tmp0b,5);
+ *((uint16_t*)(fp2+34)) = _mm256_extract_epi16(tmp0,5);
+ *((uint32_t*)(fp2+36)) = _mm256_extract_epi32(tmp0,6);
+ *((uint16_t*)(fp2+40)) = _mm256_extract_epi16(tmp0,6);
+ *((uint32_t*)(fp2+42)) = _mm256_extract_epi32(tmp0b,7);
+ *((uint16_t*)(fp2+46)) = _mm256_extract_epi16(tmp0,7);
+
+ *((uint32_t*)(fp2+48)) = _mm256_extract_epi32(tmp1b,0);
+ *((uint16_t*)(fp2+52)) = _mm256_extract_epi16(tmp0,8);
+ *((uint32_t*)(fp2+56)) = _mm256_extract_epi32(tmp1b,1);
+ *((uint16_t*)(fp2+60)) = _mm256_extract_epi16(tmp0,9);
+ *((uint32_t*)(fp2+62)) = _mm256_extract_epi32(tmp1b,2);
+ *((uint16_t*)(fp2+66)) = _mm256_extract_epi16(tmp0,10);
+ *((uint32_t*)(fp2+68)) = _mm256_extract_epi32(tmp1b,3);
+ *((uint16_t*)(fp2+72)) = _mm256_extract_epi16(tmp0,11);
+ *((uint32_t*)(fp2+74)) = _mm256_extract_epi32(tmp1b,4);
+ *((uint16_t*)(fp2+76)) = _mm256_extract_epi16(tmp0,12);
+ *((uint32_t*)(fp2+80)) = _mm256_extract_epi32(tmp1b,5);
+ *((uint16_t*)(fp2+82)) = _mm256_extract_epi16(tmp0,13);
+ *((uint32_t*)(fp2+86)) = _mm256_extract_epi32(tmp1b,6);
+ *((uint16_t*)(fp2+90)) = _mm256_extract_epi16(tmp0,14);
+ *((uint32_t*)(fp2+92)) = _mm256_extract_epi32(tmp1b,7);
+ *((uint16_t*)(fp2+94)) = _mm256_extract_epi16(tmp0,15);
+ }
+ break;
+ case 8:
+ e0=e;
+ e1=e0+EQm;
+ e2=e1+EQm;
+ e3=e2+EQm;
+ e4=e3+EQm;
+ e5=e4+EQm;
+ e6=e5+EQm;
+ e7=e6+EQm;
+
+ e0_256=(__m256i *)e0;
+ e1_256=(__m256i *)e1;
+ e2_256=(__m256i *)e2;
+ e3_256=(__m256i *)e3;
+ e4_256=(__m256i *)e4;
+ e5_256=(__m256i *)e5;
+ e6_256=(__m256i *)e6;
+ e7_256=(__m256i *)e7;
+ for (int k=0,j=0;j>5;j++,k+=8) {
+ tmp0 = _mm256_unpacklo_epi8(e0_256[j],e1_256[j]); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15)
+ tmp1 = _mm256_unpacklo_epi8(e2_256[j],e3_256[j]); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15)
+ tmp2 = _mm256_unpacklo_epi8(e4_256[j],e5_256[j]); // e4(i) e5(i) e4(i+1) e5(i+1) .... e4(i+15) e5(i+15)
+ tmp3 = _mm256_unpacklo_epi8(e6_256[j],e7_256[j]); // e6(i) e7(i) e6(i+1) e7(i+1) .... e6(i+15) e7(i+15)
+ tmp4 = _mm256_unpacklo_epi16(tmp0,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7)
+ tmp5 = _mm256_unpacklo_epi16(tmp2,tmp3); // e4(i) e5(i) e6(i) e7(i) ... e4(i+7) e5(i+7) e6(i+7) e7(i+7)
+ f_256[k] = _mm256_unpacklo_epi16(tmp4,tmp5); // e0(i) e1(i) e2(i) e3(i) e4(i) e5(i) e6(i) e7(i)... e0(i+3) e1(i+3) e2(i+3) e3(i+3) e4(i+3) e5(i+3) e6(i+3) e7(i+3))
+ f_256[k+1] = _mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+4) e1(i+4) e2(i+4) e3(i+4) e4(i+4) e5(i+4) e6(i+4) e7(i+4)... e0(i+7) e1(i+7) e2(i+7) e3(i+7) e4(i+7) e5(i+7) e6(i+7) e7(i+7))
+
+ tmp4 = _mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15)
+ tmp5 = _mm256_unpackhi_epi16(tmp2,tmp3); // e4(i+8) e5(i+8) e6(i+8) e7(i+8) ... e4(i+15) e5(i+15) e6(i+15) e7(i+15)
+ f_256[k+2] = _mm256_unpacklo_epi16(tmp4,tmp5); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) e4(i+8) e5(i+8) e6(i+8) e7(i+8)... e0(i+11) e1(i+11) e2(i+11) e3(i+11) e4(i+11) e5(i+11) e6(i+11) e7(i+11))
+ f_256[k+3] = _mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+12) e1(i+12) e2(i+12) e3(i+12) e4(i+12) e5(i+12) e6(i+12) e7(i+12)... e0(i+15) e1(i+15) e2(i+15) e3(i+15) e4(i+15) e5(i+15) e6(i+15) e7(i+15))
+
+ tmp0 = _mm256_unpackhi_epi8(e0_256[j],e1_256[j]); // e0(i+16) e1(i+16) e0(i+17) e1(i+17) .... e0(i+31) e1(i+31)
+ tmp1 = _mm256_unpackhi_epi8(e2_256[j],e3_256[j]); // e2(i+16) e3(i+16) e2(i+17) e3(i+17) .... e2(i+31) e3(i+31)
+ tmp2 = _mm256_unpackhi_epi8(e4_256[j],e5_256[j]); // e4(i+16) e5(i+16) e4(i+17) e5(i+17) .... e4(i+31) e5(i+31)
+ tmp3 = _mm256_unpackhi_epi8(e6_256[j],e7_256[j]); // e6(i+16) e7(i+16) e6(i+17) e7(i+17) .... e6(i+31) e7(i+31)
+ tmp4 = _mm256_unpacklo_epi16(tmp0,tmp1); // e0(i+!6) e1(i+16) e2(i+16) e3(i+16) ... e0(i+23) e1(i+23) e2(i+23) e3(i+23)
+ tmp5 = _mm256_unpacklo_epi16(tmp2,tmp3); // e4(i+16) e5(i+16) e6(i+16) e7(i+16) ... e4(i+23) e5(i+23) e6(i+23) e7(i+23)
+ f_256[k+4] = _mm256_unpacklo_epi16(tmp4,tmp5); // e0(i+16) e1(i+16) e2(i+16) e3(i+16) e4(i+16) e5(i+16) e6(i+16) e7(i+16)... e0(i+19) e1(i+19) e2(i+19) e3(i+19) e4(i+19) e5(i+19) e6(i+19) e7(i+19))
+ f_256[k+5] = _mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+20) e1(i+20) e2(i+20) e3(i+20) e4(i+20) e5(i+20) e6(i+20) e7(i+20)... e0(i+23) e1(i+23) e2(i+23) e3(i+23) e4(i+23) e5(i+23) e6(i+23) e7(i+23))
+
+ tmp4 = _mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) ... e0(i+31) e1(i+31) e2(i+31) e3(i+31)
+ tmp5 = _mm256_unpackhi_epi16(tmp2,tmp3); // e4(i+24) e5(i+24) e6(i+24) e7(i+24) ... e4(i+31) e5(i+31) e6(i+31) e7(i+31)
+ f_256[k+6] = _mm256_unpacklo_epi16(tmp4,tmp5); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) e4(i+24) e5(i+24) e6(i+24) e7(i+24)... e0(i+27) e1(i+27) e2(i+27) e3(i+27) e4(i+27) e5(i+27) e6(i+27) e7(i+27))
+ f_256[k+7] = _mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+28) e1(i+28) e2(i+28) e3(i+28) e4(i+28) e5(i+28) e6(i+28) e7(i+28)... e0(i+31) e1(i+31) e2(i+31) e3(i+31) e4(i+31) e5(i+31) e6(i+31) e7(i+31))
+ }
+ break;
+ default: AssertFatal(1==0,"Should be here!\n");
}
+#else
+ //original unoptimized loops
+ /*
+ for (int j = 0; j< EQm; j++,j2+=2){
+ for (int i = 0; i< Qm; i++){
+ f[(i+j*Qm)] = e[(i*EQm + j)];
+ }
+ }
+ */
+
+ int j2=0;
+ fp=f;
+ switch (Qm) {
+ case 2:
+ e0=e;
+ e1=e0+EQm;
+ for (int j = 0; j< EQm; j++,j2+=2){
+ fp=&f[j2];
+ fp[0] = e0[j];
+ fp[1] = e1[j];
+ }
+ break;
+ case 4:
+ e0=e;
+ e1=e0+EQm;
+ e2=e1+EQm;
+ e3=e2+EQm;
+ for (int j = 0; j< EQm; j++,j2+=4){
+ fp=&f[j2];
+ fp[0] = e0[j];
+ fp[1] = e1[j];
+ fp[2] = e2[j];
+ fp[3] = e3[j];
+ }
+ break;
+ case 6:
+ e0=e;
+ e1=e0+EQm;
+ e2=e1+EQm;
+ e3=e2+EQm;
+ e4=e3+EQm;
+ e5=e4+EQm;
+ fp = f;
+ for (int j = 0; j< EQm; j++){
+ *fp++ = e0[j];
+ *fp++ = e1[j];
+ *fp++ = e2[j];
+ *fp++ = e3[j];
+ *fp++ = e4[j];
+ *fp++ = e5[j];
+ }
+ break;
+ case 8:
+ e0=e;
+ e1=e0+EQm;
+ e2=e1+EQm;
+ e3=e2+EQm;
+ e4=e3+EQm;
+ e5=e4+EQm;
+ e6=e5+EQm;
+ e7=e6+EQm;
+ for (int j = 0; j< EQm; j++,j2+=8){
+ fp=&f[j2];
+ fp[0] = e0[j];
+ fp[1] = e1[j];
+ fp[2] = e2[j];
+ fp[3] = e3[j];
+ fp[4] = e4[j];
+ fp[5] = e5[j];
+ fp[6] = e6[j];
+ fp[7] = e7[j];
+ }
+ break;
+ default: AssertFatal(1==0,"Should never be here!\n");
+ }
+#endif
}
+
+
void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f)
{
@@ -71,10 +329,12 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm,
uint8_t *w,
uint8_t *e,
uint8_t C,
+ uint32_t F,
+ uint32_t Foffset,
uint8_t rvidx,
uint32_t E)
{
- uint32_t Ncb,ind,k,Nref,N;
+ uint32_t Ncb,ind,k=0,Nref,N;
if (C==0) {
printf("nr_rate_matching: invalid parameters (C %d\n",C);
@@ -94,21 +354,36 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm,
ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z;
#ifdef RM_DEBUG
- printf("nr_rate_matching_ldpc: E %d, k0 %d, Ncb %d, rvidx %d\n", E, ind, Ncb, rvidx);
+ printf("nr_rate_matching_ldpc: E %d, F %d, Foffset %d, k0 %d, Ncb %d, rvidx %d\n", E, F, Foffset,ind, Ncb, rvidx);
#endif
+ AssertFatal(Foffset <= E,"Foffset %d > E %d\n",Foffset,E);
+ AssertFatal(Foffset <= Ncb,"Foffset %d > Ncb %d\n",Foffset,Ncb);
- k=0;
+ if (ind >= Foffset && ind < (F+Foffset)) ind = F+Foffset;
- for (; (ind E %d\n",Foffset,E);
+ AssertFatal(Foffset <= Ncb,"Foffset %d > Ncb %d\n",Foffset,Ncb);
#ifdef RM_DEBUG
printf("nr_rate_matching_ldpc_rx: Clear %d, E %d, k0 %d, Ncb %d, rvidx %d\n", clear, E, ind, Ncb, rvidx);
#endif
- if (clear==1)
- memset(w,0,Ncb*sizeof(int16_t));
+ if (clear==1) memset(w,0,Ncb*sizeof(int16_t));
k=0;
+ if (ind < Foffset)
+ for (; (ind",k,ind,w[ind],soft_input[k]);
+#endif
+ w[ind]+=soft_input[k++];
+#ifdef RM_DEBUG
+ printf("%d\n",w[ind]);
+#endif
+ }
+ if (ind >= Foffset && ind < Foffset+F) ind=Foffset+F;
+
for (; (ind",k,ind,w[ind],soft_input[k]);
+#endif
w[ind] += soft_input[k++];
#ifdef RM_DEBUG
- printf("RM_RX k%d Ind: %d (%d)\n",k-1,ind,w[ind]);
-#endif
- }
-
-#ifdef RM_DEBUG
- else {
- printf("RM_RX Ind: %d NULL %d\n",ind,nulled);
- nulled++;
- }
-
+ printf("%d\n",w[ind]);
#endif
}
- if (rvidx !=0){
while(k",k,ind,w[ind],soft_input[k]);
#endif
- }
-
+ w[ind]+=soft_input[k++];
#ifdef RM_DEBUG
- else {
- printf("RM_RX Ind: %d NULL %d\n",ind,nulled);
- nulled++;
- }
-
+ printf("%d\n",w[ind]);
+#endif
+ }
+ for (ind=Foffset+F; (ind",k,ind,w[ind],soft_input[k]);
+#endif
+ w[ind] += soft_input[k++];
+#ifdef RM_DEBUG
+ printf("%d\n",w[ind]);
#endif
}
}
- }
+
return 0;
}
diff --git a/openair1/PHY/CODING/nr_segmentation.c b/openair1/PHY/CODING/nr_segmentation.c
index 90586e24d4..1d80a83131 100644
--- a/openair1/PHY/CODING/nr_segmentation.c
+++ b/openair1/PHY/CODING/nr_segmentation.c
@@ -30,13 +30,13 @@
//#define DEBUG_SEGMENTATION
int32_t nr_segmentation(unsigned char *input_buffer,
- unsigned char **output_buffers,
- unsigned int B,
- unsigned int *C,
- unsigned int *K,
- unsigned int *Zout, // [hna] Zout is Zc
- unsigned int *F,
- uint8_t BG)
+ unsigned char **output_buffers,
+ unsigned int B,
+ unsigned int *C,
+ unsigned int *K,
+ unsigned int *Zout, // [hna] Zout is Zc
+ unsigned int *F,
+ uint8_t BG)
{
unsigned int L,Bprime,Z,r,Kcb,Kb,k,s,crc,Kprime;
@@ -63,7 +63,7 @@ int32_t nr_segmentation(unsigned char *input_buffer,
#endif
}
- if ((*C)>MAX_NUM_DLSCH_SEGMENTS) {
+ if ((*C)>MAX_NUM_NR_DLSCH_SEGMENTS) {
LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime);
return(-1);
}
diff --git a/openair1/PHY/INIT/lte_parms.c b/openair1/PHY/INIT/lte_parms.c
index a3ca8421b3..12a5646df6 100644
--- a/openair1/PHY/INIT/lte_parms.c
+++ b/openair1/PHY/INIT/lte_parms.c
@@ -161,6 +161,8 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,
if (frame_parms->frame_type == TDD) set_S_config(frame_parms);
+ frame_parms->samples_per_subframe=frame_parms->samples_per_tti;
+ frame_parms->samples_per_slot=frame_parms->samples_per_tti>>1;
// frame_parms->tdd_config=3;
return(0);
}
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 9024823c04..1c0d5a6aca 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -44,34 +44,30 @@
/*
extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn);
-extern int32_t get_nr_uldl_offset(int nr_bandP);*/
-extern openair0_config_t openair0_cfg[MAX_CARDS];
-int l1_north_init_gNB()
-{
- if (RC.nb_nr_L1_inst > 0 && RC.nb_nr_L1_CC != NULL && RC.gNB != NULL) {
+extern int32_t get_nr_uldl_offset(int nr_bandP);
+extern openair0_config_t openair0_cfg[MAX_CARDS];
+*/
+
+int l1_north_init_gNB() {
+
+ if (RC.nb_nr_L1_inst > 0 && RC.gNB != NULL) {
+
AssertFatal(RC.nb_nr_L1_inst>0,"nb_nr_L1_inst=%d\n",RC.nb_nr_L1_inst);
- AssertFatal(RC.nb_nr_L1_CC!=NULL,"nb_nr_L1_CC is null\n");
AssertFatal(RC.gNB!=NULL,"RC.gNB is null\n");
LOG_I(PHY,"%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst);
for (int i=0; i0,"RC.nb_nr_L1_CC[%d]=%d\n",i,RC.nb_nr_L1_CC[i]);
- LOG_I(PHY,"%s() RC.nb_nr_L1_CC[%d]:%d\n", __FUNCTION__, i, RC.nb_nr_L1_CC[i]);
- for (int j=0; jif_inst = NR_IF_Module_init(i))<0) return(-1);
-
- LOG_I(PHY,"%s() RC.gNB[%d][%d] installing callbacks\n", __FUNCTION__, i, j);
- RC.gNB[i][j]->if_inst->NR_PHY_config_req = nr_phy_config_request;
- RC.gNB[i][j]->if_inst->NR_Schedule_response = nr_schedule_response;
- }
+ if ((RC.gNB[i]->if_inst = NR_IF_Module_init(i))<0) return(-1);
+
+ LOG_I(PHY,"%s() RC.gNB[%d] installing callbacks\n", __FUNCTION__, i);
+ RC.gNB[i]->if_inst->NR_PHY_config_req = nr_phy_config_request;
+ RC.gNB[i]->if_inst->NR_Schedule_response = nr_schedule_response;
}
} else {
- LOG_I(PHY,"%s() Not installing PHY callbacks - RC.nb_nr_L1_inst:%d RC.nb_nr_L1_CC:%p RC.gNB:%p\n", __FUNCTION__, RC.nb_nr_L1_inst, RC.nb_nr_L1_CC, RC.gNB);
+ LOG_I(PHY,"%s() Not installing PHY callbacks - RC.nb_nr_L1_inst:%d RC.gNB:%p\n", __FUNCTION__, RC.nb_nr_L1_inst, RC.gNB);
}
return(0);
@@ -83,21 +79,20 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
unsigned char abstraction_flag) {
// shortcuts
NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms;
- nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
+ NR_gNB_PRACH *const prach_vars = &gNB->prach_vars;
NR_gNB_PUSCH **const pusch_vars = gNB->pusch_vars;
- dmrs_UplinkConfig_t *dmrs_Uplink_Config = &gNB->pusch_config.dmrs_UplinkConfig;
- ptrs_UplinkConfig_t *ptrs_Uplink_Config = &gNB->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
/*LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/
int i;
+ int Ptx=cfg->carrier_config.num_tx_ant.value;
+ int Prx=cfg->carrier_config.num_rx_ant.value;
+ AssertFatal(Ptx>0 && Ptx<9,"Ptx %d is not supported\n",Ptx);
+ AssertFatal(Prx>0 && Prx<9,"Prx %d is not supported\n",Prx);
LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__);
- gNB->total_dlsch_bitrate = 0;
- gNB->total_transmitted_bits = 0;
- gNB->total_system_throughput = 0;
- gNB->check_for_MUMIMO_transmissions=0;
while(gNB->configured == 0) usleep(10000);
@@ -136,7 +131,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
}
}
- nr_init_pdcch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
+ nr_init_pdcch_dmrs(gNB, cfg->cell_config.phy_cell_id.value);
nr_init_pbch_interleaver(gNB->nr_pbch_interleaver);
//PDSCH DMRS init
gNB->nr_gold_pdsch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
@@ -157,49 +152,52 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
}
}
- //------------- config PUSCH DMRS parameters(to be updated from RRC)--------------//
- dmrs_Uplink_Config->pusch_dmrs_type = pusch_dmrs_type1;
- dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0;
- dmrs_Uplink_Config->pusch_maxLength = pusch_len1;
- //--------------------------------------------------------------------------------//
- nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
+ nr_init_pdsch_dmrs(gNB, cfg->cell_config.phy_cell_id.value);
- // default values until overwritten by RRCConnectionReconfiguration
+ //PUSCH DMRS init
+ gNB->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(2*sizeof(uint32_t ***));
+ uint32_t ****pusch_dmrs = gNB->nr_gold_pusch_dmrs;
- for (i=0;ipusch_config.pusch_TimeDomainResourceAllocation[i] = (PUSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(PUSCH_TimeDomainResourceAllocation_t));
- gNB->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB;
+ for(int nscid=0; nscid<2; nscid++) {
+ pusch_dmrs[nscid] = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
+ AssertFatal(pusch_dmrs[nscid]!=NULL, "NR init: pusch_dmrs for nscid %d - malloc failed\n", nscid);
+
+ for (int slot=0; slotslots_per_frame; slot++) {
+ pusch_dmrs[nscid][slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
+ AssertFatal(pusch_dmrs[nscid][slot]!=NULL, "NR init: pusch_dmrs for slot %d - malloc failed\n", slot);
+
+ for (int symb=0; symbsymbols_per_slot; symb++) {
+ pusch_dmrs[nscid][slot][symb] = (uint32_t *)malloc16(NR_MAX_PUSCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
+ AssertFatal(pusch_dmrs[nscid][slot][symb]!=NULL, "NR init: pusch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
+ }
+ }
}
- gNB->ptrs_configured = 0;
-
- //------------- config PUSCH PTRS parameters(to be updated from RRC)--------------//
- ptrs_Uplink_Config->timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration
- ptrs_Uplink_Config->timeDensity.ptrs_mcs2 = 0;
- ptrs_Uplink_Config->timeDensity.ptrs_mcs3 = 0;
- ptrs_Uplink_Config->frequencyDensity.n_rb0 = 0; // setting N_RB values to 0 indicate abscence of frequency_density field in the configuration
- ptrs_Uplink_Config->frequencyDensity.n_rb1 = 0;
- ptrs_Uplink_Config->resourceElementOffset = 0;
- //--------------------------------------------------------------------------------//
+ uint32_t Nid_pusch[2] = {cfg->cell_config.phy_cell_id.value,cfg->cell_config.phy_cell_id.value};
+ nr_gold_pusch(gNB, &Nid_pusch[0]);
/// Transport init necessary for NR synchro
init_nr_transport(gNB);
- gNB->first_run_I0_measurements = 1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
- common_vars->rxdata = (int32_t **)malloc16(15*sizeof(int32_t*));
- common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t*));
- common_vars->rxdataF = (int32_t **)malloc16(15*sizeof(int32_t*));
+ gNB->first_run_I0_measurements = 1;
- for (i=0;i<15;i++){
+ common_vars->rxdata = (int32_t **)malloc16(Prx*sizeof(int32_t*));
+ common_vars->txdataF = (int32_t **)malloc16(Ptx*sizeof(int32_t*));
+ common_vars->rxdataF = (int32_t **)malloc16(Prx*sizeof(int32_t*));
+
+ for (i=0;itxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP
- common_vars->rxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t));
- common_vars->rxdata[i] = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t));
-
LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
- i,common_vars->txdataF[i],
- fp->samples_per_frame_wCP*sizeof(int32_t));
+ i,common_vars->txdataF[i],
+ fp->samples_per_frame_wCP*sizeof(int32_t));
+
}
+ for (i=0;irxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t));
+ common_vars->rxdata[i] = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t));
+ }
+
// Channel estimates for SRS
/*
@@ -222,116 +220,76 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
for (UE_id=0; UE_idofdm_symbol_size*sizeof(int32_t));
}
-
+*/
// PRACH
prach_vars->prachF = (int16_t *)malloc16_clear( 1024*2*sizeof(int16_t) );
- // assume maximum of 64 RX antennas for PRACH receiver
- prach_vars->prach_ifft[0] = (int32_t **)malloc16_clear(64*sizeof(int32_t *));
+ prach_vars->rxsigF = (int16_t **)malloc16_clear(Prx*sizeof(int16_t*));
+ /*
+ for (i=0;irxsigF[i] = (int16_t *)malloc16_clear( 1024*2*sizeof(int16_t) );
+ }
+ */
+ prach_vars->prach_ifft = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
- for (i=0; i<64; i++) prach_vars->prach_ifft[0][i] = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
+ int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value;
- prach_vars->rxsigF[0] = (int16_t **)malloc16_clear(64*sizeof(int16_t *));
-*/
+ printf("Before ULSCH init : %p\n",gNB->dlsch[0][0]->harq_processes[0]);
+ for (int ULSCH_id=0; ULSCH_iddlsch[0][0]->harq_processes[0]);
+ pusch_vars[ULSCH_id] = (NR_gNB_PUSCH *)malloc16_clear( sizeof(NR_gNB_PUSCH) );
+ pusch_vars[ULSCH_id]->rxdataF_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->rxdataF_ext2 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ul_ch_estimates = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ul_ch_estimates_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ul_ch_estimates_time = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->rxdataF_comp = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ul_ch_mag0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ul_ch_magb0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ul_ch_mag = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ul_ch_magb = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->rho = (int32_t **)malloc16_clear(Prx*sizeof(int32_t*) );
- for (int UE_id=0; UE_idrxdataF_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
- pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
- pusch_vars[UE_id]->ul_ch_estimates = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
- pusch_vars[UE_id]->ul_ch_estimates_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
- pusch_vars[UE_id]->ul_ch_ptrs_estimates = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
- pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
- pusch_vars[UE_id]->ul_ch_estimates_time = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
- pusch_vars[UE_id]->rxdataF_comp = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
- pusch_vars[UE_id]->ul_ch_mag0 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
- pusch_vars[UE_id]->ul_ch_magb0 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
- pusch_vars[UE_id]->ul_ch_mag = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
- pusch_vars[UE_id]->ul_ch_magb = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
- pusch_vars[UE_id]->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
-
- for (i=0; inb_antennas_rx; i++) {
- // RK 2 times because of output format of FFT!
- // FIXME We should get rid of this
- pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
- pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
- pusch_vars[UE_id]->ul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
- pusch_vars[UE_id]->ul_ch_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
- pusch_vars[UE_id]->ul_ch_ptrs_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*2*fp->symbols_per_slot ); // max intensity in freq is 1 sc every 2 RBs
- pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*2*fp->symbols_per_slot );
- pusch_vars[UE_id]->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
- pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
- pusch_vars[UE_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
- pusch_vars[UE_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
- pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
- pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
- pusch_vars[UE_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) );
+ printf("ULSCH_id %d (before rx antenna alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
+ for (i=0; irxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
+ pusch_vars[ULSCH_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
+ pusch_vars[ULSCH_id]->ul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
+ pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
+ pusch_vars[ULSCH_id]->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
+ pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot ); // max intensity in freq is 1 sc every 2 RBs
+ pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot );
+ pusch_vars[ULSCH_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
+ pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
+ pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
+ pusch_vars[ULSCH_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
+ pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
+ pusch_vars[ULSCH_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) );
}
-
- pusch_vars[UE_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
- } //UE_id
+ printf("ULSCH_id %d (before llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
+ pusch_vars[ULSCH_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
+ printf("ULSCH_id %d (after llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
+ } //ulsch_id
/*
- for (UE_id=0; UE_idUE_stats_ptr[UE_id] = &gNB->UE_stats[UE_id];
+ for (ulsch_id=0; ulsch_idUE_stats_ptr[ulsch_id] = &gNB->UE_stats[ulsch_id];
*/
- gNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration
+ printf("After ULSCH init : %p\n",gNB->dlsch[0][0]->harq_processes[0]);
return (0);
}
-/*
-void phy_config_request(PHY_Config_t *phy_config) {
-
- uint8_t Mod_id = phy_config->Mod_id;
- int CC_id = phy_config->CC_id;
- nfapi_nr_config_request_t *cfg = phy_config->cfg;
-
- NR_DL_FRAME_PARMS *fp;
- PHICH_RESOURCE_t phich_resource_table[4]={oneSixth,half,one,two};
- int eutra_band = cfg->nfapi_config.rf_bands.rf_band[0];
- int dl_Bandwidth = cfg->rf_config.dl_carrier_bandwidth.value;
- int ul_Bandwidth = cfg->rf_config.ul_carrier_bandwidth.value;
- int Nid_cell = cfg->sch_config.physical_cell_id.value;
- int Ncp = cfg->subframe_config.dl_cyclic_prefix_type.value;
- int p_eNB = cfg->rf_config.tx_antenna_ports.value;
- uint32_t dl_CarrierFreq = cfg->nfapi_config.earfcn.value;
-
- LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,gNB_tx_antenna_ports %d,Ncp %d,DL freq %u)\n",
- Mod_id, CC_id, eutra_band, dl_Bandwidth, ul_Bandwidth, Nid_cell, p_eNB,Ncp,dl_CarrierFreq );
-
- AssertFatal(RC.gNB != NULL, "PHY instance pointer doesn't exist\n");
- AssertFatal(RC.gNB[Mod_id] != NULL, "PHY instance %d doesn't exist\n",Mod_id);
- AssertFatal(RC.gNB[Mod_id][CC_id] != NULL, "PHY instance %d, CCid %d doesn't exist\n",Mod_id,CC_id);
-
-
- if (RC.gNB[Mod_id][CC_id]->configured == 1)
- {
- LOG_E(PHY,"Already eNB already configured, do nothing\n");
- return;
- }
-
- RC.gNB[Mod_id][CC_id]->mac_enabled = 1;
-
- fp = &RC.gNB[Mod_id][CC_id]->frame_parms;
-
- fp->threequarter_fs = 0;
-
- nr_init_frame_parms(fp,1);
-
- RC.gNB[Mod_id][CC_id]->configured = 1;
- LOG_I(PHY,"gNB %d/%d configured\n",Mod_id,CC_id);
-}*/
-
void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
{
//NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms;
- //nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
NR_gNB_PUSCH **const pusch_vars = gNB->pusch_vars;
/*LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
+ int Ptx=gNB->gNB_config.carrier_config.num_tx_ant.value;
- for (int i = 0; i < 15; i++) {
+ for (int i = 0; i < Ptx; i++) {
free_and_zero(common_vars->txdataF[i]);
/* rxdataF[i] is not allocated -> don't free */
}
@@ -363,40 +321,40 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(prach_vars->prach_ifft[0]);
free_and_zero(prach_vars->rxsigF[0]);
*/
- for (int UE_id=0; UE_idrxdataF_ext[i]);
- free_and_zero(pusch_vars[UE_id]->rxdataF_ext2[i]);
- free_and_zero(pusch_vars[UE_id]->ul_ch_estimates[i]);
- free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_ext[i]);
- free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates[i]);
- free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext[i]);
- free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_time[i]);
- free_and_zero(pusch_vars[UE_id]->rxdataF_comp[i]);
- free_and_zero(pusch_vars[UE_id]->ul_ch_mag0[i]);
- free_and_zero(pusch_vars[UE_id]->ul_ch_magb0[i]);
- free_and_zero(pusch_vars[UE_id]->ul_ch_mag[i]);
- free_and_zero(pusch_vars[UE_id]->ul_ch_magb[i]);
- free_and_zero(pusch_vars[UE_id]->rho[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->rho[i]);
}
- free_and_zero(pusch_vars[UE_id]->rxdataF_ext);
- free_and_zero(pusch_vars[UE_id]->rxdataF_ext2);
- free_and_zero(pusch_vars[UE_id]->ul_ch_estimates);
- free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_ext);
- free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates);
- free_and_zero(pusch_vars[UE_id]->ul_ch_ptrs_estimates_ext);
- free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_time);
- free_and_zero(pusch_vars[UE_id]->rxdataF_comp);
- free_and_zero(pusch_vars[UE_id]->ul_ch_mag0);
- free_and_zero(pusch_vars[UE_id]->ul_ch_magb0);
- free_and_zero(pusch_vars[UE_id]->ul_ch_mag);
- free_and_zero(pusch_vars[UE_id]->ul_ch_magb);
- free_and_zero(pusch_vars[UE_id]->rho);
+ free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext);
+ free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_ext);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time);
+ free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb);
+ free_and_zero(pusch_vars[ULSCH_id]->rho);
- free_and_zero(pusch_vars[UE_id]->llr);
- free_and_zero(pusch_vars[UE_id]);
- } //UE_id
+ free_and_zero(pusch_vars[ULSCH_id]->llr);
+ free_and_zero(pusch_vars[ULSCH_id]);
+ } //ULSCH_id
/*
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) gNB->UE_stats_ptr[UE_id] = NULL;
*/
@@ -419,103 +377,127 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
uint64_t position_in_burst)
{
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
- nfapi_nr_config_request_t *gNB_config = &gNB->gNB_config;
+ nfapi_nr_config_request_scf_t *gNB_config = &gNB->gNB_config;
//overwrite for new NR parameters
- gNB_config->nfapi_config.rf_bands.rf_band[0] = 78;
- gNB_config->nfapi_config.nrarfcn.value = 620000;
- gNB_config->subframe_config.numerology_index_mu.value = mu;
- gNB_config->subframe_config.duplex_mode.value = TDD;
- gNB_config->rf_config.dl_carrier_bandwidth.value = N_RB_DL;
- gNB_config->rf_config.ul_carrier_bandwidth.value = N_RB_UL;
- gNB_config->sch_config.half_frame_index.value = 0;
- gNB_config->sch_config.ssb_subcarrier_offset.value = 0;
- gNB_config->sch_config.n_ssb_crb.value = (N_RB_DL-20);
- gNB_config->sch_config.ssb_subcarrier_offset.value = 0;
- gNB_config->sch_config.physical_cell_id.value = Nid_cell;
- gNB_config->sch_config.ssb_scg_position_in_burst.value = position_in_burst;
- gNB_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED;
+
+ uint64_t rev_burst=0;
+ for (int i=0; i<64; i++)
+ rev_burst |= (((position_in_burst>>(63-i))&0x01)<cell_config.phy_cell_id.value = Nid_cell;
+ gNB_config->ssb_config.scs_common.value = mu;
+ gNB_config->ssb_table.ssb_subcarrier_offset.value = 0;
+ gNB_config->ssb_table.ssb_offset_point_a.value = (N_RB_DL-20)>>1;
+ gNB_config->ssb_table.ssb_mask_list[1].ssb_mask.value = (rev_burst)&(0xFFFFFFFF);
+ gNB_config->ssb_table.ssb_mask_list[0].ssb_mask.value = (rev_burst>>32)&(0xFFFFFFFF);
+ gNB_config->cell_config.frame_duplex_type.value = TDD;
+ gNB_config->ssb_table.ssb_period.value = 1; //10ms
+ gNB_config->carrier_config.dl_grid_size[mu].value = N_RB_DL;
+ gNB_config->carrier_config.ul_grid_size[mu].value = N_RB_UL;
+ gNB_config->carrier_config.num_tx_ant.value = fp->nb_antennas_tx;
+ gNB_config->carrier_config.num_rx_ant.value = fp->nb_antennas_rx;
+
+ gNB_config->tdd_table.tdd_period.value = 0;
+ //gNB_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED;
gNB->mac_enabled = 1;
fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
+ fp->nr_band = 78;
fp->threequarter_fs= 0;
+
+ gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band);
+
nr_init_frame_parms(gNB_config, fp);
gNB->configured = 1;
LOG_I(PHY,"gNB configured\n");
}
-void nr_phy_config_request(NR_PHY_Config_t *phy_config)
-{
- uint8_t Mod_id = phy_config->Mod_id;
- int CC_id = phy_config->CC_id;
- NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id][CC_id]->frame_parms;
- nfapi_nr_config_request_t *gNB_config = &RC.gNB[Mod_id][CC_id]->gNB_config;
- gNB_config->nfapi_config.rf_bands.rf_band[0] = phy_config->cfg->nfapi_config.rf_bands.rf_band[0]; //22
- gNB_config->nfapi_config.nrarfcn.value = phy_config->cfg->nfapi_config.nrarfcn.value; //6600
- gNB_config->subframe_config.numerology_index_mu.value = phy_config->cfg->subframe_config.numerology_index_mu.value;//1
- gNB_config->rf_config.dl_carrier_bandwidth.value = phy_config->cfg->rf_config.dl_carrier_bandwidth.value;//106;
- gNB_config->rf_config.ul_carrier_bandwidth.value = phy_config->cfg->rf_config.ul_carrier_bandwidth.value;//106;
- gNB_config->sch_config.half_frame_index.value = 0;
- gNB_config->sch_config.ssb_subcarrier_offset.value = phy_config->cfg->sch_config.ssb_subcarrier_offset.value;//0;
- gNB_config->sch_config.n_ssb_crb.value = (phy_config->cfg->rf_config.dl_carrier_bandwidth.value-20);
- gNB_config->sch_config.physical_cell_id.value = phy_config->cfg->sch_config.physical_cell_id.value;
- gNB_config->sch_config.ssb_scg_position_in_burst.value= phy_config->cfg->sch_config.ssb_scg_position_in_burst.value;
- gNB_config->sch_config.ssb_periodicity.value = phy_config->cfg->sch_config.ssb_periodicity.value;
+void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
+ uint8_t Mod_id = phy_config->Mod_id;
+ NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms;
+ nfapi_nr_config_request_scf_t *gNB_config = &RC.gNB[Mod_id]->gNB_config;
- if (phy_config->cfg->subframe_config.duplex_mode.value == 0) {
- gNB_config->subframe_config.duplex_mode.value = FDD;
- } else {
- gNB_config->subframe_config.duplex_mode.value = TDD;
+ /*
+ gNB_config->cell_config.phy_cell_id.value = phy_config->cfg->cell_config.phy_cell_id.value;
+ gNB_config->carrier_config.dl_frequency.value = phy_config->cfg->carrier_config.dl_frequency.value;
+ gNB_config->carrier_config.uplink_frequency.value = phy_config->cfg->carrier_config.uplink_frequency.value;
+ gNB_config->ssb_config.scs_common.value = phy_config->cfg->ssb_config.scs_common.value;
+ gNB_config->carrier_config.dl_bandwidth.value = phy_config->cfg->carrier_config.dl_bandwidth.value;
+ gNB_config->carrier_config.uplink_bandwidth.value = phy_config->cfg->carrier_config.uplink_bandwidth.value;
+ gNB_config->ssb_table.ssb_subcarrier_offset.value = phy_config->cfg->ssb_table.ssb_subcarrier_offset.value;
+ gNB_config->ssb_table.ssb_offset_point_a.value = phy_config->cfg->ssb_table.ssb_offset_point_a.value;
+ gNB_config->ssb_table.ssb_mask_list[0].ssb_mask.value = phy_config->cfg->ssb_table.ssb_mask_list[0].ssb_mask.value;
+ gNB_config->ssb_table.ssb_mask_list[1].ssb_mask.value = phy_config->cfg->ssb_table.ssb_mask_list[1].ssb_mask.value;
+ gNB_config->ssb_table.ssb_period.value = phy_config->cfg->ssb_table.ssb_period.value;
+ for (int i=0; i<5; i++) {
+ gNB_config->carrier_config.dl_grid_size[i].value = phy_config->cfg->carrier_config.dl_grid_size[i].value;
+ gNB_config->carrier_config.ul_grid_size[i].value = phy_config->cfg->carrier_config.ul_grid_size[i].value;
+ gNB_config->carrier_config.dl_k0[i].value = phy_config->cfg->carrier_config.dl_k0[i].value;
+ gNB_config->carrier_config.ul_k0[i].value = phy_config->cfg->carrier_config.ul_k0[i].value;
}
- RC.gNB[Mod_id][CC_id]->mac_enabled = 1;
- fp->dl_CarrierFreq = from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
- get_band(fp->dl_CarrierFreq, &gNB_config->nfapi_config.rf_bands.rf_band[0], &uplink_frequency_offset[CC_id][0], &fp->frame_type);
- fp->ul_CarrierFreq = fp->dl_CarrierFreq + uplink_frequency_offset[CC_id][0];
- fp->threequarter_fs = openair0_cfg[0].threequarter_fs;
- LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,DL freq %u, UL freq %u)\n",
+
+ if (phy_config->cfg->cell_config.frame_duplex_type.value == 0) {
+ gNB_config->cell_config.frame_duplex_type.value = FDD;
+ } else {
+ gNB_config->cell_config.frame_duplex_type.value = TDD;
+ }
+
+ memcpy((void*)&gNB_config->prach_config,(void*)&phy_config->cfg->prach_config,sizeof(phy_config->cfg->prach_config));
+ memcpy((void*)&gNB_config->tdd_table,(void*)&phy_config->cfg->tdd_table,sizeof(phy_config->cfg->tdd_table));
+ */
+ memcpy((void*)gNB_config,phy_config->cfg,sizeof(*phy_config->cfg));
+ RC.gNB[Mod_id]->mac_enabled = 1;
+
+ uint64_t dl_bw_khz = (12*gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value)*(15<ssb_config.scs_common.value);
+ fp->dl_CarrierFreq = ((dl_bw_khz>>1) + gNB_config->carrier_config.dl_frequency.value)*1000 ;
+
+ int32_t dlul_offset = 0;
+ lte_frame_type_t frame_type = 0;
+
+ get_band(fp->dl_CarrierFreq,&fp->nr_band,&dlul_offset,&frame_type);
+
+ uint64_t ul_bw_khz = (12*gNB_config->carrier_config.ul_grid_size[gNB_config->ssb_config.scs_common.value].value)*(15<ssb_config.scs_common.value);
+ fp->ul_CarrierFreq = ((ul_bw_khz>>1) + gNB_config->carrier_config.uplink_frequency.value)*1000 ;
+
+ AssertFatal(fp->ul_CarrierFreq==(fp->dl_CarrierFreq+dlul_offset), "Disagreement in uplink frequency for band %d\n", fp->nr_band);
+
+ fp->threequarter_fs = openair0_cfg[0].threequarter_fs;
+ LOG_I(PHY,"Configuring MIB for instance %d, : (Nid_cell %d,DL freq %llu, UL freq %llu)\n",
Mod_id,
- CC_id,
- gNB_config->nfapi_config.rf_bands.rf_band[0],
- gNB_config->rf_config.dl_carrier_bandwidth.value,
- gNB_config->rf_config.ul_carrier_bandwidth.value,
- gNB_config->sch_config.physical_cell_id.value,
- fp->dl_CarrierFreq,
- fp->ul_CarrierFreq);
+ gNB_config->cell_config.phy_cell_id.value,
+ (unsigned long long)fp->dl_CarrierFreq,
+ (unsigned long long)fp->ul_CarrierFreq);
nr_init_frame_parms(gNB_config, fp);
+
- if (RC.gNB[Mod_id][CC_id]->configured == 1) {
+ if (RC.gNB[Mod_id]->configured == 1) {
LOG_E(PHY,"Already gNB already configured, do nothing\n");
return;
}
- RC.gNB[Mod_id][CC_id]->configured = 1;
- LOG_I(PHY,"gNB %d/%d configured\n",Mod_id,CC_id);
+ RC.gNB[Mod_id]->configured = 1;
+ LOG_I(PHY,"gNB %d configured\n",Mod_id);
}
void init_nr_transport(PHY_VARS_gNB *gNB) {
int i;
int j;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
- nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
LOG_I(PHY, "Initialise nr transport\n");
+ uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value;
for (i=0; idlsch[i][j] = new_gNB_dlsch(1,16,NSOFT,0,fp,cfg);
-
- if (!gNB->dlsch[i][j]) {
- LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i);
- exit(-1);
- }/* else {
- gNB->dlsch[i][j]->rnti=0;
- LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti);
- }*/
+ gNB->dlsch[i][j] = new_gNB_dlsch(fp,1,16,NSOFT,0,grid_size);
+ AssertFatal(gNB->dlsch[i][j]!=NULL,"Can't initialize dlsch %d \n", i);
}
}
@@ -542,8 +524,8 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
rel15_ul->rnti = 0x1234;
rel15_ul->ulsch_pdu_rel15.start_rb = 0;
rel15_ul->ulsch_pdu_rel15.number_rbs = 50;
- rel15_ul->ulsch_pdu_rel15.start_symbol = 0;
- rel15_ul->ulsch_pdu_rel15.number_symbols = 14;
+ rel15_ul->ulsch_pdu_rel15.start_symbol = 2;
+ rel15_ul->ulsch_pdu_rel15.number_symbols = 12;
rel15_ul->ulsch_pdu_rel15.length_dmrs = gNB->dmrs_UplinkConfig.pusch_maxLength;
rel15_ul->ulsch_pdu_rel15.Qm = 2;
rel15_ul->ulsch_pdu_rel15.R = 679;
@@ -557,18 +539,8 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
}
- gNB->dlsch_SI = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
- LOG_D(PHY,"gNB %d.%d : SI %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_SI);
- gNB->dlsch_ra = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
- LOG_D(PHY,"gNB %d.%d : RA %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_ra);
gNB->rx_total_gain_dB=130;
- for(i=0; imu_mimo_mode[i].dl_pow_off = 2;
- gNB->check_for_total_transmissions = 0;
- gNB->check_for_MUMIMO_transmissions = 0;
- gNB->FULL_MUMIMO_transmissions = 0;
- gNB->check_for_SUMIMO_transmissions = 0;
//fp->pucch_config_common.deltaPUCCH_Shift = 1;
}
diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c
index e8828d805c..2dcf035866 100644
--- a/openair1/PHY/INIT/nr_init_ru.c
+++ b/openair1/PHY/INIT/nr_init_ru.c
@@ -41,6 +41,13 @@ int nr_phy_init_RU(RU_t *ru) {
LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx);
+ nfapi_nr_config_request_scf_t *cfg;
+ ru->nb_log_antennas=0;
+ for (int n=0;ngNB_config;
+ if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas) ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value;
+ }
+ AssertFatal(ru->nb_log_antennas > 0 && ru->nb_log_antennas < 13, "ru->nb_log_antennas %d ! \n",ru->nb_log_antennas);
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals
// Time-domain signals
ru->common.txdata = (int32_t**)malloc16(ru->nb_tx*sizeof(int32_t*));
@@ -75,8 +82,8 @@ int nr_phy_init_RU(RU_t *ru) {
// allocate precoding input buffers (TX)
- ru->common.txdataF = (int32_t **)malloc16(15*sizeof(int32_t*));
- for(i=0; i< 15; ++i) ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP
+ ru->common.txdataF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
+ for(i=0; i< ru->nb_tx; ++i) ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP
// allocate IFFT input buffers (TX)
ru->common.txdataF_BF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
@@ -98,7 +105,6 @@ int nr_phy_init_RU(RU_t *ru) {
// AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
// "nb_antennas_rx too large");
ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
- for (j=0;j<4;j++) ru->prach_rxsigF_br[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
for (i=0; inb_rx; i++) {
ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
@@ -111,8 +117,8 @@ int nr_phy_init_RU(RU_t *ru) {
LOG_E(PHY,"[INIT] %s() RC.nb_nr_L1_inst:%d \n", __FUNCTION__, RC.nb_nr_L1_inst);
int beam_count = 0;
- if (ru->nb_tx>1) {
- for (p=0;pLmax;p++) {
+ if (ru->nb_log_antennas>1) {
+ for (p=0;pnb_log_antennas;p++) {
if ((fp->L_ssb >> p) & 0x01)
beam_count++;
}
@@ -120,7 +126,7 @@ int nr_phy_init_RU(RU_t *ru) {
int l_ind = 0;
for (i=0; iLmax;p++) {
+ for (p=0;pnb_log_antennas;p++) {
if ((fp->L_ssb >> p) & 0x01) {
ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
for (j=0; jnb_tx; j++) {
@@ -177,9 +183,6 @@ void nr_phy_free_RU(RU_t *ru)
for (i = 0; i < ru->nb_rx; i++) {
free_and_zero(ru->prach_rxsigF[i]);
}
- for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j]);
- free_and_zero(ru->prach_rxsigF);
- /* ru->prach_rxsigF_br is not allocated -> don't free */
for (i = 0; i < RC.nb_nr_L1_inst; i++) {
for (p = 0; p < 15; p++) {
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 7b7954583d..4ed5be2119 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -651,8 +651,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
int i,j,k,l,slot,symb,q;
int eNB_id;
int th_id;
- int n_ssb_crb=(fp->N_RB_DL-20);
- int k_ssb=0;
uint32_t ****pusch_dmrs;
uint16_t N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig
int n_scid;
@@ -663,7 +661,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
printf("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx);
//LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST);
- nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,fp->N_RB_DL,n_ssb_crb,k_ssb);
phy_init_nr_top(ue);
// many memory allocation sizes are hard coded
AssertFatal( fp->nb_antennas_rx <= 2, "hard coded allocation for ue_common_vars->dl_ch_estimates[eNB_id]" );
@@ -952,7 +949,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
ue->init_averaging = 1;
// default value until overwritten by RRCConnectionReconfiguration
- if (fp->nb_antenna_ports_eNB==2)
+ if (fp->nb_antenna_ports_gNB==2)
ue->pdsch_config_dedicated->p_a = dBm3;
else
ue->pdsch_config_dedicated->p_a = dB0;
@@ -963,7 +960,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
// enable MIB/SIB decoding by default
ue->decode_MIB = 1;
ue->decode_SIB = 1;
- ue->ssb_periodicity = 5; // initialization of ssb periodicity to 5ms according to TS38.213 section 4.1
init_prach_tables(839);
return 0;
}
@@ -982,7 +978,7 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,
ue->dlsch_SI[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
ue->dlsch_ra[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
- ue->transmission_mode[i] = ue->frame_parms.nb_antenna_ports_eNB==1 ? 1 : 2;
+ ue->transmission_mode[i] = ue->frame_parms.nb_antenna_ports_gNB==1 ? 1 : 2;
}
//ue->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1;
@@ -1009,51 +1005,54 @@ void phy_init_nr_top(PHY_VARS_NR_UE *ue) {
void set_default_frame_parms_single(nfapi_nr_config_request_t *config,
NR_DL_FRAME_PARMS *frame_parms) {
- //int CC_id;
- //for (CC_id=0; CC_idsubframe_config.numerology_index_mu.value =1;
config->subframe_config.duplex_mode.value = 1; //FDD
config->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL
- config->rf_config.dl_carrier_bandwidth.value = 106;
- config->rf_config.ul_carrier_bandwidth.value = 106;
+ config->rf_config.dl_carrier_bandwidth.value = 100;
+ config->rf_config.ul_carrier_bandwidth.value = 100;
config->sch_config.physical_cell_id.value = 0;
+
frame_parms->frame_type = FDD;
- frame_parms->tdd_config = 3;
//frame_parms[CC_id]->tdd_config_S = 0;
- frame_parms->N_RB_DL = 100;
- frame_parms->N_RB_UL = 100;
+ frame_parms->N_RB_DL = 106;
+ frame_parms->N_RB_UL = 106;
frame_parms->Ncp = NORMAL;
//frame_parms[CC_id]->Ncp_UL = NORMAL;
frame_parms->Nid_cell = 0;
//frame_parms[CC_id]->num_MBSFN_config = 0;
- frame_parms->nb_antenna_ports_eNB = 1;
+ frame_parms->nb_antenna_ports_gNB = 1;
frame_parms->nb_antennas_tx = 1;
frame_parms->nb_antennas_rx = 1;
+
//frame_parms[CC_id]->nushift = 0;
+
///frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth;
//frame_parms[CC_id]->phich_config_common.phich_duration = normal;
+
// UL RS Config
/*frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 1;//n_DMRS1 set to 0
- frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
- frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
- frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
-
- frame_parms[CC_id]->pusch_config_common.n_SB = 1;
- frame_parms[CC_id]->pusch_config_common.hoppingMode = 0;
- frame_parms[CC_id]->pusch_config_common.pusch_HoppingOffset = 0;
- frame_parms[CC_id]->pusch_config_common.enable64QAM = 0;
-
- frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22;
- frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
- frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
- frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
- frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;*/
+ frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
+ frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
+ frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
+
+ frame_parms[CC_id]->pusch_config_common.n_SB = 1;
+ frame_parms[CC_id]->pusch_config_common.hoppingMode = 0;
+ frame_parms[CC_id]->pusch_config_common.pusch_HoppingOffset = 0;
+ frame_parms[CC_id]->pusch_config_common.enable64QAM = 0;
+
+ frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22;
+ frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
+ frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
+ frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
+ frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;*/
+
// NR: Init to legacy LTE 20Mhz params
- frame_parms->numerology_index = 0;
- frame_parms->ttis_per_subframe = 1;
- frame_parms->slots_per_tti = 2;
- //}
+ frame_parms->numerology_index = 0;
+ frame_parms->ttis_per_subframe = 1;
+ frame_parms->slots_per_tti = 2;
+
+
}
diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c
index a5475a1555..c3fe9c54b1 100644
--- a/openair1/PHY/INIT/nr_parms.c
+++ b/openair1/PHY/INIT/nr_parms.c
@@ -21,16 +21,20 @@
#include "phy_init.h"
#include "common/utils/LOG/log.h"
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
/// Subcarrier spacings in Hz indexed by numerology index
uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
-uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 16, 32};
+uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16};
-int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_frame_index)
+
+int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
{
int mu = fp->numerology_index;
+ uint8_t half_frame_index = fp->half_frame_bit;
+ uint8_t i_ssb = fp->ssb_index;
int symbol = 0;
uint8_t n, n_temp;
nr_ssb_type_e type = fp->ssb_type;
@@ -79,62 +83,8 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_f
return symbol;
}
-int nr_is_ssb_slot(nfapi_nr_config_request_t *cfg, int slot, int frame)
+void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw)
{
-
- uint8_t n_hf;
- uint16_t p,mu,hf_slots;
- uint64_t ssb_map;
- int rel_slot;
-
- mu = cfg->subframe_config.numerology_index_mu.value;
-
- ssb_map = cfg->sch_config.ssb_scg_position_in_burst.value;
- p = cfg->sch_config.ssb_periodicity.value;
- n_hf = cfg->sch_config.half_frame_index.value;
-
- // if SSB periodicity is 5ms, they are transmitted in both half frames
- if ( (p>10) && (frame%(p/10)) )
- return 0;
- else {
- hf_slots = (10<>1; // number of slots per half frame
- // if SSB periodicity is 5ms, they are transmitted in both half frames
- if ( p == 5) {
- if (slot> rel_slot*2) & 0x01) || ((ssb_map >> (1+rel_slot*2)) & 0x01) );
- }
-}
-
-
-int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
- int mu,
- int Ncp,
- int N_RB_DL)
-
-{
-
-#if DISABLE_LOG_X
- printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB_DL, Ncp);
-#else
- LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB_DL, Ncp);
-#endif
-
- if (Ncp == NFAPI_CP_EXTENDED)
- AssertFatal(mu == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, mu);
-
- fp->numerology_index = mu;
- fp->Ncp = Ncp;
- fp->N_RB_DL = N_RB_DL;
-
switch(mu) {
case NR_MU_0: //15kHz scs
@@ -148,24 +98,22 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_1];
// selection of SS block pattern according to TS 38101-1 Table 5.4.3.3-1 for SCS 30kHz
- if (fp->eutra_band == 5 || fp->eutra_band == 66)
- fp->ssb_type = nr_ssb_type_B;
+ if (fp->nr_band == 5 || fp->nr_band == 66)
+ fp->ssb_type = nr_ssb_type_B;
else{
- if (fp->eutra_band == 41 || ( fp->eutra_band > 76 && fp->eutra_band < 80) )
- fp->ssb_type = nr_ssb_type_C;
+ if (fp->nr_band == 41 || ( fp->nr_band > 76 && fp->nr_band < 80) )
+ fp->ssb_type = nr_ssb_type_C;
else
- AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->eutra_band, mu);
+ AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->nr_band, mu);
}
- switch(N_RB_DL){
- case 11:
- case 24:
- case 38:
- case 78:
- case 51:
- case 65:
-
- case 106: //40 MHz
+ switch(bw){
+ case 5:
+ case 15:
+ case 20:
+ case 25:
+ case 30:
+ case 40: //40 MHz
if (fp->threequarter_fs) {
fp->ofdm_symbol_size = 1536;
fp->first_carrier_offset = 900; //1536 - ( (106*12) / 2 )
@@ -180,11 +128,11 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
}
break;
- case 133:
- case 162:
- case 189:
+ case 50:
+ case 60:
+ case 70:
- case 217: //80 MHz
+ case 80: //80 MHz
if (fp->threequarter_fs) {
fp->ofdm_symbol_size = 3072;
fp->first_carrier_offset = 1770; //3072 - ( (217*12) / 2 )
@@ -199,22 +147,22 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
}
break;
- case 245:
- AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",N_RB_DL,mu);
+ case 90:
+ AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for %d MHz band and MU %d\n",bw,mu);
fp->ofdm_symbol_size = 4096;
fp->first_carrier_offset = 2626; //4096 - ( (245*12) / 2 )
fp->nb_prefix_samples0 = 352;
fp->nb_prefix_samples = 288;
break;
- case 273:
- AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",N_RB_DL,mu);
+ case 100:
+ AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for %d MHz band and MU %d\n",bw,mu);
fp->ofdm_symbol_size = 4096;
fp->first_carrier_offset = 2458; //4096 - ( (273*12) / 2 )
fp->nb_prefix_samples0 = 352;
fp->nb_prefix_samples = 288;
break;
default:
- AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB_DL, mu, fp);
+ AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp);
}
break;
@@ -222,21 +170,21 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2];
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_2];
- switch(N_RB_DL){ //FR1 bands only
- case 11:
- case 18:
- case 38:
- case 24:
- case 31:
- case 51:
- case 65:
- case 79:
- case 93:
- case 107:
- case 121:
- case 135:
+ switch(bw){ //FR1 bands only
+ case 10:
+ case 15:
+ case 20:
+ case 25:
+ case 30:
+ case 40:
+ case 50:
+ case 60:
+ case 70:
+ case 80:
+ case 90:
+ case 100:
default:
- AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", N_RB_DL, mu, fp);
+ AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp);
}
break;
@@ -244,6 +192,22 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
fp->ssb_type = nr_ssb_type_D;
+ switch(bw){
+ case 100:
+ fp->ofdm_symbol_size = 1024;
+ fp->first_carrier_offset = 628; //1024 - ( (66*12) / 2 )
+ fp->nb_prefix_samples0 = 136;
+ fp->nb_prefix_samples = 72;
+ break;
+ case 50:
+ fp->ofdm_symbol_size = 512;
+ fp->first_carrier_offset = 320; //1024 - ( (66*12) / 2 )
+ fp->nb_prefix_samples0 = 68;
+ fp->nb_prefix_samples = 36;
+ break;
+ default:
+ AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp);
+ }
break;
case NR_MU_4:
@@ -255,10 +219,63 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
default:
AssertFatal(1==0,"Invalid numerology index %d", mu);
}
+}
+
+uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp)
+{
+ uint32_t samp_count;
+
+ if(fp->numerology_index == 0)
+ samp_count = fp->samples_per_subframe;
+ else
+ samp_count = (slot%(fp->slots_per_subframe/2)) ? fp->samples_per_slotN0 : fp->samples_per_slot0;
+
+ return samp_count;
+}
+
+uint32_t get_samples_slot_timestamp(int slot, NR_DL_FRAME_PARMS* fp, uint8_t sl_ahead)
+{
+ uint32_t samp_count = 0;
+
+ if(!sl_ahead) {
+ for(uint8_t idx_slot = 0; idx_slot < slot; idx_slot++)
+ samp_count += fp->get_samples_per_slot(idx_slot, fp);
+ } else {
+ for(uint8_t idx_slot = slot; idx_slot < slot+sl_ahead; idx_slot++)
+ samp_count += fp->get_samples_per_slot(idx_slot, fp);
+ }
+ return samp_count;
+}
+
+int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg,
+ NR_DL_FRAME_PARMS *fp)
+{
+
+ fp->frame_type = cfg->cell_config.frame_duplex_type.value;
+ fp->L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ;
+ fp->N_RB_DL = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value;
+ fp->N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value;
+
+ int Ncp = NFAPI_CP_NORMAL;
+ int mu = cfg!= NULL ? cfg->ssb_config.scs_common.value : 0;
+
+#if DISABLE_LOG_X
+ printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, fp->N_RB_DL, Ncp);
+#else
+ LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, fp->N_RB_DL, Ncp);
+#endif
+
+ if (Ncp == NFAPI_CP_EXTENDED)
+ AssertFatal(mu == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, mu);
+
+ fp->half_frame_bit = 0; // half frame bit initialized to 0 here
+ fp->numerology_index = mu;
+
+ set_scs_parameters(fp, mu, cfg->carrier_config.dl_bandwidth.value);
fp->slots_per_frame = 10* fp->slots_per_subframe;
- fp->nb_antenna_ports_eNB = 1; // default value until overwritten by RRCConnectionReconfiguration
+ fp->nb_antenna_ports_gNB = 1; // default value until overwritten by RRCConnectionReconfiguration
fp->nb_antennas_rx = 1; // default value until overwritten by RRCConnectionReconfiguration
fp->nb_antennas_tx = 1; // default value until overwritten by RRCConnectionReconfiguration
@@ -266,12 +283,17 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP;
fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size;
- fp->samples_per_slot = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size);
- fp->samples_per_subframe = (fp->samples_per_subframe_wCP + (fp->nb_prefix_samples0 * fp->slots_per_subframe) +
- (fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1)));
+ fp->samples_per_slotN0 = (fp->nb_prefix_samples + fp->ofdm_symbol_size) * fp->symbols_per_slot;
+ fp->samples_per_slot0 = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size);
+ fp->samples_per_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2 +
+ (fp->nb_prefix_samples + fp->ofdm_symbol_size) * (fp->symbols_per_slot * fp->slots_per_subframe - 2);
+ fp->get_samples_per_slot = &get_samples_per_slot;
+ fp->get_samples_slot_timestamp = &get_samples_slot_timestamp;
fp->samples_per_frame = 10 * fp->samples_per_subframe;
fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
+ fp->Ncp = Ncp;
+
// definition of Lmax according to ts 38.213 section 4.1
if (fp->dl_CarrierFreq < 6e9) {
if(fp->frame_type && (fp->ssb_type==2))
@@ -283,35 +305,92 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
}
fp->N_ssb = 0;
- for (int p=0; pLmax; p++)
+ int num_tx_ant = (cfg == NULL) ? fp->Lmax : cfg->carrier_config.num_tx_ant.value;
+
+ for (int p=0; pN_ssb += ((fp->L_ssb >> p) & 0x01);
return 0;
-}
-int nr_init_frame_parms(nfapi_nr_config_request_t* config,
- NR_DL_FRAME_PARMS *fp)
-{
-
- fp->eutra_band = config->nfapi_config.rf_bands.rf_band[0];
- fp->frame_type = config->subframe_config.duplex_mode.value;
- fp->L_ssb = config->sch_config.ssb_scg_position_in_burst.value;
- return nr_init_frame_parms0(fp,
- config->subframe_config.numerology_index_mu.value,
- config->subframe_config.dl_cyclic_prefix_type.value,
- config->rf_config.dl_carrier_bandwidth.value);
}
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
- int mu,
- int Ncp,
- int N_RB_DL,
- int n_ssb_crb,
- int ssb_subcarrier_offset)
+ fapi_nr_config_request_t* config,
+ int Ncp)
{
- /*n_ssb_crb and ssb_subcarrier_offset are given in 15kHz SCS*/
- nr_init_frame_parms0(fp,mu,Ncp,N_RB_DL);
- fp->ssb_start_subcarrier = (12 * n_ssb_crb + ssb_subcarrier_offset)/(1<carrier_config.dl_grid_size[config->ssb_config.scs_common])*(15<ssb_config.scs_common);
+ fp->dl_CarrierFreq = ((dl_bw_khz>>1) + config->carrier_config.dl_frequency)*1000 ;
+
+ uint64_t ul_bw_khz = (12*config->carrier_config.ul_grid_size[config->ssb_config.scs_common])*(15<ssb_config.scs_common);
+ fp->ul_CarrierFreq = ((ul_bw_khz>>1) + config->carrier_config.uplink_frequency)*1000 ;
+
+ fp->numerology_index = config->ssb_config.scs_common;
+ fp->N_RB_UL = config->carrier_config.ul_grid_size[fp->numerology_index];
+ fp->N_RB_DL = config->carrier_config.dl_grid_size[fp->numerology_index];
+
+ int32_t uplink_frequency_offset = 0;
+
+ get_band(fp->dl_CarrierFreq, &fp->nr_band, &uplink_frequency_offset, &fp->frame_type);
+
+ AssertFatal(fp->frame_type==config->cell_config.frame_duplex_type, "Invalid duplex type in config request file for band %d\n", fp->nr_band);
+ AssertFatal(fp->ul_CarrierFreq==(fp->dl_CarrierFreq+uplink_frequency_offset), "Disagreement in uplink frequency for band %d\n", fp->nr_band);
+
+#if DISABLE_LOG_X
+ printf("Initializing UE frame parms for mu %d, N_RB %d, Ncp %d\n",fp->numerology_index, fp->N_RB_DL, Ncp);
+#else
+ LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",fp->numerology_index, fp->N_RB_DL, Ncp);
+#endif
+
+ if (Ncp == NFAPI_CP_EXTENDED)
+ AssertFatal(fp->numerology_index == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, fp->numerology_index);
+
+ fp->Ncp = Ncp;
+
+ set_scs_parameters(fp,fp->numerology_index,config->carrier_config.dl_bandwidth);
+
+ fp->slots_per_frame = 10* fp->slots_per_subframe;
+
+ fp->nb_antenna_ports_gNB = 1; // default value until overwritten by RRCConnectionReconfiguration
+ fp->nb_antennas_rx = 1; // default value until overwritten by RRCConnectionReconfiguration
+ fp->nb_antennas_tx = 1; // default value until overwritten by RRCConnectionReconfiguration
+
+ fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
+ fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
+ fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP;
+ fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size;
+ fp->samples_per_slotN0 = (fp->nb_prefix_samples + fp->ofdm_symbol_size) * fp->symbols_per_slot;
+ fp->samples_per_slot0 = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size);
+ fp->samples_per_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2 +
+ (fp->nb_prefix_samples + fp->ofdm_symbol_size) * (fp->symbols_per_slot * fp->slots_per_subframe - 2);
+ fp->get_samples_per_slot = &get_samples_per_slot;
+ fp->get_samples_slot_timestamp = &get_samples_slot_timestamp;
+ fp->samples_per_frame = 10 * fp->samples_per_subframe;
+ fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
+
+ uint8_t sco = 0;
+ if (((fp->freq_range == nr_FR1) && (config->ssb_table.ssb_subcarrier_offset<24)) ||
+ ((fp->freq_range == nr_FR2) && (config->ssb_table.ssb_subcarrier_offset<12)) )
+ sco = config->ssb_table.ssb_subcarrier_offset;
+
+ fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco);
+
+ // definition of Lmax according to ts 38.213 section 4.1
+ if (fp->dl_CarrierFreq < 6e9) {
+ if(fp->frame_type && (fp->ssb_type==2))
+ fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8;
+ else
+ fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8;
+ } else {
+ fp->Lmax = 64;
+ }
+
+ fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[1].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask;
+
+ fp->N_ssb = 0;
+ for (int p=0; pLmax; p++)
+ fp->N_ssb += ((fp->L_ssb >> p) & 0x01);
+
return 0;
}
@@ -326,8 +405,8 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
LOG_I(PHY,"fp->samples_per_frame_wCP=%d\n",fp->samples_per_frame_wCP);
LOG_I(PHY,"fp->samples_per_subframe=%d\n",fp->samples_per_subframe);
LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame);
- LOG_I(PHY,"fp->dl_CarrierFreq=%u\n",fp->dl_CarrierFreq);
- LOG_I(PHY,"fp->ul_CarrierFreq=%u\n",fp->ul_CarrierFreq);
+ LOG_I(PHY,"fp->dl_CarrierFreq=%lu\n",fp->dl_CarrierFreq);
+ LOG_I(PHY,"fp->ul_CarrierFreq=%lu\n",fp->ul_CarrierFreq);
}
diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h
index 05d3b6c73f..1862d5f8e0 100644
--- a/openair1/PHY/INIT/phy_init.h
+++ b/openair1/PHY/INIT/phy_init.h
@@ -392,10 +392,9 @@ void phy_config_update_sib13_request(PHY_Config_t *phy_config);
int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
-int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_frame_index);
-int nr_is_ssb_slot(nfapi_nr_config_request_t *cfg, int slot, int frame);
-int nr_init_frame_parms(nfapi_nr_config_request_t *config, NR_DL_FRAME_PARMS *frame_parms);
-int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,int mu,int Ncp,int N_RB_DL,int n_ssb_crb,int ssb_subcarrier_offset);
+int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp);
+int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
+int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,fapi_nr_config_request_t *config,int Ncp);
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag);
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms);
diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h
index 1199a91baa..228299095f 100644
--- a/openair1/PHY/MODULATION/modulation_UE.h
+++ b/openair1/PHY/MODULATION/modulation_UE.h
@@ -54,6 +54,12 @@ int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue,
int sample_offset,
int no_prefix);
+int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
+ unsigned char symbol,
+ unsigned char Ns,
+ int sample_offset,
+ int no_prefix);
+
int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
unsigned char l,
int subframe,
diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c
index 57bca9e2ec..5c8fce3c38 100644
--- a/openair1/PHY/MODULATION/nr_modulation.c
+++ b/openair1/PHY/MODULATION/nr_modulation.c
@@ -51,9 +51,10 @@ void nr_modulation(uint32_t *in,
}
void nr_layer_mapping(int16_t **mod_symbs,
- uint8_t n_layers,
- uint16_t n_symbs,
- int16_t **tx_layers) {
+ uint8_t n_layers,
+ uint16_t n_symbs,
+ int16_t **tx_layers) {
+ LOG_D(PHY,"Doing layer mapping for %d layers, %d symbols\n",n_layers,n_symbs);
switch (n_layers) {
diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c
index 11aaf1f78e..f2e5d24bad 100644
--- a/openair1/PHY/MODULATION/slot_fep_nr.c
+++ b/openair1/PHY/MODULATION/slot_fep_nr.c
@@ -46,6 +46,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
unsigned char aa;
unsigned int nb_prefix_samples;
unsigned int nb_prefix_samples0;
+ unsigned int abs_symbol;
if (ue->is_synchronized) {
nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
@@ -109,7 +110,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
if (no_prefix) {
slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns);
} else {
- slot_offset = (frame_parms->samples_per_slot) * (Ns);
+ slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
}
/*if (l<0 || l>=7-frame_parms->Ncp) {
@@ -117,15 +118,15 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
return(-1);
}*/
- if (Ns<0 || Ns>=20) {
- printf("slot_fep: Ns must be between 0 and 19\n");
+ if (Ns<0 || Ns>(frame_parms->slots_per_frame-1)) {
+ printf("slot_fep: Ns must be between 0 and %d\n",frame_parms->slots_per_frame-1);
return(-1);
}
for (aa=0; aanb_antennas_rx; aa++) {
memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
- rx_offset = sample_offset + slot_offset + nb_prefix_samples0 - SOFFSET;
+ rx_offset = sample_offset + slot_offset - SOFFSET;
// Align with 256 bit
// rx_offset = rx_offset&0xfffffff8;
@@ -135,8 +136,16 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
ue->proc.proc_rxtx[(Ns)&1].frame_rx, Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
#endif
- if (symbol==0) {
+ abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
+
+ for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++)
+ rx_offset += (idx_symb%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
+ rx_offset += frame_parms->ofdm_symbol_size * symbol;
+
+ if (abs_symbol%(0x7<numerology_index)) {
+
+ rx_offset += nb_prefix_samples;
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
memcpy((short*) &common_vars->rxdata[aa][frame_length_samples],
(short*) &common_vars->rxdata[aa][0],
@@ -161,9 +170,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
}
} else {
- rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*symbol;
- // + (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
-
+ rx_offset += nb_prefix_samples0;
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
memcpy((void *) &common_vars->rxdata[aa][frame_length_samples],
(void *) &common_vars->rxdata[aa][0],
@@ -197,6 +204,181 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
}
+#ifdef DEBUG_FEP
+ printf("slot_fep: done\n");
+#endif
+ return(0);
+}
+
+int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
+ unsigned char symbol,
+ unsigned char Ns,
+ int sample_offset,
+ int no_prefix)
+{
+ NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+ NR_UE_COMMON *common_vars = &ue->common_vars;
+ unsigned char aa;
+ unsigned int nb_prefix_samples;
+ unsigned int nb_prefix_samples0;
+ unsigned int abs_symbol;
+ if (ue->is_synchronized) {
+ nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
+ nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
+ }
+ else {
+ nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
+ nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
+ }
+ //unsigned int subframe_offset;//,subframe_offset_F;
+ unsigned int slot_offset;
+ //int i;
+ unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
+ unsigned int rx_offset;
+
+
+ void (*dft)(int16_t *,int16_t *, int);
+ int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs
+
+ switch (frame_parms->ofdm_symbol_size) {
+ case 128:
+ dft = dft128;
+ break;
+
+ case 256:
+ dft = dft256;
+ break;
+
+ case 512:
+ dft = dft512;
+ break;
+
+ case 1024:
+ dft = dft1024;
+ break;
+
+ case 1536:
+ dft = dft1536;
+ break;
+
+ case 2048:
+ dft = dft2048;
+ break;
+
+ case 3072:
+ dft = dft3072;
+ break;
+
+ case 4096:
+ dft = dft4096;
+ break;
+
+ case 8192:
+ dft = dft8192;
+ break;
+
+ default:
+ printf("unsupported ofdm symbol size \n");
+ assert(0);
+ }
+
+ if (no_prefix) {
+ slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns);
+ } else {
+ slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
+ }
+
+ /*if (l<0 || l>=7-frame_parms->Ncp) {
+ printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
+ return(-1);
+ }*/
+
+ if (Ns<0 || Ns>(frame_parms->slots_per_frame-1)) {
+ printf("slot_fep: Ns must be between 0 and %d\n",frame_parms->slots_per_frame-1);
+ return(-1);
+ }
+
+ for (aa=0; aanb_antennas_rx; aa++) {
+ memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
+
+ rx_offset = sample_offset + slot_offset - SOFFSET;
+ // Align with 256 bit
+ // rx_offset = rx_offset&0xfffffff8;
+
+#ifdef DEBUG_FEP
+ // if (ue->frame <100)
+ /*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
+ ue->proc.proc_rxtx[(Ns)&1].frame_rx, Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
+#endif
+
+ abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
+
+ for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++)
+ rx_offset += (abs_symbol%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
+
+ rx_offset += frame_parms->ofdm_symbol_size * symbol;
+
+ if (abs_symbol%(0x7<numerology_index)) {
+
+ rx_offset += nb_prefix_samples;
+ if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
+ memcpy((short*) &common_vars->rxdata[aa][frame_length_samples],
+ (short*) &common_vars->rxdata[aa][0],
+ frame_parms->ofdm_symbol_size*sizeof(int));
+
+ if ((rx_offset&7)!=0) { // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
+ memcpy((void *)tmp_dft_in,
+ (void *) &common_vars->rxdata[aa][rx_offset],
+ frame_parms->ofdm_symbol_size*sizeof(int));
+ dft((int16_t *)tmp_dft_in,
+ (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+ } else { // use dft input from RX buffer directly
+#if UE_TIMING_TRACE
+ start_meas(&ue->rx_dft_stats);
+#endif
+
+ dft((int16_t *) &common_vars->rxdata[aa][rx_offset],
+ (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+#if UE_TIMING_TRACE
+ stop_meas(&ue->rx_dft_stats);
+#endif
+ }
+ } else {
+
+ rx_offset += nb_prefix_samples0;
+ if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
+ memcpy((void *) &common_vars->rxdata[aa][frame_length_samples],
+ (void *) &common_vars->rxdata[aa][0],
+ frame_parms->ofdm_symbol_size*sizeof(int));
+#if UE_TIMING_TRACE
+ start_meas(&ue->rx_dft_stats);
+#endif
+
+ if ((rx_offset&7)!=0) { // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
+ memcpy((void *)tmp_dft_in,
+ (void *) &common_vars->rxdata[aa][rx_offset],
+ frame_parms->ofdm_symbol_size*sizeof(int));
+ dft((int16_t *)tmp_dft_in,
+ (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+ } else { // use dft input from RX buffer directly
+
+ dft((int16_t *) &common_vars->rxdata[aa][rx_offset],
+ (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+ }
+#if UE_TIMING_TRACE
+ stop_meas(&ue->rx_dft_stats);
+#endif
+
+
+ }
+
+ #ifdef DEBUG_FEP
+ // if (ue->frame <100)
+ printf("slot_fep: frame %d: symbol %d rx_offset %u\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx, symbol, rx_offset);
+ #endif
+ }
+
+
#ifdef DEBUG_FEP
printf("slot_fep: done\n");
#endif
@@ -258,7 +440,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
break;
}
- slot_offset = Ns * frame_parms->samples_per_slot;
+ slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
if(symbol == 0)
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index 83c6f054cd..0d7732599f 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -31,22 +31,19 @@
int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
- uint8_t gNB_offset,
unsigned char Ns,
unsigned short p,
unsigned char symbol,
unsigned short bwp_start_subcarrier,
- unsigned short nb_rb_pusch,
- dmrs_UplinkConfig_t *dmrs_UplinkConfig)
-{
+ nfapi_nr_pusch_pdu_t *pusch_pdu) {
+
int pilot[3280] __attribute__((aligned(16)));
unsigned char aarx;
unsigned short k;
unsigned int pilot_cnt,re_cnt;
int16_t ch[2],ch_r[2],ch_l[2],*pil,*rxF,*ul_ch;
int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh;
- int ch_offset,symbol_offset, length_dmrs, UE_id = 0;
- unsigned short n_idDMRS[2] = {0,1}; //to update from pusch config
+ int ch_offset,symbol_offset, UE_id = 0;
int32_t **ul_ch_estimates_time = gNB->pusch_vars[UE_id]->ul_ch_estimates_time;
__m128i *ul_ch_128;
@@ -71,9 +68,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
k = bwp_start_subcarrier;
int re_offset = k;
+ uint16_t nb_rb_pusch = pusch_pdu->rb_size;
+
/*
#ifdef DEBUG_CH
- printf("PUSCH Channel Estimation : gNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n", gNB_offset,ch_offset,symbol_offset,gNB->frame_parms.ofdm_symbol_size,
+ printf("PUSCH Channel Estimation : ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n", ,ch_offset,symbol_offset,gNB->frame_parms.ofdm_symbol_size,
gNB->frame_parms.Ncp,l,Ns,k, symbol);
#endif
*/
@@ -117,21 +116,17 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//------------------generate DMRS------------------//
- length_dmrs = dmrs_UplinkConfig->pusch_maxLength;
-
- nr_gold_pusch(gNB, symbol, n_idDMRS, length_dmrs);
-
- nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch[gNB_offset][Ns][0], &pilot[0], 1000, 0, nb_rb_pusch, dmrs_UplinkConfig->pusch_dmrs_type);
+ nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->dmrs_config_type);
//------------------------------------------------//
for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) {
- pil = (int16_t *)&pilot[0];
- rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
- ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
+ pil = (int16_t *)&pilot[0];
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
+ ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
- memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size));
+ memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size));
#ifdef DEBUG_PUSCH
printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_UL);
@@ -141,8 +136,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#endif
//if ((gNB->frame_parms.N_RB_UL&1)==0) {
-
- if (dmrs_UplinkConfig->pusch_dmrs_type == pusch_dmrs_type1){
+ if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1){
// Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
@@ -237,10 +231,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
}
// Treat first 2 pilots specially (right edge)
- ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+ ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
- printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+ printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fm,
ch,
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
index cc84f2292c..a7789c9224 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
@@ -39,14 +39,12 @@
\param nb_rb_pusch, number of allocated RBs for this UE
*/
- int32_t nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
- uint8_t gNB_offset,
- unsigned char Ns,
- unsigned short p,
- unsigned char symbol,
- unsigned short bwp_start_subcarrier,
- unsigned short nb_rb_pusch,
- dmrs_UplinkConfig_t *dmrs_UplinkConfig);
+int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
+ unsigned char Ns,
+ unsigned short p,
+ unsigned char symbol,
+ unsigned short bwp_start_subcarrier,
+ nfapi_nr_pusch_pdu_t *pusch_pdu);
int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c
index 67118f35a9..ed37a79d0f 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c
@@ -128,22 +128,21 @@ uint8_t is_dmrs_symbol(uint8_t l,
uint16_t n,
uint8_t delta,
uint8_t duration_in_symbols,
- dmrs_UplinkConfig_t *dmrs_UplinkConfig,
- uint8_t mapping_type,
+ uint8_t dmrs_type,
uint16_t ofdm_symbol_size) {
- uint8_t is_dmrs_freq, is_dmrs_time, dmrs_type, l0;
+ uint8_t is_dmrs_freq, is_dmrs_time, l0;
int32_t l_prime_mask;
- pusch_dmrs_AdditionalPosition_t additional_pos;
+ pusch_dmrs_AdditionalPosition_t additional_pos = pusch_dmrs_pos0;
+ pusch_maxLength_t pusch_maxLength = pusch_len1;
+ uint8_t mapping_type = typeB;
is_dmrs_freq = 0;
is_dmrs_time = 0;
- dmrs_type = dmrs_UplinkConfig->pusch_dmrs_type;
- additional_pos = dmrs_UplinkConfig->pusch_dmrs_AdditionalPosition;
l0 = get_l0_ul(mapping_type, 2);
- l_prime_mask = get_l_prime(duration_in_symbols, mapping_type, additional_pos, dmrs_UplinkConfig->pusch_maxLength);
+ l_prime_mask = get_l_prime(duration_in_symbols, mapping_type, additional_pos, pusch_maxLength);
if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%ofdm_symbol_size))
is_dmrs_freq = 1;
@@ -157,7 +156,7 @@ uint8_t is_dmrs_symbol(uint8_t l,
} else if ( (l==l0) || (((l_prime_mask>>l)&1) == 1 && l!=0) )
is_dmrs_time = 1;
- if (dmrs_UplinkConfig->pusch_maxLength == pusch_len2){
+ if (pusch_maxLength == pusch_len2){
if (((l_prime_mask>>(l-1))&1) == 1 && l!=0 && l!=1)
is_dmrs_time = 1;
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h
index de77a8a6ce..f1dfffff8b 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.h
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h
@@ -66,8 +66,7 @@ uint8_t is_dmrs_symbol(uint8_t l,
uint16_t n,
uint8_t delta,
uint8_t duration_in_symbols,
- dmrs_UplinkConfig_t *dmrs_UplinkConfig,
- uint8_t mapping_type,
+ uint8_t dmrs_type,
uint16_t ofdm_symbol_size);
#undef EXTERN
diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c
index 48fcd04a0f..472d03e649 100644
--- a/openair1/PHY/NR_REFSIG/nr_gold.c
+++ b/openair1/PHY/NR_REFSIG/nr_gold.c
@@ -26,11 +26,11 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB)
unsigned int x1, x2;
uint16_t Nid, i_ssb, i_ssb2;
unsigned char Lmax, l, n_hf, N_hf;
- nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
uint8_t reset;
- Nid = cfg->sch_config.physical_cell_id.value;
+ Nid = cfg->cell_config.phy_cell_id.value;
Lmax = fp->Lmax;
N_hf = (Lmax == 4)? 2:1;
@@ -65,7 +65,7 @@ void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
for (uint8_t symb=0; symbsymbols_per_slot; symb++) {
reset = 1;
- x2 = ((1<<17) * (14*slot+symb+1) * ((Nid<<1)+1) + (Nid<<1));
+ x2 = ((1<<17) * (14*slot+symb+1) * ((Nid<<1)+1)) + (Nid<<1);
for (uint32_t n=0; nsymbols_per_slot; symb++) {
reset = 1;
x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid));
+ LOG_D(PHY,"DMRS slot %d, symb %d x2 %x\n",slot,symb,x2);
for (uint32_t n=0; nframe_parms;
+ unsigned short l;
for (nscid=0; nscid<2; nscid++) {
- if (n_idDMRS)
- nid = n_idDMRS[nscid];
- else
- nid = gNB->frame_parms.Nid_cell;
-
- //printf("gold pdsch nid %d lbar %d\n",nid,lbar);
-
- for (ns=0; ns<20; ns++) {
-
- for (l=0; l>1) ^ (x2>>2) ^ (x2>>3))<<31);
-
- // skip first 50 double words (1600 bits)
- for (n=1; n<50; n++) {
- x1 = (x1>>1) ^ (x1>>4);
- x1 = x1 ^ (x1<<31) ^ (x1<<28);
- x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
- x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
- //printf("x1 : %x, x2 : %x\n",x1,x2);
- }
+ nid = Nid[nscid];
+ for (ns=0; nsslots_per_frame; ns++) {
+ for (l=0; lsymbols_per_slot; l++) {
+ reset = 1;
+ x2 = ((1<<17) * (fp->symbols_per_slot*ns+l+1) * ((nid<<1)+1) +((nid<<1)+nscid));
+ LOG_D(PHY,"DMRS slot %d, symb %d x2 %x\n",ns,l,x2);
for (n=0; n>1) ^ (x1>>4);
- x1 = x1 ^ (x1<<31) ^ (x1<<28);
- x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
- x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
- gNB->nr_gold_pusch[nscid][ns][l][n] = x1^x2;
- // if ((ns==2)&&(l==0))
- //printf("n=%d : c %x\n",n,x1^x2);
+ gNB->nr_gold_pusch_dmrs[nscid][ns][l][n] = lte_gold_generic(&x1, &x2, reset);
+ reset = 0;
}
-
}
}
}
-}
\ No newline at end of file
+}
diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c
index 9793899dd4..39ab13b1f1 100644
--- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c
+++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c
@@ -100,7 +100,7 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
ue->nr_gold_pdcch[0][ns][l][n] = x1^x2;
- //printf("n=%d : c %x\n",n,x1^x2);
+ // if (ns==1 && l==0) printf("n=%d : c %x\n",n,x1^x2);
}
}
}
@@ -133,7 +133,7 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
x2tmp0 = ((14*ns+(lbar+l)+1)*((nid<<1)+1))<<17;
x2 = (x2tmp0+(nid<<1)+nscid)%(1<<31); //cinit
-
+ LOG_D(PHY,"UE DMRS slot %d, symb %d, lbar %d, x2 %x, nscid %d\n",ns,l,lbar,x2,nscid);
//printf("ns %d gold pdsch x2 %d\n",ns,x2);
x1 = 1+ (1<<31);
diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h
index 754edfef64..5af0e88099 100644
--- a/openair1/PHY/NR_REFSIG/nr_refsig.h
+++ b/openair1/PHY/NR_REFSIG/nr_refsig.h
@@ -39,7 +39,7 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB);
void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
-void nr_gold_pusch(PHY_VARS_gNB* gNB, unsigned short lbar,unsigned short *n_idDMRS, unsigned short length_dmrs);
+void nr_gold_pusch(PHY_VARS_gNB* gNB, uint32_t *Nid);
int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
unsigned int Ns,
diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.c b/openair1/PHY/NR_REFSIG/ptrs_nr.c
index 9be37d2d95..12f76b950f 100644
--- a/openair1/PHY/NR_REFSIG/ptrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/ptrs_nr.c
@@ -123,9 +123,6 @@ uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB){
* NAME : set_ptrs_symb_idx
*
* PARAMETERS : ptrs_symbols PTRS OFDM symbol indicies bit mask
-* ptrs_UplinkConfig PTRS uplink configuration
-* dmrs_UplinkConfig DMRS uplink configuration
-* mapping_type PUSCH time domain mapping type
* duration_in_symbols number of scheduled PUSCH ofdm symbols
* start_symbol first ofdm symbol of PUSCH within slot
* L_ptrs the parameter L_ptrs
@@ -138,64 +135,61 @@ uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB){
*********************************************************************/
void set_ptrs_symb_idx(uint16_t *ptrs_symbols,
- ptrs_UplinkConfig_t *ptrs_UplinkConfig,
- dmrs_UplinkConfig_t *dmrs_UplinkConfig,
- uint8_t mapping_type,
uint8_t duration_in_symbols,
uint8_t start_symbol,
+ uint8_t dmrs_type,
uint8_t L_ptrs,
+ uint8_t pusch_maxLength,
uint16_t ofdm_symbol_size) {
- uint8_t i, last_symbol, is_dmrs_symbol1, is_dmrs_symbol2;
- int16_t l_ref;
+ uint8_t i, last_symbol, is_dmrs_symbol1, is_dmrs_symbol2;
+ int16_t l_ref;
- *ptrs_symbols = 0;
- i = 0;
- is_dmrs_symbol1 = 0;
- is_dmrs_symbol2 = 0;
- l_ref = start_symbol;
- last_symbol = start_symbol + duration_in_symbols - 1;
+ *ptrs_symbols = 0;
+ i = 0;
+ is_dmrs_symbol1 = 0;
+ is_dmrs_symbol2 = 0;
+ l_ref = start_symbol;
+ last_symbol = start_symbol + duration_in_symbols - 1;
- while ( (l_ref + i*L_ptrs) <= last_symbol) {
+ while ( (l_ref + i*L_ptrs) <= last_symbol) {
- is_dmrs_symbol1 = is_dmrs_symbol(max((l_ref + (i-1)*L_ptrs + 1), l_ref),
- 0,
- 0,
- 0,
- 0,
- 0,
- duration_in_symbols,
- dmrs_UplinkConfig,
- mapping_type,
- ofdm_symbol_size);
+ is_dmrs_symbol1 = is_dmrs_symbol(max((l_ref + (i-1)*L_ptrs + 1), l_ref),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ duration_in_symbols,
+ dmrs_type,
+ ofdm_symbol_size);
- is_dmrs_symbol2 = is_dmrs_symbol(l_ref + i*L_ptrs,
- 0,
- 0,
- 0,
- 0,
- 0,
- duration_in_symbols,
- dmrs_UplinkConfig,
- mapping_type,
- ofdm_symbol_size);
+ is_dmrs_symbol2 = is_dmrs_symbol(l_ref + i*L_ptrs,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ duration_in_symbols,
+ dmrs_type,
+ ofdm_symbol_size);
- if ( is_dmrs_symbol1 + is_dmrs_symbol2 > 0 ) {
+ if ( is_dmrs_symbol1 + is_dmrs_symbol2 > 0 ) {
- if (dmrs_UplinkConfig->pusch_maxLength == 2)
- l_ref = l_ref + i*L_ptrs + 1;
- else
- l_ref = l_ref + i*L_ptrs;
+ if (pusch_maxLength == 2)
+ l_ref = l_ref + i*L_ptrs + 1;
+ else
+ l_ref = l_ref + i*L_ptrs;
- i = 1;
+ i = 1;
- continue;
+ continue;
- }
+ }
- *ptrs_symbols = *ptrs_symbols | (1<<(l_ref + i*L_ptrs));
- i++;
- }
+ *ptrs_symbols = *ptrs_symbols | (1<<(l_ref + i*L_ptrs));
+ i++;
+ }
}
/*******************************************************************
@@ -313,7 +307,7 @@ uint8_t is_ptrs_symbol(uint8_t l,
uint16_t start_sc,
uint16_t ofdm_symbol_size,
pusch_dmrs_type_t pusch_dmrs_type,
- ptrs_UplinkConfig_t *ptrs_UplinkConfig) {
+ uint8_t resourceElementOffset) {
uint8_t is_ptrs_freq, is_ptrs_time;
int16_t k_RE_ref;
@@ -321,7 +315,7 @@ uint8_t is_ptrs_symbol(uint8_t l,
is_ptrs_freq = 0;
is_ptrs_time = 0;
- k_RE_ref = get_kRE_ref(dmrs_antenna_port, pusch_dmrs_type, ptrs_UplinkConfig->resourceElementOffset);
+ k_RE_ref = get_kRE_ref(dmrs_antenna_port, pusch_dmrs_type, resourceElementOffset);
is_ptrs_freq = is_ptrs_subcarrier(k, K_ptrs, n_rnti, N_RB, k_RE_ref, start_sc, ofdm_symbol_size);
@@ -426,4 +420,4 @@ int main(int argc, char const *argv[])
return 0;
}
-*/
\ No newline at end of file
+*/
diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.h b/openair1/PHY/NR_REFSIG/ptrs_nr.h
index f3b42fff30..291ff4a555 100644
--- a/openair1/PHY/NR_REFSIG/ptrs_nr.h
+++ b/openair1/PHY/NR_REFSIG/ptrs_nr.h
@@ -52,12 +52,11 @@ int16_t get_kRE_ref(uint8_t dmrs_antenna_port, uint8_t pusch_dmrs_type, uint8_t
uint8_t get_K_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint16_t N_RB);
void set_ptrs_symb_idx(uint16_t *ptrs_symbols,
- ptrs_UplinkConfig_t *ptrs_UplinkConfig,
- dmrs_UplinkConfig_t *dmrs_UplinkConfig,
- uint8_t mapping_type,
uint8_t duration_in_symbols,
uint8_t start_symbol,
+ uint8_t dmrs_type,
uint8_t L_ptrs,
+ uint8_t pusch_maxLength,
uint16_t ofdm_symbol_size);
uint8_t get_L_ptrs(ptrs_UplinkConfig_t *ptrs_UplinkConfig, uint8_t I_mcs);
@@ -75,8 +74,8 @@ uint8_t is_ptrs_symbol(uint8_t l,
uint16_t start_sc,
uint16_t ofdm_symbol_size,
pusch_dmrs_type_t pusch_dmrs_type,
- ptrs_UplinkConfig_t *ptrs_UplinkConfig);
+ uint8_t resourceElementOffset);
-#endif /* PTRS_NR_H */
\ No newline at end of file
+#endif /* PTRS_NR_H */
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index 06e3948b64..d62687bd9c 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -42,8 +42,7 @@
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
nfapi_nr_rnti_type_e rnti_type,
- uint16_t N_RB,
- nfapi_nr_config_request_t *config) {
+ uint16_t N_RB) {
uint16_t size = 0;
switch(format) {
@@ -52,7 +51,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
/// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20
size += 20;
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment -- hopping scenario to be updated
- size += nr_get_dci_size(NFAPI_NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB, config) - size; // Padding to match 1_0 size
+ size += nr_get_dci_size(NFAPI_NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB) - size; // Padding to match 1_0 size
// UL/SUL indicator assumed to be 0
break;
@@ -138,7 +137,6 @@ void nr_pdcch_scrambling(uint32_t *in,
uint32_t x1, x2, s=0;
reset = 1;
x2 = (n_RNTI<<16) + Nid;
-
for (int i=0; i>(i&0x1f))&1) ^ ((s>>(i&0x1f))&1))<<(i&0x1f);
- //printf("nr_pdcch_scrambling: in %d seq 0x%08x => out %d\n",((*in)>>(i&0x1f))&1,s,((*out)>>(i&0x1f))&1);
}
}
-uint8_t nr_generate_dci_top(NR_gNB_DCI_ALLOC_t dci_alloc,
+
+uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
+ nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu,
uint32_t **gold_pdcch_dmrs,
int32_t *txdataF,
int16_t amp,
- NR_DL_FRAME_PARMS frame_parms,
- nfapi_nr_config_request_t config) {
+ NR_DL_FRAME_PARMS frame_parms) {
+
int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1]; // 3 for the max coreset duration
uint16_t cset_start_sc;
uint8_t cset_start_symb, cset_nsymb;
int k,l,k_prime,dci_idx, dmrs_idx;
- nr_cce_t cce;
- nr_reg_t reg;
- nr_reg_t reg_mapping_list[NR_MAX_PDCCH_AGG_LEVEL*NR_NB_REG_PER_CCE];
- nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc.pdcch_params;
+ /*First iteration: single DCI*/
- /*The coreset is initialised
- * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0
- * or the rb_offset for other coresets
- * in time: by its first slot and its first symbol*/
- if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1) {
+ nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15=NULL;
+
+
+ // find coreset descriptor
+
+ int rb_offset;
+ int n_rb;
+
+ AssertFatal(pdcch_pdu!=NULL || ul_dci_pdu!=NULL,"At least one pointer has to be !NULL\n");
+ AssertFatal(pdcch_pdu==NULL || ul_dci_pdu==NULL,"Can't handle both DL and UL DCI in same slot\n");
+
+
+ if (pdcch_pdu) pdcch_pdu_rel15 = &pdcch_pdu->pdcch_pdu_rel15;
+ else if (ul_dci_pdu) pdcch_pdu_rel15 = &ul_dci_pdu->pdcch_pdu.pdcch_pdu_rel15;
+
+ get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
+
+ // compute rb_offset and n_prb based on frequency allocation
+
+ if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) {
cset_start_sc = frame_parms.first_carrier_offset + (frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB +
- pdcch_params.rb_offset)*NR_NB_SC_PER_RB;
+ rb_offset)*NR_NB_SC_PER_RB;
} else
- cset_start_sc = frame_parms.first_carrier_offset + pdcch_params.rb_offset*NR_NB_SC_PER_RB;
+ cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB;
- cset_start_symb = pdcch_params.first_symbol;
- cset_nsymb = pdcch_params.n_symb;
- dci_idx = 0;
- LOG_D(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb);
- // DMRS length is per OFDM symbol
- uint32_t dmrs_length = (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS)?
- (pdcch_params.n_rb*6) : (dci_alloc.L*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE)
- uint32_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE)
- LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d\n", dmrs_length, encoded_length);
- dmrs_length += pdcch_params.rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
-
- /// DMRS QPSK modulation
- for (int symb=cset_start_symb; symbnumDlDci;d++) {
+ /*The coreset is initialised
+ * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0
+ * or the rb_offset for other coresets
+ * in time: by its first slot and its first symbol*/
+ cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
+ cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
+ dci_idx = 0;
+ LOG_D(PHY, "Coreset rb_offset %d, nb_rb %d\n",rb_offset,n_rb);
+ LOG_D(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb);
+ // DMRS length is per OFDM symbol
+ AssertFatal(pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED,
+ "Interleaved CCE REG MAPPING not supported\n");
+ uint32_t dmrs_length = (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED)?
+ (n_rb*6) : (pdcch_pdu_rel15->AggregationLevel[d]*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE)
+ uint32_t encoded_length = pdcch_pdu_rel15->AggregationLevel[d]*108; //2(QPSK)*9(per RB)*6(REG per CCE)
+ LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d)\n", dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType);
+ dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
+
+ /// DMRS QPSK modulation
+ for (int symb=cset_start_symb; symbDurationSymbols; symb++) {
+
+ nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
+
#ifdef DEBUG_PDCCH_DMRS
-
- for (int i=0; i>1; i++)
- printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
- gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
-
+
+ for (int i=0; i>1; i++)
+ printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
+ gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
+
#endif
- }
-
- /// DCI payload processing
- // CRC attachment + Scrambling + Channel coding + Rate matching
- uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
- uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params.rnti:0;
- uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)?
- pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value;
- t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
- polar_encoder_fast(dci_alloc.dci_pdu, encoder_output, pdcch_params.rnti, 1, currentPtr);
+ }
+
+ /// DCI payload processing
+ // CRC attachment + Scrambling + Channel coding + Rate matching
+ uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
+ uint16_t n_RNTI = pdcch_pdu_rel15->RNTI[d];
+ uint16_t Nid = pdcch_pdu_rel15->ScramblingId[d];
+
+ t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE,
+ pdcch_pdu_rel15->PayloadSizeBits[d],
+ pdcch_pdu_rel15->AggregationLevel[d],
+ 0,NULL);
+ polar_encoder_fast((uint64_t*)pdcch_pdu_rel15->Payload[d], encoder_output, n_RNTI,1,currentPtr);
#ifdef DEBUG_CHANNEL_CODING
- printf("polar rnti %d\n",pdcch_params.rnti);
- printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
- dci_alloc.dci_pdu[0], dci_alloc.dci_pdu[1]);
- printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5);
+ printf("polar rnti %x,length %d, L %d\n",n_RNTI, pdcch_pdu_rel15->PayloadSizeBits[d],pdcch_pdu_rel15->AggregationLevel[d]);
+ printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
+ ((uint64_t*)pdcch_pdu_rel15->Payload[d])[0], ((uint64_t*)pdcch_pdu_rel15->Payload[d])[1]);
+ printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5);
+
+ for (int i=0; i>5; i++)
+ printf("[%d]->0x%08x \t", i,encoder_output[i]);
- for (int i=0; i>5; i++)
- printf("[%d]->0x%08x \t", i,encoder_output[i]);
-
- printf("\n");
+ printf("\n");
#endif
- /// Scrambling
- uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]= {0};
- nr_pdcch_scrambling(encoder_output, encoded_length, Nid, n_RNTI, scrambled_output);
+ /// Scrambling
+ uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]= {0};
+ nr_pdcch_scrambling(encoder_output, encoded_length, Nid, n_RNTI, scrambled_output);
#ifdef DEBUG_CHANNEL_CODING
- printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\t \
+ printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\t \
[6]->0x%08x \t [7]->0x%08x \t [8]->0x%08x \t [9]->0x%08x\t [10]->0x%08x\t [11]->0x%08x\n",
- scrambled_output[0], scrambled_output[1], scrambled_output[2], scrambled_output[3], scrambled_output[4],scrambled_output[5],
- scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] );
+ scrambled_output[0], scrambled_output[1], scrambled_output[2], scrambled_output[3], scrambled_output[4],scrambled_output[5],
+ scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] );
#endif
- /// QPSK modulation
- int16_t mod_dci[NR_MAX_DCI_SIZE>>1];
- nr_modulation(scrambled_output, encoded_length, DMRS_MOD_ORDER, mod_dci); //Qm = 2 as DMRS is QPSK modulated
+ /// QPSK modulation
+ int16_t mod_dci[NR_MAX_DCI_SIZE>>1];
+ nr_modulation(scrambled_output, encoded_length, DMRS_MOD_ORDER, mod_dci); //Qm = 2 as DMRS is QPSK modulated
#ifdef DEBUG_DCI
-
- for (int i=0; i>1; i++)
- printf("i %d mod_dci %d %d\n", i, mod_dci[i<<1], mod_dci[(i<<1)+1] );
-
+
+ for (int i=0; i>1; i++)
+ printf("i %d mod_dci %d %d\n", i, mod_dci[i<<1], mod_dci[(i<<1)+1] );
+
#endif
+
+ /// Resource mapping
+
+ if (cset_start_sc >= frame_parms.ofdm_symbol_size)
+ cset_start_sc -= frame_parms.ofdm_symbol_size;
+
+ /*Reorder REG list for a freq first mapping*/
+ uint8_t nb_regs = pdcch_pdu_rel15->AggregationLevel[d]*NR_NB_REG_PER_CCE;
+ uint8_t reg_idx0 = pdcch_pdu_rel15->CceIndex[d]*NR_NB_REG_PER_CCE;
- /// Resource mapping
-
- if (cset_start_sc >= frame_parms.ofdm_symbol_size)
- cset_start_sc -= frame_parms.ofdm_symbol_size;
-
- /*Reorder REG list for a freq first mapping*/
- uint8_t nb_regs = dci_alloc.L*NR_NB_REG_PER_CCE;
-
- for (int cce_idx=0; cce_idx>1) * mod_dmrs[l][dmrs_idx<<1]) >> 15;
- ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
-#ifdef DEBUG_PDCCH_DMRS
- printf("symbol %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
- ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
-#endif
- k+=4;
-
- if (k >= frame_parms.ofdm_symbol_size)
- k -= frame_parms.ofdm_symbol_size;
-
- dmrs_idx++;
- }
- }
- }
-
- /*Now mapping the encoded DCI based on newly constructed REG list
- * and the DMRS for the precoder granularity same as REG bundle*/
- for (int reg_idx=0; reg_idx= frame_parms.ofdm_symbol_size)
- k -= frame_parms.ofdm_symbol_size;
-
- l = cset_start_symb + reg.symb_idx;
-
- // dmrs index depends on reference point for k according to 38.211 7.4.1.3.2
- if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
- dmrs_idx = (reg.reg_idx/cset_nsymb)*3;
- else
- dmrs_idx = ((reg.reg_idx/cset_nsymb)+pdcch_params.rb_offset)*3;
-
- k_prime = 0;
-
- for (int m=0; m>1) * mod_dmrs[l][dmrs_idx<<1]) >> 15;
- ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
-#ifdef DEBUG_PDCCH_DMRS
- printf("l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
- ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
-#endif
- dmrs_idx++;
- }
-
- k_prime++;
- } else { // DCI payload
- ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dci[dci_idx<<1]) >> 15;
- ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dci[(dci_idx<<1) + 1]) >> 15;
-#ifdef DEBUG_DCI
- printf("l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
- ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
-#endif
- dci_idx++;
- }
-
- k++;
-
+ /*Mapping the encoded DCI along with the DMRS */
+ for (int reg_idx=reg_idx0; reg_idx<(nb_regs+reg_idx0); reg_idx++) {
+ k = cset_start_sc + (12*reg_idx/cset_nsymb);
+
if (k >= frame_parms.ofdm_symbol_size)
- k -= frame_parms.ofdm_symbol_size;
- }
- }
-
+ k -= frame_parms.ofdm_symbol_size;
+
+ l = cset_start_symb + ((reg_idx/cset_nsymb)%cset_nsymb);
+
+ // dmrs index depends on reference point for k according to 38.211 7.4.1.3.2
+ if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
+ dmrs_idx = (reg_idx/cset_nsymb)*3;
+ else
+ dmrs_idx = ((reg_idx/cset_nsymb)+rb_offset)*3;
+
+ k_prime = 0;
+
+ for (int m=0; mCceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED) {
+ ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (2*amp * mod_dmrs[l][dmrs_idx<<1]) >> 15;
+ ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (2*amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
+#ifdef DEBUG_PDCCH_DMRS
+ printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
+ ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
+#endif
+ dmrs_idx++;
+ }
+
+ k_prime++;
+ } else { // DCI payload
+ ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dci[dci_idx<<1]) >> 15;
+ ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dci[(dci_idx<<1) + 1]) >> 15;
+#ifdef DEBUG_DCI
+ printf("PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
+ ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
+#endif
+ dci_idx++;
+ }
+
+ k++;
+
+ if (k >= frame_parms.ofdm_symbol_size)
+ k -= frame_parms.ofdm_symbol_size;
+ } // m
+ } // reg_idx
+ } // for (int d=0;dnumDlDci;d++)
return 0;
}
+
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h
index d1a0eb7a23..047139aa63 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h
@@ -27,15 +27,14 @@
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
nfapi_nr_rnti_type_e rnti_type,
- uint16_t N_RB,
- nfapi_nr_config_request_t *config);
+ uint16_t N_RB);
-uint8_t nr_generate_dci_top(NR_gNB_DCI_ALLOC_t dci_alloc,
+uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
+ nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu,
uint32_t **gold_pdcch_dmrs,
int32_t *txdataF,
int16_t amp,
- NR_DL_FRAME_PARMS frame_parms,
- nfapi_nr_config_request_t config);
+ NR_DL_FRAME_PARMS frame_parms);
void nr_pdcch_scrambling(uint32_t *in,
uint32_t size,
@@ -45,11 +44,14 @@ void nr_pdcch_scrambling(uint32_t *in,
void nr_fill_dci(PHY_VARS_gNB *gNB,
int frame,
- int slot,
- NR_gNB_DCI_ALLOC_t *dci_alloc,
- nfapi_nr_dl_config_dci_dl_pdu *pdu);
+ int slot);
-void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t *dci_alloc, uint16_t n_shift, uint8_t m);
+void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
+ int frame,
+ int slot);
+void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m);
+
+void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset);
#endif //__PHY_NR_TRANSPORT_DCI__H
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
index c33e5fd34b..c7b14571b7 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
@@ -36,11 +36,14 @@
#include "nr_dlsch.h"
-void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m) {
+/*
+ Original version to keep code for Y that needs to be moved to MAC
+
+void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint16_t n_shift, uint8_t m) {
nr_cce_t* cce;
nr_reg_t* reg;
- nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params = &dci_alloc->pdcch_params;
+ nfapi_nr_dl_config_pdcch_pdu_rel15_t* pdcch_pdu = gNB->pdcch_pdu.pdcch;
uint8_t L = dci_alloc->L;
uint8_t bsize = pdcch_params->reg_bundle_size;
@@ -54,7 +57,7 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m
AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L);
N_cce = N_reg / NR_NB_REG_PER_CCE;
- /*Max number of candidates per aggregation level -- SIB1 configured search space only*/
+ //Max number of candidates per aggregation level -- SIB1 configured search space only
M_s_max = (L==4)?4:(L==8)?2:1;
if (pdcch_params->search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_COMMON)
@@ -113,6 +116,84 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m
}
}
+*/
+
+void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) {
+
+ nr_cce_t* cce;
+ nr_reg_t* reg;
+ nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu_rel15 = &gNB->pdcch_pdu->pdcch_pdu_rel15;
+ int bsize = pdcch_pdu_rel15->RegBundleSize;
+ int R = pdcch_pdu_rel15->InterleaverSize;
+ int n_shift = pdcch_pdu_rel15->ShiftIndex;
+
+
+ //Max number of candidates per aggregation level -- SIB1 configured search space only
+
+
+ int n_rb,rb_offset;
+
+ get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
+
+
+ int N_reg = n_rb * pdcch_pdu_rel15->DurationSymbols;
+ int C=-1;
+
+ for (int d=0;dnumDlDci;d++) {
+ int L = pdcch_pdu_rel15->AggregationLevel[d];
+
+ if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1)
+ AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L);
+
+ if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
+ uint16_t assertFatalCond = (N_reg%(bsize*R));
+ AssertFatal(assertFatalCond == 0,"CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %us, bsize %d R %d)\n",N_reg, bsize, R);
+ C = N_reg/(bsize*R);
+ }
+
+ LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->CceIndex[d]);
+ for (uint8_t cce_idx=0; cce_idxcce_list[d][cce_idx];
+ cce->cce_idx = pdcch_pdu_rel15->CceIndex[d] + cce_idx;
+ LOG_D(PHY, "cce_idx %d\n", cce->cce_idx);
+
+ if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
+ LOG_D(PHY, "Interleaved CCE to REG mapping\n");
+ uint8_t j = cce->cce_idx, j_prime;
+ uint8_t r,c,idx;
+
+ for (uint8_t bundle_idx=0; bundle_idxreg_list[reg_idx];
+ reg->reg_idx = bsize*idx + reg_idx;
+ reg->start_sc_idx = (reg->reg_idx/pdcch_pdu_rel15->DurationSymbols) * NR_NB_SC_PER_RB;
+ reg->symb_idx = reg->reg_idx % pdcch_pdu_rel15->DurationSymbols;
+ LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx);
+ }
+ }
+ }
+ else { // NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED
+ LOG_D(PHY, "Non interleaved CCE to REG mapping\n");
+ for (uint8_t reg_idx=0; reg_idxreg_list[reg_idx];
+ reg->reg_idx = cce->cce_idx*NR_NB_REG_PER_CCE + reg_idx;
+ reg->start_sc_idx = (reg->reg_idx/pdcch_pdu_rel15->DurationSymbols) * NR_NB_SC_PER_RB;
+ reg->symb_idx = reg->reg_idx % pdcch_pdu_rel15->DurationSymbols;
+ LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx);
+ }
+
+ }
+
+ }
+ }
+}
+
/*static inline uint64_t dci_field(uint64_t field, uint8_t size) {
uint64_t ret = 0;
for (int i=0; idci_pdu;
- memset((void*)dci_pdu,0,2*sizeof(uint64_t));
- nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &pdcch_pdu->dci_dl_pdu_rel15;
- nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &pdcch_pdu->pdcch_params_rel15;
-
-
- nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
+ nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &gNB->pdcch_pdu->pdcch_pdu_rel15;
NR_gNB_DLSCH_t *dlsch;
+ for (int i=0;inumDlDci;i++) {
- uint16_t N_RB = params_rel15->n_RB_BWP;
- uint8_t fsize=0, pos=0, cand_idx=0;
+ //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
-
- int dlsch_id = find_nr_dlsch(params_rel15->rnti,gNB,SEARCH_EXIST_OR_FREE);
- if( (dlsch_id<0) || (dlsch_id>=NUMBER_OF_NR_DLSCH_MAX) ){
- LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",params_rel15->rnti,dlsch_id);
- return;
- }
-
- dlsch = gNB->dlsch[dlsch_id][0];
-
- dlsch->slot_tx[slot] = 1;
- dlsch->harq_ids[frame%2][slot] = pdu_rel15->harq_pid;
- AssertFatal(pdu_rel15->harq_pid < 8 && pdu_rel15->harq_pid >= 0,
- "illegal harq_pid %d\n",pdu_rel15->harq_pid);
-
- dlsch->harq_mask |= (1<harq_pid);
- dlsch->rnti = params_rel15->rnti;
-
- dci_alloc->L = 8;
- memcpy((void*)&dci_alloc->pdcch_params, (void*)params_rel15, sizeof(nfapi_nr_dl_config_pdcch_parameters_rel15_t));
- dci_alloc->size = nr_get_dci_size(dci_alloc->pdcch_params.dci_format,
- dci_alloc->pdcch_params.rnti_type,
- N_RB,
- cfg);
-
- AssertFatal(dci_alloc->size<=64, "DCI sizes above 64 bits not yet supported");
- n_shift = (dci_alloc->pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1)?
- cfg->sch_config.physical_cell_id.value : dci_alloc->pdcch_params.shift_index;
- nr_fill_cce_list(dci_alloc, n_shift, cand_idx);
-
- /// Payload generation
- switch(params_rel15->dci_format) {
-
-
- case NFAPI_NR_DL_DCI_FORMAT_1_0:
- switch(params_rel15->rnti_type) {
- case NFAPI_NR_RNTI_RA:
-
- // Freq domain assignment
- fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
- pos=fsize;
- *dci_pdu |= ((pdu_rel15->frequency_domain_assignment&((1<size-pos));
-#ifdef DEBUG_FILL_DCI
- printf("frequency-domain assignment %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->frequency_domain_assignment,fsize,dci_alloc->size-pos,*dci_pdu);
-#endif
- // Time domain assignment
- pos+=4;
- *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos));
-#ifdef DEBUG_FILL_DCI
- printf("time-domain assignment %d (3 bits)=> %d (0x%lx)\n",pdu_rel15->time_domain_assignment,dci_alloc->size-pos,*dci_pdu);
-#endif
- // VRB to PRB mapping
-
- pos++;
- *dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&0x1)<<(dci_alloc->size-pos);
-#ifdef DEBUG_FILL_DCI
- printf("vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",pdu_rel15->vrb_to_prb_mapping,dci_alloc->size-pos,*dci_pdu);
-#endif
- // MCS
- pos+=5;
- *dci_pdu |= ((uint64_t)pdu_rel15->mcs&0x1f)<<(dci_alloc->size-pos);
-#ifdef DEBUG_FILL_DCI
- printf("mcs %d (5 bits)=> %d (0x%lx)\n",pdu_rel15->mcs,dci_alloc->size-pos,*dci_pdu);
-#endif
- // TB scaling
- pos+=2;
- *dci_pdu |= ((uint64_t)pdu_rel15->tb_scaling&0x3)<<(dci_alloc->size-pos);
-#ifdef DEBUG_FILL_DCI
- printf("tb_scaling %d (2 bits)=> %d (0x%lx)\n",pdu_rel15->tb_scaling,dci_alloc->size-pos,*dci_pdu);
-#endif
- break;
-
- case NFAPI_NR_RNTI_C:
-
- // indicating a DL DCI format 1bit
- pos++;
- *dci_pdu |= ((uint64_t)pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos);
-#ifdef DEBUG_FILL_DCI
- printf("Format indicator %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->format_indicator,1,dci_alloc->size-pos,*dci_pdu);
-#endif
-
- // Freq domain assignment (275rb >> fsize = 16)
- fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
- pos+=fsize;
- *dci_pdu |= (((uint64_t)pdu_rel15->frequency_domain_assignment&((1<size-pos));
-
-#ifdef DEBUG_FILL_DCI
- printf("Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->frequency_domain_assignment,fsize,dci_alloc->size-pos,*dci_pdu);
-#endif
-
- uint16_t is_ra = 1;
- for (int i=0; ifrequency_domain_assignment>>i)&1)) {
- is_ra = 0;
- break;
+ int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->RNTI[i],gNB,SEARCH_EXIST_OR_FREE);
+ if( (dlsch_id<0) || (dlsch_id>=NUMBER_OF_NR_DLSCH_MAX) ){
+ LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->RNTI[i],dlsch_id);
+ return;
}
- if (is_ra) //fsize are all 1 38.212 p86
- {
- // ra_preamble_index 6 bits
- pos+=6;
- *dci_pdu |= ((pdu_rel15->ra_preamble_index&0x3f)<<(dci_alloc->size-pos));
+
+ dlsch = gNB->dlsch[dlsch_id][0];
+ int harq_pid = 0;//extract_harq_pid(i,pdu_rel15);
- // UL/SUL indicator 1 bit
- pos++;
- *dci_pdu |= (pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos);
+ dlsch->slot_tx[slot] = 1;
+ dlsch->harq_ids[frame%2][slot] = harq_pid;
+ AssertFatal(harq_pid < 8 && harq_pid >= 0,
+ "illegal harq_pid %d\n",harq_pid);
+
+ dlsch->harq_mask |= (1<rnti = pdcch_pdu_rel15->RNTI[i];
+
+ nr_fill_cce_list(gNB,0);
+ /*
+ LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]);
+ LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx);
+ */
+
+ }
+
+}
+void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
+ int frame,
+ int slot) {
+
+ nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &gNB->ul_dci_pdu->pdcch_pdu.pdcch_pdu_rel15;
+
+
+ for (int i=0;inumDlDci;i++) {
+
+ //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
+
+ // if there's no DL DCI then generate CCE list
+ if (gNB->pdcch_pdu) nr_fill_cce_list(gNB,0);
+ /*
+ LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]);
+ LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx);
+ */
- // SS/PBCH index 6 bits
- pos+=6;
- *dci_pdu |= ((pdu_rel15->ss_pbch_index&0x3f)<<(dci_alloc->size-pos));
-
- // prach_mask_index 4 bits
- pos+=4;
- *dci_pdu |= ((pdu_rel15->prach_mask_index&0xf)<<(dci_alloc->size-pos));
-
- } //end if
-
- else {
-
- // Time domain assignment 4bit
-
- pos+=4;
- *dci_pdu |= ((pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos));
-#ifdef DEBUG_FILL_DCI
- printf("Time domain assignment %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->time_domain_assignment,4,dci_alloc->size-pos,*dci_pdu);
-#endif
-
- // VRB to PRB mapping 1bit
- pos++;
- *dci_pdu |= (pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos);
-#ifdef DEBUG_FILL_DCI
- printf("VRB to PRB %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->vrb_to_prb_mapping,1,dci_alloc->size-pos,*dci_pdu);
-#endif
-
- // MCS 5bit //bit over 32, so dci_pdu ++
- pos+=5;
- *dci_pdu |= (pdu_rel15->mcs&0x1f)<<(dci_alloc->size-pos);
-#ifdef DEBUG_FILL_DCI
- printf("MCS %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->mcs,5,dci_alloc->size-pos,*dci_pdu);
-#endif
-
- // New data indicator 1bit
- pos++;
- *dci_pdu |= (pdu_rel15->ndi&1)<<(dci_alloc->size-pos);
-#ifdef DEBUG_FILL_DCI
- printf("NDI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->ndi,1,dci_alloc->size-pos,*dci_pdu);
-#endif
-
- // Redundancy version 2bit
- pos+=2;
- *dci_pdu |= (pdu_rel15->rv&0x3)<<(dci_alloc->size-pos);
-#ifdef DEBUG_FILL_DCI
- printf("RV %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->rv,2,dci_alloc->size-pos,*dci_pdu);
-#endif
-
- // HARQ process number 4bit
- pos+=4;
- *dci_pdu |= ((pdu_rel15->harq_pid&0xf)<<(dci_alloc->size-pos));
-#ifdef DEBUG_FILL_DCI
- printf("HARQ_PID %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->harq_pid,4,dci_alloc->size-pos,*dci_pdu);
-#endif
-
- // Downlink assignment index 2bit
- pos+=2;
- *dci_pdu |= ((pdu_rel15->dai&3)<<(dci_alloc->size-pos));
-#ifdef DEBUG_FILL_DCI
- printf("DAI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->dai,2,dci_alloc->size-pos,*dci_pdu);
-#endif
-
- // TPC command for scheduled PUCCH 2bit
- pos+=2;
- *dci_pdu |= ((pdu_rel15->tpc&3)<<(dci_alloc->size-pos));
-#ifdef DEBUG_FILL_DCI
- printf("TPC %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->tpc,2,dci_alloc->size-pos,*dci_pdu);
-#endif
-
- // PUCCH resource indicator 3bit
- pos+=3;
- *dci_pdu |= ((pdu_rel15->pucch_resource_indicator&0x7)<<(dci_alloc->size-pos));
-#ifdef DEBUG_FILL_DCI
- printf("PUCCH RI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->pucch_resource_indicator,3,dci_alloc->size-pos,*dci_pdu);
-#endif
-
- // PDSCH-to-HARQ_feedback timing indicator 3bit
- pos+=3;
- *dci_pdu |= ((pdu_rel15->pdsch_to_harq_feedback_timing_indicator&0x7)<<(dci_alloc->size-pos));
-#ifdef DEBUG_FILL_DCI
- printf("PDSCH to HARQ TI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->pdsch_to_harq_feedback_timing_indicator,3,dci_alloc->size-pos,*dci_pdu);
-#endif
-
- } //end else
- break;
-
- case NFAPI_NR_RNTI_P:
-
- // Short Messages Indicator – 2 bits
- for (int i=0; i<2; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->short_messages_indicator>>(1-i))&1)<<(dci_alloc->size-pos++);
- // Short Messages – 8 bits
- for (int i=0; i<8; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->short_messages>>(7-i))&1)<<(dci_alloc->size-pos++);
- // Freq domain assignment 0-16 bit
- fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
- for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++);
- // Time domain assignment 4 bit
- for (int i=0; i<4; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
- // VRB to PRB mapping 1 bit
- *dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++);
- // MCS 5 bit
- for (int i=0; i<5; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
-
- // TB scaling 2 bit
- for (int i=0; i<2; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->tb_scaling>>(1-i))&1)<<(dci_alloc->size-pos++);
-
-
- break;
-
- case NFAPI_NR_RNTI_SI:
- // Freq domain assignment 0-16 bit
- fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
- for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++);
- // Time domain assignment 4 bit
- for (int i=0; i<4; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
- // VRB to PRB mapping 1 bit
- *dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++);
- // MCS 5bit //bit over 32, so dci_pdu ++
- for (int i=0; i<5; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
- // Redundancy version 2bit
- for (int i=0; i<2; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
-
- break;
-
- case NFAPI_NR_RNTI_TC:
- // indicating a DL DCI format 1bit
- *dci_pdu |= ((uint64_t)pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++);
- // Freq domain assignment 0-16 bit
- fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
- for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++);
- // Time domain assignment 4 bit
- for (int i=0; i<4; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
- // VRB to PRB mapping 1 bit
- *dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++);
- // MCS 5bit //bit over 32, so dci_pdu ++
- for (int i=0; i<5; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
- // New data indicator 1bit
- *dci_pdu |= ((uint64_t)pdu_rel15->ndi&1)<<(dci_alloc->size-pos++);
- // Redundancy version 2bit
- for (int i=0; i<2; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
- // HARQ process number 4bit
- for (int i=0; i<4; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++);
-
- // Downlink assignment index – 2 bits
- for (int i=0; i<2; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->dai>>(1-i))&1)<<(dci_alloc->size-pos++);
-
- // TPC command for scheduled PUCCH – 2 bits
- for (int i=0; i<2; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++);
-
-
- // LOG_D(PHY, "DCI PDU: [0]->0x%08llx \t [1]->0x%08llx \t [2]->0x%08llx \t [3]->0x%08llx\n",
- // dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]);
-
-
- // PDSCH-to-HARQ_feedback timing indicator – 3 bits
- for (int i=0; i<3; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->pdsch_to_harq_feedback_timing_indicator>>(2-i))&1)<<(dci_alloc->size-pos++);
-
- break;
- }
- break;
-
- case NFAPI_NR_UL_DCI_FORMAT_0_0:
- switch(params_rel15->rnti_type)
- {
- case NFAPI_NR_RNTI_C:
- // indicating a DL DCI format 1bit
- *dci_pdu |= ((uint64_t)pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++);
- // Freq domain assignment max 16 bit
- fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
- for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++);
- // Time domain assignment 4bit
- for (int i=0; i<4; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
- // Frequency hopping flag – 1 bit
- *dci_pdu |= ((uint64_t)pdu_rel15->frequency_hopping_flag&1)<<(dci_alloc->size-pos++);
- // MCS 5 bit
- for (int i=0; i<5; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
- // New data indicator 1bit
- *dci_pdu |= ((uint64_t)pdu_rel15->ndi&1)<<(dci_alloc->size-pos++);
- // Redundancy version 2bit
- for (int i=0; i<2; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
- // HARQ process number 4bit
- for (int i=0; i<4; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++);
-
- // TPC command for scheduled PUSCH – 2 bits
- for (int i=0; i<2; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++);
-
- // Padding bits
- for(int a = pos;a<32;a++)
- *dci_pdu |= ((uint64_t)pdu_rel15->padding&1)<<(dci_alloc->size-pos++);
-
- // UL/SUL indicator – 1 bit
- if (cfg->pucch_config.pucch_GroupHopping.value)
- *dci_pdu |= ((uint64_t)pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos++);
-
- break;
-
- case NFAPI_NR_RNTI_TC:
-
- // indicating a DL DCI format 1bit
- *dci_pdu |= (pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++);
- // Freq domain assignment max 16 bit
- fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
- for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++);
- // Time domain assignment 4bit
- for (int i=0; i<4; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
- // Frequency hopping flag – 1 bit
- *dci_pdu |= ((uint64_t)pdu_rel15->frequency_hopping_flag&1)<<(dci_alloc->size-pos++);
- // MCS 5 bit
- for (int i=0; i<5; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
- // New data indicator 1bit
- *dci_pdu |= ((uint64_t)pdu_rel15->ndi&1)<<(dci_alloc->size-pos++);
- // Redundancy version 2bit
- for (int i=0; i<2; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
- // HARQ process number 4bit
- for (int i=0; i<4; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++);
-
- // TPC command for scheduled PUSCH – 2 bits
- for (int i=0; i<2; i++)
- *dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++);
-
- // Padding bits
- for(int a = pos;a<32;a++)
- *dci_pdu |= ((uint64_t)pdu_rel15->padding&1)<<(dci_alloc->size-pos++);
-
- // UL/SUL indicator – 1 bit
- if (cfg->pucch_config.pucch_GroupHopping.value)
- *dci_pdu |= ((uint64_t)pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos++);
-
- break;
- }
- break;
}
- LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]);
- LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx);
-
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools_common.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools_common.c
new file mode 100644
index 0000000000..d26a52f157
--- /dev/null
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools_common.c
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+/*! \file PHY/NR_TRANSPORT/nr_dci_tools_common.c
+ * \brief
+ * \author
+ * \date 2018
+ * \version 0.1
+ * \company Eurecom
+ * \email:
+ * \note
+ * \warning
+ */
+
+#include "nr_dci.h"
+
+//#define DEBUG_FILL_DCI
+
+#include "nr_dlsch.h"
+
+
+void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) {
+
+ uint8_t count=0, start=0, start_set=0;
+
+ uint64_t bitmap = (((uint64_t)FreqDomainResource[0])<<37)|
+ (((uint64_t)FreqDomainResource[1])<<29)|
+ (((uint64_t)FreqDomainResource[2])<<21)|
+ (((uint64_t)FreqDomainResource[3])<<13)|
+ (((uint64_t)FreqDomainResource[4])<<5)|
+ (((uint64_t)FreqDomainResource[5])>>3);
+
+ for (int i=0; i<45; i++)
+ if ((bitmap>>(44-i))&1) {
+ count++;
+ if (!start_set) {
+ start = i;
+ start_set = 1;
+ }
+ }
+ *rb_offset = 6*start;
+ *n_rb = 6*count;
+}
+
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index 7502d5d4a4..4518280f6b 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -65,178 +65,230 @@ void nr_pdsch_codeword_scrambling(uint8_t *in,
}
+void nr_pdsch_codeword_scrambling_optim(uint8_t *in,
+ uint32_t size,
+ uint8_t q,
+ uint32_t Nid,
+ uint32_t n_RNTI,
+ uint32_t* out) {
+
+ uint32_t x1, x2, s=0,in32;
+
+ x2 = (n_RNTI<<15) + (q<<14) + Nid;
+
+ s=lte_gold_generic(&x1, &x2, 1);
+
+#if defined(__AVX2__)
+ for (int i=0; i<((size>>5)+((size&0x1f) > 0 ? 1 : 0)); i++) {
+ in32=_mm256_movemask_epi8(_mm256_slli_epi16(((__m256i*)in)[i],7));
+ out[i]=(in32^s);
+ // printf("in[%d] %x => %x\n",i,in32,out[i]);
+ s=lte_gold_generic(&x1, &x2, 0);
+ }
+#elif defined(__SSE4__)
+ _m128i *in128;
+ for (int i=0; i<((size>>5)+((size&0x1f) > 0 ? 1 : 0)); i++) {
+ in128=&((__m128i*)in)[i<<1];
+ ((uint16_t*)&in32)[0] = _mm128_movemask_epi8(_mm256_slli_epi16(in128[0],7));
+ ((uint16_t*)&in32)[1] = _mm128_movemask_epi8(_mm256_slli_epi16(in128[1],7));
+ out[i]=(in32^s);
+ s=lte_gold_generic(&x1, &x2, 0);
+ }
+ //#elsif defined(__arm__) || defined(__aarch64)
+
+#else
+ nr_pdsch_codeword_scrambling(in,
+ size,
+ q,
+ Nid,
+ n_RNTI,
+ out);
+#endif
+}
+
uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
- NR_gNB_DCI_ALLOC_t *dci_alloc,
uint32_t ***pdsch_dmrs,
int32_t** txdataF,
int16_t amp,
int frame,
uint8_t slot,
NR_DL_FRAME_PARMS *frame_parms,
- nfapi_nr_config_request_t *config,
+ int xOverhead,
time_stats_t *dlsch_encoding_stats,
time_stats_t *dlsch_scrambling_stats,
- time_stats_t *dlsch_modulation_stats) {
+ time_stats_t *dlsch_modulation_stats,
+ time_stats_t *tinput,
+ time_stats_t *tprep,
+ time_stats_t *tparity,
+ time_stats_t *toutput,
+ time_stats_t *dlsch_rate_matching_stats,
+ time_stats_t *dlsch_interleaving_stats,
+ time_stats_t *dlsch_segmentation_stats) {
- NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[dci_alloc->harq_pid];
- nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &harq->dlsch_pdu.dlsch_pdu_rel15;
- nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc->pdcch_params;
+ int harq_pid = 0;
+ NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[harq_pid];
+ nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs;
int16_t **tx_layers = (int16_t**)dlsch->txdataF;
int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
- uint16_t nb_symbols = rel15->nb_mod_symbols;
- uint8_t Qm = rel15->modulation_order;
- uint32_t encoded_length = nb_symbols*Qm;
+ uint8_t dmrs_Type = rel15->dmrsConfigType;
+ int nb_re_dmrs = (dmrs_Type== NFAPI_NR_DMRS_TYPE1) ? 6:4;
+ uint16_t n_dmrs = ((rel15->rbSize+rel15->rbStart)*nb_re_dmrs)<<1;
+ int16_t mod_dmrs[n_dmrs<<1];
+
+ uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords;
+ uint8_t Qm = rel15->qamModOrder[0];
+ uint32_t encoded_length = nb_re*Qm;
/// CRC, coding, interleaving and rate matching
AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n");
start_meas(dlsch_encoding_stats);
- nr_dlsch_encoding(harq->pdu, frame, slot, dlsch, frame_parms);
+ nr_dlsch_encoding(harq->pdu, frame, slot, dlsch, frame_parms,tinput,tprep,tparity,toutput,
+ dlsch_rate_matching_stats,
+ dlsch_interleaving_stats,
+ dlsch_segmentation_stats);
stop_meas(dlsch_encoding_stats);
#ifdef DEBUG_DLSCH
-printf("PDSCH encoding:\nPayload:\n");
-for (int i=0; iB>>7; i++) {
- for (int j=0; j<16; j++)
- printf("0x%02x\t", harq->pdu[(i<<4)+j]);
+ printf("PDSCH encoding:\nPayload:\n");
+ for (int i=0; iB>>7; i++) {
+ for (int j=0; j<16; j++)
+ printf("0x%02x\t", harq->pdu[(i<<4)+j]);
+ printf("\n");
+ }
+ printf("\nEncoded payload:\n");
+ for (int i=0; i>3; i++) {
+ for (int j=0; j<8; j++)
+ printf("%d", harq->f[(i<<3)+j]);
+ printf("\t");
+ }
printf("\n");
-}
-printf("\nEncoded payload:\n");
-for (int i=0; i>3; i++) {
- for (int j=0; j<8; j++)
- printf("%d", harq->f[(i<<3)+j]);
- printf("\t");
-}
-printf("\n");
#endif
+
+
/// scrambling
start_meas(dlsch_scrambling_stats);
- for (int q=0; qnb_codewords; q++)
+ for (int q=0; qNrOfCodewords; q++)
memset((void*)scrambled_output[q], 0, (encoded_length>>5)*sizeof(uint32_t));
- uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \
- ((pdcch_params.scrambling_id==0)?pdcch_params.rnti:0) : 0;
- uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \
- pdcch_params.scrambling_id : config->sch_config.physical_cell_id.value;
- for (int q=0; qnb_codewords; q++)
- nr_pdsch_codeword_scrambling(harq->f,
- encoded_length,
- q,
- Nid,
- n_RNTI,
- scrambled_output[q]);
-
+ for (int q=0; qNrOfCodewords; q++)
+ nr_pdsch_codeword_scrambling_optim(harq->f,
+ encoded_length,
+ q,
+ rel15->dlDmrsScramblingId,
+ rel15->rnti,
+ scrambled_output[q]);
+
stop_meas(dlsch_scrambling_stats);
#ifdef DEBUG_DLSCH
-printf("PDSCH scrambling:\n");
-for (int i=0; i>8; i++) {
- for (int j=0; j<8; j++)
- printf("0x%08x\t", scrambled_output[0][(i<<3)+j]);
- printf("\n");
-}
+ printf("PDSCH scrambling:\n");
+ for (int i=0; i>8; i++) {
+ for (int j=0; j<8; j++)
+ printf("0x%08x\t", scrambled_output[0][(i<<3)+j]);
+ printf("\n");
+ }
#endif
/// Modulation
start_meas(dlsch_modulation_stats);
- for (int q=0; qnb_codewords; q++)
+ for (int q=0; qNrOfCodewords; q++)
nr_modulation(scrambled_output[q],
encoded_length,
Qm,
mod_symbs[q]);
stop_meas(dlsch_modulation_stats);
#ifdef DEBUG_DLSCH
-printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_symbols);
-for (int i=0; i>3; i++) {
- for (int j=0; j<8; j++) {
- printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]);
- }
- printf("\n");
-}
-#endif
-
-
- /// Layer mapping
- nr_layer_mapping(mod_symbs,
- rel15->nb_layers,
- nb_symbols,
- tx_layers);
-#ifdef DEBUG_DLSCH
-printf("Layer mapping (%d layers):\n", rel15->nb_layers);
-for (int l=0; lnb_layers; l++)
- for (int i=0; i<(nb_symbols/rel15->nb_layers)>>3; i++) {
+ printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_re);
+ for (int i=0; i>3; i++) {
for (int j=0; j<8; j++) {
- printf("%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]);
+ printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]);
}
printf("\n");
}
#endif
- /// Antenna port mapping
- //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007
-
- /// DMRS QPSK modulation
- uint16_t n_dmrs = ((rel15->n_prb+rel15->start_prb)*rel15->nb_re_dmrs)<<1;
- int16_t mod_dmrs[n_dmrs<<1];
- uint8_t dmrs_type = config->pdsch_config.dmrs_type.value;
- uint8_t mapping_type = config->pdsch_config.mapping_type.value;
-
- l0 = get_l0(mapping_type, 2);//config->pdsch_config.dmrs_typeA_position.value);
- nr_modulation(pdsch_dmrs[l0][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
+ /// Layer mapping
+ nr_layer_mapping(mod_symbs,
+ rel15->nrOfLayers,
+ nb_re,
+ tx_layers);
#ifdef DEBUG_DLSCH
-printf("DMRS modulation (single symbol %d, %d symbols, type %d):\n", l0, n_dmrs>>1, dmrs_type);
-for (int i=0; i>4; i++) {
- for (int j=0; j<8; j++) {
- printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]);
- }
- printf("\n");
-}
+ printf("Layer mapping (%d layers):\n", rel15->nrOfLayers);
+ for (int l=0; lnrOfLayers; l++)
+ for (int i=0; i<(nb_re/rel15->nrOfLayers)>>3; i++) {
+ printf("layer %d, Re %d..%d : ",l,i<<3,(i<<3)+7);
+ for (int j=0; j<8; j++) {
+ printf("l%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]);
+ }
+ printf("\n");
+ }
#endif
-
+ /// Antenna port mapping
+ //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007
+
+ /// DMRS QPSK modulation
+
+
+ l0 = get_l0(rel15->dlDmrsSymbPos);
+ nr_modulation(pdsch_dmrs[l0][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
+
+#ifdef DEBUG_DLSCH
+ printf("DMRS modulation (single symbol %d, %d symbols, type %d):\n", l0, n_dmrs>>1, dmrs_Type);
+ for (int i=0; i>4; i++) {
+ for (int j=0; j<8; j++) {
+ printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]);
+ }
+ printf("\n");
+ }
+#endif
+
+
/// Resource mapping
-
+
// Non interleaved VRB to PRB mapping
- uint16_t start_sc = frame_parms->first_carrier_offset + rel15->start_prb*NR_NB_SC_PER_RB;
+ uint16_t start_sc = frame_parms->first_carrier_offset + rel15->rbStart*NR_NB_SC_PER_RB;
if (start_sc >= frame_parms->ofdm_symbol_size)
start_sc -= frame_parms->ofdm_symbol_size;
#ifdef DEBUG_DLSCH_MAPPING
- printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_symbols %d)\n",
- start_sc, rel15->start_symbol, rel15->n_prb, rel15->nb_symbols);
+ printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
+ start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers);
#endif
- for (int ap=0; apnb_layers; ap++) {
+ for (int ap=0; apnrOfLayers; ap++) {
// DMRS params for this ap
- get_Wt(Wt, ap, dmrs_type);
- get_Wf(Wf, ap, dmrs_type);
- delta = get_delta(ap, dmrs_type);
+ get_Wt(Wt, ap, dmrs_Type);
+ get_Wf(Wf, ap, dmrs_Type);
+ delta = get_delta(ap, dmrs_Type);
l_prime[0] = 0; // single symbol ap 0
uint8_t dmrs_symbol = l0+l_prime[0];
#ifdef DEBUG_DLSCH_MAPPING
-printf("DMRS params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n",
-ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol);
+ printf("DMRS Type %d params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n",
+ 1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol);
#endif
uint8_t k_prime=0;
uint16_t m=0, n=0, dmrs_idx=0, k=0;
- int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP;
- if (dmrs_type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k)
- dmrs_idx = rel15->start_prb*6;
- else
- dmrs_idx = rel15->start_prb*4;
- for (int l=rel15->start_symbol; lstart_symbol+rel15->nb_symbols; l++) {
+ int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP;
+ if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k)
+ dmrs_idx = rel15->rbStart*6;
+ else
+ dmrs_idx = rel15->rbStart*4;
+
+ for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) {
k = start_sc;
- for (int i=0; in_prb*NR_NB_SC_PER_RB; i++) {
- if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_type))%(frame_parms->ofdm_symbol_size)))) {
+ for (int i=0; irbSize*NR_NB_SC_PER_RB; i++) {
+ if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) {
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15;
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING
-printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
-dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
-((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
+ printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
+ dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
+ ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
#endif
dmrs_idx++;
k_prime++;
@@ -249,9 +301,9 @@ dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING
-printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
+ printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
-((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
+ ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
#endif
m++;
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
index 77d5c6802f..f48905b68c 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
@@ -36,10 +36,10 @@
#include "PHY/defs_gNB.h"
void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config,
- nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
- nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu);
+ nfapi_nr_dl_tti_pdcch_pdu dci_pdu,
+ nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu);
-void nr_check_time_alloc(uint8_t S, uint8_t L, nfapi_nr_config_request_t config);
+void nr_check_time_alloc(uint8_t S, uint8_t L,nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,nfapi_nr_config_request_t *cfg);
uint16_t get_RIV(uint16_t rb_start, uint16_t L, uint16_t N_RB);
@@ -51,7 +51,10 @@ void nr_get_rbg_parms(NR_BWP_PARMS* bwp, uint8_t config_type);
void nr_get_rbg_list(uint32_t bitmap, uint8_t n_rbg, uint8_t* rbg_list);
-void nr_get_PRG_parms(NR_BWP_PARMS* bwp, NR_gNB_DCI_ALLOC_t dci_alloc, uint8_t prb_bundling_type);
+
+uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx);
+
+uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx);
void nr_pdsch_codeword_scrambling(uint8_t *in,
uint32_t size,
@@ -63,24 +66,31 @@ void nr_pdsch_codeword_scrambling(uint8_t *in,
void nr_fill_dlsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
- nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
+ nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
unsigned char *sdu);
uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
- NR_gNB_DCI_ALLOC_t *dci_alloc,
uint32_t ***pdsch_dmrs,
int32_t** txdataF,
int16_t amp,
int frame,
uint8_t slot,
NR_DL_FRAME_PARMS *frame_parms,
- nfapi_nr_config_request_t *config,
+ int xOverhead,
time_stats_t *dlsch_encoding_stats,
time_stats_t *dlsch_scrambling_stats,
- time_stats_t *dlsch_modulation_stats);
+ time_stats_t *dlsch_modulation_stats,
+ time_stats_t *tinput,
+ time_stats_t *tprep,
+ time_stats_t *tparity,
+ time_stats_t *toutput,
+ time_stats_t *dlsch_rate_matching_stats,
+ time_stats_t *dlsch_interleaving_stats,
+ time_stats_t *dlsch_segmentation_stats);
-void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr);
+
+void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,uint16_t N_RB);
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
@@ -89,9 +99,16 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
int nr_dlsch_encoding(unsigned char *a,int frame,
- uint8_t slot,
- NR_gNB_DLSCH_t *dlsch,
- NR_DL_FRAME_PARMS* frame_parms);
+ uint8_t slot,
+ NR_gNB_DLSCH_t *dlsch,
+ NR_DL_FRAME_PARMS* frame_parms,
+ time_stats_t *tinput,
+ time_stats_t *tprep,
+ time_stats_t *tparity,
+ time_stats_t *toutput,
+ time_stats_t *dlsch_rate_matching_stats,
+ time_stats_t *dlsch_interleaving_stats,
+ time_stats_t *dlsch_segmentation_stats);
void nr_emulate_dlsch_payload(uint8_t* payload, uint16_t size);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index 17de9c02af..856a7863f4 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -39,6 +39,7 @@
#include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
+#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "SCHED_NR/sched_nr.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/LOG/log.h"
@@ -47,43 +48,71 @@
//#define DEBUG_DLSCH_CODING
//#define DEBUG_DLSCH_FREE 1
-void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr)
+
+void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,uint16_t N_RB)
{
int i;
int r;
-
+
NR_gNB_DLSCH_t *dlsch = *dlschptr;
+
+ uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated
if (dlsch) {
+
+ if (N_RB != 273) {
+ a_segments = a_segments*N_RB;
+ a_segments = a_segments/273;
+ }
+
+ uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
+
+
#ifdef DEBUG_DLSCH_FREE
- printf("Freeing dlsch %p\n",dlsch);
+ LOG_D(PHY,"Freeing dlsch %p\n",dlsch);
#endif
for (i=0; iMdlharq; i++) {
#ifdef DEBUG_DLSCH_FREE
- printf("Freeing dlsch process %d\n",i);
+ LOG_D(PHY,"Freeing dlsch process %d\n",i);
#endif
if (dlsch->harq_processes[i]) {
#ifdef DEBUG_DLSCH_FREE
- printf("Freeing dlsch process %d (%p)\n",i,dlsch->harq_processes[i]);
+ LOG_D(PHY,"Freeing dlsch process %d (%p)\n",i,dlsch->harq_processes[i]);
#endif
if (dlsch->harq_processes[i]->b) {
- free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES); //this should be MAX_NR_DLSCH_PAYLOAD_BYTES
+ free16(dlsch->harq_processes[i]->b,dlsch_bytes);
dlsch->harq_processes[i]->b = NULL;
#ifdef DEBUG_DLSCH_FREE
- printf("Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b);
+ LOG_D(PHY,"Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b);
+#endif
+ }
+
+ if (dlsch->harq_processes[i]->e) {
+ free16(dlsch->harq_processes[i]->e,14*N_RB*12*8);
+ dlsch->harq_processes[i]->e = NULL;
+#ifdef DEBUG_DLSCH_FREE
+ printf("Freeing dlsch process %d e (%p)\n",i,dlsch->harq_processes[i]->e);
+#endif
+ }
+
+ if (dlsch->harq_processes[i]->f) {
+ free16(dlsch->harq_processes[i]->f,14*N_RB*12*8);
+ dlsch->harq_processes[i]->f = NULL;
+#ifdef DEBUG_DLSCH_FREE
+ printf("Freeing dlsch process %d f (%p)\n",i,dlsch->harq_processes[i]->f);
#endif
}
#ifdef DEBUG_DLSCH_FREE
- printf("Freeing dlsch process %d c (%p)\n",i,dlsch->harq_processes[i]->c);
+ LOG_D(PHY,"Freeing dlsch process %d c (%p)\n",i,dlsch->harq_processes[i]->c);
#endif
- for (r=0; rharq_processes[i]->c[r]);
+ LOG_D(PHY,"Freeing dlsch process %d c[%d] (%p)\n",i,r,dlsch->harq_processes[i]->c[r]);
#endif
if (dlsch->harq_processes[i]->c[r]) {
@@ -107,31 +136,27 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr)
}
-NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,
+NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
+ unsigned char Kmimo,
unsigned char Mdlharq,
uint32_t Nsoft,
- uint8_t abstraction_flag,
- NR_DL_FRAME_PARMS *frame_parms,
- nfapi_nr_config_request_t *config)
+ uint8_t abstraction_flag,
+ uint16_t N_RB)
{
NR_gNB_DLSCH_t *dlsch;
unsigned char exit_flag = 0,i,r,aa,layer;
int re;
- unsigned char bw_scaling =1;
- uint16_t N_RB = config->rf_config.dl_carrier_bandwidth.value;
+ uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated
- switch (N_RB) {
+ if (N_RB != 273) {
+ a_segments = a_segments*N_RB;
+ a_segments = a_segments/273;
+ }
- case 106:
- bw_scaling =2;
- break;
-
- default:
- bw_scaling =1;
- break;
- }
+ uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
+
dlsch = (NR_gNB_DLSCH_t *)malloc16(sizeof(NR_gNB_DLSCH_t));
if (dlsch) {
@@ -144,12 +169,12 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,
for (layer=0; layerue_spec_bf_weights[layer] = (int32_t**)malloc16(64*sizeof(int32_t*));
- for (aa=0; aa<64; aa++) {
+ for (aa=0; aa<64; aa++) {
dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
for (re=0;reue_spec_bf_weights[layer][aa][re] = 0x00007fff;
}
- }
+ }
dlsch->txdataF[layer] = (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH/NR_MAX_NB_LAYERS)*sizeof(int32_t)); // NR_MAX_NB_LAYERS is already included in NR_MAX_PDSCH_ENCODED_LENGTH
}
@@ -170,31 +195,31 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,
for (i=0; iharq_processes[i] = (NR_DL_gNB_HARQ_t *)malloc16(sizeof(NR_DL_gNB_HARQ_t));
- LOG_T(PHY, "Required mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p\n",
- MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling,bw_scaling, i,dlsch->harq_processes[i]);
+ LOG_T(PHY, "Required mem size %d dlsch->harq_processes[%d] %p\n",
+ dlsch_bytes, i,dlsch->harq_processes[i]);
if (dlsch->harq_processes[i]) {
bzero(dlsch->harq_processes[i],sizeof(NR_DL_gNB_HARQ_t));
// dlsch->harq_processes[i]->first_tx=1;
- dlsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling);
- dlsch->harq_processes[i]->pdu = (uint8_t*)malloc16(MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling);
+ dlsch->harq_processes[i]->b = (unsigned char*)malloc16(dlsch_bytes);
+ dlsch->harq_processes[i]->pdu = (uint8_t*)malloc16(dlsch_bytes);
if (dlsch->harq_processes[i]->pdu) {
- bzero(dlsch->harq_processes[i]->pdu,MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling);
- nr_emulate_dlsch_payload(dlsch->harq_processes[i]->pdu, (MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling)>>3);
+ bzero(dlsch->harq_processes[i]->pdu,dlsch_bytes);
+ nr_emulate_dlsch_payload(dlsch->harq_processes[i]->pdu, (dlsch_bytes)>>3);
} else {
- printf("Can't allocate PDU\n");
+ LOG_D(PHY,"Can't allocate PDU\n");
exit_flag=1;
}
if (dlsch->harq_processes[i]->b) {
- bzero(dlsch->harq_processes[i]->b,MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling);
+ bzero(dlsch->harq_processes[i]->b,dlsch_bytes);
} else {
- printf("Can't get b\n");
+ LOG_D(PHY,"Can't get b\n");
exit_flag=1;
}
if (abstraction_flag==0) {
- for (r=0; rharq_processes[i]->c[r]) {
bzero(dlsch->harq_processes[i]->c[r],8448);
} else {
- printf("Can't get c\n");
+ LOG_D(PHY,"Can't get c\n");
exit_flag=2;
}
if (dlsch->harq_processes[i]->d[r]) {
bzero(dlsch->harq_processes[i]->d[r],(3*8448));
} else {
- printf("Can't get d\n");
+ LOG_D(PHY,"Can't get d\n");
exit_flag=2;
}
}
+ dlsch->harq_processes[i]->e = (uint8_t*)malloc16(14*N_RB*12*8);
+ if (dlsch->harq_processes[i]->e) {
+ bzero(dlsch->harq_processes[i]->e,14*N_RB*12*8);
+ } else {
+ printf("Can't get e\n");
+ exit_flag=1;
+ }
+ dlsch->harq_processes[i]->f = (uint8_t*)malloc16(14*N_RB*12*8);
+ if (dlsch->harq_processes[i]->f) {
+ bzero(dlsch->harq_processes[i]->f,14*N_RB*12*8);
+ } else {
+ printf("Can't get f\n");
+ exit_flag=1;
+ }
}
} else {
- printf("Can't get harq_p %d\n",i);
+ LOG_D(PHY,"Can't get harq_p %d\n",i);
exit_flag=3;
}
}
@@ -232,7 +271,9 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,
LOG_D(PHY,"new_gNB_dlsch exit flag %d, size of %ld\n",
exit_flag, sizeof(NR_gNB_DLSCH_t));
- free_gNB_dlsch(&dlsch);
+
+ free_gNB_dlsch(&dlsch,N_RB);
+
return(NULL);
@@ -260,7 +301,7 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch)
dlsch->harq_processes[i]->round = 0;
for (j=0; j<96; j++)
- for (r=0; rharq_processes[i]->d[r])
dlsch->harq_processes[i]->d[r][j] = NR_NULL;
@@ -273,59 +314,54 @@ int nr_dlsch_encoding(unsigned char *a,
int frame,
uint8_t slot,
NR_gNB_DLSCH_t *dlsch,
- NR_DL_FRAME_PARMS* frame_parms)
+ NR_DL_FRAME_PARMS* frame_parms,
+ time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput,
+ time_stats_t *dlsch_rate_matching_stats,time_stats_t *dlsch_interleaving_stats,
+ time_stats_t *dlsch_segmentation_stats)
{
unsigned int G;
unsigned int crc=1;
- uint8_t harq_pid = dlsch->harq_ids[frame&2][slot];
+ uint8_t harq_pid = dlsch->harq_ids[frame%2][slot];
AssertFatal(harq_pid<8 && harq_pid>=0,"illegal harq_pid %d\b",harq_pid);
- nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15;
- uint16_t nb_rb = rel15.n_prb;
- uint8_t nb_symb_sch = rel15.nb_symbols;
+ nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->pdsch_pdu.pdsch_pdu_rel15;
+ uint16_t nb_rb = rel15->rbSize;
+ uint8_t nb_symb_sch = rel15->NrOfSymbols;
uint32_t A, Z, Kb, F=0;
uint32_t *Zc = &Z;
- uint8_t mod_order = rel15.modulation_order;
+ uint8_t mod_order = rel15->qamModOrder[0];
uint16_t Kr=0,r;
uint32_t r_offset=0;
- //uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS];
uint8_t BG=1;
uint32_t E;
uint8_t Ilbrm = 1;
uint32_t Tbslbrm = 950984; //max tbs
- uint8_t nb_re_dmrs = rel15.nb_re_dmrs;
- uint16_t R=rel15.coding_rate;
- uint16_t length_dmrs = 1;
+ uint8_t nb_re_dmrs = rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1 ? 6:4;
+ uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
+ uint16_t R=rel15->targetCodeRate[0];
float Coderate = 0.0;
uint8_t Nl = 4;
- /*
- uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; //unsigned char
- for(j=0;jTBSize[0]<<3;
- G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15.nb_layers);
+ G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15->nrOfLayers);
LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order);
// if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
#ifdef DEBUG_DLSCH_CODING
- printf("encoding thinks this is a new packet \n");
+ LOG_D(PHY,"encoding thinks this is a new packet \n");
#endif
- /*
+ /*
int i;
- printf("dlsch (tx): \n");
+ LOG_D(PHY,"dlsch (tx): \n");
for (i=0;i<(A>>3);i++)
- printf("%02x.",a[i]);
- printf("\n");
- */
+ LOG_D(PHY,"%02x\n",a[i]);
+ LOG_D(PHY,"\n");
+ */
if (A > 3824) {
// Add 24-bit crc (polynomial A) to payload
@@ -339,7 +375,7 @@ int nr_dlsch_encoding(unsigned char *a,
dlsch->harq_processes[harq_pid]->B = A+24;
// dlsch->harq_processes[harq_pid]->b = a;
- AssertFatal((A/8)+4 <= MAX_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_DLSCH_PAYLOAD_BYTES);
+ AssertFatal((A/8)+4 <= MAX_NR_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_NR_DLSCH_PAYLOAD_BYTES);
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); // why is this +4 if the CRC is only 3 bytes?
}
@@ -354,7 +390,7 @@ int nr_dlsch_encoding(unsigned char *a,
dlsch->harq_processes[harq_pid]->B = A+16;
// dlsch->harq_processes[harq_pid]->b = a;
- AssertFatal((A/8)+3 <= MAX_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,MAX_DLSCH_PAYLOAD_BYTES);
+ AssertFatal((A/8)+3 <= MAX_NR_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,MAX_NR_DLSCH_PAYLOAD_BYTES);
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+3); // using 3 bytes to mimic the case of 24 bit crc
}
@@ -368,6 +404,7 @@ int nr_dlsch_encoding(unsigned char *a,
else
BG = 1;
+ start_meas(dlsch_segmentation_stats);
Kb = nr_segmentation(dlsch->harq_processes[harq_pid]->b,
dlsch->harq_processes[harq_pid]->c,
dlsch->harq_processes[harq_pid]->B,
@@ -376,7 +413,7 @@ int nr_dlsch_encoding(unsigned char *a,
Zc,
&dlsch->harq_processes[harq_pid]->F,
BG);
-
+ stop_meas(dlsch_segmentation_stats);
F = dlsch->harq_processes[harq_pid]->F;
Kr = dlsch->harq_processes[harq_pid]->K;
@@ -391,13 +428,13 @@ int nr_dlsch_encoding(unsigned char *a,
//d_tmp[r] = &dlsch->harq_processes[harq_pid]->d[r][0];
//channel_input[r] = &dlsch->harq_processes[harq_pid]->d[r][0];
#ifdef DEBUG_DLSCH_CODING
- printf("Encoder: B %d F %d \n",dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->F);
- printf("start ldpc encoder segment %d/%d\n",r,dlsch->harq_processes[harq_pid]->C);
- printf("input %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->c[r][0], dlsch->harq_processes[harq_pid]->c[r][1], dlsch->harq_processes[harq_pid]->c[r][2],dlsch->harq_processes[harq_pid]->c[r][3], dlsch->harq_processes[harq_pid]->c[r][4]);
+ LOG_D(PHY,"Encoder: B %d F %d \n",dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->F);
+ LOG_D(PHY,"start ldpc encoder segment %d/%d\n",r,dlsch->harq_processes[harq_pid]->C);
+ LOG_D(PHY,"input %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->c[r][0], dlsch->harq_processes[harq_pid]->c[r][1], dlsch->harq_processes[harq_pid]->c[r][2],dlsch->harq_processes[harq_pid]->c[r][3], dlsch->harq_processes[harq_pid]->c[r][4]);
for (int cnt =0 ; cnt < 22*(*Zc)/8; cnt ++){
- printf("%d ", dlsch->harq_processes[harq_pid]->c[r][cnt]);
+ LOG_D(PHY,"%d ", dlsch->harq_processes[harq_pid]->c[r][cnt]);
}
- printf("\n");
+ LOG_D(PHY,"\n");
#endif
//ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],*Zc,Kb,Kr,BG,0);
@@ -405,6 +442,11 @@ int nr_dlsch_encoding(unsigned char *a,
}
encoder_implemparams_t impp;
impp.n_segments=dlsch->harq_processes[harq_pid]->C;
+ impp.tprep = tprep;
+ impp.tinput = tinput;
+ impp.tparity = tparity;
+ impp.toutput = toutput;
+
for(int j=0;j<(dlsch->harq_processes[harq_pid]->C/8+1);j++) {
impp.macro_num=j;
nrLDPC_encoder(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,&impp);
@@ -420,34 +462,40 @@ int nr_dlsch_encoding(unsigned char *a,
for (r=0; rharq_processes[harq_pid]->C; r++) {
- if (dlsch->harq_processes[harq_pid]->F>0) {
+ if (F>0) {
for (int k=(Kr-F-2*(*Zc)); kharq_processes[harq_pid]->d[r][k] = NR_NULL;
//if (k<(Kr-F+8))
//printf("r %d filler bits [%d] = %d \n", r,k, dlsch->harq_processes[harq_pid]->d[r][k]);
}
}
-#ifdef DEBUG_DLSCH_CODING
- printf("Rate Matching, Code segment %d (coded bits (G) %u, unpunctured/repeated bits per code segment %d, mod_order %d, nb_rb %d)...\n",
- r,
- G,
- Kr*3,
- mod_order,nb_rb);
-#endif
+
#ifdef DEBUG_DLSCH_CODING
- printf("rvidx in encoding = %d\n", rel15.redundancy_version);
+ LOG_D(PHY,"rvidx in encoding = %d\n", rel15->rvIndex[0]);
#endif
- E = nr_get_E(G, dlsch->harq_processes[harq_pid]->C, mod_order, rel15.nb_layers, r);
+ E = nr_get_E(G, dlsch->harq_processes[harq_pid]->C, mod_order, rel15->nrOfLayers, r);
+
+ //#ifdef DEBUG_DLSCH_CODING
+ LOG_D(PHY,"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb %d)...\n",
+ r,
+ dlsch->harq_processes[harq_pid]->C,
+ G,
+ E,
+ F,
+ Kr-F-2*(*Zc),
+ mod_order,nb_rb);
// for tbslbrm calculation according to 5.4.2.1 of 38.212
- if (rel15.nb_layers < Nl)
- Nl = rel15.nb_layers;
+ if (rel15->nrOfLayers < Nl)
+ Nl = rel15->nrOfLayers;
- Tbslbrm = nr_compute_tbslbrm(rel15.mcs_table,nb_rb,Nl,dlsch->harq_processes[harq_pid]->C);
+ Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl,dlsch->harq_processes[harq_pid]->C);
+ start_meas(dlsch_rate_matching_stats);
nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
BG,
@@ -455,19 +503,22 @@ int nr_dlsch_encoding(unsigned char *a,
dlsch->harq_processes[harq_pid]->d[r],
dlsch->harq_processes[harq_pid]->e+r_offset,
dlsch->harq_processes[harq_pid]->C,
- rel15.redundancy_version,
+ F,
+ Kr-F-2*(*Zc),
+ rel15->rvIndex[0],
E);
-
+ stop_meas(dlsch_rate_matching_stats);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
printf("output ratematching e[%d]= %d r_offset %u\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset);
#endif
- nr_interleaving_ldpc(E,
- mod_order,
- dlsch->harq_processes[harq_pid]->e+r_offset,
- dlsch->harq_processes[harq_pid]->f+r_offset);
-
+ start_meas(dlsch_interleaving_stats);
+ nr_interleaving_ldpc(E,
+ mod_order,
+ dlsch->harq_processes[harq_pid]->e+r_offset,
+ dlsch->harq_processes[harq_pid]->f+r_offset);
+ stop_meas(dlsch_interleaving_stats);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
index a158d5bf62..2e6fc707bd 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
@@ -27,6 +27,7 @@
* \company Eurecom
* \email: desouza@eurecom.fr
* \note
+
* \warning
*/
@@ -46,6 +47,7 @@ uint8_t nr_pdsch_default_time_alloc_C_L[15] = {2,2,2,2,2,4,4,4,4,4,7,12,11,6,6};
/// Time domain allocation routines
+/*
void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config,
nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu) {
@@ -73,9 +75,9 @@ void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config,
case NFAPI_NR_RNTI_RA:
case NFAPI_NR_RNTI_TC:
- /*AssertFatal(dci_alloc.pdcch_params.common_search_space_type == NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1,
- "Invalid common search space type %d for RNTI %d, expected %d\n",dci_alloc.pdcch_params.common_search_space_type,
- NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1, dci_alloc.rnti_type);*/
+ //AssertFatal(dci_alloc.pdcch_params.common_search_space_type == NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1,
+ //"Invalid common search space type %d for RNTI %d, expected %d\n",dci_alloc.pdcch_params.common_search_space_type,
+ //NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1, dci_alloc.rnti_type);
*alloc_type = (alloc_list_flag) ? NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_ALLOC_LIST : NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A;
break;
@@ -94,6 +96,7 @@ void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config,
}
}
+
uint16_t get_SLIV(uint8_t S, uint8_t L) {
return ( (uint16_t)(((L-1)<=7)? (14*(L-1)+S) : (14*(15-L)+(13-S))) );
}
@@ -104,26 +107,26 @@ static inline uint8_t get_K0(uint8_t row_idx, uint8_t time_alloc_type) {
((row_idx==6)||(row_idx==7)||(row_idx==15))? 1 : 0);
}
-/*ideally combine the calculation of L in the same function once the right struct is defined*/
-uint8_t nr_get_S(uint8_t row_idx, uint8_t CP, uint8_t time_alloc_type, uint8_t dmrs_typeA_position) {
+// ideally combine the calculation of L in the same function once the right struct is defined
+uint8_t nr_get_S(uint8_t row_idx, uint8_t CP, uint8_t time_alloc_type, uint8_t dmrs_TypeA_Position) {
uint8_t idx;
//uint8_t S;
switch(time_alloc_type) {
case NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A:
- idx = (row_idx>7)? (row_idx+6) : (((row_idx-1)<<1)-1+((dmrs_typeA_position==2)?0:1));
+ idx = (row_idx>7)? (row_idx+6) : (((row_idx-1)<<1)-1+((dmrs_TypeA_Position==2)?0:1));
return ((CP==NFAPI_CP_NORMAL)?nr_pdsch_default_time_alloc_A_S_nCP[idx] : nr_pdsch_default_time_alloc_A_S_eCP[idx]);
break;
case NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_B:
- idx = (row_idx<14)? (row_idx-1) : (row_idx == 14)? row_idx-1+((dmrs_typeA_position==2)?0:1) : 15;
+ idx = (row_idx<14)? (row_idx-1) : (row_idx == 14)? row_idx-1+((dmrs_TypeA_Position==2)?0:1) : 15;
return (nr_pdsch_default_time_alloc_B_S[idx]);
break;
case NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_C:
AssertFatal((row_idx!=6)&&(row_idx!=7)&&(row_idx<17), "Invalid row index %d in %s %s\n", row_idx, __FUNCTION__, __FILE__);
- idx = (row_idx<6)? (row_idx-1) : (row_idx<14)? (row_idx-3) : (row_idx == 14)? row_idx-3+((dmrs_typeA_position==2)?0:1) : (row_idx-2);
+ idx = (row_idx<6)? (row_idx-1) : (row_idx<14)? (row_idx-3) : (row_idx == 14)? row_idx-3+((dmrs_TypeA_Position==2)?0:1) : (row_idx-2);
break;
default:
@@ -132,16 +135,17 @@ uint8_t nr_get_S(uint8_t row_idx, uint8_t CP, uint8_t time_alloc_type, uint8_t d
return 0; // temp warning fix
}
-void nr_check_time_alloc(uint8_t S, uint8_t L, nfapi_nr_config_request_t config) {
- switch (config.subframe_config.dl_cyclic_prefix_type.value) {
+void nr_check_time_alloc(uint8_t S, uint8_t L,nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15,nfapi_nr_config_request_t *cfg) {
+
+ switch (cfg->subframe_config.dl_cyclic_prefix_type.value) {
case NFAPI_CP_NORMAL:
- if (config.pdsch_config.mapping_type.value == NFAPI_NR_PDSCH_MAPPING_TYPE_A) {
+ if (rel15->mapping_type == NFAPI_NR_PDSCH_MAPPING_TYPE_A) {
AssertFatal(S<4, "Invalid value of S(%d) for mapping type A and normal CP\n", S);
if (S==3)
- AssertFatal(config.pdsch_config.mapping_type.value == 3, "Invalid S %d for dmrs_typeA_position %d\n",
- S, config.pdsch_config.dmrs_typeA_position.value);
+ AssertFatal(rel15->dmrs_TypeA_Position == 3, "Invalid S %d for dmrs_TypeA_Position %d\n",
+ S, rel15->dmrs_TypeA_Position);
AssertFatal((L>2)&&(L<15), "Invalid L %d for mapping type A and normal CP\n", L);
@@ -157,12 +161,12 @@ void nr_check_time_alloc(uint8_t S, uint8_t L, nfapi_nr_config_request_t config)
break;
case NFAPI_CP_EXTENDED:
- if (config.pdsch_config.mapping_type.value == NFAPI_NR_PDSCH_MAPPING_TYPE_A) {
+ if (rel15->mapping_type == NFAPI_NR_PDSCH_MAPPING_TYPE_A) {
AssertFatal(S<4, "Invalid value of S(%d) for mapping type A and extended CP\n", S);
if (S==3)
- AssertFatal(config.pdsch_config.dmrs_typeA_position.value == 3, "Invalid S %d for dmrs_typeA_position %d\n",
- S, config.pdsch_config.dmrs_typeA_position.value);
+ AssertFatal(rel15->dmrs_TypeA_Position == 3, "Invalid S %d for dmrs_TypeA_Position %d\n",
+ S, rel15->dmrs_TypeA_Position);
AssertFatal((L>2)&&(L<13), "Invalid L %d for mapping type A and extended CP\n", L);
@@ -241,6 +245,7 @@ void nr_get_PRG_parms(NR_BWP_PARMS* bwp, NR_gNB_DCI_ALLOC_t dci_alloc, uint8_t p
LOG_I(PHY, "PRG parameters for BWP %d location %d N_RB %d:\n", bwp->bwp_id, bwp->location, bwp->N_RB);
LOG_I(PHY, "P_prime %d\t start size %d\t endsize %d\t N_PRG %d\n", prg_parms->P_prime, prg_parms->start_size, prg_parms->end_size, prg_parms->N_PRG);
}
+*/
/// Payload emulation
void nr_emulate_dlsch_payload(uint8_t* pdu, uint16_t size) {
@@ -292,10 +297,10 @@ int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
void nr_fill_dlsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
- nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
+ nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint8_t *sdu) {
- nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch_pdu->dlsch_pdu_rel15;
+ nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &pdsch_pdu->pdsch_pdu_rel15;
int dlsch_id = find_nr_dlsch(rel15->rnti,gNB,SEARCH_EXIST);
AssertFatal( (dlsch_id>=0) && (dlsch_iddlsch[dlsch_id][0];
NR_DL_gNB_HARQ_t **harq = dlsch->harq_processes;
/// DLSCH struct
- memcpy((void*)&harq[dlsch->harq_ids[frame%2][slot]]->dlsch_pdu, (void*)dlsch_pdu, sizeof(nfapi_nr_dl_config_dlsch_pdu));
+ memcpy((void*)&harq[dlsch->harq_ids[frame%2][slot]]->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu));
+ gNB->num_pdsch_rnti++;
AssertFatal(sdu!=NULL,"sdu is null\n");
harq[dlsch->harq_ids[frame%2][slot]]->pdu = sdu;
@@ -327,23 +333,9 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB,
ulsch->harq_mask |= 1<harq_process_id[slot] = harq_pid;
- nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch->harq_processes[harq_pid]->ulsch_pdu;
+ memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t));
LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid);
-
-
- //FK this is still a bad hack. We need to replace the L1 FAPI structures with the new scf ones as well.
- rel15_ul->rnti = ulsch_pdu->rnti;
- rel15_ul->ulsch_pdu_rel15.start_rb = ulsch_pdu->rb_start;
- rel15_ul->ulsch_pdu_rel15.number_rbs = ulsch_pdu->rb_size;
- rel15_ul->ulsch_pdu_rel15.start_symbol = ulsch_pdu->start_symbol_index;
- rel15_ul->ulsch_pdu_rel15.number_symbols = ulsch_pdu->nr_of_symbols;
- rel15_ul->ulsch_pdu_rel15.length_dmrs = gNB->pusch_config.dmrs_UplinkConfig.pusch_maxLength;
- rel15_ul->ulsch_pdu_rel15.Qm = ulsch_pdu->qam_mod_order;
- rel15_ul->ulsch_pdu_rel15.mcs = ulsch_pdu->mcs_index;
- rel15_ul->ulsch_pdu_rel15.rv = ulsch_pdu->pusch_data.rv_index;
- rel15_ul->ulsch_pdu_rel15.n_layers = ulsch_pdu->nrOfLayers;
- rel15_ul->ulsch_pdu_rel15.R = ulsch_pdu->target_code_rate;
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
index af83c17fc1..b6a4787193 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
@@ -50,13 +50,13 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
- nfapi_nr_config_request_t *config,
+ nfapi_nr_config_request_scf_t *config,
NR_DL_FRAME_PARMS *frame_parms) {
int k,l;
//int16_t a;
int16_t mod_dmrs[NR_PBCH_DMRS_LENGTH<<1];
uint8_t idx=0;
- uint8_t nushift = config->sch_config.physical_cell_id.value &3;
+ uint8_t nushift = config->cell_config.phy_cell_id.value &3;
LOG_D(PHY, "PBCH DMRS mapping started at symbol %d shift %d\n", ssb_start_symbol+1, nushift);
/// QPSK modulation
@@ -220,16 +220,14 @@ void nr_init_pbch_interleaver(uint8_t *interleaver) {
}
int nr_generate_pbch(NR_gNB_PBCH *pbch,
- uint8_t *pbch_pdu,
+ nfapi_nr_dl_tti_ssb_pdu *ssb_pdu,
uint8_t *interleaver,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
uint8_t n_hf,
- uint8_t Lmax,
- uint8_t ssb_index,
int sfn,
- nfapi_nr_config_request_t *config,
+ nfapi_nr_config_request_scf_t *config,
NR_DL_FRAME_PARMS *frame_parms) {
int k,l,m;
//int16_t a;
@@ -243,17 +241,18 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
///Payload generation
memset((void *)pbch, 0, sizeof(NR_gNB_PBCH));
pbch->pbch_a=0;
-
+ uint8_t ssb_index = frame_parms->ssb_index;
+ uint8_t *pbch_pdu = (uint8_t*)&ssb_pdu->ssb_pdu_rel15.bchPayload;
+ uint8_t Lmax = frame_parms->Lmax;
for (int i=0; ipbch_a |= ((pbch_pdu[2-(i>>3)]>>(7-(i&7)))&1)<pbch_a |= ((pbch_pdu[i>>3]>>(7-(i&7)))&1)<pbch_a);
-#endif
+ #endif
// Extra byte generation
for (int i=0; i<4; i++)
@@ -265,7 +264,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
for (int i=0; i<3; i++)
pbch->pbch_a |= ((ssb_index>>(5-i))&1)<<(29+i); // resp. 6th, 5th and 4th bits of ssb_index
else
- pbch->pbch_a |= ((config->sch_config.ssb_subcarrier_offset.value>>4)&1)<<29; //MSB of k_SSB (bit index 4)
+ pbch->pbch_a |= ((config->ssb_table.ssb_subcarrier_offset.value>>4)&1)<<29; //MSB of k_SSB (bit index 4)
LOG_D(PHY,"After extra byte: pbch_a = 0x%08x\n",pbch->pbch_a);
@@ -287,7 +286,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
nushift = (((sfn>>2)&1)<<1) ^ ((sfn>>1)&1);
pbch->pbch_a_prime = 0;
- nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, 0, unscrambling_mask);
+ nr_pbch_scrambling(pbch, (uint32_t)config->cell_config.phy_cell_id.value, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, 0, unscrambling_mask);
#ifdef DEBUG_PBCH_ENCODING
printf("Payload scrambling: nushift %d M %d sfn3 %d sfn2 %d\n", nushift, M, (sfn>>2)&1, (sfn>>1)&1);
printf("pbch_a_prime: 0x%08x\n", pbch->pbch_a_prime);
@@ -299,7 +298,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
/// CRC, coding and rate matching
polar_encoder_fast (&a_reversed, (uint32_t *)pbch->pbch_e, 0, 0,
- nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL)
+ nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL,0,NULL)
);
#ifdef DEBUG_PBCH_ENCODING
printf("Channel coding:\n");
@@ -312,7 +311,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
/// Scrambling
M = NR_POLAR_PBCH_E;
nushift = (Lmax==4)? ssb_index&3 : ssb_index&7;
- nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 1, 0);
+ nr_pbch_scrambling(pbch, (uint32_t)config->cell_config.phy_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 1, 0);
#ifdef DEBUG_PBCH_ENCODING
printf("Scrambling:\n");
@@ -333,7 +332,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
}
/// Resource mapping
- nushift = config->sch_config.physical_cell_id.value &3;
+ nushift = config->cell_config.phy_cell_id.value &3;
// PBCH modulated symbols are mapped within the SSB block on symbols 1, 2, 3 excluding the subcarriers used for the PBCH DMRS
///symbol 1 [0:239] -- 180 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c
new file mode 100644
index 0000000000..5710499e1a
--- /dev/null
+++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c
@@ -0,0 +1,650 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+/*! \file PHY/NR_TRANSPORT/nr_prach.c
+ * \brief Top-level routines for generating and decoding the PRACH physical channel V15.4 2018-12
+ * \author R. Knopp
+ * \date 2019
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr
+ * \note
+ * \warning
+ */
+
+#include "PHY/defs_gNB.h"
+#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto_common.h"
+
+extern uint16_t NCS_unrestricted_delta_f_RA_125[16];
+extern uint16_t NCS_restricted_TypeA_delta_f_RA_125[15];
+extern uint16_t NCS_restricted_TypeB_delta_f_RA_125[13];
+extern uint16_t NCS_unrestricted_delta_f_RA_5[16];
+extern uint16_t NCS_restricted_TypeA_delta_f_RA_5[16];
+extern uint16_t NCS_restricted_TypeB_delta_f_RA_5[14];
+extern uint16_t NCS_unrestricted_delta_f_RA_15[16];
+extern uint16_t prach_root_sequence_map_0_3[838];
+extern uint16_t prach_root_sequence_map_abc[138];
+extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
+extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
+extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10];
+extern uint16_t nr_du[838];
+extern int16_t nr_ru[2*839];
+
+void rx_nr_prach_ru(RU_t *ru,
+ int frame,
+ int subframe) {
+
+ AssertFatal(ru!=NULL,"ru is null\n");
+
+ int16_t **rxsigF=NULL;
+ NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms;
+ int16_t prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
+ int16_t *prach[ru->nb_rx];
+ uint8_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,fp->frame_type,fp->freq_range);
+
+ rxsigF = ru->prach_rxsigF;
+
+ AssertFatal(ru->if_south == LOCAL_RF,"we shouldn't call this if if_south != LOCAL_RF\n");
+ for (int aa=0; aanb_rx; aa++)
+ prach[aa] = (int16_t*)&ru->common.rxdata[aa][(subframe*fp->samples_per_subframe)-ru->N_TA_offset];
+
+
+
+ int mu = fp->numerology_index;
+ int Ncp;
+ int16_t *prach2;
+
+
+ switch (prach_fmt) {
+ case 0:
+ Ncp = 3168;
+ break;
+
+ case 1:
+ Ncp = 21024;
+ break;
+
+ case 2:
+ Ncp = 4688;
+ break;
+
+ case 3:
+ Ncp = 3168;
+ break;
+
+ case 0xa1:
+ Ncp = 288/(1<N_RB_UL, ru->nb_rx, Ncp);
+ }
+ AssertFatal(mu==1,"only 30 kHz SCS handled for now\n");
+
+ // Note: Assumes PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below
+ int kbar = 1;
+ int K = 24;
+ if (prach_fmt == 3) {
+ K=4;
+ kbar=10;
+ }
+ else if (prach_fmt > 3) {
+ // Note: Assumes that PRACH SCS is same as PUSCH SCS
+ K=1;
+ kbar=2;
+ }
+ int n_ra_prb = fp->prach_config_common.prach_ConfigInfo.msg1_frequencystart;
+ int k = (12*n_ra_prb) - 6*fp->N_RB_UL;
+
+ int N_ZC = (prach_fmt<4)?839:139;
+
+ if (k<0) k+=(fp->ofdm_symbol_size);
+
+ k*=K;
+ k+=kbar;
+ int reps=1;
+ int dftlen=0;
+
+ for (int aa=0; aanb_rx; aa++) {
+ AssertFatal(prach[aa]!=NULL,"prach[%d] is null\n",aa);
+
+
+ // do DFT
+ if (fp->N_RB_UL <= 100)
+ AssertFatal(1==0,"N_RB_UL %d not support for NR PRACH yet\n",fp->N_RB_UL);
+ else if (fp->N_RB_UL < 137) {
+ if (fp->threequarter_fs==0) {
+ //40 MHz @ 61.44 Ms/s
+ //50 MHz @ 61.44 Ms/s
+ prach2 = prach[aa] + (Ncp<<2);
+ if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2)
+ dft49152(prach2,rxsigF[aa],1);
+ if (prach_fmt == 1 || prach_fmt == 2) {
+ dft49152(prach2+98304,rxsigF[aa]+98304,1);
+ reps++;
+ }
+ if (prach_fmt == 2) {
+ dft49152(prach2+(98304*2),rxsigF[aa]+(98304*2),1);
+ dft49152(prach2+(98304*3),rxsigF[aa]+(98304*3),1);
+ reps+=2;
+ }
+ if (prach_fmt == 3) {
+ for (int i=0;i<4;i++) dft12288(prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1);
+ reps=4;
+ }
+ if (prach_fmt >3) {
+ dft2048(prach2,rxsigF[aa],1);
+ if (prach_fmt != 0xc0) {
+ dft2048(prach2+4096,rxsigF[aa]+4096,1);
+ reps++;
+ }
+ }
+ if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {
+ dft2048(prach2+4096*2,rxsigF[aa]+4096*2,1);
+ dft2048(prach2+4096*3,rxsigF[aa]+4096*3,1);
+ reps+=2;
+ }
+ if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {
+ dft2048(prach2+4096*4,rxsigF[aa]+4096*4,1);
+ dft2048(prach2+4096*5,rxsigF[aa]+4096*5,1);
+ reps+=2;
+ }
+ if (prach_fmt == 0xc2) {
+ for (int i=6;i<11;i++) dft2048(prach2+(3072*i),rxsigF[aa]+(3072*i),1);
+ reps+=6;
+ }
+ } else {
+ // 40 MHz @ 46.08 Ms/s
+ prach2 = prach[aa] + (3*Ncp);
+ AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n");
+ if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) {
+ dft36864(prach2,rxsigF[aa],1);
+ reps++;
+ }
+ if (prach_fmt == 1 || prach_fmt == 2) {
+ dft36864(prach2+73728,rxsigF[aa]+73728,1);
+ reps++;
+ }
+ if (prach_fmt == 2) {
+ dft36864(prach2+(98304*2),rxsigF[aa]+(98304*2),1);
+ dft36864(prach2+(98304*3),rxsigF[aa]+(98304*3),1);
+ reps+=2;
+ }
+ if (prach_fmt == 3) {
+ for (int i=0;i<4;i++) dft9216(prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1);
+ reps=4;
+ }
+ if (prach_fmt >3) {
+ dft1536(prach2,rxsigF[aa],1);
+ if (prach_fmt != 0xc0) {
+ dft1536(prach2+3072,rxsigF[aa]+3072,1);
+ reps++;
+ }
+ }
+ if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {
+ dft1536(prach2+3072*2,rxsigF[aa]+3072*2,1);
+ dft1536(prach2+3072*3,rxsigF[aa]+3072*3,1);
+ reps+=2;
+ }
+ if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {
+ dft1536(prach2+3072*4,rxsigF[aa]+3072*4,1);
+ dft1536(prach2+3072*5,rxsigF[aa]+3072*5,1);
+ reps+=2;
+ }
+ if (prach_fmt == 0xc2) {
+ for (int i=6;i<11;i++) dft1536(prach2+(3072*i),rxsigF[aa]+(3072*i),1);
+ reps+=6;
+ }
+ }
+ }
+ else if (fp->N_RB_UL <= 273) {
+ if (fp->threequarter_fs==0) {
+ prach2 = prach[aa] + (Ncp<<3);
+ dftlen=98304;
+ //80,90,100 MHz @ 61.44 Ms/s
+ if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2)
+ dft98304(prach2,rxsigF[aa],1);
+ if (prach_fmt == 1 || prach_fmt == 2) {
+ dft98304(prach2+196608,rxsigF[aa]+196608,1);
+ reps++;
+ }
+ if (prach_fmt == 1 || prach_fmt == 2) {
+ dft98304(prach2+196608,rxsigF[aa]+196608,1);
+ dft98304(prach2+(196608*2),rxsigF[aa]+(196608*2),1);
+ reps+=2;
+ }
+ if (prach_fmt == 3) {
+ dft24576(prach2+(2*49152),rxsigF[aa]+(2*49152),1);
+ reps=4;
+ dftlen=24576;
+ }
+ if (prach_fmt >3) {
+ dftlen=4096;
+ dft4096(prach2,rxsigF[aa],1);
+ if (prach_fmt != 0xc0) {
+ dft4096(prach2+8192,rxsigF[aa]+8192,1);
+ reps++;
+ }
+ }
+ if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {
+ dft4096(prach2+8192*2,rxsigF[aa]+8192*2,1);
+ dft4096(prach2+8192*3,rxsigF[aa]+8192*3,1);
+ reps+=2;
+ }
+ if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {
+ dft4096(prach2+8192*4,rxsigF[aa]+8192*4,1);
+ dft4096(prach2+8192*5,rxsigF[aa]+8192*5,1);
+ reps+=2;
+ }
+ if (prach_fmt == 0xc2) {
+ for (int i=6;i<11;i++) dft4096(prach2+(8192*i),rxsigF[aa]+(8192*i),1);
+ reps+=6;
+ }
+ } else {
+ AssertFatal(fp->N_RB_UL <= 217,"cannot do more than 217 PRBs with 3/4 sampling\n");
+ prach2 = prach[aa] + (6*Ncp);
+ // 80 MHz @ 46.08 Ms/s
+ dftlen=73728;
+ if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) {
+ dft73728(prach2,rxsigF[aa],1);
+ reps++;
+ }
+ if (prach_fmt == 1 || prach_fmt == 2) {
+ dft73728(prach2+(2*73728),rxsigF[aa]+(2*73728),1);
+ reps++;
+ }
+ if (prach_fmt == 3) {
+ dft73728(prach2+(4*73728),rxsigF[aa]+(4*73728),1);
+ reps=4;
+ dftlen=18432;
+ }
+
+ if (prach_fmt >3) {
+ dftlen=3072;
+ dft3072(prach2,rxsigF[aa],1);
+ if (prach_fmt != 0xc0) {
+ dft3072(prach2+6144,rxsigF[aa]+6144,1);
+ reps++;
+ }
+ }
+ if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {
+ dft3072(prach2+6144*2,rxsigF[aa]+6144*2,1);
+ dft3072(prach2+6144*3,rxsigF[aa]+6144*3,1);
+ reps+=2;
+ }
+ if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {
+ dft3072(prach2+6144*4,rxsigF[aa]+6144*4,1);
+ dft3072(prach2+6144*5,rxsigF[aa]+6144*5,1);
+ reps+=2;
+ }
+ if (prach_fmt == 0xc2) {
+ for (int i=6;i<11;i++) dft3072(prach2+(6144*i),rxsigF[aa]+(6144*i),1);
+ reps+=6;
+ }
+ }
+ }
+
+ //Coherent combining of PRACH repetitions (assumes channel does not change, to be revisted for "long" PRACH)
+ int16_t rxsigF_tmp[N_ZC<<1];
+ // if (k+N_ZC > dftlen) { // PRACH signal is split around DC
+ int16_t *rxsigF2=rxsigF[aa];
+ int k2=k<<1;
+
+ for (int j=0;jprach_vars.rxsigF;
+
+ uint8_t preamble_index;
+ uint16_t NCS=99,NCS2;
+ uint16_t preamble_offset=0,preamble_offset_old;
+ int16_t preamble_shift=0;
+ uint32_t preamble_shift2;
+ uint16_t preamble_index0=0,n_shift_ra=0,n_shift_ra_bar;
+ uint16_t d_start=0;
+ uint16_t numshift=0;
+ uint16_t *prach_root_sequence_map;
+ uint8_t not_found;
+ uint16_t u;
+ int16_t *Xu=0;
+ uint16_t offset;
+ uint16_t first_nonzero_root_idx=0;
+ uint8_t new_dft=0;
+ uint8_t aa;
+ int32_t lev;
+ int16_t levdB;
+ int log2_ifft_size=10;
+ int16_t prach_ifft_tmp[2048*2] __attribute__((aligned(32)));
+ int32_t *prach_ifft=(int32_t*)NULL;
+
+ nr_frequency_range_e freq_range;
+
+ AssertFatal(gNB!=NULL,"Can only be called from gNB\n");
+ fp = &gNB->frame_parms;
+ nb_rx = fp->nb_antennas_rx;
+
+ frame_type = fp->frame_type;
+ freq_range = fp->freq_range;
+ rootSequenceIndex = fp->prach_config_common.rootSequenceIndex;
+ prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
+ Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
+ restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag;
+
+
+ uint8_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,frame_type,freq_range);
+ uint16_t N_ZC = (prach_fmt <4)?839:139;
+
+ AssertFatal(gNB!=NULL,"gNB is null\n");
+
+ prach_ifft = gNB->prach_vars.prach_ifft;
+ prachF = gNB->prach_vars.prachF;
+ if (LOG_DEBUGFLAG(PRACH)){
+ if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for subframe %d, msg1_frequencystart %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,fp->prach_config_common.prach_ConfigInfo.msg1_frequencystart,prach_ConfigIndex,rootSequenceIndex);
+ }
+
+
+
+
+
+
+ int restricted_Type = 0; //this is hardcoded ('0' for restricted_TypeA; and '1' for restricted_TypeB). FIXME
+ if (prach_fmt<3){
+ if (restricted_set == 0) {
+ NCS = NCS_unrestricted_delta_f_RA_125[Ncs_config];
+ } else {
+ if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_125[Ncs_config]; // for TypeA, this is hardcoded. FIXME
+ if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_125[Ncs_config]; // for TypeB, this is hardcoded. FIXME
+ }
+ }
+ if (prach_fmt==3){
+ if (restricted_set == 0) {
+ NCS = NCS_unrestricted_delta_f_RA_5[Ncs_config];
+ } else {
+ if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_5[Ncs_config]; // for TypeA, this is hardcoded. FIXME
+ if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_5[Ncs_config]; // for TypeB, this is hardcoded. FIXME
+ }
+ }
+ if (prach_fmt>3){
+ NCS = NCS_unrestricted_delta_f_RA_15[Ncs_config];
+ }
+
+ AssertFatal(NCS!=99,"NCS has not been set\n");
+
+ if (gNB) start_meas(&gNB->rx_prach);
+
+
+ prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
+
+ // PDP is oversampled, e.g. 1024 sample instead of 839
+ // Adapt the NCS (zero-correlation zones) with oversampling factor e.g. 1024/839
+ NCS2 = (N_ZC==839) ? ((NCS<<10)/839) : ((NCS<<8)/139);
+
+ if (NCS2==0) NCS2 = N_ZC;
+
+
+ preamble_offset_old = 99;
+
+
+ *max_preamble_energy=0;
+ for (preamble_index=0 ; preamble_index<64 ; preamble_index++) {
+
+ if (LOG_DEBUGFLAG(PRACH)){
+ int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],(N_ZC==839) ? 840: 140));
+ if (en>60) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d \n",frame,subframe,preamble_index);
+ }
+ if (restricted_set == 0) {
+ // This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
+ preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS)));
+
+ if (preamble_offset != preamble_offset_old) {
+ preamble_offset_old = preamble_offset;
+ new_dft = 1;
+ // This is the \nu corresponding to the preamble index
+ preamble_shift = 0;
+ }
+
+ else {
+ preamble_shift -= NCS;
+
+ if (preamble_shift < 0)
+ preamble_shift+=N_ZC;
+ }
+ } else { // This is the high-speed case
+ new_dft = 0;
+
+ // set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this
+ // preamble index and find the corresponding cyclic shift
+ // Check if all shifts for that root have been processed
+ if (preamble_index0 == numshift) {
+ not_found = 1;
+ new_dft = 1;
+ preamble_index0 -= numshift;
+ (preamble_offset==0 && numshift==0) ? (preamble_offset) : (preamble_offset++);
+
+ while (not_found == 1) {
+ // current root depending on rootSequenceIndex
+ int index = (rootSequenceIndex + preamble_offset) % N_ZC;
+
+ if (prach_fmt<4) {
+ // prach_root_sequence_map points to prach_root_sequence_map0_3
+ DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) );
+ } else {
+ // prach_root_sequence_map points to prach_root_sequence_map4
+ DevAssert( index < sizeof(prach_root_sequence_map_abc) / sizeof(prach_root_sequence_map_abc[0]) );
+ }
+ u = prach_root_sequence_map[index];
+
+ uint16_t n_group_ra = 0;
+
+ if ( (nr_du[u]<(N_ZC/3)) && (nr_du[u]>=NCS) ) {
+ n_shift_ra = nr_du[u]/NCS;
+ d_start = (nr_du[u]<<1) + (n_shift_ra * NCS);
+ n_group_ra = N_ZC/d_start;
+ n_shift_ra_bar = max(0,(N_ZC-(nr_du[u]<<1)-(n_group_ra*d_start))/N_ZC);
+ } else if ( (nr_du[u]>=(N_ZC/3)) && (nr_du[u]<=((N_ZC - NCS)>>1)) ) {
+ n_shift_ra = (N_ZC - (nr_du[u]<<1))/NCS;
+ d_start = N_ZC - (nr_du[u]<<1) + (n_shift_ra * NCS);
+ n_group_ra = nr_du[u]/d_start;
+ n_shift_ra_bar = min(n_shift_ra,max(0,(nr_du[u]- (n_group_ra*d_start))/NCS));
+ } else {
+ n_shift_ra = 0;
+ n_shift_ra_bar = 0;
+ }
+
+ // This is the number of cyclic shifts for the current root u
+ numshift = (n_shift_ra*n_group_ra) + n_shift_ra_bar;
+ // skip to next root and recompute parameters if numshift==0
+ (numshift>0) ? (not_found = 0) : (preamble_offset++);
+ }
+ }
+
+
+ if (n_shift_ra>0)
+ preamble_shift = -((d_start * (preamble_index0/n_shift_ra)) + ((preamble_index0%n_shift_ra)*NCS)); // minus because the channel is h(t -\tau + Cv)
+ else
+ preamble_shift = 0;
+
+ if (preamble_shift < 0)
+ preamble_shift+=N_ZC;
+
+ preamble_index0++;
+
+ if (preamble_index == 0)
+ first_nonzero_root_idx = preamble_offset;
+ }
+
+ // Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex
+ if (LOG_DEBUGFLAG(PRACH)) {
+ int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840));
+ if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d, NCS %d, NCS_config %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n",
+ frame,subframe,preamble_index,NCS,Ncs_config,N_ZC/NCS,preamble_offset,preamble_shift,en);
+ }
+
+ if (new_dft == 1) {
+ new_dft = 0;
+
+ Xu=(int16_t*)gNB->X_u[preamble_offset-first_nonzero_root_idx];
+ memset(prach_ifft,0,((N_ZC==839) ? 2048 : 256)*sizeof(int32_t));
+
+
+ memset(prachF, 0, sizeof(int16_t)*2*1024 );
+ if (LOG_DUMPFLAG(PRACH)) {
+ LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1);
+ LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1);
+ }
+
+ for (aa=0;aa>15);
+ prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset+1] - (int32_t)Xu[offset+1]*rxsigF[aa][offset])>>15);
+ }
+
+ // Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
+ if (N_ZC == 839) {
+ log2_ifft_size = 10;
+ idft1024(prachF,prach_ifft_tmp,1);
+ // compute energy and accumulate over receive antennas
+ for (i=0;i<2048;i++)
+ prach_ifft[i] += (prach_ifft_tmp[i<<1]*prach_ifft_tmp[i<<1] + prach_ifft_tmp[1+(i<<1)]*prach_ifft_tmp[1+(i<<1)])>>10;
+ } else {
+ idft256(prachF,prach_ifft_tmp,1);
+ log2_ifft_size = 8;
+ // compute energy and accumulate over receive antennas and repetitions for BR
+ for (i=0;i<256;i++)
+ prach_ifft[i] += (prach_ifft_tmp[i<<1]*prach_ifft_tmp[(i<<1)] + prach_ifft_tmp[1+(i<<1)]*prach_ifft_tmp[1+(i<<1)])>>10;
+ }
+
+ if (LOG_DUMPFLAG(PRACH)) {
+ if (aa==0) LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
+ if (aa==1) LOG_M("prach_rxF_comp1.m","prach_rxF_comp1",prachF,1024,1,1);
+ }
+ }// antennas_rx
+ } // new dft
+
+ // check energy in nth time shift, for
+
+ preamble_shift2 = ((preamble_shift==0) ? 0 : ((preamble_shift<*max_preamble_energy) {
+ *max_preamble_energy = levdB;
+ *max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate
+ *max_preamble = preamble_index;
+ }
+ }
+ }// preamble_index
+
+ if (LOG_DUMPFLAG(PRACH)) {
+ int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840));
+ if (en>60) {
+ int k = (12*n_ra_prb) - 6*fp->N_RB_UL;
+
+ if (k<0) k+=fp->ofdm_symbol_size;
+
+ k*=12;
+ k+=13;
+ k*=2;
+
+
+ LOG_M("rxsigF.m","prach_rxF",&rxsigF[0][0],12288,1,1);
+ LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
+ LOG_M("Xu.m","xu",Xu,N_ZC,1,1);
+ LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1);
+ }
+ } /* LOG_DUMPFLAG(PRACH) */
+ if (gNB) stop_meas(&gNB->rx_prach);
+
+}
+
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.h b/openair1/PHY/NR_TRANSPORT/nr_prach.h
similarity index 100%
rename from openair1/PHY/NR_UE_TRANSPORT/nr_prach.h
rename to openair1/PHY/NR_TRANSPORT/nr_prach.h
diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c
new file mode 100644
index 0000000000..e1b80a87a2
--- /dev/null
+++ b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c
@@ -0,0 +1,370 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+/*! \file PHY/LTE_TRANSPORT/prach_common.c
+ * \brief Common routines for NR UE/gNB PRACH physical channel V15.4 2019-03
+ * \author R. Knopp
+ * \date 2019
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr
+ * \note
+ * \warning
+ */
+#include "PHY/sse_intrin.h"
+#include "common/utils/LOG/vcd_signal_dumper.h"
+#include "PHY/impl_defs_nr.h"
+#include "PHY/defs_nr_UE.h"
+#include "PHY/NR_TRANSPORT/nr_prach.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto_common.h"
+#include "common/utils/LOG/log.h"
+#include "common/utils/LOG/vcd_signal_dumper.h"
+
+#include "T.h"
+
+void init_nr_prach_tables(int N_ZC);
+
+void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe) {
+
+ FILE *fd;
+
+ fd = fopen("prach_config.txt","w");
+ fprintf(fd,"prach_config: subframe = %d\n",subframe);
+ fprintf(fd,"prach_config: N_RB_UL = %d\n",frame_parms->N_RB_UL);
+ fprintf(fd,"prach_config: frame_type = %s\n",(frame_parms->frame_type==1) ? "TDD":"FDD");
+
+ if (frame_parms->frame_type==TDD) {
+ fprintf(fd,"prach_config: p_tdd_UL_DL_Configuration.referenceSCS = %d\n",frame_parms->p_tdd_UL_DL_Configuration->referenceSubcarrierSpacing);
+ fprintf(fd,"prach_config: p_tdd_UL_DL_Configuration.dl_UL_TransmissionPeriodicity = %d\n",frame_parms->p_tdd_UL_DL_Configuration->dl_UL_TransmissionPeriodicity);
+ fprintf(fd,"prach_config: p_tdd_UL_DL_Configuration.nrofDownlinkSlots = %d\n",frame_parms->p_tdd_UL_DL_Configuration->nrofDownlinkSlots);
+ fprintf(fd,"prach_config: p_tdd_UL_DL_Configuration.nrofDownlinkSymbols = %d\n",frame_parms->p_tdd_UL_DL_Configuration->nrofDownlinkSymbols);
+ fprintf(fd,"prach_config: p_tdd_UL_DL_Configuration.nrofUownlinkSlots = %d\n",frame_parms->p_tdd_UL_DL_Configuration->nrofDownlinkSlots);
+ fprintf(fd,"prach_config: p_tdd_UL_DL_Configuration.nrofUownlinkSymbols = %d\n",frame_parms->p_tdd_UL_DL_Configuration->nrofDownlinkSymbols);
+ if (frame_parms->p_tdd_UL_DL_Configuration->p_next) {
+ fprintf(fd,"prach_config: p_tdd_UL_DL_Configuration.referenceSCS2 = %d\n",frame_parms->p_tdd_UL_DL_Configuration->p_next->referenceSubcarrierSpacing);
+ fprintf(fd,"prach_config: p_tdd_UL_DL_Configuration.dl_UL_TransmissionPeriodicity2 = %d\n",frame_parms->p_tdd_UL_DL_Configuration->p_next->dl_UL_TransmissionPeriodicity);
+ fprintf(fd,"prach_config: p_tdd_UL_DL_Configuration.nrofDownlinkSlots2 = %d\n",frame_parms->p_tdd_UL_DL_Configuration->p_next->nrofDownlinkSlots);
+ fprintf(fd,"prach_config: p_tdd_UL_DL_Configuration.nrofDownlinkSymbols2 = %d\n",frame_parms->p_tdd_UL_DL_Configuration->p_next->nrofDownlinkSymbols);
+ fprintf(fd,"prach_config: p_tdd_UL_DL_Configuration.nrofUownlinkSlots2 = %d\n",frame_parms->p_tdd_UL_DL_Configuration->p_next->nrofDownlinkSlots);
+ fprintf(fd,"prach_config: p_tdd_UL_DL_Configuration.nrofUownlinkSymbols2 = %d\n",frame_parms->p_tdd_UL_DL_Configuration->p_next->nrofDownlinkSymbols);
+
+ }
+ }
+
+ fprintf(fd,"prach_config: rootSequenceIndex = %d\n",frame_parms->prach_config_common.rootSequenceIndex);
+ fprintf(fd,"prach_config: prach_ConfigIndex = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex);
+ fprintf(fd,"prach_config: Ncs_config = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig);
+ fprintf(fd,"prach_config: highSpeedFlag = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.highSpeedFlag);
+ fprintf(fd,"prach_config: n_ra_prboffset = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.msg1_frequencystart);
+ fclose(fd);
+
+}
+
+// This function computes the du
+void nr_fill_du(uint8_t prach_fmt)
+{
+
+ uint16_t iu,u,p;
+ uint16_t N_ZC;
+ uint16_t *prach_root_sequence_map;
+
+ if (prach_fmt<4) {
+ N_ZC = 839;
+ prach_root_sequence_map = prach_root_sequence_map_0_3;
+ } else {
+ N_ZC = 139;
+ prach_root_sequence_map = prach_root_sequence_map_abc;
+ }
+
+ for (iu=0; iu<(N_ZC-1); iu++) {
+
+ u=prach_root_sequence_map[iu];
+ p=1;
+
+ while (((u*p)%N_ZC)!=1)
+ p++;
+
+ nr_du[u] = ((p<(N_ZC>>1)) ? p : (N_ZC-p));
+ }
+
+}
+
+int is_nr_prach_subframe(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe) {
+
+ uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
+ /*
+ // For FR1 paired
+ if (((frame%table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][2]) == table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][3]) &&
+ ((table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][4]&(1<slots_per_subframe;
+ // when were in the last slot of the subframe and this is a PRACH subframe ,return 1
+ if (((slot%fp->slots_per_subframe) == fp->slots_per_subframe-1)&&
+ (is_nr_prach_subframe(fp,frame,subframe))) return (1);
+ else return(0);
+}
+
+uint16_t get_nr_prach_fmt(int prach_ConfigIndex,lte_frame_type_t frame_type, nr_frequency_range_e fr)
+{
+
+ if (frame_type==FDD) return (table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][0]); // if using table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink
+ else if (fr==nr_FR1) return (table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][0]); // if using table 6.3.3.2-3: Random access configurations for FR1 and unpaired spectrum
+ else AssertFatal(1==0,"FR2 prach configuration not supported yet\n");
+ // For FR2 not implemented. FIXME
+}
+
+void compute_nr_prach_seq(uint16_t rootSequenceIndex,
+ uint8_t prach_ConfigIndex,
+ uint8_t zeroCorrelationZoneConfig,
+ uint8_t highSpeedFlag,
+ lte_frame_type_t frame_type,
+ nr_frequency_range_e fr,
+ uint32_t X_u[64][839])
+{
+
+ // Compute DFT of x_u => X_u[k] = x_u(inv(u)*k)^* X_u[k] = exp(j\pi u*inv(u)*k*(inv(u)*k+1)/N_ZC)
+ unsigned int k,inv_u,i,NCS=0,num_preambles;
+ int N_ZC;
+ uint8_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,frame_type,fr);
+ uint16_t *prach_root_sequence_map;
+ uint16_t u, preamble_offset;
+ uint16_t n_shift_ra,n_shift_ra_bar, d_start,numshift;
+ uint8_t not_found;
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_COMPUTE_PRACH, VCD_FUNCTION_IN);
+
+#ifdef NR_PRACH_DEBUG
+ LOG_I(PHY,"compute_prach_seq: NCS_config %d, prach_fmt %x\n",zeroCorrelationZoneConfig, prach_fmt);
+#endif
+
+
+ N_ZC = (prach_fmt < 4) ? 839 : 139;
+ //init_prach_tables(N_ZC); //moved to phy_init_lte_ue/eNB, since it takes to long in real-time
+
+ init_nr_prach_tables(N_ZC);
+
+ if (prach_fmt < 4) {
+ prach_root_sequence_map = prach_root_sequence_map_0_3;
+ } else {
+ // FIXME cannot be reached
+ prach_root_sequence_map = prach_root_sequence_map_abc;
+ }
+
+
+#ifdef PRACH_DEBUG
+ LOG_I( PHY, "compute_prach_seq: done init prach_tables\n" );
+#endif
+
+
+
+
+ int restricted_Type = 0; //this is hardcoded ('0' for restricted_TypeA; and '1' for restricted_TypeB). FIXME
+
+ if (highSpeedFlag== 0) {
+
+#ifdef PRACH_DEBUG
+ LOG_I(PHY,"Low speed prach : NCS_config %d\n",zeroCorrelationZoneConfig);
+#endif
+
+ AssertFatal(zeroCorrelationZoneConfig<=15,
+ "FATAL, Illegal Ncs_config for unrestricted format %"PRIu8"\n", zeroCorrelationZoneConfig );
+ if (prach_fmt<3) NCS = NCS_unrestricted_delta_f_RA_125[zeroCorrelationZoneConfig];
+ if (prach_fmt==3) NCS = NCS_unrestricted_delta_f_RA_5[zeroCorrelationZoneConfig];
+ if (prach_fmt>3) NCS = NCS_unrestricted_delta_f_RA_15[zeroCorrelationZoneConfig];
+
+ num_preambles = (NCS==0) ? 64 : ((64*NCS)/N_ZC);
+
+ if (NCS>0) num_preambles++;
+
+ preamble_offset = 0;
+ } else {
+
+#ifdef PRACH_DEBUG
+ LOG_I( PHY, "high speed prach : NCS_config %"PRIu8"\n", zeroCorrelationZoneConfig );
+#endif
+
+ AssertFatal(zeroCorrelationZoneConfig<=14,
+ "FATAL, Illegal Ncs_config for restricted format %"PRIu8"\n", zeroCorrelationZoneConfig );
+ if (prach_fmt<3){
+ if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_125[zeroCorrelationZoneConfig]; // for TypeA, this is hardcoded. FIXME
+ if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_125[zeroCorrelationZoneConfig]; // for TypeB, this is hardcoded. FIXME
+ }
+ if (prach_fmt==3){
+ if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_5[zeroCorrelationZoneConfig]; // for TypeA, this is hardcoded. FIXME
+ if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_5[zeroCorrelationZoneConfig]; // for TypeB, this is hardcoded. FIXME
+ }
+ if (prach_fmt>3){
+
+ }
+
+ nr_fill_du(prach_fmt);
+
+ num_preambles = 64; // compute ZC sequence for 64 possible roots
+ // find first non-zero shift root (stored in preamble_offset)
+ not_found = 1;
+ preamble_offset = 0;
+
+ while (not_found == 1) {
+ // current root depending on rootSequenceIndex
+ int index = (rootSequenceIndex + preamble_offset) % N_ZC;
+
+ if (prach_fmt<4) {
+ // prach_root_sequence_map points to prach_root_sequence_map0_3
+ DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) );
+ } else {
+ // prach_root_sequence_map points to prach_root_sequence_map4
+ DevAssert( index < sizeof(prach_root_sequence_map_abc) / sizeof(prach_root_sequence_map_abc[0]) );
+ }
+
+ u = prach_root_sequence_map[index];
+
+ uint16_t n_group_ra = 0;
+
+ if ( (nr_du[u]<(N_ZC/3)) && (nr_du[u]>=NCS) ) {
+ n_shift_ra = nr_du[u]/NCS;
+ d_start = (nr_du[u]<<1) + (n_shift_ra * NCS);
+ n_group_ra = N_ZC/d_start;
+ n_shift_ra_bar = max(0,(N_ZC-(nr_du[u]<<1)-(n_group_ra*d_start))/N_ZC);
+ } else if ( (nr_du[u]>=(N_ZC/3)) && (nr_du[u]<=((N_ZC - NCS)>>1)) ) {
+ n_shift_ra = (N_ZC - (nr_du[u]<<1))/NCS;
+ d_start = N_ZC - (nr_du[u]<<1) + (n_shift_ra * NCS);
+ n_group_ra = nr_du[u]/d_start;
+ n_shift_ra_bar = min(n_shift_ra,max(0,(nr_du[u]- (n_group_ra*d_start))/NCS));
+ } else {
+ n_shift_ra = 0;
+ n_shift_ra_bar = 0;
+ }
+
+ // This is the number of cyclic shifts for the current root u
+ numshift = (n_shift_ra*n_group_ra) + n_shift_ra_bar;
+
+ // skip to next root and recompute parameters if numshift==0
+ if (numshift>0)
+ not_found = 0;
+ else
+ preamble_offset++;
+ }
+ }
+
+#ifdef PRACH_DEBUG
+
+ if (NCS>0)
+ LOG_I( PHY, "Initializing %u preambles for PRACH (NCS_config %"PRIu8", NCS %u, N_ZC/NCS %u)\n",
+ num_preambles, zeroCorrelationZoneConfig, NCS, N_ZC/NCS );
+
+#endif
+
+ for (i=0; isch_config.physical_cell_id.value % 3;
+ uint8_t Nid2 = config->cell_config.phy_cell_id.value % 3;
/// Sequence generation
for (i=0; i < 7; i++)
diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c
index 63922c8c65..04045380eb 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c
@@ -84,8 +84,14 @@ uint16_t get_dmrs_freq_idx(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t d
return dmrs_idx;
}
-uint8_t get_l0(uint8_t mapping_type, uint8_t dmrs_typeA_position) {
-
- return ((mapping_type==NFAPI_NR_PDSCH_MAPPING_TYPE_A)?dmrs_typeA_position:0);
+uint8_t get_l0(uint16_t dlDmrsSymbPos) {
+ uint16_t mask=dlDmrsSymbPos;
+ int l0;
+ for (l0=0;l0<14;l0++) {
+ if ((mask&1) == 1) break;
+ mask>>=1;
+ }
+ AssertFatal(l0 < 4,"impossible l0 %d\n",l0);
+ return (l0);
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h
index 8278742a48..2b25464b84 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h
@@ -48,6 +48,6 @@ uint8_t get_delta(uint8_t ap, uint8_t config);
uint16_t get_dmrs_freq_idx(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type);
-uint8_t get_l0(uint8_t mapping_type, uint8_t dmrs_typeA_position);
+uint8_t get_l0(uint16_t dlDmrsSymbPos);
-#endif
+#endif
\ No newline at end of file
diff --git a/openair1/PHY/NR_TRANSPORT/nr_sss.c b/openair1/PHY/NR_TRANSPORT/nr_sss.c
index 154aca9ffe..7d8b551d7c 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_sss.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_sss.c
@@ -27,7 +27,7 @@ int nr_generate_sss( int16_t *d_sss,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
- nfapi_nr_config_request_t* config,
+ nfapi_nr_config_request_scf_t* config,
NR_DL_FRAME_PARMS *frame_parms)
{
int i,k,l;
@@ -39,7 +39,7 @@ int nr_generate_sss( int16_t *d_sss,
const int x1_initial[7] = { 1, 0, 0, 0, 0, 0, 0 };
/// Sequence generation
- Nid = config->sch_config.physical_cell_id.value;
+ Nid = config->cell_config.phy_cell_id.value;
Nid2 = Nid % 3;
Nid1 = (Nid - Nid2)/3;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
index 10ac17acab..ea8e39488e 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
@@ -33,187 +33,6 @@
#include "nr_transport_common_proto.h"
#include "PHY/CODING/coding_defs.h"
-//Table 5.1.3.1-1 of 38.214
-uint16_t Table_51311[29][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616},
- {4,658},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}};
-
-//Table 5.1.3.1-2 of 38.214
-// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
-uint16_t Table_51312[28][2] = {{2,120},{2,193},{2,308},{2,449},{2,602},{4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{6,466},{6,517},{6,567},{6,616},{6,666},
- {6,719},{6,772},{6,822},{6,873},{8,1365},{8,711},{8,754},{8,797},{8,841},{8,885},{8,1833},{8,948}};
-
-//Table 5.1.3.1-3 of 38.214
-uint16_t Table_51313[29][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{4,340},
- {4,378},{4,434},{4,490},{4,553},{4,616},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666}, {6,719}, {6,772}};
-
-//Table 6.1.4.1-1 of 38.214 TODO fix for tp-pi2BPSK
-uint16_t Table_61411[28][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616},
- {4,658},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}};
-
-//Table 6.1.4.1-2 of 38.214 TODO fix for tp-pi2BPSK
-uint16_t Table_61412[28][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},
- {4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{4,699},{4,772},{6,567},{6,616},{6,666}, {6,772}};
-
-
-uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) {
- switch(table_idx) {
- case 0:
- return (Table_51311[Imcs][0]);
- break;
-
- case 1:
- return (Table_51312[Imcs][0]);
- break;
-
- case 2:
- return (Table_51313[Imcs][0]);
- break;
-
- default:
- AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx);
- }
-}
-
-uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) {
- switch(table_idx) {
- case 0:
- return (Table_51311[Imcs][1]);
- break;
-
- case 1:
- return (Table_51312[Imcs][1]);
- break;
-
- case 2:
- return (Table_51313[Imcs][1]);
- break;
-
- default:
- AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx);
- }
-}
-
-uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
- switch(table_idx) {
- case 0:
- return (Table_51311[Imcs][0]);
- break;
-
- case 1:
- return (Table_51312[Imcs][0]);
- break;
-
- case 2:
- return (Table_51313[Imcs][0]);
- break;
-
- case 3:
- return (Table_61411[Imcs][0]);
- break;
-
- case 4:
- return (Table_61412[Imcs][0]);
- break;
-
- default:
- AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx);
- }
-}
-
-uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) {
- switch(table_idx) {
- case 0:
- return (Table_51311[Imcs][1]);
- break;
-
- case 1:
- return (Table_51312[Imcs][1]);
- break;
-
- case 2:
- return (Table_51313[Imcs][1]);
- break;
-
- case 3:
- return (Table_61411[Imcs][1]);
- break;
-
- case 4:
- return (Table_61412[Imcs][1]);
- break;
-
- default:
- AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx);
- }
-}
-
-static inline uint8_t is_codeword_disabled(uint8_t format, uint8_t Imcs, uint8_t rv) {
- return ((format==NFAPI_NR_DL_DCI_FORMAT_1_1)&&(Imcs==26)&&(rv==1));
-}
-
-static inline uint8_t get_table_idx(uint8_t mcs_table, uint8_t dci_format, uint8_t rnti_type, uint8_t ss_type) {
- if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1) && ((rnti_type==NFAPI_NR_RNTI_C)||(rnti_type==NFAPI_NR_RNTI_CS)))
- return 2;
- else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type!=NFAPI_NR_RNTI_new) && (rnti_type==NFAPI_NR_RNTI_C) && (ss_type==NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC))
- return 3;
- else if (rnti_type==NFAPI_NR_RNTI_new)
- return 3;
- else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (rnti_type==NFAPI_NR_RNTI_CS) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1))
- return 2; // Condition mcs_table not configured in sps_config necessary here but not yet implemented
- /*else if((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type==NFAPI_NR_RNTI_CS))
- * table_idx = 3;
- * Note: the commented block refers to the case where the mcs_table is from sps_config*/
- else
- return 1;
-}
-
-void nr_get_tbs_dl(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
- nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
- nfapi_nr_config_request_t config) {
-
- LOG_D(MAC, "TBS calculation\n");
-
- nfapi_nr_dl_config_pdcch_parameters_rel15_t params_rel15 = dci_pdu.pdcch_params_rel15;
- nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_rel15 = &dlsch_pdu->dlsch_pdu_rel15;
- uint8_t rnti_type = params_rel15.rnti_type;
- uint16_t N_PRB_oh = ((rnti_type==NFAPI_NR_RNTI_SI)||(rnti_type==NFAPI_NR_RNTI_RA)||(rnti_type==NFAPI_NR_RNTI_P))? 0 : \
- (config.pdsch_config.x_overhead.value);
- uint8_t N_PRB_DMRS = (config.pdsch_config.dmrs_type.value == NFAPI_NR_DMRS_TYPE1)?6:4; //This only works for antenna port 1000
- uint8_t N_sh_symb = dlsch_rel15->nb_symbols;
- uint8_t Imcs = dlsch_rel15->mcs_idx;
- uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh;
- LOG_D(MAC, "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n", N_RE_prime, N_sh_symb, N_PRB_DMRS, N_PRB_oh);
-
- uint16_t R;
- uint32_t TBS=0;
- uint8_t table_idx, Qm;
-
- /*uint8_t mcs_table = config.pdsch_config.mcs_table.value;
- uint8_t ss_type = params_rel15.search_space_type;
- uint8_t dci_format = params_rel15.dci_format;
- get_table_idx(mcs_table, dci_format, rnti_type, ss_type);*/
- table_idx = 0;
- R = nr_get_code_rate_dl(Imcs, table_idx);
- Qm = nr_get_Qm_dl(Imcs, table_idx);
-
- TBS = nr_compute_tbs(Qm,
- R,
- dlsch_rel15->n_prb,
- N_sh_symb,
- N_PRB_DMRS,
- N_PRB_oh,
- dlsch_rel15->nb_layers);
-
- dlsch_rel15->coding_rate = R;
- dlsch_rel15->modulation_order = Qm;
- dlsch_rel15->transport_block_size = TBS;
- dlsch_rel15->nb_re_dmrs = N_PRB_DMRS;
- dlsch_rel15->nb_mod_symbols = N_RE_prime*dlsch_rel15->n_prb*dlsch_rel15->nb_codewords;
- dlsch_rel15->mcs_table = table_idx;
-
- LOG_D(MAC, "TBS %d : N_PRB_DMRS %d N_sh_symb %d N_PRB_oh %d R %d Qm %d table %d nb_symbols %d\n",
- TBS, N_PRB_DMRS, N_sh_symb, N_PRB_oh, R, Qm, table_idx, dlsch_rel15->nb_mod_symbols);
-}
uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) {
uint32_t G;
@@ -227,7 +46,7 @@ uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r) {
AssertFatal(Nl>0,"Nl is 0\n");
AssertFatal(Qm>0,"Qm is 0\n");
-
+ LOG_D(PHY,"nr_get_E : (G %d, C %d, Qm %d, Nl %d, r %d)\n",G, C, Qm, Nl, r);
if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
E = Nl*Qm*(G/(Nl*Qm*Cprime));
else
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport.h b/openair1/PHY/NR_TRANSPORT/nr_transport.h
index 23413f591c..be73875058 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport.h
@@ -23,6 +23,7 @@
#define __NR_TRANSPORT__H__
#include "PHY/defs_gNB.h"
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#define NR_PBCH_PDU_BITS 24
@@ -36,7 +37,7 @@ int nr_generate_pss( int16_t *d_pss,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
- nfapi_nr_config_request_t *config,
+ nfapi_nr_config_request_scf_t *config,
NR_DL_FRAME_PARMS *frame_parms);
/*!
@@ -49,7 +50,7 @@ int nr_generate_sss( int16_t *d_sss,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
- nfapi_nr_config_request_t *config,
+ nfapi_nr_config_request_scf_t *config,
NR_DL_FRAME_PARMS *frame_parms);
/*!
@@ -62,7 +63,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
- nfapi_nr_config_request_t *config,
+ nfapi_nr_config_request_scf_t *config,
NR_DL_FRAME_PARMS *frame_parms);
/*!
@@ -85,16 +86,14 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
@returns 0 on success
*/
int nr_generate_pbch(NR_gNB_PBCH *pbch,
- uint8_t *pbch_pdu,
+ nfapi_nr_dl_tti_ssb_pdu *ssb_pdu,
uint8_t *interleaver,
int32_t *txdataF,
int16_t amp,
uint8_t ssb_start_symbol,
uint8_t n_hf,
- uint8_t Lmax,
- uint8_t ssb_index,
int sfn,
- nfapi_nr_config_request_t *config,
+ nfapi_nr_config_request_scf_t *config,
NR_DL_FRAME_PARMS *frame_parms);
/*!
@@ -105,11 +104,23 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
*/
void nr_init_pbch_interleaver(uint8_t *interleaver);
-NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,
+NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
+ unsigned char Kmimo,
unsigned char Mdlharq,
uint32_t Nsoft,
uint8_t abstraction_flag,
- NR_DL_FRAME_PARMS *frame_parms,
- nfapi_nr_config_request_t *config);
+ uint16_t N_RB);
+
+void rx_nr_prach(PHY_VARS_gNB *gNB,
+ int frame,
+ int subframe,
+ uint16_t *max_preamble,
+ uint16_t *max_preamble_energy,
+ uint16_t *max_preamble_delay
+ );
+
+void rx_nr_prach_ru(RU_t *ru,
+ int frame,
+ int subframe);
#endif /*__NR_TRANSPORT__H__*/
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
index 6a88203f8c..762346048f 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
@@ -23,7 +23,7 @@
/*! \file PHY/NR_TRANSPORT/nr_transport_common_proto.h
* \brief Some support routines
* \author
-* \date 2018
+* \date 2019
* \version 0.1
* \company Eurecom
* \email:
@@ -36,29 +36,13 @@
#include "PHY/defs_nr_common.h"
-#define MAX_NUM_NR_DLSCH_SEGMENTS 16
-#define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS
-
-#define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056)
-#define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056)
-
-#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*6) // 14 symbols, 273 RB
-#define MAX_NUM_NR_RE (14*273*12)
#define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1
#define NR_PUSCH_y 3 // UCI placeholder bit
-/** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */
-uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
-uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
-/** \brief Computes Q based on I_MCS PDSCH and table_idx for uplink. Implements MCS Tables from 38.214. */
-uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx);
-uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx);
-void nr_get_tbs_dl(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
- nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
- nfapi_nr_config_request_t config);
+
/** \brief Computes available bits G. */
uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint16_t length_dmrs, uint8_t Qm, uint8_t Nl);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index d3985bfd8b..9ce56421fc 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -68,15 +68,9 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
- unsigned short start_rb,
- unsigned short nb_rb_pusch,
- uint16_t n_rnti,
- NR_DL_FRAME_PARMS *frame_parms,
- uint16_t number_symbols,
- uint8_t mapping_type,
- uint8_t ptrs_configured,
- dmrs_UplinkConfig_t *dmrs_UplinkConfig,
- ptrs_UplinkConfig_t *ptrs_Uplink_Config);
+ uint8_t is_dmrs_symbol,
+ nfapi_nr_pusch_pdu_t *pusch_pdu,
+ NR_DL_FRAME_PARMS *frame_parms);
void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms,
@@ -210,3 +204,11 @@ uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
+
+void rx_nr_prach(PHY_VARS_gNB *gNB,
+ int frame,
+ int subframe,
+ uint16_t *max_preamble,
+ uint16_t *max_preamble_energy,
+ uint16_t *max_preamble_delay
+ );
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h
new file mode 100644
index 0000000000..dd37455e26
--- /dev/null
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h
@@ -0,0 +1,1760 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+/*! \file PHY/NR_UE_TRANSPORT/transport_proto_ue.h
+ * \brief Function prototypes for PHY physical/transport channel processing and generation V8.6 2009-03
+ * \author R. Knopp, F. Kaltenberger
+ * \date 2011
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr
+ * \note
+ * \warning
+ */
+#ifndef __NR_TRANSPORT_PROTO_UE__H__
+#define __NR_TRANSPORT_PROTO_UE__H__
+#include "PHY/defs_nr_UE.h"
+#include "SCHED_NR_UE/defs.h"
+//#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
+#include
+#include "nfapi_interface.h"
+
+// Functions below implement 36-211 and 36-212
+
+/** @addtogroup _PHY_TRANSPORT_
+ * @{
+ */
+
+/** \fn free_ue_dlsch(NR_UE_DLSCH_t *dlsch)
+ \brief This function frees memory allocated for a particular DLSCH at UE
+ @param dlsch Pointer to DLSCH to be removed
+*/
+void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch);
+
+/** \fn new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t abstraction_flag)
+ \brief This function allocates structures for a particular DLSCH at UE
+ @returns Pointer to DLSCH to be removed
+ @param Kmimo Kmimo factor from 36-212/36-213
+ @param Mdlharq Maximum number of HARQ rounds (36-212/36-213)
+ @param Nsoft Soft-LLR buffer size from UE-Category
+ @params N_RB_DL total number of resource blocks (determine the operating BW)
+ @param abstraction_flag Flag to indicate abstracted interface
+*/
+NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag);
+
+
+void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch);
+
+
+NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag);
+
+void fill_UE_dlsch_MCH(PHY_VARS_NR_UE *ue,int mcs,int ndi,int rvidx,int eNB_id);
+
+int rx_pmch(PHY_VARS_NR_UE *phy_vars_ue,
+ unsigned char eNB_id,
+ uint8_t subframe,
+ unsigned char symbol);
+
+/** \brief Dump OCTAVE/MATLAB files for PMCH debugging
+ @param phy_vars_ue Pointer to UE variables
+ @param eNB_id index of eNB in ue variables
+ @param coded_bits_per_codeword G from 36.211
+ @param subframe Index of subframe
+ @returns 0 on success
+*/
+void dump_mch(PHY_VARS_NR_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int subframe);
+
+
+
+/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/QPSK reception.
+ @param stream0_in Input from channel compensated (MR combined) stream 0
+ @param stream1_in Input from channel compensated (MR combined) stream 1
+ @param stream0_out Output from LLR unit for stream0
+ @param rho01 Cross-correlation between channels (MR combined)
+ @param length in complex channel outputs*/
+void qpsk_qpsk(int16_t *stream0_in,
+ int16_t *stream1_in,
+ int16_t *stream0_out,
+ int16_t *rho01,
+ int32_t length);
+
+/** \brief This function perform LLR computation for dual-stream (QPSK/QPSK) transmission.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param rxdataF_comp_i Compensated channel output for interference
+ @param rho_i Correlation between channel of signal and inteference
+ @param dlsch_llr llr output
+ @param symbol OFDM symbol index in sub-frame
+ @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
+ @param nb_rb number of RBs for this allocation
+ @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
+ @param llr128p pointer to pointer to symbol in dlsch_llr*/
+int32_t nr_dlsch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **rxdataF_comp_i,
+ int32_t **rho_i,
+ int16_t *dlsch_llr,
+ uint8_t symbol,
+ uint32_t len,
+ uint8_t first_symbol_flag,
+ uint16_t nb_rb,
+ uint16_t pbch_pss_sss_adj,
+ int16_t **llr128p);
+
+/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/16QAM reception.
+ @param stream0_in Input from channel compensated (MR combined) stream 0
+ @param stream1_in Input from channel compensated (MR combined) stream 1
+ @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
+ @param stream0_out Output from LLR unit for stream0
+ @param rho01 Cross-correlation between channels (MR combined)
+ @param length in complex channel outputs*/
+void qpsk_qam16(int16_t *stream0_in,
+ int16_t *stream1_in,
+ short *ch_mag_i,
+ int16_t *stream0_out,
+ int16_t *rho01,
+ int32_t length);
+
+/** \brief This function perform LLR computation for dual-stream (QPSK/16QAM) transmission.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param rxdataF_comp_i Compensated channel output for interference
+ @param rho_i Correlation between channel of signal and inteference
+ @param dlsch_llr llr output
+ @param symbol OFDM symbol index in sub-frame
+ @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
+ @param nb_rb number of RBs for this allocation
+ @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
+ @param llr128p pointer to pointer to symbol in dlsch_llr*/
+int32_t nr_dlsch_qpsk_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **rxdataF_comp_i,
+ int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
+ int32_t **rho_i,
+ int16_t *dlsch_llr,
+ uint8_t symbol,
+ uint8_t first_symbol_flag,
+ uint16_t nb_rb,
+ uint16_t pbch_pss_sss_adj,
+ int16_t **llr128p);
+
+
+/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/64QAM reception.
+ @param stream0_in Input from channel compensated (MR combined) stream 0
+ @param stream1_in Input from channel compensated (MR combined) stream 1
+ @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
+ @param stream0_out Output from LLR unit for stream0
+ @param rho01 Cross-correlation between channels (MR combined)
+ @param length in complex channel outputs*/
+void qpsk_qam64(int16_t *stream0_in,
+ int16_t *stream1_in,
+ short *ch_mag_i,
+ int16_t *stream0_out,
+ int16_t *rho01,
+ int32_t length);
+
+/** \brief This function perform LLR computation for dual-stream (QPSK/64QAM) transmission.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param rxdataF_comp_i Compensated channel output for interference
+ @param rho_i Correlation between channel of signal and inteference
+ @param dlsch_llr llr output
+ @param symbol OFDM symbol index in sub-frame
+ @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
+ @param nb_rb number of RBs for this allocation
+ @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
+ @param llr128p pointer to pointer to symbol in dlsch_llr*/
+int32_t nr_dlsch_qpsk_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **rxdataF_comp_i,
+ int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
+ int32_t **rho_i,
+ int16_t *dlsch_llr,
+ uint8_t symbol,
+ uint8_t first_symbol_flag,
+ uint16_t nb_rb,
+ uint16_t pbch_pss_sss_adj,
+ int16_t **llr128p);
+
+
+/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 16QAM/QPSK reception.
+ @param stream0_in Input from channel compensated (MR combined) stream 0
+ @param stream1_in Input from channel compensated (MR combined) stream 1
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param stream0_out Output from LLR unit for stream0
+ @param rho01 Cross-correlation between channels (MR combined)
+ @param length in complex channel outputs*/
+void qam16_qpsk(short *stream0_in,
+ short *stream1_in,
+ short *ch_mag,
+ short *stream0_out,
+ short *rho01,
+ int length);
+/** \brief This function perform LLR computation for dual-stream (16QAM/QPSK) transmission.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param rxdataF_comp_i Compensated channel output for interference
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param rho_i Correlation between channel of signal and inteference
+ @param dlsch_llr llr output
+ @param symbol OFDM symbol index in sub-frame
+ @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
+ @param nb_rb number of RBs for this allocation
+ @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
+ @param llr16p pointer to pointer to symbol in dlsch_llr*/
+int nr_dlsch_16qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
+ int **rxdataF_comp,
+ int **rxdataF_comp_i,
+ int **dl_ch_mag, //|h_0|^2*(2/sqrt{10})
+ int **rho_i,
+ short *dlsch_llr,
+ unsigned char symbol,
+ unsigned char first_symbol_flag,
+ unsigned short nb_rb,
+ uint16_t pbch_pss_sss_adjust,
+ short **llr16p);
+
+/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 16QAM/16QAM reception.
+ @param stream0_in Input from channel compensated (MR combined) stream 0
+ @param stream1_in Input from channel compensated (MR combined) stream 1
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
+ @param stream0_out Output from LLR unit for stream0
+ @param rho01 Cross-correlation between channels (MR combined)
+ @param length in complex channel outputs*/
+void qam16_qam16(short *stream0_in,
+ short *stream1_in,
+ short *ch_mag,
+ short *ch_mag_i,
+ short *stream0_out,
+ short *rho01,
+ int length);
+
+/** \brief This function perform LLR computation for dual-stream (16QAM/16QAM) transmission.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param rxdataF_comp_i Compensated channel output for interference
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
+ @param rho_i Correlation between channel of signal and inteference
+ @param dlsch_llr llr output
+ @param symbol OFDM symbol index in sub-frame
+ @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
+ @param nb_rb number of RBs for this allocation
+ @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
+ @param llr16p pointer to pointer to symbol in dlsch_llr*/
+int nr_dlsch_16qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
+ int **rxdataF_comp,
+ int **rxdataF_comp_i,
+ int **dl_ch_mag, //|h_0|^2*(2/sqrt{10})
+ int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
+ int **rho_i,
+ short *dlsch_llr,
+ unsigned char symbol,
+ uint32_t len,
+ unsigned char first_symbol_flag,
+ unsigned short nb_rb,
+ uint16_t pbch_pss_sss_adjust,
+ short **llr16p);
+
+/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 16QAM/64QAM reception.
+ @param stream0_in Input from channel compensated (MR combined) stream 0
+ @param stream1_in Input from channel compensated (MR combined) stream 1
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
+ @param stream0_out Output from LLR unit for stream0
+ @param rho01 Cross-correlation between channels (MR combined)
+ @param length in complex channel outputs*/
+void qam16_qam64(short *stream0_in,
+ short *stream1_in,
+ short *ch_mag,
+ short *ch_mag_i,
+ short *stream0_out,
+ short *rho01,
+ int length);
+
+/** \brief This function perform LLR computation for dual-stream (16QAM/64QAM) transmission.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param rxdataF_comp_i Compensated channel output for interference
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
+ @param rho_i Correlation between channel of signal and inteference
+ @param dlsch_llr llr output
+ @param symbol OFDM symbol index in sub-frame
+ @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
+ @param nb_rb number of RBs for this allocation
+ @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
+ @param llr16p pointer to pointer to symbol in dlsch_llr*/
+int nr_dlsch_16qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
+ int **rxdataF_comp,
+ int **rxdataF_comp_i,
+ int **dl_ch_mag, //|h_0|^2*(2/sqrt{10})
+ int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
+ int **rho_i,
+ short *dlsch_llr,
+ unsigned char symbol,
+ unsigned char first_symbol_flag,
+ unsigned short nb_rb,
+ uint16_t pbch_pss_sss_adjust,
+ short **llr16p);
+
+/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/64QAM reception.
+ @param stream0_in Input from channel compensated (MR combined) stream 0
+ @param stream1_in Input from channel compensated (MR combined) stream 1
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param stream0_out Output from LLR unit for stream0
+ @param rho01 Cross-correlation between channels (MR combined)
+ @param length in complex channel outputs*/
+void qam64_qpsk(short *stream0_in,
+ short *stream1_in,
+ short *ch_mag,
+ short *stream0_out,
+ short *rho01,
+ int length);
+
+/** \brief This function perform LLR computation for dual-stream (64QAM/64QAM) transmission.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param rxdataF_comp_i Compensated channel output for interference
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param rho_i Correlation between channel of signal and inteference
+ @param dlsch_llr llr output
+ @param symbol OFDM symbol index in sub-frame
+ @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
+ @param nb_rb number of RBs for this allocation
+ @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
+ @param llr16p pointer to pointer to symbol in dlsch_llr*/
+int nr_dlsch_64qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
+ int **rxdataF_comp,
+ int **rxdataF_comp_i,
+ int **dl_ch_mag,
+ int **rho_i,
+ short *dlsch_llr,
+ unsigned char symbol,
+ unsigned char first_symbol_flag,
+ unsigned short nb_rb,
+ uint16_t pbch_pss_sss_adjust,
+ short **llr16p);
+
+/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/16QAM reception.
+ @param stream0_in Input from channel compensated (MR combined) stream 0
+ @param stream1_in Input from channel compensated (MR combined) stream 1
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
+ @param stream0_out Output from LLR unit for stream0
+ @param rho01 Cross-correlation between channels (MR combined)
+ @param length in complex channel outputs*/
+void qam64_qam16(short *stream0_in,
+ short *stream1_in,
+ short *ch_mag,
+ short *ch_mag_i,
+ short *stream0_out,
+ short *rho01,
+ int length);
+
+/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/16QAM reception.
+ @param stream0_in Input from channel compensated (MR combined) stream 0
+ @param stream1_in Input from channel compensated (MR combined) stream 1
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
+ @param stream0_out Output from LLR unit for stream0
+ @param rho01 Cross-correlation between channels (MR combined)
+ @param length in complex channel outputs*/
+void qam64_qam16_avx2(short *stream0_in,
+ short *stream1_in,
+ short *ch_mag,
+ short *ch_mag_i,
+ short *stream0_out,
+ short *rho01,
+ int length);
+
+/** \brief This function perform LLR computation for dual-stream (64QAM/16QAM) transmission.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param rxdataF_comp_i Compensated channel output for interference
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
+ @param rho_i Correlation between channel of signal and inteference
+ @param dlsch_llr llr output
+ @param symbol OFDM symbol index in sub-frame
+ @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
+ @param nb_rb number of RBs for this allocation
+ @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
+ @param llr16p pointer to pointer to symbol in dlsch_llr*/
+int nr_dlsch_64qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
+ int **rxdataF_comp,
+ int **rxdataF_comp_i,
+ int **dl_ch_mag,
+ int **dl_ch_mag_i,
+ int **rho_i,
+ short *dlsch_llr,
+ unsigned char symbol,
+ unsigned char first_symbol_flag,
+ unsigned short nb_rb,
+ uint16_t pbch_pss_sss_adjust,
+ short **llr16p);
+
+/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/64QAM reception.
+ @param stream0_in Input from channel compensated (MR combined) stream 0
+ @param stream1_in Input from channel compensated (MR combined) stream 1
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
+ @param stream0_out Output from LLR unit for stream0
+ @param rho01 Cross-correlation between channels (MR combined)
+ @param length in complex channel outputs*/
+void qam64_qam64(short *stream0_in,
+ short *stream1_in,
+ short *ch_mag,
+ short *ch_mag_i,
+ short *stream0_out,
+ short *rho01,
+ int length);
+
+/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/64QAM reception.
+ @param stream0_in Input from channel compensated (MR combined) stream 0
+ @param stream1_in Input from channel compensated (MR combined) stream 1
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
+ @param stream0_out Output from LLR unit for stream0
+ @param rho01 Cross-correlation between channels (MR combined)
+ @param length in complex channel outputs*/
+void qam64_qam64_avx2(int32_t *stream0_in,
+ int32_t *stream1_in,
+ int32_t *ch_mag,
+ int32_t *ch_mag_i,
+ int16_t *stream0_out,
+ int32_t *rho01,
+ int length);
+
+/** \brief This function perform LLR computation for dual-stream (64QAM/64QAM) transmission.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param rxdataF_comp_i Compensated channel output for interference
+ @param ch_mag Input from scaled channel magnitude square of h0'*g0
+ @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
+ @param rho_i Correlation between channel of signal and inteference
+ @param dlsch_llr llr output
+ @param symbol OFDM symbol index in sub-frame
+ @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
+ @param nb_rb number of RBs for this allocation
+ @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
+ @param llr16p pointer to pointer to symbol in dlsch_llr*/
+int nr_dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
+ int **rxdataF_comp,
+ int **rxdataF_comp_i,
+ int **dl_ch_mag,
+ int **dl_ch_mag_i,
+ int **rho_i,
+ short *dlsch_llr,
+ unsigned char symbol,
+ uint32_t len,
+ unsigned char first_symbol_flag,
+ unsigned short nb_rb,
+ uint16_t pbch_pss_sss_adjust,
+ //short **llr16p,
+ uint32_t llr_offset);
+
+
+/** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param dlsch_llr llr output
+ @param symbol OFDM symbol index in sub-frame
+ @param first_symbol_flag
+ @param nb_rb number of RBs for this allocation
+ @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
+ @param llr128p pointer to pointer to symbol in dlsch_llr
+ @param beamforming_mode beamforming mode
+*/
+int32_t nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int16_t *dlsch_llr,
+ uint8_t symbol,
+ uint32_t len,
+ uint8_t first_symbol_flag,
+ uint16_t nb_rb,
+ uint8_t beamforming_mode);
+
+/**
+ \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param dlsch_llr llr output
+ @param dl_ch_mag Squared-magnitude of channel in each resource element position corresponding to allocation and weighted for mid-point in 16QAM constellation
+ @param symbol OFDM symbol index in sub-frame
+ @param first_symbol_flag
+ @param nb_rb number of RBs for this allocation
+ @param pbch_pss_sss_adjust Adjustment factor in RE for PBCH/PSS/SSS allocations
+ @param llr128p pointer to pointer to symbol in dlsch_llr
+ @param beamforming_mode beamforming mode
+*/
+
+int32_t nr_dlsch_qpsk_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
+ int **rxdataF_comp,
+ int32_t **sic_buffer,
+ int **rho_i,
+ short *dlsch_llr,
+ uint8_t num_pdcch_symbols,
+ uint16_t nb_rb,
+ uint8_t subframe,
+ uint16_t mod_order_0,
+ uint32_t rb_alloc);
+
+void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int16_t *dlsch_llr,
+ int32_t **dl_ch_mag,
+ uint8_t symbol,
+ uint32_t len,
+ uint8_t first_symbol_flag,
+ uint16_t nb_rb,
+ int16_t **llr32p,
+ uint8_t beamforming_mode);
+/**
+ \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param dlsch_llr llr output
+ @param dl_ch_mag Squared-magnitude of channel in each resource element position corresponding to allocation, weighted by first mid-point of 64-QAM constellation
+ @param dl_ch_magb Squared-magnitude of channel in each resource element position corresponding to allocation, weighted by second mid-point of 64-QAM constellation
+ @param symbol OFDM symbol index in sub-frame
+ @param first_symbol_flag
+ @param nb_rb number of RBs for this allocation
+ @param pbch_pss_sss_adjust PBCH/PSS/SSS RE adjustment (in REs)
+ @param beamforming_mode beamforming mode
+*/
+void nr_dlsch_16qam_llr_SIC (NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **sic_buffer, //Q15
+ int32_t **rho_i,
+ int16_t *dlsch_llr,
+ uint8_t num_pdcch_symbols,
+ int32_t **dl_ch_mag,
+ uint16_t nb_rb,
+ uint8_t subframe,
+ uint16_t mod_order_0,
+ uint32_t rb_alloc);
+
+void dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **sic_buffer, //Q15
+ int32_t **rho_i,
+ int16_t *dlsch_llr,
+ uint8_t num_pdcch_symbols,
+ int32_t **dl_ch_mag,
+ int32_t **dl_ch_magb,
+ uint16_t nb_rb,
+ uint8_t subframe,
+ uint16_t mod_order_0,
+ uint32_t rb_alloc);
+
+void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int16_t *dlsch_llr,
+ int32_t **dl_ch_mag,
+ int32_t **dl_ch_magb,
+ uint8_t symbol,
+ uint32_t len,
+ uint8_t first_symbol_flag,
+ uint16_t nb_rb,
+ uint32_t llr_offset,
+ uint8_t beamforming_mode);
+
+
+/** \fn dlsch_siso(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **rxdataF_comp_i,
+ uint8_t l,
+ uint16_t nb_rb)
+ \brief This function does the first stage of llr computation for SISO, by just extracting the pilots, PBCH and primary/secondary synchronization sequences.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param rxdataF_comp_i Compensated channel output for interference
+ @param l symbol in sub-frame
+ @param nb_rb Number of RBs in this allocation
+*/
+
+void dlsch_siso(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **rxdataF_comp_i,
+ uint8_t l,
+ uint16_t nb_rb);
+
+/** \fn dlsch_alamouti(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **dl_ch_mag,
+ int32_t **dl_ch_magb,
+ uint8_t symbol,
+ uint16_t nb_rb)
+ \brief This function does Alamouti combining on RX and prepares LLR inputs by skipping pilots, PBCH and primary/secondary synchronization signals.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
+ @param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
+ @param symbol Symbol in sub-frame
+ @param nb_rb Number of RBs in this allocation
+*/
+void dlsch_alamouti(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **dl_ch_mag,
+ int32_t **dl_ch_magb,
+ uint8_t symbol,
+ uint16_t nb_rb);
+
+/** \fn dlsch_antcyc(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **dl_ch_mag,
+ int32_t **dl_ch_magb,
+ uint8_t symbol,
+ uint16_t nb_rb)
+ \brief This function does antenna selection (based on antenna cycling pattern) on RX and prepares LLR inputs by skipping pilots, PBCH and primary/secondary synchronization signals. Note that this is not LTE, it is just included for comparison purposes.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
+ @param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
+ @param symbol Symbol in sub-frame
+ @param nb_rb Number of RBs in this allocation
+*/
+void dlsch_antcyc(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **dl_ch_mag,
+ int32_t **dl_ch_magb,
+ uint8_t symbol,
+ uint16_t nb_rb);
+
+/** \fn dlsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **rxdataF_comp_i,
+ int32_t **rho,
+ int32_t **rho_i,
+ int32_t **dl_ch_mag,
+ int32_t **dl_ch_magb,
+ uint8_t symbol,
+ uint16_t nb_rb,
+ uint8_t dual_stream_UE)
+
+ \brief This function does maximal-ratio combining for dual-antenna receivers.
+ @param frame_parms Frame descriptor structure
+ @param rxdataF_comp Compensated channel output
+ @param rxdataF_comp_i Compensated channel output for interference
+ @param rho Cross correlation between spatial channels
+ @param rho_i Cross correlation between signal and inteference channels
+ @param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
+ @param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
+ @param symbol Symbol in sub-frame
+ @param nb_rb Number of RBs in this allocation
+ @param dual_stream_UE Flag to indicate dual-stream detection
+*/
+void dlsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
+ int32_t **rxdataF_comp,
+ int32_t **rxdataF_comp_i,
+ int32_t **rho,
+ int32_t **rho_i,
+ int32_t **dl_ch_mag,
+ int32_t **dl_ch_magb,
+ int32_t **dl_ch_mag_i,
+ int32_t **dl_ch_magb_i,
+ uint8_t symbol,
+ uint16_t nb_rb,
+ uint8_t dual_stream_UE);
+
+void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms,
+ NR_UE_PDSCH *lte_ue_pdsch_vars,
+ int harq_pid,
+ int round,
+ unsigned char symbol,
+ unsigned short nb_rb,
+ unsigned char dual_stream_UE);
+
+/** \fn dlsch_extract_rbs_single(int32_t **rxdataF,
+ int32_t **dl_ch_estimates,
+ int32_t **rxdataF_ext,
+ int32_t **dl_ch_estimates_ext,
+ uint16_t pmi,
+ uint8_t *pmi_ext,
+ uint32_t *rb_alloc,
+ uint8_t symbol,
+ uint8_t subframe,
+ NR_DL_FRAME_PARMS *frame_parms)
+ \brief This function extracts the received resource blocks, both channel estimates and data symbols,
+ for the current allocation and for single antenna eNB transmission.
+ @param rxdataF Raw FFT output of received signal
+ @param dl_ch_estimates Channel estimates of current slot
+ @param rxdataF_ext FFT output for RBs in this allocation
+ @param dl_ch_estimates_ext Channel estimates for RBs in this allocation
+ @param pmi subband Precoding matrix indicator
+ @param pmi_ext Extracted PMI for chosen RBs
+ @param rb_alloc RB allocation vector
+ @param symbol Symbol to extract
+ @param subframe Subframe number
+ @param vrb_type Flag to indicate distributed VRB type
+ @param high_speed_flag
+ @param frame_parms Pointer to frame descriptor
+*/
+/*uint16_t nr_dlsch_extract_rbs_single(int32_t **rxdataF,
+ int32_t **dl_ch_estimates,
+ int32_t **rxdataF_ext,
+ int32_t **dl_ch_estimates_ext,
+ uint16_t pmi,
+ uint8_t *pmi_ext,
+ uint32_t *rb_alloc,
+ uint8_t symbol,
+ uint8_t subframe,
+ uint32_t high_speed_flag,
+ NR_DL_FRAME_PARMS *frame_parms);*/
+
+unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
+ int **dl_ch_estimates,
+ int **rxdataF_ext,
+ int **dl_ch_estimates_ext,
+ unsigned short pmi,
+ unsigned char *pmi_ext,
+ unsigned char symbol,
+ uint8_t pilots,
+ unsigned short start_rb,
+ unsigned short nb_pdsch_rb,
+ unsigned char nr_tti_rx,
+ uint32_t high_speed_flag,
+ NR_DL_FRAME_PARMS *frame_parms);
+
+/** \fn dlsch_extract_rbs_dual(int32_t **rxdataF,
+ int32_t **dl_ch_estimates,
+ int32_t **rxdataF_ext,
+ int32_t **dl_ch_estimates_ext,
+ uint16_t pmi,
+ uint8_t *pmi_ext,
+ uint32_t *rb_alloc,
+ uint8_t symbol,
+ NR_DL_FRAME_PARMS *frame_parms)
+ \brief This function extracts the received resource blocks, both channel estimates and data symbols,
+ for the current allocation and for dual antenna eNB transmission.
+ @param rxdataF Raw FFT output of received signal
+ @param dl_ch_estimates Channel estimates of current slot
+ @param rxdataF_ext FFT output for RBs in this allocation
+ @param dl_ch_estimates_ext Channel estimates for RBs in this allocation
+ @param pmi subband Precoding matrix indicator
+ @param pmi_ext Extracted PMI for chosen RBs
+ @param rb_alloc RB allocation vector
+ @param symbol Symbol to extract
+ @param subframe Subframe index
+ @param high_speed_flag
+ @param frame_parms Pointer to frame descriptor
+*/
+unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF,
+ int **dl_ch_estimates,
+ int **rxdataF_ext,
+ int **dl_ch_estimates_ext,
+ unsigned short pmi,
+ unsigned char *pmi_ext,
+ unsigned char symbol,
+ uint8_t pilots,
+ unsigned short start_rb,
+ unsigned short nb_rb_pdsch,
+ unsigned char nr_tti_rx,
+ uint32_t high_speed_flag,
+ NR_DL_FRAME_PARMS *frame_parms,
+ MIMO_mode_t mimo_mode);
+
+/** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
+ int32_t **dl_bf_ch_estimates,
+ int32_t **rxdataF_ext,
+ int32_t **dl_bf_ch_estimates_ext,
+ uint32_t *rb_alloc,
+ uint8_t symbol,
+ uint8_t subframe,
+ uint32_t high_speed_flag,
+ NR_DL_FRAME_PARMS *frame_parms)
+ \brief This function extracts the received resource blocks, both channel estimates and data symbols,
+ for the current allocation and for single antenna eNB transmission.
+ @param rxdataF Raw FFT output of received signal
+ @param dl_bf_ch_estimates Beamforming channel estimates of current slot
+ @param rxdataF_ext FFT output for RBs in this allocation
+ @param dl_bf_ch_estimates_ext Beamforming channel estimates for RBs in this allocation
+ @param rb_alloc RB allocation vector
+ @param symbol Symbol to extract
+ @param subframe Subframe number
+ @param high_speed_flag
+ @param frame_parms Pointer to frame descriptor
+*/
+uint16_t dlsch_extract_rbs_TM7(int32_t **rxdataF,
+ int32_t **dl_bf_ch_estimates,
+ int32_t **rxdataF_ext,
+ int32_t **dl_bf_ch_estimates_ext,
+ uint32_t *rb_alloc,
+ uint8_t symbol,
+ uint8_t subframe,
+ uint32_t high_speed_flag,
+ NR_DL_FRAME_PARMS *frame_parms);
+
+/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
+ @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated
+ @param dl_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated
+ @param dl_ch_mag First Channel magnitudes (16QAM/64QAM)
+ @param dl_ch_magb Second weighted Channel magnitudes (64QAM)
+ @param rxdataF_comp Compensated received waveform
+ @param rho Cross-correlation between two spatial channels on each RX antenna
+ @param frame_parms Pointer to frame descriptor
+ @param symbol Symbol on which to operate
+ @param first_symbol_flag set to 1 on first DLSCH symbol
+ @param mod_order Modulation order of allocation
+ @param nb_rb Number of RBs in allocation
+ @param output_shift Rescaling for compensated output (should be energy-normalizing)
+ @param phy_measurements Pointer to UE PHY measurements
+*/
+void nr_dlsch_channel_compensation(int32_t **rxdataF_ext,
+ int32_t **dl_ch_estimates_ext,
+ int32_t **dl_ch_mag,
+ int32_t **dl_ch_magb,
+ int32_t **rxdataF_comp,
+ int32_t **rho,
+ NR_DL_FRAME_PARMS *frame_parms,
+ uint8_t symbol,
+ uint8_t start_symbol,
+ uint8_t first_symbol_flag,
+ uint8_t mod_order,
+ uint16_t nb_rb,
+ uint8_t output_shift,
+ PHY_NR_MEASUREMENTS *phy_measurements);
+
+void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
+ int **dl_ch_estimates_ext,
+ int **dl_ch_mag,
+ int **dl_ch_magb,
+ int **rxdataF_comp,
+ int **rho,
+ unsigned char n_tx,
+ unsigned char n_rx,
+ unsigned char mod_order,
+ unsigned char output_shift,
+ int length,
+ int start_point);
+
+void nr_dlsch_deinterleaving(uint8_t symbol,
+ uint8_t start_symbol,
+ uint16_t L,
+ uint16_t *llr,
+ uint16_t *llr_deint,
+ uint16_t nb_rb_pdsch);
+
+void dlsch_dual_stream_correlation(NR_DL_FRAME_PARMS *frame_parms,
+ unsigned char symbol,
+ unsigned short nb_rb,
+ int **dl_ch_estimates_ext,
+ int **dl_ch_estimates_ext_i,
+ int **dl_ch_rho_ext,
+ unsigned char output_shift);
+
+void dlsch_dual_stream_correlationTM34(NR_DL_FRAME_PARMS *frame_parms,
+ unsigned char symbol,
+ unsigned short nb_rb,
+ int **dl_ch_estimates_ext,
+ int **dl_ch_estimates_ext_i,
+ int **dl_ch_rho_ext,
+ unsigned char output_shift0,
+ unsigned char output_shift1);
+//This function is used to compute multiplications in Hhermitian * H matrix
+void conjch0_mult_ch1(int *ch0,
+ int *ch1,
+ int32_t *ch0conj_ch1,
+ unsigned short nb_rb,
+ unsigned char output_shift0);
+
+void construct_HhH_elements(int *ch0conj_ch0,
+ int *ch1conj_ch1,
+ int *ch2conj_ch2,
+ int *ch3conj_ch3,
+ int *ch0conj_ch1,
+ int *ch1conj_ch0,
+ int *ch2conj_ch3,
+ int *ch3conj_ch2,
+ int32_t *after_mf_00,
+ int32_t *after_mf_01,
+ int32_t *after_mf_10,
+ int32_t *after_mf_11,
+ unsigned short nb_rb);
+
+void squared_matrix_element(int32_t *Hh_h_00,
+ int32_t *Hh_h_00_sq,
+ unsigned short nb_rb);
+
+void dlsch_channel_level_TM34_meas(int *ch00,
+ int *ch01,
+ int *ch10,
+ int *ch11,
+ int *avg_0,
+ int *avg_1,
+ unsigned short nb_rb);
+
+void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
+ int32_t *median,
+ int n_tx,
+ int n_rx,
+ int length,
+ int start_point);
+
+void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
+ int **rxdataF_comp_i,
+ int **rho,
+ int **rho_i,
+ int **dl_ch_mag,
+ int **dl_ch_magb,
+ int **dl_ch_mag_i,
+ int **dl_ch_magb_i,
+ unsigned char n_tx,
+ unsigned char n_rx,
+ int length,
+ int start_point);
+
+void det_HhH(int32_t *after_mf_00,
+ int32_t *after_mf_01,
+ int32_t *after_mf_10,
+ int32_t *after_mf_11,
+ int32_t *det_fin_128,
+ unsigned short nb_rb);
+
+void numer(int32_t *Hh_h_00_sq,
+ int32_t *Hh_h_01_sq,
+ int32_t *Hh_h_10_sq,
+ int32_t *Hh_h_11_sq,
+ int32_t *num_fin,
+ unsigned short nb_rb);
+
+uint8_t rank_estimation_tm3_tm4(int *dl_ch_estimates_00,
+ int *dl_ch_estimates_01,
+ int *dl_ch_estimates_10,
+ int *dl_ch_estimates_11,
+ unsigned short nb_rb);
+
+void dlsch_channel_compensation_TM56(int **rxdataF_ext,
+ int **dl_ch_estimates_ext,
+ int **dl_ch_mag,
+ int **dl_ch_magb,
+ int **rxdataF_comp,
+ unsigned char *pmi_ext,
+ NR_DL_FRAME_PARMS *frame_parms,
+ PHY_NR_MEASUREMENTS *phy_measurements,
+ int eNB_id,
+ unsigned char symbol,
+ unsigned char mod_order,
+ unsigned short nb_rb,
+ unsigned char output_shift,
+ unsigned char dl_power_off);
+
+
+void dlsch_channel_compensation_TM34(NR_DL_FRAME_PARMS *frame_parms,
+ NR_UE_PDSCH *lte_ue_pdsch_vars,
+ PHY_NR_MEASUREMENTS *phy_measurements,
+ int eNB_id,
+ unsigned char symbol,
+ unsigned char mod_order0,
+ unsigned char mod_order1,
+ int harq_pid,
+ int round,
+ MIMO_mode_t mimo_mode,
+ unsigned short nb_rb,
+ unsigned char output_shift0,
+ unsigned char output_shift1);
+
+
+/** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal
+ @param dl_ch_estimates_ext Channel estimates in allocated RBs
+ @param frame_parms Pointer to frame descriptor
+ @param avg Pointer to average signal strength
+ @param pilots_flag Flag to indicate pilots in symbol
+ @param nb_rb Number of allocated RBs
+*/
+void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
+ NR_DL_FRAME_PARMS *frame_parms,
+ int32_t *avg,
+ uint8_t symbol,
+ uint32_t len,
+ unsigned short nb_rb);
+
+
+void dlsch_channel_level_TM34(int **dl_ch_estimates_ext,
+ NR_DL_FRAME_PARMS *frame_parms,
+ unsigned char *pmi_ext,
+ int *avg_0,
+ int *avg_1,
+ uint8_t symbol,
+ unsigned short nb_rb,
+ MIMO_mode_t mimo_mode);
+
+
+void dlsch_channel_level_TM56(int32_t **dl_ch_estimates_ext,
+ NR_DL_FRAME_PARMS *frame_parms,
+ unsigned char *pmi_ext,
+ int32_t *avg,
+ uint8_t symbol_mod,
+ uint16_t nb_rb);
+
+void dlsch_channel_level_TM7(int32_t **dl_bf_ch_estimates_ext,
+ NR_DL_FRAME_PARMS *frame_parms,
+ int32_t *avg,
+ uint8_t pilots_flag,
+ uint16_t nb_rb);
+
+void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
+ NR_DL_FRAME_PARMS *frame_parms,
+ NR_UE_DLSCH_t **dlsch_ue,
+ uint8_t symbol,
+ uint8_t start_symbol,
+ uint16_t nb_rb);
+
+/** \brief This is the top-level entry point for DLSCH decoding in UE. It should be replicated on several
+ threads (on multi-core machines) corresponding to different HARQ processes. The routine first
+ computes the segmentation information, followed by rate dematching and sub-block deinterleaving the of the
+ received LLRs computed by dlsch_demodulation for each transport block segment. It then calls the
+ turbo-decoding algorithm for each segment and stops after either after unsuccesful decoding of at least
+ one segment or correct decoding of all segments. Only the segment CRCs are check for the moment, the
+ overall CRC is ignored. Finally transport block reassembly is performed.
+ @param phy_vars_ue Pointer to ue variables
+ @param dlsch_llr Pointer to LLR values computed by dlsch_demodulation
+ @param lte_frame_parms Pointer to frame descriptor
+ @param dlsch Pointer to DLSCH descriptor
+ @param frame Frame number
+ @param subframe Subframe number
+ @param num_pdcch_symbols Number of PDCCH symbols
+ @param is_crnti indicates if PDSCH belongs to a CRNTI (necessary for parallelizing decoding threads)
+ @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used
+ @returns 0 on success, 1 on unsuccessful decoding
+*/
+
+uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
+ short *dlsch_llr,
+ NR_DL_FRAME_PARMS *frame_parms,
+ NR_UE_DLSCH_t *dlsch,
+ NR_DL_UE_HARQ_t *harq_process,
+ uint32_t frame,
+ uint16_t nb_symb_sch,
+ uint8_t nr_tti_rx,
+ uint8_t harq_pid,
+ uint8_t is_crnti,
+ uint8_t llr8_flag);
+
+int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
+ NR_DL_FRAME_PARMS* frame_parms,
+ uint8_t harq_pid);
+
+/*! \brief Perform PUSCH scrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
+ @param[in] in Pointer to input bits
+ @param[in] size of input bits
+ @param[in] Nid cell id
+ @param[in] n_RNTI CRNTI
+ @param[out] out the scrambled bits
+*/
+
+void nr_pusch_codeword_scrambling(uint8_t *in,
+ uint16_t size,
+ uint32_t Nid,
+ uint32_t n_RNTI,
+ uint32_t* out);
+
+
+uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
+ UE_nr_rxtx_proc_t *proc,
+ int eNB_id,
+ short *dlsch_llr,
+ NR_DL_FRAME_PARMS *frame_parms,
+ NR_UE_DLSCH_t *dlsch,
+ NR_DL_UE_HARQ_t *harq_process,
+ uint32_t frame,
+ uint16_t nb_symb_sch,
+ uint8_t nr_tti_rx,
+ uint8_t harq_pid,
+ uint8_t is_crnti,
+ uint8_t llr8_flag);
+
+void *nr_dlsch_decoding_2thread0(void *arg);
+
+void *nr_dlsch_decoding_2thread1(void *arg);
+
+void nr_dlsch_unscrambling(int16_t* llr,
+ uint32_t size,
+ uint8_t q,
+ uint32_t Nid,
+ uint32_t n_RNTI);
+
+uint32_t dlsch_decoding_emul(PHY_VARS_NR_UE *phy_vars_ue,
+ uint8_t subframe,
+ PDSCH_t dlsch_id,
+ uint8_t eNB_id);
+
+/** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel estimation. It performs
+ - RB extraction (signal and channel estimates)
+ - channel compensation (matched filtering)
+ - RE extraction (pilot, PBCH, synch. signals)
+ - antenna combining (MRC, Alamouti, cycling)
+ - LLR computation
+ This function supports TM1, 2, 3, 5, and 6.
+ @param PHY_VARS_NR_UE Pointer to PHY variables
+ @param type Type of PDSCH (SI_PDSCH,RA_PDSCH,PDSCH,PMCH)
+ @param eNB_id eNb index (Nid1) 0,1,2
+ @param eNB_id_i Interfering eNB index (Nid1) 0,1,2, or 3 in case of MU-MIMO IC receiver
+ @param subframe Subframe number
+ @param symbol Symbol on which to act (within sub-frame)
+ @param first_symbol_flag set to 1 on first DLSCH symbol
+ @param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice.
+ @param i_mod Modulation order of the interfering stream
+*/
+int32_t nr_rx_pdsch(PHY_VARS_NR_UE *phy_vars_ue,
+ PDSCH_t type,
+ uint8_t eNB_id,
+ uint8_t eNB_id_i,
+ uint32_t frame,
+ uint8_t subframe,
+ uint8_t symbol,
+ uint8_t first_symbol_flag,
+ RX_type_t rx_type,
+ uint8_t i_mod,
+ uint8_t harq_pid);
+
+int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
+ uint32_t frame,
+ uint8_t nr_tti_rx,
+ uint8_t eNB_id,
+ MIMO_mode_t mimo_mode,
+ uint32_t high_speed_flag,
+ uint8_t is_secondary_ue,
+ int nb_coreset_active,
+ uint16_t symbol_mon,
+ NR_SEARCHSPACE_TYPE_t searchSpaceType);
+
+/*! \brief Extract PSS and SSS resource elements
+ @param phy_vars_ue Pointer to UE variables
+ @param[out] pss_ext contain the PSS signals after the extraction
+ @param[out] sss_ext contain the SSS signals after the extraction
+ @returns 0 on success
+*/
+int pss_sss_extract(PHY_VARS_NR_UE *phy_vars_ue,
+ int32_t pss_ext[4][72],
+ int32_t sss_ext[4][72],
+ uint8_t subframe);
+
+/*! \brief Extract only PSS resource elements
+ @param phy_vars_ue Pointer to UE variables
+ @param[out] pss_ext contain the PSS signals after the extraction
+ @returns 0 on success
+*/
+int pss_only_extract(PHY_VARS_NR_UE *phy_vars_ue,
+ int32_t pss_ext[4][72],
+ uint8_t subframe);
+
+/*! \brief Extract only SSS resource elements
+ @param phy_vars_ue Pointer to UE variables
+ @param[out] sss_ext contain the SSS signals after the extraction
+ @returns 0 on success
+*/
+int sss_only_extract(PHY_VARS_NR_UE *phy_vars_ue,
+ int32_t sss_ext[4][72],
+ uint8_t subframe);
+
+/*! \brief Performs detection of SSS to find cell ID and other framing parameters (FDD/TDD, normal/extended prefix)
+ @param phy_vars_ue Pointer to UE variables
+ @param tot_metric Pointer to variable containing maximum metric under framing hypothesis (to be compared to other hypotheses
+ @param flip_max Pointer to variable indicating if start of frame is in second have of RX buffer (i.e. PSS/SSS is flipped)
+ @param phase_max Pointer to variable (0 ... 6) containing rought phase offset between PSS and SSS (can be used for carrier
+ frequency adjustment. 0 means -pi/3, 6 means pi/3.
+ @returns 0 on success
+*/
+int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uint8_t *phase_max);
+
+/*! \brief receiver for the PBCH
+ \returns number of tx antennas or -1 if error
+*/
+int nr_rx_pbch( PHY_VARS_NR_UE *ue,
+ UE_nr_rxtx_proc_t *proc,
+ NR_UE_PBCH *nr_ue_pbch_vars,
+ NR_DL_FRAME_PARMS *frame_parms,
+ uint8_t eNB_id,
+ uint8_t i_ssb,
+ MIMO_mode_t mimo_mode,
+ uint32_t high_speed_flag);
+
+int nr_pbch_detection(UE_nr_rxtx_proc_t *proc,
+ PHY_VARS_NR_UE *ue,
+ int pbch_initial_symbol,
+ runmode_t mode);
+
+uint16_t rx_pbch_emul(PHY_VARS_NR_UE *phy_vars_ue,
+ uint8_t eNB_id,
+ uint8_t pbch_phase);
+
+
+/*! \brief PBCH unscrambling
+ This is similar to pbch_scrabling with the difference that inputs are signed s16s (llr values) and instead of flipping bits we change signs.
+ \param frame_parms Pointer to frame descriptor
+ \param llr Output of the demodulator
+ \param length Length of the sequence
+ \param frame_mod4 Frame number modulo 4*/
+void pbch_unscrambling(NR_DL_FRAME_PARMS *frame_parms,
+ int8_t* llr,
+ uint32_t length,
+ uint8_t frame_mod4);
+
+
+void generate_64qam_table(void);
+void generate_16qam_table(void);
+void generate_qpsk_table(void);
+
+uint16_t extract_crc(uint8_t *dci,uint8_t DCI_LENGTH);
+
+/*! \brief LLR from two streams. This function takes two streams (qpsk modulated) and calculates the LLR, considering one stream as interference.
+ \param stream0_in pointer to first stream0
+ \param stream1_in pointer to first stream1
+ \param stream0_out pointer to output stream
+ \param rho01 pointer to correlation matrix
+ \param length*/
+void qpsk_qpsk_TM3456(short *stream0_in,
+ short *stream1_in,
+ short *stream0_out,
+ short *rho01,
+ int length
+ );
+
+/** \brief Attempt decoding of a particular DCI with given length and format.
+ @param DCI_LENGTH length of DCI in bits
+ @param DCI_FMT Format of DCI
+ @param e e-sequence (soft bits)
+ @param decoded_output Output of Viterbi decoder
+*/
+void dci_decoding(uint8_t DCI_LENGTH,
+ uint8_t DCI_FMT,
+ int8_t *e,
+ uint8_t *decoded_output);
+
+/** \brief Do 36.213 DCI decoding procedure by searching different RNTI options and aggregation levels. Currently does
+ not employ the complexity reducing procedure based on RNTI.
+ @param phy_vars_ue UE variables
+ @param dci_alloc Pointer to DCI_ALLOC_t array to store results for DLSCH/ULSCH programming
+ @param do_common If 1 perform search in common search-space else ue-specific search-space
+ @param eNB_id eNB Index on which to act
+ @param subframe Index of subframe
+ @returns bitmap of occupied CCE positions (i.e. those detected)
+*/
+uint16_t dci_decoding_procedure(PHY_VARS_NR_UE *phy_vars_ue,
+ DCI_ALLOC_t *dci_alloc,
+ int do_common,
+ int16_t eNB_id,
+ uint8_t subframe);
+
+uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_NR_UE *ue,
+ DCI_ALLOC_t *dci_alloc,
+ uint8_t DCIFormat,
+ uint8_t agregationLevel,
+ int16_t eNB_id,
+ uint8_t subframe);
+
+uint16_t dci_decoding_procedure_emul(NR_UE_PDCCH **lte_ue_pdcch_vars,
+ uint8_t num_ue_spec_dci,
+ uint8_t num_common_dci,
+ DCI_ALLOC_t *dci_alloc_tx,
+ DCI_ALLOC_t *dci_alloc_rx,
+ int16_t eNB_id);
+
+/** \brief Compute Q (modulation order) based on I_MCS PDSCH. Implements table 7.1.7.1-1 from 36.213.
+ @param I_MCS */
+uint8_t get_Qm(uint8_t I_MCS);
+
+/** \brief Compute Q (modulation order) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213.
+ @param I_MCS */
+uint8_t get_Qm_ul(uint8_t I_MCS);
+
+/** \brief Compute I_TBS (transport-block size) based on I_MCS for PDSCH. Implements table 7.1.7.1-1 from 36.213.
+ @param I_MCS */
+uint8_t get_I_TBS(uint8_t I_MCS);
+
+/** \brief Compute I_TBS (transport-block size) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213.
+ @param I_MCS */
+unsigned char get_I_TBS_UL(unsigned char I_MCS);
+
+/** \brief Compute Q (modulation order) based on downlink I_MCS. Implements table 7.1.7.1-1 from 36.213.
+ @param I_MCS
+ @param nb_rb
+ @return Transport block size */
+uint32_t get_TBS_DL(uint8_t mcs, uint16_t nb_rb);
+
+/** \brief Compute Q (modulation order) based on uplink I_MCS. Implements table 7.1.7.1-1 from 36.213.
+ @param I_MCS
+ @param nb_rb
+ @return Transport block size */
+uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb);
+
+/* \brief Return bit-map of resource allocation for a given DCI rballoc (RIV format) and vrb type
+ @param N_RB_DL number of PRB on DL
+ @param indicator for even/odd slot
+ @param vrb vrb index
+ @param Ngap Gap indicator
+*/
+uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap);
+
+/* \brief Return prb for a given vrb index
+ @param vrb_type VRB type (0=localized,1=distributed)
+ @param rb_alloc_dci rballoc field from DCI
+*/
+uint32_t get_rballoc(vrb_t vrb_type,uint16_t rb_alloc_dci);
+
+
+/* \brief Return bit-map of resource allocation for a given DCI rballoc (RIV format) and vrb type
+ @returns Transmission mode (1-7)
+*/
+uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti);
+
+
+/* \brief
+ @param ra_header Header of resource allocation (0,1) (See sections 7.1.6.1/7.1.6.2 of 36.213 Rel8.6)
+ @param rb_alloc Bitmap allocation from DCI (format 1,2)
+ @returns number of physical resource blocks
+*/
+uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL);
+
+int get_G(NR_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe, uint8_t beamforming_mode);
+
+int adjust_G(NR_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe);
+int adjust_G2(NR_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol);
+
+
+#ifndef modOrder
+#define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS
+#endif
+
+/** \fn uint8_t I_TBS2I_MCS(uint8_t I_TBS);
+ \brief This function maps I_tbs to I_mcs according to Table 7.1.7.1-1 in 3GPP TS 36.213 V8.6.0. Where there is two supported modulation orders for the same I_TBS then either high or low modulation is chosen by changing the equality of the two first comparisons in the if-else statement.
+ \param I_TBS Index of Transport Block Size
+ \return I_MCS given I_TBS
+*/
+uint8_t I_TBS2I_MCS(uint8_t I_TBS);
+
+/** \fn uint8_t SE2I_TBS(float SE,
+ uint8_t N_PRB,
+ uint8_t symbPerRB);
+ \brief This function maps a requested throughput in number of bits to I_tbs. The throughput is calculated as a function of modulation order, RB allocation and number of symbols per RB. The mapping orginates in the "Transport block size table" (Table 7.1.7.2.1-1 in 3GPP TS 36.213 V8.6.0)
+ \param SE Spectral Efficiency (before casting to integer, multiply by 1024, remember to divide result by 1024!)
+ \param N_PRB Number of PhysicalResourceBlocks allocated \sa lte_frame_parms->N_RB_DL
+ \param symbPerRB Number of symbols per resource block allocated to this channel
+ \return I_TBS given an SE and an N_PRB
+*/
+uint8_t SE2I_TBS(float SE,
+ uint8_t N_PRB,
+ uint8_t symbPerRB);
+/** \brief This function generates the sounding reference symbol (SRS) for the uplink according to 36.211 v8.6.0. If IFFT_FPGA is defined, the SRS is quantized to a QPSK sequence.
+ @param frame_parms LTE DL Frame Parameters
+ @param soundingrs_ul_config_dedicated Dynamic configuration from RRC during Connection Establishment
+ @param txdataF pointer to the frequency domain TX signal
+ @returns 0 on success*/
+int generate_srs(NR_DL_FRAME_PARMS *frame_parms,
+ SOUNDINGRS_UL_CONFIG_DEDICATED *soundingrs_ul_config_dedicated,
+ int *txdataF,
+ int16_t amp,
+ uint32_t subframe);
+
+
+/*!
+ \brief This function is similar to generate_srs_tx but generates a conjugate sequence for channel estimation. If IFFT_FPGA is defined, the SRS is quantized to a QPSK sequence.
+ @param phy_vars_ue Pointer to PHY_VARS structure
+ @param eNB_id Index of destination eNB for this SRS
+ @param amp Linear amplitude of SRS
+ @param subframe Index of subframe on which to act
+ @returns 0 on success, -1 on error with message
+*/
+
+int32_t generate_srs_tx(PHY_VARS_NR_UE *phy_vars_ue,
+ uint8_t eNB_id,
+ int16_t amp,
+ uint32_t subframe);
+
+/*!
+ \brief This function generates the downlink reference signal for the PUSCH according to 36.211 v8.6.0. The DRS occuies the RS defined by rb_alloc and the symbols 2 and 8 for extended CP and 3 and 10 for normal CP.
+*/
+
+int32_t generate_drs_pusch(PHY_VARS_NR_UE *phy_vars_ue,
+ UE_nr_rxtx_proc_t *proc,
+ uint8_t eNB_id,
+ int16_t amp,
+ uint32_t subframe,
+ uint32_t first_rb,
+ uint32_t nb_rb,
+ uint8_t ant);
+
+/*!
+ \brief This function initializes the Group Hopping, Sequence Hopping and nPRS sequences for PUCCH/PUSCH according to 36.211 v8.6.0. It should be called after configuration of UE (reception of SIB2/3) and initial configuration of eNB (or after reconfiguration of cell-specific parameters).
+ @param frame_parms Pointer to a NR_DL_FRAME_PARMS structure (eNB or UE)*/
+void init_ul_hopping(NR_DL_FRAME_PARMS *frame_parms);
+
+
+/*!
+ \brief This function implements the initialization of paging parameters for UE (See Section 7, 36.304).It must be called after setting IMSImod1024 during UE startup and after receiving SIB2
+ @param ue Pointer to UE context
+ @param defaultPagingCycle T from 36.304 (0=32,1=64,2=128,3=256)
+ @param nB nB from 36.304 (0=4T,1=2T,2=T,3=T/2,4=T/4,5=T/8,6=T/16,7=T/32*/
+int init_ue_paging_info(PHY_VARS_NR_UE *ue, long defaultPagingCycle, long nB);
+
+int32_t compareints (const void * a, const void * b);
+
+
+void ulsch_modulation(int32_t **txdataF,
+ int16_t amp,
+ frame_t frame,
+ uint32_t subframe,
+ NR_DL_FRAME_PARMS *frame_parms,
+ NR_UE_ULSCH_t *ulsch);
+
+
+
+
+
+
+int generate_ue_dlsch_params_from_dci(int frame,
+ uint8_t subframe,
+ void *dci_pdu,
+ rnti_t rnti,
+ DCI_format_t dci_format,
+ NR_UE_PDCCH *pdcch_vars,
+ NR_UE_PDSCH *pdsch_vars,
+ NR_UE_DLSCH_t **dlsch,
+ NR_DL_FRAME_PARMS *frame_parms,
+ PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
+ uint16_t si_rnti,
+ uint16_t ra_rnti,
+ uint16_t p_rnti,
+ uint8_t beamforming_mode,
+ uint16_t tc_rnti);
+
+
+int generate_ue_ulsch_params_from_dci(void *dci_pdu,
+ rnti_t rnti,
+ uint8_t subframe,
+ DCI_format_t dci_format,
+ PHY_VARS_NR_UE *phy_vars_ue,
+ UE_nr_rxtx_proc_t *proc,
+ uint16_t si_rnti,
+ uint16_t ra_rnti,
+ uint16_t p_rnti,
+ uint16_t cba_rnti,
+ uint8_t eNB_id,
+ uint8_t use_srs);
+
+int32_t generate_ue_ulsch_params_from_rar(PHY_VARS_NR_UE *phy_vars_ue,
+ UE_nr_rxtx_proc_t *proc,
+ uint8_t eNB_id);
+double sinr_eff_cqi_calc(PHY_VARS_NR_UE *phy_vars_ue,
+ uint8_t eNB_id,
+ uint8_t subframe);
+
+uint8_t sinr2cqi(double sinr,uint8_t trans_mode);
+
+
+int dump_dci(NR_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci);
+
+int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, char* buffer, int length, runmode_t mode, int input_level_dBm);
+
+void init_transport_channels(uint8_t);
+
+void generate_RIV_tables(void);
+
+/*!
+ \brief This function performs the initial cell search procedure - PSS detection, SSS detection and PBCH detection. At the
+ end, the basic frame parameters are known (Frame configuration - TDD/FDD and cyclic prefix length,
+ N_RB_DL, PHICH_CONFIG and Nid_cell) and the UE can begin decoding PDCCH and DLSCH SI to retrieve the rest. Once these
+ parameters are know, the routine calls some basic initialization routines (cell-specific reference signals, etc.)
+ @param phy_vars_ue Pointer to UE variables
+ @param mode current running mode
+*/
+int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
+ PHY_VARS_NR_UE *phy_vars_ue, runmode_t mode);
+
+
+/*!
+ \brief Encoding of PUSCH/ACK/RI/ACK from 36-212.
+ @param a Pointer to ulsch SDU
+ @param frame_parms Pointer to Frame parameters
+ @param ulsch Pointer to ulsch descriptor
+ @param harq_pid HARQ process ID
+ @param tmode Transmission mode (1-7)
+ @param control_only_flag Generate PUSCH with control information only
+ @param Nbundled Parameter for ACK/NAK bundling (36.213 Section 7.3)
+*/
+uint32_t ulsch_encoding(uint8_t *a,
+ PHY_VARS_NR_UE *phy_vars_ue,
+ uint8_t harq_pid,
+ uint8_t eNB_id,
+ uint8_t subframe_rx,
+ uint8_t tmode,
+ uint8_t control_only_flag,
+ uint8_t Nbundled);
+
+void print_CQI(void *o,UCI_format_t uci_format,uint8_t eNB_id,int N_RB_DL);
+
+void fill_CQI(NR_UE_ULSCH_t *ulsch,PHY_NR_MEASUREMENTS *meas,uint8_t eNB_id, uint8_t harq_pid,int N_RB_DL, rnti_t rnti, uint8_t trans_mode,double sinr_eff);
+
+void reset_cba_uci(void *o);
+
+/** \brief This routine computes the subband PMI bitmap based on measurements (0,1,2,3 for rank 0 and 0,1 for rank 1) in the format needed for UCI
+ @param meas pointer to measurements
+ @param eNB_id eNB_id
+ @param nb_subbands number of subbands
+ @returns subband PMI bitmap
+*/
+uint16_t quantize_subband_pmi(PHY_NR_MEASUREMENTS *meas,uint8_t eNB_id,int nb_subbands);
+
+int32_t pmi_convert_rank1_from_rank2(uint16_t pmi_alloc, int tpmi, int nb_rb);
+
+uint16_t quantize_subband_pmi2(PHY_NR_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands);
+
+
+
+uint64_t cqi2hex(uint32_t cqi);
+
+uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
+
+
+/** \brief This routine extracts a single subband PMI from a bitmap coming from UCI or the pmi_extend function
+ @param N_RB_DL number of resource blocks
+ @param mimo_mode
+ @param pmi_alloc subband PMI bitmap
+ @param rb resource block for which to extract PMI
+ @returns subband PMI
+*/
+uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb);
+
+int get_nCCE_offset_l1(int *CCE_table,
+ const unsigned char L,
+ const int nCCE,
+ const int common_dci,
+ const unsigned short rnti,
+ const unsigned char subframe);
+
+uint16_t get_nCCE(uint8_t num_pdcch_symbols,NR_DL_FRAME_PARMS *frame_parms,uint8_t mi);
+
+uint16_t get_nquad(uint8_t num_pdcch_symbols,NR_DL_FRAME_PARMS *frame_parms,uint8_t mi);
+
+uint8_t get_mi(NR_DL_FRAME_PARMS *frame,uint8_t subframe);
+
+uint16_t get_nCCE_mac(uint8_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int subframe);
+
+uint8_t get_num_pdcch_symbols(uint8_t num_dci,DCI_ALLOC_t *dci_alloc,NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
+
+void pdcch_interleaving(NR_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi);
+
+void pdcch_unscrambling(NR_DL_FRAME_PARMS *frame_parms,
+ uint8_t subframe,
+ int8_t* llr,
+ uint32_t length);
+
+
+
+void dlsch_unscrambling(NR_DL_FRAME_PARMS *frame_parms,
+ int mbsfn_flag,
+ NR_UE_DLSCH_t *dlsch,
+ int G,
+ int16_t* llr,
+ uint8_t q,
+ uint8_t Ns);
+
+void init_ncs_cell(NR_DL_FRAME_PARMS *frame_parms,uint8_t ncs_cell[20][7]);
+
+void generate_pucch1x(int32_t **txdataF,
+ NR_DL_FRAME_PARMS *frame_parms,
+ uint8_t ncs_cell[20][7],
+ PUCCH_FMT_t fmt,
+ PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
+ uint16_t n1_pucch,
+ uint8_t shortened_format,
+ uint8_t *payload,
+ int16_t amp,
+ uint8_t subframe);
+
+void generate_pucch2x(int32_t **txdataF,
+ NR_DL_FRAME_PARMS *fp,
+ uint8_t ncs_cell[20][7],
+ PUCCH_FMT_t fmt,
+ PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
+ uint16_t n2_pucch,
+ uint8_t *payload,
+ int A,
+ int B2,
+ int16_t amp,
+ uint8_t subframe,
+ uint16_t rnti);
+
+void generate_pucch3x(int32_t **txdataF,
+ NR_DL_FRAME_PARMS *frame_parms,
+ uint8_t ncs_cell[20][7],
+ PUCCH_FMT_t fmt,
+ PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
+ uint16_t n3_pucch,
+ uint8_t shortened_format,
+ uint8_t *payload,
+ int16_t amp,
+ uint8_t subframe,
+ uint16_t rnti);
+
+
+void init_ulsch_power_LUT(void);
+
+/*!
+ \brief Check for PRACH TXop in subframe
+ @param frame_parms Pointer to NR_DL_FRAME_PARMS
+ @param frame frame index to check
+ @param subframe subframe index to check
+ @returns 0 on success
+*/
+int is_prach_subframe(NR_DL_FRAME_PARMS *frame_parms,frame_t frame, uint8_t subframe);
+
+/*!
+ \brief Generate PRACH waveform
+ @param phy_vars_ue Pointer to ue top-level descriptor
+ @param eNB_id Index of destination eNB
+ @param subframe subframe index to operate on
+ @param index of preamble (0-63)
+ @param Nf System frame number
+ @returns 0 on success
+
+*/
+int32_t generate_prach(PHY_VARS_NR_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe,uint16_t Nf);
+
+
+/*!
+ \brief Helper for MAC, returns number of available PRACH in TDD for a particular configuration index
+ @param frame_parms Pointer to NR_DL_FRAME_PARMS structure
+ @returns 0-5 depending on number of available prach
+*/
+uint8_t get_num_prach_tdd(module_id_t Mod_id);
+
+/*!
+ \brief Return the PRACH format as a function of the Configuration Index and Frame type.
+ @param prach_ConfigIndex PRACH Configuration Index
+ @param frame_type 0-FDD, 1-TDD
+ @returns 0-1 accordingly
+*/
+uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type);
+
+uint16_t get_nr_prach_fmt(int prach_ConfigIndex,lte_frame_type_t frame_type, nr_frequency_range_e fr);
+
+/*!
+ \brief Helper for MAC, returns frequency index of PRACH resource in TDD for a particular configuration index
+ @param frame_parms Pointer to NR_DL_FRAME_PARMS structure
+ @returns 0-5 depending on number of available prach
+*/
+uint8_t get_fid_prach_tdd(module_id_t Mod_id,uint8_t tdd_map_index);
+
+/*!
+ \brief Comp ute DFT of PRACH ZC sequences. Used for generation of prach in UE and reception of PRACH in eNB.
+ @param rootSequenceIndex PRACH root sequence
+ #param prach_ConfigIndex PRACH Configuration Index
+ @param zeroCorrelationZoneConfig PRACH ncs_config
+ @param highSpeedFlat PRACH High-Speed Flag
+ @param frame_type TDD/FDD flag
+ @param Xu DFT output
+*/
+void compute_prach_seq(uint16_t rootSequenceIndex,
+ uint8_t prach_ConfigIndex,
+ uint8_t zeroCorrelationZoneConfig,
+ uint8_t highSpeedFlag,
+ lte_frame_type_t frame_type,
+ uint32_t X_u[64][839]);
+
+
+void init_prach_tables(int N_ZC);
+
+void init_unscrambling_lut(void);
+void init_scrambling_lut(void);
+
+/*!
+ \brief Return the status of MBSFN in this frame/subframe
+ @param frame Frame index
+ @param subframe Subframe index
+ @param frame_parms Pointer to frame parameters
+ @returns 1 if subframe is for MBSFN
+*/
+int is_pmch_subframe(frame_t frame, int subframe, NR_DL_FRAME_PARMS *frame_parms);
+
+uint8_t is_not_pilot(uint8_t pilots, uint8_t re, uint8_t nushift, uint8_t use2ndpilots);
+
+uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode);
+
+uint32_t dlsch_decoding_abstraction(double *dlsch_MIPB,
+ NR_DL_FRAME_PARMS *lte_frame_parms,
+ NR_UE_DLSCH_t *dlsch,
+ uint8_t subframe,
+ uint8_t num_pdcch_symbols);
+
+// DL power control functions
+double get_pa_dB(uint8_t pa);
+
+
+double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
+ NR_UE_DLSCH_t *dlsch_ue,
+ uint8_t dl_power_off,
+ uint8_t n_antenna_port);
+
+double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
+ PDSCH_CONFIG_COMMON *pdsch_config_common,
+ uint8_t n_antenna_port,
+ NR_UE_DLSCH_t *dlsch_ue,
+ uint8_t dl_power_off);
+
+/*void compute_sqrt_RhoAoRhoB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
+ PDSCH_CONFIG_COMMON *pdsch_config_common,
+ uint8_t n_antenna_port,
+ NR_UE_DLSCH_t *dlsch_ue);
+*/
+
+uint8_t get_prach_prb_offset(NR_DL_FRAME_PARMS *frame_parms,
+ uint8_t prach_ConfigIndex,
+ uint8_t n_ra_prboffset,
+ uint8_t tdd_mapindex, uint16_t Nf);
+
+void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t nr_tti_rx,
+ int16_t *z, uint32_t length, uint16_t pdcch_DMRS_scrambling_id, int do_common);
+
+
+uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset);
+
+int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
+ PDSCH_t type,
+ unsigned char eNB_id,
+ unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
+ uint32_t frame,
+ uint8_t nr_tti_rx,
+ unsigned char symbol,
+ unsigned char first_symbol_flag,
+ RX_type_t rx_type,
+ unsigned char i_mod,
+ unsigned char harq_pid);
+
+uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) ;
+
+uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
+ short *dlsch_llr,
+ NR_DL_FRAME_PARMS *frame_parms,
+ NR_UE_DLSCH_t *dlsch,
+ NR_DL_UE_HARQ_t *harq_process,
+ uint32_t frame,
+ uint16_t nb_symb_sch,
+ uint8_t nr_tti_rx,
+ uint8_t harq_pid,
+ uint8_t is_crnti,
+ uint8_t llr8_flag);
+
+/**@}*/
+#endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
index 76a2b2b075..7ff52ae692 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
@@ -32,9 +32,9 @@
#include "PHY/defs_gNB.h"
-void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch);
+void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch,uint8_t N_RB_UL);
-NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag);
+NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint16_t N_RB_UL, uint8_t abstraction_flag);
/*! \brief Perform PUSCH decoding. TS 38.212 V15.4.0 subclause 6.2
@@ -53,12 +53,11 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t UE_id,
short *ulsch_llr,
NR_DL_FRAME_PARMS *frame_parms,
+ nfapi_nr_pusch_pdu_t *pusch_pdu,
uint32_t frame,
- uint16_t nb_symb_sch,
- uint16_t nb_re_dmrs,
uint8_t nr_tti_rx,
uint8_t harq_pid,
- uint8_t is_crnti);
+ uint32_t G);
/*! \brief Perform PUSCH unscrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index c58941b077..e8a961360f 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -57,29 +57,45 @@ static uint64_t nb_error_decod =0;
//extern double cpuf;
-void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr) {
+void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr,uint8_t N_RB_UL)
+{
+
int i,r;
+ uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated
NR_gNB_ULSCH_t *ulsch = *ulschptr;
if (ulsch) {
+ if (N_RB_UL != 273) {
+ a_segments = a_segments*N_RB_UL;
+ a_segments = a_segments/273;
+ }
+
+ uint16_t ulsch_bytes = a_segments*1056; // allocated bytes per segment
+
for (i=0; iharq_processes[i]) {
if (ulsch->harq_processes[i]->b) {
- free16(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES);
+ free16(ulsch->harq_processes[i]->b,ulsch_bytes);
ulsch->harq_processes[i]->b = NULL;
}
- for (r=0; rharq_processes[i]->c[r],(8448)*sizeof(uint8_t));
ulsch->harq_processes[i]->c[r] = NULL;
}
- for (r=0; rharq_processes[i]->d[r]) {
free16(ulsch->harq_processes[i]->d[r],(68*384)*sizeof(int16_t));
ulsch->harq_processes[i]->d[r] = NULL;
}
}
- for (r=0; r<(MAX_NUM_NR_ULSCH_SEGMENTS); r++) {
+ for (r=0; rharq_processes[i]->w[r]) {
+ free16(ulsch->harq_processes[i]->w[r],(3*(6144+64))*sizeof(int16_t));
+ ulsch->harq_processes[i]->w[r] = NULL;
+ }
+ }
+ for (r=0; rharq_processes[i]->p_nrLDPC_procBuf[r]){
nrLDPC_free_mem(ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]);
ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL;
@@ -95,23 +111,20 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr) {
}
-NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag)
+NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint16_t N_RB_UL, uint8_t abstraction_flag)
{
NR_gNB_ULSCH_t *ulsch;
uint8_t exit_flag = 0,i,r;
- unsigned char bw_scaling =1;
+ uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated
- switch (N_RB_UL) {
- case 106:
- bw_scaling =2;
- break;
-
- default:
- bw_scaling =1;
- break;
+ if (N_RB_UL != 273) {
+ a_segments = a_segments*N_RB_UL;
+ a_segments = a_segments/273;
}
+ uint16_t ulsch_bytes = a_segments*1056; // allocated bytes per segment
+
ulsch = (NR_gNB_ULSCH_t *)malloc16(sizeof(NR_gNB_ULSCH_t));
if (ulsch) {
@@ -129,15 +142,15 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8
memset(ulsch->harq_processes[i],0,sizeof(NR_UL_gNB_HARQ_t));
- ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
+ ulsch->harq_processes[i]->b = (uint8_t*)malloc16(ulsch_bytes);
if (ulsch->harq_processes[i]->b)
- memset(ulsch->harq_processes[i]->b,0,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
+ memset(ulsch->harq_processes[i]->b,0,ulsch_bytes);
else
exit_flag=3;
if (abstraction_flag == 0) {
- for (r=0; rharq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
@@ -154,6 +167,13 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8
memset(ulsch->harq_processes[i]->d[r],0,(68*384)*sizeof(int16_t));
else
exit_flag=2;
+
+ ulsch->harq_processes[i]->w[r] = (int16_t*)malloc16((3*(6144+64))*sizeof(int16_t));
+
+ if (ulsch->harq_processes[i]->w[r])
+ memset(ulsch->harq_processes[i]->w[r],0,(3*(6144+64))*sizeof(int16_t));
+ else
+ exit_flag=2;
}
}
} else {
@@ -164,9 +184,8 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8
if (exit_flag==0)
return(ulsch);
}
-
printf("new_gNB_ulsch with size %zu: exit_flag = %hhu\n",sizeof(NR_UL_gNB_HARQ_t), exit_flag);
- free_gNB_ulsch(&ulsch);
+ free_gNB_ulsch(&ulsch,N_RB_UL);
return(NULL);
}
@@ -262,7 +281,7 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
/// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
//uint8_t h[MAX_NUM_CHANNEL_BITS];
/// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
- //int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
+ //int16_t w[MAX_NUM_NR_ULSCH_SEGMENTS][3*(6144+64)];
}
}
}
@@ -276,15 +295,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t UE_id,
short *ulsch_llr,
NR_DL_FRAME_PARMS *frame_parms,
+ nfapi_nr_pusch_pdu_t *pusch_pdu,
uint32_t frame,
- uint16_t nb_symb_sch,
- uint16_t nb_re_dmrs,
uint8_t nr_tti_rx,
uint8_t harq_pid,
- uint8_t is_crnti)
-{
+ uint32_t G) {
+
uint32_t A,E;
- uint32_t G;
uint32_t ret, offset;
int32_t no_iteration_ldpc, length_dec;
uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0;
@@ -298,7 +315,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
- nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &harq_process->ulsch_pdu.ulsch_pdu_rel15;
t_nrLDPC_dec_params decParams;
t_nrLDPC_dec_params* p_decParams = &decParams;
@@ -318,13 +334,11 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
double Coderate = 0.0;
// ------------------------------------------------------------------
- uint16_t nb_rb = nfapi_ulsch_pdu_rel15->number_rbs;
- uint16_t number_symbols = nfapi_ulsch_pdu_rel15->number_symbols;
- uint8_t Qm = nfapi_ulsch_pdu_rel15->Qm;
- uint16_t R = nfapi_ulsch_pdu_rel15->R;
- uint8_t mcs = nfapi_ulsch_pdu_rel15->mcs;
- uint8_t n_layers = nfapi_ulsch_pdu_rel15->n_layers;
- uint8_t length_dmrs = nfapi_ulsch_pdu_rel15->length_dmrs;
+ uint16_t nb_rb = pusch_pdu->rb_size;
+ uint8_t Qm = pusch_pdu->qam_mod_order;
+ uint16_t R = pusch_pdu->target_code_rate;
+ uint8_t mcs = pusch_pdu->mcs_index;
+ uint8_t n_layers = pusch_pdu->nrOfLayers;
// ------------------------------------------------------------------
uint32_t i,j;
@@ -344,19 +358,20 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
}
// harq_process->trials[nfapi_ulsch_pdu_rel15->round]++;
- harq_process->TBS = nr_compute_tbs(Qm, R, nb_rb, number_symbols, nb_re_dmrs*length_dmrs, 0, n_layers);
+ harq_process->TBS = pusch_pdu->pusch_data.tb_size;
- A = harq_process->TBS;
+ A = (harq_process->TBS)<<3;
ret = ulsch->max_ldpc_iterations + 1;
- G = nr_get_G(nb_rb, number_symbols, nb_re_dmrs, length_dmrs, Qm, n_layers);
-
- LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d, nb_re_dmrs %d, Qm %d, n_layers %d\n",harq_pid,A,G, mcs, n_layers, nb_symb_sch,nb_rb, nb_re_dmrs, Qm, n_layers);
+ LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d\n",harq_pid,A,G, mcs, n_layers, nb_rb, Qm, n_layers);
if (harq_process->round == 0) {
// This is a new packet, so compute quantities regarding segmentation
- harq_process->B = A+24;
+ if (A > 3824)
+ harq_process->B = A+24;
+ else
+ harq_process->B = A+16;
if (R<1024)
Coderate = (float) R /(float) 1024;
@@ -393,20 +408,20 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
}
}
- // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
- nr_segmentation(NULL,
- NULL,
- harq_process->B,
- &harq_process->C,
- &harq_process->K,
- &harq_process->Z, // [hna] Z is Zc
- &harq_process->F,
- p_decParams->BG);
+ // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
+ nr_segmentation(NULL,
+ NULL,
+ harq_process->B,
+ &harq_process->C,
+ &harq_process->K,
+ &harq_process->Z, // [hna] Z is Zc
+ &harq_process->F,
+ p_decParams->BG);
#ifdef DEBUG_ULSCH_DECODING
printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
if (!frame%100)
- printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, harq_process->Nl);
+ printf("K %d C %d Z %d\n", harq_process->K, harq_process->C, harq_process->Z);
#endif
}
p_decParams->Z = harq_process->Z;
@@ -418,21 +433,15 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
err_flag = 0;
r_offset = 0;
- unsigned char bw_scaling =1;
+ uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated
- switch (frame_parms->N_RB_UL) {
-
- case 106:
- bw_scaling =2;
- break;
-
- default:
- bw_scaling =1;
- break;
+ if (nb_rb != 273) {
+ a_segments = a_segments*nb_rb;
+ a_segments = a_segments/273;
}
- if (harq_process->C > MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling) {
- LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling);
+ if (harq_process->C > a_segments) {
+ LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
return (ulsch->max_ldpc_iterations + 1);
}
#ifdef DEBUG_ULSCH_DECODING
@@ -447,7 +456,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
K_bytes_F = Kr_bytes-(harq_process->F>>3);
for (r=0; rC; r++) {
- E = nr_get_E(G, harq_process->C, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers, r);
+ E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
#if gNB_TIMING_TRACE
start_meas(ulsch_deinterleaving_stats);
@@ -460,7 +469,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
//////////////////////////// ulsch_llr =====> harq_process->e //////////////////////////////
nr_deinterleaving_ldpc(E,
- nfapi_ulsch_pdu_rel15->Qm,
+ Qm,
harq_process->e[r],
ulsch_llr+r_offset);
@@ -480,10 +489,10 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
harq_pid,r, G,
Kr*3,
harq_process->TBS,
- nfapi_ulsch_pdu_rel15->Qm,
- nfapi_ulsch_pdu_rel15->number_rbs,
- nfapi_ulsch_pdu_rel15->n_layers,
- nfapi_ulsch_pdu_rel15->rv,
+ Qm,
+ nb_rb,
+ n_layers,
+ pusch_pdu->pusch_data.rv_index,
harq_process->round);
#endif
//////////////////////////////////////////////////////////////////////////////////////////
@@ -495,7 +504,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
///////////////////////// harq_process->e =====> harq_process->d /////////////////////////
- Tbslbrm = nr_compute_tbslbrm(0,nb_rb,nfapi_ulsch_pdu_rel15->n_layers,harq_process->C);
+ Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers,harq_process->C);
if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm,
@@ -504,9 +513,11 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
harq_process->d[r],
harq_process->e[r],
harq_process->C,
- nfapi_ulsch_pdu_rel15->rv,
+ pusch_pdu->pusch_data.rv_index,
(harq_process->round==0)?1:0,
- E)==-1) {
+ E,
+ harq_process->F,
+ Kr-harq_process->F-2*(p_decParams->Z))==-1) {
#if gNB_TIMING_TRACE
stop_meas(ulsch_rate_unmatching_stats);
#endif
@@ -539,7 +550,11 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
// printf("done\n");
if (harq_process->C == 1) {
- crc_type = CRC24_A;
+ if (A > 3824)
+ crc_type = CRC24_A;
+ else
+ crc_type = CRC16;
+
length_dec = harq_process->B;
}
else {
@@ -564,7 +579,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
}
AssertFatal(kc!=255,"");
- for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) {
+ j+=(harq_process->F>>3);
+ // for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) {
+ for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) {
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
}
@@ -636,7 +653,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
int32_t tti_rx_prev = nr_tti_rx - 1;
if (tti_rx_prev < 0) {
frame_rx_prev--;
- tti_rx_prev += 10*frame_parms->ttis_per_subframe;
+ tti_rx_prev += frame_parms->slots_per_frame;
}
frame_rx_prev = frame_rx_prev%1024;
@@ -660,13 +677,11 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
ulsch->harq_mask &= ~(1 << harq_pid);
}
- if(is_crnti) {
- LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
- phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
- }
+ // LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
+ // phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
harq_process->handled = 1;
- return (ulsch->max_ldpc_iterations + 1);
+ ret = ulsch->max_ldpc_iterations + 1;
} else {
@@ -683,31 +698,28 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
// harq_process->harq_ack.harq_id = harq_pid;
// harq_process->harq_ack.send_harq_status = 1;
- if(is_crnti)
- {
- LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
- }
- }
-
- // Reassembly of Transport block here
- offset = 0;
- Kr = harq_process->K;
- Kr_bytes = Kr>>3;
-
- for (r=0; rC; r++) {
-
- memcpy(harq_process->b+offset,
- harq_process->c[r],
- Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
-
- offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
+ // LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
+ // Reassembly of Transport block here
+ offset = 0;
+ Kr = harq_process->K;
+ Kr_bytes = Kr>>3;
+
+ for (r=0; rC; r++) {
+
+ memcpy(harq_process->b+offset,
+ harq_process->c[r],
+ Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
+
+ offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
+
#ifdef DEBUG_ULSCH_DECODING
- printf("Segment %u : Kr = %u bytes\n", r, Kr_bytes);
- printf("copied %d bytes to b sequence (harq_pid %d)\n", (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)), harq_pid);
- printf("b[0] = %x, c[%d] = %x\n", harq_process->b[offset], harq_process->F>>3, harq_process->c[r]);
+ printf("Segment %u : Kr = %u bytes\n", r, Kr_bytes);
+ printf("copied %d bytes to b sequence (harq_pid %d)\n", (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)), harq_pid);
+ printf("b[0] = %x, c[%d] = %x\n", harq_process->b[offset], harq_process->F>>3, harq_process->c[r]);
#endif
-
+
+ }
}
#ifdef DEBUG_ULSCH_DECODING
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index 93cb721f36..bce8ddcc29 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -222,18 +222,13 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
}
+
void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
- unsigned short start_rb,
- unsigned short nb_rb_pusch,
- uint16_t n_rnti,
- NR_DL_FRAME_PARMS *frame_parms,
- uint16_t number_symbols,
- uint8_t mapping_type,
- uint8_t ptrs_configured,
- dmrs_UplinkConfig_t *dmrs_UplinkConfig,
- ptrs_UplinkConfig_t *ptrs_Uplink_Config)
+ uint8_t is_dmrs_symbol,
+ nfapi_nr_pusch_pdu_t *pusch_pdu,
+ NR_DL_FRAME_PARMS *frame_parms)
{
unsigned short start_re, re, nb_re_pusch;
unsigned char aarx;
@@ -243,27 +238,28 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
uint32_t ul_ch0_index = 0;
uint32_t ul_ch0_ptrs_ext_index = 0;
uint32_t ul_ch0_ptrs_index = 0;
- uint8_t is_dmrs_symbol_flag, is_ptrs_symbol_flag,k_prime;
+ uint8_t is_ptrs_symbol_flag,k_prime;
uint16_t n=0, num_ptrs_symbols;
int16_t *rxF,*rxF_ext;
int *ul_ch0,*ul_ch0_ext;
int *ul_ch0_ptrs,*ul_ch0_ptrs_ext;
+ uint16_t n_rnti = pusch_pdu->rnti;
+ uint8_t delta = 0;
#ifdef DEBUG_RB_EXT
printf("--------------------symbol = %d-----------------------\n", symbol);
- printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * nb_rb_pusch);
+ printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size);
#endif
- start_re = (frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size;
-
- nb_re_pusch = NR_NB_SC_PER_RB * nb_rb_pusch;
- is_dmrs_symbol_flag = 0;
+ uint8_t is_dmrs_re;
+ start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size;
+ nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size;
is_ptrs_symbol_flag = 0;
num_ptrs_symbols = 0;
- K_ptrs = get_K_ptrs(ptrs_Uplink_Config, nb_rb_pusch);
+ K_ptrs = (pusch_pdu->pusch_ptrs.ptrs_freq_density)?4:2;
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
@@ -283,30 +279,24 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
for (re = 0; re < nb_re_pusch; re++) {
- is_dmrs_symbol_flag = is_dmrs_symbol(symbol,
- (start_re + re)%frame_parms->ofdm_symbol_size,
- start_re,
- k_prime,
- n,
- 0,
- number_symbols,
- dmrs_UplinkConfig,
- mapping_type,
- frame_parms->ofdm_symbol_size);
+ if (is_dmrs_symbol)
+ is_dmrs_re = (re == get_dmrs_freq_idx_ul(n, k_prime, delta, pusch_pdu->dmrs_config_type));
+ else
+ is_dmrs_re = 0;
- if (ptrs_configured == 1){
+ if ( ((pusch_pdu->pdu_bit_map)>>2)& 0x01 ) {
is_ptrs_symbol_flag = is_ptrs_symbol(symbol,
(start_re + re)%frame_parms->ofdm_symbol_size,
n_rnti,
- nb_rb_pusch,
- number_symbols,
+ pusch_pdu->rb_size,
+ pusch_pdu->nr_of_symbols,
aarx,
K_ptrs,
pusch_vars->ptrs_symbols,
start_re,
frame_parms->ofdm_symbol_size,
- dmrs_UplinkConfig->pusch_dmrs_type,
- ptrs_Uplink_Config);
+ pusch_pdu->dmrs_config_type,
+ pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset);
if (is_ptrs_symbol_flag == 1)
num_ptrs_symbols++;
@@ -317,7 +307,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
printf("re = %d, is_dmrs_symbol_flag = %d, symbol = %d\n", re, is_dmrs_symbol_flag, symbol);
#endif
- if ( is_dmrs_symbol_flag == 0 && is_ptrs_symbol_flag == 0) {
+ if ( is_dmrs_re == 0 && is_ptrs_symbol_flag == 0) {
rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
@@ -370,7 +360,7 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13
- for (aatx=0; aatx < frame_parms->nb_antenna_ports_eNB; aatx++) {
+ for (aatx=0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++) {
for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) {
ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*nb_rb*NR_NB_SC_PER_RB];
@@ -456,7 +446,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
- for (aatx=0; aatxnb_antenna_ports_eNB; aatx++)
+ for (aatx=0; aatxnb_antenna_ports_gNB; aatx++)
for (aarx=0; aarxnb_antennas_rx; aarx++) {
//clear average level
avg128U = vdupq_n_s32(0);
@@ -472,7 +462,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[2], ul_ch128[2]));
avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[3], ul_ch128[3]));
- if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) {
+ if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_gNB!=1)) {
ul_ch128+=4;
} else {
avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[4], ul_ch128[4]));
@@ -505,18 +495,17 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
}
void nr_ulsch_channel_compensation(int **rxdataF_ext,
- int **ul_ch_estimates_ext,
- int **ul_ch_mag,
- int **ul_ch_magb,
- int **rxdataF_comp,
- int **rho,
- NR_DL_FRAME_PARMS *frame_parms,
- unsigned char symbol,
- uint8_t is_dmrs_symbol,
- unsigned char mod_order,
- unsigned short nb_rb,
- unsigned char output_shift)
-{
+ int **ul_ch_estimates_ext,
+ int **ul_ch_mag,
+ int **ul_ch_magb,
+ int **rxdataF_comp,
+ int **rho,
+ NR_DL_FRAME_PARMS *frame_parms,
+ unsigned char symbol,
+ uint8_t is_dmrs_symbol,
+ unsigned char mod_order,
+ unsigned short nb_rb,
+ unsigned char output_shift) {
#ifdef DEBUG_CH_COMP
int16_t *rxF, *ul_ch;
@@ -818,7 +807,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
- if (frame_parms->nb_antenna_ports_eNB==1) { // 10 out of 12 so don't reduce size
+ if (frame_parms->nb_antenna_ports_gNB==1) { // 10 out of 12 so don't reduce size
nb_rb=1+(5*nb_rb/6);
}
else {
@@ -826,7 +815,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
}
}
- for (aatx=0; aatxnb_antenna_ports_eNB; aatx++) {
+ for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) {
if (mod_order == 4) {
QAM_amp128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10)
QAM_amp128b = vmovq_n_s16(0);
@@ -1039,172 +1028,148 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
uint8_t first_symbol_flag, aarx, aatx, dmrs_symbol_flag, ptrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol
uint32_t nb_re_pusch, bwp_start_subcarrier;
- uint8_t mapping_type;
uint8_t L_ptrs = 0; // PTRS parameter
int avgs;
int avg[4];
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
- nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15;
- ptrs_UplinkConfig_t *ptrs_Uplink_Config = &gNB->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
+ nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu;
dmrs_symbol_flag = 0;
ptrs_symbol_flag = 0;
first_symbol_flag = 0;
- mapping_type = gNB->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol = 0;
- if (mapping_type == typeB) {
+ if(symbol == rel15_ul->start_symbol_index){
+ gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0;
+ gNB->pusch_vars[UE_id]->dmrs_symbol = 0;
+ gNB->pusch_vars[UE_id]->cl_done = 0;
+ gNB->pusch_vars[UE_id]->ptrs_symbols = 0;
+ first_symbol_flag = 1;
- if(symbol == rel15_ul->start_symbol){
- gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0;
- gNB->pusch_vars[UE_id]->dmrs_symbol = 0;
- first_symbol_flag = 1;
-
- L_ptrs = get_L_ptrs(ptrs_Uplink_Config, rel15_ul->mcs);
-
- gNB->pusch_vars[UE_id]->ptrs_symbols = 0;
+ if ( ((rel15_ul->pdu_bit_map)>>2)& 0x01 ) { // if there is ptrs pdu
+ L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density);
set_ptrs_symb_idx(&gNB->pusch_vars[UE_id]->ptrs_symbols,
- ptrs_Uplink_Config,
- &gNB->pusch_config.dmrs_UplinkConfig,
- 1,
- rel15_ul->number_symbols,
- rel15_ul->start_symbol,
+ rel15_ul->nr_of_symbols,
+ rel15_ul->start_symbol_index,
+ rel15_ul->dmrs_config_type,
L_ptrs,
+ 1, // only dmrs of length 1 is currently supported
frame_parms->ofdm_symbol_size);
-
}
-
- bwp_start_subcarrier = (rel15_ul->start_rb*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
-
- dmrs_symbol_flag = is_dmrs_symbol(symbol,
- 0,
- 0,
- 0,
- 0,
- 0,
- rel15_ul->number_symbols,
- &gNB->pusch_config.dmrs_UplinkConfig,
- mapping_type,
- frame_parms->ofdm_symbol_size);
-
- if (dmrs_symbol_flag == 1){
- nb_re_pusch = rel15_ul->number_rbs * ((gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type==pusch_dmrs_type1)?6:8);
- gNB->pusch_vars[UE_id]->dmrs_symbol = symbol;
- } else {
- nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB;
- }
-
- if (gNB->ptrs_configured == 1)
- ptrs_symbol_flag = is_ptrs_symbol(symbol,
- 0,
- gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.rnti,
- rel15_ul->number_rbs,
- rel15_ul->number_symbols,
- 0,
- get_K_ptrs(ptrs_Uplink_Config, rel15_ul->number_rbs),
- gNB->pusch_vars[UE_id]->ptrs_symbols,
- 0,
- frame_parms->ofdm_symbol_size,
- gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type,
- ptrs_Uplink_Config);
-
-
- if (ptrs_symbol_flag == 1){
- gNB->pusch_vars[UE_id]->ptrs_symbol_index = symbol;
- }
-
-
- //----------------------------------------------------------
- //--------------------- Channel estimation ---------------------
- //----------------------------------------------------------
-
- if (dmrs_symbol_flag == 1)
- nr_pusch_channel_estimation(gNB,
- 0,
- nr_tti_rx,
- 0, // p
- symbol,
- bwp_start_subcarrier,
- rel15_ul->number_rbs,
- &gNB->pusch_config.dmrs_UplinkConfig);
-
- //----------------------------------------------------------
- //--------------------- RBs extraction ---------------------
- //----------------------------------------------------------
-
- nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
- gNB->pusch_vars[UE_id],
- symbol,
- rel15_ul->start_rb,
- rel15_ul->number_rbs,
- gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.rnti,
- frame_parms,
- rel15_ul->number_symbols,
- mapping_type,
- gNB->ptrs_configured,
- &gNB->pusch_config.dmrs_UplinkConfig,
- ptrs_Uplink_Config);
-
- nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
- frame_parms,
- gNB->ulsch[UE_id],
- symbol,
- dmrs_symbol_flag,
- rel15_ul->number_rbs,
- gNB->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type);
-
- if (first_symbol_flag==1) {
-
- nr_ulsch_channel_level(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
- frame_parms,
- avg,
- symbol,
- nb_re_pusch,
- rel15_ul->number_rbs);
- avgs = 0;
-
- for (aatx=0;aatxnb_antennas_tx;aatx++)
- for (aarx=0;aarxnb_antennas_rx;aarx++)
- avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
-
- gNB->pusch_vars[UE_id]->log2_maxh = (log2_approx(avgs)/2)+1;
-
- }
-
- nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext,
- gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
- gNB->pusch_vars[UE_id]->ul_ch_mag0,
- gNB->pusch_vars[UE_id]->ul_ch_magb0,
- gNB->pusch_vars[UE_id]->rxdataF_comp,
- (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[UE_id]->rho : NULL,
- frame_parms,
- symbol,
- dmrs_symbol_flag,
- rel15_ul->Qm,
- rel15_ul->number_rbs,
- gNB->pusch_vars[UE_id]->log2_maxh);
-
- #ifdef NR_SC_FDMA
- nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], nb_re_pusch);
- #endif
-
- //----------------------------------------------------------
- //-------------------- LLRs computation --------------------
- //----------------------------------------------------------
-
- nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB],
- gNB->pusch_vars[UE_id]->ul_ch_mag0,
- gNB->pusch_vars[UE_id]->ul_ch_magb0,
- &gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->Qm],
- rel15_ul->number_rbs,
- nb_re_pusch,
- symbol,
- rel15_ul->Qm);
-
- gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch - gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol;
- } else {
- LOG_E(PHY, "PUSCH mapping type A is not supported \n");
}
+
+ bwp_start_subcarrier = (rel15_ul->rb_start*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
+
+ dmrs_symbol_flag = ((rel15_ul->ul_dmrs_symb_pos)>>symbol)&0x01;
+
+ if (dmrs_symbol_flag == 1){
+ nb_re_pusch = rel15_ul->rb_size * ((rel15_ul->dmrs_config_type==pusch_dmrs_type1)?6:8);
+ gNB->pusch_vars[UE_id]->dmrs_symbol = symbol;
+ } else {
+ nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
+ }
+
+ if ( ((rel15_ul->pdu_bit_map)>>2)& 0x01 ) { // if there is ptrs pdu
+ ptrs_symbol_flag = is_ptrs_symbol(symbol,
+ 0,
+ rel15_ul->rnti,
+ rel15_ul->rb_size,
+ rel15_ul->nr_of_symbols,
+ 0,
+ (rel15_ul->pusch_ptrs.ptrs_freq_density)?4:2,
+ gNB->pusch_vars[UE_id]->ptrs_symbols,
+ 0,
+ frame_parms->ofdm_symbol_size,
+ rel15_ul->dmrs_config_type,
+ rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset);
+ }
+
+ if (ptrs_symbol_flag == 1){
+ gNB->pusch_vars[UE_id]->ptrs_symbol_index = symbol;
+ }
+
+
+ //----------------------------------------------------------
+ //--------------------- Channel estimation ---------------------
+ //----------------------------------------------------------
+
+ if (dmrs_symbol_flag == 1)
+ nr_pusch_channel_estimation(gNB,
+ nr_tti_rx,
+ 0, // p
+ symbol,
+ bwp_start_subcarrier,
+ rel15_ul);
+
+ //----------------------------------------------------------
+ //--------------------- RBs extraction ---------------------
+ //----------------------------------------------------------
+
+ nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
+ gNB->pusch_vars[UE_id],
+ symbol,
+ dmrs_symbol_flag,
+ rel15_ul,
+ frame_parms);
+
+ nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
+ frame_parms,
+ gNB->ulsch[UE_id],
+ symbol,
+ dmrs_symbol_flag,
+ rel15_ul->rb_size,
+ rel15_ul->dmrs_config_type);
+
+
+ if (first_symbol_flag==1) {
+
+ nr_ulsch_channel_level(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
+ frame_parms,
+ avg,
+ symbol,
+ nb_re_pusch,
+ rel15_ul->rb_size);
+ avgs = 0;
+
+ for (aatx=0;aatxnb_antennas_tx;aatx++)
+ for (aarx=0;aarxnb_antennas_rx;aarx++)
+ avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
+
+ gNB->pusch_vars[UE_id]->log2_maxh = (log2_approx(avgs)/2)+1;
+
+ }
+
+ nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext,
+ gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
+ gNB->pusch_vars[UE_id]->ul_ch_mag0,
+ gNB->pusch_vars[UE_id]->ul_ch_magb0,
+ gNB->pusch_vars[UE_id]->rxdataF_comp,
+ (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[UE_id]->rho : NULL,
+ frame_parms,
+ symbol,
+ dmrs_symbol_flag,
+ rel15_ul->qam_mod_order,
+ rel15_ul->rb_size,
+ gNB->pusch_vars[UE_id]->log2_maxh);
+
+#ifdef NR_SC_FDMA
+ nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch);
+#endif
+
+ //----------------------------------------------------------
+ //-------------------- LLRs computation --------------------
+ //----------------------------------------------------------
+
+ nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB],
+ gNB->pusch_vars[UE_id]->ul_ch_mag0,
+ gNB->pusch_vars[UE_id]->ul_ch_magb0,
+ &gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order],
+ rel15_ul->rb_size,
+ nb_re_pusch,
+ symbol,
+ rel15_ul->qam_mod_order);
+
+ gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch - gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol;
}
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
index 09dadabaa5..be5c754beb 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -206,9 +206,6 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
int ch_offset,symbol_offset;
//int slot_pbch;
- //fapi_nr_pbch_config_t *pbch_config = &ue->nrUE_config.pbch_config;
- // initialized to 5ms in nr_init_ue for scenarios where UE is not configured (otherwise acquired by cell configuration from gNB or LTE)
- //uint8_t ssb_periodicity = 10;// ue->ssb_periodicity;
//uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
@@ -452,7 +449,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
{
// do ifft of channel estimate
for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++)
- for (p=0; pframe_parms.nb_antenna_ports_eNB; p++) {
+ for (p=0; pframe_parms.nb_antenna_ports_gNB; p++) {
if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx])
{
LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, ue->current_thread_id[Ns], symbol, ch_offset);
@@ -475,7 +472,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
unsigned short coreset_start_subcarrier,
unsigned short nb_rb_coreset)
{
- int pilot[200] __attribute__((aligned(16)));
+
unsigned char aarx;
unsigned short k;
unsigned int pilot_cnt;
@@ -484,12 +481,9 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
//uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
- uint8_t nushift;
int **dl_ch_estimates =ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates;
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
- nushift = 1;
- ue->frame_parms.nushift = nushift;
if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
ch_offset = ue->frame_parms.ofdm_symbol_size ;
@@ -510,14 +504,15 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
fr = filt16a_r1;
- // generate pilot
+ // generate pilot
+ int pilot[nb_rb_coreset * 3] __attribute__((aligned(16)));
nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[0],2000,nb_rb_coreset);
for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) {
pil = (int16_t *)&pilot[0];
- rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
@@ -588,7 +583,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
if (k >= ue->frame_parms.ofdm_symbol_size){
k-=ue->frame_parms.ofdm_symbol_size;
- rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];}
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
@@ -622,7 +617,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PDCCH
- printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+ printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fr,
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index ba328e39ec..af06f9a98f 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -90,11 +90,6 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue,
uint32_t rx_power_fil_dB,
uint8_t eNB_id);
-/*! \brief Function to return the path-loss based on the UE cell-specific reference signal strength and transmission power of eNB
-@param Mod_id Module ID for UE
-@param eNB_index Index of eNB on which to act
-@returns Path loss in dB
- */
-int16_t nr_get_PL(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
+int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index);
#endif
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
index ac9713fec2..aa1e2b5ade 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
@@ -19,8 +19,6 @@
* contact@openairinterface.org
*/
-// this function fills the PHY_vars->PHY_measurement structure
-
#include "PHY/defs_nr_UE.h"
#include "PHY/phy_extern_nr_ue.h"
#include "common/utils/LOG/log.h"
@@ -57,649 +55,28 @@ void print_ints(char *s,int *x)
}
#endif
-int16_t nr_get_PL(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
+int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index)
{
- PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
/*
- int RSoffset;
-
-
if (ue->frame_parms.mode1_flag == 1)
RSoffset = 6;
else
RSoffset = 3;
*/
- /* LOG_D(PHY,"nr_get_PL : rsrp %f dBm/RE (%f), eNB power %d dBm/RE\n",
+ /* LOG_D(PHY,"get_nr_PL : rsrp %f dBm/RE (%f), eNB power %d dBm/RE\n",
(1.0*dB_fixed_times10(ue->measurements.rsrp[eNB_index])-(10.0*ue->rx_total_gain_dB))/10.0,
10*log10((double)ue->measurements.rsrp[eNB_index]),
ue->frame_parms.pdsch_config_common.referenceSignalPower);*/
- return((int16_t)(((10*ue->rx_total_gain_dB) -
- dB_fixed_times10(ue->measurements.rsrp[eNB_index]))/10));
+ return((int16_t)(((10*ue->rx_total_gain_dB) - dB_fixed_times10(ue->measurements.rsrp[gNB_index]))/10));
// dB_fixed_times10(RSoffset*12*ue_g[Mod_id][CC_id]->frame_parms.N_RB_DL) +
//(ue->frame_parms.pdsch_config_common.referenceSignalPower*10))/10));
}
-#if 0
-uint8_t get_n_adj_cells (module_id_t Mod_id,uint8_t CC_id)
-{
- PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
-
- if (ue)
- return ue->measurements.n_adj_cells;
- else
- return 0;
-}
-
-uint32_t get_rx_total_gain_dB (module_id_t Mod_id,uint8_t CC_id)
-{
-
- PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
-
- if (ue)
- return ue->rx_total_gain_dB;
-
- return 0xFFFFFFFF;
-}
-uint32_t get_RSSI (module_id_t Mod_id,uint8_t CC_id)
-{
-
- PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
-
- if (ue)
- return ue->measurements.rssi;
-
- return 0xFFFFFFFF;
-}
-double get_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
-{
-
- AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is null\n");
- AssertFatal(PHY_vars_UE_g[Mod_id]!=NULL,"PHY_vars_UE_g[%d] is null\n",Mod_id);
- AssertFatal(PHY_vars_UE_g[Mod_id][CC_id]!=NULL,"PHY_vars_UE_g[%d][%d] is null\n",Mod_id,CC_id);
-
- PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
-
- if (ue)
- return ((dB_fixed_times10(ue->measurements.rsrp[eNB_index]))/10.0-
- get_rx_total_gain_dB(Mod_id,0) -
- 10*log10(ue->frame_parms.N_RB_DL*12));
- return -140.0;
-}
-
-uint32_t get_RSRQ(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
-{
-
- PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
-
- if (ue)
- return ue->measurements.rsrq[eNB_index];
-
- return 0xFFFFFFFF;
-}
-
-int8_t set_RSRP_filtered(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,float rsrp)
-{
-
- PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
-
- if (ue) {
- ue->measurements.rsrp_filtered[eNB_index]=rsrp;
- return 0;
- }
-
- LOG_W(PHY,"[UE%d] could not set the rsrp\n",Mod_id);
- return -1;
-}
-
-int8_t set_RSRQ_filtered(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,float rsrq)
-{
-
- PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
-
- if (ue) {
- ue->measurements.rsrq_filtered[eNB_index]=rsrq;
- return 0;
- }
-
- LOG_W(PHY,"[UE%d] could not set the rsrq\n",Mod_id);
- return -1;
-
-}
-#endif
-
-#if 0
-void ue_rrc_measurements(PHY_VARS_UE *ue,
- uint8_t slot,
- uint8_t abstraction_flag)
-{
-
- uint8_t subframe = slot>>1;
- int aarx,rb;
- uint8_t pss_symb;
- uint8_t sss_symb;
-
- int32_t **rxdataF;
- int16_t *rxF,*rxF_pss,*rxF_sss;
-
- uint16_t Nid_cell = ue->frame_parms.Nid_cell;
- uint8_t eNB_offset,nu,l,nushift,k;
- uint16_t off;
- uint8_t previous_thread_id = ue->current_thread_id[subframe]==0 ? (RX_NB_TH-1):(ue->current_thread_id[subframe]-1);
-
- //uint8_t isPss; // indicate if this is a slot for extracting PSS
- //uint8_t isSss; // indicate if this is a slot for extracting SSS
- //int32_t pss_ext[4][72]; // contain the extracted 6*12 REs for mapping the PSS
- //int32_t sss_ext[4][72]; // contain the extracted 6*12 REs for mapping the SSS
- //int32_t (*xss_ext)[72]; // point to either pss_ext or sss_ext for common calculation
- //int16_t *re,*im; // real and imag part of each 32-bit xss_ext[][] value
-
- //LOG_I(PHY,"UE RRC MEAS Start Subframe %d Frame Type %d slot %d \n",subframe,ue->frame_parms.frame_type,slot);
- for (eNB_offset = 0; eNB_offset<1+ue->measurements.n_adj_cells; eNB_offset++) {
-
- if (eNB_offset==0) {
- ue->measurements.rssi = 0;
- //ue->measurements.n0_power_tot = 0;
-
- if (abstraction_flag == 0) {
- if ( ((ue->frame_parms.frame_type == FDD) && ((subframe == 0) || (subframe == 5))) ||
- ((ue->frame_parms.frame_type == TDD) && ((subframe == 1) || (subframe == 6)))
- )
- { // FDD PSS/SSS, compute noise in DTX REs
- if (ue->frame_parms.Ncp == NORMAL) {
- for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) {
- if(ue->frame_parms.frame_type == FDD)
- {
- rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)];
- rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
- }
- else
- {
- rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].rxdataF[aarx][(13*ue->frame_parms.ofdm_symbol_size)];
- rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(2*ue->frame_parms.ofdm_symbol_size)];
- }
- //-ve spectrum from SSS
-
- //+ve spectrum from SSS
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65]));
- // ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
- // printf("sssp32 %d\n",ue->measurements.n0_power[aarx]);
- //+ve spectrum from PSS
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+70]*rxF_pss[2+70])+((int32_t)rxF_pss[2+69]*rxF_pss[2+69]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+68]*rxF_pss[2+68])+((int32_t)rxF_pss[2+67]*rxF_pss[2+67]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+66]*rxF_pss[2+66])+((int32_t)rxF_pss[2+65]*rxF_pss[2+65]));
- // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+64]*rxF_pss[2+64])+((int32_t)rxF_pss[2+63]*rxF_pss[2+63]));
- // printf("pss32 %d\n",ue->measurements.n0_power[aarx]); //-ve spectrum from PSS
- if(ue->frame_parms.frame_type == FDD)
- {
- rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
- rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
- }
- else
- {
- rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].rxdataF[aarx][(14*ue->frame_parms.ofdm_symbol_size)];
- rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(3*ue->frame_parms.ofdm_symbol_size)];
- }
- // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
- // printf("pssm36 %d\n",ue->measurements.n0_power[aarx]);
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
-
- ue->measurements.n0_power[aarx] = (((int32_t)rxF_sss[-70]*rxF_sss[-70])+((int32_t)rxF_sss[-69]*rxF_sss[-69]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[-68]*rxF_sss[-68])+((int32_t)rxF_sss[-67]*rxF_sss[-67]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[-66]*rxF_sss[-66])+((int32_t)rxF_sss[-65]*rxF_sss[-65]));
-
- // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
- // printf("pssm32 %d\n",ue->measurements.n0_power[aarx]);
- ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12);
- ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx];
- }
-
- //LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot);
-
- ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx));
- ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size);
- } else {
- LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length == EXTENDED\n");
- }
- }
- else if ((ue->frame_parms.frame_type == TDD) &&
- ((subframe == 1) || (subframe == 6))) { // TDD PSS/SSS, compute noise in DTX REs // 2016-09-29 wilson fix incorrect noise power calculation
-
-
- pss_symb = 2;
- sss_symb = ue->frame_parms.symbols_per_tti-1;
- if (ue->frame_parms.Ncp==NORMAL) {
- for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) {
-
- rxdataF = ue->common_vars.common_vars_rx_data_per_thread[(ue->current_thread_id[subframe])].rxdataF;
- rxF_pss = (int16_t *) &rxdataF[aarx][((pss_symb*(ue->frame_parms.ofdm_symbol_size)))];
-
- rxdataF = ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].rxdataF;
- rxF_sss = (int16_t *) &rxdataF[aarx][((sss_symb*(ue->frame_parms.ofdm_symbol_size)))];
-
- //-ve spectrum from SSS
- // printf("slot %d: SSS DTX: %d,%d, non-DTX %d,%d\n",slot,rxF_pss[-72],rxF_pss[-71],rxF_pss[-36],rxF_pss[-35]);
-
- // ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
- // printf("sssn36 %d\n",ue->measurements.n0_power[aarx]);
- ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
- // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
- // printf("sssm32 %d\n",ue->measurements.n0_power[aarx]);
- //+ve spectrum from SSS
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65]));
- // ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
- // printf("sssp32 %d\n",ue->measurements.n0_power[aarx]);
- //+ve spectrum from PSS
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+70]*rxF_pss[2+70])+((int32_t)rxF_pss[2+69]*rxF_pss[2+69]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+68]*rxF_pss[2+68])+((int32_t)rxF_pss[2+67]*rxF_pss[2+67]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+66]*rxF_pss[2+66])+((int32_t)rxF_pss[2+65]*rxF_pss[2+65]));
- // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+64]*rxF_pss[2+64])+((int32_t)rxF_pss[2+63]*rxF_pss[2+63]));
- // printf("pss32 %d\n",ue->measurements.n0_power[aarx]); //-ve spectrum from PSS
- rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
- // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
- // printf("pssm36 %d\n",ue->measurements.n0_power[aarx]);
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
- ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
- // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
- // printf("pssm32 %d\n",ue->measurements.n0_power[aarx]);
- ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12);
- ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx];
- }
-
- ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx));
- ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size);
-
- //LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot);
-
- }
- }
- }
- }
- // recompute nushift with eNB_offset corresponding to adjacent eNB on which to perform channel estimation
- // printf("[PHY][UE %d] Frame %d slot %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, Nid2 %d, nushift %d, eNB_offset %d)\n",ue->Mod_id,ue->frame,slot,Nid_cell,Nid2,nushift,eNB_offset);
- if (eNB_offset > 0)
- Nid_cell = ue->measurements.adj_cell_id[eNB_offset-1];
-
-
- nushift = Nid_cell%6;
-
-
-
- ue->measurements.rsrp[eNB_offset] = 0;
-
-
- if (abstraction_flag == 0) {
-
- // compute RSRP using symbols 0 and 4-frame_parms->Ncp
-
- for (l=0,nu=0; l<=(4-ue->frame_parms.Ncp); l+=(4-ue->frame_parms.Ncp),nu=3) {
- k = (nu + nushift)%6;
- //#ifdef DEBUG_MEAS_RRC
- LOG_D(PHY,"[UE %d] Frame %d subframe %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, nushift %d, eNB_offset %d, k %d, l %d)\n",ue->Mod_id,ue->proc.proc_rxtx[subframe&1].frame_rx,subframe,Nid_cell,nushift,
- eNB_offset,k,l);
- //#endif
-
- for (aarx=0; aarx