Commit b51833d8 authored by ISIP CS/NCTU's avatar ISIP CS/NCTU

isip turbo decoder thread parallel and dynamic assignment according to code segment

parent 6551ec4c
......@@ -66,113 +66,127 @@
void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch)
{
int i,r;
int i, r;
if (ulsch) {
for (i=0; i<8; i++) {
if (ulsch->harq_processes[i]) {
if (ulsch->harq_processes[i]->b) {
free16(ulsch->harq_processes[i]->b,MAX_ULSCH_PAYLOAD_BYTES);
if (ulsch)
{
for (i = 0; i < 8; i++)
{
if (ulsch->harq_processes[i])
{
if (ulsch->harq_processes[i]->b)
{
free16(ulsch->harq_processes[i]->b, MAX_ULSCH_PAYLOAD_BYTES);
ulsch->harq_processes[i]->b = NULL;
}
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 768);
for (r = 0; r < MAX_NUM_ULSCH_SEGMENTS; r++)
{
free16(ulsch->harq_processes[i]->c[r], ((r == 0) ? 8 : 0) + 768);
ulsch->harq_processes[i]->c[r] = NULL;
}
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++)
if (ulsch->harq_processes[i]->d[r]) {
free16(ulsch->harq_processes[i]->d[r],((3*8*6144)+12+96)*sizeof(short));
for (r = 0; r < MAX_NUM_ULSCH_SEGMENTS; r++)
if (ulsch->harq_processes[i]->d[r])
{
free16(ulsch->harq_processes[i]->d[r], ((3 * 8 * 6144) + 12 + 96) * sizeof(short));
ulsch->harq_processes[i]->d[r] = NULL;
}
free16(ulsch->harq_processes[i],sizeof(LTE_UL_eNB_HARQ_t));
free16(ulsch->harq_processes[i], sizeof(LTE_UL_eNB_HARQ_t));
ulsch->harq_processes[i] = NULL;
}
}
free16(ulsch,sizeof(LTE_eNB_ULSCH_t));
free16(ulsch, sizeof(LTE_eNB_ULSCH_t));
ulsch = NULL;
}
}
LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag)
LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations, uint8_t N_RB_UL, uint8_t abstraction_flag)
{
LTE_eNB_ULSCH_t *ulsch;
uint8_t exit_flag = 0,i,r;
unsigned char bw_scaling =1;
uint8_t exit_flag = 0, i, r;
unsigned char bw_scaling = 1;
switch (N_RB_UL) {
switch (N_RB_UL)
{
case 6:
bw_scaling =16;
bw_scaling = 16;
break;
case 25:
bw_scaling =4;
bw_scaling = 4;
break;
case 50:
bw_scaling =2;
bw_scaling = 2;
break;
default:
bw_scaling =1;
bw_scaling = 1;
break;
}
ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t));
if (ulsch) {
memset(ulsch,0,sizeof(LTE_eNB_ULSCH_t));
if (ulsch)
{
memset(ulsch, 0, sizeof(LTE_eNB_ULSCH_t));
ulsch->max_turbo_iterations = max_turbo_iterations;
ulsch->Mlimit = 4;
for (i=0; i<8; i++) {
for (i = 0; i < 8; i++)
{
// printf("new_ue_ulsch: Harq process %d\n",i);
ulsch->harq_processes[i] = (LTE_UL_eNB_HARQ_t *)malloc16(sizeof(LTE_UL_eNB_HARQ_t));
if (ulsch->harq_processes[i]) {
memset(ulsch->harq_processes[i],0,sizeof(LTE_UL_eNB_HARQ_t));
ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
if (ulsch->harq_processes[i])
{
memset(ulsch->harq_processes[i], 0, sizeof(LTE_UL_eNB_HARQ_t));
ulsch->harq_processes[i]->b = (uint8_t *)malloc16(MAX_ULSCH_PAYLOAD_BYTES / bw_scaling);
if (ulsch->harq_processes[i]->b)
memset(ulsch->harq_processes[i]->b,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
memset(ulsch->harq_processes[i]->b, 0, MAX_ULSCH_PAYLOAD_BYTES / bw_scaling);
else
exit_flag=3;
exit_flag = 3;
if (abstraction_flag==0) {
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS/bw_scaling; r++) {
ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+768);
if (abstraction_flag == 0)
{
for (r = 0; r < MAX_NUM_ULSCH_SEGMENTS / bw_scaling; r++)
{
ulsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(((r == 0) ? 8 : 0) + 3 + 768);
if (ulsch->harq_processes[i]->c[r])
memset(ulsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+768);
memset(ulsch->harq_processes[i]->c[r], 0, ((r == 0) ? 8 : 0) + 3 + 768);
else
exit_flag=2;
exit_flag = 2;
ulsch->harq_processes[i]->d[r] = (short*)malloc16(((3*8*6144)+12+96)*sizeof(short));
ulsch->harq_processes[i]->d[r] = (short *)malloc16(((3 * 8 * 6144) + 12 + 96) * sizeof(short));
if (ulsch->harq_processes[i]->d[r])
memset(ulsch->harq_processes[i]->d[r],0,((3*8*6144)+12+96)*sizeof(short));
memset(ulsch->harq_processes[i]->d[r], 0, ((3 * 8 * 6144) + 12 + 96) * sizeof(short));
else
exit_flag=2;
exit_flag = 2;
}
ulsch->harq_processes[i]->subframe_scheduling_flag = 0;
}
} else {
exit_flag=1;
}
else
{
exit_flag = 1;
}
}
if (exit_flag==0)
return(ulsch);
if (exit_flag == 0)
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);
return(NULL);
return (NULL);
}
void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch)
......@@ -181,11 +195,14 @@ void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch)
unsigned char i;
//ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t));
if (ulsch) {
if (ulsch)
{
ulsch->rnti = 0;
for (i=0; i<8; i++) {
if (ulsch->harq_processes[i]) {
for (i = 0; i < 8; i++)
{
if (ulsch->harq_processes[i])
{
// ulsch->harq_processes[i]->Ndi = 0;
ulsch->harq_processes[i]->status = 0;
ulsch->harq_processes[i]->subframe_scheduling_flag = 0;
......@@ -194,57 +211,50 @@ void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch)
ulsch->harq_processes[i]->round = 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;
crc = cqi[CQI_LENGTH>>3];
crc = cqi[CQI_LENGTH >> 3];
// printf("crc1: %x, shift %d\n",crc,CQI_LENGTH&0x7);
crc = (crc<<(CQI_LENGTH&0x7));
crc = (crc << (CQI_LENGTH & 0x7));
// clear crc bits
// ((char *)cqi)[CQI_LENGTH>>3] &= 0xff>>(8-(CQI_LENGTH&0x7));
// 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
//(((char *)cqi)[1+(CQI_LENGTH>>3)]) = 0;
// printf("crc : %x\n",crc);
return(crc);
return (crc);
}
int ulsch_decoding_data_2thread0(td_params* tdp) {
int ulsch_decoding_data_2thread0(td_params *tdp)
{
PHY_VARS_eNB *eNB = tdp->eNB;
int UE_id = tdp->UE_id;
int harq_pid = tdp->harq_pid;
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;
int offset = 0;
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_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
int Q_m = get_Qm_ul(ulsch_harq->mcs);
int G = ulsch_harq->G;
uint32_t E;
uint32_t Gp,GpmodC,Nl=1;
uint32_t Gp, GpmodC, Nl = 1;
uint32_t C = ulsch_harq->C;
uint8_t (*tc)(int16_t *y,
uint8_t (*tc)(int16_t * y,
uint8_t *,
uint16_t,
uint16_t,
......@@ -265,118 +275,122 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
else
tc = phy_threegpplte_turbo_decoder8;
// 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
if (r<ulsch_harq->Cminus)
if (r < ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
Kr_bytes = Kr >> 3;
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
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);
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);
iind = 123 + ((Kr_bytes - 256) >> 3);
else
{
LOG_E(PHY, "ulsch_decoding: Illegal codeword size %d!!!\n", Kr_bytes);
return (-1);
}
// This is stolen from rate-matching algorithm to get the value of E
Gp = G/Nl/Q_m;
GpmodC = Gp%C;
Gp = G / Nl / Q_m;
GpmodC = Gp % C;
if (r < (C-(GpmodC)))
E = Nl*Q_m * (Gp/C);
if (r < (C - (GpmodC)))
E = Nl * Q_m * (Gp / C);
else
E = Nl*Q_m * ((GpmodC==0?0:1) + (Gp/C));
E = Nl * Q_m * ((GpmodC == 0 ? 0 : 1) + (Gp / C));
r_offset += E;
if (r==0) {
offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
} else {
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
if (r == 0)
{
offset = Kr_bytes - (ulsch_harq->F >> 3) - ((ulsch_harq->C > 1) ? 3 : 0);
}
else
{
offset += (Kr_bytes - ((ulsch_harq->C > 1) ? 3 : 0));
}
}
// go through second half of segments
for (; r<(ulsch_harq->C); r++) {
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)
if (r < ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
Kr_bytes = Kr >> 3;
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
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);
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);
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
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
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
(uint8_t*)&dummy_w[r][0],
(r==0) ? ulsch_harq->F : 0);
memset(&dummy_w[r][0], 0, 3 * (6144 + 64) * sizeof(short));
ulsch_harq->RTC[r] = generate_dummy_w(4 + (Kr_bytes * 8),
(uint8_t *)&dummy_w[r][0],
(r == 0) ? ulsch_harq->F : 0);
#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",
r, G,
Kr*3,
Kr * 3,
Q_m,
nb_rb,
ulsch_harq->Nl);
#endif
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,
(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->round == 0) ? 1 : 0, // clear
get_Qm_ul(ulsch_harq->mcs),
1,
r,
&E)==-1) {
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
return(-1);
&E) == -1)
{
LOG_E(PHY, "ulsch_decoding.c: Problem in rate matching\n");
return (-1);
}
r_offset += E;
sub_block_deinterleaving_turbo(4+Kr,
sub_block_deinterleaving_turbo(4 + Kr,
&ulsch_harq->d[r][96],
ulsch_harq->w[r]);
......@@ -385,15 +399,14 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
else
crc_type = CRC24_B;
ret = tc(&ulsch_harq->d[r][96],
ulsch_harq->c[r],
Kr,
f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1],
ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
f1f2mat_old[iind * 2],
f1f2mat_old[(iind * 2) + 1],
ulsch->max_turbo_iterations, //MAX_TURBO_ITERATIONS,
crc_type,
(r==0) ? ulsch_harq->F : 0,
(r == 0) ? ulsch_harq->F : 0,
&eNB->ulsch_tc_init_stats,
&eNB->ulsch_tc_alpha_stats,
&eNB->ulsch_tc_beta_stats,
......@@ -404,61 +417,67 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
// Reassembly of Transport block here
if (ret != (1+ulsch->max_turbo_iterations)) {
if (r<ulsch_harq->Cminus)
if (ret != (1 + ulsch->max_turbo_iterations))
{
if (r < ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
Kr_bytes = Kr >> 3;
memcpy(ulsch_harq->b+offset,
memcpy(ulsch_harq->b + offset,
ulsch_harq->c[r],
Kr_bytes - ((ulsch_harq->C>1)?3:0));
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
} else {
Kr_bytes - ((ulsch_harq->C > 1) ? 3 : 0));
offset += (Kr_bytes - ((ulsch_harq->C > 1) ? 3 : 0));
}
else
{
break;
}
}
return(ret);
return (ret);
}
extern int oai_exit;
void *td_thread(void *param) {
pthread_setname_np( pthread_self(), "td processing");
PHY_VARS_eNB *eNB = ((td_params*)param)->eNB;
void *td_thread(void *param)
{
pthread_setname_np(pthread_self(), "td processing");
PHY_VARS_eNB *eNB = ((td_params *)param)->eNB;
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");
exit_fun( "ERROR pthread_cond_signal" );
return(NULL);
exit_fun("ERROR pthread_cond_signal");
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;
unsigned int r,r_offset=0,Kr,Kr_bytes,iind;
unsigned int r, r_offset = 0, Kr, Kr_bytes, iind;
uint8_t crc_type;
int offset = 0;
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_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
//int Q_m = get_Qm_ul(ulsch_harq->mcs);
......@@ -466,7 +485,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
unsigned int E;
int Cby2;
uint8_t (*tc)(int16_t *y,
uint8_t (*tc)(int16_t * y,
uint8_t *,
uint16_t,
uint16_t,
......@@ -484,26 +503,28 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
wait.tv_sec = 0;
wait.tv_nsec = 5000000L;
if (llr8_flag == 0)
tc = phy_threegpplte_turbo_decoder16;
else
tc = phy_threegpplte_turbo_decoder8;
if (ulsch_harq->C>1) { // wakeup worker if more than 1 segment
if (pthread_mutex_timedlock(&proc->mutex_td,&wait) != 0) {
if (ulsch_harq->C > 1)
{ // wakeup worker if more than 1 segment
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);
exit_fun( "error locking mutex_fep" );
exit_fun("error locking mutex_fep");
return -1;
}
if (proc->instance_cnt_td==0) {
if (proc->instance_cnt_td == 0)
{
printf("[eNB] TD thread busy\n");
exit_fun("TD thread busy");
pthread_mutex_unlock( &proc->mutex_td );
pthread_mutex_unlock(&proc->mutex_td);
return -1;
}
......@@ -514,59 +535,62 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
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) {
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);
exit_fun("ERROR pthread_cond_signal");
return (1 + ulsch->max_turbo_iterations);
}
pthread_mutex_unlock( &proc->mutex_td );
Cby2 = ulsch_harq->C/2;
pthread_mutex_unlock(&proc->mutex_td);
Cby2 = ulsch_harq->C / 2;
}
else {
else
{
Cby2 = 1;
}
// go through first half of segments in main thread
for (r=0; r<Cby2; r++) {
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)
if (r < ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
Kr_bytes = Kr >> 3;
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
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);
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);
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
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
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
(uint8_t*)&dummy_w[r][0],
(r==0) ? ulsch_harq->F : 0);
memset(&dummy_w[r][0], 0, 3 * (6144 + 64) * sizeof(short));
ulsch_harq->RTC[r] = generate_dummy_w(4 + (Kr_bytes * 8),
(uint8_t *)&dummy_w[r][0],
(r == 0) ? ulsch_harq->F : 0);
#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",
r, G,
Kr*3,
Kr * 3,
Q_m,
nb_rb,
ulsch_harq->Nl);
......@@ -577,27 +601,28 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
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,
(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->round == 0) ? 1 : 0, // clear
get_Qm_ul(ulsch_harq->mcs),
1,
r,
&E)==-1) {
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
return(-1);
&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;
start_meas(&eNB->ulsch_deinterleaving_stats);
sub_block_deinterleaving_turbo(4+Kr,
sub_block_deinterleaving_turbo(4 + Kr,
&ulsch_harq->d[r][96],
ulsch_harq->w[r]);
stop_meas(&eNB->ulsch_deinterleaving_stats);
......@@ -612,11 +637,11 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
ret = tc(&ulsch_harq->d[r][96],
ulsch_harq->c[r],
Kr,
f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1],
ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
f1f2mat_old[iind * 2],
f1f2mat_old[(iind * 2) + 1],
ulsch->max_turbo_iterations, //MAX_TURBO_ITERATIONS,
crc_type,
(r==0) ? ulsch_harq->F : 0,
(r == 0) ? ulsch_harq->F : 0,
&eNB->ulsch_tc_init_stats,
&eNB->ulsch_tc_alpha_stats,
&eNB->ulsch_tc_beta_stats,
......@@ -627,27 +652,32 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
// Reassembly of Transport block here
if (ret != (1+ulsch->max_turbo_iterations)) {
if (r<ulsch_harq->Cminus)
if (ret != (1 + ulsch->max_turbo_iterations))
{
if (r < ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
Kr_bytes = Kr >> 3;
if (r==0) {
if (r == 0)
{
memcpy(ulsch_harq->b,
&ulsch_harq->c[0][(ulsch_harq->F>>3)],
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 {
memcpy(ulsch_harq->b+offset,
&ulsch_harq->c[0][(ulsch_harq->F >> 3)],
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
{
memcpy(ulsch_harq->b + offset,
ulsch_harq->c[r],
Kr_bytes - ((ulsch_harq->C>1)?3:0));
offset += (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));
}
} else {
}
else
{
break;
}
stop_meas(&eNB->ulsch_turbo_decoding_stats);
......@@ -655,25 +685,26 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
// 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);
}
int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) {
int ulsch_decoding_data(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int 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;
int offset = 0;
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_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
//int Q_m = get_Qm_ul(ulsch_harq->mcs);
int G = ulsch_harq->G;
unsigned int E;
uint8_t (*tc)(int16_t *y,
uint8_t (*tc)(int16_t * y,
uint8_t *,
uint16_t,
uint16_t,
......@@ -694,44 +725,45 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
else
tc = phy_threegpplte_turbo_decoder8;
for (r=0; r<ulsch_harq->C; r++) {
for (r = 0; 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)
if (r < ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
Kr_bytes = Kr >> 3;
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
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);
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);
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
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
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
(uint8_t*)&dummy_w[r][0],
(r==0) ? ulsch_harq->F : 0);
memset(&dummy_w[r][0], 0, 3 * (6144 + 64) * sizeof(short));
ulsch_harq->RTC[r] = generate_dummy_w(4 + (Kr_bytes * 8),
(uint8_t *)&dummy_w[r][0],
(r == 0) ? ulsch_harq->F : 0);
#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",
r, G,
Kr*3,
Kr * 3,
Q_m,
nb_rb,
ulsch_harq->Nl);
......@@ -742,27 +774,28 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
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,
(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->round == 0) ? 1 : 0, // clear
get_Qm_ul(ulsch_harq->mcs),
1,
r,
&E)==-1) {
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
return(-1);
&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;
start_meas(&eNB->ulsch_deinterleaving_stats);
sub_block_deinterleaving_turbo(4+Kr,
sub_block_deinterleaving_turbo(4 + Kr,
&ulsch_harq->d[r][96],
ulsch_harq->w[r]);
stop_meas(&eNB->ulsch_deinterleaving_stats);
......@@ -777,11 +810,11 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
ret = tc(&ulsch_harq->d[r][96],
ulsch_harq->c[r],
Kr,
f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1],
ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
f1f2mat_old[iind * 2],
f1f2mat_old[(iind * 2) + 1],
ulsch->max_turbo_iterations, //MAX_TURBO_ITERATIONS,
crc_type,
(r==0) ? ulsch_harq->F : 0,
(r == 0) ? ulsch_harq->F : 0,
&eNB->ulsch_tc_init_stats,
&eNB->ulsch_tc_alpha_stats,
&eNB->ulsch_tc_beta_stats,
......@@ -794,33 +827,37 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
// Reassembly of Transport block here
if (ret != (1+ulsch->max_turbo_iterations)) {
if (r<ulsch_harq->Cminus)
if (ret != (1 + ulsch->max_turbo_iterations))
{
if (r < ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
Kr_bytes = Kr >> 3;
if (r==0) {
if (r == 0)
{
memcpy(ulsch_harq->b,
&ulsch_harq->c[0][(ulsch_harq->F>>3)],
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 {
memcpy(ulsch_harq->b+offset,
&ulsch_harq->c[0][(ulsch_harq->F >> 3)],
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
{
memcpy(ulsch_harq->b + offset,
ulsch_harq->c[r],
Kr_bytes - ((ulsch_harq->C>1)?3:0));
offset += (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));
}
} else {
}
else
{
break;
}
}
return(ret);
return (ret);
}
// ISIP Turbo Decoder
......@@ -863,7 +900,7 @@ int isip_ulsch_decoding_data(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int llr
tc = phy_threegpplte_turbo_decoder8;
// for (r = 0; r < ulsch_harq->C; r++)
for (r = (ulsch_harq->C * current_thread_num) / (ISIP_TURBO_THREAD_NUM); r < (ulsch_harq->C * (current_thread_num + 1)) / (ISIP_TURBO_THREAD_NUM); r++)
for (r = current_thread_num; r < current_thread_num + 1; r++)
{
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
......@@ -909,7 +946,7 @@ int isip_ulsch_decoding_data(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int llr
start_meas(&eNB->ulsch_rate_unmatching_stats);
if (r == (ulsch_harq->C * current_thread_num) / (ISIP_TURBO_THREAD_NUM))
if (r == current_thread_num)
{
r_offset = r * E;
}
......@@ -1001,7 +1038,8 @@ int isip_ulsch_decoding_data(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int llr
// Kr_bytes - ((ulsch_harq->C > 1) ? 3 : 0));
// offset += (Kr_bytes - ((ulsch_harq->C > 1) ? 3 : 0));
// }
if (r == (ulsch_harq->C * current_thread_num) / (ISIP_TURBO_THREAD_NUM))
if (r == current_thread_num)
{
//fprintf(fp, "First... \n");
if (r == 0)
......@@ -1011,7 +1049,6 @@ int isip_ulsch_decoding_data(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int llr
&ulsch_harq->c[0][(ulsch_harq->F >> 3)],
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
{
......@@ -1021,7 +1058,6 @@ int isip_ulsch_decoding_data(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int llr
ulsch_harq->c[r],
Kr_bytes - ((ulsch_harq->C > 1) ? 3 : 0));
offset += (Kr_bytes - ((ulsch_harq->C > 1) ? 3 : 0));
}
}
else
......@@ -1035,7 +1071,6 @@ int isip_ulsch_decoding_data(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int llr
ulsch_harq->c[r],
Kr_bytes - ((ulsch_harq->C > 1) ? 3 : 0));
offset += (Kr_bytes - ((ulsch_harq->C > 1) ? 3 : 0));
}
}
else
......@@ -1053,37 +1088,37 @@ static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2,
{
int n;
if (reset) {
*x1 = 1+ (1<<31);
*x2=*x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31);
if (reset)
{
*x1 = 1 + (1 << 31);
*x2 = *x2 ^ ((*x2 ^ (*x2 >> 1) ^ (*x2 >> 2) ^ (*x2 >> 3)) << 31);
// skip first 50 double words (1600 bits)
// printf("n=0 : x1 %x, x2 %x\n",x1,x2);
for (n=1; n<50; n++) {
*x1 = (*x1>>1) ^ (*x1>>4);
*x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
*x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
*x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
for (n = 1; n < 50; n++)
{
*x1 = (*x1 >> 1) ^ (*x1 >> 4);
*x1 = *x1 ^ (*x1 << 31) ^ (*x1 << 28);
*x2 = (*x2 >> 1) ^ (*x2 >> 2) ^ (*x2 >> 3) ^ (*x2 >> 4);
*x2 = *x2 ^ (*x2 << 31) ^ (*x2 << 30) ^ (*x2 << 29) ^ (*x2 << 28);
}
}
*x1 = (*x1>>1) ^ (*x1>>4);
*x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
*x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
*x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
return(*x1^*x2);
*x1 = (*x1 >> 1) ^ (*x1 >> 4);
*x1 = *x1 ^ (*x1 << 31) ^ (*x1 << 28);
*x2 = (*x2 >> 1) ^ (*x2 >> 2) ^ (*x2 >> 3) ^ (*x2 >> 4);
*x2 = *x2 ^ (*x2 << 31) ^ (*x2 << 30) ^ (*x2 << 29) ^ (*x2 << 28);
return (*x1 ^ *x2);
// printf("n=%d : c %x\n",n,x1^x2);
}
unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
unsigned int ulsch_decoding(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
uint8_t UE_id,
uint8_t control_only_flag,
uint8_t Nbundled,
uint8_t llr8_flag)
{
int16_t *ulsch_llr = eNB->pusch_vars[UE_id]->llr;
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
......@@ -1091,68 +1126,65 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
unsigned short nb_rb;
unsigned int A;
uint8_t Q_m;
unsigned int i,i2,q,j,j2;
unsigned int i, i2, q, j, j2;
int iprime;
unsigned int ret=0;
unsigned int ret = 0;
// uint8_t dummy_channel_output[(3*8*block_length)+12];
int r,Kr;
int r, Kr;
uint8_t *columnset;
unsigned int sumKr=0;
unsigned int Qprime,L,G,Q_CQI,Q_RI,H,Hprime,Hpp,Cmux,Rmux_prime,O_RCC;
unsigned int Qprime_ACK,Qprime_RI,len_ACK=0,len_RI=0;
unsigned int sumKr = 0;
unsigned int Qprime, L, G, Q_CQI, Q_RI, H, Hprime, Hpp, Cmux, Rmux_prime, O_RCC;
unsigned int Qprime_ACK, Qprime_RI, len_ACK = 0, len_RI = 0;
// uint8_t q_ACK[MAX_ACK_PAYLOAD],q_RI[MAX_RI_PAYLOAD];
int metric,metric_new;
int metric, metric_new;
uint8_t o_flip[8];
uint32_t x1, x2, s=0;
int16_t ys,c;
uint32_t x1, x2, s = 0;
int16_t ys, c;
uint32_t wACK_idx;
uint8_t dummy_w_cc[3*(MAX_CQI_BITS+8+32)];
int16_t y[6*14*1200] __attribute__((aligned(32)));
uint8_t ytag[14*1200];
uint8_t dummy_w_cc[3 * (MAX_CQI_BITS + 8 + 32)];
int16_t y[6 * 14 * 1200] __attribute__((aligned(32)));
uint8_t ytag[14 * 1200];
// uint8_t ytag2[6*14*1200],*ytag2_ptr;
int16_t cseq[6*14*1200];
int16_t cseq[6 * 14 * 1200];
int off;
int subframe = proc->subframe_rx;
LTE_UL_eNB_HARQ_t *ulsch_harq;
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
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];
if (harq_pid==255) {
if (harq_pid == 255)
{
LOG_E(PHY, "FATAL ERROR: illegal harq_pid, returning\n");
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 -1;
}
if (ulsch_harq->Nsymb_pusch == 0) {
LOG_E(PHY, "FATAL ERROR: harq_pid %d, Nsymb 0!\n",harq_pid);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,0);
return 1+ulsch->max_turbo_iterations;
if (ulsch_harq->Nsymb_pusch == 0)
{
LOG_E(PHY, "FATAL ERROR: harq_pid %d, Nsymb 0!\n", harq_pid);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0 + harq_pid, 0);
return 1 + ulsch->max_turbo_iterations;
}
nb_rb = ulsch_harq->nb_rb;
A = ulsch_harq->TBS;
Q_m = get_Qm_ul(ulsch_harq->mcs);
G = nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch;
#ifdef DEBUG_ULSCH_DECODING
printf("ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
frame_parms->Nid_cell,ulsch->rnti,x2,
frame_parms->Nid_cell, ulsch->rnti, x2,
ulsch_harq->round,
ulsch_harq->rvidx,
ulsch_harq->mcs,
......@@ -1162,9 +1194,10 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
subframe);
#endif
if (ulsch_harq->round == 0) {
if (ulsch_harq->round == 0)
{
// This is a new packet, so compute quantities regarding segmentation
ulsch_harq->B = A+24;
ulsch_harq->B = A + 24;
lte_segmentation(NULL,
NULL,
ulsch_harq->B,
......@@ -1181,8 +1214,9 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
sumKr = 0;
for (r=0; r<ulsch_harq->C; r++) {
if (r<ulsch_harq->Cminus)
for (r = 0; r < ulsch_harq->C; r++)
{
if (r < ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
......@@ -1190,10 +1224,11 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
sumKr += Kr;
}
if (sumKr==0) {
LOG_N(PHY,"[eNB %d] ulsch_decoding.c: FATAL sumKr is 0!\n",eNB->Mod_id);
LOG_D(PHY,"ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
frame_parms->Nid_cell,ulsch->rnti,x2,
if (sumKr == 0)
{
LOG_N(PHY, "[eNB %d] ulsch_decoding.c: FATAL sumKr is 0!\n", eNB->Mod_id);
LOG_D(PHY, "ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, mcs %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,
......@@ -1203,110 +1238,108 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
G,
subframe);
mac_xface->macphy_exit("ulsch_decoding.c: FATAL sumKr is 0!");
return(-1);
return (-1);
}
// Compute Q_ri
Qprime = ulsch_harq->O_RI*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_ri_times8;
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));
if (Qprime > 0)
{
if ((Qprime % (8 * sumKr)) > 0)
Qprime = 1 + (Qprime / (8 * sumKr));
else
Qprime = Qprime/(8*sumKr);
Qprime = Qprime / (8 * sumKr);
if (Qprime > 4*nb_rb * 12)
Qprime = 4*nb_rb * 12;
if (Qprime > 4 * nb_rb * 12)
Qprime = 4 * nb_rb * 12;
}
Q_RI = Q_m*Qprime;
Q_RI = Q_m * Qprime;
Qprime_RI = Qprime;
// Compute Q_ack
Qprime = ulsch_harq->O_ACK*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_harqack_times8;
Qprime = ulsch_harq->O_ACK * ulsch_harq->Msc_initial * ulsch_harq->Nsymb_initial * ulsch->beta_offset_harqack_times8;
if (Qprime > 0) {
if ((Qprime % (8*sumKr)) > 0)
Qprime = 1+(Qprime/(8*sumKr));
if (Qprime > 0)
{
if ((Qprime % (8 * sumKr)) > 0)
Qprime = 1 + (Qprime / (8 * sumKr));
else
Qprime = Qprime/(8*sumKr);
Qprime = Qprime / (8 * sumKr);
if (Qprime > (4*nb_rb * 12))
Qprime = 4*nb_rb * 12;
if (Qprime > (4 * nb_rb * 12))
Qprime = 4 * nb_rb * 12;
}
// Q_ACK = Qprime * Q_m;
Qprime_ACK = Qprime;
#ifdef DEBUG_ULSCH_DECODING
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
// Compute Q_cqi
if (ulsch_harq->Or1 < 12)
L=0;
L = 0;
else
L=8;
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;
Qprime = (ulsch_harq->Or1 + L) * ulsch_harq->Msc_initial * ulsch_harq->Nsymb_initial * ulsch->beta_offset_cqi_times8;
else
Qprime=0;
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));
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);
Qprime = Qprime / (8 * sumKr);
}
G = nb_rb * (12 * Q_m) * (ulsch_harq->Nsymb_pusch);
Q_CQI = Q_m * Qprime;
#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
G = G - Q_RI - Q_CQI;
ulsch_harq->G = G;
if ((int)G < 0) {
LOG_E(PHY,"FATAL: ulsch_decoding.c G < 0 (%d) : Q_RI %d, Q_CQI %d\n",G,Q_RI,Q_CQI);
return(-1);
if ((int)G < 0)
{
LOG_E(PHY, "FATAL: ulsch_decoding.c G < 0 (%d) : Q_RI %d, Q_CQI %d\n", G, Q_RI, Q_CQI);
return (-1);
}
H = G + Q_CQI;
Hprime = H/Q_m;
Hprime = H / Q_m;
// Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI
start_meas(&eNB->ulsch_demultiplexing_stats);
Hpp = Hprime + Qprime_RI;
Cmux = ulsch_harq->Nsymb_pusch;
Rmux_prime = Hpp/Cmux;
Rmux_prime = Hpp / Cmux;
// Clear "tag" interleaving matrix to allow for CQI/DATA identification
memset(ytag,0,Cmux*Rmux_prime);
memset(ytag, 0, Cmux * Rmux_prime);
i=0;
memset(y,LTE_NULL,Q_m*Hpp);
i = 0;
memset(y, LTE_NULL, Q_m * Hpp);
// read in buffer and unscramble llrs for everything but placeholder bits
// llrs stored per symbol correspond to columns of interleaving matrix
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++) {
cseq[i2++] = (int16_t)((((s>>j)&1)<<1)-1);
......@@ -1314,26 +1347,25 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
*/
#if defined(__x86_64__) || defined(__i386__)
#ifndef __AVX2__
((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[(s&65535)<<1];
((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[1+((s&65535)<<1)];
s>>=16;
((__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)[(s & 65535) << 1];
((__m128i *)cseq)[i2++] = ((__m128i *)unscrambling_lut)[1 + ((s & 65535) << 1)];
s >>= 16;
((__m128i *)cseq)[i2++] = ((__m128i *)unscrambling_lut)[(s & 65535) << 1];
((__m128i *)cseq)[i2++] = ((__m128i *)unscrambling_lut)[1 + ((s & 65535) << 1)];
#else
((__m256i*)cseq)[i2++] = ((__m256i*)unscrambling_lut)[s&65535];
((__m256i*)cseq)[i2++] = ((__m256i*)unscrambling_lut)[(s>>16)&65535];
((__m256i *)cseq)[i2++] = ((__m256i *)unscrambling_lut)[s & 65535];
((__m256i *)cseq)[i2++] = ((__m256i *)unscrambling_lut)[(s >> 16) & 65535];
#endif
#elif defined(__arm__)
((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[(s&65535)<<1];
((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[1+((s&65535)<<1)];
s>>=16;
((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)[(s & 65535) << 1];
((int16x8_t *)cseq)[i2++] = ((int16x8_t *)unscrambling_lut)[1 + ((s & 65535) << 1)];
s >>= 16;
((int16x8_t *)cseq)[i2++] = ((int16x8_t *)unscrambling_lut)[(s & 65535) << 1];
((int16x8_t *)cseq)[i2++] = ((int16x8_t *)unscrambling_lut)[1 + ((s & 65535) << 1)];
#endif
s = lte_gold_unscram(&x1, &x2, 0);
}
// printf("after unscrambling c[%d] = %p\n",0,ulsch_harq->c[0]);
if (frame_parms->Ncp == 0)
......@@ -1341,22 +1373,22 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
else
columnset = cs_ri_extended;
j=0;
j = 0;
for (i=0; i<Qprime_RI; i++) {
r = Rmux_prime - 1 - (i>>2);
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
off = ((Rmux_prime * Q_m * columnset[j]) + (r * Q_m));
cseq[off + 1] = cseq[off]; // PUSCH_y
j=(j+3)&3;
for (q = 2; q < Q_m; q++)
cseq[off + q] = -1; // PUSCH_x
j = (j + 3) & 3;
}
// printf("after RI c[%d] = %p\n",0,ulsch_harq->c[0]);
......@@ -1367,58 +1399,65 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
else
columnset = cs_ack_extended;
j=0;
j = 0;
for (i=0; i<Qprime_ACK; i++) {
r = Rmux_prime - 1 - (i>>2);
off =((Rmux_prime*Q_m*columnset[j])+(r*Q_m));
for (i = 0; i < Qprime_ACK; i++)
{
r = Rmux_prime - 1 - (i >> 2);
off = ((Rmux_prime * Q_m * columnset[j]) + (r * Q_m));
if (ulsch_harq->O_ACK == 1) {
if (ulsch->bundling==0)
cseq[off+1] = cseq[off]; // PUSCH_y
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
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
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
j=(j+3)&3;
j = (j + 3) & 3;
}
i = 0;
i=0;
switch (Q_m) {
switch (Q_m)
{
case 2:
for (j=0; j<Cmux; j++) {
i2=j<<1;
for (j = 0; j < Cmux; j++)
{
i2 = j << 1;
for (r=0; r<Rmux_prime; r++) {
for (r = 0; r < Rmux_prime; r++)
{
c = cseq[i];
// printf("ulsch %d: %d * ",i,c);
y[i2++] = c*ulsch_llr[i++];
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++];
y[i2] = c * ulsch_llr[i++];
// printf("%d\n",ulsch_llr[i-1]);
i2=(i2+(Cmux<<1)-1);
i2 = (i2 + (Cmux << 1) - 1);
}
}
break;
case 4:
for (j=0; j<Cmux; j++) {
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++];
......@@ -1431,43 +1470,42 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
i2=(i2+(Cmux<<2)-3);
*/
// 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]);i+=4;i2+=(Cmux<<2);
*(__m64 *)&y[i2] = _mm_sign_pi16(*(__m64 *)&ulsch_llr[i], *(__m64 *)&cseq[i]);
i += 4;
i2 += (Cmux << 2);
}
}
break;
case 6:
for (j=0; j<Cmux; j++) {
i2=j*6;
for (j = 0; j < Cmux; j++)
{
i2 = j * 6;
for (r=0; r<Rmux_prime; r++) {
for (r = 0; r < Rmux_prime; r++)
{
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
y[i2++] = c * ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
y[i2++] = c * ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
y[i2++] = c * ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
y[i2++] = c * ulsch_llr[i++];
c = cseq[i];
y[i2++] = c*ulsch_llr[i++];
y[i2++] = c * ulsch_llr[i++];
c = cseq[i];
y[i2] = c*ulsch_llr[i++];
i2=(i2+(Cmux*6)-5);
y[i2] = c * ulsch_llr[i++];
i2 = (i2 + (Cmux * 6) - 5);
}
}
break;
}
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);
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);
// HARQ-ACK Bits (LLRs are nulled in overwritten bits after copying HARQ-ACK LLR)
......@@ -1476,10 +1514,12 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
else
columnset = cs_ack_extended;
j=0;
j = 0;
if (ulsch_harq->O_ACK == 1) {
switch (Q_m) {
if (ulsch_harq->O_ACK == 1)
{
switch (Q_m)
{
case 2:
len_ACK = 2;
break;
......@@ -1494,8 +1534,10 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
}
}
if (ulsch_harq->O_ACK == 2) {
switch (Q_m) {
if (ulsch_harq->O_ACK == 2)
{
switch (Q_m)
{
case 2:
len_ACK = 6;
break;
......@@ -1510,53 +1552,58 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
}
}
if (ulsch_harq->O_ACK > 2) {
LOG_E(PHY,"ulsch_decoding: FATAL, ACK cannot be more than 2 bits yet\n");
return(-1);
if (ulsch_harq->O_ACK > 2)
{
LOG_E(PHY, "ulsch_decoding: FATAL, ACK cannot be more than 2 bits yet\n");
return (-1);
}
for (i=0; i<len_ACK; i++)
for (i = 0; i < len_ACK; i++)
ulsch_harq->q_ACK[i] = 0;
for (i = 0; i < Qprime_ACK; i++)
{
r = Rmux_prime - 1 - (i >> 2);
for (i=0; i<Qprime_ACK; i++) {
r = Rmux_prime -1 - (i>>2);
for (q=0; q<Q_m; q++) {
if (y[q+(Q_m*((r*Cmux) + columnset[j]))]!=0)
ulsch_harq->q_ACK[(q+(Q_m*i))%len_ACK] += y[q+(Q_m*((r*Cmux) + columnset[j]))];
y[q+(Q_m*((r*Cmux) + columnset[j]))]=0; // NULL LLRs in ACK positions
for (q = 0; q < Q_m; q++)
{
if (y[q + (Q_m * ((r * Cmux) + columnset[j]))] != 0)
ulsch_harq->q_ACK[(q + (Q_m * i)) % len_ACK] += y[q + (Q_m * ((r * Cmux) + columnset[j]))];
y[q + (Q_m * ((r * Cmux) + columnset[j]))] = 0; // NULL LLRs in ACK positions
}
j=(j+3)&3;
j = (j + 3) & 3;
}
// printf("after ACKNAK c[%d] = %p\n",0,ulsch_harq->c[0]);
// RI BITS
if (ulsch_harq->O_RI == 1) {
switch (Q_m) {
if (ulsch_harq->O_RI == 1)
{
switch (Q_m)
{
case 2:
len_RI=2;
len_RI = 2;
break;
case 4:
len_RI=4;
len_RI = 4;
break;
case 6:
len_RI=6;
len_RI = 6;
break;
}
}
if (ulsch_harq->O_RI > 1) {
LOG_E(PHY,"ulsch_decoding: FATAL, RI cannot be more than 1 bit yet\n");
return(-1);
if (ulsch_harq->O_RI > 1)
{
LOG_E(PHY, "ulsch_decoding: FATAL, RI cannot be more than 1 bit yet\n");
return (-1);
}
for (i=0; i<len_RI; i++)
for (i = 0; i < len_RI; i++)
ulsch_harq->q_RI[i] = 0;
if (frame_parms->Ncp == 0)
......@@ -1564,86 +1611,94 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
else
columnset = cs_ri_extended;
j=0;
j = 0;
for (i=0; i<Qprime_RI; i++) {
r = Rmux_prime -1 - (i>>2);
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]))];
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;
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;
j = 0;
j2 = 0;
// r=0;
if (Q_RI>0) {
for (i=0; i<(Q_CQI/Q_m); i++) {
if (Q_RI > 0)
{
for (i = 0; i < (Q_CQI / Q_m); i++)
{
while (ytag[j]==LTE_NULL) {
while (ytag[j] == LTE_NULL)
{
j++;
j2+=Q_m;
j2 += Q_m;
}
for (q=0; q<Q_m; q++) {
for (q = 0; q < Q_m; q++)
{
// ys = y[q+(Q_m*((r*Cmux)+j))];
ys = y[q+j2];
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;
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;
ulsch_harq->q[q + (Q_m * i)] = ys;
}
j2+=Q_m;
j2 += Q_m;
}
switch (Q_m) {
switch (Q_m)
{
case 2:
for (iprime=0; iprime<G;) {
while (ytag[j]==LTE_NULL) {
for (iprime = 0; iprime < G;)
{
while (ytag[j] == LTE_NULL)
{
j++;
j2+=2;
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) {
for (iprime = 0; iprime < G;)
{
while (ytag[j] == LTE_NULL)
{
j++;
j2+=4;
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) {
for (iprime = 0; iprime < G;)
{
while (ytag[j] == LTE_NULL)
{
j++;
j2+=6;
j2 += 6;
}
ulsch_harq->e[iprime++] = y[j2++];
......@@ -1652,30 +1707,30 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
ulsch_harq->e[iprime++] = y[j2++];
}
break;
}
} // Q_RI>0
else {
else
{
for (i=0; i<(Q_CQI/Q_m); i++) {
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;
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;
ulsch_harq->q[q + (Q_m * i)] = ys;
}
j2+=Q_m;
j2 += Q_m;
}
/* To be improved according to alignment of j2
#if defined(__x86_64__)||defined(__i386__)
......@@ -1691,10 +1746,11 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
*((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) {
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];
......@@ -1706,7 +1762,6 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
}
}
stop_meas(&eNB->ulsch_demultiplexing_stats);
// printf("after ACKNAK2 c[%d] = %p (iprime %d, G %d)\n",0,ulsch_harq->c[0],iprime,G);
......@@ -1714,11 +1769,12 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
// Do CQI/RI/HARQ-ACK Decoding first and pass to MAC
// HARQ-ACK
wACK_idx = (ulsch->bundling==0) ? 4 : ((Nbundled-1)&3);
wACK_idx = (ulsch->bundling == 0) ? 4 : ((Nbundled - 1) & 3);
if (ulsch_harq->O_ACK == 1) {
if (ulsch_harq->O_ACK == 1)
{
ulsch_harq->q_ACK[0] *= wACK_RX[wACK_idx][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];
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];
if (ulsch_harq->q_ACK[0] < 0)
ulsch_harq->o_ACK[0] = 0;
......@@ -1726,49 +1782,53 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
ulsch_harq->o_ACK[0] = 1;
}
if (ulsch_harq->O_ACK == 2) {
switch (Q_m) {
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];
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];
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];
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];
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;
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];
metric_new = ulsch_harq->q_ACK[0] - ulsch_harq->q_ACK[1] + ulsch_harq->q_ACK[2];
if (metric_new > metric) {
if (metric_new > metric)
{
ulsch_harq->o_ACK[0] = 1;
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];
metric_new = -ulsch_harq->q_ACK[0] - ulsch_harq->q_ACK[1] - ulsch_harq->q_ACK[2];
if (metric_new > metric) {
if (metric_new > metric)
{
ulsch_harq->o_ACK[0] = 0;
ulsch_harq->o_ACK[1] = 0;
metric = metric_new;
......@@ -1778,64 +1838,67 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
// RI
// rank 1
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;
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;
}
// CQI
// printf("before cqi c[%d] = %p\n",0,ulsch_harq->c[0]);
ulsch_harq->cqi_crc_status = 0;
if (Q_CQI>0) {
memset((void *)&dummy_w_cc[0],0,3*(ulsch_harq->Or1+8+32));
if (Q_CQI > 0)
{
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]);
lte_rate_matching_cc_rx(O_RCC,
Q_CQI,
ulsch_harq->o_w,
dummy_w_cc,
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_w[0]);
memset(o_flip,0,1+((8+ulsch_harq->Or1)/8));
phy_viterbi_lte_sse2(ulsch_harq->o_d+96,o_flip,8+ulsch_harq->Or1);
memset(o_flip, 0, 1 + ((8 + ulsch_harq->Or1) / 8));
phy_viterbi_lte_sse2(ulsch_harq->o_d + 96, o_flip, 8 + ulsch_harq->Or1);
if (extract_cqi_crc(o_flip,ulsch_harq->Or1) == (crc8(o_flip,ulsch_harq->Or1)>>24))
if (extract_cqi_crc(o_flip, ulsch_harq->Or1) == (crc8(o_flip, ulsch_harq->Or1) >> 24))
ulsch_harq->cqi_crc_status = 1;
if (ulsch->harq_processes[harq_pid]->Or1<=32) {
ulsch_harq->o[3] = o_flip[0] ;
ulsch_harq->o[2] = o_flip[1] ;
ulsch_harq->o[1] = o_flip[2] ;
ulsch_harq->o[0] = o_flip[3] ;
} else {
ulsch_harq->o[7] = o_flip[0] ;
ulsch_harq->o[6] = o_flip[1] ;
ulsch_harq->o[5] = o_flip[2] ;
ulsch_harq->o[4] = o_flip[3] ;
ulsch_harq->o[3] = o_flip[4] ;
ulsch_harq->o[2] = o_flip[5] ;
ulsch_harq->o[1] = o_flip[6] ;
ulsch_harq->o[0] = o_flip[7] ;
if (ulsch->harq_processes[harq_pid]->Or1 <= 32)
{
ulsch_harq->o[3] = o_flip[0];
ulsch_harq->o[2] = o_flip[1];
ulsch_harq->o[1] = o_flip[2];
ulsch_harq->o[0] = o_flip[3];
}
else
{
ulsch_harq->o[7] = o_flip[0];
ulsch_harq->o[6] = o_flip[1];
ulsch_harq->o[5] = o_flip[2];
ulsch_harq->o[4] = o_flip[3];
ulsch_harq->o[3] = o_flip[4];
ulsch_harq->o[2] = o_flip[5];
ulsch_harq->o[1] = o_flip[6];
ulsch_harq->o[0] = o_flip[7];
}
#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++)
printf("ulsch_decoding: O[%d] %d\n",i,ulsch_harq->o[i]);
for (i = 0; i < 1 + ((8 + ulsch_harq->Or1) / 8); i++)
printf("ulsch_decoding: O[%d] %d\n", i, ulsch_harq->o[i]);
if (ulsch_harq->cqi_crc_status == 1)
printf("RX CQI CRC OK (%x)\n",extract_cqi_crc(o_flip,ulsch_harq->Or1));
printf("RX CQI CRC OK (%x)\n", extract_cqi_crc(o_flip, ulsch_harq->Or1));
else
printf("RX CQI CRC NOT OK (%x)\n",extract_cqi_crc(o_flip,ulsch_harq->Or1));
printf("RX CQI CRC NOT OK (%x)\n", extract_cqi_crc(o_flip, ulsch_harq->Or1));
#endif
}
......@@ -1846,14 +1909,42 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
// ISIP Turbo Decoder Parallel Start
start_meas(&eNB->isip_turbo_stats);
int isip_thread_cnt;
int16_t isip_turbo_complete_status = 0;
int turbo_complete = (1 << ISIP_TURBO_THREAD_NUM) - 1;
int local_turbo_thread_status = ulsch_harq->C;
unsigned int temp;
unsigned int status_cnt = 0;
start_meas(&eNB->isip_turbo_stats);
do
{
temp = eNB->isip_turbo_thread_status;
while (temp)
{
status_cnt++;
temp &= (temp - 1);
}
// zero_cnt = 32 - status_cnt;
if (status_cnt + local_turbo_thread_status <= ISIP_TURBO_THREAD_NUM)
{
if (eNB->isip_turbo_thread_status != 0xFFFFFFFF)
{
// temp = temp >> status_cnt;
// temp = (((2 ^ local_turbo_thread_status) - 1) | temp) << status_cnt;
// eNB->isip_turbo_thread_status |= temp;
eNB->isip_turbo_thread_status = (eNB->isip_turbo_thread_status << local_turbo_thread_status) | ((1 << local_turbo_thread_status) - 1);
break;
}
}
} while (1);
for (isip_thread_cnt = 0; isip_thread_cnt < ISIP_TURBO_THREAD_NUM; isip_thread_cnt++)
// for (isip_thread_cnt = 0; isip_thread_cnt < ISIP_TURBO_THREAD_NUM; isip_thread_cnt++)
for (isip_thread_cnt = 0; isip_thread_cnt < ulsch_harq->C; isip_thread_cnt++)
{
// Do ULSCH Decoding for data portion
// ISIP Thread Start
eNB->isip_turbo_thread[isip_thread_cnt].thread_id = isip_thread_cnt;
eNB->isip_turbo_thread[isip_thread_cnt].UE_id = UE_id; // ISIP Thread
eNB->isip_turbo_thread[isip_thread_cnt].harq_pid = harq_pid; // ISIP Thread
......@@ -1864,152 +1955,159 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
pthread_cond_signal(&eNB->isip_turbo_thread[isip_thread_cnt].cond_rx); // ISIP Thread
}
// int done_cnt;
// int turbo_complete = (1 << ISIP_TURBO_THREAD_NUM) - 1;
int turbo_complete = (1 << ulsch_harq->C) - 1;
start_meas(&eNB->isip_wait_loop);
do
{
#if (ISIP_TURBO_THREAD_NUM == 1)
if (ulsch_harq->C == 1)
isip_turbo_complete_status = eNB->isip_turbo_thread[0].flag_done;
#elif (ISIP_TURBO_THREAD_NUM == 2)
else if (ulsch_harq->C == 2)
isip_turbo_complete_status = eNB->isip_turbo_thread[0].flag_done | eNB->isip_turbo_thread[1].flag_done;
#elif (ISIP_TURBO_THREAD_NUM == 3)
else if (ulsch_harq->C == 3)
isip_turbo_complete_status = eNB->isip_turbo_thread[0].flag_done | eNB->isip_turbo_thread[1].flag_done | eNB->isip_turbo_thread[2].flag_done;
#elif (ISIP_TURBO_THREAD_NUM == 4)
else if (ulsch_harq->C == 4)
isip_turbo_complete_status = eNB->isip_turbo_thread[0].flag_done | eNB->isip_turbo_thread[1].flag_done | eNB->isip_turbo_thread[2].flag_done | eNB->isip_turbo_thread[3].flag_done;
#elif (ISIP_TURBO_THREAD_NUM == 5)
else if (ulsch_harq->C == 5)
isip_turbo_complete_status = eNB->isip_turbo_thread[0].flag_done | eNB->isip_turbo_thread[1].flag_done | eNB->isip_turbo_thread[2].flag_done | eNB->isip_turbo_thread[3].flag_done | eNB->isip_turbo_thread[4].flag_done;
#elif (ISIP_TURBO_THREAD_NUM == 6)
else if (ulsch_harq->C == 6)
isip_turbo_complete_status = eNB->isip_turbo_thread[0].flag_done | eNB->isip_turbo_thread[1].flag_done | eNB->isip_turbo_thread[2].flag_done | eNB->isip_turbo_thread[3].flag_done | eNB->isip_turbo_thread[4].flag_done | eNB->isip_turbo_thread[5].flag_done;
#elif (ISIP_TURBO_THREAD_NUM == 7)
else if (ulsch_harq->C == 7)
isip_turbo_complete_status = eNB->isip_turbo_thread[0].flag_done | eNB->isip_turbo_thread[1].flag_done | eNB->isip_turbo_thread[2].flag_done | eNB->isip_turbo_thread[3].flag_done | eNB->isip_turbo_thread[4].flag_done | eNB->isip_turbo_thread[5].flag_done | eNB->isip_turbo_thread[6].flag_done;
#elif (ISIP_TURBO_THREAD_NUM == 8)
else if (ulsch_harq->C == 8)
isip_turbo_complete_status = eNB->isip_turbo_thread[0].flag_done | eNB->isip_turbo_thread[1].flag_done | eNB->isip_turbo_thread[2].flag_done | eNB->isip_turbo_thread[3].flag_done | eNB->isip_turbo_thread[4].flag_done | eNB->isip_turbo_thread[5].flag_done | eNB->isip_turbo_thread[6].flag_done | eNB->isip_turbo_thread[7].flag_done;
#elif (ISIP_TURBO_THREAD_NUM == 9)
else if (ulsch_harq->C == 9)
isip_turbo_complete_status = eNB->isip_turbo_thread[0].flag_done | eNB->isip_turbo_thread[1].flag_done | eNB->isip_turbo_thread[2].flag_done | eNB->isip_turbo_thread[3].flag_done | eNB->isip_turbo_thread[4].flag_done | eNB->isip_turbo_thread[5].flag_done | eNB->isip_turbo_thread[6].flag_done | eNB->isip_turbo_thread[7].flag_done | eNB->isip_turbo_thread[8].flag_done;
#elif (ISIP_TURBO_THREAD_NUM == 10)
else if (ulsch_harq->C == 10)
isip_turbo_complete_status = eNB->isip_turbo_thread[0].flag_done | eNB->isip_turbo_thread[1].flag_done | eNB->isip_turbo_thread[2].flag_done | eNB->isip_turbo_thread[3].flag_done | eNB->isip_turbo_thread[4].flag_done | eNB->isip_turbo_thread[5].flag_done | eNB->isip_turbo_thread[6].flag_done | eNB->isip_turbo_thread[7].flag_done | eNB->isip_turbo_thread[8].flag_done | eNB->isip_turbo_thread[9].flag_done;
#elif (ISIP_TURBO_THREAD_NUM == 11)
else if (ulsch_harq->C == 11)
isip_turbo_complete_status = eNB->isip_turbo_thread[0].flag_done | eNB->isip_turbo_thread[1].flag_done | eNB->isip_turbo_thread[2].flag_done | eNB->isip_turbo_thread[3].flag_done | eNB->isip_turbo_thread[4].flag_done | eNB->isip_turbo_thread[5].flag_done | eNB->isip_turbo_thread[6].flag_done | eNB->isip_turbo_thread[7].flag_done | eNB->isip_turbo_thread[8].flag_done | eNB->isip_turbo_thread[9].flag_done | eNB->isip_turbo_thread[10].flag_done;
#elif (ISIP_TURBO_THREAD_NUM == 12)
else if (ulsch_harq->C == 12)
isip_turbo_complete_status = eNB->isip_turbo_thread[0].flag_done | eNB->isip_turbo_thread[1].flag_done | eNB->isip_turbo_thread[2].flag_done | eNB->isip_turbo_thread[3].flag_done | eNB->isip_turbo_thread[4].flag_done | eNB->isip_turbo_thread[5].flag_done | eNB->isip_turbo_thread[6].flag_done | eNB->isip_turbo_thread[7].flag_done | eNB->isip_turbo_thread[8].flag_done | eNB->isip_turbo_thread[9].flag_done | eNB->isip_turbo_thread[10].flag_done | eNB->isip_turbo_thread[11].flag_done;
#elif (ISIP_TURBO_THREAD_NUM == 13)
else if (ulsch_harq->C == 13)
isip_turbo_complete_status = eNB->isip_turbo_thread[0].flag_done | eNB->isip_turbo_thread[1].flag_done | eNB->isip_turbo_thread[2].flag_done | eNB->isip_turbo_thread[3].flag_done | eNB->isip_turbo_thread[4].flag_done | eNB->isip_turbo_thread[5].flag_done | eNB->isip_turbo_thread[6].flag_done | eNB->isip_turbo_thread[7].flag_done | eNB->isip_turbo_thread[8].flag_done | eNB->isip_turbo_thread[9].flag_done | eNB->isip_turbo_thread[10].flag_done | eNB->isip_turbo_thread[11].flag_done | eNB->isip_turbo_thread[12].flag_done;
#endif
} while (isip_turbo_complete_status != turbo_complete);
stop_meas(&eNB->isip_wait_loop);
#if (ISIP_TURBO_THREAD_NUM == 1)
if (ulsch_harq->C == 1)
ret = eNB->isip_turbo_thread[0].ret;
#elif (ISIP_TURBO_THREAD_NUM == 2)
else if (ulsch_harq->C == 2)
ret = eNB->isip_turbo_thread[0].ret | eNB->isip_turbo_thread[1].ret;
#elif (ISIP_TURBO_THREAD_NUM == 3)
else if (ulsch_harq->C == 3)
ret = eNB->isip_turbo_thread[0].ret | eNB->isip_turbo_thread[1].ret | eNB->isip_turbo_thread[2].ret;
#elif (ISIP_TURBO_THREAD_NUM == 4)
else if (ulsch_harq->C == 4)
ret = eNB->isip_turbo_thread[0].ret | eNB->isip_turbo_thread[1].ret | eNB->isip_turbo_thread[2].ret | eNB->isip_turbo_thread[3].ret;
#elif (ISIP_TURBO_THREAD_NUM == 5)
else if (ulsch_harq->C == 5)
ret = eNB->isip_turbo_thread[0].ret | eNB->isip_turbo_thread[1].ret | eNB->isip_turbo_thread[2].ret | eNB->isip_turbo_thread[3].ret | eNB->isip_turbo_thread[4].ret;
#elif (ISIP_TURBO_THREAD_NUM == 6)
else if (ulsch_harq->C == 6)
ret = eNB->isip_turbo_thread[0].ret | eNB->isip_turbo_thread[1].ret | eNB->isip_turbo_thread[2].ret | eNB->isip_turbo_thread[3].ret | eNB->isip_turbo_thread[4].ret | eNB->isip_turbo_thread[5].ret;
#elif (ISIP_TURBO_THREAD_NUM == 7)
else if (ulsch_harq->C == 7)
ret = eNB->isip_turbo_thread[0].ret | eNB->isip_turbo_thread[1].ret | eNB->isip_turbo_thread[2].ret | eNB->isip_turbo_thread[3].ret | eNB->isip_turbo_thread[4].ret | eNB->isip_turbo_thread[5].ret | eNB->isip_turbo_thread[6].ret;
#elif (ISIP_TURBO_THREAD_NUM == 8)
else if (ulsch_harq->C == 8)
ret = eNB->isip_turbo_thread[0].ret | eNB->isip_turbo_thread[1].ret | eNB->isip_turbo_thread[2].ret | eNB->isip_turbo_thread[3].ret | eNB->isip_turbo_thread[4].ret | eNB->isip_turbo_thread[5].ret | eNB->isip_turbo_thread[6].ret | eNB->isip_turbo_thread[7].ret;
#elif (ISIP_TURBO_THREAD_NUM == 9)
else if (ulsch_harq->C == 9)
ret = eNB->isip_turbo_thread[0].ret | eNB->isip_turbo_thread[1].ret | eNB->isip_turbo_thread[2].ret | eNB->isip_turbo_thread[3].ret | eNB->isip_turbo_thread[4].ret | eNB->isip_turbo_thread[5].ret | eNB->isip_turbo_thread[6].ret | eNB->isip_turbo_thread[7].ret | eNB->isip_turbo_thread[8].ret;
#elif (ISIP_TURBO_THREAD_NUM == 10)
else if (ulsch_harq->C == 10)
ret = eNB->isip_turbo_thread[0].ret | eNB->isip_turbo_thread[1].ret | eNB->isip_turbo_thread[2].ret | eNB->isip_turbo_thread[3].ret | eNB->isip_turbo_thread[4].ret | eNB->isip_turbo_thread[5].ret | eNB->isip_turbo_thread[6].ret | eNB->isip_turbo_thread[7].ret | eNB->isip_turbo_thread[8].ret | eNB->isip_turbo_thread[9].ret;
#elif (ISIP_TURBO_THREAD_NUM == 11)
else if (ulsch_harq->C == 11)
ret = eNB->isip_turbo_thread[0].ret | eNB->isip_turbo_thread[1].ret | eNB->isip_turbo_thread[2].ret | eNB->isip_turbo_thread[3].ret | eNB->isip_turbo_thread[4].ret | eNB->isip_turbo_thread[5].ret | eNB->isip_turbo_thread[6].ret | eNB->isip_turbo_thread[7].ret | eNB->isip_turbo_thread[8].ret | eNB->isip_turbo_thread[9].ret | eNB->isip_turbo_thread[10].ret;
#elif (ISIP_TURBO_THREAD_NUM == 12)
else if (ulsch_harq->C == 12)
ret = eNB->isip_turbo_thread[0].ret | eNB->isip_turbo_thread[1].ret | eNB->isip_turbo_thread[2].ret | eNB->isip_turbo_thread[3].ret | eNB->isip_turbo_thread[4].ret | eNB->isip_turbo_thread[5].ret | eNB->isip_turbo_thread[6].ret | eNB->isip_turbo_thread[7].ret | eNB->isip_turbo_thread[8].ret | eNB->isip_turbo_thread[9].ret | eNB->isip_turbo_thread[10].ret | eNB->isip_turbo_thread[11].ret;
#elif (ISIP_TURBO_THREAD_NUM == 13)
else if (ulsch_harq->C == 13)
ret = eNB->isip_turbo_thread[0].ret | eNB->isip_turbo_thread[1].ret | eNB->isip_turbo_thread[2].ret | eNB->isip_turbo_thread[3].ret | eNB->isip_turbo_thread[4].ret | eNB->isip_turbo_thread[5].ret | eNB->isip_turbo_thread[6].ret | eNB->isip_turbo_thread[7].ret | eNB->isip_turbo_thread[8].ret | eNB->isip_turbo_thread[9].ret | eNB->isip_turbo_thread[10].ret | eNB->isip_turbo_thread[11].ret | eNB->isip_turbo_thread[12].ret;
#endif
// remove used turbo thread
eNB->isip_turbo_thread_status = eNB->isip_turbo_thread_status >> local_turbo_thread_status;
// Turbo Decoding Paralleling End
stop_meas(&eNB->isip_turbo_stats);
// Turbo Decoding Paralleling End
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_UL
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;
int rb_count = 0;
int offset;
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 *= 10;
sinr_eff = floor(sinr_eff);
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++) {
if(index == 0) {
if (sinr_eff < sinr_bler_map_up[mcs][0][index]) {
for (index = 0; index < 16; index++)
{
if (index == 0)
{
if (sinr_eff < sinr_bler_map_up[mcs][0][index])
{
bler = 1;
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];
}
}
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
if (uniformrandom() < bler) {
LOG_I(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
return(0);
} else {
LOG_I(OCM,"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
return(1);
if (uniformrandom() < bler)
{
LOG_I(OCM, "abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n", mcs, sinr_eff, bler);
return (0);
}
else
{
LOG_I(OCM, "abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n", mcs, sinr_eff, bler);
return (1);
}
#endif
}
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;
double sinr_eff = 0;
double sinr_db1 = 0;
double sinr_db2 = 0;
double SI=0;
double RBIR=0;
double SI = 0;
double RBIR = 0;
int rb_count = 0;
int offset, M=0;
int offset, M = 0;
double bler = 0;
int start,middle,end;
TM = TM-1;
int start, middle, end;
TM = TM - 1;
for (offset = frb; offset <= (frb + nrb -1); offset++) {
for (offset = frb; offset <= (frb + nrb - 1); offset++)
{
rb_count++;
//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_db2 = sinr_dB[offset*2+1];
sinr_db1 = sinr_dB[offset * 2];
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
sinr_db1 *= 10;
......@@ -2018,142 +2116,171 @@ int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb
sinr_db1 = floor(sinr_db1);
sinr_db2 = floor(sinr_db2);
if ((int)sinr_db1%2) {
if ((int)sinr_db1 % 2)
{
sinr_db1 += 1;
}
if ((int)sinr_db2%2) {
if ((int)sinr_db2 % 2)
{
sinr_db2 += 1;
}
sinr_db1 /= 10;
sinr_db2 /= 10;
if(mcs<10) {
if (mcs < 10)
{
//for sinr_db1
for (index = 0; index < 162; index++) {
if (sinr_db1 < MI_map_4qam[0][0]) {
SI += (MI_map_4qam[1][0]/beta1_dlsch_MI[TM][mcs]);
M +=2;
for (index = 0; index < 162; index++)
{
if (sinr_db1 < MI_map_4qam[0][0])
{
SI += (MI_map_4qam[1][0] / beta1_dlsch_MI[TM][mcs]);
M += 2;
break;
}
if (sinr_db1 > MI_map_4qam[0][161]) {
SI += (MI_map_4qam[1][161]/beta1_dlsch_MI[TM][mcs]);
M +=2;
if (sinr_db1 > MI_map_4qam[0][161])
{
SI += (MI_map_4qam[1][161] / beta1_dlsch_MI[TM][mcs]);
M += 2;
break;
}
if (sinr_db1 == MI_map_4qam[0][index]) {
SI += (MI_map_4qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=2;
if (sinr_db1 == MI_map_4qam[0][index])
{
SI += (MI_map_4qam[1][index] / beta1_dlsch_MI[TM][mcs]);
M += 2;
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;
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]) {
SI += (MI_map_4qam[1][161]/beta1_dlsch_MI[TM][mcs]);
M +=2;
if (sinr_db2 > MI_map_4qam[0][161])
{
SI += (MI_map_4qam[1][161] / beta1_dlsch_MI[TM][mcs]);
M += 2;
break;
}
if (sinr_db2 == MI_map_4qam[0][index]) {
SI += (MI_map_4qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=2;
if (sinr_db2 == MI_map_4qam[0][index])
{
SI += (MI_map_4qam[1][index] / beta1_dlsch_MI[TM][mcs]);
M += 2;
break;
}
}
} else if(mcs>9 && mcs<17) {
}
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;
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]) {
SI += (MI_map_16qam[1][196]/beta1_dlsch_MI[TM][mcs]);
M +=4;
if (sinr_db1 > MI_map_16qam[0][196])
{
SI += (MI_map_16qam[1][196] / beta1_dlsch_MI[TM][mcs]);
M += 4;
break;
}
if (sinr_db1 == MI_map_16qam[0][index]) {
SI += (MI_map_16qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=4;
if (sinr_db1 == MI_map_16qam[0][index])
{
SI += (MI_map_16qam[1][index] / 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;
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]) {
SI += (MI_map_16qam[1][196]/beta1_dlsch_MI[TM][mcs]);
M +=4;
if (sinr_db2 > MI_map_16qam[0][196])
{
SI += (MI_map_16qam[1][196] / beta1_dlsch_MI[TM][mcs]);
M += 4;
break;
}
if (sinr_db2 == MI_map_16qam[0][index]) {
SI += (MI_map_16qam[1][index]/beta1_dlsch_MI[TM][mcs]);
M +=4;
if (sinr_db2 == MI_map_16qam[0][index])
{
SI += (MI_map_16qam[1][index] / beta1_dlsch_MI[TM][mcs]);
M += 4;
break;
}
}
} else if(mcs>16 && mcs<22) {
}
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;
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]) {
SI += (MI_map_64qam[1][226]/beta1_dlsch_MI[TM][mcs]);
M +=6;
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;
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;
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;
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;
if (sinr_db2 == MI_map_64qam[0][index])
{
SI += (MI_map_64qam[1][index] / beta1_dlsch_MI[TM][mcs]);
M += 6;
break;
}
}
......@@ -2162,34 +2289,44 @@ int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb
// }
RBIR = SI/M;
RBIR = SI / M;
//Now RBIR->SINR_effective Mapping
//binary search method is performed here
if(mcs<10) {
if (mcs < 10)
{
start = 0;
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];
} else {
}
else
{
if (RBIR >= MI_map_4qam[2][end])
sinr_eff = MI_map_4qam[0][end];
else {
else
{
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if (RBIR < MI_map_4qam[2][middle]) {
if (RBIR < MI_map_4qam[2][middle])
{
end = middle;
middle = end/2;
} else {
middle = end / 2;
}
else
{
start = middle;
middle = (end-middle)/2;
middle = (end - middle) / 2;
}
}
for (; end>start; end--) {
if ((RBIR < MI_map_4qam[2][end]) && (RBIR > MI_map_4qam[2][end-2])) {
sinr_eff = MI_map_4qam[0][end-1];
for (; end > start; end--)
{
if ((RBIR < MI_map_4qam[2][end]) && (RBIR > MI_map_4qam[2][end - 2]))
{
sinr_eff = MI_map_4qam[0][end - 1];
break;
}
}
......@@ -2198,63 +2335,82 @@ int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb
sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs];
}
else if (mcs>9 && mcs<17) {
else if (mcs > 9 && mcs < 17)
{
start = 0;
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];
} else {
}
else
{
if (RBIR >= MI_map_16qam[2][end])
sinr_eff = MI_map_16qam[0][end];
else {
else
{
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if (RBIR < MI_map_16qam[2][middle]) {
if (RBIR < MI_map_16qam[2][middle])
{
end = middle;
middle = end/2;
} else {
middle = end / 2;
}
else
{
start = middle;
middle = (end-middle)/2;
middle = (end - middle) / 2;
}
}
for (; end>start; end--) {
if ((RBIR < MI_map_16qam[2][end]) && (RBIR > MI_map_16qam[2][end-2])) {
sinr_eff = MI_map_16qam[0][end-1];
for (; end > start; end--)
{
if ((RBIR < MI_map_16qam[2][end]) && (RBIR > MI_map_16qam[2][end - 2]))
{
sinr_eff = MI_map_16qam[0][end - 1];
break;
}
}
}
sinr_eff = sinr_eff * beta2_dlsch_MI[TM][mcs];
} else if (mcs>16) {
}
else if (mcs > 16)
{
start = 0;
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];
} else {
}
else
{
if (RBIR >= MI_map_64qam[2][end])
sinr_eff = MI_map_64qam[0][end];
else {
else
{
//while((end-start > 1) && (RBIR >= MI_map_4qam[2]))
if (RBIR < MI_map_64qam[2][middle]) {
if (RBIR < MI_map_64qam[2][middle])
{
end = middle;
middle = end/2;
} else {
middle = end / 2;
}
else
{
start = middle;
middle = (end-middle)/2;
middle = (end - middle) / 2;
}
}
for (; end>start; end--) {
if ((RBIR < MI_map_64qam[2][end]) && (RBIR > MI_map_64qam[2][end-2])) {
sinr_eff = MI_map_64qam[0][end-1];
for (; end > start; end--)
{
if ((RBIR < MI_map_64qam[2][end]) && (RBIR > MI_map_64qam[2][end - 2]))
{
sinr_eff = MI_map_64qam[0][end - 1];
break;
}
}
......@@ -2263,7 +2419,7 @@ int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb
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 = floor(sinr_eff);
......@@ -2271,33 +2427,39 @@ int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb
// sinr_eff += 1;
// }
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++) {
if(index == 0) {
if (sinr_eff < sinr_bler_map_up[mcs][0][index]) {
for (index = 0; index < 16; index++)
{
if (index == 0)
{
if (sinr_eff < sinr_bler_map_up[mcs][0][index])
{
bler = 1;
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];
}
}
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
if (uniformrandom() < bler) {
printf("abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
return(0);
} else {
printf("abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler);
return(1);
if (uniformrandom() < bler)
{
printf("abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n", mcs, sinr_eff, bler);
return (0);
}
else
{
printf("abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)\n", mcs, sinr_eff, bler);
return (1);
}
#endif
}
#endif
......@@ -2313,31 +2475,36 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
uint8_t harq_pid;
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;
#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
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)
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",
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);
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) {
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
PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->harq_processes[harq_pid]->status = IDLE;
}
else
*crnti = 0x0;
// Do abstraction here to determine if packet it in error
......@@ -2345,7 +2512,6 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
flag = 1;
else flag = 0;*/
/*
//SINRdbPost = eNB->sinr_dB_eNB;
mcsPost = eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,
......@@ -2367,7 +2533,6 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
//
// write_output("postprocSINR.m","SINReNB",eNB->sinr_dB,301,1,7);
//Yazdir buraya her frame icin 300 eNb
// fprintf(SINRrx,"%e,%e,%e,%e;\n",SINRdbPost);
//fprintf(SINRrx,"%e\n",SINRdbPost);
......@@ -2375,29 +2540,33 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
// fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
// if (ulsch_abstraction(eNB->sinr_dB,1, eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch[UE_id]->harq_processes[harq_pid]->first_rb) == 1) {
if (1) {
LOG_D(PHY,"ulsch_decoding_emul abstraction successful\n");
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);
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))) {
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);
}
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
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],
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->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,
PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->O);
......@@ -2407,20 +2576,21 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
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;
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, 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);
eNB->ulsch[UE_index]->harq_processes[harq_pid]->cqi_crc_status = 1;
return(1);
} else {
LOG_W(PHY,"[eNB %d] ulsch_decoding_emul abstraction failed for UE %d\n",eNB->Mod_id,UE_index);
return (1);
}
else
{
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;
// retransmission
return(1+eNB->ulsch[UE_index]->max_turbo_iterations);
return (1 + eNB->ulsch[UE_index]->max_turbo_iterations);
}
}
#endif
......@@ -725,6 +725,7 @@ typedef struct PHY_VARS_eNB_s {
//isip turbo thread
isip_turbo isip_turbo_thread[ISIP_TURBO_THREAD_NUM];
unsigned int isip_turbo_thread_status;
} PHY_VARS_eNB;
......
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