PPE-X is a compact, domain-specific digital protocol-emulation ASIC architecture designed for the Jane Street Protocol Emulator ASIC Competition. Rather than implementing fixed hardware state machines for individual digital protocols, PPE-X combines a lightweight, programmable protocol execution engine, cycle-deterministic timing hardware, and a configurable GPIO pin matrix.
A host processor configures pin routing, sets timing parameters, and uploads micro-programs and payload data through a standardized host interface (SPI slave). The same silicon can be dynamically reconfigured for diverse digital protocols—including UART, SPI, I2C, custom synchronous bitstreams, and sensor interfaces—simply by loading a new instruction sequence.
The architecture is cleanly divided into a Management Plane and a Protocol/Data Plane, operating in two selectable modes:
- Mode 0: Protocol Emulator:
- The PPE Core executes stored microcode programs to emulate or interact with a digital protocol device.
- RX and TX engines operate under software sequencer control with host FIFO data movements.
- Mode 1: Protocol Translator:
- Hardware bridging between two physical protocols in real time:
- RX Engine (Decode / Capture): Receives and deserializes Protocol A from External Device A.
- Translation / Data Path: Automatically routes, formats, masks, bit-reverses, or filters packets through FIFO interconnects.
- TX Engine (Encode / Generate): Serializes and generates Protocol B waveforms to External Device B without requiring host CPU intervention.
-
Host Interface Unit (HIU):
- Physical SPI Mode 0 Slave with fast 2-stage input synchronizers.
- Command Decoder & Transaction FSM converting framed serial packets (
CMD + ADDR + DATA32) into internal register bus cycles. - Direct parallel bus bypass for zero-overhead testbench verification and bring-up.
-
Control & Status Registers (CSR):
- Memory-mapped registers for chip identification (
DEVICE_ID), operating mode (EMULATIONvsTRANSLATION), execution control (START,STOP,RESET,ENABLE), status monitoring (BUSY,DONE,ERROR,TIMEOUT, FIFO levels), interrupt handling, GPIO pin configuration, timer prescalers, and translation filters.
- Memory-mapped registers for chip identification (
-
Program Memory (Instruction SRAM):
- 256-word × 16-bit dual-port instruction SRAM macro (
ppe_sram_dp). - Port A: Host load/readback with auto-incrementing address capability.
- Port B: Low-latency fetch by the Execution Engine for zero-latency execution.
- 256-word × 16-bit dual-port instruction SRAM macro (
-
Data Buffers (RX FIFO / TX FIFO - SRAM-backed):
- Synchronous 16-entry × 8-bit First-Word Fall-Through (FWFT) FIFOs utilizing dual-port SRAM (
ppe_sram_dp) storage arrays. - Decouples host data transfers from protocol execution and translation rates.
- Synchronous 16-entry × 8-bit First-Word Fall-Through (FWFT) FIFOs utilizing dual-port SRAM (
-
Hardware Translation & Data Path Engine:
- High-throughput autonomous data forwarding engine between RX and TX paths.
- On-the-fly bitwise masking, XOR manipulation, bit order reversal (endianness/nibble swap), and pattern filtering (dropping unwanted packets).
- Real-time translated byte counter.
-
Protocol Execution Engine (PPE Core):
- Domain-specific RISC micro-engine with a 16-bit instruction format.
- 8 × 8-bit working registers (
R0–R7). - 8-bit ALU supporting addition, subtraction, logic operations, bitwise negation, shifts, and comparisons with status flags (
Z,N,C). - Dedicated Shift/Capture Unit with independent TX serialization and RX deserialization shift registers.
- Zero-overhead branch and loop controller featuring a dedicated single-cycle
DJNZ(Decrement and Jump if Not Zero) instruction.
-
Timing / Event Engine & Timeout Detection:
- Cycle-accurate delay generator for deterministic
WAIT Ncycles. - Programmable prescaler tick generator and 32-bit master cycle counter.
- Hardware watchdog timer for protocol framing and transaction timeout detection (
TIMEOUTflag & IRQ).
- Cycle-accurate delay generator for deterministic
-
Input / Edge Detection Subsystem:
- 2-stage input synchronizers on all GPIO pins.
- Configurable per-pin edge detectors (rising, falling, both, level).
- Generates engine wake-up events for event-driven protocols (
WAIT_EVENT).
-
GPIO Control & Pin Matrix:
- Controls direction (OE), push-pull vs. open-drain driving, CSR manual overrides, and pin sampling.
-
Interrupt & Event Controller (6 Channels):
- Collects execution completion (
DONE), FIFO thresholds (RX_VALID,TX_EMPTY), GPIO edges, core errors, and framing timeouts (TIMEOUT). - Configurable interrupt masks (
IRQ_ENABLE), write-1-to-clear sticky status (IRQ_STATUS), and hostirqpin generation.
- Collects execution completion (
All host transactions over SPI follow standard Mode 0 (CPOL=0, CPHA=0):
- Byte 0 (Command):
0x80= 32-bit Register Write,0x00= 32-bit Register Read. - Byte 1 (Address): 8-bit byte offset (
0x00–0x6C). - Bytes 2–5 (Data): 32-bit data transferred MSB-first (
DATA[31:24],DATA[23:16],DATA[15:8],DATA[7:0]).
| Offset | Register Name | Access | Reset Value | Description |
|---|---|---|---|---|
0x00 |
DEVICE_ID |
RO | 0x50504531 |
ASIC Architecture Identifier ("PPE1" ASCII) |
0x04 |
CONTROL |
RW | 0x00000008 |
[0]: START, [1]: STOP, [2]: RESET, [3]: ENABLE, [4]: MODE (0=Emulation, 1=Translation) |
0x08 |
STATUS |
RO | 0x00000010 |
[0]: BUSY, [1]: DONE, [2]: ERROR, [3]: TX_FULL, [4]: TX_EMPTY, [5]: RX_FULL, [6]: RX_VALID, [7]: TIMEOUT |
0x0C |
IRQ_STATUS |
W1C | 0x00000000 |
Latched interrupt status: [0]: DONE, [1]: RX_READY, [2]: TX_EMPTY, [3]: EDGE, [4]: ERROR, [5]: TIMEOUT |
0x10 |
IRQ_ENABLE |
RW | 0x00000000 |
Interrupt enable mask bits corresponding to IRQ_STATUS |
0x14 |
PIN_CFG0 |
RW | 0x00000000 |
GPIO 0 configuration ([0]: override OE, [1]: manual out, [2]: open-drain, [4:3]: edge mode, [8]: sampled in) |
0x18–0x30 |
PIN_CFG1–7 |
RW | 0x00000000 |
GPIO 1 through 7 configurations |
0x40 |
TIMER_CFG |
RW | 0x00000000 |
[15:0]: Prescaler divider count, [16]: Timer enable |
0x44 |
TIMEOUT_CFG |
RW | 0x00000000 |
[15:0]: Framing timeout limit (cycles), [16]: Timeout watchdog enable |
0x48 |
TRANS_CFG |
RW | 0x00000000 |
[0]: Auto-forward enable, [1]: Mask en, [2]: XOR en, [3]: Bit swap, [4]: Filter en, [16]: Active status |
0x4C |
TRANS_MASK |
RW | 0x00000000 |
[7:0]: Bitwise mask / drop pattern, [15:8]: XOR manipulation pattern |
0x50 |
TX_DATA |
WO / RO | 0x00000010 |
Write: Push wdata[7:0] to TX FIFO. Read: returns TX status & count |
0x54 |
RX_DATA |
RO | 0x00000000 |
Read: Pop rdata[7:0] from RX FIFO |
0x60 |
PROGRAM_ADDR |
RW | 0x00000000 |
[7:0]: Instruction memory address, [15]: Auto-increment enable |
0x64 |
PROGRAM_DATA |
RW | 0x00000000 |
[15:0]: Instruction word written to Program SRAM at PROGRAM_ADDR |
0x68 |
PC |
RO | 0x00000000 |
Current Execution Program Counter ([7:0]) |
0x6C |
ERROR_CODE |
RO | 0x00000000 |
[7:0]: Core error code, [15:8]: Translated byte counter |
Each instruction is encoded as a fixed 16-bit word: instr[15:12] specifies the primary 4-bit opcode.
| Opcode | Mnemonic | Format | Description |
|---|---|---|---|
0x0 |
NOP |
16'h0000 |
No operation (1 cycle) |
0x1 |
ALU |
[11:9]=Rd, [8:6]=Rs, [3:0]=Func |
Perform ALU operation Rd = Rd Func Rs. Functions: ADD, SUB, AND, OR, XOR, NOT, SHL, SHR, CMP
|
0x2 |
LDI |
[11:9]=Rd, [7:0]=imm8 |
Load 8-bit immediate into register: Rd = imm8
|
0x3 |
MOV |
[11:9]=Rd, [8:6]=Rs |
Copy register: Rd = Rs
|
0x4 |
PIN_SET |
[10:8]=pin, [7]=val |
Drive GPIO output pin high (val=1) or low (val=0) |
0x5 |
PIN_DIR |
[10:8]=pin, [7]=oe |
Set GPIO direction: Output (oe=1) or Input/Hi-Z (oe=0) |
0x6 |
WAIT_CYCLES |
[11:0]=cycles |
Stall execution engine for deterministic cycle count ( |
0x7 |
WAIT_REG |
[11:9]=Rs |
Stall execution engine for cycles specified in register Rs
|
0x8 |
WAIT_EVENT |
[10:8]=pin, [7:6]=cond |
Stall execution until pin matches condition (00=Low, 01=High, 10=Rise, 11=Fall) |
0x9 |
SHIFT_OUT |
[10:8]=pin, [7]=order |
Shift out 1 bit from TX shift register to GPIO pin (order: 0=MSB, 1=LSB) |
0xA |
SHIFT_IN |
[10:8]=pin, [7]=order |
Sample 1 bit from GPIO pin into RX shift register (order: 0=MSB, 1=LSB) |
0xB |
FIFO |
[11:8]=subop, [7:5]=reg |
FIFO operations: LOAD_TX (pop to Rd), STORE_RX (push Rs), LOAD_SR_TX (pop to sreg), STORE_SR_RX (push sreg), MOV_SR_REG, MOV_REG_SR
|
0xC |
JMP |
[7:0]=addr |
Unconditional jump: PC = addr
|
0xD |
JCOND |
[11]=cond, [10:8]=Rs, [7:0]=addr |
Conditional jump: cond=0 (JZ: if Rs==0), cond=1 (JNZ: if Rs!=0) |
0xE |
DJNZ |
[11:9]=Rd, [7:0]=addr |
Decrement Rd and Jump if not zero: Rd = Rd - 1; if (Rd != 0) PC = addr
|
0xF |
SYS |
[11:8]=subop |
System instructions: HALT (subop=0), TRIG_IRQ (subop=1), SAMPLE_PIN (subop=2), ERROR (subop=0xF) |
; Address 0: Configure Pin 0 as TX output
PIN_DIR pin=0, oe=1
; Address 1: Drive line idle high
PIN_SET pin=0, val=1
; Address 2: Fetch byte to send from TX FIFO into shift register
FIFO_LOAD_SR_TX
; Address 3: Initialize bit counter (8 data bits)
LDI R1, 8
; Address 4: Start bit (drive line low)
PIN_SET pin=0, val=0
; Address 5: Wait remaining baud cycles for start bit
WAIT_CYCLES 6
; Address 6 (LOOP): Shift out next data bit (LSB first)
SHIFT_OUT pin=0, order=LSB
; Address 7: Wait baud bit duration
WAIT_CYCLES 6
; Address 8: Decrement bit counter, branch to LOOP if bits remain
DJNZ R1, target=6
; Address 9: Stop bit (drive line high)
PIN_SET pin=0, val=1
; Address 10: Wait stop bit duration
WAIT_CYCLES 7
; Address 11: Assert DONE interrupt and halt
SYS_HALT; Setup pins: Pin 0=SCLK, Pin 1=MOSI, Pin 2=CS_N, Pin 3=MISO
PIN_DIR pin=0, oe=1
PIN_DIR pin=1, oe=1
PIN_DIR pin=2, oe=1
PIN_DIR pin=3, oe=0
PIN_SET pin=2, val=1 ; Deassert CS_N
PIN_SET pin=0, val=0 ; SCLK idle low (CPOL=0)
FIFO_LOAD_SR_TX ; Load transmit byte from TX FIFO
PIN_SET pin=2, val=0 ; Assert CS_N active low
LDI R1, 8 ; 8 bits
; SPI_LOOP:
SHIFT_OUT pin=1, order=MSB ; Drive MOSI bit
PIN_SET pin=0, val=1 ; SCLK rising edge
WAIT_CYCLES 4 ; Clock high time
SHIFT_IN pin=3, order=MSB ; Sample MISO bit
PIN_SET pin=0, val=0 ; SCLK falling edge
WAIT_CYCLES 4 ; Clock low time
DJNZ R1, target=SPI_LOOP ; Repeat for 8 bits
PIN_SET pin=2, val=1 ; Deassert CS_N high
FIFO_STORE_SR_RX ; Push captured byte into RX FIFO
SYS_HALT ; Complete transactionPPEE/
├── docs/
│ └── images/
│ ├── ppe_top_architecture.png # Top-level architecture diagram
│ └── ppe_host_interface.png # Host interface block diagram
│
├── rtl/
│ ├── ppe_defines.vh # Global architecture definitions & macros
│ ├── ppe_top.v # Top-level ASIC chip module
│ │
│ ├── host_interface/
│ │ ├── ppe_spi_slave.v # Physical SPI Mode 0 slave with synchronizers
│ │ ├── ppe_cmd_decoder.v # SPI packet decoder & bus sequencer FSM
│ │ └── ppe_host_if.v # Host interface integration wrapper
│ │
│ ├── registers/
│ │ └── ppe_csr.v # Memory-mapped Control & Status Registers
│ │
│ ├── memory/
│ │ ├── ppe_sram_sp.v # Generic single-port SRAM macro model
│ │ ├── ppe_sram_dp.v # Generic dual-port SRAM macro model
│ │ └── ppe_prog_mem.v # Dual-port instruction memory (SRAM wrapper)
│ │
│ ├── fifo/
│ │ └── ppe_fifo.v # Synchronous FWFT FIFO backed by dual-port SRAM
│ │
│ ├── execution_engine/
│ │ ├── ppe_instr_decoder.v # 16-bit instruction decoder
│ │ ├── ppe_regfile.v # 8 x 8-bit working register file (R0-R7)
│ │ ├── ppe_alu.v # 8-bit ALU with arithmetic, logic, and flags
│ │ ├── ppe_shift_unit.v # Independent TX/RX serialization shift registers
│ │ ├── ppe_sequencer.v # Sequencer, PC, stalls, and DJNZ branch logic
│ │ └── ppe_exec_engine.v # Protocol Execution Engine top-level
│ │
│ ├── translation/
│ │ └── ppe_trans_engine.v # Hardware Translation & Data Path Engine
│ │
│ ├── timing/
│ │ └── ppe_timing_unit.v # Cycle counter, prescaler, delays, and timeout detection
│ │
│ ├── gpio/
│ │ ├── ppe_edge_detect.v # 2-stage synchronizers & edge/level detectors
│ │ └── ppe_gpio_matrix.v # Direction, push-pull/open-drain drive matrix
│ │
│ └── interrupt/
│ └── ppe_irq_controller.v # 6-channel event latching and host IRQ generation
│
├── tb/
│ ├── tb_ppe_sram.v # SRAM macros unit testbench (SP & DP)
│ ├── tb_ppe_alu.v # ALU unit testbench
│ ├── tb_ppe_fifo.v # Synchronous FIFO unit testbench
│ ├── tb_ppe_timing.v # Timing, prescaler, and timeout testbench
│ ├── tb_ppe_exec_engine.v # Execution engine core testbench
│ ├── tb_ppe_trans_engine.v # Hardware translation data path testbench
│ ├── tb_ppe_top_uart.v # Top-level UART 8-N-1 TX emulation testbench
│ ├── tb_ppe_top_spi.v # Top-level full-duplex SPI Master testbench
│ ├── tb_ppe_top_translation.v # Top-level Protocol Translation integration testbench
│ └── tb_ppe_top_full.v # End-to-end physical SPI host testbench
│
├── .gitignore # Git ignore rules for simulation artifacts
├── run_tests.py # Automated regression test runner
└── README.md # Project documentation
- Icarus Verilog (
iverilog) version 10.0+ (tested with v12.0) - Python 3.8+ (for test runner)
To compile and execute all unit, protocol, translation, and full-chip integration testbenches:
python run_tests.pyExpected output:
======================================================================
PPE-X Programmable Protocol Emulation Engine - Test Suite
======================================================================
[PASS] SRAM Macros Unit Test
[PASS] ALU Unit Test
[PASS] FIFO Unit Test
[PASS] Timing Unit Test
[PASS] Execution Engine Unit Test
[PASS] Translation Engine Unit Test
[PASS] Top-Level UART Protocol Test
[PASS] Top-Level SPI Master Protocol Test
[PASS] Top-Level Protocol Translation Test
[PASS] Top-Level Full Physical SPI Host Test
======================================================================
Test Description | Status
----------------------------------------------------------------------
SRAM Macros Unit Test | PASSED
ALU Unit Test | PASSED
FIFO Unit Test | PASSED
Timing Unit Test | PASSED
Execution Engine Unit Test | PASSED
Translation Engine Unit Test | PASSED
Top-Level UART Protocol Test | PASSED
Top-Level SPI Master Protocol Test | PASSED
Top-Level Protocol Translation Test | PASSED
Top-Level Full Physical SPI Host Test | PASSED
======================================================================
>>> ALL REGRESSION TESTS PASSED (100% SUCCESS) <<<
iverilog -I rtl -o sim_alu rtl/execution_engine/ppe_alu.v tb/tb_ppe_alu.v
vvp sim_aluiverilog -o sim_fifo rtl/fifo/ppe_fifo.v tb/tb_ppe_fifo.v
vvp sim_fifoiverilog -o sim_timing rtl/timing/ppe_timing_unit.v tb/tb_ppe_timing.v
vvp sim_timingiverilog -I rtl -o sim_exec rtl/execution_engine/*.v tb/tb_ppe_exec_engine.v
vvp sim_execiverilog -I rtl -o sim_uart rtl/fifo/*.v rtl/memory/*.v rtl/registers/*.v rtl/timing/*.v rtl/gpio/*.v rtl/interrupt/*.v rtl/execution_engine/*.v rtl/host_interface/*.v rtl/ppe_top.v tb/tb_ppe_top_uart.v
vvp sim_uartiverilog -I rtl -o sim_spi rtl/fifo/*.v rtl/memory/*.v rtl/registers/*.v rtl/timing/*.v rtl/gpio/*.v rtl/interrupt/*.v rtl/execution_engine/*.v rtl/host_interface/*.v rtl/ppe_top.v tb/tb_ppe_top_spi.v
vvp sim_spiiverilog -I rtl -o sim_full rtl/fifo/*.v rtl/memory/*.v rtl/registers/*.v rtl/timing/*.v rtl/gpio/*.v rtl/interrupt/*.v rtl/execution_engine/*.v rtl/host_interface/*.v rtl/ppe_top.v tb/tb_ppe_top_full.v
vvp sim_fullDeveloped for the Jane Street Protocol Emulator ASIC Competition.
Design based on the PPE-X Architecture and Host Interface Detailed Design Specification.

