34 Preinception: Simple Compute Accelerator

34 : Preinception: Simple Compute Accelerator

Design render

How it works

The C++ driver API, build instructions and hardware models for "Preinception" can be found in the PRESM repository.

Architecture

All commands are sent via the C++ driver.

+------------------------------------------------+
|               driver (C++ API)                 | 
+------------------------------------------------+
        |           (Host)          ^
        |                           |    
--------|------[ 48-bit packet ]----|-------------
        |                           |
        Y           (Device)        |
+------------------------------------------------+
|                   UARTPacket                   |
|     +-------------+           +-------------+  |
|     |   UARTRx    |           |   UARTTx    |  |
|     +-------------+           +-------------+  |
|                                                |
+------------------------------------------------+
        |                           ^
        |                           |
        Y                           |
+------------------------------------------------+
|                   Command                      |
|                  Processor                     |
|                     (CP)                       |
+------------------------------------------------+

Host-Device packet structure (48-bit packet)

+-----------------------------------------------+-------------------+
|            16-bit header                      |   32-bit body     |
++----------------------------------------------+-------------------+
|| 4-bit     | 4-bit   | 4-bit   | 4-bit       ||   32-bits data   ||
|| Unique ID | Type    | Command | Sub-command ||                  ||
++--------------------------------------------------+---------------+

How to test

<b>Prerequisits</b>

  • A Linux PC with a spare USB port
  • The demo board from Tiny Tapeout

<b>Notes</b>

  • The code is officially tested on Ubuntu
  • You can also use Ubuntu under WSL.
  • With WSL however, the underlying port to which the demo board is connected will have to be exposed to WSL

Clone PRESM and navigate to the cloned directory.

Build the Tiny Tapeout config for Preinception:

python scripts/build.py --config hw_configs/preinception/serial_tapeout_tt_ihp26b.json

Next, we need to connect the chip to the PC.

The chip can be connected in two ways:

  • Connect the demo board to the PC with USB.
  • With an exteral UART module attached to the demo board. The UART module is connected to the PC with USB.

As of now, not sure which one will work, so give both a go when chips become available.

You may need to run the following command to activate the FTDI drivers:

sudo modprobe ftdi_sio

Direct Demo Board Connection

This is straightforward. Testing is done by running verification apps:

python scripts/verify.py --config hw_configs/preinception/serial_tapeout_tt_ihp26b.json

You should see an output like so:

++ Copying files from /home/aakashkt/presm/build/verification/ to verify_runs/00491
++ Copying file /home/aakashkt/presm/build/driver/matrix/libmatrix_serial.so to verify_runs/00491
++ Copying file hw_configs/preinception/serial_fpga_tangnano20k.json to verify_runs/00491/hw_config.json
++ ======================
++ PRESM Execution Begin
++ ======================
++ Changing working directory to: /home/aakashkt/presm/verify_runs/00491
++ Executing: ./verification sanity device
++ Environment:
{'LD_PRELOAD': 'libmatrix_serial.so'}
++ Changing working directory to: /home/aakashkt/presm
++ ======================
++ PRESM Execution End
++ ======================

++ Changing working directory to: /home/aakashkt/presm/verify_runs/00491
++ Executing: ./verification sanity host
++ Changing working directory to: /home/aakashkt/presm

++ Verification of "sanity" succeeded.

++ ======================
++ PRESM Execution Begin
++ ======================
++ Changing working directory to: /home/aakashkt/presm/verify_runs/00491
++ Executing: ./verification addition device
++ Environment:
{'LD_PRELOAD': 'libmatrix_serial.so'}
++ Changing working directory to: /home/aakashkt/presm
++ ======================
++ PRESM Execution End
++ ======================

++ Changing working directory to: /home/aakashkt/presm/verify_runs/00491
++ Executing: ./verification addition host
++ Changing working directory to: /home/aakashkt/presm

++ Verification of "addition" succeeded.

.....
.....

Via External UART module

On the demo board:

  • Connect output pin 6 uo[6] (PIN_HI in datasheet) to input pin 0 ui[0] (SEL_RX_TX in datasheet).
    • This changes the UART RX and TX pins from the default to two other free pins
  • Next, connect the external UART module
    • Connect TX to input pin 7 ui[7] (RX_secondary in datasheet)
    • Connect RX to input pin 7 uo[7] (TX_secondary in datasheet)

Now we can run the verification apps like above.

Using the chip with your own code

Make sure you have built Preinception with the tapeout configuration.

python scripts/build.py --config hw_configs/preinception/serial_tapeout_tt_ihp26b.json

The build creates a package of the driver in packages/, which looks like:

├── packages/
│   ├── matrix/
│   |   ├── include/
|   |   |   ├── matrix.h # Driver API header
|   |   ├── lib/
|   |   |   ├── libmatrix_serial.so # Driver library

Lets compile a simple C++ code that uses the driver to add two numbers on preinception.

#include "include/matrix.h"
#include <iostream>

int main()
{
    mInit(); // Initialize the driver
    
    // Allocate memory for device, and initialize it
    MIntDeviceMemory a(-64); 
    MIntDeviceMemory b(-80);
    MIntDeviceMemory c(10);

    mAdd(a, b, c); // Call add on 'a' and 'b', store in 'c'
    mSync(); // Wait for device to finish

    std::cout << a.getValue() << " + " << b.getValue() << " = " << c.getValue() << std::endl;

    mFree(); // Free driver resources
}

Compilation needs to link with the driver library:

g++ main.cpp -L./lib/ -lmatrix_serial -o main -Wl,-rpath,./lib

Running the program:

$ ./main
-64 + -80 = -144

Failure cases

  • The driver currently assumes that the device shows up in one of these: /dev/ttyUSB0 --> /dev/ttyUSB4
    • Essentially, it searches for and does a handshake protocol for devices from index 0 to 4.
    • If the device shows up in another name or after index 4, the driver will quit with an error.

External hardware

Possibly requires an external UART-USB module.

IO

#InputOutputBidirectional
0SEL_RX_TX
1
2
3RX_primary
4TX_primary
5
6PIN_HI
7RX_secondaryTX_secondary

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)