This project implements an 8-bit pipelined Arithmetic Logic Unit (ALU) designed for Tiny Tapeout. The ALU utilizes 32-bit internal arithmetic for precision but operates on 8-bit operands due to I/O constraints. It features a 3-stage pipeline architecture for high throughput and supports comprehensive arithmetic and logical operations.
The ALU consists of two main components:
tt_um_8bitalu
): Handles I/O mapping, pipeline control, and result formattingalu32_pipelined
): Performs the actual arithmetic and logical operations with 32-bit internal precisionThe design efficiently utilizes Tiny Tapeout's 8-bit input pins:
ui_in[7:0]
: 8-bit operand A (zero-extended to 32 bits internally)uio_in[7:3]
: 5-bit operand B (zero-extended to 32 bits internally)uio_in[4:0]
: 5-bit operation code (only lower 3 bits used)This encoding allows meaningful 8-bit arithmetic operations while maintaining full precision through internal 32-bit calculations.
The ALU implements a 3-stage pipeline for optimal performance:
Stage 1: ALU Computation → pipe1_result
Stage 2: Pipeline Delay → pipe2_result
Stage 3: Output Ready → pipe3_result → uo_out
Pipeline Characteristics:
Opcode | Operation | Description | Example |
---|---|---|---|
000 |
ADD | 8-bit addition with carry | A + B |
001 |
SUB | 8-bit subtraction | A - B |
010 |
MUL | 8-bit multiplication | A × B |
011 |
DIV | 8-bit division (with zero protection) | A ÷ B |
100 |
SHL | Barrel shift left | A << B[4:0] |
101 |
SHR | Barrel shift right | A >> B[4:0] |
The ALU generates comprehensive status flags:
Pin | Function | Description |
---|---|---|
ui_in[7:0] |
Operand A | 8-bit operand A (primary input) |
uio_in[7:3] |
Operand B | 5-bit operand B (0-31 range) |
uio_in[4:0] |
Operation Code | ALU operation selection |
ena |
Enable | Module enable (always 1) |
clk |
Clock | System clock |
rst_n |
Reset | Active-low asynchronous reset |
Pin | Function | Description |
---|---|---|
uo_out[7:0] |
Result | 8-bit ALU result |
uio_out[3:0] |
Flags | Status flags {zero, neg, carry, overflow} |
uio_out[7:4] |
Unused | Tied to zero |
uio_oe[7:0] |
Output Enable | 0x0F (enables lower 4 bits of uio) |
rst_n = 0
for 10 clock cycles, then releasedut.ui_in.value = 20 # Operand A = 20
dut.uio_in.value = (30 << 3) | 0 # Operand B = 30, Opcode = ADD
await ClockCycles(dut.clk, 5) # Wait for pipeline
result = dut.uo_out.value # Should be 50
dut.ui_in.value = 30 # Operand A = 30
dut.uio_in.value = (10 << 3) | 1 # Operand B = 10, Opcode = SUB
await ClockCycles(dut.clk, 5) # Wait for pipeline
result = dut.uo_out.value # Should be 20
dut.ui_in.value = 6 # Operand A = 6
dut.uio_in.value = (7 << 3) | 2 # Operand B = 7, Opcode = MUL
await ClockCycles(dut.clk, 5) # Wait for pipeline
result = dut.uo_out.value # Should be 42
The included testbench (test.py
) provides comprehensive verification:
uio_out[3] = zero_flag // 1 if result == 0
uio_out[2] = negative_flag // 1 if result[7] == 1
uio_out[1] = carry_flag // 1 if arithmetic carry/borrow
uio_out[0] = overflow_flag // 1 if signed overflow (ADD only)
8'b0
when divisor is zero8'b0
outputclk
rst_n
)This project requires no external hardware beyond the standard Tiny Tapeout demo board. All functionality is self-contained within the chip design.
Optional Testing Equipment:
The design has been validated through:
Potential improvements for future versions:
Project Repository: https://github.com/pathanrehman/tt_um_8bitALU
Author: Pathan Rehman Ahmed Khan
License: Apache-2.0
This 8-bit ALU demonstrates how efficient arithmetic processing can be implemented within Tiny Tapeout's constraints while maintaining educational value and practical functionality for 8-bit computing applications.
# | Input | Output | Bidirectional |
---|---|---|---|
0 | ALU_DATA_0 | RESULT_0 | OPERAND_B_0 |
1 | ALU_DATA_1 | RESULT_1 | OPERAND_B_1 |
2 | ALU_DATA_2 | RESULT_2 | OPERAND_B_2 |
3 | ALU_DATA_3 | RESULT_3 | ALU_OP_0 |
4 | ALU_DATA_4 | RESULT_4 | ALU_OP_1 |
5 | ALU_DATA_5 | RESULT_5 | ALU_OP_2 |
6 | ALU_DATA_6 | RESULT_6 | FLAGS_OUT |
7 | ALU_DATA_7 | RESULT_7 | PIPELINE_EN |