Shortened PUSCH/PUCCH working

master
ismagom 10 years ago
parent ccfdb783c9
commit 1035ca1e99

@ -1,6 +1,6 @@
clear
ueConfig=struct('NCellID',25,'RNTI',11,'NULRB',6,'NSubframe',1,'CyclicPrefixUL','Normal','NTxAnts',1,'Hopping','Off');
pucchConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0,'ResourceSize',0);
pucchConfig=struct('NLayers',1,'OrthCover','Off','Shortened',1,'ResourceSize',0);
addpath('../../build/srslte/lib/phch/test')

@ -8,7 +8,7 @@ cqilen=0;
rvs=[0 2];
mods={'16QAM'};
betas=0;
subf=[1:8];
subf=[0:9];
for i=1:length(TBs)
for m=1:length(mods)

@ -107,9 +107,9 @@ namespace ue {
return true;
}
}
bool to_pusch_cfg(srslte_pusch_hopping_cfg_t *hopping_cfg, srslte_pusch_srs_cfg_t *srs_cfg, uint32_t sf_idx, srslte_ue_ul_t *ue_ul) {
bool to_pusch_cfg(srslte_pusch_hopping_cfg_t *hopping_cfg, srslte_refsignal_srs_cfg_t *srs_cfg, uint32_t tti, 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, hopping_cfg, srs_cfg, sf_idx, get_rv())) {
if (srslte_ue_ul_cfg_grant(ue_ul, NULL, hopping_cfg, srs_cfg, tti, get_rv())) {
return false;
}
return true;

@ -175,24 +175,24 @@ 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) {
srslte_pusch_hopping_cfg_t pusch_hopping_cfg;
srslte_pusch_srs_cfg_t pusch_srs_cfg;
srslte_refsignal_srs_cfg_t srs_cfg;
bzero(&pusch_hopping_cfg, sizeof(srslte_pusch_hopping_cfg_t));
bzero(&pusch_srs_cfg, sizeof(srslte_pusch_srs_cfg_t));
bzero(&srs_cfg, sizeof(srslte_refsignal_srs_cfg_t));
pusch_hopping_cfg.n_sb = params_db->get_param(phy_params::PUSCH_HOPPING_N_SB);
pusch_hopping_cfg.hop_mode = params_db->get_param(phy_params::PUSCH_HOPPING_INTRA_SF) ?
pusch_hopping.SRSLTE_PUSCH_HOP_MODE_INTRA_SF :
pusch_hopping.SRSLTE_PUSCH_HOP_MODE_INTER_SF;
srslte_pusch_hopping_cfg_t::SRSLTE_PUSCH_HOP_MODE_INTRA_SF :
srslte_pusch_hopping_cfg_t::SRSLTE_PUSCH_HOP_MODE_INTER_SF;
pusch_hopping_cfg.hopping_offset = params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET);
pusch_hopping_cfg.current_tx_nb = grant->get_current_tx_nb();
pusch_srs_cfg.cs_configured = params_db->get_param(phy_params::SRS_IS_CS_CONFIGURED)?true:false;
pusch_srs_cfg.ue_configured = params_db->get_param(phy_params::SRS_IS_UE_CONFIGURED)?true:false;
pusch_srs_cfg.cs_subf_cfg = (uint32_t) params_db->get_param(phy_params::SRS_CS_SFCFG);
pusch_srs_cfg.cs_bw_cfg = (uint32_t) params_db->get_param(phy_params::SRS_CS_BWCFG);
pusch_srs_cfg.ue_config_idx = (uint32_t) params_db->get_param(phy_params::SRS_UE_CONFIGINDEX);
srs_cfg.cs_configured = params_db->get_param(phy_params::SRS_IS_CS_CONFIGURED)?true:false;
srs_cfg.ue_configured = params_db->get_param(phy_params::SRS_IS_UE_CONFIGURED)?true:false;
srs_cfg.subframe_config = (uint32_t) params_db->get_param(phy_params::SRS_CS_SFCFG);
srs_cfg.bw_cfg = (uint32_t) params_db->get_param(phy_params::SRS_CS_BWCFG);
srs_cfg.I_srs = (uint32_t) params_db->get_param(phy_params::SRS_UE_CONFIGINDEX);
grant->to_pusch_cfg(&pusch_hopping_cfg, &pusch_srs_cfg, tti%10, &ue_ul);
grant->to_pusch_cfg(&pusch_hopping_cfg, &srs_cfg, tti, &ue_ul);
n = srslte_ue_ul_pusch_encode_rnti_softbuffer(&ue_ul,
payload, uci_data,
@ -204,7 +204,7 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof
tti, grant->get_tbs(), srslte_mod_string(ue_ul.pusch_cfg.grant.mcs.mod), ue_ul.pusch_cfg.grant.n_prb[0],
ue_ul.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(), ue_ul.pusch_is_shortened?"yes":"no");
grant->get_rnti(), ue_ul.pusch.shortened?"yes":"no");
} else {

@ -383,8 +383,6 @@ cell.nof_ports = 1;
srslte_ue_ul_set_cfo_enable(&ue_ul, true);
srslte_pusch_hopping_cfg_t hop_cfg;
bzero(&hop_cfg, sizeof(srslte_pusch_hopping_cfg_t));
srslte_refsignal_dmrs_pusch_cfg_t dmrs_cfg;
bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t));
dmrs_cfg.beta_pusch = 1.0;
@ -394,7 +392,7 @@ cell.nof_ports = 1;
dmrs_cfg.cyclic_shift = 0;
dmrs_cfg.cyclic_shift_for_dmrs = 0;
dmrs_cfg.en_dmrs_2 = false;
srslte_ue_ul_set_cfg(&ue_ul, &dmrs_cfg, &hop_cfg, NULL, NULL);
srslte_ue_ul_set_cfg(&ue_ul, &dmrs_cfg, NULL, NULL);
cf_t *ul_signal = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
if (!ul_signal) {

@ -56,7 +56,17 @@ typedef struct SRSLTE_API {
}srslte_refsignal_dmrs_pusch_cfg_t;
typedef struct SRSLTE_API {
uint32_t nof_prb;
float beta_srs;
uint32_t subframe_config;
uint32_t I_srs;
uint32_t bw_cfg;
uint32_t n_srs;
uint32_t k_tc;
uint32_t n_rrc;
uint32_t B;
uint32_t b_hop;
bool cs_configured;
bool ue_configured;
}srslte_refsignal_srs_cfg_t;
/** Uplink DeModulation Reference Signal (DMRS) */
@ -64,6 +74,7 @@ typedef struct SRSLTE_API {
srslte_cell_t cell;
srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg;
srslte_pucch_cfg_t pucch_cfg;
srslte_refsignal_srs_cfg_t srs_cfg;
uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB];
float *tmp_arg;
@ -85,6 +96,9 @@ SRSLTE_API void srslte_refsignal_ul_set_pusch_cfg(srslte_refsignal_ul_t *q,
SRSLTE_API bool srslte_refsignal_ul_set_pucch_cfg(srslte_refsignal_ul_t *q,
srslte_pucch_cfg_t *cfg);
SRSLTE_API bool srslte_refsignal_ul_set_srs_cfg(srslte_refsignal_ul_t *q,
srslte_refsignal_srs_cfg_t *cfg);
SRSLTE_API void srslte_refsignal_r_uv_arg_1prb(float *arg,
uint32_t u);
@ -116,14 +130,26 @@ SRSLTE_API int srslte_refsignal_dmrs_pucch_put(srslte_refsignal_ul_t* q,
cf_t *r_pucch,
cf_t *output);
SRSLTE_API void srslte_refsignal_srs_gen(srslte_refsignal_ul_t *q,
SRSLTE_API int srslte_refsignal_srs_gen(srslte_refsignal_ul_t *q,
uint32_t sf_idx,
cf_t *r_srs);
SRSLTE_API int srslte_refsignal_srs_put(srslte_refsignal_ul_t *q,
uint32_t sf_idx,
cf_t *r_srs,
cf_t *sf_symbols);
SRSLTE_API int srslte_refsignal_srs_send_cs(uint32_t subframe_config,
uint32_t sf_idx);
SRSLTE_API int srslte_refsignal_srs_send_ue(uint32_t I_srs,
uint32_t tti);
SRSLTE_API uint32_t srslte_refsignal_srs_rb_start_cs(uint32_t bw_cfg,
uint32_t nof_prb);
SRSLTE_API uint32_t srslte_refsignal_srs_rb_L_cs(uint32_t bw_cfg,
uint32_t nof_prb);
#endif

@ -105,7 +105,8 @@ SRSLTE_API int srslte_pucch_set_crnti(srslte_pucch_t *q,
uint16_t c_rnti);
SRSLTE_API uint32_t srslte_pucch_nof_symbols(srslte_pucch_cfg_t *cfg,
srslte_pucch_format_t format);
srslte_pucch_format_t format,
bool shortened);
SRSLTE_API int srslte_pucch_encode(srslte_pucch_t *q,
srslte_pucch_format_t format,

@ -48,6 +48,7 @@
#include "srslte/phch/sch.h"
#include "srslte/phch/pusch_cfg.h"
#include "srslte/dft/dft_precoding.h"
#include "srslte/ch_estimation/refsignal_ul.h"
#define SRSLTE_PUSCH_MAX_TDEC_ITERS 5
@ -64,14 +65,6 @@ typedef struct {
uint32_t n_sb;
} srslte_pusch_hopping_cfg_t;
typedef struct {
bool cs_configured;
bool ue_configured;
uint32_t cs_subf_cfg;
uint32_t cs_bw_cfg;
uint32_t ue_config_idx;
} srslte_pusch_srs_cfg_t;
/* PUSCH object */
typedef struct SRSLTE_API {
srslte_cell_t cell;
@ -100,6 +93,7 @@ typedef struct SRSLTE_API {
srslte_sequence_t seq_type2_fo;
srslte_sch_t dl_sch;
bool shortened;
}srslte_pusch_t;
@ -109,19 +103,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_API int srslte_pusch_cfg(srslte_pusch_t *q,
srslte_pusch_cfg_t *cfg,
srslte_dci_msg_t *dci_msg,
srslte_pusch_hopping_cfg_t *hopping_cfg,
srslte_pusch_srs_cfg_t *srs_cfg,
uint32_t sf_idx,
srslte_refsignal_srs_cfg_t *srs_cfg,
uint32_t tti,
uint32_t rvidx);
SRSLTE_API void srslte_pusch_freq_hopping(srslte_ra_ul_grant_t *grant,
srslte_pusch_hopping_cfg_t *hopping,
uint32_t sf_idx,
uint32_t nof_prb);
SRSLTE_API int srslte_pusch_set_rnti(srslte_pusch_t *q,
uint16_t rnti);

@ -106,8 +106,8 @@ SRSLTE_API void srslte_ue_ul_set_cfg(srslte_ue_ul_t *q,
SRSLTE_API int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q,
srslte_dci_msg_t *dci_msg,
srslte_pusch_hopping_cfg_t *hopping_cfg,
srslte_pusch_srs_cfg_t *srs_cfg,
uint32_t sf_idx,
srslte_refsignal_srs_cfg_t *srs_cfg,
uint32_t tti,
uint32_t rvidx);
SRSLTE_API int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q,

@ -235,7 +235,7 @@ static void arg_r_uv_mprb(float *arg, uint32_t M_sc, uint32_t u, uint32_t v) {
}
/* Computes argument of r_u_v signal */
static void compute_pusch_r_uv_arg(srslte_refsignal_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *cfg, uint32_t nof_prb, uint32_t u, uint32_t v) {
static void compute_r_uv_arg(srslte_refsignal_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *cfg, uint32_t nof_prb, uint32_t u, uint32_t v) {
if (nof_prb == 1) {
srslte_refsignal_r_uv_arg_1prb(q->tmp_arg, u);
} else if (nof_prb == 2) {
@ -278,15 +278,8 @@ void srslte_refsignal_dmrs_pusch_put(srslte_refsignal_ul_t *q, cf_t *r_pusch, ui
}
}
/* Generate DRMS for PUSCH signal according to 5.5.2.1 of 36.211 */
int srslte_refsignal_dmrs_pusch_gen(srslte_refsignal_ul_t *q, uint32_t nof_prb, uint32_t sf_idx, cf_t *r_pusch)
{
int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (srslte_refsignal_dmrs_pusch_cfg_isvalid(q, &q->pusch_cfg, nof_prb)) {
ret = SRSLTE_ERROR;
for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) {
/* Computes r sequence */
void compute_r(srslte_refsignal_ul_t *q, uint32_t nof_prb, uint32_t ns) {
// Get group hopping number u
uint32_t f_gh=0;
if (q->pusch_cfg.group_hopping_en) {
@ -301,18 +294,25 @@ int srslte_refsignal_dmrs_pusch_gen(srslte_refsignal_ul_t *q, uint32_t nof_prb,
}
// Compute signal argument
compute_pusch_r_uv_arg(q, &q->pusch_cfg, nof_prb, u, v);
compute_r_uv_arg(q, &q->pusch_cfg, nof_prb, u, v);
}
/* Generate DRMS for PUSCH signal according to 5.5.2.1 of 36.211 */
int srslte_refsignal_dmrs_pusch_gen(srslte_refsignal_ul_t *q, uint32_t nof_prb, uint32_t sf_idx, cf_t *r_pusch)
{
int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (srslte_refsignal_dmrs_pusch_cfg_isvalid(q, &q->pusch_cfg, nof_prb)) {
ret = SRSLTE_ERROR;
for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) {
compute_r(q, nof_prb, ns);
// Add cyclic prefix alpha
float alpha = pusch_alpha(q, &q->pusch_cfg, ns);
if (srslte_verbose == SRSLTE_VERBOSE_DEBUG) {
uint32_t N_sz = largest_prime_lower_than(nof_prb*SRSLTE_NRE);
DEBUG("Generating PUSCH DRMS sequence with parameters:\n",0);
DEBUG("\tbeta: %.1f, nof_prb: %d, u: %d, v: %d, alpha: %f, N_sc: %d, root q: %d, nprs: %d\n",
q->pusch_cfg.beta_pusch, nof_prb, u, v, alpha, N_sz, get_q(u,v,N_sz),q->n_prs_pusch[q->pusch_cfg.delta_ss][ns]);
}
// Do complex exponential and adjust amplitude
for (int i=0;i<SRSLTE_NRE*nof_prb;i++) {
r_pusch[(ns%2)*SRSLTE_NRE*nof_prb+i] = q->pusch_cfg.beta_pusch * cexpf(I*(q->tmp_arg[i] + alpha*i));
@ -492,11 +492,31 @@ int srslte_refsignal_dmrs_pucch_put(srslte_refsignal_ul_t *q, srslte_pucch_forma
return ret;
}
void srslte_refsignal_srs_gen(srslte_refsignal_ul_t *q, uint32_t ns, cf_t *r_srs)
{
uint32_t T_srs_table(uint32_t I_srs) {
uint32_t T_srs;
/* This is Table 8.2-1 */
if (I_srs < 2) {
T_srs = 2;
} else if (I_srs < 7) {
T_srs = 5;
} else if (I_srs < 17) {
T_srs = 10;
} else if (I_srs < 37) {
T_srs = 20;
} else if (I_srs < 77) {
T_srs = 40;
} else if (I_srs < 157) {
T_srs = 80;
} else if (I_srs < 317) {
T_srs = 160;
} else if (I_srs < 637) {
T_srs = 320;
} else {
T_srs = 0;
}
return T_srs;
}
/* Returns 1 if tti is a valid subframe for SRS transmission according to I_srs (UE-specific
* configuration index), as defined in Section 8.1 of 36.213.
@ -504,37 +524,28 @@ void srslte_refsignal_srs_gen(srslte_refsignal_ul_t *q, uint32_t ns, cf_t *r_srs
*/
int srslte_refsignal_srs_send_ue(uint32_t I_srs, uint32_t tti) {
if (I_srs < 1024 && tti < 10240) {
uint32_t T_srs = 0;
uint32_t Toffset = 0;
/* This is Table 8.2-1 */
if (I_srs < 2) {
T_srs = 2;
Toffset = I_srs;
} else if (I_srs < 7) {
T_srs = 5;
Toffset = I_srs-2;
} else if (I_srs < 17) {
T_srs = 10;
Toffset = I_srs-7;
} else if (I_srs < 37) {
T_srs = 20;
Toffset = I_srs-17;
} else if (I_srs < 77) {
T_srs = 40;
Toffset = I_srs-37;
} else if (I_srs < 157) {
T_srs = 80;
Toffset = I_srs-77;
} else if (I_srs < 317) {
T_srs = 160;
Toffset = I_srs-157;
} else if (I_srs < 637) {
T_srs = 320;
Toffset = I_srs-317;
} else {
return 0;
}
if (((tti-Toffset)%T_srs) == 0) {
if (((tti-Toffset)%T_srs_table(I_srs)) == 0) {
return 1;
} else {
return 0;
@ -594,3 +605,156 @@ int srslte_refsignal_srs_send_cs(uint32_t subframe_config, uint32_t sf_idx) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
}
uint32_t m_srs_b[4][4][8] = {{
/* m_srs for 6<n_rb<40. Table 5.5.3.2-1 */
{36, 32, 24, 20, 16, 12, 8, 4},
{12, 16, 4, 4, 4, 4, 4, 4},
{ 4, 8, 4, 4, 4, 4, 4, 4},
{ 4, 4, 4, 4, 4, 4, 4, 4}},
{
/* m_srs for 40<n_rb<60. Table 5.5.3.2-2 */
{48, 48, 40, 36, 32, 24, 20, 16},
{24, 16, 20, 12, 16, 4, 4, 4},
{12, 16, 4, 12, 8, 4, 4, 8},
{ 4, 4, 4, 4, 4, 4, 4, 4}},
{
/* m_srs for 60<n_rb<80. Table 5.5.3.2-3 */
{72, 64, 60, 48, 48, 40, 36, 32},
{24, 32, 20, 24, 16, 20, 12, 16},
{12, 16, 4, 12, 8, 4, 4, 8},
{ 4, 4, 4, 4, 4, 4, 4, 4}},
{
/* m_srs for 80<n_rb<110. Table 5.5.3.2-4 */
{96, 96, 80, 72, 64, 60, 48, 48},
{48, 32, 40, 24, 32, 20, 24, 16},
{24, 16, 20, 12, 16, 4, 12, 8},
{ 4, 4, 4, 4, 4, 4, 4, 4}}};
/* Same tables for Nb */
uint32_t Nb[4][4][8] = {{
{1, 1, 1, 1, 1, 1, 1, 1},
{3, 2, 6, 5, 4, 3, 2, 1},
{3, 2, 1, 1, 1, 1, 1, 1},
{1, 2, 1, 1, 1, 1, 1, 1}},
{
{1, 1, 1, 1, 1, 1, 1, 1},
{2, 3, 2, 3, 2, 6, 5, 4},
{2, 2, 5, 3, 2, 1, 1, 1},
{3, 2, 1, 1, 2, 1, 1, 1}},
{
{1, 1, 1, 1, 1, 1, 1, 1},
{3, 2, 3, 2, 3, 2, 3, 2},
{2, 2, 5, 2, 2, 5, 3, 2},
{3, 4, 1, 3, 2, 1, 1, 2}},
{
{1, 1, 1, 1, 1, 1, 1, 1},
{2, 3, 2, 3, 2, 3, 2, 3},
{2, 2, 2, 2, 2, 5, 2, 2},
{6, 4, 5, 3, 4, 1, 3, 2}}};
uint32_t srsbwtable_idx(uint32_t nof_prb) {
if (nof_prb <= 40) {
return 0;
} else if (nof_prb <= 60) {
return 1;
} else if (nof_prb <= 80) {
return 2;
} else {
return 3;
}
}
/* Returns start of common SRS BW region */
uint32_t srslte_refsignal_srs_rb_start_cs(uint32_t bw_cfg, uint32_t nof_prb) {
if (bw_cfg < 8) {
return nof_prb/2-m_srs_b[srsbwtable_idx(nof_prb)][0][bw_cfg]/2;
}
return 0;
}
/* Returns number of RB defined for the cell-specific SRS */
uint32_t srslte_refsignal_srs_rb_L_cs(uint32_t bw_cfg, uint32_t nof_prb) {
if (bw_cfg < 8) {
return m_srs_b[srsbwtable_idx(nof_prb)][0][bw_cfg];
}
return 0;
}
uint32_t srs_Fb(srslte_refsignal_srs_cfg_t *cfg, uint32_t nof_prb, uint32_t tti) {
uint32_t n_srs = tti/T_srs_table(cfg->I_srs);
uint32_t N_b = Nb[srsbwtable_idx(nof_prb)][cfg->B][cfg->bw_cfg];
uint32_t prod_1=1;
for (uint32_t b=cfg->b_hop;b<cfg->B-1;b++) {
prod_1 *= Nb[srsbwtable_idx(nof_prb)][b][cfg->bw_cfg];
}
uint32_t prod_2 = prod_1*Nb[srsbwtable_idx(nof_prb)][cfg->B][cfg->bw_cfg];
if (N_b%2) {
return N_b/2*((n_srs%prod_2)/prod_1)+((n_srs%prod_2)/prod_1/2);
} else {
return N_b/2*(n_srs/prod_1);
}
}
/* Returns k0: frequency-domain starting position for ue-specific SRS */
uint32_t srs_k0_ue(srslte_refsignal_srs_cfg_t *cfg, uint32_t nof_prb, uint32_t tti) {
if (cfg->bw_cfg < 8 && cfg->B < 4 && cfg->k_tc < 2) {
uint32_t m_srs = m_srs_b[srsbwtable_idx(nof_prb)][cfg->B][cfg->bw_cfg];
uint32_t nb = (4*cfg->n_rrc/m_srs)%Nb[srsbwtable_idx(nof_prb)][cfg->B][cfg->bw_cfg];
if (cfg->b_hop < cfg->B) {
nb += srs_Fb(cfg, nof_prb, tti);
}
uint32_t k0p = srslte_refsignal_srs_rb_start_cs(cfg->bw_cfg, nof_prb)*SRSLTE_NRE + cfg->k_tc;
uint32_t m_sc = m_srs*SRSLTE_NRE/2;
uint32_t k0 = k0p;
for (int b=0;b<cfg->B;b++) {
k0 += 2*m_sc*nb;
}
return k0;
}
return 0;
}
/* Genearte SRS signal as defined in Section 5.5.3.1 */
int srslte_refsignal_srs_gen(srslte_refsignal_ul_t *q, uint32_t sf_idx, cf_t *r_srs)
{
int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (r_srs && q) {
ret = SRSLTE_ERROR;
uint32_t M_sc = srslte_refsignal_srs_rb_L_cs(q->srs_cfg.bw_cfg, q->cell.nof_prb)*SRSLTE_NRE/2;
for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) {
compute_r(q, M_sc/SRSLTE_NRE, ns);
float alpha = 2*M_PI*q->srs_cfg.n_srs/8;
// Do complex exponential and adjust amplitude
for (int i=0;i<M_sc;i++) {
r_srs[(ns%2)*M_sc+i] = q->srs_cfg.beta_srs * cexpf(I*(q->tmp_arg[i] + alpha*i));
}
}
ret = SRSLTE_SUCCESS;
}
return ret;
}
int srslte_refsignal_srs_put(srslte_refsignal_ul_t *q, uint32_t tti, cf_t *r_srs, cf_t *sf_symbols) {
int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (r_srs && q) {
ret = SRSLTE_ERROR;
if (srslte_refsignal_srs_send_ue(q->srs_cfg.I_srs, tti) == 1 &&
srslte_refsignal_srs_send_cs(q->srs_cfg.subframe_config, tti) == 1)
{
uint32_t M_sc = srslte_refsignal_srs_rb_L_cs(q->srs_cfg.bw_cfg, q->cell.nof_prb)*SRSLTE_NRE/2;
uint32_t k0 = srs_k0_ue(&q->srs_cfg, q->cell.nof_prb, tti);
for (int i=0;i<M_sc;i++) {
sf_symbols[SRSLTE_RE_IDX(q->cell.nof_prb, 2*SRSLTE_CP_NSYMB(q->cell.cp)-1, k0 + 2*i)] = r_srs[i];
}
}
ret = SRSLTE_SUCCESS;
}
return ret;
}

@ -107,10 +107,10 @@ uint32_t get_N_sf(srslte_pucch_format_t format, uint32_t slot_idx, bool shortene
return 0;
}
uint32_t srslte_pucch_nof_symbols(srslte_pucch_cfg_t *cfg, srslte_pucch_format_t format) {
uint32_t srslte_pucch_nof_symbols(srslte_pucch_cfg_t *cfg, srslte_pucch_format_t format, bool shortened) {
uint32_t len=0;
for (uint32_t ns=0;ns<2;ns++) {
len += SRSLTE_NRE*get_N_sf(format, ns, cfg->shortened);
len += SRSLTE_NRE*get_N_sf(format, ns, shortened);
}
return len;
}
@ -482,8 +482,8 @@ int srslte_pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format,
ret = SRSLTE_ERROR;
// Shortened PUCCH happen in every cell-specific SRS subframes for Format 1/1a/1b
q->shortened = false;
if (q->pucch_cfg.srs_cs_configured && format < SRSLTE_PUCCH_FORMAT_2) {
q->shortened = false;
// If CQI is not transmitted, PUCCH will be normal unless ACK/NACK and SRS simultaneous transmission is enabled
if (q->pucch_cfg.srs_simul_ack) {
// If simultaneous ACK and SRS is enabled, PUCCH is shortened in cell-specific SRS subframes

@ -86,7 +86,9 @@ static int f_m(srslte_pusch_t *q, srslte_pusch_hopping_cfg_t *hopping, uint32_t
}
/* Computes PUSCH frequency hopping as defined in Section 8.4 of 36.213 */
void srslte_pusch_freq_hopping(srslte_ra_ul_grant_t *grant, srslte_pusch_hopping_cfg_t *hopping, uint32_t sf_idx, uint32_t nof_prb)
void compute_freq_hopping(srslte_pusch_t *q, srslte_ra_ul_grant_t *grant,
srslte_pusch_hopping_cfg_t *hopping,
uint32_t sf_idx)
{
for (uint32_t slot=0;slot<2;slot++) {
@ -113,7 +115,7 @@ void srslte_pusch_freq_hopping(srslte_ra_ul_grant_t *grant, srslte_pusch_hopping
} else {
i = 2*sf_idx+slot;
}
uint32_t n_rb_sb = nof_prb;
uint32_t n_rb_sb = q->cell.nof_prb;
if (hopping->n_sb > 1) {
n_rb_sb = (n_rb_sb-hopping->hopping_offset-hopping->hopping_offset%2)/hopping->n_sb;
}
@ -144,8 +146,12 @@ int pusch_cp(srslte_pusch_t *q, srslte_ra_ul_grant_t *grant, cf_t *input, cf_t *
L_ref = 2;
}
for (uint32_t slot=0;slot<2;slot++) {
uint32_t N_srs = 0;
if (q->shortened && slot == 1) {
N_srs = 1;
}
INFO("Allocating PUSCH %d PRB to index %d at slot %d\n",grant->L_prb, grant->n_prb_tilde[slot], slot);
for (uint32_t l=0;l<SRSLTE_CP_NSYMB(q->cell.cp);l++) {
for (uint32_t l=0;l<SRSLTE_CP_NSYMB(q->cell.cp)-N_srs;l++) {
if (l != L_ref) {
uint32_t idx = SRSLTE_RE_IDX(q->cell.nof_prb, l+slot*SRSLTE_CP_NSYMB(q->cell.cp),
grant->n_prb_tilde[slot]*SRSLTE_NRE);
@ -166,12 +172,12 @@ int pusch_cp(srslte_pusch_t *q, srslte_ra_ul_grant_t *grant, cf_t *input, cf_t *
return SRSLTE_NRE*grant->L_prb;
}
int pusch_put(srslte_pusch_t *q, srslte_ra_ul_grant_t *grant, uint32_t sf_idx, cf_t *input, cf_t *output) {
return pusch_cp(q, grant, sf_idx, input, output, true);
int pusch_put(srslte_pusch_t *q, srslte_ra_ul_grant_t *grant, cf_t *input, cf_t *output) {
return pusch_cp(q, grant, input, output, true);
}
int pusch_get(srslte_pusch_t *q, srslte_ra_ul_grant_t *grant, uint32_t sf_idx, cf_t *input, cf_t *output) {
return pusch_cp(q, grant, sf_idx, input, output, false);
int pusch_get(srslte_pusch_t *q, srslte_ra_ul_grant_t *grant, cf_t *input, cf_t *output) {
return pusch_cp(q, grant, input, output, false);
}
@ -284,6 +290,8 @@ void srslte_pusch_free(srslte_pusch_t *q) {
srslte_sequence_free(&q->seq[i]);
}
srslte_sequence_free(&q->seq_type2_fo);
for (i = 0; i < 4; i++) {
srslte_modem_table_free(&q->mod[i]);
}
@ -297,13 +305,13 @@ void srslte_pusch_free(srslte_pusch_t *q) {
/* 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,
srslte_pusch_hopping_cfg_t *hopping_cfg, srslte_pusch_srs_cfg_t *srs_cfg,
uint32_t sf_idx, uint32_t rvidx)
int srslte_pusch_cfg(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_dci_msg_t *dci_msg,
srslte_pusch_hopping_cfg_t *hopping_cfg, srslte_refsignal_srs_cfg_t *srs_cfg,
uint32_t tti, 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)) {
if (srslte_dci_msg_to_ul_grant(dci_msg, q->cell.nof_prb, hopping_cfg->hopping_offset, &ul_dci, &cfg->grant)) {
fprintf(stderr, "Error unpacking UL grant from DCI message\n");
return SRSLTE_ERROR;
}
@ -314,31 +322,51 @@ int srslte_pusch_cfg(srslte_pusch_cfg_t *cfg, srslte_cell_t cell, srslte_dci_msg
}
/* Compute PUSCH frequency hopping */
srslte_pusch_freq_hopping(&cfg->grant, hopping_cfg, sf_idx, cell.nof_prb);
uint32_t N_srs = 0;
if (hopping_cfg) {
compute_freq_hopping(q, &cfg->grant, hopping_cfg, tti%10);
} else {
cfg->grant.n_prb_tilde[0] = cfg->grant.n_prb[0];
cfg->grant.n_prb_tilde[1] = cfg->grant.n_prb[1];
}
if (srs_cfg) {
q->shortened = false;
if (srs_cfg->cs_configured) {
// If UE-specific SRS is configured, PUSCH is shortened every time UE transmits SRS even if overlaping in the same RB or not
if (srs_cfg->ue_configured) {
if (srslte_refsignal_srs_send_cs(srs_cfg->cs_subf_cfg, sf_idx) == 1 &&
srslte_refsignal_srs_send_ue(srs_cfg->ue_config_idx, sf_idx) == 1)
if (srslte_refsignal_srs_send_cs(srs_cfg->subframe_config, tti%10) == 1 &&
srslte_refsignal_srs_send_ue(srs_cfg->I_srs, tti) == 1)
{
N_srs = 1;
printf("SRS UE transmission\n");
q->shortened = true;
}
}
// If not coincides with UE transmission. PUSCH shall be shortened if cell-specific SRS transmission RB coincides with PUSCH allocated RB
if (!q->shortened) {
uint32_t k0_srs = srslte_refsignal_srs_rb_start_cs(srs_cfg->bw_cfg, q->cell.nof_prb);
uint32_t nrb_srs = srslte_refsignal_srs_rb_L_cs(srs_cfg->bw_cfg, q->cell.nof_prb);
for (uint32_t ns=0;ns<2 && !q->shortened;ns++) {
if ((cfg->grant.n_prb_tilde[ns] >= k0_srs && cfg->grant.n_prb_tilde[ns] < k0_srs + nrb_srs) ||
(cfg->grant.n_prb_tilde[ns] + cfg->grant.L_prb >= k0_srs &&
cfg->grant.n_prb_tilde[ns] + cfg->grant.L_prb < k0_srs + nrb_srs))
{
q->shortened = true;
printf("CS n_prb=%d, L=%d, k0=%d, nrb=%d\n", cfg->grant.n_prb_tilde[ns], cfg->grant.L_prb, k0_srs, nrb_srs);
}
}
}
}
// If not coincides with UE transmission. PUSCH shall be shortened if cell-specific SRS transmission bw coincides with PUSCH allocated RB
if (N_srs == 0) {
if (q->shortened) {
printf("PUSCH is shortened TTI=%d\n", tti);
}
}
/* Compute final number of bits and RE */
srslte_ra_ul_grant_to_nbits(&cfg->grant, cell.cp, N_srs, &cfg->nbits);
srslte_ra_ul_grant_to_nbits(&cfg->grant, q->cell.cp, q->shortened?1:0, &cfg->nbits);
cfg->sf_idx = sf_idx;
cfg->sf_idx = tti%10;
cfg->rv = rvidx;
cfg->cp = cell.cp;
cfg->cp = q->cell.cp;
return SRSLTE_SUCCESS;
}
@ -383,14 +411,14 @@ int srslte_pusch_decode(srslte_pusch_t *q,
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);
n = pusch_get(q, &cfg->grant, sf_symbols, q->d);
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);
n = pusch_get(q, &cfg->grant, ce, q->ce);
if (n != cfg->nbits.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
return SRSLTE_ERROR;
@ -504,7 +532,7 @@ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srs
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);
pusch_put(q, &cfg->grant, q->z, sf_symbols);
ret = SRSLTE_SUCCESS;
}

@ -109,11 +109,11 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
mxFree(hop);
}
pucch_cfg.shortened = false;
pucch.shortened = false;
uint32_t sh = 0;
mexutils_read_uint32_struct(PUCCHCFG, "Shortened", &sh);
if (sh == 1) {
pucch_cfg.shortened = true;
pucch.shortened = true;
}
uint8_t bits[SRSLTE_PUCCH_MAX_BITS];
@ -174,7 +174,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
}
if (nlhs >= 1) {
uint32_t n_bits = srslte_pucch_nof_symbols(&pucch_cfg, format);
uint32_t n_bits = srslte_pucch_nof_symbols(&pucch_cfg, format, pucch.shortened);
mexutils_write_cf(pucch.z, &plhs[0], n_bits, 1);
}

@ -110,14 +110,16 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
uint32_t N_srs = 0;
mexutils_read_uint32_struct(PUSCHCFG, "Shortened", &N_srs);
if (N_srs == 1) {
pusch.shortened = true;
}
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.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.Qm = srslte_mod_bits_x_symbol(cfg.grant.mcs.mod);
if (srslte_pusch_cfg(&cfg, cell, NULL, 0, 0, cfg.sf_idx, cfg.rv)) {
if (srslte_pusch_cfg(&pusch, &cfg, NULL, NULL, NULL, cfg.sf_idx, cfg.rv)) {
fprintf(stderr, "Error configuring PDSCH\n");
exit(-1);
}

@ -152,20 +152,27 @@ int main(int argc, char **argv) {
}
srslte_pusch_hopping_cfg_t ul_hopping;
ul_hopping.n_sb = 1;
ul_hopping.hopping_offset = 0;
ul_hopping.hop_mode = SRSLTE_PUSCH_HOP_MODE_INTER_SF;
ul_hopping.current_tx_nb = 0;
if (srslte_pusch_init(&pusch, cell)) {
fprintf(stderr, "Error creating PDSCH object\n");
goto quit;
}
/* 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;
cfg.grant.Qm = srslte_mod_bits_x_symbol(modulation);
if (srslte_pusch_cfg(&cfg, cell, NULL, 0, 0, subframe, 0)) {
if (srslte_pusch_cfg(&pusch, &cfg, NULL, &ul_hopping, NULL, subframe, 0)) {
fprintf(stderr, "Error configuring PDSCH\n");
exit(-1);
}
if (srslte_pusch_init(&pusch, cell)) {
fprintf(stderr, "Error creating PDSCH object\n");
goto quit;
}
srslte_pusch_set_rnti(&pusch, 1234);
if (srslte_softbuffer_tx_init(&softbuffer, cell)) {
@ -195,14 +202,6 @@ int main(int argc, char **argv) {
uci_data.uci_ri = 0;
uci_data.uci_ack = 0;
srslte_pusch_hopping_cfg_t ul_hopping;
ul_hopping.n_sb = 1;
ul_hopping.hopping_offset = 0;
ul_hopping.hop_mode = SRSLTE_PUSCH_HOP_MODE_INTER_SF;
ul_hopping.current_tx_nb = 0;
srslte_pusch_set_hopping_cfg(&pusch, &ul_hopping);
uint32_t nof_re = SRSLTE_NRE*cell.nof_prb*2*SRSLTE_CP_NSYMB(cell.cp);
sf_symbols = srslte_vec_malloc(sizeof(cf_t) * nof_re);
if (!sf_symbols) {

@ -168,9 +168,10 @@ 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,
srslte_pusch_hopping_cfg_t *hopping_cfg, srslte_pusch_srs_cfg_t *srs_cfg, uint32_t sf_idx, uint32_t rvidx)
srslte_pusch_hopping_cfg_t *hopping_cfg, srslte_refsignal_srs_cfg_t *srs_cfg,
uint32_t tti, uint32_t rvidx)
{
return srslte_pusch_cfg(&q->pusch_cfg, q->cell, dci_msg, hopping_cfg, srs_cfg, sf_idx, rvidx);
return srslte_pusch_cfg(&q->pusch, &q->pusch_cfg, dci_msg, hopping_cfg, srs_cfg, tti, rvidx);
}
/* Choose PUCCH format as in Sec 10.1 of 36.213 and generate PUCCH signal

Loading…
Cancel
Save