Skip to content

§ 2.5. Flags

ALU8FlagUnit derives result flags and selects the carry/overflow signals exposed by the complete ALU. It is combinational: flags describe the current result and operation group, not a previous operation.

Component Description Structural Behavioral
ALU8FlagUnit Derives zero/negative flags from the selected result and gates arithmetic/shift carry and arithmetic overflow Yes Yes

These columns indicate registered simulator implementations; the simplified C++ examples below are not counted.

The simplified C++ example describes binary behavior, not the simulator implementation; it omits propagation delays and X/Z handling.

2.5.1. ALU8FlagUnit

The unit consumes an already selected result and status signals from the arithmetic and shift paths. It does not perform arithmetic, select the result word, or decode an opcode.

IO pins

Pin Direction Width Description
RESULT Input 8 Final selected ALU result
ARITHMETIC Input 1 Enable arithmetic carry and overflow
SHIFT Input 1 Enable shift/rotate carry
ARITH_CARRY Input 1 Carry/no-borrow output of the arithmetic unit
ARITH_OVERFLOW Input 1 Signed-overflow output of the arithmetic unit
SHIFT_CARRY Input 1 Carry output of the shifter
ZERO Output 1 1 when RESULT is zero
NEGATIVE Output 1 Bit 7 of a binary RESULT
CARRY Output 1 Enabled carry signals combined by OR
OVERFLOW Output 1 Enabled arithmetic overflow

There is no OP, C_IN, INVALID_OP, clock, or flag-write input. In particular, the unit does not preserve an old carry when neither group is selected. The shifter itself handles the zero-distance rule that forwards the ALU's C_IN.

Behavior

For binary inputs,

\[ \begin{aligned} \mathrm{ZERO} &= [\mathrm{RESULT}=0], \\ \mathrm{NEGATIVE} &= \mathrm{RESULT}_7, \\ \mathrm{CARRY} &= (\mathrm{ARITHMETIC}\land\mathrm{ARITH\_CARRY}) \lor(\mathrm{SHIFT}\land\mathrm{SHIFT\_CARRY}), \\ \mathrm{OVERFLOW} &= \mathrm{ARITHMETIC}\land\mathrm{ARITH\_OVERFLOW}. \end{aligned} \]
ARITHMETIC SHIFT CARRY OVERFLOW
0 0 0 0
1 0 ARITH_CARRY ARITH_OVERFLOW
0 1 SHIFT_CARRY 0
1 1 ARITH_CARRY OR SHIFT_CARRY ARITH_OVERFLOW

The last row is defined by the gates, but does not occur for a settled, known opcode in ALU8: its arithmetic and shift groups are mutually exclusive. This is an OR of enabled sources, not an arithmetic-priority multiplexer.

ZERO and NEGATIVE always describe RESULT, independently of these enables. NEGATIVE is not an overflow-corrected sign or a comparison result. For example, an overflowing addition can produce RESULT = 0x80, NEGATIVE = 1, and OVERFLOW = 1 together.

Comparison operations use subtraction internally, but the complete ALU drives both flag enables low for those operations. Internal subtraction carry/overflow help decide the comparison; they are not exposed as the comparison operation's output flags.

C++ example

#include <cstdint>

struct Flags8Result {
    bool ZERO;
    bool NEGATIVE;
    bool CARRY;
    bool OVERFLOW;
};

Flags8Result flags8_ref(
    std::uint8_t result, bool arithmetic, bool shift,
    bool arith_carry, bool arith_overflow, bool shift_carry) {
    return {
        result == 0,
        (result & 0x80u) != 0,
        (arithmetic && arith_carry) || (shift && shift_carry),
        arithmetic && arith_overflow,
    };
}

The example's inputs are independent, just like the standalone unit's pins; it does not check whether the supplied result and source flags came from the same computation.

Unknown inputs and timing

ZERO follows the ZeroDetect8 rules: a known 1 anywhere in RESULT establishes ZERO = 0; no known 1 and at least one X/Z produces ZERO = X. NEGATIVE is X when bit 7 is X or Z; unknown lower bits do not affect it.

A low group enable masks an unknown source flag to zero. A high enable passes a binary flag, or produces X from an X/Z flag. The carry OR can still establish 1 if either enabled contribution is known 1. Unknown enables follow the same AND/OR gate rules; they are not treated as false.

The result and flag sources can arrive at different times. The structural version has no single declared unit latency or atomic flag update. Checkpoints in the recorded scenario inspect settled values; the C++ example does not model propagation or four-state inputs.

Implementation

Structural implementation

Internal component Function
ZERO_DETECT (ZeroDetect8) Reduce RESULT to the zero flag
RESULT_SPLIT (BitSplitter<8>) Expose the result sign bit
LOW and SIGN (ORGate) Compute RESULT[7] OR 0, converting a high-impedance sign input to unknown logic
ARITH_CARRY_MASK, SHIFT_CARRY_MASK (ANDGate) Gate each carry source with its group enable
CARRY_SELECT (ORGate) Combine the two masked carry sources
OVERFLOW_SELECT (ANDGate) Gate arithmetic overflow with ARITHMETIC

The unit contains no flag register. A processor that needs persistent condition codes would store these outputs in a separate stateful component.

Behavioral implementation

Behavioral8<ALU8FlagUnit> calls flags. It reduces RESULT for ZERO, evaluates RESULT[7] OR 0 for NEGATIVE, and masks/combines the carry and overflow inputs with four-state AND/OR functions. It stores no flags and does not impose priority when both group enables are high.

The evaluator is defined in ALU8Behavioral.cpp; its value functions are in ALU8ValueModel.hpp. It retains the public pins without functional circuit children. Catalog construction supplies a delay table characterized from the gates; where a delay twin is available and agrees with the computed value, publication can follow the current inputs’ gate-level settling time within that bound, subject to older pending results. The compact evaluator does not reproduce transient gate glitches.

The recorded scenario runs against both implementations in CTest. ALU8FidelityContractTest checks binary/X/Z settled-output equivalence against the structural circuit. The example table uses the default structural run; its checkpoint times need not match the behavioral run.

Examples

All 128 recorded rows of ALU8FlagUnitTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.

Default scenario profile: canonical-default-preview / structural (26844736655d3a8e). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units ARITHMETICInput · 1 bit ARITH_CARRYInput · 1 bit ARITH_OVERFLOWInput · 1 bit RESULTInput · 8 bit SHIFTInput · 1 bit SHIFT_CARRYInput · 1 bit CARRYExpected output · 1 bit NEGATIVEExpected output · 1 bit OVERFLOWExpected output · 1 bit ZEROExpected output · 1 bit
#0row-05 0 0 0 0x00 0 0 0 0 0 1
#1row-111 0 0 0 0x01 0 0 0 0 0 0
#2row-216 0 0 0 0x80 0 0 0 1 0 0
#3row-321 0 0 0 0xFF 0 0 0 1 0 0
#4row-427 1 0 0 0x00 0 0 0 0 0 1
#5row-533 1 0 0 0x01 0 0 0 0 0 0
#6row-638 1 0 0 0x80 0 0 0 1 0 0
#7row-743 1 0 0 0xFF 0 0 0 1 0 0
#8row-849 0 0 0 0x00 1 0 0 0 0 1
#9row-955 0 0 0 0x01 1 0 0 0 0 0
#10row-1060 0 0 0 0x80 1 0 0 1 0 0
#11row-1165 0 0 0 0xFF 1 0 0 1 0 0
#12row-1271 1 0 0 0x00 1 0 0 0 0 1
#13row-1377 1 0 0 0x01 1 0 0 0 0 0
#14row-1482 1 0 0 0x80 1 0 0 1 0 0
#15row-1587 1 0 0 0xFF 1 0 0 1 0 0
#16row-1693 0 1 0 0x00 0 0 0 0 0 1
#17row-1799 0 1 0 0x01 0 0 0 0 0 0
#18row-18104 0 1 0 0x80 0 0 0 1 0 0
#19row-19109 0 1 0 0xFF 0 0 0 1 0 0
#20row-20115 1 1 0 0x00 0 0 1 0 0 1
#21row-21121 1 1 0 0x01 0 0 1 0 0 0
#22row-22126 1 1 0 0x80 0 0 1 1 0 0
#23row-23131 1 1 0 0xFF 0 0 1 1 0 0
#24row-24137 0 1 0 0x00 1 0 0 0 0 1
#25row-25143 0 1 0 0x01 1 0 0 0 0 0
#26row-26148 0 1 0 0x80 1 0 0 1 0 0
#27row-27153 0 1 0 0xFF 1 0 0 1 0 0
#28row-28159 1 1 0 0x00 1 0 1 0 0 1
#29row-29165 1 1 0 0x01 1 0 1 0 0 0
#30row-30170 1 1 0 0x80 1 0 1 1 0 0
#31row-31175 1 1 0 0xFF 1 0 1 1 0 0
#32row-32181 0 0 1 0x00 0 0 0 0 0 1
#33row-33187 0 0 1 0x01 0 0 0 0 0 0
#34row-34192 0 0 1 0x80 0 0 0 1 0 0
#35row-35197 0 0 1 0xFF 0 0 0 1 0 0
#36row-36203 1 0 1 0x00 0 0 0 0 1 1
#37row-37209 1 0 1 0x01 0 0 0 0 1 0
#38row-38214 1 0 1 0x80 0 0 0 1 1 0
#39row-39219 1 0 1 0xFF 0 0 0 1 1 0
#40row-40225 0 0 1 0x00 1 0 0 0 0 1
#41row-41231 0 0 1 0x01 1 0 0 0 0 0
#42row-42236 0 0 1 0x80 1 0 0 1 0 0
#43row-43241 0 0 1 0xFF 1 0 0 1 0 0
#44row-44247 1 0 1 0x00 1 0 0 0 1 1
#45row-45253 1 0 1 0x01 1 0 0 0 1 0
#46row-46258 1 0 1 0x80 1 0 0 1 1 0
#47row-47263 1 0 1 0xFF 1 0 0 1 1 0
#48row-48269 0 1 1 0x00 0 0 0 0 0 1
#49row-49275 0 1 1 0x01 0 0 0 0 0 0
#50row-50280 0 1 1 0x80 0 0 0 1 0 0
#51row-51285 0 1 1 0xFF 0 0 0 1 0 0
#52row-52291 1 1 1 0x00 0 0 1 0 1 1
#53row-53297 1 1 1 0x01 0 0 1 0 1 0
#54row-54302 1 1 1 0x80 0 0 1 1 1 0
#55row-55307 1 1 1 0xFF 0 0 1 1 1 0
#56row-56313 0 1 1 0x00 1 0 0 0 0 1
#57row-57319 0 1 1 0x01 1 0 0 0 0 0
#58row-58324 0 1 1 0x80 1 0 0 1 0 0
#59row-59329 0 1 1 0xFF 1 0 0 1 0 0
#60row-60335 1 1 1 0x00 1 0 1 0 1 1
#61row-61341 1 1 1 0x01 1 0 1 0 1 0
#62row-62346 1 1 1 0x80 1 0 1 1 1 0
#63row-63351 1 1 1 0xFF 1 0 1 1 1 0
#64row-64357 0 0 0 0x00 0 1 0 0 0 1
#65row-65363 0 0 0 0x01 0 1 0 0 0 0
#66row-66368 0 0 0 0x80 0 1 0 1 0 0
#67row-67373 0 0 0 0xFF 0 1 0 1 0 0
#68row-68379 1 0 0 0x00 0 1 0 0 0 1
#69row-69385 1 0 0 0x01 0 1 0 0 0 0
#70row-70390 1 0 0 0x80 0 1 0 1 0 0
#71row-71395 1 0 0 0xFF 0 1 0 1 0 0
#72row-72401 0 0 0 0x00 1 1 1 0 0 1
#73row-73407 0 0 0 0x01 1 1 1 0 0 0
#74row-74412 0 0 0 0x80 1 1 1 1 0 0
#75row-75417 0 0 0 0xFF 1 1 1 1 0 0
#76row-76423 1 0 0 0x00 1 1 1 0 0 1
#77row-77429 1 0 0 0x01 1 1 1 0 0 0
#78row-78434 1 0 0 0x80 1 1 1 1 0 0
#79row-79439 1 0 0 0xFF 1 1 1 1 0 0
#80row-80445 0 1 0 0x00 0 1 0 0 0 1
#81row-81451 0 1 0 0x01 0 1 0 0 0 0
#82row-82456 0 1 0 0x80 0 1 0 1 0 0
#83row-83461 0 1 0 0xFF 0 1 0 1 0 0
#84row-84467 1 1 0 0x00 0 1 1 0 0 1
#85row-85473 1 1 0 0x01 0 1 1 0 0 0
#86row-86478 1 1 0 0x80 0 1 1 1 0 0
#87row-87483 1 1 0 0xFF 0 1 1 1 0 0
#88row-88489 0 1 0 0x00 1 1 1 0 0 1
#89row-89495 0 1 0 0x01 1 1 1 0 0 0
#90row-90500 0 1 0 0x80 1 1 1 1 0 0
#91row-91505 0 1 0 0xFF 1 1 1 1 0 0
#92row-92511 1 1 0 0x00 1 1 1 0 0 1
#93row-93517 1 1 0 0x01 1 1 1 0 0 0
#94row-94522 1 1 0 0x80 1 1 1 1 0 0
#95row-95527 1 1 0 0xFF 1 1 1 1 0 0
#96row-96533 0 0 1 0x00 0 1 0 0 0 1
#97row-97539 0 0 1 0x01 0 1 0 0 0 0
#98row-98544 0 0 1 0x80 0 1 0 1 0 0
#99row-99549 0 0 1 0xFF 0 1 0 1 0 0
#100row-100555 1 0 1 0x00 0 1 0 0 1 1
#101row-101561 1 0 1 0x01 0 1 0 0 1 0
#102row-102566 1 0 1 0x80 0 1 0 1 1 0
#103row-103571 1 0 1 0xFF 0 1 0 1 1 0
#104row-104577 0 0 1 0x00 1 1 1 0 0 1
#105row-105583 0 0 1 0x01 1 1 1 0 0 0
#106row-106588 0 0 1 0x80 1 1 1 1 0 0
#107row-107593 0 0 1 0xFF 1 1 1 1 0 0
#108row-108599 1 0 1 0x00 1 1 1 0 1 1
#109row-109605 1 0 1 0x01 1 1 1 0 1 0
#110row-110610 1 0 1 0x80 1 1 1 1 1 0
#111row-111615 1 0 1 0xFF 1 1 1 1 1 0
#112row-112621 0 1 1 0x00 0 1 0 0 0 1
#113row-113627 0 1 1 0x01 0 1 0 0 0 0
#114row-114632 0 1 1 0x80 0 1 0 1 0 0
#115row-115637 0 1 1 0xFF 0 1 0 1 0 0
#116row-116643 1 1 1 0x00 0 1 1 0 1 1
#117row-117649 1 1 1 0x01 0 1 1 0 1 0
#118row-118654 1 1 1 0x80 0 1 1 1 1 0
#119row-119659 1 1 1 0xFF 0 1 1 1 1 0
#120row-120665 0 1 1 0x00 1 1 1 0 0 1
#121row-121671 0 1 1 0x01 1 1 1 0 0 0
#122row-122676 0 1 1 0x80 1 1 1 1 0 0
#123row-123681 0 1 1 0xFF 1 1 1 1 0 0
#124row-124687 1 1 1 0x00 1 1 1 0 1 1
#125row-125693 1 1 1 0x01 1 1 1 0 1 0
#126row-126698 1 1 1 0x80 1 1 1 1 1 0
#127row-127703 1 1 1 0xFF 1 1 1 1 1 0

Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.

Rows with both ARITHMETIC = 1 and SHIFT = 1 demonstrate the standalone both-enables-high behavior, not a valid complete-ALU operation group.

Embedded simulation

The alu8-flags scenario runs ALU8FlagUnitTest: 128 recorded binary cases, covering all 32 combinations of the five single-bit inputs with each of four result words (0x00, 0x01, 0x80, 0xFF). All appear in the table above. The source flags are driven by the test; upstream arithmetic and shifting are not part of this standalone circuit.

Open ALU8FlagUnit in the simulator

Source and tests

Test Coverage
ALU8FlagUnitTest / flagsRows() 128 recorded binary cases: 32 control/source-flag combinations × four result words. Checks all four outputs, including both enables high; this is the embedded scenario.
ALU8Test and ALU8ContractTest Check flags through the complete ALU, with its actual result selector and group enables. Contract cases include unknown result data and unknown carry for a zero-distance rotation.

The 128-case scenario is exhaustive over the five binary single-bit inputs for those four result words, not over all 256 words or four-state combinations.