Altifigence Academy

51 / 63 · Concept

ALU et indicateurs zéro, négatif, retenue et dépassement

Partager l'additionneur ADD/SUB et distinguer retenue et dépassement signé pour dériver les comparaisons.

Prérequis : complément à deuxComplément à deux Représentation d'un entier signé par un motif de largeur fixe. Sur n bits, la plage va de −2^(n−1) à 2^(n−1)−1. En savoir plus, additionneurs, 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 combinatoires et extension de largeur.

Une ALU produit résultat et état

L'ALU sélectionne le résultat des circuits opératoires et fournit des bits d'état pour l'interpréter. Les entrées A,BA,B et le résultat RR ont WW bits ; les opérations sont ADD, SUB, AND, OR et XOR. Le résultat arithmétique est toujours tronqué aux WW bits bas. Le même motif étant lisible en non signéNon signé Interprétation d'un motif de bits comme entier non négatif. Sur n bits, la plage va de 0 à 2^n−1 et peut différer de l'interprétation signée du même motif. En savoir plus ou en complément à deux, retenue et dépassement sont séparés. Il n'est pas nécessaire de construire deux additionneurs pour les deux interprétations.

Les indicateurs sont Z=(R=0)Z=(R=0) et N=RW−1N=R_{W-1}. Z est la réduction NOR du résultat sélectionné, N son bit de poids fort. N=1 indique une interprétation signée négative du motif stocké. En cas de dépassement, ce signe peut différer de celui du résultat exact à précision illimitée.

Séparer retenue et dépassement

En addition, C est le bit de poids fort de la somme étendue TT.

T={0,A}+{0,B},R=T[W−1:0],C=T[W]T=\{0,A\}+\{0,B\},\qquad R=T[W-1:0],\quad C=T[W]

V vaut 1 lorsque les deux entrées ont le même signe et le résultat le signe opposé. En notant a,b,ra,b,r leurs bits de poids fort :

Vadd=¬(a⊕b)∧(a⊕r)V_{\mathrm{add}}=\neg(a\oplus b)\land(a\oplus r)

Sur huit bits, 255+1255+1 donne R=0,C=1,V=0 : en signé, −1+1=0-1+1=0 reste représentable. En revanche, 127+1127+1 donne R=0x80,C=0,V=1 : 128 tient en non signé, mais dépasse le maximum signé 127. Fusionner C et V perd cette distinction.

En soustraction, inversezNégation L'opération NOT échange 0 et 1. Une barre au-dessus d'une expression applique NOT à toute l'expression qu'elle couvre. En savoir plus seulement les W bits de B puis étendez par un zéro : T={0,A}+{0,¬B}+1T=\{0,A\}+\{0,\neg B\}+1. Inverser les W+1 bits changerait le sens de la retenue haute. Ici, C=1 signifie absence d'emprunt ; en comparaison non signée, A<BA<B vaut donc ¬C\neg C.

Vsub=(a⊕b)∧(a⊕r)V_{\mathrm{sub}}=(a\oplus b)\land(a\oplus r)

Seule la soustraction de signes différents peut produire un dépassement signé. Une comparaison peut utiliser les indicateurs de SUB sans stocker R. En signé, A<BA<B vaut N⊕VN\oplus V et A≤BA\le B vaut Z∨(N⊕V)Z\lor(N\oplus V). Par exemple, −128−1-128-1 se stocke comme +127, mais V=1 corrige l'erreur d'une lecture de N seul.

L'exemple ADD huit bits ci-dessous est représentable en non signé mais dépasse en signé. C=0 et V=1 peuvent donc coexister.

Distinguer C et V pour 127 + 1
  1. A=7F · B=01: Signé : 127 + 1
  2. Somme T sur 9 bits: 0_10000000
  3. Résultat R sur 8 bits: 80 → signé −128
  4. Indicateurs d'état: Z=0 · N=1 · C=0 · V=1

Additionneur partagé et règles de sortie explicites

Le RTL suppose W≥2. Les opcodes 0–4 représentent ADD,SUB,AND,OR,XOR. Les opérations logiques imposent C=V=0. Un opcode inutilisé donne R=0,Z=1 et les autres indicateurs à 0. C'est le contrat de cette ALU, pas l'imitation d'une ISA particulière.

SystemVerilog
module alu #(parameter int W = 8) (
  input  logic [W-1:0] a, b,
  input  logic [2:0] op,
  output logic [W-1:0] y,
  output logic z, n, c, v
);
  logic sub;
  logic [W-1:0] bx;
  logic [W:0] sum;
  always_comb begin
    sub = (op == 3'd1);
    bx = b ^ {W{sub}};
    sum = {1'b0, a} + {1'b0, bx}
        + {{W{1'b0}}, sub};
    y = '0;
    c = 1'b0;
    v = 1'b0;
    case (op)
      3'd0, 3'd1: begin
        y = sum[W-1:0];
        c = sum[W];
        if (sub)
          v = (a[W-1] ^ b[W-1]) & (a[W-1] ^ y[W-1]);
        else
          v = ~(a[W-1] ^ b[W-1]) & (a[W-1] ^ y[W-1]);
      end
      3'd2: y = a & b;
      3'd3: y = a | b;
      3'd4: y = a ^ b;
      default: y = '0;
    endcase
    z = ~(|y);
    n = y[W-1];
  end
endmodule

L'inversion conditionnelle de B et la retenue initiale partagent la structure d'addition entre ADD et SUB. Calculer y avant Z,N dans chaque branche produit des indicateurs cohérents même pour les opérations logiques. Les valeurs par défaut couvrent tous les chemins et évitent les verrousVerrou Élément de stockage suivant l'entrée quand sa commande est active et conservant sa valeur sinon. Il diffère d'une bascule capturant seulement au front. En savoir plus. Sans registreRegistre Circuit stockant plusieurs bits d'état. Les registres synchrones du cours capturent leur entrée définie sur un front d'horloge. En savoir plus, il n'y a pas de latence en cycles, mais il existe un retard physique. Sélection d'opération et détection de zéro doivent aussi atteindre le registre suivant avant sa limite setup.

Testez des paires incluant 0, maximum non signé, minimum/maximum signés et leurs voisins. Comparez R à une référence modulo 2W2^W, C à la somme non signée étendue et V au dépassement de plage signée. Un résultat correct peut accompagner des indicateurs incorrects.

Un exemple réel de cette distinction entre signe, zéro, retenue non signée et dépassement signé figure dans l'explication des indicateurs Arm.

Essayez vous-même

Sur huit bits, calculez R,Z,N,C,V pour (1) 0x7F+0x01, (2) 0xFF+0x01, (3) 0x00−0x01, (4) 0x80−0x01. Pourquoi N seul compare-t-il mal les opérandes signés du cas 4 ?

Lire l’explication

Dans l'ordre (R,Z,N,C,V) : (1) (0x80,0,1,0,1), (2) (0x00,1,0,1,0), (3) (0xFF,0,1,0,0), (4) (0x7F,0,0,1,1). Le cas 3 emprunte en non signé, donc C=0, mais −1 signé est représentable. Le cas 4 fait 128−1=127 sans emprunt, donc C=1. En signé, −128−1=−129 dépasse, donc V=1 ; N=0 du résultat stocké ne reflète pas le vrai signe. N xor V=1 rend correctement A<B vrai.

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