§ 2.1. Arithmetic Components¶
The arithmetic path of ALU8 provides addition, subtraction, carry-aware arithmetic, increment, decrement, and negation. This page specifies its components in construction order: one-bit adders, the eight-bit carry chain, shared addition/subtraction, and arithmetic-operation selection. Each reference covers IO pins, behavior, circuit structure, and examples. Multiplication and division are not included.
| Component | Description | Structural | Behavioral |
|---|---|---|---|
HalfAdder |
Adds two bits; produces a sum bit and carry without a carry input | Yes | No |
FullAdder |
Adds two bits and a carry input using two half adders and an OR gate | Yes | No |
Adder8 |
Adds two eight-bit operands and a carry input; produces a sum and carry output | Yes | Yes |
AddSub8 |
Shares an addition/subtraction path with independent carry input, carry/no-borrow output, and signed overflow | Yes | Yes |
ArithmeticUnit8 |
Selects and prepares operands for addition, subtraction, carry-aware arithmetic, increment, decrement, and negation | Yes | Yes |
These columns indicate registered simulator implementations; the simplified C++ examples below are not counted.
Conventions¶
HalfAdderandFullAdderhave one-bit pins. Their carry outputs represent the second bit of the unsigned sum, not signed-overflow flags.- Eight-bit pins carry bit patterns from
0x00through0xFF; bit 0 is the least significant bit. - Arithmetic results wrap modulo 256. Carry and overflow report information lost from the eight-bit result; they do not change or saturate it.
- Signed interpretation uses two's complement:
0x00–0x7Frepresent 0–127, and0x80–0xFFrepresent −128–−1. - A subtraction carry output of
1means no unsigned borrow. An incoming carry of0supplies an incoming borrow forSBC. - The components are combinational. They have no clock, reset, stored flags, or completion signal. Results below describe settled outputs, not intermediate propagation states.
The simplified C++ examples under Behavior describe binary values, not the simulator implementation. They omit event scheduling, gate delays, and X/Z handling. The functions can be compiled together in the order shown.
The Behavioral implementation subsections describe the registered compact evaluators and how they compute four-state outputs. These are separate from the simplified C++ examples. The structural implementation remains the default for the embedded simulations and checkpoint tables.
When selected through the component catalog, an ALU8 behavioral part receives an output delay table characterized from its structural counterpart. The table distinguishes input-to-output paths and, for the complete ALU, operation codes. A supported delay twin follows the current input bits through a flat gate list and can publish when that case settles, within the table's bound. The compact part still omits intermediate gate glitches. A directly created part without an attached table retains its constructor delay. These are simulator ticks, not a CPU clock period or calibrated hardware time.
2.1.1. HalfAdder¶
HalfAdder adds two one-bit operands. It has no carry input, so it cannot by itself be a general cell in a multi-bit carry chain.
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
A |
Input | 1 | First operand bit |
B |
Input | 1 | Second operand bit |
Sum |
Output | 1 | Low bit of the sum |
Carry |
Output | 1 | Carry into the next bit position |
The output is named Carry, not Carry_out or Cout. Pin names are case-sensitive.
Behavior¶
For binary inputs,
Interpreting the bits as unsigned integers, A + B = Sum + 2*Carry. For example, 1 + 1 gives Sum = 0, Carry = 1. The component has no clock, stored state, or flags beyond this carry.
C++ example¶
struct HalfAdderResult {
bool Sum;
bool Carry;
};
HalfAdderResult half_adder_ref(bool a, bool b) {
return {a != b, a && b};
}
This binary-only function describes the settled outputs. It is not a registered behavioral implementation.
Unknown inputs and timing¶
The simulator's XOR produces X if either input is X or Z. The AND produces 0 if either input is definitely 0, 1 only if both are definitely 1, and X otherwise. Neither output drives Z.
A |
B |
Settled Sum |
Settled Carry |
|---|---|---|---|
| 0 | X or Z |
X |
0 |
| 1 | X or Z |
X |
X |
Both gates have a one-tick delay; the settling analysis proves that no output changes later than one tick after its inputs. These are abstract simulator ticks, not calibrated hardware timing. The recorded checkpoint times include the test's stimulus spacing and settling margin, so they are not the gate delay itself.
Implementation¶
Structural implementation¶
Both inputs fan out to two gates, which operate in parallel:
| Child | Type | Inputs → output |
|---|---|---|
XOR1 |
XORGate |
A, B → Sum |
AND1 |
ANDGate |
A, B → Carry |
There is no internal carry chain or storage. HalfAdder currently has only this structural implementation; the two gates remain visible in the simulator.
Examples¶
All 16 recorded rows of HalfAdderTest, 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 (7fa4118a10b2bf2c). Changing fidelity or the circuit can change these times.
| Checkpointzero-based number · timeline label | Timesimulator units | AInput · 1 bit |
BInput · 1 bit |
CarryExpected output · 1 bit |
SumExpected output · 1 bit |
|---|---|---|---|---|---|
#0row-0 | 1 | 0 |
0 |
0 |
0 |
#1row-1 | 3 | 0 |
1 |
0 |
1 |
#2row-2 | 5 | 0 |
X |
0 |
X |
#3row-3 | 7 | 0 |
Z |
0 |
X |
#4row-4 | 9 | 1 |
0 |
0 |
1 |
#5row-5 | 11 | 1 |
1 |
1 |
0 |
#6row-6 | 13 | 1 |
X |
X |
X |
#7row-7 | 15 | 1 |
Z |
X |
X |
#8row-8 | 17 | X |
0 |
0 |
X |
#9row-9 | 19 | X |
1 |
X |
X |
#10row-10 | 21 | X |
X |
X |
X |
#11row-11 | 23 | X |
Z |
X |
X |
#12row-12 | 25 | Z |
0 |
0 |
X |
#13row-13 | 27 | Z |
1 |
X |
X |
#14row-14 | 29 | Z |
X |
X |
X |
#15row-15 | 31 | Z |
Z |
X |
X |
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.
The table contains all 16 combinations of A and B from {0, 1, X, Z}: four binary cases and twelve nonbinary cases. Each row checks both outputs. The checkpoint number and time identify the same settled observation in the simulation below.
Embedded simulation¶
The half-adder scenario runs HalfAdderTest. Inspect XOR1 and AND1 for the sum and carry paths. Compare (A, B) = (0, X) with (1, X) to see how a known zero suppresses uncertainty in the AND output without making the sum known.
Open HalfAdder in the simulator
Source and tests¶
| Test | Coverage |
|---|---|
HalfAdderTest / halfAdderRows() |
All 16 four-state input combinations; verifies settled Sum and Carry |
SettlingAnalysisTest |
Proves a one-tick settling bound |
DocumentationExamplesTest |
Checks the reference pattern, implementation availability, and complete example-table export; compiles the actual C++ example and checks all four binary cases |
The binary C++ check does not verify X/Z behavior. Those cases are verified by the structural scenario and retained in its table and simulation.
2.1.2. FullAdder¶
FullAdder adds two one-bit operands and a carry input. Its carry output can feed the next bit position; eight such cells form Adder8.
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
A |
Input | 1 | First operand bit |
B |
Input | 1 | Second operand bit |
Carry_in |
Input | 1 | Carry from the previous bit position |
Sum |
Output | 1 | Low bit of the three-input sum |
Carry_out |
Output | 1 | Carry into the next bit position |
Carry_in and Carry_out are the actual pins; they are not named Cin and Cout as on Adder8.
Behavior¶
Define the first half adder's sum as P = A XOR B. For binary inputs,
Thus A + B + Carry_in = Sum + 2*Carry_out. With three input ones, the result is Sum = 1, Carry_out = 1; with exactly two ones, it is Sum = 0, Carry_out = 1. The carry is not a signed-overflow indication.
C++ example¶
struct FullAdderResult {
bool Sum;
bool Carry_out;
};
FullAdderResult full_adder_ref(bool a, bool b, bool carry_in) {
const auto first = half_adder_ref(a, b);
const auto second = half_adder_ref(first.Sum, carry_in);
return {second.Sum, first.Carry || second.Carry};
}
This example reuses half_adder_ref above and follows the actual two-half-adder composition. It describes binary settled values, not simulator events or a selectable behavioral implementation.
Unknown inputs and timing¶
X/Z inputs propagate through the two half adders and final OR gate. Use the stated XOR/AND/OR network, not an arbitrary binary-equivalent rewrite, to determine four-state results. For example:
A |
B |
Carry_in |
Settled Sum |
Settled Carry_out |
|---|---|---|---|---|
| 0 | 0 | Z |
X |
0 |
| 1 | 1 | X |
X |
1 |
| 1 | X |
1 | X |
X |
In the last row, both the first sum and both intermediate carries are unknown. The binary-equivalent majority expression (A AND B) OR (A AND Carry_in) OR (B AND Carry_in) would instead yield carry 1 because A AND Carry_in = 1. That is not this structural circuit's four-state contract. Neither output drives Z.
The longest structural path is HA1.XOR1 → HA2.AND1 → OR1, totaling three abstract delay ticks. The sum path through two XOR gates is shorter, so sum and carry need not settle simultaneously. The settling analysis proves the three-tick bound; the example table records later settled checkpoints, not each internal transition.
Implementation¶
Structural implementation¶
| Child | Type | Inputs → output |
|---|---|---|
HA1 |
HalfAdder |
External A, B → intermediate sum and first carry |
HA2 |
HalfAdder |
HA1.Sum, external Carry_in → external Sum and second carry |
OR1 |
ORGate |
HA1.Carry, HA2.Carry → external Carry_out |
Expanding the two half adders reveals five primitive gates in total: two XORs, two ANDs, and one OR. There is no stored carry or clock. FullAdder currently has only this structural implementation.
In the eight-bit chain, Adder8.Cin drives FA0.Carry_in, each cell's Carry_out drives the next cell's Carry_in, and FA7.Carry_out drives Adder8.Cout. This is a ripple-carry connection, not eight independent additions.
Examples¶
All 64 recorded rows of FullAdderTest, 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 (25ccf9ef8ae550ea). Changing fidelity or the circuit can change these times.
| Checkpointzero-based number · timeline label | Timesimulator units | AInput · 1 bit |
BInput · 1 bit |
Carry_inInput · 1 bit |
Carry_outExpected output · 1 bit |
SumExpected output · 1 bit |
|---|---|---|---|---|---|---|
#0row-0 | 2 | 0 |
0 |
0 |
0 |
0 |
#1row-1 | 4 | 0 |
0 |
1 |
0 |
1 |
#2row-2 | 6 | 0 |
0 |
X |
0 |
X |
#3row-3 | 8 | 0 |
0 |
Z |
0 |
X |
#4row-4 | 11 | 0 |
1 |
0 |
0 |
1 |
#5row-5 | 14 | 0 |
1 |
1 |
1 |
0 |
#6row-6 | 17 | 0 |
1 |
X |
X |
X |
#7row-7 | 19 | 0 |
1 |
Z |
X |
X |
#8row-8 | 22 | 0 |
X |
0 |
0 |
X |
#9row-9 | 25 | 0 |
X |
1 |
X |
X |
#10row-10 | 27 | 0 |
X |
X |
X |
X |
#11row-11 | 29 | 0 |
X |
Z |
X |
X |
#12row-12 | 32 | 0 |
Z |
0 |
0 |
X |
#13row-13 | 35 | 0 |
Z |
1 |
X |
X |
#14row-14 | 37 | 0 |
Z |
X |
X |
X |
#15row-15 | 39 | 0 |
Z |
Z |
X |
X |
#16row-16 | 42 | 1 |
0 |
0 |
0 |
1 |
#17row-17 | 45 | 1 |
0 |
1 |
1 |
0 |
#18row-18 | 48 | 1 |
0 |
X |
X |
X |
#19row-19 | 50 | 1 |
0 |
Z |
X |
X |
#20row-20 | 53 | 1 |
1 |
0 |
1 |
0 |
#21row-21 | 55 | 1 |
1 |
1 |
1 |
1 |
#22row-22 | 57 | 1 |
1 |
X |
1 |
X |
#23row-23 | 59 | 1 |
1 |
Z |
1 |
X |
#24row-24 | 62 | 1 |
X |
0 |
X |
X |
#25row-25 | 65 | 1 |
X |
1 |
X |
X |
#26row-26 | 67 | 1 |
X |
X |
X |
X |
#27row-27 | 69 | 1 |
X |
Z |
X |
X |
#28row-28 | 72 | 1 |
Z |
0 |
X |
X |
#29row-29 | 75 | 1 |
Z |
1 |
X |
X |
#30row-30 | 77 | 1 |
Z |
X |
X |
X |
#31row-31 | 79 | 1 |
Z |
Z |
X |
X |
#32row-32 | 82 | X |
0 |
0 |
0 |
X |
#33row-33 | 85 | X |
0 |
1 |
X |
X |
#34row-34 | 87 | X |
0 |
X |
X |
X |
#35row-35 | 89 | X |
0 |
Z |
X |
X |
#36row-36 | 92 | X |
1 |
0 |
X |
X |
#37row-37 | 95 | X |
1 |
1 |
X |
X |
#38row-38 | 97 | X |
1 |
X |
X |
X |
#39row-39 | 99 | X |
1 |
Z |
X |
X |
#40row-40 | 102 | X |
X |
0 |
X |
X |
#41row-41 | 105 | X |
X |
1 |
X |
X |
#42row-42 | 107 | X |
X |
X |
X |
X |
#43row-43 | 109 | X |
X |
Z |
X |
X |
#44row-44 | 112 | X |
Z |
0 |
X |
X |
#45row-45 | 115 | X |
Z |
1 |
X |
X |
#46row-46 | 117 | X |
Z |
X |
X |
X |
#47row-47 | 119 | X |
Z |
Z |
X |
X |
#48row-48 | 122 | Z |
0 |
0 |
0 |
X |
#49row-49 | 125 | Z |
0 |
1 |
X |
X |
#50row-50 | 127 | Z |
0 |
X |
X |
X |
#51row-51 | 129 | Z |
0 |
Z |
X |
X |
#52row-52 | 132 | Z |
1 |
0 |
X |
X |
#53row-53 | 135 | Z |
1 |
1 |
X |
X |
#54row-54 | 137 | Z |
1 |
X |
X |
X |
#55row-55 | 139 | Z |
1 |
Z |
X |
X |
#56row-56 | 142 | Z |
X |
0 |
X |
X |
#57row-57 | 145 | Z |
X |
1 |
X |
X |
#58row-58 | 147 | Z |
X |
X |
X |
X |
#59row-59 | 149 | Z |
X |
Z |
X |
X |
#60row-60 | 152 | Z |
Z |
0 |
X |
X |
#61row-61 | 155 | Z |
Z |
1 |
X |
X |
#62row-62 | 157 | Z |
Z |
X |
X |
X |
#63row-63 | 159 | Z |
Z |
Z |
X |
X |
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.
The table contains all 64 combinations of A, B, and Carry_in from {0, 1, X, Z}: eight binary cases and 56 nonbinary cases. Both outputs are checked at every checkpoint. The cases are exhaustive for settled four-state input combinations, not for every possible sequence of propagation glitches.
Embedded simulation¶
The full-adder scenario runs FullAdderTest. Expand HA1 and HA2 to inspect their gates, or keep them collapsed to trace the two intermediate carries into OR1. Compare (1, 1, X) with (1, X, 1) to inspect the four-state distinction described above.
Open FullAdder in the simulator
Source and tests¶
| Test | Coverage |
|---|---|
FullAdderTest / fullAdderRows() |
All 64 four-state input combinations; verifies settled Sum and Carry_out against the two-half-adder network |
SettlingAnalysisTest |
Proves the three-tick settling bound and reports its path |
DocumentationExamplesTest |
Checks the reference pattern, implementation availability, and complete example-table export; compiles this C++ example with half_adder_ref and checks all eight binary cases |
The embedded simulation and table use the structural test's complete sequence. The C++ function checks only binary values; it does not replace the four-state structural test.
2.1.3. Adder8¶
Adder8 adds two eight-bit operands and a one-bit carry input. It produces the low eight bits of the sum and a separate carry output.
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
A |
Input | 8 | First operand |
B |
Input | 8 | Second operand |
Cin |
Input | 1 | Carry added to the operands |
Sum |
Output | 8 | Low eight bits of the sum |
Cout |
Output | 1 | Carry beyond bit 7 |
Pin names are case-sensitive. Cin, Sum, and Cout are the existing component's names; they are not aliases for the uppercase pins on the new components.
Behavior¶
Treating A and B as unsigned values, let
Then
Here, brackets denote a Boolean condition: 1 when true, otherwise 0. Adder8 does not expose signed overflow, zero, or negative flags.
C++ example¶
#include <cstdint>
struct Adder8Result {
std::uint8_t Sum;
bool Cout;
};
Adder8Result adder8_ref(std::uint8_t a, std::uint8_t b, bool cin) {
const unsigned total = unsigned(a) + unsigned(b) + unsigned(cin);
return {
static_cast<std::uint8_t>(total & 0xFFu),
total >= 0x100u,
};
}
The intermediate value must be wider than eight bits so that computing Cout does not lose the carry.
Unknown inputs and timing¶
The structural implementation preserves gate-level four-state behavior. An unknown bit need not make every output unknown. For example, with bits written from bit 7 to bit 0:
A |
B |
Cin |
Settled Sum |
Settled Cout |
|---|---|---|---|---|
0000000X |
00000000 |
0 | 0000000X |
0 |
0000000Z |
00000000 |
0 | 0000000X |
0 |
In this table, Z denotes high impedance, not the ALU's zero flag. The examples are covered by the current Adder8Test rows. The C++ example cannot represent these inputs.
Output changes pass through the splitter, full-adder gates, and joiner. There is no single declared structural Adder8 latency; consumers must allow the structural circuit to settle before interpreting its outputs.
Implementation¶
Structural implementation¶
The current component contains:
| Internal component | Count | Connection |
|---|---|---|
BitSplitter<8> |
2 | Splits A and B into individual bits |
FullAdder |
8 | Adds corresponding operand bits and the incoming carry |
BitJoiner<8> |
1 | Assembles the eight sum bits into Sum |
Cin connects to FA0.Carry_in. Each FAi.Carry_out connects to the next cell's Carry_in; FA7.Carry_out drives Cout. Each full adder consists of two half adders and an ORGate.
The implementation currently instantiates eight full adders directly. It does not contain a separate four-bit slice component.
Behavioral implementation¶
Behavioral8<Adder8> calls the four-state add function. It computes each sum bit and the carry chain using the same XOR/AND/OR expressions as the full-adder cells, without constructing eight FullAdder objects.
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 14 recorded rows of Adder8Test, 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 (7f3b5bb631aed64b). Changing fidelity or the circuit can change these times.
| Checkpointzero-based number · timeline label | Timesimulator units | AInput · 8 bit |
BInput · 8 bit |
CinInput · 1 bit |
CoutExpected output · 1 bit |
SumExpected output · 8 bit |
|---|---|---|---|---|---|---|
#0row-0 | 5 | 0x00 |
0x00 |
0 |
0 |
0x00 |
#1row-1 | 9 | 0x01 |
0x02 |
0 |
0 |
0x03 |
#2row-2 | 20 | 0x0F |
0x01 |
0 |
0 |
0x10 |
#3row-3 | 31 | 0xFF |
0x01 |
0 |
1 |
0x00 |
#4row-4 | 50 | 0xFF |
0x00 |
1 |
1 |
0x00 |
#5row-5 | 55 | 0x7F |
0x00 |
1 |
0 |
0x80 |
#6row-6 | 61 | 0x80 |
0x80 |
0 |
1 |
0x00 |
#7row-7 | 80 | 0xAA |
0x55 |
1 |
1 |
0x00 |
#8row-8 | 86 | 0x00 |
0x00 |
1 |
0 |
0x01 |
#9row-9 | 91 | 0xFF |
0xFF |
0 |
1 |
0xFE |
#10row-10 | 110 | 0x80 |
0x7F |
1 |
1 |
0x00 |
#11row-11 | 127 | 0x55 |
0xAA |
0 |
0 |
0xFF |
#12row-12 | 131 | 0b0000000X |
0x00 |
0 |
0 |
0b0000000X |
#13row-13 | 134 | 0b0000000Z |
0x00 |
0 |
0 |
0b0000000X |
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.
For wider addition, connect the lower byte's Cout to the upper byte's Cin. For example, 0x00FF + 0x0001 produces a low-byte result of 0x00 with carry 1, followed by an upper-byte result of 0x01.
Embedded simulation¶
The existing adder8 scenario exposes Adder8Test. Its 14 recorded cases include ordinary sums, carry propagation, and two unknown-value cases; it is not an exhaustive input sweep. The table above contains the complete recorded sequence. Match its checkpoint labels and times with the timeline to inspect settled outputs.
Source and tests¶
| Test | Coverage |
|---|---|
Adder8Test / adder8Rows() |
14 recorded cases: 12 binary cases and two cases with bit 0 of A driven to X or Z. Checks Sum and Cout; not an exhaustive sweep. |
The embedded simulation runs this same recorded scenario. The C++ example is binary-only and does not verify four-state propagation or settling time.
2.1.4. AddSub8¶
AddSub8 extends an eight-bit addition path with conditional inversion of B and signed-overflow detection. SUB controls inversion; C_IN independently controls the initial carry.
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
A |
Input | 8 | First operand |
B |
Input | 8 | Second operand before conditional inversion |
SUB |
Input | 1 | 0: use B; 1: use the eight-bit complement of B |
C_IN |
Input | 1 | Initial carry into the addition path |
OUT |
Output | 8 | Low eight bits of the result |
CARRY_OUT |
Output | 1 | Addition carry-out; no-borrow indicator for subtraction |
OVERFLOW |
Output | 1 | Signed result lies outside −128–127 |
Unlike AddSub32, whose initial carry is tied to SUB, AddSub8 exposes the carry independently.
Behavior¶
Define the effective second operand as
The unsigned addition path computes
SUB |
C_IN |
Arithmetic operation |
|---|---|---|
| 0 | 0 | A + B |
| 0 | 1 | A + B + 1 |
| 1 | 1 | A - B |
| 1 | 0 | A - B - 1 |
Subtraction does not automatically supply the carry
Setting SUB = 1 only complements B. Ordinary subtraction also requires C_IN = 1. SUB = 1, C_IN = 0 includes an incoming borrow.
For subtraction, the carry condition can also be written as
where the comparison is evaluated without eight-bit truncation. In particular, B = 0xFF, C_IN = 0 gives a threshold of 256, not zero.
Let \(s(x)\) interpret an eight-bit pattern as a signed integer:
OVERFLOW is 1 when the corresponding signed mathematical result is outside −128–127:
Carry and overflow are independent outputs. There is no signed/unsigned mode pin.
C++ example¶
struct AddSub8Result {
std::uint8_t OUT;
bool CARRY_OUT;
bool OVERFLOW;
};
AddSub8Result addsub8_ref(
std::uint8_t a, std::uint8_t b, bool sub, bool c_in) {
const auto effective_b = static_cast<std::uint8_t>(
b ^ (sub ? 0xFFu : 0x00u));
const auto sum = adder8_ref(a, effective_b, c_in);
const bool same_sign = ((a ^ effective_b) & 0x80u) == 0;
const bool result_changed_sign = ((a ^ sum.Sum) & 0x80u) != 0;
return {sum.Sum, sum.Cout, same_sign && result_changed_sign};
}
Unknown inputs and timing¶
The structural simulator variant evaluates the actual XOR gates, adder, and sign-bit logic, rather than the C++ example. It supports four signal states: 0, 1, X (unknown), and Z (high impedance). Gates interpret X and Z as unknown logic, not as an assumed 0 or 1; some outputs can still be determined from the other inputs.
After an input changes, values propagate through the internal gates. OUT, CARRY_OUT, and OVERFLOW can change at different times, so intermediate timeline positions can show temporary values or unknown bits. The operation tables describe settled outputs. Recorded test checkpoints occur after the circuit has settled; they are the appropriate points for checking those tables.
Implementation¶
Structural implementation¶
| Internal component | Function |
|---|---|
Eight XORGate instances |
Compute B'[i] = B[i] XOR SUB |
One Adder8 |
Compute A + B' + C_IN |
| Splitters and joiners | Expose operand/result bits and assemble B' |
| Sign-bit logic | Compute signed overflow from A[7], B'[7], and OUT[7] |
The output wiring is Adder8.Sum → OUT and Adder8.Cout → CARRY_OUT. Overflow follows
This arrangement reuses Adder8 without requiring access to its internal carry wires. No separate subtractor or stored state is needed.
Behavioral implementation¶
Behavioral8<AddSub8> calls addsub: it XORs each bit of B with SUB, evaluates the shared addition function with C_IN, and derives signed overflow from the operand and result sign bits. These operations use four-state logic rather than integer subtraction.
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 80 recorded rows of AddSub8Test, 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 (d2f4800e277ccc71). Changing fidelity or the circuit can change these times.
| Checkpointzero-based number · timeline label | Timesimulator units | AInput · 8 bit |
BInput · 8 bit |
C_INInput · 1 bit |
SUBInput · 1 bit |
CARRY_OUTExpected output · 1 bit |
OUTExpected output · 8 bit |
OVERFLOWExpected output · 1 bit |
|---|---|---|---|---|---|---|---|---|
#0row-0 | 10 | 0x00 |
0x00 |
0 |
0 |
0 |
0x00 |
0 |
#1row-1 | 13 | 0x00 |
0x00 |
1 |
0 |
0 |
0x01 |
0 |
#2row-2 | 21 | 0x00 |
0x00 |
0 |
1 |
0 |
0xFF |
0 |
#3row-3 | 40 | 0x00 |
0x00 |
1 |
1 |
1 |
0x00 |
0 |
#4row-4 | 50 | 0x00 |
0x01 |
0 |
0 |
0 |
0x01 |
0 |
#5row-5 | 55 | 0x00 |
0x01 |
1 |
0 |
0 |
0x02 |
0 |
#6row-6 | 63 | 0x00 |
0x01 |
0 |
1 |
0 |
0xFE |
0 |
#7row-7 | 66 | 0x00 |
0x01 |
1 |
1 |
0 |
0xFF |
0 |
#8row-8 | 75 | 0x00 |
0x80 |
0 |
0 |
0 |
0x80 |
0 |
#9row-9 | 78 | 0x00 |
0x80 |
1 |
0 |
0 |
0x81 |
0 |
#10row-10 | 86 | 0x00 |
0x80 |
0 |
1 |
0 |
0x7F |
0 |
#11row-11 | 105 | 0x00 |
0x80 |
1 |
1 |
0 |
0x80 |
1 |
#12row-12 | 123 | 0x00 |
0xFF |
0 |
0 |
0 |
0xFF |
0 |
#13row-13 | 142 | 0x00 |
0xFF |
1 |
0 |
1 |
0x00 |
0 |
#14row-14 | 152 | 0x00 |
0xFF |
0 |
1 |
0 |
0x00 |
0 |
#15row-15 | 155 | 0x00 |
0xFF |
1 |
1 |
0 |
0x01 |
0 |
#16row-16 | 164 | 0x01 |
0x00 |
0 |
0 |
0 |
0x01 |
0 |
#17row-17 | 169 | 0x01 |
0x00 |
1 |
0 |
0 |
0x02 |
0 |
#18row-18 | 190 | 0x01 |
0x00 |
0 |
1 |
1 |
0x00 |
0 |
#19row-19 | 193 | 0x01 |
0x00 |
1 |
1 |
1 |
0x01 |
0 |
#20row-20 | 203 | 0x01 |
0x01 |
0 |
0 |
0 |
0x02 |
0 |
#21row-21 | 206 | 0x01 |
0x01 |
1 |
0 |
0 |
0x03 |
0 |
#22row-22 | 227 | 0x01 |
0x01 |
0 |
1 |
0 |
0xFF |
0 |
#23row-23 | 246 | 0x01 |
0x01 |
1 |
1 |
1 |
0x00 |
0 |
#24row-24 | 256 | 0x01 |
0x80 |
0 |
0 |
0 |
0x81 |
0 |
#25row-25 | 261 | 0x01 |
0x80 |
1 |
0 |
0 |
0x82 |
0 |
#26row-26 | 282 | 0x01 |
0x80 |
0 |
1 |
0 |
0x80 |
1 |
#27row-27 | 285 | 0x01 |
0x80 |
1 |
1 |
0 |
0x81 |
1 |
#28row-28 | 307 | 0x01 |
0xFF |
0 |
0 |
1 |
0x00 |
0 |
#29row-29 | 310 | 0x01 |
0xFF |
1 |
0 |
1 |
0x01 |
0 |
#30row-30 | 320 | 0x01 |
0xFF |
0 |
1 |
0 |
0x01 |
0 |
#31row-31 | 325 | 0x01 |
0xFF |
1 |
1 |
0 |
0x02 |
0 |
#32row-32 | 347 | 0x7F |
0x00 |
0 |
0 |
0 |
0x7F |
0 |
#33row-33 | 366 | 0x7F |
0x00 |
1 |
0 |
0 |
0x80 |
1 |
#34row-34 | 374 | 0x7F |
0x00 |
0 |
1 |
1 |
0x7E |
0 |
#35row-35 | 377 | 0x7F |
0x00 |
1 |
1 |
1 |
0x7F |
0 |
#36row-36 | 399 | 0x7F |
0x01 |
0 |
0 |
0 |
0x80 |
1 |
#37row-37 | 402 | 0x7F |
0x01 |
1 |
0 |
0 |
0x81 |
1 |
#38row-38 | 410 | 0x7F |
0x01 |
0 |
1 |
1 |
0x7D |
0 |
#39row-39 | 415 | 0x7F |
0x01 |
1 |
1 |
1 |
0x7E |
0 |
#40row-40 | 437 | 0x7F |
0x80 |
0 |
0 |
0 |
0xFF |
0 |
#41row-41 | 456 | 0x7F |
0x80 |
1 |
0 |
1 |
0x00 |
0 |
#42row-42 | 464 | 0x7F |
0x80 |
0 |
1 |
0 |
0xFE |
1 |
#43row-43 | 467 | 0x7F |
0x80 |
1 |
1 |
0 |
0xFF |
1 |
#44row-44 | 477 | 0x7F |
0xFF |
0 |
0 |
1 |
0x7E |
0 |
#45row-45 | 480 | 0x7F |
0xFF |
1 |
0 |
1 |
0x7F |
0 |
#46row-46 | 501 | 0x7F |
0xFF |
0 |
1 |
0 |
0x7F |
0 |
#47row-47 | 520 | 0x7F |
0xFF |
1 |
1 |
0 |
0x80 |
1 |
#48row-48 | 531 | 0x80 |
0x00 |
0 |
0 |
0 |
0x80 |
0 |
#49row-49 | 534 | 0x80 |
0x00 |
1 |
0 |
0 |
0x81 |
0 |
#50row-50 | 542 | 0x80 |
0x00 |
0 |
1 |
1 |
0x7F |
1 |
#51row-51 | 561 | 0x80 |
0x00 |
1 |
1 |
1 |
0x80 |
0 |
#52row-52 | 571 | 0x80 |
0x01 |
0 |
0 |
0 |
0x81 |
0 |
#53row-53 | 576 | 0x80 |
0x01 |
1 |
0 |
0 |
0x82 |
0 |
#54row-54 | 584 | 0x80 |
0x01 |
0 |
1 |
1 |
0x7E |
1 |
#55row-55 | 587 | 0x80 |
0x01 |
1 |
1 |
1 |
0x7F |
1 |
#56row-56 | 596 | 0x80 |
0x80 |
0 |
0 |
1 |
0x00 |
1 |
#57row-57 | 599 | 0x80 |
0x80 |
1 |
0 |
1 |
0x01 |
1 |
#58row-58 | 607 | 0x80 |
0x80 |
0 |
1 |
0 |
0xFF |
0 |
#59row-59 | 626 | 0x80 |
0x80 |
1 |
1 |
1 |
0x00 |
0 |
#60row-60 | 644 | 0x80 |
0xFF |
0 |
0 |
1 |
0x7F |
1 |
#61row-61 | 663 | 0x80 |
0xFF |
1 |
0 |
1 |
0x80 |
0 |
#62row-62 | 673 | 0x80 |
0xFF |
0 |
1 |
0 |
0x80 |
0 |
#63row-63 | 676 | 0x80 |
0xFF |
1 |
1 |
0 |
0x81 |
0 |
#64row-64 | 698 | 0xFF |
0x00 |
0 |
0 |
0 |
0xFF |
0 |
#65row-65 | 717 | 0xFF |
0x00 |
1 |
0 |
1 |
0x00 |
0 |
#66row-66 | 725 | 0xFF |
0x00 |
0 |
1 |
1 |
0xFE |
0 |
#67row-67 | 728 | 0xFF |
0x00 |
1 |
1 |
1 |
0xFF |
0 |
#68row-68 | 750 | 0xFF |
0x01 |
0 |
0 |
1 |
0x00 |
0 |
#69row-69 | 753 | 0xFF |
0x01 |
1 |
0 |
1 |
0x01 |
0 |
#70row-70 | 761 | 0xFF |
0x01 |
0 |
1 |
1 |
0xFD |
0 |
#71row-71 | 766 | 0xFF |
0x01 |
1 |
1 |
1 |
0xFE |
0 |
#72row-72 | 788 | 0xFF |
0x80 |
0 |
0 |
1 |
0x7F |
1 |
#73row-73 | 807 | 0xFF |
0x80 |
1 |
0 |
1 |
0x80 |
0 |
#74row-74 | 815 | 0xFF |
0x80 |
0 |
1 |
1 |
0x7E |
0 |
#75row-75 | 818 | 0xFF |
0x80 |
1 |
1 |
1 |
0x7F |
0 |
#76row-76 | 828 | 0xFF |
0xFF |
0 |
0 |
1 |
0xFE |
0 |
#77row-77 | 831 | 0xFF |
0xFF |
1 |
0 |
1 |
0xFF |
0 |
#78row-78 | 852 | 0xFF |
0xFF |
0 |
1 |
0 |
0xFF |
0 |
#79row-79 | 871 | 0xFF |
0xFF |
1 |
1 |
1 |
0x00 |
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.
For A = B = 0xFF, SUB = 1, and C_IN = 0, the calculation is 255 - 255 - 1 = -1 under unsigned arithmetic, so it requires a borrow. Under signed interpretation it is -1 - (-1) - 1 = -1, which does not overflow.
For wider subtraction, initialize the lowest byte with SUB = 1, C_IN = 1, then connect each byte's CARRY_OUT to the next byte's C_IN. For 0x0100 - 0x0001, the low byte produces 0xFF with carry 0; the upper byte consumes that borrow and produces 0x00 with carry 1.
Embedded simulation¶
The addsub8 scenario exposes AddSub8Test, with 80 recorded cases covering both SUB values and both carry inputs. Use the timeline checkpoints to inspect settled results. In particular, SUB = 1, C_IN = 0 computes A - B - 1; ordinary A - B requires C_IN = 1.
Source and tests¶
| Test | Coverage |
|---|---|
AddSub8Test |
80 recorded binary cases: five A values × four B values × both SUB values × both C_IN values. Checks result, carry, and overflow. |
ALU8ContractTest: standalone AddSub8 sweep |
All 262,144 binary input combinations: 256 × 256 × 2 × 2. Checks OUT, CARRY_OUT, and OVERFLOW on both structural and behavioral AddSub8 implementations. |
The embedded simulation contains the 80 AddSub8Test cases, not the 262,144-case sweep. The sweep disables history recording and drains the event queue between cases; it is exhaustive for binary inputs, not for all four-state input patterns.
2.1.5. ArithmeticUnit8¶
ArithmeticUnit8 selects operands and controls for one AddSub8. It implements all seven arithmetic operations of ALU8 without instantiating a separate datapath for every opcode.
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
A |
Input | 8 | Primary operand |
B |
Input | 8 | Secondary operand; ignored by unary operations |
OP |
Input | 3 | Local arithmetic operation selector |
C_IN |
Input | 1 | Carry input; used only by ADC and SBC |
OUT |
Output | 8 | Selected arithmetic result |
CARRY |
Output | 1 | Carry-out or no-borrow indication |
OVERFLOW |
Output | 1 | Signed overflow for the selected operation |
INVALID_OP |
Output | 1 | Local opcode 0b111 is selected |
ZERO and NEGATIVE are not outputs of this subcomponent. The complete ALU8 computes them from its final selected OUT, which may come from an arithmetic, logic, shift, or comparison component.
Behavior¶
OP selects one of seven arithmetic operations. The result wraps modulo 256; CARRY and OVERFLOW report the unsigned carry/no-borrow condition and signed overflow for that operation.
Local OP |
Operation | Mathematical result before wrapping | Uses B? |
Uses C_IN? |
|---|---|---|---|---|
0b000 |
ADD |
A + B |
Yes | No |
0b001 |
ADC |
A + B + C_IN |
Yes | Yes |
0b010 |
SUB |
A - B |
Yes | No |
0b011 |
SBC |
A - B - (1 - C_IN) |
Yes | Yes |
0b100 |
INC |
A + 1 |
No | No |
0b101 |
DEC |
A - 1 |
No | No |
0b110 |
NEG |
0 - A |
No | No |
0b111 |
Reserved | OUT = 0, CARRY = 0, OVERFLOW = 0, INVALID_OP = 1 |
No | No |
For supported, fully known opcodes, INVALID_OP = 0, independently of the operand values. It reports an invalid encoding, not unknown data or an unsettled circuit.
The complete ALU8 has a five-bit OP. Its arithmetic encodings 0x00–0x06 match this local selector, but the top-level decoder must also check the operation group. A logic opcode must not become an arithmetic operation merely because its low three bits match one of these values.
Arithmetic flags¶
All comparisons in the carry column use unsigned operand values. As in AddSub8, \(s(x)\) denotes the signed interpretation of an eight-bit pattern.
| Operation | CARRY = 1 when |
OVERFLOW = 1 when |
|---|---|---|
ADD |
A + B >= 256 |
s(A) + s(B) is outside −128–127 |
ADC |
A + B + C_IN >= 256 |
s(A) + s(B) + C_IN is outside −128–127 |
SUB |
A >= B |
s(A) - s(B) is outside −128–127 |
SBC |
A >= B + (1 - C_IN) |
s(A) - s(B) - (1 - C_IN) is outside −128–127 |
INC |
A == 0xFF |
A == 0x7F |
DEC |
A != 0x00 |
A == 0x80 |
NEG |
A == 0x00 |
A == 0x80 |
NEG follows the same no-borrow convention as SUB: subtracting zero from zero requires no borrow, whereas subtracting a nonzero unsigned operand from zero does.
C++ example¶
struct Arithmetic8Result {
std::uint8_t OUT;
bool CARRY;
bool OVERFLOW;
bool INVALID_OP;
};
Arithmetic8Result arithmetic8_ref(
std::uint8_t a, std::uint8_t b, std::uint8_t op, bool c_in) {
std::uint8_t x = a;
std::uint8_t y = b;
bool sub = false;
bool carry_in = false;
switch (op) {
case 0x00: break; // ADD
case 0x01: carry_in = c_in; break; // ADC
case 0x02: sub = true; carry_in = true; break; // SUB
case 0x03: sub = true; carry_in = c_in; break; // SBC
case 0x04: y = 0; carry_in = true; break; // INC
case 0x05: y = 1; sub = true; carry_in = true; break; // DEC
case 0x06: x = 0; y = a; sub = true;
carry_in = true; break; // NEG
default: return {0, false, false, true};
}
const auto result = addsub8_ref(x, y, sub, carry_in);
return {result.OUT, result.CARRY_OUT, result.OVERFLOW, false};
}
The function's op argument represents the three-bit local selector. Its default branch also rejects out-of-range integer arguments, although those cannot occur on a three-bit binary pin.
Unknown inputs and timing¶
The selected operands pass through multiplexers before reaching AddSub8, so unknown values follow the underlying gates' four-state behavior. Unused inputs are isolated by the selection logic: for example, during NEG, unknown bits on B or C_IN do not affect the settled result or flags. With the known reserved opcode 0b111, output masking produces zero result, carry, and overflow, and INVALID_OP = 1, even when data inputs are unknown.
Changing OP can change the internal operands and carry controls before the final outputs settle. There is no single declared structural ArithmeticUnit8 latency; the result and flags can change at different times. Use the recorded checkpoints to inspect settled behavior. The C++ example does not model these propagation states.
Implementation¶
Structural implementation¶
The component consists of opcode-controlled operand/control multiplexers, constants, one AddSub8, and output masking for the reserved opcode. On a valid opcode, AddSub8.OUT, CARRY_OUT, and OVERFLOW drive the corresponding arithmetic outputs.
The following table defines the signals supplied to the shared AddSub8 instance. X and Y are local eight-bit operand wires, not additional external pins.
| Operation | AddSub8.A (X) |
AddSub8.B (Y) |
AddSub8.SUB |
AddSub8.C_IN |
|---|---|---|---|---|
ADD |
A |
B |
0 | 0 |
ADC |
A |
B |
0 | C_IN |
SUB |
A |
B |
1 | 1 |
SBC |
A |
B |
1 | C_IN |
INC |
A |
0x00 |
0 | 1 |
DEC |
A |
0x01 |
1 | 1 |
NEG |
0x00 |
A |
1 | 1 |
Behavioral implementation¶
Behavioral8<ArithmeticUnit8> calls arithmetic. Four-state multiplexer functions select the operands, subtraction control, and initial carry for one addsub evaluation. The reserved-opcode result masks OUT, CARRY, and OVERFLOW to zero and drives INVALID_OP.
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 80 recorded rows of ArithmeticUnit8Test, 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 (a46e324fa954d9a1). Changing fidelity or the circuit can change these times.
| Checkpointzero-based number · timeline label | Timesimulator units | AInput · 8 bit |
BInput · 8 bit |
C_INInput · 1 bit |
OPInput · 3 bit |
CARRYExpected output · 1 bit |
INVALID_OPExpected output · 1 bit |
OUTExpected output · 8 bit |
OVERFLOWExpected output · 1 bit |
|---|---|---|---|---|---|---|---|---|---|
#0row-0 | 18 | 0x00 |
0x01 |
0 |
0x0 |
0 |
0 |
0x01 |
0 |
#1row-1 | 20 | 0x00 |
0x01 |
1 |
0x0 |
0 |
0 |
0x01 |
0 |
#2row-2 | 34 | 0x01 |
0x01 |
0 |
0x0 |
0 |
0 |
0x02 |
0 |
#3row-3 | 36 | 0x01 |
0x01 |
1 |
0x0 |
0 |
0 |
0x02 |
0 |
#4row-4 | 63 | 0x7F |
0x01 |
0 |
0x0 |
0 |
0 |
0x80 |
1 |
#5row-5 | 65 | 0x7F |
0x01 |
1 |
0x0 |
0 |
0 |
0x80 |
1 |
#6row-6 | 81 | 0x80 |
0x01 |
0 |
0x0 |
0 |
0 |
0x81 |
0 |
#7row-7 | 83 | 0x80 |
0x01 |
1 |
0x0 |
0 |
0 |
0x81 |
0 |
#8row-8 | 110 | 0xFF |
0x01 |
0 |
0x0 |
1 |
0 |
0x00 |
0 |
#9row-9 | 112 | 0xFF |
0x01 |
1 |
0x0 |
1 |
0 |
0x00 |
0 |
#10row-10 | 129 | 0x00 |
0x01 |
0 |
0x1 |
0 |
0 |
0x01 |
0 |
#11row-11 | 141 | 0x00 |
0x01 |
1 |
0x1 |
0 |
0 |
0x02 |
0 |
#12row-12 | 155 | 0x01 |
0x01 |
0 |
0x1 |
0 |
0 |
0x02 |
0 |
#13row-13 | 165 | 0x01 |
0x01 |
1 |
0x1 |
0 |
0 |
0x03 |
0 |
#14row-14 | 192 | 0x7F |
0x01 |
0 |
0x1 |
0 |
0 |
0x80 |
1 |
#15row-15 | 202 | 0x7F |
0x01 |
1 |
0x1 |
0 |
0 |
0x81 |
1 |
#16row-16 | 218 | 0x80 |
0x01 |
0 |
0x1 |
0 |
0 |
0x81 |
0 |
#17row-17 | 230 | 0x80 |
0x01 |
1 |
0x1 |
0 |
0 |
0x82 |
0 |
#18row-18 | 257 | 0xFF |
0x01 |
0 |
0x1 |
1 |
0 |
0x00 |
0 |
#19row-19 | 267 | 0xFF |
0x01 |
1 |
0x1 |
1 |
0 |
0x01 |
0 |
#20row-20 | 298 | 0x00 |
0x01 |
0 |
0x2 |
0 |
0 |
0xFF |
0 |
#21row-21 | 300 | 0x00 |
0x01 |
1 |
0x2 |
0 |
0 |
0xFF |
0 |
#22row-22 | 328 | 0x01 |
0x01 |
0 |
0x2 |
1 |
0 |
0x00 |
0 |
#23row-23 | 330 | 0x01 |
0x01 |
1 |
0x2 |
1 |
0 |
0x00 |
0 |
#24row-24 | 343 | 0x7F |
0x01 |
0 |
0x2 |
1 |
0 |
0x7E |
0 |
#25row-25 | 345 | 0x7F |
0x01 |
1 |
0x2 |
1 |
0 |
0x7E |
0 |
#26row-26 | 374 | 0x80 |
0x01 |
0 |
0x2 |
1 |
0 |
0x7F |
1 |
#27row-27 | 376 | 0x80 |
0x01 |
1 |
0x2 |
1 |
0 |
0x7F |
1 |
#28row-28 | 392 | 0xFF |
0x01 |
0 |
0x2 |
1 |
0 |
0xFE |
0 |
#29row-29 | 394 | 0xFF |
0x01 |
1 |
0x2 |
1 |
0 |
0xFE |
0 |
#30row-30 | 421 | 0x00 |
0x01 |
0 |
0x3 |
0 |
0 |
0xFE |
0 |
#31row-31 | 431 | 0x00 |
0x01 |
1 |
0x3 |
0 |
0 |
0xFF |
0 |
#32row-32 | 444 | 0x01 |
0x01 |
0 |
0x3 |
0 |
0 |
0xFF |
0 |
#33row-33 | 469 | 0x01 |
0x01 |
1 |
0x3 |
1 |
0 |
0x00 |
0 |
#34row-34 | 482 | 0x7F |
0x01 |
0 |
0x3 |
1 |
0 |
0x7D |
0 |
#35row-35 | 494 | 0x7F |
0x01 |
1 |
0x3 |
1 |
0 |
0x7E |
0 |
#36row-36 | 520 | 0x80 |
0x01 |
0 |
0x3 |
1 |
0 |
0x7E |
1 |
#37row-37 | 530 | 0x80 |
0x01 |
1 |
0x3 |
1 |
0 |
0x7F |
1 |
#38row-38 | 546 | 0xFF |
0x01 |
0 |
0x3 |
1 |
0 |
0xFD |
0 |
#39row-39 | 558 | 0xFF |
0x01 |
1 |
0x3 |
1 |
0 |
0xFE |
0 |
#40row-40 | 575 | 0x00 |
0x01 |
0 |
0x4 |
0 |
0 |
0x01 |
0 |
#41row-41 | 577 | 0x00 |
0x01 |
1 |
0x4 |
0 |
0 |
0x01 |
0 |
#42row-42 | 592 | 0x01 |
0x01 |
0 |
0x4 |
0 |
0 |
0x02 |
0 |
#43row-43 | 594 | 0x01 |
0x01 |
1 |
0x4 |
0 |
0 |
0x02 |
0 |
#44row-44 | 621 | 0x7F |
0x01 |
0 |
0x4 |
0 |
0 |
0x80 |
1 |
#45row-45 | 623 | 0x7F |
0x01 |
1 |
0x4 |
0 |
0 |
0x80 |
1 |
#46row-46 | 639 | 0x80 |
0x01 |
0 |
0x4 |
0 |
0 |
0x81 |
0 |
#47row-47 | 641 | 0x80 |
0x01 |
1 |
0x4 |
0 |
0 |
0x81 |
0 |
#48row-48 | 669 | 0xFF |
0x01 |
0 |
0x4 |
1 |
0 |
0x00 |
0 |
#49row-49 | 671 | 0xFF |
0x01 |
1 |
0x4 |
1 |
0 |
0x00 |
0 |
#50row-50 | 701 | 0x00 |
0x01 |
0 |
0x5 |
0 |
0 |
0xFF |
0 |
#51row-51 | 707 | 0x00 |
0x01 |
1 |
0x5 |
0 |
0 |
0xFF |
0 |
#52row-52 | 735 | 0x01 |
0x01 |
0 |
0x5 |
1 |
0 |
0x00 |
0 |
#53row-53 | 741 | 0x01 |
0x01 |
1 |
0x5 |
1 |
0 |
0x00 |
0 |
#54row-54 | 754 | 0x7F |
0x01 |
0 |
0x5 |
1 |
0 |
0x7E |
0 |
#55row-55 | 760 | 0x7F |
0x01 |
1 |
0x5 |
1 |
0 |
0x7E |
0 |
#56row-56 | 789 | 0x80 |
0x01 |
0 |
0x5 |
1 |
0 |
0x7F |
1 |
#57row-57 | 795 | 0x80 |
0x01 |
1 |
0x5 |
1 |
0 |
0x7F |
1 |
#58row-58 | 811 | 0xFF |
0x01 |
0 |
0x5 |
1 |
0 |
0xFE |
0 |
#59row-59 | 817 | 0xFF |
0x01 |
1 |
0x5 |
1 |
0 |
0xFE |
0 |
#60row-60 | 847 | 0x00 |
0x01 |
0 |
0x6 |
1 |
0 |
0x00 |
0 |
#61row-61 | 849 | 0x00 |
0x01 |
1 |
0x6 |
1 |
0 |
0x00 |
0 |
#62row-62 | 879 | 0x01 |
0x01 |
0 |
0x6 |
0 |
0 |
0xFF |
0 |
#63row-63 | 881 | 0x01 |
0x01 |
1 |
0x6 |
0 |
0 |
0xFF |
0 |
#64row-64 | 896 | 0x7F |
0x01 |
0 |
0x6 |
0 |
0 |
0x81 |
0 |
#65row-65 | 898 | 0x7F |
0x01 |
1 |
0x6 |
0 |
0 |
0x81 |
0 |
#66row-66 | 929 | 0x80 |
0x01 |
0 |
0x6 |
0 |
0 |
0x80 |
1 |
#67row-67 | 931 | 0x80 |
0x01 |
1 |
0x6 |
0 |
0 |
0x80 |
1 |
#68row-68 | 950 | 0xFF |
0x01 |
0 |
0x6 |
0 |
0 |
0x01 |
0 |
#69row-69 | 952 | 0xFF |
0x01 |
1 |
0x6 |
0 |
0 |
0x01 |
0 |
#70row-70 | 964 | 0x00 |
0x01 |
0 |
0x7 |
0 |
1 |
0x00 |
0 |
#71row-71 | 970 | 0x00 |
0x01 |
1 |
0x7 |
0 |
1 |
0x00 |
0 |
#72row-72 | 977 | 0x01 |
0x01 |
0 |
0x7 |
0 |
1 |
0x00 |
0 |
#73row-73 | 983 | 0x01 |
0x01 |
1 |
0x7 |
0 |
1 |
0x00 |
0 |
#74row-74 | 990 | 0x7F |
0x01 |
0 |
0x7 |
0 |
1 |
0x00 |
0 |
#75row-75 | 996 | 0x7F |
0x01 |
1 |
0x7 |
0 |
1 |
0x00 |
0 |
#76row-76 | 1003 | 0x80 |
0x01 |
0 |
0x7 |
0 |
1 |
0x00 |
0 |
#77row-77 | 1009 | 0x80 |
0x01 |
1 |
0x7 |
0 |
1 |
0x00 |
0 |
#78row-78 | 1016 | 0xFF |
0x01 |
0 |
0x7 |
0 |
1 |
0x00 |
0 |
#79row-79 | 1022 | 0xFF |
0x01 |
1 |
0x7 |
0 |
1 |
0x00 |
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.
Embedded simulation¶
The arithmetic8 scenario exposes ArithmeticUnit8Test, with 80 recorded cases including unary boundary cases, both carry inputs, and the reserved local opcode. Each checkpoint shows the settled result and flags for one case.
Open ArithmeticUnit8 in the simulator
Source and tests¶
| Test | Coverage |
|---|---|
ArithmeticUnit8Test |
80 recorded binary cases: all eight local opcodes × five A values × both C_IN values, with B = 1. Checks OUT, CARRY, OVERFLOW, and INVALID_OP. |
ALU8ContractTest: integrated ALU8 checks |
5,184 boundary cases across all 32 top-level opcodes, 2,048 seeded random cases, and 28 targeted four-state cases. These include arithmetic results and flags, reserved encodings, and isolation of selected ignored inputs. Also verifies that the ALU contains one shared AddSub8, one Adder8, and eight FullAdder instances. |
The embedded simulation contains the 80 ArithmeticUnit8Test cases. The integrated checks are not an exhaustive sweep of ArithmeticUnit8 or ALU8; the 262,144-case exhaustive sweep described above targets the standalone AddSub8. The contract-test harness disables history recording, while the recorded component scenarios retain it.