Skip to content

§ 2.2. Logic Operations

LogicUnit8 provides the seven bitwise operations of ALU8. This page specifies the standalone component; its local operation selector is not the complete ALU's five-bit opcode.

Component Description Structural Behavioral
LogicUnit8 Selects an eight-bit AND, OR, XOR, NOT, NAND, NOR, or XNOR result Yes Yes

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

The bit numbering and combinational conventions from 2.1. Arithmetic Components apply here. The simplified C++ example describes binary behavior, not the simulator implementation; it omits propagation delays and X/Z handling.

2.2.1. LogicUnit8

LogicUnit8 computes bitwise results from two eight-bit operands and selects one result for OUT. It has no carry input, flags, or stored state.

IO pins

Pin Direction Width Description
A Input 8 First operand; the only operand used by NOT
B Input 8 Second operand; ignored by NOT and the reserved selection
OP Input 3 Local logic operation selector
OUT Output 8 Selected bitwise result

Behavior

Each output bit depends on the corresponding operand bits. There is no carry propagation between bit positions. Complements are restricted to eight bits; these are bitwise operations, not logical operations on whole-word truth values.

Local OP Operation OUT Uses B? Complete ALU8.OP
0b000 AND A & B Yes 0x08
0b001 OR A \| B Yes 0x09
0b010 XOR A ^ B Yes 0x0A
0b011 NOT (~A) & 0xFF No 0x0B
0b100 NAND (~(A & B)) & 0xFF Yes 0x0C
0b101 NOR (~(A \| B)) & 0xFF Yes 0x0D
0b110 XNOR (~(A ^ B)) & 0xFF Yes 0x0E
0b111 Reserved 0x00, independently of A and B No 0x0F is reserved

The standalone component has no INVALID_OP output. Its reserved selection returns zero; the complete ALU separately reports reserved global encodings through INVALID_OP. The complete ALU also derives ZERO and NEGATIVE from the selected result and clears CARRY and OVERFLOW for logic operations.

C++ example

#include <cstdint>

std::uint8_t logic8_ref(
    std::uint8_t a, std::uint8_t b, std::uint8_t op) {
    const unsigned x = a, y = b;
    unsigned result;
    switch (op) {
    case 0: result = x & y; break;
    case 1: result = x | y; break;
    case 2: result = x ^ y; break;
    case 3: result = ~x; break;
    case 4: result = ~(x & y); break;
    case 5: result = ~(x | y); break;
    case 6: result = ~(x ^ y); break;
    default: result = 0; break;
    }
    return static_cast<std::uint8_t>(result & 0xFFu);
}

op represents the three-bit local selector. Out-of-range integer arguments also return zero, although they cannot occur on a three-bit binary pin.

Unknown inputs and timing

For a known OP, the gates retain bit-level four-state behavior:

  • 0 AND X = 0 and 1 OR X = 1; a controlling operand can determine an output despite an unknown input.
  • XOR and inversion produce X when their relevant input is unknown. Z inputs are treated as unknown logic by these gates, not forwarded as high impedance.
  • NOT ignores B, including X or Z values. The known reserved selection returns zero even when either operand is unknown.

An unknown selector follows the structural multiplexer gates; it is not interpreted as the reserved binary code. The C++ example cannot represent these states.

Operand or opcode changes propagate through gates and multiplexers. Different result bits can settle at different times; there is no single declared component latency. The tables specify settled outputs.

Implementation

Structural implementation

Internal component Count Function
BitSplitter<8> 2 Expose the individual bits of A and B
ANDGate, ORGate, XORGate 8 each Compute the three binary operations, one gate per bit
NOTGate 32 Invert A and the three binary results for NOT, NAND, NOR, and XNOR
Mux8to1 8 Select one of seven results or constant zero for each bit
ConstantValue<1> 1 Supply the reserved selection's zero
BitJoiner<8> 1 Assemble the selected bits into OUT

These counts describe direct children of LogicUnit8; the multiplexers contain additional gates. NAND, NOR, and XNOR reuse the corresponding non-inverted result and a NOTGate, rather than instantiate separate eight-bit operation modules.

Behavioral implementation

Behavioral8<LogicUnit8> calls logic. For each bit, it computes the AND, OR, XOR, and inverted candidates, then selects one through a four-state eight-way multiplexer function. The reserved input is constant zero. Unknown selectors follow the multiplexer expressions, not a binary switch.

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 32 recorded rows of LogicUnit8Test, 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 (eeec4c95c93305c1). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units AInput · 8 bit BInput · 8 bit OPInput · 3 bit OUTExpected output · 8 bit
#0row-08 0x00 0x0F 0x0 0x00
#1row-117 0x55 0x0F 0x0 0x05
#2row-226 0x80 0x0F 0x0 0x00
#3row-335 0xFF 0x0F 0x0 0x0F
#4row-444 0x00 0x0F 0x1 0x0F
#5row-553 0x55 0x0F 0x1 0x5F
#6row-662 0x80 0x0F 0x1 0x8F
#7row-771 0xFF 0x0F 0x1 0xFF
#8row-880 0x00 0x0F 0x2 0x0F
#9row-989 0x55 0x0F 0x2 0x5A
#10row-1098 0x80 0x0F 0x2 0x8F
#11row-11107 0xFF 0x0F 0x2 0xF0
#12row-12116 0x00 0x0F 0x3 0xFF
#13row-13125 0x55 0x0F 0x3 0xAA
#14row-14134 0x80 0x0F 0x3 0x7F
#15row-15143 0xFF 0x0F 0x3 0x00
#16row-16153 0x00 0x0F 0x4 0xFF
#17row-17163 0x55 0x0F 0x4 0xFA
#18row-18173 0x80 0x0F 0x4 0xFF
#19row-19183 0xFF 0x0F 0x4 0xF0
#20row-20193 0x00 0x0F 0x5 0xF0
#21row-21203 0x55 0x0F 0x5 0xA0
#22row-22213 0x80 0x0F 0x5 0x70
#23row-23223 0xFF 0x0F 0x5 0x00
#24row-24233 0x00 0x0F 0x6 0xF0
#25row-25243 0x55 0x0F 0x6 0xA5
#26row-26253 0x80 0x0F 0x6 0x70
#27row-27263 0xFF 0x0F 0x6 0x0F
#28row-28272 0x00 0x0F 0x7 0x00
#29row-29280 0x55 0x0F 0x7 0x00
#30row-30288 0x80 0x0F 0x7 0x00
#31row-31296 0xFF 0x0F 0x7 0x00

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.

Embedded simulation

The logic8 scenario runs LogicUnit8Test: 32 recorded cases covering all eight local selections, with A drawn from 0x00, 0x55, 0x80, and 0xFF, and B = 0x0F. The table above lists every recorded row; use its checkpoint labels to locate the settled outputs.

Open LogicUnit8 in the simulator

Source and tests

Test Coverage
LogicUnit8Test 32 binary cases: eight local selections × four A values, with B = 0x0F. Checks OUT; this is the embedded scenario.
ALU8ContractTest: integrated checks Boundary and seeded random cases across all global opcodes, including logic operations. Targeted X/Z cases check NOT's ignored inputs, AND masking, XOR propagation, and reserved global encodings.

Neither test exhaustively sweeps standalone LogicUnit8 inputs. The integrated test's larger arithmetic and shifter sweeps do not constitute an exhaustive logic-unit test.