Files
retroSoC/docs/ip/opipsram.md
T
maksyuki c0f04067b2 docs: add licensing information and attribution comments to various RTL and test files
- Updated multiple RTL files in the  and  directories to include licensing information under the Mulan PSL v2.
- Added attribution comments for contributions from ETH Zurich and University of Bologna in .
- Enhanced test files in the  directory with licensing details and ensured compliance with the Solderpad Hardware License, Version 0.51.
- Introduced a new test in  to verify the preservation of attribution for PULP HyperBus sources.
2026-08-24 10:02:48 +08:00

19 KiB

OPI PSRAM and Single-Clock HyperBus Controller

Status and Scope

This document freezes the version 1 architecture and software-visible contract for the retroSoC octal PSRAM controller. The controller is a prototype until a specific 3.3 V OPI PSRAM and a specific 3.3 V single-clock HyperBus-style device have completed electrical, timing, board, and silicon qualification.

The same controller, digital PHY, and pins support two boot-selected profiles:

  • an octal DDR xSPI transaction profile for OPI PSRAM; and
  • a HyperBus transaction profile modified for one externally routed clock.

Software selects a profile after reset. COMMAND.INIT latches and locks that profile until COMMAND.SOFT_RESET completes. A live protocol switch is not supported.

The controller coexists with the ESP-PSRAM64H controller. Its data and management windows are:

Window Address range Purpose
AXI4 memory 0x48000000 - 0x4FFFFFFF CPU, user core, and central-DMA data access
APB4 management 0x10010000 - 0x10010FFF Configuration, indirect access, status, interrupts, and counters

Version 1 has one chip select, one single-ended clock, eight DDR data pins, and one bidirectional RWDS/DQS pin. The 128 MiB aperture does not imply device capacity. DEVICE_SIZE bounds every mapped access; an out-of-range access returns SLVERR and never wraps to device address zero.

Evidence and Compatibility Boundary

The digital PHY is adapted from PULP Platform HyperBus v0.0.4 at commit 80de8df600edc5d7956a94c9d42f911d6e61efd7, as locked by the Basilisk integration. The following files retain their corresponding upstream Solderpad Hardware License 0.51 (SHL-0.51) copyright and author notices:

retroSoC file PULP HyperBus source
rtl/ip/memory/opipsram_phy.sv src/hyperbus_phy.sv
rtl/ip/memory/opipsram_trx.sv src/hyperbus_trx.sv
rtl/tech/tc_opipsram_delay.sv src/hyperbus_delay.sv

retroSoC modifications adapt the PHY to OPI/xSPI, one routed clock for the HyperBus profile, the project's Common primitives and interfaces, reset conventions, and technology-specific delay mapping. The upstream SHL-0.51 text is preserved in ../../licenses/PULP_Platform-SHL-0.51; the retroSoC modifications retain their Mulan PSL v2 declaration in each file.

The following upstream concepts are reused:

  • separate system and PHY clock domains;
  • transaction and response handshakes plus asynchronous payload FIFOs;
  • a shared DDR DQ/RWDS transceiver below a protocol-specific transaction FSM;
  • a programmable delay on RWDS before receive sampling; and
  • a PHY input clock at twice the external memory clock.

The HyperBus command/address encoder is not reusable for OPI. OPI uses command/address/dummy/data phases; HyperBus uses a 48-bit CA phase, RWDS additional-latency indication, and protocol-specific turnaround. The two engines therefore share the transceiver but not protocol state. The upstream IP exposes an AXI slave and Regbus configuration port but no controller-owned DMA engine or interrupt output; those are SoC integration features in retroSoC.

Upstream references:

The PULP sources are provenance references, not a build-time checkout or a restricted vendor-model dependency. The retained source notices and the repository NOTICE cover the adapted PHY files; unrelated controller, protocol, register, interface, HAL, model, and SoC integration code remains retroSoC owned.

Commercial Reference Selection

The following public commercial-SoC implementations were evaluated in order of relevance. They are architecture references, not evidence that one device simultaneously provides a 3.3 V OPI memory interface and a 3.3 V, single-clock HyperBus interface.

Rank Reference Problem solved and architecture Reuse in retroSoC Boundary to avoid
1 STM32H7B3 OCTOSPI Memory-mapped and indirect HyperRAM access with DQS, fixed latency, DMA reachability, and explicit cache-maintenance constraints Separate mapped/indirect paths, latency configuration, error reporting, and cache policy The MCU or board supply does not prove that the memory protocol, device, or pads meet this project's 3.3 V and single-clock requirements
2 NXP i.MX RT1180 FlexSPI2 A programmable LUT feeds both an AHB memory window and IP commands; examples exercise HyperRAM and the surrounding DMA ecosystem Bounded transaction profiles, software-reset boundaries, and mapped/IP-command layering FlexSPI capability and electrical support vary by part and board; an unrestricted waveform LUT would also make verification impractical
3 ESP32-S3 MSPI Octal DTR PSRAM startup, identification, command/address geometry, and phase calibration Low-speed discovery, versioned device profiles, and calibration flow Its OPI engine is not a HyperBus CA/RWDS engine, and high-frequency SDK settings are not reusable signoff evidence
4 Renesas RA8P1 OSPI-B/XSPI An 8D-8D-8D OPI HyperRAM profile with fixed latency and direct memory access Explicit command-set profiles and separation of direct and register access The product name “HyperRAM” does not imply conventional HyperBus CA encoding; opcodes and dummy cycles remain device-specific
5 ESP32-P4 MSPI A high-bandwidth, separately routed external-memory path with optional ECC and execute-in-place integration Future ECC, bandwidth, and cache-roadmap reference Its wider AP-memory path is not a standard octal OPI or HyperBus compatibility reference

These vendor SDK families remain maintained and useful as integration references. The most reusable common pattern is a restricted, versioned transaction profile behind separate mapped and indirect front ends, followed by startup identification and timing calibration. The design deliberately avoids an arbitrary waveform-programming interface, undocumented cache coherency, runtime protocol switching, and frequency claims derived only from another SoC's software configuration.

Public reference evidence:

Clock, Reset, and CDC Contract

clk_i and rst_n_i own AXI4, APB4, interrupts, and software-visible state. clk_phy_i and rst_phy_n_i own transaction serialization and receive sampling. Common handshakes and asynchronous FIFOs carry commands, payload, responses, and warm-flush state across the boundary.

The PHY divides clk_phy_i by two to produce external ck_o. The Mini SoC version 1 integration connects the PHY and system clocks together. With the committed 72 MHz system clock this produces a 36 MHz external clock. A later integration may provide a qualified 144-200 MHz PHY clock to produce a 72-100 MHz external clock without changing the IP interface.

Reset holds ck_o low, cs_n_o high, DQ and RWDS output enables low, and the memory window unavailable. Reset assertion is asynchronous at each domain; release is synchronized by the owning SoC reset tree. A warm reset flushes both directions of every CDC queue before accepting another initialization.

The GPIO21-31 Mini SoC binding does not route a dedicated device reset pin. Boards must provide the device-defined reset state, such as an external pull-up or an approved command reset sequence. A device that requires a separately driven reset or complementary clock is not compatible with that pin binding.

AXI4 Contract

The slave has 32-bit data, one-bit ID, and one-bit USER fields. Version 1 accepts one mapped transaction at a time and supports:

  • aligned 1-, 2-, and 4-byte beats;
  • INCR bursts of at most 16 beats;
  • byte write strobes, including sparse strobes;
  • read and write backpressure; and
  • complete response termination after protocol, timeout, availability, or bounds errors.

Unsupported burst types, unaligned beats, 4 KiB crossings, aperture crossings, device-size crossings, exclusive accesses, and accesses while the memory window is unavailable return SLVERR. An invalid write drains all promised W beats before its B response. An invalid read returns the promised number of R beats with the final RLAST.

Mapped and indirect commands arbitrate at command boundaries. An indirect operation prevents new AXI addresses but never interrupts an accepted AXI transaction. A 32-byte, four-entry read-line buffer may accelerate legal linear reads. A mapped or indirect write invalidates a matching entry; initialization, abort, soft reset, profile changes, and errors invalidate all entries.

The existing central AXI4 DMA accesses this window as ordinary memory. The controller has no private DMA engine and adds no dma_req_if request source.

Protocol Profiles

OPI/xSPI Profile

Version 1 provides a constrained 8D-8D-8D template:

  • 8- or 16-bit command;
  • 24- or 32-bit address;
  • programmable read, write, register-read, and register-write commands;
  • programmable fixed latency/dummy cycles;
  • optional DQS output for writes and required DQS/RWDS input for reads; and
  • programmable linear burst boundary.

The controller does not expose arbitrary edge-by-edge waveform programming. Configuration validation rejects command geometry that the transaction engine cannot execute. A profile is evidence for a specific device only after its data sheet, ID/register sequence, model, and board test are recorded.

Single-Clock HyperBus Profile

Version 1 implements the HyperBus CA, memory/register address spaces, fixed or RWDS-requested additional latency, read/write recovery, and linear burst turnaround while routing only ck_o. It does not route the complementary CK# used by conventional HyperBus devices. This is a documented device-profile extension, not a blanket claim of standard HyperBus interoperability.

The software and AXI interfaces use byte addresses. Before forming CA, the controller converts a HyperBus byte address to the device's 16-bit word address. Odd-address memory accesses share CA with the preceding even byte and use RWDS to mask the leading byte; odd transfer lengths similarly mask the trailing byte. HyperBus register-space writes do not drive RWDS and therefore require an even address and even length.

Digital PHY and Technology Delay

The transmit path uses the two-times PHY clock to create the external clock and DDR data phases without an analog phase shifter. The receive path delays RWDS/DQS before using it to sample DQ. Software may update a delay tap only while CS# is inactive, the receive clock gate is disabled, and the CDC payload queues are empty.

ICS55 has DLY1X2H7R and DLY4X2H7R cells. Its implementation uses a fine/coarse tapped chain and a balanced mux tree protected from optimization. The 3-bit coarse selector covers eight taps with seven DLY4X2H7R stages; the 5-bit fine selector covers 32 taps with 31 DLY1X2H7R stages. The synthesized ICS55 netlist retains all 38 delay cells, the seven coarse muxes, and the 31 fine muxes. The smoke STA loads this netlist and the locked slow-corner libraries, but it does not constrain or report the delayed-RWDS capture path. Tap monotonicity, useful range, source-synchronous constraints, placement, PVT, and pad timing therefore remain physical-signoff work.

The current IHP130, GF180, and SKY130 integrations do not define a qualified programmable delay cell for this IP. They may run protocol, RTL, synthesis, and netlist-connectivity tests, but they are not source-synchronous PHY signoff. Behavioral simulation delay is not ASIC timing evidence.

Register ABI

Registers are 32-bit and naturally aligned. Unmapped, unaligned, directionally-invalid, or forbidden busy-time accesses return APB4 pslverr. Configuration registers accept byte strobes. Action and RW1C registers require the low byte strobe.

Offset Name Access Reset Description
0x000 IP_ID RO 0x4F504938 ASCII-compatible OPI8 identifier
0x004 IP_VERSION RO 0x00010000 ABI version 1.0
0x008 CAPABILITY RO implementation Geometry and feature bits
0x00C CTRL RW 0 enable [0], memory enable [1], auto-init [2], line buffer [3]
0x010 COMMAND WO 0 init [0], abort [1], soft reset [2], train [3]
0x014 STATUS RO 0 busy/initialized/ready/quiesced/trained/error
0x018 PROTOCOL_CFG RW 0 OPI 0, single-clock HyperBus 1; locked after init
0x01C DEVICE_SIZE RW 0x00800000 Valid bytes, power of two, maximum 128 MiB
0x020 OPI_READ_CMD RW 0x0000EE11 Read command and width
0x024 OPI_WRITE_CMD RW 0x000012ED Write command and width
0x028 OPI_REG_READ_CMD RW 0 Register-read command
0x02C OPI_REG_WRITE_CMD RW 0 Register-write command
0x030 OPI_TIMING RW implementation Address bytes, dummy cycles, DQS policy, burst boundary
0x034 HYPER_TIMING RW implementation Initial/additional latency and recovery cycles
0x038 CLK_CONFIG RW 0 Divider mode and effective PHY ratio
0x03C CS_TIMING RW implementation CS setup, hold, and high cycles
0x040 POWERUP_CYCLES RW implementation Minimum wait before initialization
0x044 TIMEOUT_CYCLES RW implementation Transaction watchdog
0x048 RX_DELAY RW 0 Fine [4:0], coarse [7:5]; idle-only
0x04C PROFILE_STATUS RO implementation Latched profile and validation result
0x050 INDIRECT_CTRL RW/action 0 Direction, register space, length, start
0x054 INDIRECT_ADDR RW 0 Device-local byte address
0x058 INDIRECT_WDATA_LO RW 0 Write payload [31:0]
0x05C INDIRECT_WDATA_HI RW 0 Write payload [63:32]
0x060 INDIRECT_RDATA_LO RO 0 Read payload [31:0]
0x064 INDIRECT_RDATA_HI RO 0 Read payload [63:32]
0x068 LAST_ERROR RO 0 Error class and protocol phase
0x06C LAST_ERROR_ADDR RO 0 First failing mapped or local address
0x070 TRAIN_STATUS RO 0 Busy, valid, selected tap, and window width
0x074 TRAIN_WINDOW RO 0 First and last passing taps
0x080 INTR_STATE RW1C 0 Sticky interrupt state
0x084 INTR_ENABLE RW 0 Interrupt mask
0x088 INTR_STATUS RO 0 INTR_STATE & INTR_ENABLE
0x08C INTR_TEST WO 0 Set interrupt state bits
0x090 PERF_CTRL RW/action 0 enable, freeze, and clear
0x094 PERF_READ_BYTES RO 0 Saturating mapped-read byte count
0x098 PERF_WRITE_BYTES RO 0 Saturating mapped-write byte count
0x09C PERF_COMMANDS RO 0 Saturating physical-command count
0x0A0 PERF_CACHE_HITS RO 0 Saturating read-line hit count
0x0A4 PERF_STALL_CYCLES RO 0 Saturating AXI stall count
0x0A8 PERF_ERROR_COUNT RO 0 Saturating error count

Interrupt bits are init done [0], indirect done [1], training done [2], error [3], and timeout [4]. New events win over a same-cycle RW1C clear.

Error classes are none 0, illegal transaction 1, unavailable 2, timeout 3, profile 4, aborted 5, PHY 6, protocol 7, bounds 8, and training 9.

MVP and Deferred Features

Version 1 includes one device, one accepted transaction, 16-beat bursts, indirect access, manual delay programming, software-assisted training, interrupts, counters, a read-line buffer, and central-DMA access.

Deferred features include multiple chip selects, multiple AXI outstanding transactions, write combining, coherent cache, ECC/scrub, inline encryption, runtime protocol switching, online PVT tracking, low-power retention, and execute/boot from this window.

Verification and Signoff

The delivery requires:

  • self-owned OPI and HyperBus protocol models with no restricted vendor model;
  • APB4 ABI/access, AXI4 burst/error-drain/backpressure, protocol, reset, abort, timeout, delay-window, interrupt, counter, and DMA tests;
  • formal checks for AXI termination, FIFO bounds, CDC handshakes, configuration locking, legal FSM recovery, and sticky interrupts;
  • RTL formatting/style/readiness, host C tests, Pytest, firmware, IHP130 regression, and ICS55 synthesis/STA/netlist evidence; and
  • warning and metric review without hand-editing baselines.

The local IHP130 regression may use --netsim-boot-only; it terminates the long Icarus netlist simulation only after Hello retroSoC! and continues the remaining STA, warning, and metric steps.

The 2026-08-19 delivery candidate completed the IHP130 and ICS55 PR regressions, including firmware, Verilator and Icarus RTL simulation, Yosys synthesis, Icarus netlist boot, and OpenSTA smoke analysis. Both netlist runs observed Hello retroSoC! and terminated through the configured success-marker path. The ICS55 netlist inspection confirmed the delay and mux counts above. Final prove, BMC, and cover runs passed, and self-owned OPI RTL has no new Verilator lint signatures. The final post-cleanup IHP130 rerun skipped netsim by operator request; its firmware, RTL simulations, synthesis, STA, warning, and metric stages completed, while the earlier IHP130 netlist result remains the recorded boot evidence.

Metrics remain in observe mode. The smoke STA reports contain global SoC timing violations and are not timing closure. Warning review also remains open: the regression records increased Yosys aggregate signatures without modifying the approved baselines. These observations do not invalidate protocol or netlist-connectivity results, but they prevent a claim of physical signoff.

Controller RTL, I/O pads and voltage domains, single-ended clock output, RWDS/DQS delay calibration, CDC constraints, refresh assumptions, board-level signal integrity, cache consistency, DMA reachability, timeout/error handling, and PVT evidence are separate acceptance items. Protocol simulation cannot substitute for any of those physical or system-level signoff items.