Computational routine
eng


gengold

File content


/* Modnumlib Scicos interfacing function
 * Copyright (C) 2009-2011 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],&reg1,&reg2,&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],&reg1,&reg2,&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],&reg1,&reg2,&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);
  }
}