PDSCH-NR fixed with unit test

master
Xavier Arteaga 4 years ago committed by Andre Puschmann
parent 6defd2658c
commit 0138c3b856

@ -77,6 +77,6 @@ SRSLTE_API int srslte_layerdemap_type(cf_t* x[SRSLTE_MAX_LAYERS],
SRSLTE_API int srslte_layermap_nr(cf_t** d, int nof_cw, cf_t** x, int nof_layers, uint32_t nof_re);
SRSLTE_API int srslte_layerdemap_nr(cf_t** d, int nof_cw, const cf_t** x, int nof_layers, uint32_t nof_re);
SRSLTE_API int srslte_layerdemap_nr(cf_t** d, int nof_cw, cf_t** x, int nof_layers, uint32_t nof_re);
#endif // SRSLTE_LAYERMAP_H

@ -41,6 +41,7 @@ typedef struct SRSLTE_API {
int tbs; ///< Payload size, TS 38.212 refers to it as A
double R; ///< Target LDPC rate
int rv;
uint32_t nof_re; ///< Number of available resource elements to send, known as N_RE
uint32_t nof_bits; ///< Number of available bits to send, known as G
uint32_t cw_idx;
bool enabled;

@ -262,7 +262,7 @@ int srslte_layermap_nr(cf_t** d, int nof_cw, cf_t** x, int nof_layers, uint32_t
return SRSLTE_ERROR;
}
int srslte_layerdemap_nr(cf_t** d, int nof_cw, const cf_t** x, int nof_layers, uint32_t nof_re)
int srslte_layerdemap_nr(cf_t** d, int nof_cw, cf_t** x, int nof_layers, uint32_t nof_re)
{
if (nof_cw == 1 && nof_layers > 0 && nof_layers < 5) {
for (uint32_t i = 0; i < nof_re / nof_layers; i++) {

@ -20,6 +20,7 @@
*/
#include "srslte/phy/phch/pdsch_nr.h"
#include "srslte/phy/common/phy_common_nr.h"
#include "srslte/phy/phch/ra_nr.h"
int pdsch_nr_init_common(srslte_pdsch_nr_t* q)
{
@ -64,6 +65,7 @@ int srslte_pdsch_nr_init_rx(srslte_pdsch_nr_t* q)
}
srslte_sch_nr_decoder_cfg_t decoder_cfg = {};
decoder_cfg.disable_simd = true;
if (srslte_sch_nr_init_rx(&q->sch, &decoder_cfg)) {
ERROR("Initialising SCH\n");
return SRSLTE_ERROR;
@ -319,7 +321,12 @@ static int srslte_pdsch_nr_cp(const srslte_pdsch_nr_t* q,
return SRSLTE_ERROR;
}
for (uint32_t l = grant->S; l < grant->L; l++) {
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
printf("dmrs_l_idx=");
srslte_vec_fprint_i(stdout, (int32_t*)dmrs_l_idx, nof_dmrs_symbols);
}
for (uint32_t l = grant->S; l < grant->S + grant->L; l++) {
// Advance DMRS symbol counter until:
// - the current DMRS symbol index is greater or equal than current symbol l
// - no more DMRS symbols
@ -386,6 +393,11 @@ static inline int pdsch_nr_encode_codeword(srslte_pdsch_nr_t* q,
return SRSLTE_ERROR;
}
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
printf("b=");
srslte_vec_fprint_b(stdout, q->b[tb->cw_idx], tb->nof_bits);
}
// 7.3.1.1 Scrambling
uint32_t n_id = q->carrier.id;
if (cfg->scrambling_id_present && SRSLTE_RNTI_ISUSER(rnti)) {
@ -397,6 +409,11 @@ static inline int pdsch_nr_encode_codeword(srslte_pdsch_nr_t* q,
// 7.3.1.2 Modulation
srslte_mod_modulate(&q->modem_tables[tb->mod], q->b[tb->cw_idx], q->d[tb->cw_idx], tb->nof_bits);
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
printf("d=");
srslte_vec_fprint_c(stdout, q->d[tb->cw_idx], tb->nof_re);
}
return SRSLTE_SUCCESS;
}
@ -471,12 +488,20 @@ static inline int pdsch_nr_decode_codeword(srslte_pdsch_nr_t* q,
return SRSLTE_ERROR_OUT_OF_BOUNDS;
}
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
printf("d=");
srslte_vec_fprint_c(stdout, q->d[tb->cw_idx], tb->nof_re);
}
// Demodulation
cf_t** d = (tb->N_L > 1) ? q->d : q->x;
int8_t* llr = (int8_t*)q->b;
if (srslte_demod_soft_demodulate_b(tb->mod, d[tb->cw_idx], llr, tb->nof_bits)) {
int8_t* llr = (int8_t*)q->b[tb->cw_idx];
if (srslte_demod_soft_demodulate_b(tb->mod, q->d[tb->cw_idx], llr, tb->nof_re)) {
return SRSLTE_ERROR;
}
// Change LLR sign
for (uint32_t i = 0; i < tb->nof_bits; i++) {
llr[i] = -llr[i];
}
// Descrambling
uint32_t n_id = q->carrier.id;
@ -486,6 +511,11 @@ static inline int pdsch_nr_decode_codeword(srslte_pdsch_nr_t* q,
uint32_t cinit = ((uint32_t)rnti << 15U) + (tb->cw_idx << 14U) + n_id;
srslte_sequence_apply_c(llr, llr, tb->nof_bits, cinit);
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
printf("b=");
srslte_vec_fprint_b(stdout, q->b[tb->cw_idx], tb->nof_bits);
}
// Decode SCH
if (srslte_dlsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, llr, res->payload, &res->crc) < SRSLTE_SUCCESS) {
ERROR("Error in DL-SCH encoding\n");
@ -507,8 +537,15 @@ int srslte_pdsch_nr_decode(srslte_pdsch_nr_t* q,
nof_cw += grant->tb[tb].enabled ? 1 : 0;
}
uint32_t nof_re = srslte_ra_dl_nr_slot_nof_re(cfg, grant);
// Demapping from virtual to physical resource blocks
srslte_pdsch_nr_get(q, cfg, grant, q->x[0], sf_symbols[0]);
cf_t** x = (grant->nof_layers > 1) ? q->x : q->d;
uint32_t nof_re_get = srslte_pdsch_nr_get(q, cfg, grant, x[0], sf_symbols[0]);
if (nof_re_get != nof_re) {
ERROR("Inconsistent number of RE (%d!=%d)\n", nof_re_get, nof_re);
return SRSLTE_ERROR;
}
// Demapping to virtual resource blocks
// ... Not implemented
@ -518,7 +555,7 @@ int srslte_pdsch_nr_decode(srslte_pdsch_nr_t* q,
// Layer demapping
if (grant->nof_layers > 1) {
srslte_layermap_nr(q->d, nof_cw, q->x, grant->nof_layers, grant->nof_layers);
srslte_layerdemap_nr(q->d, nof_cw, q->x, grant->nof_layers, nof_re);
}
// SCH decode
@ -532,4 +569,4 @@ int srslte_pdsch_nr_decode(srslte_pdsch_nr_t* q,
}
return SRSLTE_SUCCESS;
}
}

@ -381,7 +381,8 @@ int srslte_ra_nr_fill_tb(const srslte_pdsch_cfg_nr_t* pdsch_cfg,
tb->tbs = (int)srslte_ra_nr_tbs(N_re, S, R, Qm, tb->N_L);
tb->R = R;
tb->mod = m;
tb->nof_bits = N_re * Qm * grant->nof_layers;
tb->nof_re = N_re * grant->nof_layers;
tb->nof_bits = tb->nof_re * Qm;
tb->enabled = true;
return SRSLTE_SUCCESS;

@ -405,7 +405,10 @@ int srslte_dlsch_nr_encode(srslte_sch_nr_t* q,
// Calculate TB CRC
uint32_t checksum_tb = srslte_crc_checksum_byte(cfg.crc_tb, data, tb->tbs);
// printf(" Encode: "); srslte_vec_fprint_byte(stdout, data, tb->tbs / 8);
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
printf("Encode: ");
srslte_vec_fprint_byte(stdout, data, tb->tbs / 8);
}
// For each code block...
uint32_t j = 0;
@ -423,23 +426,30 @@ int srslte_dlsch_nr_encode(srslte_sch_nr_t* q,
// If it is the last segment...
if (r == cfg.C - 1) {
cb_len -= cfg.L_tb;
// Copy payload without TB CRC
srslte_bit_unpack_vector(input_ptr, q->temp_cb, (int)(cb_len - cfg.L_tb));
srslte_bit_unpack_vector(input_ptr, q->temp_cb, (int)cb_len);
// Append TB CRC
uint8_t* ptr = &q->temp_cb[cfg.Kp - cfg.L_cb - cfg.L_tb];
uint8_t* ptr = &q->temp_cb[cb_len];
srslte_bit_unpack(checksum_tb, &ptr, cfg.L_tb);
INFO("CB %d: appending TB CRC=%06x\n", r, checksum_tb);
} else {
// Copy payload
srslte_bit_unpack_vector(input_ptr, q->temp_cb, (int)cb_len);
}
// printf("CB %d:", r); srslte_vec_fprint_byte(stdout, input_ptr, cb_len / 8);
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
printf("CB %d:", r);
srslte_vec_fprint_byte(stdout, input_ptr, cb_len / 8);
}
input_ptr += cb_len / 8;
// Attach code block CRC if required
if (cfg.L_cb) {
srslte_crc_attach(&q->crc_cb, q->temp_cb, (int)cb_len);
srslte_crc_attach(&q->crc_cb, q->temp_cb, (int)(cfg.Kp - cfg.L_cb));
INFO("CB %d: CRC=%06x\n", r, (uint32_t)srslte_crc_checksum_get(&q->crc_cb));
}
@ -604,7 +614,11 @@ int srslte_dlsch_nr_decode(srslte_sch_nr_t* q,
srslte_vec_u8_copy(output_ptr, tb->softbuffer.rx->data[r], cb_len / 8);
output_ptr += cb_len / 8;
// printf("CB %d:", r); srslte_vec_fprint_byte(stdout, tb->softbuffer.rx->data[r], cb_len / 8);
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
printf("CB %d:", r);
srslte_vec_fprint_byte(stdout, tb->softbuffer.rx->data[r], cb_len / 8);
}
if (r == cfg.C - 1) {
uint8_t tb_crc_unpacked[24] = {};
@ -619,7 +633,10 @@ int srslte_dlsch_nr_decode(srslte_sch_nr_t* q,
*crc_ok = (checksum1 == checksum2);
INFO("TB: TBS=%d; CRC={%06x, %06x}\n", tb->tbs, checksum1, checksum2);
// printf("Decoded: "); srslte_vec_fprint_byte(stdout, data, tb->tbs / 8);
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
printf("Decode: ");
srslte_vec_fprint_byte(stdout, data, tb->tbs / 8);
}
} else {
*crc_ok = false;
}

@ -23,9 +23,9 @@
#include "srslte/phy/phch/ra_nr.h"
#include "srslte/phy/ue/ue_dl_nr_data.h"
#include "srslte/phy/utils/debug.h"
#include "srslte/phy/utils/random.h"
#include "srslte/phy/utils/vector.h"
#include <getopt.h>
#include <srslte/phy/utils/random.h>
static srslte_carrier_nr_t carrier = {
0, // cell_id
@ -217,12 +217,33 @@ int main(int argc, char** argv)
goto clean_exit;
}
float mse = 0.0f;
uint32_t nof_re = srslte_ra_dl_nr_slot_nof_re(&pdsch_cfg, &pdsch_grant);
for (uint32_t i = 0; i < pdsch_grant.nof_layers; i++) {
for (uint32_t j = 0; j < nof_re; j++) {
mse += cabsf(pdsch_tx.d[i][j] - pdsch_rx.d[i][j]);
}
}
if (nof_re * pdsch_grant.nof_layers > 0) {
mse = mse / (nof_re * pdsch_grant.nof_layers);
}
if (mse > 0.001) {
ERROR("MSE error (%f) is too high\n", mse);
for (uint32_t i = 0; i < pdsch_grant.nof_layers; i++) {
printf("d_tx[%d]=", i);
srslte_vec_fprint_c(stdout, pdsch_tx.d[i], nof_re);
printf("d_rx[%d]=", i);
srslte_vec_fprint_c(stdout, pdsch_rx.d[i], nof_re);
}
goto clean_exit;
}
if (!pdsch_res[0].crc) {
ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;\n", n_prb, mcs, pdsch_grant.tb[0].tbs);
goto clean_exit;
}
if (memcmp(data_tx, data_rx, pdsch_grant.tb[0].tbs / 8) != 0) {
if (memcmp(data_tx[0], data_rx[0], pdsch_grant.tb[0].tbs / 8) != 0) {
ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;\n", n_prb, mcs, pdsch_grant.tb[0].tbs);
printf("Tx data: ");
srslte_vec_fprint_byte(stdout, data_tx[0], pdsch_grant.tb[0].tbs / 8);
@ -257,5 +278,5 @@ clean_exit:
srslte_softbuffer_tx_free(&softbuffer_tx);
srslte_softbuffer_rx_free(&softbuffer_rx);
return SRSLTE_SUCCESS;
return ret;
}

Loading…
Cancel
Save