Fixed PDSCH resource mapping bug for 1 antenna. Added dynamic buffer to soft demapper (fixes QAM64 bug)

master
ismagom 10 years ago
parent 636cb301f8
commit 2afdb97b1f

@ -369,7 +369,9 @@ int main(int argc, char **argv) {
sss_put_slot(sf_idx ? sss_signal5 : sss_signal0, sf_buffer, cell.nof_prb, sss_put_slot(sf_idx ? sss_signal5 : sss_signal0, sf_buffer, cell.nof_prb,
CPNORM); CPNORM);
} }
refsignal_cs_put_sf(cell, 0, est.csr_signal.pilots[0][sf_idx], sf_buffer);
bcch_bch_pack(&cell, sfn, bch_payload_packed, BCH_PAYLOAD_LEN/8); bcch_bch_pack(&cell, sfn, bch_payload_packed, BCH_PAYLOAD_LEN/8);
bit_pack_vector(bch_payload_packed, bch_payload, BCH_PAYLOAD_LEN); bit_pack_vector(bch_payload_packed, bch_payload, BCH_PAYLOAD_LEN);
if (sf_idx == 0) { if (sf_idx == 0) {
@ -378,7 +380,6 @@ int main(int argc, char **argv) {
pcfich_encode(&pcfich, cfi, sf_symbols, sf_idx); pcfich_encode(&pcfich, cfi, sf_symbols, sf_idx);
/* Transmit PDCCH + PDSCH only when there is data to send */ /* Transmit PDCCH + PDSCH only when there is data to send */
if (sf_idx != 0) { if (sf_idx != 0) {
if (udp_port > 0) { if (udp_port > 0) {
@ -416,8 +417,6 @@ int main(int argc, char **argv) {
} }
} }
refsignal_cs_put_sf(cell, 0, est.csr_signal.pilots[0][sf_idx], sf_buffer);
/* Transform to OFDM symbols */ /* Transform to OFDM symbols */
lte_ifft_run_sf(&ifft, sf_buffer, output_buffer); lte_ifft_run_sf(&ifft, sf_buffer, output_buffer);

@ -135,7 +135,7 @@ typedef enum LIBLTE_API {
} lte_mimo_type_t; } lte_mimo_type_t;
typedef enum LIBLTE_API { typedef enum LIBLTE_API {
LTE_BPSK = 1, LTE_QPSK = 2, LTE_QAM16 = 4, LTE_QAM64 = 6 LTE_BPSK = 0, LTE_QPSK = 1, LTE_QAM16 = 2, LTE_QAM64 = 3
} lte_mod_t; } lte_mod_t;

@ -41,9 +41,12 @@ typedef struct LIBLTE_API {
float sigma; // noise power float sigma; // noise power
enum alg alg_type; // soft demapping algorithm (EXACT or APPROX) enum alg alg_type; // soft demapping algorithm (EXACT or APPROX)
modem_table_t *table; // symbol mapping table (see modem_table.h) modem_table_t *table; // symbol mapping table (see modem_table.h)
uint32_t *zones;
float *dd;
uint32_t max_symbols;
}demod_soft_t; }demod_soft_t;
LIBLTE_API void demod_soft_init(demod_soft_t *q); LIBLTE_API void demod_soft_init(demod_soft_t *q, uint32_t max_symbols);
LIBLTE_API void demod_soft_table_set(demod_soft_t *q, modem_table_t *table); LIBLTE_API void demod_soft_table_set(demod_soft_t *q, modem_table_t *table);
LIBLTE_API void demod_soft_alg_set(demod_soft_t *q, enum alg alg_type); LIBLTE_API void demod_soft_alg_set(demod_soft_t *q, enum alg alg_type);
LIBLTE_API void demod_soft_sigma_set(demod_soft_t *q, float sigma); LIBLTE_API void demod_soft_sigma_set(demod_soft_t *q, float sigma);

@ -29,14 +29,18 @@
#include <stdlib.h> #include <stdlib.h>
#include <strings.h> #include <strings.h>
#include "liblte/phy/utils/vector.h"
#include "liblte/phy/utils/bit.h" #include "liblte/phy/utils/bit.h"
#include "liblte/phy/modem/demod_soft.h" #include "liblte/phy/modem/demod_soft.h"
#include "soft_algs.h" #include "soft_algs.h"
void demod_soft_init(demod_soft_t *q) { void demod_soft_init(demod_soft_t *q, uint32_t max_symbols) {
bzero((void*)q,sizeof(demod_soft_t)); bzero((void*)q,sizeof(demod_soft_t));
q->sigma = 1.0; q->sigma = 1.0;
q->zones = vec_malloc(sizeof(uint32_t) * max_symbols);
q->dd = vec_malloc(sizeof(float*) * max_symbols * 7);
q->max_symbols = max_symbols;
} }
void demod_soft_table_set(demod_soft_t *q, modem_table_t *table) { void demod_soft_table_set(demod_soft_t *q, modem_table_t *table) {
@ -58,10 +62,17 @@ int demod_soft_demodulate(demod_soft_t *q, const cf_t* symbols, float* llr, int
q->table->symbol_table, q->table->soft_table.idx, q->sigma); q->table->symbol_table, q->table->soft_table.idx, q->sigma);
break; break;
case APPROX: case APPROX:
/* llr_approx(symbols, llr, nsymbols, q->table->nsymbols, q->table->nbits_x_symbol, if (nsymbols <= q->max_symbols) {
q->table->symbol_table, q->table->soft_table.idx, q->sigma); llr_approx(symbols, llr, nsymbols, q->table->nsymbols,
*/ llr_approx(symbols, llr, nsymbols, q->table->nsymbols, q->table->nbits_x_symbol, q->table->nbits_x_symbol,
q->table->symbol_table, q->table->soft_table.idx, q->table->soft_table.d_idx, q->table->soft_table.min_idx, q->sigma); q->table->symbol_table, q->table->soft_table.idx,
q->table->soft_table.d_idx, q->table->soft_table.min_idx, q->sigma,
q->zones, q->dd);
} else {
fprintf(stderr, "Too many symbols (%d>%d)\n", nsymbols, q->max_symbols);
return -1;
}
break; break;
} }
return nsymbols*q->table->nbits_x_symbol; return nsymbols*q->table->nbits_x_symbol;
@ -75,7 +86,7 @@ int demod_soft_initialize(demod_soft_hl* hl) {
if (modem_table_lte(&hl->table,hl->init.std,true)) { if (modem_table_lte(&hl->table,hl->init.std,true)) {
return -1; return -1;
} }
demod_soft_init(&hl->obj); demod_soft_init(&hl->obj, 10000);
hl->obj.table = &hl->table; hl->obj.table = &hl->table;
return 0; return 0;

@ -49,9 +49,6 @@ typedef _Complex float cf_t;
#if LLR_APPROX_IMPLEMENTATION == 1 #if LLR_APPROX_IMPLEMENTATION == 1
float dd[10000][7]; // 7 distances that are needed to compute LLR approx for 64QAM
uint32_t zone[10000]; // Zone of received symbol with respect to grid of QAM constellation diagram
/** /**
* @ingroup Received modulation symbol zone * @ingroup Received modulation symbol zone
@ -447,7 +444,7 @@ static void compute_zone(const cf_t * in, uint32_t * z, int N, int B)
{ {
switch (B) { switch (B) {
case 1:{ case 1:{
memset(zone, 0, N * sizeof(int)); memset(z, 0, N * sizeof(uint32_t));
break; break;
} /* BPSK */ } /* BPSK */
case 2:{ case 2:{
@ -465,7 +462,7 @@ static void compute_zone(const cf_t * in, uint32_t * z, int N, int B)
} }
} }
static void compute_square_dist(const cf_t * in, cf_t * symbols, static void compute_square_dist(uint32_t *zone, float *dd, const cf_t * in, cf_t * symbols,
uint32_t(*idx)[7], int N, int B) uint32_t(*idx)[7], int N, int B)
{ {
int s, b; int s, b;
@ -473,38 +470,35 @@ static void compute_square_dist(const cf_t * in, cf_t * symbols,
cf_t symbols_extract[7]; cf_t symbols_extract[7];
for (s = 0; s < N; s++) { /* N: number of received symbols */ for (s = 0; s < N; s++) { /* N: number of received symbols */
d_ptr = dd[s]; d_ptr = &dd[7*s];
for (b = 0; b < B + 1; b++) { for (b = 0; b < B + 1; b++) {
symbols_extract[b] = symbols[idx[zone[s]][b]]; /* only subset of distances to constellation points needed for LLR approx */ symbols_extract[b] = symbols[idx[zone[s]][b]];
//x = __real__ in[s] - __real__ symbols[idx[zone[s]][b]]; /* only subset of distances to constellation points needed for LLR approx */
//y = __imag__ in[s] - __imag__ symbols[idx[zone[s]][b]];
//dd[s][b] = x*x + y*y;
//printf("\n%f + j %f", __real__ symbols_extract[b], __imag__ symbols_extract[b]);
} }
vec_square_dist(in[s], symbols_extract, d_ptr, B + 1); /* B+1 distances to be computed */ vec_square_dist(in[s], symbols_extract, d_ptr, B + 1); /* B+1 distances to be computed */
} }
} }
static void compute_llr(int N, int B, uint32_t(*min)[64][6], float sigma2, static void compute_llr(uint32_t *zone, float *dd, int N, int B, uint32_t(*min)[64][6], float sigma2,
float *out) float *out)
{ {
int s, b; int s, b;
for (s = 0; s < N; s++) { for (s = 0; s < N; s++) {
for (b = 0; b < B; b++) { /* bits per symbol */ for (b = 0; b < B; b++) { /* bits per symbol */
out[s * B + b] = out[s * B + b] =
(dd[s][min[0][zone[s]][b]] - dd[s][min[1][zone[s]][b]]) / sigma2; (dd[7*s+min[0][zone[s]][b]] - dd[7*s+min[1][zone[s]][b]]) / sigma2;
} }
} }
} }
void llr_approx(const _Complex float *in, float *out, int N, int M, int B, void llr_approx(const _Complex float *in, float *out, int N, int M, int B,
_Complex float *symbols, uint32_t(*S)[6][32], uint32_t(*idx)[7], _Complex float *symbols, uint32_t(*S)[6][32], uint32_t(*idx)[7],
uint32_t(*min)[64][6], float sigma2) uint32_t(*min)[64][6], float sigma2, uint32_t *zone, float *dd)
{ {
if ((M == 2) || (M == 4) || (M == 16) || (M == 64)) { if ((M == 1) || (M == 2) || (M == 4) || (M == 16) || (M == 64)) {
compute_zone(in, zone, N, B); compute_zone(in, zone, N, B);
compute_square_dist(in, symbols, idx, N, B); compute_square_dist(zone, dd, in, symbols, idx, N, B);
compute_llr(N, B, min, sigma2, out); compute_llr(zone, dd, N, B, min, sigma2, out);
} }
} }

@ -44,7 +44,9 @@ void llr_approx(const _Complex float *in,
uint32_t (*S)[6][32], uint32_t (*S)[6][32],
uint32_t (*idx)[7], /*64x7 table of integers [0..63], indices to 7 distances to be computed */ uint32_t (*idx)[7], /*64x7 table of integers [0..63], indices to 7 distances to be computed */
uint32_t (*min)[64][6], /*2x64x6 table of integers [0..6], indices to 2x6 nearest symbols */ uint32_t (*min)[64][6], /*2x64x6 table of integers [0..6], indices to 2x6 nearest symbols */
float sigma2); float sigma2,
uint32_t *zone,
float *dd);
void llr_exact(const _Complex float *in, void llr_exact(const _Complex float *in,
float *out, float *out,

@ -120,7 +120,7 @@ int main(int argc, char **argv) {
} }
if (soft_output) { if (soft_output) {
demod_soft_init(&demod_soft); demod_soft_init(&demod_soft, num_bits / mod.nbits_x_symbol);
demod_soft_table_set(&demod_soft, &mod); demod_soft_table_set(&demod_soft, &mod);
demod_soft_alg_set(&demod_soft, soft_exact?EXACT:APPROX); demod_soft_alg_set(&demod_soft, soft_exact?EXACT:APPROX);
} else { } else {

@ -38,7 +38,7 @@
int nof_frames = 10; int nof_frames = 10;
int num_bits = 1000; int num_bits = 1000;
lte_mod_t modulation = 0; lte_mod_t modulation = 10;
void usage(char *prog) { void usage(char *prog) {
printf("Usage: %s [nfv] -m modulation (1: BPSK, 2: QPSK, 4: QAM16, 6: QAM64)\n", prog); printf("Usage: %s [nfv] -m modulation (1: BPSK, 2: QPSK, 4: QAM16, 6: QAM64)\n", prog);
@ -85,7 +85,7 @@ void parse_args(int argc, char **argv) {
exit(-1); exit(-1);
} }
} }
if (modulation == 0) { if (modulation == 10) {
usage(argv[0]); usage(argv[0]);
exit(-1); exit(-1);
} }
@ -125,7 +125,7 @@ int main(int argc, char **argv) {
/* check that num_bits is multiple of num_bits x symbol */ /* check that num_bits is multiple of num_bits x symbol */
num_bits = mod.nbits_x_symbol * (num_bits / mod.nbits_x_symbol); num_bits = mod.nbits_x_symbol * (num_bits / mod.nbits_x_symbol);
demod_soft_init(&demod_soft); demod_soft_init(&demod_soft, num_bits / mod.nbits_x_symbol);
demod_soft_table_set(&demod_soft, &mod); demod_soft_table_set(&demod_soft, &mod);
demod_soft_sigma_set(&demod_soft, 2.0 / mod.nbits_x_symbol); demod_soft_sigma_set(&demod_soft, 2.0 / mod.nbits_x_symbol);

@ -137,6 +137,7 @@ int pbch_init(pbch_t *q, lte_cell_t cell) {
bzero(q, sizeof(pbch_t)); bzero(q, sizeof(pbch_t));
q->cell = cell; q->cell = cell;
q->nof_symbols = (CP_ISNORM(q->cell.cp)) ? PBCH_RE_CPNORM : PBCH_RE_CPEXT;
if (precoding_init(&q->precoding, SF_LEN_RE(cell.nof_prb, cell.cp))) { if (precoding_init(&q->precoding, SF_LEN_RE(cell.nof_prb, cell.cp))) {
fprintf(stderr, "Error initializing precoding\n"); fprintf(stderr, "Error initializing precoding\n");
@ -145,7 +146,7 @@ int pbch_init(pbch_t *q, lte_cell_t cell) {
if (modem_table_lte(&q->mod, LTE_QPSK, true)) { if (modem_table_lte(&q->mod, LTE_QPSK, true)) {
goto clean; goto clean;
} }
demod_soft_init(&q->demod); demod_soft_init(&q->demod, q->nof_symbols);
demod_soft_table_set(&q->demod, &q->mod); demod_soft_table_set(&q->demod, &q->mod);
demod_soft_alg_set(&q->demod, APPROX); demod_soft_alg_set(&q->demod, APPROX);
@ -165,8 +166,6 @@ int pbch_init(pbch_t *q, lte_cell_t cell) {
q->encoder.tail_biting = true; q->encoder.tail_biting = true;
memcpy(q->encoder.poly, poly, 3 * sizeof(int)); memcpy(q->encoder.poly, poly, 3 * sizeof(int));
q->nof_symbols = (CP_ISNORM(q->cell.cp)) ? PBCH_RE_CPNORM : PBCH_RE_CPEXT;
q->pbch_d = malloc(sizeof(cf_t) * q->nof_symbols); q->pbch_d = malloc(sizeof(cf_t) * q->nof_symbols);
if (!q->pbch_d) { if (!q->pbch_d) {
goto clean; goto clean;

@ -73,6 +73,7 @@ int pcfich_init(pcfich_t *q, regs_t *regs, lte_cell_t cell) {
bzero(q, sizeof(pcfich_t)); bzero(q, sizeof(pcfich_t));
q->cell = cell; q->cell = cell;
q->regs = regs; q->regs = regs;
q->nof_symbols = PCFICH_RE;
if (precoding_init(&q->precoding, SF_LEN_RE(cell.nof_prb, cell.cp))) { if (precoding_init(&q->precoding, SF_LEN_RE(cell.nof_prb, cell.cp))) {
fprintf(stderr, "Error initializing precoding\n"); fprintf(stderr, "Error initializing precoding\n");
@ -82,7 +83,7 @@ int pcfich_init(pcfich_t *q, regs_t *regs, lte_cell_t cell) {
goto clean; goto clean;
} }
demod_soft_init(&q->demod); demod_soft_init(&q->demod, q->nof_symbols);
demod_soft_table_set(&q->demod, &q->mod); demod_soft_table_set(&q->demod, &q->mod);
demod_soft_alg_set(&q->demod, APPROX); demod_soft_alg_set(&q->demod, APPROX);
@ -99,8 +100,6 @@ int pcfich_init(pcfich_t *q, regs_t *regs, lte_cell_t cell) {
} }
} }
q->nof_symbols = PCFICH_RE;
ret = LIBLTE_SUCCESS; ret = LIBLTE_SUCCESS;
} }

@ -85,7 +85,7 @@ int pdcch_init(pdcch_t *q, regs_t *regs, lte_cell_t cell) {
goto clean; goto clean;
} }
demod_soft_init(&q->demod); demod_soft_init(&q->demod, q->max_bits / 2);
demod_soft_table_set(&q->demod, &q->mod); demod_soft_table_set(&q->demod, &q->mod);
demod_soft_alg_set(&q->demod, APPROX); demod_soft_alg_set(&q->demod, APPROX);

@ -53,8 +53,11 @@ const lte_mod_t modulations[4] =
#ifdef DEBUG_IDX #ifdef DEBUG_IDX
cf_t *offset_original=NULL; cf_t *offset_original=NULL;
extern int indices[2048];
extern int indices_ptr;
#endif #endif
int pdsch_cp(pdsch_t *q, cf_t *input, cf_t *output, ra_prb_t *prb_alloc, int pdsch_cp(pdsch_t *q, cf_t *input, cf_t *output, ra_prb_t *prb_alloc,
uint32_t nsubframe, bool put) { uint32_t nsubframe, bool put) {
uint32_t s, n, l, lp, lstart, lend, nof_refs; uint32_t s, n, l, lp, lstart, lend, nof_refs;
@ -66,7 +69,12 @@ int pdsch_cp(pdsch_t *q, cf_t *input, cf_t *output, ra_prb_t *prb_alloc,
prb_alloc->re_sf[nsubframe], prb_alloc->slot[0].nof_prb); prb_alloc->re_sf[nsubframe], prb_alloc->slot[0].nof_prb);
#ifdef DEBUG_IDX #ifdef DEBUG_IDX
offset_original = input; indices_ptr = 0;
if (put) {
offset_original = output;
} else {
offset_original = input;
}
#endif #endif
if (q->cell.nof_ports == 1) { if (q->cell.nof_ports == 1) {
@ -116,7 +124,7 @@ int pdsch_cp(pdsch_t *q, cf_t *input, cf_t *output, ra_prb_t *prb_alloc,
// This is a symbol in a normal PRB with or without references // This is a symbol in a normal PRB with or without references
if (l >= lstart && l < lend) { if (l >= lstart && l < lend) {
if (SYMBOL_HAS_REF(l, q->cell.cp, q->cell.nof_ports)) { if (SYMBOL_HAS_REF(l, q->cell.cp, q->cell.nof_ports)) {
if (nof_refs == 2 && l == 0) { if (nof_refs == 2 && l != 0) {
offset = q->cell.id % 3 + 3; offset = q->cell.id % 3 + 3;
} else { } else {
offset = q->cell.id % 3; offset = q->cell.id % 3;
@ -152,12 +160,15 @@ int pdsch_cp(pdsch_t *q, cf_t *input, cf_t *output, ra_prb_t *prb_alloc,
} }
} }
} }
int r;
if (put) { if (put) {
return abs((int) (input - in_ptr)); r = abs((int) (input - in_ptr));
} else { } else {
return abs((int) (output - out_ptr)); r = abs((int) (output - out_ptr));
} }
return r;
} }
/** /**
@ -221,7 +232,7 @@ int pdsch_init(pdsch_t *q, lte_cell_t cell) {
goto clean; goto clean;
} }
demod_soft_init(&q->demod); demod_soft_init(&q->demod, q->max_symbols);
demod_soft_alg_set(&q->demod, APPROX); demod_soft_alg_set(&q->demod, APPROX);
q->rnti_is_set = false; q->rnti_is_set = false;
@ -247,7 +258,7 @@ int pdsch_init(pdsch_t *q, lte_cell_t cell) {
} }
// Allocate floats for reception (LLRs) // Allocate floats for reception (LLRs)
q->pdsch_e = malloc(sizeof(float) * q->max_symbols * q->mod[3].nbits_x_symbol); q->pdsch_e = malloc(sizeof(float) * q->max_symbols * lte_mod_bits_x_symbol(LTE_QAM64));
if (!q->pdsch_e) { if (!q->pdsch_e) {
goto clean; goto clean;
} }
@ -327,7 +338,7 @@ int pdsch_set_rnti(pdsch_t *q, uint16_t rnti) {
uint32_t i; uint32_t i;
for (i = 0; i < NSUBFRAMES_X_FRAME; i++) { for (i = 0; i < NSUBFRAMES_X_FRAME; i++) {
if (sequence_pdsch(&q->seq_pdsch[i], rnti, 0, 2 * i, q->cell.id, if (sequence_pdsch(&q->seq_pdsch[i], rnti, 0, 2 * i, q->cell.id,
q->max_symbols * q->mod[3].nbits_x_symbol)) { q->max_symbols * lte_mod_bits_x_symbol(LTE_QAM64))) {
return LIBLTE_ERROR; return LIBLTE_ERROR;
} }
} }
@ -400,9 +411,8 @@ int pdsch_harq_init(pdsch_harq_t *p, pdsch_t *pdsch) {
return LIBLTE_ERROR; return LIBLTE_ERROR;
} }
// We add 50 % larger buffer to the maximum expected bits per subframe
// FIXME: Use HARQ buffer limitation based on UE category // FIXME: Use HARQ buffer limitation based on UE category
p->w_buff_size = p->cell.nof_prb * MAX_PDSCH_RE(p->cell.cp) * 6 * 2; p->w_buff_size = p->cell.nof_prb * MAX_PDSCH_RE(p->cell.cp) * 6 * 10;
for (i=0;i<p->max_cb;i++) { for (i=0;i<p->max_cb;i++) {
p->pdsch_w_buff_f[i] = vec_malloc(sizeof(float) * p->w_buff_size); p->pdsch_w_buff_f[i] = vec_malloc(sizeof(float) * p->w_buff_size);
if (!p->pdsch_w_buff_f[i]) { if (!p->pdsch_w_buff_f[i]) {
@ -529,7 +539,7 @@ int pdsch_decode_tb(pdsch_t *q, uint8_t *data, uint32_t tbs, uint32_t nb_e,
if (q != NULL && if (q != NULL &&
data != NULL && data != NULL &&
nb_e < q->max_symbols * q->mod[3].nbits_x_symbol) nb_e < q->max_symbols * lte_mod_bits_x_symbol(LTE_QAM64))
{ {
rp = 0; rp = 0;
@ -662,17 +672,16 @@ int pdsch_decode(pdsch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_
sf_symbols != NULL && sf_symbols != NULL &&
data != NULL && data != NULL &&
subframe < 10 && subframe < 10 &&
harq_process != NULL && harq_process != NULL)
harq_process->mcs.mod > 0)
{ {
nof_bits = harq_process->mcs.tbs; nof_bits = harq_process->mcs.tbs;
nof_symbols = harq_process->prb_alloc.re_sf[subframe]; nof_symbols = harq_process->prb_alloc.re_sf[subframe];
nof_bits_e = nof_symbols * q->mod[harq_process->mcs.mod - 1].nbits_x_symbol; nof_bits_e = nof_symbols * lte_mod_bits_x_symbol(harq_process->mcs.mod);
INFO("Decoding PDSCH SF: %d, Mod %d, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", INFO("Decoding PDSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
subframe, harq_process->mcs.mod, nof_bits, nof_symbols, nof_bits_e, rv_idx); subframe, lte_mod_string(harq_process->mcs.mod), nof_bits, nof_symbols, nof_bits_e, rv_idx);
/* number of layers equals number of ports */ /* number of layers equals number of ports */
for (i = 0; i < q->cell.nof_ports; i++) { for (i = 0; i < q->cell.nof_ports; i++) {
@ -712,8 +721,8 @@ int pdsch_decode(pdsch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_
* The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation, * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
* thus we don't need tot set it in the LLRs normalization * thus we don't need tot set it in the LLRs normalization
*/ */
demod_soft_sigma_set(&q->demod, sqrt(q->mod[harq_process->mcs.mod - 1].nbits_x_symbol/2)); demod_soft_sigma_set(&q->demod, sqrt((float) lte_mod_bits_x_symbol(harq_process->mcs.mod)/2));
demod_soft_table_set(&q->demod, &q->mod[harq_process->mcs.mod - 1]); demod_soft_table_set(&q->demod, &q->mod[harq_process->mcs.mod]);
demod_soft_demodulate(&q->demod, q->pdsch_d, q->pdsch_e, nof_symbols); demod_soft_demodulate(&q->demod, q->pdsch_d, q->pdsch_e, nof_symbols);
/* descramble */ /* descramble */
@ -741,7 +750,7 @@ int pdsch_encode_tb(pdsch_t *q, uint8_t *data, uint32_t tbs, uint32_t nb_e,
if (q != NULL && if (q != NULL &&
data != NULL && data != NULL &&
nb_e < q->max_symbols * q->mod[3].nbits_x_symbol) nb_e < q->max_symbols * lte_mod_bits_x_symbol(LTE_QAM64))
{ {
if (q->rnti_is_set) { if (q->rnti_is_set) {
@ -856,8 +865,7 @@ int pdsch_encode(pdsch_t *q, uint8_t *data, cf_t *sf_symbols[MAX_PORTS], uint32_
if (q != NULL && if (q != NULL &&
data != NULL && data != NULL &&
subframe < 10 && subframe < 10 &&
harq_process != NULL && harq_process != NULL)
harq_process->mcs.mod > 0)
{ {
if (q->rnti_is_set) { if (q->rnti_is_set) {
@ -869,7 +877,7 @@ int pdsch_encode(pdsch_t *q, uint8_t *data, cf_t *sf_symbols[MAX_PORTS], uint32_
nof_bits = harq_process->mcs.tbs; nof_bits = harq_process->mcs.tbs;
nof_symbols = harq_process->prb_alloc.re_sf[subframe]; nof_symbols = harq_process->prb_alloc.re_sf[subframe];
nof_bits_e = nof_symbols * q->mod[harq_process->mcs.mod - 1].nbits_x_symbol; nof_bits_e = nof_symbols * lte_mod_bits_x_symbol(harq_process->mcs.mod);
if (harq_process->mcs.tbs == 0) { if (harq_process->mcs.tbs == 0) {
return LIBLTE_ERROR_INVALID_INPUTS; return LIBLTE_ERROR_INVALID_INPUTS;
@ -887,8 +895,8 @@ int pdsch_encode(pdsch_t *q, uint8_t *data, cf_t *sf_symbols[MAX_PORTS], uint32_
return LIBLTE_ERROR_INVALID_INPUTS; return LIBLTE_ERROR_INVALID_INPUTS;
} }
INFO("Encoding PDSCH SF: %d, Mod %d, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", INFO("Encoding PDSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
subframe, harq_process->mcs.mod, nof_bits, nof_symbols, nof_bits_e, rv_idx); subframe, lte_mod_string(harq_process->mcs.mod), nof_bits, nof_symbols, nof_bits_e, rv_idx);
/* number of layers equals number of ports */ /* number of layers equals number of ports */
for (i = 0; i < q->cell.nof_ports; i++) { for (i = 0; i < q->cell.nof_ports; i++) {
@ -903,7 +911,7 @@ int pdsch_encode(pdsch_t *q, uint8_t *data, cf_t *sf_symbols[MAX_PORTS], uint32_
scrambling_b_offset(&q->seq_pdsch[subframe], (uint8_t*) q->pdsch_e, 0, nof_bits_e); scrambling_b_offset(&q->seq_pdsch[subframe], (uint8_t*) q->pdsch_e, 0, nof_bits_e);
mod_modulate(&q->mod[harq_process->mcs.mod - 1], (uint8_t*) q->pdsch_e, q->pdsch_d, nof_bits_e); mod_modulate(&q->mod[harq_process->mcs.mod], (uint8_t*) q->pdsch_e, q->pdsch_d, nof_bits_e);
/* TODO: only diversity supported */ /* TODO: only diversity supported */
if (q->cell.nof_ports > 1) { if (q->cell.nof_ports > 1) {

@ -32,12 +32,12 @@
#include "prb.h" #include "prb.h"
#include "liblte/phy/common/phy_common.h" #include "liblte/phy/common/phy_common.h"
#define DEBUG_IDX //#define DEBUG_IDX
#ifdef DEBUG_IDX #ifdef DEBUG_IDX
extern cf_t *offset_original; extern cf_t *offset_original;
LIBLTE_API int indices[2048]; LIBLTE_API int indices[2048];
int indices_ptr=0; LIBLTE_API int indices_ptr=0;
#endif #endif
void print_indexes(cf_t *offset, int len) { void print_indexes(cf_t *offset, int len) {
@ -55,7 +55,7 @@ void prb_cp_ref(cf_t **input, cf_t **output, int offset, int nof_refs,
int ref_interval = ((RE_X_RB / nof_refs) - 1); int ref_interval = ((RE_X_RB / nof_refs) - 1);
memcpy(*output, *input, offset * sizeof(cf_t)); memcpy(*output, *input, offset * sizeof(cf_t));
print_indexes(*input, offset); print_indexes(*output, offset);
*input += offset; *input += offset;
*output += offset; *output += offset;
for (i = 0; i < nof_intervals - 1; i++) { for (i = 0; i < nof_intervals - 1; i++) {
@ -65,7 +65,7 @@ void prb_cp_ref(cf_t **input, cf_t **output, int offset, int nof_refs,
(*input)++; (*input)++;
} }
memcpy(*output, *input, ref_interval * sizeof(cf_t)); memcpy(*output, *input, ref_interval * sizeof(cf_t));
print_indexes(*input, ref_interval); print_indexes(*output, ref_interval);
*output += ref_interval; *output += ref_interval;
*input += ref_interval; *input += ref_interval;
} }
@ -76,7 +76,7 @@ void prb_cp_ref(cf_t **input, cf_t **output, int offset, int nof_refs,
(*input)++; (*input)++;
} }
memcpy(*output, *input, (ref_interval - offset) * sizeof(cf_t)); memcpy(*output, *input, (ref_interval - offset) * sizeof(cf_t));
print_indexes(*input, ref_interval-offset); print_indexes(*output, ref_interval-offset);
*output += (ref_interval - offset); *output += (ref_interval - offset);
*input += (ref_interval - offset); *input += (ref_interval - offset);
} }
@ -84,7 +84,7 @@ void prb_cp_ref(cf_t **input, cf_t **output, int offset, int nof_refs,
void prb_cp(cf_t **input, cf_t **output, int nof_prb) { void prb_cp(cf_t **input, cf_t **output, int nof_prb) {
memcpy(*output, *input, sizeof(cf_t) * RE_X_RB * nof_prb); memcpy(*output, *input, sizeof(cf_t) * RE_X_RB * nof_prb);
print_indexes(*input, RE_X_RB); print_indexes(*output, RE_X_RB);
*input += nof_prb * RE_X_RB; *input += nof_prb * RE_X_RB;
*output += nof_prb * RE_X_RB; *output += nof_prb * RE_X_RB;
} }
@ -92,7 +92,7 @@ void prb_cp(cf_t **input, cf_t **output, int nof_prb) {
void prb_cp_half(cf_t **input, cf_t **output, int nof_prb) { void prb_cp_half(cf_t **input, cf_t **output, int nof_prb) {
memcpy(*output, *input, sizeof(cf_t) * RE_X_RB * nof_prb / 2); memcpy(*output, *input, sizeof(cf_t) * RE_X_RB * nof_prb / 2);
print_indexes(*input, RE_X_RB/2); print_indexes(*output, RE_X_RB/2);
*input += nof_prb * RE_X_RB / 2; *input += nof_prb * RE_X_RB / 2;
*output += nof_prb * RE_X_RB / 2; *output += nof_prb * RE_X_RB / 2;
} }

@ -93,8 +93,10 @@ BuildMex(MEXNAME pdcch SOURCES pdcch_test_mex.c LIBRARIES lte_phy liblte_mex)
ADD_EXECUTABLE(pdsch_test pdsch_test.c) ADD_EXECUTABLE(pdsch_test pdsch_test.c)
TARGET_LINK_LIBRARIES(pdsch_test lte_phy) TARGET_LINK_LIBRARIES(pdsch_test lte_phy)
ADD_TEST(pdsch_test pdsch_test -l 50000 -m 4 -n 110) ADD_TEST(pdsch_test_bpsk pdsch_test -l 500 -m 1 -n 50 -r 2)
ADD_TEST(pdsch_test pdsch_test -l 500 -m 2 -n 50 -r 2) ADD_TEST(pdsch_test_qpsk pdsch_test -l 1000 -m 2 -n 50 -r 1)
ADD_TEST(pdsch_test_qam16 pdsch_test -l 50000 -m 4 -n 110)
ADD_TEST(pdsch_test_qam64 pdsch_test -l 5000 -m 6 -n 50 -r 0)
######################################################################## ########################################################################
# FILE TEST # FILE TEST

Loading…
Cancel
Save