Commit edfef131 authored by laurent's avatar laurent

add counters for non turbo-codec part

parent fe5058ed
...@@ -56,45 +56,45 @@ ...@@ -56,45 +56,45 @@
void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch)
{ {
int i; int i;
int r; int r;
if (dlsch) { if (dlsch) {
#ifdef DEBUG_DLSCH_FREE #ifdef DEBUG_DLSCH_FREE
printf("Freeing dlsch %p\n",dlsch); printf("Freeing dlsch %p\n",dlsch);
#endif #endif
for (i=0; i<dlsch->Mdlharq; i++) { for (i=0; i<dlsch->Mdlharq; i++) {
#ifdef DEBUG_DLSCH_FREE #ifdef DEBUG_DLSCH_FREE
printf("Freeing dlsch process %d\n",i); printf("Freeing dlsch process %d\n",i);
#endif #endif
if (dlsch->harq_processes[i]) { if (dlsch->harq_processes[i]) {
#ifdef DEBUG_DLSCH_FREE #ifdef DEBUG_DLSCH_FREE
printf("Freeing dlsch process %d (%p)\n",i,dlsch->harq_processes[i]); printf("Freeing dlsch process %d (%p)\n",i,dlsch->harq_processes[i]);
#endif #endif
if (dlsch->harq_processes[i]->b) { if (dlsch->harq_processes[i]->b) {
free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES); free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES);
dlsch->harq_processes[i]->b = NULL; dlsch->harq_processes[i]->b = NULL;
#ifdef DEBUG_DLSCH_FREE #ifdef DEBUG_DLSCH_FREE
printf("Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b); printf("Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b);
#endif #endif
} }
#ifdef DEBUG_DLSCH_FREE #ifdef DEBUG_DLSCH_FREE
printf("Freeing dlsch process %d c (%p)\n",i,dlsch->harq_processes[i]->c); printf("Freeing dlsch process %d c (%p)\n",i,dlsch->harq_processes[i]->c);
#endif #endif
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++) { for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++) {
#ifdef DEBUG_DLSCH_FREE #ifdef DEBUG_DLSCH_FREE
printf("Freeing dlsch process %d c[%d] (%p)\n",i,r,dlsch->harq_processes[i]->c[r]); printf("Freeing dlsch process %d c[%d] (%p)\n",i,r,dlsch->harq_processes[i]->c[r]);
#endif #endif
if (dlsch->harq_processes[i]->c[r]) { if (dlsch->harq_processes[i]->c[r]) {
free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
dlsch->harq_processes[i]->c[r] = NULL; dlsch->harq_processes[i]->c[r] = NULL;
} }
} }
free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t)); free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t));
...@@ -114,78 +114,78 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ ...@@ -114,78 +114,78 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_
LTE_eNB_DLSCH_t *dlsch; LTE_eNB_DLSCH_t *dlsch;
unsigned char exit_flag = 0,i,r,aa,layer; unsigned char exit_flag = 0,i,r,aa,layer;
int re; int re;
unsigned char bw_scaling =1; unsigned char bw_scaling =1;
switch (N_RB_DL) { switch (N_RB_DL) {
case 6: case 6:
bw_scaling =16; bw_scaling =16;
break; break;
case 25:
bw_scaling =4;
break;
case 50:
bw_scaling =2;
break;
default:
bw_scaling =1;
break;
}
dlsch = (LTE_eNB_DLSCH_t *)malloc16(sizeof(LTE_eNB_DLSCH_t));
if (dlsch) {
bzero(dlsch,sizeof(LTE_eNB_DLSCH_t));
dlsch->Kmimo = Kmimo;
dlsch->Mdlharq = Mdlharq;
dlsch->Mlimit = 8;
dlsch->Nsoft = Nsoft;
for (layer=0; layer<4; layer++) {
dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(64*sizeof(int32_t*));
for (aa=0; aa<64; aa++) {
dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
for (re=0;re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
}
}
}
// NOTE: THIS HAS TO BE REVISED FOR RU, commenting to remove memory leak !!!!! case 25:
/* bw_scaling =4;
dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*)); break;
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
}*/ case 50:
bw_scaling =2;
break;
for (i=0; i<10; i++) default:
dlsch->harq_ids[i] = Mdlharq; bw_scaling =1;
break;
}
for (i=0; i<Mdlharq; i++) { dlsch = (LTE_eNB_DLSCH_t *)malloc16(sizeof(LTE_eNB_DLSCH_t));
dlsch->harq_processes[i] = (LTE_DL_eNB_HARQ_t *)malloc16(sizeof(LTE_DL_eNB_HARQ_t));
LOG_T(PHY, "Required mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p\n",
MAX_DLSCH_PAYLOAD_BYTES/bw_scaling,bw_scaling, i,dlsch->harq_processes[i]);
if (dlsch->harq_processes[i]) { if (dlsch) {
bzero(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t)); bzero(dlsch,sizeof(LTE_eNB_DLSCH_t));
// dlsch->harq_processes[i]->first_tx=1; dlsch->Kmimo = Kmimo;
dlsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling); dlsch->Mdlharq = Mdlharq;
dlsch->Mlimit = 8;
dlsch->Nsoft = Nsoft;
if (dlsch->harq_processes[i]->b) { for (layer=0; layer<4; layer++) {
bzero(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES/bw_scaling); dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(64*sizeof(int32_t*));
} else {
printf("Can't get b\n"); for (aa=0; aa<64; aa++) {
exit_flag=1; dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
for (re=0; re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
}
}
} }
if (abstraction_flag==0) { // NOTE: THIS HAS TO BE REVISED FOR RU, commenting to remove memory leak !!!!!
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) { /*
// account for filler in first segment and CRCs for multiple segment case dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+ 768); for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
}*/
for (i=0; i<10; i++)
dlsch->harq_ids[i] = Mdlharq;
for (i=0; i<Mdlharq; i++) {
dlsch->harq_processes[i] = (LTE_DL_eNB_HARQ_t *)malloc16(sizeof(LTE_DL_eNB_HARQ_t));
LOG_T(PHY, "Required mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p\n",
MAX_DLSCH_PAYLOAD_BYTES/bw_scaling,bw_scaling, i,dlsch->harq_processes[i]);
if (dlsch->harq_processes[i]) {
bzero(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t));
// dlsch->harq_processes[i]->first_tx=1;
dlsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);
if (dlsch->harq_processes[i]->b) {
bzero(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);
} else {
printf("Can't get b\n");
exit_flag=1;
}
if (abstraction_flag==0) {
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
// account for filler in first segment and CRCs for multiple segment case
dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+ 768);
if (dlsch->harq_processes[i]->c[r]) { if (dlsch->harq_processes[i]->c[r]) {
bzero(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+ 768); bzero(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+ 768);
} else { } else {
...@@ -205,14 +205,14 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ ...@@ -205,14 +205,14 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_
dlsch->harq_processes[i]->round=0; dlsch->harq_processes[i]->round=0;
} }
return(dlsch); return(dlsch);
}
} }
}
LOG_D(PHY,"new_eNB_dlsch exit flag %d, size of %ld\n", LOG_D(PHY,"new_eNB_dlsch exit flag %d, size of %ld\n",
exit_flag, sizeof(LTE_eNB_DLSCH_t)); exit_flag, sizeof(LTE_eNB_DLSCH_t));
free_eNB_dlsch(dlsch); free_eNB_dlsch(dlsch);
return(NULL); return(NULL);
} }
...@@ -222,10 +222,10 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) ...@@ -222,10 +222,10 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch)
unsigned char Mdlharq; unsigned char Mdlharq;
if (dlsch) { if (dlsch) {
Mdlharq = dlsch->Mdlharq; Mdlharq = dlsch->Mdlharq;
dlsch->rnti = 0; dlsch->rnti = 0;
dlsch->active = 0; dlsch->active = 0;
for (int i=0; i<10; i++) for (int i=0; i<10; i++)
dlsch->harq_ids[i] = Mdlharq; dlsch->harq_ids[i] = Mdlharq;
...@@ -239,49 +239,49 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) ...@@ -239,49 +239,49 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch)
} }
} }
} }
} }
int dlsch_encoding_2threads0(te_params *tep) { int dlsch_encoding_2threads0(te_params *tep) {
LTE_eNB_DLSCH_t *dlsch = tep->dlsch; LTE_eNB_DLSCH_t *dlsch = tep->dlsch;
unsigned int G = tep->G; unsigned int G = tep->G;
unsigned char harq_pid = tep->harq_pid; unsigned char harq_pid = tep->harq_pid;
unsigned short iind; unsigned short iind;
unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb; unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
unsigned int Kr=0,Kr_bytes,r,r_offset=0; unsigned int Kr=0,Kr_bytes,r,r_offset=0;
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs; // unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_IN);
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
for (r=0; r<dlsch->harq_processes[harq_pid]->C>>1; r++) { for (r=0; r<dlsch->harq_processes[harq_pid]->C>>1; r++) {
if (r<dlsch->harq_processes[harq_pid]->Cminus) if (r<dlsch->harq_processes[harq_pid]->Cminus)
Kr = dlsch->harq_processes[harq_pid]->Kminus; Kr = dlsch->harq_processes[harq_pid]->Kminus;
else else
Kr = dlsch->harq_processes[harq_pid]->Kplus; Kr = dlsch->harq_processes[harq_pid]->Kplus;
Kr_bytes = Kr>>3; Kr_bytes = Kr>>3;
// get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14) // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
if (Kr_bytes<=64) if (Kr_bytes<=64)
iind = (Kr_bytes-5); iind = (Kr_bytes-5);
else if (Kr_bytes <=128) else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1); iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256) else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2); iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768) else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3); iind = 123 + ((Kr_bytes-256)>>3);
else { else {
printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes); printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
return(-1); return(-1);
} }
uint8_t tmp[96+12+3+3*6144]= {0}; uint8_t tmp[96+12+3+3*6144]= {0};
...@@ -299,164 +299,164 @@ int dlsch_encoding_2threads0(te_params *tep) { ...@@ -299,164 +299,164 @@ int dlsch_encoding_2threads0(te_params *tep) {
sub_block_interleaving_turbo(4+(Kr_bytes*8), sub_block_interleaving_turbo(4+(Kr_bytes*8),
tmp+96, //&dlsch->harq_processes[harq_pid]->d[r][96], tmp+96, //&dlsch->harq_processes[harq_pid]->d[r][96],
dlsch->harq_processes[harq_pid]->w[r]); dlsch->harq_processes[harq_pid]->w[r]);
}
} }
} // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
// outputs for each code segment, see Section 5.1.5 p.20
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
// outputs for each code segment, see Section 5.1.5 p.20 for (r=0; r<dlsch->harq_processes[harq_pid]->C>>1; r++) {
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
for (r=0; r<dlsch->harq_processes[harq_pid]->C>>1; r++) { G, //G
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], dlsch->harq_processes[harq_pid]->w[r],
G, //G dlsch->harq_processes[harq_pid]->e+r_offset,
dlsch->harq_processes[harq_pid]->w[r], dlsch->harq_processes[harq_pid]->C, // C
dlsch->harq_processes[harq_pid]->e+r_offset, dlsch->Nsoft, // Nsoft,
dlsch->harq_processes[harq_pid]->C, // C dlsch->Mdlharq,
dlsch->Nsoft, // Nsoft, dlsch->Kmimo,
dlsch->Mdlharq, dlsch->harq_processes[harq_pid]->rvidx,
dlsch->Kmimo, dlsch->harq_processes[harq_pid]->Qm,
dlsch->harq_processes[harq_pid]->rvidx, dlsch->harq_processes[harq_pid]->Nl,
dlsch->harq_processes[harq_pid]->Qm, r,
dlsch->harq_processes[harq_pid]->Nl, nb_rb);
r, // m); // r
nb_rb); }
// m); // r
} VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_OUT);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_OUT); return(0);
return(0);
} }
extern int oai_exit; extern int oai_exit;
void *te_thread(void *param) { void *te_thread(void *param) {
pthread_setname_np( pthread_self(),"te processing"); pthread_setname_np( pthread_self(),"te processing");
LOG_I(PHY,"thread te created id=%ld", syscall(__NR_gettid)); LOG_I(PHY,"thread te created id=%ld", syscall(__NR_gettid));
eNB_proc_t *proc = &((te_params *)param)->eNB->proc; eNB_proc_t *proc = &((te_params *)param)->eNB->proc;
while (!oai_exit) { while (!oai_exit) {
if (wait_on_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread")<0) break; if (wait_on_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread")<0) break;
dlsch_encoding_2threads0((te_params*)param); dlsch_encoding_2threads0((te_params*)param);
if (release_thread(&proc->mutex_te,&proc->instance_cnt_te,"te thread")<0) break; if (release_thread(&proc->mutex_te,&proc->instance_cnt_te,"te thread")<0) break;
if (pthread_cond_signal(&proc->cond_te) != 0) { if (pthread_cond_signal(&proc->cond_te) != 0) {
printf("[eNB] ERROR pthread_cond_signal for te thread exit\n"); printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
return(NULL); return(NULL);
}
} }
}
return(NULL); return(NULL);
} }
int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
unsigned char *a, unsigned char *a,
uint8_t num_pdcch_symbols, uint8_t num_pdcch_symbols,
LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch,
int frame, int frame,
uint8_t subframe, uint8_t subframe,
time_stats_t *rm_stats, time_stats_t *rm_stats,
time_stats_t *te_stats, time_stats_t *te_stats,
time_stats_t *i_stats) time_stats_t *i_stats)
{ {
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
unsigned int G; unsigned int G;
unsigned int crc=1; unsigned int crc=1;
unsigned short iind; unsigned short iind;
unsigned char harq_pid = dlsch->harq_ids[subframe]; unsigned char harq_pid = dlsch->harq_ids[subframe];
unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb; unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
unsigned int A; unsigned int A;
unsigned char mod_order; unsigned char mod_order;
unsigned int Kr=0,Kr_bytes,r,r_offset=0; unsigned int Kr=0,Kr_bytes,r,r_offset=0;
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs; // unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
A = dlsch->harq_processes[harq_pid]->TBS; //6228 A = dlsch->harq_processes[harq_pid]->TBS; //6228
mod_order = dlsch->harq_processes[harq_pid]->Qm; mod_order = dlsch->harq_processes[harq_pid]->Qm;
G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,dlsch->harq_processes[harq_pid]->mimo_mode==TM7?7:0); G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,dlsch->harq_processes[harq_pid]->mimo_mode==TM7?7:0);
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
// Add 24-bit crc (polynomial A) to payload // Add 24-bit crc (polynomial A) to payload
crc = crc24a(a, crc = crc24a(a,
A)>>8; A)>>8;
a[A>>3] = ((uint8_t*)&crc)[2]; a[A>>3] = ((uint8_t*)&crc)[2];
a[1+(A>>3)] = ((uint8_t*)&crc)[1]; a[1+(A>>3)] = ((uint8_t*)&crc)[1];
a[2+(A>>3)] = ((uint8_t*)&crc)[0]; a[2+(A>>3)] = ((uint8_t*)&crc)[0];
dlsch->harq_processes[harq_pid]->B = A+24; dlsch->harq_processes[harq_pid]->B = A+24;
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
if (lte_segmentation(dlsch->harq_processes[harq_pid]->b, if (lte_segmentation(dlsch->harq_processes[harq_pid]->b,
dlsch->harq_processes[harq_pid]->c, dlsch->harq_processes[harq_pid]->c,
dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->B,
&dlsch->harq_processes[harq_pid]->C, &dlsch->harq_processes[harq_pid]->C,
&dlsch->harq_processes[harq_pid]->Cplus, &dlsch->harq_processes[harq_pid]->Cplus,
&dlsch->harq_processes[harq_pid]->Cminus, &dlsch->harq_processes[harq_pid]->Cminus,
&dlsch->harq_processes[harq_pid]->Kplus, &dlsch->harq_processes[harq_pid]->Kplus,
&dlsch->harq_processes[harq_pid]->Kminus, &dlsch->harq_processes[harq_pid]->Kminus,
&dlsch->harq_processes[harq_pid]->F)<0) &dlsch->harq_processes[harq_pid]->F)<0)
return(-1); return(-1);
if (proc->instance_cnt_te==0) { if (proc->instance_cnt_te==0) {
printf("[eNB] TE thread busy\n"); printf("[eNB] TE thread busy\n");
exit_fun("TE thread busy"); exit_fun("TE thread busy");
pthread_mutex_unlock( &proc->mutex_te ); pthread_mutex_unlock( &proc->mutex_te );
return(-1); return(-1);
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
++proc->instance_cnt_te; ++proc->instance_cnt_te;
proc->tep.eNB = eNB;
proc->tep.dlsch = dlsch;
proc->tep.G = G;
proc->tep.harq_pid = harq_pid;
// wakeup worker to do second half segments
if (pthread_cond_signal(&proc->cond_te) != 0) {
printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
exit_fun( "ERROR pthread_cond_signal" );
return (-1);
}
pthread_mutex_unlock( &proc->mutex_te ); proc->tep.eNB = eNB;
proc->tep.dlsch = dlsch;
proc->tep.G = G;
proc->tep.harq_pid = harq_pid;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); // wakeup worker to do second half segments
for (r=dlsch->harq_processes[harq_pid]->C>>1; r<dlsch->harq_processes[harq_pid]->C; r++) { if (pthread_cond_signal(&proc->cond_te) != 0) {
printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
if (r<dlsch->harq_processes[harq_pid]->Cminus) exit_fun( "ERROR pthread_cond_signal" );
Kr = dlsch->harq_processes[harq_pid]->Kminus; return (-1);
else }
Kr = dlsch->harq_processes[harq_pid]->Kplus;
pthread_mutex_unlock( &proc->mutex_te );
Kr_bytes = Kr>>3;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
// get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14) for (r=dlsch->harq_processes[harq_pid]->C>>1; r<dlsch->harq_processes[harq_pid]->C; r++) {
if (Kr_bytes<=64)
iind = (Kr_bytes-5); if (r<dlsch->harq_processes[harq_pid]->Cminus)
else if (Kr_bytes <=128) Kr = dlsch->harq_processes[harq_pid]->Kminus;
iind = 59 + ((Kr_bytes-64)>>1); else
else if (Kr_bytes <= 256) Kr = dlsch->harq_processes[harq_pid]->Kplus;
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768) Kr_bytes = Kr>>3;
iind = 123 + ((Kr_bytes-256)>>3);
else { // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes); if (Kr_bytes<=64)
return(-1); iind = (Kr_bytes-5);
} else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
return(-1);
}
start_meas(te_stats); start_meas(te_stats);
...@@ -480,70 +480,70 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, ...@@ -480,70 +480,70 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
stop_meas(i_stats); stop_meas(i_stats);
} }
} }
else { else {
proc->tep.eNB = eNB; proc->tep.eNB = eNB;
proc->tep.dlsch = dlsch; proc->tep.dlsch = dlsch;
proc->tep.G = G; proc->tep.G = G;
// wakeup worker to do second half segments // wakeup worker to do second half segments
if (pthread_cond_signal(&proc->cond_te) != 0) { if (pthread_cond_signal(&proc->cond_te) != 0) {
printf("[eNB] ERROR pthread_cond_signal for te thread exit\n"); printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
return (-1); return (-1);
} }
}
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
// outputs for each code segment, see Section 5.1.5 p.20
for (r=0,r_offset=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
// get information for E for the segments that are handled by the worker thread
if (r<(dlsch->harq_processes[harq_pid]->C>>1)) {
int Nl=dlsch->harq_processes[harq_pid]->Nl;
int Qm=dlsch->harq_processes[harq_pid]->Qm;
int C = dlsch->harq_processes[harq_pid]->C;
int Gp = G/Nl/Qm;
int GpmodC = Gp%C;
if (r < (C-(GpmodC)))
r_offset += Nl*Qm * (Gp/C);
else
r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
} }
else {
start_meas(rm_stats); // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], // outputs for each code segment, see Section 5.1.5 p.20
G, //G
dlsch->harq_processes[harq_pid]->w[r], for (r=0,r_offset=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
dlsch->harq_processes[harq_pid]->e+r_offset,
dlsch->harq_processes[harq_pid]->C, // C // get information for E for the segments that are handled by the worker thread
dlsch->Nsoft, // Nsoft, if (r<(dlsch->harq_processes[harq_pid]->C>>1)) {
dlsch->Mdlharq, int Nl=dlsch->harq_processes[harq_pid]->Nl;
dlsch->Kmimo, int Qm=dlsch->harq_processes[harq_pid]->Qm;
dlsch->harq_processes[harq_pid]->rvidx, int C = dlsch->harq_processes[harq_pid]->C;
dlsch->harq_processes[harq_pid]->Qm, int Gp = G/Nl/Qm;
dlsch->harq_processes[harq_pid]->Nl, int GpmodC = Gp%C;
r, if (r < (C-(GpmodC)))
nb_rb); r_offset += Nl*Qm * (Gp/C);
// m); // r else
stop_meas(rm_stats); r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
}
else {
start_meas(rm_stats);
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
G, //G
dlsch->harq_processes[harq_pid]->w[r],
dlsch->harq_processes[harq_pid]->e+r_offset,
dlsch->harq_processes[harq_pid]->C, // C
dlsch->Nsoft, // Nsoft,
dlsch->Mdlharq,
dlsch->Kmimo,
dlsch->harq_processes[harq_pid]->rvidx,
dlsch->harq_processes[harq_pid]->Qm,
dlsch->harq_processes[harq_pid]->Nl,
r,
nb_rb);
// m); // r
stop_meas(rm_stats);
}
} }
}
// wait for worker to finish // wait for worker to finish
wait_on_busy_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread"); wait_on_busy_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return(0); return(0);
} }
int dlsch_encoding(PHY_VARS_eNB *eNB, int dlsch_encoding(PHY_VARS_eNB *eNB,
unsigned char *a, unsigned char *a,
uint8_t num_pdcch_symbols, uint8_t num_pdcch_symbols,
LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch,
int frame, int frame,
...@@ -565,7 +565,6 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, ...@@ -565,7 +565,6 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
a[1+(A>>3)] = ((uint8_t*)&crc)[1]; a[1+(A>>3)] = ((uint8_t*)&crc)[1];
a[2+(A>>3)] = ((uint8_t*)&crc)[0]; a[2+(A>>3)] = ((uint8_t*)&crc)[0];
// printf("CRC %x (A %d)\n",crc,A); // printf("CRC %x (A %d)\n",crc,A);
dlsch->harq_processes[harq_pid]->B = A+24; dlsch->harq_processes[harq_pid]->B = A+24;
// dlsch->harq_processes[harq_pid]->b = a; // dlsch->harq_processes[harq_pid]->b = a;
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
...@@ -606,9 +605,10 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, ...@@ -606,9 +605,10 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
return(-1); return(-1);
} }
request_t *req=createRequest(ENCODE,sizeof(turboEncode_t)); request_t *req=createRequest(ENCODE,sizeof(turboEncode_t));
union turboReqUnion id={.s={dlsch->rnti,frame,subframe,r,0}}; union turboReqUnion id= {.s={dlsch->rnti,frame,subframe,r,0}};
req->id= id.p; req->id= id.p;
req->decodeIterations=0; req->decodeIterations=0;
req->startUELoop=eNB->proc.threadPool.startProcessingUE;
turboEncode_t * rdata=(turboEncode_t *) req->data; turboEncode_t * rdata=(turboEncode_t *) req->data;
rdata->input=dlsch->harq_processes[harq_pid]->c[r]; rdata->input=dlsch->harq_processes[harq_pid]->c[r];
rdata->Kr_bytes=Kr>>3; rdata->Kr_bytes=Kr>>3;
...@@ -622,7 +622,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, ...@@ -622,7 +622,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
} else { } else {
memset(rdata->output,LTE_NULL, TURBO_SIMD_SOFTBITS); memset(rdata->output,LTE_NULL, TURBO_SIMD_SOFTBITS);
start_meas(te_stats); start_meas(te_stats);
req->creationTime=req->startProcessingTime=rdtsc(); req->startProcessingTime=rdtsc();
threegpplte_turbo_encoder(rdata->input, threegpplte_turbo_encoder(rdata->input,
rdata->Kr_bytes, rdata->Kr_bytes,
rdata->output+96,//&dlsch->harq_processes[harq_pid]->d[r][96], rdata->output+96,//&dlsch->harq_processes[harq_pid]->d[r][96],
...@@ -635,11 +635,12 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, ...@@ -635,11 +635,12 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
req->decodeIterations=0; req->decodeIterations=0;
req->coreId=0; req->coreId=0;
req->processedBy[0]=0; req->processedBy[0]=0;
req->decodeIterations=0; req->decodeIterations=0;
req->next=eNB->proc.threadPool.doneRequests; req->next=eNB->proc.threadPool.doneRequests;
eNB->proc.threadPool.doneRequests=req; eNB->proc.threadPool.doneRequests=req;
stop_meas(i_stats); stop_meas(i_stats);
} }
eNB->proc.threadPool.startProcessingUE=rdtsc();
} }
return 0; return 0;
} }
...@@ -677,157 +678,157 @@ int dlsch_encoding2(PHY_VARS_eNB *eNB, ...@@ -677,157 +678,157 @@ int dlsch_encoding2(PHY_VARS_eNB *eNB,
for (int r=0; r<dlsch->harq_processes[harq_pid]->C; r++) { for (int r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
#ifdef DEBUG_DLSCH_CODING #ifdef DEBUG_DLSCH_CODING
printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n", printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n",
r, r,
G, G,
Kr*3, Kr*3,
mod_order,nb_rb); mod_order,nb_rb);
#endif #endif
start_meas(rm_stats); start_meas(rm_stats);
#ifdef DEBUG_DLSCH_CODING #ifdef DEBUG_DLSCH_CODING
printf("rvidx in encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx); printf("rvidx in encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
#endif #endif
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
G, //G G, //G
dlsch->harq_processes[harq_pid]->w[r], dlsch->harq_processes[harq_pid]->w[r],
dlsch->harq_processes[harq_pid]->e+r_offset, dlsch->harq_processes[harq_pid]->e+r_offset,
dlsch->harq_processes[harq_pid]->C, // C dlsch->harq_processes[harq_pid]->C, // C
dlsch->Nsoft, // Nsoft, dlsch->Nsoft, // Nsoft,
dlsch->Mdlharq, dlsch->Mdlharq,
dlsch->Kmimo, dlsch->Kmimo,
dlsch->harq_processes[harq_pid]->rvidx, dlsch->harq_processes[harq_pid]->rvidx,
dlsch->harq_processes[harq_pid]->Qm, dlsch->harq_processes[harq_pid]->Qm,
dlsch->harq_processes[harq_pid]->Nl, dlsch->harq_processes[harq_pid]->Nl,
r, r,
nb_rb); nb_rb);
// m); // r // m); // r
stop_meas(rm_stats); stop_meas(rm_stats);
#ifdef DEBUG_DLSCH_CODING #ifdef DEBUG_DLSCH_CODING
if (r==dlsch->harq_processes[harq_pid]->C-1) if (r==dlsch->harq_processes[harq_pid]->C-1)
write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4); write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4);
#endif #endif
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return(0); return(0);
} }
int dlsch_encoding_SIC(PHY_VARS_UE *ue, int dlsch_encoding_SIC(PHY_VARS_UE *ue,
unsigned char *a, unsigned char *a,
uint8_t num_pdcch_symbols, uint8_t num_pdcch_symbols,
LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch,
int frame, int frame,
uint8_t subframe, uint8_t subframe,
time_stats_t *rm_stats, time_stats_t *rm_stats,
time_stats_t *te_stats, time_stats_t *te_stats,
time_stats_t *i_stats) time_stats_t *i_stats)
{ {
unsigned int G;
unsigned int crc=1;
unsigned short iind;
LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
unsigned char harq_pid = ue->dlsch[subframe&2][0][0]->rnti;
unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
unsigned int A;
unsigned char mod_order;
unsigned int Kr=0,Kr_bytes,r,r_offset=0;
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
uint8_t beamforming_mode=0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
A = dlsch->harq_processes[harq_pid]->TBS; //6228
// printf("Encoder: A: %d\n",A);
mod_order = dlsch->harq_processes[harq_pid]->Qm;
if(dlsch->harq_processes[harq_pid]->mimo_mode == TM7)
beamforming_mode = 7;
else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM8)
beamforming_mode = 8;
else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10)
beamforming_mode = 9;
G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode);
// if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
#ifdef DEBUG_DLSCH_CODING
printf("SIC encoding thinks this is a new packet \n");
#endif
/*
int i;
printf("dlsch (tx): \n");
for (i=0;i<(A>>3);i++)
printf("%02x.",a[i]);
printf("\n");
*/
// Add 24-bit crc (polynomial A) to payload
crc = crc24a(a,
A)>>8;
a[A>>3] = ((uint8_t*)&crc)[2];
a[1+(A>>3)] = ((uint8_t*)&crc)[1];
a[2+(A>>3)] = ((uint8_t*)&crc)[0];
// printf("CRC %x (A %d)\n",crc,A);
dlsch->harq_processes[harq_pid]->B = A+24; unsigned int G;
// dlsch->harq_processes[harq_pid]->b = a; unsigned int crc=1;
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); unsigned short iind;
if (lte_segmentation(dlsch->harq_processes[harq_pid]->b, LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
dlsch->harq_processes[harq_pid]->c, unsigned char harq_pid = ue->dlsch[subframe&2][0][0]->rnti;
dlsch->harq_processes[harq_pid]->B, unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
&dlsch->harq_processes[harq_pid]->C, unsigned int A;
&dlsch->harq_processes[harq_pid]->Cplus, unsigned char mod_order;
&dlsch->harq_processes[harq_pid]->Cminus, unsigned int Kr=0,Kr_bytes,r,r_offset=0;
&dlsch->harq_processes[harq_pid]->Kplus, // unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
&dlsch->harq_processes[harq_pid]->Kminus, uint8_t beamforming_mode=0;
&dlsch->harq_processes[harq_pid]->F)<0)
return(-1);
for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
if (r<dlsch->harq_processes[harq_pid]->Cminus) A = dlsch->harq_processes[harq_pid]->TBS; //6228
Kr = dlsch->harq_processes[harq_pid]->Kminus; // printf("Encoder: A: %d\n",A);
else mod_order = dlsch->harq_processes[harq_pid]->Qm;
Kr = dlsch->harq_processes[harq_pid]->Kplus;
if(dlsch->harq_processes[harq_pid]->mimo_mode == TM7)
Kr_bytes = Kr>>3; beamforming_mode = 7;
else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM8)
// get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14) beamforming_mode = 8;
if (Kr_bytes<=64) else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10)
iind = (Kr_bytes-5); beamforming_mode = 9;
else if (Kr_bytes <=128) G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode);
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
return(-1);
}
// if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
#ifdef DEBUG_DLSCH_CODING #ifdef DEBUG_DLSCH_CODING
printf("Generating Code Segment %d (%d bits)\n",r,Kr); printf("SIC encoding thinks this is a new packet \n");
// generate codewords #endif
/*
int i;
printf("dlsch (tx): \n");
for (i=0;i<(A>>3);i++)
printf("%02x.",a[i]);
printf("\n");
*/
// Add 24-bit crc (polynomial A) to payload
crc = crc24a(a,
A)>>8;
a[A>>3] = ((uint8_t*)&crc)[2];
a[1+(A>>3)] = ((uint8_t*)&crc)[1];
a[2+(A>>3)] = ((uint8_t*)&crc)[0];
// printf("CRC %x (A %d)\n",crc,A);
dlsch->harq_processes[harq_pid]->B = A+24;
// dlsch->harq_processes[harq_pid]->b = a;
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
if (lte_segmentation(dlsch->harq_processes[harq_pid]->b,
dlsch->harq_processes[harq_pid]->c,
dlsch->harq_processes[harq_pid]->B,
&dlsch->harq_processes[harq_pid]->C,
&dlsch->harq_processes[harq_pid]->Cplus,
&dlsch->harq_processes[harq_pid]->Cminus,
&dlsch->harq_processes[harq_pid]->Kplus,
&dlsch->harq_processes[harq_pid]->Kminus,
&dlsch->harq_processes[harq_pid]->F)<0)
return(-1);
for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
if (r<dlsch->harq_processes[harq_pid]->Cminus)
Kr = dlsch->harq_processes[harq_pid]->Kminus;
else
Kr = dlsch->harq_processes[harq_pid]->Kplus;
Kr_bytes = Kr>>3;
// get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
return(-1);
}
printf("bits_per_codeword (Kr)= %d, A %d\n",Kr,A);
printf("N_RB = %d\n",nb_rb); #ifdef DEBUG_DLSCH_CODING
printf("Ncp %d\n",frame_parms->Ncp); printf("Generating Code Segment %d (%d bits)\n",r,Kr);
printf("mod_order %d\n",mod_order); // generate codewords
printf("bits_per_codeword (Kr)= %d, A %d\n",Kr,A);
printf("N_RB = %d\n",nb_rb);
printf("Ncp %d\n",frame_parms->Ncp);
printf("mod_order %d\n",mod_order);
#endif #endif
#ifdef DEBUG_DLSCH_CODING #ifdef DEBUG_DLSCH_CODING
printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]); printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]);
#endif #endif
start_meas(te_stats); start_meas(te_stats);
uint8_t tmp[96+12+3+3*6144]= {0}; uint8_t tmp[96+12+3+3*6144]= {0};
...@@ -853,52 +854,52 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue, ...@@ -853,52 +854,52 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue,
tmp+96, //&dlsch->harq_processes[harq_pid]->d[r][96], tmp+96, //&dlsch->harq_processes[harq_pid]->d[r][96],
dlsch->harq_processes[harq_pid]->w[r]); dlsch->harq_processes[harq_pid]->w[r]);
stop_meas(i_stats); stop_meas(i_stats);
} }
} }
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
// outputs for each code segment, see Section 5.1.5 p.20 // outputs for each code segment, see Section 5.1.5 p.20
for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) { for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
#ifdef DEBUG_DLSCH_CODING #ifdef DEBUG_DLSCH_CODING
printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n", printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n",
r, r,
G, G,
Kr*3, Kr*3,
mod_order,nb_rb); mod_order,nb_rb);
#endif #endif
start_meas(rm_stats); start_meas(rm_stats);
#ifdef DEBUG_DLSCH_CODING #ifdef DEBUG_DLSCH_CODING
printf("rvidx in SIC encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx); printf("rvidx in SIC encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
#endif #endif
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
G, //G G, //G
dlsch->harq_processes[harq_pid]->w[r], dlsch->harq_processes[harq_pid]->w[r],
dlsch->harq_processes[harq_pid]->e+r_offset, dlsch->harq_processes[harq_pid]->e+r_offset,
dlsch->harq_processes[harq_pid]->C, // C dlsch->harq_processes[harq_pid]->C, // C
dlsch->Nsoft, // Nsoft, dlsch->Nsoft, // Nsoft,
dlsch->Mdlharq, dlsch->Mdlharq,
dlsch->Kmimo, dlsch->Kmimo,
dlsch->harq_processes[harq_pid]->rvidx, dlsch->harq_processes[harq_pid]->rvidx,
dlsch->harq_processes[harq_pid]->Qm, dlsch->harq_processes[harq_pid]->Qm,
dlsch->harq_processes[harq_pid]->Nl, dlsch->harq_processes[harq_pid]->Nl,
r, r,
nb_rb); nb_rb);
// m); // r // m); // r
stop_meas(rm_stats); stop_meas(rm_stats);
#ifdef DEBUG_DLSCH_CODING #ifdef DEBUG_DLSCH_CODING
if (r==dlsch->harq_processes[harq_pid]->C-1) if (r==dlsch->harq_processes[harq_pid]->C-1)
write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4); write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4);
#endif #endif
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return(0); return(0);
} }
......
...@@ -80,29 +80,29 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin ...@@ -80,29 +80,29 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin
uint8_t exit_flag = 0; uint8_t exit_flag = 0;
unsigned char bw_scaling; unsigned char bw_scaling;
switch (N_RB_UL) { switch (N_RB_UL) {
case 6: case 6:
bw_scaling =16; bw_scaling =16;
break; break;
case 25: case 25:
bw_scaling =4; bw_scaling =4;
break; break;
case 50: case 50:
bw_scaling =2; bw_scaling =2;
break; break;
default: default:
bw_scaling =1; bw_scaling =1;
break; break;
} }
ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t)); ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t));
if (ulsch) { if (ulsch) {
memset(ulsch,0,sizeof(LTE_eNB_ULSCH_t)); memset(ulsch,0,sizeof(LTE_eNB_ULSCH_t));
ulsch->max_turbo_iterations = max_turbo_iterations; ulsch->max_turbo_iterations = max_turbo_iterations;
ulsch->Mlimit = 4; ulsch->Mlimit = 4;
for (int i=0; i<8; i++) { for (int i=0; i<8; i++) {
...@@ -126,69 +126,69 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin ...@@ -126,69 +126,69 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin
return(ulsch); return(ulsch);
} }
LOG_E(PHY,"new_ue_ulsch: exit_flag = %d\n",exit_flag); LOG_E(PHY,"new_ue_ulsch: exit_flag = %d\n",exit_flag);
free_eNB_ulsch(ulsch); free_eNB_ulsch(ulsch);
return(NULL); return(NULL);
} }
void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch) void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch)
{ {
unsigned char i; unsigned char i;
//ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t)); //ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t));
if (ulsch) { if (ulsch) {
ulsch->rnti = 0; ulsch->rnti = 0;
for (i=0; i<8; i++) { for (i=0; i<8; i++) {
if (ulsch->harq_processes[i]) { if (ulsch->harq_processes[i]) {
// ulsch->harq_processes[i]->Ndi = 0; // ulsch->harq_processes[i]->Ndi = 0;
ulsch->harq_processes[i]->status = 0; ulsch->harq_processes[i]->status = 0;
//ulsch->harq_processes[i]->phich_active = 0; //this will be done later after transmission of PHICH //ulsch->harq_processes[i]->phich_active = 0; //this will be done later after transmission of PHICH
ulsch->harq_processes[i]->phich_ACK = 0; ulsch->harq_processes[i]->phich_ACK = 0;
ulsch->harq_processes[i]->round = 0; ulsch->harq_processes[i]->round = 0;
ulsch->harq_processes[i]->rar_alloc = 0; ulsch->harq_processes[i]->rar_alloc = 0;
ulsch->harq_processes[i]->first_rb = 0; ulsch->harq_processes[i]->first_rb = 0;
ulsch->harq_processes[i]->nb_rb = 0; ulsch->harq_processes[i]->nb_rb = 0;
ulsch->harq_processes[i]->TBS = 0; ulsch->harq_processes[i]->TBS = 0;
ulsch->harq_processes[i]->Or1 = 0; ulsch->harq_processes[i]->Or1 = 0;
ulsch->harq_processes[i]->Or2 = 0; ulsch->harq_processes[i]->Or2 = 0;
for ( int j = 0; j < 2; j++ ) { for ( int j = 0; j < 2; j++ ) {
ulsch->harq_processes[i]->o_RI[j] = 0; ulsch->harq_processes[i]->o_RI[j] = 0;
}
ulsch->harq_processes[i]->O_ACK = 0;
ulsch->harq_processes[i]->srs_active = 0;
ulsch->harq_processes[i]->rvidx = 0;
ulsch->harq_processes[i]->Msc_initial = 0;
ulsch->harq_processes[i]->Nsymb_initial = 0;
}
} }
ulsch->harq_processes[i]->O_ACK = 0; ulsch->beta_offset_cqi_times8 = 0;
ulsch->harq_processes[i]->srs_active = 0; ulsch->beta_offset_ri_times8 = 0;
ulsch->harq_processes[i]->rvidx = 0; ulsch->beta_offset_harqack_times8 = 0;
ulsch->harq_processes[i]->Msc_initial = 0; ulsch->Msg3_active = 0;
ulsch->harq_processes[i]->Nsymb_initial = 0;
}
} }
ulsch->beta_offset_cqi_times8 = 0;
ulsch->beta_offset_ri_times8 = 0;
ulsch->beta_offset_harqack_times8 = 0;
ulsch->Msg3_active = 0;
}
} }
uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH) uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH)
{ {
uint8_t crc; uint8_t crc;
crc = cqi[CQI_LENGTH>>3]; crc = cqi[CQI_LENGTH>>3];
// printf("crc1: %x, shift %d\n",crc,CQI_LENGTH&0x7); // printf("crc1: %x, shift %d\n",crc,CQI_LENGTH&0x7);
crc = (crc<<(CQI_LENGTH&0x7)); crc = (crc<<(CQI_LENGTH&0x7));
// clear crc bits // clear crc bits
// ((char *)cqi)[CQI_LENGTH>>3] &= 0xff>>(8-(CQI_LENGTH&0x7)); // ((char *)cqi)[CQI_LENGTH>>3] &= 0xff>>(8-(CQI_LENGTH&0x7));
// printf("crc2: %x, cqi0 %x\n",crc,cqi[1+(CQI_LENGTH>>3)]); // printf("crc2: %x, cqi0 %x\n",crc,cqi[1+(CQI_LENGTH>>3)]);
crc |= (cqi[1+(CQI_LENGTH>>3)])>>(8-(CQI_LENGTH&0x7)); crc |= (cqi[1+(CQI_LENGTH>>3)])>>(8-(CQI_LENGTH&0x7));
// clear crc bits // clear crc bits
//(((char *)cqi)[1+(CQI_LENGTH>>3)]) = 0; //(((char *)cqi)[1+(CQI_LENGTH>>3)]) = 0;
// printf("crc : %x\n",crc); // printf("crc : %x\n",crc);
return(crc); return(crc);
} }
...@@ -199,135 +199,135 @@ uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH) ...@@ -199,135 +199,135 @@ uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH)
int ulsch_decoding_data_2thread0(td_params* tdp) { int ulsch_decoding_data_2thread0(td_params* tdp) {
PHY_VARS_eNB *eNB = tdp->eNB; PHY_VARS_eNB *eNB = tdp->eNB;
int UE_id = tdp->UE_id; int UE_id = tdp->UE_id;
int harq_pid = tdp->harq_pid; int harq_pid = tdp->harq_pid;
int llr8_flag = tdp->llr8_flag; int llr8_flag = tdp->llr8_flag;
unsigned int r,r_offset=0,Kr,Kr_bytes,iind; unsigned int r,r_offset=0,Kr,Kr_bytes,iind;
uint8_t crc_type; uint8_t crc_type;
int offset = 0; int offset = 0;
int ret = 1; int ret = 1;
int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)]; int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
int Q_m = ulsch_harq->Qm; int Q_m = ulsch_harq->Qm;
int G = ulsch_harq->G; int G = ulsch_harq->G;
uint32_t E=0; uint32_t E=0;
uint32_t Gp,GpmodC,Nl=1; uint32_t Gp,GpmodC,Nl=1;
uint32_t C = ulsch_harq->C; uint32_t C = ulsch_harq->C;
turboDecoder * tc=llr8_flag? turboDecoder * tc=llr8_flag?
phy_threegpplte_turbo_decoder8: phy_threegpplte_turbo_decoder8:
phy_threegpplte_turbo_decoder16 ; phy_threegpplte_turbo_decoder16 ;
// go through first half of segments to get r_offset // go through first half of segments to get r_offset
for (r=0; r<(ulsch_harq->C/2); r++) { for (r=0; r<(ulsch_harq->C/2); r++) {
// Get Turbo interleaver parameters // Get Turbo interleaver parameters
if (r<ulsch_harq->Cminus) if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus; Kr = ulsch_harq->Kminus;
else else
Kr = ulsch_harq->Kplus; Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
AssertFatal(1==0,"ulsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
}
// This is stolen from rate-matching algorithm to get the value of E Kr_bytes = Kr>>3;
Gp = G/Nl/Q_m;
GpmodC = Gp%C;
if (r < (C-(GpmodC)))
E = Nl*Q_m * (Gp/C);
else
E = Nl*Q_m * ((GpmodC==0?0:1) + (Gp/C));
r_offset += E;
if (r==0) { if (Kr_bytes<=64)
offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0); iind = (Kr_bytes-5);
} else { else if (Kr_bytes <=128)
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0)); iind = 59 + ((Kr_bytes-64)>>1);
} else if (Kr_bytes <= 256)
} iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
AssertFatal(1==0,"ulsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
}
// go through second half of segments // This is stolen from rate-matching algorithm to get the value of E
for (; r<(ulsch_harq->C); r++) {
Gp = G/Nl/Q_m;
GpmodC = Gp%C;
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]); if (r < (C-(GpmodC)))
// Get Turbo interleaver parameters E = Nl*Q_m * (Gp/C);
if (r<ulsch_harq->Cminus) else
Kr = ulsch_harq->Kminus; E = Nl*Q_m * ((GpmodC==0?0:1) + (Gp/C));
else
Kr = ulsch_harq->Kplus; r_offset += E;
Kr_bytes = Kr>>3; if (r==0) {
offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
if (Kr_bytes<=64) } else {
iind = (Kr_bytes-5); offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
else if (Kr_bytes <=128) }
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
LOG_E(PHY,"ulsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
return(-1);
} }
// go through second half of segments
for (; r<(ulsch_harq->C); r++) {
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
LOG_E(PHY,"ulsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
return(-1);
}
#ifdef DEBUG_ULSCH_DECODING #ifdef DEBUG_ULSCH_DECODING
printf("f1 %d, f2 %d, F %d\n",f1f2mat_old[2*iind],f1f2mat_old[1+(2*iind)],(r==0) ? ulsch_harq->F : 0); printf("f1 %d, f2 %d, F %d\n",f1f2mat_old[2*iind],f1f2mat_old[1+(2*iind)],(r==0) ? ulsch_harq->F : 0);
#endif #endif
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short)); memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8), ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
(uint8_t*)&dummy_w[r][0], (uint8_t*)&dummy_w[r][0],
(r==0) ? ulsch_harq->F : 0); (r==0) ? ulsch_harq->F : 0);
#ifdef DEBUG_ULSCH_DECODING #ifdef DEBUG_ULSCH_DECODING
printf("Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...\n", printf("Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...\n",
r, G, r, G,
Kr*3, Kr*3,
Q_m, Q_m,
nb_rb, nb_rb,
ulsch_harq->Nl); ulsch_harq->Nl);
#endif #endif
if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r], if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
G, G,
ulsch_harq->w[r], ulsch_harq->w[r],
(uint8_t*) &dummy_w[r][0], (uint8_t*) &dummy_w[r][0],
ulsch_harq->e+r_offset, ulsch_harq->e+r_offset,
ulsch_harq->C, ulsch_harq->C,
NSOFT, NSOFT,
0, //Uplink 0, //Uplink
1, 1,
ulsch_harq->rvidx, ulsch_harq->rvidx,
(ulsch_harq->round==0)?1:0, // clear (ulsch_harq->round==0)?1:0, // clear
ulsch_harq->Qm, ulsch_harq->Qm,
1, 1,
r, r,
&E)==-1) { &E)==-1) {
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n"); LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
return(-1); return(-1);
} }
r_offset += E; r_offset += E;
int16_t soft_bits[3*8*6144+12+96] __attribute__((aligned(32))); int16_t soft_bits[3*8*6144+12+96] __attribute__((aligned(32)));
sub_block_deinterleaving_turbo(4+Kr, sub_block_deinterleaving_turbo(4+Kr,
...@@ -343,83 +343,83 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { ...@@ -343,83 +343,83 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
uint8_t decoded_bytes[3+768] __attribute__((aligned(32))); uint8_t decoded_bytes[3+768] __attribute__((aligned(32)));
ret = tc(soft_bits+96, ret = tc(soft_bits+96,
decoded_bytes, decoded_bytes,
Kr, Kr,
f1f2mat_old[iind*2], f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1], f1f2mat_old[(iind*2)+1],
ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS, ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
crc_type, crc_type,
(r==0) ? ulsch_harq->F : 0, (r==0) ? ulsch_harq->F : 0,
&eNB->ulsch_tc_init_stats, &eNB->ulsch_tc_init_stats,
&eNB->ulsch_tc_alpha_stats, &eNB->ulsch_tc_alpha_stats,
&eNB->ulsch_tc_beta_stats, &eNB->ulsch_tc_beta_stats,
&eNB->ulsch_tc_gamma_stats, &eNB->ulsch_tc_gamma_stats,
&eNB->ulsch_tc_ext_stats, &eNB->ulsch_tc_ext_stats,
&eNB->ulsch_tc_intl1_stats, &eNB->ulsch_tc_intl1_stats,
&eNB->ulsch_tc_intl2_stats); &eNB->ulsch_tc_intl2_stats);
// Reassembly of Transport block here // Reassembly of Transport block here
if (ret != (1+ulsch->max_turbo_iterations)) { if (ret != (1+ulsch->max_turbo_iterations)) {
if (r<ulsch_harq->Cminus) if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus; Kr = ulsch_harq->Kminus;
else else
Kr = ulsch_harq->Kplus; Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3; Kr_bytes = Kr>>3;
memcpy(ulsch_harq->b+offset, memcpy(ulsch_harq->b+offset,
decoded_bytes, decoded_bytes,
Kr_bytes - ((ulsch_harq->C>1)?3:0)); Kr_bytes - ((ulsch_harq->C>1)?3:0));
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0)); offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
} else { } else {
break; break;
}
} }
}
return(ret); return(ret);
} }
extern int oai_exit; extern int oai_exit;
void *td_thread(void *param) { void *td_thread(void *param) {
pthread_setname_np( pthread_self(), "td processing"); pthread_setname_np( pthread_self(), "td processing");
PHY_VARS_eNB *eNB = ((td_params*)param)->eNB; PHY_VARS_eNB *eNB = ((td_params*)param)->eNB;
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
while (!oai_exit) { while (!oai_exit) {
if (wait_on_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread")<0) break; if (wait_on_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread")<0) break;
((td_params*)param)->ret = ulsch_decoding_data_2thread0((td_params*)param); ((td_params*)param)->ret = ulsch_decoding_data_2thread0((td_params*)param);
if (release_thread(&proc->mutex_td,&proc->instance_cnt_td,"td thread")<0) break; if (release_thread(&proc->mutex_td,&proc->instance_cnt_td,"td thread")<0) break;
if (pthread_cond_signal(&proc->cond_td) != 0) { if (pthread_cond_signal(&proc->cond_td) != 0) {
printf("[eNB] ERROR pthread_cond_signal for td thread exit\n"); printf("[eNB] ERROR pthread_cond_signal for td thread exit\n");
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
return(NULL); return(NULL);
}
} }
}
return(NULL); return(NULL);
} }
int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) { int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) {
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
unsigned int r,r_offset=0,Kr,Kr_bytes,iind; unsigned int r,r_offset=0,Kr,Kr_bytes,iind;
uint8_t crc_type; uint8_t crc_type;
int offset = 0; int offset = 0;
int ret = 1; int ret = 1;
int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)]; int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
int G = ulsch_harq->G; int G = ulsch_harq->G;
unsigned int E; unsigned int E;
int Cby2; int Cby2;
struct timespec wait; struct timespec wait;
...@@ -429,107 +429,107 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr ...@@ -429,107 +429,107 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
phy_threegpplte_turbo_decoder8: phy_threegpplte_turbo_decoder8:
phy_threegpplte_turbo_decoder16 ; phy_threegpplte_turbo_decoder16 ;
if (ulsch_harq->C>1) { // wakeup worker if more than 1 segment if (ulsch_harq->C>1) { // wakeup worker if more than 1 segment
if (pthread_mutex_timedlock(&proc->mutex_td,&wait) != 0) { if (pthread_mutex_timedlock(&proc->mutex_td,&wait) != 0) {
printf("[eNB] ERROR pthread_mutex_lock for TD thread (IC %d)\n", proc->instance_cnt_td); printf("[eNB] ERROR pthread_mutex_lock for TD thread (IC %d)\n", proc->instance_cnt_td);
exit_fun( "error locking mutex_fep" ); exit_fun( "error locking mutex_fep" );
return -1; return -1;
} }
if (proc->instance_cnt_td==0) {
printf("[eNB] TD thread busy\n");
exit_fun("TD thread busy");
pthread_mutex_unlock( &proc->mutex_td );
return -1;
}
++proc->instance_cnt_td;
proc->tdp.eNB = eNB;
proc->tdp.UE_id = UE_id;
proc->tdp.harq_pid = harq_pid;
proc->tdp.llr8_flag = llr8_flag;
// wakeup worker to do second half segments
if (pthread_cond_signal(&proc->cond_td) != 0) {
printf("[eNB] ERROR pthread_cond_signal for td thread exit\n");
exit_fun( "ERROR pthread_cond_signal" );
return (1+ulsch->max_turbo_iterations);
}
pthread_mutex_unlock( &proc->mutex_td ); if (proc->instance_cnt_td==0) {
Cby2 = ulsch_harq->C/2; printf("[eNB] TD thread busy\n");
} exit_fun("TD thread busy");
else { pthread_mutex_unlock( &proc->mutex_td );
Cby2 = 1; return -1;
} }
// go through first half of segments in main thread ++proc->instance_cnt_td;
for (r=0; r<Cby2; r++) {
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]); proc->tdp.eNB = eNB;
// Get Turbo interleaver parameters proc->tdp.UE_id = UE_id;
if (r<ulsch_harq->Cminus) proc->tdp.harq_pid = harq_pid;
Kr = ulsch_harq->Kminus; proc->tdp.llr8_flag = llr8_flag;
else
Kr = ulsch_harq->Kplus;
// wakeup worker to do second half segments
Kr_bytes = Kr>>3; if (pthread_cond_signal(&proc->cond_td) != 0) {
printf("[eNB] ERROR pthread_cond_signal for td thread exit\n");
if (Kr_bytes<=64) exit_fun( "ERROR pthread_cond_signal" );
iind = (Kr_bytes-5); return (1+ulsch->max_turbo_iterations);
else if (Kr_bytes <=128) }
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256) pthread_mutex_unlock( &proc->mutex_td );
iind = 91 + ((Kr_bytes-128)>>2); Cby2 = ulsch_harq->C/2;
else if (Kr_bytes <= 768) }
iind = 123 + ((Kr_bytes-256)>>3);
else { else {
LOG_E(PHY,"ulsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes); Cby2 = 1;
return(-1);
} }
// go through first half of segments in main thread
for (r=0; r<Cby2; r++) {
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
LOG_E(PHY,"ulsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
return(-1);
}
#ifdef DEBUG_ULSCH_DECODING #ifdef DEBUG_ULSCH_DECODING
printf("f1 %d, f2 %d, F %d\n",f1f2mat_old[2*iind],f1f2mat_old[1+(2*iind)],(r==0) ? ulsch_harq->F : 0); printf("f1 %d, f2 %d, F %d\n",f1f2mat_old[2*iind],f1f2mat_old[1+(2*iind)],(r==0) ? ulsch_harq->F : 0);
#endif #endif
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short)); memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8), ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
(uint8_t*)&dummy_w[r][0], (uint8_t*)&dummy_w[r][0],
(r==0) ? ulsch_harq->F : 0); (r==0) ? ulsch_harq->F : 0);
#ifdef DEBUG_ULSCH_DECODING #ifdef DEBUG_ULSCH_DECODING
printf("Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...\n", printf("Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...\n",
r, G, r, G,
Kr*3, Kr*3,
Q_m, Q_m,
nb_rb, nb_rb,
ulsch_harq->Nl); ulsch_harq->Nl);
#endif #endif
start_meas(&eNB->ulsch_rate_unmatching_stats); start_meas(&eNB->ulsch_rate_unmatching_stats);
if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
G,
ulsch_harq->w[r],
(uint8_t*) &dummy_w[r][0],
ulsch_harq->e+r_offset,
ulsch_harq->C,
NSOFT,
0, //Uplink
1,
ulsch_harq->rvidx,
(ulsch_harq->round==0)?1:0, // clear
ulsch_harq->Qm,
1,
r,
&E)==-1) {
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
return(-1);
}
stop_meas(&eNB->ulsch_rate_unmatching_stats); if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
G,
ulsch_harq->w[r],
(uint8_t*) &dummy_w[r][0],
ulsch_harq->e+r_offset,
ulsch_harq->C,
NSOFT,
0, //Uplink
1,
ulsch_harq->rvidx,
(ulsch_harq->round==0)?1:0, // clear
ulsch_harq->Qm,
1,
r,
&E)==-1) {
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
return(-1);
}
stop_meas(&eNB->ulsch_rate_unmatching_stats);
r_offset += E; r_offset += E;
int16_t soft_bits[3*8*6144+12+96] __attribute__((aligned(32))); int16_t soft_bits[3*8*6144+12+96] __attribute__((aligned(32)));
...@@ -577,25 +577,25 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr ...@@ -577,25 +577,25 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
memcpy(ulsch_harq->b, memcpy(ulsch_harq->b,
decoded_bytes+(ulsch_harq->F>>3), decoded_bytes+(ulsch_harq->F>>3),
Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0)); Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0));
offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0); offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
} else { } else {
memcpy(ulsch_harq->b+offset, memcpy(ulsch_harq->b+offset,
decoded_bytes, decoded_bytes,
Kr_bytes - ((ulsch_harq->C>1)?3:0)); Kr_bytes - ((ulsch_harq->C>1)?3:0));
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0)); offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
} }
} else { } else {
break; break;
}
stop_meas(&eNB->ulsch_turbo_decoding_stats);
} }
stop_meas(&eNB->ulsch_turbo_decoding_stats);
}
// wait for worker to finish // wait for worker to finish
wait_on_busy_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread"); wait_on_busy_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread");
return( (ret>proc->tdp.ret) ? ret : proc->tdp.ret ); return( (ret>proc->tdp.ret) ? ret : proc->tdp.ret );
} }
request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag, int frame, int subframe) { request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag, int frame, int subframe) {
...@@ -642,6 +642,7 @@ request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr ...@@ -642,6 +642,7 @@ request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
r_offset += E; r_offset += E;
start_meas(&eNB->ulsch_deinterleaving_stats); start_meas(&eNB->ulsch_deinterleaving_stats);
req=createRequest(DECODE,sizeof(turboDecode_t)); req=createRequest(DECODE,sizeof(turboDecode_t));
req->startUELoop=eNB->proc.threadPool.startProcessingUE;
union turboReqUnion id= {.s={eNB->ulsch[UE_id]->rnti,frame,subframe,r,0}}; union turboReqUnion id= {.s={eNB->ulsch[UE_id]->rnti,frame,subframe,r,0}};
req->id= id.p; req->id= id.p;
turboDecode_t * rdata=(turboDecode_t *) req->data; turboDecode_t * rdata=(turboDecode_t *) req->data;
...@@ -682,7 +683,7 @@ request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr ...@@ -682,7 +683,7 @@ request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
add_request(req, &eNB->proc.threadPool); add_request(req, &eNB->proc.threadPool);
req=NULL; req=NULL;
} else { } else {
req->creationTime=req->startProcessingTime=rdtsc(); req->startProcessingTime=rdtsc();
rdata->decodeIterations = td( rdata->soft_bits+96, rdata->decodeIterations = td( rdata->soft_bits+96,
rdata->decoded_bytes, rdata->decoded_bytes,
rdata->Kr, rdata->Kr,
...@@ -704,14 +705,15 @@ request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr ...@@ -704,14 +705,15 @@ request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
req->decodeIterations=rdata->decodeIterations; req->decodeIterations=rdata->decodeIterations;
req->coreId=0; req->coreId=0;
req->processedBy[0]=0; req->processedBy[0]=0;
req->next=eNB->proc.threadPool.doneRequests; req->next=eNB->proc.threadPool.doneRequests;
eNB->proc.threadPool.doneRequests=req; eNB->proc.threadPool.doneRequests=req;
if (rdata->decodeIterations > eNB->ulsch[UE_id]->max_turbo_iterations ) if (rdata->decodeIterations > eNB->ulsch[UE_id]->max_turbo_iterations )
// Entire TPU need retransmission // Entire TPU need retransmission
break; break;
} }
offset += blockSize; offset += blockSize;
eNB->proc.threadPool.startProcessingUE=rdtsc();
} }
return NULL; return NULL;
} }
...@@ -719,28 +721,28 @@ request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr ...@@ -719,28 +721,28 @@ request_t * ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline)); static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline));
static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset)
{ {
int n; int n;
if (reset) { if (reset) {
*x1 = 1+ (1<<31); *x1 = 1+ (1<<31);
*x2=*x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31); *x2=*x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31);
// skip first 50 double words (1600 bits) // skip first 50 double words (1600 bits)
// printf("n=0 : x1 %x, x2 %x\n",x1,x2); // printf("n=0 : x1 %x, x2 %x\n",x1,x2);
for (n=1; n<50; n++) { for (n=1; n<50; n++) {
*x1 = (*x1>>1) ^ (*x1>>4); *x1 = (*x1>>1) ^ (*x1>>4);
*x1 = *x1 ^ (*x1<<31) ^ (*x1<<28); *x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
*x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4); *x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
*x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28); *x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
}
} }
}
*x1 = (*x1>>1) ^ (*x1>>4); *x1 = (*x1>>1) ^ (*x1>>4);
*x1 = *x1 ^ (*x1<<31) ^ (*x1<<28); *x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
*x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4); *x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
*x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28); *x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
return(*x1^*x2); return(*x1^*x2);
// printf("n=%d : c %x\n",n,x1^x2); // printf("n=%d : c %x\n",n,x1^x2);
} }
...@@ -790,389 +792,389 @@ request_t* ulsch_decoding(PHY_VARS_eNB *eNB, ...@@ -790,389 +792,389 @@ request_t* ulsch_decoding(PHY_VARS_eNB *eNB,
harq_pid = subframe2harq_pid(frame_parms,proc->frame_rx,subframe); harq_pid = subframe2harq_pid(frame_parms,proc->frame_rx,subframe);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,1);
// x1 is set in lte_gold_generic // x1 is set in lte_gold_generic
x2 = ((uint32_t)ulsch->rnti<<14) + ((uint32_t)subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1 x2 = ((uint32_t)ulsch->rnti<<14) + ((uint32_t)subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1
ulsch_harq = ulsch->harq_processes[harq_pid]; ulsch_harq = ulsch->harq_processes[harq_pid];
AssertFatal(harq_pid<8, AssertFatal(harq_pid<8,
"FATAL ERROR: illegal harq_pid, returning\n"); "FATAL ERROR: illegal harq_pid, returning\n");
AssertFatal(ulsch_harq->Nsymb_pusch != 0, AssertFatal(ulsch_harq->Nsymb_pusch != 0,
"FATAL ERROR: harq_pid %d, Nsymb 0!\n",harq_pid); "FATAL ERROR: harq_pid %d, Nsymb 0!\n",harq_pid);
nb_rb = ulsch_harq->nb_rb; nb_rb = ulsch_harq->nb_rb;
A = ulsch_harq->TBS; A = ulsch_harq->TBS;
Q_m = ulsch_harq->Qm; Q_m = ulsch_harq->Qm;
G = nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch; G = nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch;
//#ifdef DEBUG_ULSCH_DECODING //#ifdef DEBUG_ULSCH_DECODING
LOG_D(PHY,"[PUSCH %d] Frame %d, Subframe %d: ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): A %d, round %d, RV %d, O_r1 %d, O_RI %d, O_ACK %d, G %d, Q_m %d Nsymb_pusch %d nb_rb %d\n", LOG_D(PHY,"[PUSCH %d] Frame %d, Subframe %d: ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): A %d, round %d, RV %d, O_r1 %d, O_RI %d, O_ACK %d, G %d, Q_m %d Nsymb_pusch %d nb_rb %d\n",
harq_pid, harq_pid,
proc->frame_rx,subframe, proc->frame_rx,subframe,
frame_parms->Nid_cell,ulsch->rnti,x2, frame_parms->Nid_cell,ulsch->rnti,x2,
A, A,
ulsch_harq->round, ulsch_harq->round,
ulsch_harq->rvidx, ulsch_harq->rvidx,
ulsch_harq->Or1, ulsch_harq->Or1,
ulsch_harq->O_RI, ulsch_harq->O_RI,
ulsch_harq->O_ACK, ulsch_harq->O_ACK,
G, G,
ulsch_harq->Qm, ulsch_harq->Qm,
ulsch_harq->Nsymb_pusch, ulsch_harq->Nsymb_pusch,
nb_rb); nb_rb);
//#endif //#endif
if (ulsch_harq->round == 0) { if (ulsch_harq->round == 0) {
// This is a new packet, so compute quantities regarding segmentation // This is a new packet, so compute quantities regarding segmentation
ulsch_harq->B = A+24; ulsch_harq->B = A+24;
lte_segmentation(NULL, lte_segmentation(NULL,
NULL, NULL,
ulsch_harq->B, ulsch_harq->B,
&ulsch_harq->C, &ulsch_harq->C,
&ulsch_harq->Cplus, &ulsch_harq->Cplus,
&ulsch_harq->Cminus, &ulsch_harq->Cminus,
&ulsch_harq->Kplus, &ulsch_harq->Kplus,
&ulsch_harq->Kminus, &ulsch_harq->Kminus,
&ulsch_harq->F); &ulsch_harq->F);
// CLEAR LLR's HERE for first packet in process // CLEAR LLR's HERE for first packet in process
} }
// printf("after segmentation c[%d] = %p\n",0,ulsch_harq->c[0]);
sumKr = 0;
for (r=0; r<ulsch_harq->C; r++) {
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
sumKr += Kr; // printf("after segmentation c[%d] = %p\n",0,ulsch_harq->c[0]);
}
AssertFatal(sumKr>0, sumKr = 0;
"[eNB] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
frame_parms->Nid_cell,ulsch->rnti,x2,
harq_pid,
ulsch_harq->round,
ulsch_harq->rvidx,
ulsch_harq->O_RI,
ulsch_harq->O_ACK,
G,
subframe);
for (r=0; r<ulsch_harq->C; r++) {
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
// Compute Q_ri sumKr += Kr;
Qprime = ulsch_harq->O_RI*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_ri_times8; }
if (Qprime > 0 ) { AssertFatal(sumKr>0,
if ((Qprime % (8*sumKr)) > 0) "[eNB] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
Qprime = 1+(Qprime/(8*sumKr)); frame_parms->Nid_cell,ulsch->rnti,x2,
else harq_pid,
Qprime = Qprime/(8*sumKr); ulsch_harq->round,
ulsch_harq->rvidx,
ulsch_harq->O_RI,
ulsch_harq->O_ACK,
G,
subframe);
if (Qprime > 4*nb_rb * 12)
Qprime = 4*nb_rb * 12;
}
Q_RI = Q_m*Qprime; // Compute Q_ri
Qprime_RI = Qprime; Qprime = ulsch_harq->O_RI*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_ri_times8;
if (Qprime > 0 ) {
if ((Qprime % (8*sumKr)) > 0)
Qprime = 1+(Qprime/(8*sumKr));
else
Qprime = Qprime/(8*sumKr);
if (Qprime > 4*nb_rb * 12)
Qprime = 4*nb_rb * 12;
}
// Compute Q_ack Q_RI = Q_m*Qprime;
Qprime_RI = Qprime;
Qprime = ulsch_harq->O_ACK*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_harqack_times8;
if (Qprime > 0) { // Compute Q_ack
if ((Qprime % (8*sumKr)) > 0)
Qprime = 1+(Qprime/(8*sumKr)); Qprime = ulsch_harq->O_ACK*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_harqack_times8;
else
Qprime = Qprime/(8*sumKr); if (Qprime > 0) {
if ((Qprime % (8*sumKr)) > 0)
Qprime = 1+(Qprime/(8*sumKr));
else
Qprime = Qprime/(8*sumKr);
if (Qprime > (4*nb_rb * 12)) if (Qprime > (4*nb_rb * 12))
Qprime = 4*nb_rb * 12; Qprime = 4*nb_rb * 12;
} }
// Q_ACK = Qprime * Q_m; // Q_ACK = Qprime * Q_m;
Qprime_ACK = Qprime; Qprime_ACK = Qprime;
#ifdef DEBUG_ULSCH_DECODING #ifdef DEBUG_ULSCH_DECODING
printf("ulsch_decoding.c: Qprime_ACK %d, Msc_initial %d, Nsymb_initial %d, sumKr %d\n", printf("ulsch_decoding.c: Qprime_ACK %d, Msc_initial %d, Nsymb_initial %d, sumKr %d\n",
Qprime_ACK,ulsch_harq->Msc_initial,ulsch_harq->Nsymb_initial,sumKr); Qprime_ACK,ulsch_harq->Msc_initial,ulsch_harq->Nsymb_initial,sumKr);
#endif #endif
// Compute Q_cqi // Compute Q_cqi
if (ulsch_harq->Or1 < 12) if (ulsch_harq->Or1 < 12)
L=0; L=0;
else
L=8;
// NOTE: we have to handle the case where we have a very small number of bits (condition on pg. 26 36.212)
if (ulsch_harq->Or1 > 0)
Qprime = (ulsch_harq->Or1 + L) * ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_cqi_times8;
else
Qprime=0;
if (Qprime > 0) { // check if ceiling is larger than floor in Q' expression
if ((Qprime % (8*sumKr)) > 0)
Qprime = 1+(Qprime/(8*sumKr));
else else
Qprime = Qprime/(8*sumKr); L=8;
}
G = nb_rb * (12 * Q_m) * (ulsch_harq->Nsymb_pusch); // NOTE: we have to handle the case where we have a very small number of bits (condition on pg. 26 36.212)
if (ulsch_harq->Or1 > 0)
Qprime = (ulsch_harq->Or1 + L) * ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_cqi_times8;
else
Qprime=0;
if (Qprime > 0) { // check if ceiling is larger than floor in Q' expression
if ((Qprime % (8*sumKr)) > 0)
Qprime = 1+(Qprime/(8*sumKr));
else
Qprime = Qprime/(8*sumKr);
}
G = nb_rb * (12 * Q_m) * (ulsch_harq->Nsymb_pusch);
Q_CQI = Q_m * Qprime;
Q_CQI = Q_m * Qprime;
#ifdef DEBUG_ULSCH_DECODING #ifdef DEBUG_ULSCH_DECODING
printf("ulsch_decoding: G %d, Q_RI %d, Q_CQI %d (L %d, Or1 %d) O_ACK %d\n",G,Q_RI,Q_CQI,L,ulsch_harq->Or1,ulsch_harq->O_ACK); printf("ulsch_decoding: G %d, Q_RI %d, Q_CQI %d (L %d, Or1 %d) O_ACK %d\n",G,Q_RI,Q_CQI,L,ulsch_harq->Or1,ulsch_harq->O_ACK);
#endif #endif
G = G - Q_RI - Q_CQI; G = G - Q_RI - Q_CQI;
ulsch_harq->G = G; ulsch_harq->G = G;
AssertFatal((int)G > 0, AssertFatal((int)G > 0,
"FATAL: ulsch_decoding.c G < 0 (%d) : Q_RI %d, Q_CQI %d\n",G,Q_RI,Q_CQI); "FATAL: ulsch_decoding.c G < 0 (%d) : Q_RI %d, Q_CQI %d\n",G,Q_RI,Q_CQI);
H = G + Q_CQI; H = G + Q_CQI;
Hprime = H/Q_m; Hprime = H/Q_m;
// Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI // Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI
start_meas(&eNB->ulsch_demultiplexing_stats); start_meas(&eNB->ulsch_demultiplexing_stats);
Hpp = Hprime + Qprime_RI; Hpp = Hprime + Qprime_RI;
Cmux = ulsch_harq->Nsymb_pusch; Cmux = ulsch_harq->Nsymb_pusch;
Rmux_prime = Hpp/Cmux; Rmux_prime = Hpp/Cmux;
// Clear "tag" interleaving matrix to allow for CQI/DATA identification // Clear "tag" interleaving matrix to allow for CQI/DATA identification
memset(ytag,0,Cmux*Rmux_prime); memset(ytag,0,Cmux*Rmux_prime);
i=0; i=0;
memset(y,LTE_NULL,Q_m*Hpp); memset(y,LTE_NULL,Q_m*Hpp);
// read in buffer and unscramble llrs for everything but placeholder bits // read in buffer and unscramble llrs for everything but placeholder bits
// llrs stored per symbol correspond to columns of interleaving matrix // llrs stored per symbol correspond to columns of interleaving matrix
s = lte_gold_unscram(&x1, &x2, 1); s = lte_gold_unscram(&x1, &x2, 1);
i2=0; i2=0;
for (i=0; i<((Hpp*Q_m)>>5); i++) { for (i=0; i<((Hpp*Q_m)>>5); i++) {
/* /*
for (j=0; j<32; j++) { for (j=0; j<32; j++) {
cseq[i2++] = (int16_t)((((s>>j)&1)<<1)-1); cseq[i2++] = (int16_t)((((s>>j)&1)<<1)-1);
} }
*/ */
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
#ifndef __AVX2__ #ifndef __AVX2__
((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[(s&65535)<<1]; ((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[(s&65535)<<1];
((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[1+((s&65535)<<1)]; ((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[1+((s&65535)<<1)];
s>>=16; s>>=16;
((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[(s&65535)<<1]; ((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[(s&65535)<<1];
((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[1+((s&65535)<<1)]; ((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[1+((s&65535)<<1)];
#else #else
((__m256i*)cseq)[i2++] = ((__m256i*)unscrambling_lut)[s&65535]; ((__m256i*)cseq)[i2++] = ((__m256i*)unscrambling_lut)[s&65535];
((__m256i*)cseq)[i2++] = ((__m256i*)unscrambling_lut)[(s>>16)&65535]; ((__m256i*)cseq)[i2++] = ((__m256i*)unscrambling_lut)[(s>>16)&65535];
#endif #endif
#elif defined(__arm__) #elif defined(__arm__)
((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[(s&65535)<<1]; ((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[(s&65535)<<1];
((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[1+((s&65535)<<1)]; ((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[1+((s&65535)<<1)];
s>>=16; s>>=16;
((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[(s&65535)<<1]; ((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[(s&65535)<<1];
((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[1+((s&65535)<<1)]; ((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[1+((s&65535)<<1)];
#endif #endif
s = lte_gold_unscram(&x1, &x2, 0); s = lte_gold_unscram(&x1, &x2, 0);
} }
// printf("after unscrambling c[%d] = %p\n",0,ulsch_harq->c[0]);
if (frame_parms->Ncp == 0)
columnset = cs_ri_normal;
else
columnset = cs_ri_extended;
j=0; // printf("after unscrambling c[%d] = %p\n",0,ulsch_harq->c[0]);
for (i=0; i<Qprime_RI; i++) { if (frame_parms->Ncp == 0)
r = Rmux_prime - 1 - (i>>2); columnset = cs_ri_normal;
/* else
for (q=0;q<Q_m;q++) columnset = cs_ri_extended;
ytag2[q+(Q_m*((r*Cmux) + columnset[j]))] = q_RI[(q+(Q_m*i))%len_RI];
*/
off =((Rmux_prime*Q_m*columnset[j])+(r*Q_m));
cseq[off+1] = cseq[off]; // PUSCH_y
for (q=2; q<Q_m; q++) j=0;
cseq[off+q] = -1; // PUSCH_x
j=(j+3)&3; for (i=0; i<Qprime_RI; i++) {
r = Rmux_prime - 1 - (i>>2);
/*
for (q=0;q<Q_m;q++)
ytag2[q+(Q_m*((r*Cmux) + columnset[j]))] = q_RI[(q+(Q_m*i))%len_RI];
*/
off =((Rmux_prime*Q_m*columnset[j])+(r*Q_m));
cseq[off+1] = cseq[off]; // PUSCH_y
} for (q=2; q<Q_m; q++)
cseq[off+q] = -1; // PUSCH_x
// printf("after RI c[%d] = %p\n",0,ulsch_harq->c[0]); j=(j+3)&3;
// HARQ-ACK Bits (Note these overwrite some bits) }
if (frame_parms->Ncp == 0)
columnset = cs_ack_normal;
else
columnset = cs_ack_extended;
j=0; // printf("after RI c[%d] = %p\n",0,ulsch_harq->c[0]);
for (i=0; i<Qprime_ACK; i++) { // HARQ-ACK Bits (Note these overwrite some bits)
r = Rmux_prime - 1 - (i>>2); if (frame_parms->Ncp == 0)
off =((Rmux_prime*Q_m*columnset[j])+(r*Q_m)); columnset = cs_ack_normal;
else
columnset = cs_ack_extended;
if (ulsch_harq->O_ACK == 1) { j=0;
if (ulsch->bundling==0)
cseq[off+1] = cseq[off]; // PUSCH_y
for (q=2; q<Q_m; q++) for (i=0; i<Qprime_ACK; i++) {
cseq[off+q] = -1; // PUSCH_x r = Rmux_prime - 1 - (i>>2);
} else if (ulsch_harq->O_ACK == 2) { off =((Rmux_prime*Q_m*columnset[j])+(r*Q_m));
for (q=2; q<Q_m; q++)
cseq[off+q] = -1; // PUSCH_x if (ulsch_harq->O_ACK == 1) {
} if (ulsch->bundling==0)
cseq[off+1] = cseq[off]; // PUSCH_y
for (q=2; q<Q_m; q++)
cseq[off+q] = -1; // PUSCH_x
} else if (ulsch_harq->O_ACK == 2) {
for (q=2; q<Q_m; q++)
cseq[off+q] = -1; // PUSCH_x
}
#ifdef DEBUG_ULSCH_DECODING #ifdef DEBUG_ULSCH_DECODING
printf("ulsch_decoding.c: ACK i %d, r %d, j %d, ColumnSet[j] %d\n",i,r,j,columnset[j]); printf("ulsch_decoding.c: ACK i %d, r %d, j %d, ColumnSet[j] %d\n",i,r,j,columnset[j]);
#endif #endif
j=(j+3)&3; j=(j+3)&3;
} }
i=0; i=0;
switch (Q_m) { switch (Q_m) {
case 2: case 2:
for (j=0; j<Cmux; j++) { for (j=0; j<Cmux; j++) {
i2=j<<1; i2=j<<1;
for (r=0; r<Rmux_prime; r++) {
c = cseq[i];
// printf("ulsch %d: %d * ",i,c);
y[i2++] = c*ulsch_llr[i++];
// printf("%d\n",ulsch_llr[i-1]);
c = cseq[i];
// printf("ulsch %d: %d * ",i,c);
y[i2] = c*ulsch_llr[i++];
// printf("%d\n",ulsch_llr[i-1]);
i2=(i2+(Cmux<<1)-1);
}
}
for (r=0; r<Rmux_prime; r++) { break;
c = cseq[i];
// printf("ulsch %d: %d * ",i,c);
y[i2++] = c*ulsch_llr[i++];
// printf("%d\n",ulsch_llr[i-1]);
c = cseq[i];
// printf("ulsch %d: %d * ",i,c);
y[i2] = c*ulsch_llr[i++];
// printf("%d\n",ulsch_llr[i-1]);
i2=(i2+(Cmux<<1)-1);
}
}
break; case 4:
for (j=0; j<Cmux; j++) {
case 4: i2=j<<2;
for (j=0; j<Cmux; j++) {
i2=j<<2; for (r=0; r<Rmux_prime; r++) {
/*
for (r=0; r<Rmux_prime; r++) { c = cseq[i];
/* y[i2++] = c*ulsch_llr[i++];
c = cseq[i]; c = cseq[i];
y[i2++] = c*ulsch_llr[i++]; y[i2++] = c*ulsch_llr[i++];
c = cseq[i]; c = cseq[i];
y[i2++] = c*ulsch_llr[i++]; y[i2++] = c*ulsch_llr[i++];
c = cseq[i]; c = cseq[i];
y[i2++] = c*ulsch_llr[i++]; y[i2] = c*ulsch_llr[i++];
c = cseq[i]; i2=(i2+(Cmux<<2)-3);
y[i2] = c*ulsch_llr[i++]; */
i2=(i2+(Cmux<<2)-3);
*/
// slightly more optimized version (equivalent to above) for 16QAM to improve computational performance // slightly more optimized version (equivalent to above) for 16QAM to improve computational performance
*(__m64 *)&y[i2] = _mm_sign_pi16(*(__m64*)&ulsch_llr[i],*(__m64*)&cseq[i]); *(__m64 *)&y[i2] = _mm_sign_pi16(*(__m64*)&ulsch_llr[i],*(__m64*)&cseq[i]);
i+=4; i+=4;
i2+=(Cmux<<2); i2+=(Cmux<<2);
} }
} }
break; break;
case 6:
for (j=0; j<Cmux; j++) {
i2=j*6;
for (r=0; r<Rmux_prime; r++) {
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2] = c*ulsch_llr[i++];
i2=(i2+(Cmux*6)-5);
}
}
break; case 6:
} for (j=0; j<Cmux; j++) {
i2=j*6;
for (r=0; r<Rmux_prime; r++) {
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
c = cseq[i];
y[i2] = c*ulsch_llr[i++];
i2=(i2+(Cmux*6)-5);
}
}
break;
}
if (i!=(H+Q_RI)) if (i!=(H+Q_RI))
LOG_D(PHY,"ulsch_decoding.c: Error in input buffer length (j %d, H+Q_RI %d)\n",i,H+Q_RI); LOG_D(PHY,"ulsch_decoding.c: Error in input buffer length (j %d, H+Q_RI %d)\n",i,H+Q_RI);
// HARQ-ACK Bits (LLRs are nulled in overwritten bits after copying HARQ-ACK LLR) // HARQ-ACK Bits (LLRs are nulled in overwritten bits after copying HARQ-ACK LLR)
if (frame_parms->Ncp == 0) if (frame_parms->Ncp == 0)
columnset = cs_ack_normal; columnset = cs_ack_normal;
else else
columnset = cs_ack_extended; columnset = cs_ack_extended;
j=0; j=0;
if (ulsch_harq->O_ACK == 1) { if (ulsch_harq->O_ACK == 1) {
switch (Q_m) { switch (Q_m) {
case 2: case 2:
len_ACK = 2; len_ACK = 2;
break; break;
case 4: case 4:
len_ACK = 4; len_ACK = 4;
break; break;
case 6: case 6:
len_ACK = 6; len_ACK = 6;
break; break;
}
} }
}
if (ulsch_harq->O_ACK == 2) { if (ulsch_harq->O_ACK == 2) {
switch (Q_m) { switch (Q_m) {
case 2: case 2:
len_ACK = 6; len_ACK = 6;
break; break;
case 4: case 4:
len_ACK = 12; len_ACK = 12;
break; break;
case 6: case 6:
len_ACK = 18; len_ACK = 18;
break; break;
}
} }
}
if (ulsch_harq->O_ACK > 2) { if (ulsch_harq->O_ACK > 2) {
LOG_E(PHY,"ulsch_decoding: FATAL, ACK cannot be more than 2 bits yet\n"); LOG_E(PHY,"ulsch_decoding: FATAL, ACK cannot be more than 2 bits yet\n");
...@@ -1220,282 +1222,282 @@ request_t* ulsch_decoding(PHY_VARS_eNB *eNB, ...@@ -1220,282 +1222,282 @@ request_t* ulsch_decoding(PHY_VARS_eNB *eNB,
return NULL; return NULL;
} }
for (i=0; i<len_RI; i++) for (i=0; i<len_RI; i++)
ulsch_harq->q_RI[i] = 0; ulsch_harq->q_RI[i] = 0;
if (frame_parms->Ncp == 0)
columnset = cs_ri_normal;
else
columnset = cs_ri_extended;
j=0;
for (i=0; i<Qprime_RI; i++) {
r = Rmux_prime -1 - (i>>2);
for (q=0; q<Q_m; q++)
ulsch_harq->q_RI[(q+(Q_m*i))%len_RI] += y[q+(Q_m*((r*Cmux) + columnset[j]))];
ytag[(r*Cmux) + columnset[j]] = LTE_NULL;
j=(j+3)&3;
}
// printf("after RI2 c[%d] = %p\n",0,ulsch_harq->c[0]);
// CQI and Data bits
j=0;
j2=0;
// r=0;
if (Q_RI>0) {
for (i=0; i<(Q_CQI/Q_m); i++) {
while (ytag[j]==LTE_NULL) {
j++;
j2+=Q_m;
}
for (q=0; q<Q_m; q++) {
// ys = y[q+(Q_m*((r*Cmux)+j))];
ys = y[q+j2];
if (ys>127)
ulsch_harq->q[q+(Q_m*i)] = 127;
else if (ys<-128)
ulsch_harq->q[q+(Q_m*i)] = -128;
else
ulsch_harq->q[q+(Q_m*i)] = ys;
}
j2+=Q_m;
}
switch (Q_m) {
case 2:
for (iprime=0; iprime<G;) {
while (ytag[j]==LTE_NULL) {
j++;
j2+=2;
}
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
}
break;
case 4:
for (iprime=0; iprime<G;) {
while (ytag[j]==LTE_NULL) {
j++;
j2+=4;
}
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
}
break;
case 6:
for (iprime=0; iprime<G;) {
while (ytag[j]==LTE_NULL) {
j++;
j2+=6;
}
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
}
break;
if (frame_parms->Ncp == 0)
columnset = cs_ri_normal;
else
columnset = cs_ri_extended;
j=0;
for (i=0; i<Qprime_RI; i++) {
r = Rmux_prime -1 - (i>>2);
for (q=0; q<Q_m; q++)
ulsch_harq->q_RI[(q+(Q_m*i))%len_RI] += y[q+(Q_m*((r*Cmux) + columnset[j]))];
ytag[(r*Cmux) + columnset[j]] = LTE_NULL;
j=(j+3)&3;
} }
} // Q_RI>0
else {
for (i=0; i<(Q_CQI/Q_m); i++) {
for (q=0; q<Q_m; q++) {
ys = y[q+j2];
if (ys>127)
ulsch_harq->q[q+(Q_m*i)] = 127;
else if (ys<-128)
ulsch_harq->q[q+(Q_m*i)] = -128;
else
ulsch_harq->q[q+(Q_m*i)] = ys;
}
j2+=Q_m;
}
/* To be improved according to alignment of j2
#if defined(__x86_64__)||defined(__i386__)
#ifndef __AVX2__
for (iprime=0; iprime<G;iprime+=8,j2+=8)
*((__m128i *)&ulsch_harq->e[iprime]) = *((__m128i *)&y[j2]);
#else
for (iprime=0; iprime<G;iprime+=16,j2+=16)
*((__m256i *)&ulsch_harq->e[iprime]) = *((__m256i *)&y[j2]);
#endif
#elif defined(__arm__)
for (iprime=0; iprime<G;iprime+=8,j2+=8)
*((int16x8_t *)&ulsch_harq->e[iprime]) = *((int16x8_t *)&y[j2]);
#endif
*/
int16_t *yp,*ep;
for (iprime=0,yp=&y[j2],ep=&ulsch_harq->e[0];
iprime<G;
iprime+=8,j2+=8,ep+=8,yp+=8) {
ep[0] = yp[0];
ep[1] = yp[1];
ep[2] = yp[2];
ep[3] = yp[3];
ep[4] = yp[4];
ep[5] = yp[5];
ep[6] = yp[6];
ep[7] = yp[7];
}
}
stop_meas(&eNB->ulsch_demultiplexing_stats);
// printf("after ACKNAK2 c[%d] = %p (iprime %d, G %d)\n",0,ulsch_harq->c[0],iprime,G); // printf("after RI2 c[%d] = %p\n",0,ulsch_harq->c[0]);
// Do CQI/RI/HARQ-ACK Decoding first and pass to MAC // CQI and Data bits
j=0;
j2=0;
// HARQ-ACK // r=0;
wACK_idx = (ulsch->bundling==0) ? 4 : ((Nbundled-1)&3); if (Q_RI>0) {
for (i=0; i<(Q_CQI/Q_m); i++) {
if (ulsch_harq->O_ACK == 1) { while (ytag[j]==LTE_NULL) {
ulsch_harq->q_ACK[0] *= wACK_RX[wACK_idx][0]; j++;
ulsch_harq->q_ACK[0] += (ulsch->bundling==0) ? ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] : ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][1]; j2+=Q_m;
}
if (ulsch_harq->q_ACK[0] < 0) for (q=0; q<Q_m; q++) {
ulsch_harq->o_ACK[0] = 0; // ys = y[q+(Q_m*((r*Cmux)+j))];
else ys = y[q+j2];
ulsch_harq->o_ACK[0] = 1;
}
if (ulsch_harq->O_ACK == 2) { if (ys>127)
switch (Q_m) { ulsch_harq->q[q+(Q_m*i)] = 127;
else if (ys<-128)
ulsch_harq->q[q+(Q_m*i)] = -128;
else
ulsch_harq->q[q+(Q_m*i)] = ys;
}
case 2: j2+=Q_m;
ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[3]*wACK_RX[wACK_idx][1]; }
ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[4]*wACK_RX[wACK_idx][1];
ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[2]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX[wACK_idx][1];
break;
case 4:
ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX[wACK_idx][1];
ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[8]*wACK_RX[wACK_idx][1];
ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[4]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[9]*wACK_RX[wACK_idx][1];
break;
case 6:
ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[7]*wACK_RX[wACK_idx][1];
ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[12]*wACK_RX[wACK_idx][1];
ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[6]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[13]*wACK_RX[wACK_idx][1];
break;
}
ulsch_harq->o_ACK[0] = 1;
ulsch_harq->o_ACK[1] = 1;
metric = ulsch_harq->q_ACK[0]+ulsch_harq->q_ACK[1]-ulsch_harq->q_ACK[2];
metric_new = -ulsch_harq->q_ACK[0]+ulsch_harq->q_ACK[1]+ulsch_harq->q_ACK[2];
if (metric_new > metric) { switch (Q_m) {
ulsch_harq->o_ACK[0]=0; case 2:
ulsch_harq->o_ACK[1]=1; for (iprime=0; iprime<G;) {
metric = metric_new; while (ytag[j]==LTE_NULL) {
j++;
j2+=2;
}
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
}
break;
case 4:
for (iprime=0; iprime<G;) {
while (ytag[j]==LTE_NULL) {
j++;
j2+=4;
}
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
}
break;
case 6:
for (iprime=0; iprime<G;) {
while (ytag[j]==LTE_NULL) {
j++;
j2+=6;
}
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
}
break;
}
} // Q_RI>0
else {
for (i=0; i<(Q_CQI/Q_m); i++) {
for (q=0; q<Q_m; q++) {
ys = y[q+j2];
if (ys>127)
ulsch_harq->q[q+(Q_m*i)] = 127;
else if (ys<-128)
ulsch_harq->q[q+(Q_m*i)] = -128;
else
ulsch_harq->q[q+(Q_m*i)] = ys;
}
j2+=Q_m;
}
/* To be improved according to alignment of j2
#if defined(__x86_64__)||defined(__i386__)
#ifndef __AVX2__
for (iprime=0; iprime<G;iprime+=8,j2+=8)
*((__m128i *)&ulsch_harq->e[iprime]) = *((__m128i *)&y[j2]);
#else
for (iprime=0; iprime<G;iprime+=16,j2+=16)
*((__m256i *)&ulsch_harq->e[iprime]) = *((__m256i *)&y[j2]);
#endif
#elif defined(__arm__)
for (iprime=0; iprime<G;iprime+=8,j2+=8)
*((int16x8_t *)&ulsch_harq->e[iprime]) = *((int16x8_t *)&y[j2]);
#endif
*/
int16_t *yp,*ep;
for (iprime=0,yp=&y[j2],ep=&ulsch_harq->e[0];
iprime<G;
iprime+=8,j2+=8,ep+=8,yp+=8) {
ep[0] = yp[0];
ep[1] = yp[1];
ep[2] = yp[2];
ep[3] = yp[3];
ep[4] = yp[4];
ep[5] = yp[5];
ep[6] = yp[6];
ep[7] = yp[7];
}
} }
metric_new = ulsch_harq->q_ACK[0]-ulsch_harq->q_ACK[1]+ulsch_harq->q_ACK[2];
stop_meas(&eNB->ulsch_demultiplexing_stats);
// printf("after ACKNAK2 c[%d] = %p (iprime %d, G %d)\n",0,ulsch_harq->c[0],iprime,G);
// Do CQI/RI/HARQ-ACK Decoding first and pass to MAC
// HARQ-ACK
wACK_idx = (ulsch->bundling==0) ? 4 : ((Nbundled-1)&3);
if (metric_new > metric) { if (ulsch_harq->O_ACK == 1) {
ulsch_harq->o_ACK[0] = 1; ulsch_harq->q_ACK[0] *= wACK_RX[wACK_idx][0];
ulsch_harq->o_ACK[1] = 0; ulsch_harq->q_ACK[0] += (ulsch->bundling==0) ? ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] : ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][1];
metric = metric_new;
if (ulsch_harq->q_ACK[0] < 0)
ulsch_harq->o_ACK[0] = 0;
else
ulsch_harq->o_ACK[0] = 1;
} }
metric_new = -ulsch_harq->q_ACK[0]-ulsch_harq->q_ACK[1]-ulsch_harq->q_ACK[2]; if (ulsch_harq->O_ACK == 2) {
switch (Q_m) {
case 2:
ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[3]*wACK_RX[wACK_idx][1];
ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[4]*wACK_RX[wACK_idx][1];
ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[2]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX[wACK_idx][1];
break;
case 4:
ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX[wACK_idx][1];
ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[8]*wACK_RX[wACK_idx][1];
ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[4]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[9]*wACK_RX[wACK_idx][1];
break;
case 6:
ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[7]*wACK_RX[wACK_idx][1];
ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[12]*wACK_RX[wACK_idx][1];
ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[6]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[13]*wACK_RX[wACK_idx][1];
break;
}
ulsch_harq->o_ACK[0] = 1;
ulsch_harq->o_ACK[1] = 1;
metric = ulsch_harq->q_ACK[0]+ulsch_harq->q_ACK[1]-ulsch_harq->q_ACK[2];
metric_new = -ulsch_harq->q_ACK[0]+ulsch_harq->q_ACK[1]+ulsch_harq->q_ACK[2];
if (metric_new > metric) {
ulsch_harq->o_ACK[0]=0;
ulsch_harq->o_ACK[1]=1;
metric = metric_new;
}
metric_new = ulsch_harq->q_ACK[0]-ulsch_harq->q_ACK[1]+ulsch_harq->q_ACK[2];
if (metric_new > metric) {
ulsch_harq->o_ACK[0] = 0; if (metric_new > metric) {
ulsch_harq->o_ACK[1] = 0; ulsch_harq->o_ACK[0] = 1;
metric = metric_new; ulsch_harq->o_ACK[1] = 0;
metric = metric_new;
}
metric_new = -ulsch_harq->q_ACK[0]-ulsch_harq->q_ACK[1]-ulsch_harq->q_ACK[2];
if (metric_new > metric) {
ulsch_harq->o_ACK[0] = 0;
ulsch_harq->o_ACK[1] = 0;
metric = metric_new;
}
} }
}
// RI // RI
// rank 1 // rank 1
if ((ulsch_harq->O_RI == 1) && (Qprime_RI > 0)) { if ((ulsch_harq->O_RI == 1) && (Qprime_RI > 0)) {
ulsch_harq->o_RI[0] = ((ulsch_harq->q_RI[0] + ulsch_harq->q_RI[Q_m/2]) > 0) ? 0 : 1; ulsch_harq->o_RI[0] = ((ulsch_harq->q_RI[0] + ulsch_harq->q_RI[Q_m/2]) > 0) ? 0 : 1;
} }
// CQI // CQI
// printf("before cqi c[%d] = %p\n",0,ulsch_harq->c[0]); // printf("before cqi c[%d] = %p\n",0,ulsch_harq->c[0]);
ulsch_harq->cqi_crc_status = 0; ulsch_harq->cqi_crc_status = 0;
if (Q_CQI>0) { if (Q_CQI>0) {
memset((void *)&dummy_w_cc[0],0,3*(ulsch_harq->Or1+8+32)); memset((void *)&dummy_w_cc[0],0,3*(ulsch_harq->Or1+8+32));
O_RCC = generate_dummy_w_cc(ulsch_harq->Or1+8, O_RCC = generate_dummy_w_cc(ulsch_harq->Or1+8,
&dummy_w_cc[0]); &dummy_w_cc[0]);
lte_rate_matching_cc_rx(O_RCC, lte_rate_matching_cc_rx(O_RCC,
Q_CQI, Q_CQI,
ulsch_harq->o_w, ulsch_harq->o_w,
dummy_w_cc, dummy_w_cc,
ulsch_harq->q); ulsch_harq->q);
sub_block_deinterleaving_cc((unsigned int)(ulsch_harq->Or1+8), sub_block_deinterleaving_cc((unsigned int)(ulsch_harq->Or1+8),
&ulsch_harq->o_d[96], &ulsch_harq->o_d[96],
&ulsch_harq->o_w[0]); &ulsch_harq->o_w[0]);
memset(ulsch_harq->o,0,(7+8+ulsch_harq->Or1) / 8); memset(ulsch_harq->o,0,(7+8+ulsch_harq->Or1) / 8);
phy_viterbi_lte_sse2(ulsch_harq->o_d+96,ulsch_harq->o,8+ulsch_harq->Or1); phy_viterbi_lte_sse2(ulsch_harq->o_d+96,ulsch_harq->o,8+ulsch_harq->Or1);
if (extract_cqi_crc(ulsch_harq->o,ulsch_harq->Or1) == (crc8(ulsch_harq->o,ulsch_harq->Or1)>>24)) if (extract_cqi_crc(ulsch_harq->o,ulsch_harq->Or1) == (crc8(ulsch_harq->o,ulsch_harq->Or1)>>24))
ulsch_harq->cqi_crc_status = 1; ulsch_harq->cqi_crc_status = 1;
#ifdef DEBUG_ULSCH_DECODING #ifdef DEBUG_ULSCH_DECODING
printf("ulsch_decoding: Or1=%d\n",ulsch_harq->Or1); printf("ulsch_decoding: Or1=%d\n",ulsch_harq->Or1);
for (i=0; i<1+((8+ulsch_harq->Or1)/8); i++) for (i=0; i<1+((8+ulsch_harq->Or1)/8); i++)
printf("ulsch_decoding: O[%d] %d\n",i,ulsch_harq->o[i]); printf("ulsch_decoding: O[%d] %d\n",i,ulsch_harq->o[i]);
if (ulsch_harq->cqi_crc_status == 1) if (ulsch_harq->cqi_crc_status == 1)
printf("RX CQI CRC OK (%x)\n",extract_cqi_crc(ulsch_harq->o,ulsch_harq->Or1)); printf("RX CQI CRC OK (%x)\n",extract_cqi_crc(ulsch_harq->o,ulsch_harq->Or1));
else else
printf("RX CQI CRC NOT OK (%x)\n",extract_cqi_crc(ulsch_harq->o,ulsch_harq->Or1)); printf("RX CQI CRC NOT OK (%x)\n",extract_cqi_crc(ulsch_harq->o,ulsch_harq->Or1));
#endif #endif
} }
LOG_D(PHY,"frame %d subframe %d O_ACK:%d o_ACK[]=%d:%d:%d:%d\n",frame,subframe,ulsch_harq->O_ACK,ulsch_harq->o_ACK[0],ulsch_harq->o_ACK[1],ulsch_harq->o_ACK[2],ulsch_harq->o_ACK[3]); LOG_D(PHY,"frame %d subframe %d O_ACK:%d o_ACK[]=%d:%d:%d:%d\n",frame,subframe,ulsch_harq->O_ACK,ulsch_harq->o_ACK[0],ulsch_harq->o_ACK[1],ulsch_harq->o_ACK[2],ulsch_harq->o_ACK[3]);
// Do ULSCH Decoding for data portion // Do ULSCH Decoding for data portion
request_t * ret = eNB->td(eNB,UE_id,harq_pid,llr8_flag, frame, subframe); request_t * ret = eNB->td(eNB,UE_id,harq_pid,llr8_flag, frame, subframe);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,0);
return(ret); return(ret);
} }
#ifdef PHY_ABSTRACTION #ifdef PHY_ABSTRACTION
...@@ -1504,43 +1506,43 @@ request_t* ulsch_decoding(PHY_VARS_eNB *eNB, ...@@ -1504,43 +1506,43 @@ request_t* ulsch_decoding(PHY_VARS_eNB *eNB,
int ulsch_abstraction(double* sinr_dB, uint8_t TM, uint8_t mcs,uint16_t nrb, uint16_t frb) int ulsch_abstraction(double* sinr_dB, uint8_t TM, uint8_t mcs,uint16_t nrb, uint16_t frb)
{ {
int index,ii; int index,ii;
double sinr_eff = 0; double sinr_eff = 0;
int rb_count = 0; int rb_count = 0;
int offset; int offset;
double bler = 0; double bler = 0;
TM = TM-1; TM = TM-1;
sinr_eff = sinr_dB[frb]; //the single sinr_eff value we calculated with MMSE FDE formula in init_snr_up function sinr_eff = sinr_dB[frb]; //the single sinr_eff value we calculated with MMSE FDE formula in init_snr_up function
sinr_eff *= 10; sinr_eff *= 10;
sinr_eff = floor(sinr_eff); sinr_eff = floor(sinr_eff);
sinr_eff /= 10; sinr_eff /= 10;
LOG_D(PHY,"[ABSTRACTION] sinr_eff after rounding = %f\n",sinr_eff); LOG_D(PHY,"[ABSTRACTION] sinr_eff after rounding = %f\n",sinr_eff);
for (index = 0; index < 16; index++) { for (index = 0; index < 16; index++) {
if(index == 0) { if(index == 0) {
if (sinr_eff < sinr_bler_map_up[mcs][0][index]) { if (sinr_eff < sinr_bler_map_up[mcs][0][index]) {
bler = 1; bler = 1;
break; break;
} }
} }
if (sinr_eff == sinr_bler_map_up[mcs][0][index]) { if (sinr_eff == sinr_bler_map_up[mcs][0][index]) {
bler = sinr_bler_map_up[mcs][1][index]; bler = sinr_bler_map_up[mcs][1][index];
}
} }
}
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space #ifdef USER_MODE // need to be adapted for the emulation in the kernel space
if (uniformrandom() < bler) { if (uniformrandom() < bler) {
LOG_I(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler); LOG_I(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
return(0); return(0);
} else { } else {
LOG_I(OCM,"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler); LOG_I(OCM,"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
return(1); return(1);
} }
#endif #endif
} }
...@@ -1553,313 +1555,313 @@ int ulsch_abstraction(double* sinr_dB, uint8_t TM, uint8_t mcs,uint16_t nrb, uin ...@@ -1553,313 +1555,313 @@ int ulsch_abstraction(double* sinr_dB, uint8_t TM, uint8_t mcs,uint16_t nrb, uin
int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb, uint16_t frb) int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb, uint16_t frb)
{ {
int index; int index;
double sinr_eff = 0; double sinr_eff = 0;
double sinr_db1 = 0; double sinr_db1 = 0;
double sinr_db2 = 0; double sinr_db2 = 0;
double SI=0; double SI=0;
double RBIR=0; double RBIR=0;
int rb_count = 0; int rb_count = 0;
int offset, M=0; int offset, M=0;
double bler = 0; double bler = 0;
int start,middle,end; int start,middle,end;
TM = TM-1; TM = TM-1;
for (offset = frb; offset <= (frb + nrb -1); offset++) { for (offset = frb; offset <= (frb + nrb -1); offset++) {
rb_count++; rb_count++;
//we need to do the table lookups here for the mutual information corresponding to the certain sinr_dB. //we need to do the table lookups here for the mutual information corresponding to the certain sinr_dB.
sinr_db1 = sinr_dB[offset*2]; sinr_db1 = sinr_dB[offset*2];
sinr_db2 = sinr_dB[offset*2+1]; sinr_db2 = sinr_dB[offset*2+1];
printf("sinr_db1=%f\n,sinr_db2=%f\n",sinr_db1,sinr_db2); printf("sinr_db1=%f\n,sinr_db2=%f\n",sinr_db1,sinr_db2);
//rounding up for the table lookup //rounding up for the table lookup
sinr_db1 *= 10; sinr_db1 *= 10;
sinr_db2 *= 10; sinr_db2 *= 10;
sinr_db1 = floor(sinr_db1); sinr_db1 = floor(sinr_db1);
sinr_db2 = floor(sinr_db2); sinr_db2 = floor(sinr_db2);
if ((int)sinr_db1%2) { if ((int)sinr_db1%2) {
sinr_db1 += 1; sinr_db1 += 1;
} }
if ((int)sinr_db2%2) { if ((int)sinr_db2%2) {
sinr_db2 += 1; sinr_db2 += 1;
} }
sinr_db1 /= 10; sinr_db1 /= 10;
sinr_db2 /= 10; sinr_db2 /= 10;
if(mcs<10) { if(mcs<10) {
//for sinr_db1 //for sinr_db1
for (index = 0; index < 162; index++) { for (index = 0; index < 162; index++) {
if (sinr_db1 < MI_map_4qam[0][0]) { if (sinr_db1 < MI_map_4qam[0][0]) {
SI += (MI_map_4qam[1][0]/beta1_dlsch_MI[TM][mcs]); SI += (MI_map_4qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=2; M +=2;
break; break;
} }
if (sinr_db1 > MI_map_4qam[0][161]) { if (sinr_db1 > MI_map_4qam[0][161]) {
SI += (MI_map_4qam[1][161]/beta1_dlsch_MI[TM][mcs]); SI += (MI_map_4qam[1][161]/beta1_dlsch_MI[TM][mcs]);
M +=2; M +=2;
break; break;
} }
if (sinr_db1 == MI_map_4qam[0][index]) { if (sinr_db1 == MI_map_4qam[0][index]) {
SI += (MI_map_4qam[1][index]/beta1_dlsch_MI[TM][mcs]); SI += (MI_map_4qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=2; M +=2;
break; break;
} }
} }
//for sinr_db2
for (index = 0; index < 162; index++) {
if (sinr_db2 < MI_map_4qam[0][0]) {
SI += (MI_map_4qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=2;
break;
}
if (sinr_db2 > MI_map_4qam[0][161]) { //for sinr_db2
SI += (MI_map_4qam[1][161]/beta1_dlsch_MI[TM][mcs]); for (index = 0; index < 162; index++) {
M +=2; if (sinr_db2 < MI_map_4qam[0][0]) {
break; SI += (MI_map_4qam[1][0]/beta1_dlsch_MI[TM][mcs]);
} M +=2;
break;
}
if (sinr_db2 == MI_map_4qam[0][index]) { if (sinr_db2 > MI_map_4qam[0][161]) {
SI += (MI_map_4qam[1][index]/beta1_dlsch_MI[TM][mcs]); SI += (MI_map_4qam[1][161]/beta1_dlsch_MI[TM][mcs]);
M +=2; M +=2;
break; break;
} }
}
} else if(mcs>9 && mcs<17) {
//for sinr_db1
for (index = 0; index < 197; index++) {
if (sinr_db1 < MI_map_16qam[0][0]) {
SI += (MI_map_16qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=4;
break;
}
if (sinr_db1 > MI_map_16qam[0][196]) { if (sinr_db2 == MI_map_4qam[0][index]) {
SI += (MI_map_16qam[1][196]/beta1_dlsch_MI[TM][mcs]); SI += (MI_map_4qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=4; M +=2;
break; break;
} }
}
if (sinr_db1 == MI_map_16qam[0][index]) { } else if(mcs>9 && mcs<17) {
SI += (MI_map_16qam[1][index]/beta1_dlsch_MI[TM][mcs]); //for sinr_db1
M +=4; for (index = 0; index < 197; index++) {
break; if (sinr_db1 < MI_map_16qam[0][0]) {
} SI += (MI_map_16qam[1][0]/beta1_dlsch_MI[TM][mcs]);
} M +=4;
break;
//for sinr_db2 }
for (index = 0; index < 197; index++) {
if (sinr_db2 < MI_map_16qam[0][0]) {
SI += (MI_map_16qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=4;
break;
}
if (sinr_db2 > MI_map_16qam[0][196]) { if (sinr_db1 > MI_map_16qam[0][196]) {
SI += (MI_map_16qam[1][196]/beta1_dlsch_MI[TM][mcs]); SI += (MI_map_16qam[1][196]/beta1_dlsch_MI[TM][mcs]);
M +=4; M +=4;
break; break;
} }
if (sinr_db2 == MI_map_16qam[0][index]) { if (sinr_db1 == MI_map_16qam[0][index]) {
SI += (MI_map_16qam[1][index]/beta1_dlsch_MI[TM][mcs]); SI += (MI_map_16qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=4; M +=4;
break; break;
} }
} }
} else if(mcs>16 && mcs<22) {
//for sinr_db1
for (index = 0; index < 227; index++) {
if (sinr_db1 < MI_map_64qam[0][0]) {
SI += (MI_map_64qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
if (sinr_db1 > MI_map_64qam[0][226]) { //for sinr_db2
SI += (MI_map_64qam[1][226]/beta1_dlsch_MI[TM][mcs]); for (index = 0; index < 197; index++) {
M +=6; if (sinr_db2 < MI_map_16qam[0][0]) {
break; SI += (MI_map_16qam[1][0]/beta1_dlsch_MI[TM][mcs]);
} M +=4;
break;
}
if (sinr_db1 == MI_map_64qam[0][index]) { if (sinr_db2 > MI_map_16qam[0][196]) {
SI += (MI_map_64qam[1][index]/beta1_dlsch_MI[TM][mcs]); SI += (MI_map_16qam[1][196]/beta1_dlsch_MI[TM][mcs]);
M +=6; M +=4;
break; break;
} }
}
//for sinr_db2
for (index = 0; index < 227; index++) {
if (sinr_db2 < MI_map_64qam[0][0]) {
SI += (MI_map_64qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
if (sinr_db2 > MI_map_64qam[0][226]) { if (sinr_db2 == MI_map_16qam[0][index]) {
SI += (MI_map_64qam[1][226]/beta1_dlsch_MI[TM][mcs]); SI += (MI_map_16qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=6; M +=4;
break; break;
} }
}
if (sinr_db2 == MI_map_64qam[0][index]) { } else if(mcs>16 && mcs<22) {
SI += (MI_map_64qam[1][index]/beta1_dlsch_MI[TM][mcs]); //for sinr_db1
M +=6; for (index = 0; index < 227; index++) {
break; if (sinr_db1 < MI_map_64qam[0][0]) {
SI += (MI_map_64qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
if (sinr_db1 > MI_map_64qam[0][226]) {
SI += (MI_map_64qam[1][226]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
if (sinr_db1 == MI_map_64qam[0][index]) {
SI += (MI_map_64qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
}
//for sinr_db2
for (index = 0; index < 227; index++) {
if (sinr_db2 < MI_map_64qam[0][0]) {
SI += (MI_map_64qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
if (sinr_db2 > MI_map_64qam[0][226]) {
SI += (MI_map_64qam[1][226]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
if (sinr_db2 == MI_map_64qam[0][index]) {
SI += (MI_map_64qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=6;
break;
}
}
} }
}
} }
}
// } // }
RBIR = SI/M; RBIR = SI/M;
//Now RBIR->SINR_effective Mapping //Now RBIR->SINR_effective Mapping
//binary search method is performed here //binary search method is performed here
if(mcs<10) { if(mcs<10) {
start = 0; start = 0;
end = 161; end = 161;
middle = end/2; middle = end/2;
if (RBIR <= MI_map_4qam[2][start]) { if (RBIR <= MI_map_4qam[2][start]) {
sinr_eff = MI_map_4qam[0][start]; sinr_eff = MI_map_4qam[0][start];
} else {
if (RBIR >= MI_map_4qam[2][end])
sinr_eff = MI_map_4qam[0][end];
else {
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if (RBIR < MI_map_4qam[2][middle]) {
end = middle;
middle = end/2;
} else { } else {
start = middle; if (RBIR >= MI_map_4qam[2][end])
middle = (end-middle)/2; sinr_eff = MI_map_4qam[0][end];
} else {
} //while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if (RBIR < MI_map_4qam[2][middle]) {
end = middle;
middle = end/2;
} else {
start = middle;
middle = (end-middle)/2;
}
}
for (; end>start; end--) { for (; end>start; end--) {
if ((RBIR < MI_map_4qam[2][end]) && (RBIR > MI_map_4qam[2][end-2])) { if ((RBIR < MI_map_4qam[2][end]) && (RBIR > MI_map_4qam[2][end-2])) {
sinr_eff = MI_map_4qam[0][end-1]; sinr_eff = MI_map_4qam[0][end-1];
break; break;
}
}
} }
}
}
sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs]; sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs];
} }
else if (mcs>9 && mcs<17) { else if (mcs>9 && mcs<17) {
start = 0; start = 0;
end = 196; end = 196;
middle = end/2; middle = end/2;
if (RBIR <= MI_map_16qam[2][start]) { if (RBIR <= MI_map_16qam[2][start]) {
sinr_eff = MI_map_16qam[0][start]; sinr_eff = MI_map_16qam[0][start];
} else {
if (RBIR >= MI_map_16qam[2][end])
sinr_eff = MI_map_16qam[0][end];
else {
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if (RBIR < MI_map_16qam[2][middle]) {
end = middle;
middle = end/2;
} else { } else {
start = middle; if (RBIR >= MI_map_16qam[2][end])
middle = (end-middle)/2; sinr_eff = MI_map_16qam[0][end];
} else {
} //while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if (RBIR < MI_map_16qam[2][middle]) {
end = middle;
middle = end/2;
} else {
start = middle;
middle = (end-middle)/2;
}
}
for (; end>start; end--) { for (; end>start; end--) {
if ((RBIR < MI_map_16qam[2][end]) && (RBIR > MI_map_16qam[2][end-2])) { if ((RBIR < MI_map_16qam[2][end]) && (RBIR > MI_map_16qam[2][end-2])) {
sinr_eff = MI_map_16qam[0][end-1]; sinr_eff = MI_map_16qam[0][end-1];
break; break;
}
}
} }
}
}
sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs]; sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs];
} else if (mcs>16) { } else if (mcs>16) {
start = 0; start = 0;
end = 226; end = 226;
middle = end/2; middle = end/2;
if (RBIR <= MI_map_64qam[2][start]) { if (RBIR <= MI_map_64qam[2][start]) {
sinr_eff = MI_map_64qam[0][start]; sinr_eff = MI_map_64qam[0][start];
} else {
if (RBIR >= MI_map_64qam[2][end])
sinr_eff = MI_map_64qam[0][end];
else {
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if (RBIR < MI_map_64qam[2][middle]) {
end = middle;
middle = end/2;
} else { } else {
start = middle; if (RBIR >= MI_map_64qam[2][end])
middle = (end-middle)/2; sinr_eff = MI_map_64qam[0][end];
} else {
} //while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if (RBIR < MI_map_64qam[2][middle]) {
end = middle;
middle = end/2;
} else {
start = middle;
middle = (end-middle)/2;
}
}
for (; end>start; end--) { for (; end>start; end--) {
if ((RBIR < MI_map_64qam[2][end]) && (RBIR > MI_map_64qam[2][end-2])) { if ((RBIR < MI_map_64qam[2][end]) && (RBIR > MI_map_64qam[2][end-2])) {
sinr_eff = MI_map_64qam[0][end-1]; sinr_eff = MI_map_64qam[0][end-1];
break; break;
}
}
} }
}
}
sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs]; sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs];
} }
printf("SINR_Eff = %e\n",sinr_eff); printf("SINR_Eff = %e\n",sinr_eff);
sinr_eff *= 10; sinr_eff *= 10;
sinr_eff = floor(sinr_eff); sinr_eff = floor(sinr_eff);
// if ((int)sinr_eff%2) { // if ((int)sinr_eff%2) {
// sinr_eff += 1; // sinr_eff += 1;
// } // }
sinr_eff /= 10; sinr_eff /= 10;
printf("sinr_eff after rounding = %f\n",sinr_eff); printf("sinr_eff after rounding = %f\n",sinr_eff);
for (index = 0; index < 16; index++) { for (index = 0; index < 16; index++) {
if(index == 0) { if(index == 0) {
if (sinr_eff < sinr_bler_map_up[mcs][0][index]) { if (sinr_eff < sinr_bler_map_up[mcs][0][index]) {
bler = 1; bler = 1;
break; break;
} }
} }
if (sinr_eff == sinr_bler_map_up[mcs][0][index]) { if (sinr_eff == sinr_bler_map_up[mcs][0][index]) {
bler = sinr_bler_map_up[mcs][1][index]; bler = sinr_bler_map_up[mcs][1][index];
}
} }
}
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space #ifdef USER_MODE // need to be adapted for the emulation in the kernel space
if (uniformrandom() < bler) { if (uniformrandom() < bler) {
printf("abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler); printf("abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
return(0); return(0);
} else { } else {
printf("abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler); printf("abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
return(1); return(1);
} }
#endif #endif
...@@ -1872,85 +1874,85 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, ...@@ -1872,85 +1874,85 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
uint16_t *crnti) uint16_t *crnti)
{ {
uint8_t UE_id; uint8_t UE_id;
uint16_t rnti; uint16_t rnti;
int subframe = proc->subframe_rx; int subframe = proc->subframe_rx;
uint8_t harq_pid; uint8_t harq_pid;
uint8_t CC_id = eNB->CC_id; uint8_t CC_id = eNB->CC_id;
harq_pid = subframe2harq_pid(&eNB->frame_parms,proc->frame_rx,subframe); harq_pid = subframe2harq_pid(&eNB->frame_parms,proc->frame_rx,subframe);
rnti = eNB->ulsch[UE_index]->rnti; rnti = eNB->ulsch[UE_index]->rnti;
#ifdef DEBUG_PHY #ifdef DEBUG_PHY
LOG_D(PHY,"[eNB %d] ulsch_decoding_emul : subframe %d UE_index %d harq_pid %d rnti %x\n",eNB->Mod_id,subframe,UE_index,harq_pid,rnti); LOG_D(PHY,"[eNB %d] ulsch_decoding_emul : subframe %d UE_index %d harq_pid %d rnti %x\n",eNB->Mod_id,subframe,UE_index,harq_pid,rnti);
#endif #endif
for (UE_id=0; UE_id<NB_UE_INST; UE_id++) { for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[PHY_vars_UE_g[UE_id][CC_id]->current_thread_id[subframe]][0]->crnti) if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[PHY_vars_UE_g[UE_id][CC_id]->current_thread_id[subframe]][0]->crnti)
break; break;
}
if (UE_id==NB_UE_INST) {
LOG_W(PHY,"[eNB %d] ulsch_decoding_emul: FATAL, didn't find UE with rnti %x (UE index %d)\n",
eNB->Mod_id, rnti, UE_index);
return(1+eNB->ulsch[UE_id]->max_turbo_iterations);
} else {
LOG_D(PHY,"[eNB %d] Found UE with rnti %x => UE_id %d\n",eNB->Mod_id, rnti, UE_id);
}
if (PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->harq_processes[harq_pid]->status == CBA_ACTIVE) {
*crnti = rnti;
PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->harq_processes[harq_pid]->status=IDLE;
} else
*crnti = 0x0;
if (1) {
LOG_D(PHY,"ulsch_decoding_emul abstraction successful\n");
memcpy(eNB->ulsch[UE_index]->harq_processes[harq_pid]->b,
PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->harq_processes[harq_pid]->b,
eNB->ulsch[UE_index]->harq_processes[harq_pid]->TBS>>3);
// get local ue's ack
if ((UE_index >= oai_emulation.info.first_ue_local) ||(UE_index <(oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local))) {
get_ack(&eNB->frame_parms,
PHY_vars_UE_g[UE_id][CC_id]->dlsch[0][0][0]->harq_ack,
proc->subframe_tx,
proc->subframe_rx,
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK,0);
} else { // get remote UEs' ack
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[0] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[0];
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[1] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[1];
} }
// Do abstraction of PUSCH feedback if (UE_id==NB_UE_INST) {
LOG_W(PHY,"[eNB %d] ulsch_decoding_emul: FATAL, didn't find UE with rnti %x (UE index %d)\n",
eNB->Mod_id, rnti, UE_index);
return(1+eNB->ulsch[UE_id]->max_turbo_iterations);
} else {
LOG_D(PHY,"[eNB %d] Found UE with rnti %x => UE_id %d\n",eNB->Mod_id, rnti, UE_id);
}
if (PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->harq_processes[harq_pid]->status == CBA_ACTIVE) {
*crnti = rnti;
PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->harq_processes[harq_pid]->status=IDLE;
} else
*crnti = 0x0;
if (1) {
LOG_D(PHY,"ulsch_decoding_emul abstraction successful\n");
memcpy(eNB->ulsch[UE_index]->harq_processes[harq_pid]->b,
PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->harq_processes[harq_pid]->b,
eNB->ulsch[UE_index]->harq_processes[harq_pid]->TBS>>3);
// get local ue's ack
if ((UE_index >= oai_emulation.info.first_ue_local) ||(UE_index <(oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local))) {
get_ack(&eNB->frame_parms,
PHY_vars_UE_g[UE_id][CC_id]->dlsch[0][0][0]->harq_ack,
proc->subframe_tx,
proc->subframe_rx,
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK,0);
} else { // get remote UEs' ack
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[0] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[0];
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[1] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[1];
}
// Do abstraction of PUSCH feedback
#ifdef DEBUG_PHY #ifdef DEBUG_PHY
LOG_D(PHY,"[eNB %d][EMUL] ue index %d UE_id %d: subframe %d : o_ACK (%d %d), cqi (val %d, len %d)\n", LOG_D(PHY,"[eNB %d][EMUL] ue index %d UE_id %d: subframe %d : o_ACK (%d %d), cqi (val %d, len %d)\n",
eNB->Mod_id,UE_index, UE_id, subframe,eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[0], eNB->Mod_id,UE_index, UE_id, subframe,eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[0],
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[1], eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[1],
((HLC_subband_cqi_rank1_2A_5MHz *)PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o)->cqi1, ((HLC_subband_cqi_rank1_2A_5MHz *)PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o)->cqi1,
PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->O); PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->O);
#endif #endif
eNB->ulsch[UE_index]->harq_processes[harq_pid]->Or1 = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->O; eNB->ulsch[UE_index]->harq_processes[harq_pid]->Or1 = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->O;
eNB->ulsch[UE_index]->harq_processes[harq_pid]->Or2 = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->O; eNB->ulsch[UE_index]->harq_processes[harq_pid]->Or2 = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->O;
eNB->ulsch[UE_index]->harq_processes[harq_pid]->uci_format = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->uci_format; eNB->ulsch[UE_index]->harq_processes[harq_pid]->uci_format = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->uci_format;
memcpy(eNB->ulsch[UE_index]->harq_processes[harq_pid]->o,PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o,MAX_CQI_BYTES); memcpy(eNB->ulsch[UE_index]->harq_processes[harq_pid]->o,PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o,MAX_CQI_BYTES);
memcpy(eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_RI,PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_RI,2); memcpy(eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_RI,PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_RI,2);
eNB->ulsch[UE_index]->harq_processes[harq_pid]->cqi_crc_status = 1; eNB->ulsch[UE_index]->harq_processes[harq_pid]->cqi_crc_status = 1;
return(1); return(1);
} else { } else {
LOG_W(PHY,"[eNB %d] ulsch_decoding_emul abstraction failed for UE %d\n",eNB->Mod_id,UE_index); LOG_W(PHY,"[eNB %d] ulsch_decoding_emul abstraction failed for UE %d\n",eNB->Mod_id,UE_index);
eNB->ulsch[UE_index]->harq_processes[harq_pid]->cqi_crc_status = 0; eNB->ulsch[UE_index]->harq_processes[harq_pid]->cqi_crc_status = 0;
// retransmission // retransmission
return(1+eNB->ulsch[UE_index]->max_turbo_iterations); return(1+eNB->ulsch[UE_index]->max_turbo_iterations);
} }
} }
#endif #endif
......
...@@ -555,6 +555,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, ...@@ -555,6 +555,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
uint64_t startTime=rdtsc(); uint64_t startTime=rdtsc();
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++)
{ {
eNB->proc.threadPool.startProcessingUE=rdtsc();
dlsch0 = eNB->dlsch[(uint8_t)UE_id][0]; dlsch0 = eNB->dlsch[(uint8_t)UE_id][0];
dlsch1 = eNB->dlsch[(uint8_t)UE_id][1]; dlsch1 = eNB->dlsch[(uint8_t)UE_id][1];
...@@ -567,11 +568,9 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, ...@@ -567,11 +568,9 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
AssertFatal(harq_pid>=0,"harq_pid is negative\n"); AssertFatal(harq_pid>=0,"harq_pid is negative\n");
if (harq_pid>=8) if (harq_pid>=8)
{ LOG_E(PHY,"harq_pid:%d corrupt must be 0-7 UE_id:%d frame:%d subframe:%d rnti:%x\n",
LOG_E(PHY,"harq_pid:%d corrupt must be 0-7 UE_id:%d frame:%d subframe:%d rnti:%x\n", harq_pid,UE_id,frame,subframe,dlsch0->rnti); harq_pid,UE_id,frame,subframe,dlsch0->rnti);
}
else else
{
// generate pdsch // generate pdsch
pdsch_procedures(eNB, pdsch_procedures(eNB,
proc, proc,
...@@ -580,7 +579,6 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, ...@@ -580,7 +579,6 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
dlsch1, dlsch1,
&eNB->UE_stats[(uint32_t)UE_id], &eNB->UE_stats[(uint32_t)UE_id],
0); 0);
}
} }
} }
...@@ -615,19 +613,19 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, ...@@ -615,19 +613,19 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
} }
request_t* tmp; request_t* tmp;
while ((tmp=eNB->proc.threadPool.doneRequests)!=NULL) { while ((tmp=eNB->proc.threadPool.doneRequests)!=NULL) {
tmp->returnTime=rdtsc(); tmp->returnTime=rdtsc();
tmp->cumulSubframe=tmp->returnTime-startTime; tmp->cumulSubframe=tmp->returnTime-startTime;
// Ignore write error (if no trace listner) // Ignore write error (if no trace listner)
if (write(eNB->proc.threadPool.traceFd, tmp, sizeof(request_t)- 2*sizeof(void*))) {}; if (write(eNB->proc.threadPool.traceFd, tmp, sizeof(request_t)- 2*sizeof(void*))) {};
eNB->proc.threadPool.doneRequests=tmp->next; eNB->proc.threadPool.doneRequests=tmp->next;
start_meas(&eNB->dlsch_interleaving_stats); start_meas(&eNB->dlsch_interleaving_stats);
turboEncode_t * rdata=(turboEncode_t *) tmp->data; turboEncode_t * rdata=(turboEncode_t *) tmp->data;
rdata->dlsch->harq_processes[rdata->harq_pid]->RTC[rdata->r] = rdata->dlsch->harq_processes[rdata->harq_pid]->RTC[rdata->r] =
sub_block_interleaving_turbo(4+(rdata->Kr_bytes*8), sub_block_interleaving_turbo(4+(rdata->Kr_bytes*8),
rdata->output+96, //&dlsch->harq_processes[harq_pid]->d[r][96], rdata->output+96, //&dlsch->harq_processes[harq_pid]->d[r][96],
rdata->dlsch->harq_processes[rdata->harq_pid]->w[rdata->r]); rdata->dlsch->harq_processes[rdata->harq_pid]->w[rdata->r]);
freeRequest(tmp); freeRequest(tmp);
stop_meas(&eNB->dlsch_interleaving_stats); stop_meas(&eNB->dlsch_interleaving_stats);
} }
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
...@@ -1506,9 +1504,10 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) ...@@ -1506,9 +1504,10 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
eNB->proc.threadPool.newestRequests != NULL || eNB->proc.threadPool.newestRequests != NULL ||
eNB->proc.threadPool.doneRequests != NULL eNB->proc.threadPool.doneRequests != NULL
) )
LOG_E(PHY,"no finished = %d\n",eNB->proc.threadPool.notFinishedJobs); LOG_E(PHY,"no finished = %d\n",eNB->proc.threadPool.notFinishedJobs);
uint64_t startTime=rdtsc(); uint64_t startTime=rdtsc();
for (int i=0; i<NUMBER_OF_UE_MAX; i++) { for (int i=0; i<NUMBER_OF_UE_MAX; i++) {
eNB->proc.threadPool.startProcessingUE=rdtsc();
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[i]; LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[i];
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
...@@ -1590,15 +1589,15 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) ...@@ -1590,15 +1589,15 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
request_t* tmp; request_t* tmp;
while ((tmp=eNB->proc.threadPool.doneRequests)!=NULL) { while ((tmp=eNB->proc.threadPool.doneRequests)!=NULL) {
turboDecode_t * rdata=(turboDecode_t *) tmp->data; turboDecode_t * rdata=(turboDecode_t *) tmp->data;
tmp->decodeIterations=rdata->decodeIterations; tmp->decodeIterations=rdata->decodeIterations;
post_decode(tmp); post_decode(tmp);
tmp->returnTime=rdtsc(); tmp->returnTime=rdtsc();
tmp->cumulSubframe=tmp->returnTime-startTime; tmp->cumulSubframe=tmp->returnTime-startTime;
// Ignore write error (if no trace listner) // Ignore write error (if no trace listner)
if (write(eNB->proc.threadPool.traceFd, tmp, sizeof(request_t)- 2*sizeof(void*))) {}; if (write(eNB->proc.threadPool.traceFd, tmp, sizeof(request_t)- 2*sizeof(void*))) {};
eNB->proc.threadPool.doneRequests=tmp->next; eNB->proc.threadPool.doneRequests=tmp->next;
freeRequest(tmp); freeRequest(tmp);
} }
} }
......
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
uint64_t cpuCyclesMicroSec; uint64_t cpuCyclesMicroSec;
static __inline__ uint64_t rdtsc(void) { static __inline__ uint64_t rdtsc(void) {
uint64_t a, d; uint64_t a, d;
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
return (d<<32) | a; return (d<<32) | a;
} }
#include "thread-pool.h" #include "thread-pool.h"
...@@ -30,10 +30,10 @@ int main(int argc, char* argv[]) { ...@@ -30,10 +30,10 @@ int main(int argc, char* argv[]) {
usleep(100000); usleep(100000);
cpuCyclesMicroSec=(rdtsc()-deb)/100000; cpuCyclesMicroSec=(rdtsc()-deb)/100000;
printf("Cycles per µs: %lu\n",cpuCyclesMicroSec); printf("Cycles per µs: %lu\n",cpuCyclesMicroSec);
#define SEP "\t" #define SEP "\t"
printf("Frame" SEP "SubFrame" SEP "CodeBlock" SEP "RNTI" SEP "Iterations" SEP printf("Frame" SEP "SubFrame" SEP "CodeBlock" SEP "RNTI" SEP "Iterations" SEP
"StartTime" SEP "RunTime" SEP "ReturnTime" SEP "CumulSubFrame" "PreparationTime" SEP "StartTime" SEP "RunTime" SEP "ReturnTime" SEP "CumulSubFrame"
SEP "CPUcore" SEP "ThreadID" "\n"); SEP "CPUcore" SEP "ThreadID" "\n");
mkfifo("/tmp/test-tcri",0666); mkfifo("/tmp/test-tcri",0666);
int fd=open("/tmp/test-tcri", O_RDONLY); int fd=open("/tmp/test-tcri", O_RDONLY);
...@@ -44,27 +44,28 @@ int main(int argc, char* argv[]) { ...@@ -44,27 +44,28 @@ int main(int argc, char* argv[]) {
request_t doneRequest; request_t doneRequest;
int s=sizeof(request_t) -2*sizeof(void*); int s=sizeof(request_t) -2*sizeof(void*);
while ( 1 ) { while ( 1 ) {
if ( read(fd,&doneRequest, s) == s ) { if ( read(fd,&doneRequest, s) == s ) {
union turboReqUnion id={.p=doneRequest.id}; union turboReqUnion id= {.p=doneRequest.id};
doneRequest.processedBy[15]='\0'; doneRequest.processedBy[15]='\0';
printf("%u" SEP "%u" SEP "%u" SEP "%u" SEP "%lu" SEP printf("%u" SEP "%u" SEP "%u" SEP "%u" SEP "%lu" SEP
"%lu" SEP "%lu" SEP "%lu" SEP "%lu" SEP "%lu" SEP "%lu" SEP "%lu" SEP
"%lu" SEP "%u" SEP "%s" "\n", "%lu" SEP "%u" SEP "%s" "\n",
id.s.frame, id.s.frame,
id.s.subframe, id.s.subframe,
id.s.codeblock, id.s.codeblock,
id.s.rnti, id.s.rnti,
doneRequest.decodeIterations, doneRequest.decodeIterations,
(doneRequest.startProcessingTime-doneRequest.creationTime)/cpuCyclesMicroSec, (doneRequest.creationTime-doneRequest.startUELoop)/cpuCyclesMicroSec,
(doneRequest.endProcessingTime-doneRequest.startProcessingTime)/cpuCyclesMicroSec, (doneRequest.startProcessingTime-doneRequest.creationTime)/cpuCyclesMicroSec,
(doneRequest.returnTime-doneRequest.endProcessingTime)/cpuCyclesMicroSec, (doneRequest.endProcessingTime-doneRequest.startProcessingTime)/cpuCyclesMicroSec,
doneRequest.cumulSubframe/cpuCyclesMicroSec, (doneRequest.returnTime-doneRequest.endProcessingTime)/cpuCyclesMicroSec,
doneRequest.coreId, doneRequest.cumulSubframe/cpuCyclesMicroSec,
doneRequest.processedBy doneRequest.coreId,
); doneRequest.processedBy
} else { );
printf("no measurements\n"); } else {
sleep(1); printf("no measurements\n");
} sleep(1);
}
} }
} }
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
request_t * createRequest(enum request_t type,int size) { request_t * createRequest(enum request_t type,int size) {
request_t* request; request_t* request;
AssertFatal( (request = (request_t*)aligned_alloc(32,sizeof(request_t)+size)) != NULL,""); AssertFatal( (request = (request_t*)aligned_alloc(32,sizeof(request_t)+size)) != NULL,"");
memset(request,0,sizeof(request_t));
request->id = 0; request->id = 0;
request->type=type; request->type=type;
request->next = NULL; request->next = NULL;
...@@ -200,12 +201,7 @@ void handle_request(tpool_t * tp, request_t* request) { ...@@ -200,12 +201,7 @@ void handle_request(tpool_t * tp, request_t* request) {
tp->doneRequests=request; tp->doneRequests=request;
condsignal(tp->notifDone); condsignal(tp->notifDone);
mutexunlock(tp->lockReportDone); mutexunlock(tp->lockReportDone);
/*
printf("Thread '%ld' handled request '%d' delay in µs:%ld\n",
syscall( SYS_gettid ),
request->id,
(rdtsc() - request->creationTime)/tp->cpuCyclesMicroSec);
*/
} }
void* one_thread(void* data) { void* one_thread(void* data) {
......
...@@ -25,11 +25,12 @@ union turboReqUnion { ...@@ -25,11 +25,12 @@ union turboReqUnion {
typedef struct request { typedef struct request {
uint64_t id; uint64_t id;
enum request_t type; enum request_t type;
uint64_t startUELoop;
uint64_t creationTime; uint64_t creationTime;
uint64_t startProcessingTime; uint64_t startProcessingTime;
uint64_t endProcessingTime; uint64_t endProcessingTime;
uint64_t returnTime; uint64_t returnTime;
uint64_t cumulSubframe; uint64_t cumulSubframe;
uint64_t decodeIterations; uint64_t decodeIterations;
int coreId; int coreId;
char processedBy[16]; char processedBy[16];
...@@ -60,6 +61,7 @@ typedef struct thread_pool { ...@@ -60,6 +61,7 @@ typedef struct thread_pool {
int traceFd; int traceFd;
int dummyTraceFd; int dummyTraceFd;
uint64_t cpuCyclesMicroSec; uint64_t cpuCyclesMicroSec;
uint64_t startProcessingUE;
int nbThreads; int nbThreads;
bool restrictRNTI; bool restrictRNTI;
struct one_thread * allthreads; struct one_thread * allthreads;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment