📄 simrscbv.c
字号:
/*============================================================================
* Syntax:[sys, x0, str, ts] = simrscbv(t, x, u, flag, n, k, pg, tp, dim)
* SIMRSCBV SIMULINK S-function for Reed-Solomon code, binary vector version
* This file is designed to be used in a SIMULINK S-Function block.
* This function will encode the k*dim input binary vector to a n*m
* binary code word.
* Parameters: n -- length of code word.
* k -- length of message.
* pg-- generator polynomial
* tp-- list of all GF(2^M) elements. n=2^M-1.
* dim -- M.
*
* The output has length n*dim.
*============================================================================
* Original designed by Wes Wang,
* Jun Wu, The Mathworks, Inc.
* Feb-07, 1996
*
* Copyright (c) 1996 by The MAthWorks, Inc.
* All Rights Reserved
* $Revision: 1.1 $ $Date: 1996/04/01 19:04:50 $
*============================================================================
*/
#define S_FUNCTION_NAME simrscbv
/* need to include simstruc.h for the definition of the SimStruct and
* its associated macro definitions.
*/
#include "simstruc.h"
#include "gflib.c"
#ifdef MATLAB_MEX_FILE
#include "mex.h" /* needed for declaration of mexErrMsgTxt */
#endif
#define NUM_ARGS 5 /* five additional input arguments */
#define N ssGetArg(S,0)
#define K ssGetArg(S,1)
#define PG ssGetArg(S,2)
#define P ssGetArg(S,3)
#define DIM ssGetArg(S,4)
#define Prim 2
/*elseif flag == 0
* if 2^dim-1 ~= n
* error('Reed-Solomon encode has illegal code word length')
* end;
* sys(1) = 0; % no continuous state
* sys(2) = 0;
* sys(3) = n * dim; % number of output, code word length plus one.
* sys(4) = k * dim + 1; % number of input, message length.
* sys(5) = 0;
* sys(6) = 1; % direct through flag.
* sys(7) = 1; % one sample rate
* x0 = [];
* ts = [-1, 0];
*else
* sys = [];
*end;
*/
static void mdlInitializeSizes(S)
SimStruct *S;
{
int i, np, len_pg;
int n = (int)mxGetPr(N)[0];
int k = (int)mxGetPr(K)[0];
int dim = (int)mxGetPr(DIM)[0];
len_pg = mxGetM(PG)*mxGetN(PG);
np = 1;
for(i=0; i < dim; i++)
np = np*2;
if ( np-1 != n ){
#ifdef MATLAB_MEX_FILE
mexErrMsgTxt("Reed-Solomon decode has illegal code word length");
#endif
}
ssSetNumContStates( S, 0); /* no continuous states */
ssSetNumDiscStates( S, 0); /* no discrete states */
ssSetNumOutputs( S, n*dim); /* number of output, code word length plus one*/
ssSetNumInputs( S, k*dim+1); /* number of inputs, message length*/
ssSetDirectFeedThrough( S, 1); /* direct feedthrough flag */
ssSetNumSampleTimes( S, 1); /* number of sample times */
ssSetNumInputArgs( S, NUM_ARGS); /* number of input arguments*/
ssSetNumRWork( S, 0);
ssSetNumIWork( S, (2*n+3)*dim+len_pg+k+3*n+6);
/* (n+1)*dim --- *pp
* len_pg-1 ------- *pgg
* k*dim ---------- *tmpRoom
* k -------------- *pDec
* n -------------- *msg
* 1 -------------- *tmpMul
* 1 -------------- *len
* n+3+dim -------- Iwork for gfpmul()
* n+2+dim -------- Iwork for gfpadd()
* (n-k)*dim ------ tmpOut
*/
ssSetNumPWork( S, 0);
}
/*
* mdlInitializeConditions - initialize the states
* Initialize the states, Integers and real-numbers
*/
static void mdlInitializeConditions(x0, S)
double *x0;
SimStruct *S;
{
int i, len_pg;
int n, k, dim;
int *pp, *pgg, *tmpRoom, *pDec, *msg, *tmpMul;
int *len, *IworkMul, *IworkAdd, *tmpOut;
double *p, *pg;
pg = mxGetPr(PG);
p = mxGetPr(P);
len_pg = mxGetM(PG)*mxGetN(PG);
n = (int)mxGetPr(N)[0];
k = (int)mxGetPr(K)[0];
dim = (int)mxGetPr(DIM)[0];
pp = ssGetIWork(S);
pgg = ssGetIWork(S)+(n+1)*dim;
tmpRoom = ssGetIWork(S)+(n+1)*dim+len_pg-1;
pDec = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim;
msg = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim+k;
tmpMul = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim+k+n;
len = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim+k+n+1;
IworkMul = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim+k+n+2;
IworkAdd = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim+k+n+2+n+3+dim;
tmpOut = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim+k+n+2+n+3+dim+n+2+dim;
for( i=0; i<(n+1)*dim; i++ )
pp[i] = (int)p[i];
for(i=0; i<len_pg-1; i++)
pgg[i] = (int)pg[len_pg-2-i];
}
/*
* mdlInitializeSampleTimes - initialize the sample times array
*
* This function is used to specify the sample time(s) for your S-function.
* If your S-function is continuous, you must specify a sample time of 0.0.
* Sample times must be registered in ascending order.
*/
static void mdlInitializeSampleTimes(S)
SimStruct *S;
{
ssSetSampleTimeEvent(S, 0, -1.0);
ssSetOffsetTimeEvent(S, 0, 0.0);
}
/*if (flag == 3)
* % refresh the state only when there is a trigger signal
* len_u = length(u);
* if u(len_u)
* % main calculation
* t2 = n - k;
* pgg = fliplr(pg(1:length(pg)-1)); % pg is a monic polynomial
* msg = bi2de(vec2mat(u(1 : len_u-1), dim)) - 1;
* msg = [flipud(msg); -ones(t2,1)];
* sz = (len_u - 1) /dim;
* for main_j = 1 : sz
* if msg(main_j)>= 0
* for main_k = 1: t2
* msg(main_j + main_k) = gfadd(msg(main_j + main_k), gfmul(msg(main_j), pgg(main_k), tp), tp);
* end;
* end;
* end;
* sys = [flipud(msg(sz+1:n))+1];
* indx = find(~(sys >= 0));
* sys(indx) = indx - indx;
* sys = de2bi(sys, dim)';
* sys = sys(:);
* sys = [sys; u(1:len_u - 1)];
*% disp(['should output ', num2str(n * dim), ' it is now ', num2str(length(sys))])
* else
* % if there is no trigger, no calculation.
* if t <= 0
* sys = zeros(n * dim, 1);
* end;
* end;
*/
/* mdlOutputs - compute the outputs
* In this function, you compute the outputs of your S-function
* block. The outputs are placed in the y variable.
*/
static void mdlOutputs(y, x, u, S, tid)
double *y, *x, *u;
SimStruct *S;
int tid;
{
int i, j, len_pg, t2, tmp;
int main_j, main_k;
int n, k, dim;
int *pp, *pgg, *tmpRoom, *pDec, *msg, *tmpMul;
int *len, *IworkMul, *IworkAdd, *tmpOut;
double *p, *pg;
double t;
t = ssGetT(S);
pg = mxGetPr(PG);
p = mxGetPr(P);
len_pg= mxGetM(PG)*mxGetN(PG);
n = (int)mxGetPr(N)[0];
k = (int)mxGetPr(K)[0];
dim = (int)mxGetPr(DIM)[0];
pp = ssGetIWork(S);
pgg = ssGetIWork(S)+(n+1)*dim;
tmpRoom = ssGetIWork(S)+(n+1)*dim+len_pg-1;
pDec = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim;
msg = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim+k;
tmpMul = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim+k+n;
len = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim+k+n+1;
IworkMul = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim+k+n+2;
IworkAdd = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim+k+n+2+n+3+dim;
tmpOut = ssGetIWork(S)+(n+1)*dim+len_pg-1+k*dim+k+n+2+n+3+dim+n+2+dim;
if( u[k*dim] != 0 ){
for( i=0; i<(n+1)*dim; i++ )
pp[i] = (int)p[i];
for(i=0; i<len_pg-1; i++)
pgg[i] = (int)pg[len_pg-2-i];
t2 = n - k;
for(i=0; i < dim; i++){
for(j=0; j < k; j++)
tmpRoom[i*k+j] = (int)u[i+j*dim];
}
bi2de(tmpRoom, k, dim, Prim, pDec);
for(i=0; i < n; i++){
if(i < k)
msg[i] = pDec[k-1-i]-1;
else
msg[i] = -1;
}
for(main_j=0; main_j < k; main_j++){
if (msg[main_j] >= 0){
for(main_k=0; main_k < t2; main_k++){
tmpMul[0] = 0;
len[0] = 1;
gfpmul(&msg[main_j],1,&pgg[main_k],1,pp,n+1,dim,tmpMul,len,IworkMul);
gfpadd(&msg[main_j+main_k+1],1,tmpMul,1,pp,n+1,dim,&msg[main_j+main_k+1],len,IworkAdd);
}
}
}
for(i=0; i < n-k; i++){
if( msg[n-1-i]+1 >= 0 )
tmp = msg[n-1-i]+1;
else
tmp = 0;
for(j=0; j < dim; j++){
tmpOut[i*dim+j] = tmp % Prim;
if(j < dim-1)
tmp = (int)tmp/Prim;
}
}
for(i=0; i<(n-k)*dim; i++)
y[i] = (double)tmpOut[i];
for(i=0; i < k*dim; i++)
y[i+(n-k)*dim] = u[i];
}else{
if ( t <= 0 ){
for(i=0; i < n*dim; i++)
y[i] = 0.0;
}
}
}
/*
* mdlUpdate - perform action at major integration time step
*
* This function is called once for every major integration time step.
* Discrete states are typically updated here, but this function is useful
* for performing any tasks that should only take place once per integration
* step.
*/
static void mdlUpdate(x, u, S, tid)
double *x, *u;
SimStruct *S;
int tid;
{
}
/*
* mdlDerivatives - compute the derivatives
*
* In this function, you compute the S-function block's derivatives.
* The derivatives are placed in the dx variable.
*/
static void mdlDerivatives(dx, x, u, S, tid)
double *dx, *x, *u;
SimStruct *S;
int tid;
{
}
/*
* mdlTerminate - called when the simulation is terminated.
*
* In this function, you should perform any actions that are necessary
* at the termination of a simulation. For example, if memory was allocated
* in mdlInitializeConditions, this is the place to free it.
*/
static void mdlTerminate(S)
SimStruct *S;
{
}
#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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -