Outils pour utilisateurs

Outils du site


td1_tns

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
td1_tns [2016/03/10 17:08]
bvandepo [Opérations de calcul en virgule fixe]
td1_tns [2016/03/10 17:18] (Version actuelle)
bvandepo
Ligne 70: Ligne 70:
  
  
- + 
-====Quantification des coefficients du filtre==== +
- +
-Les coefficients du filtre sont stockés dans des tableaux de valeur codés en double. Nous souhaitons maintenant les approximer par codage en virgule fixe au format Q0.15. +
- +
-Déterminer les types adéquats pour les paramètres d'​entrée/​sortie de la fonction **quantCoeffsShortInt**. Cette fonction prend en entrée: +
-  - un tableau **tabDouble** des coefficients à convertir. +
-  - un tableau **tabInt** pour ranger les coefficients convertis en virgule fixe.    +
-  - un tableau **tabDoubleQuant** pour ranger les coefficients convertis en virgule fixe exprimés en virgule flottante. Ce tableau permettra de comparer les valeurs flottantes avant et après conversion.  +
-  - un nombre de coefficients **nbCoeffs** indiquant le nombre de case du tableau **tabDouble** à traiter. ​   +
-  - une valeur **nbBitsFractionnairenbCoeffs** indiquant le nombre de bits utilisés pour la partie fractionnaires des nombres en virgule fixe. +
- +
-Coder en C cette fonctions. On utilisera l'​arrondi plutôt que la troncature pour le calcul. +
- +
- +
-Le code ci dessous devra être intégré dans la fonction **quantCoeffsShortInt** pour permettre la vérification des calculs: +
- +
-<file cpp simu3.cpp>​ +
-    void quantCoeffsShortInt(double * tabDouble, short int * tabInt, double * tabDoubleQuant,​ int nbCoeffs, unsigned int nbBitsFractionnaire){ +
-      int i; +
-      long int temp; +
-      for (i=0;​i<​nbCoeffs;​i++) +
-        { +
-       TODO: affecter à la variable temp le résultat de la conversion de tabDouble[i] au format virgule fixe signé avec nbBitsFractionnaire bits après la virgule.  +
-        +
-        +
-            //Vérifier qu'il n'y a pas de dépassement sinon saturer +
-            if (temp>( (1<<​15)-1) ) +
-              temp= (1<<​15)-1;​ +
-            if (temp<( -(1<<​15)) ) +
-              temp=-(1<<​15);​ +
-            tabInt[i]= (short int)temp; +
-            tabDoubleQuant[i]=tabInt[i] / (double)(1<<​nbBitsFractionnaire);​ +
-            printf("​coefficient %d valant %lf codé avec %d bits pour la partie fractionnaire:​ %d soit %lf\n",​i,​tabDouble[i],​nbBitsFractionnaire,​tabInt[i],​tabDoubleQuant[i]);​ fflush(stdout); ​      +
-        } +
-    } +
-</​file> ​               +
-                +
-<ifauth @prof> +
-===Solution:​=== +
-<file cpp simu3s.cpp>​ +
-   +
-        temp= floor( ​ (tabDouble[i] ​ * (1<<​nbBitsFractionnaire) ) + 0.5) ; //ou round +
-         +
-</​file>​ +
-</​ifauth>​ +
- +
- +
-====Opérations de calcul en virgule fixe==== +
- +
-<color red> +
- ​Inserer figure de hugues. +
-Fournir code de la fonction en double sur papier à modifier pour passer en virgules fixe +
- +
-</​color>​ +
- +
-Pour le RIF, le tableau **memoireVk** contient les échantillons d'​entrée $e_k$, interprété au format UQn.0. +
- +
-On considère que les coefficients du numérateur de la fonction de transfert (b[i]) sont codés en Q0.15. +
- +
-On utilisera ici un entier 32 bits pour stocker le résultat de $s_k=\sum_{i=0}^{N}b_i.e_{k-i}$ +
- +
-Indiquer le format de $s_k$ par application du calcul sur les entiers codant les nombres en virgule fixe. +
- +
-On souhaite un résultat entier au format UQN.0 pour piloter le DAC. Avant l'​ajout d'​offset numérique sur la sortie dû au référencement par rapport au zéro, on utilise donc le codage au format Q(N-1).0. Quelle opération doit on effectuer pour convertir le résultat de $s_k$ à ce format? +
- +
-En déduire l’intérêt d'​avoir effectué les calculs intermédiaires sur 32 bits pour obtenir un résultat sur 16 bits. +
- +
-Si la sortie de la fonction d'​application du calcul doit être utilisée pour piloter un DAC 10 bits, indiquer les opérations à effectuer pour s'​assurer que le résultat obtenu après conversion puisse être codé au format UQ10.0 (et donc Q(N-1).0 avant ajout d'​offset numérique). +
- +
-<ifauth @prof> +
-===Solution:​=== +
-<file cpp simudouble.cpp>​ +
-  double skout; //valeur pour la sortie calculée +
- //​calcul de sk +
-    skout = 0; //valeur par défaut pour le résultat +
-    indice_lec = indice_ecr;​ +
-    for (i = 0; i <​NB_COEFF_B;​ i++){ //N+1 itérations +
-        skout = skout + b[i] * memoireVk[indice_lec];​ +
-   } +
-</​file>​ +
- +
-<file cpp simuvfixe.cpp>​ +
-  short int skout = 0; //valeur pour la sortie calculée +
-  long int temp; // calcul intermediaire sur 32 bits +
-   +
- //​calcul de sk +
-    temp = 0; //valeur par défaut pour le résultat +
-    indice_lec = indice_ecr;​ +
-    for (i = 0; i <​NB_COEFF_B;​ i++){ //N+1 itérations +
-         temp += (long int) b[i] * (long int)(memoireVk[indice_lec]); ​  // calcul sur 32 bits +
-    } +
-     +
-    if  (temp & (1<<​(NB_BITS_FRACTIONNAIRE-1))!=0 ) // calcul de l'​arrondi,​ est ce que le premier bit qui sera éliminé est à 1 +
-      skout = (temp >> NB_BITS_FRACTIONNAIRE ) + 1; //oui alors ajouter 1 au résultat tronqué +
-  else  +
-    skout = (temp >> NB_BITS_FRACTIONNAIRE ) ;      //sinon utiliser le résultat tronqué +
-  if (skout >  (1<<​(nbBitsQuantDAC-1)) -1 )                // saturation du résultat sur 10 bits +
-    skout = (1<<​(nbBitsQuantDAC-1)) -1 ;  +
-  else if (skout < -(1<<​(nbBitsQuantDAC-1)) ​  )  +
-    skout = -(1<<​(nbBitsQuantDAC-1))) ​   ;  +
-  return ​ skout + OFFSET_SORTIE;​  +
- +
-</​file>​ +
- +
- +
-<file cpp vfixe.cpp>​ +
-inline ​ short int execFiltre_i_filtre_rif(short int e) +
-+
-  long int temp; // calcul intermediaire sur 32 bits +
-  int i; //indice de lecture pour les valeurs des coefficients du filtre +
-  int indice_lec_i_filtre_rif = indice_ecr_i_filtre_rif;​ //indice de lecture pour les échantillons d'​entrée +
-  short int skout = 0; //valeur pour la sortie calculée +
-  ek_filtre_i_RIF[indice_ecr_i_filtre_rif] = e - 512; //rangement de l'​echantillon d'​entrée dans le buffer circulaire des entrées en référencant par rapport au 0 +
-//  indice_ecr_i_filtre_rif = (indice_ecr_i_filtre_rif + 1) % SIZEFILTER_RIF;​ +
-  indice_ecr_i_filtre_rif = (indice_ecr_i_filtre_rif + 1); +
-  if (indice_ecr_i_filtre_rif>​=SIZEFILTER_RIF) +
-    indice_ecr_i_filtre_rif=0;​ +
-  temp = 0; //valeur par défaut pour le résultat +
-  for (i = 0; i < SIZEFILTER_RIF;​ i++) +
-  { +
-    temp += (long int) numCoeff_i_FILTRE_RIF[i] * (long int)(ek_filtre_i_RIF[indice_lec_i_filtre_rif]); ​  // calcul sur 32 bits +
-    indice_lec_i_filtre_rif--;​ +
-    if (indice_lec_i_filtre_rif < 0) +
-      indice_lec_i_filtre_rif = SIZEFILTER_RIF - 1; +
-  } +
-  if  (temp & (1<<​(NB_BITS_FRACTIONNAIRE-1)) ) // calcul de l'​arrondi +
-    skout = (temp >> NB_BITS_FRACTIONNAIRE ) + 1;  +
-  else  +
-    skout = (temp >> NB_BITS_FRACTIONNAIRE ) ; +
-  if (skout >  511 )                // saturation du résultat sur 10 bits +
-    skout = 511 ;  +
-  else if (skout < -512 )  +
-    skout = -512 ;  +
-  return ​ skout + 512;   +
-+
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////​ +
-</​file>​ +
-</​ifauth>​ +
- +
- +
-En vous inspirant du codage de la fonction **double filtreUnEchantillon(double ek)**  (qui réalise un filtre RII), proposer une implémentation de **unsigned short int filtreUnEchantillon_RIF(unsigned short int ek)** qui réalise un filtre RIF en VIRGULE FIXE. Pour cela, vous modifierez le code imprimé sur la feuille distribuée pendant la séance. <color red>Vous ferez valider cette étape d'​analyse avant de réaliser le codage sur machine.</​color>​ +
- +
- +
- +
-Une fois la fonction ​ **unsigned short int filtreUnEchantillon_RIF(unsigned short int ek)** codée, vous remplacerez l'​appel de **double filtreUnEchantillon(double ek)** par cette nouvelle fonction et vérifierez que les réponses temporelles sont inchangées.+
  
  
td1_tns.txt · Dernière modification: 2016/03/10 17:18 par bvandepo