Computational routine
eng
gengold
/* Modnumlib Scicos interfacing function
* Copyright (C) 2009 Alan Layec
*
* This library 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 2 of the License, or (at your option) any later version.
*
* This library 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 this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* Gengold Scicos Gold Sequences Generator block
* Type 4 simulation function ver 1.1 - scilab-3.0
* 15 décembre 2004 - IRCOM GROUP - Author : A.Layec
*/
/* REVISION HISTORY :
* $Log$
*/
#include "modnum_lib.h"
#include "scicos_block.h"
/* Cette fonction de simulation est un générateur de sequences de gold.
* Les valeurs de sortie sont soit -1 soit 1 et dependent d'une combinaison linéaire
* des valeurs des registres internes Z. Les opérations sont réalisées grâce à des
* opérateurs de manipulations de bit, et les mots binaires sont stockés par leurs valeurs entières.
* La fonction est capable de délivrer des vecteurs de nb_gen générateurs.
*/
/* Entrée régulière : néant
* Sorties régulières : y[0..ny[0]-1] : sortie du générateur 1
* y[ny[0]..ny[0]+ny[1]-1] : sortie du générateur 2
* ...
* y[ny[nb_gen-2]..ny[nb_gen-2]+ny[nb_gen-1]] : sortie du générateur nb_gen
*
* Entrée évenementielle : période de déclenchement
* Sortie évènementielle : néant.
*
* Etats discrets : z[0..nb_gen-1] : valeur des registres à décalage 1
* z[nb_gen..2*nb_gen-1] : valeur des registres à décalage 2
*
* paramètres entiers : ipar[0] : nb_gen nombre de générateurs
* ipar[1..nb_gen] : ny[0..nb_gen-1] longeur des vecteurs de sortie des géné
* ipar[nb_gen+1..2*nb_gen] : longueur des registres (nbre de bascules)
* ipar[2*nb_gen+1..3*nb_gen] : valeurs des coefficients des registres 1
* ipar[3*nb_gen+1..4*nb_gen] : valeurs des coeff des registres 2
*/
/*work structure of that block*/
typedef struct work_st {
double *y__; /* discrete output state of generators */
} work_struct;
void gengold(scicos_block *block,int flag)
{
/*déclaration des variables*/
int ny;
int my=1; /* */
int nb_gen;
int reg1,reg2,N;
int coef1,coef2;
int k;
int n;
int y_ptr;
int m,decal;
double *y;
/*ptr of the struct of that block*/
work_struct *work;
/*get the struct of that block*/
work = (work_struct*) *block->work;
/*Récupération de l'adresse du port de sortie*/
y=(double *)block->outptr[0];
/*Récupération du nombre de générateurs*/
nb_gen=block->ipar[0];
/*Fait décalage initial*/
if(flag==4) {
/*Récuperation de la 1ere dimension du port de sortie*/
ny = block->outsz[0];
/*allocation*/
if ((work=(work_struct*) scicos_malloc(sizeof(work_struct))) == NULL) {
set_block_error(-16);
return;
}
/*etats cachés pour le calcul des états discrets*/
if ((work->y__=(double*) scicos_malloc(my*ny*sizeof(double))) == NULL) {
set_block_error(-16);
return;
}
/*store my_st in block->work*/
*block->work=(void *)work; /*store my_st in *block->work*/
/*récupère le nombre de décalage initial*/
decal=(int) block->rpar[0];
for (k=0;k<nb_gen;k++) {
/*Récupération de la longueur des registres*/
N=block->ipar[nb_gen+1+k];
/*Récupération de la valeur du registre 1 et 2*/
reg1=(int) block->z[k];
reg2=(int) block->z[nb_gen+k];
/*Récupération de la valeur des coef*/
coef1=block->ipar[2*nb_gen+1+k];
coef2=block->ipar[3*nb_gen+1+k];
for(n=0;n<decal;n++) {
/*Appel routine gold_c*/
gold_c(&N,(m=1,&m),&y[0],®1,®2,&coef1,&coef2);
}
/*Définition de l'adresse de départ de la sortie du géné k*/
if(k!=0) y_ptr=y_ptr+block->ipar[k];
else y_ptr=0;
/*Récupération de la longueur du vecteur de sortie*/
ny=block->ipar[1+k];
/*Appel routine gold_c*/
gold_c(&N,&ny,&work->y__[y_ptr],®1,®2,&coef1,&coef2);
/*Sauvegarde la valeur du registre1 dans z[0] et la valeur du reg 2 dans z[1]*/
block->z[k]=(double)reg1;
block->z[nb_gen+k]=(double)reg2;
}
}
/*Calcul des sorties */
else if((flag==1)||(flag==6)) {
/*Récuperation de la 1ere dimension du port de sortie*/
ny = block->outsz[0];
/*appel copyd_c*/
copyd_c((m=ny*my,&m),work->y__,y);
}
/*Calcul des états */
else if(flag==2) {
for (k=0;k<nb_gen;k++) {
/*Définition de l'adresse de départ de la sortie du géné k*/
if(k!=0) y_ptr=y_ptr+block->ipar[k];
else y_ptr=0;
/*Récupération de la longueur du vecteur de sortie*/
ny=block->ipar[1+k];
/*Récupération de la longueur des registres*/
N=block->ipar[nb_gen+1+k];
/*Récupération de la valeur du registre 1 et 2*/
reg1=(int) block->z[k];
reg2=(int) block->z[nb_gen+k];
/*Récupération de la valeur des coef*/
coef1=block->ipar[2*nb_gen+1+k];
coef2=block->ipar[3*nb_gen+1+k];
/*Appel routine gold_c*/
gold_c(&N,&ny,&work->y__[y_ptr],®1,®2,&coef1,&coef2);
/*Sauvegarde la valeur du registre1 dans z[0] et la valeur du reg 2 dans z[1]*/
block->z[k]=(double)reg1;
block->z[nb_gen+k]=(double)reg2;
}
}
/*Terminaison*/
else if(flag==5) {
if (work!=NULL) {
scicos_free(work->y__);
}
scicos_free(work);
}
}