Skip to content

Conversation

@robtaylor
Copy link
Contributor

This adds the ability to easily add SystemVerilog modules, with a simple JSON file for interface metadata.

It also has initial support for SpinalHDL

robtaylor and others added 18 commits January 13, 2026 16:13
Transforms the experimental _svtest.py into a complete VerilogWrapper
system that creates Amaranth wiring.Component classes from TOML
configuration files.

Features:
- Automatic Signature generation from TOML port/pin definitions
- SpinalHDL code generation support
- Clock and reset signal mapping
- Port interface mapping (Wishbone, simple signals, etc.)
- Verilog file loading for platform.add_file()

Also adds:
- Unit tests for the wrapper system
- Package exports for VerilogWrapper and load_wrapper_from_toml
- pydantic and tomli as new dependencies
Extends the Verilog wrapper system to support SystemVerilog files:

- Add GenerateSV2V class for SystemVerilog to Verilog conversion via sv2v
- Add SYSTEMVERILOG generator type for TOML configs
- Support .sv file extensions in source collection
- Add include_dirs, defines, and top_module options for sv2v

Also includes a sample wb_timer IP:
- Simple 32-bit Wishbone B4 timer/counter in SystemVerilog
- Features: prescaler, compare match, interrupt generation
- TOML config and C driver header included

This enables wrapping external SystemVerilog IPs (like OpenTitan) in
Amaranth designs by converting them to Verilog at build time.
Enhances the Verilog wrapper system with proper ChipFlow integration:

- Add DriverConfig for SoftwareDriverSignature support (regs_struct, c_files, h_files)
- Add explicit 'direction' field to Port config ('in' or 'out')
- Ports default to direction='in', pins default to direction='out'
- Use SoftwareDriverSignature when driver config is provided

This enables wrapped Verilog modules to work with ChipFlow's driver
generation system, matching the pattern used by native peripherals
like GPIOPeripheral and I2CPeripheral.

Also updates wb_timer example:
- Moves irq to pins section (as it goes to IO pads)
- Adds proper driver config with regs_struct
- Creates separate C header file in drivers/ directory
Adds automatic port mapping generation for known interface types,
reducing TOML verbosity and ensuring consistent signal naming.

- Add interface registry for Wishbone, CSR, GPIO, UART, I2C, SPI, QSPI
- Port.map is now optional - uses auto-generation when not provided
- Add Port.prefix field for customizing auto-generated signal names
- Infer prefix from port name and interface type when not specified
- Update wb_timer example to use auto-mapping instead of explicit map
- Add comprehensive tests for auto-mapping functionality
Instead of generating expected signal names from a prefix, auto-mapping
now parses the actual Verilog module ports and matches patterns to
identify interface signals. This adapts to any naming convention.

- Add _parse_verilog_ports() to extract port names from Verilog
- Add _infer_auto_map() to match patterns against actual ports
- Pattern-based matching for Wishbone, CSR, UART, I2C, SPI, GPIO
- Falls back to prefix-based generation if Verilog not available
- Update wb_timer to use inference (no prefix needed for bus)
- Update tests with Verilog parsing and inference tests
Adds comprehensive tests for the wb_timer SystemVerilog IP:
- Configuration tests verify TOML parsing works correctly
- Wrapper tests check signature creation (requires sv2v)
- Simulation tests verify timer functionality via Wishbone bus:
  - Timer enable and counting
  - Compare match and IRQ generation
  - Prescaler divides count rate

Tests use @skipUnless decorator to gracefully skip when sv2v
is not installed, allowing config tests to pass regardless.
Add GenerateYosysSlang as an alternative to sv2v for converting SystemVerilog
to Verilog. This allows using yowasp-yosys (pure Python) for a portable
solution without native tool dependencies.

- Add GenerateYosysSlang class with yosys-slang plugin support
- Add YOSYS_SLANG to Generators enum
- Update wb_timer.toml to use yosys_slang generator
- Update test_wb_timer.py with _has_yosys_slang() check
yowasp-yosys statically links yosys-slang, so read_slang is available
without -m slang. Update GenerateYosysSlang._find_yosys() to return
both the command and whether slang is built-in, then conditionally
add -m slang only for native yosys.
yowasp-yosys includes yosys-slang built-in, enabling SystemVerilog
parsing without native tool dependencies. This allows the YOSYS_SLANG
generator to work in CI and any Python environment.
- Resolve source_path relative to TOML file directory, not CWD
- Use local build/ directory for test output (yowasp-yosys WASM can't
  access /tmp)
- Fix type hint: remove unsupported In | Out union
- Fix submodule check: use hasattr() instead of dict()
- Fix auto-map direction flipping: only flip for bus interfaces
  (Wishbone, CSR), not pin interfaces (UART, I2C, SPI, GPIO)
- Update requires-python to >=3.12 (required by chipflow-lib)
PDM's partial clone (--filter=blob:none) doesn't fetch all refs, causing
git rev-parse to fail when resolving branch names. Using the commit hash
directly works around this issue.

Co-developed-by: Claude Code v2.1.6 (claude-opus-4-5-20251101)
Required for amaranth_types imports used in _rfc_uart.py.

Co-developed-by: Claude Code v2.1.6 (claude-opus-4-5-20251101)
- Add _validate_signal_bindings() to check that configured clock/reset
  signals exist in the Verilog module and warn about unmapped ports
- Fix _parse_verilog_ports() to correctly parse non-ANSI style Verilog
  by starting at module_match.end() instead of searching for next semicolon
- Skip wb_timer simulation tests since Amaranth's Python simulator cannot
  execute Instance() black boxes (would require CXXRTL or co-simulation)

Co-developed-by: Claude Code v2.1.6 (claude-opus-4-5-20251101)
- Move logger initialization after imports in _verilog_wrapper.py (E402)
- Remove unused _INTERFACE_REGISTRY import from test_verilog_wrapper.py (F401)
- Replace try/import with importlib.util.find_spec for yowasp_yosys check (F401)
- Remove unused tempfile import from test_wb_timer.py (F401)

Co-developed-by: Claude Code v2.1.7 (claude-opus-4-5-20251101)
…line

Document the simulation architecture options for ChipFlow ecosystem:
- Comparison of CXXRTL vs Verilator debug APIs
- Proposed multi-HDL architecture using Yosys frontends
- yosys-slang -> CXXRTL pipeline validation results (tested with wb_timer)
- Hybrid approach for risk mitigation

The pipeline was validated end-to-end: SystemVerilog -> slang -> RTLIL ->
CXXRTL -> compiled C++ simulation with all timer functionality working.

Co-developed-by: Claude Code v2.1.7 (claude-opus-4-5-20251101)
- Remove trailing whitespace in _glasgow_i2c.py and _glasgow_iostream.py
- Remove unused imports HasElaborate, ValueLike from _rfc_uart.py

Co-developed-by: Claude Code v2.1.7 (claude-opus-4-5-20251101)
The document has been migrated to Google Docs for easier
collaboration and editing. Document ID: 1U8Mbxl3SbeBwcji1BisLeFc12y6kESUKeTduxjh3tJY

Co-developed-by: Claude Code v2.1.7 (claude-opus-4-5-20251101)
Add build_simulator() method to VerilogWrapper that compiles
Verilog/SystemVerilog sources into a CXXRTL shared library and
returns a CxxrtlSimulator instance for fast compiled simulation.

Also adds helper methods:
- get_source_files(): Returns list of Verilog source files
- get_top_module(): Returns the top module name
- get_signal_map(): Returns Amaranth→Verilog signal mappings

Updates test_wb_timer.py to use CXXRTL simulation instead of
skipping the simulation tests (Amaranth's Python sim can't
execute Instance() black boxes).

Co-developed-by: Claude Code v2.1.9 (claude-opus-4-5-20250929)
Add comprehensive example demonstrating the complete workflow for
simulating SystemVerilog IP using VerilogWrapper and CXXRTL:

- README.md: Step-by-step guide covering TOML configuration,
  register map, signal naming, and usage patterns
- simulate_timer.py: Runnable example showing reset, register
  access, timer counting, and IRQ generation

Co-developed-by: Claude Code v2.1.9 (claude-opus-4-5-20250929)
Comprehensive documentation for VerilogWrapper including:
- TOML configuration reference with all sections explained
- Auto-mapping patterns for common bus interfaces
- CXXRTL simulation usage with signal naming guide
- SpinalHDL integration example
- API reference linking to docstrings

Co-developed-by: Claude Code v2.1.9 (claude-opus-4-5-20250929)
Co-developed-by: Claude Code v2.1.12 (claude-opus-4-5-20250929)
Add a complete example demonstrating VerilogWrapper integration into a
ChipFlow SoC, similar to chipflow-examples/minimal. Includes:

- SoC design with Minerva CPU, Flash, SRAM, GPIO, UART, and SV timer
- ULX3S FPGA board step
- Firmware demonstrating timer usage
- CXXRTL simulation test for the timer peripheral
- Comprehensive README documentation

The example shows how to:
- Load SystemVerilog components via TOML configuration
- Connect wrapped modules to Wishbone bus
- Build and run CXXRTL simulations
- Write software drivers for wrapped peripherals

Co-developed-by: Claude Code v2.1.12 (claude-opus-4-5-20251101)
- Remove unused Sky130DriveMode import
- Remove extraneous f-string prefix

Co-developed-by: Claude Code v2.1.12 (claude-opus-4-5-20251101)
Update sv_soc example to import wb_timer from chipflow_digital_ip.io.sv_timer
instead of maintaining a local copy. This demonstrates the intended usage
pattern where components are imported from the package.

Changes:
- Remove local rtl/ directory with wb_timer copy
- Update design.py to use package path
- Update test_timer_sim.py to use package path
- Inline timer register definitions in main.c
- Update README to reflect new structure

Co-developed-by: Claude Code v2.1.12 (claude-opus-4-5-20251101)
- Add MemoryMap to Wishbone interfaces in VerilogWrapper for decoder compatibility
- Resolve driver h_files and c_files paths relative to TOML file location
- Move timer from CSR region (0xB3000000) to Wishbone region (0xA0000000)
- Update main.c to use generated soc.h definitions instead of local definitions
- Fix GPIO member name from 'out' to 'output'

These fixes enable `chipflow software` and `chipflow sim` to work with
the sv_soc example that uses VerilogWrapper to integrate SystemVerilog
peripherals.

Co-developed-by: Claude Code v2.1.12 (claude-opus-4-5-20251101)
The RTL wrapper infrastructure is now in chipflow-lib as chipflow.rtl.
This is core infrastructure for integrating external RTL modules, not
an IP block itself.

Changes:
- Remove _verilog_wrapper.py from chipflow_digital_ip.io
- Update all imports to use chipflow.rtl
- Keep wb_timer and sv_timer IP in this repo

Co-developed-by: Claude Code v2.1.12 (claude-opus-4-5-20251101)
Co-developed-by: Claude Code v2.1.12 (claude-opus-4-5-20251101)
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.

3 participants