Added PUSCH with no UL-SCH

master
ismagom 10 years ago
parent 45f9917ad4
commit e83165dc2c

@ -97,7 +97,6 @@ LIBLTE_API int dlsch_decode(sch_t *q,
LIBLTE_API int ulsch_encode(sch_t *q, LIBLTE_API int ulsch_encode(sch_t *q,
uint8_t *data, uint8_t *data,
uint8_t *q_bits, uint8_t *q_bits,
uint32_t nb_q,
harq_t *harq_process, harq_t *harq_process,
uint32_t rv_idx); uint32_t rv_idx);
@ -105,7 +104,6 @@ LIBLTE_API int ulsch_uci_encode(sch_t *q,
uint8_t *data, uint8_t *data,
uci_data_t uci_data, uci_data_t uci_data,
uint8_t *q_bits, uint8_t *q_bits,
uint32_t nb_q,
uint8_t *q_bits_ack, uint8_t *q_bits_ack,
uint8_t *q_bits_ri, uint8_t *q_bits_ri,
harq_t *harq_process, harq_t *harq_process,

@ -67,7 +67,8 @@ LIBLTE_API int uci_encode_cqi(uci_cqi_t *q,
uint8_t *q_bits); uint8_t *q_bits);
/* Encode UCI RI and HARQ ACK/NACK bits */ /* Encode UCI RI and HARQ ACK/NACK bits */
LIBLTE_API int uci_encode_ri_ack(uint8_t data, LIBLTE_API int uci_encode_ri_ack(uint8_t data,
uint32_t O_cqi,
float beta, float beta,
harq_t *harq_process, harq_t *harq_process,
uint8_t q_bits[6]); uint8_t q_bits[6]);

@ -48,42 +48,48 @@
int codeblock_segmentation(struct cb_segm *s, uint32_t tbs) { int codeblock_segmentation(struct cb_segm *s, uint32_t tbs) {
uint32_t Bp, B, idx1; uint32_t Bp, B, idx1;
int ret; int ret;
B = tbs + 24;
/* Calculate CB sizes */ if (tbs == 0) {
if (B <= MAX_LONG_CB) { bzero(s, sizeof(struct cb_segm));
s->C = 1; ret = LIBLTE_SUCCESS;
Bp = B;
} else { } else {
s->C = (uint32_t) ceilf((float) B / (MAX_LONG_CB - 24)); B = tbs + 24;
Bp = B + 24 * s->C;
} /* Calculate CB sizes */
ret = lte_find_cb_index((Bp-1) / s->C + 1); if (B <= MAX_LONG_CB) {
if (ret != LIBLTE_ERROR) { s->C = 1;
idx1 = (uint32_t) ret; Bp = B;
ret = lte_cb_size(idx1); } else {
s->C = (uint32_t) ceilf((float) B / (MAX_LONG_CB - 24));
Bp = B + 24 * s->C;
}
ret = lte_find_cb_index((Bp-1) / s->C + 1);
if (ret != LIBLTE_ERROR) { if (ret != LIBLTE_ERROR) {
s->K1 = (uint32_t) ret; idx1 = (uint32_t) ret;
if (idx1 > 0) { ret = lte_cb_size(idx1);
ret = lte_cb_size(idx1 - 1);
}
if (ret != LIBLTE_ERROR) { if (ret != LIBLTE_ERROR) {
if (s->C == 1) { s->K1 = (uint32_t) ret;
s->K2 = 0; if (idx1 > 0) {
s->C2 = 0; ret = lte_cb_size(idx1 - 1);
s->C1 = 1; }
} else { if (ret != LIBLTE_ERROR) {
s->K2 = (uint32_t) ret; if (s->C == 1) {
s->C2 = (s->C * s->K1 - Bp) / (s->K1 - s->K2); s->K2 = 0;
s->C1 = s->C - s->C2; s->C2 = 0;
s->C1 = 1;
} else {
s->K2 = (uint32_t) ret;
s->C2 = (s->C * s->K1 - Bp) / (s->K1 - s->K2);
s->C1 = s->C - s->C2;
}
s->F = s->C1 * s->K1 + s->C2 * s->K2 - Bp;
INFO("CB Segmentation: TBS: %d, C=%d, C+=%d K+=%d, C-=%d, K-=%d, F=%d, Bp=%d\n",
tbs, s->C, s->C1, s->K1, s->C2, s->K2, s->F, Bp);
} }
s->F = s->C1 * s->K1 + s->C2 * s->K2 - Bp;
INFO("CB Segmentation: TBS: %d, C=%d, C+=%d K+=%d, C-=%d, K-=%d, F=%d, Bp=%d\n",
tbs, s->C, s->C1, s->K1, s->C2, s->K2, s->F, Bp);
} }
} }
}
}
return ret; return ret;
} }
@ -179,15 +185,14 @@ void harq_reset(harq_t *q) {
int harq_setup(harq_t *q, ra_mcs_t mcs, ra_prb_t *prb_alloc) { int harq_setup(harq_t *q, ra_mcs_t mcs, ra_prb_t *prb_alloc) {
int ret = LIBLTE_ERROR_INVALID_INPUTS; int ret = LIBLTE_ERROR_INVALID_INPUTS;
if (q != NULL && if (q != NULL)
mcs.tbs > 0)
{ {
q->mcs = mcs; q->mcs = mcs;
memcpy(&q->prb_alloc, prb_alloc, sizeof(ra_prb_t)); memcpy(&q->prb_alloc, prb_alloc, sizeof(ra_prb_t));
q->N_symb_ul = 2*(CP_NSYMB(q->cell.cp)-1); q->N_symb_ul = 2*(CP_NSYMB(q->cell.cp)-1);
q->nof_prb_pusch_init = q->prb_alloc.slot[0].nof_prb; q->nof_prb_pusch_init = q->prb_alloc.slot[0].nof_prb;
codeblock_segmentation(&q->cb_segm, mcs.tbs); codeblock_segmentation(&q->cb_segm, mcs.tbs);
if (q->cb_segm.C > q->max_cb) { if (q->cb_segm.C > q->max_cb) {
fprintf(stderr, "Codeblock segmentation returned more CBs (%d) than allocated (%d)\n", fprintf(stderr, "Codeblock segmentation returned more CBs (%d) than allocated (%d)\n",

@ -354,7 +354,7 @@ int pusch_uci_encode(pusch_t *q, uint8_t *data, uci_data_t uci_data,
} }
memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); 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_e, nof_bits_e, if (ulsch_uci_encode(&q->dl_sch, data, uci_data, q->pusch_e,
q->pusch_q_ack, q->pusch_q_ri, harq_process, rv_idx)) q->pusch_q_ack, q->pusch_q_ri, harq_process, rv_idx))
{ {
fprintf(stderr, "Error encoding TB\n"); fprintf(stderr, "Error encoding TB\n");

@ -506,15 +506,15 @@ void ulsch_interleave(uint8_t *q_bits, uint32_t nb_q,
} }
int ulsch_encode(sch_t *q, uint8_t *data, uint8_t *q_bits, uint32_t nb_q, int ulsch_encode(sch_t *q, uint8_t *data, uint8_t *q_bits,
harq_t *harq_process, uint32_t rv_idx) harq_t *harq_process, uint32_t rv_idx)
{ {
uci_data_t uci_data; uci_data_t uci_data;
bzero(&uci_data, sizeof(uci_data_t)); bzero(&uci_data, sizeof(uci_data_t));
return ulsch_uci_encode(q, data, uci_data, q_bits, nb_q, NULL, NULL, harq_process, rv_idx); return ulsch_uci_encode(q, data, uci_data, q_bits, NULL, NULL, harq_process, rv_idx);
} }
int ulsch_uci_encode(sch_t *q, uint8_t *data, uci_data_t uci_data, uint8_t *q_bits, uint32_t nb_q, int ulsch_uci_encode(sch_t *q, uint8_t *data, uci_data_t uci_data, uint8_t *q_bits,
uint8_t *q_bits_ack, uint8_t *q_bits_ri, uint8_t *q_bits_ack, uint8_t *q_bits_ri,
harq_t *harq_process, uint32_t rv_idx) harq_t *harq_process, uint32_t rv_idx)
{ {
@ -526,9 +526,16 @@ int ulsch_uci_encode(sch_t *q, uint8_t *data, uci_data_t uci_data, uint8_t *q_bi
uint32_t Q_prime_ri = 0; uint32_t Q_prime_ri = 0;
uint32_t Q_m = lte_mod_bits_x_symbol(harq_process->mcs.mod); uint32_t Q_m = lte_mod_bits_x_symbol(harq_process->mcs.mod);
uint32_t nof_symbols = 12*harq_process->prb_alloc.slot[0].nof_prb*RE_X_RB;
uint32_t nb_q = nof_symbols * Q_m;
// Encode ACK // Encode ACK
if (uci_data.uci_ack_len > 0) { if (uci_data.uci_ack_len > 0) {
ret = uci_encode_ri_ack(uci_data.uci_ack, uci_data.beta_ack, harq_process, q_bits_ack); float beta = uci_data.beta_ack;
if (harq_process->mcs.tbs == 0) {
beta /= uci_data.beta_cqi;
}
ret = uci_encode_ri_ack(uci_data.uci_ack, uci_data.uci_cqi_len, beta, harq_process, q_bits_ack);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -537,7 +544,11 @@ int ulsch_uci_encode(sch_t *q, uint8_t *data, uci_data_t uci_data, uint8_t *q_bi
// Encode RI // Encode RI
if (uci_data.uci_ri_len > 0) { if (uci_data.uci_ri_len > 0) {
ret = uci_encode_ri_ack(uci_data.uci_ri, uci_data.beta_ri, harq_process, q_bits_ri); float beta = uci_data.beta_ri;
if (harq_process->mcs.tbs == 0) {
beta /= uci_data.beta_cqi;
}
ret = uci_encode_ri_ack(uci_data.uci_ri, uci_data.uci_cqi_len, beta, harq_process, q_bits_ri);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -556,19 +567,16 @@ int ulsch_uci_encode(sch_t *q, uint8_t *data, uci_data_t uci_data, uint8_t *q_bi
e_offset += Q_prime_cqi*Q_m; e_offset += Q_prime_cqi*Q_m;
uint32_t G = nb_q/Q_m - Q_prime_ri - Q_prime_cqi; printf("Q_prime_ack=%d, Q_prime_cqi=%d, Q_prime_ri=%d\n",Q_prime_ack, Q_prime_cqi, Q_prime_ri);
printf("Offset: %d*%d=%d, G*Q_m=%d*%d=%d, n_bq=%d Q_prime_cq=%d\n",Q_prime_cqi, Q_m, e_offset, G, Q_m, G*Q_m, nb_q, Q_prime_cqi);
// Encode UL-SCH // Encode UL-SCH
ret = encode_tb(q, data, &q_bits[e_offset], harq_process->mcs.tbs, if (harq_process->mcs.tbs > 0) {
G*Q_m, harq_process, rv_idx); uint32_t G = nb_q/Q_m - Q_prime_ri - Q_prime_cqi;
if (ret) { ret = encode_tb(q, data, &q_bits[e_offset], harq_process->mcs.tbs,
return ret; G*Q_m, harq_process, rv_idx);
} if (ret) {
return ret;
}
}
// Multiplexing and Interleaving // Multiplexing and Interleaving
ulsch_interleave(q_bits, nb_q/Q_m-Q_prime_ri, ulsch_interleave(q_bits, nb_q/Q_m-Q_prime_ri,

@ -80,7 +80,6 @@ static uint8_t M_basis_seq[32][11]={
}; };
int uci_cqi_init(uci_cqi_t *q) { int uci_cqi_init(uci_cqi_t *q) {
printf("init\n");
if (crc_init(&q->crc, LTE_CRC8, 8)) { if (crc_init(&q->crc, LTE_CRC8, 8)) {
return LIBLTE_ERROR; return LIBLTE_ERROR;
} }
@ -96,11 +95,17 @@ static uint32_t Q_prime_cqi(uint32_t O, float beta, uint32_t Q_prime_ri, harq_t
uint32_t K = harq_process->cb_segm.C1*harq_process->cb_segm.K1 + uint32_t K = harq_process->cb_segm.C1*harq_process->cb_segm.K1 +
harq_process->cb_segm.C2*harq_process->cb_segm.K2; harq_process->cb_segm.C2*harq_process->cb_segm.K2;
uint32_t M_sc_init = harq_process->nof_prb_pusch_init * RE_X_RB;
uint32_t L = (O<11)?0:8; uint32_t Q_prime = 0;
uint32_t x = (uint32_t) ceilf((float) (O+L)*M_sc_init*harq_process->N_symb_ul*beta/K); if (K > 0) {
uint32_t M_sc_init = harq_process->nof_prb_pusch_init * RE_X_RB;
uint32_t L = (O<11)?0:8;
uint32_t x = (uint32_t) ceilf((float) (O+L)*M_sc_init*harq_process->N_symb_ul*beta/K);
uint32_t Q_prime = MIN(x, M_sc * harq_process->N_symb_ul - Q_prime_ri); Q_prime = MIN(x, M_sc * harq_process->N_symb_ul - Q_prime_ri);
} else {
Q_prime = 12*harq_process->prb_alloc.slot[0].nof_prb*RE_X_RB - Q_prime_ri;
}
return Q_prime; return Q_prime;
} }
@ -160,7 +165,6 @@ int encode_cqi_long(uci_cqi_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_b
vec_fprint_b(stdout, q->encoded_cqi, 3 * (nof_bits + 8)); vec_fprint_b(stdout, q->encoded_cqi, 3 * (nof_bits + 8));
} }
printf("rm to Q=%d\n", Q);
rm_conv_tx(q->encoded_cqi, 3 * (nof_bits + 8), q_bits, Q); rm_conv_tx(q->encoded_cqi, 3 * (nof_bits + 8), q_bits, Q);
return LIBLTE_SUCCESS; return LIBLTE_SUCCESS;
@ -178,7 +182,6 @@ int uci_encode_cqi(uci_cqi_t *q, uint8_t *cqi_data, uint32_t cqi_len, float beta
uint32_t Q_prime = Q_prime_cqi(cqi_len, beta, Q_prime_ri, harq_process); uint32_t Q_prime = Q_prime_cqi(cqi_len, beta, Q_prime_ri, harq_process);
uint32_t Q_m = lte_mod_bits_x_symbol(harq_process->mcs.mod); uint32_t Q_m = lte_mod_bits_x_symbol(harq_process->mcs.mod);
printf("Q_prime_cqi: %d\n", Q_prime);
int ret = LIBLTE_ERROR; int ret = LIBLTE_ERROR;
if (cqi_len <= 11) { if (cqi_len <= 11) {
ret = encode_cqi_short(q, cqi_data, cqi_len, q_bits, Q_prime*Q_m); ret = encode_cqi_short(q, cqi_data, cqi_len, q_bits, Q_prime*Q_m);
@ -192,11 +195,17 @@ int uci_encode_cqi(uci_cqi_t *q, uint8_t *cqi_data, uint32_t cqi_len, float beta
} }
} }
static uint32_t Q_prime_ri_ack(uint32_t O, float beta, harq_t *harq_process) { static uint32_t Q_prime_ri_ack(uint32_t O, uint32_t O_cqi, float beta, harq_t *harq_process) {
uint32_t M_sc = harq_process->prb_alloc.slot[0].nof_prb * RE_X_RB; uint32_t M_sc = harq_process->prb_alloc.slot[0].nof_prb * RE_X_RB;
uint32_t K = harq_process->cb_segm.C1*harq_process->cb_segm.K1 + uint32_t K = harq_process->cb_segm.C1*harq_process->cb_segm.K1 +
harq_process->cb_segm.C2*harq_process->cb_segm.K2; harq_process->cb_segm.C2*harq_process->cb_segm.K2;
// If not carrying UL-SCH, get Q_prime according to 5.2.4.1
if (K == 0) {
K = O_cqi+8;
}
uint32_t M_sc_init = harq_process->nof_prb_pusch_init * RE_X_RB; uint32_t M_sc_init = harq_process->nof_prb_pusch_init * RE_X_RB;
uint32_t x = (uint32_t) ceilf((float) O*M_sc_init*harq_process->N_symb_ul*beta/K); uint32_t x = (uint32_t) ceilf((float) O*M_sc_init*harq_process->N_symb_ul*beta/K);
@ -209,7 +218,7 @@ static uint32_t Q_prime_ri_ack(uint32_t O, float beta, harq_t *harq_process) {
/* Encode UCI RI and HARQ bits as described in 5.2.2.6 of 36.212 /* Encode UCI RI and HARQ bits as described in 5.2.2.6 of 36.212
* Currently only supporting 1-bit RI or 1-bit HARQ * Currently only supporting 1-bit RI or 1-bit HARQ
*/ */
int uci_encode_ri_ack(uint8_t data, float beta, harq_t *harq_process, uint8_t *q_bits) int uci_encode_ri_ack(uint8_t data, uint32_t O_cqi, float beta, harq_t *harq_process, uint8_t *q_bits)
{ {
uint32_t Q_m = lte_mod_bits_x_symbol(harq_process->mcs.mod); uint32_t Q_m = lte_mod_bits_x_symbol(harq_process->mcs.mod);
@ -219,7 +228,7 @@ int uci_encode_ri_ack(uint8_t data, float beta, harq_t *harq_process, uint8_t *q
q_bits[i] = 3; q_bits[i] = 3;
} }
uint32_t Qprime = Q_prime_ri_ack(1, beta, harq_process); uint32_t Qprime = Q_prime_ri_ack(1, O_cqi, beta, harq_process);
for (uint32_t i=1;i<Qprime;i++) { for (uint32_t i=1;i<Qprime;i++) {
memcpy(&q_bits[i*Q_m], q_bits, Q_m*sizeof(uint8_t)); memcpy(&q_bits[i*Q_m], q_bits, Q_m*sizeof(uint8_t));

@ -111,10 +111,6 @@ void parse_args(int argc, char **argv) {
exit(-1); exit(-1);
} }
} }
if (tbs == 0) {
usage(argv[0]);
exit(-1);
}
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
@ -205,12 +201,12 @@ int main(int argc, char **argv) {
uci_data.uci_cqi = tmp; uci_data.uci_cqi = tmp;
uci_data.uci_cqi_len = 20; uci_data.uci_cqi_len = 20;
uci_data.uci_ri_len = 0; uci_data.uci_ri_len = 0;
uci_data.uci_ack_len = 0; uci_data.uci_ack_len = 1;
uint32_t nof_symbols = 12*harq_process.prb_alloc.slot[0].nof_prb*RE_X_RB; 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); uint32_t nof_bits_e = nof_symbols * lte_mod_bits_x_symbol(harq_process.mcs.mod);
if (ulsch_uci_encode(&pusch.dl_sch, data, uci_data, pusch.pusch_e, nof_bits_e, if (ulsch_uci_encode(&pusch.dl_sch, data, uci_data, pusch.pusch_e,
pusch.pusch_q_ack, pusch.pusch_q_ri, &harq_process, rv)) pusch.pusch_q_ack, pusch.pusch_q_ri, &harq_process, rv))
{ {
fprintf(stderr, "Error encoding TB\n"); fprintf(stderr, "Error encoding TB\n");

@ -74,10 +74,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
} }
mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin); mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin);
if (mcs.tbs == 0) {
mexErrMsgTxt("Error trblklen is zero\n");
return;
}
uci_data.uci_cqi_len = mexutils_read_uint8(CQI, &uci_data.uci_cqi); uci_data.uci_cqi_len = mexutils_read_uint8(CQI, &uci_data.uci_cqi);
uint8_t *tmp; uint8_t *tmp;
uci_data.uci_ri_len = mexutils_read_uint8(RI, &tmp); uci_data.uci_ri_len = mexutils_read_uint8(RI, &tmp);
@ -172,7 +169,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
if (ulsch_uci_encode(&ulsch, trblkin, uci_data, q_bits, nof_q_bits, if (ulsch_uci_encode(&ulsch, trblkin, uci_data, q_bits,
q_bits_ack, q_bits_ri, &harq_process, rv)) q_bits_ack, q_bits_ri, &harq_process, rv))
{ {
mexErrMsgTxt("Error encoding TB\n"); mexErrMsgTxt("Error encoding TB\n");

@ -1,5 +1,5 @@
ueConfig=struct('NCellID',1,'CyclicPrefixUL','Normal','NTxAnts',1); ueConfig=struct('NCellID',1,'CyclicPrefixUL','Normal','NTxAnts',1);
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',0,'Modulation','QPSK','RV',0,'Shortened',0); puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',0,'Modulation','64QAM','RV',0,'Shortened',0);
addpath('../../debug/lte/phy/lib/phch/test') addpath('../../debug/lte/phy/lib/phch/test')
@ -7,16 +7,17 @@ TBs=99;
error=zeros(size(TBs)); error=zeros(size(TBs));
for i=1:length(error) for i=1:length(error)
%trblkin=randi(2,TBs(i),1)-1; %trblkin=randi(2,TBs(i),1)-1;
trblkin=ones(TBs(i),1); %trblkin=ones(TBs(i),1);
trblkin=[];
puschConfig.BetaCQI = 7.0; puschConfig.BetaCQI = 7.0;
puschConfig.BetaRI = 11.0; puschConfig.BetaRI = 5.0;
puschConfig.BetaACK = 5.0; puschConfig.BetaACK = 11.0;
[mat, info]=lteULSCH(ueConfig,puschConfig,trblkin,[ones(1,20)],[1],[0],[]); [mat, info]=lteULSCH(ueConfig,puschConfig,trblkin,[ones(1,25)],[1],[1],[]);
mat(mat==-2)=2; mat(mat==-2)=2;
mat(mat==-1)=3; mat(mat==-1)=3;
[lib]=liblte_ulsch_encode(ueConfig,puschConfig,trblkin,[ones(1,20)],[1],[0]); [lib]=liblte_ulsch_encode(ueConfig,puschConfig,trblkin,[ones(1,25)],[1],[1]);
error(i)=sum(abs(double(mat)-double(lib))); error(i)=sum(abs(double(mat)-double(lib)));
if (length(TBs) == 1) if (length(TBs) == 1)
disp(error(i)) disp(error(i))

Loading…
Cancel
Save