moving Matlab to extras
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7223 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -1,89 +0,0 @@
|
||||
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)
|
||||
-249
@@ -1,249 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
#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();
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
#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]);
|
||||
}
|
||||
}
|
||||
@@ -1,252 +0,0 @@
|
||||
#include "../../../defs.h"
|
||||
|
||||
/*==============================================================================
|
||||
* dlsch_detection_mrc.c
|
||||
*
|
||||
* Combines the parameters of both receive antennas.
|
||||
*
|
||||
* example: [ymf heff hmag hmagb] = dlsch_detection_mrc(ymf0,ymf1,hmag0,hmag1,hamgb0,hmagb1,rho10,struct,slot)
|
||||
*
|
||||
* Author: Sebastian Wagner
|
||||
* Date: 23-07-2012
|
||||
*
|
||||
===============================================================================*/
|
||||
|
||||
//#define DEBUG_DETECTION_MRC
|
||||
|
||||
void mexFunction( int nlhs, mxArray *plhs[],
|
||||
int nrhs, const mxArray *prhs[]
|
||||
)
|
||||
{
|
||||
/* Declare */
|
||||
int *ymf0, *ymf1, *Hmag0, *Hmag1, *Hmag0b, *Hmag1b, *rho10;
|
||||
int *ymf0_out, *ymf1_out, *Hmag0_out, *Hmag1_out, *Hmag0b_out, *Hmag1b_out, *rho10_out;
|
||||
int *ymf0_cpy, *ymf1_cpy, *Hmag0_cpy, *Hmag1_cpy, *Hmag0b_cpy, *Hmag1b_cpy, *rho10_cpy;
|
||||
int *rxdataF_comp[NB_ANTENNAS_RX*NB_ANTENNAS_TX], *rxdataF_comp_i[NB_ANTENNAS_RX*NB_ANTENNAS_TX], *rho_i[NB_ANTENNAS_RX*NB_ANTENNAS_TX];
|
||||
int *dl_ch_mag[NB_ANTENNAS_RX*NB_ANTENNAS_TX], *dl_ch_mag_i[NB_ANTENNAS_RX*NB_ANTENNAS_TX], *dl_ch_magb[NB_ANTENNAS_RX*NB_ANTENNAS_TX], *dl_ch_magb_i[NB_ANTENNAS_RX*NB_ANTENNAS_TX];
|
||||
int i;
|
||||
mxArray *tmp;
|
||||
|
||||
unsigned int nb_re_per_symbol, nb_re_per_frame;
|
||||
unsigned char symbol, dual_stream_UE;
|
||||
|
||||
LTE_DL_FRAME_PARMS *frame_parms;
|
||||
|
||||
/* Check proper input and output. */
|
||||
if(nrhs!=9)
|
||||
mexErrMsgTxt("9 inputs required.");
|
||||
else if(nlhs > 7)
|
||||
mexErrMsgTxt("Too many output arguments.");
|
||||
else if(!mxIsStruct(prhs[7]))
|
||||
mexErrMsgTxt("8th 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("Fourth argument must belong to Int16 class.");
|
||||
|
||||
if(!mxIsInt16(prhs[4]))
|
||||
mexErrMsgTxt("Fifth argument must belong to Int16 class.");
|
||||
|
||||
if(!mxIsInt16(prhs[5]))
|
||||
mexErrMsgTxt("Sixth argument must belong to Int16 class.");
|
||||
|
||||
if(!mxIsInt16(prhs[6]))
|
||||
mexErrMsgTxt("Seventh argument must belong to Int16 class.");
|
||||
|
||||
/* Allocate input */
|
||||
ymf0 = (int*) mxGetData(prhs[0]);
|
||||
ymf1 = (int*) mxGetData(prhs[1]);
|
||||
Hmag0 = (int*) mxGetData(prhs[2]);
|
||||
Hmag1 = (int*) mxGetData(prhs[3]);
|
||||
Hmag0b = (int*) mxGetData(prhs[4]);
|
||||
Hmag1b = (int*) mxGetData(prhs[5]);
|
||||
rho10 = (int*) mxGetData(prhs[6]);
|
||||
symbol = (unsigned char) mxGetScalar(prhs[8]);
|
||||
|
||||
|
||||
tmp = mxGetField(prhs[7],0,"nb_re_per_frame");
|
||||
|
||||
if (tmp == NULL) {
|
||||
mexErrMsgTxt("Non-existing field 'nb_re_per_frame' in input argument 8.");
|
||||
} 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[7],0,"nb_rb");
|
||||
|
||||
if (tmp == NULL) {
|
||||
mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 8.");
|
||||
} else {
|
||||
frame_parms->N_RB_DL = (unsigned char) mxGetScalar(tmp);
|
||||
}
|
||||
|
||||
tmp = mxGetField(prhs[7],0,"nb_antennas_rx");
|
||||
|
||||
if (tmp == NULL) {
|
||||
mexErrMsgTxt("Non-existing field 'nb_antennas_rx' in input argument 8.");
|
||||
} else {
|
||||
frame_parms->nb_antennas_rx = (unsigned char) mxGetScalar(tmp);
|
||||
}
|
||||
|
||||
tmp = mxGetField(prhs[7],0,"nb_antennas_tx_eNB");
|
||||
|
||||
if (tmp == NULL) {
|
||||
mexErrMsgTxt("Non-existing field 'nb_antennas_tx_eNB' in input argument 8.");
|
||||
} else {
|
||||
frame_parms->nb_antennas_tx_eNB = (unsigned char) mxGetScalar(tmp);
|
||||
}
|
||||
|
||||
nb_re_per_symbol = frame_parms->N_RB_DL*12;
|
||||
|
||||
if (frame_parms->nb_antennas_rx>1)
|
||||
dual_stream_UE = 1;
|
||||
|
||||
// Make copies of inputs to avoid override
|
||||
ymf0_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
|
||||
ymf1_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
|
||||
Hmag0_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
|
||||
Hmag1_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
|
||||
Hmag0b_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
|
||||
Hmag1b_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
|
||||
rho10_cpy = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
|
||||
|
||||
memcpy(ymf0_cpy,ymf0,NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2);
|
||||
memcpy(ymf1_cpy,ymf1,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2));
|
||||
memcpy(Hmag0_cpy,Hmag0,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2));
|
||||
memcpy(Hmag1_cpy,Hmag1,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2));
|
||||
memcpy(Hmag0b_cpy,Hmag0b,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2));
|
||||
memcpy(Hmag1b_cpy,Hmag1b,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2));
|
||||
memcpy(rho10_cpy,rho10,(NB_ANTENNAS_RX*NB_ANTENNAS_TX*nb_re_per_frame<<2));
|
||||
|
||||
// Assign correct inputs to algo
|
||||
rxdataF_comp[0] = ymf0_cpy;
|
||||
rxdataF_comp[1] = &ymf0_cpy[nb_re_per_frame];
|
||||
rxdataF_comp[2] = &ymf0_cpy[2*nb_re_per_frame];
|
||||
rxdataF_comp[3] = &ymf0_cpy[3*nb_re_per_frame];
|
||||
rxdataF_comp_i[0] = ymf1_cpy;
|
||||
rxdataF_comp_i[1] = &ymf1_cpy[nb_re_per_frame];
|
||||
rxdataF_comp_i[2] = &ymf1_cpy[2*nb_re_per_frame];
|
||||
rxdataF_comp_i[3] = &ymf1_cpy[3*nb_re_per_frame];
|
||||
rho_i[0] = rho10_cpy;
|
||||
rho_i[1] = &rho10_cpy[nb_re_per_frame];
|
||||
rho_i[2] = &rho10_cpy[2*nb_re_per_frame];
|
||||
rho_i[3] = &rho10_cpy[3*nb_re_per_frame];
|
||||
dl_ch_mag[0] = Hmag0_cpy;
|
||||
dl_ch_mag[1] = &Hmag0_cpy[nb_re_per_frame];
|
||||
dl_ch_mag[2] = &Hmag0_cpy[2*nb_re_per_frame];
|
||||
dl_ch_mag[3] = &Hmag0_cpy[3*nb_re_per_frame];
|
||||
dl_ch_magb[0] = Hmag0b_cpy;
|
||||
dl_ch_magb[1] = &Hmag0b_cpy[nb_re_per_frame];
|
||||
dl_ch_magb[2] = &Hmag0b_cpy[2*nb_re_per_frame];
|
||||
dl_ch_magb[3] = &Hmag0b_cpy[3*nb_re_per_frame];
|
||||
dl_ch_mag_i[0] = Hmag1_cpy;
|
||||
dl_ch_mag_i[1] = &Hmag1_cpy[nb_re_per_frame];
|
||||
dl_ch_mag_i[2] = &Hmag1_cpy[2*nb_re_per_frame];
|
||||
dl_ch_mag_i[3] = &Hmag1_cpy[3*nb_re_per_frame];
|
||||
dl_ch_magb_i[0] = Hmag1b_cpy;
|
||||
dl_ch_magb_i[1] = &Hmag1b_cpy[nb_re_per_frame];
|
||||
dl_ch_magb_i[2] = &Hmag1b_cpy[2*nb_re_per_frame];
|
||||
dl_ch_magb_i[3] = &Hmag1b_cpy[3*nb_re_per_frame];
|
||||
|
||||
/* Allocate Output */
|
||||
plhs[0] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
|
||||
ymf0_out = (int*) mxGetPr(plhs[0]);
|
||||
|
||||
plhs[1] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
|
||||
ymf1_out = (int*) mxGetPr(plhs[1]);
|
||||
|
||||
plhs[2] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
|
||||
Hmag0_out = (int*) mxGetPr(plhs[2]);
|
||||
|
||||
plhs[3] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
|
||||
Hmag0b_out = (int*) mxGetPr(plhs[3]);
|
||||
|
||||
plhs[4] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
|
||||
Hmag1_out = (int*) mxGetPr(plhs[4]);
|
||||
|
||||
plhs[5] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
|
||||
Hmag1b_out = (int*) mxGetPr(plhs[5]);
|
||||
|
||||
plhs[6] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);
|
||||
rho10_out = (int*) mxGetPr(plhs[6]);
|
||||
|
||||
#ifdef DEBUG_DETECTION_MRC
|
||||
mexPrintf("Got until here\n");
|
||||
#endif
|
||||
|
||||
|
||||
/* Algo */
|
||||
dlsch_detection_mrc(frame_parms,
|
||||
rxdataF_comp,
|
||||
rxdataF_comp_i,
|
||||
NULL,
|
||||
rho_i,
|
||||
dl_ch_mag,
|
||||
dl_ch_magb,
|
||||
dl_ch_mag_i,
|
||||
dl_ch_magb_i,
|
||||
symbol,
|
||||
frame_parms->N_RB_DL,
|
||||
dual_stream_UE);
|
||||
|
||||
#ifdef DEBUG_DETECTION_MRC
|
||||
mexPrintf("Got until here too\n");
|
||||
#endif
|
||||
|
||||
// memcpy copies bytes!
|
||||
memcpy(ymf0_out,&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&ymf0_out[nb_re_per_symbol],&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&ymf0_out[2*nb_re_per_symbol],&rxdataF_comp[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&ymf0_out[3*nb_re_per_symbol],&rxdataF_comp[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
|
||||
memcpy(ymf1_out,&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&ymf1_out[nb_re_per_symbol],&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&ymf1_out[2*nb_re_per_symbol],&rxdataF_comp_i[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&ymf1_out[3*nb_re_per_symbol],&rxdataF_comp_i[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(Hmag0_out,&dl_ch_mag[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&Hmag0_out[nb_re_per_symbol],&dl_ch_mag[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&Hmag0_out[2*nb_re_per_symbol],&dl_ch_mag[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&Hmag0_out[3*nb_re_per_symbol],&dl_ch_mag[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
|
||||
memcpy(Hmag0b_out, &dl_ch_magb[0][symbol*frame_parms->N_RB_DL*12], nb_re_per_symbol<<2);
|
||||
memcpy(&Hmag0b_out[nb_re_per_symbol],&dl_ch_magb[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&Hmag0b_out[2*nb_re_per_symbol],&dl_ch_magb[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&Hmag0b_out[3*nb_re_per_symbol],&dl_ch_magb[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
|
||||
memcpy(Hmag1_out,&dl_ch_mag_i[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&Hmag1_out[nb_re_per_symbol],&dl_ch_mag_i[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&Hmag1_out[2*nb_re_per_symbol],&dl_ch_mag_i[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&Hmag1_out[3*nb_re_per_symbol],&dl_ch_mag_i[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
|
||||
memcpy(Hmag1b_out, &dl_ch_magb_i[0][symbol*frame_parms->N_RB_DL*12], nb_re_per_symbol<<2);
|
||||
memcpy(&Hmag1b_out[nb_re_per_symbol],&dl_ch_magb_i[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&Hmag1b_out[2*nb_re_per_symbol],&dl_ch_magb_i[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&Hmag1b_out[3*nb_re_per_symbol],&dl_ch_magb_i[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
|
||||
memcpy(rho10_out, &rho_i[0][symbol*frame_parms->N_RB_DL*12], nb_re_per_symbol<<2);
|
||||
memcpy(&rho10_out[nb_re_per_symbol],&rho_i[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&rho10_out[2*nb_re_per_symbol],&rho_i[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
memcpy(&rho10_out[3*nb_re_per_symbol],&rho_i[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
|
||||
|
||||
|
||||
/* free */
|
||||
free(frame_parms);
|
||||
mxFree(ymf0_cpy);
|
||||
mxFree(ymf1_cpy);
|
||||
mxFree(Hmag0_cpy);
|
||||
mxFree(Hmag1_cpy);
|
||||
mxFree(Hmag0b_cpy);
|
||||
mxFree(Hmag1b_cpy);
|
||||
mxFree(rho10_cpy);
|
||||
}
|
||||
-129
@@ -1,129 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,225 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
#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];
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
%% 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);
|
||||
@@ -1,21 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
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
|
||||
|
||||
@@ -1,290 +0,0 @@
|
||||
%% Header
|
||||
%==========================================================================
|
||||
% This testbench simulates transmission mode 4 on subframe 7.
|
||||
% Results can be compared to "./dlsim -x5 -S7 -R1 -u1" with perfect chest
|
||||
% No OFDM Modulation and Demodulation is applied!
|
||||
% Only 5 MHz bandwidth simulated. The Channel is Rayleigh block-fading.
|
||||
%
|
||||
% The matrices ymf0, ymf1, etc are in the form samples x antennas.
|
||||
% More precisely:
|
||||
% row dimension = [Re Im Re Im ...]
|
||||
% col dimension: Heffx: [tx1->rx1 tx1->rx2 tx2->rx1 tx2->rx2]
|
||||
% ymfx, Hmagx, Hmagbx, rho10 : [rx1 rx2 rx3 rx4]
|
||||
%
|
||||
% The same random data is generate as in dlsim.c by setting the right
|
||||
% seed value simparms.tseeds.
|
||||
%
|
||||
%
|
||||
% Author: Sebastian Wagner
|
||||
% Date: 10-04-2013
|
||||
%
|
||||
%==========================================================================
|
||||
|
||||
clear all;
|
||||
close all;
|
||||
clear mex;
|
||||
|
||||
addpath('../../../PHY/LTE_TRANSPORT/mexfiles');
|
||||
addpath('../../../PHY/TOOLS/mexfiles');
|
||||
addpath('../../../SIMULATION/TOOLS/mexfiles');
|
||||
|
||||
% profile on;
|
||||
%% System parameters
|
||||
nt = 2; % number of transmit antennas
|
||||
nr = 2; % number of receive antennas
|
||||
N = 100; % number of frames (or subframes, codewords)
|
||||
nSNR = 1; % number of SNR points
|
||||
SNRdB = 5; % SNR per receive antenna in dB
|
||||
% nSNR = 13;
|
||||
% SNRdB = linspace(8,20,nSNR);
|
||||
MCS = [16 16]; % MCS for the 2 users
|
||||
j = sqrt(-1);
|
||||
amp = 1/32; % amplitude scaling for FXP conversion
|
||||
XFORMS = 0; % flag to activate graphics
|
||||
|
||||
% LLRs are computed for 8 RE make sure enough valid memory is allocated
|
||||
LLR_GUARD_SAMPLES = 8*6; % max mod_order 6 for 8 REs
|
||||
|
||||
%% Initialize simparms
|
||||
simparms = InitSimparms(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
|
||||
% The LLRs of subframe
|
||||
llr0 = zeros(simparms.codeword(1).G, 1,'int16');
|
||||
llr1 = zeros(simparms.codeword(2).G, 1,'int16');
|
||||
% received signal transformed to FXP
|
||||
y_fxp = zeros(simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,simparms.nb_re_per_frame,'int16');
|
||||
% FXP received signal with transformed dimensions
|
||||
y_fxp_t = zeros(2*simparms.nb_re_per_frame,simparms.NB_ANTENNAS_RX*simparms.NB_ANTENNAS_TX,'int16');
|
||||
|
||||
% MF output of desired user
|
||||
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');
|
||||
rho01 = 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');mu_mimo
|
||||
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')];
|
||||
|
||||
% Turbo encoding of 2 streams for 2 users
|
||||
edata0 = dlsch_encoding(data0,simparms,simparms.codeword(1)); % user 1
|
||||
edata1 = dlsch_encoding(data1,simparms,simparms.codeword(2)); % user 2
|
||||
|
||||
% Symbol mapping and 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);
|
||||
|
||||
%% 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
|
||||
H(1:nr,1:nt) = (randn(nr,nt) + j*randn(nr,nt))/sqrt(2);
|
||||
|
||||
%% PMI computation
|
||||
pmi = 1;
|
||||
r = H(:,2)'*H(:,1); % correlation
|
||||
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));
|
||||
|
||||
% normelized precoding vectors
|
||||
g0 = simparms.CB(:,pmi);
|
||||
g1 = simparms.CB(:,pmi_o);
|
||||
|
||||
%% Transmit signal (frequency domain)
|
||||
x = [g0,g1]*conj(s'); % E[|x|^2] = amp^2
|
||||
Ptx = sum(diag(x'*x))/simparms.nb_re; % average transmit power per RE
|
||||
|
||||
%% Noise
|
||||
sigma2 = (Ptx/cSNR);
|
||||
% E[|noise|^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);
|
||||
% real SNR per receive antenna
|
||||
SNR_real = 10*log10(Ptx / ((noise(1,:)*noise(1,:)')/simparms.nb_re));
|
||||
|
||||
%% Received signal
|
||||
y = H*x + noise; % flat-fading channel model
|
||||
|
||||
% Quantization
|
||||
y_fxp_data = int16(floor(y*pow2(15)));
|
||||
H_fxp = int16(fix(H*floor(amp*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
|
||||
llr0p = 1; % LLR pointer for codeword 0
|
||||
llr1p = 1; % LLR pointer for codeword 1
|
||||
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 stream
|
||||
[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
|
||||
[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);
|
||||
|
||||
%% LLR computation
|
||||
% first stream
|
||||
llr0_t = 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(llr0p:llr0p+length(llr0_t)-1,:) = llr0_t;
|
||||
llr0p = llr0p + length(llr0_t);
|
||||
|
||||
% second stream
|
||||
% compute conj. correlation term
|
||||
tmp = rho10(idxs:idxe,:);
|
||||
tmp(2:2:end) = -tmp(2:2:end);
|
||||
rho01(idxs:idxe,:) = tmp;
|
||||
|
||||
llr1_t = dlsch_mu_mimo_llr([ymf1(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
|
||||
[ymf0(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
|
||||
[Hmag1(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
|
||||
[Hmag0(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
|
||||
[rho01(idxs:idxe,1); zeros(LLR_GUARD_SAMPLES,1,'int16')],...
|
||||
simparms,...
|
||||
symbol-1);
|
||||
|
||||
llr1(llr1p:llr1p+length(llr1_t)-1,:) = llr1_t;
|
||||
llr1p = llr1p + length(llr1_t);
|
||||
|
||||
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)
|
||||
llr1 = -llr1; % invert (since no scrambling applied)
|
||||
ret0 = dlsch_decoding(llr0,simparms,simparms.codeword(1));
|
||||
ret1 = dlsch_decoding(llr1,simparms,simparms.codeword(2));
|
||||
|
||||
% Check if decoded correctly
|
||||
if (ret0 >= simparms.MAX_TURBO_ITERATIONS)
|
||||
simparms.frame_errors(iSNR,1) = simparms.frame_errors(iSNR,1) + 1;
|
||||
end
|
||||
if (ret1 >= simparms.MAX_TURBO_ITERATIONS)
|
||||
simparms.frame_errors(iSNR,2) = simparms.frame_errors(iSNR,2) + 1;
|
||||
end
|
||||
|
||||
end
|
||||
fprintf('********************SNR = %3.1f dB processed on %s********************\n',real(simparms.snr_db(iSNR)),datestr(now));
|
||||
fprintf('Errors: %d/%d\n',simparms.frame_errors(iSNR,1),N);
|
||||
fprintf('Errors: %d/%d\n',simparms.frame_errors(iSNR,2),N);
|
||||
end
|
||||
|
||||
%% Post Processing
|
||||
% total_frame_errors = sum(frame_errors,2);
|
||||
% fer = total_frame_errors/N;
|
||||
% figure; semilogy(SNRdB,fer); grid;
|
||||
%
|
||||
% disp(fer);
|
||||
|
||||
% profile viewer
|
||||
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
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
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
%% 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
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
#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;
|
||||
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*******************************************************************************
|
||||
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"
|
||||
@@ -1,409 +0,0 @@
|
||||
/*
|
||||
* @(#)mex.h generated by: makeheader 5.1.5 Mon Jun 29 15:54:48 2009
|
||||
*
|
||||
* built from: ../../src/include/copyright.h
|
||||
* ../../src/include/pragma_interface.h
|
||||
* mex_typedefs.h
|
||||
* mexfunction.hpp
|
||||
* fmexapi.cpp
|
||||
* fmexapi_stdcall.cpp
|
||||
* globals.cpp
|
||||
* mexapi.cpp
|
||||
* mexcbk.cpp
|
||||
* mexdispatch.cpp
|
||||
* mexintrf.cpp
|
||||
* mexdbg.h
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3))
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#ifndef mex_h
|
||||
#define mex_h
|
||||
|
||||
|
||||
/*
|
||||
* Copyright 1984-2003 The MathWorks, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* Copyright 2003-2006 The MathWorks, Inc. */
|
||||
|
||||
/* Only define EXTERN_C if it hasn't been defined already. This allows
|
||||
* individual modules to have more control over managing their exports.
|
||||
*/
|
||||
#ifndef EXTERN_C
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN_C extern "C"
|
||||
#else
|
||||
#define EXTERN_C extern
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Copyright 1999-2007 The MathWorks, Inc. */
|
||||
|
||||
/* $Revision: 1.7.4.4 $ */
|
||||
#ifndef mex_typedefs_h
|
||||
#define mex_typedefs_h
|
||||
|
||||
typedef struct impl_info_tag *MEX_impl_info;
|
||||
|
||||
#include "matrix.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
typedef void (*mex_exit_fn)(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct mexGlobalTableEntry_Tag {
|
||||
const char *name; /* The name of the global */
|
||||
mxArray **variable; /* A pointer to the variable */
|
||||
} mexGlobalTableEntry, *mexGlobalTable;
|
||||
|
||||
#ifdef _WIN32
|
||||
#define cicompare(s1,s2) utStrcmpi((s1),(s2))
|
||||
#else
|
||||
#define cicompare(s1,s2) strcmp((s1),(s2))
|
||||
#endif
|
||||
#define cscompare(s1,s2) strcmp((s1),(s2))
|
||||
|
||||
typedef struct mexFunctionTableEntry_tag {
|
||||
const char * name;
|
||||
mxFunctionPtr f;
|
||||
int nargin;
|
||||
int nargout;
|
||||
struct _mexLocalFunctionTable *local_function_table;
|
||||
} mexFunctionTableEntry, *mexFunctionTable;
|
||||
|
||||
typedef struct _mexLocalFunctionTable {
|
||||
size_t length;
|
||||
mexFunctionTable entries;
|
||||
} _mexLocalFunctionTable, *mexLocalFunctionTable;
|
||||
|
||||
typedef struct {
|
||||
void (*initialize)(void);
|
||||
void (*terminate)(void);
|
||||
} _mexInitTermTableEntry, *mexInitTermTableEntry;
|
||||
|
||||
#define MEX_INFORMATION_VERSION 1
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int file_function_table_length;
|
||||
mexFunctionTable file_function_table;
|
||||
int global_variable_table_length;
|
||||
mexGlobalTable global_variable_table;
|
||||
int npaths;
|
||||
const char ** paths;
|
||||
int init_term_table_length;
|
||||
mexInitTermTableEntry init_term_table;
|
||||
} _mex_information, *mex_information;
|
||||
|
||||
typedef mex_information(*fn_mex_file)(void);
|
||||
|
||||
typedef void (*fn_clean_up_after_error)(void);
|
||||
typedef const char *(*fn_simple_function_to_string)(mxFunctionPtr f);
|
||||
|
||||
typedef void (*fn_mex_enter_mex_library)(mex_information x);
|
||||
typedef fn_mex_enter_mex_library fn_mex_exit_mex_library;
|
||||
|
||||
typedef mexLocalFunctionTable (*fn_mex_get_local_function_table)(void);
|
||||
typedef mexLocalFunctionTable (*fn_mex_set_local_function_table)(mexLocalFunctionTable);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef EXPORT_EXTERN_C
|
||||
# define MEXFUNCTION_LINKAGE EXPORT_EXTERN_C
|
||||
#else
|
||||
# ifdef MW_NEEDS_VERSION_H
|
||||
# include "version.h"
|
||||
# define MEXFUNCTION_LINKAGE EXPORT_EXTERN_C
|
||||
# else
|
||||
# define MEXFUNCTION_LINKAGE EXTERN_C
|
||||
# endif
|
||||
#endif
|
||||
|
||||
MEXFUNCTION_LINKAGE
|
||||
/*
|
||||
* mexFunction is the user-defined C routine that is called upon invocation
|
||||
* of a MEX-function.
|
||||
*/
|
||||
void mexFunction(
|
||||
int nlhs, /* number of expected outputs */
|
||||
mxArray *plhs[], /* array of pointers to output arguments */
|
||||
int nrhs, /* number of inputs */
|
||||
const mxArray *prhs[] /* array of pointers to input arguments */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* This header file "mex.h" declares all the types, macros and
|
||||
* functions necessary to interface mex files with the current
|
||||
* version of MATLAB. See the release notes for information on
|
||||
* supporting syntax from earlier versions.
|
||||
*/
|
||||
#include "matrix.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Issue error message and return to MATLAB prompt
|
||||
*/
|
||||
EXTERN_C void mexErrMsgTxt(
|
||||
const char *error_msg /* string with error message */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* Issue formatted error message with corresponding error identifier and return to MATLAB
|
||||
* prompt.
|
||||
*/
|
||||
EXTERN_C void mexErrMsgIdAndTxt(
|
||||
const char * identifier, /* string with error message identifier */
|
||||
const char * err_msg, /* string with error message printf-style format */
|
||||
... /* any additional arguments */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* Invoke an unidentified warning. Such warnings can only be affected by the M-code
|
||||
* 'warning * all', since they have no specific identifier. See also mexWarnMsgIdAndTxt.
|
||||
*/
|
||||
EXTERN_C void mexWarnMsgTxt(
|
||||
const char *warn_msg /* string with warning message */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* Invoke a warning with message identifier 'identifier' and message derived from 'fmt' and
|
||||
* subsequent arguments. The warning may either get printed as is (if it is set to 'on'), or
|
||||
* not actually get printed (if set to 'off'). See 'help warning' in MATLAB for more
|
||||
* details.
|
||||
*/
|
||||
EXTERN_C void mexWarnMsgIdAndTxt(
|
||||
const char * identifier, /* string with warning message identifer */
|
||||
const char * warn_msg, /* string with warning message printf-style format */
|
||||
... /* any additional arguments */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* mex equivalent to MATLAB's "disp" function
|
||||
*/
|
||||
EXTERN_C int mexPrintf(
|
||||
const char *fmt, /* printf style format */
|
||||
... /* any additional arguments */
|
||||
);
|
||||
|
||||
|
||||
#define printf mexPrintf
|
||||
|
||||
|
||||
/*
|
||||
* Remove all components of an array plus the array header itself
|
||||
* from MATLAB's memory allocation list. The array will now
|
||||
* persist between calls to the mex function. To destroy this
|
||||
* array, you will need to explicitly call mxDestroyArray().
|
||||
*/
|
||||
EXTERN_C void mexMakeArrayPersistent(
|
||||
mxArray *pa /* pointer to array */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* Remove memory previously allocated via mxCalloc from MATLAB's
|
||||
* memory allocation list. To free this memory, you will need to
|
||||
* explicitly call mxFree().
|
||||
*/
|
||||
EXTERN_C void mexMakeMemoryPersistent(void *ptr);
|
||||
|
||||
|
||||
/*
|
||||
* mex equivalent to MATLAB's "set" function
|
||||
*/
|
||||
EXTERN_C int mexSet(double handle, const char *property, mxArray *value);
|
||||
|
||||
|
||||
/* API interface which mimics the "get" function */
|
||||
EXTERN_C const mxArray *mexGet(double handle, const char *property);
|
||||
|
||||
|
||||
/*
|
||||
* call MATLAB function
|
||||
*/
|
||||
EXTERN_C int mexCallMATLAB(
|
||||
int nlhs, /* number of expected outputs */
|
||||
mxArray *plhs[], /* pointer array to outputs */
|
||||
int nrhs, /* number of inputs */
|
||||
mxArray *prhs[], /* pointer array to inputs */
|
||||
const char *fcn_name /* name of function to execute */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* call MATLAB function with Trap
|
||||
*/
|
||||
EXTERN_C mxArray *mexCallMATLABWithTrap(
|
||||
int nlhs, /* number of expected outputs */
|
||||
mxArray *plhs[], /* pointer array to outputs */
|
||||
int nrhs, /* number of inputs */
|
||||
mxArray *prhs[], /* pointer array to inputs */
|
||||
const char *fcn_name /* name of function to execute */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* set or clear mexCallMATLAB trap flag (if set then an error in
|
||||
* mexCallMATLAB is caught and mexCallMATLAB will return a status value,
|
||||
* if not set an error will cause control to revert to MATLAB)
|
||||
*/
|
||||
EXTERN_C void mexSetTrapFlag(int flag);
|
||||
|
||||
|
||||
/*
|
||||
* Print an assertion-style error message and return control to the
|
||||
* MATLAB command line.
|
||||
*/
|
||||
EXTERN_C void mexPrintAssertion(
|
||||
const char *test,
|
||||
const char *fname,
|
||||
int linenum,
|
||||
const char *message);
|
||||
|
||||
|
||||
/*
|
||||
* Tell whether or not a mxArray is in MATLAB's global workspace.
|
||||
*/
|
||||
EXTERN_C bool mexIsGlobal(const mxArray *pA);
|
||||
|
||||
|
||||
/*
|
||||
* Place a copy of the array value into the specified workspace with the
|
||||
* specified name
|
||||
*/
|
||||
EXTERN_C int mexPutVariable(
|
||||
const char *workspace,
|
||||
const char *name,
|
||||
const mxArray *parray /* matrix to copy */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* return a pointer to the array value with the specified variable
|
||||
* name in the specified workspace
|
||||
*/
|
||||
EXTERN_C const mxArray *mexGetVariablePtr(
|
||||
const char *workspace,
|
||||
const char *name /* name of symbol */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* return a copy of the array value with the specified variable
|
||||
* name in the specified workspace
|
||||
*/
|
||||
EXTERN_C mxArray *mexGetVariable(
|
||||
const char *workspace,
|
||||
const char *name /* name of variable in question */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* Lock a MEX-function so that it cannot be cleared from memory.
|
||||
*/
|
||||
EXTERN_C void mexLock(void);
|
||||
|
||||
|
||||
/*
|
||||
* Unlock a locked MEX-function so that it can be cleared from memory.
|
||||
*/
|
||||
EXTERN_C void mexUnlock(void);
|
||||
|
||||
|
||||
/*
|
||||
* Return true if the MEX-function is currently locked, false otherwise.
|
||||
*/
|
||||
EXTERN_C bool mexIsLocked(void);
|
||||
|
||||
|
||||
/*
|
||||
* Return the name of a the MEXfunction currently executing.
|
||||
*/
|
||||
EXTERN_C const char *mexFunctionName(void);
|
||||
|
||||
|
||||
/*
|
||||
* Parse and execute MATLAB syntax in string. Returns zero if successful,
|
||||
* and a non zero value if an error occurs.
|
||||
*/
|
||||
EXTERN_C int mexEvalString(
|
||||
const char *str /* matlab command string */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* Parse and execute MATLAB syntax in string. Returns NULL if successful,
|
||||
* and an MException if an error occurs.
|
||||
*/
|
||||
EXTERN_C mxArray* mexEvalStringWithTrap(
|
||||
const char *str /* matlab command string */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* Register Mex-file's At-Exit function (accessed via MEX callback)
|
||||
*/
|
||||
EXTERN_C int mexAtExit(mex_exit_fn exit_fcn );
|
||||
|
||||
|
||||
/* Copyright 1996-2006 The MathWorks, Inc. */
|
||||
|
||||
/* $Revision: 1.9.4.3 $ */
|
||||
|
||||
/*
|
||||
* Revisit. Conflicts with 32-bit compatibility API. XXX
|
||||
*/
|
||||
#if 0
|
||||
|
||||
#ifdef ARGCHECK
|
||||
|
||||
#include "mwdebug.h" /* Prototype _d versions of API functions */
|
||||
|
||||
#define mexAtExit(exitfcn) mexAtExit_d(exitfcn, __FILE__, __LINE__)
|
||||
#define mexCallMATLAB(nlhs, plhs, nrhs, prhs, fcn) mexCallMATLAB_d(nlhs, plhs, nrhs, prhs, fcn, __FILE__, __LINE__)
|
||||
#define mexErrMsgTxt(errmsg) mexErrMsgTxt_d(errmsg, __FILE__, __LINE__)
|
||||
#define mexEvalString(str) mexEvalString_d(str, __FILE__, __LINE__)
|
||||
#define mexGet(handle, property) mexGet_d(handle, property, __FILE__, __LINE__)
|
||||
#define mexGetVariable(workspace, name) mexGetVariable_d(workspace, name, __FILE__, __LINE__)
|
||||
#define mexGetVariablePtr(workspace, name) mexGetVariablePtr_d(workspace, name, __FILE__, __LINE__)
|
||||
#define mexIsGlobal(pa) mexIsGlobal_d(pa, __FILE__, __LINE__)
|
||||
#define mexMakeArrayPersistent(pa) mexMakeArrayPersistent_d(pa, __FILE__, __LINE__)
|
||||
#define mexMakeMemoryPersistent(ptr) mexMakeMemoryPersistent_d(ptr, __FILE__, __LINE__)
|
||||
#define mexPutVariable(workspace, name, pa) mexPutVariable_d(workspace, name, pa, __FILE__, __LINE__)
|
||||
#define mexSet(handle, property, value) mexSet_d(handle, property, value, __FILE__, __LINE__)
|
||||
#define mexSetTrapFlag(value) mexSetTrapFlag_d(value, __FILE__, __LINE__)
|
||||
#define mexSubsAssign(plhs, sub, nsubs, rhs) mexSubsAssign_d(plhs, sub, nsubs, rhs, __FILE__, __LINE__)
|
||||
#define mexSubsReference(prhs, sub, nsubs) mexSubsReference_d(prhs, sub, nsubs, __FILE__, __LINE__)
|
||||
#define mexWarnMsgTxt(str) mexWarnMsgTxt_d(str, __FILE__, __LINE__)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* mex_h */
|
||||
Reference in New Issue
Block a user