261 SEQ8 Programmable Sequencer

261 : SEQ8 Programmable Sequencer

Design render

How it works

SEQ8 is a very small programmable sequencer: an 8-instruction state machine that drives 8 output pins.

You shift a program into it over a simple SPI-like port, raise the RUN pin, and it starts executing from address 0. Each instruction either writes a new pattern to the output pins, pauses for a programmable length of time, or jumps, optionally depending on one of two input pins.

The behaviour is not baked into the silicon. One chip can be a traffic light, a stepper-motor driver, an LED chaser, a test pattern generator, or a servo pulse source, depending only on the 8 words you load into it.

Blocks

  • Program memory: 8 words x 10 bits, written by the loader, read by the program counter.
  • Loader: a shift register clocked by SCK while CS_N is low. Every 10 bits it writes one instruction and auto-increments the write address.
  • Tick generator: a 12-bit counter that makes one "tick" every 1, 16, 256 or 4096 clock cycles, chosen by pins ui[7:6]. WAIT counts ticks.
  • Core: a 3-bit program counter, an 8-bit wait counter and the 8-bit output register.

Instruction set

Every instruction is 10 bits: a 2-bit opcode and an 8-bit operand.

Opcode Name Operand Effect
00 OUT 8-bit value drive uo_out
01 WAIT count pause for (count + 1) ticks
10 JMP cond[7:6], addr[2:0] jump; see below
11 NOP - do nothing

Jump conditions (operand bits 7:6):

cond Behaviour
00 always jump to addr
01 jump to addr if IN0 (ui[4]) is high, otherwise continue
10 jump to addr if IN1 (ui[5]) is high, otherwise continue
11 HALT: stop and hold the current outputs

The program counter is 3 bits, so it wraps from address 7 back to 0 by itself. A program that fills all 8 words loops with no JMP at all. A shorter program must end with a JMP or HALT, otherwise it runs on into memory that was never loaded.

Tick speed

ui[7:6] Clock cycles per tick
00 1
01 16
10 256
11 4096

For example, with ui[7:6] = 11 and a 4096 Hz clock, one tick is one second, so WAIT 9 lasts 10 seconds.

Loading a program

  1. Hold RUN low. The core stays in reset while you load.
  2. Pull CS_N low. The write address resets to 0.
  3. For each instruction, shift 10 bits on the rising edge of SCK, most significant bit first. Instructions are written back to back starting at address 0.
  4. Raise CS_N.
  5. Set ui[7:6] for the tick speed, then raise RUN. Execution starts at address 0.

The chip samples SCK, MOSI and CS_N with its own clock, so keep every pin steady for at least 4 clock cycles per step. In practice, load the program with a fast clock (for example 1 MHz), then switch to the slow clock you want for running.

Dropping RUN low at any time clears the outputs and rewinds to address 0, so you can restart a program without reloading it.

How to test

The easiest way is with the RP2350 on the demo board driving the load pins in MicroPython. Shift in a program, raise RUN, and watch the output pins.

A worked example, a two-direction traffic light, is in tools/traffic.s along with an assembler (tools/seq16asm.py) that turns the source into the words you shift in.

For a quick manual check without any software, load this two instruction program and confirm that all eight uo_out pins go high: OUT 0xFF (0x0FF), HALT (0x2C0).

The cocotb test suite in test/ covers reset behaviour, the loader, WAIT timing, the tick speed select, both conditional jumps, program counter wraparound and a full traffic-light sequence.

External hardware

None required. LEDs with series resistors on the output pins make the behaviour visible. The design can also drive a 7-segment display, motor driver inputs, or anything else that takes logic-level signals.

IO

#InputOutputBidirectional
0SCK - program load clockOUT0
1MOSI - program load dataOUT1
2CS_N - program load select, active lowOUT2
3RUN - high to execute, low to reset the coreOUT3
4IN0 - branch input 0OUT4
5IN1 - branch input 1OUT5
6TICK0 - tick speed select, low bitOUT6
7TICK1 - tick speed select, high bitOUT7

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)