ALU & Flags

Flags

My ALU has four flags: Zero (Z), Negative (N), Carry (C), and Overflow (O/V).

1. Arithmetic and Logic Operations

Zero (Z) Flag

The Z flag is set when the result of an operation is zero. It’s often used in control flow operations to make decisions based on the zero/non-zero outcome of previous operations.

Example:

0100 (4) - 0100 (4) = 0000 (0) sets the Z flag because the result is zero.

Negative (N) Flag

The N flag is set when the result of an operation, interpreted in two’s complement, is negative.

Example:

0001 (1) - 0100 (4) = 1111 (-3) in two’s complement sets the N flag as the result is negative.

Carry (C) Flag

The C flag is affected during unsigned arithmetic to indicate whether there’s a carry out of the most significant bit during addition, or a borrow during subtraction.

Example:

1111 (15) + 0001 (1) = 0000 (0) in unsigned arithmetic sets the C flag because there’s a carry out of the most significant bit.

Overflow (O/V) Flag

The O (or V) flag is set during signed arithmetic if the signed result falls outside the representable range for the given number of bits. In other words, the flag is set when adding two positive numbers yields a negative value, or vice versa. The Overflow flag is not affected by or concerned with unsigned arithmetic.

Example:

0110 (6) + 0101 (5) = 1011 (-5)

1110 (-6) + 1001 (-1) = **1**0111 (7)

In signed arithmetic these results set the O flag because the result has overflowed the positive representable range.

An overflow is checked by comparing the carry into and out of the MSB. If they’re different, the O flag is set. The ALU internally uses a XOR operation on these two carry signals to set the O flag:

  • If both are equal (either both are 0 or both are 1), there is no overflow, and the Overflow flag is not set.
  • If they are different (one is 0 and the other is 1), there is an overflow, and the Overflow flag is set.
Figure 1: Full Subtractor With Overflow Check)
Figure 1: Full Subtractor With Overflow Check)


Examples:

 (4) +  (5) = (9)
0100 + 0101 = 1001  <-- ("4 + 5 = -7" in two's complements)

Carry      01000
Number A    0100
Number B  + 0101
            -----
            1001

(Carry out (0)) XOR (carry into MSB (1)) = 1 (Overflow flag is set)

(-4) + (-2) = (-6)
1100 + 1110 = 1010 <-- ("-4 - 2 = -6" in two's complements)

Carry      11000
Number A    1100
Number B  + 1110
            -----
            1010

(Carry out (1)) XOR (carry into MSB (1)) = 0 (Overflow flag is not set)

2. Shift Operations

Shift operations also influence the Z, N, and C flags.

Zero (Z) Flag in Shift Operations

  • Example: Right shift 0001 (1) to 0000 (0) sets the Z flag, indicating the result is zero.

Negative (N) Flag in Shift Operations

  • Example: Left shift 0100 (4) to 1000 (-8) in two’s complement sets the N flag because the result is negative.

Carry (C) Flag in Shift Operations

The carry flag can be influenced during shift operations, especially during right shifts where the last bit shifted out is often stored in the carry flag.

  • Examples:

    Right shift 1001 (9) to 0100 (4) sets the C flag as the last bit shifted out is 1.

Together, the Z, O, N, and C flags provide a detailed post-operation status that can be used for efficient decision-making, error handling, and optimized control flow in various computational tasks.

Implementation

Control lines involved(10):

  • |←~ZE Accumulator enable: Outputs accumulator’s content to 8-bit bus.
  • |← ZS ALU select: 382 ALU or the Shift register.
  • |← ZW Accumulator write
  • |← Z0 ALU select_0
  • |← Z1 ALU select_1
  • |← Z2 ALU select_2
  • |← HC_in Shift register’s carry-in: Replaces the shifted bit.
  • |←~HC Shift register’s clear
  • |←~FE Flags register’s enable: Flag register’s content enable to 8-bit bus
  • |←~FW Flags register’s write
  • |→ II Interrupt inhibit(Just uses a spare pin of flag register’s transceiver)(Comes from Interrupt logic and is not really related to the flags module)

The 74LS382 is the central chip of my ALU module. For reasons that I ignore, this chip is not available in the HC or HCT family. It performs the following arithmetic and logic operations: Addition, subtraction, OR, exclusive OR, and AND. Additionally it can mirror its content and a null/zero output to the bus. It operates on 4-bit words, so just like the 74HCT173, I use a pair of it to do 8-bit operations.

Pin NoPin NameDescription
3, 1, 19, 17A0, A1, A2, A3Word A inputs
4, 2, 18, 16B0, B1, B2, B3Word B inputs
5, 6, 7S0, S1, S2Function Select
8. 9, 11, 12F0, F1, F2, F3Output Pins
10GNDGround
11, 12, 13, 14D3, D4, D5, D6Data Input 3, 2, 1, 0
20VCCSupply Voltage
13~GGenerate Carry Output
14~PRipple-Carry Output
15CnCarry Input

Table 1: 74LS382 Pin Configuration

S2 S1 S0Operation
0 0 0ZERO/NULL
0 0 1B minus A
0 1 0A minus B
0 1 1A plus B
1 0 0A XOR B
1 0 1A OR B (A+B)
1 1 0A AND B (AB)
1 1 1Mirror Input

Table 2: 74LS382 Functions

To perform shift operations, I use a pair of 74HCT194; a 4-bit bidirectional shift register with parallel and serial data input modes. It enables shifting data left or right and has an asynchronous master reset.

Pin NoPin NameDescription
1~MR D4, D5, D6, D7Active Low Asynchronous Master Reset
2DsrSerial Data Input Pin (shift right)
3, 4, 5, 6,D0, D1, D2, D3,Parallel Data Inputs
7DslSerial Data Input Pin (shift left)
8GNDGround Pin
9, 10S0, S1Function Select
11CPClock Pulse Input
15, 14, 13, 12Q0, Q1, Q2, Q3Parallel Output Pin 0, 1, 2, 3
16VCCChip Supply Voltage

Table 3: 74HCT194 Pin Configuration

For zero-detection, I use a 74HCT688 8-Bit Magnitude Comparator, which provides a cleaner and more efficient solution compared to using two separate ICs(a NOR and an AND IC) to construct my zero detector

Pin NoPin NameDescription
1EEnable input
2, 4, 6, 8, 11, 13, 15, 17P0 to P7Word P inputs
3, 5, 7, 9, 12, 14, 16, 18Q0 to Q7Word Q inputs
10GNDGround Pin
19~(P = Q)Active Low Equal to output
20VCCChip Supply Voltage

Table 4: 74HCT688 Pin Configuration

Looking at the high level schematic/diagram below:

Let’s call the two 74LS382, the Arithmetic and Logic submodule (382), and the two 74HCT194, the shift submodule (194) or shift register. The accumulator/Z-reg (74HCT574) stores the result of the ALU’s operations.

Figure 2: ALU Overview Diagram)
Figure 2: ALU Overview Diagram)


From the bottom up:

1- Both sub-modules receive their inputs from the data bus, with the 382 getting its second input/operand, from the accumulator. This means that to perform an operation between two operands, A and B; B must first be loaded into the accumulator.

2- The outputs of both sub-modules are directly connected to an 8-bit multiplexer made with two 74HCT257/257 4-bit muxs.

Note: While I use a 74HCT257, a 74HCT157 could also serve the purpose. The only difference between the two is that the 257 has a tri-state output, which I am not using.

The ZS control lines determine which sub-module’s value gets selected by the multiplexer. ZS = 0 selects the Arithmetic and Logic sub-module and ZS = 1 selects the shift sub-module.

3- The output from the sub-modules mux is connected directly to both the accumulator and the zero-detector. The transceiver, positioned between the accumulator’s output and the bus, much like most transceivers in this build, allows the content of the accumulator to be displayed on status LEDs without interfering with the bus content.

The two 74HCT153 multiplexers(flags mux) are used to select the appropriate flag based on the current operation. The output from the flags mux is then fed into a final 74HCT257 before entering the flags register allowing to either overwrite the content of the flag register or use the previous flags.

The two figures below show the full schematic of the ALU module:

Figure 3: ALU Schematic 1/2)
Figure 3: ALU Schematic 1/2)


Figure 4: ALU Schematic 2/2)
Figure 4: ALU Schematic 2/2)


ZsZ2Z1Z0Accumulator’s inputZ flagO/V flagN flagC flag
00000x00ZOVRD7Cn+4
0001B - AZOVRD7Cn+4
0010A - BZOVRD7Cn+4
0011A + BZOVRD7Cn+4
0100A XOR BZOVRD7Cn+4
0101A OR BZOVRD7Cn+4
0110A AND BZOVRD7Cn+4
01110XFFZOVRD7Cn+4
1000194ZOVRD7Cn+4
1001LSLZ0D7D7
1010LSRZ0D7D0
1011BusD3D2D1D0
1100Reset CarryZO/VN0
1101Set CarryZO/VN1

Table 5: ALU’s Truth Table

Important Microcode-Related Notes

Mirroring Bus Content

Note that the 74LS382 does not have a “mirror bus” function; which would have made loading the accumulator with the value on the bus very straightforward. The 74HCT194 on the other hand does have this function; but since it is a sequential component, it requires an extra cycle to be loaded before its output can be loaded into the accumulator.

Flags And Shift Register Control Contention

Writing the bus content to the flags register requires Zs = Z1 = Z0 = 1. This essentially sets the shift register to also get the bus content. In other words; every time the bus content is being written to the flags register, it is also getting written in the shift register. Besides the soft reset instruction, I do not have any instruction that uses both FLG_MIRROR_BUS and a shift operation right now.

ADD and SUB

The ALU’s Carry-in is permanently connected to the carry out from the previous operation, which means that if for example $A contains 0b11111111, and $B contains 0b0. An ADD $A, 0b1, will obviously set the C flag. However; if following this first ADD, an ADD $B, 0b1 is performed, the input will have a carry-in added to it, so $B will contain 0b10 instead of 0b01. In other words, my ADD and SUB are actually ADC and SBC. I however have a STC, and CLC.

So an actual regular ADD $A, 1, for example, on my CPU is :

CLC
ADD $A, 1

And an actual regular SUB $A, 1 is :

CLC
SUB $A, 1


ICs

2 x 74LS382(Datasheet)

2x 74HCT194 (Digikey, Datasheet)

4x 74HCT257 Quarduple 2:1 mux (Digikey, Datasheet)

2x 74LS153 (Dual 4- to 1-Line Selector/Multiplexer), (Digikey, Datasheet).

1x 74HCT688 8-Bit Magnitude Comparator, (Jameco, Datasheet).

2x 74HCT245, Octal Bus Transceivers With 3-State Outputs, (Digikey, Datasheet).

1x 74HCT173, 4-Bit D-type Registers with tri-state Outputs, (Digikey, Datasheet).

1x 74HCT08 Quadruple 2-Input Positive-AND Gates 74HCT08 (Digikey, Datasheet)


«««««««««« Previous Post: ALU Primer

                                Next Post: RAM & ROM Primer  »»»»»»»»»»

Updated:

back to top