128 iTALU: Interactive Testable Arithmetic Logic Unit

128 : iTALU: Interactive Testable Arithmetic Logic Unit

Design render

iTALU: Interactive Testable Arithmetic Logic Unit

Project Overview

iTALU is an 8-bit Arithmetic Logic Unit (ALU) with comprehensive Design-for-Testability (DFT) features, designed for Tiny Tapeout using the IHP SG13G2 (130nm) technology. The project demonstrates industry-standard testing techniques — scan chain, LFSR/MISR-based BIST, and fault injection — with a simple serial user interface.

Key Features
  • 8-bit ALU with 16 operations (arithmetic, logic, shifts/rotates, compare, min/max, saturating arithmetic)
  • 4 status flags (Zero, Carry, Negative, Overflow)
  • 20-bit serial instruction interface (LSB first)
  • 64-bit scan chain covering all internal state
  • Built-In Self-Test (BIST) with 8-bit LFSR pattern generator and 8-bit MISR response compactor (256 patterns per run)
  • User-controlled fault injection: stuck-at-0/1, inversion, coupling
  • Status readback mux: flags/BIST status, MISR signature, fault counter, cycle counter
Specifications
Parameter Value
Technology IHP SG13G2 (130nm)
Tile Size 1x1
Clock Frequency 50 MHz (tested), no hard requirement
Top Module tt_um_italu
I/O Pins 8 input, 8 output, 8 bidirectional

Architecture

                    +---------------------------------------------+
                    |                  tt_um_italu                |
                    |                                             |
 ui_in[0] DATA ---->| +------------------+   +-----------------+   |
 ui_in[1] LOAD ---->| | Serial           |   | Normal ALU      |   |
 ui_in[2] EXEC ---->| | Instruction Reg  |-->| + Result/Flags  |-->| uo_out = result
                    | | (20b, LSB first) |   +-----------------+   |
                    | +--------+---------+                         |
                    |          |                                   |
                    |          v   +-----------------+             |
                    | +------->|   | Direct Exec ALU |             |
                    | |        |   +-----------------+             |
                    | |  +-----+---------+                         |
                    | |  | Fault Injector|--+ (SA0/SA1/invert/couple)
                    | |  +---------------+                         |
 uio_in fault cfg ->| |                                            |
                    | v                                            |
                    | +------------------+   +-----------------+   |
 ui_in[7] START --->| | BIST FSM         |   | LFSR -> MISR    |   |
                    | | IDLE/LOAD/EXEC/  |<->| 256 patterns    |   |
                    | | DONE             |   | golden sig 0x93 |   |
                    | +------------------+   +-----------------+   |
                    |                                              |
 ui_in[3] CAPTURE ->| +------------------+   +-----------------+   |
 ui_in[6] SHIFT --->| | 64-bit Scan Chain|   | Status Mux      |-->| uio_out
                    | +------------------+   +-----------------+   |
                    +---------------------------------------------+

ALU Operations

Code Operation Description
0x0 ADD A + B with carry out
0x1 SUB A - B (carry = no borrow)
0x2 AND Bitwise AND
0x3 OR Bitwise OR
0x4 XOR Bitwise XOR
0x5 NOT Bitwise NOT of A
0x6 SHL Logical shift A left by 1
0x7 SHR Logical shift A right by 1
0x8 SAR Arithmetic shift A right by 1
0x9 ROL Rotate A left by 1
0xA ROR Rotate A right by 1
0xB SLT Signed less-than: 1 if A < B else 0
0xC MIN Unsigned minimum of A and B
0xD MAX Unsigned maximum of A and B
0xE SATADD Saturating signed add (clamps at 0x7F / 0x80)
0xF SATSUB Saturating signed subtract (clamps at 0x7F / 0x80)

Status Flags

With STATUS_SEL = 00, uio_out[3:0] shows:

Flag Bit Position Description
Zero (Z) bit 0 Result is 0x00
Carry (C) bit 1 Carry out (ADD) or no borrow (SUB)
Negative (N) bit 2 MSB of result is 1
Overflow (O) bit 3 Signed arithmetic overflow

The same select also reports [4] = BIST done, [5] = BIST pass and [6] = scan out.


Design-for-Testability (DFT) Implementation

1. Serial Instruction Interface

A 20-bit shift register is filled LSB first while LOAD_EN is high:

[19:16] opcode
[15:8]  operand B
[7:0]   operand A

Pulsing EXECUTE latches the operands/op into the normal ALU registers and stores the (possibly fault-injected) result and flags.

2. Scan Chain

A single 64-bit chain captures all internal state:

operand_a(8) -> operand_b(8) -> operation(4) -> alu_result(8) ->
flags Z/C/N/O(4) -> misr(8) -> bist_done(1) -> test_pass(1) ->
fault_counter(8) -> cycle_counter(8) -> padding(6)
  • SCAN_CAPTURE (ui_in[3]) loads the chain from live state in one clock
  • SCAN_SHIFT (ui_in[6]) shifts one bit per clock onto SCAN_OUT (uio_out[6]), LSB first
3. Built-In Self-Test (BIST)
+-----------+    +----------------+    +-----------+
|   LFSR    |--->|      ALU       |--->|   MISR    |
|  Pattern  |    |  (Under Test)  |    | Response  |
| Generator |    |  Reference     |    | Compactor |
+-----------+    +-------+--------+    +-----------+
                         |
                   +-----v-----+
                   | Comparator|----> pass/fail + fault counter
                   +-----------+
  • 8-bit LFSR generates operand A; operand B is a nibble-swap of A; the opcode comes from the low nibble of the LFSR value
  • 256 patterns run automatically (IDLE → LOAD → EXEC → DONE FSM)
  • Responses are compacted into an 8-bit MISR
  • Fault-free golden MISR signature: 0x93
  • On completion BIST_DONE (uio_out[4]) asserts and stays asserted until the next BIST_START, so it can be polled reliably
  • TEST_PASS (uio_out[5]) is high on a fault-free run, low when any mismatch or active fault injection was observed
  • Detected faults increment an 8-bit fault counter (STATUS_SEL = 10)
4. Fault Injection

Configured via uio_in while the status output is driven:

Field Pins Values
Enable uio_in[0] 1 = inject
Type uio_in[2:1] 00 = stuck-at-0, 01 = stuck-at-1, 10 = inversion, 11 = coupling
Bit uio_in[5:3] Result bit 0–7 the fault applies to

The injected fault affects the normal ALU path, the serial-execution path and the BIST comparison simultaneously — so a faulted chip fails its own self-test, which is the core demonstration of the DFT flow.

5. Status Readback Multiplexer
STATUS_SEL (uio_in[7:6]) uio_out content
00 Flags + BIST done/pass + scan out
01 MISR signature
10 Fault counter
11 Free-running cycle counter

Pin Configuration

Input Pins (ui_in)
Pin Name Description
ui_in[0] DATA_IN Serial data input for instruction loading
ui_in[1] LOAD_EN Shift one bit into the instruction register
ui_in[2] EXECUTE Execute the loaded instruction
ui_in[3] SCAN_CAPTURE Capture state into the scan chain
ui_in[4] Unused
ui_in[5] Unused
ui_in[6] SCAN_SHIFT Shift the scan chain one bit per clock
ui_in[7] BIST_START Start a BIST run
Output Pins (uo_out)
Pin Name Description
uo_out[7:0] RESULT 8-bit ALU result
Bidirectional Pins (uio)

Inputs (fault configuration / status select):

Pin Name Description
uio[0] FAULT_ENABLE Fault injection enable
uio[2:1] FAULT_TYPE Fault type selection
uio[5:3] FAULT_BIT Faulted result bit
uio[7:6] STATUS_SEL Status output select

Outputs (status, selected by STATUS_SEL):

Pin Select 00 Select 01 Select 10 Select 11
uio[7:0] Flags/BIST/scan-out MISR Fault counter Cycle counter

How to Test

RTL Simulation

Requires cocotb and Icarus Verilog:

cd test
make -B

This runs the full 11-test regression against src/project.v, producing results.xml and an FST waveform. See test/README.md for gate-level simulation and waveform viewing.

Regression Coverage
# Test What it verifies
1 test_add Basic ADD: 0x0F + 0x03 = 0x12
2 test_sub Basic SUB: 0x0A - 0x05 = 0x05
3 test_all_alu_operations All 16 opcodes vs a Python reference model
4 test_alu_flags Zero/Carry/Negative/Overflow flag generation
5 test_normal_fault_injection Injected fault changes the ALU result
6 test_bist_pass Fault-free BIST completes, passes, MISR = 0x93
7 test_bist_fault_detection All 4 fault types detected by the BIST
8 test_fault_counter Fault counter increments on detected faults
9 test_scan_chain Capture + shift returns operands correctly
10 test_cycle_counter Cycle counter advances with the clock
11 test_complete_system End-to-end: ALU, clean BIST, fault detection

Status: 11/11 passing, GDS hardened successfully with LibreLane.

Manual Testing on Hardware

Basic operation:

  1. Reset the chip (rst_n = 0, then release).
  2. Shift a 20-bit instruction in LSB first via DATA_IN/LOAD_EN.
  3. Pulse EXECUTE; read the result on uo_out and the flags on uio_out.

Self-test:

  1. Pulse BIST_START.
  2. Poll uio_out until bit 4 (BIST done) is high.
  3. Check bit 5 (pass/fail) and optionally read the MISR via STATUS_SEL = 01.

Fault demonstration:

  1. Set FAULT_ENABLE with a type/bit combination on uio_in.
  2. Re-run the BIST; TEST_PASS now goes low and the fault counter (STATUS_SEL = 10) increments.

Scan:

  1. Pulse SCAN_CAPTURE, then clock SCAN_SHIFT 64 times reading SCAN_OUT.

External Hardware

No external hardware is strictly required — everything can be driven by a microcontroller or FPGA over the serial interface. For standalone bench use: push buttons/DIP switches for ui_in, LEDs or a logic analyzer on uio_out, and an LED bus or MCU reading uo_out.


License

This project is licensed under Apache-2.0.

Acknowledgments

  • Tiny Tapeout for providing the platform
  • IHP for the SG13G2 PDK
  • Open source EDA community

IO

#InputOutputBidirectional
0DATA_INRESULT_0ZERO_FLAG
1LOAD_ENRESULT_1CARRY_FLAG
2EXECUTERESULT_2NEG_FLAG
3RESULT_3OVF_FLAG
4RESULT_4BIST_DONE
5RESULT_5TEST_PASS
6SCAN_ENRESULT_6SCAN_OUT
7BIST_STARTRESULT_7

Chip location

Controller Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Analog Mux Mux Mux Mux Mux Mux Mux Mux tt_um_chip_rom (Chip ROM) tt_um_factory_test (Tiny Tapeout Factory Test) tt_um_ieee_LDO (LDO) tt_um_chip_ieee_analog (IEEE Bandgap Reference) tt_um_snn_voice_calculator_mauro_ciccone (snn-voice-calculator) tt_um_hx2003_delay (4 Channel - 32 Tap Programmable Delay with Delay Locked Loop Calibration) tt_um_adxl362_test (tt_um_adxl362_test) tt_um_larsnit_cfar (1D CA/GO/SO CFAR radar detector) tt_um_abeccari_swsynth (Sine Wave Synthesizer) tt_um_dpi_adexp (AdExp DPI Neuron ) tt_um_140oo041_fpu130 (FPU-130) tt_um_blonghi_uart (uart) tt_um_directsgg_mini_proceo_8bit (Mini 8-bit Processor) tt_um_umaece1982_lfsr (Low-Power LFSR-Based Test Pattern Generator) tt_um_deploy_timer (launch deployment timer) tt_um_urish_simon (Simon Says memory game) tt_um_nimelli_kinematic_wave_engine (Kinematic Wave Engine) tt_um_multi_seg_monitor (Multi Segment Monitor) tt_um_UART_TX (project) tt_um_crc8_lfsr (CRC-8 Serial LFSR) tt_um_tinynpu4 (TinyNPU4) tt_um_alu_bns (6-bit multi function ALU ( eldawly_V2) ) tt_um_echoworld424_tpv (Timing-Prediction Test Vehicle) tt_um_gyro_lockin (Laser Gyro Lock-in Readout Core) tt_um_josue_olivos_sar_adc (4-Bit Charge-Redistribution SAR ADC Controller) tt_um_flower (VGA Flower) tt_um_vperumal_l1_fabric (Scalable Banked L1 Memory Fabric for Edge AI) tt_um_preinception_top (Preinception: Simple Compute Accelerator) tt_um_italu (iTALU: Interactive Testable Arithmetic Logic Unit) tt_um_neuron (4-Input Signed Neuron / Perceptron) tt_um_4tap_mac (4-Tap Signed MAC Unit) tt_um_mac_engine (DSP MAC Engine) tt_um_crypto_led_demo (QAMER CryptoUART: Encrypted UART with LED Status) tt_um_layernorm (LayerNorm) tt_um_ez130_8t_mystery (EZ130 8T Mystery Circuit) tt_um_sent2spi (SENT Receiver with SPI Interface) tt_um_llr_hepiarisc (Hepiarisc with SPI flash) tt_um_rebeccargb_vga_pride (VGA Pride) tt_um_hasi_ising (Oscillator Ising Machine) tt_um_c061618g2 (Circuitli C061618G2) tt_um_tiny_dram_pim (Tiny Dual-Channel DRAM-PIM Controller + PU) tt_um_Tbilisi_CORDIC_Engine (Tbilisi CORDIC Engine) tt_um_rahulmascarenhas_folded_nn (Frozen ternary backbone + loadable head) tt_um_miniMAC (miniMAC_IHP26b) tt_um_rumcajs (IEEE DOORSH) tt_um_sg13g2_mystery (SG13G2 Mystery Circuit) tt_um_ULSR88 (ULSR demo) tt_um_ez130_7t_mystery (EZ130 7T Mystery Circuit) tt_um_tinyopt4 (ieee_tt_tinyopt4) tt_um_vga_example (IEEE VGA Animated Beach) tt_um_hyphen133_drone_detection (IEEE Acoustic Drone Detector) tt_um_nuatlabs_fifo_pwm (Async FIFO with CDC + PWM Peripheral) tt_um_nuatlabs_uart (8N1 UART Transceiver) tt_um_eeg_threshold_detector (IEEE Digital EEG Threshold Event Detector) tt_um_smart_traffic (Smart Traffic Light Controller) tt_um_94442024_mini_cpu (Mini 8-bit Accumulator CPU) tt_um_wokwi_475369131246576641 (IEEE_UPB_TT_1) tt_um_aion (AION) tt_um_rebeccargb_hardware_utf8 (Hardware UTF Encoder/Decoder) tt_um_rebeccargb_universal_decoder (Universal Binary to Segment Decoder) tt_um_rebeccargb_intercal_alu (INTERCAL ALU) tt_um_flappy_bird (IEEE Flappy Bird VGA Game) tt_um_oryan01_alu (ALU CASS PUCV) tt_um_S4xU4 (S4xU4) tt_um_vga_ca (Space CA) tt_um_llr_simplenpu (simple SPI flash streaming NPU) tt_um_pucv_pspwm (3LFCC PS-PWM Modulator) tt_um_yuri_fpga (Tiny FPGA) tt_um_mikailgedik_inverted_inverters (Inverted inverters) tt_um_esauqch_hamming74 (Hamming(7,4) encoder/decoder (IEEE)) tt_um_hackin7_analog_experiments (TinyAnalogExperiments) tt_um_snake (snake game) tt_um_mini_kraken (Kraken IO Subprocessor) tt_um_fabien_pio (AstraPIO) tt_um_chiplab (ChipLab) tt_um_wokwi_475490677474407425 (Tiny_Divider) tt_um_c061618g2tr (Circuitli C061618G2TR) tt_um_catalinlazar_nanopio (nanoPIO) tt_um_catalinlazar_uart_spi_i2c_bridge (UART-SPI-I2C Bridge) tt_um_enzonappi_sent_i2c (SENT to I2C bridge) tt_um_kush1434_proof (Proof) tt_um_schwallsunk_signal_discriminator (Highspeed voltage discriminator) tt_um_tiarinix_ttihp_verilog_template (8-bit educational SAP-style CPU) tt_um_vga_glyph_mode (BOOTCAMP) tt_um_GiulioGirelli_packet_processor (Configurable Low-Latency Match-Action Packet Processor) tt_um_vga_tictactoe (Tic Tac Toe) tt_um_vga_dvd_player (DVD player) tt_um_clea_katseye_rain (KATSEYE) tt_um_romd_uart_hello (UART Hello World) tt_um_vga_snake (CDM PYTHON GAME) tt_um_vga_slot_machine (tt_um_vga_slot_machine) tt_um_jet_seq8b (SEQ8 Programmable Sequencer) tt_um_kibo_leak_inspect (KIBO Leak-Inspection Target Controller (VGA)) tt_um_endless_runner (Endless Runner) tt_um_omega_infinity_kaoru (OMEGA INFINITY KAORU 3D Metal Grid Processor) tt_um_nikleberg_mixer (Mixer) tt_um_lahnb_sgdma (TinyDMA: A Descriptor-Based Dual-PSRAM Memory Mover) tt_um_gstj_lockin (Digital IQ Lock-in (IEEE)) tt_um_benpayne_ps2_decoder (PS/2 Keyboard Decoder for 68k) tt_um_cass_s_ui_neuron_lif (Neurona LIF con Aprendizaje STDP Dinamico (IEEE)) tt_um_vga_glyph_mode_CDM_Matrix (CDM Matrix) tt_um_qd39l_xor_stream (Fixed-ROM XOR Stream Engine) tt_um_conv3x3 (3x3 Clock Rate Streaming Input Convolution Engine) tt_um_mc14500b_soc_extended (MC14500B Extended 1-bit Microcontroller SoC) tt_um_vga_hypno_spiral (tt_um_vga_hypno_spiral) tt_um_mattizen_morse_tree (Morse Tree LED Decoder) tt_um_CDM (Colegio de Muntinlupa DVD-like Display) tt_um_romd_uart_loader (UART SPI RAM Loader) tt_um_TscherterJunior_stapel_geraet (stapel gerät) tt_um_das2225_dna_accel (DNA_Accel) tt_um_tinysoc (TinySoC) tt_um_barrel_shifter (Barrel Shifter) tt_um_approx_mac_coprocessor (Approximate DSP: Time-Multiplexed MAC Coprocessor) tt_um_joesagents_market_split_oracle (Market-split oracle) tt_um_mgpauly1458_ringmeter (Ring oscillator frequency meter) tt_um_pettit_prism_lite (PRISM with Risc-V (TinyQV) SoC) tt_um_workshop_cpu (IEEE Workshop Simple CPU) tt_um_algofoogle_analog_junk (Simple comparator + 2 DACs analog layout in a 1x1 tile) tt_um_lkhanh_cordic (TinyQV SoC (Dual Memory Backend)) tt_um_4x4npu (4x4NPU: Dual-Lane INT4 Neural Accelerator) tt_um_abiaselli_izh_bridge_3x2 (Izhikevich event bridge (4 contexts)) tt_um_fabulous_ihp_26b (Tiny FABulous FPGA) tt_um_zanderivo_voronoi (Four-Metric VGA Nearest-Prototype Visualizer)