Added DFT Transform Precoding. Added PUSCH matlab test. Added UCI PUCCH coding

This commit is contained in:
ismagom 2015-02-13 10:02:10 +01:00
parent 908e4f0373
commit 6b8d019fce
11 changed files with 215 additions and 168 deletions

View File

@ -58,15 +58,37 @@ typedef struct LIBLTE_API {
uint32_t position_subband; // L-bit width
} cqi_ue_subband_t;
/* Table 5.2.3.3.1-1: Fields for channel quality information feedback for wideband CQI reports
(transmission mode 1, transmission mode 2, transmission mode 3, transmission mode 7 and
transmission mode 8 configured without PMI/RI reporting).
This is for PUCCH Format 2 reports
*/
typedef struct LIBLTE_API {
uint8_t wideband_cqi; // 4-bit width
} cqi_format2_wideband_t;
LIBLTE_API void cqi_hl_subband_pack(cqi_hl_subband_t *msg,
typedef struct LIBLTE_API {
uint8_t subband_cqi; // 4-bit width
uint8_t subband_label; // 1- or 2-bit width
} cqi_format2_subband_t;
LIBLTE_API int cqi_hl_subband_pack(cqi_hl_subband_t *msg,
uint32_t N,
uint8_t *buff,
uint32_t buff_len);
LIBLTE_API void cqi_ue_subband_pack(cqi_ue_subband_t *msg,
LIBLTE_API int cqi_ue_subband_pack(cqi_ue_subband_t *msg,
uint32_t L,
uint8_t *buff,
uint32_t buff_len);
LIBLTE_API int cqi_format2_wideband_pack(cqi_format2_wideband_t *msg,
uint8_t *buff,
uint32_t buff_len);
LIBLTE_API int cqi_format2_subband_pack(cqi_format2_subband_t *msg,
uint8_t *buff,
uint32_t buff_len);
#endif // CQI_

View File

@ -26,7 +26,7 @@
*/
#ifndef PUCH_
#ifndef PUSCH_
#define PUSCH_
#include "liblte/config.h"
@ -39,24 +39,28 @@
#include "liblte/phy/phch/regs.h"
#include "liblte/phy/phch/sch.h"
#include "liblte/phy/phch/harq.h"
#include "liblte/phy/filter/dft_precoding.h"
#define TDEC_MAX_ITERATIONS 5
typedef _Complex float cf_t;
/* PDSCH object */
/* PUSCH object */
typedef struct LIBLTE_API {
lte_cell_t cell;
uint32_t max_symbols;
bool rnti_is_set;
uint16_t rnti;
dft_precoding_t dft_precoding;
precoding_t equalizer;
/* buffers */
// void buffers are shared for tx and rx
cf_t *ce[MAX_PORTS];
cf_t *pusch_symbols[MAX_PORTS];
cf_t *pusch_x[MAX_PORTS];
cf_t *ce;
cf_t *pusch_z;
cf_t *pusch_d;
void *pusch_q;
@ -84,7 +88,7 @@ LIBLTE_API int pusch_set_rnti(pusch_t *q,
LIBLTE_API int pusch_encode(pusch_t *q,
uint8_t *data,
cf_t *sf_symbols[MAX_PORTS],
cf_t *sf_symbols,
uint32_t nsubframe,
harq_t *harq_process,
uint32_t rv_idx);
@ -92,14 +96,14 @@ LIBLTE_API int pusch_encode(pusch_t *q,
LIBLTE_API int pusch_uci_encode(pusch_t *q,
uint8_t *data,
uci_data_t uci_data,
cf_t *sf_symbols[MAX_PORTS],
cf_t *sf_symbols,
uint32_t subframe,
harq_t *harq_process,
uint32_t rv_idx);
LIBLTE_API int pusch_decode(pusch_t *q,
cf_t *sf_symbols,
cf_t *ce[MAX_PORTS],
cf_t *ce,
float noise_estimate,
uint8_t *data,
uint32_t nsubframe,

View File

@ -65,7 +65,7 @@ typedef struct LIBLTE_API {
crc_t crc_tb;
crc_t crc_cb;
uci_cqi_t uci_cqi;
uci_cqi_pusch_t uci_cqi;
} sch_t;

View File

@ -34,13 +34,16 @@
#include "liblte/phy/phch/harq.h"
#include "liblte/phy/fec/crc.h"
#define MAX_CQI_LEN 512
#define MAX_CQI_LEN_PUSCH 512
#define MAX_CQI_LEN_PUCCH 13
#define CQI_CODED_PUCCH_B 20
typedef struct LIBLTE_API {
crc_t crc;
uint8_t tmp_cqi[MAX_CQI_LEN];
uint8_t encoded_cqi[3*MAX_CQI_LEN];
} uci_cqi_t;
uint8_t tmp_cqi[MAX_CQI_LEN_PUSCH];
uint8_t encoded_cqi[3*MAX_CQI_LEN_PUSCH];
} uci_cqi_pusch_t;
typedef struct LIBLTE_API {
uint8_t *uci_cqi;
@ -54,17 +57,21 @@ typedef struct LIBLTE_API {
float beta_ack;
} uci_data_t;
LIBLTE_API int uci_cqi_init(uci_cqi_t *q);
LIBLTE_API int uci_cqi_init(uci_cqi_pusch_t *q);
LIBLTE_API void uci_cqi_free(uci_cqi_t *q);
LIBLTE_API void uci_cqi_free(uci_cqi_pusch_t *q);
LIBLTE_API int uci_encode_cqi(uci_cqi_t *q,
uint8_t *cqi_data,
uint32_t cqi_len,
float beta,
uint32_t Q_prime_ri,
harq_t *harq_process,
uint8_t *q_bits);
LIBLTE_API int uci_encode_cqi_pusch(uci_cqi_pusch_t *q,
uint8_t *cqi_data,
uint32_t cqi_len,
float beta,
uint32_t Q_prime_ri,
harq_t *harq_process,
uint8_t *q_bits);
LIBLTE_API int uci_encode_cqi_pucch(uint8_t *cqi_data,
uint32_t cqi_len,
uint8_t b_bits[CQI_CODED_PUCCH_B]);
LIBLTE_API int uci_encode_ack(uint8_t data,
uint32_t O_cqi,

View File

@ -71,6 +71,7 @@
#include "liblte/phy/fec/rm_turbo.h"
#include "liblte/phy/filter/filter2d.h"
#include "liblte/phy/filter/dft_precoding.h"
#include "liblte/phy/io/binsource.h"
#include "liblte/phy/io/filesink.h"
@ -86,17 +87,18 @@
#include "liblte/phy/mimo/precoding.h"
#include "liblte/phy/mimo/layermap.h"
#include "liblte/phy/phch/regs.h"
#include "liblte/phy/phch/cqi.h"
#include "liblte/phy/phch/dci.h"
#include "liblte/phy/phch/pdcch.h"
#include "liblte/phy/phch/pdsch.h"
#include "liblte/phy/phch/harq.h"
#include "liblte/phy/phch/pbch.h"
#include "liblte/phy/phch/pcfich.h"
#include "liblte/phy/phch/pdcch.h"
#include "liblte/phy/phch/pdsch.h"
#include "liblte/phy/phch/phich.h"
#include "liblte/phy/phch/sch.h"
#include "liblte/phy/phch/pusch.h"
#include "liblte/phy/phch/ra.h"
#include "liblte/phy/phch/regs.h"
#include "liblte/phy/phch/sch.h"
#include "liblte/phy/phch/uci.h"
#include "liblte/phy/ue/ue_sync.h"

View File

@ -41,17 +41,37 @@
#include "liblte/phy/utils/debug.h"
void cqi_hl_subband_pack(cqi_hl_subband_t *msg, uint32_t N, uint8_t *buff, uint32_t buff_len)
int cqi_hl_subband_pack(cqi_hl_subband_t *msg, uint32_t N, uint8_t *buff, uint32_t buff_len)
{
uint8_t *body_ptr = buff;
bit_pack(msg->wideband_cqi, &body_ptr, 4);
bit_pack(msg->subband_diff_cqi, &body_ptr, 2*N);
return 4+2*N;
}
void cqi_ue_subband_pack(cqi_ue_subband_t *msg, uint32_t L, uint8_t *buff, uint32_t buff_len)
int cqi_ue_subband_pack(cqi_ue_subband_t *msg, uint32_t L, uint8_t *buff, uint32_t buff_len)
{
uint8_t *body_ptr = buff;
bit_pack(msg->wideband_cqi, &body_ptr, 4);
bit_pack(msg->subband_diff_cqi, &body_ptr, 2);
bit_pack(msg->subband_diff_cqi, &body_ptr, L);
return 4+2+L;
}
int cqi_format2_wideband_pack(cqi_format2_wideband_t *msg, uint8_t *buff, uint32_t buff_len)
{
uint8_t *body_ptr = buff;
bit_pack(msg->wideband_cqi, &body_ptr, 4);
return 4;
}
int cqi_format2_subband_pack(cqi_format2_subband_t *msg, uint8_t *buff, uint32_t buff_len)
{
uint8_t *body_ptr = buff;
bit_pack(msg->subband_cqi, &body_ptr, 4);
bit_pack(msg->subband_label, &body_ptr, 1);
return 4+1;
}

View File

@ -41,7 +41,7 @@
#include "liblte/phy/utils/bit.h"
#include "liblte/phy/utils/debug.h"
#include "liblte/phy/utils/vector.h"
#include "liblte/phy/filter/dft_precoding.h"
#define MAX_PUSCH_RE(cp) (2 * CP_NSYMB(cp) * 12)
@ -118,6 +118,14 @@ int pusch_init(pusch_t *q, lte_cell_t cell) {
sch_init(&q->dl_sch);
dft_precoding_init(&q->dft_precoding, cell.nof_prb);
/* This is for equalization at receiver */
if (precoding_init(&q->equalizer, SF_LEN_RE(cell.nof_prb, cell.cp))) {
fprintf(stderr, "Error initializing precoding\n");
goto clean;
}
q->rnti_is_set = false;
// Allocate floats for reception (LLRs). Buffer casted to uint8_t for transmission
@ -136,19 +144,13 @@ int pusch_init(pusch_t *q, lte_cell_t cell) {
goto clean;
}
for (i = 0; i < q->cell.nof_ports; i++) {
q->ce[i] = vec_malloc(sizeof(cf_t) * q->max_symbols);
if (!q->ce[i]) {
goto clean;
}
q->pusch_x[i] = vec_malloc(sizeof(cf_t) * q->max_symbols);
if (!q->pusch_x[i]) {
goto clean;
}
q->pusch_symbols[i] = vec_malloc(sizeof(cf_t) * q->max_symbols);
if (!q->pusch_symbols[i]) {
goto clean;
}
q->ce = vec_malloc(sizeof(cf_t) * q->max_symbols);
if (!q->ce) {
goto clean;
}
q->pusch_z = vec_malloc(sizeof(cf_t) * q->max_symbols);
if (!q->pusch_z) {
goto clean;
}
ret = LIBLTE_SUCCESS;
@ -172,18 +174,17 @@ void pusch_free(pusch_t *q) {
if (q->pusch_g) {
free(q->pusch_g);
}
for (i = 0; i < q->cell.nof_ports; i++) {
if (q->ce[i]) {
free(q->ce[i]);
}
if (q->pusch_x[i]) {
free(q->pusch_x[i]);
}
if (q->pusch_symbols[i]) {
free(q->pusch_symbols[i]);
}
if (q->ce) {
free(q->ce);
}
if (q->pusch_z) {
free(q->pusch_z);
}
dft_precoding_free(&q->dft_precoding);
precoding_free(&q->equalizer);
for (i = 0; i < NSUBFRAMES_X_FRAME; i++) {
sequence_free(&q->seq_pusch[i]);
}
@ -215,13 +216,12 @@ int pusch_set_rnti(pusch_t *q, uint16_t rnti) {
/** Decodes the PUSCH from the received symbols
*/
int pusch_decode(pusch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_estimate, uint8_t *data, uint32_t subframe,
int pusch_decode(pusch_t *q, cf_t *sf_symbols, cf_t *ce, float noise_estimate, uint8_t *data, uint32_t subframe,
harq_t *harq_process, uint32_t rv_idx)
{
/* Set pointers for layermapping & precoding */
uint32_t i, n;
cf_t *x[MAX_LAYERS];
uint32_t n;
uint32_t nof_symbols, nof_bits, nof_bits_e;
if (q != NULL &&
@ -233,35 +233,32 @@ int pusch_decode(pusch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_
if (q->rnti_is_set) {
nof_bits = harq_process->mcs.tbs;
nof_symbols = harq_process->prb_alloc.re_sf[subframe];
nof_symbols = 2*harq_process->prb_alloc.slot[0].nof_prb*RE_X_RB*(CP_NSYMB(q->cell.cp)-1);
nof_bits_e = nof_symbols * lte_mod_bits_x_symbol(harq_process->mcs.mod);
INFO("Decoding PUSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
subframe, lte_mod_string(harq_process->mcs.mod), nof_bits, nof_symbols, nof_bits_e, rv_idx);
/* number of layers equals number of ports */
for (i = 0; i < q->cell.nof_ports; i++) {
x[i] = q->pusch_x[i];
}
memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports));
/* extract symbols */
n = pusch_get(q, sf_symbols, q->pusch_symbols[0], &harq_process->prb_alloc, subframe);
n = pusch_get(q, sf_symbols, q->pusch_d, &harq_process->prb_alloc, subframe);
if (n != nof_symbols) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", nof_symbols, n);
return LIBLTE_ERROR;
}
/* extract channel estimates */
for (i = 0; i < q->cell.nof_ports; i++) {
n = pusch_get(q, ce[i], q->ce[i], &harq_process->prb_alloc, subframe);
if (n != nof_symbols) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", nof_symbols, n);
return LIBLTE_ERROR;
}
n = pusch_get(q, ce, q->ce, &harq_process->prb_alloc, subframe);
if (n != nof_symbols) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", nof_symbols, n);
return LIBLTE_ERROR;
}
predecoding_single(&q->equalizer, q->pusch_d, q->ce, q->pusch_z,
nof_symbols, noise_estimate);
dft_predecoding(&q->dft_precoding, q->pusch_z, q->pusch_d,
harq_process->prb_alloc.slot[0].nof_prb, harq_process->N_symb_ul);
/* demodulate symbols
* 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
@ -277,14 +274,13 @@ int pusch_decode(pusch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_
} else {
fprintf(stderr, "Must call pusch_set_rnti() before calling pusch_decode()\n");
return LIBLTE_ERROR;
}
}
} else {
return LIBLTE_ERROR_INVALID_INPUTS;
}
}
int pusch_qncode(pusch_t *q, uint8_t *data, cf_t *sf_symbols[MAX_PORTS], uint32_t subframe,
int pusch_encode(pusch_t *q, uint8_t *data, cf_t *sf_symbols, uint32_t subframe,
harq_t *harq_process, uint32_t rv_idx)
{
uci_data_t uci_data;
@ -295,28 +291,19 @@ int pusch_qncode(pusch_t *q, uint8_t *data, cf_t *sf_symbols[MAX_PORTS], uint32_
/** Converts the PUSCH data bits to symbols mapped to the slot ready for transmission
*/
int pusch_uci_encode(pusch_t *q, uint8_t *data, uci_data_t uci_data,
cf_t *sf_symbols[MAX_PORTS], uint32_t subframe,
cf_t *sf_symbols, uint32_t subframe,
harq_t *harq_process, uint32_t rv_idx)
{
int i;
uint32_t nof_symbols, nof_bits_ulsch, nof_bits_e;
/* Set pointers for layermapping & precoding */
cf_t *x[MAX_LAYERS];
int ret = LIBLTE_ERROR_INVALID_INPUTS;
int ret = LIBLTE_ERROR_INVALID_INPUTS;
if (q != NULL &&
if (q != NULL &&
data != NULL &&
subframe < 10 &&
harq_process != NULL)
{
if (q->rnti_is_set) {
for (i=0;i<q->cell.nof_ports;i++) {
if (sf_symbols[i] == NULL) {
return LIBLTE_ERROR_INVALID_INPUTS;
}
}
nof_bits_ulsch = harq_process->mcs.tbs;
nof_symbols = 2*harq_process->prb_alloc.slot[0].nof_prb*RE_X_RB*(CP_NSYMB(q->cell.cp)-1);
nof_bits_e = nof_symbols * lte_mod_bits_x_symbol(harq_process->mcs.mod);
@ -339,12 +326,6 @@ int pusch_uci_encode(pusch_t *q, uint8_t *data, uci_data_t uci_data,
INFO("Encoding PUSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
subframe, lte_mod_string(harq_process->mcs.mod), nof_bits_ulsch, nof_symbols, nof_bits_e, rv_idx);
/* number of layers equals number of ports */
for (i = 0; i < q->cell.nof_ports; i++) {
x[i] = q->pusch_x[i];
}
memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports));
if (ulsch_uci_encode(&q->dl_sch, data, uci_data, q->pusch_g, harq_process, rv_idx, q->pusch_q))
{
@ -356,11 +337,11 @@ int pusch_uci_encode(pusch_t *q, uint8_t *data, uci_data_t uci_data,
mod_modulate(&q->mod[harq_process->mcs.mod], (uint8_t*) q->pusch_q, q->pusch_d, nof_bits_e);
/* mapping to resource elements */
dft_precoding(&q->dft_precoding, q->pusch_d, q->pusch_z,
harq_process->prb_alloc.slot[0].nof_prb, harq_process->N_symb_ul);
for (i = 0; i < q->cell.nof_ports; i++) {
pusch_put(q, q->pusch_symbols[i], sf_symbols[i], &harq_process->prb_alloc, subframe);
}
/* mapping to resource elements */
pusch_put(q, q->pusch_z, sf_symbols, &harq_process->prb_alloc, subframe);
ret = LIBLTE_SUCCESS;
} else {

View File

@ -467,7 +467,7 @@ int ulsch_uci_encode(sch_t *q, uint8_t *data, uci_data_t uci_data, uint8_t *g_bi
// Encode CQI
if (uci_data.uci_cqi_len > 0) {
ret = uci_encode_cqi(&q->uci_cqi, uci_data.uci_cqi, uci_data.uci_cqi_len, uci_data.beta_cqi,
ret = uci_encode_cqi_pusch(&q->uci_cqi, uci_data.uci_cqi, uci_data.uci_cqi_len, uci_data.beta_cqi,
Q_prime_ri, harq_process, g_bits);
if (ret < 0) {
return ret;

View File

@ -44,7 +44,7 @@
#include "liblte/phy/utils/debug.h"
/* Table 5.2.2.6.4-1: Basis sequence for (32, O) code */
static uint8_t M_basis_seq[32][11]={
static uint8_t M_basis_seq_pusch[32][11]={
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1 },
{1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 },
@ -79,14 +79,38 @@ static uint8_t M_basis_seq[32][11]={
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};
int uci_cqi_init(uci_cqi_t *q) {
static uint8_t M_basis_seq_pucch[20][13]={
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
{1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
{1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1},
{1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1},
{1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1},
{1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1},
{1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1},
{1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1},
{1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1},
{1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1},
{1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1},
{1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1},
{1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1},
{1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1},
{1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1},
{1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1},
{1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1},
{1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
};
int uci_cqi_init(uci_cqi_pusch_t *q) {
if (crc_init(&q->crc, LTE_CRC8, 8)) {
return LIBLTE_ERROR;
}
return LIBLTE_SUCCESS;
}
void uci_cqi_free(uci_cqi_t *q) {
void uci_cqi_free(uci_cqi_pusch_t *q) {
}
@ -112,17 +136,17 @@ static uint32_t Q_prime_cqi(uint32_t O, float beta, uint32_t Q_prime_ri, harq_t
/* Encode UCI CQI/PMI for payloads equal or lower to 11 bits (Sec 5.2.2.6.4)
*/
int encode_cqi_short(uci_cqi_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_bits, uint32_t Q)
int encode_cqi_short(uci_cqi_pusch_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_bits, uint32_t Q)
{
if (nof_bits < MAX_CQI_LEN &&
q != NULL &&
data != NULL &&
if (nof_bits < MAX_CQI_LEN_PUSCH &&
q != NULL &&
data != NULL &&
q_bits != NULL)
{
for (int i=0;i<32;i++) {
q->encoded_cqi[i] = 0;
for (int n=0;n<nof_bits;n++) {
q->encoded_cqi[i] += (data[n] * M_basis_seq[i][n]);
q->encoded_cqi[i] += (data[n] * M_basis_seq_pusch[i][n]);
}
}
@ -137,13 +161,13 @@ int encode_cqi_short(uci_cqi_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_
/* Encode UCI CQI/PMI for payloads greater than 11 bits (go through CRC, conv coder and rate match)
*/
int encode_cqi_long(uci_cqi_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_bits, uint32_t Q)
int encode_cqi_long(uci_cqi_pusch_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_bits, uint32_t Q)
{
convcoder_t encoder;
if (nof_bits + 8 < MAX_CQI_LEN &&
q != NULL &&
data != NULL &&
if (nof_bits + 8 < MAX_CQI_LEN_PUSCH &&
q != NULL &&
data != NULL &&
q_bits != NULL)
{
@ -173,9 +197,27 @@ int encode_cqi_long(uci_cqi_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_b
}
}
/* Encode UCI CQI/PMI as described in 5.2.3.3 of 36.212
*/
int uci_encode_cqi_pucch(uint8_t *cqi_data, uint32_t cqi_len, uint8_t b_bits[CQI_CODED_PUCCH_B])
{
if (cqi_len <= MAX_CQI_LEN_PUCCH) {
for (uint32_t i=0;i<CQI_CODED_PUCCH_B;i++) {
uint64_t x=0;
for (uint32_t n=0;n<cqi_len;n++) {
x += cqi_data[n]*M_basis_seq_pucch[n][i];
}
b_bits[i] = (uint8_t) (x%2);
}
return LIBLTE_SUCCESS;
} else {
return LIBLTE_ERROR_INVALID_INPUTS;
}
}
/* Encode UCI CQI/PMI as described in 5.2.2.6 of 36.212
*/
int uci_encode_cqi(uci_cqi_t *q, uint8_t *cqi_data, uint32_t cqi_len, float beta, uint32_t Q_prime_ri,
int uci_encode_cqi_pusch(uci_cqi_pusch_t *q, uint8_t *cqi_data, uint32_t cqi_len, float beta, uint32_t Q_prime_ri,
harq_t *harq_process, uint8_t *q_bits)
{
@ -313,3 +355,4 @@ int uci_encode_ri(uint8_t data, uint32_t O_cqi, float beta, harq_t *harq_process
return (int) Qprime;
}

View File

@ -134,6 +134,7 @@ ADD_EXECUTABLE(pusch_test pusch_test.c)
TARGET_LINK_LIBRARIES(pusch_test lte_phy)
BuildMex(MEXNAME ulsch_encode SOURCES ulsch_encode_test_mex.c LIBRARIES lte_phy liblte_mex)
BuildMex(MEXNAME pusch_encode SOURCES pusch_encode_test_mex.c LIBRARIES lte_phy liblte_mex)

View File

@ -50,20 +50,19 @@ lte_mod_t modulation = LTE_QPSK;
uint32_t rv_idx = 0;
void usage(char *prog) {
printf("Usage: %s [cpsrnfvmt] -l TBS \n", prog);
printf("Usage: %s [csrnfvmt] -l TBS \n", prog);
printf("\t-m modulation (1: BPSK, 2: QPSK, 3: QAM16, 4: QAM64) [Default BPSK]\n");
printf("\t-c cell id [Default %d]\n", cell.id);
printf("\t-s subframe [Default %d]\n", subframe);
printf("\t-r rv_idx [Default %d]\n", rv_idx);
printf("\t-f cfi [Default %d]\n", cfi);
printf("\t-p cell.nof_ports [Default %d]\n", cell.nof_ports);
printf("\t-n cell.nof_prb [Default %d]\n", cell.nof_prb);
printf("\t-v [set verbose to debug, default none]\n");
}
void parse_args(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "lcpnfvmtsr")) != -1) {
while ((opt = getopt(argc, argv, "lcnfvmtsr")) != -1) {
switch(opt) {
case 'm':
switch(atoi(argv[optind])) {
@ -94,9 +93,6 @@ void parse_args(int argc, char **argv) {
case 'l':
tbs = atoi(argv[optind]);
break;
case 'p':
cell.nof_ports = atoi(argv[optind]);
break;
case 'n':
cell.nof_prb = atoi(argv[optind]);
break;
@ -115,11 +111,10 @@ void parse_args(int argc, char **argv) {
int main(int argc, char **argv) {
pusch_t pusch;
uint32_t i, j;
uint8_t *data = NULL;
cf_t *ce[MAX_PORTS];
cf_t *ce;
uint32_t nof_re;
cf_t *slot_symbols[MAX_PORTS];
cf_t *sf_symbols;
int ret = -1;
struct timeval t[3];
ra_mcs_t mcs;
@ -134,26 +129,18 @@ int main(int argc, char **argv) {
mcs.mod = modulation;
prb_alloc.slot[0].nof_prb = 1;
//for (i=0;i<prb_alloc.slot[0].nof_prb;i++) {
// prb_alloc.slot[0].prb_idx[i] = true;
//}
memcpy(&prb_alloc.slot[1], &prb_alloc.slot[0], sizeof(ra_prb_slot_t));
/* init memory */
for (i=0;i<cell.nof_ports;i++) {
ce[i] = malloc(sizeof(cf_t) * nof_re);
if (!ce[i]) {
perror("malloc");
goto quit;
}
for (j=0;j<nof_re;j++) {
ce[i][j] = 1;
}
slot_symbols[i] = calloc(sizeof(cf_t) , nof_re);
if (!slot_symbols[i]) {
perror("malloc");
goto quit;
}
ce = malloc(sizeof(cf_t) * nof_re);
if (!ce) {
perror("malloc");
goto quit;
}
sf_symbols = calloc(sizeof(cf_t) , nof_re);
if (!sf_symbols) {
perror("malloc");
goto quit;
}
data = malloc(sizeof(uint8_t) * mcs.tbs);
@ -178,7 +165,7 @@ int main(int argc, char **argv) {
goto quit;
}
for (i=0;i<mcs.tbs;i++) {
for (uint32_t i=0;i<mcs.tbs;i++) {
data[i] = 1;
}
@ -188,7 +175,7 @@ int main(int argc, char **argv) {
printf("Encoding rv_idx=%d\n",rv_idx);
uint8_t tmp[20];
for (i=0;i<20;i++) {
for (uint32_t i=0;i<20;i++) {
tmp[i] = 1;
}
uci_data_t uci_data;
@ -206,37 +193,19 @@ int main(int argc, char **argv) {
uci_data.uci_ack = 1;
uint32_t nof_symbols = 12*harq_process.prb_alloc.slot[0].nof_prb*RE_X_RB;
uint32_t nof_bits_e = nof_symbols * lte_mod_bits_x_symbol(harq_process.mcs.mod);
bzero(pusch.pusch_q, nof_bits_e*sizeof(uint8_t));
if (ulsch_uci_encode(&pusch.dl_sch, data, uci_data, pusch.pusch_g, &harq_process, 0, pusch.pusch_q))
{
if (pusch_uci_encode(&pusch, data, uci_data, sf_symbols, subframe, &harq_process, 0)) {
fprintf(stderr, "Error encoding TB\n");
exit(-1);
}
if (rv_idx > 0) {
if (ulsch_uci_encode(&pusch.dl_sch, data, uci_data, pusch.pusch_g, &harq_process, rv_idx, pusch.pusch_q))
{
if (pusch_uci_encode(&pusch, data, uci_data, sf_symbols, subframe, &harq_process, rv_idx)) {
fprintf(stderr, "Error encoding TB\n");
exit(-1);
}
}
vec_fprint_b(stdout, pusch.pusch_q, nof_bits_e);
/* combine outputs */
for (i=0;i<cell.nof_ports;i++) {
for (j=0;j<nof_re;j++) {
if (i > 0) {
slot_symbols[0][j] += slot_symbols[i][j];
}
ce[i][j] = 1;
}
}
gettimeofday(&t[1], NULL);
//int r = pusch_decode(&pusch, slot_symbols[0], ce, 0, data, subframe, &harq_process, rv);
int r = 0;
@ -255,13 +224,11 @@ quit:
pusch_free(&pusch);
harq_free(&harq_process);
for (i=0;i<cell.nof_ports;i++) {
if (ce[i]) {
free(ce[i]);
}
if (slot_symbols[i]) {
free(slot_symbols[i]);
}
if (ce) {
free(ce);
}
if (sf_symbols) {
free(sf_symbols);
}
if (data) {
free(data);