Commit 75a2c3cf authored by Raymond Knopp's avatar Raymond Knopp

Merge branch 'enhancement-10-harmony' of...

Merge branch 'enhancement-10-harmony' of https://gitlab.eurecom.fr/oai/openairinterface5g into enhancement-10-harmony

Conflicts:
	openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
parents 862e480e 4b022799
......@@ -132,18 +132,18 @@ void log_map8(llr_t* systematic,
msg("log_map, frame_length %d\n",frame_length);
#endif
start_meas(gamma_stats) ;
if (gamma_stats) start_meas(gamma_stats) ;
compute_gamma8(m11,m10,systematic,y_parity,frame_length,term_flag) ;
stop_meas(gamma_stats);
start_meas(alpha_stats) ;
if (gamma_stats) stop_meas(gamma_stats);
if (alpha_stats) start_meas(alpha_stats) ;
compute_alpha8(alpha,beta,m11,m10,frame_length,F) ;
stop_meas(alpha_stats);
start_meas(beta_stats) ;
if (alpha_stats) stop_meas(alpha_stats);
if (beta_stats) start_meas(beta_stats) ;
compute_beta8(alpha,beta,m11,m10,frame_length,F,offset8_flag) ;
stop_meas(beta_stats);
start_meas(ext_stats) ;
if (beta_stats) stop_meas(beta_stats);
if (ext_stats) start_meas(ext_stats) ;
compute_ext8(alpha,beta,m11,m10,ext,systematic,frame_length) ;
stop_meas(ext_stats);
if (ext_stats) stop_meas(ext_stats);
}
......@@ -963,7 +963,7 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
}
start_meas(init_stats);
if (init_stats) start_meas(init_stats);
if ((n&15)>0) {
......@@ -1326,7 +1326,7 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
msg("\n");
#endif //DEBUG_LOGMAP
stop_meas(init_stats);
if (init_stats) stop_meas(init_stats);
// do log_map from first parity bit
......@@ -1338,7 +1338,7 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
printf("\n*******************ITERATION %d (n %d, n2 %d), ext %p\n\n",iteration_cnt,n,n2,ext);
#endif //DEBUG_LOGMAP
start_meas(intl1_stats);
if (intl1_stats) start_meas(intl1_stats);
pi4_p=pi4tab8[iind];
for (i=0; i<(n2>>4); i++) { // steady-state portion
......@@ -1379,7 +1379,7 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
#endif
}
stop_meas(intl1_stats);
if (intl1_stats) stop_meas(intl1_stats);
// do log_map from second parity bit
......@@ -1484,7 +1484,7 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
// Check if we decoded the block
if (iteration_cnt>1) {
start_meas(intl2_stats);
if (intl2_stats) start_meas(intl2_stats);
if ((n2&0x7f) == 0) { // n2 is a multiple of 128 bits
......@@ -1623,7 +1623,7 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
break;
}
stop_meas(intl2_stats);
if (intl2_stats) stop_meas(intl2_stats);
if ((crc == oldcrc) && (crc!=0)) {
return(iteration_cnt);
......
......@@ -864,7 +864,8 @@ void phy_init_lte_top(LTE_DL_FRAME_PARMS *frame_parms)
generate_16qam_table();
generate_RIV_tables();
init_unscrambling_lut();
init_scrambling_lut();
//set_taus_seed(1328);
}
......@@ -1107,6 +1108,7 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
init_prach_tables(839);
return 0;
}
......
......@@ -143,7 +143,7 @@ typedef struct {
/// downlink power offset field
uint8_t dl_power_off;
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
uint8_t e[MAX_NUM_CHANNEL_BITS];
uint8_t e[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
/// Turbo-code outputs (36-212 V8.6 2009-03, p.12
uint8_t *d[MAX_NUM_DLSCH_SEGMENTS];//[(96+3+(3*6144))];
/// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17)
......@@ -407,7 +407,7 @@ typedef struct {
/// coded RI bits
int16_t q_RI[MAX_RI_PAYLOAD];
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
int16_t e[MAX_NUM_CHANNEL_BITS];
int16_t e[MAX_NUM_CHANNEL_BITS] __attribute__((aligned(32)));
/// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
uint8_t h[MAX_NUM_CHANNEL_BITS];
/// Pointer to the payload
......
This diff is collapsed.
......@@ -325,47 +325,74 @@ int allocate_REs_in_RB_no_pilots_64QAM_siso(LTE_DL_FRAME_PARMS *frame_parms,
if (skip_dc == 0) {
x0p=&x0[*jj],tti_offset=symbol_offset+re_offset;
for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
/* for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
re<12;
re+=4,x0p+=24,tti_offset+=4) {
re+=4,x0p+=24,tti_offset+=4) {*/
qam64_table_offset_re=FOUR[x0p[0]];
qam64_table_offset_im=FOUR[x0p[1]];
qam64_table_offset_re+=TWO[x0p[2]];
qam64_table_offset_im+=TWO[x0p[3]];
qam64_table_offset_re+=x0p[4];
qam64_table_offset_im+=x0p[5];
qam64_table_offset_re=(x0p[0]<<2)|(x0p[2]<<1)|x0p[4];
qam64_table_offset_im=(x0p[1]<<2)|(x0p[3]<<1)|x0p[5];
((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im];
qam64_table_offset_re=FOUR[x0p[6]];
qam64_table_offset_im=FOUR[x0p[7]];
qam64_table_offset_re+=TWO[x0p[8]];
qam64_table_offset_im+=TWO[x0p[9]];
qam64_table_offset_re+=x0p[10];
qam64_table_offset_im+=x0p[11];
qam64_table_offset_re=(x0p[6]<<2)|(x0p[8]<<1)|x0p[10];
qam64_table_offset_im=(x0p[7]<<2)|(x0p[9]<<1)|x0p[11];
((int16_t *)&txdataF[0][tti_offset])[2]=qam_table_s0[qam64_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[3]=qam_table_s0[qam64_table_offset_im];
qam64_table_offset_re=FOUR[x0p[12]];
qam64_table_offset_im=FOUR[x0p[13]];
qam64_table_offset_re+=TWO[x0p[14]];
qam64_table_offset_im+=TWO[x0p[15]];
qam64_table_offset_re+=x0p[16];
qam64_table_offset_im+=x0p[17];
qam64_table_offset_re=(x0p[12]<<2)|(x0p[14]<<1)|x0p[16];
qam64_table_offset_im=(x0p[13]<<2)|(x0p[15]<<1)|x0p[17];
((int16_t *)&txdataF[0][tti_offset])[4]=qam_table_s0[qam64_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[5]=qam_table_s0[qam64_table_offset_im];
qam64_table_offset_re=FOUR[x0p[18]];
qam64_table_offset_im=FOUR[x0p[19]];
qam64_table_offset_re+=TWO[x0p[20]];
qam64_table_offset_im+=TWO[x0p[21]];
qam64_table_offset_re+=x0p[22];
qam64_table_offset_im+=x0p[23];
qam64_table_offset_re=(x0p[18]<<2)|(x0p[20]<<1)|x0p[22];
qam64_table_offset_im=(x0p[19]<<2)|(x0p[21]<<1)|x0p[23];
((int16_t *)&txdataF[0][tti_offset])[6]=qam_table_s0[qam64_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[7]=qam_table_s0[qam64_table_offset_im];
}
qam64_table_offset_re=(x0p[24]<<2)|(x0p[26]<<1)|x0p[28];
qam64_table_offset_im=(x0p[25]<<2)|(x0p[27]<<1)|x0p[29];
((int16_t *)&txdataF[0][tti_offset])[8]=qam_table_s0[qam64_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[9]=qam_table_s0[qam64_table_offset_im];
qam64_table_offset_re=(x0p[30]<<2)|(x0p[32]<<1)|x0p[34];
qam64_table_offset_im=(x0p[31]<<2)|(x0p[33]<<1)|x0p[35];
((int16_t *)&txdataF[0][tti_offset])[10]=qam_table_s0[qam64_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[11]=qam_table_s0[qam64_table_offset_im];
qam64_table_offset_re=(x0p[36]<<2)|(x0p[38]<<1)|x0p[40];
qam64_table_offset_im=(x0p[37]<<2)|(x0p[39]<<1)|x0p[41];
((int16_t *)&txdataF[0][tti_offset])[12]=qam_table_s0[qam64_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[13]=qam_table_s0[qam64_table_offset_im];
qam64_table_offset_re=(x0p[42]<<2)|(x0p[44]<<1)|x0p[46];
qam64_table_offset_im=(x0p[43]<<2)|(x0p[45]<<1)|x0p[47];
((int16_t *)&txdataF[0][tti_offset])[14]=qam_table_s0[qam64_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[15]=qam_table_s0[qam64_table_offset_im];
qam64_table_offset_re=(x0p[48]<<2)|(x0p[50]<<1)|x0p[52];
qam64_table_offset_im=(x0p[49]<<2)|(x0p[51]<<1)|x0p[53];
((int16_t *)&txdataF[0][tti_offset])[16]=qam_table_s0[qam64_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[17]=qam_table_s0[qam64_table_offset_im];
qam64_table_offset_re=(x0p[54]<<2)|(x0p[56]<<1)|x0p[58];
qam64_table_offset_im=(x0p[55]<<2)|(x0p[57]<<1)|x0p[59];
((int16_t *)&txdataF[0][tti_offset])[18]=qam_table_s0[qam64_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[19]=qam_table_s0[qam64_table_offset_im];
qam64_table_offset_re=(x0p[60]<<2)|(x0p[62]<<1)|x0p[64];
qam64_table_offset_im=(x0p[61]<<2)|(x0p[63]<<1)|x0p[65];
((int16_t *)&txdataF[0][tti_offset])[20]=qam_table_s0[qam64_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[21]=qam_table_s0[qam64_table_offset_im];
qam64_table_offset_re=(x0p[66]<<2)|(x0p[68]<<1)|x0p[70];
qam64_table_offset_im=(x0p[67]<<2)|(x0p[69]<<1)|x0p[71];
((int16_t *)&txdataF[0][tti_offset])[22]=qam_table_s0[qam64_table_offset_re];
((int16_t *)&txdataF[0][tti_offset])[23]=qam_table_s0[qam64_table_offset_im];
// }
}
else {
for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
......@@ -1668,6 +1695,69 @@ int dlsch_modulation(int32_t **txdataF,
re_offset = frame_parms->first_carrier_offset;
symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb));
allocate_REs = allocate_REs_in_RB;
switch (mod_order0) {
case 2:
qam_table_s0 = NULL;
break;
case 4:
if (pilots) {
qam_table_s0 = qam16_table_b0;
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_pilots_16QAM_siso :
allocate_REs_in_RB;
}
else {
qam_table_s0 = qam16_table_a0;
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_no_pilots_16QAM_siso :
allocate_REs_in_RB;
}
break;
case 6:
if (pilots) {
qam_table_s0 = qam64_table_b0;
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_pilots_64QAM_siso :
allocate_REs_in_RB;
}
else {
qam_table_s0 = qam64_table_a0;
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_no_pilots_64QAM_siso :
allocate_REs_in_RB;
}
break;
}
switch (mod_order1) {
case 2:
qam_table_s1 = NULL;
allocate_REs = allocate_REs_in_RB;
break;
case 4:
if (pilots) {
qam_table_s1 = qam16_table_b1;
}
else {
qam_table_s1 = qam16_table_a1;
}
break;
case 6:
if (pilots) {
qam_table_s1 = qam64_table_b1;
}
else {
qam_table_s1 = qam64_table_a1;
}
break;
}
//for (aa=0;aa<frame_parms->nb_antennas_tx;aa++)
// memset(&txdataF[aa][symbol_offset],0,frame_parms->ofdm_symbol_size<<2);
//printf("symbol_offset %d,subframe offset %d : pilots %d\n",symbol_offset,subframe_offset,pilots);
......@@ -1816,68 +1906,7 @@ int dlsch_modulation(int32_t **txdataF,
}
}
allocate_REs = allocate_REs_in_RB;
switch (mod_order0) {
case 2:
qam_table_s0 = NULL;
break;
case 4:
if (pilots) {
qam_table_s0 = qam16_table_b0;
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_pilots_16QAM_siso :
allocate_REs_in_RB;
}
else {
qam_table_s0 = qam16_table_a0;
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_no_pilots_16QAM_siso :
allocate_REs_in_RB;
}
break;
case 6:
if (pilots) {
qam_table_s0 = qam64_table_b0;
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_pilots_64QAM_siso :
allocate_REs_in_RB;
}
else {
qam_table_s0 = qam64_table_a0;
allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
allocate_REs_in_RB_no_pilots_64QAM_siso :
allocate_REs_in_RB;
}
break;
}
switch (mod_order1) {
case 2:
qam_table_s1 = NULL;
allocate_REs = allocate_REs_in_RB;
break;
case 4:
if (pilots) {
qam_table_s1 = qam16_table_b1;
}
else {
qam_table_s1 = qam16_table_a1;
}
break;
case 6:
if (pilots) {
qam_table_s1 = qam64_table_b1;
}
else {
qam_table_s1 = qam64_table_a1;
}
break;
}
if (rb_alloc_ind > 0) {
// printf("Allocated rb %d/symbol %d, skip_half %d, subframe_offset %d, symbol_offset %d, re_offset %d, jj %d\n",rb,l,skip_half,subframe_offset,symbol_offset,re_offset,jj);
......
......@@ -48,6 +48,34 @@
#include "PHY/extern.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
static inline unsigned int lte_gold_scram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline));
static inline unsigned int lte_gold_scram(unsigned int *x1, unsigned int *x2, unsigned char reset)
{
int n;
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);
}
}
*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);
}
void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
int mbsfn_flag,
LTE_eNB_DLSCH_t *dlsch,
......@@ -75,53 +103,57 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
#ifdef DEBUG_SCRAMBLING
printf("scrambling: rnti %x, q %d, Ns %d, Nid_cell %d, length %d\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell, G);
#endif
s = lte_gold_generic(&x1, &x2, 1);
s = lte_gold_scram(&x1, &x2, 1);
for (i=0; i<(1+(G>>5)); i++) {
#ifdef DEBUG_SCRAMBLING
printf("scrambling %d : %d => ",k,e[k]);
#endif
e[0] = (e[0]) ^ (s&1);
e[1] = (e[1]) ^ ((s>>1)&1);
e[2] = (e[2]) ^ ((s>>2)&1);
e[3] = (e[3]) ^ ((s>>3)&1);
e[4] = (e[4]) ^ ((s>>4)&1);
e[5] = (e[5]) ^ ((s>>5)&1);
e[6] = (e[6]) ^ ((s>>6)&1);
e[7] = (e[7]) ^ ((s>>7)&1);
e[8] = (e[8]) ^ ((s>>8)&1);
e[9] = (e[9]) ^ ((s>>9)&1);
e[10] = (e[10]) ^ ((s>>10)&1);
e[11] = (e[11]) ^ ((s>>11)&1);
e[12] = (e[12]) ^ ((s>>12)&1);
e[13] = (e[13]) ^ ((s>>13)&1);
e[14] = (e[14]) ^ ((s>>14)&1);
e[15] = (e[15]) ^ ((s>>15)&1);
e[16] = (e[16]) ^ ((s>>16)&1);
e[17] = (e[17]) ^ ((s>>17)&1);
e[18] = (e[18]) ^ ((s>>18)&1);
e[19] = (e[19]) ^ ((s>>19)&1);
e[20] = (e[20]) ^ ((s>>20)&1);
e[21] = (e[21]) ^ ((s>>21)&1);
e[22] = (e[22]) ^ ((s>>22)&1);
e[23] = (e[23]) ^ ((s>>23)&1);
e[24] = (e[24]) ^ ((s>>24)&1);
e[25] = (e[25]) ^ ((s>>25)&1);
e[26] = (e[26]) ^ ((s>>26)&1);
e[27] = (e[27]) ^ ((s>>27)&1);
e[28] = (e[28]) ^ ((s>>28)&1);
e[29] = (e[29]) ^ ((s>>29)&1);
e[30] = (e[30]) ^ ((s>>30)&1);
e[31] = (e[31]) ^ ((s>>31)&1);
e[0] = (e[0]&1) ^ (s&1);
e[1] = (e[1]&1) ^ ((s>>1)&1);
e[2] = (e[2]&1) ^ ((s>>2)&1);
e[3] = (e[3]&1) ^ ((s>>3)&1);
e[4] = (e[4]&1) ^ ((s>>4)&1);
e[5] = (e[5]&1) ^ ((s>>5)&1);
e[6] = (e[6]&1) ^ ((s>>6)&1);
e[7] = (e[7]&1) ^ ((s>>7)&1);
e[8] = (e[8]&1) ^ ((s>>8)&1);
e[9] = (e[9]&1) ^ ((s>>9)&1);
e[10] = (e[10]&1) ^ ((s>>10)&1);
e[11] = (e[11]&1) ^ ((s>>11)&1);
e[12] = (e[12]&1) ^ ((s>>12)&1);
e[13] = (e[13]&1) ^ ((s>>13)&1);
e[14] = (e[14]&1) ^ ((s>>14)&1);
e[15] = (e[15]&1) ^ ((s>>15)&1);
e[16] = (e[16]&1) ^ ((s>>16)&1);
e[17] = (e[17]&1) ^ ((s>>17)&1);
e[18] = (e[18]&1) ^ ((s>>18)&1);
e[19] = (e[19]&1) ^ ((s>>19)&1);
e[20] = (e[20]&1) ^ ((s>>20)&1);
e[21] = (e[21]&1) ^ ((s>>21)&1);
e[22] = (e[22]&1) ^ ((s>>22)&1);
e[23] = (e[23]&1) ^ ((s>>23)&1);
e[24] = (e[24]&1) ^ ((s>>24)&1);
e[25] = (e[25]&1) ^ ((s>>25)&1);
e[26] = (e[26]&1) ^ ((s>>26)&1);
e[27] = (e[27]&1) ^ ((s>>27)&1);
e[28] = (e[28]&1) ^ ((s>>28)&1);
e[29] = (e[29]&1) ^ ((s>>29)&1);
e[30] = (e[30]&1) ^ ((s>>30)&1);
e[31] = (e[31]&1) ^ ((s>>31)&1);
// This is not faster for some unknown reason
// ((__m128i *)e)[0] = _mm_xor_si128(((__m128i *)e)[0],((__m128i *)scrambling_lut)[s&65535]);
// ((__m128i *)e)[1] = _mm_xor_si128(((__m128i *)e)[1],((__m128i *)scrambling_lut)[s>>16]);
#ifdef DEBUG_SCRAMBLING
printf("%d\n",e[k]);
#endif
s = lte_gold_generic(&x1, &x2, 0);
s = lte_gold_scram(&x1, &x2, 0);
e += 32;
}
......@@ -153,7 +185,7 @@ void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
#ifdef DEBUG_SCRAMBLING
printf("unscrambling: rnti %x, q %d, Ns %d, Nid_cell %d length %d\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell,G);
#endif
s = lte_gold_generic(&x1, &x2, 1);
s = lte_gold_scram(&x1, &x2, 1);
for (i=0; i<(1+(G>>5)); i++) {
for (j=0; j<32; j++,k++) {
......@@ -166,6 +198,30 @@ void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
#endif
}
s = lte_gold_generic(&x1, &x2, 0);
s = lte_gold_scram(&x1, &x2, 0);
}
}
void init_unscrambling_lut() {
uint32_t s;
int i=0,j;
for (s=0;s<=65535;s++) {
for (j=0;j<16;j++) {
unscrambling_lut[i++] = (int16_t)((((s>>j)&1)<<1)-1);
}
}
}
void init_scrambling_lut() {
uint32_t s;
int i=0,j;
for (s=0;s<=65535;s++) {
for (j=0;j<16;j++) {
scrambling_lut[i++] = (uint8_t)((s>>j)&1);
}
}
}
......@@ -93,7 +93,8 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin
LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag);
/** \fn dlsch_encoding(uint8_t *input_buffer,
/** \fn dlsch_encoding(PHY_VARS_eNB *eNB,
uint8_t *input_buffer,
LTE_DL_FRAME_PARMS *frame_parms,
uint8_t num_pdcch_symbols,
LTE_eNB_DLSCH_t *dlsch,
......@@ -105,6 +106,7 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag);
- Channel coding (Turbo coding)
- Rate matching (sub-block interleaving, bit collection, selection and transmission
- Code block concatenation
@param eNB Pointer to eNB PHY context
@param input_buffer Pointer to input buffer for sub-frame
@param frame_parms Pointer to frame descriptor structure
@param num_pdcch_symbols Number of PDCCH symbols in this subframe
......@@ -116,8 +118,8 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag);
@param i_stats Time statistics for interleaving
@returns status
*/
int32_t dlsch_encoding(uint8_t *a,
LTE_DL_FRAME_PARMS *frame_parms,
int32_t dlsch_encoding(PHY_VARS_eNB *eNB,
uint8_t *a,
uint8_t num_pdcch_symbols,
LTE_eNB_DLSCH_t *dlsch,
int frame,
......@@ -126,6 +128,39 @@ int32_t dlsch_encoding(uint8_t *a,
time_stats_t *te_stats,
time_stats_t *i_stats);
/** \fn dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
uint8_t *input_buffer,
uint8_t num_pdcch_symbols,
LTE_eNB_DLSCH_t *dlsch,
int frame,
uint8_t subframe)
\brief This function performs a subset of the bit-coding functions for LTE as described in 36-212, Release 8.Support is limited to turbo-coded channels (DLSCH/ULSCH). This version spawns 1 worker thread. The implemented functions are:
- CRC computation and addition
- Code block segmentation and sub-block CRC addition
- Channel coding (Turbo coding)
- Rate matching (sub-block interleaving, bit collection, selection and transmission
- Code block concatenation
@param eNB Pointer to eNB PHY context
@param input_buffer Pointer to input buffer for sub-frame
@param num_pdcch_symbols Number of PDCCH symbols in this subframe
@param dlsch Pointer to dlsch to be encoded
@param frame Frame number
@param subframe Subframe number
@param rm_stats Time statistics for rate-matching
@param te_stats Time statistics for turbo-encoding
@param i_stats Time statistics for interleaving
@returns status
*/
int32_t dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
uint8_t *a,
uint8_t num_pdcch_symbols,
LTE_eNB_DLSCH_t *dlsch,
int frame,
uint8_t subframe,
time_stats_t *rm_stats,
time_stats_t *te_stats,
time_stats_t *i_stats);
void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB,
uint8_t *DLSCH_pdu,
LTE_eNB_DLSCH_t *dlsch);
......@@ -1544,6 +1579,32 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB,
uint8_t Nbundled,
uint8_t llr8_flag);
/*!
\brief Decoding of ULSCH data component from 36-212. This one spawns 1 worker thread in parallel,half of the segments in each thread.
@param phy_vars_eNB Pointer to eNB top-level descriptor
@param UE_id ID of UE transmitting this PUSCH
@param harq_pid HARQ process ID
@param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used
@returns 0 on success
*/
int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,
int UE_id,
int harq_pid,
int llr8_flag);
/*!
\brief Decoding of ULSCH data component from 36-212. This one is single thread.
@param phy_vars_eNB Pointer to eNB top-level descriptor
@param UE_id ID of UE transmitting this PUSCH
@param harq_pid HARQ process ID
@param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used
@returns 0 on success
*/
int ulsch_decoding_data(PHY_VARS_eNB *eNB,
int UE_id,
int harq_pid,
int llr8_flag);
uint32_t ulsch_decoding_emul(PHY_VARS_eNB *phy_vars_eNB,
eNB_rxtx_proc_t *proc,
uint8_t UE_index,
......@@ -1755,6 +1816,9 @@ void compute_prach_seq(PRACH_CONFIG_COMMON *prach_config_common,
void init_prach_tables(int N_ZC);
void init_unscrambling_lut(void);
void init_scrambling_lut(void);
/*!
\brief Return the status of MBSFN in this frame/subframe
@param frame Frame index
......
This diff is collapsed.
......@@ -211,6 +211,21 @@ typedef struct {
/// scheduling parameters for RXn-TXnp4 thread
struct sched_param sched_param_rxtx;
} eNB_rxtx_proc_t;
typedef struct {
struct PHY_VARS_eNB_s *eNB;
int UE_id;
int harq_pid;
int llr8_flag;
int ret;
} td_params;
typedef struct {
struct PHY_VARS_eNB_s *eNB;
LTE_eNB_DLSCH_t *dlsch;
int G;
} te_params;
/// Context data structure for eNB subframe processing
typedef struct eNB_proc_t_s {
/// Component Carrier index
......@@ -229,6 +244,10 @@ typedef struct eNB_proc_t_s {
int frame_prach;
/// \internal This variable is protected by \ref mutex_fep.
int instance_cnt_fep;
/// \internal This variable is protected by \ref mutex_td.
int instance_cnt_td;
/// \internal This variable is protected by \ref mutex_te.
int instance_cnt_te;
/// \brief Instance count for FH processing thread.
/// \internal This variable is protected by \ref mutex_FH.
int instance_cnt_FH;
......@@ -249,6 +268,10 @@ typedef struct eNB_proc_t_s {
int first_tx;
/// pthread attributes for parallel fep thread
pthread_attr_t attr_fep;
/// pthread attributes for parallel turbo-decoder thread
pthread_attr_t attr_td;
/// pthread attributes for parallel turbo-encoder thread
pthread_attr_t attr_te;
/// pthread attributes for FH processing thread
pthread_attr_t attr_FH;
/// pthread attributes for single eNB processing thread
......@@ -259,6 +282,10 @@ typedef struct eNB_proc_t_s {
pthread_attr_t attr_asynch_rxtx;
/// scheduling parameters for parallel fep thread
struct sched_param sched_param_fep;
/// scheduling parameters for parallel turbo-decoder thread
struct sched_param sched_param_td;
/// scheduling parameters for parallel turbo-encoder thread
struct sched_param sched_param_te;
/// scheduling parameters for FH thread
struct sched_param sched_param_FH;
/// scheduling parameters for single eNB thread
......@@ -269,10 +296,18 @@ typedef struct eNB_proc_t_s {
struct sched_param sched_param_asynch_rxtx;
/// pthread structure for parallel fep thread
pthread_t pthread_fep;
/// pthread structure for parallel turbo-decoder thread
pthread_t pthread_td;
/// pthread structure for parallel turbo-encoder thread
pthread_t pthread_te;
/// pthread structure for PRACH thread
pthread_t pthread_prach;
/// condition variable for parallel fep thread
pthread_cond_t cond_fep;
/// condition variable for parallel turbo-decoder thread
pthread_cond_t cond_td;
/// condition variable for parallel turbo-encoder thread
pthread_cond_t cond_te;
/// condition variable for FH thread
pthread_cond_t cond_FH;
/// condition variable for PRACH processing thread;
......@@ -281,12 +316,20 @@ typedef struct eNB_proc_t_s {
pthread_cond_t cond_asynch_rxtx;
/// mutex for parallel fep thread
pthread_mutex_t mutex_fep;
/// mutex for parallel turbo-decoder thread
pthread_mutex_t mutex_td;
/// mutex for parallel turbo-encoder thread
pthread_mutex_t mutex_te;
/// mutex for FH
pthread_mutex_t mutex_FH;
/// mutex for PRACH thread
pthread_mutex_t mutex_prach;
/// mutex for asynch RX/TX thread
pthread_mutex_t mutex_asynch_rxtx;
/// parameters for turbo-decoding worker thread
td_params tdp;
/// parameters for turbo-encoding worker thread
te_params tep;
/// set of scheduling variables RXn-TXnp4 threads
eNB_rxtx_proc_t proc_rxtx[2];
/// number of slave threads
......@@ -367,6 +410,8 @@ typedef struct PHY_VARS_eNB_s {
int abstraction_flag;
void (*do_prach)(struct PHY_VARS_eNB_s *eNB);
void (*fep)(struct PHY_VARS_eNB_s *eNB);
int (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag);
int (*te)(struct PHY_VARS_eNB_s *,uint8_t *,uint8_t,LTE_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *);
void (*proc_uespec_rx)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc,const relaying_type_t r_type);
void (*proc_tx)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type,PHY_VARS_RN *rn);
void (*tx_fh)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc);
......@@ -828,6 +873,69 @@ typedef struct {
} PHY_VARS_UE;
void exit_fun(const char* s);
inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) {
if (pthread_mutex_lock(mutex) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
while (*instance_cnt < 0) {
// most of the time the thread is waiting here
// proc->instance_cnt_rxtx is -1
pthread_cond_wait(cond,mutex); // this unlocks mutex_rxtx while waiting and then locks it again
}
if (pthread_mutex_unlock(mutex) != 0) {
LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
return(0);
}
inline int wait_on_busy_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) {
if (pthread_mutex_lock(mutex) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
while (*instance_cnt == 0) {
// most of the time the thread will skip this
// waits only if proc->instance_cnt_rxtx is 0
pthread_cond_wait(cond,mutex); // this unlocks mutex_rxtx while waiting and then locks it again
}
if (pthread_mutex_unlock(mutex) != 0) {
LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
return(0);
}
inline int release_thread(pthread_mutex_t *mutex,int *instance_cnt,char *name) {
if (pthread_mutex_lock(mutex) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
*instance_cnt=*instance_cnt-1;
if (pthread_mutex_unlock(mutex) != 0) {
LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
return(0);
}
#include "PHY/INIT/defs.h"
......
......@@ -115,5 +115,8 @@ extern char eNB_functions[6][20];
extern char eNB_timing[2][20];
extern int16_t unscrambling_lut[65536*16];
extern uint8_t scrambling_lut[65536*16];
#endif /*__PHY_EXTERN_H__ */
......@@ -607,34 +607,34 @@ typedef struct {
int32_t **txdataF[3];
/// \brief Holds the received data in time domain.
/// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna [0..nb_antennas_rx[
/// - third index: sample [0..]
int32_t **rxdata[3];
/// \brief Holds the last subframe of received data in time domain after removal of 7.5kHz frequency offset.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: secotr id [0..2] (hard coded)
/// - second index: rx antenna [0..nb_antennas_rx[
/// - third index: sample [0..samples_per_tti[
int32_t **rxdata_7_5kHz[3];
/// \brief Holds the received data in the frequency domain.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna [0..nb_antennas_rx[
/// - third index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[
int32_t **rxdataF[3];
/// \brief Holds output of the sync correlator.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: sample [0..samples_per_tti*10[
uint32_t *sync_corr[3];
} LTE_eNB_COMMON;
typedef struct {
/// \brief Hold the channel estimates in frequency domain based on SRS.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna id [0..nb_antennas_rx[
/// - third index: ? [0..ofdm_symbol_size[
int32_t **srs_ch_estimates[3];
/// \brief Hold the channel estimates in time domain based on SRS.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna id [0..nb_antennas_rx[
/// - third index: ? [0..2*ofdm_symbol_size[
int32_t **srs_ch_estimates_time[3];
......@@ -645,54 +645,54 @@ typedef struct {
typedef struct {
/// \brief Holds the received data in the frequency domain for the allocated RBs in repeated format.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna id [0..nb_antennas_rx[
/// - third index: ? [0..2*ofdm_symbol_size[
/// - third index (definition from phy_init_lte_eNB()): ? [0..24*N_RB_UL*frame_parms->symbols_per_tti[
/// \warning inconsistent third index definition
int32_t **rxdataF_ext[3];
/// \brief Holds the received data in the frequency domain for the allocated RBs in normal format.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna id [0..nb_antennas_rx[
/// - third index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **rxdataF_ext2[3];
/// \brief Hold the channel estimates in time domain based on DRS.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna id [0..nb_antennas_rx[
/// - third index: ? [0..4*ofdm_symbol_size[
int32_t **drs_ch_estimates_time[3];
/// \brief Hold the channel estimates in frequency domain based on DRS.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna id [0..nb_antennas_rx[
/// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **drs_ch_estimates[3];
/// \brief Hold the channel estimates for UE0 in case of Distributed Alamouti Scheme.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna id [0..nb_antennas_rx[
/// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **drs_ch_estimates_0[3];
/// \brief Hold the channel estimates for UE1 in case of Distributed Almouti Scheme.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna id [0..nb_antennas_rx[
/// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **drs_ch_estimates_1[3];
/// \brief Holds the compensated signal.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna id [0..nb_antennas_rx[
/// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **rxdataF_comp[3];
/// \brief Hold the compensated data (y)*(h0*) in case of Distributed Alamouti Scheme.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna id [0..nb_antennas_rx[
/// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **rxdataF_comp_0[3];
/// \brief Hold the compensated data (y*)*(h1) in case of Distributed Alamouti Scheme.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna id [0..nb_antennas_rx[
/// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **rxdataF_comp_1[3];
/// \brief ?.
/// - first index: eNB id [0..2] (hard coded)
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna id [0..nb_antennas_rx[
/// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **ul_ch_mag[3];
......
......@@ -142,6 +142,10 @@ double beta2_dlsch[6][MCS_COUNT] = { {2.52163, 0.83231, 0.77472, 1.36536, 1.1682
char eNB_functions[6][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RCC_IF4p5","NGFI_RAI_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5",};
char eNB_timing[2][20]={"synch_to_ext_device","synch_to_other"};
/// lookup table for unscrambling in RX
int16_t unscrambling_lut[65536*16] __attribute__((aligned(32)));
/// lookup table for scrambling in TX
uint8_t scrambling_lut[65536*16] __attribute__((aligned(32)));
#endif /*__PHY_VARS_H__ */
......@@ -163,8 +163,9 @@ void phy_procedures_UE_S_RX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abst
@param abstraction_flag Indicator of PHY abstraction
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
@param phy_vars_rn pointer to the RN variables
@param do_meas Do inline timing measurement
*/
void phy_procedures_eNB_TX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
void phy_procedures_eNB_TX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn,int do_meas);
/*! \brief Scheduling for eNB RX UE-specific procedures in normal subframes.
@param phy_vars_eNB Pointer to eNB variables on which to act
......
......@@ -1030,14 +1030,14 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *d
LOG_D(PHY,"Generating DLSCH/PDSCH %d\n",ra_flag);
// 36-212
start_meas(&eNB->dlsch_encoding_stats);
dlsch_encoding(DLSCH_pdu,
fp,
num_pdcch_symbols,
dlsch,
frame,subframe,
&eNB->dlsch_rate_matching_stats,
&eNB->dlsch_turbo_encoding_stats,
&eNB->dlsch_interleaving_stats);
eNB->te(eNB,
DLSCH_pdu,
num_pdcch_symbols,
dlsch,
frame,subframe,
&eNB->dlsch_rate_matching_stats,
&eNB->dlsch_turbo_encoding_stats,
&eNB->dlsch_interleaving_stats);
stop_meas(&eNB->dlsch_encoding_stats);
// 36-211
start_meas(&eNB->dlsch_scrambling_stats);
......@@ -1053,6 +1053,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *d
0,
subframe<<1);
stop_meas(&eNB->dlsch_scrambling_stats);
start_meas(&eNB->dlsch_modulation_stats);
......@@ -1084,7 +1085,8 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *d
void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
eNB_rxtx_proc_t *proc,
relaying_type_t r_type,
PHY_VARS_RN *rn)
PHY_VARS_RN *rn,
int do_meas)
{
UNUSED(rn);
int frame=proc->frame_tx;
......@@ -1113,7 +1115,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_DL)) return;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1);
start_meas(&eNB->phy_proc_tx);
if (do_meas==1) start_meas(&eNB->phy_proc_tx);
T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe));
......@@ -1399,7 +1401,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,0);
stop_meas(&eNB->phy_proc_tx);
if (do_meas==1) stop_meas(&eNB->phy_proc_tx);
}
......@@ -2522,73 +2524,10 @@ void fep0(PHY_VARS_eNB *eNB,int slot) {
}
}
static inline int release_thread(pthread_mutex_t *mutex,int *instance_cnt,char *name) {
if (pthread_mutex_lock(mutex) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
*instance_cnt=*instance_cnt-1;
if (pthread_mutex_unlock(mutex) != 0) {
LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
return(0);
}
static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) {
if (pthread_mutex_lock(mutex) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
while (*instance_cnt < 0) {
// most of the time the thread is waiting here
// proc->instance_cnt_rxtx is -1
pthread_cond_wait(cond,mutex); // this unlocks mutex_rxtx while waiting and then locks it again
}
if (pthread_mutex_unlock(mutex) != 0) {
LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
return(0);
}
static inline int wait_on_busy_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) {
if (pthread_mutex_lock(mutex) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
while (*instance_cnt == 0) {
// most of the time the thread will skip this
// waits only if proc->instance_cnt_rxtx is 0
pthread_cond_wait(cond,mutex); // this unlocks mutex_rxtx while waiting and then locks it again
}
if (pthread_mutex_unlock(mutex) != 0) {
LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
return(0);
}
extern int oai_exit;
#define THREAD_FULL 1
#ifdef THREAD_FULL
static void *fep_thread(void *param) {
PHY_VARS_eNB *eNB = (PHY_VARS_eNB *)param;
......@@ -2611,31 +2550,50 @@ static void *fep_thread(void *param) {
return(NULL);
}
#else
void init_fep_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_fep) {
static void *fep_thread(void *param) {
eNB_proc_t *proc = &eNB->proc;
PHY_VARS_eNB *eNB = (PHY_VARS_eNB *)param;
eNB_proc_t *proc = &eNB->proc;
proc->instance_cnt_fep = -1;
pthread_mutex_init( &proc->mutex_fep, NULL);
pthread_cond_init( &proc->cond_fep, NULL);
pthread_create(&proc->pthread_fep, attr_fep, fep_thread, (void*)eNB);
fep0(eNB,0);
return(NULL);
}
#endif
void init_fep_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_fep) {
extern void *td_thread(void*);
void init_td_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_td) {
eNB_proc_t *proc = &eNB->proc;
proc->instance_cnt_fep = -1;
proc->tdp.eNB = eNB;
proc->instance_cnt_td = -1;
pthread_mutex_init( &proc->mutex_fep, NULL);
pthread_cond_init( &proc->cond_fep, NULL);
pthread_mutex_init( &proc->mutex_td, NULL);
pthread_cond_init( &proc->cond_td, NULL);
#ifdef THREAD_FULL
pthread_create(&proc->pthread_fep, attr_fep, fep_thread, (void*)eNB);
#endif
pthread_create(&proc->pthread_td, attr_td, td_thread, (void*)&proc->tdp);
}
extern void *te_thread(void*);
void init_te_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_te) {
eNB_proc_t *proc = &eNB->proc;
proc->tep.eNB = eNB;
proc->instance_cnt_te = -1;
pthread_mutex_init( &proc->mutex_te, NULL);
pthread_cond_init( &proc->cond_te, NULL);
printf("Creating te_thread\n");
pthread_create(&proc->pthread_te, attr_te, te_thread, (void*)&proc->tep);
}
......@@ -2645,15 +2603,13 @@ void eNB_fep_full_2thread(PHY_VARS_eNB *eNB) {
eNB_proc_t *proc = &eNB->proc;
struct timespec wait;
int wait_cnt=0;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,1);
start_meas(&eNB->ofdm_demod_stats);
#ifdef THREAD_FULL
if (pthread_mutex_timedlock(&proc->mutex_fep,&wait) != 0) {
printf("[eNB] ERROR pthread_mutex_lock for fep thread %d (IC %d)\n", proc->instance_cnt_fep);
exit_fun( "error locking mutex_fep" );
......@@ -2683,14 +2639,6 @@ void eNB_fep_full_2thread(PHY_VARS_eNB *eNB) {
wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread");
#else
pthread_create(&proc->pthread_fep, NULL, fep_thread, (void*)eNB);
// call second slot in this symbol
fep0(eNB,1);
pthread_join(proc->pthread_fep,(void**)NULL);
#endif
stop_meas(&eNB->ofdm_demod_stats);
}
......
......@@ -1381,6 +1381,7 @@ int main(int argc, char **argv)
char csv_fname[32];
int dci_flag=1;
int llr8_flag=1;
int two_thread_flag=0;
int DLSCH_RB_ALLOC;
#if defined(__arm__)
......@@ -1412,7 +1413,7 @@ int main(int argc, char **argv)
// num_layers = 1;
perfect_ce = 0;
while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:XY")) != -1) {
while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:WXY")) != -1) {
switch (c) {
case 'a':
awgn_flag = 1;
......@@ -1479,7 +1480,10 @@ int main(int argc, char **argv)
case 'L':
llr8_flag=1;
break;
case 'W':
two_thread_flag = 1;
break;
case 'l':
offset_mumimo_llr_drange_fix=atoi(optarg);
break;
......@@ -1779,6 +1783,15 @@ int main(int argc, char **argv)
perfect_ce);
eNB->mac_enabled=1;
if (two_thread_flag == 0) {
eNB->te = dlsch_encoding;
}
else {
eNB->te = dlsch_encoding_2threads;
init_td_thread(eNB,NULL);
init_te_thread(eNB,NULL);
}
// callback functions required for phy_procedures_tx
mac_xface->get_dci_sdu = get_dci_sdu;
mac_xface->get_dlsch_sdu = get_dlsch_sdu;
......@@ -2272,7 +2285,6 @@ int main(int argc, char **argv)
if (input_fd==NULL) {
start_meas(&eNB->phy_proc_tx);
// Simulate HARQ procedures!!!
memset(CCE_table,0,800*sizeof(int));
......@@ -2345,7 +2357,7 @@ int main(int argc, char **argv)
proc_eNB->subframe_tx = subframe;
eNB->abstraction_flag=0;
phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL);
phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,1);
start_meas(&eNB->ofdm_mod_stats);
......@@ -2366,7 +2378,7 @@ int main(int argc, char **argv)
proc_eNB->subframe_tx = subframe+1;
phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL);
phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,0);
do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id],
eNB->common_vars.txdata[eNB_id],
......
......@@ -676,8 +676,10 @@ int main(int argc, char **argv)
eNB->ulsch[0] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0);
UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0);
if (parallel_flag == 1) init_fep_thread(eNB,&eNB->proc.attr_fep);
if (parallel_flag == 1) {
init_fep_thread(eNB,NULL);
init_td_thread(eNB,NULL);
}
// Create transport channel structures for 2 transport blocks (MIMO)
for (i=0; i<2; i++) {
eNB->dlsch[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0);
......@@ -1171,7 +1173,8 @@ int main(int argc, char **argv)
}
eNB->fep = (parallel_flag == 1) ? eNB_fep_full_2thread : eNB_fep_full;
eNB->fep = (parallel_flag == 1) ? eNB_fep_full_2thread : eNB_fep_full;
eNB->td = (parallel_flag == 1) ? ulsch_decoding_data_2thread : ulsch_decoding_data;
eNB->do_prach = NULL;
phy_procedures_eNB_common_RX(eNB);
......
......@@ -279,51 +279,6 @@ static inline void wait_sync(char *thread_name) {
}
static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) {
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
if (pthread_mutex_timedlock(mutex,&wait) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
while (*instance_cnt < 0) {
// most of the time the thread is waiting here
// proc->instance_cnt_rxtx is -1
pthread_cond_wait(cond,mutex); // this unlocks mutex_rxtx while waiting and then locks it again
}
if (pthread_mutex_unlock(mutex) != 0) {
LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
return(0);
}
static inline int release_thread(pthread_mutex_t *mutex,int *instance_cnt,char *name) {
if (pthread_mutex_lock(mutex) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
*instance_cnt=*instance_cnt-1;
if (pthread_mutex_unlock(mutex) != 0) {
LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for %s\n",name);
exit_fun("nothing to add");
return(-1);
}
return(0);
}
void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
unsigned int aa,slot_offset, slot_offset_F;
......@@ -470,7 +425,7 @@ void proc_tx_high0(PHY_VARS_eNB *eNB,
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB+offset, proc->frame_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB+offset, proc->subframe_tx );
phy_procedures_eNB_TX(eNB,proc,r_type,rn);
phy_procedures_eNB_TX(eNB,proc,r_type,rn,1);
/* we're done, let the next one proceed */
if (pthread_mutex_lock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
......@@ -1344,7 +1299,7 @@ void init_eNB_proc(int inst) {
PHY_VARS_eNB *eNB;
eNB_proc_t *proc;
eNB_rxtx_proc_t *proc_rxtx;
pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_single=NULL,*attr_fep=NULL;
pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_single=NULL,*attr_fep=NULL,*attr_td=NULL;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
eNB = PHY_vars_eNB_g[inst][CC_id];
......@@ -1379,6 +1334,8 @@ void init_eNB_proc(int inst) {
pthread_attr_init( &proc->attr_asynch_rxtx);
pthread_attr_init( &proc->attr_single);
pthread_attr_init( &proc->attr_fep);
pthread_attr_init( &proc->attr_td);
pthread_attr_init( &proc->attr_te);
pthread_attr_init( &proc_rxtx[0].attr_rxtx);
pthread_attr_init( &proc_rxtx[1].attr_rxtx);
#ifndef DEADLINE_SCHEDULER
......@@ -1389,6 +1346,8 @@ void init_eNB_proc(int inst) {
attr_asynch = &proc->attr_asynch_rxtx;
attr_single = &proc->attr_single;
attr_fep = &proc->attr_fep;
attr_td = &proc->attr_td;
attr_te = &proc->attr_te;
#endif
if (eNB->single_thread_flag==0) {
......@@ -1399,6 +1358,8 @@ void init_eNB_proc(int inst) {
else {
pthread_create(&proc->pthread_single, attr_single, eNB_thread_single, &eNB->proc);
init_fep_thread(eNB,attr_fep);
init_td_thread(eNB,attr_td);
init_te_thread(eNB,attr_te);
}
pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, &eNB->proc );
if ((eNB->node_timing == synch_to_other) ||
......@@ -1625,6 +1586,8 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
case NGFI_RRU_IF5:
eNB->do_prach = NULL;
eNB->fep = eNB_fep_rru_if5;
eNB->td = NULL;
eNB->te = NULL;
eNB->proc_uespec_rx = NULL;
eNB->proc_tx = NULL;
eNB->tx_fh = NULL;
......@@ -1649,6 +1612,8 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
case NGFI_RRU_IF4p5:
eNB->do_prach = do_prach;
eNB->fep = eNB_fep_full;
eNB->td = NULL;
eNB->te = NULL;
eNB->proc_uespec_rx = NULL;
eNB->proc_tx = NULL;//proc_tx_rru_if4p5;
eNB->tx_fh = NULL;
......@@ -1676,6 +1641,8 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
case eNodeB_3GPP:
eNB->do_prach = do_prach;
eNB->fep = eNB_fep_full;
eNB->td = ulsch_decoding_data_2thread;
eNB->te = dlsch_encoding_2thread;
eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX;
eNB->proc_tx = proc_tx_full;
eNB->tx_fh = NULL;
......@@ -1694,6 +1661,8 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
case eNodeB_3GPP_BBU:
eNB->do_prach = do_prach;
eNB->fep = eNB_fep_full;
eNB->td = ulsch_decoding_data_2thread;
eNB->te = dlsch_encoding_2thread;
eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX;
eNB->proc_tx = proc_tx_full;
eNB->tx_fh = tx_fh_if5;
......@@ -1716,6 +1685,8 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
case NGFI_RCC_IF4p5:
eNB->do_prach = do_prach;
eNB->fep = NULL;
eNB->td = ulsch_decoding_data_2thread;
eNB->te = dlsch_encoding_2thread;
eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX;
eNB->proc_tx = proc_tx_high;
eNB->tx_fh = tx_fh_if4p5;
......@@ -1737,6 +1708,8 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
case NGFI_RAU_IF4p5:
eNB->do_prach = do_prach;
eNB->fep = NULL;
eNB->td = ulsch_decoding_data_2thread;
eNB->te = dlsch_encoding_2thread;
eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX;
eNB->proc_tx = proc_tx_high;
eNB->tx_fh = tx_fh_if4p5;
......
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