Skip to content

JITx-Inc/example_python_protocols

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JITX Protocol Examples and Validation Library

This repository contains JITX Python implementations of high-speed protocol bundles, signal integrity constraints, and component validation utilities. It demonstrates how to define and constrain memory and serial interfaces in hardware designs.

Table of Contents


Overview

This library provides:

  1. Protocol Bundles: Port definitions for memory interfaces (DDR4, LPDDR4, LPDDR5, GDDR7) and high-speed serial interfaces (PCIe, SATA, SFP/QSFP)

  2. Signal Integrity Constraints: Timing skew, insertion loss, and impedance constraints that can be applied to protocol connections

  3. Example Designs: Complete working examples showing controller-to-memory and device-to-device connections with SI constraints

  4. Resistor Validation: Utilities to validate resistor values against E-series standards and check power dissipation limits

Quick Start

# Build all designs
./.venv/bin/python -m jitx build-all

# Expected output: 8 designs, all status: ok

Protocols

Memory Protocols

DDR4 (protocols/memory/ddr4.py)

DDR4 SDRAM interface supporting x16 width with single or dual rank configurations.

Bundle Structure:

DDR4
├── data: DDR4Data
│   ├── DQ[16]         - 16-bit data bus
│   ├── DQS[2]         - Data strobes (DiffPair per byte lane)
│   └── DM_n[2]        - Data masks
└── acc: DDR4ACC
    ├── A[17]          - Address bus
    ├── BA[2]          - Bank address
    ├── BG[2]          - Bank group
    ├── CK[2]          - Clock (DiffPair per chip)
    ├── CKE[1-2]       - Clock enable
    ├── CS_n[1-2]      - Chip select
    ├── ODT[1-2]       - On-die termination
    ├── ACT_n          - Activate
    ├── RESET_n        - Reset
    ├── PAR            - Parity
    └── ALERT_n        - Alert

Constraint Parameters (DDR4ConstraintParams):

Parameter Default Description
skew_ck ±2.5ps CK intra-pair skew
skew_dqs ±2.5ps DQS intra-pair skew
skew_ck_dqs -300ps to +500ps CK to DQS timing
skew_dqs_dq ±10ps DQS to DQ/DM skew
loss 5.0dB Maximum insertion loss

LPDDR4 (protocols/memory/lpddr4.py)

Low-power DDR4 for mobile applications. Supports x16, x32, and x64 widths with 1-3 ranks.

Bundle Structure:

LPDDR4
└── ch[1-4]: LPDDR4_X16      - x16 channels
    ├── d[2]: LPDDR4Lane     - Byte lanes
    │   ├── dq[8]            - Data bits
    │   ├── dqs (DiffPair)   - Data strobe
    │   └── dmi              - Data mask/inversion
    ├── ck (DiffPair)        - Clock
    ├── cke[ranks]           - Clock enable
    ├── cs[ranks]            - Chip select
    └── ca[6]                - Command/address

Constraint Parameters (LPDDR4ConstraintParams):

Parameter Default Description
skew_ck ±2.0ps CK intra-pair skew
skew_ck_cke ±8.0ps CK to CKE skew
skew_ck_cs ±8.0ps CK to CS skew
skew_ck_ca ±8.0ps CK to CA skew
skew_ck_dqs -500ps to +2500ps CK to DQS skew
skew_dqs ±2.0ps DQS intra-pair skew
skew_dqs_dq ±5.0ps DQS to DQ/DMI skew
loss 5.0dB Maximum insertion loss

LPDDR5 (protocols/memory/lpddr5.py)

LPDDR5/LPDDR5X for high-bandwidth mobile applications. Supports x32 and x64 widths.

Key Differences from LPDDR4:

  • Separate Write Clock (WCK) and Read Data Strobe (RDQS)
  • 7-bit Command/Address bus
  • Tighter timing constraints

Bundle Structure:

LPDDR5
├── d[channels][2]: LPDDR5DataLane
│   ├── dq[8]              - Data bits
│   ├── wck (DiffPair)     - Write clock
│   ├── rdqs (DiffPair)    - Read data strobe
│   └── dmi                - Data mask/inversion
├── cs[channels][ranks]    - Chip selects
├── ck[channels] (DiffPair) - Clocks
├── ca[channels][7]        - Command/address
└── reset_n                - Shared reset

GDDR7 (protocols/memory/gddr7.py)

Graphics DDR7 for high-performance GPU memory. Fixed 4-channel architecture.

Bundle Structure:

GDDR7
├── data[4]: GDDR7DataChannel
│   ├── DQ[10]             - 10-bit data (PAM3/NRZ)
│   ├── RCK (DiffPair)     - Read clock
│   ├── WCK (DiffPair)     - Write clock
│   ├── CA[5]              - Command/address
│   ├── DQE                - Error detection
│   └── ERR                - Error flag
└── control: GDDR7ControlChannel
    ├── RESET_n            - Reset
    ├── ZQ_AB              - Impedance cal (A/B)
    └── ZQ_CD              - Impedance cal (C/D)

Constraint Parameters (GDDR7ConstraintParams):

Parameter Default Description
skew_rck ±10fs RCK intra-pair skew
skew_wck ±10fs WCK intra-pair skew
skew_rck_wck ±20ps RCK to WCK skew
skew_dq_dqe ±5ps DQ to DQE skew
loss 5.0dB Maximum insertion loss

High-Speed Serial Protocols

PCIe (protocols/pcie.py)

PCI Express supporting Gen1 through Gen6, x1 through x16 widths.

Bundle Structure:

PCIe
├── data: PCIeData
│   └── lane[width]: PCIeLane
│       ├── TX (DiffPair)  - Transmit pair
│       └── RX (DiffPair)  - Receive pair
└── ctrl: PCIeControl (optional)
    ├── REFCLK (DiffPair)  - Reference clock
    ├── PERST_n            - Reset
    ├── CLKREQ_n           - Clock request
    ├── WAKE_n             - Wake
    └── PRSNT              - Presence detect

Usage Modes:

  • xover=False (default): Straight-through (TX→TX, RX→RX) for card-edge connectors
  • xover=True: Crossover (TX→RX, RX→TX) for IC-to-IC connections

Helper Function:

connect_pcie_null_modem(a: PCIe, b: PCIe) -> list

Creates crossover topology connections for null-modem (IC-to-IC) configurations.

SATA (protocols/sata.py)

Serial ATA interface for storage devices.

Bundle Structure:

SATA
└── lane: SATALane
    ├── TX (DiffPair)      - Transmit pair
    └── RX (DiffPair)      - Receive pair

Constraint Notes:

  • Always uses crossover topology (TX→RX)
  • 100Ω differential impedance
  • Insertion loss ≤5.0dB

SFP/QSFP (protocols/sfp.py)

Small Form-factor Pluggable interfaces for optical/copper networking.

Variants:

Type Lanes Description
SFP 1 Standard SFP/SFP+
SFP_DD 2 SFP Double Density
QSFP 4 Quad SFP
QSFP_DD 8 QSFP Double Density

Bundle Structure:

SFP_Lane (base for all variants)
└── lanes[n]: SFPLink
    ├── TX (DiffPair)      - Transmit pair
    └── RX (DiffPair)      - Receive pair

Protocol Examples

All examples are in test_protocols/examples/protocols/ and demonstrate:

  • Component definition with landpatterns and pad mappings
  • Memory/controller circuits with direct ports or Provide() patterns
  • Topology connections using >> for SI constraint propagation
  • Application of protocol-specific constraints

Memory Examples

DDR4 Example (examples/protocols/memory/ddr4_example.py)

Demonstrates DDR4 x16 fly-by topology with two Micron MT40A1G16TB memory chips.

Components:

  • MT40A1G16TB_062E_F: Real Micron DDR4 memory with FBGA96 split-BGA landpattern
  • DDR4ControllerComponent2: Generic controller with Provide() pattern

Key Features:

  • Split-BGA landpattern generator for DDR4 package
  • Fly-by topology: io.DQ → mem0.DQ → mem1.DQ
  • Per-chip clock and control signals

LPDDR4 Example (examples/protocols/memory/lpddr4_example.py)

Samsung K4FBE3D4HB-KHCL x32 dual-rank memory connected to controller.

Components:

  • K4FBE3D4HB_KHCL: Samsung LPDDR4 memory (22x12 BGA)
  • LPDDR4ControllerComponent: Controller with Provide() pattern

Key Features:

  • Dual x16 channels (A and B)
  • Dual rank support with per-rank CKE/CS

LPDDR5 Example (examples/protocols/memory/lpddr5_example.py)

Micron MT62F4G32D8DV-026_AIT_B LPDDR5X memory (automotive grade).

Components:

  • MT62F4G32D8DV_026_AIT_B: 16GB LPDDR5X (315-ball LFBGA)
  • LPDDR5ControllerCircuit: Controller with Provide() pattern

Key Features:

  • x32 DualRank configuration
  • Separate WCK and RDQS per lane
  • 7-bit CA bus per channel

GDDR7 Example (examples/protocols/memory/gddr7_example.py)

GPU IC to GDDR7 memory connection with 4-channel interface.

Components:

  • GDDR7MemoryComponent: FBGA266 split-BGA memory
  • GDDR7ICComponent: 30x30 BGA GPU/IC with checkerboard ground pattern

Key Features:

  • 4 data channels with 10-bit PAM3 data
  • RCK/WCK clock pairs per channel
  • Checkerboard signal/ground ball pattern for IC

Serial Examples

PCIe Example (examples/protocols/pcie/pcie_example.py)

PCIe Gen3 x2 with AC coupling and null-modem topology.

Features:

  • DiffPairCoupler: AC coupling circuit using blocking caps
  • Card-edge mode (straight-through) and IC-to-IC mode (crossover)
  • connect_pcie_null_modem() helper for null-modem connections

SATA Example (examples/protocols/sata/sata_example.py)

SATA host-to-device and IC-to-IC connections.

Features:

  • TX→RX crossover topology
  • AC coupling with blocking capacitors

SFP Example (examples/protocols/sfp/sfp_example.py)

Single-lane SFP and 4-lane QSFP connections.

Features:

  • TX→RX crossover topology (optical-style)
  • AC coupling on TX paths

Resistor Validation

E-Series Validation (eseries_check.py)

Validates that resistance values conform to standard E-series (E96 by default).

from eseries_check import check_eseries_value, ESeriesResult

# Check if 10kΩ is E96 standard
result = check_eseries_value(10000)  # ok=True, severity="ok"

# Check non-standard value
result = check_eseries_value(47500)  # ok=False, severity="error"

# Allow non-standard as warning
result = check_eseries_value(47500, allow_warning=True)  # severity="warning"

Return Object (ESeriesResult):

Field Type Description
ok bool True if value matches E-series
severity str "ok", "warning", or "error"
value_ohms float Input value
series str E-series checked (e.g., "E96")
nearest_standard_ohms float Nearest E-series value
rel_error float Relative error from nearest
message str Human-readable result

Power Dissipation Check (resistor_power_check.py)

Validates that resistor power dissipation (P = I²R) is within package limits.

from resistor_power_check import check_resistor_power, ResistorPowerResult

# Check 1kΩ resistor with 10mA in 0603 package
result = check_resistor_power(
    size="0603",
    resistance_ohms=1000,
    current_amps=0.01,
    derating_factor=0.8,  # 80% derating
    design_margin=2.0,    # 2x safety margin
)

Package Power Ratings:

Imperial Metric Power (W)
01005 0402 0.031
0201 0603 0.050
0402 1005 0.062
0603 1608 0.100
0805 2012 0.125
1206 3216 0.250
1210 3225 0.500
1812 4532 0.750
2010 5025 0.750
2512 6332 1.000

Size Normalization:

  • Ambiguous sizes (0402, 0603) default to imperial
  • Use explicit prefix for clarity: I0402 (imperial) or M1005 (metric)

Combined Resistor Rules (resistor_rules.py)

Combines E-series validation with optional power check.

from resistor_rules import check_resistor, ResistorRuleResult

# E-series only (power check skipped)
result = check_resistor(size="0603", resistance_ohms=10000)

# E-series + power check
result = check_resistor(
    size="0603",
    resistance_ohms=10000,
    current_amps=0.005,
    derating_factor=0.8,
    design_margin=2.0,
)

# Allow non-standard as warning
result = check_resistor(
    size="0603",
    resistance_ohms=9950,  # Not E96
    allow_nonstandard_warning=True,
)

Return Object (ResistorRuleResult):

Field Type Description
ok bool All enforced rules pass
severity str "ok", "warning", or "error"
summary str Single-line status
issues list[str] All messages (info/warning/error)
eseries ESeriesResult E-series validation result
power ResistorPowerResult Power check result (or None if skipped)

Common Infrastructure

Board and Stackup (common/example_board.py)

Provides a 6-layer PCB stackup suitable for high-speed designs.

Stackup:

Top Soldermask (13µm)
Layer 0 - Signal (30µm Cu)
Prepreg (60µm)
Layer 1 - Inner (25µm Cu)
Prepreg (60µm)
Layer 2 - Signal (15µm Cu)
Core (70µm FR4)
Layer 3 - Signal (25µm Cu)
Prepreg (60µm)
Layer 4 - Inner (25µm Cu)
Prepreg (60µm)
Layer 5 - Signal (30µm Cu)
Bottom Soldermask (13µm)

Routing Structures:

Structure Impedance Use Case
SE40RoutingStructure 40Ω LPDDR4
SE45RoutingStructure 45Ω DDR4
SE50RoutingStructure 50Ω General SE
diff_85 85Ω diff LPDDR4 CK/DQS
diff_90 90Ω diff DDR4 CK/DQS
diff_100 100Ω diff PCIe, SATA, SFP

Via Definitions:

  • MicroViaTop1-4: Laser-drilled microvias to inner layers
  • DefaultTHVia: Mechanical through-hole via

Example Components (common/example_components.py)

Components with pin models for SI topology propagation.

BlockingCapacitor:

  • 0201 package blocking capacitor for AC coupling
  • BridgingPinModel allows SI constraints to propagate through

PullUpResistor:

  • 0201 package pull-up resistor
  • BridgingPinModel for SI propagation

Development

Building

# Activate virtual environment
source .venv/bin/activate

# Build all designs
python -m jitx build-all

Project Structure

test_protocols/
├── protocols/                 # Protocol bundle definitions
│   ├── memory/
│   │   ├── ddr4.py           # DDR4 bundle + constraints
│   │   ├── lpddr4.py         # LPDDR4 bundle + constraints
│   │   ├── lpddr5.py         # LPDDR5 bundle + constraints
│   │   └── gddr7.py          # GDDR7 bundle + constraints
│   ├── pcie.py               # PCIe bundle + constraints
│   ├── sata.py               # SATA bundle + constraints
│   └── sfp.py                # SFP/QSFP bundle + constraints
├── examples/protocols/        # Example designs
│   ├── memory/
│   │   ├── ddr4_components.py
│   │   ├── ddr4_example.py
│   │   ├── lpddr4_components.py
│   │   ├── lpddr4_example.py
│   │   ├── lpddr5_components.py
│   │   ├── lpddr5_example.py
│   │   ├── MT62F4G32D8DV_026_AIT_B.py
│   │   ├── gddr7_components.py
│   │   └── gddr7_example.py
│   ├── pcie/
│   ├── sata/
│   └── sfp/
├── common/                    # Shared infrastructure
│   ├── example_board.py      # Board, stackup, vias
│   └── example_components.py # Blocking caps, pull-ups
├── eseries_check.py          # E-series validation
├── resistor_power_check.py   # Power dissipation check
└── resistor_rules.py         # Combined resistor validation

Key Patterns

Topology Connections: Use >> operator to preserve topology for SI constraints:

# Correct - preserves topology
self.topos.append(self.io.dq[i] >> self.mem.DQ[i])

# Incorrect - loses topology information
self.nets.append(self.io.dq[i] + self.mem.DQ[i])

Direct Port vs Provide:

  • Memory components: Use direct ports (io = LPDDR5(...)) for fixed pin assignments
  • Controller components: Use Provide() for flexible pin assignment

Crossover Topology: For SFP/SATA/PCIe IC-to-IC connections:

# TX from source connects to RX on destination
topos.append(src.lane.TX >> dst.lane.RX)
topos.append(dst.lane.TX >> src.lane.RX)

License

See LICENSE file for details.

About

Pythonic test protocol library

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages