Changes on PUSCH DRMS configuration structure

This commit is contained in:
ismagom 2015-03-08 21:28:02 +01:00
parent 4e2f9311b7
commit ee53e11a8b
12 changed files with 86 additions and 70 deletions

View File

@ -427,6 +427,10 @@ int main(int argc, char **argv) {
if (((sfn%2) == 1) && (ue_sync_get_sfidx(&ue_sync) == 1)) {
ue_sync_get_last_timestamp(&ue_sync, &uhd_time);
cfo_correct(&ue_sync.sfind.cfocorr,
prach_buffers[7], prach_buffers[7],
-ue_sync_get_cfo(&ue_sync) / lte_symbol_sz(cell.nof_prb));
timestamp_copy(&next_tx_time, &uhd_time);
timestamp_add(&next_tx_time, 0, 0.01); // send next frame (10 ms)
printf("Send prach sfn: %d. Last frame time = %.6f, send prach time = %.6f\n",
@ -490,7 +494,7 @@ int main(int argc, char **argv) {
printf("ta: %d, n_ta: %d\n", rar_msg.timing_adv_cmd, n_ta);
float time_adv_sec = ((float) n_ta)*TS_PRB(cell.nof_prb);
vec_sc_prod_cfc(ul_signal, 2, ul_signal, SF_LEN_PRB(cell.nof_prb));
vec_sc_prod_cfc(ul_signal, 20, ul_signal, SF_LEN_PRB(cell.nof_prb));
timestamp_copy(&next_tx_time, &uhd_time);
@ -501,7 +505,7 @@ int main(int argc, char **argv) {
timestamp_real(&next_tx_time), time_adv_sec*1000000);
cuhd_send_timed(uhd, ul_signal, SF_LEN_PRB(cell.nof_prb),
next_tx_time.full_secs, next_tx_time.frac_secs);
go_exit = 1;
}
if (sfn >= rar_window_stop) {

View File

@ -52,8 +52,8 @@ typedef struct LIBLTE_API {
typedef struct LIBLTE_API {
refsignal_ul_cfg_t common;
float beta_pusch;
lte_hopping_method_t hopping_method;
uint32_t nof_prb;
bool group_hopping_en;
bool sequence_hopping_en;
}refsignal_drms_pusch_cfg_t;
typedef struct LIBLTE_API {
@ -86,19 +86,31 @@ LIBLTE_API int refsignal_ul_init(refsignal_ul_t *q,
LIBLTE_API void refsignal_ul_free(refsignal_ul_t *q);
LIBLTE_API bool refsignal_drms_pusch_cfg_isvalid(refsignal_ul_t *q,
refsignal_drms_pusch_cfg_t *cfg);
refsignal_drms_pusch_cfg_t *cfg,
uint32_t nof_prb);
LIBLTE_API void refsignal_drms_pusch_put(refsignal_ul_t *q,
refsignal_drms_pusch_cfg_t *cfg,
cf_t *r_pusch,
uint32_t ns_idx,
uint32_t nof_prb,
uint32_t n_prb,
cf_t *sf_symbols);
LIBLTE_API int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, uint32_t ns, cf_t *r_pusch);
LIBLTE_API int refsignal_dmrs_pusch_gen(refsignal_ul_t *q,
refsignal_drms_pusch_cfg_t *cfg,
uint32_t nof_prb,
uint32_t ns,
cf_t *r_pusch);
LIBLTE_API void refsignal_dmrs_pucch_gen(refsignal_ul_t *q, refsignal_drms_pucch_cfg_t *cfg, uint32_t ns, cf_t *r_pucch);
LIBLTE_API void refsignal_dmrs_pucch_gen(refsignal_ul_t *q,
refsignal_drms_pucch_cfg_t *cfg,
uint32_t ns,
cf_t *r_pucch);
LIBLTE_API void refsignal_srs_gen(refsignal_ul_t *q, refsignal_srs_cfg_t *cfg, uint32_t ns, cf_t *r_srs);
LIBLTE_API void refsignal_srs_gen(refsignal_ul_t *q,
refsignal_srs_cfg_t *cfg,
uint32_t ns,
cf_t *r_srs);
#endif

View File

@ -144,10 +144,6 @@ typedef enum LIBLTE_API {
LTE_BPSK = 0, LTE_QPSK = 1, LTE_QAM16 = 2, LTE_QAM64 = 3
} lte_mod_t;
typedef enum LIBLTE_API {
HOPPING_OFF = 0, HOPPING_GROUP = 1, HOPPING_SEQUENCE = 2
} lte_hopping_method_t;
typedef struct LIBLTE_API {
int id;
float fd;

View File

@ -210,13 +210,13 @@ 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(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, uint32_t u, uint32_t v) {
if (cfg->nof_prb == 1) {
static void compute_pusch_r_uv_arg(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, uint32_t nof_prb, uint32_t u, uint32_t v) {
if (nof_prb == 1) {
arg_r_uv_1prb(q->tmp_arg, u);
} else if (cfg->nof_prb == 2) {
} else if (nof_prb == 2) {
arg_r_uv_2prb(q->tmp_arg, u);
} else {
arg_r_uv_mprb(q->tmp_arg, RE_X_RB*cfg->nof_prb, u, v);
arg_r_uv_mprb(q->tmp_arg, RE_X_RB*nof_prb, u, v);
}
}
@ -232,11 +232,11 @@ static float get_alpha(refsignal_ul_t *q, refsignal_ul_cfg_t *cfg, uint32_t ns)
}
bool refsignal_drms_pusch_cfg_isvalid(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg) {
bool refsignal_drms_pusch_cfg_isvalid(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, uint32_t nof_prb) {
if (cfg->common.cyclic_shift < NOF_CSHIFT &&
cfg->common.cyclic_shift_for_drms < NOF_CSHIFT &&
cfg->common.delta_ss < NOF_DELTA_SS &&
cfg->nof_prb < q->cell.nof_prb) {
nof_prb < q->cell.nof_prb) {
return true;
} else {
return false;
@ -245,25 +245,28 @@ bool refsignal_drms_pusch_cfg_isvalid(refsignal_ul_t *q, refsignal_drms_pusch_cf
void refsignal_drms_pusch_put(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg,
cf_t *r_pusch,
uint32_t ns_idx, uint32_t n_prb,
uint32_t ns_idx,
uint32_t nof_prb,
uint32_t n_prb,
cf_t *sf_symbols)
{
if (ns_idx < 2) {
DEBUG("Putting DRMS to n_prb: %d, L: %d, ns_idx: %d\n", n_prb, nof_prb, ns_idx);
uint32_t L = (ns_idx+1)*CP_NSYMB(q->cell.cp)-4;
memcpy(&sf_symbols[RE_IDX(q->cell.nof_prb, L, n_prb*RE_X_RB)], r_pusch, cfg->nof_prb*RE_X_RB*sizeof(cf_t));
memcpy(&sf_symbols[RE_IDX(q->cell.nof_prb, L, n_prb*RE_X_RB)], r_pusch, nof_prb*RE_X_RB*sizeof(cf_t));
}
}
/* Generate DRMS for PUSCH signal according to 5.5.2.1 of 36.211 */
int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, uint32_t ns, cf_t *r_pusch) {
int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, uint32_t nof_prb, uint32_t ns, cf_t *r_pusch) {
int ret = LIBLTE_ERROR_INVALID_INPUTS;
if (refsignal_drms_pusch_cfg_isvalid(q, cfg)) {
if (refsignal_drms_pusch_cfg_isvalid(q, cfg, nof_prb)) {
ret = LIBLTE_ERROR;
// Get group hopping number u
uint32_t f_gh=0;
if (cfg->hopping_method == HOPPING_GROUP) {
if (cfg->group_hopping_en) {
f_gh = q->f_gh[ns];
}
uint32_t u = (f_gh + (q->cell.id%30)+cfg->common.delta_ss)%30;
@ -271,25 +274,25 @@ int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg,
// Get sequence hopping number v
uint32_t v = 0;
if (cfg->nof_prb >= 6 && cfg->hopping_method == HOPPING_SEQUENCE) {
if (nof_prb >= 6 && cfg->sequence_hopping_en) {
v = q->v_pusch[ns][cfg->common.delta_ss];
}
// Compute signal argument
compute_pusch_r_uv_arg(q, cfg, u, v);
compute_pusch_r_uv_arg(q, cfg, nof_prb, u, v);
// Add cyclic prefix alpha
float alpha = get_alpha(q, &cfg->common, ns);
if (verbose == VERBOSE_DEBUG) {
uint32_t N_sz = largest_prime_lower_than(cfg->nof_prb*RE_X_RB);
uint32_t N_sz = largest_prime_lower_than(nof_prb*RE_X_RB);
DEBUG("Generating PUSCH DRMS sequence with parameters:\n",0);
DEBUG("\tu: %d, v: %d, alpha: %f, N_sc: %d, root q: %d\n",
u, v, alpha, N_sz, get_q(u,v,N_sz));
DEBUG("\tnof_prb: %d, u: %d, v: %d, alpha: %f, N_sc: %d, root q: %d\n",
nof_prb, u, v, alpha, N_sz, get_q(u,v,N_sz));
}
// Do complex exponential and adjust amplitude
for (int i=0;i<RE_X_RB*cfg->nof_prb;i++) {
for (int i=0;i<RE_X_RB*nof_prb;i++) {
r_pusch[i] = cfg->beta_pusch * cexpf(I*(q->tmp_arg[i] + alpha*i));
}
ret = 0;

View File

@ -76,18 +76,16 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
bzero(&pusch_cfg, sizeof(refsignal_drms_pusch_cfg_t));
pusch_cfg.group_hopping_en = false;
pusch_cfg.sequence_hopping_en = false;
char *tmp = mexutils_get_char_struct(UECFG, "Hopping");
if (tmp) {
if (!strcmp(tmp, "Group")) {
pusch_cfg.hopping_method = HOPPING_GROUP;
pusch_cfg.group_hopping_en = true;
} else if (!strcmp(tmp, "Sequence")) {
pusch_cfg.hopping_method = HOPPING_SEQUENCE;
} else {
pusch_cfg.hopping_method = HOPPING_OFF;
pusch_cfg.sequence_hopping_en = true;
}
mxFree(tmp);
} else {
pusch_cfg.hopping_method = HOPPING_OFF;
}
@ -104,7 +102,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
mexErrMsgTxt("Error field PRBSet not found in PUSCH config\n");
return;
}
pusch_cfg.nof_prb = mexutils_read_f(p, &prbset);
uint32_t nof_prb = mexutils_read_f(p, &prbset);
if (mexutils_read_uint32_struct(PUSCHCFG, "DynCyclicShift", &pusch_cfg.common.cyclic_shift_for_drms)) {
pusch_cfg.common.cyclic_shift_for_drms = 0;
@ -120,13 +118,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return;
}
mexPrintf("nof_prb: %d, ",pusch_cfg.nof_prb);
mexPrintf("nof_prb: %d, ",nof_prb);
mexPrintf("cyclic_shift: %d, ",pusch_cfg.common.cyclic_shift);
mexPrintf("cyclic_shift_for_drms: %d, ",pusch_cfg.common.cyclic_shift_for_drms);
mexPrintf("delta_ss: %d, ",pusch_cfg.common.delta_ss);
mexPrintf("hopping_method: %d\n, ",pusch_cfg.hopping_method);
cf_t *signal = vec_malloc(2*RE_X_RB*pusch_cfg.nof_prb*sizeof(cf_t));
cf_t *signal = vec_malloc(2*RE_X_RB*nof_prb*sizeof(cf_t));
if (!signal) {
perror("malloc");
return;
@ -139,10 +136,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
bzero(sf_symbols, SF_LEN_RE(cell.nof_prb, cell.cp)*sizeof(cf_t));
for (uint32_t i=0;i<2;i++) {
//mexPrintf("Generating DRMS for ns=%d, nof_prb=%d\n", 2*sf_idx+i,pusch_cfg.nof_prb);
refsignal_dmrs_pusch_gen(&refs, &pusch_cfg, 2*sf_idx+i, &signal[i*RE_X_RB*pusch_cfg.nof_prb]);
refsignal_dmrs_pusch_gen(&refs, &pusch_cfg, nof_prb, 2*sf_idx+i, &signal[i*RE_X_RB*nof_prb]);
}
for (uint32_t i=0;i<2;i++) {
refsignal_drms_pusch_put(&refs, &pusch_cfg, &signal[i*RE_X_RB*pusch_cfg.nof_prb], i, prbset[0], sf_symbols);
refsignal_drms_pusch_put(&refs, &pusch_cfg, &signal[i*RE_X_RB*nof_prb], i, nof_prb, prbset[0], sf_symbols);
}
if (nlhs >= 1) {
mexutils_write_cf(sf_symbols, &plhs[0], SF_LEN_RE(cell.nof_prb, cell.cp), 1);

View File

@ -74,8 +74,6 @@ void parse_args(int argc, char **argv) {
}
}
lte_hopping_method_t hopping_modes[3]={HOPPING_OFF, HOPPING_SEQUENCE, HOPPING_GROUP};
int main(int argc, char **argv) {
refsignal_ul_t refs;
refsignal_drms_pusch_cfg_t pusch_cfg;
@ -100,25 +98,33 @@ int main(int argc, char **argv) {
for (int n=6;n<cell.nof_prb;n++) {
for (int delta_ss=29;delta_ss<NOF_DELTA_SS;delta_ss++) {
for (int cshift=0;cshift<NOF_CSHIFT;cshift++) {
for (int h=1;h<3;h++) {
for (int h=0;h<3;h++) {
for (int ns=0;ns<NSLOTS_X_FRAME;ns++) {
for (int cshift_drms=0;cshift_drms<NOF_CSHIFT;cshift_drms++) {
pusch_cfg.beta_pusch = 1.0;
pusch_cfg.nof_prb = n;
uint32_t nof_prb = n;
pusch_cfg.common.cyclic_shift = cshift;
pusch_cfg.common.cyclic_shift_for_drms = cshift_drms;
pusch_cfg.common.delta_ss = delta_ss;
pusch_cfg.hopping_method = hopping_modes[h];
if (!h) {
pusch_cfg.group_hopping_en = false;
pusch_cfg.sequence_hopping_en = false;
} else if (h == 1) {
pusch_cfg.group_hopping_en = false;
pusch_cfg.sequence_hopping_en = true;
} else if (h == 2) {
pusch_cfg.group_hopping_en = true;
pusch_cfg.sequence_hopping_en = false;
}
pusch_cfg.common.en_drms_2 = true;
printf("Beta: %f, ",pusch_cfg.beta_pusch);
printf("nof_prb: %d, ",pusch_cfg.nof_prb);
printf("nof_prb: %d, ",nof_prb);
printf("cyclic_shift: %d, ",pusch_cfg.common.cyclic_shift);
printf("cyclic_shift_for_drms: %d, ",pusch_cfg.common.cyclic_shift_for_drms);
printf("delta_ss: %d, ",pusch_cfg.common.delta_ss);
printf("hopping_method: %d, ",pusch_cfg.hopping_method);
printf("Slot: %d\n", ns);
refsignal_dmrs_pusch_gen(&refs, &pusch_cfg, ns, signal);
exit(0);
refsignal_dmrs_pusch_gen(&refs, &pusch_cfg, nof_prb, ns, signal);
exit(0);
}
}
}

View File

@ -409,8 +409,8 @@ int pusch_uci_encode_rnti(pusch_t *q, harq_t *harq, uint8_t *data, uci_data_t uc
return LIBLTE_ERROR_INVALID_INPUTS;
}
INFO("Encoding PUSCH SF: %d, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
harq->sf_idx, lte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv);
INFO("Encoding PUSCH SF: %d, Mod %s, RNTI: %d, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
harq->sf_idx, lte_mod_string(harq->mcs.mod), rnti, harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv);
bzero(q->pusch_q, harq->nof_bits);
if (ulsch_uci_encode(&q->dl_sch, harq, data, uci_data, q->pusch_g, q->pusch_q)) {

View File

@ -112,8 +112,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
ra_ul_alloc_t prb_alloc;
bzero(&prb_alloc, sizeof(ra_ul_alloc_t));
prb_alloc.L_prb = mexutils_read_f(p, &prbset);
prb_alloc.n_prb[2*sf_idx] = prbset[0];
prb_alloc.n_prb[2*sf_idx+1] = prbset[0];
prb_alloc.n_prb[0] = prbset[0];
prb_alloc.n_prb[1] = prbset[0];
free(prbset);
mexPrintf("L_prb: %d, n_prb: %d\n", prb_alloc.L_prb, prb_alloc.n_prb[2*sf_idx]);

View File

@ -140,7 +140,7 @@ void ue_ul_reset(ue_ul_t *q) {
void ue_ul_set_pusch_cfg(ue_ul_t *q, refsignal_drms_pusch_cfg_t *pusch_drms_cfg, pusch_hopping_cfg_t *pusch_hopping_cfg)
{
memcpy(&q->pusch_drms_cfg, pusch_drms_cfg, sizeof(refsignal_drms_pucch_cfg_t));
memcpy(&q->pusch_drms_cfg, pusch_drms_cfg, sizeof(refsignal_drms_pusch_cfg_t));
pusch_set_hopping_cfg(&q->pusch, pusch_hopping_cfg);
}
@ -186,27 +186,25 @@ int ue_ul_pusch_uci_encode_rnti(ue_ul_t *q, ra_pusch_t *ra_ul, uint8_t *data, uc
fprintf(stderr, "Error configuring HARQ process\n");
return ret;
}
printf("sf_idx: %d, rnti: %d\n", sf_idx, rnti);
if (pusch_encode_rnti(&q->pusch, &q->harq_process[0], data, rnti, q->sf_symbols)) {
fprintf(stderr, "Error encoding TB\n");
return ret;
}
q->pusch_drms_cfg.nof_prb = ra_ul->prb_alloc.L_prb;
for (uint32_t i=0;i<2;i++) {
// FIXME: Pregenerate for all possible number of prb
if (refsignal_dmrs_pusch_gen(&q->drms, &q->pusch_drms_cfg, 2*sf_idx+i, q->refsignal)) {
if (refsignal_dmrs_pusch_gen(&q->drms, &q->pusch_drms_cfg, ra_ul->prb_alloc.L_prb, 2*sf_idx+i, q->refsignal)) {
fprintf(stderr, "Error generating PUSCH DRMS signals\n");
return ret;
}
printf("n_prb_tilde[%d] = %d\n", i, ra_ul->prb_alloc.n_prb_tilde[i]);
refsignal_drms_pusch_put(&q->drms, &q->pusch_drms_cfg, q->refsignal, i,
ra_ul->prb_alloc.n_prb_tilde[i], q->sf_symbols);
ra_ul->prb_alloc.L_prb, ra_ul->prb_alloc.n_prb_tilde[i], q->sf_symbols);
}
lte_ifft_run_sf(&q->fft, q->sf_symbols, output_signal);
// cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / lte_symbol_sz(q->cell.nof_prb));
cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / lte_symbol_sz(q->cell.nof_prb));
ret = LIBLTE_SUCCESS;
}

View File

@ -96,7 +96,7 @@ void vec_sub_fff(float *x, float *y, float *z, uint32_t len) {
}
void vec_sub_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len) {
return vec_sub_fff((float*) x,(float*) y,(float*) z,2*len);
return vec_sub_fff((float*) x,(float*) y,(float*) z, 2*len);
}
void vec_sum_fff(float *x, float *y, float *z, uint32_t len) {

View File

@ -35,7 +35,6 @@ for prb=3
if (error(k) > 10^-3)
k=1;
end
read_real
k=k+1;
end
end
@ -49,5 +48,5 @@ plot(error);
disp(info)
disp(length(subframe_mat))
n=1:length(subframe_mat(:));
plot(n,real(subframe_mat(:)),n,real(subframe_lib(:)))
%plot(n,real(subframe_mat(:)),n,real(subframe_lib(:)))
plot(abs(subframe_mat(:)-subframe_lib(:)))

View File

@ -1,6 +1,6 @@
clear
ueConfig=struct('NCellID',1,'NULRB',25,'NSubframe',4,'RNTI',82,'CyclicPrefixUL','Normal','NTxAnts',1);
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',[21:24]','Modulation','QPSK','RV',0,'Shortened',0);
ueConfig=struct('NCellID',0,'NULRB',25,'NSubframe',4,'RNTI',82,'CyclicPrefixUL','Normal','NTxAnts',1);
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',[0:2]','Modulation','QPSK','RV',0,'Shortened',0);
addpath('../../debug/lte/phy/lib/phch/test')
@ -10,7 +10,7 @@ addpath('../../debug/lte/phy/lib/phch/test')
% rvs=0;
% betas=0:3:11;
TBs=88;
TBs=56;
cqilen=0;
mods={'QPSK'};
rvs=0;
@ -68,7 +68,8 @@ end
if (length(TBs) == 1)
%disp(info)
n=1:length(mat);
%n=1:length(mat);
%plot(abs(double(mat)-double(lib)))
plot(n,real(lib(n)),n,real(mat(n)))
%plot(n,real(lib(n)),n,real(mat(n)))
plot(abs(waveform_lib-waveform))
end