diff --git a/lib/src/phy/phch/pbch_nr.c b/lib/src/phy/phch/pbch_nr.c index a96cea33b..3b20a0aaa 100644 --- a/lib/src/phy/phch/pbch_nr.c +++ b/lib/src/phy/phch/pbch_nr.c @@ -410,9 +410,11 @@ static void pbch_nr_scramble_tx(const srsran_pbch_nr_cfg_t* cfg, uint32_t M_bit = PBCH_NR_E; // Select value v - uint32_t v = (ssb_idx & 0x7U); + // for L max = 8 or L max = 64 , & is the three least significant bits of the SS/PBCH block index + uint32_t v = (ssb_idx & 0b111U); if (cfg->Lmax == 4) { - v = ssb_idx & 0x3U; + // for L max = 4 , & is the two least significant bits of the SS/PBCH block index + v = ssb_idx & 0b11U; } // Advance sequence @@ -435,8 +437,10 @@ static void pbch_nr_scramble_rx(const srsran_pbch_nr_cfg_t* cfg, uint32_t M_bit = PBCH_NR_E; // Select value v + // for L max = 8 or L max = 64 , & is the three least significant bits of the SS/PBCH block index uint32_t v = (ssb_idx & 0b111U); if (cfg->Lmax == 4) { + // for L max = 4 , & is the two least significant bits of the SS/PBCH block index v = ssb_idx & 0b11U; } diff --git a/lib/src/phy/sync/ssb.c b/lib/src/phy/sync/ssb.c index d0462ee09..7ac2352a8 100644 --- a/lib/src/phy/sync/ssb.c +++ b/lib/src/phy/sync/ssb.c @@ -558,10 +558,11 @@ int srsran_ssb_add(srsran_ssb_t* q, uint32_t N_id, const srsran_pbch_msg_nr_t* m // Put PBCH DMRS srsran_dmrs_pbch_cfg_t pbch_dmrs_cfg = {}; pbch_dmrs_cfg.N_id = N_id; - pbch_dmrs_cfg.n_hf = msg->hrf ? 0 : 1; + pbch_dmrs_cfg.n_hf = msg->hrf ? 1 : 0; pbch_dmrs_cfg.ssb_idx = msg->ssb_idx; pbch_dmrs_cfg.L_max = q->Lmax; pbch_dmrs_cfg.beta = 0.0f; + pbch_dmrs_cfg.scs = q->cfg.scs; if (srsran_dmrs_pbch_put(&pbch_dmrs_cfg, ssb_grid) < SRSRAN_SUCCESS) { ERROR("Error putting PBCH DMRS"); return SRSRAN_ERROR; @@ -570,7 +571,10 @@ int srsran_ssb_add(srsran_ssb_t* q, uint32_t N_id, const srsran_pbch_msg_nr_t* m // Put PBCH payload srsran_pbch_nr_cfg_t pbch_cfg = {}; pbch_cfg.N_id = N_id; + pbch_cfg.n_hf = msg->hrf; + pbch_cfg.ssb_idx = msg->ssb_idx; pbch_cfg.Lmax = q->Lmax; + pbch_cfg.beta = 0.0f; if (srsran_pbch_nr_encode(&q->pbch, &pbch_cfg, msg, ssb_grid) < SRSRAN_SUCCESS) { ERROR("Error encoding PBCH"); return SRSRAN_ERROR; diff --git a/lib/src/phy/sync/test/CMakeLists.txt b/lib/src/phy/sync/test/CMakeLists.txt index 6878da0db..776af07e8 100644 --- a/lib/src/phy/sync/test/CMakeLists.txt +++ b/lib/src/phy/sync/test/CMakeLists.txt @@ -137,11 +137,25 @@ target_link_libraries(ssb_decode_test srsran_phy) foreach (SSB_SCS 15 30) # For each supported Cell/Carrier subcarrier spacing foreach (CELL_SCS 15 30) - # Test SSB measurements - add_nr_test(ssb_measure_test_${SSB_SCS}_${CELL_SCS} ssb_measure_test -s ${SSB_SCS} -S ${CELL_SCS}) - - # Test SSB PBCH decoding - add_nr_test(ssb_decode_test_${SSB_SCS}_${CELL_SCS} ssb_decode_test -s ${SSB_SCS} -S ${CELL_SCS}) + # For 1.0 GHz and 3.5 GHz Center frequencies + foreach (CELL_FREQ 1000000000 3500000000) + # For SSB centered at -960, 0 and 960 kHz from the center frequency + foreach (SSB_OFFSET_FREQ -960000 0 960000) + # For patterns A, B, C + foreach (SSB_PATTERN A B C) + # Calculate Actual SSB center frequency + math(EXPR SSB_FREQ "${CELL_FREQ} + ${SSB_OFFSET_FREQ}") + + # Test SSB measurements + add_nr_test(ssb_measure_test_${CELL_FREQ}_${CELL_SCS}_${SSB_FREQ}_${SSB_SCS}_${SSB_PATTERN} ssb_measure_test + -F ${CELL_FREQ} -S ${CELL_SCS} -f ${SSB_FREQ} -s ${SSB_SCS}) + + # Test SSB PBCH decoding + add_nr_test(ssb_decode_test_${CELL_FREQ}_${CELL_SCS}_${SSB_FREQ}_${SSB_SCS}_${SSB_PATTERN} ssb_decode_test + -F ${CELL_FREQ} -S ${CELL_SCS} -f ${SSB_FREQ} -s ${SSB_SCS}) + endforeach () + endforeach () + endforeach () endforeach () endforeach () diff --git a/lib/src/phy/sync/test/ssb_decode_test.c b/lib/src/phy/sync/test/ssb_decode_test.c index 91377ea88..be0fd322f 100644 --- a/lib/src/phy/sync/test/ssb_decode_test.c +++ b/lib/src/phy/sync/test/ssb_decode_test.c @@ -23,7 +23,10 @@ // NR parameters static uint32_t carrier_nof_prb = 52; static srsran_subcarrier_spacing_t carrier_scs = srsran_subcarrier_spacing_15kHz; +static double carrier_freq_hz = 3.5e9 + 960e3; static srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_30kHz; +static double ssb_freq_hz = 3.5e9; +static srsran_ssb_patern_t ssb_pattern = SRSRAN_SSB_PATTERN_A; // Channel parameters static cf_t wideband_gain = 1.0f + 0.5 * I; @@ -42,14 +45,17 @@ static void usage(char* prog) { printf("Usage: %s [v]\n", prog); printf("\t-s SSB subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(ssb_scs)); + printf("\t-f SSB center frequency [default, %.3f MHz]\n", ssb_freq_hz / 1e6); printf("\t-S cell/carrier subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(carrier_scs)); + printf("\t-F cell/carrier center frequency in Hz [default, %.3f MHz]\n", carrier_freq_hz / 1e6); + printf("\t-P SSB pattern [default, %s]\n", srsran_ssb_pattern_to_str(ssb_pattern)); printf("\t-v [set srsran_verbose to debug, default none]\n"); } static void parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "Ssv")) != -1) { + while ((opt = getopt(argc, argv, "SsFfv")) != -1) { switch (opt) { case 's': ssb_scs = srsran_subcarrier_spacing_from_str(argv[optind]); @@ -58,6 +64,9 @@ static void parse_args(int argc, char** argv) exit(-1); } break; + case 'f': + ssb_freq_hz = strtod(argv[optind], NULL); + break; case 'S': carrier_scs = srsran_subcarrier_spacing_from_str(argv[optind]); if (carrier_scs == srsran_subcarrier_spacing_invalid) { @@ -65,6 +74,12 @@ static void parse_args(int argc, char** argv) exit(-1); } break; + case 'F': + carrier_freq_hz = strtod(argv[optind], NULL); + break; + case 'P': + ssb_pattern = srsran_ssb_pattern_fom_str(argv[optind]); + break; case 'v': srsran_verbose++; break; @@ -114,10 +129,10 @@ static int test_case_1(srsran_ssb_t* ssb) // SSB configuration srsran_ssb_cfg_t ssb_cfg = {}; ssb_cfg.srate_hz = srate_hz; - ssb_cfg.center_freq_hz = 3.5e9; - ssb_cfg.ssb_freq_hz = 3.5e9 - 960e3; + ssb_cfg.center_freq_hz = carrier_freq_hz; + ssb_cfg.ssb_freq_hz = ssb_freq_hz; ssb_cfg.scs = ssb_scs; - ssb_cfg.pattern = SRSRAN_SSB_PATTERN_C; + ssb_cfg.pattern = ssb_pattern; TESTASSERT(srsran_ssb_set_cfg(ssb, &ssb_cfg) == SRSRAN_SUCCESS); diff --git a/lib/src/phy/sync/test/ssb_measure_test.c b/lib/src/phy/sync/test/ssb_measure_test.c index 830d0a5e9..5ecad89ee 100644 --- a/lib/src/phy/sync/test/ssb_measure_test.c +++ b/lib/src/phy/sync/test/ssb_measure_test.c @@ -21,7 +21,10 @@ // NR parameters static uint32_t carrier_nof_prb = 52; static srsran_subcarrier_spacing_t carrier_scs = srsran_subcarrier_spacing_15kHz; +static double carrier_freq_hz = 3.5e9 + 960e3; static srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_30kHz; +static double ssb_freq_hz = 3.5e9; +static srsran_ssb_patern_t ssb_pattern = SRSRAN_SSB_PATTERN_A; // Channel parameters static int32_t delay_n = 1; @@ -46,14 +49,18 @@ static void usage(char* prog) { printf("Usage: %s [v]\n", prog); printf("\t-s SSB subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(ssb_scs)); + printf("\t-f SSB center frequency [default, %.3f MHz]\n", ssb_freq_hz / 1e6); printf("\t-S cell/carrier subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(carrier_scs)); + printf("\t-F cell/carrier center frequency in Hz [default, %.3f MHz]\n", carrier_freq_hz / 1e6); + printf("\t-P SSB pattern [default, %s]\n", srsran_ssb_pattern_to_str(ssb_pattern)); printf("\t-v [set srsran_verbose to debug, default none]\n"); } + static void parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "Ssv")) != -1) { + while ((opt = getopt(argc, argv, "SsFfv")) != -1) { switch (opt) { case 's': ssb_scs = srsran_subcarrier_spacing_from_str(argv[optind]); @@ -62,6 +69,9 @@ static void parse_args(int argc, char** argv) exit(-1); } break; + case 'f': + ssb_freq_hz = strtod(argv[optind], NULL); + break; case 'S': carrier_scs = srsran_subcarrier_spacing_from_str(argv[optind]); if (carrier_scs == srsran_subcarrier_spacing_invalid) { @@ -69,6 +79,12 @@ static void parse_args(int argc, char** argv) exit(-1); } break; + case 'F': + carrier_freq_hz = strtod(argv[optind], NULL); + break; + case 'P': + ssb_pattern = srsran_ssb_pattern_fom_str(argv[optind]); + break; case 'v': srsran_verbose++; break; @@ -114,10 +130,10 @@ static int test_case_1(srsran_ssb_t* ssb) // SSB configuration srsran_ssb_cfg_t ssb_cfg = {}; ssb_cfg.srate_hz = srate_hz; - ssb_cfg.center_freq_hz = 3.5e9; - ssb_cfg.ssb_freq_hz = 3.5e9 - 960e3; + ssb_cfg.center_freq_hz = carrier_freq_hz; + ssb_cfg.ssb_freq_hz = ssb_freq_hz; ssb_cfg.scs = ssb_scs; - ssb_cfg.pattern = SRSRAN_SSB_PATTERN_C; + ssb_cfg.pattern = ssb_pattern; TESTASSERT(srsran_ssb_set_cfg(ssb, &ssb_cfg) == SRSRAN_SUCCESS);