Commit b9ddfe65 authored by Florian Kaltenberger's avatar Florian Kaltenberger

moving Matlab to extras


git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7223 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 7fe41b08
include $(OPENAIR_HOME)/common/utils/Makefile.inc
#include $(OPENAIR1_DIR)/SIMULATION/LTE_PHY/Makefile
COMMON_UTILS_DIR = $(OPENAIR_HOME)/common/utils
TOP_DIR = $(OPENAIR1_DIR)
OPENAIR1_TOP = $(OPENAIR1_DIR)
OPENAIR2_TOP = $(OPENAIR2_DIR)
OPENAIR3 = $(OPENAIR3_DIR)
CFLAGS += -DMAX_NUM_CCs=1 -Wall -DPHYSIM -DNODE_RG -DUSER_MODE -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TXRX=2 -DNB_ANTENNAS_TX=2 -DPHY_CONTEXT=1 -DMALLOC_CHECK_=1 -DENABLE_VCD_FIFO
CFLAGS += -DOPENAIR_LTE -DNO_RRM -DOPENAIR1 #-DPHY_ABSTRACTION #-DOPENAIR2
CFLAGS += -I/usr/include/X11 -I/usr/X11R6/include
include $(COMMON_UTILS_DIR)/Makefile.inc
include $(TOP_DIR)/PHY/Makefile.inc
include $(TOP_DIR)/SCHED/Makefile.inc
SCHED_OBJS = $(TOP_DIR)/SCHED/phy_procedures_lte_common.o #$(TOP_DIR)/SCHED/phy_procedures_lte_eNb.o $(TOP_DIR)/SCHED/phy_procedures_lte_ue.o
include $(TOP_DIR)/SIMULATION/Makefile.inc
include $(OPENAIR2_DIR)/LAYER2/Makefile.inc
include $(OPENAIR2_DIR)/UTIL/Makefile.inc
include $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc
ASN1_MSG_INC = $(OPENAIR2_DIR)/RRC/LITE/MESSAGES
CFLAGS += $(L2_incl) -I$(ASN1_MSG_INC) -I$(TOP_DIR) -I$(OPENAIR2_DIR) -I$(OPENAIR3) $(UTIL_incl) $(UTILS_incl)
CFLAGS += -DMEX -fPIC
CFLAGS += -I/opt/MATLAB/R2014a/extern/include/
# Set mex extension, can be determined with mexext function in Matlab
MEXEXT = mexglx
# Just compile all the PHY objects
OBJ = $(PHY_OBJS) $(TOP_DIR)/SIMULATION/TOOLS/taus.o $(LOG_DIR)/log.o $(LOG_DIR)/vcd_signal_dumper.o
# List of all mex-files to compile
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/get_tbs.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_encoding.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_decoding.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_decoding_init.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_channel_level_prec.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_channel_compensation_prec.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_dual_stream_correlation.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_detection_mrc.$(MEXEXT)
MEX_FILES += ./PHY/LTE_TRANSPORT/mexfiles/dlsch_mu_mimo_llr.$(MEXEXT)
MEX_FILES += ./PHY/TOOLS/mexfiles/log2_approx.$(MEXEXT)
MEX_FILES += ./SIMULATION/TOOLS/mexfiles/taus.$(MEXEXT)
MEX_FILES += ./SIMULATION/TOOLS/mexfiles/set_taus_seed.$(MEXEXT)
# ===========================================================================================
# Commands to compile the static and shared lib for mex-files
# Libpath
LIBDIR := ./lib
LIBNAME := oai
sharedlib : $(OBJ)
@$(CC) -shared -Wl,-soname,lib$(LIBNAME).so.1 -o $(LIBDIR)/lib$(LIBNAME).so.1.0.1 $(OBJ) -lc
staticlib : $(OBJ)
@ar ruv $(LIBDIR)/lib$(LIBNAME).a $(OBJ)
libs : $(OBJ)
@$(CC) -shared -Wl,-soname,lib$(LIBNAME).so.1 -o $(LIBDIR)/lib$(LIBNAME).so.1.0.1 $(OBJ) -lc
@ar ruv $(LIBDIR)/lib$(LIBNAME).a $(OBJ)
$(MEX_FILES) : %.$(MEXEXT) : %.c
@echo
@echo Compiling $< ...
@mex CFLAGS="$(CFLAGS)" -l$(LIBNAME) -L$(LIBDIR) -output $@ $<
mex : $(MEX_FILES)
cleanlibs :
rm -f $(LIBDIR)/lib$(LIBNAME).*
cleanmex :
rm -f $(MEX_FILES)
clean:
rm -f $(OBJ)
cleanall: clean cleanlibs cleanmex
show :
echo $(ASN1_MSG_INC)
#include "../../../defs.h"
/*==============================================================================
* dlsch_channel_compensation_prec.c
*
* Returns the matched filter channel and the scaled channel magnitude.
*
* example: [ymf heff hmag hmagb] = dlsch_channel_compensation_prec(y,H,pmi,struct1,struct2,slot)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
// #define DEBUG_CHANNEL_COMP
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
int *H,*y,*dl_ch_estimates_ext[NB_ANTENNAS_RX*NB_ANTENNAS_TX],*rxdataF_ext[NB_ANTENNAS_RX*NB_ANTENNAS_TX],*ymf, *hmag, *hmagb,*dl_ch_mag[NB_ANTENNAS_RX*NB_ANTENNAS_TX],
*dl_ch_magb[NB_ANTENNAS_RX*NB_ANTENNAS_TX];
int *rxdataF_comp[NB_ANTENNAS_RX*NB_ANTENNAS_TX], *ymf_out, *hmag_out, *hmagb_out, *heff_out, *heff;
unsigned int nb_re_per_symbol, nb_re, nb_re_per_frame;
unsigned char *pmi_ext, mod_order, output_shift,dl_power_off;
unsigned char symbol;
int eNB_id = 0,i; // dummy
mxArray *tmp;
LTE_DL_FRAME_PARMS *frame_parms;
PHY_MEASUREMENTS *phy_measurements;
/* Check proper input and output. */
if(nrhs!=6)
mexErrMsgTxt("5 inputs required.");
else if(nlhs > 4)
mexErrMsgTxt("Too many output arguments.");
else if(!mxIsStruct(prhs[3]))
mexErrMsgTxt("Fourth input must be a structure.");
else if(!mxIsStruct(prhs[4]))
mexErrMsgTxt("Fifth input must be a structure.");
if(!mxIsInt16(prhs[0]))
mexErrMsgTxt("First argument must belong to Int16 class.");
if(!mxIsInt16(prhs[1]))
mexErrMsgTxt("Second argument must belong to Int16 class.");
if(!mxIsUint8(prhs[2]))
mexErrMsgTxt("Third argument must belong to Uint8 class.");
/* Allocate input */
y = (int*) mxGetData(prhs[0]);
H = (int*) mxGetData(prhs[1]);
pmi_ext = (unsigned char*) mxGetData(prhs[2]);
symbol = (unsigned char) mxGetScalar(prhs[5]);
tmp = mxGetField(prhs[4],0,"mod_order");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'mod_order' in input argument 5.");
} else {
mod_order = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"log2_maxh");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'log2_maxh' in input argument 4.");
} else {
output_shift = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"dl_power_offset");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'dl_power_offset' in input argument 4.");
} else {
dl_power_off = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"nb_re");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_re' in input argument 4.");
} else {
nb_re = (unsigned int) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"nb_re_per_frame");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_re_per_frame' in input argument 4.");
} else {
nb_re_per_frame = (unsigned int) mxGetScalar(tmp);
}
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = calloc(1,sizeof(LTE_DL_FRAME_PARMS));
tmp = mxGetField(prhs[3],0,"nb_rb");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 4.");
} else {
frame_parms->N_RB_DL = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"nb_antennas_rx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_rx' in input argument 4.");
} else {
frame_parms->nb_antennas_rx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"nb_antennas_tx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_tx' in input argument 4.");
} else {
frame_parms->nb_antennas_tx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"Ncp");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Ncp' in input argument 4.");
} else {
frame_parms->Ncp = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[3],0,"ofdm_symbol_size");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'ofdm_symbol_size' in input argument 4.");
} else {
frame_parms->ofdm_symbol_size = (unsigned short) mxGetScalar(tmp);
}
// Create PHY_MEASUREMENTS structure and assign required params
phy_measurements = calloc(1,sizeof(PHY_MEASUREMENTS));
phy_measurements->n0_power[0] = 1; // dummy values
phy_measurements->n0_power[1] = 1;
phy_measurements->n0_power_tot = 1;
// Adapt the channel estimates and receive signal
nb_re_per_symbol = frame_parms->N_RB_DL*12;
// Assign pointers
rxdataF_ext[0] = y;
rxdataF_ext[1] = &y[nb_re_per_frame];
rxdataF_ext[2] = &y[2*nb_re_per_frame];
rxdataF_ext[3] = &y[3*nb_re_per_frame];
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
ymf_out = (int*) mxGetPr(plhs[0]);
plhs[1] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
heff_out = (int*) mxGetPr(plhs[1]);
plhs[2] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
hmag_out = (int*) mxGetPr(plhs[2]);
plhs[3] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
hmagb_out = (int*) mxGetPr(plhs[3]);
ymf = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
heff = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
hmag = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
hmagb = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
// copy input since it gets modified in function "dlsch_channel_compensation_prec"
memcpy(heff,H,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame)<<2);
rxdataF_comp[0] = ymf;
rxdataF_comp[1] = &ymf[nb_re_per_frame];
rxdataF_comp[2] = &ymf[2*nb_re_per_frame];
rxdataF_comp[3] = &ymf[3*nb_re_per_frame];
dl_ch_estimates_ext[0] = heff;
dl_ch_estimates_ext[1] = &heff[nb_re_per_frame];
dl_ch_estimates_ext[2] = &heff[2*nb_re_per_frame];
dl_ch_estimates_ext[3] = &heff[3*nb_re_per_frame];
dl_ch_mag[0] = hmag;
dl_ch_mag[1] = &hmag[nb_re_per_frame];
dl_ch_mag[2] = &hmag[2*nb_re_per_frame];
dl_ch_mag[3] = &hmag[3*nb_re_per_frame];
dl_ch_magb[0] = hmagb;
dl_ch_magb[1] = &hmagb[nb_re_per_frame];
dl_ch_magb[2] = &hmagb[2*nb_re_per_frame];
dl_ch_magb[3] = &hmagb[3*nb_re_per_frame];
#ifdef DEBUG_CHANNEL_COMP
mexPrintf("symbol = %d\n", symbol);
mexPrintf("nb_re_per_symbol = %d\n", nb_re_per_symbol);
mexPrintf("nb_re_per_frame = %d\n", nb_re_per_frame);
for(i=0; i<25; i++)
mexPrintf("pmi_ext = %d\n", pmi_ext[i]);
#endif
/* Algo */
dlsch_channel_compensation_prec(rxdataF_ext,
dl_ch_estimates_ext,
dl_ch_mag,
dl_ch_magb,
rxdataF_comp,
pmi_ext,
frame_parms,
phy_measurements,
eNB_id,
symbol,
mod_order,
frame_parms->N_RB_DL,
output_shift,
dl_power_off);
// memcpy copies bytes!
memcpy(ymf_out,&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&ymf_out[nb_re_per_symbol],&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&ymf_out[2*nb_re_per_symbol],&rxdataF_comp[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&ymf_out[3*nb_re_per_symbol],&rxdataF_comp[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(hmag_out,&dl_ch_mag[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&hmag_out[nb_re_per_symbol],&dl_ch_mag[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&hmag_out[2*nb_re_per_symbol],&dl_ch_mag[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&hmag_out[3*nb_re_per_symbol],&dl_ch_mag[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(hmagb_out, &dl_ch_magb[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&hmagb_out[nb_re_per_symbol],&dl_ch_magb[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&hmagb_out[2*nb_re_per_symbol],&dl_ch_magb[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&hmagb_out[3*nb_re_per_symbol],&dl_ch_magb[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(heff_out,&dl_ch_estimates_ext[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&heff_out[nb_re_per_symbol],&dl_ch_estimates_ext[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&heff_out[2*nb_re_per_symbol],&dl_ch_estimates_ext[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&heff_out[3*nb_re_per_symbol],&dl_ch_estimates_ext[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
/* free */
free(frame_parms);
free(phy_measurements);
mxFree(ymf);
mxFree(heff);
mxFree(hmag);
mxFree(hmagb);
}
#include "../../../defs.h"
/*==============================================================================
* dlsch_channel_level_prec.c
*
* Returns average squared channel magnitude of effective channel.
*
* example: avg = dlsch_channel_level_prec(H,pmi,simparms);
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
int *H,*dl_ch_estimates_ext[4];
unsigned int nb_re_per_frame;
unsigned char *pmi_ext;
unsigned char symbol_mod = 3;
int *avg;
mxArray *tmp;
LTE_DL_FRAME_PARMS *frame_parms;
/* Check proper input and output. */
if(nrhs!=3)
mexErrMsgTxt("Three inputs required.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
else if(!mxIsStruct(prhs[2]))
mexErrMsgTxt("Third input must be a structure.");
if(!mxIsInt16(prhs[0]))
mexErrMsgTxt("First argument must belong to Int16 class.");
if(!mxIsUint8(prhs[1]))
mexErrMsgTxt("Second argument must belong to Uint8 class.");
/* Allocate input */
H = (int*) mxGetData(prhs[0]);
pmi_ext = (unsigned char*) mxGetData(prhs[1]);
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = calloc(1,sizeof(LTE_DL_FRAME_PARMS));
tmp = mxGetField(prhs[2],0,"nb_rb");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 3.");
} else {
frame_parms->N_RB_DL = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"nb_antennas_rx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_rx' in input argument 3.");
} else {
frame_parms->nb_antennas_rx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"mode1_flag");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'mode1_flag' in input argument 3.");
} else {
frame_parms->mode1_flag = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"Ncp");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Ncp' in input argument 3.");
} else {
frame_parms->Ncp = (unsigned char) mxGetScalar(tmp);
}
// Adapt the channel estimates
tmp = mxGetField(prhs[2],0,"nb_re_per_frame");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_re_per_frame' in input argument 3.");
} else {
nb_re_per_frame = (unsigned int) mxGetScalar(tmp);
}
dl_ch_estimates_ext[0] = (int*) H;
dl_ch_estimates_ext[1] = (int*) &H[nb_re_per_frame];
dl_ch_estimates_ext[2] = (int*) &H[2*nb_re_per_frame];
dl_ch_estimates_ext[3] = (int*) &H[3*nb_re_per_frame];
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL);
avg = (int*) mxGetPr(plhs[0]);
/* Algo */
dlsch_channel_level_prec(dl_ch_estimates_ext, frame_parms, pmi_ext, avg, symbol_mod, frame_parms->N_RB_DL);
/* free */
free(frame_parms);
}
#include "../../../defs.h"
/*==============================================================================
* dlsch_encoding.c
*
* Returns the decoded bit sequence.
*
* example: e = dlsch_encoding(llrs,struct1,struct2)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
#define DEBUG_DLSCH_DECODING
void mexFunction( int mlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
short *dlsch_llr;
unsigned char mcs;
unsigned int *ret;
unsigned char mod_order;
unsigned char num_pdcch_symbols;
unsigned char harq_pid;
unsigned char subframe;
unsigned char Kmimo;
unsigned char Mdlharq;
unsigned char abstraction_flag;
LTE_UE_DLSCH_t* dlsch;
LTE_DL_FRAME_PARMS *frame_parms;
PHY_VARS_UE *phy_vars_ue;
extern int *pi2tab16[188],*pi5tab16[188],*pi4tab16[188],*pi6tab16[188];
unsigned long *ptr_td; //hack for 64bit
int *tmp[1];
/* Allocate input */
dlsch_llr = (short*) mxGetData(prhs[0]);
/* Create new dlsch */
Kmimo = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"Kmimo"));
Mdlharq = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"Mdlharq"));
abstraction_flag = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"abstraction_flag"));
mcs = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"mcs"));
#ifdef DEBUG_DLSCH_DECODING
mexPrintf("Kmimo %d\n",Kmimo);
mexPrintf("Mdlharq %d\n",Mdlharq);
mexPrintf("abstraction_flag %d\n",abstraction_flag);
mexPrintf("mcs %d\n",mcs);
#endif
/* Create new dlsch */
dlsch = new_ue_dlsch(Kmimo,Mdlharq,8,25,abstraction_flag);
// Init CRC tables
crcTableInit();
// init_td();
// copy the pointers to memory allocated in dlsch_decoding_init
ptr_td = (unsigned int*) mxGetData(mxGetField(prhs[1],0,"ptr_td"));
#ifdef DEBUG_DLSCH_DECODING
mexPrintf("ptr_td0 %p\n",ptr_td[0]);
mexPrintf("ptr_td1 %p\n",ptr_td[1]);
mexPrintf("ptr_td2 %p\n",ptr_td[2]);
mexPrintf("ptr_td3 %p\n",ptr_td[3]);
#endif
memcpy(&tmp[0], &ptr_td[0], sizeof(ptr_td[0]));
memcpy(&pi2tab16[0], tmp[0], 188*sizeof(pi2tab16[0]));
memcpy(&tmp[0], &ptr_td[1], sizeof(ptr_td[1]));
memcpy(&pi4tab16[0], tmp[0], 188*sizeof(pi4tab16[0]));
memcpy(&tmp[0], &ptr_td[2], sizeof(ptr_td[2]));
memcpy(&pi5tab16[0], tmp[0], 188*sizeof(pi5tab16[0]));
memcpy(&tmp[0], &ptr_td[3], sizeof(ptr_td[3]));
memcpy(&pi6tab16[0], tmp[0], 188*sizeof(pi6tab16[0]));
harq_pid = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"harq_pid"));
dlsch->current_harq_pid = harq_pid;
dlsch->harq_processes[harq_pid]->rvidx = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"rvidx"));
dlsch->harq_processes[harq_pid]->Nl = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"Nl"));
//dlsch->harq_processes[harq_pid]->Ndi = (unsigned char) mxGetScalar(mxGetField(prhs[2],0,"Ndi"));
dlsch->harq_processes[harq_pid]->mcs = mcs;
dlsch->harq_processes[harq_pid]->rb_alloc[0] = (unsigned int) mxGetScalar(mxGetField(prhs[1],0,"rb_alloc"));
dlsch->harq_processes[harq_pid]->nb_rb = (unsigned short) mxGetScalar(mxGetField(prhs[1],0,"nb_rb"));
dlsch->harq_processes[harq_pid]->TBS = dlsch_tbs25[get_I_TBS(mcs)][dlsch->harq_processes[harq_pid]->nb_rb-1];
num_pdcch_symbols = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"num_pdcch_symbols"));
subframe = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"subframe"));
phy_vars_ue = calloc(1,sizeof(PHY_VARS_UE));
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = calloc(1,sizeof(LTE_DL_FRAME_PARMS));
frame_parms->N_RB_DL = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"nb_rb"));
frame_parms->frame_type = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"frame_type"));
frame_parms->mode1_flag = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"mode1_flag"));
frame_parms->Ncp = (unsigned char) mxGetScalar(mxGetField(prhs[1],0,"Ncp"));
mod_order = get_Qm(dlsch->harq_processes[harq_pid]->mcs);
dlsch->harq_processes[harq_pid]->G = get_G(frame_parms,dlsch->harq_processes[harq_pid]->nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,
0,subframe);
#ifdef DEBUG_DLSCH_DECODING
mexPrintf("TBS %d\n",dlsch->harq_processes[harq_pid]->TBS);
mexPrintf("nb_rb %d\n",dlsch->harq_processes[harq_pid]->nb_rb);
mexPrintf("ncs %d\n",dlsch->harq_processes[harq_pid]->mcs);
mexPrintf("num_pdcch_symbols %d\n",num_pdcch_symbols);
mexPrintf("subframe %d\n",subframe);
mexPrintf("G %d\n",dlsch->harq_processes[harq_pid]->G);
#endif
if (dlsch->harq_processes[harq_pid]->G != mxGetM(prhs[0])) {
free_ue_dlsch(dlsch);
free(frame_parms);
free(phy_vars_ue);
mexErrMsgTxt("Length of the LLR vector is incorrect.");
}
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
ret = (unsigned int*) mxGetPr(plhs[0]);
/* Algo */
*ret = dlsch_decoding(phy_vars_ue, dlsch_llr, frame_parms, dlsch, dlsch->harq_processes[harq_pid], subframe, dlsch->current_harq_pid, 1,0);
/* free dlsch */
free_ue_dlsch(dlsch);
free(frame_parms);
free(phy_vars_ue);
// free_td();
}
#include "../../../defs.h"
/*==============================================================================
* dlsch_encoding_init.c
*
* Returns the decoded bit sequence.
*
* example: dlsch_decoding_init(struct1)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
#define DEBUG_DLSCH_DECODING_INIT
void mexFunction( int mlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
extern int *pi2tab16[188],*pi5tab16[188],*pi4tab16[188],*pi6tab16[188];
int i;
unsigned long *ptr; //hack for 64bit
int **tmp[1];
// Init CRC tables
// crcTableInit();
init_td16();
// assign output
plhs[0] = mxCreateNumericMatrix(4,1, mxUINT64_CLASS, mxREAL);
ptr = (unsigned int*) mxGetData(plhs[0]);
tmp[0] = &pi2tab16[0];
memcpy(&ptr[0], tmp, sizeof(tmp[0]));
tmp[0] = &pi4tab16[0];
memcpy(&ptr[1], tmp, sizeof(tmp[0]));
tmp[0] = &pi5tab16[0];
memcpy(&ptr[2], tmp, sizeof(tmp[0]));
tmp[0] = &pi6tab16[0];
memcpy(&ptr[3], tmp, sizeof(tmp[0]));
#ifdef DEBUG_DLSCH_DECODING_INIT
mexPrintf("pi2tab %p\n",&pi2tab16[0]);
mexPrintf("pi4tab %p\n",&pi4tab16[0]);
mexPrintf("pi5tab %p\n",&pi5tab16[0]);
mexPrintf("pi6tab %p\n",&pi6tab16[0]);
mexPrintf("ptr0 %p\n",ptr[0]);
mexPrintf("ptr1 %p\n",ptr[1]);
mexPrintf("ptr2 %p\n",ptr[2]);
mexPrintf("ptr3 %p\n",ptr[3]);
#endif
// The memory here is never explictly freed via mxFree. It is implicitly taken
// care of by clear functions at the beginning of the simulation.
for (i=0; i<188; i++) {
mexMakeMemoryPersistent((void *) pi2tab16[i]);
mexMakeMemoryPersistent((void *) pi5tab16[i]);
mexMakeMemoryPersistent((void *) pi4tab16[i]);
mexMakeMemoryPersistent((void *) pi6tab16[i]);
}
}
#include "../../../defs.h"
/*==============================================================================
* dlsch_dual_stream_correlation.c
*
* Returns the correlation coefficient Heff1'Heff0.
*
* example: rho = dlsch_dual_stream_correlation(Heff0,Heff1,simparms,slot);
*
* Author: Sebastian Wagner
* Date: 24-07-2012
*
===============================================================================*/
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
int *dl_ch_estimates_ext[NB_ANTENNAS_RX*NB_ANTENNAS_TX],*dl_ch_estimates_ext_i[NB_ANTENNAS_RX*NB_ANTENNAS_TX],*Heff0,*Heff1,*rho10,*rho10_out,*dl_ch_rho_ext[NB_ANTENNAS_RX*NB_ANTENNAS_TX];
unsigned int nb_re_per_symbol, nb_re_per_frame;
unsigned char output_shift, symbol;
LTE_DL_FRAME_PARMS *frame_parms;
mxArray *tmp;
/* Check proper input and output. */
if(nrhs!=4)
mexErrMsgTxt("4 inputs required.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
else if(!mxIsStruct(prhs[2]))
mexErrMsgTxt("Third input must be a structure.");
if(!mxIsInt16(prhs[0]))
mexErrMsgTxt("First argument must belong to Int16 class.");
if(!mxIsInt16(prhs[1]))
mexErrMsgTxt("Second argument must belong to Int16 class.");
/* Allocate input */
Heff0 = (int*) mxGetData(prhs[0]);
Heff1 = (int*) mxGetData(prhs[1]);
symbol = (unsigned char) mxGetScalar(prhs[3]);
tmp = mxGetField(prhs[2],0,"log2_maxh");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'log2_maxh' in input argument 3.");
} else {
output_shift = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"nb_re_per_frame");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_re_per_frame' in input argument 3.");
} else {
nb_re_per_frame = (unsigned int) mxGetScalar(tmp);
}
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = calloc(1,sizeof(LTE_DL_FRAME_PARMS));
tmp = mxGetField(prhs[2],0,"nb_rb");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 3.");
} else {
frame_parms->N_RB_DL = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"nb_antennas_rx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_rx' in input argument 3.");
} else {
frame_parms->nb_antennas_rx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"Ncp");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Ncp' in input argument 3.");
} else {
frame_parms->Ncp = (unsigned char) mxGetScalar(tmp);
}
nb_re_per_symbol = frame_parms->N_RB_DL*12;
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
rho10_out = (int*) mxGetPr(plhs[0]);
rho10 = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
dl_ch_rho_ext[0] = rho10;
dl_ch_rho_ext[1] = &rho10[nb_re_per_frame];
dl_ch_rho_ext[2] = &rho10[2*nb_re_per_frame];
dl_ch_rho_ext[3] = &rho10[3*nb_re_per_frame];
dl_ch_estimates_ext[0] = Heff0;
dl_ch_estimates_ext[1] = &Heff0[nb_re_per_frame];
dl_ch_estimates_ext[2] = &Heff0[2*nb_re_per_frame];
dl_ch_estimates_ext[3] = &Heff0[3*nb_re_per_frame];
dl_ch_estimates_ext_i[0] = Heff1;
dl_ch_estimates_ext_i[1] = &Heff1[nb_re_per_frame];
dl_ch_estimates_ext_i[2] = &Heff1[2*nb_re_per_frame];
dl_ch_estimates_ext_i[3] = &Heff1[3*nb_re_per_frame];
/* Algo */
dlsch_dual_stream_correlation(frame_parms,
symbol,
frame_parms->N_RB_DL,
dl_ch_estimates_ext,
dl_ch_estimates_ext_i,
dl_ch_rho_ext,
output_shift);
memcpy(rho10_out,&dl_ch_rho_ext[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&rho10_out[nb_re_per_symbol],&dl_ch_rho_ext[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&rho10_out[2*nb_re_per_symbol],&dl_ch_rho_ext[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
memcpy(&rho10_out[3*nb_re_per_symbol],&dl_ch_rho_ext[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
/* free */
free(frame_parms);
mxFree(rho10);
}
#include "../../../defs.h"
/*==============================================================================
* dlsch_encoding.c
*
* Returns the encoded bit sequence.
*
* example: e = dlsch_encoding(bits,struct1,struct2)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
// #define DEBUG_DLSCH_ENCODING
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
unsigned char *input_buffer;
unsigned char *e; // encoded bits = output
unsigned char mcs=0;
unsigned char mod_order=2;
unsigned char num_pdcch_symbols=1;
unsigned char harq_pid=0;
unsigned char subframe=0;
unsigned char Kmimo=1;
unsigned char Mdlharq=8;
unsigned char abstraction_flag;
int ret, input_buffer_length;
unsigned int G;
mxArray *tmp;
LTE_eNB_DLSCH_t* dlsch;
LTE_DL_FRAME_PARMS *frame_parms;
time_stats_t dlsch_rate_matching_stats, dlsch_turbo_encoding_stats, dlsch_interleaving_stats;
/* Check proper input and output. */
if(nrhs!=3)
mexErrMsgTxt("Three inputs required.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
else if(!mxIsStruct(prhs[1]))
mexErrMsgTxt("Second input must be a structure.");
else if(!mxIsStruct(prhs[2]))
mexErrMsgTxt("Third input must be a structure.");
// Init CRC tables
crcTableInit();
/* Create new dlsch */
tmp = mxGetField(prhs[2],0,"Kmimo");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Kmimo' in input argument 3.");
} else {
Kmimo = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"Mdlharq");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Mdlharq' in input argument 3.");
} else {
Mdlharq = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"abstraction_flag");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'abstraction_flag' in input argument 2.");
} else {
abstraction_flag = (unsigned char) mxGetScalar(tmp);
}
dlsch = new_eNB_dlsch(Kmimo,Mdlharq,25,abstraction_flag);
/* Allocate input */
input_buffer = (unsigned char*) mxGetData(prhs[0]);
(mxGetM(prhs[0]) > 1) ? (input_buffer_length = mxGetM(prhs[0])) : (input_buffer_length = mxGetN(prhs[0]));
tmp = mxGetField(prhs[2],0,"mcs");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'mcs' in input argument 3.");
} else {
mcs = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"harq_pid");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'harq_pid' in input argument 3.");
} else {
harq_pid = (unsigned char) mxGetScalar(tmp);
}
dlsch->current_harq_pid = harq_pid;
dlsch->harq_processes[harq_pid]->mcs = mcs;
tmp = mxGetField(prhs[2],0,"rvidx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'rvidx' in input argument 3.");
} else {
dlsch->harq_processes[harq_pid]->rvidx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"Nl");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Nl' in input argument 3.");
} else {
dlsch->harq_processes[harq_pid]->Nl = (unsigned char) mxGetScalar(tmp);
}
/*
tmp = mxGetField(prhs[2],0,"Ndi");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Ndi' in input argument 3.");
} else {
dlsch->harq_processes[harq_pid]->Ndi = (unsigned char) mxGetScalar(tmp);
}
*/
tmp = mxGetField(prhs[1],0,"rb_alloc");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'rb_alloc' in input argument 2.");
} else {
dlsch->rb_alloc[0] = (unsigned int) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"nb_rb");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 2.");
} else {
dlsch->nb_rb = (unsigned short) mxGetScalar(tmp);
}
dlsch->harq_processes[harq_pid]->TBS = dlsch_tbs25[get_I_TBS(mcs)][dlsch->nb_rb-1];
// Check if input buffer length is correct
if ((input_buffer_length) != (dlsch->harq_processes[harq_pid]->TBS/8+4)) {
free_eNB_dlsch(dlsch);
mexErrMsgTxt("Length of the input buffer is incorrect.");
}
tmp = mxGetField(prhs[1],0,"num_pdcch_symbols");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'num_pdcch_symbols' in input argument 2.");
} else {
num_pdcch_symbols = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"subframe");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'subframe' in input argument 2.");
} else {
subframe = (unsigned char) mxGetScalar(tmp);
}
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = calloc(1,sizeof(LTE_DL_FRAME_PARMS));
frame_parms->N_RB_DL = (unsigned char) dlsch->nb_rb;
tmp = mxGetField(prhs[1],0,"frame_type");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'frame_type' in input argument 2.");
} else {
frame_parms->frame_type = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"mode1_flag");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'frame_type' in input argument 2.");
} else {
frame_parms->mode1_flag = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"Ncp");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'frame_type' in input argument 2.");
} else {
frame_parms->Ncp = (unsigned char) mxGetScalar(tmp);
}
mod_order = get_Qm(dlsch->harq_processes[harq_pid]->mcs);
G = get_G(frame_parms,dlsch->nb_rb,dlsch->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,0,subframe);
#ifdef DEBUG_DLSCH_ENCODING
mexPrintf("dlsch->current_harq_pid = %d\n", dlsch->current_harq_pid);
mexPrintf("dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
mexPrintf("dlsch->harq_processes[harq_pid]->Nl = %d\n", dlsch->harq_processes[harq_pid]->Nl);
mexPrintf("dlsch->harq_processes[harq_pid]->Ndi = %d\n", dlsch->harq_processes[harq_pid]->Ndi);
mexPrintf("mod_order = %d\n",mod_order);
mexPrintf("G = %d\n",G);
mexPrintf("frame_parms->N_RB_DL = %d\n", frame_parms->N_RB_DL);
mexPrintf("frame_parms->frame_type = %d\n", frame_parms->frame_type);
mexPrintf("frame_parms->mode1_flag = %d\n", frame_parms->mode1_flag);
mexPrintf("frame_parms->Ncp = %d\n", frame_parms->Ncp);
#endif
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(G, 1, mxUINT8_CLASS, mxREAL);
e = (unsigned char*) mxGetPr(plhs[0]);
/* Algo */
ret = dlsch_encoding(input_buffer, frame_parms, num_pdcch_symbols, dlsch, 0, subframe,&dlsch_rate_matching_stats, &dlsch_turbo_encoding_stats, &dlsch_interleaving_stats);
/* Assign output */
memcpy((void*) e, (void*) dlsch->e,G);
/* free */
free_eNB_dlsch(dlsch);
free(frame_parms);
}
#include "../../../defs.h"
/*==============================================================================
* dlsch_mu_mimo_llr.c
*
* Returns the LLRs for interference aware receiver.
*
* example: llr = dlsch_mu_mimo_llr(ymf0,ymf1,Hmag0,Hmag1,rho10,simparms,slot);
*
* Author: Sebastian Wagner
* Date: 24-07-2012
*
===============================================================================*/
// #define DEBUG_MU_MIMO_LLR
#define LLR_GUARD 48
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
short *ymf0, *ymf1,*hmag0, *hmag1, *rho10, *llr;
short *llr_16 __attribute__ ((aligned(16)));
unsigned char mod_order;
unsigned char symbol, symbol_mod;
int nb_re_per_symbol,i;
mxArray *tmp;
LTE_DL_FRAME_PARMS *frame_parms;
/* Check proper input and output. */
if(nrhs!=7)
mexErrMsgTxt("7 inputs required.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
else if(!mxIsStruct(prhs[5]))
mexErrMsgTxt("6. input must be a structure.");
if(!mxIsInt16(prhs[0]))
mexErrMsgTxt("First argument must belong to Int16 class.");
if(!mxIsInt16(prhs[1]))
mexErrMsgTxt("Second argument must belong to Int16 class.");
if(!mxIsInt16(prhs[2]))
mexErrMsgTxt("Third argument must belong to Int16 class.");
if(!mxIsInt16(prhs[3]))
mexErrMsgTxt("4. argument must belong to Int16 class.");
if(!mxIsInt16(prhs[4]))
mexErrMsgTxt("5. argument must belong to Int16 class.");
/* Allocate input */
ymf0 = (short*) mxGetData(prhs[0]);
ymf1 = (short*) mxGetData(prhs[1]);
hmag0 = (short*) mxGetData(prhs[2]);
hmag1 = (short*) mxGetData(prhs[3]);
rho10 = (short*) mxGetData(prhs[4]);
symbol = (unsigned char) mxGetScalar(prhs[6]);
tmp = mxGetField(prhs[5],0,"codeword");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'codeword' in input argument 6.");
} else {
tmp = mxGetField(mxGetField(prhs[5],0,"codeword"),0,"mod_order");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'mod_order' in input argument '6.codeword(1)'.");
} else {
mod_order = (unsigned char) mxGetScalar(tmp);
}
}
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = (LTE_DL_FRAME_PARMS*) mxCalloc(1,sizeof(LTE_DL_FRAME_PARMS));
tmp = mxGetField(prhs[5],0,"nb_rb");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 6.");
} else {
frame_parms->N_RB_DL = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[5],0,"nb_antennas_rx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_rx' in input argument 6.");
} else {
frame_parms->nb_antennas_rx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[5],0,"nb_antennas_tx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_antennas_tx' in input argument 6.");
} else {
frame_parms->nb_antennas_tx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[5],0,"Ncp");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Ncp' in input argument 6.");
} else {
frame_parms->Ncp = (unsigned char) mxGetScalar(tmp);
}
// Adapt the channel estimates and receive signal
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp)))
nb_re_per_symbol = frame_parms->N_RB_DL*8; // pilots
else
nb_re_per_symbol = frame_parms->N_RB_DL*12;
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(mod_order*nb_re_per_symbol,1, mxINT16_CLASS, mxREAL);
llr = (short*) mxGetPr(plhs[0]);
#ifdef DEBUG_MU_MIMO_LLR
mexPrintf("mod_order: %d\n", mod_order);
mexPrintf("frame_parms->N_RB_DL %d\n", frame_parms->N_RB_DL);
mexPrintf("frame_parms->nb_antennas_rx %d\n", frame_parms->nb_antennas_rx);
mexPrintf("frame_parms->nb_antennas_tx %d\n", frame_parms->nb_antennas_tx);
mexPrintf("frame_parms->Ncp %d\n", frame_parms->Ncp);
mexPrintf("nb_re_per_symbol %d\n", nb_re_per_symbol);
mexPrintf("frame_parms %p\n", frame_parms);
// mexPrintf("ymf0 %p\n",ymf0);
// mexPrintf("ymf1 %p\n",ymf1);
// mexPrintf("llr %p\n",llr);
// mexPrintf("hmag0 %p\n",hmag0);
// mexPrintf("hmag1 %p\n",hmag1);
// mexPrintf("rho10 %p\n",rho10);
// for(i=0;i<(nb_re_per_symbol*2);i++) {
for(i=0; i<(8*2); i++) {
mexPrintf("i=%d\n",i);
mexPrintf("ymf0 = %d\n",ymf0[i]);
mexPrintf("ymf1 = %d\n",ymf1[i]);
mexPrintf("hmag0 = %d\n",hmag0[i]);
mexPrintf("hmag1 = %d\n",hmag1[i]);
mexPrintf("rho10 = %d\n",rho10[i]);
}
#endif
// 16 bit aligned memory allocation with guard samples
llr_16 = (short *) malloc16((mod_order*nb_re_per_symbol+LLR_GUARD)*sizeof(short));
/* Algo */
switch (mod_order) {
case 2 :
qpsk_qpsk(ymf0, ymf1, llr_16, rho10, nb_re_per_symbol);
break;
case 4 :
qam16_qam16(ymf0, ymf1, hmag0, hmag1, llr_16, rho10, nb_re_per_symbol);
break;
case 6 :
qam64_qam64(ymf0, ymf1, hmag0, hmag1, llr_16, rho10, nb_re_per_symbol);
break;
default :
mexErrMsgTxt("Unknown mod_order.");
break;
}
// copy just valid LLRs to output
memcpy((void*) llr, (void *) llr_16, mod_order*nb_re_per_symbol*sizeof(short));
/* free */
mxFree(frame_parms);
free(llr_16);
}
#include "../../../defs.h"
/*==============================================================================
* get_tbs.c
*
* Returns the transport block size (TBS) given the MCS and the number of RBs.
*
* example: tbs = get_tbs(16,25)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
unsigned char get_I_TBS(unsigned char I_MCS);
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
unsigned char mcs, nb_rb;
unsigned int *tbs;
/* Check correct I/O number */
if(nrhs!=2) {
mexErrMsgTxt("Two inputs required.");
} else if(nlhs>1) {
mexErrMsgTxt("Too many output arguments.");
}
/* Allocate input */
mcs = (unsigned char) mxGetScalar(prhs[0]);
nb_rb = (unsigned char) mxGetScalar(prhs[1]);
/* Check input */
if((mcs < 0) || (mcs > 28)) {
mexErrMsgTxt("Wrong MCS index.");
} else if((nb_rb<=0) || (nb_rb>25)) {
mexErrMsgTxt("Unsupported number of RBs.");
};
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
tbs = (unsigned int*) mxGetPr(plhs[0]);
/* Algo */
*tbs = dlsch_tbs25[get_I_TBS(mcs)][nb_rb-1];
}
%% Testfile for dlsch_encoding mex-function
clear all;
addpath('../mexfiles');
%% Input
simparms.nb_rb = 25; % fixed number of RB per OFDM symbol
simparms.rb_alloc = hex2dec('1FFFFFF'); % 25 ones
simparms.num_pdcch_symbols = 3;
simparms.subframe = 7;
simparms.abstraction_flag = 0;
simparms.frame_type = 1; % TDD frame
simparms.mode1_flag = 0; % is TM1 active?
simparms.Ncp = 0; % Normal CP
codeword.mcs = 13;
codeword.TBS = get_tbs(codeword.mcs,simparms.nb_rb);
codeword.Kmimo = 1;
codeword.harq_pid = 0; % First HARQ round
codeword.Mdlharq = 1; % Number of HARQ rounds
codeword.rvidx = 0;
codeword.Nl = 1;
codeword.Ndi = 1;
data0 = uint8(randi([0,255],codeword.TBS/8+4,1));
%% mex
edata0 = dlsch_encoding(data0,simparms,codeword);
llr = int16((double(edata0)-0.5)*128);
ret0 = dlsch_decoding(llr,simparms,codeword);
%% Print
disp(ret0);
\ No newline at end of file
#include "../../../defs.h"
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
unsigned int x;
unsigned char *l2;
/* Allocate input */
x = (unsigned int) mxGetScalar(prhs[0]);
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(1, 1, mxUINT8_CLASS, mxREAL);
l2 = (unsigned char*) mxGetPr(plhs[0]);
/* Algo */
*l2 = log2_approx(x);
}
\ No newline at end of file
function [ simparms ] = InitSimparms( mcs, n_frames, SNRdB )
%INITSIMPARMS initialize simparms struct for TM5
% There are always 2 user schedules for transmission
% INPUT:
% nb_antennas_tx = Number of transmit antennas, max = 2
% nb_antennas_rx = Number of receive antennas per UE, max = 2
% MCS(2) = Modulation and Coding Scheme [1,...,27]
% n_frames = Number of frames to simulate
% SNRdB = SNR in dB
addpath('../../../PHY/LTE_TRANSPORT/mexfiles');
j = sqrt(-1);
%% Custom parameters
simparms.nb_antennas_tx = 2;
simparms.nb_antennas_tx_eNB = simparms.nb_antennas_tx;
simparms.nb_antennas_rx = 2;
simparms.n_frames = n_frames;
simparms.snr_db = SNRdB;
%% Constant parameters
simparms.NB_ANTENNAS_TX = 2; % max number of TX antennas
simparms.NB_ANTENNAS_RX = 2; % max number of RX antennas
simparms.snr = 10.^(SNRdB/10);
simparms.num_pdcch_symbols = 3;
simparms.subframe = 7;
simparms.abstraction_flag = 0;
simparms.nb_rb = 25; % fixed number of RB per OFDM symbol
simparms.rb_alloc = hex2dec('1FFF'); % 25 RBs
simparms.MAX_TURBO_ITERATIONS = 5;
simparms.nb_re = 3000; % there are 3000 REs in subframe 7
simparms.frame_type = 1; % TDD frame
simparms.mode1_flag = 0; % no is TM1 active
simparms.Ncp = 0; % Normal CP
simparms.ofdm_symbol_size = 512;
simparms.log2_maxh = 16;
simparms.dl_power_offset= 1; % no 3dB power offset
simparms.nb_slots = 14;
simparms.nb_re_per_symbol = simparms.nb_rb*12;
simparms.nb_re_per_frame = simparms.nb_slots*simparms.nb_re_per_symbol;
simparms.frame_errors = zeros(length(simparms.snr),simparms.NB_ANTENNAS_RX);
simparms.CB = [[1;1],[1;-1],[1;j],[1;-j]]/sqrt(2); % codebook
simparms.tseeds = set_taus_seed(1); % taus seeds
% Turbo decoder: set the pointer to the td tables allocated by init_td()
simparms.ptr_td = dlsch_decoding_init();
% Init codewords
% simparms.codeword(1) = InitCodeword(simparms,mcs(1));
% simparms.codeword(2) = InitCodeword(simparms,mcs(2));
simparms.codeword(1) = InitCodeword(simparms,mcs(1));
simparms.codeword(2) = InitCodeword(simparms,mcs(2));
% simparms.codeword(3) = InitCodeword(simparms,mcs(1));
% simparms.codeword(4) = InitCodeword(simparms,mcs(1));
end
function codeword = InitCodeword(simparms,mcs)
% Constellation
j = sqrt(-1);
amp = 1/32;
Q4 = amp*[ 1+j, 1- j, -1+j, -1-j]./sqrt(2);
Q16 = amp*[ 1+j, 1+3*j, 3+j, 3+3*j, 1-j, 1-3*j, 3-j, 3-3*j,...
-1+j, -1+3*j, -3+j, -3+3*j, -1-j, -1-3*j, -3-j, -3-3*j]./sqrt(10);
Q64 = amp*[ 3+3*j, 3+j, 1+3*j, 1+ j, 3+5*j, 3+7*j, 1+5*j, 1+7*j,...
5+3*j, 5+j, 7+ j, 7+3*j, 5+5*j, 5+7*j, 7+5*j, 7+7*j,...
3-3*j, 3-j, 1-3*j, 1- j, 3-5*j, 3-7*j, 1-5*j, 1-7*j,...
5-3*j, 5-j, 7-3*j, 7- j, 5-5*j, 5-7*j, 7-5*j, 7-7*j,...
-3+3*j,-3+j,-1+3*j,-1+ j,-3+5*j,-3+7*j,-1+5*j,-1+7*j,...
-5+3*j,-5+j,-7+3*j,-7+ j,-5+5*j,-5+7*j,-7+5*j,-7+7*j,...
-3-3*j,-3-j,-1-3*j,-1- j,-3-5*j,-3-7*j,-1-5*j,-1-7*j,...
-5-3*j,-5-j,-7-3*j,-7- j,-5-5*j,-5-7*j,-7-5*j,-7-7*j]./sqrt(42);
if (mcs <= 9)
codeword.mod_order = 2;
codeword.base2 = [2 1];
codeword.const = Q4;
elseif (mcs <= 16)
codeword.mod_order = 4;
codeword.base2 = [8 4 2 1];
codeword.const = Q16;
elseif (mcs <= 27)
codeword.mod_order = 6;
codeword.base2 = [32 16 8 4 2 1];
codeword.const = Q64;
else
error('invalid MCS: %d\n', mcs);
end
codeword.mcs = mcs;
codeword.G = simparms.nb_re*codeword.mod_order; % Number of softbits
codeword.TBS = get_tbs(mcs,simparms.nb_rb);
codeword.Kmimo = 2;
codeword.harq_pid = 0; % First HARQ round
codeword.Mdlharq = 1; % Number of HARQ rounds
codeword.rvidx = 0;
codeword.Nl = 1;
codeword.Ndi = 1;
end
function [ simparms ] = InitSimparms( nb_antennas_tx, nb_antennas_rx, mcs, n_frames, SNRdB )
%INITSIMPARMS initialize simparms struct for TM5
% There are always 2 user schedules for transmission
% INPUT:
% nb_antennas_tx = Number of transmit antennas, max = 2
% nb_antennas_rx = Number of receive antennas per UE, max = 2
% MCS(2) = Modulation and Coding Scheme [1,...,27]
% n_frames = Number of frames to simulate
% SNRdB = SNR in dB
addpath('../../../PHY/LTE_TRANSPORT/mexfiles');
if (nb_antennas_tx ~= 2)
error('unsupported number of tx antennas, only 2 is valid');
elseif (nb_antennas_rx > 2 || nb_antennas_rx < 1)
error('unsupported number of rx antennas, only 1,2 is valid');
end
j = sqrt(-1);
%% Custom parameters
simparms.nb_antennas_tx = nb_antennas_tx;
simparms.nb_antennas_tx_eNB = simparms.nb_antennas_tx;
simparms.nb_antennas_rx = nb_antennas_rx;
simparms.n_frames = n_frames;
simparms.snr_db = SNRdB;
%% Constant parameters
simparms.NB_ANTENNAS_TX = 2; % max number of TX antennas
simparms.NB_ANTENNAS_RX = 2; % max number of RX antennas
simparms.snr = 10.^(SNRdB/10);
simparms.num_pdcch_symbols = 3;
simparms.subframe = 7;
simparms.abstraction_flag = 0;
simparms.nb_rb = 25; % fixed number of RB per OFDM symbol
simparms.rb_alloc = hex2dec('1FFF'); % 25 RBs
simparms.MAX_TURBO_ITERATIONS = 5;
simparms.nb_re = 3000; % there are 3000 REs in subframe 7
simparms.frame_type = 1; % TDD frame
simparms.mode1_flag = 0; % is TM1 active?
simparms.Ncp = 0; % Normal CP
simparms.ofdm_symbol_size = 512;
simparms.log2_maxh = 16;
simparms.dl_power_offset= 0; % 0 = 3dB power offset
simparms.nb_slots = 14;
simparms.nb_re_per_symbol = simparms.nb_rb*12;
simparms.nb_re_per_frame = simparms.nb_slots*simparms.nb_re_per_symbol;
simparms.frame_errors = zeros(length(simparms.snr),1);
simparms.CB = [[1;1],[1;-1],[1;j],[1;-j]]; % codebook
simparms.tseeds = set_taus_seed(1); % taus seeds
% Turbo decoder: set the pointer to the td tables allocated by init_td()
simparms.ptr_td = dlsch_decoding_init();
% Init codewords
simparms.codeword(1) = InitCodeword(simparms,mcs(1));
simparms.codeword(2) = InitCodeword(simparms,mcs(2));
end
function codeword = InitCodeword(simparms,mcs)
% Constellation
j = sqrt(-1);
amp = 1/32;
Q4 = amp*[ 1+j, 1- j, -1+j, -1-j]./sqrt(2);
Q16 = amp*[ 1+j, 1+3*j, 3+j, 3+3*j, 1-j, 1-3*j, 3-j, 3-3*j,...
-1+j, -1+3*j, -3+j, -3+3*j, -1-j, -1-3*j, -3-j, -3-3*j]./sqrt(10);
Q64 = amp*[ 3+3*j, 3+j, 1+3*j, 1+ j, 3+5*j, 3+7*j, 1+5*j, 1+7*j,...
5+3*j, 5+j, 7+ j, 7+3*j, 5+5*j, 5+7*j, 7+5*j, 7+7*j,...
3-3*j, 3-j, 1-3*j, 1- j, 3-5*j, 3-7*j, 1-5*j, 1-7*j,...
5-3*j, 5-j, 7-3*j, 7- j, 5-5*j, 5-7*j, 7-5*j, 7-7*j,...
-3+3*j,-3+j,-1+3*j,-1+ j,-3+5*j,-3+7*j,-1+5*j,-1+7*j,...
-5+3*j,-5+j,-7+3*j,-7+ j,-5+5*j,-5+7*j,-7+5*j,-7+7*j,...
-3-3*j,-3-j,-1-3*j,-1- j,-3-5*j,-3-7*j,-1-5*j,-1-7*j,...
-5-3*j,-5-j,-7-3*j,-7- j,-5-5*j,-5-7*j,-7-5*j,-7-7*j]./sqrt(42);
if (mcs <= 9)
codeword.mod_order = 2;
codeword.base2 = [2 1];
codeword.const = Q4;
elseif (mcs <= 16)
codeword.mod_order = 4;
codeword.base2 = [8 4 2 1];
codeword.const = Q16;
elseif (mcs <= 27)
codeword.mod_order = 6;
codeword.base2 = [32 16 8 4 2 1];
codeword.const = Q64;
else
error('invalid MCS: %d\n', mcs);
end
codeword.mcs = mcs;
codeword.G = simparms.nb_re*codeword.mod_order; % Number of softbits
codeword.TBS = get_tbs(mcs,simparms.nb_rb);
codeword.Kmimo = 1;
codeword.harq_pid = 0; % First HARQ round
codeword.Mdlharq = 1; % Number of HARQ rounds
codeword.rvidx = 0;
codeword.Nl = 1;
codeword.Ndi = 1;
end
%% Header
%==========================================================================
% This testbench simulations transmission mode 5 on subframe 7.
% Results can be compared to "./dlsim -x5 -S7 -R1 -u1" with perfect chest
% No OFDM Modulation and Demodulation is applied!
%
% Author: Sebastian Wagner
% Date: 24-07-2012
%
%==========================================================================
clear all;
close all;
clear mex;
addpath('../../../PHY/LTE_TRANSPORT/mexfiles');
addpath('../../../PHY/TOOLS/mexfiles');
addpath('../../../SIMULATION/TOOLS/mexfiles');
% profile on;
tic
%% System parameters
nt = 2;
nr = 2;
N = 1000; % number of frames (codewords)
nSNR = 1;
%SNRdB = [1:20];
SNRdB = 10;
% nSNR = 13;
%SNRdB = linspace(1,20,nSNR);
MCS = [9 9]; % MCS for the 2 users, currently it is assumed that mcs(2)=mcs(1)
j = sqrt(-1);
amp = 1/32;
XFORMS = 0;
% LLRs are computed for 8RE make sure enough valid memory is allocated
LLR_GUARD_SAMPLES = 8*6; % max mod_order 6 for 8 REs
%% Initialize simparms
simparms = InitSimparms( nt, nr, MCS, N, SNRdB);
%% Random data, same seed as in dlsim.c
[tmp simparms.tseeds] = taus(1,simparms.tseeds);
%% Index of REs carrying data
data_idx = [901:1400 1501:2300 2401:3500 3601:4200];
data_idx_int = [1801:2800 3001:4600 4801:7000 7201:8400]; % [Re Im] format
data_idx_int_r = data_idx_int(1:2:length(data_idx_int));
data_idx_int_i = data_idx_int(2:2:length(data_idx_int));
%% Allocate memory
llr0 = zeros(simparms.codeword(1).G, 1,'int16');
y_fxp = zeros(simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,simparms.nb_re_per_frame,'int16');
y_fxp_t = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
ymf0 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
% Effective channel will contain the channel estimate at pilot positions
Heff0 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Hmag0 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Hmagb0 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
ymf1 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Heff1 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Hmag1 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
Hmagb1 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
rho10 = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
H = zeros(simparms.NB_ANTENNAS_RX,simparms.NB_ANTENNAS_TX);
noise = zeros(simparms.NB_ANTENNAS_RX,simparms.nb_re);
%% XFORMS
if (XFORMS)
scrsz = get(0,'ScreenSize');
figure('Position',[1 scrsz(4)/2 scrsz(3)/2 scrsz(4)/2])
subplot(1,2,1);
xlim([1 simparms.codeword(1).G]);
title('LLRs of UE 0');
fig_llr0 = scatter(1:simparms.codeword(1).G,llr0,'.','YDataSource','llr0');
subplot(1,2,2);
title('MF output of UE 0');
fig_ymf = scatter(ymf0(data_idx_int_r),ymf0(data_idx_int_i),'.','XDataSource','ymf0(data_idx_int_r)','YDataSource','ymf0(data_idx_int_i)');
end
%% Encode and modulate transmit signal
% The same data is used throughout the simulation -> saves time
[data0 simparms.tseeds] = taus(simparms.codeword(1).TBS/8,simparms.tseeds);
[data1 simparms.tseeds] = taus(simparms.codeword(2).TBS/8,simparms.tseeds);
% Add 4 bytes CRC
data0 = [data0; zeros(4,1,'uint8')];
data1 = [data1; zeros(4,1,'uint8')];
edata0 = dlsch_encoding(data0,simparms,simparms.codeword(1)); % user 1
edata1 = dlsch_encoding(data1,simparms,simparms.codeword(2)); % user 2
% Modulation
edata_enc(:,1) = simparms.codeword(1).base2*double(reshape(edata0,simparms.codeword(1).mod_order,simparms.nb_re));
edata_enc(:,2) = simparms.codeword(2).base2*double(reshape(edata1,simparms.codeword(2).mod_order,simparms.nb_re));
s(:,1) = simparms.codeword(1).const(edata_enc(:,1)+1);
s(:,2) = simparms.codeword(2).const(edata_enc(:,2)+1);
Ptx = sum(diag(s'*s))/simparms.nb_re; % average transmit power per RE
%% Loop over SNRs
for iSNR=1:length(simparms.snr)
cSNR = simparms.snr(iSNR); % current SNR
%% Loop over Frames
for n=1:simparms.n_frames
%% Channel
% Rayleigh channel, constant for whole codeblock/frame, always 2x2
H(1:nr,1:nt) = (randn(nr,nt) + j*randn(nr,nt))/sqrt(2);
%% PMI computation
pmi = 1;
r = H(:,2)'*H(:,1);
rr = real(r);
ri = imag(r);
if (rr>ri && rr>-ri)
pmi = 1;
elseif (rr<ri && rr>-ri)
pmi = 3;
elseif (rr<ri && rr<-ri)
pmi = 2;
elseif (rr>ri && rr<-ri)
pmi = 4;
end
% opposite pmi
if(pmi<3)
pmi_o = mod(pmi,2) + 1;
else
pmi_o = mod(pmi,2) + 3;
end
pmi_ext = uint8(repmat(pmi-1,1,simparms.nb_rb));
pmi_ext_o = uint8(repmat(pmi_o-1,1,simparms.nb_rb));
% precoding vectors
g0 = simparms.CB(:,pmi);
g1 = simparms.CB(:,pmi_o);
%% Transmit signal (frequency domain)
x = [g0,g1]*conj(s')/sqrt(2); % E[|x|^2] = 2*amp^2
%% Noise
sigma2 = (Ptx/cSNR);
% E[|noise|^2] = 2*amp^2/sqrt(SNR) -> SNR=1/sigma^2
noise(1:nr,:) = sqrt(sigma2)*(randn(nr,simparms.nb_re) + j*randn(nr,simparms.nb_re))/sqrt(2);
%% Received signal
y = H*x + noise;
% Quantization
y_fxp_data = int16(floor(y*pow2(15)));
H_fxp = int16(fix(H*floor(amp/sqrt(2)*pow2(15)))); % Perfect Chest
% insert dummy pilots
y_fxp(1:2,data_idx) = y_fxp_data;
% reorder for processing
H_fxp_t = repmat([real(H_fxp(:)) imag(H_fxp(:))]',simparms.nb_re_per_frame,1);
y_fxp_t(:,1) = reshape([real(y_fxp(1,:)); imag(y_fxp(1,:))],2*simparms.nb_re_per_frame,1);
y_fxp_t(:,2) = reshape([real(y_fxp(2,:)); imag(y_fxp(2,:))],2*simparms.nb_re_per_frame,1);
%% Compute Scaling
avg = dlsch_channel_level_prec(H_fxp_t,pmi_ext,simparms);
simparms.log2_maxh = max(double(log2_approx(avg))-13,0);
%% Inner receiver loop
llrp = 1; % LLR pointer
for symbol = 4:14
idxs = 2*(symbol-1)*simparms.nb_re_per_symbol + 1;
idxe = 2*(symbol-1)*simparms.nb_re_per_symbol + 2*simparms.nb_re_per_symbol;
%% Preprocessing
[ymf0(idxs:idxe,:)...
Heff0(idxs:idxe,:)...
Hmag0(idxs:idxe,:)...
Hmagb0(idxs:idxe,:)]...
= dlsch_channel_compensation_prec(y_fxp_t,H_fxp_t,pmi_ext,simparms,simparms.codeword(1),symbol-1);
% Interfering user
[ymf1(idxs:idxe,:)...
Heff1(idxs:idxe,:)...
Hmag1(idxs:idxe,:)...
Hmagb1(idxs:idxe,:)]...
= dlsch_channel_compensation_prec(y_fxp_t,H_fxp_t,pmi_ext_o,simparms,simparms.codeword(2),symbol-1);
%% Correlation coefficient
rho10(idxs:idxe,:) = dlsch_dual_stream_correlation(Heff0,Heff1,simparms,symbol-1);
%% Combining
if (nr>1)
[ymf0(idxs:idxe,:)...
ymf1(idxs:idxe,:)...
Hmag0(idxs:idxe,:)...
Hmagb0(idxs:idxe,:)...
Hmag1(idxs:idxe,:)...
Hmagb1(idxs:idxe,:)...
rho10(idxs:idxe,:)]...
= dlsch_detection_mrc(ymf0,ymf1,Hmag0,Hmag1,Hmagb0,Hmagb1,rho10,simparms,symbol-1);
end
%% LLR computation
llr = dlsch_mu_mimo_llr([ymf0(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[ymf1(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[Hmag0(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[Hmag1(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
[rho10(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
simparms,...
symbol-1);
llr0(llrp:llrp+length(llr)-1,:) = llr;
llrp = llrp + length(llr);
end
if (XFORMS)
refreshdata(fig_llr0,'caller');
drawnow;
refreshdata(fig_ymf,'caller');
drawnow; pause(0.1);
end
%% Channel decoding
llr0 = -llr0; % invert (since no scrambling applied)
ret0 = dlsch_decoding(llr0,simparms,simparms.codeword(1));
% Check if decoded correctly
if (ret0 >= simparms.MAX_TURBO_ITERATIONS)
simparms.frame_errors(iSNR,1) = simparms.frame_errors(iSNR,1) + 1;
end
end
fprintf('********************SNR = %3.1f dB processed on %s********************\n',real(simparms.snr_db(iSNR)),datestr(now));
fprintf('Errors: %d/%d\nPe = %1.5f\n',simparms.frame_errors(iSNR,1),N,simparms.frame_errors(iSNR,1)/N);
end
%% Post Processing
% total_frame_erros = sum(simparms.frame_errors,2);
% fer = total_frame_erros/N;
% figure; semilogy(SNRdB,fer); grid;
%
% disp(fer);
%
% profile viewer
toc
#include "../../../defs.h"
/*==============================================================================
* set_taus_seed.c
*
* Returns seeds which are the input to taus.c.
*
* example: seeds = set_taus_seed(0)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
unsigned int seed_init;
unsigned int s0, s1, s2, *ret;
if(nrhs!=1)
mexErrMsgTxt("Single input required.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
/* Allocate input */
seed_init = (unsigned int) mxGetScalar(prhs[0]);
/* Algo */
#ifdef USER_MODE
struct drand48_data buffer;
unsigned int result = 0;
#endif
if (seed_init == 0) {
s0 = (unsigned int)time(NULL);
s1 = (unsigned int)time(NULL);
s2 = (unsigned int)time(NULL);
} else {
#ifndef USER_MODE
s0 = (unsigned int)0x1e23d852;
s1 = (unsigned int)0x81f38a1c;
s2 = (unsigned int)0xfe1a133e;
#else
/* Use reentrant version of rand48 to ensure that no conflicts with other generators occur */
srand48_r((long int)seed_init, &buffer);
mrand48_r(&buffer, (long int *)&result);
s0 = result;
mrand48_r(&buffer, (long int *)&result);
s1 = result;
mrand48_r(&buffer, (long int *)&result);
s2 = result;
#endif
}
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(3, 1, mxUINT32_CLASS, mxREAL);
ret = (unsigned int*) mxGetPr(plhs[0]);
ret[0] = s0;
ret[1] = s1;
ret[2] = s2;
}
\ No newline at end of file
#include "../../../defs.h"
/*==============================================================================
* taus.c
*
* Returns random unsigned chars as well as the new seeds.
*
* example: [rchar seeds] = taus(len, seeds)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
unsigned int s0, s1, s2, b;
inline unsigned int mtaus()
{
b = (((s0 << 13) ^ s0) >> 19);
s0 = (((s0 & 0xFFFFFFFE) << 12)^ b);
b = (((s1 << 2) ^ s1) >> 25);
s1 = (((s1 & 0xFFFFFFF8) << 4)^ b);
b = (((s2 << 3) ^ s2) >> 11);
s2 = (((s2 & 0xFFFFFFF0) << 17)^ b);
return s0 ^ s1 ^ s2;
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
unsigned int len, *tseeds, *tseeds_out;
unsigned char *out;
int i;
if(nrhs!=2)
mexErrMsgTxt("Two inputs required.");
else if(nlhs > 2)
mexErrMsgTxt("Too many output arguments.");
/* Allocate input */
len = (unsigned int) mxGetScalar(prhs[0]);
tseeds = (unsigned int*) mxGetData(prhs[1]);
if (mxGetM(prhs[1])!=3 && mxGetN(prhs[1])!=3)
mexErrMsgTxt("Three seeds are required.");
s0 = tseeds[0];
s1 = tseeds[1];
s2 = tseeds[2];
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(len, 1, mxUINT8_CLASS, mxREAL);
out = (unsigned char*) mxGetPr(plhs[0]);
plhs[1] = mxCreateNumericMatrix(3, 1, mxUINT32_CLASS, mxREAL);
tseeds_out = (unsigned int*) mxGetPr(plhs[1]);
/* Algo */
for(i=0; i<len; i++)
out[i] = (unsigned char)(mtaus()&0xff);
tseeds_out[0] = s0;
tseeds_out[1] = s1;
tseeds_out[2] = s2;
}
\ No newline at end of file
/*******************************************************************************
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 "mex.h"
#include "../../SIMULATION/TOOLS/defs.h"
#include "../../PHY/types.h"
#include "../../PHY/TOOLS/defs.h"
#include "../../PHY/defs.h"
#include "../../PHY/vars.h"
#include "../../MAC_INTERFACE/vars.h"
This diff is collapsed.
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