mirror of https://github.com/PentHertz/srsLTE.git
fix PSBCH and use UL-SCH interleaver
This commit is contained in:
parent
9012ca5faa
commit
d98bc71057
|
@ -361,11 +361,11 @@ 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 (7) ///< SL-BCH is in 7 OFDM symbols
|
||||
#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_DMRS_SYMBOLS (2) ///< PSBCH has 2 DMRS symbols
|
||||
#define SRSLTE_PSBCH_TM12_NUM_SYNC_SYMBOLS (4) ///< Two symbols PSSS and two SSSS
|
||||
|
||||
#define SRSLTE_PSBCH_TM34_NUM_DATA_SYMBOLS (6) ///< SL-BCH is in 7 OFDM symbols
|
||||
#define SRSLTE_PSBCH_TM34_NUM_DATA_SYMBOLS (7) ///< SL-BCH is in 7 OFDM symbols (but only 6 are tx'ed)
|
||||
#define SRSLTE_PSBCH_TM34_NUM_DMRS_SYMBOLS (3) ///< PSBCH has 3 DMRS symbols in TM3 and TM4
|
||||
#define SRSLTE_PSBCH_TM34_NUM_SYNC_SYMBOLS (4) ///< Two symbols PSSS and two SSSS
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ typedef struct SRSLTE_API {
|
|||
|
||||
} srslte_mib_sl_t;
|
||||
|
||||
static const int srslte_mib_sl_bandwith_to_prb[6] = {6, 15, 25, 50, 75, 100};
|
||||
|
||||
SRSLTE_API int srslte_mib_sl_init(srslte_mib_sl_t* q, srslte_sl_tm_t tm);
|
||||
|
||||
SRSLTE_API int srslte_mib_sl_set(srslte_mib_sl_t* q,
|
||||
|
|
|
@ -42,12 +42,13 @@ typedef struct SRSLTE_API {
|
|||
srslte_sl_tm_t tm;
|
||||
srslte_cp_t cp;
|
||||
|
||||
uint32_t nof_data_re;
|
||||
uint32_t nof_data_re; ///< Number of RE considered during the channel mapping
|
||||
uint32_t nof_tx_re; ///< Number of RE actually transmitted over the air (without last OFDM symbol)
|
||||
uint32_t E;
|
||||
uint32_t Qm;
|
||||
uint32_t len_after_mod;
|
||||
uint32_t nof_prb;
|
||||
uint32_t nof_data_symbols;
|
||||
uint32_t nof_tx_symbols;
|
||||
uint32_t sl_bch_tb_len;
|
||||
uint32_t sl_bch_tb_crc_len;
|
||||
uint32_t sl_bch_encoded_len;
|
||||
|
@ -64,14 +65,16 @@ typedef struct SRSLTE_API {
|
|||
srslte_viterbi_t dec;
|
||||
srslte_convcoder_t encoder;
|
||||
uint8_t* d;
|
||||
float* d_float;
|
||||
int16_t* d_16;
|
||||
|
||||
// rate matching
|
||||
uint8_t* e;
|
||||
float* e_float;
|
||||
uint8_t* e_bytes; ///< To pack bits to bytes
|
||||
int16_t* e_16;
|
||||
|
||||
uint8_t* codeword;
|
||||
float* llr;
|
||||
uint8_t* codeword_bytes;
|
||||
int16_t* llr;
|
||||
|
||||
// interleaving
|
||||
uint32_t* interleaver_lut;
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#include "srslte/phy/phch/mib_sl.h"
|
||||
#include "srslte/phy/utils/bit.h"
|
||||
//#include "srslte/phy/common/phy_sl_common.h"
|
||||
|
||||
int srslte_mib_sl_init(srslte_mib_sl_t* q, srslte_sl_tm_t tm)
|
||||
{
|
||||
|
|
|
@ -22,38 +22,13 @@
|
|||
#include "srslte/phy/phch/psbch.h"
|
||||
#include "srslte/phy/fec/rm_conv.h"
|
||||
#include "srslte/phy/modem/mod.h"
|
||||
#include "srslte/phy/phch/sch.h"
|
||||
#include "srslte/phy/utils/bit.h"
|
||||
#include "srslte/phy/utils/debug.h"
|
||||
#include "srslte/phy/utils/vector.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define HAVE_INTERLEAVING 1
|
||||
|
||||
#if HAVE_INTERLEAVING
|
||||
void slbch_interleave_gen(uint32_t H_prime_total, uint32_t N_pusch_symbs, uint32_t Qm, uint32_t* interleaver_lut)
|
||||
{
|
||||
uint32_t NL = 1;
|
||||
uint32_t Cmux = N_pusch_symbs;
|
||||
uint32_t Rmux = H_prime_total * Qm * NL / Cmux;
|
||||
uint32_t y_indices[Rmux][Cmux];
|
||||
|
||||
for (int i = 0; i < Rmux; i++) {
|
||||
for (int k = 0; k < Cmux; k++) {
|
||||
y_indices[i][k] = Rmux * k + i;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t arrayIdx = 0;
|
||||
for (int i = 0; i < Rmux; i += 2) {
|
||||
for (int k = 0; k < Cmux; k++) {
|
||||
interleaver_lut[arrayIdx++] = y_indices[i][k];
|
||||
interleaver_lut[arrayIdx++] = y_indices[i + 1][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // HAVE_INTERLEAVING
|
||||
|
||||
int srslte_psbch_init(srslte_psbch_t* q, uint32_t nof_prb, uint32_t N_sl_id, srslte_sl_tm_t tm, srslte_cp_t cp)
|
||||
{
|
||||
bzero(q, sizeof(srslte_psbch_t));
|
||||
|
@ -77,7 +52,9 @@ int srslte_psbch_init(srslte_psbch_t* q, uint32_t nof_prb, uint32_t N_sl_id, srs
|
|||
q->nof_data_symbols = SRSLTE_PSBCH_TM34_NUM_DATA_SYMBOLS;
|
||||
q->sl_bch_tb_len = SRSLTE_MIB_SL_V2X_LEN;
|
||||
}
|
||||
q->nof_tx_symbols = q->nof_data_symbols - 1; ///< Last OFDM symbol is used channel processing but not transmitted
|
||||
q->nof_data_re = q->nof_data_symbols * (SRSLTE_NRE * SRSLTE_PSBCH_NOF_PRB);
|
||||
q->nof_tx_re = q->nof_tx_symbols * (SRSLTE_NRE * SRSLTE_PSBCH_NOF_PRB);
|
||||
q->sl_bch_tb_crc_len = q->sl_bch_tb_len + SRSLTE_SL_BCH_CRC_LEN;
|
||||
q->sl_bch_encoded_len = 3 * q->sl_bch_tb_crc_len;
|
||||
|
||||
|
@ -93,8 +70,8 @@ int srslte_psbch_init(srslte_psbch_t* q, uint32_t nof_prb, uint32_t N_sl_id, srs
|
|||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
q->d_float = srslte_vec_malloc(sizeof(float) * q->sl_bch_encoded_len);
|
||||
if (!q->d_float) {
|
||||
q->d_16 = srslte_vec_malloc(sizeof(int16_t) * q->sl_bch_encoded_len);
|
||||
if (!q->d_16) {
|
||||
ERROR("Error allocating memory\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
@ -133,21 +110,17 @@ int srslte_psbch_init(srslte_psbch_t* q, uint32_t nof_prb, uint32_t N_sl_id, srs
|
|||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
q->e_float = srslte_vec_malloc(sizeof(float) * q->E);
|
||||
if (!q->e_float) {
|
||||
q->e_16 = srslte_vec_malloc(sizeof(int16_t) * q->E);
|
||||
if (!q->e_16) {
|
||||
ERROR("Error allocating memory\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
#if HAVE_INTERLEAVING
|
||||
// Interleaving
|
||||
q->interleaver_lut = srslte_vec_malloc(sizeof(uint32_t) * q->E);
|
||||
if (!q->interleaver_lut) {
|
||||
q->e_bytes = srslte_vec_malloc(sizeof(uint8_t) * q->E / 8);
|
||||
if (!q->e_bytes) {
|
||||
ERROR("Error allocating memory\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
slbch_interleave_gen(q->nof_data_re, q->nof_data_symbols, q->Qm, q->interleaver_lut);
|
||||
#endif
|
||||
|
||||
// Scrambling
|
||||
bzero(&q->seq, sizeof(srslte_sequence_t));
|
||||
|
@ -162,6 +135,19 @@ int srslte_psbch_init(srslte_psbch_t* q, uint32_t nof_prb, uint32_t N_sl_id, srs
|
|||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
q->codeword_bytes = srslte_vec_malloc(sizeof(uint8_t) * q->E / 8);
|
||||
if (!q->codeword_bytes) {
|
||||
ERROR("Error allocating memory\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// Interleaving
|
||||
q->interleaver_lut = srslte_vec_malloc(sizeof(uint32_t) * q->E);
|
||||
if (!q->interleaver_lut) {
|
||||
ERROR("Error allocating memory\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// Modulation QPSK
|
||||
if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK) != SRSLTE_SUCCESS) {
|
||||
ERROR("Error srslte_modem_table_lte\n");
|
||||
|
@ -174,7 +160,8 @@ int srslte_psbch_init(srslte_psbch_t* q, uint32_t nof_prb, uint32_t N_sl_id, srs
|
|||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
q->llr = srslte_vec_malloc(sizeof(float) * q->E);
|
||||
// Soft-demod
|
||||
q->llr = srslte_vec_malloc(sizeof(int16_t) * q->E);
|
||||
if (!q->llr) {
|
||||
ERROR("Error allocating memory\n");
|
||||
return SRSLTE_ERROR;
|
||||
|
@ -192,6 +179,8 @@ int srslte_psbch_init(srslte_psbch_t* q, uint32_t nof_prb, uint32_t N_sl_id, srs
|
|||
ERROR("Error allocating memory\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
///< Make sure last bits are zero as they are not considered during unpack
|
||||
bzero(q->scfdma_symbols, sizeof(cf_t) * q->nof_data_re);
|
||||
|
||||
if (srslte_dft_precoding_init_rx(&q->idft_precoder, SRSLTE_PSBCH_NOF_PRB) != SRSLTE_SUCCESS) {
|
||||
ERROR("Error srslte_idft_precoding_init\n");
|
||||
|
@ -218,20 +207,23 @@ int srslte_psbch_encode(srslte_psbch_t* q, uint8_t* input, uint32_t input_len, c
|
|||
srslte_convcoder_encode(&q->encoder, q->c, q->d, q->sl_bch_tb_crc_len);
|
||||
|
||||
// Rate matching
|
||||
srslte_rm_conv_tx(q->d, q->sl_bch_encoded_len, q->codeword, q->E);
|
||||
srslte_rm_conv_tx(q->d, q->sl_bch_encoded_len, q->e, q->E);
|
||||
|
||||
#if HAVE_INTERLEAVING
|
||||
// PUSCH de-interleaving
|
||||
for (int i = 0; i < q->E; i++) {
|
||||
q->e[i] = q->codeword[q->interleaver_lut[i]];
|
||||
}
|
||||
#endif
|
||||
// Interleaving
|
||||
srslte_bit_pack_vector(q->e, q->e_bytes, q->E);
|
||||
srslte_sl_ulsch_interleave(q->e_bytes, // input bytes
|
||||
q->Qm, // modulation
|
||||
q->nof_data_re, // prime number
|
||||
q->nof_data_symbols, // number of symbols
|
||||
q->codeword_bytes // output
|
||||
);
|
||||
srslte_bit_unpack_vector(q->codeword_bytes, q->codeword, q->E);
|
||||
|
||||
// Scrambling
|
||||
srslte_scrambling_b(&q->seq, q->e);
|
||||
srslte_scrambling_b(&q->seq, q->codeword);
|
||||
|
||||
// Modulation
|
||||
srslte_mod_modulate(&q->mod, q->e, q->mod_symbols, q->E);
|
||||
srslte_mod_modulate(&q->mod, q->codeword, q->mod_symbols, q->E);
|
||||
|
||||
// Layer Mapping
|
||||
// Void: Single layer
|
||||
|
@ -258,7 +250,7 @@ int srslte_psbch_decode(srslte_psbch_t* q, cf_t* equalized_sf_syms, uint8_t* out
|
|||
}
|
||||
|
||||
// RE extraction
|
||||
if (q->nof_data_re != srslte_psbch_get(q, equalized_sf_syms, q->scfdma_symbols)) {
|
||||
if (q->nof_tx_re != srslte_psbch_get(q, equalized_sf_syms, q->scfdma_symbols)) {
|
||||
ERROR("There was an error getting the PSBCH symbols\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
@ -275,26 +267,19 @@ int srslte_psbch_decode(srslte_psbch_t* q, cf_t* equalized_sf_syms, uint8_t* out
|
|||
// 3GPP TS 36.211 version 15.6.0 Release 15 Sec. 9.6.3
|
||||
|
||||
// Demodulation
|
||||
srslte_demod_soft_demodulate(SRSLTE_MOD_QPSK, q->mod_symbols, q->e_float, q->nof_data_re);
|
||||
srslte_demod_soft_demodulate_s(SRSLTE_MOD_QPSK, q->mod_symbols, q->llr, q->nof_data_re);
|
||||
|
||||
// De-scramble
|
||||
srslte_scrambling_f(&q->seq, q->e_float);
|
||||
srslte_scrambling_s(&q->seq, q->llr);
|
||||
|
||||
#if HAVE_INTERLEAVING
|
||||
// Deinterleaving
|
||||
for (int i = 0; i < q->E; i++) {
|
||||
q->e_float[q->interleaver_lut[i]] = q->e_float[i];
|
||||
}
|
||||
#endif
|
||||
srslte_sl_ulsch_deinterleave(q->llr, q->Qm, q->nof_data_re, q->nof_data_symbols, q->e_16, q->interleaver_lut);
|
||||
|
||||
// Rate match
|
||||
srslte_rm_conv_rx(q->e_float, q->E, q->d_float, q->sl_bch_encoded_len);
|
||||
srslte_rm_conv_rx_s(q->e_16, q->E, q->d_16, q->sl_bch_encoded_len);
|
||||
|
||||
// Channel decoding
|
||||
srslte_viterbi_decode_f(&q->dec, q->d_float, q->c, q->sl_bch_tb_crc_len);
|
||||
|
||||
printf("after viterbi\n");
|
||||
srslte_vec_fprint_b(stdout, q->c, q->sl_bch_tb_crc_len);
|
||||
srslte_viterbi_decode_s(&q->dec, q->d_16, q->c, q->sl_bch_tb_crc_len);
|
||||
|
||||
// Copy received crc to temp
|
||||
memcpy(q->crc_temp, &q->c[q->sl_bch_tb_len], sizeof(uint8_t) * SRSLTE_SL_BCH_CRC_LEN);
|
||||
|
@ -386,14 +371,17 @@ void srslte_psbch_free(srslte_psbch_t* q)
|
|||
if (q->d) {
|
||||
free(q->d);
|
||||
}
|
||||
if (q->d_float) {
|
||||
free(q->d_float);
|
||||
if (q->d_16) {
|
||||
free(q->d_16);
|
||||
}
|
||||
if (q->e) {
|
||||
free(q->e);
|
||||
}
|
||||
if (q->e_float) {
|
||||
free(q->e_float);
|
||||
if (q->e_bytes) {
|
||||
free(q->e_bytes);
|
||||
}
|
||||
if (q->e_16) {
|
||||
free(q->e_16);
|
||||
}
|
||||
if (q->interleaver_lut) {
|
||||
free(q->interleaver_lut);
|
||||
|
@ -401,6 +389,9 @@ void srslte_psbch_free(srslte_psbch_t* q)
|
|||
if (q->codeword) {
|
||||
free(q->codeword);
|
||||
}
|
||||
if (q->codeword_bytes) {
|
||||
free(q->codeword_bytes);
|
||||
}
|
||||
if (q->llr) {
|
||||
free(q->llr);
|
||||
}
|
||||
|
|
|
@ -131,16 +131,21 @@ int main(int argc, char** argv)
|
|||
srslte_mib_sl_unpack(&mib_sl, mib_sl_rx);
|
||||
srslte_mib_sl_printf(stdout, &mib_sl);
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
// check decoded bandwidth matches user configured value
|
||||
if (srslte_mib_sl_bandwith_to_prb[mib_sl.sl_bandwidth_r12] == nof_prb) {
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
// Sanity check (less REs are transmitted than mapped)
|
||||
if (tm <= SRSLTE_SIDELINK_TM2) {
|
||||
// TM1 and TM2 have always 504 PSBCH resource elements
|
||||
TESTASSERT(psbch.E / psbch.Qm == 504);
|
||||
// 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 {
|
||||
// TM3 and TM4 have always 432 PSBCH resource elements
|
||||
TESTASSERT(psbch.E / psbch.Qm == 432);
|
||||
// TM3 and TM4 have always 504 mapped PSBCH resource elements of which 432 are transmitted
|
||||
TESTASSERT(psbch.nof_data_re == 504);
|
||||
TESTASSERT(psbch.nof_tx_re == 432);
|
||||
}
|
||||
|
||||
if (SRSLTE_VERBOSE_ISDEBUG()) {
|
||||
|
|
Loading…
Reference in New Issue