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') addpath('../../build/srslte/lib/phch/test')
TBs=336; TBs=[111 336];
cqilen=0; cqilen=0;
rvs=0; rvs=[0 2];
mods={'16QAM'}; mods={'16QAM'};
betas=0; betas=0;
subf=8; subf=[1:8];
for i=1:length(TBs) for i=1:length(TBs)
for m=1:length(mods) for m=1:length(mods)
@ -41,17 +41,17 @@ for i=1:length(TBs)
if (cqilen(c)>0 || TBs(i)>0) if (cqilen(c)>0 || TBs(i)>0)
[cw, info]=lteULSCH(ueConfig,puschConfig,trblkin); [cw, info]=lteULSCH(ueConfig,puschConfig,trblkin);
cw_mat=ltePUSCH(ueConfig,puschConfig,cw); cw_mat=ltePUSCH(ueConfig,puschConfig,cw);
drs=ltePUSCHDRS(ueConfig,puschConfig); %drs=ltePUSCHDRS(ueConfig,puschConfig);
idx=ltePUSCHIndices(ueConfig,puschConfig); idx=ltePUSCHIndices(ueConfig,puschConfig);
drs_idx=ltePUSCHDRSIndices(ueConfig,puschConfig); %drs_idx=ltePUSCHDRSIndices(ueConfig,puschConfig);
subframe_mat = lteULResourceGrid(ueConfig); subframe_mat = lteULResourceGrid(ueConfig);
subframe_mat(idx)=cw_mat; subframe_mat(idx)=cw_mat;
subframe_mat(drs_idx)=drs; %subframe_mat(drs_idx)=drs;
waveform = lteSCFDMAModulate(ueConfig,subframe_mat,0); 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); [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)); err=max(abs(waveform-waveform_lib));
if (err > 10^-8) if (err > 10^-5)
disp(err) disp(err)
error('Error!'); error('Error!');
end end

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

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

@ -183,14 +183,23 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof
// Transmit on PUSCH if UL grant available, otherwise in PUCCH // Transmit on PUSCH if UL grant available, otherwise in PUCCH
if (grant) { 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", 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, 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", uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no",
grant->get_rnti(), tti%10); grant->get_rnti(), tti%10);
n = srslte_ue_ul_pusch_encode_cfg(&ue_ul, &pusch_cfg, n = srslte_ue_ul_pusch_encode_rnti_softbuffer(&ue_ul,
payload, uci_data, payload, uci_data,
softbuffer, softbuffer,
grant->get_rnti(), grant->get_rnti(),

@ -331,12 +331,14 @@ int update_radl() {
srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb); srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb);
srslte_ra_dl_grant_t dummy_grant; 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); srslte_ra_dl_grant_fprint(stdout, &dummy_grant);
printf("Type new MCS index and press Enter: "); fflush(stdout); printf("Type new MCS index and press Enter: "); fflush(stdout);
if (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_grant.nof_bits, (float) dummy_grant.mcs.tbs / dummy_grant.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; return -1;
} }
@ -522,6 +524,8 @@ int main(int argc, char **argv) {
nf = 0; nf = 0;
bool send_data = false; bool send_data = false;
bool start_of_burst = true;
srslte_softbuffer_tx_reset(&softbuffer);
while (nf < nof_frames || nof_frames == -1) { 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++) { 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) { 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); 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); 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)) { 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); 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)) { if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer, data, sf_symbols)) {
fprintf(stderr, "Error encoding PDSCH\n"); fprintf(stderr, "Error encoding PDSCH\n");
exit(-1); exit(-1);
@ -605,7 +613,8 @@ int main(int argc, char **argv) {
// FIXME // FIXME
float norm_factor = (float) cell.nof_prb/15/sqrtf(pdsch_cfg.grant.nof_prb); 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)); 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 #endif
} }
nf++; nf++;

@ -631,7 +631,7 @@ void *plot_thread_run(void *arg) {
while(1) { while(1) {
sem_wait(&plot_sem); 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) { if (!prog_args.disable_plots_except_constellation) {
for (i = 0; i < nof_re; i++) { for (i = 0; i < nof_re; i++) {
tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[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.hopping_flag = rar_msg.hopping_flag;
rar_grant.rba = rar_msg.rba; rar_grant.rba = rar_msg.rba;
rar_grant.trunc_mcs = rar_msg.mcs; 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_ra_pusch_fprint(stdout, &ra_pusch, cell.nof_prb);
srslte_ue_sync_get_last_timestamp(&ue_sync, &uhd_time); 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); printf("Setting CFO: %f (%f)\n", cfo, cfo*15000);
srslte_ue_ul_set_cfo(&ue_ul, cfo); 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) { if (n < 0) {
fprintf(stderr, "Error encoding PUSCH\n"); fprintf(stderr, "Error encoding PUSCH\n");
exit(-1); exit(-1);

@ -118,6 +118,12 @@ SRSLTE_API int cuhd_send(void *h,
uint32_t nsamples, uint32_t nsamples,
bool blocking); 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, SRSLTE_API int cuhd_send(void *h,
void *data, void *data,

@ -97,21 +97,18 @@ typedef struct SRSLTE_API {
*/ */
SRSLTE_API int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg, SRSLTE_API int srslte_dci_msg_to_dl_grant(srslte_dci_msg_t *msg,
uint16_t msg_rnti, uint16_t msg_rnti,
srslte_cell_t cell, uint32_t nof_prb,
uint32_t cfi,
uint32_t sf_idx,
srslte_ra_dl_dci_t *dl_dci, srslte_ra_dl_dci_t *dl_dci,
srslte_ra_dl_grant_t *grant); srslte_ra_dl_grant_t *grant);
SRSLTE_API int srslte_dci_msg_to_ul_grant(srslte_dci_msg_t *msg, SRSLTE_API int srslte_dci_msg_to_ul_grant(srslte_dci_msg_t *msg,
srslte_cell_t cell, uint32_t nof_prb,
uint32_t N_srs,
uint32_t n_rb_ho, uint32_t n_rb_ho,
srslte_ra_ul_dci_t *ul_dci, srslte_ra_ul_dci_t *ul_dci,
srslte_ra_ul_grant_t *grant); srslte_ra_ul_grant_t *grant);
SRSLTE_API int srslte_dci_rar_to_ul_grant(srslte_dci_rar_grant_t *rar, 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, uint32_t n_rb_ho,
srslte_ra_ul_dci_t *ul_dci, srslte_ra_ul_dci_t *ul_dci,
srslte_ra_ul_grant_t *grant); 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, SRSLTE_API int srslte_pdsch_set_rnti(srslte_pdsch_t *q,
uint16_t rnti); 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_API int srslte_pdsch_encode(srslte_pdsch_t *q,
srslte_pdsch_cfg_t *cfg, srslte_pdsch_cfg_t *cfg,
srslte_softbuffer_tx_t *softbuffer, srslte_softbuffer_tx_t *softbuffer,

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

@ -44,6 +44,7 @@
#include "srslte/modem/demod_soft.h" #include "srslte/modem/demod_soft.h"
#include "srslte/scrambling/scrambling.h" #include "srslte/scrambling/scrambling.h"
#include "srslte/phch/regs.h" #include "srslte/phch/regs.h"
#include "srslte/phch/dci.h"
#include "srslte/phch/sch.h" #include "srslte/phch/sch.h"
#include "srslte/phch/pusch_cfg.h" #include "srslte/phch/pusch_cfg.h"
#include "srslte/dft/dft_precoding.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 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_API void srslte_pusch_set_hopping_cfg(srslte_pusch_t *q,
srslte_pusch_hopping_cfg_t *cfg); srslte_pusch_hopping_cfg_t *cfg);

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

@ -52,6 +52,15 @@ typedef struct SRSLTE_API {
int tbs; int tbs;
} srslte_ra_mcs_t; } 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 { typedef enum SRSLTE_API {
SRSLTE_RA_ALLOC_TYPE0 = 0, SRSLTE_RA_ALLOC_TYPE0 = 0,
SRSLTE_RA_ALLOC_TYPE1 = 1, SRSLTE_RA_ALLOC_TYPE1 = 1,
@ -86,18 +95,12 @@ typedef struct SRSLTE_API {
/************************************************** /**************************************************
* Structures used for Downlink Resource Allocation * Structures used for Downlink Resource Allocation
**************************************************/ **************************************************/
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
bool prb_idx[2][SRSLTE_MAX_PRB]; 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 nof_prb;
uint32_t Qm; uint32_t Qm;
srslte_ra_mcs_t mcs; srslte_ra_mcs_t mcs;
@ -138,10 +141,6 @@ typedef struct SRSLTE_API {
uint32_t n_prb_tilde[2]; uint32_t n_prb_tilde[2];
uint32_t L_prb; uint32_t L_prb;
uint32_t freq_hopping; 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;
uint32_t M_sc_init; uint32_t M_sc_init;
uint32_t Qm; 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_API int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t *dci,
srslte_ra_dl_grant_t* grant, 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, srslte_cell_t cell,
uint32_t sf_idx, uint32_t sf_idx,
uint32_t cfi, srslte_ra_nbits_t *nbits);
bool crc_is_crnti);
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, srslte_cell_t cell,
uint32_t sf_idx, uint32_t sf_idx,
uint32_t nof_ctrl_symbols); uint32_t nof_ctrl_symbols);
SRSLTE_API int srslte_ra_ul_dci_to_grant(srslte_ra_ul_dci_t *dci, SRSLTE_API int srslte_ra_ul_dci_to_grant(srslte_ra_ul_dci_t *dci,
srslte_ra_ul_grant_t *grant, uint32_t nof_prb,
srslte_cell_t cell,
uint32_t n_rb_ho, 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_API int srslte_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci,
srslte_ra_ul_grant_t *grant, 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 sf_idx,
uint32_t *cfi); 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_API int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q,
srslte_dci_msg_t *dci_msg, srslte_dci_msg_t *dci_msg,
uint8_t *data, uint8_t *data,

@ -44,6 +44,7 @@
#include "srslte/dft/ofdm.h" #include "srslte/dft/ofdm.h"
#include "srslte/ch_estimation/refsignal_ul.h" #include "srslte/ch_estimation/refsignal_ul.h"
#include "srslte/phch/pusch.h" #include "srslte/phch/pusch.h"
#include "srslte/phch/dci.h"
#include "srslte/phch/ra.h" #include "srslte/phch/ra.h"
#include "srslte/sync/cfo.h" #include "srslte/sync/cfo.h"
#include "srslte/utils/vector.h" #include "srslte/utils/vector.h"
@ -99,45 +100,39 @@ SRSLTE_API void srslte_ue_ul_set_cfg(srslte_ue_ul_t *q,
srslte_pucch_cfg_t *pucch_cfg, srslte_pucch_cfg_t *pucch_cfg,
srslte_pucch_sched_t *pucch_sched); 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_API int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q,
srslte_uci_data_t uci_data, srslte_uci_data_t uci_data,
uint32_t sf_idx, uint32_t sf_idx,
cf_t *output_signal); cf_t *output_signal);
SRSLTE_API int srslte_ue_ul_pusch_encode(srslte_ue_ul_t *q, SRSLTE_API int srslte_ue_ul_pusch_encode(srslte_ue_ul_t *q,
srslte_ra_ul_grant_t *grant,
uint8_t *data, uint8_t *data,
uint32_t sf_idx,
uint32_t rv,
cf_t *output_signal); cf_t *output_signal);
SRSLTE_API int srslte_ue_ul_pusch_encode_rnti(srslte_ue_ul_t *q, SRSLTE_API int srslte_ue_ul_pusch_encode_rnti(srslte_ue_ul_t *q,
srslte_ra_ul_grant_t *grant,
uint8_t *data, uint8_t *data,
uint32_t sf_idx,
uint32_t rv,
uint16_t rnti, uint16_t rnti,
cf_t *output_signal); cf_t *output_signal);
SRSLTE_API int srslte_ue_ul_pusch_uci_encode(srslte_ue_ul_t *q, SRSLTE_API int srslte_ue_ul_pusch_uci_encode(srslte_ue_ul_t *q,
srslte_ra_ul_grant_t *grant,
uint8_t *data, uint8_t *data,
srslte_uci_data_t uci_data, srslte_uci_data_t uci_data,
uint32_t sf_idx,
uint32_t rv,
cf_t *output_signal); cf_t *output_signal);
SRSLTE_API int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q, SRSLTE_API int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q,
srslte_ra_ul_grant_t *grant,
uint8_t *data, uint8_t *data,
srslte_uci_data_t uci_data, srslte_uci_data_t uci_data,
uint32_t sf_idx,
uint32_t rv,
uint16_t rnti, uint16_t rnti,
cf_t *output_signal); cf_t *output_signal);
SRSLTE_API int srslte_ue_ul_pusch_encode_cfg(srslte_ue_ul_t *q, SRSLTE_API int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q,
srslte_pusch_cfg_t *cfg,
uint8_t *data, uint8_t *data,
srslte_uci_data_t uci_data, srslte_uci_data_t uci_data,
srslte_softbuffer_tx_t *softbuffer, srslte_softbuffer_tx_t *softbuffer,

@ -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) 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); cuhd_handler *handler = static_cast < cuhd_handler * >(h);
uhd::tx_metadata_t md; 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) { if (blocking) {
int n = 0, p; int n = 0, p;
complex_t *data_c = (complex_t *) data; 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 // 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++) { for (uint32_t i=0;i<q->max_cb;i++) {
q->buffer_f[i] = srslte_vec_malloc(sizeof(float) * q->buff_size); q->buffer_f[i] = srslte_vec_malloc(sizeof(float) * q->buff_size);
if (!q->buffer_f[i]) { if (!q->buffer_f[i]) {

@ -44,23 +44,20 @@
/* Unpacks a DCI message and configures the DL grant object /* 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, 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_dci_t *dl_dci,
srslte_ra_dl_grant_t *grant) srslte_ra_dl_grant_t *grant)
{ {
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (msg != NULL && if (msg != NULL &&
grant != NULL && grant != NULL)
srslte_cell_isvalid(&cell) &&
cfi > 0 &&
cfi < 4)
{ {
ret = SRSLTE_ERROR; ret = SRSLTE_ERROR;
srslte_dci_msg_type_t type; 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"); fprintf(stderr, "Can't get DCI message type\n");
return ret; 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) { if (msg_rnti >= SRSLTE_CRNTI_START && msg_rnti <= SRSLTE_CRNTI_END) {
crc_is_crnti = true; 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"); fprintf(stderr, "Can't unpack DCI message\n");
return ret; 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()) { 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); 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 /* 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, uint32_t n_rb_ho,
srslte_ra_ul_dci_t *ul_dci, srslte_ra_ul_dci_t *ul_dci,
srslte_ra_ul_grant_t *grant) 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; uint32_t riv = rar->rba;
// Truncate resource block assignment // Truncate resource block assignment
uint32_t b = 0; uint32_t b = 0;
if (cell.nof_prb <= 44) { if (nof_prb <= 44) {
b = (uint32_t) (ceilf(log2((float) cell.nof_prb*(cell.nof_prb+1)/2))); b = (uint32_t) (ceilf(log2((float) nof_prb*(nof_prb+1)/2)));
riv = riv & ((1<<(b+1))-1); riv = riv & ((1<<(b+1))-1);
} }
ul_dci->type2_alloc.riv = riv; ul_dci->type2_alloc.riv = riv;
ul_dci->mcs_idx = rar->trunc_mcs; 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, 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"); fprintf(stderr, "Error computing resource allocation\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (SRSLTE_VERBOSE_ISINFO()) { 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); srslte_ra_ul_grant_fprint(stdout, grant);
} }
return SRSLTE_SUCCESS; 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 /* 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, int srslte_dci_msg_to_ul_grant(srslte_dci_msg_t *msg, uint32_t nof_prb,
uint32_t N_srs, uint32_t n_rb_ho, uint32_t n_rb_ho,
srslte_ra_ul_dci_t *ul_dci, srslte_ra_ul_dci_t *ul_dci,
srslte_ra_ul_grant_t *grant) srslte_ra_ul_grant_t *grant)
{ {
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (msg != NULL && if (msg != NULL &&
srslte_cell_isvalid(&cell) &&
grant != NULL) grant != NULL)
{ {
ret = SRSLTE_ERROR; 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(ul_dci, sizeof(srslte_ra_ul_dci_t));
bzero(grant, 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; 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"); fprintf(stderr, "Error computing resource allocation\n");
return ret; return ret;
} }
if (SRSLTE_VERBOSE_ISINFO()) { 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); srslte_ra_ul_grant_fprint(stdout, grant);
} }

@ -59,16 +59,13 @@ extern int indices_ptr;
#endif #endif
int srslte_pdsch_cp(srslte_pdsch_t *q, cf_t *input, cf_t *output, srslte_ra_dl_grant_t *grant, 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 nsubframe, bool put) { {
uint32_t s, n, l, lp, lstart, lend, nof_refs; uint32_t s, n, l, lp, lstart, lend, nof_refs;
bool is_pbch, is_sss; bool is_pbch, is_sss;
cf_t *in_ptr = input, *out_ptr = output; cf_t *in_ptr = input, *out_ptr = output;
uint32_t offset = 0; uint32_t offset = 0;
INFO("%s %d RE from %d PRB\n", put ? "Putting" : "Getting",
grant->nof_re, grant->nof_prb);
#ifdef DEBUG_IDX #ifdef DEBUG_IDX
indices_ptr = 0; indices_ptr = 0;
if (put) { 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 this PRB is assigned
if (grant->prb_idx[s][n]) { if (grant->prb_idx[s][n]) {
if (s == 0) { if (s == 0) {
lstart = grant->lstart; lstart = lstart_grant;
} else { } else {
lstart = 0; 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 * 36.211 10.3 section 6.3.5
*/ */
int srslte_pdsch_put(srslte_pdsch_t *q, cf_t *symbols, cf_t *sf_symbols, int srslte_pdsch_put(srslte_pdsch_t *q, cf_t *symbols, cf_t *sf_symbols,
srslte_ra_dl_grant_t *grant, uint32_t subframe) { srslte_ra_dl_grant_t *grant, uint32_t lstart, uint32_t subframe)
return srslte_pdsch_cp(q, symbols, sf_symbols, grant, subframe, true); {
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 * 36.211 10.3 section 6.3.5
*/ */
int srslte_pdsch_get(srslte_pdsch_t *q, cf_t *sf_symbols, cf_t *symbols, int srslte_pdsch_get(srslte_pdsch_t *q, cf_t *sf_symbols, cf_t *symbols,
srslte_ra_dl_grant_t *grant, uint32_t subframe) { srslte_ra_dl_grant_t *grant, uint32_t lstart, uint32_t subframe)
return srslte_pdsch_cp(q, sf_symbols, symbols, grant, subframe, false); {
return srslte_pdsch_cp(q, sf_symbols, symbols, grant, lstart, subframe, false);
} }
/** Initializes the PDCCH transmitter and receiver */ /** 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 /* 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. * 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", 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->sf_idx, rnti, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs, cfg->nbits.nof_re,
cfg->grant.nof_bits, cfg->rv); cfg->nbits.nof_bits, cfg->rv);
if (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->grant.nof_bits, (float) cfg->grant.mcs.tbs / cfg->grant.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; 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)); memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports));
/* extract symbols */ /* extract symbols */
n = srslte_pdsch_get(q, sf_symbols, q->symbols[0], &cfg->grant, cfg->sf_idx); n = srslte_pdsch_get(q, sf_symbols, q->symbols[0], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
if (n != cfg->grant.nof_re) { if (n != cfg->nbits.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n); fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
/* extract channel estimates */ /* extract channel estimates */
for (i = 0; i < q->cell.nof_ports; i++) { for (i = 0; i < q->cell.nof_ports; i++) {
n = srslte_pdsch_get(q, ce[i], q->ce[i], &cfg->grant, cfg->sf_idx); n = srslte_pdsch_get(q, ce[i], q->ce[i], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
if (n != cfg->grant.nof_re) { if (n != cfg->nbits.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n); fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
} }
@ -393,12 +422,12 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q,
if (q->cell.nof_ports == 1) { if (q->cell.nof_ports == 1) {
/* no need for layer demapping */ /* no need for layer demapping */
srslte_predecoding_single(&q->precoding, q->symbols[0], q->ce[0], q->d, 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 { } else {
srslte_predecoding_diversity(&q->precoding, q->symbols[0], q->ce, x, q->cell.nof_ports, 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, 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 /* 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_sigma_set(&q->demod, sqrt(0.5));
srslte_demod_soft_table_set(&q->demod, &q->mod[cfg->grant.mcs.mod]); 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 */ /* descramble */
if (rnti != q->rnti) { if (rnti != q->rnti) {
srslte_sequence_t seq; 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; 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); srslte_sequence_free(&seq);
} else { } 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); 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; return SRSLTE_ERROR_INVALID_INPUTS;
} }
if (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->grant.nof_bits, (float) cfg->grant.mcs.tbs / cfg->grant.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; return SRSLTE_ERROR_INVALID_INPUTS;
} }
if (cfg->grant.nof_re > q->max_re) { if (cfg->nbits.nof_re > q->max_re) {
fprintf(stderr, fprintf(stderr,
"Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n", "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; return SRSLTE_ERROR_INVALID_INPUTS;
} }
INFO("Encoding PDSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", INFO("Encoding PDSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
cfg->sf_idx, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs, 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 */ /* number of layers equals number of ports */
for (i = 0; i < q->cell.nof_ports; i++) { for (i = 0; i < q->cell.nof_ports; i++) {
@ -502,29 +531,29 @@ int srslte_pdsch_encode_rnti(srslte_pdsch_t *q,
if (rnti != q->rnti) { if (rnti != q->rnti) {
srslte_sequence_t seq; 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; 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); srslte_sequence_free(&seq);
} else { } 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 */ /* TODO: only diversity supported */
if (q->cell.nof_ports > 1) { 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, 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 { } 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 */ /* mapping to resource elements */
for (i = 0; i < q->cell.nof_ports; i++) { 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; 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 /* 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. * 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 */ * 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) { if (q->rnti_is_set) {
INFO("Decoding PUSCH SF: %d, Mod %s, NofBits: %d, NofRE: %d, NofSymbols=%d, NofBitsE: %d, rv_idx: %d\n", 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->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 */ /* extract symbols */
n = pusch_get(q, &cfg->grant, cfg->sf_idx, sf_symbols, q->d); n = pusch_get(q, &cfg->grant, cfg->sf_idx, sf_symbols, q->d);
if (n != cfg->grant.nof_re) { if (n != cfg->nbits.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n); fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
/* extract channel estimates */ /* extract channel estimates */
n = pusch_get(q, &cfg->grant, cfg->sf_idx, ce, q->ce); n = pusch_get(q, &cfg->grant, cfg->sf_idx, ce, q->ce);
if (n != cfg->grant.nof_re) { if (n != cfg->nbits.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->grant.nof_re, n); fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
srslte_predecoding_single(&q->equalizer, q->d, q->ce, q->z, 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 /* demodulate symbols
* The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation, * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
@ -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_sigma_set(&q->demod, sqrt(0.5));
srslte_demod_soft_table_set(&q->demod, &q->mod[cfg->grant.mcs.mod]); 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 */ /* 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); return srslte_ulsch_decode(&q->dl_sch, cfg, softbuffer, q->q, data);
} else { } else {
@ -412,22 +436,22 @@ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srs
if (q != NULL && if (q != NULL &&
cfg != NULL) cfg != NULL)
{ {
if (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->grant.nof_bits); fprintf(stderr, "Invalid code rate %.2f\n", (float) cfg->grant.mcs.tbs / cfg->nbits.nof_bits);
return SRSLTE_ERROR_INVALID_INPUTS; 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", 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; 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", 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->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)) { if (srslte_ulsch_uci_encode(&q->dl_sch, cfg, softbuffer, data, uci_data, q->g, q->q)) {
fprintf(stderr, "Error encoding TB\n"); fprintf(stderr, "Error encoding TB\n");
return SRSLTE_ERROR; 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) { if (rnti != q->rnti) {
srslte_sequence_t seq; 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; 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); srslte_sequence_free(&seq);
} else { } 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 */ /* mapping to resource elements */
pusch_put(q, &cfg->grant, cfg->sf_idx, q->z, sf_symbols); 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; return re;
} }
int srslte_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci, srslte_ra_ul_grant_t *grant, 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)
uint32_t n_rb_ho, uint32_t nof_prb) { {
bzero(grant, sizeof(srslte_ra_ul_grant_t)); bzero(grant, sizeof(srslte_ra_ul_grant_t));
grant->L_prb = dci->type2_alloc.L_crb; grant->L_prb = dci->type2_alloc.L_crb;
uint32_t n_prb_1 = dci->type2_alloc.RB_start; 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 */ /** 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, 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)
uint32_t n_rb_ho, uint32_t N_srs)
{ {
// Compute PRB allocation // 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 // Compute MCS
if (!ul_dci_to_grant_mcs(dci, grant)) { if (!ul_dci_to_grant_mcs(dci, grant)) {
// Fill rest of grant structure // 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 = grant->L_prb*SRSLTE_NRE;
grant->M_sc_init = grant->M_sc; // FIXME: What should M_sc_init be? 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->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod);
grant->nof_bits = grant->nof_re * grant->Qm;
} else { } else {
fprintf(stderr, "Error computing MCS\n"); fprintf(stderr, "Error computing MCS\n");
return SRSLTE_ERROR; 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 */ /* 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 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 sf_idx, uint32_t nof_ctrl_symbols)
{ {
uint32_t j, s; uint32_t j, s;
// Compute number of RE per PRB // Compute number of RE per PRB
grant->nof_re = 0; uint32_t nof_re = 0;
for (s = 0; s < 2; s++) { for (s = 0; s < 2; s++) {
for (j = 0; j < cell.nof_prb; j++) { for (j = 0; j < cell.nof_prb; j++) {
if (grant->prb_idx[s][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); 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 */ /** 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, 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)
uint32_t sf_idx, uint32_t cfi, bool crc_is_crnti)
{ {
// Compute PRB allocation // Compute PRB allocation
if (!dl_dci_to_grant_prb_allocation(dci, grant, cell.nof_prb)) { if (!dl_dci_to_grant_prb_allocation(dci, grant, nof_prb)) {
// Compute number of RE
srslte_dl_dci_to_grant_nof_re(grant, cell, sf_idx, cell.nof_prb<10?(cfi+1):cfi);
// Compute MCS // Compute MCS
if (!dl_dci_to_grant_mcs(dci, grant, crc_is_crnti)) { if (!dl_dci_to_grant_mcs(dci, grant, crc_is_crnti)) {
// Fill rest of grant structure // 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->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod);
grant->nof_bits = grant->nof_re * grant->Qm;
} else { } else {
return SRSLTE_ERROR; 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, return decode_tb(q,
softbuffer, &cfg->cb_segm, 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); 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, return encode_tb(q,
softbuffer, &cfg->cb_segm, 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); 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, return decode_tb(q,
softbuffer, &cfg->cb_segm, 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); 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_ack = 0;
uint32_t Q_prime_ri = 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; uint32_t Qm = cfg->grant.Qm;
bzero(q_bits, sizeof(uint8_t) * nb_q); 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) // 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 // Encode (and interleave) ACK
if (uci_data.uci_ack_len > 0) { 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; uint32_t x = 999999;
if (K > 0) { 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; 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); 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); encode_ri_ack(data, q_encoded_bits, cfg->grant.Qm);
for (uint32_t i=0;i<Qprime;i++) { 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; 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); encode_ri_ack(data, q_encoded_bits, cfg->grant.Qm);
for (uint32_t i=0;i<Qprime;i++) { 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; return (int) Qprime;

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

@ -45,14 +45,12 @@ srslte_cell_t cell = {
uint32_t cfi = 2; uint32_t cfi = 2;
uint32_t tbs = 0; uint32_t tbs = 0;
uint32_t nof_tbs = 0;
uint32_t subframe = 1; uint32_t subframe = 1;
srslte_mod_t modulation = SRSLTE_MOD_BPSK; srslte_mod_t modulation = SRSLTE_MOD_BPSK;
uint32_t rv_idx = 0; uint32_t rv_idx = 0;
void usage(char *prog) { void usage(char *prog) {
printf("Usage: %s [Lcpsrnfvmt] -l TBS \n", 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-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-c cell id [Default %d]\n", cell.id);
printf("\t-s subframe [Default %d]\n", subframe); printf("\t-s subframe [Default %d]\n", subframe);
@ -65,7 +63,7 @@ void usage(char *prog) {
void parse_args(int argc, char **argv) { void parse_args(int argc, char **argv) {
int opt; int opt;
while ((opt = getopt(argc, argv, "lLcpnfvmtsr")) != -1) { while ((opt = getopt(argc, argv, "lcpnfvmtsr")) != -1) {
switch(opt) { switch(opt) {
case 'm': case 'm':
switch(atoi(argv[optind])) { switch(atoi(argv[optind])) {
@ -96,9 +94,6 @@ void parse_args(int argc, char **argv) {
case 'l': case 'l':
tbs = atoi(argv[optind]); tbs = atoi(argv[optind]);
break; break;
case 'L':
nof_tbs = atoi(argv[optind]);
break;
case 'p': case 'p':
cell.nof_ports = atoi(argv[optind]); cell.nof_ports = atoi(argv[optind]);
break; break;
@ -142,22 +137,20 @@ int main(int argc, char **argv) {
bzero(ce, sizeof(cf_t*)*SRSLTE_MAX_PORTS); bzero(ce, sizeof(cf_t*)*SRSLTE_MAX_PORTS);
bzero(slot_symbols, 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.mcs.mod = modulation;
pdsch_cfg.grant.Qm = srslte_mod_bits_x_symbol(pdsch_cfg.grant.mcs.mod);
pdsch_cfg.grant.nof_prb = cell.nof_prb; pdsch_cfg.grant.nof_prb = cell.nof_prb; // Allocate all PRB
for (i=0;i<pdsch_cfg.grant.nof_prb;i++) { for (i=0;i<pdsch_cfg.grant.nof_prb;i++) {
pdsch_cfg.grant.prb_idx[0][i] = true; 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)); 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); /* Configure PDSCH */
// Fill rest of grant structure if (srslte_pdsch_cfg(&pdsch_cfg, cell, NULL, cfi, subframe, 1234, 0)) {
pdsch_cfg.grant.lstart = cell.nof_prb<10?(cfi+1):cfi; fprintf(stderr, "Error configuring PDSCH\n");
pdsch_cfg.grant.nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-pdsch_cfg.grant.lstart; exit(-1);
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;
/* init memory */ /* init memory */
for (i=0;i<cell.nof_ports;i++) { for (i=0;i<cell.nof_ports;i++) {
@ -166,7 +159,7 @@ int main(int argc, char **argv) {
perror("malloc"); perror("malloc");
goto quit; 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; ce[i][j] = 1;
} }
slot_symbols[i] = calloc(sizeof(cf_t) , SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp)); 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) { if (!data) {
perror("malloc"); perror("malloc");
goto quit; goto quit;
@ -199,7 +192,6 @@ int main(int argc, char **argv) {
goto quit; 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()) { if (SRSLTE_VERBOSE_ISNONE()) {
printf("Decoding TBS: %d\r",pdsch_cfg.grant.mcs.tbs); printf("Decoding TBS: %d\r",pdsch_cfg.grant.mcs.tbs);
} }
@ -208,7 +200,8 @@ int main(int argc, char **argv) {
} }
for (rv=0;rv<=rv_idx;rv++) { for (rv=0;rv<=rv_idx;rv++) {
srslte_cbsegm(&pdsch_cfg.cb_segm, pdsch_cfg.grant.mcs.tbs);
pdsch_cfg.rv = rv;
if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer_tx, data, slot_symbols)) { if (srslte_pdsch_encode(&pdsch, &pdsch_cfg, &softbuffer_tx, data, slot_symbols)) {
fprintf(stderr, "Error encoding PDSCH\n"); fprintf(stderr, "Error encoding PDSCH\n");
@ -234,12 +227,9 @@ int main(int argc, char **argv) {
ret = -1; ret = -1;
goto quit; goto quit;
} else { } 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); 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; ret = 0;
quit: quit:
srslte_pdsch_free(&pdsch); srslte_pdsch_free(&pdsch);

@ -163,13 +163,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
free(prbset); free(prbset);
srslte_dl_dci_to_grant_nof_re(&cfg.grant, cell, cfg.sf_idx, cell.nof_prb<10?(cfi+1):cfi); /* Configure rest of pdsch_cfg parameters */
// 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;
cfg.grant.Qm = srslte_mod_bits_x_symbol(cfg.grant.mcs.mod); 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 */ /** Allocate input buffers */
if (mexutils_read_cf(INPUT, &input_signal) < 0) { 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); mexutils_write_uint8(data, &plhs[1], cfg.grant.mcs.tbs, 1);
} }
if (nlhs >= 3) { 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) { 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) { 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); 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.L_prb = mexutils_read_f(p, &prbset);
cfg.grant.n_prb[0] = prbset[0]; cfg.grant.n_prb[0] = prbset[0];
cfg.grant.n_prb[1] = 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 = cfg.grant.L_prb*SRSLTE_NRE;
cfg.grant.M_sc_init = cfg.grant.M_sc; // FIXME: What should M_sc_init be? 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.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); 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("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); int r = srslte_pusch_uci_encode(&pusch, &cfg, &softbuffer, trblkin, uci_data, sf_symbols);
if (r < 0) { if (r < 0) {
mexErrMsgTxt("Error encoding PUSCH\n"); 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); mexutils_write_cf(sf_symbols, &plhs[1], nof_re, 1);
} }
if (nlhs >= 3) { 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); srslte_pusch_free(&pusch);
free(trblkin); free(trblkin);

@ -150,18 +150,16 @@ int main(int argc, char **argv) {
} else { } 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); 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.tbs = tbs;
cfg.grant.mcs.mod = modulation; cfg.grant.mcs.mod = modulation;
cfg.grant.Qm = srslte_mod_bits_x_symbol(modulation);
// Compute PRB allocation if (srslte_pusch_cfg(&cfg, cell, NULL, 0, 0, subframe, 0)) {
if (!srslte_ul_dci_to_grant_prb_allocation(&dci, &cfg.grant, 0, cell.nof_prb)) { fprintf(stderr, "Error configuring PDSCH\n");
cfg.grant.lstart = 0; exit(-1);
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;
} }
if (srslte_pusch_init(&pusch, cell)) { if (srslte_pusch_init(&pusch, cell)) {
@ -197,10 +195,6 @@ int main(int argc, char **argv) {
uci_data.uci_ri = 0; uci_data.uci_ri = 0;
uci_data.uci_ack = 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; srslte_pusch_hopping_cfg_t ul_hopping;
ul_hopping.n_sb = 1; ul_hopping.n_sb = 1;
ul_hopping.hopping_offset = 0; 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.L_prb = mexutils_read_f(p, &prbset);
cfg.grant.n_prb[0] = prbset[0]; cfg.grant.n_prb[0] = prbset[0];
cfg.grant.n_prb[1] = prbset[0]; cfg.grant.n_prb[1] = prbset[0];
cfg.grant.lstart = 0; cfg.nbits.lstart = 0;
cfg.grant.nof_symb = 2*(SRSLTE_CP_NSYMB(cell.cp)-1) - N_srs; 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 = cfg.grant.L_prb*SRSLTE_NRE;
cfg.grant.M_sc_init = cfg.grant.M_sc; // FIXME: What should M_sc_init be? 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.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); 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; 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) { if (!q_bits) {
return; 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) { if (!g_bits) {
return; return;
} }
@ -186,7 +186,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
} }
if (nlhs >= 1) { 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); 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, 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) 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++; 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)) { /* Setup PDSCH configuration for this CFI, SFIDX and RVIDX */
//fprintf(stderr, "Error unpacking PDSCH scheduling DCI message\n"); if (srslte_ue_dl_cfg_grant(q, dci_msg, cfi, sf_idx, rnti, rvidx)) {
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);
return SRSLTE_ERROR; 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) { if (q->pdsch_cfg.rv == 0) {
srslte_softbuffer_rx_reset(&q->softbuffer); 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); int found_dci = srslte_ue_dl_find_dl_dci(q, &dci_msg, q->cfi, sf_idx, rnti);
if (found_dci == 1) { if (found_dci == 1) {
ret = srslte_ue_dl_decode_rnti_rv_packet(q, &dci_msg, data, q->cfi, sf_idx, rnti, rvidx); 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 /* 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, int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
@ -281,56 +286,47 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
return ret; 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; srslte_uci_data_t uci_data;
bzero(&uci_data, sizeof(srslte_uci_data_t)); 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; srslte_uci_data_t uci_data;
bzero(&uci_data, sizeof(srslte_uci_data_t)); 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, 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) cf_t *output_signal)
{ {
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (q != NULL && if (q != NULL &&
grant != NULL &&
output_signal != 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"); fprintf(stderr, "Invalid UL PRB allocation (L_prb=0)\n");
return ret; return SRSLTE_ERROR;
} }
ret = SRSLTE_ERROR; return srslte_ue_ul_pusch_encode_rnti_softbuffer(q, data, uci_data, &q->softbuffer, rnti, output_signal);
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 ret; return ret;
} }
int srslte_ue_ul_pusch_encode_cfg(srslte_ue_ul_t *q, srslte_pusch_cfg_t *cfg, int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q,
uint8_t *data, srslte_uci_data_t uci_data, uint8_t *data, srslte_uci_data_t uci_data,
srslte_softbuffer_tx_t *softbuffer, srslte_softbuffer_tx_t *softbuffer,
uint16_t rnti, uint16_t rnti,
@ -341,23 +337,23 @@ int srslte_ue_ul_pusch_encode_cfg(srslte_ue_ul_t *q, srslte_pusch_cfg_t *cfg,
bzero(q->sf_symbols, sizeof(cf_t)*SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)); bzero(q->sf_symbols, sizeof(cf_t)*SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp));
if (q != NULL && if (q != NULL &&
cfg != NULL && softbuffer != NULL &&
output_signal != 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"); fprintf(stderr, "Error encoding TB\n");
return ret; return ret;
} }
// FIXME: Pregenerate for all possible number of prb // 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"); fprintf(stderr, "Error generating PUSCH DRMS signals\n");
return ret; return ret;
} }
srslte_refsignal_dmrs_pusch_put(&q->dmrs, q->refsignal, srslte_refsignal_dmrs_pusch_put(&q->dmrs, q->refsignal,
cfg->grant.L_prb, q->pusch_cfg.grant.L_prb,
cfg->grant.n_prb_tilde, q->pusch_cfg.grant.n_prb_tilde,
q->sf_symbols); q->sf_symbols);
srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal); 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) { 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)); srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
} }

Loading…
Cancel
Save