📄 turboencoder.c
字号:
/*****************************************************************************************************
***************function RSCencoder
***************功能说明:专用RSC卷积码编码器 固定多项式。
***************主要参数、变量说明:无设置参数
***************输入端口说明:端口数1,动态确定输入宽度(帧格式),动态确定类型(建议上一模块为整型)
***************输出端口说明:端口数1,动态确定输出宽度,输出类型为整型
***************采样时间说明:继承前模块
***************状态说明:无离散状态,无连续状态,存在直接反馈
***************Copyright 2004-2008
***************$Revision: 1.0 $ $Date: 2004/11/04 22:55 $ 函数版
*******************************************************************************************************/
#define M 3
#define tail_num 12 //附加的尾比特数
#define get_data_length ssGetInputPortWidth(S,0)
#define inputdata_type double
#define outputdata_type double
#define S_FUNCTION_NAME Turboencoder
#define S_FUNCTION_LEVEL 2
#include "stdlib.h"
#include "stdio.h"
#include "simstruc.h"
/*====================*
* S-function methods *
*====================*/
int gcd(int x,int y);
void interweave_pattern( int data_len, int *p_inter_perm);
void TD_SCDMA_RSC_encoder(inputdata_type *p_data,inputdata_type *p_parity, int data_len);
void TD_SCDMA_turbo_encoder( int data_len, int *p_inter_perm,inputdata_type *p_data,outputdata_type *p_code);
/*******************************************************************************************
***********************数据大小初始化*******************************************************
********************************************************************************************/
static void mdlInitializeSizes(SimStruct *S)
{
/* See sfuntmpl_doc.c for more details on the macros below */
/***************************设置参数个数*****************************************************/
ssSetNumSFcnParams(S, 0); /* Number of expected parameters */
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
/* Return if number of expected != number of actual parameters */
return;
}
/***************************设置离散以及连续状态个数********************************************/
ssSetNumContStates(S, 0);
ssSetNumDiscStates(S, 1);
/***************************设置输入端口的属性*****************************************************/
if (!ssSetNumInputPorts(S, 1)) return;
//ssSetInputPortWidth(S, 0,DYNAMICALLY_SIZED);
if(!ssSetInputPortDimensionInfo( S, 0, DYNAMIC_DIMENSION)) return;
ssSetInputPortDataType( S, 0, DYNAMICALLY_TYPED);
//ssSetInputPortDataType(S, 0, SS_INT16);
ssSetInputPortFrameData(S, 0, FRAME_YES);
/***************************设置输出端口的属性个数**************************************************/
if (!ssSetNumOutputPorts(S, 1)) return;
//ssSetOutputPortWidth(S, 0, DYNAMICALLY_SIZED);
if(!ssSetOutputPortDimensionInfo(S, 0, DYNAMIC_DIMENSION)) return;
ssSetOutputPortDataType( S, 0, DYNAMICALLY_TYPED);
//ssSetOutputPortDataType( S, 0, SS_INT16);
ssSetOutputPortFrameData(S, 0, FRAME_YES);
/***************************设置直接反馈**************************************************/
/*
* Set direct feedthrough flag (1=yes, 0=no).
* A port has direct feedthrough if the input is used in either
* the mdlOutputs or mdlGetTimeOfNextVarHit functions.
* See matlabroot/simulink/src/sfuntmpl_directfeed.txt.
*/
ssSetInputPortDirectFeedThrough(S, 0, 1);
/***************************设置存储特性**************************************************/
ssSetInputPortRequiredContiguous(S, 0, true); /*direct input signal access*/
/***************************设置采样时间个数**********************************************/
ssSetNumSampleTimes(S, 1);
/***************************设置工作向量*************************************************/
ssSetNumRWork(S, 0);
ssSetNumIWork(S, DYNAMICALLY_SIZED);
ssSetNumPWork(S, DYNAMICALLY_SIZED);
ssSetNumModes(S, 0);
/***************************设置过零采样的状态个数*****************************************/
ssSetNumNonsampledZCs(S, 0);
/***************************设置s函数工作选项***********************************************/
ssSetOptions(S, SS_OPTION_WORKS_WITH_CODE_REUSE |
SS_OPTION_EXCEPTION_FREE_CODE |
SS_OPTION_USE_TLC_WITH_ACCELERATOR);
}
/*******************************************************************************************
***********************设定采样时间*********************************************************
********************************************************************************************/
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0,INHERITED_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
}
#if defined(MATLAB_MEX_FILE)
#define MDL_SET_WORK_WIDTHS /* Change to #undef to remove function */
mdlSetWorkWidths(SimStruct *S)
{
ssSetNumIWork(S,get_data_length);
ssSetNumPWork(S,1);
}
#endif
#define MDL_START /* Change to #undef to remove function */
#if defined(MDL_START)
static void mdlStart(SimStruct *S)
{ int i;
int data_len;
inputdata_type *p_data;
// outputdata_type *p_code;
data_len=get_data_length;
p_data=(inputdata_type*)calloc(data_len+M,sizeof(inputdata_type));
//p_code=(outputdata_type*)calloc(3*data_len+4*M,sizeof(outputdata_type));
if(p_data==0)
{
printf("分配指针为空\n");
exit(0);
}
ssGetPWork(S)[0]=p_data;
//ssGetPWork(S)[1]=p_code;
interweave_pattern( data_len, ssGetIWork(S));
}
#endif /* MDL_START */
/*******************************************************************************************
***********************输出数据计算*********************************************************
********************************************************************************************/
static void mdlOutputs(SimStruct *S, int_T tid)
{
int i;
int data_len;
int code_length;
int *p_inter_perm;
inputdata_type *p_data,*p_datab,*ub;
outputdata_type *p_code;
inputdata_type *u = ssGetInputPortSignal(S,0);//输入信号的指针
outputdata_type *y = ssGetOutputPortSignal(S,0);//输出信号的指针
ub=u;
data_len=get_data_length;
code_length=3*data_len+tail_num;
p_data=ssGetPWork(S)[0];
p_code=y;//ssGetPWork(S)[1];
p_datab=p_data;
for(i=0;i<data_len;i++)
*(p_datab++)=*(ub++);
p_inter_perm=ssGetIWork(S);
TD_SCDMA_turbo_encoder( data_len, p_inter_perm,p_data,p_code);
}
/*******************************************************************************************
***********************确定输入端口的数据宽度***********************************************
********************************************************************************************/
#if defined(MATLAB_MEX_FILE)
#define MDL_SET_INPUT_PORT_DIMENSION_INFO
/* Function: mdlSetInputPortDimensionInfo ====================================
* Abstract:
* This routine is called with the candidate dimensions for an input port
* with unknown dimensions. If the proposed dimensions are acceptable, the
* routine should go ahead and set the actual port dimensions.
* If they are unacceptable an error should be generated via
* ssSetErrorStatus.
* Note that any other input or output ports whose dimensions are
* implicitly defined by virtue of knowing the dimensions of the given port
* can also have their dimensions set.
*/
static void mdlSetInputPortDimensionInfo(SimStruct *S,
int_T port,
const DimsInfo_T *dimsInfo)
{ DECL_AND_INIT_DIMSINFO(oDims);
int xg_outdims[2];
if (!ssSetInputPortDimensionInfo(S, port, dimsInfo)) return;
oDims.width = 3*(dimsInfo->width)+4*M;
oDims.numDims = 2;
xg_outdims[0] = 3*(dimsInfo->dims[0])+4*M;
xg_outdims[1] = dimsInfo->dims[1];
oDims.dims = &(xg_outdims[0]);
if(!ssSetInputPortDimensionInfo(S, 0, dimsInfo)) return;
ssSetOutputPortDimensionInfo(S, port, &oDims);
}
#endif
/*******************************************************************************************
***********************确定输出端口的数据宽度***********************************************
********************************************************************************************/
#define MDL_SET_OUTPUT_PORT_DIMENSION_INFO
#if defined(MDL_SET_OUTPUT_PORT_DIMENSION_INFO) && defined(MATLAB_MEX_FILE)
/* Function: mdlSetOutputPortDimensionInfo ===================================
* Abstract:
* This routine is called with the candidate dimensions for an output port
* with unknown dimensions. If the proposed dimensions are acceptable, the
* routine should go ahead and set the actual port dimensions.
* If they are unacceptable an error should be generated via
* ssSetErrorStatus.
* Note that any other input or output ports whose dimensions are
* implicitly defined by virtue of knowing the dimensions of the given
* port can also have their dimensions set.
*/
static void mdlSetOutputPortDimensionInfo(SimStruct *S,
int_T port,
const DimsInfo_T *dimsInfo)
{
DECL_AND_INIT_DIMSINFO(inDims);
int xg_indims[2];
if (!ssSetOutputPortDimensionInfo(S, port, dimsInfo)) return;
inDims.width = (dimsInfo->width-4*M)/3;
inDims.numDims = 2;
xg_indims[0] = (dimsInfo->dims[0]-4*M)/3;
xg_indims[1] = dimsInfo->dims[1];
inDims.dims = &(xg_indims[0]);
if(!ssSetInputPortDimensionInfo(S, port, &inDims)) return;
ssSetOutputPortDimensionInfo(S, port, dimsInfo);
}
#endif
/* Function: mdlTerminate =====================================================
* Abstract:
* In this function, you should perform any actions that are necessary
* at the termination of a simulation. For example, if memory was
* allocated in mdlStart, this is the place to free it.
*/
static void mdlTerminate(SimStruct *S)
{
free(ssGetPWork(S)[0]);
}
/*======================================================*
* See sfuntmpl_doc.c for the optional S-function methods *
*======================================================*/
/*=============================*
* Required S-function trailer *
*=============================*/
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif
/*******************************************************************************************
***********************求最大公约数*********************************************************
********************************************************************************************/
int gcd(int x,int y) /* the function used to calculate the maximal common divisor*/
{
int i,z,temp;
if (x>y)
{temp=x;
x=y;
y=temp;}
z=1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -