Skip to content

3GGP New Radio frequency settings generation module

License

Notifications You must be signed in to change notification settings

mkrugly/nr_frequency

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nr_frequency

Ever struggled to compose consistent frequency parameters for 5G New Radio cells? Ever tried to configure 5G New Radio contiguous carriers for CA? Ever wondered where your 5G New Radio cell's SSBlock candidates are located in the time domain?

The nr_frequency module will let you do this efficiently.

The nr_frequency module provides classes for consistent generation of frequency related parameters such as ARFCN for SSB, carrier frequency, reference PointA, relative offsets e.g. OffsetToPointA etc. making sure the SSB frequency is in the sync raster and carrier frequency in the channel raster within the defined band frequency range.

It provides methods for handling frequency to arfcn and back, uplink from downlink frequencies (and vice versa), calculation of carrier aggregation related parameters like nominal channel spacing or guardband.

The implementation is based on the TS 38.104 and TS 38.508. The parameters are calculated with the assumption that the Control resource set zero (Coreset0) and Synchronization Signal Block (SS Block) should be as close as possible to the beginning of the initial BWP (Coreset0 shall start with the start of initial BWP).

All the input and output frequencies are expressed in kHz.

Moreover it provides methods for the resolution of the SSB candidates possitions (index, start symbols, slots, subframes) based on the TS 38.213 sec. 4.1

With only a few optional input parameters the module provides an optimal set of consistent NR settings for different scenarios.

Usage

Single 5G NR cell frequency NR operating band n77, SCS 30 kHz and ΔFRaster 30 kHz (ref. 38.508-1 Table 4.3.1.1.1.77-2):

>>> from nr_frequency import nr_frequency
>>> c = nr_frequency.Config(
...        param={
...            "scs_ssb": 30,     # SS/PBCH block subcarrier spacing TS 38.101-1 Table 5.4.3.3-1, TS 38.101-2 Table 5.4.3.3-1
...            "scs_common": 30,  # subCarrierSpacingCommon in MIB (scs for SIB1, Msg.2/4, broadcast etc.)
...            "scs_carrier": 30, # subcarrier spacing for the carrier (SCS-SpecificCarrier),
...                               # TS 38.101-1 Table 5.3.5-1, TS 38.101-2 Table 5.3.5-1
...            "fc_channel": 3750000, # proposed channel center frequency (maybe shifted
...                                   # if not in channel raster or coreset0, BWP start adjustment necessary)
...            "band": 77,  # NR operating band
...            "bw": 50,    # channel bandwidth
...            "pdcchConfigSib1": 24,  # pdcch-ConfigSIB1 in MIB (used to derive )
...            "offset_to_carrier": 102,  # offset between Point A and the lower edge of the carrier
...        }
...    )
INFO:[{'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 0}, {'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 1}, {'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 2}, {'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 3}, {'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 4}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 0}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 1}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 2}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 3}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 4}, {'pattern': 1, 'n_rb': 48, 'n_sym': 1, 'offset': 12}, {'pattern': 1, 'n_rb': 48, 'n_sym': 1, 'offset': 14}, {'pattern': 1, 'n_rb': 48, 'n_sym': 1, 'offset': 16}, {'pattern': 1, 'n_rb': 48, 'n_sym': 2, 'offset': 12}, {'pattern': 1, 'n_rb': 48, 'n_sym': 2, 'offset': 14}, {'pattern': 1, 'n_rb': 48, 'n_sym': 2, 'offset': 16}]
DEBUG:freq_l:3300000, freq_h:4200000, bw:900000, cbw:47880, scs_carrier:30, channel_bw:50
INFO:Adjusting Dl channel frequency to be in channel raster
DEBUG:DL fc range:(3323940, 3750000, 4176060), fc_dl: 3750000
INFO:Setting DL center frequency to 3738480
INFO:Setting Ul channel frequency based on DL channel frequency
INFO:Setting Ul channel bandwidth equal to Dl channel bandwidth
DEBUG:freq_l:3300000, freq_h:4200000, bw:900000, cbw:47880, scs_carrier:30, channel_bw:50
INFO:Adjusting Ul channel frequency to be in channel raster
DEBUG:UL FC range:(3323940, 3750000, 4176060), fc_ul: 3750000
INFO:Setting UL center frequency to 3738480

>>> cell1_cfg = c.calculate()
DEBUG:fc_dl:3750000, cwb_dl:47880, bw_ssb:7200, f_offset_rb:360
INFO:Starting GSCN/F_SS selection from f_ssb_min:3730020
INFO:Found f_ss:3730080 for gscn:8006
INFO:Selected GSCN:8006, F_SS:3730080
INFO:Adjusting channel frequency to align BWP start with Coreset0 start.
INFO:f_diff(f_off_ssb_carrier:420 - f_offset_rb:360) = 60
INFO:f_diff (k_ssb:4) <= k_ssb_max:22. Channel frequency shift not needed
INFO:Absolute Frequency PointA ARFCN:645956 (f_pointA:3689340)
INFO:Absolute Frequency SSB ARFCN:648672 (f_ss:3730080)
INFO:Calculated Common Coreset: s_rb=0 (s_crb=102), n_rb=24, n_rbg=4, bitm=111100000000000000000000000000000000000000000
INFO:Params: {'arfcn_point_a': 645956,
 'arfcn_point_a_ul': 645956,
 'arfcn_ssb': 648672,
 'band': 77,
 'band_bw_dl': 900000,
 'band_bw_ul': 900000,
 'band_dl_f_range': (3300000, 4200000),
 'band_ul_f_range': (3300000, 4200000),
 'bw': 50,
 'bw_ssb': 7200,
 'bw_ul': 50,
 'cbw_dl': 47880,
 'cbw_dl_nrb': 133,
 'cbw_ul': 47880,
 'cbw_ul_nrb': 133,
 'duplex': 'TDD',
 'f_domain_res': '111100000000000000000000000000000000000000000',
 'f_fc_to_point_a': 49140,
 'f_off_to_carrier': 36720,
 'f_offset_rb': 360,
 'f_point_a': 3689340,
 'f_point_a_ul': 3689340,
 'f_ss': 3730080,
 'fc_channel_dl': 3750000,
 'fc_channel_dl_high': 4176060,
 'fc_channel_dl_low': 3323940,
 'fc_channel_dl_range': (3323940, 3750000, 4176060),
 'fc_channel_ul': 3750000,
 'fc_channel_ul_high': 4176060,
 'fc_channel_ul_low': 3323940,
 'fc_channel_ul_range': (3323940, 3750000, 4176060),
 'fc_dl': 3738480,
 'fc_ul': 3738480,
 'freq_raster': 30,
 'gscn': 8006,
 'k_ssb': 4,
 'k_ssb_max': 22,
 'max_location_and_bw_dl': 36300,
 'max_location_and_bw_ul': 36300,
 'n_rb_coreset0': 24,
 'n_sym_coreset0': 2,
 'offset_coreset0_carrier': 0,
 'offset_rb': 1,
 'offset_to_carrier': 102,
 'offset_to_pa': 206,
 'pdcch_cfg_sib1': 24,
 'rb_6_size': 2160,
 'rb_size': 360,
 'scs_carrier': 30,
 'scs_carrier_num': 1,
 'scs_common': 30,
 'scs_common_num': 1,
 'scs_kssb': 15,
 'scs_ssb': 30,
 'scs_ssb_num': 1,
 'ssb_enabled': True,
 'ssb_pattern': 'caseC',
 'use_sync_raster': True}

>>> cell1_cfg.get("gscn")
8006
>>> cell1_cfg.get("k_ssb")
4
>>> cell1_cfg.get("fc_channel_dl")
3750000
>>> cell1_cfg.get("offset_rb")
1
>>> cell1_cfg.get("offset_to_pa")
206
>>> cell1_cfg.get("arfcn_point_a")
645956
>>> cell1_cfg.get("arfcn_ssb")
648672

Example of a contiguous intra-band two carriers configuration (NR operating band n77, SCS 30 kHz and ΔFRaster 30 kHz):

>>> from nr_frequency.nr_frequency import Config, CaConfig
>>> c1 = Config(
...         param={
...             "scs_ssb": 30,
...             "scs_common": 30,
...             "scs_carrier": 30,
...             "fc_channel": 3750000,
...             "band": 77,
...             "bw": 50,
...             "pdcchConfigSib1": 164,
...             "offset_to_carrier": 0,
...         }
...     )
INFO:[{'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 0}, {'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 1}, {'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 2}, {'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 3}, {'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 4}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 0}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 1}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 2}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 3}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 4}, {'pattern': 1, 'n_rb': 48, 'n_sym': 1, 'offset': 12}, {'pattern': 1, 'n_rb': 48, 'n_sym': 1, 'offset': 14}, {'pattern': 1, 'n_rb': 48, 'n_sym': 1, 'offset': 16}, {'pattern': 1, 'n_rb': 48, 'n_sym': 2, 'offset': 12}, {'pattern': 1, 'n_rb': 48, 'n_sym': 2, 'offset': 14}, {'pattern': 1, 'n_rb': 48, 'n_sym': 2, 'offset': 16}]
DEBUG:freq_l:3300000, freq_h:4200000, bw:900000, cbw:47880, scs_carrier:30, channel_bw:50
INFO:Adjusting Dl channel frequency to be in channel raster
DEBUG:DL fc range:(3323940, 3750000, 4176060), fc_dl: 3750000
INFO:Setting DL center frequency to 3775200
INFO:Setting Ul channel frequency based on DL channel frequency
INFO:Setting Ul channel bandwidth equal to Dl channel bandwidth
DEBUG:freq_l:3300000, freq_h:4200000, bw:900000, cbw:47880, scs_carrier:30, channel_bw:50
INFO:Adjusting Ul channel frequency to be in channel raster
DEBUG:UL FC range:(3323940, 3750000, 4176060), fc_ul: 3750000
INFO:Setting UL center frequency to 3775200

>>> cell1_cfg = c1.calculate()
DEBUG:fc_dl:3750000, cwb_dl:47880, bw_ssb:7200, f_offset_rb:4320
INFO:Starting GSCN/F_SS selection from f_ssb_min:3733980
INFO:Found f_ss:3734400 for gscn:8009
INFO:Selected GSCN:8009, F_SS:3734400
INFO:Adjusting channel frequency to align BWP start with Coreset0 start.
INFO:f_diff(f_off_ssb_carrier:4740 - f_offset_rb:4320) = 420
INFO:f_diff (k_ssb:28) > k_ssb_max:22. Channel frequency shift needed
INFO:trying _f_shift:420, k_ssb:0, f_k_ssb:0
INFO:Shifting Channel Frequency up by shift:420 to 3750420, k_ssb:0
INFO:Setting DL center frequency to 3775620
INFO:Setting UL center frequency to 3775620
INFO:Absolute Frequency PointA ARFCN:648432 (f_pointA:3726480)
INFO:Absolute Frequency SSB ARFCN:648960 (f_ss:3734400)
INFO:Calculated Common Coreset: s_rb=0 (s_crb=0), n_rb=48, n_rbg=8, bitm=111111110000000000000000000000000000000000000
INFO:Params: {'arfcn_point_a': 648432,
 'arfcn_point_a_ul': 648432,
 'arfcn_ssb': 648960,
 'band': 77,
 'band_bw_dl': 900000,
 'band_bw_ul': 900000,
 'band_dl_f_range': (3300000, 4200000),
 'band_ul_f_range': (3300000, 4200000),
 'bw': 50,
 'bw_ssb': 7200,
 'bw_ul': 50,
 'cbw_dl': 47880,
 'cbw_dl_nrb': 133,
 'cbw_ul': 47880,
 'cbw_ul_nrb': 133,
 'duplex': 'TDD',
 'f_domain_res': '111111110000000000000000000000000000000000000',
 'f_fc_to_point_a': 49140,
 'f_off_to_carrier': 0,
 'f_offset_rb': 4320,
 'f_point_a': 3726480,
 'f_point_a_ul': 3726480,
 'f_ss': 3734400,
 'fc_channel_dl': 3750420,
 'fc_channel_dl_high': 4176060,
 'fc_channel_dl_low': 3323940,
 'fc_channel_dl_range': (3323940, 3750000, 4176060),
 'fc_channel_ul': 3750420,
 'fc_channel_ul_high': 4176060,
 'fc_channel_ul_low': 3323940,
 'fc_channel_ul_range': (3323940, 3750000, 4176060),
 'fc_dl': 3775620,
 'fc_ul': 3775620,
 'freq_raster': 30,
 'gscn': 8009,
 'k_ssb': 0,
 'k_ssb_max': 22,
 'max_location_and_bw_dl': 36300,
 'max_location_and_bw_ul': 36300,
 'n_rb_coreset0': 48,
 'n_sym_coreset0': 1,
 'offset_coreset0_carrier': 0,
 'offset_rb': 12,
 'offset_to_carrier': 0,
 'offset_to_pa': 24,
 'pdcch_cfg_sib1': 164,
 'rb_6_size': 2160,
 'rb_size': 360,
 'scs_carrier': 30,
 'scs_carrier_num': 1,
 'scs_common': 30,
 'scs_common_num': 1,
 'scs_kssb': 15,
 'scs_ssb': 30,
 'scs_ssb_num': 1,
 'ssb_enabled': True,
 'ssb_pattern': 'caseC',
 'use_sync_raster': True}

>>> nom_cs = CaConfig.nominal_spacing(bw_c1=50, bw_c2=80, scs_c1=30, scs_c2=30, band=77)
INFO:Calculating nominal channel spacing for band:77, channel_bandwidth pair:(50, 80) and subcarrier_spacing pair:(30, 30)
INFO:checking mi_zero for {80, 50} in set()
INFO:checking mi_zero for {80, 50} in set()
INFO:checking mi_zero for {80, 50} in {100, 70, 40, 10, 15, 80, 50, 20, 25, 90, 60, 30}
INFO:Found mi_zero: 2
INFO:Calculated nominal channel spacing is 64860 kHz

>>> c2 = Config(
...         param={
...             "scs_ssb": 30,
...             "scs_common": 30,
...             "scs_carrier": 30,
...             "fc_channel": c1.fc_channel_dl + nom_cs,
...             "band": 77,
...             "bw": 80,
...             "pdcchConfigSib1": 164,
...             "offset_to_carrier": 0,
...             "use_sync_raster": False,
...         }
...     )
INFO:[{'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 0}, {'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 1}, {'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 2}, {'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 3}, {'pattern': 1, 'n_rb': 24, 'n_sym': 2, 'offset': 4}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 0}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 1}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 2}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 3}, {'pattern': 1, 'n_rb': 24, 'n_sym': 3, 'offset': 4}, {'pattern': 1, 'n_rb': 48, 'n_sym': 1, 'offset': 12}, {'pattern': 1, 'n_rb': 48, 'n_sym': 1, 'offset': 14}, {'pattern': 1, 'n_rb': 48, 'n_sym': 1, 'offset': 16}, {'pattern': 1, 'n_rb': 48, 'n_sym': 2, 'offset': 12}, {'pattern': 1, 'n_rb': 48, 'n_sym': 2, 'offset': 14}, {'pattern': 1, 'n_rb': 48, 'n_sym': 2, 'offset': 16}]
DEBUG:freq_l:3300000, freq_h:4200000, bw:900000, cbw:78120, scs_carrier:30, channel_bw:80
INFO:Adjusting Dl channel frequency to be in channel raster
DEBUG:DL fc range:(3339060, 3750000, 4160940), fc_dl: 3815280
INFO:Setting DL center frequency to 3825360
INFO:Setting Ul channel frequency based on DL channel frequency
INFO:Setting Ul channel bandwidth equal to Dl channel bandwidth
DEBUG:freq_l:3300000, freq_h:4200000, bw:900000, cbw:78120, scs_carrier:30, channel_bw:80
INFO:Adjusting Ul channel frequency to be in channel raster
DEBUG:UL FC range:(3339060, 3750000, 4160940), fc_ul: 3815280
INFO:Setting UL center frequency to 3825360
cell2_cfg = c2.calculate()
DEBUG:fc_dl:3815280, cwb_dl:78120, bw_ssb:7200, f_offset_rb:4320
INFO:Adjusting channel frequency to align BWP start with Coreset0 start.
INFO:f_diff(f_off_ssb_carrier:4320 - f_offset_rb:4320) = 0
INFO:f_diff (k_ssb:0) <= k_ssb_max:22. Channel frequency shift not needed
INFO:Absolute Frequency PointA ARFCN:651748 (f_pointA:3776220)
INFO:Absolute Frequency SSB ARFCN:652276 (f_ss:3784140)
INFO:Calculated Common Coreset: s_rb=0 (s_crb=0), n_rb=48, n_rbg=8, bitm=111111110000000000000000000000000000000000000
INFO:Params: {'arfcn_point_a': 651748,
 'arfcn_point_a_ul': 651748,
 'arfcn_ssb': 652276,
 'band': 77,
 'band_bw_dl': 900000,
 'band_bw_ul': 900000,
 'band_dl_f_range': (3300000, 4200000),
 'band_ul_f_range': (3300000, 4200000),
 'bw': 80,
 'bw_ssb': 7200,
 'bw_ul': 80,
 'cbw_dl': 78120,
 'cbw_dl_nrb': 217,
 'cbw_ul': 78120,
 'cbw_ul_nrb': 217,
 'duplex': 'TDD',
 'f_domain_res': '111111110000000000000000000000000000000000000',
 'f_fc_to_point_a': 49140,
 'f_off_to_carrier': 0,
 'f_offset_rb': 4320,
 'f_point_a': 3776220,
 'f_point_a_ul': 3776220,
 'f_ss': 3784140,
 'fc_channel_dl': 3815280,
 'fc_channel_dl_high': 4160940,
 'fc_channel_dl_low': 3339060,
 'fc_channel_dl_range': (3339060, 3750000, 4160940),
 'fc_channel_ul': 3815280,
 'fc_channel_ul_high': 4160940,
 'fc_channel_ul_low': 3339060,
 'fc_channel_ul_range': (3339060, 3750000, 4160940),
 'fc_dl': 3825360,
 'fc_ul': 3825360,
 'freq_raster': 30,
 'gscn': 0,
 'k_ssb': 0,
 'k_ssb_max': 22,
 'max_location_and_bw_dl': 16499,
 'max_location_and_bw_ul': 16499,
 'n_rb_coreset0': 48,
 'n_sym_coreset0': 1,
 'offset_coreset0_carrier': 0,
 'offset_rb': 12,
 'offset_to_carrier': 0,
 'offset_to_pa': 24,
 'pdcch_cfg_sib1': 164,
 'rb_6_size': 2160,
 'rb_size': 360,
 'scs_carrier': 30,
 'scs_carrier_num': 1,
 'scs_common': 30,
 'scs_common_num': 1,
 'scs_kssb': 15,
 'scs_ssb': 30,
 'scs_ssb_num': 1,
 'ssb_enabled': True,
 'ssb_pattern': 'caseC',
 'use_sync_raster': False}

Finding SSB candidates positions:

>>> from nr_frequency import nr_frequency
>>> ss = nr_frequency.SsbPositions(band=257, scs_common=120, scs_ssb=120, in_onegroup='10000000', group_presence='10101010')
>>> ss.ssb_candidates
{0: (4, 0, 0), 16: (144, 10, 1), 32: (284, 20, 2), 48: (424, 30, 3)}
>>> ss.scs_ssb=30
>>> ss.scs_common=30
>>> ss.band=77
>>> ss.ssb_candidates
{0: (2, 0, 0)}
>>> ss.in_onegroup='11110001'
>>> ss.ssb_candidates
{0: (2, 0, 0), 1: (8, 0, 0), 2: (16, 1, 0), 3: (22, 1, 0), 7: (50, 3, 1)}
>>> ss.ssb_pattern
'caseC'
>>> ss.ssb_candidates_start_symbols
[2, 8, 16, 22, 50]
>>> ss.ssb_candidates_index
[0, 1, 2, 3, 7]

Releases

No releases published

Packages

No packages published

Languages