From fa356620445b2aee53377c5d30873c193704a1c4 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Tue, 17 Nov 2020 14:10:10 +0100 Subject: [PATCH 01/27] 10 MHz config file --- .../CONF/testing_gnb_24PRB.conf | 297 ++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf new file mode 100644 index 0000000000..df1aa852e4 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf @@ -0,0 +1,297 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 222; mnc = 01; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 31; //0; + pdsch_AntennaPorts = 1; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 12 PRBs@30kHz SCS + absoluteFrequencySSB = 640288; + 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 = 24; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6325; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57) + initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 24; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6325; +# 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 = -100; +#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 = 5; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; //15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 2; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 2; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + + 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; #0x80; + +# 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; //8; //7; + nrofDownlinkSymbols = 6; //0; //6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; //0; //4; + + ssPBCH_BlockPower = -25; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.18.99"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "192.168.18.199"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.198/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.198/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + GNB_IPV4_ADDRESS_FOR_X2C = "192.168.18.198/24"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + clock_src = "external"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + //parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + From 450f98228ab1cd27fe5fbe570d794bd8af404e6c Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 18 Nov 2020 17:21:30 +0100 Subject: [PATCH 02/27] 10 MHz USRP n300 config file --- .../CONF/gnb.band78.tm1.24PRB.usrpn300.conf | 283 ++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf new file mode 100644 index 0000000000..75b2b6c27d --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf @@ -0,0 +1,283 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 640288; + 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 = 24; + #initialDownlinkBWP + #genericParameters + # this is RBstart=41,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6325; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=5 + initialDLBWPstartSymbolAndLength_3 = 57; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 24; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6325; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 6; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + + 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; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; + clock_src = "external"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + From 6a0ec688c9fd3f4ad89e7fd82ff27a17c23efed7 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 18 Nov 2020 17:29:24 +0100 Subject: [PATCH 03/27] modifications in RRC for lower number of RBs --- openair2/RRC/NR/rrc_gNB_reconfig.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index a9e27da95d..68710ed2bc 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -412,12 +412,21 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=NULL; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet)); + int curr_bwp = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); + NR_ControlResourceSet_t *coreset = calloc(1,sizeof(*coreset)); coreset->controlResourceSetId=1; - // frequencyDomainResources '11111111 11111111 00000000 00000000 00000000 00000'B, + // frequency domain resources depends on BWP size + // options are 24, 48 or 96 coreset->frequencyDomainResources.buf = calloc(1,6); - coreset->frequencyDomainResources.buf[0] = 0xff; - coreset->frequencyDomainResources.buf[1] = 0xff; + if (curr_bwp < 48) + coreset->frequencyDomainResources.buf[0] = 0xf0; + else + coreset->frequencyDomainResources.buf[0] = 0xff; + if (curr_bwp < 96) + coreset->frequencyDomainResources.buf[1] = 0; + else + coreset->frequencyDomainResources.buf[1] = 0xff; coreset->frequencyDomainResources.buf[2] = 0; coreset->frequencyDomainResources.buf[3] = 0; coreset->frequencyDomainResources.buf[4] = 0; @@ -531,7 +540,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ss2->nrofCandidates=calloc(1,sizeof(*ss2->nrofCandidates)); ss2->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; ss2->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; - ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n4; + if (curr_bwp < 48) + ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; + else if (curr_bwp < 96) + ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2; + else + ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n4; ss2->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; ss2->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; ss2->searchSpaceType=calloc(1,sizeof(*ss2->searchSpaceType)); @@ -915,7 +929,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2)); NR_PUCCH_Resource_t *pucchres3=calloc(1,sizeof(*pucchres3)); pucchres0->pucch_ResourceId=1; - pucchres0->startingPRB=48; + pucchres0->startingPRB=8; pucchres0->intraSlotFrequencyHopping=NULL; pucchres0->secondHopPRB=NULL; pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0; @@ -926,7 +940,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0); pucchres1->pucch_ResourceId=2; - pucchres1->startingPRB=48; + pucchres1->startingPRB=8; pucchres1->intraSlotFrequencyHopping=NULL; pucchres1->secondHopPRB=NULL; pucchres1->format.present= NR_PUCCH_Resource__format_PR_format0; @@ -937,7 +951,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres1); pucchres2->pucch_ResourceId=3; - pucchres2->startingPRB=40; + pucchres2->startingPRB=0; pucchres2->intraSlotFrequencyHopping=NULL; pucchres2->secondHopPRB=NULL; pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2; @@ -948,7 +962,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2); pucchres3->pucch_ResourceId=4; - pucchres3->startingPRB=40; + pucchres3->startingPRB=0; pucchres3->intraSlotFrequencyHopping=NULL; pucchres3->secondHopPRB=NULL; pucchres3->format.present= NR_PUCCH_Resource__format_PR_format2; From 78e0af5893b0596ef449fe00e407d706d7b8b5a2 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 18 Nov 2020 17:45:05 +0100 Subject: [PATCH 04/27] adding 10MHz option (values to be verified) --- executables/nr-ru.c | 9 +++++++++ openair1/PHY/INIT/nr_parms.c | 8 +++++++- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index feff0c29c2..7d4e3607df 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1113,6 +1113,15 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->tx_bw = 40e6; cfg->rx_bw = 40e6; } + } else if(N_RB == 24) { + if (fp->threequarter_fs) { + AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 24\n"); + } else { + cfg->sample_rate=15.36e6; + cfg->samples_per_frame = 153600; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } } else { AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); } diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 92d8c2a1c6..db7a30183b 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -108,6 +108,12 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) switch(bw){ case 5: + case 10: + fp->ofdm_symbol_size = 512; + fp->first_carrier_offset = 368; //512 - ( (24*12) / 2 ) + fp->nb_prefix_samples0 = 44; + fp->nb_prefix_samples = 36; + break; case 15: case 20: case 25: @@ -200,7 +206,7 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) break; case 50: fp->ofdm_symbol_size = 512; - fp->first_carrier_offset = 320; //1024 - ( (66*12) / 2 ) + fp->first_carrier_offset = 320; //512 - ( (32*12) / 2 ) fp->nb_prefix_samples0 = 68; fp->nb_prefix_samples = 36; break; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 9ad0afba85..3ab58c35a7 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -379,6 +379,7 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size switch (gNB->frame_parms.N_RB_DL) { + case 24: timing_advance_update /= 4; break; case 106: timing_advance_update /= 16; break; case 217: timing_advance_update /= 32; break; case 245: timing_advance_update /= 32; break; From 8ac98d553f573272a5eaa08953021f8bf9892702 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Mon, 2 Nov 2020 14:19:14 +0100 Subject: [PATCH 05/27] first version of PRACH for FR2. to be tested --- openair1/PHY/INIT/nr_init.c | 17 +- openair1/PHY/NR_TRANSPORT/nr_prach.c | 259 +++++++++++++----------- openair1/PHY/NR_UE_TRANSPORT/nr_prach.c | 224 ++++++++++++++++---- openair1/SIMULATION/NR_PHY/prachsim.c | 25 ++- 4 files changed, 352 insertions(+), 173 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 80469f3e81..49ec60c94b 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -431,11 +431,18 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, //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; - + if (mu==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; + } else if (mu==3) { + fp->dl_CarrierFreq = 27524520000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); + fp->ul_CarrierFreq = 27524520000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); + fp->nr_band = 261; + // 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); diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index ba0705cde7..3c4a1a41ff 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -188,7 +188,7 @@ void rx_nr_prach_ru(RU_t *ru, prach[aa] = (int16_t*)&ru->common.rxdata[aa][(slot2*fp->get_samples_per_slot(slot,fp))+sample_offset_slot-ru->N_TA_offset]; } - + idft_size_idx_t dftsize; int dftlen=0; int mu = fp->numerology_index; int Ncp = 0; @@ -269,7 +269,8 @@ void rx_nr_prach_ru(RU_t *ru, if (LOG_DEBUGFLAG(PRACH)) { LOG_D(PHY,"rx_prach: Doing PRACH FFT for nb_rx:%d Ncp:%d\n",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; @@ -299,6 +300,7 @@ void rx_nr_prach_ru(RU_t *ru, AssertFatal(prach[aa]!=NULL,"prach[%d] is null\n",aa); // do DFT + if (mu==1) { 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) { @@ -327,36 +329,29 @@ void rx_nr_prach_ru(RU_t *ru, } }// 839 sequence else { - if ((mu==0 && - (prachStartSymbol == 0 || prachStartSymbol == 7)) || - (mu==1 && prachStartSymbol == 0)) prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only) + if (prachStartSymbol == 0) + prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only) - if (mu==0) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==1) { - dftlen=2048; - dft(DFT_2048,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1); - reps++; - } - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1); - dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1); - dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1); - reps+=6; - } + dftlen=2048; + dft(DFT_2048,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1); + reps++; + } + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1); + dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1); + dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1); + reps+=6; } - else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n"); } } else { // threequarter sampling // 40 MHz @ 46.08 Ms/s @@ -383,36 +378,28 @@ void rx_nr_prach_ru(RU_t *ru, reps=4; } } else { - if ((mu==0 && - (prachStartSymbol == 0 || prachStartSymbol == 7)) || - (mu==1 && prachStartSymbol == 0)) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only) - if (mu==0) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==1) { - dftlen=1536; - dft(DFT_1536,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1); - reps++; - } - - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1); - dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1); - dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1); - reps+=6; - } - }// mu==1 - else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n"); + if (prachStartSymbol == 0) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only) + dftlen=1536; + dft(DFT_1536,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1); + reps++; + } + + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1); + dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1); + dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1); + reps+=6; + } } // short format } // 3/4 sampling } // <=50 MHz BW @@ -442,37 +429,29 @@ void rx_nr_prach_ru(RU_t *ru, } } else { - if ((mu==0 && - (prachStartSymbol == 0 || prachStartSymbol == 7)) || - (mu==1 && prachStartSymbol == 0)) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) + if (prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) - if (mu==0) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==1) { - dftlen=4096; - dft(DFT_4096,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1); - reps++; - } - - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1); - dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1); - dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1); - reps+=6; - } + dftlen=4096; + dft(DFT_4096,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1); + reps++; + } + + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1); + dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1); + dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1); + reps+=6; } - else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n"); } } else { AssertFatal(fp->N_RB_UL <= 217,"cannot do more than 217 PRBs with 3/4 sampling\n"); @@ -494,40 +473,84 @@ void rx_nr_prach_ru(RU_t *ru, reps=4; } } else { - if ((mu==0 && - (prachStartSymbol == 0 || prachStartSymbol == 7)) || - (mu==1 && prachStartSymbol == 0)) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) + if (prachStartSymbol == 0) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) - if (mu==0) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==1) { - dftlen=3072; - dft(DFT_3072,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1); - reps++; - } - - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1); - dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1); - dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1); - reps+=6; - } + dftlen=3072; + dft(DFT_3072,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1); + reps++; + } + + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1); + dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1); + dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1); + reps+=6; } - else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n"); } } } + } + else if (mu==3) { + if (fp->threequarter_fs) { + AssertFatal(1==0,"3/4 sampling not supported for numerology %d\n",mu); + } + if (prach_sequence_length == 0) { + AssertFatal(1==0,"long prach not supported for numerology %d\n",mu); + } + if (fp->N_RB_UL == 32) { + prach2 = prach[aa] + (Ncp<<2); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 for 61.44Msps + if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) + prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe + dftlen=512; + dftsize = IDFT_512; + } + else if (fp->N_RB_UL == 66) { + prach2 = prach[aa] + (Ncp<<3); // Ncp is for 30.72 Ms/s, so multiply by 4 for I/Q, and 2 for 122.88Msps + if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) + prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe + dftlen=1024; + dftsize = IDFT_1024; + } + else { + AssertFatal(1==0,"N_RB_UL %d not support for numerology %d\n",fp->N_RB_UL,mu); + } + + dft(dftsize,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(dftsize,prach2+dftlen*2,rxsigF[aa]+dftlen*2,1); + reps++; + } + + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(dftsize,prach2+dftlen*4,rxsigF[aa]+dftlen*4,1); + dft(dftsize,prach2+dftlen*6,rxsigF[aa]+dftlen*6,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(dftsize,prach2+dftlen*8,rxsigF[aa]+dftlen*8,1); + dft(dftsize,prach2+dftlen*10,rxsigF[aa]+dftlen*10,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) + dft(dftsize,prach2+(dftlen*2*i),rxsigF[aa]+(dftlen*2*i),1); + reps+=6; + } + } + else { + AssertFatal(1==0,"Numerology not supported\n"); + } + //Coherent combining of PRACH repetitions (assumes channel does not change, to be revisted for "long" PRACH) LOG_D(PHY,"Doing PRACH combining of %d reptitions N_ZC %d\n",reps,N_ZC); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index 465598d468..181abca69e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -241,6 +241,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ * *********************************************************/ + if (mu==1) { 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) { @@ -321,6 +322,22 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ } } } + } + else if (mu==3) { + if (fp->threequarter_fs) + AssertFatal(1==0,"3/4 sampling not supported for numerology %d\n",mu); + + if (prach_sequence_length == 0) + AssertFatal(1==0,"long prach not supported for numerology %d\n",mu); + + if (fp->N_RB_UL == 32) + dftlen=512; + else if (fp->N_RB_UL == 66) + dftlen=1024; + else + AssertFatal(1==0,"N_RB_UL %d not support for numerology %d\n",fp->N_RB_UL,mu); + } + for (offset=0,offset2=0; offsetN_RB_UL <= 100) - AssertFatal(1==0,"N_RB_UL %d not supported for NR PRACH yet\n",fp->N_RB_UL); + //actually what we should be checking here is how often the current prach crosses a 0.5ms boundary. I am not quite sure for which paramter set this would be the case, so I will ignore it for now and just check if the prach starts on a 0.5ms boundary + uint8_t use_extended_prach_prefix = 0; + if(fp->numerology_index == 0) { + if (prachStartSymbol == 0 || prachStartSymbol == 7) + use_extended_prach_prefix = 1; + } + else { + if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) + use_extended_prach_prefix = 1; + } + + if (fp->N_RB_UL <= 34) { //32 PRB case 61.44Msps + if (fp->threequarter_fs == 0) { + Ncp<<=1; //to account for 61.44Mbps + // This is after cyclic prefix + prach2 = prach+(Ncp<<1); //times 2 for complex samples + if (prach_sequence_length == 0) + AssertFatal(1==0,"no long PRACH for this PRACH size %d\n",fp->N_RB_UL); + else { + if (use_extended_prach_prefix) + Ncp+=32; // 16*kappa, kappa=2 for 61.44Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples + if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { + idft(IDFT_512,prachF,prach2,1); + // here we have |empty | Prach512 | + if (prach_fmt_id != 9) { + memmove(prach2+(512<<1),prach2,(512<<2)); + prach_len = (512*2)+Ncp; + } + else prach_len = (512*1)+Ncp; + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have |Prefix | Prach512 | Prach512 (if ! 0xc0) | + } else if (prach_fmt_id == 5) { // 6x512 + idft(IDFT_512,prachF,prach2,1); + // here we have |empty | Prach512 | + memmove(prach2+(512<<1),prach2,(512<<2)); + // here we have |empty | Prach512 | Prach512| empty512 | empty512 | + memmove(prach2+(512<<2),prach2,(512<<3)); + // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have |Prefix | Prach512 | + prach_len = (512*4)+Ncp; + } else if (prach_fmt_id == 6) { // 6x512 + idft(IDFT_512,prachF,prach2,1); + // here we have |empty | Prach512 | + memmove(prach2+(512<<1),prach2,(512<<2)); + // here we have |empty | Prach512 | Prach512| empty512 | empty512 | empty512 | empty512 + memmove(prach2+(512<<2),prach2,(512<<3)); + // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | empty512 | empty512 + memmove(prach2+(512<<3),prach2,(512<<3)); + // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512 + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have |Prefix | Prach512 | + prach_len = (512*6)+Ncp; + } else if (prach_fmt_id == 8) { // 12x512 + idft(IDFT_512,prachF,prach2,1); + // here we have |empty | Prach512 | + memmove(prach2+(512<<1),prach2,(512<<2)); + // here we have |empty | Prach512 | Prach512| empty512 | empty512 | empty512 | empty512 + memmove(prach2+(512<<2),prach2,(512<<3)); + // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | empty512 | empty512 + memmove(prach2+(512<<3),prach2,(512<<3)); + // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512 + memmove(prach2+(512<<1)*6,prach2,(512<<2)*6); + // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512| + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have |Prefix | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512| + prach_len = (512*12)+Ncp; + } + } + } + else + AssertFatal(1==0,"3/4 sampling not supported for this PRACH size %d\n",fp->N_RB_UL); + + } + else if (fp->N_RB_UL <= 68) {//66 PRB case, 122.88 Msps + if (fp->threequarter_fs == 0) { + Ncp<<=2; //to account for 122.88Mbps + // This is after cyclic prefix + prach2 = prach+(Ncp<<1); //times 2 for complex samples + if (prach_sequence_length == 0) + AssertFatal(1==0,"no long PRACH for this PRACH size %d\n",fp->N_RB_UL); + else { + if (use_extended_prach_prefix) + Ncp+=64; // 16*kappa, kappa=4 for 122.88Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples + if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { + idft(IDFT_1024,prachF,prach2,1); + // here we have |empty | Prach1024 | + if (prach_fmt_id != 9) { + memmove(prach2+(1024<<1),prach2,(1024<<2)); + prach_len = (1024*2)+Ncp; + } + else prach_len = (1024*1)+Ncp; + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have |Prefix | Prach1024 | Prach1024 (if ! 0xc0) | + } else if (prach_fmt_id == 5) { // 6x1024 + idft(IDFT_1024,prachF,prach2,1); + // here we have |empty | Prach1024 | + memmove(prach2+(1024<<1),prach2,(1024<<2)); + // here we have |empty | Prach1024 | Prach1024| empty1024 | empty1024 | + memmove(prach2+(1024<<2),prach2,(1024<<3)); + // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have |Prefix | Prach1024 | + prach_len = (1024*4)+Ncp; + } else if (prach_fmt_id == 6) { // 6x1024 + idft(IDFT_1024,prachF,prach2,1); + // here we have |empty | Prach1024 | + memmove(prach2+(1024<<1),prach2,(1024<<2)); + // here we have |empty | Prach1024 | Prach1024| empty1024 | empty1024 | empty1024 | empty1024 + memmove(prach2+(1024<<2),prach2,(1024<<3)); + // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | empty1024 | empty1024 + memmove(prach2+(1024<<3),prach2,(1024<<3)); + // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024 + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have |Prefix | Prach1024 | + prach_len = (1024*6)+Ncp; + } else if (prach_fmt_id == 8) { // 12x1024 + idft(IDFT_1024,prachF,prach2,1); + // here we have |empty | Prach1024 | + memmove(prach2+(1024<<1),prach2,(1024<<2)); + // here we have |empty | Prach1024 | Prach1024| empty1024 | empty1024 | empty1024 | empty1024 + memmove(prach2+(1024<<2),prach2,(1024<<3)); + // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | empty1024 | empty1024 + memmove(prach2+(1024<<3),prach2,(1024<<3)); + // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024 + memmove(prach2+(1024<<1)*6,prach2,(1024<<2)*6); + // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024| + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have |Prefix | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024| + prach_len = (1024*12)+Ncp; + } + } + } + else + AssertFatal(1==0,"3/4 sampling not supported for this PRACH size %d\n",fp->N_RB_UL); + } else if (fp->N_RB_UL < 137) { // 46.08 or 61.44 Ms/s if (fp->threequarter_fs == 0) { // full sampling @ 61.44 Ms/s - Ncp<<=1; - // This is after cyclic prefix (Ncp<<1 samples for 30.72 Ms/s, Ncp<<2 samples for 61.44 Ms/s - prach2 = prach+(Ncp<<1); + Ncp<<=1; //to account for 61.44Mbps + // This is after cyclic prefix + prach2 = prach+(Ncp<<1); //times 2 for complex samples if (prach_sequence_length == 0){ if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s idft(IDFT_49152,prachF,prach2,1); @@ -442,9 +596,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (12288*4)+Ncp; } } else { // short PRACH sequence + if (use_extended_prach_prefix) + Ncp+=32; // 16*kappa, kappa=2 for 61.44Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { - Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_2048,prachF,prach2,1); // here we have |empty | Prach2048 | if (prach_fmt_id != 9) { @@ -455,8 +610,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ memmove(prach,prach+(2048<<1),(Ncp<<2)); // here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) | } else if (prach_fmt_id == 5) { // 6x2048 - Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_2048,prachF,prach2,1); // here we have |empty | Prach2048 | memmove(prach2+(2048<<1),prach2,(2048<<2)); @@ -467,8 +620,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ // here we have |Prefix | Prach2048 | prach_len = (2048*4)+Ncp; } else if (prach_fmt_id == 6) { // 6x2048 - Ncp+=32; - prach2 = prach+(Ncp<<1); idft(IDFT_2048,prachF,prach2,1); // here we have |empty | Prach2048 | memmove(prach2+(2048<<1),prach2,(2048<<2)); @@ -481,8 +632,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ // here we have |Prefix | Prach2048 | prach_len = (2048*6)+Ncp; } else if (prach_fmt_id == 8) { // 12x2048 - Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_2048,prachF,prach2,1); // here we have |empty | Prach2048 | memmove(prach2+(2048<<1),prach2,(2048<<2)); @@ -535,9 +684,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (9216*4)+Ncp; } } else { // short sequence + if (use_extended_prach_prefix) + Ncp+=24; // 16*kappa, kappa=1.5 for 46.08Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { - Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_1536,prachF,prach2,1); // here we have |empty | Prach1536 | if (prach_fmt_id != 9) { @@ -549,9 +699,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ // here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) | } else if (prach_fmt_id == 5) { // 6x1536 - - Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_1536,prachF,prach2,1); // here we have |empty | Prach1536 | memmove(prach2+(1536<<1),prach2,(1536<<2)); @@ -562,8 +709,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ // here we have |Prefix | Prach1536 | prach_len = (1536*4)+Ncp; } else if (prach_fmt_id == 6) { // 6x1536 - Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_1536,prachF,prach2,1); // here we have |empty | Prach1536 | memmove(prach2+(1536<<1),prach2,(1536<<2)); @@ -576,8 +721,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ // here we have |Prefix | Prach1536 | prach_len = (1536*6)+Ncp; } else if (prach_fmt_id == 8) { // 12x1536 - Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_1536,prachF,prach2,1); // here we have |empty | Prach1536 | memmove(prach2+(1536<<1),prach2,(1536<<2)); @@ -596,8 +739,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ } } else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s if (fp->threequarter_fs == 0) { // full sampling @ 122.88 Ms/s - Ncp<<=2; - prach2 = prach+(Ncp<<1); + Ncp<<=2; //to account for 122.88Mbps + // This is after cyclic prefix + prach2 = prach+(Ncp<<1); //times 2 for complex samples if (prach_sequence_length == 0){ if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s idft(IDFT_98304,prachF,prach2,1); @@ -632,9 +776,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (24576*4)+Ncp; } } else { // short sequence + if (use_extended_prach_prefix) + Ncp+=64; // 16*kappa, kappa=4 for 122.88Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { - Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_4096,prachF,prach2,1); // here we have |empty | Prach4096 | if (prach_fmt_id != 9) { @@ -644,8 +789,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ memmove(prach,prach+(4096<<1),(Ncp<<2)); // here we have |Prefix | Prach4096 | Prach4096 (if ! 0xc0) | } else if (prach_fmt_id == 5) { // 4x4096 - Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_4096,prachF,prach2,1); // here we have |empty | Prach4096 | memmove(prach2+(4096<<1),prach2,(4096<<2)); @@ -656,8 +799,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ // here we have |Prefix | Prach4096 | prach_len = (4096*4)+Ncp; } else if (prach_fmt_id == 6) { // 6x4096 - Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_4096,prachF,prach2,1); // here we have |empty | Prach4096 | memmove(prach2+(4096<<1),prach2,(4096<<2)); @@ -670,8 +811,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ // here we have |Prefix | Prach4096 | prach_len = (4096*6)+Ncp; } else if (prach_fmt_id == 8) { // 12x4096 - Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_4096,prachF,prach2,1); // here we have |empty | Prach4096 | memmove(prach2+(4096<<1),prach2,(4096<<2)); @@ -688,8 +827,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ } } } else { // three quarter sampling @ 92.16 Ms/s - Ncp = (Ncp*3); - prach2 = prach+(Ncp<<1); + Ncp = (Ncp*3); //to account for 92.16 Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples if (prach_sequence_length == 0){ if (prach_fmt_id == 0) { idft(IDFT_73728,prachF,prach2,1); @@ -724,20 +863,19 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (18432*4)+Ncp; } } else { // short sequence - if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { - Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + if (use_extended_prach_prefix) + Ncp+=48; // 16*kappa, kappa=3 for 92.16Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples + if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { idft(IDFT_3072,prachF,prach2,1); // here we have |empty | Prach3072 | if (prach_fmt_id != 9) { memmove(prach2+(3072<<1),prach2,(3072<<2)); prach_len = (3072*2)+Ncp; } else prach_len = (3072*1)+Ncp; - memmove(prach,prach+(3072<<1),(Ncp<<2)); - // here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) | + memmove(prach,prach+(3072<<1),(Ncp<<2)); + // here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) | } else if (prach_fmt_id == 6) { // 6x3072 - Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_3072,prachF,prach2,1); // here we have |empty | Prach3072 | memmove(prach2+(3072<<1),prach2,(3072<<2)); @@ -750,8 +888,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ // here we have |Prefix | Prach3072 | prach_len = (3072*6)+Ncp; } else if (prach_fmt_id == 5) { // 4x3072 - Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_3072,prachF,prach2,1); // here we have |empty | Prach3072 | memmove(prach2+(3072<<1),prach2,(3072<<2)); @@ -762,8 +898,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ // here we have |Prefix | Prach3072 | prach_len = (3072*4)+Ncp; } else if (prach_fmt_id == 6) { // 12x3072 - Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_3072,prachF,prach2,1); // here we have |empty | Prach3072 | memmove(prach2+(3072<<1),prach2,(3072<<2)); diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index fc02cf5ece..6e75150bd2 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -153,7 +153,7 @@ int main(int argc, char **argv){ randominit(0); - while ((c = getopt (argc, argv, "hHaA:Cc:r:p:g:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) { + while ((c = getopt (argc, argv, "hHaA:Cc:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) { switch (c) { case 'a': printf("Running AWGN simulation\n"); @@ -243,6 +243,10 @@ int main(int argc, char **argv){ threequarter_fs=1; break; + case 'm': + mu = atoi(optarg); + break; + case 'n': n_frames = atoi(optarg); break; @@ -371,9 +375,8 @@ int main(int argc, char **argv){ } - if (config_index<67) { prach_sequence_length=0; slot = subframe*2; slot_gNB = 1+(subframe*2); } - uint16_t N_ZC; - N_ZC = prach_sequence_length == 0 ? 839 : 139; + if (config_index<67 && mu==1) { prach_sequence_length=0; slot = subframe*2; slot_gNB = 1+(subframe*2); } + uint16_t N_ZC = prach_sequence_length == 0 ? 839 : 139; printf("Config_index %d, prach_sequence_length %d\n",config_index,prach_sequence_length); @@ -416,6 +419,11 @@ int main(int argc, char **argv){ nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions); + absoluteFrequencyPointA = to_nrarfcn(frame_parms->nr_band, + frame_parms->dl_CarrierFreq, + frame_parms->numerology_index, + frame_parms->N_RB_UL*(180e3)*(1 << frame_parms->numerology_index)); + //nsymb = (frame_parms->Ncp == 0) ? 14 : 12; printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Frame type %s, Frequency Range %s\n", @@ -432,7 +440,14 @@ int main(int argc, char **argv){ gNB->gNB_config.carrier_config.num_tx_ant.value = 1; gNB->gNB_config.carrier_config.num_rx_ant.value = 1; - gNB->gNB_config.tdd_table.tdd_period.value = 6; + if (mu==1) + gNB->gNB_config.tdd_table.tdd_period.value = 6; + else if (mu==3) + gNB->gNB_config.tdd_table.tdd_period.value = 3; + else { + printf("unsupported numerology %d\n",mu); + exit(-1); + } gNB->gNB_config.prach_config.num_prach_fd_occasions.value = num_prach_fd_occasions; gNB->gNB_config.prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *) malloc(num_prach_fd_occasions*sizeof(nfapi_nr_num_prach_fd_occasions_t)); From bba103dc2d1bc092be33fb96d3d57249d66d06bb Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 3 Nov 2020 10:49:12 +0100 Subject: [PATCH 06/27] some fixes - prachsim working now for FR2 - added testcases --- cmake_targets/autotests/test_case_list.xml | 14 +++++++++----- openair1/PHY/NR_TRANSPORT/nr_prach.c | 7 ++++--- openair1/PHY/NR_UE_TRANSPORT/nr_prach.c | 2 ++ openair1/SIMULATION/NR_PHY/prachsim.c | 16 ++++++++-------- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 7e43a9d01c..8ce35c355e 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1302,10 +1302,12 @@ execution - nr_prachsim Test cases. (Test1: 106 PRBs - Prach format A2), - (Test2: 217 PRBs - Prach format A2), - (Test3: 273 PRBs - Prach format A2), - (Test4: 106 PRBs - Prach format 0) + nr_prachsim Test cases. (Test1: 30kHz SCS, 106 PRBs, Prach format A2), + (Test2: 30kHz SCS, 217 PRBs, Prach format A2), + (Test3: 30kHz SCS, 273 PRBs, Prach format A2), + (Test4: 30kHz SCS, 106 PRBs, Prach format 0) + (Test5: 120kHz SCS, 32 PRBs, Prach format A2) + (Test5: 120kHz SCS, 66 PRBs, Prach format A2) $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c @@ -1315,7 +1317,9 @@ -a -s -30 -n 100 -p 63 -R 106 -a -s -30 -n 100 -p 63 -R 217 -a -s -30 -n 100 -p 63 -R 273 - -a -s -30 -n 100 -p 63 -R 106 -c 4 + -a -s -30 -n 100 -p 63 -R 106 -c 4 + -a -s -30 -n 100 -p 32 -R 32 -m 3 -c52 + -a -s -30 -n 100 -p 32 -R 66 -m 3 -c52 nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 PRACH test OK segmentation fault|assertion|exiting|fatal diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 3c4a1a41ff..b5a3c061e9 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -185,7 +185,7 @@ void rx_nr_prach_ru(RU_t *ru, for (int aa=0; aanb_rx; aa++){ if (prach_sequence_length == 0) slot2=(slot/fp->slots_per_subframe)*fp->slots_per_subframe; - prach[aa] = (int16_t*)&ru->common.rxdata[aa][(slot2*fp->get_samples_per_slot(slot,fp))+sample_offset_slot-ru->N_TA_offset]; + prach[aa] = (int16_t*)&ru->common.rxdata[aa][fp->get_samples_slot_timestamp(slot2,fp,0)+sample_offset_slot-ru->N_TA_offset]; } idft_size_idx_t dftsize; @@ -512,14 +512,14 @@ void rx_nr_prach_ru(RU_t *ru, if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe dftlen=512; - dftsize = IDFT_512; + dftsize = DFT_512; } else if (fp->N_RB_UL == 66) { prach2 = prach[aa] + (Ncp<<3); // Ncp is for 30.72 Ms/s, so multiply by 4 for I/Q, and 2 for 122.88Msps if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe dftlen=1024; - dftsize = IDFT_1024; + dftsize = DFT_1024; } else { AssertFatal(1==0,"N_RB_UL %d not support for numerology %d\n",fp->N_RB_UL,mu); @@ -551,6 +551,7 @@ void rx_nr_prach_ru(RU_t *ru, AssertFatal(1==0,"Numerology not supported\n"); } + //LOG_M("ru_rxsigF_tmp.m","rxsFtmp", rxsigF[aa], dftlen*2*reps, 1, 1); //Coherent combining of PRACH repetitions (assumes channel does not change, to be revisted for "long" PRACH) LOG_D(PHY,"Doing PRACH combining of %d reptitions N_ZC %d\n",reps,N_ZC); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index 181abca69e..0ae271c2db 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -105,6 +105,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1)); prach_start = fp->get_samples_slot_timestamp(slot, fp, 0) + sample_offset_slot; + //printf("prachstartsymbold %d, sample_offset_slot %d, prach_start %d\n",prachStartSymbol, sample_offset_slot, prach_start); + // First compute physical root sequence /************************************************************************ * 4G and NR NCS tables are slightly different and depend on prach format diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 6e75150bd2..e91c0425ae 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -374,12 +374,6 @@ int main(int argc, char **argv){ } } - - if (config_index<67 && mu==1) { prach_sequence_length=0; slot = subframe*2; slot_gNB = 1+(subframe*2); } - uint16_t N_ZC = prach_sequence_length == 0 ? 839 : 139; - - printf("Config_index %d, prach_sequence_length %d\n",config_index,prach_sequence_length); - // Configure log logInit(); set_glog(loglvl); @@ -424,7 +418,13 @@ int main(int argc, char **argv){ frame_parms->numerology_index, frame_parms->N_RB_UL*(180e3)*(1 << frame_parms->numerology_index)); - //nsymb = (frame_parms->Ncp == 0) ? 14 : 12; + subframe = slot/frame_parms->slots_per_subframe; + + if (config_index<67 && mu==1) { prach_sequence_length=0; slot = subframe*2; slot_gNB = 1+(subframe*2); } + uint16_t N_ZC = prach_sequence_length == 0 ? 839 : 139; + + printf("Config_index %d, prach_sequence_length %d\n",config_index,prach_sequence_length); + printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Frame type %s, Frequency Range %s\n", NUMBER_OF_OFDM_CARRIERS, @@ -767,7 +767,7 @@ int main(int argc, char **argv){ LOG_M("prachF0.m","prachF0", &gNB->prach_vars.prachF[0], N_ZC, 1, 1); LOG_M("rxsig0.m","rxs0", &gNB->common_vars.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); - LOG_M("rxsigF0.m","rxsF0", gNB->prach_vars.rxsigF[0], N_ZC, 1, 1); + LOG_M("ru_rxsigF0.m","rxsF0", ru->prach_rxsigF[0][0], N_ZC, 1, 1); LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1); LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1); #endif From 6213307061ff7715cf2b814031e089312dd1bcde Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Thu, 19 Nov 2020 17:11:54 +0100 Subject: [PATCH 07/27] fix indentation in nr_prach --- openair1/PHY/NR_TRANSPORT/nr_prach.c | 382 +++++++++++++-------------- 1 file changed, 190 insertions(+), 192 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index b5a3c061e9..aae310d45a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -301,205 +301,203 @@ void rx_nr_prach_ru(RU_t *ru, // do DFT if (mu==1) { - 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); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s - if (prach_sequence_length == 0) { - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=49152; - dft(DFT_49152,prach2,rxsigF[aa],1); + 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); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=49152; + dft(DFT_49152,prach2,rxsigF[aa],1); + } + if (prachFormat == 1 || prachFormat == 2) { + dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1); + reps++; + } + if (prachFormat == 2) { + dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1); + dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=12288; + for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1); + reps=4; + } + }// 839 sequence + else { + if (prachStartSymbol == 0) + prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only) + dftlen=2048; + dft(DFT_2048,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1); + reps++; + } + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1); + dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1); + dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1); + reps+=6; + } } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1); - reps++; - } - if (prachFormat == 2) { - dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1); - dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1); - reps+=2; - } - if (prachFormat == 3) { - dftlen=12288; - for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1); - reps=4; - } - }// 839 sequence - else { - if (prachStartSymbol == 0) - prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only) + } else { // threequarter sampling + // 40 MHz @ 46.08 Ms/s + prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q + if (prach_sequence_length == 0) { + AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n"); + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=36864; + dft(DFT_36864,prach2,rxsigF[aa],1); + reps++; + } + if (prachFormat == 1 || prachFormat == 2) { + dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1); + reps++; + } + if (prachFormat == 2) { + dft(DFT_36864,prach2+(73728*2),rxsigF[aa]+(73728*2),1); + dft(DFT_36864,prach2+(73728*3),rxsigF[aa]+(73728*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=9216; + for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1); + reps=4; + } + } else { + if (prachStartSymbol == 0) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only) + dftlen=1536; + dft(DFT_1536,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1); + reps++; + } + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1); + dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1); + dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1); + reps+=6; + } + } // short format + } // 3/4 sampling + } // <=50 MHz BW + else if (fp->N_RB_UL <= 273) { + if (fp->threequarter_fs==0) { + prach2 = prach[aa] + (Ncp<<3); + //80,90,100 MHz @ 122.88 Ms/s - dftlen=2048; - dft(DFT_2048,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1); - reps++; - } - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1); - dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1); - dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1); - reps+=6; - } - } - } else { // threequarter sampling - // 40 MHz @ 46.08 Ms/s - prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q - if (prach_sequence_length == 0) { - AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n"); - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=36864; - dft(DFT_36864,prach2,rxsigF[aa],1); - reps++; - } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1); - reps++; - } - if (prachFormat == 2) { - dft(DFT_36864,prach2+(73728*2),rxsigF[aa]+(73728*2),1); - dft(DFT_36864,prach2+(73728*3),rxsigF[aa]+(73728*3),1); - reps+=2; - } - if (prachFormat == 3) { - dftlen=9216; - for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1); - reps=4; - } - } else { - if (prachStartSymbol == 0) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only) - dftlen=1536; - dft(DFT_1536,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1); - reps++; - } - - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1); - dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1); - dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1); - reps+=6; - } - } // short format - } // 3/4 sampling - } // <=50 MHz BW - else if (fp->N_RB_UL <= 273) { - if (fp->threequarter_fs==0) { - prach2 = prach[aa] + (Ncp<<3); - //80,90,100 MHz @ 122.88 Ms/s - - if (prach_sequence_length == 0) { - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=98304; - dft(DFT_98304,prach2,rxsigF[aa],1); + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=98304; + dft(DFT_98304,prach2,rxsigF[aa],1); + } + if (prachFormat == 1 || prachFormat == 2) { + dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1); + reps++; + } + if (prachFormat == 2) { + dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1); + dft(DFT_98304,prach2+(196608*3),rxsigF[aa]+(196608*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=24576; + for (int i=0;i<4;i++) dft(DFT_24576,prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1); + reps=4; + } } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1); - reps++; - } - if (prachFormat == 2) { - dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1); - dft(DFT_98304,prach2+(196608*3),rxsigF[aa]+(196608*3),1); - reps+=2; - } - if (prachFormat == 3) { - dftlen=24576; - for (int i=0;i<4;i++) dft(DFT_24576,prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1); - reps=4; - } - } - else { - if (prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) + else { + if (prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) - dftlen=4096; - dft(DFT_4096,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1); - reps++; - } - - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1); - dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1); - dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_4096,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 @ 92.16 Ms/s - if (prach_sequence_length == 0) { - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=73728; - dft(DFT_73728,prach2,rxsigF[aa],1); - reps++; - } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_73728,prach2+(2*73728),rxsigF[aa]+(2*73728),1); - reps++; - } - if (prachFormat == 3) { - dftlen=18432; - for (int i=0;i<4;i++) dft(DFT_18432,prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1); - reps=4; - } - } else { - if (prachStartSymbol == 0) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) + dftlen=4096; + dft(DFT_4096,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1); + reps++; + } - dftlen=3072; - dft(DFT_3072,prach2,rxsigF[aa],1); - if (prachFormat != 9/*C0*/) { - dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1); - reps++; - } - - if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { - dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1); - dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1); - reps+=2; - } - if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { - dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1); - dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1); - reps+=2; - } - if (prachFormat == 8/*B4*/) { - for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1); - reps+=6; - } - } + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1); + dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1); + dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_4096,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 @ 92.16 Ms/s + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=73728; + dft(DFT_73728,prach2,rxsigF[aa],1); + reps++; + } + if (prachFormat == 1 || prachFormat == 2) { + dft(DFT_73728,prach2+(2*73728),rxsigF[aa]+(2*73728),1); + reps++; + } + if (prachFormat == 3) { + dftlen=18432; + for (int i=0;i<4;i++) dft(DFT_18432,prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1); + reps=4; + } + } else { + if (prachStartSymbol == 0) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) + + dftlen=3072; + dft(DFT_3072,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1); + reps++; + } + + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1); + dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1); + dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1); + reps+=6; + } + } + } } } - } else if (mu==3) { if (fp->threequarter_fs) { AssertFatal(1==0,"3/4 sampling not supported for numerology %d\n",mu); From 3efb07735763dfd025316b95e78506f70f439e36 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Sat, 21 Nov 2020 11:11:28 +0100 Subject: [PATCH 08/27] 24 RB option in uesoftmodem --- executables/nr-uesoftmodem.c | 44 +++++++++++++++++------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 08834ed740..ea3f6b64b5 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -337,23 +337,30 @@ void init_openair0(void) { openair0_cfg[card].configFilename = NULL; openair0_cfg[card].threequarter_fs = frame_parms->threequarter_fs; numerology = frame_parms->numerology_index; - - if(frame_parms->N_RB_DL == 66) { + if(frame_parms->N_RB_DL == 24) { + if (numerology==1) { + openair0_cfg[card].sample_rate=15.36e6; + openair0_cfg[card].samples_per_frame = 153600; + } else { + LOG_E(PHY,"Unsupported numerology!\n"); + exit(-1); + } + }else if(frame_parms->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); - } + 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->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); - } + 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->N_RB_DL == 217) { if (numerology==1) { if (frame_parms->threequarter_fs) { @@ -406,15 +413,6 @@ void init_openair0(void) { LOG_E(PHY,"Unsupported numerology!\n"); exit(-1); } - } else if(frame_parms->N_RB_DL == 50) { - openair0_cfg[card].sample_rate=15.36e6; - openair0_cfg[card].samples_per_frame = 153600; - } else if (frame_parms->N_RB_DL == 25) { - openair0_cfg[card].sample_rate=7.68e6; - openair0_cfg[card].samples_per_frame = 76800; - } else if (frame_parms->N_RB_DL == 6) { - openair0_cfg[card].sample_rate=1.92e6; - openair0_cfg[card].samples_per_frame = 19200; } else { LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms->N_RB_DL); From fbdcba9fa40ea822acade80376f1ec895665aef7 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Sat, 21 Nov 2020 11:12:11 +0100 Subject: [PATCH 09/27] bugfix in dci_nr --- openair1/PHY/NR_UE_TRANSPORT/dci_nr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 53456bb691..9d51bc0e21 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -372,8 +372,12 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, c_rb = n_BWP_start; for (int rb=0;rb>3] & (1<<(c_rb_by6&7))) == 0) c_rb+=6; + while ((coreset_freq_dom[c_rb_by6>>3] & (1<<(7-(c_rb_by6&7)))) == 0){ + c_rb+=6; + c_rb_by6 = c_rb/6; + } LOG_DDD("c_rb=%d\n",c_rb); rxF=NULL; From 66f957fb486bbe062f76bd997fbbd5161ee1b360 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Thu, 26 Nov 2020 17:17:27 +0100 Subject: [PATCH 10/27] fix TA scaling at ue --- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index b0d765b746..878fe37a21 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -138,13 +138,14 @@ uint16_t get_bw_scaling(uint16_t bwp_ul_NB_RB){ uint16_t bw_scaling; // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size switch (bwp_ul_NB_RB) { + case 24: bw_scaling = 4; break; case 32: bw_scaling = 4; break; case 66: bw_scaling = 8; break; case 106: bw_scaling = 16; break; case 217: bw_scaling = 32; break; case 245: bw_scaling = 32; break; case 273: bw_scaling = 32; break; - default: abort(); + default: AssertFatal(1==0,"N_RB_UL %d not supported\n",bwp_ul_NB_RB); } return bw_scaling; } @@ -1243,13 +1244,14 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size switch (ue->frame_parms.N_RB_DL) { + case 24: bw_scaling = 4; break; case 32: bw_scaling = 4; break; case 66: bw_scaling = 8; break; case 106: bw_scaling = 16; break; case 217: bw_scaling = 32; break; case 245: bw_scaling = 32; break; case 273: bw_scaling = 32; break; - default: abort(); + default: AssertFatal(1==0,"N_RB_DL %d not supported\n",ue->frame_parms.N_RB_DL); } /* Time Alignment procedure From 3eb2b4d7b2fc246516a851d0554837bf9c521b6e Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 4 Feb 2021 14:50:55 +0100 Subject: [PATCH 11/27] Generalize some frame parameter calculations Enabling more numerology combinations and 100 MHz support with 3/4 sampling for USRP X300/X310, too. --- executables/nr-ru.c | 276 +++++++++++++++++++++------------ executables/nr-softmodem.c | 90 ----------- executables/nr-ue.c | 37 ----- executables/nr-uesoftmodem.c | 92 +---------- openair1/PHY/INIT/nr_init_ue.c | 34 ++-- openair1/PHY/INIT/nr_parms.c | 120 ++------------ 6 files changed, 211 insertions(+), 438 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 7d4e3607df..3ef5b3d157 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1049,58 +1049,21 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { int mu = config->ssb_config.scs_common.value; int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; - if (mu == NR_MU_0) { //or if LTE - if(N_RB == 100) { - if (fp->threequarter_fs) { - cfg->sample_rate=23.04e6; - cfg->samples_per_frame = 230400; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } else { - cfg->sample_rate=30.72e6; - cfg->samples_per_frame = 307200; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - } else if(N_RB == 50) { - cfg->sample_rate=15.36e6; - cfg->samples_per_frame = 153600; - cfg->tx_bw = 5e6; - cfg->rx_bw = 5e6; - } else if (N_RB == 25) { - cfg->sample_rate=7.68e6; - cfg->samples_per_frame = 76800; - cfg->tx_bw = 2.5e6; - cfg->rx_bw = 2.5e6; - } else if (N_RB == 6) { - cfg->sample_rate=1.92e6; - cfg->samples_per_frame = 19200; - cfg->tx_bw = 1.5e6; - cfg->rx_bw = 1.5e6; - } else AssertFatal(1==0,"Unknown N_RB %d\n",N_RB); - } else if (mu == NR_MU_1) { - if(N_RB == 273) { - if (fp->threequarter_fs) { - AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n"); - } else { - cfg->sample_rate=122.88e6; - cfg->samples_per_frame = 1228800; - cfg->tx_bw = 100e6; - cfg->rx_bw = 100e6; - } - } else if(N_RB == 217) { + if (mu == NR_MU_0) { + switch(N_RB) { + case 270: if (fp->threequarter_fs) { cfg->sample_rate=92.16e6; cfg->samples_per_frame = 921600; - cfg->tx_bw = 80e6; - cfg->rx_bw = 80e6; + cfg->tx_bw = 50e6; + cfg->rx_bw = 50e6; } else { - cfg->sample_rate=122.88e6; - cfg->samples_per_frame = 1228800; - cfg->tx_bw = 80e6; - cfg->rx_bw = 80e6; + cfg->sample_rate=61.44e6; + cfg->samples_per_frame = 614400; + cfg->tx_bw = 50e6; + cfg->rx_bw = 50e6; } - } else if(N_RB == 106) { + case 216: if (fp->threequarter_fs) { cfg->sample_rate=46.08e6; cfg->samples_per_frame = 460800; @@ -1113,29 +1076,154 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->tx_bw = 40e6; cfg->rx_bw = 40e6; } - } else if(N_RB == 24) { + break; + case 106: if (fp->threequarter_fs) { - AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 24\n"); - } else { + cfg->sample_rate=23.04e6; + cfg->samples_per_frame = 230400; + cfg->tx_bw = 20e6; + cfg->rx_bw = 20e6; + } + else { + cfg->sample_rate=30.72e6; + cfg->samples_per_frame = 307200; + cfg->tx_bw = 20e6; + cfg->rx_bw = 20e6; + } + break; + case 52: + if (fp->threequarter_fs) { + cfg->sample_rate=11.52e6; + cfg->samples_per_frame = 115200; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } + else { cfg->sample_rate=15.36e6; cfg->samples_per_frame = 153600; cfg->tx_bw = 10e6; cfg->rx_bw = 10e6; } - } else { + case 25: + if (fp->threequarter_fs) { + cfg->sample_rate=5.76e6; + cfg->samples_per_frame = 57600; + cfg->tx_bw = 5e6; + cfg->rx_bw = 5e6; + } + else { + cfg->sample_rate=7.68e6; + cfg->samples_per_frame = 76800; + cfg->tx_bw = 5e6; + cfg->rx_bw = 5e6; + } + break; + default: + AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); + } + } else if (mu == NR_MU_1) { + switch(N_RB) { + case 273: + if (fp->threequarter_fs) { + cfg->sample_rate=184.32e6; + cfg->samples_per_frame = 1843200; + cfg->tx_bw = 100e6; + cfg->rx_bw = 100e6; + } else { + cfg->sample_rate=122.88e6; + cfg->samples_per_frame = 1228800; + cfg->tx_bw = 100e6; + cfg->rx_bw = 100e6; + } + break; + case 217: + if (fp->threequarter_fs) { + cfg->sample_rate=92.16e6; + cfg->samples_per_frame = 921600; + cfg->tx_bw = 80e6; + cfg->rx_bw = 80e6; + } else { + cfg->sample_rate=122.88e6; + cfg->samples_per_frame = 1228800; + cfg->tx_bw = 80e6; + cfg->rx_bw = 80e6; + } + break; + case 106: + if (fp->threequarter_fs) { + cfg->sample_rate=46.08e6; + cfg->samples_per_frame = 460800; + cfg->tx_bw = 40e6; + cfg->rx_bw = 40e6; + } + else { + cfg->sample_rate=61.44e6; + cfg->samples_per_frame = 614400; + cfg->tx_bw = 40e6; + cfg->rx_bw = 40e6; + } + break; + case 51: + if (fp->threequarter_fs) { + cfg->sample_rate=23.04e6; + cfg->samples_per_frame = 230400; + cfg->tx_bw = 20e6; + cfg->rx_bw = 20e6; + } + else { + cfg->sample_rate=30.72e6; + cfg->samples_per_frame = 307200; + cfg->tx_bw = 20e6; + cfg->rx_bw = 20e6; + } + break; + case 24: + if (fp->threequarter_fs) { + cfg->sample_rate=11.52e6; + cfg->samples_per_frame = 115200; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } + else { + cfg->sample_rate=15.36e6; + cfg->samples_per_frame = 153600; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } + break; + default: 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; + switch(N_RB) { + case 66: + if (fp->threequarter_fs) { + cfg->sample_rate=184.32e6; + cfg->samples_per_frame = 1843200; + cfg->tx_bw = 100e6; + cfg->rx_bw = 100e6; + } else { + cfg->sample_rate = 122.88e6; + cfg->samples_per_frame = 1228800; + cfg->tx_bw = 100e6; + cfg->rx_bw = 100e6; + } + break; + case 32: + if (fp->threequarter_fs) { + cfg->sample_rate=92.16e6; + cfg->samples_per_frame = 921600; + cfg->tx_bw = 50e6; + cfg->rx_bw = 50e6; + } else { + cfg->sample_rate=61.44e6; + cfg->samples_per_frame = 614400; + cfg->tx_bw = 50e6; + cfg->rx_bw = 50e6; + } + break; + default: + AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); } } else { AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu); @@ -1182,60 +1270,52 @@ int setup_RU_buffers(RU_t *ru) { int i,j; int card,ant; //uint16_t N_TA_offset = 0; - NR_DL_FRAME_PARMS *frame_parms; + NR_DL_FRAME_PARMS *fp; nfapi_nr_config_request_scf_t *config = &ru->config; if (ru) { - frame_parms = ru->nr_frame_parms; - printf("setup_RU_buffers: frame_parms = %p\n",frame_parms); + fp = ru->nr_frame_parms; + printf("setup_RU_buffers: frame_parms = %p\n",fp); } else { printf("ru pointer is NULL\n"); return(-1); } + int mu = config->ssb_config.scs_common.value; int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; - if (config->cell_config.frame_duplex_type.value == TDD) { int N_TA_offset = config->carrier_config.uplink_frequency.value < 6000000 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2 double factor=1; - switch (mu) { - case 0: //15 kHz scs - AssertFatal(N_TA_offset == 400,"scs_common 15kHz only for FR1\n"); - if (N_RB <= 25) factor = .25; // 7.68 Ms/s - else if (N_RB <=50) factor = .5; // 15.36 Ms/s - else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s - else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s - else AssertFatal(1==0,"Too many PRBS for mu=0\n"); - break; - case 1: //30 kHz sc - AssertFatal(N_TA_offset == 400,"scs_common 30kHz only for FR1\n"); - if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s - else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s - break; - case 2: //60 kHz scs - AssertFatal(1==0,"scs_common should not be 60 kHz\n"); - break; - case 3: //120 kHz scs - AssertFatal(N_TA_offset == 431,"scs_common 120kHz only for FR2\n"); - break; - case 4: //240 kHz scs - AssertFatal(1==0,"scs_common should not be 60 kHz\n"); - if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s - else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s - else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB); - break; - - if (N_RB == 100) ru->N_TA_offset = 624; - else if (N_RB == 50) ru->N_TA_offset = 624/2; - else if (N_RB == 25) ru->N_TA_offset = 624/4; + case 0: //15 kHz scs + AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n"); + factor = fp->samples_per_subframe / 30720.0; + break; + case 1: //30 kHz sc + AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n"); + factor = fp->samples_per_subframe / 30720.0; + break; + case 2: //60 kHz scs + AssertFatal(1==0, "scs_common should not be 60 kHz\n"); + break; + case 3: //120 kHz scs + AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n"); + factor = fp->samples_per_subframe / 61440.0; + break; + case 4: //240 kHz scs + AssertFatal(N_TA_offset == 431, "scs_common 240kHz only for FR2\n"); + factor = fp->samples_per_subframe / 61440.0; + break; + default: + AssertFatal(1==0, "Invalid scs_common!\n"); } - if (frame_parms->threequarter_fs == 1) factor = factor*.75; + ru->N_TA_offset = (int)(N_TA_offset * factor); - LOG_I(PHY,"RU %d Setting N_TA_offset to %d samples (factor %f, UL Freq %d, N_RB %d)\n",ru->idx,ru->N_TA_offset,factor, - config->carrier_config.uplink_frequency.value, N_RB); + + LOG_I(PHY,"RU %d Setting N_TA_offset to %d samples (factor %f, UL Freq %d, N_RB %d, mu %d)\n",ru->idx,ru->N_TA_offset,factor, + config->carrier_config.uplink_frequency.value, N_RB, mu); } else ru->N_TA_offset = 0; diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index d986e98267..4e4aa50661 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -135,9 +135,6 @@ double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}}; double rx_gain_off = 0.0; -double sample_rate=30.72e6; -double bw = 10.0e6; - static int tx_max_power[MAX_NUM_CCs]; /* = {0,0}*/; @@ -475,93 +472,6 @@ void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], } } -/* -void init_openair0(void) { - - int card; - int i; - - for (card=0; cardrf_config.dl_carrier_bandwidth.value == 100) { - if (frame_parms[0]->threequarter_fs) { - openair0_cfg[card].sample_rate=23.04e6; - openair0_cfg[card].samples_per_frame = 230400; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; - } else { - openair0_cfg[card].sample_rate=30.72e6; - openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; - } - } else if(config[0]->rf_config.dl_carrier_bandwidth.value == 50) { - openair0_cfg[card].sample_rate=15.36e6; - openair0_cfg[card].samples_per_frame = 153600; - openair0_cfg[card].tx_bw = 5e6; - openair0_cfg[card].rx_bw = 5e6; - } else if (config[0]->rf_config.dl_carrier_bandwidth.value == 25) { - openair0_cfg[card].sample_rate=7.68e6; - openair0_cfg[card].samples_per_frame = 76800; - openair0_cfg[card].tx_bw = 2.5e6; - openair0_cfg[card].rx_bw = 2.5e6; - } else if (config[0]->rf_config.dl_carrier_bandwidth.value == 6) { - openair0_cfg[card].sample_rate=1.92e6; - openair0_cfg[card].samples_per_frame = 19200; - openair0_cfg[card].tx_bw = 1.5e6; - openair0_cfg[card].rx_bw = 1.5e6; - } - - - if (config[0]->subframe_config.duplex_mode.value==TDD) - openair0_cfg[card].duplex_mode = duplex_mode_TDD; - else //FDD - openair0_cfg[card].duplex_mode = duplex_mode_FDD; - - printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, - 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; - - openair0_cfg[card].clock_source = clock_source; - - - 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++) { - - if (irx_total_gain_dB; - - - openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file; - printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", - card,i, openair0_cfg[card].tx_gain[i], - openair0_cfg[card].rx_gain[i], - openair0_cfg[card].tx_freq[i], - openair0_cfg[card].rx_freq[i]); - } - } // for loop on cards -} -*/ - void wait_RUs(void) { LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask); // wait for all RUs to be configured over fronthaul diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 6833f2fed3..fcea62ee53 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -237,43 +237,6 @@ static void UE_synch(void *arg) { openair0_cfg[UE->rf_map.card].rx_freq[0], openair0_cfg[UE->rf_map.card].tx_freq[0]); - // reconfigure for potentially different bandwidth - switch(UE->frame_parms.N_RB_DL) { - case 6: - openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; - openair0_cfg[UE->rf_map.card].rx_bw =.96e6; - openair0_cfg[UE->rf_map.card].tx_bw =.96e6; - // openair0_cfg[0].rx_gain[0] -= 12; - break; - - case 25: - openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; - openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; - openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; - // openair0_cfg[0].rx_gain[0] -= 6; - break; - - case 50: - openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; - openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; - openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; - // openair0_cfg[0].rx_gain[0] -= 3; - break; - - case 100: - openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; - openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; - 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) { UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 4f445f394d..7624506011 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -145,7 +145,6 @@ int chain_offset = 0; int card_offset = 0; uint64_t num_missed_slots = 0; // counter for the number of missed slots int transmission_mode = 1; -int numerology = 0; int usrp_tx_thread = 0; int oaisim_flag = 0; int emulate_rf = 0; @@ -316,90 +315,10 @@ void init_openair0(void) { for (card=0; cardthreequarter_fs; - numerology = frame_parms->numerology_index; - if(frame_parms->N_RB_DL == 24) { - if (numerology==1) { - openair0_cfg[card].sample_rate=15.36e6; - openair0_cfg[card].samples_per_frame = 153600; - } else { - LOG_E(PHY,"Unsupported numerology!\n"); - exit(-1); - } - }else if(frame_parms->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->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->N_RB_DL == 217) { - if (numerology==1) { - if (frame_parms->threequarter_fs) { - openair0_cfg[card].sample_rate=92.16e6; - openair0_cfg[card].samples_per_frame = 921600; - } - else { - openair0_cfg[card].sample_rate=122.88e6; - openair0_cfg[card].samples_per_frame = 1228800; - } - } else { - LOG_E(PHY,"Unsupported numerology!\n"); - exit(-1); - } - } else if(frame_parms->N_RB_DL == 273) { - if (numerology==1) { - if (frame_parms->threequarter_fs) { - AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n"); - } - else { - openair0_cfg[card].sample_rate=122.88e6; - openair0_cfg[card].samples_per_frame = 1228800; - } - } else { - LOG_E(PHY,"Unsupported numerology!\n"); - exit(-1); - } - } else if(frame_parms->N_RB_DL == 106) { - if (numerology==0) { - if (frame_parms->threequarter_fs) { - openair0_cfg[card].sample_rate=23.04e6; - openair0_cfg[card].samples_per_frame = 230400; - } else { - openair0_cfg[card].sample_rate=30.72e6; - openair0_cfg[card].samples_per_frame = 307200; - } - } else if (numerology==1) { - if (frame_parms->threequarter_fs) { - openair0_cfg[card].sample_rate=46.08e6; - openair0_cfg[card].samples_per_frame = 460800; - } - else { - openair0_cfg[card].sample_rate=61.44e6; - openair0_cfg[card].samples_per_frame = 614400; - } - } else if (numerology==2) { - openair0_cfg[card].sample_rate=122.88e6; - openair0_cfg[card].samples_per_frame = 1228800; - } else { - LOG_E(PHY,"Unsupported numerology!\n"); - exit(-1); - } - } - else { - LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms->N_RB_DL); - exit(-1); - } + openair0_cfg[card].configFilename = NULL; + openair0_cfg[card].threequarter_fs = frame_parms->threequarter_fs; + openair0_cfg[card].sample_rate = frame_parms->samples_per_subframe * 1e3; + openair0_cfg[card].samples_per_frame = frame_parms->samples_per_frame; if (frame_parms->frame_type==TDD) openair0_cfg[card].duplex_mode = duplex_mode_TDD; @@ -413,8 +332,9 @@ void init_openair0(void) { openair0_cfg[card].tx_num_channels = min(2, frame_parms->nb_antennas_tx); openair0_cfg[card].rx_num_channels = min(2, frame_parms->nb_antennas_rx); - LOG_I(PHY, "HW: Configuring card %d, tx/rx num_channels %d/%d, duplex_mode %s\n", + LOG_I(PHY, "HW: Configuring card %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n", card, + openair0_cfg[card].sample_rate, openair0_cfg[card].tx_num_channels, openair0_cfg[card].rx_num_channels, duplex_mode[openair0_cfg[card].duplex_mode]); diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 8bcc58160f..3132fb9960 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -507,50 +507,36 @@ void init_N_TA_offset(PHY_VARS_NR_UE *ue){ if (fp->frame_type == FDD) { ue->N_TA_offset = 0; } else { - int N_RB = fp->N_RB_DL; int N_TA_offset = fp->ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2 - double factor = 1; + + double factor = 1.0; switch (fp->numerology_index) { case 0: //15 kHz scs AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n"); - if (N_RB <= 25) factor = .25; // 7.68 Ms/s - else if (N_RB <=50) factor = .5; // 15.36 Ms/s - else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s - else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s - else AssertFatal(1==0, "Too many PRBS for mu=0\n"); + factor = fp->samples_per_subframe / 30720.0; break; case 1: //30 kHz sc AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n"); - if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s - else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s + factor = fp->samples_per_subframe / 30720.0; break; case 2: //60 kHz scs AssertFatal(1==0, "scs_common should not be 60 kHz\n"); break; case 3: //120 kHz scs AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n"); + factor = fp->samples_per_subframe / 61440.0; break; case 4: //240 kHz scs - AssertFatal(1==0, "scs_common should not be 60 kHz\n"); - if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s - else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s - else AssertFatal(1==0, "N_RB %d is too big for curretn FR2 implementation\n", N_RB); + AssertFatal(N_TA_offset == 431, "scs_common 240kHz only for FR2\n"); + factor = fp->samples_per_subframe / 61440.0; break; - - if (N_RB == 100) - ue->N_TA_offset = 624; - else if (N_RB == 50) - ue->N_TA_offset = 624/2; - else if (N_RB == 25) - ue->N_TA_offset = 624/4; + default: + AssertFatal(1==0, "Invalid scs_common!\n"); } - if (fp->threequarter_fs == 1) - factor = factor*.75; - ue->N_TA_offset = (int)(N_TA_offset * factor); - LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, N_RB); + LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d, mu %d)\n", ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, fp->N_RB_DL, fp->numerology_index); } } diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index e11fedf973..d0fc227492 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -75,9 +75,8 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp) return symbol; } -void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) +void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL) { - switch(mu) { case NR_MU_0: //15kHz scs @@ -99,114 +98,17 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) else AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->nr_band, mu); } - - switch(bw){ - case 5: - case 10: - fp->ofdm_symbol_size = 512; - fp->first_carrier_offset = 368; //512 - ( (24*12) / 2 ) - fp->nb_prefix_samples0 = 44; - fp->nb_prefix_samples = 36; - break; - 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 ) - fp->nb_prefix_samples0 = 132; - fp->nb_prefix_samples = 108; - } - else { - fp->ofdm_symbol_size = 2048; - fp->first_carrier_offset = 1412; //2048 - ( (106*12) / 2 ) - fp->nb_prefix_samples0 = 176; - fp->nb_prefix_samples = 144; - } - break; - - case 50: - case 60: - case 70: - - case 80: //80 MHz - if (fp->threequarter_fs) { - fp->ofdm_symbol_size = 3072; - fp->first_carrier_offset = 1770; //3072 - ( (217*12) / 2 ) - fp->nb_prefix_samples0 = 264; - fp->nb_prefix_samples = 216; - } - else { - fp->ofdm_symbol_size = 4096; - fp->first_carrier_offset = 2794; //4096 - ( (217*12) / 2 ) - fp->nb_prefix_samples0 = 352; - fp->nb_prefix_samples = 288; - } - break; - - 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 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,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp); - } break; case NR_MU_2: //60kHz scs fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_2]; - - 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,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp); - } break; case NR_MU_3: 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; //512 - ( (32*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: @@ -215,9 +117,21 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) fp->ssb_type = nr_ssb_type_E; break; - default: - AssertFatal(1==0,"Invalid numerology index %d", mu); + default: + AssertFatal(1==0,"Invalid numerology index %d", mu); } + + if(fp->threequarter_fs) + fp->ofdm_symbol_size = 3 * 128; + else + fp->ofdm_symbol_size = 4 * 128; + + while(fp->ofdm_symbol_size < N_RB_DL * 12) + fp->ofdm_symbol_size <<= 1; + + fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2); + fp->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9; + fp->nb_prefix_samples0 = fp->ofdm_symbol_size / 128 * (9 + (1 << mu)); } uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp) @@ -286,7 +200,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, 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); + set_scs_parameters(fp, mu, fp->N_RB_DL); fp->slots_per_frame = 10* fp->slots_per_subframe; @@ -380,7 +294,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->Ncp = Ncp; - set_scs_parameters(fp,fp->numerology_index,config->carrier_config.dl_bandwidth); + set_scs_parameters(fp, fp->numerology_index, fp->N_RB_DL); fp->slots_per_frame = 10* fp->slots_per_subframe; fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats From 6e57abc7ae25633a85b6df443ca3eefb577a64d5 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 8 Feb 2021 13:44:58 +0100 Subject: [PATCH 12/27] NR_UE: consider sync position (1/8 CP) in initial sync and UL write timestamp --- executables/nr-ue.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index fcea62ee53..0fca5bbd2d 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -657,7 +657,7 @@ void *UE_thread(void *arg) { // use previous timing_advance value to compute writeTimestamp writeTimestamp = timestamp + UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms,DURATION_RX_TO_TX - RX_NB_TH) - - firstSymSamp - openair0_cfg[0].tx_sample_advance - UE->N_TA_offset - timing_advance; + firstSymSamp - openair0_cfg[0].tx_sample_advance - UE->N_TA_offset - timing_advance + UE->frame_parms.nb_prefix_samples / 8; // but use current UE->timing_advance value to compute writeBlockSize if (UE->timing_advance != timing_advance) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 13270c5c4b..3d750d2ab3 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -309,6 +309,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames) // every 7*(1<symbol_offset/(7*(1<ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples); + sync_pos_frame += fp->nb_prefix_samples / 8; // shift sync position ahead by 1/8th of cyclic prefix, same as in nr_adjust_synch_ue() if (ue->ssb_offset < sync_pos_frame) ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset; else From a676ccbb80609f7464312db5ca11a0925737271a Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 8 Feb 2021 13:51:17 +0100 Subject: [PATCH 13/27] gNB: fix PRACH reception for some configurations and some cleanup --- openair1/PHY/NR_TRANSPORT/nr_prach.c | 71 ++++++++++++++-------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index aae310d45a..2ddb75af04 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -301,13 +301,10 @@ void rx_nr_prach_ru(RU_t *ru, // do DFT if (mu==1) { - 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); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s + switch(fp->samples_per_subframe) { + case 61440: + // 40, 50, 60 MHz @ 61.44 Ms/s + prach2 = prach[aa] + (4*Ncp); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s if (prach_sequence_length == 0) { if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { dftlen=49152; @@ -327,10 +324,9 @@ void rx_nr_prach_ru(RU_t *ru, for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1); reps=4; } - }// 839 sequence - else { - if (prachStartSymbol == 0) - prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only) + } else { // 839 sequence + if (prachStartSymbol == 0) prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only) + dftlen=2048; dft(DFT_2048,prach2,rxsigF[aa],1); if (prachFormat != 9/*C0*/) { @@ -352,15 +348,15 @@ void rx_nr_prach_ru(RU_t *ru, reps+=6; } } - } else { // threequarter sampling - // 40 MHz @ 46.08 Ms/s + break; + + case 46080: + // 40 MHz @ 46.08 Ms/s prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q if (prach_sequence_length == 0) { - AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n"); if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { dftlen=36864; dft(DFT_36864,prach2,rxsigF[aa],1); - reps++; } if (prachFormat == 1 || prachFormat == 2) { dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1); @@ -374,10 +370,11 @@ void rx_nr_prach_ru(RU_t *ru, if (prachFormat == 3) { dftlen=9216; for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1); - reps=4; + reps=4; } - } else { + } else { // 839 sequence if (prachStartSymbol == 0) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only) + dftlen=1536; dft(DFT_1536,prach2,rxsigF[aa],1); if (prachFormat != 9/*C0*/) { @@ -398,14 +395,12 @@ void rx_nr_prach_ru(RU_t *ru, for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1); reps+=6; } - } // short format - } // 3/4 sampling - } // <=50 MHz BW - else if (fp->N_RB_UL <= 273) { - if (fp->threequarter_fs==0) { - prach2 = prach[aa] + (Ncp<<3); - //80,90,100 MHz @ 122.88 Ms/s + } + break; + case 122880: + // 70, 80, 90, 100 MHz @ 122.88 Ms/s + prach2 = prach[aa] + (8*Ncp); if (prach_sequence_length == 0) { if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { dftlen=98304; @@ -425,8 +420,7 @@ void rx_nr_prach_ru(RU_t *ru, for (int i=0;i<4;i++) dft(DFT_24576,prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1); reps=4; } - } - else { + } else { // 839 sequence if (prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) dftlen=4096; @@ -451,24 +445,29 @@ void rx_nr_prach_ru(RU_t *ru, reps+=6; } } - } else { - AssertFatal(fp->N_RB_UL <= 217,"cannot do more than 217 PRBs with 3/4 sampling\n"); + break; + + case 92160: + // 80, 90 MHz @ 92.16 Ms/s prach2 = prach[aa] + (6*Ncp); - // 80 MHz @ 92.16 Ms/s if (prach_sequence_length == 0) { if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { dftlen=73728; - dft(DFT_73728,prach2,rxsigF[aa],1); - reps++; + dft(DFT_73728,prach2,rxsigF[aa],1); } if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_73728,prach2+(2*73728),rxsigF[aa]+(2*73728),1); + dft(DFT_73728,prach2+147456,rxsigF[aa]+147456,1); reps++; } + if (prachFormat == 2) { + dft(DFT_73728,prach2+(147456*2),rxsigF[aa]+(147456*2),1); + dft(DFT_73728,prach2+(147456*3),rxsigF[aa]+(147456*3),1); + reps+=2; + } if (prachFormat == 3) { dftlen=18432; - for (int i=0;i<4;i++) dft(DFT_18432,prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1); - reps=4; + for (int i=0;i<4;i++) dft(DFT_18432,prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1); + reps=4; } } else { if (prachStartSymbol == 0) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) @@ -495,7 +494,9 @@ void rx_nr_prach_ru(RU_t *ru, reps+=6; } } - } + break; + default: + AssertFatal(1==0,"sample_rate %f MHz not support for NR PRACH yet\n", fp->samples_per_subframe / 1000.0); } } else if (mu==3) { From 92e654c6fc4a3f05e58394fc325adc2bf871b6bd Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 8 Feb 2021 13:58:32 +0100 Subject: [PATCH 14/27] gNB: Add PRACH reception support for 10 to 30 MHz (30 kHz SCS) --- openair1/PHY/NR_TRANSPORT/nr_prach.c | 96 ++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 2ddb75af04..64b14091d6 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -302,6 +302,102 @@ void rx_nr_prach_ru(RU_t *ru, // do DFT if (mu==1) { switch(fp->samples_per_subframe) { + case 15360: + // 10, 15 MHz @ 15.36 Ms/s + prach2 = prach[aa] + (1*Ncp); // Ncp is for 30.72 Ms/s, so divide by 2 to bring to 15.36 Ms/s and multiply by 2 for I/Q + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=12288; + dft(DFT_12288,prach2,rxsigF[aa],1); + } + if (prachFormat == 1 || prachFormat == 2) { + dft(DFT_12288,prach2+24576,rxsigF[aa]+24576,1); + reps++; + } + if (prachFormat == 2) { + dft(DFT_12288,prach2+(24576*2),rxsigF[aa]+(24576*2),1); + dft(DFT_12288,prach2+(24576*3),rxsigF[aa]+(24576*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=3072; + for (int i=0;i<4;i++) dft(DFT_3072,prach2+(i*3072*2),rxsigF[aa]+(i*3072*2),1); + reps=4; + } + } else { // 839 sequence + if (prachStartSymbol == 0) prach2+=16; // 8 samples @ 15.36 Ms/s in first symbol of each half subframe (15/30 kHz only) + + dftlen=512; + dft(DFT_512,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_512,prach2+1024,rxsigF[aa]+1024,1); + reps++; + } + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_512,prach2+1024*2,rxsigF[aa]+1024*2,1); + dft(DFT_512,prach2+1024*3,rxsigF[aa]+1024*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_512,prach2+1024*4,rxsigF[aa]+1024*4,1); + dft(DFT_512,prach2+1024*5,rxsigF[aa]+1024*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_512,prach2+(1024*i),rxsigF[aa]+(1024*i),1); + reps+=6; + } + } + break; + + case 30720: + // 20, 25, 30 MHz @ 30.72 Ms/s + prach2 = prach[aa] + (2*Ncp); // Ncp is for 30.72 Ms/s, so just multiply by 2 for I/Q + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=24576; + dft(DFT_24576,prach2,rxsigF[aa],1); + } + if (prachFormat == 1 || prachFormat == 2) { + dft(DFT_24576,prach2+49152,rxsigF[aa]+49152,1); + reps++; + } + if (prachFormat == 2) { + dft(DFT_24576,prach2+(49152*2),rxsigF[aa]+(49152*2),1); + dft(DFT_24576,prach2+(49152*3),rxsigF[aa]+(49152*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=6144; + for (int i=0;i<4;i++) dft(DFT_6144,prach2+(i*6144*2),rxsigF[aa]+(i*6144*2),1); + reps=4; + } + } else { // 839 sequence + if (prachStartSymbol == 0) prach2+=32; // 16 samples @ 30.72 Ms/s in first symbol of each half subframe (15/30 kHz only) + + dftlen=1024; + dft(DFT_1024,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_1024,prach2+2048,rxsigF[aa]+2048,1); + reps++; + } + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_1024,prach2+2048*2,rxsigF[aa]+2048*2,1); + dft(DFT_1024,prach2+2048*3,rxsigF[aa]+2048*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_1024,prach2+2048*4,rxsigF[aa]+2048*4,1); + dft(DFT_1024,prach2+2048*5,rxsigF[aa]+2048*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_1024,prach2+(2048*i),rxsigF[aa]+(2048*i),1); + reps+=6; + } + } + break; + case 61440: // 40, 50, 60 MHz @ 61.44 Ms/s prach2 = prach[aa] + (4*Ncp); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s From c5734aa110263d91360d868fe233ed4bfe2d20b4 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 8 Feb 2021 14:02:12 +0100 Subject: [PATCH 15/27] NR_UE: slightly cleanup PRACH generation --- openair1/PHY/NR_UE_TRANSPORT/nr_prach.c | 157 ++++++++++-------------- 1 file changed, 68 insertions(+), 89 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index 9ce49cd4b7..fe62b4cacc 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -244,86 +244,58 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ *********************************************************/ if (mu==1) { - 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 + switch(fp->samples_per_subframe) { + case 46080: + // 40 MHz @ 46.08 Ms/s if (prach_sequence_length == 0) { - if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) - dftlen = 49152; - if (prach_fmt_id == 3) - dftlen = 12288; - } // 839 sequence - else { - switch (mu){ - case 1: - dftlen = 2048; - break; - default: - AssertFatal(1 == 0, "Shouldn't get here\n"); - break; - } - } - } else { // threequarter sampling - // 40 MHz @ 46.08 Ms/s - if (prach_sequence_length == 0) { - AssertFatal(fp->N_RB_UL <= 107, "cannot do 108..136 PRBs with 3/4 sampling\n"); if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) dftlen = 36864; if (prach_fmt_id == 3) dftlen = 9216; - } else { - switch (mu){ - case 1: - dftlen = 1536; - break; - default: - AssertFatal(1 == 0, "Shouldn't get here\n"); - break; - } - } // short format - } // 3/4 sampling - } // <=50 MHz BW - else if (fp->N_RB_UL <= 273) { - if (fp->threequarter_fs == 0) { - //80,90,100 MHz @ 122.88 Ms/s + } else { // 839 sequence + dftlen = 1536; + } + break; + + case 61440: + // 40, 50, 60 MHz @ 61.44 Ms/s + if (prach_sequence_length == 0) { + if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) + dftlen = 49152; + if (prach_fmt_id == 3) + dftlen = 12288; + } else { // 839 sequence + dftlen = 2048; + } + break; + + case 92160: + // 50, 60, 70, 80, 90 MHz @ 92.16 Ms/s + if (prach_sequence_length == 0) { + if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) + dftlen = 73728; + if (prach_fmt_id == 3) + dftlen = 18432; + } else { // 839 sequence + dftlen = 3072; + } + break; + + case 122880: + // 70, 80, 90, 100 MHz @ 122.88 Ms/s if (prach_sequence_length == 0) { if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) dftlen = 98304; if (prach_fmt_id == 3) dftlen = 24576; + } else { // 839 sequence + dftlen = 4096; } - } else { // threequarter sampling - switch (mu){ - case 1: - dftlen = 4096; - break; - default: - AssertFatal(1 == 0, "Shouldn't get here\n"); - break; - } + break; + + default: + AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu); } - } else { - AssertFatal(fp->N_RB_UL <= 217, "cannot do more than 217 PRBs with 3/4 sampling\n"); - // 80 MHz @ 92.16 Ms/s - if (prach_sequence_length == 0) { - if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) - dftlen = 73728; - if (prach_fmt_id == 3) - dftlen = 18432; - } else { - switch (mu){ - case 1: - dftlen = 3072; - break; - default: - AssertFatal(1 == 0, "Shouldn't get here\n"); - break; - } - } - } } else if (mu==3) { if (fp->threequarter_fs) @@ -432,8 +404,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ use_extended_prach_prefix = 1; } - if (fp->N_RB_UL <= 34) { //32 PRB case 61.44Msps - if (fp->threequarter_fs == 0) { + if (mu == 3) { + switch (fp->samples_per_subframe) { + case 61440: // 32 PRB case, 61.44 Msps Ncp<<=1; //to account for 61.44Mbps // This is after cyclic prefix prach2 = prach+(Ncp<<1); //times 2 for complex samples @@ -491,13 +464,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (512*12)+Ncp; } } - } - else - AssertFatal(1==0,"3/4 sampling not supported for this PRACH size %d\n",fp->N_RB_UL); - - } - else if (fp->N_RB_UL <= 68) {//66 PRB case, 122.88 Msps - if (fp->threequarter_fs == 0) { + break; + + case 122880: // 66 PRB case, 122.88 Msps Ncp<<=2; //to account for 122.88Mbps // This is after cyclic prefix prach2 = prach+(Ncp<<1); //times 2 for complex samples @@ -555,13 +524,15 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (1024*12)+Ncp; } } + break; + + default: + AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu); } - else - AssertFatal(1==0,"3/4 sampling not supported for this PRACH size %d\n",fp->N_RB_UL); - } - else if (fp->N_RB_UL < 137) { // 46.08 or 61.44 Ms/s - if (fp->threequarter_fs == 0) { // full sampling @ 61.44 Ms/s - Ncp<<=1; //to account for 61.44Mbps + } else if (mu == 1) { + switch (fp->samples_per_subframe) { + case 61440: // full sampling @ 61.44 Ms/s + Ncp = Ncp*2; // to account for 61.44 Ms/s // This is after cyclic prefix prach2 = prach+(Ncp<<1); //times 2 for complex samples if (prach_sequence_length == 0){ @@ -587,7 +558,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ memmove(prach,prach+(49152<<3),(Ncp<<2)); // here we have |Prefix | Prach49152 | Prach49152| Prach49152 | Prach49152 prach_len = (49152*4)+Ncp; - } else if (prach_fmt_id == 3) { // //6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s + } else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s idft(IDFT_12288,prachF,prach2,1); memmove(prach2+(12288<<1),prach2,(12288<<2)); // here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288 @@ -649,7 +620,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (2048*12)+Ncp; } } - } else { // threequarter sampling @ 46.08 Ms/s + break; + + case 46080: // threequarter sampling @ 46.08 Ms/s Ncp = (Ncp*3)/2; prach2 = prach+(Ncp<<1); if (prach_sequence_length == 0){ @@ -738,9 +711,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (1536*12)+Ncp; } } - } - } else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s - if (fp->threequarter_fs == 0) { // full sampling @ 122.88 Ms/s + break; + + case 122880: // full sampling @ 122.88 Ms/s Ncp<<=2; //to account for 122.88Mbps // This is after cyclic prefix prach2 = prach+(Ncp<<1); //times 2 for complex samples @@ -828,7 +801,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (4096*12)+Ncp; } } - } else { // three quarter sampling @ 92.16 Ms/s + break; + + case 92160: // three quarter sampling @ 92.16 Ms/s Ncp = (Ncp*3); //to account for 92.16 Msps prach2 = prach+(Ncp<<1); //times 2 for complex samples if (prach_sequence_length == 0){ @@ -915,6 +890,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (3072*12)+Ncp; } } + break; + + default: + AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu); } } From adc24a797ed78cf26f167e303daac4bb947998be Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 8 Feb 2021 14:04:43 +0100 Subject: [PATCH 16/27] NR_UE: Add PRACH generation for 10 to 30 MHz (30 kHz SCS) --- openair1/PHY/NR_UE_TRANSPORT/nr_prach.c | 220 ++++++++++++++++++++++++ 1 file changed, 220 insertions(+) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index fe62b4cacc..0ba02c6bac 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -245,6 +245,30 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ if (mu==1) { switch(fp->samples_per_subframe) { + case 15360: + // 10, 15 MHz @ 15.36 Ms/s + if (prach_sequence_length == 0) { + if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) + dftlen = 12288; + if (prach_fmt_id == 3) + dftlen = 3072; + } else { // 839 sequence + dftlen = 512; + } + break; + + case 30720: + // 20, 25, 30 MHz @ 30.72 Ms/s + if (prach_sequence_length == 0) { + if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) + dftlen = 24576; + if (prach_fmt_id == 3) + dftlen = 6144; + } else { // 839 sequence + dftlen = 1024; + } + break; + case 46080: // 40 MHz @ 46.08 Ms/s if (prach_sequence_length == 0) { @@ -531,6 +555,202 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ } } else if (mu == 1) { switch (fp->samples_per_subframe) { + case 15360: // full sampling @ 15.36 Ms/s + Ncp = Ncp/2; // to account for 15.36 Ms/s + // This is after cyclic prefix + prach2 = prach+(2*Ncp); // times 2 for complex samples + if (prach_sequence_length == 0){ + if (prach_fmt_id == 0) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s + idft(IDFT_12288,prachF,prach2,1); + // here we have | empty | Prach12288 | + memmove(prach,prach+(12288<<1),(Ncp<<2)); + // here we have | Prefix | Prach12288 | + prach_len = 12288+Ncp; + } else if (prach_fmt_id == 1) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s + idft(IDFT_12288,prachF,prach2,1); + // here we have | empty | Prach12288 | empty12288 | + memmove(prach2+(12288<<1),prach2,(12288<<2)); + // here we have | empty | Prach12288 | Prach12288 | + memmove(prach,prach+(12288<<2),(Ncp<<2)); + // here we have | Prefix | Prach12288 | Prach12288 | + prach_len = (12288*2)+Ncp; + } else if (prach_fmt_id == 2) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s + idft(IDFT_12288,prachF,prach2,1); + // here we have | empty | Prach12288 | empty12288 | empty12288 | empty12288 | + memmove(prach2+(12288<<1),prach2,(12288<<2)); + // here we have | empty | Prach12288 | Prach12288 | empty12288 | empty12288 | + memmove(prach2+(12288<<2),prach2,(12288<<3)); + // here we have | empty | Prach12288 | Prach12288 | Prach12288 | Prach12288 | + memmove(prach,prach+(12288<<3),(Ncp<<2)); + // here we have | Prefix | Prach12288 | Prach12288 | Prach12288 | Prach12288 | + prach_len = (12288*4)+Ncp; + } else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s, 3072 samples @ 15.36 Ms/s + idft(IDFT_3072,prachF,prach2,1); + // here we have | empty | Prach3072 | empty3072 | empty3072 | empty3072 | + memmove(prach2+(3072<<1),prach2,(3072<<2)); + // here we have | empty | Prach3072 | Prach3072 | empty3072 | empty3072 | + memmove(prach2+(3072<<2),prach2,(3072<<3)); + // here we have | empty | Prach3072 | Prach3072 | Prach3072 | Prach3072 | + memmove(prach,prach+(3072<<3),(Ncp<<2)); + // here we have | Prefix | Prach3072 | Prach3072 | Prach3072 | Prach3072 | + prach_len = (3072*4)+Ncp; + } + } else { // short PRACH sequence + if (use_extended_prach_prefix) + Ncp += 8; // 16*kappa, kappa=0.5 for 15.36 Ms/s + prach2 = prach+(2*Ncp); // times 2 for complex samples + if (prach_fmt_id == 9) { + idft(IDFT_512,prachF,prach2,1); + // here we have | empty | Prach512 | + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have | Prefix | Prach512 | + prach_len = (512*1)+Ncp; + } else if (prach_fmt_id == 4 || prach_fmt_id == 7) { + idft(IDFT_512,prachF,prach2,1); + // here we have | empty | Prach512 | empty512 | + memmove(prach2+(512<<1),prach2,(512<<2)); + // here we have | empty | Prach512 | Prach512 | + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have | Prefix | Prach512 | Prach512 | + prach_len = (512*2)+Ncp; + } else if (prach_fmt_id == 5) { // 4x512 + idft(IDFT_512,prachF,prach2,1); + // here we have | empty | Prach512 | empty512 | empty512 | empty512 | + memmove(prach2+(512<<1),prach2,(512<<2)); + // here we have | empty | Prach512 | Prach512 | empty512 | empty512 | + memmove(prach2+(512<<2),prach2,(512<<3)); + // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have | Prefix | Prach512 | Prach512 | Prach512 | Prach512 | + prach_len = (512*4)+Ncp; + } else if (prach_fmt_id == 6) { // 6x512 + idft(IDFT_512,prachF,prach2,1); + // here we have | empty | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | + memmove(prach2+(512<<1),prach2,(512<<2)); + // here we have | empty | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | + memmove(prach2+(512<<2),prach2,(512<<3)); + // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 | + memmove(prach2+(512<<3),prach2,(512<<3)); + // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have | Prefix | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | + prach_len = (512*6)+Ncp; + } else if (prach_fmt_id == 8) { // 12x512 + idft(IDFT_512,prachF,prach2,1); + // here we have | empty | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | + memmove(prach2+(512<<1),prach2,(512<<2)); + // here we have | empty | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | + memmove(prach2+(512<<2),prach2,(512<<3)); + // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | + memmove(prach2+(512<<3),prach2,(512<<3)); + // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | + memmove(prach2+(512<<1)*6,prach2,(512<<2)*6); + // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have | Prefix | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | + prach_len = (512*12)+Ncp; + } + } + break; + + case 30720: // full sampling @ 30.72 Ms/s + Ncp = Ncp*1; // to account for 30.72 Ms/s + // This is after cyclic prefix + prach2 = prach+(2*Ncp); // times 2 for complex samples + if (prach_sequence_length == 0){ + if (prach_fmt_id == 0) { // 24576 samples @ 30.72 Ms/s + idft(IDFT_24576,prachF,prach2,1); + // here we have | empty | Prach24576 | + memmove(prach,prach+(24576<<1),(Ncp<<2)); + // here we have | Prefix | Prach24576 | + prach_len = 24576+Ncp; + } else if (prach_fmt_id == 1) { // 24576 samples @ 30.72 Ms/s + idft(IDFT_24576,prachF,prach2,1); + // here we have | empty | Prach24576 | empty24576 | + memmove(prach2+(24576<<1),prach2,(24576<<2)); + // here we have | empty | Prach24576 | Prach24576 | + memmove(prach,prach+(24576<<2),(Ncp<<2)); + // here we have | Prefix | Prach24576 | Prach24576 | + prach_len = (24576*2)+Ncp; + } else if (prach_fmt_id == 2) { // 24576 samples @ 30.72 Ms/s + idft(IDFT_24576,prachF,prach2,1); + // here we have | empty | Prach24576 | empty24576 | empty24576 | empty24576 | + memmove(prach2+(24576<<1),prach2,(24576<<2)); + // here we have | empty | Prach24576 | Prach24576 | empty24576 | empty24576 | + memmove(prach2+(24576<<2),prach2,(24576<<3)); + // here we have | empty | Prach24576 | Prach24576 | Prach24576 | Prach24576 | + memmove(prach,prach+(24576<<3),(Ncp<<2)); + // here we have | Prefix | Prach24576 | Prach24576 | Prach24576 | Prach24576 | + prach_len = (24576*4)+Ncp; + } else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s + idft(IDFT_6144,prachF,prach2,1); + // here we have | empty | Prach6144 | empty6144 | empty6144 | empty6144 | + memmove(prach2+(6144<<1),prach2,(6144<<2)); + // here we have | empty | Prach6144 | Prach6144 | empty6144 | empty6144 | + memmove(prach2+(6144<<2),prach2,(6144<<3)); + // here we have | empty | Prach6144 | Prach6144 | Prach6144 | Prach6144 | + memmove(prach,prach+(6144<<3),(Ncp<<2)); + // here we have | Prefix | Prach6144 | Prach6144 | Prach6144 | Prach6144 | + prach_len = (6144*4)+Ncp; + } + } else { // short PRACH sequence + if (use_extended_prach_prefix) + Ncp += 16; // 16*kappa, kappa=1 for 30.72Msps + prach2 = prach+(2*Ncp); // times 2 for complex samples + if (prach_fmt_id == 9) { + idft(IDFT_1024,prachF,prach2,1); + // here we have | empty | Prach1024 | + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have | Prefix | Prach1024 | + prach_len = (1024*1)+Ncp; + } else if (prach_fmt_id == 4 || prach_fmt_id == 7) { + idft(IDFT_1024,prachF,prach2,1); + // here we have | empty | Prach1024 | empty1024 | + memmove(prach2+(1024<<1),prach2,(1024<<2)); + // here we have | empty | Prach1024 | Prach1024 | + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have | Prefix | Prach1024 | Prach1024 | + prach_len = (1024*2)+Ncp; + } else if (prach_fmt_id == 5) { // 4x1024 + idft(IDFT_1024,prachF,prach2,1); + // here we have | empty | Prach1024 | empty1024 | empty1024 | empty1024 | + memmove(prach2+(1024<<1),prach2,(1024<<2)); + // here we have | empty | Prach1024 | Prach1024 | empty1024 | empty1024 | + memmove(prach2+(1024<<2),prach2,(1024<<3)); + // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have | Prefix | Prach1024 | Prach1024 | Prach1024 | Prach1024 | + prach_len = (1024*4)+Ncp; + } else if (prach_fmt_id == 6) { // 6x1024 + idft(IDFT_1024,prachF,prach2,1); + // here we have | empty | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | + memmove(prach2+(1024<<1),prach2,(1024<<2)); + // here we have | empty | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | + memmove(prach2+(1024<<2),prach2,(1024<<3)); + // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 | + memmove(prach2+(1024<<3),prach2,(1024<<3)); + // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have | Prefix | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | + prach_len = (1024*6)+Ncp; + } else if (prach_fmt_id == 8) { // 12x1024 + idft(IDFT_1024,prachF,prach2,1); + // here we have | empty | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | + memmove(prach2+(1024<<1),prach2,(1024<<2)); + // here we have | empty | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | + memmove(prach2+(1024<<2),prach2,(1024<<3)); + // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | + memmove(prach2+(1024<<3),prach2,(1024<<3)); + // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | + memmove(prach2+(1024<<1)*6,prach2,(1024<<2)*6); + // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have | Prefix | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | + prach_len = (1024*12)+Ncp; + } + } + break; + case 61440: // full sampling @ 61.44 Ms/s Ncp = Ncp*2; // to account for 61.44 Ms/s // This is after cyclic prefix From 28f739bb707c19a935af42ff324adcac1de4efa4 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 9 Feb 2021 17:50:32 +0100 Subject: [PATCH 17/27] add 10 MHz configuration file for USRP X300 --- .../CONF/gnb.band78.tm1.24PRB.usrpx300.conf | 283 ++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf new file mode 100644 index 0000000000..b6a0847843 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf @@ -0,0 +1,283 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 640288; + 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 = 24; + #initialDownlinkBWP + #genericParameters + # this is RBstart=41,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6325; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=5 + initialDLBWPstartSymbolAndLength_3 = 57; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 24; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6325; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 6; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + + 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; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + sdr_addrs = "type=x300"; + clock_src = "external"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + From b9e99f1e649636a157964c14f9dd77744e190d87 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 9 Feb 2021 17:51:33 +0100 Subject: [PATCH 18/27] update tx_sample_advance for 10 MHz and USRP X300 Tests with our USRP X300, connected via PCIe, show that tx_sample_advance of 45 is slightly too much. Unfortunately, transmitting the PRACH preamble too early is very bad, slightly too late is no problem. So change this value from 45 to 40. This helps receiving the PRACH preamble reliably. --- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index dd29d01fae..ac14633130 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -1125,7 +1125,7 @@ extern "C" { case 15360000: //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 45; + openair0_cfg[0].tx_sample_advance = 40; openair0_cfg[0].tx_bw = 10e6; openair0_cfg[0].rx_bw = 10e6; break; From 75cd4c79d9bc3b5129f7e7137cdc8974fc0552d4 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 9 Feb 2021 18:09:11 +0100 Subject: [PATCH 19/27] update tx_sample_advance for 40 MHz and USRP X300 (3/4 sampling) Testing RA with OAI gNB and UE both using X300 via PCIe link indicated a value of 15 was way too small. The correct value for this setup seems to be 65. --- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index ac14633130..61a742af65 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -1110,7 +1110,7 @@ extern "C" { case 46080000: //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; + openair0_cfg[0].tx_sample_advance = 65; openair0_cfg[0].tx_bw = 40e6; openair0_cfg[0].rx_bw = 40e6; break; From 82804981bd2bc72bd8e9a676b8fc8c08d4db9d8e Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 11 Feb 2021 17:42:20 +0100 Subject: [PATCH 20/27] fix timing advance command scaling scaling with 2^mu is already part of 'bw_scaling', so don't do it twice! Also simplify the computation in get_bw_scaling() by using a one-line computation instead of a switch-case table. --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 14 +------ openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 41 ++++++++------------- 2 files changed, 18 insertions(+), 37 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 12ebf9cf43..fb2ca60d7d 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -367,7 +367,6 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, int timing_advance_update, cqi; int sync_pos; - uint16_t mu = gNB->frame_parms.numerology_index; NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id][0]; NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid]; @@ -375,19 +374,10 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, // pdu->data = gNB->ulsch[ULSCH_id+1][0]->harq_processes[harq_pid]->b; sync_pos = nr_est_timing_advance_pusch(gNB, ULSCH_id); // estimate timing advance for MAC - timing_advance_update = sync_pos * (1 << mu); // scale by the used scs numerology // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size - switch (gNB->frame_parms.N_RB_DL) { - case 24: timing_advance_update /= 4; break; - case 106: timing_advance_update /= 16; break; - case 217: timing_advance_update /= 32; break; - case 245: timing_advance_update /= 32; break; - case 273: timing_advance_update /= 32; break; - case 66: timing_advance_update /= 12; break; - case 32: timing_advance_update /= 12; break; - default: AssertFatal(0==1,"No case defined for PRB %d to calculate timing_advance_update\n",gNB->frame_parms.N_RB_DL); - } + uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048; + timing_advance_update = sync_pos / bw_scaling; // put timing advance command in 0..63 range timing_advance_update += 31; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 02a8238abe..5b4446b3e0 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -202,22 +202,15 @@ uint8_t get_ra_PreambleIndex(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_id){ } - -// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size -uint16_t get_bw_scaling(uint16_t nb_rb){ - uint16_t bw_scaling; - - switch (nb_rb) { - case 24: bw_scaling = 4; break; - case 32: bw_scaling = 4; break; - case 66: bw_scaling = 8; break; - case 106: bw_scaling = 16; break; - case 217: bw_scaling = 32; break; - case 245: bw_scaling = 32; break; - case 273: bw_scaling = 32; break; - default: AssertFatal(1==0,"N_RB_UL %d not supported\n",nb_rb); - } - return bw_scaling; +// convert time factor "16 * 64 * T_c / (2^mu)" in N_TA calculation in TS38.213 section 4.2 to samples by multiplying with samples per second +// 16 * 64 * T_c / (2^mu) * samples_per_second +// = 16 * T_s / (2^mu) * samples_per_second +// = 16 * 1 / (15 kHz * 2048) / (2^mu) * (15 kHz * 2^mu * ofdm_symbol_size) +// = 16 * 1 / 2048 * ofdm_symbol_size +// = 16 * ofdm_symbol_size / 2048 +static inline +uint16_t get_bw_scaling(uint16_t ofdm_symbol_size){ + return 16 * ofdm_symbol_size / 2048; } // UL time alignment procedures: @@ -235,18 +228,16 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){ if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) { - uint8_t numerology = ue->frame_parms.numerology_index; - uint16_t bwp_ul_NB_RB = ue->frame_parms.N_RB_UL; - int factor_mu = 1 << numerology; - uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB); + uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size; + uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size); LOG_D(PHY, "In %s: applying timing advance -- frame %d -- slot %d -- UE_mode %d\n", __FUNCTION__, frame_tx, slot_tx, ue->UE_mode[gNB_id]); if (ue->UE_mode[gNB_id] == RA_RESPONSE){ - ue->timing_advance = ul_time_alignment->ta_command * bw_scaling / factor_mu; + ue->timing_advance += ul_time_alignment->ta_command * bw_scaling; - LOG_D(PHY, "In %s: [UE %d] [%d.%d] Received (RAR) timing advance command %d new value is %u \n", + LOG_D(PHY, "In %s: [UE %d] [%d.%d] Received (RAR) timing advance command %u new value is %d\n", __FUNCTION__, ue->Mod_id, frame_tx, @@ -256,7 +247,7 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){ } else if (ue->UE_mode[gNB_id] == PUSCH){ - ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling / factor_mu; + ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling; LOG_D(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n", __FUNCTION__, @@ -1259,7 +1250,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if (ue->mac_enabled == 1) { - uint16_t bw_scaling = get_bw_scaling(ue->frame_parms.N_RB_DL); + uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size); /* Time Alignment procedure // - UE processing capability 1 @@ -1268,7 +1259,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, // - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are // computed according to sections 5.3 and 6.4 of TS 38.214 */ factor_mu = 1 << numerology; - N_TA_max = 3846 * bw_scaling / factor_mu; + N_TA_max = 3846 * bw_scaling; /* PDSCH decoding time N_1 for processing capability 1 */ if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos0) From 00a7adf198047cd1b23cc033b99535b2c5e3d46a Mon Sep 17 00:00:00 2001 From: cig Date: Wed, 10 Feb 2021 10:46:50 +0100 Subject: [PATCH 21/27] NR_UE: cleanup and fix computation of ta_slot (when to apply the timing advance value) - made hardcoded constants explicit - made the code more readable according to OAI coding style guidelines - fixed some formatting and logging --- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 106 ++++++-------------- 1 file changed, 33 insertions(+), 73 deletions(-) diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 5b4446b3e0..19a4e43569 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -920,33 +920,19 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, int nr_slot_rx = proc->nr_slot_rx; int ret=0, ret1=0; NR_UE_PDSCH *pdsch_vars; - uint8_t is_cw0_active = 0; - uint8_t is_cw1_active = 0; - uint8_t dmrs_type, nb_re_dmrs; uint16_t dmrs_len = get_num_dmrs(dlsch0->harq_processes[dlsch0->current_harq_pid]->dlDmrsSymbPos); - uint16_t nb_symb_sch = 9; nr_downlink_indication_t dl_indication; fapi_nr_rx_indication_t rx_ind; uint16_t number_pdus = 1; // params for UL time alignment procedure NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[eNB_id]; - uint16_t slots_per_frame = ue->frame_parms.slots_per_frame; - uint16_t slots_per_subframe = ue->frame_parms.slots_per_subframe; - uint8_t numerology = ue->frame_parms.numerology_index, mapping_type_ul, mapping_type_dl; - int ul_tx_timing_adjustment, N_TA_max, factor_mu, N_t_1, N_t_2, N_1, N_2, d_1_1 = 0, d_2_1, d; - uint8_t d_2_2 = 0;// set to 0 because there is only 1 BWP - // TODO this should corresponds to the switching time as defined in - // TS 38.133 - uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size; - uint16_t nb_prefix_samples = ue->frame_parms.nb_prefix_samples; - uint32_t t_subframe = 1; // subframe duration of 1 msec - uint16_t start_symbol; - float tc_factor; - is_cw0_active = dlsch0->harq_processes[harq_pid]->status; - nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols; - start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol; - dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType; + uint8_t is_cw0_active = dlsch0->harq_processes[harq_pid]->status; + uint16_t nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols; + uint16_t start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol; + uint8_t dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType; + + uint8_t nb_re_dmrs; if (dmrs_type==NFAPI_NR_DMRS_TYPE1) { nb_re_dmrs = 6*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups; } @@ -954,6 +940,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, nb_re_dmrs = 4*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups; } + uint8_t is_cw1_active = 0; if(dlsch1) is_cw1_active = dlsch1->harq_processes[harq_pid]->status; @@ -1215,53 +1202,29 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, } } - // TODO CRC check for CW0 - - // Check CRC for CW 0 - /*if (ret == (1+dlsch0->max_turbo_iterations)) { - *dlsch_errors=*dlsch_errors+1; - if(dlsch0->rnti != 0xffff){ - LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n", - ue->Mod_id,dlsch0->rnti, - harq_pid,frame_rx,nr_slot_rx, - dlsch0->harq_processes[harq_pid]->rvidx, - dlsch0->harq_processes[harq_pid]->round, - dlsch0->harq_processes[harq_pid]->mcs, - dlsch0->harq_processes[harq_pid]->TBS); - } - } else { - if(dlsch0->rnti != 0xffff){ - LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n", - ue->Mod_id,dlsch0->rnti, - harq_pid,frame_rx,nr_slot_rx, - dlsch0->harq_processes[harq_pid]->rvidx, - dlsch0->harq_processes[harq_pid]->round, - dlsch0->harq_processes[harq_pid]->mcs, - dlsch0->harq_processes[harq_pid]->TBS); - } - if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){ - int j; - LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid); - - for (j=0; jharq_processes[dlsch0->current_harq_pid]->TBS>>3; j++) - LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]); - LOG_T(PHY,"\n"); - }*/ - if (ue->mac_enabled == 1) { - uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size); - /* Time Alignment procedure // - UE processing capability 1 // - Setting the TA update to be applied after the reception of the TA command // - Timing adjustment computed according to TS 38.213 section 4.2 // - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are // computed according to sections 5.3 and 6.4 of TS 38.214 */ - factor_mu = 1 << numerology; - N_TA_max = 3846 * bw_scaling; + const int numerology = ue->frame_parms.numerology_index; + const int ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size; + const int nb_prefix_samples = ue->frame_parms.nb_prefix_samples; + const int samples_per_subframe = ue->frame_parms.samples_per_subframe; + const int slots_per_frame = ue->frame_parms.slots_per_frame; + const int slots_per_subframe = ue->frame_parms.slots_per_subframe; + + const double tc_factor = 1.0 / samples_per_subframe; + const uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size); + + const int Ta_max = 3846; // Max value of 12 bits TA Command + const double N_TA_max = Ta_max * bw_scaling * tc_factor; /* PDSCH decoding time N_1 for processing capability 1 */ + int N_1; if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos0) N_1 = pdsch_N_1_capability_1[numerology][1]; else if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos1 || ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == 2) // TODO set to pdsch_dmrs_pos2 when available @@ -1270,12 +1233,12 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, N_1 = pdsch_N_1_capability_1[numerology][3]; /* PUSCH preapration time N_2 for processing capability 1 */ - N_2 = pusch_N_2_timing_capability_1[numerology][1]; - mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType; - mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; + const int N_2 = pusch_N_2_timing_capability_1[numerology][1]; /* d_1_1 depending on the number of PDSCH symbols allocated */ - d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH + const int d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH + int d_1_1 = 0; + mappingType_t mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType; if (mapping_type_dl == typeA) if (nb_symb_sch + start_symbol < 7) d_1_1 = 7 - (nb_symb_sch + start_symbol); @@ -1290,22 +1253,26 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, } /* d_2_1 */ + int d_2_1; + mappingType_t mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; if (mapping_type_ul == typeB && start_symbol != 0) d_2_1 = 0; else d_2_1 = 1; + /* d_2_2 */ + const double d_2_2 = 0.0; // set to 0 because there is only 1 BWP: TODO this should corresponds to the switching time as defined in TS 38.133 + /* N_t_1 time duration in msec of N_1 symbols corresponding to a PDSCH reception time // N_t_2 time duration in msec of N_2 symbols corresponding to a PUSCH preparation time */ - N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu; - N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu; + double N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor; + double N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor; if (N_t_2 < d_2_2) N_t_2 = d_2_2; /* Time alignment procedure */ - // N_t_1 + N_t_2 + N_TA_max is in unit of Ts, therefore must be converted to Tc // N_t_1 + N_t_2 + N_TA_max must be in msec - tc_factor = 64 * 0.509 * 10e-7; - ul_tx_timing_adjustment = 1 + ceil(slots_per_subframe*((N_t_1 + N_t_2 + N_TA_max)*tc_factor + 0.5)/t_subframe); + const double t_subframe = 1.0; // subframe duration of 1 msec + const int ul_tx_timing_adjustment = 1 + (int)ceil(slots_per_subframe*(N_t_1 + N_t_2 + N_TA_max + 0.5)/t_subframe); if (ul_time_alignment->apply_ta == 1){ ul_time_alignment->ta_slot = (nr_slot_rx + ul_tx_timing_adjustment) % slots_per_frame; @@ -1319,13 +1286,6 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", frame_rx, nr_slot_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot); } } - - /*ue->total_TBS[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS; - ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS; - }*/ - - // TODO CRC check for CW1 - } } From eef684d91a6127e0a85455930f68b5d800e55d80 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 15 Feb 2021 16:25:30 +0100 Subject: [PATCH 22/27] adding 24 PRB to X2AP function --- openair2/X2AP/x2ap_eNB_generate_messages.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index fdce8678b0..7c3a89e7f4 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1318,6 +1318,9 @@ MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr, freq_band); switch (instance_p->N_RB_DL[i]) { + case 24: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb24; + break; case 32: servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb32; break; From eab6379bffef426f1d82b30de0e133cf6fdda86d Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 24 Feb 2021 10:20:44 +0100 Subject: [PATCH 23/27] gNB: cut OFDM symbol for PUSCH reception within 1/8th of CP to avoid ISI --- openair1/PHY/MODULATION/slot_fep_nr.c | 10 ++++++---- openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c | 12 +++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 60b28d4ad1..3ca007daf2 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -468,10 +468,12 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); - if(symbol == 0) - rxdata_offset = slot_offset + nb_prefix_samples0 - SOFFSET; - else - rxdata_offset = slot_offset + nb_prefix_samples0 + (symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples)) - SOFFSET; + // offset of first OFDM symbol + rxdata_offset = slot_offset + nb_prefix_samples0 - SOFFSET; + // offset of n-th OFDM symbol + rxdata_offset += symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples); + // use OFDM symbol from within 1/8th of the CP to avoid ISI + rxdata_offset -= nb_prefix_samples / 8; if(sample_offset>rxdata_offset) { memcpy1((void *)tmp_dft_in, diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index ec55eabf31..a54aec7bc2 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -37,22 +37,20 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id) { - int temp, i, aa, max_pos = 0, max_val = 0; - short Re, Im; - uint8_t cyclic_shift = 0; + int i, aa, max_pos = 0, max_val = 0; NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; NR_gNB_PUSCH *gNB_pusch_vars = gNB->pusch_vars[UE_id]; int32_t **ul_ch_estimates_time = gNB_pusch_vars->ul_ch_estimates_time; - int sync_pos = (frame_parms->ofdm_symbol_size - cyclic_shift*frame_parms->ofdm_symbol_size/12) % (frame_parms->ofdm_symbol_size); + int sync_pos = frame_parms->nb_prefix_samples / 8; for (i = 0; i < frame_parms->ofdm_symbol_size; i++) { - temp = 0; + int temp = 0; for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { - Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)]; - Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)]; + short Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)]; + short Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } From dd275d014822304b70162e7b77065eceee6446f2 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 25 Feb 2021 18:05:21 +0100 Subject: [PATCH 24/27] improve nr_slot_fep() and variants --- openair1/PHY/MODULATION/modulation_UE.h | 7 +- openair1/PHY/MODULATION/nr_modulation.h | 4 +- openair1/PHY/MODULATION/slot_fep_nr.c | 618 +++++++----------- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 3 +- openair1/SCHED_NR/nr_ru_procedures.c | 6 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 3 - openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 12 +- openair1/SIMULATION/NR_PHY/pbchsim.c | 4 +- 8 files changed, 234 insertions(+), 423 deletions(-) diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h index 72a1334fe9..20fdaa7ad8 100644 --- a/openair1/PHY/MODULATION/modulation_UE.h +++ b/openair1/PHY/MODULATION/modulation_UE.h @@ -51,16 +51,13 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue, int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, unsigned char l, - unsigned char Ns, - int sample_offset, - int no_prefix); + unsigned char Ns); int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, unsigned char symbol, unsigned char Ns, - int sample_offset, - int no_prefix); + int sample_offset); int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue, unsigned char l, diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 3d2be905ac..62b3ab90d5 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -74,7 +74,6 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, \param symbol symbol within slot (0..12/14) \param Ns Slot number (0..19) \param sample_offset offset within rxdata (points to beginning of subframe) -\param no_prefix if 1 prefix is removed by HW */ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, @@ -82,8 +81,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, int32_t *rxdataF, unsigned char symbol, unsigned char Ns, - int sample_offset, - int no_prefix); + int sample_offset); /*! \brief This function implements the dft transform precoding in PUSCH diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 3ca007daf2..42bfa88b6c 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -29,361 +29,115 @@ //#define DEBUG_FEP -#define SOFFSET 0 - /*#ifdef LOG_I #undef LOG_I #define LOG_I(A,B...) printf(A) #endif*/ +dft_size_idx_t get_dft_size_idx(uint16_t ofdm_symbol_size) +{ + switch (ofdm_symbol_size) { + case 128: + return DFT_128; + + case 256: + return DFT_256; + + case 512: + return DFT_512; + + case 1024: + return DFT_1024; + + case 1536: + return DFT_1536; + + case 2048: + return DFT_2048; + + case 3072: + return DFT_3072; + + case 4096: + return DFT_4096; + + case 6144: + return DFT_6144; + + case 8192: + return DFT_8192; + + default: + printf("unsupported ofdm symbol size \n"); + assert(0); + } + + return DFT_SIZE_IDXTABLESIZE; +} + int nr_slot_fep(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, unsigned char symbol, - unsigned char Ns, - int sample_offset, - int no_prefix) + unsigned char Ns) { NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - NR_UE_COMMON *common_vars = &ue->common_vars; - unsigned char aa; + NR_UE_COMMON *common_vars = &ue->common_vars; + + AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1); + AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1); + 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; - - - dft_size_idx_t dftsize; - 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: - dftsize = DFT_128; - break; - - case 256: - dftsize = DFT_256; - break; - - case 512: - dftsize = DFT_512; - break; - - case 1024: - dftsize = DFT_1024; - break; - - case 1536: - dftsize = DFT_1536; - break; - - case 2048: - dftsize = DFT_2048; - break; - - case 3072: - dftsize = DFT_3072; - break; - - case 4096: - dftsize = DFT_4096; - break; - - case 8192: - dftsize = DFT_8192; - 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); + nb_prefix_samples = frame_parms->nb_prefix_samples; + nb_prefix_samples0 = frame_parms->nb_prefix_samples0; } else { - slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); + nb_prefix_samples = frame_parms->nb_prefix_samples; + nb_prefix_samples0 = frame_parms->nb_prefix_samples; } - /*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); - }*/ + dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size); + // This is for misalignment issues + int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); - 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[proc->thread_id].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; + unsigned int rx_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); + unsigned int 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; #ifdef DEBUG_FEP - // if (ue->frame <100) - /*LOG_I(PHY,*/printf("slot_fep: 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", - Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples); + // if (ue->frame <100) + printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n", + Ns, symbol, nb_prefix_samples, nb_prefix_samples0, rx_offset); #endif - 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; + for (unsigned char aa=0; aanb_antennas_rx; aa++) { + memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int32_t)); - 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_length_samples], - frame_parms->ofdm_symbol_size*sizeof(int)); - dft(dftsize,(int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].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(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].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_length_samples], - frame_parms->ofdm_symbol_size*sizeof(int)); - dft(dftsize,(int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); - } else { // use dft input from RX buffer directly - - dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); - } -#if UE_TIMING_TRACE - stop_meas(&ue->rx_dft_stats); -#endif + int16_t *rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset]; + // if input to dft is not 256-bit aligned + if ((rx_offset & 7) != 0) { + memcpy((void *)&tmp_dft_in[0], + (void *)&common_vars->rxdata[aa][rx_offset], + frame_parms->ofdm_symbol_size * sizeof(int32_t)); + rxdata_ptr = (int16_t *)tmp_dft_in; } -#ifdef DEBUG_FEP - // if (ue->frame <100) - printf("slot_fep: symbol %d rx_offset %u\n", symbol, rx_offset); -#endif - - int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; - int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset]; - ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; - rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], - (int16_t*)&rot2, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], - frame_parms->ofdm_symbol_size, - 15); - - } - - -#ifdef DEBUG_FEP - printf("slot_fep: done\n"); -#endif - return(0); -} - -int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - 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; - - - dft_size_idx_t dftsize; - 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: - dftsize = DFT_128; - break; - - case 256: - dftsize = DFT_256; - break; - - case 512: - dftsize = DFT_512; - break; - - case 1024: - dftsize = DFT_1024; - break; - - case 1536: - dftsize = DFT_1536; - break; - - case 2048: - dftsize = DFT_2048; - break; - - case 3072: - dftsize = DFT_3072; - break; - - case 4096: - dftsize = DFT_4096; - break; - - case 8192: - dftsize = DFT_8192; - 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[proc->thread_id].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: 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", - 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(dftsize,(int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].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); + start_meas(&ue->rx_dft_stats); #endif + dft(dftsize, + rxdata_ptr, + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + 1); - dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); #if UE_TIMING_TRACE - stop_meas(&ue->rx_dft_stats); + 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(dftsize,(int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); - } else { // use dft input from RX buffer directly - dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); - } -#if UE_TIMING_TRACE - stop_meas(&ue->rx_dft_stats); -#endif - - - } int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset]; @@ -400,14 +154,121 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], frame_parms->ofdm_symbol_size, 15); - } - #ifdef DEBUG_FEP printf("slot_fep: done\n"); #endif - return(0); + + return 0; +} + +int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + unsigned char symbol, + unsigned char Ns, + int sample_offset) +{ + NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + NR_UE_COMMON *common_vars = &ue->common_vars; + + AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1); + AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1); + + unsigned int nb_prefix_samples; + unsigned int nb_prefix_samples0; + if (ue->is_synchronized) { + nb_prefix_samples = frame_parms->nb_prefix_samples; + nb_prefix_samples0 = frame_parms->nb_prefix_samples0; + } + else { + nb_prefix_samples = frame_parms->nb_prefix_samples; + nb_prefix_samples0 = frame_parms->nb_prefix_samples; + } + unsigned int frame_length_samples = frame_parms->samples_per_frame; + + dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size); + // This is for misalignment issues + int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); + + unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); + unsigned int rx_offset = sample_offset + slot_offset; + unsigned int 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; + +#ifdef DEBUG_FEP + // if (ue->frame <100) + printf("slot_fep: 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", + Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples); +#endif + + for (unsigned char aa=0; aanb_antennas_rx; aa++) { + memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int32_t)); + + int16_t *rxdata_ptr; + + if (frame_length_samples - rx_offset < frame_parms->ofdm_symbol_size) { + + memcpy((void *)&tmp_dft_in[0], + (void *)&common_vars->rxdata[aa][rx_offset], + (frame_length_samples - rx_offset) * sizeof(int32_t)); + memcpy((void *)&tmp_dft_in[frame_length_samples - rx_offset], + (void *)&common_vars->rxdata[aa][0], + (frame_parms->ofdm_symbol_size - (frame_length_samples - rx_offset)) * sizeof(int32_t)); + rxdata_ptr = (int16_t *)&tmp_dft_in[0]; + + } else if ((rx_offset & 7) != 0) { + + // if input to dft is not 256-bit aligned + memcpy((void *)&tmp_dft_in[0], + (void *)&common_vars->rxdata[aa][rx_offset], + frame_parms->ofdm_symbol_size * sizeof(int32_t)); + rxdata_ptr = (int16_t *)&tmp_dft_in[0]; + + } else { + + // use dft input from RX buffer directly + rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset]; + + } + +#if UE_TIMING_TRACE + start_meas(&ue->rx_dft_stats); +#endif + + dft(dftsize, + rxdata_ptr, + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + 1); + +#if UE_TIMING_TRACE + stop_meas(&ue->rx_dft_stats); +#endif + + int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; + int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset]; + ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; + +#ifdef DEBUG_FEP + // if (ue->frame <100) + printf("slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset, + symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); +#endif + + rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + (int16_t*)&rot2, + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + frame_parms->ofdm_symbol_size, + 15); + } + +#ifdef DEBUG_FEP + printf("slot_fep: done\n"); +#endif + + return 0; } @@ -416,91 +277,60 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, int32_t *rxdataF, unsigned char symbol, unsigned char Ns, - int sample_offset, - int no_prefix) + int sample_offset) { - int32_t slot_offset, rxdata_offset; - - unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples); - unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0); + unsigned int nb_prefix_samples = frame_parms->nb_prefix_samples; + unsigned int nb_prefix_samples0 = frame_parms->nb_prefix_samples0; - int tmp_dft_in[8192] __attribute__ ((aligned (32))); + dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size); + // This is for misalignment issues + int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); - dft_size_idx_t dftsize; - - switch (frame_parms->ofdm_symbol_size) { - case 128: - dftsize = DFT_128; - break; - - case 256: - dftsize = DFT_256; - break; - - case 512: - dftsize = DFT_512; - break; - - case 1024: - dftsize = DFT_1024; - break; - - case 1536: - dftsize = DFT_1536; - break; - - case 2048: - dftsize = DFT_2048; - break; - - case 4096: - dftsize = DFT_4096; - break; - - case 8192: - dftsize = DFT_8192; - break; - - default: - dftsize = DFT_512; - break; - } - - slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); + unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); // offset of first OFDM symbol - rxdata_offset = slot_offset + nb_prefix_samples0 - SOFFSET; + int32_t rxdata_offset = slot_offset + nb_prefix_samples0; // offset of n-th OFDM symbol rxdata_offset += symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples); // use OFDM symbol from within 1/8th of the CP to avoid ISI rxdata_offset -= nb_prefix_samples / 8; - if(sample_offset>rxdata_offset) { - memcpy1((void *)tmp_dft_in, - (void *) &rxdata[frame_parms->samples_per_frame-sample_offset+rxdata_offset], - (sample_offset-rxdata_offset)*sizeof(int)); + int16_t *rxdata_ptr; - memcpy1((void *)&tmp_dft_in[sample_offset-rxdata_offset], - (void *) &rxdata[0], - (frame_parms->ofdm_symbol_size-sample_offset+rxdata_offset)*sizeof(int)); + if(sample_offset > rxdata_offset) { + + memcpy((void *)&tmp_dft_in[0], + (void *)&rxdata[frame_parms->samples_per_frame - sample_offset + rxdata_offset], + (sample_offset - rxdata_offset) * sizeof(int32_t)); + memcpy((void *)&tmp_dft_in[sample_offset - rxdata_offset], + (void *)&rxdata[0], + (frame_parms->ofdm_symbol_size - sample_offset + rxdata_offset) * sizeof(int32_t)); + rxdata_ptr = (int16_t *)&tmp_dft_in[0]; + + } else if (((rxdata_offset - sample_offset) & 7) != 0) { + + // if input to dft is not 256-bit aligned + memcpy((void *)&tmp_dft_in[0], + (void *)&rxdata[rxdata_offset - sample_offset], + (frame_parms->ofdm_symbol_size) * sizeof(int32_t)); + rxdata_ptr = (int16_t *)&tmp_dft_in[0]; + + } else { + + // use dft input from RX buffer directly + rxdata_ptr = (int16_t *)&rxdata[rxdata_offset - sample_offset]; - dft(dftsize,(int16_t *)&tmp_dft_in, - (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); - } - else { - //dft(dftsize,(int16_t *)&rxdata[rxdata_offset-sample_offset], - // (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); - memcpy((void *)tmp_dft_in, - (void *) &rxdata[rxdata_offset-sample_offset], - (frame_parms->ofdm_symbol_size)*sizeof(int)); - dft(dftsize,(int16_t *)&tmp_dft_in, - (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); } + dft(dftsize, + rxdata_ptr, + (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], + 1); + // clear DC carrier from OFDM symbols rxdataF[symbol * frame_parms->ofdm_symbol_size] = 0; - return(0); + return 0; } void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 3d750d2ab3..164c1f08c9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -289,8 +289,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames) proc, i, 0, - is*fp->samples_per_frame+ue->ssb_offset, - 0); + is*fp->samples_per_frame+ue->ssb_offset); #ifdef DEBUG_INITIAL_SYNCH LOG_I(PHY,"Calling sss detection (normal CP)\n"); diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index a78b1f4805..9a71f96815 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -520,8 +520,7 @@ void nr_fep0(RU_t *ru, int first_half) { ru->common.rxdataF[aa], l, proc->tti_rx, - ru->N_TA_offset, - 0); + ru->N_TA_offset); } } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 0); @@ -657,8 +656,7 @@ void nr_fep_full(RU_t *ru, int slot) { ru->common.rxdataF[aa], l, proc->tti_rx, - ru->N_TA_offset, - 0); + ru->N_TA_offset); } } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 761ff4a142..ff7d531313 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -508,15 +508,12 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) unsigned char aa; for(symbol = 0; symbol < (gNB->frame_parms.Ncp==EXTENDED?12:14); symbol++) { - // nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0); - for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { nr_slot_fep_ul(&gNB->frame_parms, gNB->common_vars.rxdata[aa], gNB->common_vars.rxdataF[aa], symbol, slot_rx, - 0, 0); } } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 19a4e43569..f97d33fa97 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1689,9 +1689,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, nr_slot_fep(ue, proc, (ue->symbol_offset+i)%(fp->symbols_per_slot), - nr_slot_rx, - 0, - 0); + nr_slot_rx); #if UE_TIMING_TRACE start_meas(&ue->dlsch_channel_estimation_stats); @@ -1744,9 +1742,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, nr_slot_fep(ue, proc, l, - nr_slot_rx, - 0, - 0); + nr_slot_rx); dci_cnt = 0; for(int n_ss = 0; n_ssnb_search_space; n_ss++) { @@ -1805,9 +1801,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, nr_slot_fep(ue, proc, m, //to be updated from higher layer - nr_slot_rx, - 0, - 0); + nr_slot_rx); } } } else { diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 2512988371..d8b356df54 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -692,9 +692,7 @@ int main(int argc, char **argv) nr_slot_fep(UE, &proc, i%frame_parms->symbols_per_slot, - ssb_slot, - 0, - 0); + ssb_slot); nr_pbch_channel_estimation(UE,&proc,0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf); From 2266d4611ad477f54a7d20d916db6b441139b939 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 25 Feb 2021 18:34:45 +0100 Subject: [PATCH 25/27] NR_UE: move OFDM symbol cut position handling to nr_slot_fep() this slightly cleans up nr_initial_sync() and UE_thread() --- executables/nr-ue.c | 2 +- openair1/PHY/MODULATION/slot_fep_nr.c | 3 +++ openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 1 - 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index a8302666a1..02d0aa31f0 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -656,7 +656,7 @@ void *UE_thread(void *arg) { // use previous timing_advance value to compute writeTimestamp writeTimestamp = timestamp + UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms,DURATION_RX_TO_TX - RX_NB_TH) - - firstSymSamp - openair0_cfg[0].tx_sample_advance - UE->N_TA_offset - timing_advance + UE->frame_parms.nb_prefix_samples / 8; + firstSymSamp - openair0_cfg[0].tx_sample_advance - UE->N_TA_offset - timing_advance; // but use current UE->timing_advance value to compute writeBlockSize if (UE->timing_advance != timing_advance) { diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 42bfa88b6c..2ed0063d83 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -106,6 +106,9 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, rx_offset += (idx_symb%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; rx_offset += frame_parms->ofdm_symbol_size * symbol; + // use OFDM symbol from within 1/8th of the CP to avoid ISI + rx_offset -= nb_prefix_samples / 8; + #ifdef DEBUG_FEP // if (ue->frame <100) printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n", diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 164c1f08c9..189ad53efa 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -308,7 +308,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames) // every 7*(1<symbol_offset/(7*(1<ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples); - sync_pos_frame += fp->nb_prefix_samples / 8; // shift sync position ahead by 1/8th of cyclic prefix, same as in nr_adjust_synch_ue() if (ue->ssb_offset < sync_pos_frame) ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset; else From 606fa3c3aa5dca1e31216cbe129aebd3a1d07630 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 8 Mar 2021 10:59:43 +0100 Subject: [PATCH 26/27] fix nr_prachsim: 3.5 GHz is _not_ a valid DL frequency for 30 kHz SCS, so change it to 3.6 GHz --- openair1/PHY/INIT/nr_init.c | 4 ++-- openair1/SIMULATION/NR_PHY/pbchsim.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index d00bc90315..4ad948a9bc 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -431,8 +431,8 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, gNB->mac_enabled = 1; if (mu==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->dl_CarrierFreq = 3600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); + fp->ul_CarrierFreq = 3600000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); fp->nr_band = 78; // fp->threequarter_fs= 0; } else if (mu==3) { diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index d8b356df54..e981077207 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -101,8 +101,8 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB, //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->dl_CarrierFreq = 3600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); + fp->ul_CarrierFreq = 3600000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); if (mu>2) fp->nr_band = 257; else fp->nr_band = 78; fp->threequarter_fs= 0; From c56a7e203774cf1817f0af5e35c1370220121070 Mon Sep 17 00:00:00 2001 From: Turker YILMAZ Date: Wed, 10 Mar 2021 19:30:23 +0100 Subject: [PATCH 27/27] Very minor update to test git on new the machine --- .../CONF/gnb.band78.tm1.24PRB.usrpb210.conf | 285 ++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf new file mode 100644 index 0000000000..33f06b5f89 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf @@ -0,0 +1,285 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 640288; + 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 = 24; + #initialDownlinkBWP + #genericParameters + # this is RBstart=41,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6325; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=5 + initialDLBWPstartSymbolAndLength_3 = 57; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 24; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6325; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 6; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + + 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; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + sdr_addrs = "type=b200"; + #"addr=192.168.18.207"; + #"addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; + clock_src = "external"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; +