Files
openairinterface5g/openair1/PHY/CODING/TESTBENCH/ltetest.c
T
2015-01-22 07:24:06 +00:00

490 lines
13 KiB
C

/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "PHY/defs.h"
#include "PHY/vars.h"
#include "MAC_INTERFACE/vars.h"
#include "PHY/CODING/defs.h"
#include "SCHED/defs.h"
#include "SCHED/vars.h"
#include "LAYER2/MAC/vars.h"
#include "OCG_vars.h"
#include "UTIL/LOG/log.h"
//#include "PHY/CODING/lte_interleaver.h"
//#include "PHY/CODING/lte_interleaver_inline.h"
#include "SIMULATION/TOOLS/defs.h"
//#include "decoder.h"
#define INPUT_LENGTH 5
#define F1 3
#define F2 10
#include "PHY/sse_intrin.h"
#define sgn(a) (((a)<0) ? 0 : 1)
//#define DEBUG_CODER 1
int current_dlsch_cqi;
PHY_VARS_eNB *PHY_vars_eNB;
PHY_VARS_UE *PHY_vars_UE;
DCI1_5MHz_TDD_t DLSCH_alloc_pdu;
channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX];
void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmission_mode,unsigned char extended_prefix_flag,uint16_t Nid_cell,uint8_t tdd_config) {
unsigned int ind;
LTE_DL_FRAME_PARMS *lte_frame_parms;
printf("Start lte_param_init (Nid_cell %d, extended_prefix %d, transmission_mode %d, N_tx %d, N_rx %d)\n",
Nid_cell, extended_prefix_flag,transmission_mode,N_tx,N_rx);
PHY_vars_eNB = malloc(sizeof(PHY_VARS_eNB));
PHY_vars_UE = malloc(sizeof(PHY_VARS_UE));
mac_xface = malloc(sizeof(MAC_xface));
randominit(0);
set_taus_seed(0);
lte_frame_parms = &(PHY_vars_eNB->lte_frame_parms);
lte_frame_parms->N_RB_DL = 25; //50 for 10MHz and 25 for 5 MHz
lte_frame_parms->N_RB_UL = 25;
lte_frame_parms->Ncp = extended_prefix_flag;
lte_frame_parms->Nid_cell = Nid_cell;
lte_frame_parms->nushift = 0;
lte_frame_parms->nb_antennas_tx = N_tx;
lte_frame_parms->nb_antennas_rx = N_rx;
lte_frame_parms->tdd_config = tdd_config;
// lte_frame_parms->Csrs = 2;
// lte_frame_parms->Bsrs = 0;
// lte_frame_parms->kTC = 0;
// lte_frame_parms->n_RRC = 0;
lte_frame_parms->mode1_flag = (transmission_mode == 1)? 1 : 0;
init_frame_parms(lte_frame_parms,1);
//copy_lte_parms_to_phy_framing(lte_frame_parms, &(PHY_config->PHY_framing));
phy_init_top(lte_frame_parms); //allocation
lte_frame_parms->twiddle_fft = twiddle_fft;
lte_frame_parms->twiddle_ifft = twiddle_ifft;
lte_frame_parms->rev = rev;
memcpy(&PHY_vars_UE->lte_frame_parms,lte_frame_parms,sizeof(LTE_DL_FRAME_PARMS));
phy_init_lte_top(lte_frame_parms);
phy_init_lte_ue(PHY_vars_UE,1,0);
phy_init_lte_eNB(PHY_vars_eNB,0,0,0);
printf("Done lte_param_init\n");
}
/*
void print_shorts(char *s,__m128i *x) {
short *tempb = (short *)x;
printf("%s : %d,%d,%d,%d,%d,%d,%d,%d\n",s,
tempb[0],tempb[1],tempb[2],tempb[3],tempb[4],tempb[5],tempb[6],tempb[7]
);
}
*/
// 4-bit quantizer
char quantize4bit(double D,double x) {
double qxd;
qxd = floor(x/D);
// printf("x=%f,qxd=%f\n",x,qxd);
if (qxd <= -8)
qxd = -8;
else if (qxd > 7)
qxd = 7;
return((char)qxd);
}
char quantize(double D,double x,unsigned char B) {
double qxd;
char maxlev;
qxd = floor(x/D);
// printf("x=%f,qxd=%f\n",x,qxd);
maxlev = 1<<(B-1);
if (qxd <= -maxlev)
qxd = -maxlev;
else if (qxd >= maxlev)
qxd = maxlev-1;
return((char)qxd);
}
#define MAX_BLOCK_LENGTH 6000
int test_logmap8(LTE_eNB_DLSCH_t *dlsch_eNB,
LTE_UE_DLSCH_t *dlsch_ue,
unsigned int coded_bits,
unsigned char NB_RB,
double sigma,
unsigned char qbits,
unsigned int block_length,
unsigned int ntrials,
unsigned int *errors,
unsigned int *trials,
unsigned int *uerrors,
unsigned int *crc_misses,
unsigned int *iterations,
unsigned int num_pdcch_symbols,
unsigned int subframe) {
unsigned char test_input[block_length+1];
short *channel_output;
unsigned char decoded_output[block_length];
unsigned int i,trial=0;
unsigned int crc=0;
unsigned char ret;
unsigned char uerr;
unsigned char crc_type;
channel_output = (short *)malloc(coded_bits*sizeof(short));
*iterations=0;
*errors=0;
*crc_misses=0;
*uerrors=0;
// printf("dlsch_eNB->TBS= %d, block_length %d\n",dlsch_eNB->harq_processes[0]->TBS,block_length);
while (trial++ < ntrials) {
// printf("encoding\n");
// test_input[0] = 0x80;
for (i=0;i<block_length;i++) {
test_input[i] = i&0xff;//(unsigned char)(taus()&0xff);
}
dlsch_encoding(test_input,
&PHY_vars_eNB->lte_frame_parms,
num_pdcch_symbols,
PHY_vars_eNB->dlsch_eNB[0][0],
0,
subframe,
&PHY_vars_eNB->dlsch_rate_matching_stats,
&PHY_vars_eNB->dlsch_turbo_encoding_stats,
&PHY_vars_eNB->dlsch_interleaving_stats);
uerr=0;
for (i = 0; i < coded_bits; i++){
#ifdef DEBUG_CODER
if ((i&0xf)==0)
printf("\ne %d..%d: ",i,i+15);
printf("%d.",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->e[i]);
#endif
channel_output[i] = (short)quantize(sigma/4.0,(2.0*PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->e[i]) - 1.0 + sigma*gaussdouble(0.0,1.0),qbits);
// printf("input %d, output %f\n",(2*PHY_vars_eNB->dlsch_eNB[0][0]->e[i]) - 1,
// (2.0*PHY_vars_eNB->dlsch_eNB[0][0]->e[i]) - 1.0 + sigma*gaussdouble(0.0,1.0));
}
#ifdef DEBUG_CODER
printf("\n");
exit(-1);
#endif
PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->G = coded_bits;
ret = dlsch_decoding(PHY_vars_UE,
channel_output,
&PHY_vars_UE->lte_frame_parms,
PHY_vars_UE->dlsch_ue[0][0],
PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid],
subframe,
PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid,
num_pdcch_symbols,1);
/* int diffs = 0,puncts=0;
for (i=0;i<dlsch_ue->harq_processes[0]->Kplus*3;i++) {
if (dlsch_ue->harq_processes[0]->d[0][96+i] == 0) {
printf("%d punct (%d,%d)\n",i,dlsch_ue->harq_processes[0]->d[0][96+i],dlsch_eNb->harq_processes[0]->d[0][96+i]);
puncts++;
}
else if (sgn(dlsch_ue->harq_processes[0]->d[0][96+i]) != dlsch_eNb->harq_processes[0]->d[0][96+i]) {
printf("%d differs (%d,%d)\n",i,dlsch_ue->harq_processes[0]->d[0][96+i],dlsch_eNb->harq_processes[0]->d[0][96+i]);
diffs++;
}
else
printf("%d same (%d,%d)\n",i,dlsch_ue->harq_processes[0]->d[0][96+i],dlsch_eNb->harq_processes[0]->d[0][96+i]);
}
printf("diffs %d puncts %d(%d,%d,%d,%d,%d)\n",diffs,puncts,dlsch_ue->harq_processes[0]->F,coded_bits,3*(block_length<<3),3*dlsch_ue->harq_processes[0]->Kplus,3*dlsch_ue->harq_processes[0]->F+3*(block_length<<3)-coded_bits);
printf("ret %d (max %d)\n",ret,dlsch_ue->max_turbo_iterations);
printf("trial %d : i %d/%d : Input %x, Output %x (%x, F %d)\n",trial,0,block_length,test_input[0],
dlsch_ue->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->b[0],
dlsch_ue->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->c[0][0],
(dlsch_ue->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->F>>3));
*/
if (ret < dlsch_ue->max_turbo_iterations+1) {
*iterations = (*iterations) + ret;
// if (ret>1)
// printf("ret %d\n",ret);
}
else
*iterations = (*iterations) + (ret-1);
if (uerr==1)
*uerrors = (*uerrors) + 1;
for (i=0;i<block_length;i++) {
if (dlsch_ue->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->c[0][i] != test_input[i]) {
/*
printf("i %d/%d : Input %x, Output %x (%x, F %d)\n",i,block_length,test_input[i],
dlsch_ue->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->b[i],
dlsch_ue->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->c[0][i],
(dlsch_ue->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->F>>3));
*/
*errors = (*errors) + 1;
// printf("*%d, ret %d\n",*errors,ret);
if (ret < dlsch_ue->max_turbo_iterations+1)
*crc_misses = (*crc_misses)+1;
break;
}
}
if (ret == dlsch_ue->max_turbo_iterations+1) {
// exit(-1);
}
/*
else {
for (i=0;i<block_length;i++) {
if (dlsch_ue->harq_processes[0]->b[i] != test_input[i]) {
printf("i %d/%d : Input %x, Output %x (%x, F %d)\n",i,block_length,test_input[i],
dlsch_ue->harq_processes[0]->b[i],
dlsch_ue->harq_processes[0]->c[0][i],
(dlsch_ue->harq_processes[0]->F>>3));
}
}
}*/
if (*errors == 100) {
printf("trials %d\n",trial);
break;
}
}
*trials = trial;
// printf("lte: trials %d, errors %d\n",trial,*errors);
return(0);
}
#define NTRIALS 10000
#define DLSCH_RB_ALLOC 0x1fff//0x1fbf // igore DC component,RB13
int main(int argc, char *argv[]) {
int ret,ret2;
unsigned int errors,uerrors,errors2,crc_misses,iterations,trials,trials2,block_length,errors3,trials3;
double SNR,sigma,rate=.5;
unsigned char qbits,mcs;
char done0=0;
char done1=1;
char done2=1;
unsigned int coded_bits;
unsigned char NB_RB=25;
int num_pdcch_symbols = 1;
int subframe = 6;
randominit(0);
logInit();
lte_param_init(1,1,1,0,0,3);
PHY_vars_eNB->dlsch_eNB[0][0] = new_eNB_dlsch(1,8,NB_RB,0);
PHY_vars_UE->dlsch_ue[0][0] = new_ue_dlsch(1,8,4,NB_RB,0);
PHY_vars_eNB->dlsch_eNB[0][1] = new_eNB_dlsch(1,8,NB_RB,0);
PHY_vars_UE->dlsch_ue[0][1] = new_ue_dlsch(1,8,4,NB_RB,0);
if (argc>1)
mcs = atoi(argv[1]);
else
mcs = 0;
printf("NB_RB %d\n",NB_RB);
DLSCH_alloc_pdu.rah = 0;
DLSCH_alloc_pdu.rballoc = DLSCH_RB_ALLOC;
DLSCH_alloc_pdu.TPC = 0;
DLSCH_alloc_pdu.dai = 0;
DLSCH_alloc_pdu.harq_pid = 0;
//DLSCH_alloc_pdu2.tb_swap = 0;
DLSCH_alloc_pdu.mcs = mcs;
DLSCH_alloc_pdu.ndi = 1;
DLSCH_alloc_pdu.rv = 0;
if (argc>2)
qbits = atoi(argv[2]);
else
qbits = 4;
printf("Quantization bits %d\n",qbits);
generate_eNB_dlsch_params_from_dci(subframe,
&DLSCH_alloc_pdu,
0x1234,
format1,
PHY_vars_eNB->dlsch_eNB[0],
&PHY_vars_eNB->lte_frame_parms,
PHY_vars_eNB->pdsch_config_dedicated,
SI_RNTI,
0,
P_RNTI,
0); //change this later
generate_ue_dlsch_params_from_dci(subframe,
&DLSCH_alloc_pdu,
C_RNTI,
format1,
PHY_vars_UE->dlsch_ue[0],
&PHY_vars_UE->lte_frame_parms,
PHY_vars_UE->pdsch_config_dedicated,
SI_RNTI,
0,
P_RNTI);
coded_bits = get_G(&PHY_vars_eNB->lte_frame_parms,
PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->nb_rb,
PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rb_alloc,
get_Qm(mcs),
1,
num_pdcch_symbols,
0,
subframe);
printf("Coded_bits (G) = %d\n",coded_bits);
block_length = dlsch_tbs25[get_I_TBS(mcs)][NB_RB-1]>>3;
printf("Block_length = %d bytes (%d bits, rate %f), mcs %d, I_TBS %d, F %d, NB_RB %d\n",block_length,
dlsch_tbs25[get_I_TBS(mcs)][NB_RB-1],(double)dlsch_tbs25[get_I_TBS(mcs)][NB_RB-1]/coded_bits,
mcs,get_I_TBS(mcs),PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->F,NB_RB);
for (SNR=-5;SNR<15;SNR+=.1) {
sigma = pow(10.0,-.05*SNR);
printf("\n\nSNR %f dB => sigma %f\n",SNR,sigma);
errors=0;
crc_misses=0;
errors2=0;
errors3=0;
iterations=0;
if (done0 == 0) {
ret = test_logmap8(PHY_vars_eNB->dlsch_eNB[0][0],
PHY_vars_UE->dlsch_ue[0][0],
coded_bits,
NB_RB,
sigma, // noise standard deviation
qbits,
block_length, // block length bytes
NTRIALS,
&errors,
&trials,
&uerrors,
&crc_misses,
&iterations,
num_pdcch_symbols,
subframe);
if (ret>=0)
printf("%f,%f,%f,%f\n",SNR,(double)errors/trials,(double)crc_misses/trials,(double)iterations/trials);
if (((double)errors/trials) < 1e-2)
done0=1;
}
if ((done0==1) && (done1==1) && (done2==1)) {
printf("done\n");
break;
}
}
return(0);
}