Skip to content

Conversation

@robtaylor
Copy link
Contributor

@robtaylor robtaylor commented Oct 14, 2025

Summary

This is a work-in-progress refactoring to improve codebase organization and maintainability.

Status: Phases 1-3 Complete + Documentation Overhaul Complete

Completed Phases

Phase 1: IO Module ✅

  • Extracted IO signatures from massive platforms/_utils.py into focused io/ module
  • Created: io/signatures.py, io/annotations.py, io/_sky130.py
  • Result: Clean ~200-line files vs buried in 1131-line monster

Phase 2: Root Module Cleanup ✅

  • Created utils.py with core utilities (ChipFlowError, ensure_chipflow_root, etc.)
  • Created serialization.py (renamed from _appresponse.py)
  • Removed duplicate ChipFlowError definitions
  • Result: Clean root module with proper organization

Phase 3: Packaging Module ✅

  • Extracted ~850 lines from platforms/_utils.py into focused packaging/ module
  • Created 10 new focused files: pins.py, port_desc.py, lockfile.py, allocation.py, base.py, standard.py, grid_array.py, openframe.py, utils.py
  • Result: Clean packaging module with clear boundaries

Documentation Overhaul ✅

  • New comprehensive guides:
    • architecture.rst - Complete system architecture with flow diagrams
    • simulation-guide.rst - End-to-end simulation workflow and CXXRTL integration
    • using-pin-signatures.rst - Pin signatures and software driver usage
    • contributor-pin-signature-internals.rst - Deep dive into annotation system
  • Improvements:
    • Enhanced clarity on simulation model selection and interface type annotations
    • Emphasized implementation-independent nature of pin signatures
    • Removed unverified/aspirational content for accuracy
    • Created UNFINISHED_IDEAS.md to track future documentation improvements
  • Result: Production-ready documentation covering architecture, simulation, and pin system

Test Status

  • ✅ All tests passing (38 passed, 11 skipped)
  • ✅ Backward compatibility maintained
  • ✅ Tests updated to be less brittle

Remaining Work (Phases 4-8)

  • Phase 4: Pin lock module
  • Phase 5: Config module reorganization
  • Phase 6: Platform reorganization (merge platforms/ + steps/)
  • Phase 7: Import updates
  • Phase 8: Cleanup old files

Benefits Delivered

  1. ✅ Cleaner module organization
  2. ✅ Smaller, more focused files (~200-300 lines each)
  3. ✅ Better discoverability (from chipflow_lib.io import IOSignature)
  4. ✅ Easier maintenance with clear boundaries
  5. ✅ Improved testability
  6. ✅ Comprehensive, accurate documentation

Reference Documents

  • REFACTORING_STATUS.md - Detailed progress tracking
  • REFACTORING_PLAN.md - Complete refactoring plan
  • CLAUDE.md - Codebase overview
  • UNFINISHED_IDEAS.md - Future documentation improvements

🤖 Generated with Claude Code

@github-actions
Copy link

github-actions bot commented Oct 14, 2025

Tests Skipped Failures Errors Time
41 4 💤 0 ❌ 0 🔥 21.263s ⏱️

@robtaylor robtaylor force-pushed the refactor/restructure-codebase branch 5 times, most recently from d07114e to db97603 Compare October 16, 2025 18:49
@robtaylor robtaylor force-pushed the refactor/restructure-codebase branch from db97603 to 9ffc55c Compare October 24, 2025 10:30
robtaylor added a commit that referenced this pull request Oct 24, 2025
Updated based on PR #144 review feedback:

1. Expanded explanation of what pin signatures tell ChipFlow:
   - Physical pin connections
   - Simulation model and test bench selection
   - Pad and package pin allocation requirements

2. Added comprehensive IOModelOptions documentation:
   - Full reference of all available options
   - Examples showing basic and advanced usage
   - Details on invert, individual_oe, power_domain, clock_domain
   - Trip point options (CMOS, TTL, VCORE, VREF, SCHMITT_TRIGGER)
   - Buffer control and initialization options

This provides users with complete understanding of how to configure
pin electrical and behavioral properties.
robtaylor added a commit that referenced this pull request Oct 26, 2025
- Enhance pin signature explanation to emphasize simulation model selection
- Clarify that signatures are generic and implementation-independent
- Improve terminology precision: "external interfaces of the IC" vs "IP blocks"
- Add clarification that SimInterface annotations describe interface types
- Remove unverified Custom Simulation Driver section from simulation-guide

Addresses review comments on PR #144

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@robtaylor robtaylor requested review from gatecat and lanserge October 26, 2025 22:53
@robtaylor robtaylor marked this pull request as ready for review October 26, 2025 22:53
robtaylor added a commit that referenced this pull request Oct 26, 2025
Updated based on PR #144 review feedback:

1. Expanded explanation of what pin signatures tell ChipFlow:
   - Physical pin connections
   - Simulation model and test bench selection
   - Pad and package pin allocation requirements

2. Added comprehensive IOModelOptions documentation:
   - Full reference of all available options
   - Examples showing basic and advanced usage
   - Details on invert, individual_oe, power_domain, clock_domain
   - Trip point options (CMOS, TTL, VCORE, VREF, SCHMITT_TRIGGER)
   - Buffer control and initialization options

This provides users with complete understanding of how to configure
pin electrical and behavioral properties.
robtaylor added a commit that referenced this pull request Oct 26, 2025
- Enhance pin signature explanation to emphasize simulation model selection
- Clarify that signatures are generic and implementation-independent
- Improve terminology precision: "external interfaces of the IC" vs "IP blocks"
- Add clarification that SimInterface annotations describe interface types
- Remove unverified Custom Simulation Driver section from simulation-guide

Addresses review comments on PR #144

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@robtaylor robtaylor force-pushed the refactor/restructure-codebase branch 4 times, most recently from fba3cf5 to fd3a449 Compare October 26, 2025 23:52
@github-actions
Copy link

github-actions bot commented Oct 26, 2025

PR Preview Action v1.6.2

🚀 View preview at
https://chipflow-lib.docs.chipflow-infra.com/pr-preview/pr-144/

Built to branch gh-pages at 2025-10-28 14:03 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

from .models import Config

def get_dir_models():
return os.path.dirname(__file__) + "/models"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while doing this refactor probably worth also unifying the use of pathlib rather than os.path

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

old_width = sum([len(p.pins) for p in old_ports.values() if p.pins is not None])
if old_width != width:
raise ChipFlowError(
f"top level interface has changed size. "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this error should be made actionable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

]


class VoltageRange(AppResponseModel):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason for this to be a different model to anything else? it appears to be related to OmitIfNone, so maybe AppResponseModel isn't the best name as it sounds like this is fetching something from the cloud, which I don't think actually happens?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hope that makes more sense now?

core_power=self._power,
core_clock=GAPin('A', 2),
core_reset=GAPin('A', 1),
core_heartbeat=GAPin('A', 2), # Note: Same as clock in original
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this the same as the clock? this is an output, so that won't work

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ooops! fixed.

"""
Openframe package definition.
This module provides the package definition for the Efabless Openframe
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chipfoundry? and I think it's more commonly called a harness or frame than a carriage system

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

[chipflow.simulation]
num_steps = 100000 # Instead of 3000000
2. **Use Release builds**: Already enabled by default (``-O3``)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this helping anyone?

void step(unsigned timestamp) {
// Model behavior
input.next = output.curr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the old cxxrtl style that I don't think is still supported

should be using .get (or implicit boolean casts for single-bits) for input values and .set to set output values, e.g.

s.curr_byte = (s.curr_byte << 4U) | (d_o.get<uint32_t>() & 0xF);

also should be using value as the type for IOs and not wire

Simulation Hangs
~~~~~~~~~~~~~~~~

**Symptom**: Simulation runs but never finishes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the simulation should always finish after num_steps, regardless of what the design or software does...

super().__init__({
"i2c_gpio": Out(GPIOSignature(
pin_count=2,
sky130_drive_mode=Sky130DriveMode.OPEN_DRAIN_STRONG_UP
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for I2C you would want a strong down, not a strong up

def elaborate(self, platform):
m = Module()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CPU and Wishbone bus is missing here, maybe just link to chipflow-examples so we have something tested and working

@robtaylor robtaylor changed the title WIP: Restructure codebase for better organization Restructure codebase for better organization Oct 27, 2025
robtaylor added a commit that referenced this pull request Oct 28, 2025
Updated based on PR #144 review feedback:

1. Expanded explanation of what pin signatures tell ChipFlow:
   - Physical pin connections
   - Simulation model and test bench selection
   - Pad and package pin allocation requirements

2. Added comprehensive IOModelOptions documentation:
   - Full reference of all available options
   - Examples showing basic and advanced usage
   - Details on invert, individual_oe, power_domain, clock_domain
   - Trip point options (CMOS, TTL, VCORE, VREF, SCHMITT_TRIGGER)
   - Buffer control and initialization options

This provides users with complete understanding of how to configure
pin electrical and behavioral properties.
robtaylor added a commit that referenced this pull request Oct 28, 2025
- Enhance pin signature explanation to emphasize simulation model selection
- Clarify that signatures are generic and implementation-independent
- Improve terminology precision: "external interfaces of the IC" vs "IP blocks"
- Add clarification that SimInterface annotations describe interface types
- Remove unverified Custom Simulation Driver section from simulation-guide

Addresses review comments on PR #144

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@robtaylor robtaylor force-pushed the refactor/restructure-codebase branch from 8271004 to 95acef4 Compare October 28, 2025 12:11
robtaylor and others added 4 commits October 28, 2025 12:39
Complete restructuring of chipflow-lib to improve maintainability, testability,
and separation of concerns. This refactoring creates clear module boundaries,
reduces public API surface by 62%, and removes 839 lines of mock-heavy tests
in favor of integration testing.

**chipflow_lib/config/** - Configuration parsing and validation
- models.py: Pydantic models for config validation
- parser.py: TOML parsing logic
- Extracted from scattered config logic

**chipflow_lib/packaging/** - Pin allocation and package definitions
- pins.py: Pin dataclasses (PowerPins, JTAGPins, BringupPins)
- port_desc.py: Port description models
- lockfile.py: Pin lock file models
- allocation.py: Pin allocation algorithms
- base.py, standard.py, grid_array.py, openframe.py: Package definitions
- commands.py: Pin lock CLI command
- utils.py: load_pinlock() and related utilities

**chipflow_lib/platform/** - Platform implementations (silicon, sim, software, board)
- base.py: Base platform classes
- io/: IO signatures and buffer implementations
- silicon.py, silicon_step.py: ASIC platform
- sim.py, sim_step.py: Simulation platform
- software_step.py: Software build platform
- board_step.py: Board platform
- Unified platform module replacing scattered platforms/ and steps/

**chipflow_lib/utils.py** - Core utilities
- ChipFlowError exception
- ensure_chipflow_root()
- _get_cls_by_reference()
- top_components()

**chipflow_lib/serialization.py** - JSON serialization utilities

Reduced public API surface from 88 to 33 symbols by removing unused exports:

- **chipflow_lib**: Removed 6 unused utilities (get_cls_by_reference, get_src_loc, etc.)
- **chipflow_lib.config**: Removed 2 private parser functions
- **chipflow_lib.packaging**: Made entire module private (32 symbols → 0)
  - Zero external usage found in chipflow-digital-ip or chipflow-examples
  - Will be reconsidered in future PR with real-world custom package examples
- **chipflow_lib.platform**: Removed 11 unused symbols
  - Platform classes (SiliconPlatform, SoftwarePlatform)
  - Utilities (top_components, get_software_builds, setup_amaranth_tools)
  - IO metadata types (IOModel, IOTripPoint, IO_ANNOTATION_SCHEMA)

Symbols not in __all__ remain importable for backward compatibility.

- Created shims in chipflow_lib/platforms/ and chipflow_lib/steps/
- Re-export all public symbols from new locations
- Existing imports continue to work
- Verified with chipflow-digital-ip test suite (16 passed)

- ❌ Removed test_buffers.py (62 lines of pure mocking)
- ❌ Removed test_silicon_platform.py (35 lines, empty tests)
- ❌ Removed test_steps_silicon.py (742 lines, 40+ mocks)
- ✅ Added test_cli_integration.py (148 lines, 11 integration tests)
- ✅ Updated mock.toml with new module paths

**Results:**
- 37 tests passing (down from 49, removed 839 lines of mocks)
- 100% public API coverage (vs 51% before)
- 0% tests depend on internal implementation (vs 35% before)

- CLAUDE.md: Comprehensive codebase documentation for Claude Code

- +3,922 lines (new module structure, integration tests, documentation)
- -3,298 lines (removed/reorganized code, mock tests)
- Net: +624 lines (+141 documentation, +483 better organized code)

None - all public APIs maintain backward compatibility through shims.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
 - Add architecture documentation
   - High-level design flow with ASCII diagrams
   - Core components (signatures, annotations, packages, platforms, steps)
   - Detailed flow from Python → RTLIL → target outputs
   - Pin allocation flow diagram
   - Annotation system architecture
   - Package system architecture
   - Configuration system
   - Extension points (custom signatures, steps, packages, platforms)

 - Add simulation documentation
   - Basic simulation workflow
   - What happens during simulation (6-stage process)
   - SimPlatform internals and automatic model matching
   - Port instantiation and clock/reset handling
   - Generated main.cc structure
   - Configuration options
   - Simulation commands (build/run/check)
   - RTL Debugger integration
   - Event logging for automated testing
   - Customizing simulation (adding models, custom drivers)
   - Performance tips and troubleshooting
   - Complete working example

 - Created detailed documentation covering:
   - How to use pin signatures (UARTSignature, GPIOSignature, etc.)
   - How to create peripherals with SoftwareDriverSignature
   - Organizing driver C/H files alongside Python peripherals
   - Using attach_data() to load software into flash
   - Complete working examples from chipflow-digital-ip

 - Added comprehensive IOModelOptions documentation:
   - Full reference of all available options
   - Examples showing basic and advanced usage
   - Details on invert, individual_oe, power_domain, clock_domain
   - Trip point options (CMOS, TTL, VCORE, VREF, SCHMITT_TRIGGER)
   - Buffer control and initialization options

 - Add contributor documentation for pin signature architecture
   - Annotation infrastructure (amaranth_annotate, submodule_metadata)
   - IOSignature base classes and IOModelOptions
   - Concrete pin signatures (UART, GPIO, SPI, etc.)
   - simulatable_interface and SoftwareDriverSignature decorators
   - Platform consumption patterns (silicon, software)
   - Complete flow example from signature definition to code generation
   - Guide for adding new signatures and platform backends
Update simulation-guide.rst to show the correct input.json format with:
- Root object with 'commands' array
- Command objects with 'type', 'peripheral', 'event', 'payload' fields
- 'action' type for queuing actions
- 'wait' type for waiting on events

Based on actual implementation in chipflow_lib/common/sim/models.cc:log_event

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
AutoAPI is encountering "Unable to read file" warnings for all modules
in the CI environment, preventing documentation from building. The root
cause appears to be related to module import resolution in CI that does
not occur locally.

Adds manual API documentation using sphinx.ext.autodoc directives to
ensure comprehensive API coverage.

Changes:
- Set autoapi_generate_api_docs = False in docs/conf.py
- Removed duplicate ../chipflow_lib/platforms from autoapi_dirs
- Removed all autoapi references from documentation files
- Documentation now relies on manual API documentation in platform-api.rst
- Add api to docs/platform-api.rst
- Organized API docs by category: Platforms, Build Steps, IO Signatures,
  IO Configuration, Utilities, and Constants

Co-Authored-By: Claude <noreply@anthropic.com>
robtaylor and others added 6 commits October 28, 2025 12:48
- Include interface name in error message
- Provide guidance to delete pins.lock or verify design
- Addresses gatecat review comment on allocation.py:221
- Change core_heartbeat from A2 to A8 (after JTAG pins A3-A7)
- Heartbeat is an output, clock is an input - can't share pin
- Addresses gatecat review comment on grid_array.py:220
- Replace 'Efabless' with 'ChipFoundry' (Efabless IP now owned by ChipFoundry)
- Change 'carriage system' to 'harness' for correct terminology
- Addresses gatecat review comment on openframe.py:5
Address gatecat's review comments on documentation:

- docs/using-pin-signatures.rst:
  * Fix I2C example to use OPEN_DRAIN_STRONG_DOWN (not STRONG_UP)
  * Add note linking to chipflow-examples for CPU/Wishbone examples

- docs/simulation-guide.rst:
  * Fix input.json format to use wait_for/action (not timestamps)
  * Update CXXRTL code to use cxxrtl::value (not wire)
  * Use .get()/.set() methods instead of .curr/.next
  * Retitle "Simulation Hangs" to "Incomplete Simulation Output"
  * Clarify that simulation always stops after num_steps

- docs/architecture.rst:
  * Add example showing how to attach simulation models to custom signatures

- docs/contributor-pin-signature-internals.rst:
  * Replace verbose "Summary" section with concise "Key Files" list
  * Remove redundant feature bullet points

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Replace incomplete code example with practical guidance:
- Point to existing model implementations in chipflow_lib/common/sim/
- Reference CXXRTL documentation and runtime source
- Show simplified model registration example
- Add note that comprehensive CXXRTL runtime docs are planned

This provides actionable guidance while acknowledging that detailed
CXXRTL runtime documentation should be separate work.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Note that the custom simulation model interface is subject to change
in future releases, while built-in models remain stable.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@robtaylor robtaylor force-pushed the refactor/restructure-codebase branch 2 times, most recently from b568bf8 to 1dc2906 Compare October 28, 2025 13:39
@robtaylor robtaylor force-pushed the refactor/restructure-codebase branch from 1dc2906 to 8397916 Compare October 28, 2025 13:56
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