Skip to content

Openframe GPIO configurator - #33

Draft
marwaneltoukhy wants to merge 6 commits into
mainfrom
cursor/openframe-configurator-5655
Draft

marwaneltoukhy wants to merge 6 commits into
mainfrom
cursor/openframe-configurator-5655

Conversation

@marwaneltoukhy

@marwaneltoukhy marwaneltoukhy commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Why

  • GPIO setup: Openframe GPIOs were configured by hand-editing CF_gpio_config instances in openframe_project_wrapper.v. cf gpio-config refused openframe projects, and it writes user_defines.v, which is the wrong model for openframe. There was no single source of truth for pad modes, and nothing a web configurator could produce.
  • Power: The wrapper power setup only worked for vccd1, through bridge macros. The new native multi-domain PDN (openframe_user_project PR) needs its power domains to come from the same spec and to be passed to LibreLane as power.json.
  • LibreLane version: The native PDN needs LibreLane 3, so the pin moves from CI2511 (2.4.6) to CI2609 (3.0.14).
  • Harden command line: cf harden passed a single config file, so it could not harden the new wrapper. LibreLane has no config include, and the last file's meta wins, so power.json must come before config.json.
  • Stale generated files: Hardening or prechecking with files that no longer match the spec silently produces the wrong chip, so the CLI now warns.
  • Terminal bug: In a real terminal, cf harden aborted on LibreLane 3 before LibreLane even started. LibreLane 3 writes a cursor-restore escape to stdout on exit, which broke cf-cli's JSON parse of the step list.

What

  • Spec (project.openframe in .cf/project.json, schema_version: 1).
    • Covers 44 pads: mode, signal and bus bit, optional pad overrides, plus unused_mode.
    • Covers power: enabled domains (vccd1, vccd2, vdda1, vdda2) and a per-macro domain mapping.
    • Ships a JSON Schema (chipfoundry_cli/openframe/openframe.schema.json).
    • Semantic validation rejects: duplicate pads, unlisted pads without unused_mode, bus gaps or duplicate bits, mixed directions on one signal, output/bidir pads without a signal, analog pads with a signal, reserved or keyword names, generated-port clashes, macros on a disabled domain, and duplicate JSON/YAML keys.
    • Every error is reported at once, and there are no silent defaults. This follows the repo's no-fallback rule.
  • Generators.
    • verilog/rtl/openframe_gpio.v: one CF_gpio_config per pad with named user ports. A bidir signal x becomes x_in, x_out and x_oeb.
    • openlane/openframe_project_wrapper/power.json: VDD_NETS, GND_NETS and PDN_MACRO_CONNECTIONS, using LibreLane 3 names.
    • Both files carry a spec-sha256 header, so staleness can be detected.
  • Commands.
    • cf openframe validate
    • cf openframe generate [--check], where --check is for CI
    • cf openframe export and cf openframe import [--force], in YAML or JSON, for hand edits and the future web configurator
  • cf gpio-config on openframe. It opens a Textual 44-pad grid (mode, signal/bit and override modal, power modal, validate-on-save) and regenerates the files. The caravel path is unchanged.
  • cf init on openframe. It seeds the spec from the template's .cf/openframe_default.json when the project has none.
  • LibreLane pin. versions.json pins openlane_version: CI2609, which is upstream LibreLane 3.0.14.
  • cf harden config ordering. When openlane/<macro>/power.json exists, it is passed before config.* on both Nix and Docker, matching openlane/Makefile. This lives in a shared helper that cf preview also uses. The banner shows Config: power.json + config.json.
  • Out-of-sync warnings.
    • cf harden openframe_project_wrapper and cf precheck print a warning panel when the generated files don't match the spec.
    • Each file gets a reason: missing, generated from a different spec, edited by hand, or not generated by cf.
    • They also warn when the spec is missing or invalid.
    • The command then continues with the files on disk. Other macros don't warn, because they don't use these files.
  • Step-list probe fix. The probe now tags its JSON line, and cf harden parses only that line. It raises an error if the tag is missing.
  • Housekeeping.
    • New dependencies: pyyaml and jsonschema.
    • Version 2.6.0 → 2.7.1.
    • README sections for the openframe configurator, harden and precheck, plus a new docs/OPENFRAME.md covering configure → generate → harden → precheck.

Testing

  • Test suite: pytest gives 234 passed, 1 skipped. There are 89 new tests:
    • validator rules and schema errors
    • YAML/JSON round trip and duplicate-key rejection
    • a golden generated file for the timer pinout
    • overrides and bidir ports
    • power.json contents
    • CLI: generate --check, import/export/--force, init seeding
    • Textual pilot tests of the grid
    • power.json ordering for nix, docker and preview
    • every staleness reason in harden and precheck
    • the terminal-escape probe case
  • Lint: verilator --lint-only -Wall and iverilog -Wall are clean on generated RTL for the timer spec and a mixed-mode spec (tests skip if the tools are missing). Ruff E/F/I is clean on the new code.
  • Real run: cf harden openframe_project_wrapper --use-docker on the openframe PDN branch ran with LibreLane 3.0.14 and ghcr.io/librelane/librelane:3.0.14.
    • resolved.json shows the power.json nets.
    • The flow finished with Magic DRC 0, KLayout DRC 0, LVS 0, XOR 0, route DRC 0 and power-grid violations 0.

Follow-ups

  • CI2609 tag: it doesn't exist yet in chipfoundry/openlane-2 (see the openlane-2 PR). Until it is created, cf setup --only-openlane and the nix path cannot fetch it.
  • open_pdks pin: versions.json pins open_pdks 3e0e31dc…, which is not published in the ciel releases. LibreLane 3.0.14 pins sky130 8afc8346…, and that revision was used for all verification. Update open_pdks_commits (and mpw_tags if needed) before release.
  • Harden reads versions.json from upstream: cf harden reads it from cf-cli main, so the nix path keeps using CI2511 until this PR is merged.
  • CF_gpio_config v1.2.0: it must be released (GitHub release asset v1.2.0.tar.gz plus an IPM catalog entry) before pad overrides can be installed through IPM. Generated RTL with no overrides also works with v1.1.4.

…n openframe)

- project.openframe spec in .cf/project.json (schema_version 1) with a shipped
  JSON Schema plus semantic validation: duplicate pads, bus bit gaps/duplicates,
  mixed directions, missing signals, reserved/keyword names, port clashes,
  macro domains not enabled. All errors are reported; no silent defaults.
- Generators for verilog/rtl/openframe_gpio.v (CF_gpio_config per pad, named
  user ports, override parameters) and openlane/openframe_project_wrapper/power.json
  (VDD_NETS, GND_NETS, PDN_MACRO_CONNECTIONS).
- cf openframe validate/generate [--check]/export/import (YAML or JSON).
- cf gpio-config opens a Textual 44-pad grid on openframe projects.
- cf init seeds project.openframe from .cf/openframe_default.json when present.
- Adds pyyaml and jsonschema dependencies; bumps version to 2.7.0.
LibreLane 3 writes a cursor-restore escape to stdout on exit when attached to
a TTY, so parsing the whole probe output as JSON failed with 'Extra data' and
cf harden aborted before starting LibreLane. The probe now tags its JSON line
and cf harden parses only that line, raising if it is missing.
…les are out of sync

- When openlane/<macro>/power.json exists, cf harden (Nix and Docker) and the
  shared build_librelane_command pass it before config.* like openlane/Makefile,
  since LibreLane has no include and the last file's meta wins.
- cf harden openframe_project_wrapper and cf precheck print a warning panel when
  project.openframe and the generated files differ, per file: missing,
  generated from a different spec (spec-sha256), edited by hand, or not
  generated by cf; also when the spec is missing or invalid.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants