diff --git a/lib/include/srslte/phy/common/phy_common_sl.h b/lib/include/srslte/phy/common/phy_common_sl.h index 838b6beee..62cbc7bbf 100644 --- a/lib/include/srslte/phy/common/phy_common_sl.h +++ b/lib/include/srslte/phy/common/phy_common_sl.h @@ -91,7 +91,9 @@ typedef enum SRSLTE_API { #define SRSLTE_SL_TM12_DEFAULT_NUM_DMRS_SYMBOLS (2) #define SRSLTE_SL_TM34_DEFAULT_NUM_DMRS_SYMBOLS (4) ///< In TM3/4, all channels have 4 DMRS by default -#define SRSLTE_PSBCH_TM12_NUM_DATA_SYMBOLS (8) ///< SL-BCH is in 8 OFDM symbols (but only 7 are tx'ed) +#define SRSLTE_PSBCH_TM12_NUM_DATA_SYMBOLS (8) // PSBCH is in 8 OFDM symbols (but only 7 are tx'ed) +#define SRSLTE_PSBCH_TM12_NUM_DATA_SYMBOLS_EXT \ + (6) // PSBCH is in 7 OFDM symbols for extended cyclic prefix (but only 6 are tx'ed) #define SRSLTE_PSBCH_TM12_NUM_DMRS_SYMBOLS (2) ///< PSBCH has 2 DMRS symbols #define SRSLTE_PSBCH_TM12_NUM_SYNC_SYMBOLS (4) ///< Two symbols PSSS and two SSSS diff --git a/lib/src/phy/phch/psbch.c b/lib/src/phy/phch/psbch.c index 811623517..4722eb0ec 100644 --- a/lib/src/phy/phch/psbch.c +++ b/lib/src/phy/phch/psbch.c @@ -35,11 +35,10 @@ int srslte_psbch_init(srslte_psbch_t* q, uint32_t nof_prb, uint32_t N_sl_id, srs q->N_sl_id = N_sl_id; q->tm = tm; - q->nof_prb = nof_prb; - if (SRSLTE_CP_ISEXT(cp)) { - ERROR("Extended CP is not supported yet."); + if (SRSLTE_CP_ISEXT(cp) && (tm >= SRSLTE_SIDELINK_TM3)) { + ERROR("Selected TM does not support extended CP"); return SRSLTE_ERROR; } q->cp = cp; @@ -48,6 +47,9 @@ int srslte_psbch_init(srslte_psbch_t* q, uint32_t nof_prb, uint32_t N_sl_id, srs if (q->tm <= SRSLTE_SIDELINK_TM2) { q->nof_data_symbols = SRSLTE_PSBCH_TM12_NUM_DATA_SYMBOLS; q->sl_bch_tb_len = SRSLTE_MIB_SL_LEN; + if (SRSLTE_CP_ISEXT(cp)) { + q->nof_data_symbols = SRSLTE_PSBCH_TM12_NUM_DATA_SYMBOLS_EXT; + } } else { q->nof_data_symbols = SRSLTE_PSBCH_TM34_NUM_DATA_SYMBOLS; q->sl_bch_tb_len = SRSLTE_MIB_SL_V2X_LEN; @@ -322,7 +324,7 @@ int srslte_psbch_put(srslte_psbch_t* q, cf_t* symbols, cf_t* sf_buffer) uint32_t k = q->nof_prb * SRSLTE_NRE / 2 - 36; // Mapping to physical resources - for (uint32_t i = 0; i < SRSLTE_CP_NORM_SF_NSYMB; i++) { + for (uint32_t i = 0; i < srslte_sl_get_num_symbols(q->tm, q->cp); i++) { if (srslte_psbch_is_symbol(SRSLTE_SIDELINK_DATA_SYMBOL, q->tm, i, q->cp)) { memcpy(&sf_buffer[k + i * q->nof_prb * SRSLTE_NRE], &symbols[sample_pos], @@ -340,7 +342,7 @@ int srslte_psbch_get(srslte_psbch_t* q, cf_t* sf_buffer, cf_t* symbols) uint32_t k = q->nof_prb * SRSLTE_NRE / 2 - 36; // Get PSBCH REs - for (uint32_t i = 0; i < SRSLTE_CP_NORM_SF_NSYMB; i++) { + for (uint32_t i = 0; i < srslte_sl_get_num_symbols(q->tm, q->cp); i++) { if (srslte_psbch_is_symbol(SRSLTE_SIDELINK_DATA_SYMBOL, q->tm, i, q->cp)) { memcpy(&symbols[sample_pos], &sf_buffer[k + i * q->nof_prb * SRSLTE_NRE], diff --git a/lib/src/phy/phch/test/CMakeLists.txt b/lib/src/phy/phch/test/CMakeLists.txt index 8215137bd..4553fe5d4 100644 --- a/lib/src/phy/phch/test/CMakeLists.txt +++ b/lib/src/phy/phch/test/CMakeLists.txt @@ -43,6 +43,8 @@ target_link_libraries(psbch_test srslte_phy) add_test(psbch_test_self_test_tm2_p6_c168_self psbch_test -p 6 -c 168 -t 2) add_test(psbch_test_self_test_tm2_p50_c168_self psbch_test -p 50 -c 252 -t 2) add_test(psbch_test_self_test_tm2_p100_c168_self psbch_test -p 100 -c 335 -t 2) +add_test(psbch_test_self_test_tm2_p25_c168_ext_self psbch_test -p 25 -c 168 -e) +add_test(psbch_test_self_test_tm2_p100_c335_ext_self psbch_test -p 100 -c 335 -e) # TM4 self tests add_test(psbch_test_self_test_tm4_p6_c168_self psbch_test -p 6 -c 168 -t 4) @@ -53,11 +55,12 @@ add_executable(psbch_file_test psbch_file_test.c) target_link_libraries(psbch_file_test srslte_phy) # TM2 file tests -add_test(psbch_file_test_ideal_tm2_p6_c0 psbch_file_test -p 6 -t 2 -c 0 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p6_c0_s1.92e6.dat) -add_test(psbch_file_test_ideal_tm2_p15_c84 psbch_file_test -p 15 -t 2 -c 84 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p15_c84_s3.84e6.dat) -add_test(psbch_file_test_ideal_tm2_p25_c168 psbch_file_test -p 25 -t 2 -c 168 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p25_c168_s7.68e6.dat) -add_test(psbch_file_test_ideal_tm2_p50_c252 psbch_file_test -p 50 -t 2 -c 252 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6.dat) -add_test(psbch_file_test_ideal_tm2_p100_c335 psbch_file_test -p 100 -t 2 -c 335 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p100_c335_s30.72e6.dat) +add_test(psbch_file_test_ideal_tm2_p6_c0 psbch_file_test -p 6 -c 0 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p6_c0_s1.92e6.dat) +add_test(psbch_file_test_ideal_tm2_p15_c84 psbch_file_test -p 15 -c 84 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p15_c84_s3.84e6.dat) +add_test(psbch_file_test_ideal_tm2_p25_c168 psbch_file_test -p 25 -c 168 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p25_c168_s7.68e6.dat) +add_test(psbch_file_test_ideal_tm2_p50_c252 psbch_file_test -p 50 -c 252 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6.dat) +add_test(psbch_file_test_ideal_tm2_p100_c335 psbch_file_test -p 100 -c 335 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p100_c335_s30.72e6.dat) +add_test(psbch_file_test_ideal_tm2_p50_c252_ext psbch_file_test -p 50 -c 252 -e -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6_ext.dat) # TM4 file tests add_test(psbch_file_test_cmw_tm4_p50_c169 psbch_file_test -p 50 -c 169 -t 4 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_cmw500_f5.92e9_s11.52e6_50prb_slss_id169.dat) diff --git a/lib/src/phy/phch/test/psbch_file_test.c b/lib/src/phy/phch/test/psbch_file_test.c index 4a4356aee..369461d9f 100644 --- a/lib/src/phy/phch/test/psbch_file_test.c +++ b/lib/src/phy/phch/test/psbch_file_test.c @@ -29,18 +29,16 @@ #include "srslte/phy/io/filesource.h" #include "srslte/phy/phch/mib_sl.h" #include "srslte/phy/phch/psbch.h" -#include "srslte/phy/sync/cfo.h" #include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/vector.h" srslte_cell_sl_t cell = {.nof_prb = 6, .N_sl_id = 168, .tm = SRSLTE_SIDELINK_TM2, .cp = SRSLTE_CP_NORM}; - -char* input_file_name; -uint32_t offset = 0; -float frequency_offset = 0.0; -float snr = 100.0; -bool use_standard_lte_rates = false; -bool do_equalization = true; +char* input_file_name; +uint32_t offset = 0; +float frequency_offset = 0.0; +float snr = 100.0; +bool use_standard_lte_rates = false; +bool do_equalization = true; srslte_filesource_t fsrc; @@ -107,6 +105,11 @@ void parse_args(int argc, char** argv) exit(-1); } } + if (SRSLTE_CP_ISEXT(cell.cp) && cell.tm >= SRSLTE_SIDELINK_TM3) { + ERROR("Selected TM does not support extended CP"); + usage(argv[0]); + exit(-1); + } } int main(int argc, char** argv) @@ -122,7 +125,7 @@ int main(int argc, char** argv) uint32_t sf_n_samples = srslte_symbol_sz(cell.nof_prb) * 15; printf("sf_n_samples: %i\n", sf_n_samples); - uint32_t sf_n_re = SRSLTE_CP_NSYMB(cell.cp) * SRSLTE_NRE * 2 * cell.nof_prb; + uint32_t sf_n_re = SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp); cf_t* sf_buffer = srslte_vec_cf_malloc(sf_n_re); cf_t* equalized_sf_buffer = srslte_vec_cf_malloc(sf_n_re); @@ -149,7 +152,7 @@ int main(int argc, char** argv) // PSBCH srslte_psbch_t psbch; - if (srslte_psbch_init(&psbch, cell.nof_prb, cell.N_sl_id, cell.tm, SRSLTE_CP_NORM) != SRSLTE_SUCCESS) { + if (srslte_psbch_init(&psbch, cell.nof_prb, cell.N_sl_id, cell.tm, cell.cp) != SRSLTE_SUCCESS) { ERROR("Error in psbch init\n"); return SRSLTE_ERROR; } diff --git a/lib/src/phy/phch/test/psbch_test.c b/lib/src/phy/phch/test/psbch_test.c index 5aaa98088..842e453eb 100644 --- a/lib/src/phy/phch/test/psbch_test.c +++ b/lib/src/phy/phch/test/psbch_test.c @@ -20,7 +20,6 @@ */ #include -#include #include #include @@ -30,18 +29,15 @@ #include #include -int32_t N_sl_id = 168; -srslte_cp_t cp = SRSLTE_CP_NORM; -uint32_t nof_prb = 6; -srslte_sl_tm_t tm = SRSLTE_SIDELINK_TM2; +srslte_cell_sl_t cell = {.nof_prb = 6, .N_sl_id = 168, .tm = SRSLTE_SIDELINK_TM2, .cp = SRSLTE_CP_NORM}; void usage(char* prog) { printf("Usage: %s [cdeipt]\n", prog); - printf("\t-p nof_prb [Default %d]\n", nof_prb); + printf("\t-p nof_prb [Default %d]\n", cell.nof_prb); printf("\t-e extended CP [Default normal]\n"); - printf("\t-c N_sl_id [Default %d]\n", N_sl_id); - printf("\t-t Sidelink transmission mode {1,2,3,4} [Default %d]\n", (tm + 1)); + printf("\t-c N_sl_id [Default %d]\n", cell.N_sl_id); + printf("\t-t Sidelink transmission mode {1,2,3,4} [Default %d]\n", (cell.tm + 1)); printf("\t-v [set srslte_verbose to debug, default none]\n"); } @@ -51,27 +47,27 @@ void parse_args(int argc, char** argv) while ((opt = getopt(argc, argv, "ceiptv")) != -1) { switch (opt) { case 'c': - N_sl_id = (int32_t)strtol(argv[optind], NULL, 10); + cell.N_sl_id = (int32_t)strtol(argv[optind], NULL, 10); break; case 'e': - cp = SRSLTE_CP_EXT; + cell.cp = SRSLTE_CP_EXT; break; case 'p': - nof_prb = (uint32_t)strtol(argv[optind], NULL, 10); + cell.nof_prb = (uint32_t)strtol(argv[optind], NULL, 10); break; case 't': switch (strtol(argv[optind], NULL, 10)) { case 1: - tm = SRSLTE_SIDELINK_TM1; + cell.tm = SRSLTE_SIDELINK_TM1; break; case 2: - tm = SRSLTE_SIDELINK_TM2; + cell.tm = SRSLTE_SIDELINK_TM2; break; case 3: - tm = SRSLTE_SIDELINK_TM3; + cell.tm = SRSLTE_SIDELINK_TM3; break; case 4: - tm = SRSLTE_SIDELINK_TM4; + cell.tm = SRSLTE_SIDELINK_TM4; break; default: usage(argv[0]); @@ -87,6 +83,11 @@ void parse_args(int argc, char** argv) exit(-1); } } + if (SRSLTE_CP_ISEXT(cell.cp) && cell.tm >= SRSLTE_SIDELINK_TM3) { + ERROR("Selected TM does not support extended CP"); + usage(argv[0]); + exit(-1); + } } int main(int argc, char** argv) @@ -95,17 +96,17 @@ int main(int argc, char** argv) parse_args(argc, argv); - uint32_t sf_n_re = SRSLTE_SF_LEN_RE(nof_prb, cp); + uint32_t sf_n_re = SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp); cf_t* sf_buffer = srslte_vec_cf_malloc(sf_n_re); // MIB-SL srslte_mib_sl_t mib_sl; - srslte_mib_sl_init(&mib_sl, tm); - srslte_mib_sl_set(&mib_sl, nof_prb, 0, 128, 4, false); + srslte_mib_sl_init(&mib_sl, cell.tm); + srslte_mib_sl_set(&mib_sl, cell.nof_prb, 0, 128, 4, false); // PSBCH srslte_psbch_t psbch; - if (srslte_psbch_init(&psbch, nof_prb, N_sl_id, tm, SRSLTE_CP_NORM) != SRSLTE_SUCCESS) { + if (srslte_psbch_init(&psbch, cell.nof_prb, cell.N_sl_id, cell.tm, cell.cp) != SRSLTE_SUCCESS) { ERROR("Error in psbch init\n"); return SRSLTE_ERROR; } @@ -132,16 +133,22 @@ int main(int argc, char** argv) srslte_mib_sl_printf(stdout, &mib_sl); // check decoded bandwidth matches user configured value - if (srslte_mib_sl_bandwith_to_prb[mib_sl.sl_bandwidth_r12] == nof_prb) { + if (srslte_mib_sl_bandwith_to_prb[mib_sl.sl_bandwidth_r12] == cell.nof_prb) { ret = SRSLTE_SUCCESS; } } // Sanity check (less REs are transmitted than mapped) - if (tm <= SRSLTE_SIDELINK_TM2) { - // TM1 and TM2 have always 576 mapped PSBCH resource elements of which 504 are transmitted - TESTASSERT(psbch.nof_data_re == 576); - TESTASSERT(psbch.nof_tx_re == 504); + if (cell.tm <= SRSLTE_SIDELINK_TM2) { + if (SRSLTE_CP_ISNORM(cell.cp)) { + // TM1 and TM2 have always 576 mapped PSBCH resource elements of which 504 are transmitted + TESTASSERT(psbch.nof_data_re == 576); + TESTASSERT(psbch.nof_tx_re == 504); + } else { + // TM1 and TM2 with extended cp have always 432 mapped PSBCH resource elements of which 360 are transmitted + TESTASSERT(psbch.nof_data_re == 432); + TESTASSERT(psbch.nof_tx_re == 360); + } } else { // TM3 and TM4 have always 504 mapped PSBCH resource elements of which 432 are transmitted TESTASSERT(psbch.nof_data_re == 504); diff --git a/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6_ext.dat b/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6_ext.dat new file mode 100644 index 000000000..c68a974e7 Binary files /dev/null and b/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6_ext.dat differ