Sur FPGA ou sur un petit microcontrôleur sans unité flottante, on calcule en virgule fixe : un entier dont on décide où se trouve la virgule. L’outil donne la plage et la résolution d’un format, la valeur réellement codée et l’entier brut. L’onglet IEEE-754 montre comment un nombre est stocké en flottant, et pourquoi 0,1 n’y est jamais exact. L’onglet Opérations simule les quatre opérations sur des entiers, étape par étape, avec l’arrondi et le traitement des dépassements de votre choix, et génère le code C correspondant.
Notation
–
Résolution
–
Plage
–
Valeur codée
–
Entier brut
–
Hexadécimal
–
Valeur réellement stockée
–
Champs
–
Simulation du calcul sur entiers
Résultat
–
Format du résultat
–
Valeur exacte
–
Erreur
–
En flottant 32 bits
–
Code C équivalent
Virgule fixe
résolution = 2^(IWL − WL)
signé : −2^(IWL−1) … 2^(IWL−1) − résolution
non signé : 0 … 2^IWL − résolution
valeur = entier brut × résolution
WL est la longueur totale du mot, IWL le nombre de bits de la partie entière (bit de signe compris pour un format signé), selon la convention de LabVIEW FPGA notée <±,WL,IWL>. La notation Qm.n, courante en traitement du signal, compte m bits entiers hors signe et n bits fractionnaires : <±,16,4> correspond à Q3.12.
L’outil arrondit au plus proche avec égalité au pair (le mode par défaut de LabVIEW) et sature en cas de dépassement. En LabVIEW FPGA, la largeur du mot se paie en ressources : un multiplieur 18 × 25 bits tient dans un seul bloc DSP48 d’un FPGA Xilinx, au-delà il en faut plusieurs.
IEEE-754
| Format | Signe | Exposant | Mantisse | Chiffres significatifs |
|---|---|---|---|---|
| Simple (32 bits) | 1 | 8 (biais 127) | 23 | ≈ 7 |
| Double (64 bits) | 1 | 11 (biais 1023) | 52 | ≈ 16 |
Un flottant représente exactement les fractions dont le dénominateur est une puissance de deux. 0,1 = 1/10 n’en fait pas partie : il est stocké 0,100000001490116 en simple précision. D’où la règle : ne jamais comparer deux flottants avec une égalité stricte, mais avec une tolérance.
Les quatre opérations en virgule fixe
En virgule fixe, une opération se ramène à une opération sur les entiers bruts, suivie d’un ajustement de la position de la virgule. Le résultat exact demande en général plus de bits que les opérandes ; c’est ce que LabVIEW appelle la pleine précision.
| Opération | Bits fractionnaires du résultat exact | Bits entiers | À retenir |
|---|---|---|---|
| a ± b | max(fa, fb) | max(ia, ib) + 1 | aligner les virgules avant d’additionner |
| a × b | fa + fb | ia + ib | un produit 16 × 16 bits tient sur 32 bits |
| a ÷ b | au choix | jusqu’à ia + fb (+1 en signé) | pas de résultat exact : il faut choisir la précision |
Avec fa, fb le nombre de bits fractionnaires et ia, ib le nombre de bits entiers des opérandes.
Addition et soustraction
Les deux entiers doivent représenter la même puissance de deux : on décale vers la gauche celui qui a le moins de bits fractionnaires, puis on additionne. Un bit entier supplémentaire absorbe la retenue. La soustraction de deux non signés donne un résultat signé.
Multiplication
On multiplie directement les entiers : les bits fractionnaires s’ajoutent. Le produit est exact mais deux fois plus large ; pour revenir au format de départ, on le décale vers la droite, et c’est là qu’intervient l’arrondi. En C, il faut convertir un opérande vers un type plus large avant la multiplication : (int32_t)a * b, sinon le produit déborde.
Division
Le quotient de deux entiers perd sa partie fractionnaire. Pour garder f bits fractionnaires au résultat, on décale le dividende vers la gauche avant de diviser, de f − fa + fb bits. La division est l’opération la plus coûteuse : on lui préfère quand c’est possible une multiplication par l’inverse précalculé, ou un décalage pour une puissance de deux.
Arrondi et dépassement
- Troncature : on abandonne les bits de poids faible, ce qui arrondit vers −∞. C’est gratuit, mais l’erreur moyenne vaut −½ LSB : sur un filtre ou un accumulateur, ce biais s’accumule.
- Arrondi au plus proche : on ajoute ½ LSB avant de tronquer. L’égalité vers +∞ garde un léger biais ; l’égalité au pair le supprime, pour un peu plus de logique.
- Saturation : un résultat hors plage est bloqué à la valeur extrême. C’est le choix sûr pour une commande ou une mesure.
- Repliement : les bits de poids fort sont perdus, comme sur un entier ordinaire. Un grand positif devient négatif, ce qui est catastrophique sur une commande mais voulu sur un accumulateur de phase (NCO), dont le comportement modulo est exactement celui recherché.
En C et en LabVIEW FPGA
- En C, le
>>d’un entier signé négatif est arithmétique sur les compilateurs courants (garanti à partir de C23), mais le<<d’un négatif est un comportement indéfini : le code généré utilise des multiplications par des puissances de deux, que le compilateur transforme en décalages. - La division entière du C tronque vers zéro, pas vers −∞ : −7 / 2 donne −3 en C, alors qu’une troncature en virgule fixe donne −4. Le code généré corrige ce point.
- En LabVIEW FPGA, les mêmes choix se font dans l’onglet Output Configuration des propriétés d’une fonction numérique : décocher Adapt to source pour imposer le format, puis choisir le mode d’arrondi (Truncate, Round-Half-Up, Round-Half-Even) et de dépassement (Saturate, Wrap). Ce sont les options de l’outil. La division passe par les fonctions High Throughput Math.

Laisser un commentaire
Vous devez vous connecter pour publier un commentaire.