51 / 63 · Konzept
ALU und Zero-, Negative-, Carry- und Overflow-Flags
ADD/SUB mit gemeinsamem Addierer implementieren und aus getrenntem Carry/Overflow Vergleichsbedingungen ableiten.
Lektionen sind frei lesbar. Schreibe dich ein, um deinen Fortschritt zu speichern.
Voraussetzungen: ZweierkomplementZweierkomplement Darstellung vorzeichenbehafteter Ganzzahlen mit fester Bitbreite. n Bit reichen von −2^(n−1) bis 2^(n−1)−1. Mehr erfahren, Addierer, kombinatorischer MUXMultiplexer Kombinatorische Schaltung, die gemäß Auswahlsignal einen Eingang zum Ausgang verbindet. Die Zuordnung von Auswahlbits und Eingangsnummern muss festgelegt sein. Mehr erfahren und Bitbreitenerweiterung.
Eine ALU erzeugt Ergebnis und Status
Die ALU wählt zwischen Rechenergebnissen und liefert Statusbits zu deren Interpretation. Eingänge und Ergebnis haben Bit; unterstützt werden ADD, SUB, AND, OR und XOR. Arithmetik behält stets nur die unteren Bit. Da dieselben Bits unsignedUnsigned Interpretation einer Bitfolge als nichtnegative Ganzzahl. Der n-Bit-Bereich ist 0 bis 2^n−1 und kann sich von der signed-Interpretation derselben Bits unterscheiden. Mehr erfahren oder signed im Zweierkomplement gelesen werden können, werden Carry und Overflow getrennt ausgegeben. Dafür sind keine zwei verschiedenen Addierer nötig.
Die Flags sind und . Z ist das Reduktions-NOR des gewählten Ergebnisses, N dessen höchstes Bit. N=1 bedeutet ein negatives gespeichertes signed-Ergebnis. Bei Overflow kann dessen Vorzeichen vom mathematischen Ergebnis mit unbegrenzter Genauigkeit abweichen.
Carry und Overflow trennen
Bei Addition ist C das oberste Bit der erweiterten Summe .
V ist 1, wenn die Eingänge gleiche Vorzeichen haben, das Ergebnis aber ein anderes. Für die höchsten Bits gilt:
In acht Bit ergibt R=0, C=1, V=0: Signed ist darstellbar. Dagegen ergibt R=0x80, C=0, V=1: Unsigned passt 128, signed wird das Maximum 127 überschritten. Ein gemeinsames C/V-Flag könnte beide Fälle nicht unterscheiden.
Für Subtraktion wird nur das W-Bit-B invertiertInversion NOT vertauscht 0 und 1. Ein Überstrich wendet NOT auf den gesamten darunterstehenden Ausdruck an. Mehr erfahren und danach mit 0 erweitert: . Inversion aller W+1 Bit verändert die Carry-Bedeutung. Hier heißt C=1 kein Borrow; unsigned entspricht deshalb .
Signed-Overflow bei Subtraktion ist nur für verschiedene Eingangszeichen möglich. Ein Vergleich kann SUB-Flags nutzen, ohne R zu speichern. Signed ist , ist . Bei wird etwa +127 gespeichert; V=1 korrigiert die irreführende alleinige Betrachtung von N.
Das 8-Bit-ADD-Beispiel unten passt unsigned, überschreitet aber signed den Bereich. C=0 und V=1 können bei derselben Summe gleichzeitig gelten.
- A=7F · B=01: signed 127 + 1
- 9-Bit-Summe T: 0_10000000
- 8-Bit-Ergebnis R: 80 → signed −128
- Statusflags: Z=0 · N=1 · C=0 · V=1
Gemeinsamer Addierer, explizite Ausgaberegeln
Das RTL setzt W≥2 voraus. Opcodes 0–4 sind ADD, SUB, AND, OR, XOR. Logikoperationen setzen C, V auf 0. Unbenutzte Opcodes liefern R=0, Z=1 und sonst 0. Dies ist der Vertrag dieser ALU, keine Nachbildung eines bestimmten CPU-Befehlssatzes.
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
endmoduleBedingte B-Inversion und Anfangsübertrag teilen eine Addierstruktur für ADD/SUB. y wird vor Z, N bestimmt, sodass auch Logikoperationen konsistente Flags erhalten. Standardzuweisungen definieren alle Pfade und verhindern LatchesLatch Speicherelement, das bei aktiver Steuerung dem Eingang folgt und sonst hält. Anders als ein Flipflop speichert es nicht nur an Flanken. Mehr erfahren. Ohne RegisterRegister Speichert einen Zustand aus mehreren Bits. Die synchronen Register dieses Kurses übernehmen festgelegte Eingaben an Taktflanken. Mehr erfahren gibt es keine Zykluslatenz, jedoch reale Laufzeit. Auch Operations-MUX und Nullerkennung müssen vor dem Setup des nächsten Registers fertig sein.
Testen Sie Paarungen von 0, unsigned-Maximum, signed-Minimum/-Maximum und benachbarten Grenzwerten. Prüfen Sie R anhand des Ergebnisses modulo , C anhand der erweiterten unsigned-Summe und V anhand der signed-Bereichsüberschreitung jeweils unabhängig. Ein korrektes R garantiert keine korrekten Flags.
Ein reales Beispiel der Trennung von Vorzeichen, Null, unsigned-Carry und signed-Overflow bietet Arms Erklärung der Bedingungsflags.
Selbst ausprobieren
Bestimmen Sie für acht Bit (R, Z, N, C, V) von (1) 0x7F+0x01, (2) 0xFF+0x01, (3) 0x00−0x01, (4) 0x80−0x01. Warum ist bei signed-Vergleich von (4) N allein falsch?
Erklärung lesen
(1) (0x80,0,1,0,1), (2) (0x00,1,0,1,0), (3) (0xFF,0,1,0,0), (4) (0x7F,0,0,1,1). In (3) gibt es unsigned Borrow, also C=0; signed −1 passt. In (4) ist unsigned 128−1=127 ohne Borrow, also C=1. Signed −128−1=−129 überschreitet den Bereich: V=1, während das gespeicherte N=0 nicht das echte Vorzeichen zeigt. N xor V=1 ergibt korrekt signed A<B.