Changed PUSCH/PDSCH RA configuration to enable Shortened PUSCH due to SRS transmission

master
ismagom 10 years ago
parent 5143af5e00
commit f38cc2e938

@ -3,12 +3,12 @@ puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',22,'Shortened',0);
addpath('../../build/srslte/lib/phch/test')
TBs=336;
TBs=[111 336];
cqilen=0;
rvs=0;
rvs=[0 2];
mods={'16QAM'};
betas=0;
subf=8;
subf=[1:8];
for i=1:length(TBs)
for m=1:length(mods)
@ -41,17 +41,17 @@ for i=1:length(TBs)
if (cqilen(c)>0 || TBs(i)>0)
[cw, info]=lteULSCH(ueConfig,puschConfig,trblkin);
cw_mat=ltePUSCH(ueConfig,puschConfig,cw);
drs=ltePUSCHDRS(ueConfig,puschConfig);
%drs=ltePUSCHDRS(ueConfig,puschConfig);
idx=ltePUSCHIndices(ueConfig,puschConfig);
drs_idx=ltePUSCHDRSIndices(ueConfig,puschConfig);
%drs_idx=ltePUSCHDRSIndices(ueConfig,puschConfig);
subframe_mat = lteULResourceGrid(ueConfig);
subframe_mat(idx)=cw_mat;
subframe_mat(drs_idx)=drs;
%subframe_mat(drs_idx)=drs;
waveform = lteSCFDMAModulate(ueConfig,subframe_mat,0);
[waveform_lib, subframe_lib, cwlib]=srslte_pusch_encode(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit);
err=mean(abs(waveform-waveform_lib));
if (err > 10^-8)
err=max(abs(waveform-waveform_lib));
if (err > 10^-5)
disp(err)
error('Error!');
end

@ -75,19 +75,22 @@ namespace ue {
uint32_t get_mcs() {
return dl_dci.mcs_idx;
}
bool create_from_dci(srslte_dci_msg_t *msg, srslte_cell_t cell, uint32_t cfi, uint32_t sf_idx, uint32_t ncce_) {
bool create_from_dci(srslte_dci_msg_t *msg, uint32_t nof_prb, uint32_t ncce_) {
ncce = ncce_;
if (srslte_dci_msg_to_dl_grant(msg, rnti, cell, cfi, sf_idx, &dl_dci, &grant)) {
if (srslte_dci_msg_to_dl_grant(msg, rnti, nof_prb, &dl_dci, &grant)) {
return false;
} else {
return true;
}
}
void get_pdsch_cfg(uint32_t sf_idx, srslte_pdsch_cfg_t *cfg) {
srslte_cbsegm(&cfg->cb_segm, grant.mcs.tbs);
memcpy(&cfg->grant, &grant, sizeof(srslte_ra_dl_grant_t));
cfg->sf_idx = sf_idx;
cfg->rv = dl_dci.rv_idx;
bool get_pdsch_cfg(uint32_t sf_idx, uint32_t cfi, srslte_ue_dl_t *ue_dl) {
memcpy(&ue_dl->pdsch_cfg.grant, &grant, sizeof(srslte_ra_dl_grant_t));
/* Setup PDSCH configuration for this CFI, SFIDX and RVIDX */
if (srslte_ue_dl_cfg_grant(ue_dl, NULL, cfi, sf_idx, rnti, get_rv())) {
return false;
}
return true;
}
private:
srslte_ra_dl_grant_t grant;

@ -40,12 +40,8 @@ namespace ue {
class ul_sched_grant : public sched_grant {
public:
ul_sched_grant(rnti_type_t type, uint16_t rnti) : sched_grant(type, rnti) {
N_srs = 0;
}
ul_sched_grant(uint16_t rnti) : sched_grant(rnti) {
N_srs = 0;
}
ul_sched_grant(rnti_type_t type, uint16_t rnti) : sched_grant(type, rnti) {}
ul_sched_grant(uint16_t rnti) : sched_grant(rnti) {}
uint32_t get_rv() {
return ul_dci.rv_idx;
@ -59,13 +55,6 @@ namespace ue {
void set_ndi(bool value) {
ul_dci.ndi = value;
}
void set_shortened(bool enabled) {
if (enabled) {
N_srs = 1;
} else {
N_srs = 0;
}
}
bool get_cqi_request() {
return ul_dci.cqi_request;
}
@ -98,7 +87,7 @@ namespace ue {
}
bool create_from_dci(srslte_dci_msg_t *msg, srslte_cell_t cell, uint32_t n_rb_ho) {
grant_is_from_rar = false;
if (srslte_dci_msg_to_ul_grant(msg, cell, N_srs, n_rb_ho, &ul_dci, &grant)) {
if (srslte_dci_msg_to_ul_grant(msg, cell.nof_prb, n_rb_ho, &ul_dci, &grant)) {
return false;
} else {
if (SRSLTE_VERBOSE_ISINFO()) {
@ -109,7 +98,7 @@ namespace ue {
}
bool create_from_rar(srslte_dci_rar_grant_t *rar, srslte_cell_t cell, uint32_t n_rb_ho) {
grant_is_from_rar = true;
if (srslte_dci_rar_to_ul_grant(rar, cell, n_rb_ho, &ul_dci, &grant)) {
if (srslte_dci_rar_to_ul_grant(rar, cell.nof_prb, n_rb_ho, &ul_dci, &grant)) {
return false;
} else {
if (SRSLTE_VERBOSE_ISINFO()) {
@ -118,12 +107,12 @@ namespace ue {
return true;
}
}
void to_pusch_cfg(uint32_t sf_idx, srslte_cp_t cp, srslte_pusch_cfg_t *cfg) {
srslte_cbsegm(&cfg->cb_segm, grant.mcs.tbs);
cfg->cp = cp;
memcpy(&cfg->grant, &grant, sizeof(srslte_ra_ul_grant_t));
cfg->rv = ul_dci.rv_idx;
cfg->sf_idx = sf_idx;
bool to_pusch_cfg(uint32_t sf_idx, uint32_t N_srs, srslte_ue_ul_t *ue_ul) {
memcpy(&ue_ul->pusch_cfg.grant, &grant, sizeof(srslte_ra_ul_grant_t));
if (srslte_ue_ul_cfg_grant(ue_ul, NULL, 0, N_srs, sf_idx, get_rv())) {
return false;
}
return true;
}
private:
srslte_ra_ul_grant_t grant;
@ -131,7 +120,6 @@ namespace ue {
uint32_t current_tx_nb;
uint16_t rnti;
bool grant_is_from_rar;
uint32_t N_srs;
};
}

@ -117,15 +117,6 @@ bool dl_buffer::get_ul_grant(ul_sched_grant *grant)
return false;
}
grant->set_shortened(false);
if (params_db->get_param(phy_params::SRS_IS_CS_CONFIGURED)) {
if (srslte_refsignal_srs_send_cs((uint32_t) params_db->get_param(phy_params::SRS_CS_SFCFG), (tti+4)%10) == 1) {
grant->set_shortened(true);
printf("UL grant tti=%d is shortened. SF-CFG=%d\n", tti+4,
(int) params_db->get_param(phy_params::SRS_CS_SFCFG));
}
}
return grant->create_from_dci(&dci_msg, cell, params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET));
}
}
@ -177,7 +168,7 @@ bool dl_buffer::get_dl_grant(dl_sched_grant *grant)
Info("Found DL DCI cce_index=%d, n_data_bits=%d\n", ue_dl.last_n_cce, dci_msg.nof_bits);
return grant->create_from_dci(&dci_msg, cell, cfi, tti%10, srslte_ue_dl_get_ncce(&ue_dl));
return grant->create_from_dci(&dci_msg, cell.nof_prb, srslte_ue_dl_get_ncce(&ue_dl));
}
}
@ -217,14 +208,14 @@ bool dl_buffer::decode_data(dl_sched_grant *grant, srslte_softbuffer_rx_t *softb
sf_symbols_and_ce_done = true;
}
grant->get_pdsch_cfg(tti%10, &ue_dl.pdsch_cfg);
grant->get_pdsch_cfg(tti%10, cfi, &ue_dl);
if (ue_dl.pdsch_cfg.grant.mcs.mod > 0 && ue_dl.pdsch_cfg.grant.mcs.tbs >= 0) {
int ret = srslte_pdsch_decode_rnti(&ue_dl.pdsch, &ue_dl.pdsch_cfg, softbuffer, ue_dl.sf_symbols,
ue_dl.ce, 0, grant->get_rnti(), payload);
if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_save_file((char*) "pdsch_d", ue_dl.pdsch.d, ue_dl.pdsch_cfg.grant.nof_re*sizeof(cf_t));
srslte_vec_save_file((char*) "pdsch_d", ue_dl.pdsch.d, ue_dl.pdsch_cfg.nbits.nof_re*sizeof(cf_t));
}
if (ret == SRSLTE_SUCCESS) {
return true;

@ -183,19 +183,28 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof
// Transmit on PUSCH if UL grant available, otherwise in PUCCH
if (grant) {
grant->to_pusch_cfg(tti%10, cell.cp, &pusch_cfg);
uint32_t N_srs = 0;
if (params_db->get_param(phy_params::SRS_IS_CS_CONFIGURED)) {
if (srslte_refsignal_srs_send_cs((uint32_t) params_db->get_param(phy_params::SRS_CS_SFCFG), tti%10) == 1) {
N_srs = 1;
printf("UL grant tti=%d is shortened. SF-CFG=%d\n", tti,
(int) params_db->get_param(phy_params::SRS_CS_SFCFG));
}
}
grant->to_pusch_cfg(tti%10, N_srs, &ue_ul);
Info("Encoding PUSCH TBS=%d, mod=%s, rb_start=%d n_prb=%d, ack=%s, sr=%s, rnti=%d, sf_idx=%d\n",
grant->get_tbs(), srslte_mod_string(pusch_cfg.grant.mcs.mod), pusch_cfg.grant.n_prb[0], pusch_cfg.grant.L_prb,
uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no",
grant->get_rnti(), tti%10);
n = srslte_ue_ul_pusch_encode_cfg(&ue_ul, &pusch_cfg,
payload, uci_data,
softbuffer,
grant->get_rnti(),
signal_buffer);
} else {
n = srslte_ue_ul_pusch_encode_rnti_softbuffer(&ue_ul,
payload, uci_data,
softbuffer,
grant->get_rnti(),
signal_buffer);
} else {
Info("Encoding PUCCH n_cce=%d, ack=%d, sr=%d\n", last_n_cce, uci_data.uci_ack, uci_data.scheduling_request);
n = srslte_ue_ul_pucch_encode(&ue_ul, uci_data, tti&10, signal_buffer);

@ -331,12 +331,14 @@ int update_radl() {
srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb);
srslte_ra_dl_grant_t dummy_grant;
srslte_ra_dl_dci_to_grant(&ra_dl, &dummy_grant, cell, 1, cfi, true);
srslte_ra_nbits_t dummy_nbits;
srslte_ra_dl_dci_to_grant(&ra_dl, cell.nof_prb, true, &dummy_grant);
srslte_ra_dl_grant_to_nbits(&dummy_grant, cfi, cell, 0, &dummy_nbits);
srslte_ra_dl_grant_fprint(stdout, &dummy_grant);
printf("Type new MCS index and press Enter: "); fflush(stdout);
if (dummy_grant.mcs.tbs > dummy_grant.nof_bits) {
fprintf(stderr, "Invalid code rate %d/%d=%.2f\n", dummy_grant.mcs.tbs, dummy_grant.nof_bits, (float) dummy_grant.mcs.tbs / dummy_grant.nof_bits);
if (dummy_grant.mcs.tbs > dummy_nbits.nof_bits) {
fprintf(stderr, "Invalid code rate %d/%d=%.2f\n", dummy_grant.mcs.tbs, dummy_nbits.nof_bits, (float) dummy_grant.mcs.tbs / dummy_nbits.nof_bits);
return -1;
}
@ -522,6 +524,8 @@ int main(int argc, char **argv) {
nf = 0;
bool send_data = false;
bool start_of_burst = true;
srslte_softbuffer_tx_reset(&softbuffer);
while (nf < nof_frames || nof_frames == -1) {
for (sf_idx = 0; sf_idx < SRSLTE_NSUBFRAMES_X_FRAME && (nf < nof_frames || nof_frames == -1); sf_idx++) {
@ -562,12 +566,8 @@ int main(int argc, char **argv) {
}
if (send_data) {
srslte_ra_dl_dci_to_grant(&ra_dl, &pdsch_cfg.grant, cell, sf_idx, cfi, true);
srslte_cbsegm(&pdsch_cfg.cb_segm, pdsch_cfg.grant.mcs.tbs);
srslte_softbuffer_tx_reset(&softbuffer);
pdsch_cfg.sf_idx = sf_idx;
pdsch_cfg.rv = 0;
/* Encode PDCCH */
srslte_dci_msg_pack_pdsch(&ra_dl, &dci_msg, SRSLTE_DCI_FORMAT1, cell.nof_prb, false);
INFO("Putting DCI to location: n=%d, L=%d\n", locations[sf_idx][0].ncce, locations[sf_idx][0].L);
if (srslte_pdcch_encode(&pdcch, &dci_msg, locations[sf_idx][0], UE_CRNTI, sf_symbols, sf_idx, cfi)) {
@ -575,6 +575,14 @@ int main(int argc, char **argv) {
exit(-1);
}
/* Configure pdsch_cfg parameters */
srslte_ra_dl_dci_to_grant(&ra_dl, cell.nof_prb, true, &pdsch_cfg.grant);
if (srslte_pdsch_cfg(&pdsch_cfg, cell, NULL, cfi, sf_idx, UE_CRNTI, 0)) {
fprintf(stderr, "Error configuring PDSCH\n");
exit(-1);
}
/* Encode PDSCH */
if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer, data, sf_symbols)) {
fprintf(stderr, "Error encoding PDSCH\n");
exit(-1);
@ -605,7 +613,8 @@ int main(int argc, char **argv) {
// FIXME
float norm_factor = (float) cell.nof_prb/15/sqrtf(pdsch_cfg.grant.nof_prb);
srslte_vec_sc_prod_cfc(output_buffer, uhd_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
cuhd_send(uhd, output_buffer, sf_n_samples, true);
cuhd_send2(uhd, output_buffer, sf_n_samples, true, start_of_burst, false);
start_of_burst=false;
#endif
}
nf++;

@ -631,7 +631,7 @@ void *plot_thread_run(void *arg) {
while(1) {
sem_wait(&plot_sem);
uint32_t nof_symbols = ue_dl.pdsch_cfg.grant.nof_re;
uint32_t nof_symbols = ue_dl.pdsch_cfg.nbits.nof_re;
if (!prog_args.disable_plots_except_constellation) {
for (i = 0; i < nof_re; i++) {
tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i]));

@ -499,7 +499,7 @@ cell.nof_ports = 1;
rar_grant.hopping_flag = rar_msg.hopping_flag;
rar_grant.rba = rar_msg.rba;
rar_grant.trunc_mcs = rar_msg.mcs;
srslte_dci_rar_to_ul_grant(&rar_grant, cell, 0, &ra_pusch, &ra_grant);
srslte_dci_rar_to_ul_grant(&rar_grant, cell.nof_prb, 0, &ra_pusch, &ra_grant);
srslte_ra_pusch_fprint(stdout, &ra_pusch, cell.nof_prb);
srslte_ue_sync_get_last_timestamp(&ue_sync, &uhd_time);
@ -522,7 +522,10 @@ cell.nof_ports = 1;
printf("Setting CFO: %f (%f)\n", cfo, cfo*15000);
srslte_ue_ul_set_cfo(&ue_ul, cfo);
n = srslte_ue_ul_pusch_encode_rnti(&ue_ul, &ra_grant, data, ul_sf_idx, 0, rar_msg.temp_c_rnti, ul_signal);
memcpy(&ue_ul.pusch_cfg.grant, &ra_grant, sizeof(srslte_ra_ul_grant_t));
srslte_ue_ul_cfg_grant(&ue_ul, NULL, 0, 0, ul_sf_idx, 0);
n = srslte_ue_ul_pusch_encode_rnti(&ue_ul, data, rar_msg.temp_c_rnti, ul_signal);
if (n < 0) {
fprintf(stderr, "Error encoding PUSCH\n");
exit(-1);

@ -118,6 +118,12 @@ SRSLTE_API int cuhd_send(void *h,
uint32_t nsamples,
bool blocking);
SRSLTE_API int cuhd_send2(void *h,
void *data,
uint32_t nsamples,
bool blocking,
bool start_of_burst,
bool end_of_burst);
SRSLTE_API int cuhd_send(void *h,
void *data,

@ -97,21 +97,18 @@ typedef struct SRSLTE_API {
*/
SRSLTE_API int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg,
uint16_t msg_rnti,
srslte_cell_t cell,
uint32_t cfi,
uint32_t sf_idx,
uint32_t nof_prb,
srslte_ra_dl_dci_t *dl_dci,
srslte_ra_dl_grant_t *grant);
SRSLTE_API int srslte_dci_msg_to_ul_grant(srslte_dci_msg_t *msg,
srslte_cell_t cell,
uint32_t N_srs,
uint32_t nof_prb,
uint32_t n_rb_ho,
srslte_ra_ul_dci_t *ul_dci,
srslte_ra_ul_grant_t *grant);
SRSLTE_API int srslte_dci_rar_to_ul_grant(srslte_dci_rar_grant_t *rar,
srslte_cell_t cell,
uint32_t nof_prb,
uint32_t n_rb_ho,
srslte_ra_ul_dci_t *ul_dci,
srslte_ra_ul_grant_t *grant);

@ -82,6 +82,14 @@ SRSLTE_API void srslte_pdsch_free(srslte_pdsch_t *q);
SRSLTE_API int srslte_pdsch_set_rnti(srslte_pdsch_t *q,
uint16_t rnti);
SRSLTE_API int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg,
srslte_cell_t cell,
srslte_dci_msg_t *dci_msg,
uint32_t cfi,
uint32_t sf_idx,
uint16_t rnti,
uint32_t rvidx);
SRSLTE_API int srslte_pdsch_encode(srslte_pdsch_t *q,
srslte_pdsch_cfg_t *cfg,
srslte_softbuffer_tx_t *softbuffer,

@ -43,6 +43,7 @@
typedef struct SRSLTE_API {
srslte_cbsegm_t cb_segm;
srslte_ra_dl_grant_t grant;
srslte_ra_nbits_t nbits;
uint32_t rv;
uint32_t sf_idx;
} srslte_pdsch_cfg_t;

@ -44,6 +44,7 @@
#include "srslte/modem/demod_soft.h"
#include "srslte/scrambling/scrambling.h"
#include "srslte/phch/regs.h"
#include "srslte/phch/dci.h"
#include "srslte/phch/sch.h"
#include "srslte/phch/pusch_cfg.h"
#include "srslte/dft/dft_precoding.h"
@ -103,6 +104,14 @@ SRSLTE_API int srslte_pusch_init(srslte_pusch_t *q,
SRSLTE_API void srslte_pusch_free(srslte_pusch_t *q);
SRSLTE_API int srslte_pusch_cfg(srslte_pusch_cfg_t *cfg,
srslte_cell_t cell,
srslte_dci_msg_t *dci_msg,
uint32_t n_rb_ho,
uint32_t N_srs,
uint32_t sf_idx,
uint32_t rvidx);
SRSLTE_API void srslte_pusch_set_hopping_cfg(srslte_pusch_t *q,
srslte_pusch_hopping_cfg_t *cfg);

@ -43,6 +43,7 @@
typedef struct SRSLTE_API {
srslte_cbsegm_t cb_segm;
srslte_ra_ul_grant_t grant;
srslte_ra_nbits_t nbits;
uint32_t rv;
uint32_t sf_idx;
srslte_cp_t cp;

@ -52,6 +52,15 @@ typedef struct SRSLTE_API {
int tbs;
} srslte_ra_mcs_t;
/* Structure that gives the number of encoded bits and RE for a UL/DL grant */
typedef struct {
uint32_t lstart;
uint32_t nof_symb;
uint32_t nof_bits;
uint32_t nof_re;
} srslte_ra_nbits_t;
typedef enum SRSLTE_API {
SRSLTE_RA_ALLOC_TYPE0 = 0,
SRSLTE_RA_ALLOC_TYPE1 = 1,
@ -86,18 +95,12 @@ typedef struct SRSLTE_API {
/**************************************************
* Structures used for Downlink Resource Allocation
**************************************************/
typedef struct SRSLTE_API {
bool prb_idx[2][SRSLTE_MAX_PRB];
uint32_t lstart;
uint32_t nof_re;
uint32_t nof_bits;
uint32_t nof_symb;
uint32_t nof_prb;
uint32_t Qm;
srslte_ra_mcs_t mcs;
@ -138,10 +141,6 @@ typedef struct SRSLTE_API {
uint32_t n_prb_tilde[2];
uint32_t L_prb;
uint32_t freq_hopping;
uint32_t lstart;
uint32_t nof_re;
uint32_t nof_bits;
uint32_t nof_symb;
uint32_t M_sc;
uint32_t M_sc_init;
uint32_t Qm;
@ -180,23 +179,31 @@ typedef struct SRSLTE_API {
**************************************************/
SRSLTE_API int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t* dci,
srslte_ra_dl_grant_t* grant,
srslte_cell_t cell,
uint32_t sf_idx,
uint32_t cfi,
bool crc_is_crnti);
SRSLTE_API int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t *dci,
uint32_t nof_prb,
bool crc_is_crnti,
srslte_ra_dl_grant_t *grant);
SRSLTE_API void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant,
uint32_t cfi,
srslte_cell_t cell,
uint32_t sf_idx,
srslte_ra_nbits_t *nbits);
SRSLTE_API void srslte_dl_dci_to_grant_nof_re(srslte_ra_dl_grant_t *grant,
SRSLTE_API uint32_t srslte_ra_dl_grant_nof_re(srslte_ra_dl_grant_t *grant,
srslte_cell_t cell,
uint32_t sf_idx,
uint32_t nof_ctrl_symbols);
SRSLTE_API int srslte_ra_ul_dci_to_grant(srslte_ra_ul_dci_t *dci,
srslte_ra_ul_grant_t *grant,
srslte_cell_t cell,
uint32_t nof_prb,
uint32_t n_rb_ho,
uint32_t N_srs);
srslte_ra_ul_grant_t *grant);
SRSLTE_API void srslte_ra_ul_grant_to_nbits(srslte_ra_ul_grant_t *grant,
srslte_cp_t cp,
uint32_t N_srs,
srslte_ra_nbits_t *nbits);
SRSLTE_API int srslte_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci,
srslte_ra_ul_grant_t *grant,

@ -97,6 +97,13 @@ SRSLTE_API int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q,
uint32_t sf_idx,
uint32_t *cfi);
SRSLTE_API int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q,
srslte_dci_msg_t *dci_msg,
uint32_t cfi,
uint32_t sf_idx,
uint16_t rnti,
uint32_t rvidx);
SRSLTE_API int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q,
srslte_dci_msg_t *dci_msg,
uint8_t *data,

@ -44,6 +44,7 @@
#include "srslte/dft/ofdm.h"
#include "srslte/ch_estimation/refsignal_ul.h"
#include "srslte/phch/pusch.h"
#include "srslte/phch/dci.h"
#include "srslte/phch/ra.h"
#include "srslte/sync/cfo.h"
#include "srslte/utils/vector.h"
@ -99,50 +100,44 @@ SRSLTE_API void srslte_ue_ul_set_cfg(srslte_ue_ul_t *q,
srslte_pucch_cfg_t *pucch_cfg,
srslte_pucch_sched_t *pucch_sched);
SRSLTE_API int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q,
srslte_dci_msg_t *dci_msg,
uint32_t n_rb_ho,
uint32_t N_srs,
uint32_t sf_idx,
uint32_t rvidx);
SRSLTE_API int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q,
srslte_uci_data_t uci_data,
uint32_t sf_idx,
cf_t *output_signal);
SRSLTE_API int srslte_ue_ul_pusch_encode(srslte_ue_ul_t *q,
srslte_ra_ul_grant_t *grant,
uint8_t *data,
uint32_t sf_idx,
uint32_t rv,
cf_t *output_signal);
SRSLTE_API int srslte_ue_ul_pusch_encode_rnti(srslte_ue_ul_t *q,
srslte_ra_ul_grant_t *grant,
uint8_t *data,
uint32_t sf_idx,
uint32_t rv,
uint16_t rnti,
cf_t *output_signal);
SRSLTE_API int srslte_ue_ul_pusch_uci_encode(srslte_ue_ul_t *q,
srslte_ra_ul_grant_t *grant,
uint8_t *data,
srslte_uci_data_t uci_data,
uint32_t sf_idx,
uint32_t rv,
cf_t *output_signal);
SRSLTE_API int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q,
srslte_ra_ul_grant_t *grant,
uint8_t *data,
srslte_uci_data_t uci_data,
uint32_t sf_idx,
uint32_t rv,
uint16_t rnti,
cf_t *output_signal);
SRSLTE_API int srslte_ue_ul_pusch_encode_cfg(srslte_ue_ul_t *q,
srslte_pusch_cfg_t *cfg,
uint8_t *data,
srslte_uci_data_t uci_data,
srslte_softbuffer_tx_t *softbuffer,
uint16_t rnti,
cf_t *output_signal);
SRSLTE_API int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q,
uint8_t *data,
srslte_uci_data_t uci_data,
srslte_softbuffer_tx_t *softbuffer,
uint16_t rnti,
cf_t *output_signal);
SRSLTE_API void srslte_ue_ul_reset(srslte_ue_ul_t *q);

@ -366,9 +366,17 @@ void cuhd_get_time(void *h, time_t *secs, double *frac_secs) {
}
int cuhd_send(void *h, void *data, uint32_t nsamples, bool blocking)
{
return cuhd_send2(h, data, nsamples, blocking, true, true);
}
int cuhd_send2(void *h, void *data, uint32_t nsamples, bool blocking, bool start_of_burst, bool end_of_burst)
{
cuhd_handler *handler = static_cast < cuhd_handler * >(h);
uhd::tx_metadata_t md;
md.has_time_spec = false;
md.start_of_burst = start_of_burst;
md.end_of_burst = end_of_burst;
if (blocking) {
int n = 0, p;
complex_t *data_c = (complex_t *) data;

@ -63,7 +63,7 @@ int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, srslte_cell_t cell) {
}
// FIXME: Use HARQ buffer limitation based on UE category
q->buff_size = cell.nof_prb * MAX_PDSCH_RE(cell.cp) * 6 * 10;
q->buff_size = cell.nof_prb * MAX_PDSCH_RE(cell.cp) * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM);
for (uint32_t i=0;i<q->max_cb;i++) {
q->buffer_f[i] = srslte_vec_malloc(sizeof(float) * q->buff_size);
if (!q->buffer_f[i]) {

@ -44,23 +44,20 @@
/* Unpacks a DCI message and configures the DL grant object
*/
int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti,
srslte_cell_t cell, uint32_t cfi, uint32_t sf_idx,
uint32_t nof_prb,
srslte_ra_dl_dci_t *dl_dci,
srslte_ra_dl_grant_t *grant)
{
int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (msg != NULL &&
grant != NULL &&
srslte_cell_isvalid(&cell) &&
cfi > 0 &&
cfi < 4)
grant != NULL)
{
ret = SRSLTE_ERROR;
srslte_dci_msg_type_t type;
if (srslte_dci_msg_get_type(msg, &type, cell.nof_prb, msg_rnti)) {
if (srslte_dci_msg_get_type(msg, &type, nof_prb, msg_rnti)) {
fprintf(stderr, "Can't get DCI message type\n");
return ret;
}
@ -77,15 +74,15 @@ int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti,
if (msg_rnti >= SRSLTE_CRNTI_START && msg_rnti <= SRSLTE_CRNTI_END) {
crc_is_crnti = true;
}
if (srslte_dci_msg_unpack_pdsch(msg, dl_dci, cell.nof_prb, crc_is_crnti)) {
if (srslte_dci_msg_unpack_pdsch(msg, dl_dci, nof_prb, crc_is_crnti)) {
fprintf(stderr, "Can't unpack DCI message\n");
return ret;
}
srslte_ra_dl_dci_to_grant(dl_dci, grant, cell, sf_idx, cfi, crc_is_crnti);
srslte_ra_dl_dci_to_grant(dl_dci, nof_prb, crc_is_crnti, grant);
if (SRSLTE_VERBOSE_ISINFO()) {
srslte_ra_pdsch_fprint(stdout, dl_dci, cell.nof_prb);
srslte_ra_pdsch_fprint(stdout, dl_dci, nof_prb);
srslte_ra_dl_grant_fprint(stdout, grant);
}
@ -102,7 +99,7 @@ int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, uint16_t msg_rnti,
/* Creates the UL PUSCH resource allocation grant from the random access respone message
*/
int srslte_dci_rar_to_ul_grant(srslte_dci_rar_grant_t *rar, srslte_cell_t cell,
int srslte_dci_rar_to_ul_grant(srslte_dci_rar_grant_t *rar, uint32_t nof_prb,
uint32_t n_rb_ho,
srslte_ra_ul_dci_t *ul_dci,
srslte_ra_ul_grant_t *grant)
@ -118,23 +115,23 @@ int srslte_dci_rar_to_ul_grant(srslte_dci_rar_grant_t *rar, srslte_cell_t cell,
uint32_t riv = rar->rba;
// Truncate resource block assignment
uint32_t b = 0;
if (cell.nof_prb <= 44) {
b = (uint32_t) (ceilf(log2((float) cell.nof_prb*(cell.nof_prb+1)/2)));
if (nof_prb <= 44) {
b = (uint32_t) (ceilf(log2((float) nof_prb*(nof_prb+1)/2)));
riv = riv & ((1<<(b+1))-1);
}
ul_dci->type2_alloc.riv = riv;
ul_dci->mcs_idx = rar->trunc_mcs;
srslte_ra_type2_from_riv(riv, &ul_dci->type2_alloc.L_crb, &ul_dci->type2_alloc.RB_start,
cell.nof_prb, cell.nof_prb);
nof_prb, nof_prb);
if (srslte_ra_ul_dci_to_grant(ul_dci, grant, cell, n_rb_ho, 0)) {
if (srslte_ra_ul_dci_to_grant(ul_dci, nof_prb, n_rb_ho, grant)) {
fprintf(stderr, "Error computing resource allocation\n");
return SRSLTE_ERROR;
}
if (SRSLTE_VERBOSE_ISINFO()) {
srslte_ra_pusch_fprint(stdout, ul_dci, cell.nof_prb);
srslte_ra_pusch_fprint(stdout, ul_dci, nof_prb);
srslte_ra_ul_grant_fprint(stdout, grant);
}
return SRSLTE_SUCCESS;
@ -163,15 +160,14 @@ void srslte_dci_rar_grant_fprint(FILE *stream, srslte_dci_rar_grant_t *rar) {
/* Creates the UL PUSCH resource allocation grant from a DCI format 0 message
*/
int srslte_dci_msg_to_ul_grant(srslte_dci_msg_t *msg, srslte_cell_t cell,
uint32_t N_srs, uint32_t n_rb_ho,
int srslte_dci_msg_to_ul_grant(srslte_dci_msg_t *msg, uint32_t nof_prb,
uint32_t n_rb_ho,
srslte_ra_ul_dci_t *ul_dci,
srslte_ra_ul_grant_t *grant)
{
int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (msg != NULL &&
srslte_cell_isvalid(&cell) &&
grant != NULL)
{
ret = SRSLTE_ERROR;
@ -179,17 +175,17 @@ int srslte_dci_msg_to_ul_grant(srslte_dci_msg_t *msg, srslte_cell_t cell,
bzero(ul_dci, sizeof(srslte_ra_ul_dci_t));
bzero(grant, sizeof(srslte_ra_ul_dci_t));
if (srslte_dci_msg_unpack_pusch(msg, ul_dci, cell.nof_prb)) {
if (srslte_dci_msg_unpack_pusch(msg, ul_dci, nof_prb)) {
return ret;
}
if (srslte_ra_ul_dci_to_grant(ul_dci, grant, cell, n_rb_ho, N_srs)) {
if (srslte_ra_ul_dci_to_grant(ul_dci, nof_prb, n_rb_ho, grant)) {
fprintf(stderr, "Error computing resource allocation\n");
return ret;
}
if (SRSLTE_VERBOSE_ISINFO()) {
srslte_ra_pusch_fprint(stdout, ul_dci, cell.nof_prb);
srslte_ra_pusch_fprint(stdout, ul_dci, nof_prb);
srslte_ra_ul_grant_fprint(stdout, grant);
}

@ -59,16 +59,13 @@ extern int indices_ptr;
#endif
int srslte_pdsch_cp(srslte_pdsch_t *q, cf_t *input, cf_t *output, srslte_ra_dl_grant_t *grant,
uint32_t nsubframe, bool put) {
int srslte_pdsch_cp(srslte_pdsch_t *q, cf_t *input, cf_t *output, srslte_ra_dl_grant_t *grant, uint32_t lstart_grant, uint32_t nsubframe, bool put)
{
uint32_t s, n, l, lp, lstart, lend, nof_refs;
bool is_pbch, is_sss;
cf_t *in_ptr = input, *out_ptr = output;
uint32_t offset = 0;
INFO("%s %d RE from %d PRB\n", put ? "Putting" : "Getting",
grant->nof_re, grant->nof_prb);
#ifdef DEBUG_IDX
indices_ptr = 0;
if (put) {
@ -91,7 +88,7 @@ int srslte_pdsch_cp(srslte_pdsch_t *q, cf_t *input, cf_t *output, srslte_ra_dl_g
// If this PRB is assigned
if (grant->prb_idx[s][n]) {
if (s == 0) {
lstart = grant->lstart;
lstart = lstart_grant;
} else {
lstart = 0;
}
@ -180,8 +177,9 @@ int srslte_pdsch_cp(srslte_pdsch_t *q, cf_t *input, cf_t *output, srslte_ra_dl_g
* 36.211 10.3 section 6.3.5
*/
int srslte_pdsch_put(srslte_pdsch_t *q, cf_t *symbols, cf_t *sf_symbols,
srslte_ra_dl_grant_t *grant, uint32_t subframe) {
return srslte_pdsch_cp(q, symbols, sf_symbols, grant, subframe, true);
srslte_ra_dl_grant_t *grant, uint32_t lstart, uint32_t subframe)
{
return srslte_pdsch_cp(q, symbols, sf_symbols, grant, lstart, subframe, true);
}
/**
@ -192,8 +190,9 @@ int srslte_pdsch_put(srslte_pdsch_t *q, cf_t *symbols, cf_t *sf_symbols,
* 36.211 10.3 section 6.3.5
*/
int srslte_pdsch_get(srslte_pdsch_t *q, cf_t *sf_symbols, cf_t *symbols,
srslte_ra_dl_grant_t *grant, uint32_t subframe) {
return srslte_pdsch_cp(q, sf_symbols, symbols, grant, subframe, false);
srslte_ra_dl_grant_t *grant, uint32_t lstart, uint32_t subframe)
{
return srslte_pdsch_cp(q, sf_symbols, symbols, grant, lstart, subframe, false);
}
/** Initializes the PDCCH transmitter and receiver */
@ -303,6 +302,36 @@ void srslte_pdsch_free(srslte_pdsch_t *q) {
}
/* Configures the structure srslte_pdsch_cfg_t from the DL DCI allocation dci_msg.
* If dci_msg is NULL, the grant is assumed to be already stored in cfg->grant
*/
int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx)
{
if (dci_msg) {
srslte_ra_dl_dci_t dl_dci;
if (srslte_dci_msg_to_dl_grant(dci_msg, rnti, cell.nof_prb, &dl_dci, &cfg->grant)) {
//fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n");
return SRSLTE_ERROR;
}
if (rnti == SRSLTE_SIRNTI) {
cfg->rv = rvidx;
} else {
cfg->rv = dl_dci.rv_idx;
}
} else {
cfg->rv = rvidx;
}
if (srslte_cbsegm(&cfg->cb_segm, cfg->grant.mcs.tbs)) {
fprintf(stderr, "Error computing Codeblock segmentation for TBS=%d\n", cfg->grant.mcs.tbs);
return SRSLTE_ERROR;
}
srslte_ra_dl_grant_to_nbits(&cfg->grant, cfi, cell, sf_idx, &cfg->nbits);
cfg->sf_idx = sf_idx;
return SRSLTE_SUCCESS;
}
/* Precalculate the PDSCH scramble sequences for a given RNTI. This function takes a while
* to execute, so shall be called once the final C-RNTI has been allocated for the session.
*/
@ -359,11 +388,11 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q,
{
INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
cfg->sf_idx, rnti, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs, cfg->grant.nof_re,
cfg->grant.nof_bits, cfg->rv);
cfg->sf_idx, rnti, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs, cfg->nbits.nof_re,
cfg->nbits.nof_bits, cfg->rv);
if (cfg->grant.mcs.tbs > cfg->grant.nof_bits) {
fprintf(stderr, "Invalid code rate %d/%d=%.2f\n", cfg->grant.mcs.tbs, cfg->grant.nof_bits, (float) cfg->grant.mcs.tbs / cfg->grant.nof_bits);
if (cfg->grant.mcs.tbs > cfg->nbits.nof_bits) {
fprintf(stderr, "Invalid code rate %d/%d=%.2f\n", cfg->grant.mcs.tbs, cfg->nbits.nof_bits, (float) cfg->grant.mcs.tbs / cfg->nbits.nof_bits);
return SRSLTE_ERROR_INVALID_INPUTS;
}
@ -374,17 +403,17 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q,
memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports));
/* extract symbols */
n = srslte_pdsch_get(q, sf_symbols, q->symbols[0], &cfg->grant, cfg->sf_idx);
if (n != cfg->grant.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n);
n = srslte_pdsch_get(q, sf_symbols, q->symbols[0], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
if (n != cfg->nbits.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
return SRSLTE_ERROR;
}
/* extract channel estimates */
for (i = 0; i < q->cell.nof_ports; i++) {
n = srslte_pdsch_get(q, ce[i], q->ce[i], &cfg->grant, cfg->sf_idx);
if (n != cfg->grant.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n);
n = srslte_pdsch_get(q, ce[i], q->ce[i], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
if (n != cfg->nbits.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
return SRSLTE_ERROR;
}
}
@ -393,12 +422,12 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q,
if (q->cell.nof_ports == 1) {
/* no need for layer demapping */
srslte_predecoding_single(&q->precoding, q->symbols[0], q->ce[0], q->d,
cfg->grant.nof_re, noise_estimate);
cfg->nbits.nof_re, noise_estimate);
} else {
srslte_predecoding_diversity(&q->precoding, q->symbols[0], q->ce, x, q->cell.nof_ports,
cfg->grant.nof_re, noise_estimate);
cfg->nbits.nof_re, noise_estimate);
srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports,
cfg->grant.nof_re / q->cell.nof_ports);
cfg->nbits.nof_re / q->cell.nof_ports);
}
/* demodulate symbols
@ -407,18 +436,18 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q,
*/
srslte_demod_soft_sigma_set(&q->demod, sqrt(0.5));
srslte_demod_soft_table_set(&q->demod, &q->mod[cfg->grant.mcs.mod]);
srslte_demod_soft_demodulate(&q->demod, q->d, q->e, cfg->grant.nof_re);
srslte_demod_soft_demodulate(&q->demod, q->d, q->e, cfg->nbits.nof_re);
/* descramble */
if (rnti != q->rnti) {
srslte_sequence_t seq;
if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->grant.nof_bits)) {
if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
return SRSLTE_ERROR;
}
srslte_scrambling_f_offset(&seq, q->e, 0, cfg->grant.nof_bits);
srslte_scrambling_f_offset(&seq, q->e, 0, cfg->nbits.nof_bits);
srslte_sequence_free(&seq);
} else {
srslte_scrambling_f_offset(&q->seq[cfg->sf_idx], q->e, 0, cfg->grant.nof_bits);
srslte_scrambling_f_offset(&q->seq[cfg->sf_idx], q->e, 0, cfg->nbits.nof_bits);
}
return srslte_dlsch_decode(&q->dl_sch, cfg, softbuffer, q->e, data);
@ -473,21 +502,21 @@ int srslte_pdsch_encode_rnti(srslte_pdsch_t *q,
return SRSLTE_ERROR_INVALID_INPUTS;
}
if (cfg->grant.mcs.tbs > cfg->grant.nof_bits) {
fprintf(stderr, "Invalid code rate %d/%d=%.2f\n", cfg->grant.mcs.tbs, cfg->grant.nof_bits, (float) cfg->grant.mcs.tbs / cfg->grant.nof_bits);
if (cfg->grant.mcs.tbs > cfg->nbits.nof_bits) {
fprintf(stderr, "Invalid code rate %d/%d=%.2f\n", cfg->grant.mcs.tbs, cfg->nbits.nof_bits, (float) cfg->grant.mcs.tbs / cfg->nbits.nof_bits);
return SRSLTE_ERROR_INVALID_INPUTS;
}
if (cfg->grant.nof_re > q->max_re) {
if (cfg->nbits.nof_re > q->max_re) {
fprintf(stderr,
"Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n",
cfg->grant.nof_re, q->max_re, q->cell.nof_prb);
cfg->nbits.nof_re, q->max_re, q->cell.nof_prb);
return SRSLTE_ERROR_INVALID_INPUTS;
}
INFO("Encoding PDSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
cfg->sf_idx, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs,
cfg->grant.nof_re, cfg->grant.nof_bits, cfg->rv);
cfg->nbits.nof_re, cfg->nbits.nof_bits, cfg->rv);
/* number of layers equals number of ports */
for (i = 0; i < q->cell.nof_ports; i++) {
@ -502,29 +531,29 @@ int srslte_pdsch_encode_rnti(srslte_pdsch_t *q,
if (rnti != q->rnti) {
srslte_sequence_t seq;
if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->grant.nof_bits)) {
if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
return SRSLTE_ERROR;
}
srslte_scrambling_b_offset(&seq, (uint8_t*) q->e, 0, cfg->grant.nof_bits);
srslte_scrambling_b_offset(&seq, (uint8_t*) q->e, 0, cfg->nbits.nof_bits);
srslte_sequence_free(&seq);
} else {
srslte_scrambling_b_offset(&q->seq[cfg->sf_idx], (uint8_t*) q->e, 0, cfg->grant.nof_bits);
srslte_scrambling_b_offset(&q->seq[cfg->sf_idx], (uint8_t*) q->e, 0, cfg->nbits.nof_bits);
}
srslte_mod_modulate(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->e, q->d, cfg->grant.nof_bits);
srslte_mod_modulate(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->e, q->d, cfg->nbits.nof_bits);
/* TODO: only diversity supported */
if (q->cell.nof_ports > 1) {
srslte_layermap_diversity(q->d, x, q->cell.nof_ports, cfg->grant.nof_re);
srslte_layermap_diversity(q->d, x, q->cell.nof_ports, cfg->nbits.nof_re);
srslte_precoding_diversity(&q->precoding, x, q->symbols, q->cell.nof_ports,
cfg->grant.nof_re / q->cell.nof_ports);
cfg->nbits.nof_re / q->cell.nof_ports);
} else {
memcpy(q->symbols[0], q->d, cfg->grant.nof_re * sizeof(cf_t));
memcpy(q->symbols[0], q->d, cfg->nbits.nof_re * sizeof(cf_t));
}
/* mapping to resource elements */
for (i = 0; i < q->cell.nof_ports; i++) {
srslte_pdsch_put(q, q->symbols[i], sf_symbols[i], &cfg->grant, cfg->sf_idx);
srslte_pdsch_put(q, q->symbols[i], sf_symbols[i], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
}
ret = SRSLTE_SUCCESS;
}

@ -288,6 +288,30 @@ void srslte_pusch_set_hopping_cfg(srslte_pusch_t *q, srslte_pusch_hopping_cfg_t
}
}
/* Configures the structure srslte_pusch_cfg_t from the UL DCI allocation dci_msg.
* If dci_msg is NULL, the grant is assumed to be already stored in cfg->grant
*/
int srslte_pusch_cfg(srslte_pusch_cfg_t *cfg, srslte_cell_t cell, srslte_dci_msg_t *dci_msg, uint32_t n_rb_ho, uint32_t N_srs, uint32_t sf_idx, uint32_t rvidx)
{
if (dci_msg) {
srslte_ra_ul_dci_t ul_dci;
if (srslte_dci_msg_to_ul_grant(dci_msg, cell.nof_prb, n_rb_ho, &ul_dci, &cfg->grant)) {
fprintf(stderr, "Error unpacking UL grant from DCI message\n");
return SRSLTE_ERROR;
}
}
if (srslte_cbsegm(&cfg->cb_segm, cfg->grant.mcs.tbs)) {
fprintf(stderr, "Error computing Codeblock segmentation for TBS=%d\n", cfg->grant.mcs.tbs);
return SRSLTE_ERROR;
}
srslte_ra_ul_grant_to_nbits(&cfg->grant, cell.cp, N_srs, &cfg->nbits);
cfg->sf_idx = sf_idx;
cfg->rv = rvidx;
cfg->cp = cell.cp;
return SRSLTE_SUCCESS;
}
/* Precalculate the PUSCH scramble sequences for a given RNTI. This function takes a while
* to execute, so shall be called once the final C-RNTI has been allocated for the session.
* For the connection procedure, use srslte_pusch_encode_rnti() or srslte_pusch_decode_rnti() functions */
@ -325,26 +349,26 @@ int srslte_pusch_decode(srslte_pusch_t *q,
if (q->rnti_is_set) {
INFO("Decoding PUSCH SF: %d, Mod %s, NofBits: %d, NofRE: %d, NofSymbols=%d, NofBitsE: %d, rv_idx: %d\n",
cfg->sf_idx, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs,
cfg->grant.nof_re, cfg->grant.nof_symb, cfg->grant.nof_bits, cfg->rv);
cfg->nbits.nof_re, cfg->nbits.nof_symb, cfg->nbits.nof_bits, cfg->rv);
/* extract symbols */
n = pusch_get(q, &cfg->grant, cfg->sf_idx, sf_symbols, q->d);
if (n != cfg->grant.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n);
if (n != cfg->nbits.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
return SRSLTE_ERROR;
}
/* extract channel estimates */
n = pusch_get(q, &cfg->grant, cfg->sf_idx, ce, q->ce);
if (n != cfg->grant.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n);
if (n != cfg->nbits.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
return SRSLTE_ERROR;
}
srslte_predecoding_single(&q->equalizer, q->d, q->ce, q->z,
cfg->grant.nof_re, noise_estimate);
cfg->nbits.nof_re, noise_estimate);
srslte_dft_predecoding(&q->dft_precoding, q->z, q->d, cfg->grant.L_prb, cfg->grant.nof_symb);
srslte_dft_predecoding(&q->dft_precoding, q->z, q->d, cfg->grant.L_prb, cfg->nbits.nof_symb);
/* demodulate symbols
* The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
@ -352,10 +376,10 @@ int srslte_pusch_decode(srslte_pusch_t *q,
*/
srslte_demod_soft_sigma_set(&q->demod, sqrt(0.5));
srslte_demod_soft_table_set(&q->demod, &q->mod[cfg->grant.mcs.mod]);
srslte_demod_soft_demodulate(&q->demod, q->d, q->q, cfg->grant.nof_re);
srslte_demod_soft_demodulate(&q->demod, q->d, q->q, cfg->nbits.nof_re);
/* descramble */
srslte_scrambling_f_offset(&q->seq[cfg->sf_idx], q->q, 0, cfg->grant.nof_bits);
srslte_scrambling_f_offset(&q->seq[cfg->sf_idx], q->q, 0, cfg->nbits.nof_bits);
return srslte_ulsch_decode(&q->dl_sch, cfg, softbuffer, q->q, data);
} else {
@ -412,22 +436,22 @@ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srs
if (q != NULL &&
cfg != NULL)
{
if (cfg->grant.mcs.tbs > cfg->grant.nof_bits) {
fprintf(stderr, "Invalid code rate %.2f\n", (float) cfg->grant.mcs.tbs / cfg->grant.nof_bits);
if (cfg->grant.mcs.tbs > cfg->nbits.nof_bits) {
fprintf(stderr, "Invalid code rate %.2f\n", (float) cfg->grant.mcs.tbs / cfg->nbits.nof_bits);
return SRSLTE_ERROR_INVALID_INPUTS;
}
if (cfg->grant.nof_re > q->max_re) {
if (cfg->nbits.nof_re > q->max_re) {
fprintf(stderr, "Error too many RE per subframe (%d). PUSCH configured for %d RE (%d PRB)\n",
cfg->grant.nof_re, q->max_re, q->cell.nof_prb);
cfg->nbits.nof_re, q->max_re, q->cell.nof_prb);
return SRSLTE_ERROR_INVALID_INPUTS;
}
INFO("Encoding PUSCH SF: %d, Mod %s, RNTI: %d, TBS: %d, NofRE: %d, NofSymbols=%d, NofBitsE: %d, rv_idx: %d\n",
cfg->sf_idx, srslte_mod_string(cfg->grant.mcs.mod), rnti,
cfg->grant.mcs.tbs, cfg->grant.nof_re, cfg->grant.nof_symb, cfg->grant.nof_bits, cfg->rv);
cfg->grant.mcs.tbs, cfg->nbits.nof_re, cfg->nbits.nof_symb, cfg->nbits.nof_bits, cfg->rv);
bzero(q->q, cfg->grant.nof_bits);
bzero(q->q, cfg->nbits.nof_bits);
if (srslte_ulsch_uci_encode(&q->dl_sch, cfg, softbuffer, data, uci_data, q->g, q->q)) {
fprintf(stderr, "Error encoding TB\n");
return SRSLTE_ERROR;
@ -435,18 +459,18 @@ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srs
if (rnti != q->rnti) {
srslte_sequence_t seq;
if (srslte_sequence_pusch(&seq, rnti, 2 * cfg->sf_idx, q->cell.id, cfg->grant.nof_bits)) {
if (srslte_sequence_pusch(&seq, rnti, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
return SRSLTE_ERROR;
}
srslte_scrambling_b_offset_pusch(&seq, (uint8_t*) q->q, 0, cfg->grant.nof_bits);
srslte_scrambling_b_offset_pusch(&seq, (uint8_t*) q->q, 0, cfg->nbits.nof_bits);
srslte_sequence_free(&seq);
} else {
srslte_scrambling_b_offset_pusch(&q->seq[cfg->sf_idx], (uint8_t*) q->q, 0, cfg->grant.nof_bits);
srslte_scrambling_b_offset_pusch(&q->seq[cfg->sf_idx], (uint8_t*) q->q, 0, cfg->nbits.nof_bits);
}
srslte_mod_modulate(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->q, q->d, cfg->grant.nof_bits);
srslte_mod_modulate(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->q, q->d, cfg->nbits.nof_bits);
srslte_dft_precoding(&q->dft_precoding, q->d, q->z, cfg->grant.L_prb, cfg->grant.nof_symb);
srslte_dft_precoding(&q->dft_precoding, q->d, q->z, cfg->grant.L_prb, cfg->nbits.nof_symb);
/* mapping to resource elements */
pusch_put(q, &cfg->grant, cfg->sf_idx, q->z, sf_symbols);

@ -108,8 +108,8 @@ uint32_t ra_re_x_prb(uint32_t subframe, uint32_t slot, uint32_t prb_idx, uint32_
return re;
}
int srslte_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *grant,
uint32_t n_rb_ho, uint32_t nof_prb) {
int srslte_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *grant, uint32_t n_rb_ho, uint32_t nof_prb)
{
bzero(grant, sizeof(srslte_ra_ul_grant_t));
grant->L_prb = dci->type2_alloc.L_crb;
uint32_t n_prb_1 = dci->type2_alloc.RB_start;
@ -205,25 +205,27 @@ static int ul_dci_to_grant_mcs(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *gr
}
}
void srslte_ra_ul_grant_to_nbits(srslte_ra_ul_grant_t *grant, srslte_cp_t cp, uint32_t N_srs, srslte_ra_nbits_t *nbits)
{
nbits->nof_symb = 2*(SRSLTE_CP_NSYMB(cp)-1) - N_srs;
nbits->nof_re = nbits->nof_symb*grant->M_sc;
nbits->nof_bits = nbits->nof_re * grant->Qm;
}
/** Compute PRB allocation for Uplink as defined in 8.1 and 8.4 of 36.213 */
int srslte_ra_ul_dci_to_grant(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *grant, srslte_cell_t cell,
uint32_t n_rb_ho, uint32_t N_srs)
int srslte_ra_ul_dci_to_grant(srslte_ra_ul_dci_t *dci, uint32_t nof_prb, uint32_t n_rb_ho, srslte_ra_ul_grant_t *grant)
{
// Compute PRB allocation
if (!srslte_ul_dci_to_grant_prb_allocation(dci, grant, n_rb_ho, cell.nof_prb)) {
if (!srslte_ul_dci_to_grant_prb_allocation(dci, grant, n_rb_ho, nof_prb)) {
// Compute MCS
if (!ul_dci_to_grant_mcs(dci, grant)) {
// Fill rest of grant structure
grant->lstart = 0;
grant->nof_symb = 2*(SRSLTE_CP_NSYMB(cell.cp)-1) - N_srs;
grant->M_sc = grant->L_prb*SRSLTE_NRE;
grant->M_sc_init = grant->M_sc; // FIXME: What should M_sc_init be?
grant->nof_re = grant->nof_symb*grant->M_sc;
grant->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod);
grant->nof_bits = grant->nof_re * grant->Qm;
} else {
fprintf(stderr, "Error computing MCS\n");
return SRSLTE_ERROR;
@ -236,21 +238,22 @@ int srslte_ra_ul_dci_to_grant(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *gra
}
/* Computes the number of RE for each PRB in the prb_dist structure */
void srslte_dl_dci_to_grant_nof_re(srslte_ra_dl_grant_t *grant, srslte_cell_t cell,
uint32_t sf_idx, uint32_t nof_ctrl_symbols)
uint32_t srslte_ra_dl_grant_nof_re(srslte_ra_dl_grant_t *grant, srslte_cell_t cell,
uint32_t sf_idx, uint32_t nof_ctrl_symbols)
{
uint32_t j, s;
// Compute number of RE per PRB
grant->nof_re = 0;
uint32_t nof_re = 0;
for (s = 0; s < 2; s++) {
for (j = 0; j < cell.nof_prb; j++) {
if (grant->prb_idx[s][j]) {
grant->nof_re += ra_re_x_prb(sf_idx, s, j,
nof_re += ra_re_x_prb(sf_idx, s, j,
cell.nof_prb, cell.nof_ports, nof_ctrl_symbols, cell.cp);
}
}
}
return nof_re;
}
@ -418,21 +421,24 @@ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *gr
}
}
void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant, uint32_t cfi, srslte_cell_t cell, uint32_t sf_idx, srslte_ra_nbits_t *nbits)
{
// Compute number of RE
nbits->nof_re = srslte_ra_dl_grant_nof_re(grant, cell, sf_idx, cell.nof_prb<10?(cfi+1):cfi);
nbits->lstart = cell.nof_prb<10?(cfi+1):cfi;
nbits->nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-nbits->lstart;
nbits->nof_bits = nbits->nof_re * grant->Qm;
}
/** Obtains a DL grant from a DCI grant for PDSCH */
int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *grant, srslte_cell_t cell,
uint32_t sf_idx, uint32_t cfi, bool crc_is_crnti)
int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t *dci, uint32_t nof_prb, bool crc_is_crnti, srslte_ra_dl_grant_t *grant)
{
// Compute PRB allocation
if (!dl_dci_to_grant_prb_allocation(dci, grant, cell.nof_prb)) {
// Compute number of RE
srslte_dl_dci_to_grant_nof_re(grant, cell, sf_idx, cell.nof_prb<10?(cfi+1):cfi);
if (!dl_dci_to_grant_prb_allocation(dci, grant, nof_prb)) {
// Compute MCS
if (!dl_dci_to_grant_mcs(dci, grant, crc_is_crnti)) {
// Fill rest of grant structure
grant->lstart = cell.nof_prb<10?(cfi+1):cfi;
grant->nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-grant->lstart;
grant->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod);
grant->nof_bits = grant->nof_re * grant->Qm;
} else {
return SRSLTE_ERROR;
}

@ -448,7 +448,7 @@ int srslte_dlsch_decode(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuf
{
return decode_tb(q,
softbuffer, &cfg->cb_segm,
cfg->grant.Qm, cfg->rv, cfg->grant.nof_bits,
cfg->grant.Qm, cfg->rv, cfg->nbits.nof_bits,
e_bits, data);
}
@ -457,7 +457,7 @@ int srslte_dlsch_encode(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuf
{
return encode_tb(q,
softbuffer, &cfg->cb_segm,
cfg->grant.Qm, cfg->rv, cfg->grant.nof_bits,
cfg->grant.Qm, cfg->rv, cfg->nbits.nof_bits,
data, e_bits);
}
@ -466,7 +466,7 @@ int srslte_ulsch_decode(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuf
{
return decode_tb(q,
softbuffer, &cfg->cb_segm,
cfg->grant.Qm, cfg->rv, cfg->grant.nof_bits,
cfg->grant.Qm, cfg->rv, cfg->nbits.nof_bits,
e_bits, data);
}
@ -514,7 +514,7 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q,
uint32_t Q_prime_ack = 0;
uint32_t Q_prime_ri = 0;
uint32_t nb_q = cfg->grant.nof_bits;
uint32_t nb_q = cfg->nbits.nof_bits;
uint32_t Qm = cfg->grant.Qm;
bzero(q_bits, sizeof(uint8_t) * nb_q);
@ -558,7 +558,7 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q,
}
// Interleave UL-SCH (and RI and CQI)
ulsch_interleave(g_bits, Qm, nb_q/Qm, cfg->grant.nof_symb, q_bits);
ulsch_interleave(g_bits, Qm, nb_q/Qm, cfg->nbits.nof_symb, q_bits);
// Encode (and interleave) ACK
if (uci_data.uci_ack_len > 0) {

@ -125,10 +125,10 @@ static uint32_t Q_prime_cqi(srslte_pusch_cfg_t *cfg,
uint32_t x = 999999;
if (K > 0) {
x = (uint32_t) ceilf((float) (O+L)*cfg->grant.M_sc_init*cfg->grant.nof_symb*beta/K);
x = (uint32_t) ceilf((float) (O+L)*cfg->grant.M_sc_init*cfg->nbits.nof_symb*beta/K);
}
Q_prime = SRSLTE_MIN(x, cfg->grant.M_sc * cfg->grant.nof_symb - Q_prime_ri);
Q_prime = SRSLTE_MIN(x, cfg->grant.M_sc * cfg->nbits.nof_symb - Q_prime_ri);
return Q_prime;
}
@ -310,7 +310,7 @@ static uint32_t Q_prime_ri_ack(srslte_pusch_cfg_t *cfg,
}
}
uint32_t x = (uint32_t) ceilf((float) O*cfg->grant.M_sc_init*cfg->grant.nof_symb*beta/K);
uint32_t x = (uint32_t) ceilf((float) O*cfg->grant.M_sc_init*cfg->nbits.nof_symb*beta/K);
uint32_t Q_prime = SRSLTE_MIN(x, 4*cfg->grant.M_sc);
@ -344,7 +344,7 @@ int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg,
encode_ri_ack(data, q_encoded_bits, cfg->grant.Qm);
for (uint32_t i=0;i<Qprime;i++) {
uci_ulsch_interleave_ack(q_encoded_bits, i, cfg->grant.Qm, H_prime_total, cfg->grant.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, q_bits);
}
return (int) Qprime;
@ -369,7 +369,7 @@ int srslte_uci_encode_ri(srslte_pusch_cfg_t *cfg,
encode_ri_ack(data, q_encoded_bits, cfg->grant.Qm);
for (uint32_t i=0;i<Qprime;i++) {
uci_ulsch_interleave_ri(q_encoded_bits, i, cfg->grant.Qm, H_prime_total, cfg->grant.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, q_bits);
}
return (int) Qprime;

@ -96,8 +96,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return;
}
cfg.grant.nof_bits = mxGetScalar(OUTLEN);
uint8_t *e_bits = srslte_vec_malloc(cfg.grant.nof_bits * sizeof(uint8_t));
cfg.nbits.nof_bits = mxGetScalar(OUTLEN);
uint8_t *e_bits = srslte_vec_malloc(cfg.nbits.nof_bits * sizeof(uint8_t));
if (!e_bits) {
return;
}
@ -111,7 +111,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
}
if (nlhs >= 1) {
mexutils_write_uint8(e_bits, &plhs[0], cfg.grant.nof_bits, 1);
mexutils_write_uint8(e_bits, &plhs[0], cfg.nbits.nof_bits, 1);
}
srslte_sch_free(&dlsch);

@ -45,14 +45,12 @@ srslte_cell_t cell = {
uint32_t cfi = 2;
uint32_t tbs = 0;
uint32_t nof_tbs = 0;
uint32_t subframe = 1;
srslte_mod_t modulation = SRSLTE_MOD_BPSK;
uint32_t rv_idx = 0;
void usage(char *prog) {
printf("Usage: %s [Lcpsrnfvmt] -l TBS \n", prog);
printf("\t-L number of consequent TBS [Default 0]\n");
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);
@ -65,7 +63,7 @@ void usage(char *prog) {
void parse_args(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "lLcpnfvmtsr")) != -1) {
while ((opt = getopt(argc, argv, "lcpnfvmtsr")) != -1) {
switch(opt) {
case 'm':
switch(atoi(argv[optind])) {
@ -96,9 +94,6 @@ void parse_args(int argc, char **argv) {
case 'l':
tbs = atoi(argv[optind]);
break;
case 'L':
nof_tbs = atoi(argv[optind]);
break;
case 'p':
cell.nof_ports = atoi(argv[optind]);
break;
@ -142,22 +137,20 @@ int main(int argc, char **argv) {
bzero(ce, sizeof(cf_t*)*SRSLTE_MAX_PORTS);
bzero(slot_symbols, sizeof(cf_t*)*SRSLTE_MAX_PORTS);
pdsch_cfg.grant.nof_re = 2 * SRSLTE_CP_NORM_NSYMB * cell.nof_prb * SRSLTE_NRE;
pdsch_cfg.grant.mcs.tbs = tbs;
pdsch_cfg.grant.mcs.mod = modulation;
pdsch_cfg.grant.nof_prb = cell.nof_prb;
pdsch_cfg.grant.Qm = srslte_mod_bits_x_symbol(pdsch_cfg.grant.mcs.mod);
pdsch_cfg.grant.nof_prb = cell.nof_prb; // Allocate all PRB
for (i=0;i<pdsch_cfg.grant.nof_prb;i++) {
pdsch_cfg.grant.prb_idx[0][i] = true;
}
memcpy(&pdsch_cfg.grant.prb_idx[1], &pdsch_cfg.grant.prb_idx[0], SRSLTE_MAX_PRB * sizeof(bool));
srslte_dl_dci_to_grant_nof_re(&pdsch_cfg.grant, cell, pdsch_cfg.sf_idx, cell.nof_prb<10?(cfi+1):cfi);
// Fill rest of grant structure
pdsch_cfg.grant.lstart = cell.nof_prb<10?(cfi+1):cfi;
pdsch_cfg.grant.nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-pdsch_cfg.grant.lstart;
pdsch_cfg.grant.Qm = srslte_mod_bits_x_symbol(pdsch_cfg.grant.mcs.mod);
pdsch_cfg.grant.nof_bits = pdsch_cfg.grant.nof_re * pdsch_cfg.grant.Qm;
/* Configure PDSCH */
if (srslte_pdsch_cfg(&pdsch_cfg, cell, NULL, cfi, subframe, 1234, 0)) {
fprintf(stderr, "Error configuring PDSCH\n");
exit(-1);
}
/* init memory */
for (i=0;i<cell.nof_ports;i++) {
@ -166,7 +159,7 @@ int main(int argc, char **argv) {
perror("malloc");
goto quit;
}
for (j=0;j<pdsch_cfg.grant.nof_re;j++) {
for (j=0;j<SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);j++) {
ce[i][j] = 1;
}
slot_symbols[i] = calloc(sizeof(cf_t) , SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp));
@ -176,7 +169,7 @@ int main(int argc, char **argv) {
}
}
data = malloc(sizeof(uint8_t) * (tbs+nof_tbs));
data = malloc(sizeof(uint8_t) * tbs);
if (!data) {
perror("malloc");
goto quit;
@ -199,46 +192,43 @@ int main(int argc, char **argv) {
goto quit;
}
for (pdsch_cfg.grant.mcs.tbs = tbs;pdsch_cfg.grant.mcs.tbs<=tbs+nof_tbs;pdsch_cfg.grant.mcs.tbs++) {
if (SRSLTE_VERBOSE_ISNONE()) {
printf("Decoding TBS: %d\r",pdsch_cfg.grant.mcs.tbs);
}
for (i=0;i<pdsch_cfg.grant.mcs.tbs;i++) {
data[i] = rand()%2;
}
if (SRSLTE_VERBOSE_ISNONE()) {
printf("Decoding TBS: %d\r",pdsch_cfg.grant.mcs.tbs);
}
for (i=0;i<pdsch_cfg.grant.mcs.tbs;i++) {
data[i] = rand()%2;
}
for (rv=0;rv<=rv_idx;rv++) {
srslte_cbsegm(&pdsch_cfg.cb_segm, pdsch_cfg.grant.mcs.tbs);
for (rv=0;rv<=rv_idx;rv++) {
if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer_tx, data, slot_symbols)) {
fprintf(stderr, "Error encoding PDSCH\n");
goto quit;
}
pdsch_cfg.rv = rv;
/* combine outputs */
for (i=0;i<cell.nof_ports;i++) {
for (j=0;j<SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);j++) {
if (i > 0) {
slot_symbols[0][j] += slot_symbols[i][j];
}
ce[i][j] = 1;
}
}
if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer_tx, data, slot_symbols)) {
fprintf(stderr, "Error encoding PDSCH\n");
goto quit;
}
gettimeofday(&t[1], NULL);
int r = srslte_pdsch_decode(&pdsch, &pdsch_cfg, &softbuffer_rx, slot_symbols[0], ce, 0, data);
gettimeofday(&t[2], NULL);
get_time_interval(t);
if (r) {
printf("Error decoding TBS: %d\n", pdsch_cfg.grant.mcs.tbs);
ret = -1;
goto quit;
} else {
if (nof_tbs == 0) {
printf("DECODED OK in %d:%d (%.2f Mbps)\n", (int) t[0].tv_sec, (int) t[0].tv_usec, (float) pdsch_cfg.grant.mcs.tbs/t[0].tv_usec);
/* combine outputs */
for (i=0;i<cell.nof_ports;i++) {
for (j=0;j<SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);j++) {
if (i > 0) {
slot_symbols[0][j] += slot_symbols[i][j];
}
ce[i][j] = 1;
}
}
gettimeofday(&t[1], NULL);
int r = srslte_pdsch_decode(&pdsch, &pdsch_cfg, &softbuffer_rx, slot_symbols[0], ce, 0, data);
gettimeofday(&t[2], NULL);
get_time_interval(t);
if (r) {
printf("Error decoding TBS: %d\n", pdsch_cfg.grant.mcs.tbs);
ret = -1;
goto quit;
} else {
printf("DECODED OK in %d:%d (%.2f Mbps)\n", (int) t[0].tv_sec, (int) t[0].tv_usec, (float) pdsch_cfg.grant.mcs.tbs/t[0].tv_usec);
}
}
ret = 0;
quit:

@ -163,13 +163,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
free(prbset);
srslte_dl_dci_to_grant_nof_re(&cfg.grant, cell, cfg.sf_idx, cell.nof_prb<10?(cfi+1):cfi);
// Fill rest of grant structure
cfg.grant.lstart = cell.nof_prb<10?(cfi+1):cfi;
cfg.grant.nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-cfg.grant.lstart;
/* Configure rest of pdsch_cfg parameters */
cfg.grant.Qm = srslte_mod_bits_x_symbol(cfg.grant.mcs.mod);
cfg.grant.nof_bits = cfg.grant.nof_re * cfg.grant.Qm;
if (srslte_pdsch_cfg(&cfg, cell, NULL, cfi, cfg.sf_idx, (uint16_t) (rnti32 & 0xffff), cfg.rv)) {
fprintf(stderr, "Error configuring PDSCH\n");
exit(-1);
}
/** Allocate input buffers */
if (mexutils_read_cf(INPUT, &input_signal) < 0) {
@ -222,13 +221,13 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
mexutils_write_uint8(data, &plhs[1], cfg.grant.mcs.tbs, 1);
}
if (nlhs >= 3) {
mexutils_write_cf(pdsch.symbols[0], &plhs[2], cfg.grant.nof_re, 1);
mexutils_write_cf(pdsch.symbols[0], &plhs[2], cfg.nbits.nof_re, 1);
}
if (nlhs >= 4) {
mexutils_write_cf(pdsch.d, &plhs[3], cfg.grant.nof_re, 1);
mexutils_write_cf(pdsch.d, &plhs[3], cfg.nbits.nof_re, 1);
}
if (nlhs >= 5) {
mexutils_write_f(pdsch.e, &plhs[4], cfg.grant.nof_bits, 1);
mexutils_write_f(pdsch.e, &plhs[4], cfg.nbits.nof_bits, 1);
}
srslte_chest_dl_free(&chest);

@ -114,13 +114,13 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
cfg.grant.L_prb = mexutils_read_f(p, &prbset);
cfg.grant.n_prb[0] = prbset[0];
cfg.grant.n_prb[1] = prbset[0];
cfg.grant.lstart = 0;
cfg.grant.nof_symb = 2*(SRSLTE_CP_NSYMB(cell.cp)-1) - N_srs;
cfg.grant.M_sc = cfg.grant.L_prb*SRSLTE_NRE;
cfg.grant.M_sc_init = cfg.grant.M_sc; // FIXME: What should M_sc_init be?
cfg.grant.nof_re = cfg.grant.nof_symb*cfg.grant.M_sc;
cfg.grant.Qm = srslte_mod_bits_x_symbol(cfg.grant.mcs.mod);
cfg.grant.nof_bits = cfg.grant.nof_re * cfg.grant.Qm;
if (srslte_pusch_cfg(&cfg, cell, NULL, 0, 0, cfg.sf_idx, cfg.rv)) {
fprintf(stderr, "Error configuring PDSCH\n");
exit(-1);
}
free(prbset);
@ -185,7 +185,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
mexPrintf("I_cqi: %d, I_ri: %d, I_ack=%d\n", uci_data.I_offset_cqi, uci_data.I_offset_ri, uci_data.I_offset_ack);
mexPrintf("NofRE: %d, NofBits: %d, TBS: %d, N_srs=%d\n", cfg.grant.nof_re, cfg.grant.nof_bits, cfg.grant.mcs.tbs, N_srs);
mexPrintf("NofRE: %d, NofBits: %d, TBS: %d, N_srs=%d\n", cfg.nbits.nof_re, cfg.nbits.nof_bits, cfg.grant.mcs.tbs, N_srs);
int r = srslte_pusch_uci_encode(&pusch, &cfg, &softbuffer, trblkin, uci_data, sf_symbols);
if (r < 0) {
mexErrMsgTxt("Error encoding PUSCH\n");
@ -221,7 +221,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
mexutils_write_cf(sf_symbols, &plhs[1], nof_re, 1);
}
if (nlhs >= 3) {
mexutils_write_cf(pusch.z, &plhs[2], cfg.grant.nof_re, 1);
mexutils_write_cf(pusch.z, &plhs[2], cfg.nbits.nof_re, 1);
}
srslte_pusch_free(&pusch);
free(trblkin);

@ -150,18 +150,16 @@ int main(int argc, char **argv) {
} else {
srslte_ra_type2_from_riv((uint32_t) riv, &dci.type2_alloc.L_crb, &dci.type2_alloc.RB_start, cell.nof_prb, cell.nof_prb);
}
/* Configure PUSCH */
srslte_ul_dci_to_grant_prb_allocation(&dci, &cfg.grant, 0, cell.nof_prb);
cfg.grant.mcs.tbs = tbs;
cfg.grant.mcs.mod = modulation;
// Compute PRB allocation
if (!srslte_ul_dci_to_grant_prb_allocation(&dci, &cfg.grant, 0, cell.nof_prb)) {
cfg.grant.lstart = 0;
cfg.grant.nof_symb = 2*(SRSLTE_CP_NSYMB(cell.cp)-1);
cfg.grant.M_sc = cfg.grant.L_prb*SRSLTE_NRE;
cfg.grant.M_sc_init = cfg.grant.M_sc; // FIXME: What should M_sc_init be?
cfg.grant.nof_re = cfg.grant.nof_symb*cfg.grant.M_sc;
cfg.grant.Qm = srslte_mod_bits_x_symbol(cfg.grant.mcs.mod);
cfg.grant.nof_bits = cfg.grant.nof_re * cfg.grant.Qm;
cfg.grant.Qm = srslte_mod_bits_x_symbol(modulation);
if (srslte_pusch_cfg(&cfg, cell, NULL, 0, 0, subframe, 0)) {
fprintf(stderr, "Error configuring PDSCH\n");
exit(-1);
}
if (srslte_pusch_init(&pusch, cell)) {
@ -197,10 +195,6 @@ int main(int argc, char **argv) {
uci_data.uci_ri = 0;
uci_data.uci_ack = 0;
if (srslte_cbsegm(&cfg.cb_segm, cfg.grant.mcs.tbs)) {
fprintf(stderr, "Error configuring CB segmentation\n");
goto quit;
}
srslte_pusch_hopping_cfg_t ul_hopping;
ul_hopping.n_sb = 1;
ul_hopping.hopping_offset = 0;

@ -148,13 +148,13 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
cfg.grant.L_prb = mexutils_read_f(p, &prbset);
cfg.grant.n_prb[0] = prbset[0];
cfg.grant.n_prb[1] = prbset[0];
cfg.grant.lstart = 0;
cfg.grant.nof_symb = 2*(SRSLTE_CP_NSYMB(cell.cp)-1) - N_srs;
cfg.nbits.lstart = 0;
cfg.nbits.nof_symb = 2*(SRSLTE_CP_NSYMB(cell.cp)-1) - N_srs;
cfg.grant.M_sc = cfg.grant.L_prb*SRSLTE_NRE;
cfg.grant.M_sc_init = cfg.grant.M_sc; // FIXME: What should M_sc_init be?
cfg.grant.nof_re = cfg.grant.nof_symb*cfg.grant.M_sc;
cfg.nbits.nof_re = cfg.nbits.nof_symb*cfg.grant.M_sc;
cfg.grant.Qm = srslte_mod_bits_x_symbol(cfg.grant.mcs.mod);
cfg.grant.nof_bits = cfg.grant.nof_re * cfg.grant.Qm;
cfg.nbits.nof_bits = cfg.nbits.nof_re * cfg.grant.Qm;
mexPrintf("Q_m: %d, NPRB: %d, RV: %d, Nsrs=%d\n", srslte_mod_bits_x_symbol(cfg.grant.mcs.mod), cfg.grant.L_prb, cfg.rv, N_srs);
@ -163,11 +163,11 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return;
}
uint8_t *q_bits = srslte_vec_malloc(cfg.grant.nof_bits * sizeof(uint8_t));
uint8_t *q_bits = srslte_vec_malloc(cfg.nbits.nof_bits * sizeof(uint8_t));
if (!q_bits) {
return;
}
uint8_t *g_bits = srslte_vec_malloc(cfg.grant.nof_bits * sizeof(uint8_t));
uint8_t *g_bits = srslte_vec_malloc(cfg.nbits.nof_bits * sizeof(uint8_t));
if (!g_bits) {
return;
}
@ -186,7 +186,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
}
if (nlhs >= 1) {
mexutils_write_uint8(q_bits, &plhs[0], cfg.grant.nof_bits, 1);
mexutils_write_uint8(q_bits, &plhs[0], cfg.nbits.nof_bits, 1);
}
srslte_sch_free(&ulsch);

@ -203,6 +203,11 @@ int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input, uint32_t sf
}
}
int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx)
{
return srslte_pdsch_cfg(&q->pdsch_cfg, q->cell, dci_msg, cfi, sf_idx, rnti, rvidx);
}
int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint8_t *data,
uint32_t cfi, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx)
{
@ -210,20 +215,11 @@ int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_
q->nof_detected++;
if (srslte_dci_msg_to_dl_grant(dci_msg, rnti, q->cell, cfi, sf_idx, &q->dl_dci, &q->pdsch_cfg.grant)) {
//fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n");
return SRSLTE_ERROR;
}
if (srslte_cbsegm(&q->pdsch_cfg.cb_segm, q->pdsch_cfg.grant.mcs.tbs)) {
fprintf(stderr, "Error computing Codeblock segmentation for TBS=%d\n", q->pdsch_cfg.grant.mcs.tbs);
/* Setup PDSCH configuration for this CFI, SFIDX and RVIDX */
if (srslte_ue_dl_cfg_grant(q, dci_msg, cfi, sf_idx, rnti, rvidx)) {
return SRSLTE_ERROR;
}
q->pdsch_cfg.sf_idx = sf_idx;
if (rnti == SRSLTE_SIRNTI) {
q->pdsch_cfg.rv = rvidx;
} else {
q->pdsch_cfg.rv = q->dl_dci.rv_idx;
}
if (q->pdsch_cfg.rv == 0) {
srslte_softbuffer_rx_reset(&q->softbuffer);
}
@ -339,6 +335,7 @@ int srslte_ue_dl_decode_rnti_rv(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, u
}
int found_dci = srslte_ue_dl_find_dl_dci(q, &dci_msg, q->cfi, sf_idx, rnti);
if (found_dci == 1) {
ret = srslte_ue_dl_decode_rnti_rv_packet(q, &dci_msg, data, q->cfi, sf_idx, rnti, rvidx);
}

@ -169,6 +169,11 @@ void srslte_ue_ul_set_cfg(srslte_ue_ul_t *q,
}
}
int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q, srslte_dci_msg_t *dci_msg, uint32_t n_rb_ho, uint32_t N_srs, uint32_t sf_idx, uint32_t rvidx)
{
return srslte_pusch_cfg(&q->pusch_cfg, q->cell, dci_msg, n_rb_ho, N_srs, sf_idx, rvidx);
}
/* Choose PUCCH format as in Sec 10.1 of 36.213 and generate PUCCH signal
*/
int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
@ -281,83 +286,74 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
return ret;
}
int srslte_ue_ul_pusch_encode(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *grant, uint8_t *data, uint32_t sf_idx, uint32_t rv, cf_t *output_signal)
int srslte_ue_ul_pusch_encode(srslte_ue_ul_t *q, uint8_t *data, cf_t *output_signal)
{
srslte_uci_data_t uci_data;
bzero(&uci_data, sizeof(srslte_uci_data_t));
return srslte_ue_ul_pusch_uci_encode_rnti(q, grant, data, uci_data, sf_idx, rv, q->current_rnti, output_signal);
return srslte_ue_ul_pusch_uci_encode_rnti(q, data, uci_data, q->current_rnti, output_signal);
}
int srslte_ue_ul_pusch_encode_rnti(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *grant, uint8_t *data, uint32_t sf_idx, uint32_t rv, uint16_t rnti, cf_t *output_signal)
int srslte_ue_ul_pusch_encode_rnti(srslte_ue_ul_t *q, uint8_t *data, uint16_t rnti, cf_t *output_signal)
{
srslte_uci_data_t uci_data;
bzero(&uci_data, sizeof(srslte_uci_data_t));
return srslte_ue_ul_pusch_uci_encode_rnti(q, grant, data, uci_data, sf_idx, rv,rnti, output_signal);
return srslte_ue_ul_pusch_uci_encode_rnti(q, data, uci_data, rnti, output_signal);
}
int srslte_ue_ul_pusch_uci_encode(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *grant, uint8_t *data, srslte_uci_data_t uci_data, uint32_t sf_idx, uint32_t rv, cf_t *output_signal)
int srslte_ue_ul_pusch_uci_encode(srslte_ue_ul_t *q, uint8_t *data, srslte_uci_data_t uci_data, cf_t *output_signal)
{
return srslte_ue_ul_pusch_uci_encode_rnti(q, grant, data, uci_data, sf_idx, rv, q->current_rnti, output_signal);
return srslte_ue_ul_pusch_uci_encode_rnti(q, data, uci_data, q->current_rnti, output_signal);
}
int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *grant,
int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q,
uint8_t *data, srslte_uci_data_t uci_data,
uint32_t sf_idx, uint32_t rv, uint16_t rnti,
uint16_t rnti,
cf_t *output_signal)
{
int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (q != NULL &&
grant != NULL &&
output_signal != NULL)
{
if (grant->L_prb == 0) {
if (q->pusch_cfg.grant.L_prb == 0) {
fprintf(stderr, "Invalid UL PRB allocation (L_prb=0)\n");
return ret;
return SRSLTE_ERROR;
}
ret = SRSLTE_ERROR;
memcpy(&q->pusch_cfg.grant, grant, sizeof(srslte_ra_ul_grant_t));
q->pusch_cfg.sf_idx = sf_idx;
q->pusch_cfg.rv = rv;
q->pusch_cfg.cp = q->cell.cp;
srslte_cbsegm(&q->pusch_cfg.cb_segm, grant->mcs.tbs);
return srslte_ue_ul_pusch_encode_cfg(q, &q->pusch_cfg, data, uci_data, &q->softbuffer, rnti, output_signal);
return srslte_ue_ul_pusch_encode_rnti_softbuffer(q, data, uci_data, &q->softbuffer, rnti, output_signal);
}
return ret;
}
int srslte_ue_ul_pusch_encode_cfg(srslte_ue_ul_t *q, srslte_pusch_cfg_t *cfg,
uint8_t *data, srslte_uci_data_t uci_data,
srslte_softbuffer_tx_t *softbuffer,
uint16_t rnti,
cf_t *output_signal)
int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q,
uint8_t *data, srslte_uci_data_t uci_data,
srslte_softbuffer_tx_t *softbuffer,
uint16_t rnti,
cf_t *output_signal)
{
int ret = SRSLTE_ERROR_INVALID_INPUTS;
bzero(q->sf_symbols, sizeof(cf_t)*SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp));
if (q != NULL &&
cfg != NULL &&
softbuffer != NULL &&
output_signal != NULL)
{
if (srslte_pusch_encode_rnti(&q->pusch, cfg, softbuffer, data, rnti, q->sf_symbols)) {
if (srslte_pusch_encode_rnti(&q->pusch, &q->pusch_cfg, softbuffer, data, rnti, q->sf_symbols)) {
fprintf(stderr, "Error encoding TB\n");
return ret;
}
// FIXME: Pregenerate for all possible number of prb
if (srslte_refsignal_dmrs_pusch_gen(&q->dmrs, cfg->grant.L_prb, cfg->sf_idx, q->refsignal))
if (srslte_refsignal_dmrs_pusch_gen(&q->dmrs, q->pusch_cfg.grant.L_prb, q->pusch_cfg.sf_idx, q->refsignal))
{
fprintf(stderr, "Error generating PUSCH DRMS signals\n");
return ret;
}
srslte_refsignal_dmrs_pusch_put(&q->dmrs, q->refsignal,
cfg->grant.L_prb,
cfg->grant.n_prb_tilde,
q->pusch_cfg.grant.L_prb,
q->pusch_cfg.grant.n_prb_tilde,
q->sf_symbols);
srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal);
@ -367,7 +363,7 @@ int srslte_ue_ul_pusch_encode_cfg(srslte_ue_ul_t *q, srslte_pusch_cfg_t *cfg,
}
if (q->normalize_en) {
float norm_factor = (float) q->cell.nof_prb/10/sqrtf(cfg->grant.L_prb);
float norm_factor = (float) q->cell.nof_prb/10/sqrtf(q->pusch_cfg.grant.L_prb);
srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
}

Loading…
Cancel
Save