Altifigence Academy

53 / 63 · Concept

Virgule fixe, arrondi et saturation

Définir la plage par W,F et concevoir l'arrondi pair guard/sticky suivi de saturation.

Prérequis : largeur des additions/multiplications signées, décalage arithmétique droit et dépassement.

Définir la position de la virgule par contrat

La virgule fixeVirgule fixe Représentation où une position de virgule prédéfinie applique une échelle fixe à un entier binaire. Largeur, signe et nombre de bits fractionnaires doivent être définis ensemble. interprète l'entier X comme x=X2−Fx=X2^{-F} ; aucun bit de virgule n'est stocké. Ici, W comprend le signe et F compte les bits fractionnaires. Les conventions Q diffèrent selon l'inclusion du signe dans la partie entière ; indiquer W,F dans l'interface évite l'ambiguïté.

−2W−1−F≤x≤2W−1−F−2−F-2^{W-1-F}\le x\le 2^{W-1-F}-2^{-F}

Avec W=8,F=4, le pas est 1/16 et la plage −8 à 7.9375. 0x18 représente 1.5, pas l'entier 24 ; avec F=3, il représente 3. Relier les fils ne garantit pas l'échelle numérique : documentez celle de chaque port.

Avant une addition, alignez les virgules. Pour des F différents, élargissez suffisamment l'opérande au plus petit F puis décalez-le à gauche, ou réduisez le plus grand F selon un arrondi défini. Deux nombres de mêmes W,F demandent W+1 bits et le même F pour une somme exacte. Une multiplication multiplie les entiers bruts et additionne les nombres de bits fractionnaires.

P=XAXB,FP=FA+FBP=X_A X_B,\qquad F_P=F_A+F_B

Le produit complet de deux valeurs huit bits F=4 a seize bits signés F=8. Pour revenir à huit bits F=4, supprimez quatre bits fractionnaires puis vérifiez la plage signée huit bits. Tronquer d'abord le produit à huit bits détruit l'information de grandeur nécessaire à la saturation.

Troncature et arrondi

Un décalage arithmétique de d bits donne q=⌊P/2d⌋q=\lfloor P/2^d\rfloor, vers le bas même pour les négatifs. Pour P=−24,d=4P=-24,d=4, le quotient exact −1.5 donne q=−2, contrairement à une troncature vers zéro. Ne supposez pas que conserver les bits hauts produit les mêmes propriétés d'erreur pour les deux signes.

Construisons l'arrondi au plus proche, avec choix de l'entier pair en cas d'égalité. g, le guard, est le bit haut supprimé ; t, le sticky, est le OR des autres bits supprimés ; l est le bit bas du quotient conservé.

inc=g∧(t∨l),qrnd=q+inc\mathrm{inc}=g\land(t\lor l),\qquad q_{\mathrm{rnd}}=q+\mathrm{inc}

g=0 signifie moins d'une moitié : ne changez rien. g=1,t=1 signifie plus d'une moitié : incrémentez. g=1,t=0 est l'égalité : ajoutez 1 seulement si q est impair. Cela marche aussi en négatif, car avec le quotient plancher et r=P−q2dr=P-q2^d, on a toujours 0≤r<2d0\le r<2^d.

Ainsi, −24/16=−1.5 donne q=−2 pair, donc −2 ; −40/16=−2.5 donne q=−3 impair, donc −2. Une règle spéciale « soustraire 1 aux négatifs » serait fausse. Sans saturation, l'erreur finale ne dépasse pas la moitié du LSBLSB Bit de poids le plus faible. Vérifiez ensemble sens d'écriture et règles d'indexation. En savoir plus de sortie. Le choix pair ne garantit pas une erreur moyenne nulle pour toute distribution, mais réduit le biais des égalités toujours dirigées du même côté.

Pour P brut=2040 en seize bits F=8 vers huit bits F=4, 127.5 s'arrondit à 128 pair, puis se limite à 127. Conservez une largeur suffisante jusqu'au stockage final.

Arrondir avant de saturer
  1. Entrée P=2040: 16 bits · F=8
  2. Réduction d'échelle: 2040 / 16 = 127.5
  3. Égalité vers le pair: Valeur brute arrondie = 128
  4. Stocker après saturation: Brut 127 → 7.9375

Saturer après l'arrondi

La saturation limite au maximum ou minimum si nécessaire. Contrairement au rebouclage, un grand positif ne devient pas négatif. Une valeur déjà tronquée et rebouclée ne permet plus une saturation correcte.

Ce module combinatoire convertit seize bits signés F=8 en huit bits signés F=4. Avec d=4, guard=p[3] et sticky=OR(p[2:0]). L'incrément d'arrondi et les comparaisons se font sur dix-sept bits signés ; les huit bits ne sont extraits qu'à la fin.

SystemVerilog
module requantize (
  input  logic signed [15:0] p,
  output logic signed [7:0] y,
  output logic saturated
);
  logic signed [16:0] wide, q, rounded;
  logic inc;
  always_comb begin
    wide = {p[15], p};
    q = wide >>> 4;
    inc = p[3] & ((|p[2:0]) | q[0]);
    rounded = q + (inc ? 17'sd1 : 17'sd0);
    saturated = 1'b0;
    if (rounded > 17'sd127) begin
      y = 8'sh7f;
      saturated = 1'b1;
    end else if (rounded < -17'sd128) begin
      y = 8'sh80;
      saturated = 1'b1;
    end else begin
      y = rounded[7:0];
    end
  end
endmodule

P=2040 donne 127.5, arrondi à 128 puis saturé à 127, soit 7.9375. Tester seulement q=127 avant l'arrondi manquerait le dépassement. saturated indique une limitation hors plage, pas simplement la perte de bits fractionnaires.

Dans un module générique, d=0 n'a aucun bit à supprimer et d=1 aucun champ sticky. Cacher une tranche invalide dans un if ne suffit pas toujours à éviter une erreur d'élaboration.

Arrondi et saturation sont des politiques distinctes ajoutant additionneur, comparateur, MUXMultiplexeur Circuit combinatoire reliant une entrée parmi plusieurs à la sortie selon une sélection. La correspondance entre bits de sélection et numéro d'entrée doit être spécifiée. En savoir plus et retard, comme le précise aussi la documentation AMD des formats fixes. Pour une accumulation, décidez d'abord si la largeur intermédiaire sera conservée jusqu'à une conversion finale unique. Saturer à chaque étape peut casser l'associativité ; arrondir à chaque étape peut accumuler de petites erreurs.

Essayez vous-même

Convertissez P signé seize bits F=8 en huit bits F=4. Pour 24,40,−24,−40,2040, donnez quotient plancher q, guard/sticky, entier arrondi, sortie raw finale et valeur réelle. Que risque une saturation testée avant arrondi pour 2040 ?

Lire l’explication

Les quatre bits bas sont toujours 1000 : guard=1,sticky=0. P=24 : q=1 impair→2, raw=2, valeur=0.125. P=40 : q=2 pair→2, raw=2, 0.125. P=−24 : q=−2 pair→−2, raw=−2, −0.125. P=−40 : q=−3 impair→−2, raw=−2, −0.125. P=2040 : q=127 impair→128, puis saturation signed huit bits : raw=127, valeur=7.9375,saturated=1. Tester q=127 puis ajouter 1 sur huit bits pourrait reboucler à 0x80, soit −8. Terminez l'incrément et la comparaison en signé large.

Votre choix s’applique à ce navigateur. Modifiez-le à tout moment en bas de page.