Designing an 8-bit ALU

Rather than overcomplicating things, let's start off with the design:


Design Decisions

To get a grip on the basics and to build a strong foundation, I decided to research prior ALU designs and go through articles and datasheets with solid community backing.

Lucky for me, I stumbled upon a goldmine — a detailed breakdown of the classic 74181 IC, a 4-bit ALU chip that became a standard reference for simple ALU design.

74181 IC

From its function table, I understood how the chip operates, including the variety of logic and arithmetic operations it supports.

74181 Operations Table

However, after reading discussions about the 74181's internal design, I noticed a bit of division in the community. Some love it for its elegance; others think it's unnecessarily complex.

So, I decided to go with a more minimal and modular approach tailored to my own understanding. And instead of sticking with a 4-bit design like the original 74181, I upgraded to an 8-bit ALU. This gave me more headroom for meaningful operations while still keeping the design manageable.


OPCODE Mapping (8-bit ALU)

To control the operations, I created a simple 4-bit OPCODE system, allowing for 16 unique instructions:

OPCODEUNITOPERATIONDESCRIPTION
0000AUADDCAdd with Carry
0001AUSUBCSubtract with Carry
0010AUADDOAdd with Overflow
0011AUSUBOSubtract with Overflow
1000LUXORBitwise XOR
1001LUNOTBitwise NOT
1010LUANDBitwise AND
1011LUORBitwise OR
1100LUNANDBitwise NAND
1101LUNOPNo Operation
1110LUXNORBitwise XNOR
1111LUNORBitwise NOR

Final Design Specs

FLAGS

FLAGDescription
OVERFLOWOnly for signed addition operations
ZEROSet if result is zero
NEGATIVEOnly for subtraction operations
CARRYFor additions exceeding 8-bit limits

BUS Layout

BUSWIDTH
INPUT_BUS8
OP_CODE4
OUTPUT_BUS8
STATUS_IN1
STATUS_OUT4

Workflow

My approach wasn't exactly linear — I leaned into an iterative workflow, learning from each version of the build. Each iteration gave me new insights and helped polish the final design step by step.


Design Implementation & Selection

I experimented with multiple logic gates and missed a few things here and there.
Here's my implementation for the AU, which is quite conventional.

1 BIT AU

Here, the AU performs the selection of operations:

OP_CODEOPERATION
x00ADDC
x01SUBC
x10ADDO
x11SUBO
1 BIT LU

Similarly, the LU performs the Logical Operations:

OP_CODEOPERATION
000XOR
001NOT
010AND
011OR
100NAND
101NOP
110XNOR
111NOR
Note: The lack of the last bit of the input OPCODE is because it will be used to choose between the AU and the LU.
1 BIT ALU

Finally, this is the fundamental block for the operation of the ALU — the mighty 1-bit ALU.

Now that the hard part of designing the fundamentals is done, the more complex-looking block comes into play, where all of the smaller blocks are copied and pasted to get a final design like this:

8 BIT ALU

This implementation of the 8-bit ALU is very basic and might contain unnecessary operations. Yet, I call it not unnecessary, as more or less all the required operations have to be implemented — and the added operations that are implemented within it are always dependent on the task to be accomplished.

Playing around with the final block, I implemented the input as 8-bit registers which can be manipulated by the user, and the output from the previous carry is fed back into the register as a part of operation in the ALU.

Playing Around

I personally didn't get into the HDL or VHDL implementation of these circuits, as they were quite irrelevant and out of my expertise at the time.


References