docs: design required mxpic_router stack
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
# Required mxpic_router Stack Design
|
||||
|
||||
Date: 2026-05-31
|
||||
|
||||
## Goal
|
||||
|
||||
Unify layout preview and GDS generation behind the same Nazca/mxpic_router
|
||||
pipeline. `mxpic_router` is no longer an optional routed-only helper. It is a
|
||||
required runtime package for `mxpic_EDA`, and both repositories should be
|
||||
released together as a matched pair.
|
||||
|
||||
## Current Problem
|
||||
|
||||
`Build Layout` currently has two backend preview paths:
|
||||
|
||||
- No `bundles.*.links`: `server.py` calls `create_layout_svg_from_gds`, which
|
||||
directly places PDK GDS with gdstk.
|
||||
- With `bundles.*.links`: `server.py` calls `create_routed_layout_svg`, which
|
||||
delegates to `mxpic_router`, builds Nazca GDS, then converts that GDS to SVG.
|
||||
|
||||
This duplicates layout semantics. Placement-only cells and routed cells can
|
||||
drift because they are built by different engines. Maintenance is harder
|
||||
because every future layout feature must be considered in two paths.
|
||||
|
||||
## Decision
|
||||
|
||||
Use one canonical build path for both preview SVG and project GDS:
|
||||
|
||||
`saved YAML -> mxpic_router -> Nazca GDS -> gdstk SVG conversion when needed`
|
||||
|
||||
`mxpic_router` and its required build stack are hard dependencies. The Flask
|
||||
server should verify the whole stack before startup, fail early if anything is
|
||||
missing, and give an actionable message.
|
||||
|
||||
## Dependency Gate
|
||||
|
||||
Add `backend/router_dependency.py` as the single backend module responsible for
|
||||
router dependency validation.
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- Add the sibling checkout path `../mxpic_router` to `sys.path` when it exists,
|
||||
preserving the current local-development pattern.
|
||||
- Import `mxpic_router.build_project_gds`.
|
||||
- Import `nazca`, because router output is built as Nazca cells.
|
||||
- Import `gdstk`, because preview SVG still converts router-generated GDS with
|
||||
`gdstk.read_gds(...).top_level()[0].write_svg(...)`.
|
||||
- Probe the route backend by importing
|
||||
`mxpic_router.builder._import_mxpic_forge_route` and calling it. This uses the
|
||||
same `mxpic_forge`/`mxpic.Route` lookup that actual router builds use.
|
||||
- Return a small structured result for startup logging and tests.
|
||||
- Raise a clear `RuntimeError` when the stack is incomplete.
|
||||
|
||||
Server startup should call this check before `app.run`. In script mode, startup
|
||||
should exit before Flask launches if the dependency gate fails.
|
||||
|
||||
## Build Layout Flow
|
||||
|
||||
`Build Layout` should always use the router-backed preview path:
|
||||
|
||||
`frontend/canvas.html handleBuildLayout` -> POST `/api/save-layout` ->
|
||||
`backend/server.py save_layout` writes `<cell>.yml` and route sidecar ->
|
||||
`create_routed_layout_svg(...)` -> `mxpic_router.build_project_gds(...)` with
|
||||
`target_cell_name=<cell>` -> temporary `.gds` -> `gdstk.write_svg(...)` ->
|
||||
saved `<cell>.svg`.
|
||||
|
||||
There should be no `layout_has_links` branch in `save_layout`. A no-link layout
|
||||
is still a valid router input; the router builds placed instances and exports
|
||||
the requested top cell without drawing routes.
|
||||
|
||||
`layout_preview.py` can remain in the tree only if it is still useful as a
|
||||
manual diagnostic module. It should not be used by production preview requests.
|
||||
|
||||
## Build GDS Flow
|
||||
|
||||
`Build GDS` should always delegate to `mxpic_router`.
|
||||
|
||||
`backend/gds_builder.py build_project_gds` should:
|
||||
|
||||
- Load saved project YAML files only if needed for validation/error messages.
|
||||
- Call `_build_with_mxpic_router(...)` as the canonical builder.
|
||||
- Remove silent fallback to `_build_with_gdstk` and `_build_with_nazca`.
|
||||
- Raise a clear error if the required router stack is unavailable, though this
|
||||
should normally be caught at server startup.
|
||||
|
||||
The old fallback functions may be removed if tests and imports no longer need
|
||||
them. If kept temporarily, they must be clearly marked as unused diagnostics
|
||||
and not reachable from the production API.
|
||||
|
||||
## Error Handling
|
||||
|
||||
Dependency failures should be early and explicit:
|
||||
|
||||
- Missing `mxpic_router`: tell the operator to install or place the matched
|
||||
sibling checkout.
|
||||
- Missing `nazca`: tell the operator the router runtime cannot build GDS.
|
||||
- Missing `gdstk`: tell the operator previews cannot convert GDS to SVG.
|
||||
- Missing route backend: tell the operator routing primitives are unavailable.
|
||||
|
||||
Request-time failures should remain JSON API errors, but normal deployment
|
||||
should fail at startup before users can reach these routes.
|
||||
|
||||
## Testing
|
||||
|
||||
Update static/backend tests to assert the new contract:
|
||||
|
||||
- `server.py` imports and calls the router dependency gate before startup.
|
||||
- `/api/save-layout` calls `create_routed_layout_svg` unconditionally for
|
||||
previews.
|
||||
- `/api/save-layout` no longer branches on `layout_has_links` to choose
|
||||
between gdstk and router preview builders.
|
||||
- `gds_builder.py` delegates to `_build_with_mxpic_router` without gdstk/Nazca
|
||||
production fallback.
|
||||
- The router dependency module checks `mxpic_router`, `nazca`, `gdstk`, and the
|
||||
route backend.
|
||||
- `GDS_SVG_GENERATION_LOGIC.md` documents the unified path.
|
||||
|
||||
Add a runtime smoke test for the local development environment when the required
|
||||
router stack is installed: a no-link saved YAML cell should generate SVG through
|
||||
`create_routed_layout_svg`. If CI does not install Nazca/router dependencies,
|
||||
keep that test explicitly skipped unless the dependency gate passes.
|
||||
|
||||
## Release Policy
|
||||
|
||||
`mxpic_EDA` and `mxpic_router` should be released simultaneously.
|
||||
|
||||
Recommended lightweight policy:
|
||||
|
||||
- Update deployment notes to state that both repositories must be deployed as a
|
||||
matched pair.
|
||||
- Keep a visible compatibility note in `README.md` or deployment docs.
|
||||
- Version compatibility checks are out of scope until both repositories expose
|
||||
explicit version constants; until then, deployment docs carry the matched-pair
|
||||
release requirement.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Do not redesign the frontend YAML format in this change.
|
||||
- Do not vendor/copy `mxpic_router` source into `mxpic_EDA`.
|
||||
- Do not replace gdstk SVG conversion in this change; it remains the converter
|
||||
after router-generated GDS.
|
||||
- Do not add fallback behavior that hides a missing or incompatible router
|
||||
stack.
|
||||
Reference in New Issue
Block a user