diff --git a/matlab/tests/ulsch_test.m b/matlab/tests/ulsch_test.m index 8a4ada651..013ebca1d 100644 --- a/matlab/tests/ulsch_test.m +++ b/matlab/tests/ulsch_test.m @@ -2,13 +2,12 @@ clear ueConfig=struct('NCellID',1,'CyclicPrefixUL','Normal','NTxAnts',1); puschConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0); -addpath('../../build/srslte/lib/phch/test') +addpath('/home/ismael/work/srsLTE/debug/srslte/lib/phch/test') - -cqilen=0; -mods={'QPSK'}; +cqilen=[0 20]; +mods={'QPSK','16QAM', '64QAM'}; rvs=0; -betas=0; +betas=[0 2.0 2.5 5.0, 20.0]; for p=1:100 for i=0:26 for m=1:length(mods) @@ -17,10 +16,11 @@ for p=1:100 for back=1:length(betas) for c=1:length(cqilen) puschConfig.PRBSet=(0:p-1)'; + TBs=lteTBS(length(puschConfig.PRBSet),i); - %TBs=24496; - trblkin=randi(2,TBs,1)-1; - %trblkin=ones(1,TBs); + %TBs=256; + %trblkin=randi(2,TBs,1)-1; + trblkin=ones(1,TBs); puschConfig.Modulation = mods{m}; puschConfig.RV = rvs(r); @@ -28,24 +28,22 @@ for p=1:100 puschConfig.BetaRI = betas(bri); puschConfig.BetaACK = betas(back); - if (betas(bri)>0) - ri_bit=randi(2,1,1)-1; - else - ri_bit=[]; - end - if (betas(back)>0) - ack_bit=randi(2,1,1)-1; - else - ack_bit=[]; - end - + if (betas(bri)>0) + ri_bit=randi(2,1,1)-1; + else + ri_bit=[]; + end + if (betas(back)>0) + ack_bit=randi(2,1,1)-1; + else + ack_bit=[]; + end + if (cqilen(c)>0 || TBs>0) [lib]=srslte_ulsch_encode(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit); - lib(lib==192)=3; - lib(lib==48)=2; [mat, info]=lteULSCH(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit,[]); - mat(mat==-2)=3; - mat(mat==-1)=2; + mat(mat==-2)=0; + mat(mat==-1)=0; err=sum(abs(double(mat)-double(lib))); if (err > 0) disp(err) diff --git a/srslte/include/srslte/common/sequence.h b/srslte/include/srslte/common/sequence.h index 6a22f8876..6d33a7d3c 100644 --- a/srslte/include/srslte/common/sequence.h +++ b/srslte/include/srslte/common/sequence.h @@ -42,6 +42,7 @@ typedef struct SRSLTE_API { uint8_t *c; + uint8_t *c_bytes; uint32_t len; } srslte_sequence_t; diff --git a/srslte/include/srslte/phch/sch.h b/srslte/include/srslte/phch/sch.h index 90811320a..99b4c76bd 100644 --- a/srslte/include/srslte/phch/sch.h +++ b/srslte/include/srslte/phch/sch.h @@ -65,17 +65,19 @@ typedef struct SRSLTE_API { /* buffers */ uint8_t *cb_in; - uint8_t *cb_temp; void *cb_out; void *e; + uint8_t *temp_g_bits; + uint32_t *ul_interleaver; + srslte_uci_bit_t ack_ri_bits[12*288]; + uint32_t nof_ri_ack_bits; srslte_tcod_t encoder; srslte_tdec_t decoder; srslte_crc_t crc_tb; srslte_crc_t crc_cb; - srslte_uci_cqi_pusch_t uci_cqi; - srslte_uci_pos_t uci_pos; + srslte_uci_cqi_pusch_t uci_cqi; } srslte_sch_t; diff --git a/srslte/include/srslte/phch/uci.h b/srslte/include/srslte/phch/uci.h index 78e6b5423..153b3ed4e 100644 --- a/srslte/include/srslte/phch/uci.h +++ b/srslte/include/srslte/phch/uci.h @@ -46,9 +46,6 @@ #define SRSLTE_UCI_MAX_CQI_LEN_PUCCH 13 #define SRSLTE_UCI_CQI_CODED_PUCCH_B 20 -#define SRSLTE_UCI_ACK_RI_PLACEHOLDER_REPETITION 0xC0 -#define SRSLTE_UCI_ACK_RI_PLACEHOLDER 0x30 - typedef struct SRSLTE_API { srslte_crc_t crc; uint8_t tmp_cqi[SRSLTE_UCI_MAX_CQI_LEN_PUSCH]; @@ -67,10 +64,14 @@ typedef struct SRSLTE_API { bool channel_selection; } srslte_uci_data_t; +typedef enum { + UCI_BIT_1 = 0, UCI_BIT_0, UCI_BIT_REPETITION, UCI_BIT_PLACEHOLDER +} srslte_uci_bit_type_t; + typedef struct { - uint32_t idx; - uint32_t pos[SRSLTE_UCI_MAX_CQI_LEN_PUSCH]; -} srslte_uci_pos_t; + uint32_t position; + srslte_uci_bit_type_t type; +} srslte_uci_bit_t; SRSLTE_API int srslte_uci_cqi_init(srslte_uci_cqi_pusch_t *q); @@ -89,19 +90,18 @@ SRSLTE_API int srslte_uci_encode_cqi_pucch(uint8_t *cqi_data, uint8_t b_bits[SRSLTE_UCI_CQI_CODED_PUCCH_B]); SRSLTE_API int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg, - srslte_uci_pos_t *pos, uint8_t data, uint32_t O_cqi, float beta, uint32_t H_prime_total, - uint8_t *q_bits); + srslte_uci_bit_t *ri_bits); SRSLTE_API int srslte_uci_encode_ri(srslte_pusch_cfg_t *cfg, uint8_t data, uint32_t O_cqi, float beta, uint32_t H_prime_total, - uint8_t *q_bits); + srslte_uci_bit_t *ri_bits); #endif diff --git a/srslte/include/srslte/scrambling/scrambling.h b/srslte/include/srslte/scrambling/scrambling.h index 59418b4ea..e7129fa7b 100644 --- a/srslte/include/srslte/scrambling/scrambling.h +++ b/srslte/include/srslte/scrambling/scrambling.h @@ -49,6 +49,14 @@ SRSLTE_API void srslte_scrambling_b_offset(srslte_sequence_t *s, int offset, int len); +SRSLTE_API void srslte_scrambling_bytes(srslte_sequence_t *s, + uint8_t *data); + +SRSLTE_API void srslte_scrambling_bytes_offset(srslte_sequence_t *s, + uint8_t *data, + int offset, + int len); + SRSLTE_API void srslte_scrambling_f(srslte_sequence_t *s, float *data); diff --git a/srslte/lib/common/src/sequence.c b/srslte/lib/common/src/sequence.c index d9bd485f4..109c036c0 100644 --- a/srslte/lib/common/src/sequence.c +++ b/srslte/lib/common/src/sequence.c @@ -32,6 +32,7 @@ #include "srslte/common/sequence.h" #include "srslte/utils/vector.h" +#include "srslte/utils/bit.h" #define Nc 1600 @@ -81,18 +82,26 @@ int srslte_sequence_LTE_pr(srslte_sequence_t *q, uint32_t len, uint32_t seed) { } q->len = len; srslte_sequence_set_LTE_pr(q, seed); + srslte_bit_pack_vector(q->c, q->c_bytes, len); return SRSLTE_SUCCESS; } int srslte_sequence_init(srslte_sequence_t *q, uint32_t len) { if (q->c && (q->len != len)) { free(q->c); + if (q->c_bytes) { + free(q->c_bytes); + } } if (!q->c) { q->c = srslte_vec_malloc(len * sizeof(uint8_t)); if (!q->c) { return SRSLTE_ERROR; } + q->c_bytes = srslte_vec_malloc(len * sizeof(uint8_t)/8); + if (!q->c_bytes) { + return SRSLTE_ERROR; + } q->len = len; } return SRSLTE_SUCCESS; @@ -102,6 +111,9 @@ void srslte_sequence_free(srslte_sequence_t *q) { if (q->c) { free(q->c); } + if (q->c_bytes) { + free(q->c_bytes); + } bzero(q, sizeof(srslte_sequence_t)); } diff --git a/srslte/lib/fec/src/cbsegm.c b/srslte/lib/fec/src/cbsegm.c index e32a064d4..73fcfa874 100644 --- a/srslte/lib/fec/src/cbsegm.c +++ b/srslte/lib/fec/src/cbsegm.c @@ -89,7 +89,7 @@ int srslte_cbsegm(srslte_cbsegm_t *s, uint32_t tbs) { s->C1 = s->C - s->C2; } s->F = s->C1 * s->K1 + s->C2 * s->K2 - Bp; - printf("CB Segmentation: TBS: %d, C=%d, C+=%d K+=%d, C-=%d, K-=%d, F=%d, Bp=%d\n", + 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); ret = SRSLTE_SUCCESS; } diff --git a/srslte/lib/phch/src/pusch.c b/srslte/lib/phch/src/pusch.c index 0b28f23fb..a2066a236 100644 --- a/srslte/lib/phch/src/pusch.c +++ b/srslte/lib/phch/src/pusch.c @@ -546,12 +546,18 @@ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srs // Correct UCI placeholder bits uint8_t *d = q->q; - for (int i = 0; i < q->dl_sch.uci_pos.idx; i++) { - if (d[q->dl_sch.uci_pos.pos[i]] & SRSLTE_UCI_ACK_RI_PLACEHOLDER) { - d[q->dl_sch.uci_pos.pos[i]] = 1; - } else if (d[q->dl_sch.uci_pos.pos[i]] & SRSLTE_UCI_ACK_RI_PLACEHOLDER_REPETITION) { - if (q->dl_sch.uci_pos.pos[i] > 1) { - d[q->dl_sch.uci_pos.pos[i]] = d[q->dl_sch.uci_pos.pos[i]-1]; + for (int i = 0; i < q->dl_sch.nof_ri_ack_bits; i++) { + if (q->dl_sch.ack_ri_bits[i].type == UCI_BIT_PLACEHOLDER) { + d[q->dl_sch.ack_ri_bits[i].position/8] |= (1<<(q->dl_sch.ack_ri_bits[i].position%8)); + } else if (q->dl_sch.ack_ri_bits[i].type == UCI_BIT_REPETITION) { + if (q->dl_sch.ack_ri_bits[i].position > 1) { + uint32_t p=q->dl_sch.ack_ri_bits[i].position; + uint8_t bit = d[(p-1)/8] & (1<<((p-1)%8)); + if (bit) { + d[p/8] |= 1<<(p%8); + } else { + d[p/8] &= ~(1<<(p%8)); + } } } } diff --git a/srslte/lib/phch/src/sch.c b/srslte/lib/phch/src/sch.c index 3420a0387..404786a01 100644 --- a/srslte/lib/phch/src/sch.c +++ b/srslte/lib/phch/src/sch.c @@ -113,15 +113,20 @@ int srslte_sch_init(srslte_sch_t *q) { if (!q->cb_in) { goto clean; } - q->cb_temp = srslte_vec_malloc(sizeof(uint8_t) * SRSLTE_TCOD_MAX_LEN_CB+4); - if (!q->cb_temp) { - goto clean; - } q->cb_out = srslte_vec_malloc(sizeof(float) * (3 * SRSLTE_TCOD_MAX_LEN_CB + 12)); if (!q->cb_out) { goto clean; } + q->temp_g_bits = srslte_vec_malloc(sizeof(uint8_t)*SRSLTE_MAX_PRB*12*12*12); + if (!q->temp_g_bits) { + goto clean; + } + bzero(q->temp_g_bits, SRSLTE_MAX_PRB*12*12*12); + q->ul_interleaver = srslte_vec_malloc(sizeof(uint32_t)*SRSLTE_MAX_PRB*12*12*12); + if (!q->ul_interleaver) { + goto clean; + } if (srslte_uci_cqi_init(&q->uci_cqi)) { goto clean; } @@ -139,12 +144,15 @@ void srslte_sch_free(srslte_sch_t *q) { if (q->cb_in) { free(q->cb_in); } - if (q->cb_temp) { - free(q->cb_temp); - } if (q->cb_out) { free(q->cb_out); } + if (q->temp_g_bits) { + free(q->temp_g_bits); + } + if (q->ul_interleaver) { + free(q->ul_interleaver); + } srslte_tdec_free(&q->decoder); srslte_tcod_free(&q->encoder); srslte_uci_cqi_free(&q->uci_cqi); @@ -161,15 +169,13 @@ uint32_t srslte_sch_last_noi(srslte_sch_t *q) { } -uint8_t temp[64*1024]; - /* Encode a transport block according to 36.212 5.3.2 * */ -static int encode_tb(srslte_sch_t *q, +static int encode_tb_off(srslte_sch_t *q, srslte_softbuffer_tx_t *soft_buffer, srslte_cbsegm_t *cb_segm, uint32_t Qm, uint32_t rv, uint32_t nof_e_bits, - uint8_t *data, uint8_t *e_bits) + uint8_t *data, uint8_t *e_bits, uint32_t w_offset) { uint8_t parity[3] = {0, 0, 0}; uint32_t par; @@ -281,12 +287,11 @@ static int encode_tb(srslte_sch_t *q, /* Rate matching */ if (3*cb_len+12 < soft_buffer->buff_size) { - if (srslte_rm_turbo_tx_lut(soft_buffer->buffer_b[i], q->cb_in, (uint8_t*) q->cb_out, &temp[wp/8], cblen_idx, n_e, wp%8, rv)) + if (srslte_rm_turbo_tx_lut(soft_buffer->buffer_b[i], q->cb_in, (uint8_t*) q->cb_out, &e_bits[(wp+w_offset)/8], cblen_idx, n_e, (wp+w_offset)%8, rv)) { fprintf(stderr, "Error in rate matching\n"); return SRSLTE_ERROR; } - srslte_vec_fprint_byte(stdout, &temp[wp/8], (n_e-1)/8+1); } else { fprintf(stderr, "Encoded CB length exceeds RM buffer (%d>%d)\n",3*cb_len+12,soft_buffer->buff_size); return SRSLTE_ERROR; @@ -295,8 +300,6 @@ static int encode_tb(srslte_sch_t *q, rp += rlen; wp += n_e; } - srslte_bit_unpack_vector(temp, e_bits, nof_e_bits); - srslte_vec_fprint_b(stdout, e_bits, nof_e_bits); INFO("END CB#%d: wp: %d, rp: %d\n", i, wp, rp); ret = SRSLTE_SUCCESS; @@ -304,6 +307,16 @@ static int encode_tb(srslte_sch_t *q, return ret; } + +static int encode_tb(srslte_sch_t *q, + srslte_softbuffer_tx_t *soft_buffer, srslte_cbsegm_t *cb_segm, + uint32_t Qm, uint32_t rv, uint32_t nof_e_bits, + uint8_t *data, uint8_t *e_bits) +{ + return encode_tb_off(q, soft_buffer, cb_segm, Qm, rv, nof_e_bits, data, e_bits, 0); +} + + /* Decode a transport block according to 36.212 5.3.2 * */ @@ -498,34 +511,58 @@ int srslte_ulsch_decode(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuf e_bits, data); } - /* UL-SCH channel interleaver according to 5.2.2.8 of 36.212 */ -void ulsch_interleave(srslte_uci_pos_t *q, uint8_t *g_bits, uint32_t Qm, uint32_t H_prime_total, - uint32_t N_pusch_symbs, uint8_t *q_bits) +void ulsch_interleave(uint8_t *g_bits, uint32_t Qm, uint32_t H_prime_total, + uint32_t N_pusch_symbs, uint8_t *q_bits, srslte_uci_bit_t *ri_bits, uint32_t nof_ri_bits, + uint32_t *interleaver_buffer, uint8_t *temp_buffer, uint32_t buffer_sz) { uint32_t rows = H_prime_total/N_pusch_symbs; uint32_t cols = N_pusch_symbs; + // Prepare ri_bits for fast search using temp_buffer + if (nof_ri_bits > 0) { + for (uint32_t i=0;i= 10) { - q_bits[j*Qm + i*rows*Qm + k] -= 10; - q->pos[q->idx%SRSLTE_UCI_MAX_CQI_LEN_PUSCH] = j*Qm + i*rows*Qm + k; - q->idx++; - if (q->idx >= SRSLTE_UCI_MAX_CQI_LEN_PUSCH) { - fprintf(stderr, "Error number of UCI bits exceeds SRSLTE_UCI_MAX_CQI_LEN_PUSCH\n"); - } + if (temp_buffer[j*Qm + i*rows*Qm + k]) { + interleaver_buffer[j*Qm + i*rows*Qm + k] = 0; } else { - q_bits[j*Qm + i*rows*Qm + k] = g_bits[idx]; - idx++; + if (j*Qm + i*rows*Qm + k < buffer_sz) { + interleaver_buffer[j*Qm + i*rows*Qm + k] = idx; + idx++; + } else { + fprintf(stderr, "Error computing ULSCH interleaver. Position %d exceeds buffer size %d\n", j*Qm + i*rows*Qm + k, buffer_sz); + } } } } } + srslte_bit_interleave(g_bits, q_bits, interleaver_buffer, H_prime_total*Qm); + // Reset temp_buffer because will be reused next time + if (nof_ri_bits > 0) { + for (uint32_t i=0;inbits.nof_bits; uint32_t Qm = cfg->grant.Qm; - bzero(q_bits, sizeof(uint8_t) * nb_q); - // Encode RI if (uci_data.uci_ri_len > 0) { float beta = beta_ri_offset[cfg->uci_cfg.I_offset_ri]; if (cfg->cb_segm.tbs == 0) { beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi]; } - ret = srslte_uci_encode_ri(cfg, uci_data.uci_ri, uci_data.uci_cqi_len, beta, nb_q/Qm, q_bits); + ret = srslte_uci_encode_ri(cfg, uci_data.uci_ri, uci_data.uci_cqi_len, beta, nb_q/Qm, q->ack_ri_bits); if (ret < 0) { return ret; } @@ -571,43 +606,65 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q, ret = srslte_uci_encode_cqi_pusch(&q->uci_cqi, cfg, uci_data.uci_cqi, uci_data.uci_cqi_len, beta_cqi_offset[cfg->uci_cfg.I_offset_cqi], - Q_prime_ri, g_bits); + Q_prime_ri, q->temp_g_bits); if (ret < 0) { return ret; } Q_prime_cqi = (uint32_t) ret; + srslte_bit_pack_vector(q->temp_g_bits, g_bits, Q_prime_cqi*Qm); + // Reset the buffer because will be reused in ulsch_interleave + bzero(q->temp_g_bits, Q_prime_cqi*Qm); } e_offset += Q_prime_cqi*Qm; - + // Encode UL-SCH if (cfg->cb_segm.tbs > 0) { uint32_t G = nb_q/Qm - Q_prime_ri - Q_prime_cqi; - ret = encode_tb(q, softbuffer, &cfg->cb_segm, + ret = encode_tb_off(q, softbuffer, &cfg->cb_segm, Qm, cfg->rv, G*Qm, - data, &g_bits[e_offset]); + data, &g_bits[e_offset/8], e_offset%8); if (ret) { return ret; } } - + + //srslte_bit_unpack_vector(g_bits, kk, nb_q); + //srslte_vec_fprint_b(stdout, kk, nb_q); + // Interleave UL-SCH (and RI and CQI) - q->uci_pos.idx=0; - ulsch_interleave(&q->uci_pos, g_bits, Qm, nb_q/Qm, cfg->nbits.nof_symb, q_bits); - + ulsch_interleave(g_bits, Qm, nb_q/Qm, cfg->nbits.nof_symb, q_bits, q->ack_ri_bits, Q_prime_ri*Qm, + q->ul_interleaver, q->temp_g_bits, SRSLTE_MAX_PRB*12*12*12); + // Encode (and interleave) ACK if (uci_data.uci_ack_len > 0) { float beta = beta_harq_offset[cfg->uci_cfg.I_offset_ack]; if (cfg->cb_segm.tbs == 0) { beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi]; } - ret = srslte_uci_encode_ack(cfg, &q->uci_pos, uci_data.uci_ack, uci_data.uci_cqi_len, beta, nb_q/Qm, q_bits); + ret = srslte_uci_encode_ack(cfg, uci_data.uci_ack, uci_data.uci_cqi_len, beta, nb_q/Qm, &q->ack_ri_bits[Q_prime_ri*Qm]); if (ret < 0) { return ret; } Q_prime_ack = (uint32_t) ret; } + + q->nof_ri_ack_bits = (Q_prime_ack+Q_prime_ri)*Qm; + + for (uint32_t i=0;inof_ri_ack_bits;i++) { + uint32_t p = q->ack_ri_bits[i].position; + if (p < nb_q) { + if (q->ack_ri_bits[i].type == UCI_BIT_1) { + q_bits[p/8] |= (1<<(7-p%8)); + } else { + q_bits[p/8] &= ~(1<<(7-p%8)); + } + } else { + fprintf(stderr, "Invalid RI/ACK bit position %d. Max bits=%d\n", p, nb_q); + } + } + INFO("Q_prime_ack=%d, Q_prime_cqi=%d, Q_prime_ri=%d\n",Q_prime_ack, Q_prime_cqi, Q_prime_ri); return SRSLTE_SUCCESS; diff --git a/srslte/lib/phch/src/uci.c b/srslte/lib/phch/src/uci.c index 456c6c4b2..79a6027ef 100644 --- a/srslte/lib/phch/src/uci.c +++ b/srslte/lib/phch/src/uci.c @@ -241,10 +241,10 @@ int srslte_uci_encode_cqi_pusch(srslte_uci_cqi_pusch_t *q, srslte_pusch_cfg_t *c } } -/* Inserts UCI-ACK bits into the correct positions in the g buffer before interleaving */ -static int uci_ulsch_interleave_ack(srslte_uci_pos_t *q, uint8_t ack_coded_bits[6], uint32_t ack_q_bit_idx, +/* Generates UCI-ACK bits and computes position in q bits */ +static int uci_ulsch_interleave_ack(srslte_uci_bit_type_t ack_coded_bits[6], uint32_t ack_q_bit_idx, uint32_t Qm, uint32_t H_prime_total, uint32_t N_pusch_symbs, srslte_cp_t cp, - uint8_t *q_bits) { + srslte_uci_bit_t *ack_bits) { const uint32_t ack_column_set_norm[4] = {2, 3, 8, 9}; const uint32_t ack_column_set_ext[4] = {1, 2, 6, 7}; @@ -255,14 +255,8 @@ static int uci_ulsch_interleave_ack(srslte_uci_pos_t *q, uint8_t ack_coded_bits[ uint32_t colidx = (3*ack_q_bit_idx)%4; uint32_t col = SRSLTE_CP_ISNORM(cp)?ack_column_set_norm[colidx]:ack_column_set_ext[colidx]; for(uint32_t k=0; kpos[q->idx%SRSLTE_UCI_MAX_CQI_LEN_PUSCH] = row *Qm + (H_prime_total/N_pusch_symbs)*col*Qm + k; - q->idx++; - if (q->idx >= SRSLTE_UCI_MAX_CQI_LEN_PUSCH) { - fprintf(stderr, "Error number of UCI bits exceeds SRSLTE_UCI_MAX_CQI_LEN_PUSCH\n"); - } + ack_bits[k].position = row *Qm + (H_prime_total/N_pusch_symbs)*col*Qm + k; + ack_bits[k].type = ack_coded_bits[k]; } return SRSLTE_SUCCESS; } else { @@ -273,9 +267,9 @@ static int uci_ulsch_interleave_ack(srslte_uci_pos_t *q, uint8_t ack_coded_bits[ } /* Inserts UCI-RI bits into the correct positions in the g buffer before interleaving */ -static int uci_ulsch_interleave_ri(uint8_t ri_coded_bits[6], uint32_t ri_q_bit_idx, +static int uci_ulsch_interleave_ri(srslte_uci_bit_type_t ri_coded_bits[6], uint32_t ri_q_bit_idx, uint32_t Qm, uint32_t H_prime_total, uint32_t N_pusch_symbs, srslte_cp_t cp, - uint8_t *q_bits) { + srslte_uci_bit_t *ri_bits) { static uint32_t ri_column_set_norm[4] = {1, 4, 7, 10}; static uint32_t ri_column_set_ext[4] = {0, 3, 5, 8}; @@ -286,7 +280,8 @@ static int uci_ulsch_interleave_ri(uint8_t ri_coded_bits[6], uint32_t ri_q_bit_i uint32_t col = SRSLTE_CP_ISNORM(cp)?ri_column_set_norm[colidx]:ri_column_set_ext[colidx]; for(uint32_t k=0; kgrant.Qm); for (uint32_t i=0;igrant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, q_bits); + uci_ulsch_interleave_ack(q_encoded_bits, i, cfg->grant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, &ack_bits[cfg->grant.Qm*i]); } return (int) Qprime; @@ -363,19 +357,19 @@ int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg, srslte_uci_pos_t *pos, int srslte_uci_encode_ri(srslte_pusch_cfg_t *cfg, uint8_t data, uint32_t O_cqi, float beta, uint32_t H_prime_total, - uint8_t *q_bits) + srslte_uci_bit_t *ri_bits) { if (beta < 0) { fprintf(stderr, "Error beta is reserved\n"); return -1; } uint32_t Qprime = Q_prime_ri_ack(cfg, 1, O_cqi, beta); - uint8_t q_encoded_bits[6]; + srslte_uci_bit_type_t q_encoded_bits[6]; encode_ri_ack(data, q_encoded_bits, cfg->grant.Qm); for (uint32_t i=0;igrant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, q_bits); + uci_ulsch_interleave_ri(q_encoded_bits, i, cfg->grant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, &ri_bits[cfg->grant.Qm*i]); } return (int) Qprime; diff --git a/srslte/lib/phch/test/pusch_test.c b/srslte/lib/phch/test/pusch_test.c index 364f26adc..a08ef8f9e 100644 --- a/srslte/lib/phch/test/pusch_test.c +++ b/srslte/lib/phch/test/pusch_test.c @@ -167,7 +167,7 @@ int main(int argc, char **argv) { srslte_uci_data_t uci_data; bzero(&uci_data, sizeof(srslte_uci_data_t)); - uci_data.uci_cqi_len = 0; + uci_data.uci_cqi_len = 20; uci_data.uci_ri_len = 0; uci_data.uci_ack_len = 0; @@ -202,7 +202,7 @@ int main(int argc, char **argv) { data[i] = 1; } - if (srslte_softbuffer_tx_init(&softbuffer, 4*cell.nof_prb)) { + if (srslte_softbuffer_tx_init(&softbuffer, 100)) { fprintf(stderr, "Error initiating soft buffer\n"); goto quit; } diff --git a/srslte/lib/phch/test/ulsch_encode_test_mex.c b/srslte/lib/phch/test/ulsch_encode_test_mex.c index dd793721d..d2be9c19b 100644 --- a/srslte/lib/phch/test/ulsch_encode_test_mex.c +++ b/srslte/lib/phch/test/ulsch_encode_test_mex.c @@ -69,7 +69,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) cell.id=1; cell.cp=SRSLTE_CP_NORM; - srslte_verbose = SRSLTE_VERBOSE_INFO; + srslte_verbose = SRSLTE_VERBOSE_NONE; if (srslte_softbuffer_tx_init(&softbuffer, cell.nof_prb)) { mexErrMsgTxt("Error initiating HARQ\n"); @@ -175,11 +175,15 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) return; } - uint8_t *q_bits = srslte_vec_malloc(cfg.nbits.nof_bits * sizeof(uint8_t)); + uint8_t *q_bits = srslte_vec_malloc(cfg.nbits.nof_bits * sizeof(uint8_t)/8); if (!q_bits) { return; } - uint8_t *g_bits = srslte_vec_malloc(cfg.nbits.nof_bits * sizeof(uint8_t)); + uint8_t *q_bits_unpacked = srslte_vec_malloc(cfg.nbits.nof_bits * sizeof(uint8_t)); + if (!q_bits_unpacked) { + return; + } + uint8_t *g_bits = srslte_vec_malloc(cfg.nbits.nof_bits * sizeof(uint8_t)/8); if (!g_bits) { return; } @@ -196,9 +200,11 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) return; } } - + + srslte_bit_unpack_vector(q_bits, q_bits_unpacked, cfg.nbits.nof_bits); + if (nlhs >= 1) { - mexutils_write_uint8(q_bits, &plhs[0], cfg.nbits.nof_bits, 1); + mexutils_write_uint8(q_bits_unpacked, &plhs[0], cfg.nbits.nof_bits, 1); } srslte_sch_free(&ulsch); @@ -206,6 +212,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) free(trblkin); free(g_bits); + free(q_bits_unpacked); free(q_bits); diff --git a/srslte/lib/scrambling/src/scrambling.c b/srslte/lib/scrambling/src/scrambling.c index fe4136ba7..3a2dded0d 100644 --- a/srslte/lib/scrambling/src/scrambling.c +++ b/srslte/lib/scrambling/src/scrambling.c @@ -58,37 +58,47 @@ void srslte_scrambling_c_offset(srslte_sequence_t *s, cf_t *data, int offset, in } } -void srslte_scrambling_b(srslte_sequence_t *s, uint8_t *data) { - srslte_scrambling_b_offset(s, data, 0, s->len); -} - -void srslte_scrambling_b_offset(srslte_sequence_t *s, uint8_t *data, int offset, int len) { +void scrambling_b(uint8_t *c, uint8_t *data, int offset, int len) { int i; - assert (len + offset <= s->len); // Do XOR on a word basis if (!(len%8)) { uint64_t *x = (uint64_t*) data; - uint64_t *y = (uint64_t*) &s->c[offset]; + uint64_t *y = (uint64_t*) &c[offset]; for (int i=0;ic[offset]; + uint32_t *y = (uint32_t*) &c[offset]; for (int i=0;ic[offset]; + uint16_t *y = (uint16_t*) &c[offset]; for (int i=0;ic[i + offset]) % 2; + data[i] = (data[i] ^ c[i + offset]); } } } +void srslte_scrambling_b(srslte_sequence_t *s, uint8_t *data) { + scrambling_b(s->c, data, 0, s->len); +} + +void srslte_scrambling_b_offset(srslte_sequence_t *s, uint8_t *data, int offset, int len) { + scrambling_b(s->c, data, offset, len); +} + +void srslte_scrambling_bytes(srslte_sequence_t *s, uint8_t *data) { + scrambling_b(s->c_bytes, data, 0, s->len); +} + +void srslte_scrambling_bytes_offset(srslte_sequence_t *s, uint8_t *data, int offset, int len) { + scrambling_b(s->c_bytes, data, offset, len); +} diff --git a/srslte/lib/utils/src/bit.c b/srslte/lib/utils/src/bit.c index fe2f4be67..5dfe9bf44 100644 --- a/srslte/lib/utils/src/bit.c +++ b/srslte/lib/utils/src/bit.c @@ -212,23 +212,14 @@ bitarray_copy(const unsigned char *src_org, int src_offset, int src_len, void srslte_bit_copy(uint8_t *dst, uint32_t dst_offset, uint8_t *src, uint32_t src_offset, uint32_t nof_bits) { - static const uint8_t mask_src[] = - { 0x00, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff }; static const uint8_t mask_dst[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; - if ((dst_offset%8) == (src_offset%8)) { - if (src_offset%8) { - // copy 1st word - dst[dst_offset/8] &= 0xf0; - dst[dst_offset/8] |= (src[src_offset/8] & mask_src[src_offset%8]); - dst_offset+=(src_offset%8); - src_offset+=(src_offset%8); - } + if ((dst_offset%8) == 0 && (src_offset%8) == 0) { // copy rest of words memcpy(&dst[dst_offset/8], &src[src_offset/8], nof_bits/8); // copy last word - if ((src_offset%8+nof_bits)%8) { - dst[dst_offset/8+nof_bits/8] = src[src_offset/8+nof_bits/8] & mask_dst[(src_offset%8+nof_bits)%8]; + if (nof_bits%8) { + dst[dst_offset/8+nof_bits/8] = src[src_offset/8+nof_bits/8] & mask_dst[nof_bits%8]; } } else { bitarray_copy(src, src_offset, nof_bits, dst, dst_offset);