Commit eea066a0 authored by Khodr Saaifan's avatar Khodr Saaifan Committed by Thomas Schlichter

implement tm4 into MAC and PHY for eNB TX

parent 1da3b555
......@@ -1628,7 +1628,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
// assume both TBs are active
if (dlsch0_harq != NULL)
dlsch0_harq->Nl = 1;
dlsch0_harq->Nl = 1;//SFN: 2 TM4 test
if (dlsch1_harq != NULL)
dlsch1_harq->Nl = 1;
......@@ -1668,14 +1668,10 @@ int generate_eNB_dlsch_params_from_dci(int frame,
} else if ((dlsch0 != NULL) && (dlsch1 == NULL)) { // only CW 0 active
dlsch0_harq->dl_power_off = 1;
if (dlsch0_harq->round == 0) {
// MCS and TBS don't change across HARQ rounds
dlsch0_harq->TBS= TBStable[get_I_TBS(dlsch0_harq->mcs)][(Nl_layer*dlsch0_harq->nb_rb)-1];
}
switch (tpmi) {
case 0 :
dlsch0_harq->mimo_mode = ALAMOUTI;
dlsch0_harq->Nl = 1;
break;
case 1:
dlsch0_harq->mimo_mode = UNIFORM_PRECODING11;
......@@ -1701,6 +1697,15 @@ int generate_eNB_dlsch_params_from_dci(int frame,
dlsch0_harq->mimo_mode = PUSCH_PRECODING1;
dlsch0_harq->pmi_alloc = DL_pmi_single;
break;
case 7://SFN:
dlsch0_harq->mimo_mode = TM4_NO_PRECODING;
dlsch0_harq->Nl = 2;
break;
}
if (dlsch0_harq->round == 0)
{
// MCS and TBS don't change across HARQ rounds
dlsch0_harq->TBS= TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->Nl*dlsch0_harq->nb_rb)-1];
}
} else if ((dlsch0 == NULL) && (dlsch1 != NULL)) {
dlsch1_harq->dl_power_off = 1;
......
......@@ -628,10 +628,10 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
((int16_t *)&qpsk[0])[0] = gain_lin_QPSK;
((int16_t *)&qpsk[0])[1] = gain_lin_QPSK;
((int16_t *)&qpsk[1])[0] = -gain_lin_QPSK;
((int16_t *)&qpsk[1])[1] = gain_lin_QPSK;;
((int16_t *)&qpsk[2])[0] = gain_lin_QPSK;;
((int16_t *)&qpsk[2])[1] = -gain_lin_QPSK;;
((int16_t *)&qpsk[3])[0] = -gain_lin_QPSK;;
((int16_t *)&qpsk[1])[1] = gain_lin_QPSK;
((int16_t *)&qpsk[2])[0] = gain_lin_QPSK;
((int16_t *)&qpsk[2])[1] = -gain_lin_QPSK;
((int16_t *)&qpsk[3])[0] = -gain_lin_QPSK;
((int16_t *)&qpsk[3])[1] = -gain_lin_QPSK;
if ((dlsch0_harq != NULL) && (dlsch1_harq != NULL)) { //this is for TM3, TM4
......@@ -958,6 +958,128 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
}
}
/*Author: Khodr Saaifan (Fraunhofer IIs)
* RE mapping for TM4
*/
else if (mimo_mode == TM4_NO_PRECODING){
*re_allocated = *re_allocated + 1;
amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15);
switch (mod_order0) {
// This implements TM4 without Precoding for 2 TX antennas
// - - - - - - - - - - - -
//| y0 | | 1 0 || x0 | | x0 |
//| y1 | = | 0 1 || x1 | = | x1 |
// - - - - - - - - - - -
case 2: //QPSK
// first layer symbol n -> x0
((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// second layer symbol n -> x1
((int16_t*)&tmp_sample2)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
//No precoding
//Map x0 to the first antenna
((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]));
((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]));
//Map x1 to the second antenna
((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]));
((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]));
break;
case 4: //16QAM
//Antenna 0: first layer symbol n -> x0
qam16_table_offset_re = 0;
qam16_table_offset_im = 0;
if (x0[*jj] == 1)
qam16_table_offset_re+=2;
*jj=*jj+1;
if (x0[*jj] == 1)
qam16_table_offset_im+=2;
*jj=*jj+1;
if (x0[*jj] == 1)
qam16_table_offset_re+=1;
*jj=*jj+1;
if (x0[*jj] == 1)
qam16_table_offset_im+=1;
*jj=*jj+1;
((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam16_table_offset_re]);
((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]);
// Antenna 1: second layer symbol n -> x1
qam16_table_offset_re = 0;
qam16_table_offset_im = 0;
if (x0[*jj] == 1)
qam16_table_offset_re+=2;
*jj=*jj+1;
if (x0[*jj] == 1)
qam16_table_offset_im+=2;
*jj=*jj+1;
if (x0[*jj] == 1)
qam16_table_offset_re+=1;
*jj=*jj+1;
if (x0[*jj] == 1)
qam16_table_offset_im+=1;
*jj=*jj+1;
((int16_t *)&txdataF[1][tti_offset])[0]+=(qam_table_s0[qam16_table_offset_re]);
((int16_t *)&txdataF[1][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]);
break;
case 6: // 64-QAM
// Antenna 0
qam64_table_offset_re = 0;
qam64_table_offset_im = 0;
if (x0[*jj] == 1)
qam64_table_offset_re+=4;
*jj=*jj+1;
if (x0[*jj] == 1)
qam64_table_offset_im+=4;
*jj=*jj+1;
if (x0[*jj] == 1)
qam64_table_offset_re+=2;
*jj=*jj+1;
if (x0[*jj] == 1)
qam64_table_offset_im+=2;
*jj=*jj+1;
if (x0[*jj] == 1)
qam64_table_offset_re+=1;
*jj=*jj+1;
if (x0[*jj] == 1)
qam64_table_offset_im+=1;
*jj=*jj+1;
((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]);
// Antenna 1 => x1
qam64_table_offset_re = 0;
qam64_table_offset_im = 0;
if (x0[*jj] == 1)
qam64_table_offset_re+=4;
*jj=*jj+1;
if (x0[*jj] == 1)
qam64_table_offset_im+=4;
*jj=*jj+1;
if (x0[*jj] == 1)
qam64_table_offset_re+=2;
*jj=*jj+1;
if (x0[*jj] == 1)
qam64_table_offset_im+=2;
*jj=*jj+1;
if (x0[*jj] == 1)
qam64_table_offset_re+=1;
*jj=*jj+1;
if (x0[*jj] == 1)
qam64_table_offset_im+=1;
*jj=*jj+1;
((int16_t *)&txdataF[1][tti_offset])[0]+=(qam_table_s0[qam64_table_offset_re]);
((int16_t *)&txdataF[1][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]);
break;
}
}
else if (mimo_mode == LARGE_CDD) {
*re_allocated = *re_allocated + 1;
......@@ -1556,7 +1678,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
}
} else if (mimo_mode >= TM8) { //TM8,TM9,TM10
} else if ((mimo_mode >= TM8) && (mimo_mode < TM9_10)) { //TM8,TM9,TM10
//uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode)
if (is_not_UEspecRS(lprime,re,frame_parms->nushift,frame_parms->Ncp,8)) {
......@@ -1650,7 +1772,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
}
}
} else if (mimo_mode>=TM9_10) {
} else if (mimo_mode==TM9_10) {
printf("allocate_REs_in_RB() [dlsch.c] : ERROR, unknown mimo_mode %d\n",mimo_mode);
return(-1);
}
......
......@@ -712,8 +712,15 @@ int dump_eNB_stats(PHY_VARS_eNB *eNB, char* buffer, int length)
len += sprintf(&buffer[len],"////////////////////////******************/////////////////////////////\n");
for (i=0; i<8; i++){
len+= sprintf(&buffer[len],"DL TM %d, DL Nl %d, rb %d, TBS %d, \n",
eNB->dlsch[(uint8_t)UE_id][0]->harq_processes[i]->mimo_mode==15?4 : 2,
eNB->dlsch[(uint8_t)UE_id][0]->harq_processes[i]->Nl,
eNB->dlsch[(uint8_t)UE_id][0]->harq_processes[i]->nb_rb,
eNB->dlsch[(uint8_t)UE_id][0]->harq_processes[i]->TBS);
}
len += sprintf(&buffer[len],"Timing advance %d samples (%d 16Ts), update %d ",
eNB->UE_stats[UE_id].UE_timing_offset,
......
......@@ -615,7 +615,8 @@ typedef enum {
TM7=12,
TM8=13,
TM9_10=14,
////sfn: test TM4
/*: Khodr Saaifan (Fraunhofer IIS):
*Test TM4 2 layers*/
TM4_NO_PRECODING=15
} MIMO_mode_t;
......
......@@ -21,7 +21,7 @@
#define FHG_TM4_LOG_CQI
//#define FHG_LOG
#define FHG_LOG_TM4
......@@ -29,6 +29,13 @@
extern FILE *debug_sudas_LOG_PHY;
extern FILE *debug_sudas_LOG_MAC;
#ifdef FHG_LOG_TM4
#define sudas_LOG_TM(c,...) fprintf(c,__VA_ARGS__)
#else
#define sudas_LOG_TM(c,...)
#endif
#ifdef FHG_LOG
#define sudas_LOG_PHY(c,...) fprintf(c,__VA_ARGS__)
......
......@@ -543,9 +543,9 @@ schedule_ue_spec(
eNB_UE_stats->DL_cqi[0],
format2A);
case 4:
aggregation = get_aggregation(get_bw_index(module_idP,CC_id),
aggregation = 3;/*get_aggregation(get_bw_index(module_idP,CC_id),
eNB_UE_stats->DL_cqi[0],
format2);
format2);*/
break;
default:
LOG_W(MAC,"Unsupported transmission mode %d\n", mac_xface->get_transmission_mode(module_idP,CC_id,rnti));
......@@ -852,8 +852,8 @@ fflush(debug_sudas_LOG_MAC);
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1;
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=eNB_UE_stats->dlsch_mcs1;
} else {
LOG_E(MAC,"[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n",
module_idP, frameP, CC_id, UE_id);
LOG_E(MAC,"[eNB %d] Frame %d subframeP %d CC_id %d : don't schedule UE %d, its retransmission takes nb_rb %d more resources than we have nb_available_rb %d\n",
module_idP, frameP, subframeP,CC_id, UE_id,nb_rb,nb_available_rb);
}
} else { /* This is a potentially new SDU opportunity */
......@@ -1059,7 +1059,7 @@ fflush(debug_sudas_LOG_MAC);
nb_rb=min_rb_unit[CC_id];
}
char N_layer=1;
int N_layer=1;
switch(mac_xface->get_transmission_mode(module_idP,CC_id,rnti)){
case 1:
case 2:
......@@ -1067,7 +1067,7 @@ fflush(debug_sudas_LOG_MAC);
N_layer=1;
break;
case 4:
N_layer=1;
N_layer=2;
break;
default:
N_layer=1;
......@@ -1075,22 +1075,22 @@ fflush(debug_sudas_LOG_MAC);
TBS = mac_xface->get_TBS_DL(mcs,nb_rb);
TBS = mac_xface->get_TBS_DL(mcs,N_layer*nb_rb);
while (TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) {
nb_rb += min_rb_unit[CC_id]; //
if (nb_rb>nb_available_rb) { // if we've gone beyond the maximum number of RBs
// (can happen if N_RB_DL is odd)
TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_available_rb);
TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,N_layer*nb_available_rb);
nb_rb = nb_available_rb;
break;
}
TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rb);
TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,N_layer*nb_rb);
}
nb_rb/=N_layer;
if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
for(j=0; j<frame_parms[CC_id]->N_RBG; j++) { // for indicating the rballoc for each sub-band
UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j];
......@@ -1411,7 +1411,7 @@ fflush(debug_sudas_LOG_MAC);
((DCI2A_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
((DCI2A_5MHz_2A_TDD_t*)DLSCH_dci)->rv1 = 0;
((DCI2A_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
((DCI2A_5MHz_2A_TDD_t*)DLSCH_dci)->TPC = tpc;
((DCI2A_5MHz_2A_TDD_t*)DLSCH_dci)->TPC = tpc;
// deactivate TB2
((DCI2A_5MHz_2A_TDD_t*)DLSCH_dci)->mcs2 = 0;
......@@ -1525,7 +1525,7 @@ fflush(debug_sudas_LOG_MAC);
break;
case 4:
((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->tpmi = 0;//ALAMOUTI
((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->tpmi = 7;//0: ALAMOUTI/7: test TM4_NO_precoding
((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->mcs1 = mcs;
((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->ndi1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
......@@ -2023,7 +2023,7 @@ fill_DLSCH_dci(
case 4:
// sfnDCI format 2_2A
/* sfn: DCI format 2*/
((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->rah = 0;
......@@ -2031,7 +2031,7 @@ fill_DLSCH_dci(
DLSCH_dci,
rnti,
sizeof(DCI2_5MHz_2A_FDD_t),
get_aggregation(get_bw_index(module_idP,CC_id),eNB_UE_stats->DL_cqi[0],format2),
3,//get_aggregation(get_bw_index(module_idP,CC_id),eNB_UE_stats->DL_cqi[0],format2)
sizeof_DCI2_5MHz_2A_FDD_t,
format2,
0);
......
......@@ -185,6 +185,9 @@ void assign_rbs_required (module_id_t Mod_id,
// UE_TEMPLATE *UE_template;
LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
//sfn for TM4 testing
eNB_MAC_INST *eNB = &eNB_mac_inst[Mod_id];
// clear rb allocations across all CC_ids
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
if (UE_list->active[UE_id] != TRUE) continue;
......@@ -258,7 +261,7 @@ void assign_rbs_required (module_id_t Mod_id,
N_layer=1;
break;
case 4:
N_layer=1;
N_layer=2;
break;
default:
N_layer=1;
......@@ -270,7 +273,7 @@ void assign_rbs_required (module_id_t Mod_id,
nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id];
}
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,N_layer*nb_rbs_required[CC_id][UE_id]);
LOG_D(MAC,"[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n",
UE_id, CC_id, UE_list->UE_template[pCCid][UE_id].dl_buffer_total,
......@@ -280,15 +283,15 @@ void assign_rbs_required (module_id_t Mod_id,
while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) {
nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id];
if (nb_rbs_required[CC_id][UE_id] > frame_parms[CC_id]->N_RB_DL) {
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,frame_parms[CC_id]->N_RB_DL);
nb_rbs_required[CC_id][UE_id] = frame_parms[CC_id]->N_RB_DL;
if (nb_rbs_required[CC_id][UE_id] > eNB->eNB_stats[CC_id].available_prbs) {//sfn: replace frame_parms[CC_id]->N_RB_DL
nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id]*(eNB->eNB_stats[CC_id].available_prbs/min_rb_unit[CC_id]);
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,N_layer*nb_rbs_required[CC_id][UE_id]);
break;
}
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,N_layer*nb_rbs_required[CC_id][UE_id]);
} // end of while
nb_rbs_required[CC_id][UE_id]/=N_layer;
LOG_D(MAC,"[eNB %d] Frame %d: UE %d on CC %d: RB unit %d, nb_required RB %d (TBS %d, mcs %d)\n",
Mod_id, frameP,UE_id, CC_id, min_rb_unit[CC_id], nb_rbs_required[CC_id][UE_id], TBS, eNB_UE_stats[CC_id]->dlsch_mcs1);
......@@ -560,7 +563,8 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
int transmission_mode = 0;
UE_sched_ctrl *ue_sched_ctl;
// int rrc_status = RRC_IDLE;
//sfn
eNB_MAC_INST *eNB = &eNB_mac_inst[Mod_id];
LTE_eNB_UE_stats *eNB_UE_stats[MAX_NUM_CCs];
#ifdef TM5
int harq_pid1=0,harq_pid2=0;
......@@ -608,26 +612,29 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
round = ue_sched_ctl->round[CC_id];
rnti = UE_RNTI(Mod_id,i);
eNB_UE_stats[CC_id] = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti);
/*
PHY_vars_eNB_g[Mod_id][CC_id]->UE_stats[UE_id].rank = eNB_UE_stats[CC_id]->rank;
if (round==0)
{
//set the mode of the tranmission mode
/* SFN: Enable Format2 scheduling
* select TM according to rank
*
*/
if (eNB_UE_stats[CC_id]->rank)
{
PHY_vars_eNB_g[Mod_id][CC_id]->transmission_mode[UE_id]=4;
UE_list->UE_template[CC_id][UE_id].Trans_Mode[harq_pid][CC_id]=4;
}else
PHY_vars_eNB_g[Mod_id][CC_id]->transmission_mode[UE_id]=4;
UE_list->UE_template[CC_id][UE_id].Trans_Mode[harq_pid][CC_id]=4;
}
else
{
PHY_vars_eNB_g[Mod_id][CC_id]->transmission_mode[UE_id]=2;
UE_list->UE_template[CC_id][UE_id].Trans_Mode[harq_pid][CC_id]=2;
}
}else{
}
else//Retransmission
{
PHY_vars_eNB_g[Mod_id][CC_id]->transmission_mode[UE_id]=UE_list->UE_template[CC_id][UE_id].Trans_Mode[harq_pid][CC_id];;
}
*/
}
}
......@@ -699,8 +706,9 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id,
if (total_ue_count == 0) {
average_rbs_per_user[CC_id] = 0;
} else if( (min_rb_unit[CC_id] * total_ue_count) <= (frame_parms[CC_id]->N_RB_DL) ) {
average_rbs_per_user[CC_id] = (uint16_t) floor(frame_parms[CC_id]->N_RB_DL/total_ue_count);
} else if(total_ue_count <= (eNB->eNB_stats[CC_id].available_prbs/min_rb_unit[CC_id]) ) {
average_rbs_per_user[CC_id] = min_rb_unit[CC_id]*((uint16_t)floor(eNB->eNB_stats[CC_id].available_prbs/total_ue_count)/min_rb_unit[CC_id]);//sfn: replace frame_parms[CC_id]->N_RB_DL
} else {
average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
}
......
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