
This project implements a 32-bit Arithmetic Logic Unit (ALU) for Tiny Tapeout.
The ALU supports arithmetic, logic, shift, comparison, and multiplication operations.
Operands are 32-bit wide, while the operation code is provided as a 6-bit function field (FUNC_BITS).
Supported operations are:
ADD, ADDU, SUB, SUBUAND, OR, XORSLL, SRL, SRASEQ, SNE, SLT, SGT, SLE, SGE, SLTU, SGTU, SLEU, SGEUMULFor the MUL operation, only the lower 8 bits of each operand are used internally by the multiplier, producing a 16-bit product.
This product is then zero-extended to 32 bits on the ALU output.
The project uses a simple custom serial protocol with 4-bit parallel transfers ("nibble interface").
ui_in[0] = ext_progrui_in[7:4] = input nibble (in_data)ui_in[3:1] = unuseduo_out[7:4] = output nibble (out_data)uo_out[2] = busyuo_out[1] = frame_erroruo_out[0] = result_validuo_out[3] = unuseduio_in[7:0] unuseduio_out[7:0] unuseduio_oe[7:0] all disabledWhen ext_progr is asserted high, the wrapper starts a transaction.
Each transaction has two phases:
Read previous result
uo_out[7:4]Load new operation
To use the project, drive the interface synchronously with the main clock.
ui_in[0] = 1 (ext_progr = 1)For 8 clock cycles:
uo_out[7:4]For 8 clock cycles:
ui_in[7:4]For 8 clock cycles:
ui_in[7:4]For 2 clock cycles:
{2'b00, FUNC[5:4]}FUNC[3:0]ext_progr = 1 for 2 more clock cyclesui_in[0] = 0The result of the operation just submitted is not returned immediately.
It will be available as the "previous result" at the beginning of the next transaction.
uo_out[2] = busy: transaction in progressuo_out[1] = frame_error: protocol erroruo_out[0] = result_valid: at least one valid result has been computed| Operation | FUNC_BITS |
|---|---|
| SLL | 000100 |
| SRL | 000110 |
| SRA | 000111 |
| ADD | 100000 |
| ADDU | 100001 |
| SUB | 100010 |
| SUBU | 100011 |
| AND | 100100 |
| OR | 100101 |
| XOR | 100110 |
| SEQ | 100111 |
| SNE | 101000 |
| SLT | 101001 |
| SGT | 101010 |
| SLE | 101011 |
| SGE | 101100 |
| SLTU | 111010 |
| SGTU | 111011 |
| SLEU | 111100 |
| SGEU | 111101 |
| MUL | 111110 |
No external hardware is required. The protocol can be driven by a microcontroller.
| # | Input | Output | Bidirectional |
|---|---|---|---|
| 0 | ext_progr (start/hold transaction) | result_valid | unused |
| 1 | unused | frame_error | unused |
| 2 | unused | busy | unused |
| 3 | unused | unused | unused |
| 4 | in_data[0] (LSB of input nibble) | out_data[0] (LSB of output nibble) | unused |
| 5 | in_data[1] | out_data[1] | unused |
| 6 | in_data[2] | out_data[2] | unused |
| 7 | in_data[3] (MSB of input nibble) | out_data[3] (MSB of output nibble) | unused |