gui
gui
cicpy gui opens a Qt viewer on a .cic file — the Python successor to ciccreator’s C++ cic-gui. Phase 1 ships a layout-only viewer; a side-by-side schematic pane is planned for Phase 2 (see gui_plan).
Install
PySide6 is an optional dependency, gated behind the gui extra:
pip install -e '.[gui]'
Run
cicpy gui path/to/CELL.cic
The tech file and dependency libraries are auto-discovered from the IP layout — no flags required for the common case.
Auto-discovery
- Tech file — walks up from
CELL.ciclooking fortech/cic/*.tech. Picks the first match. - Dependency libraries — walks up to find the IP’s
config.yaml, treats top-level keys withremote:/revision:entries as cicconf dependencies, and globs<workspace>/<dep>/design/*.cicfor each. All discovered files are logged at INFO level on launch. - Sibling cells — the selected
.cicfile’s directory is indexed for.cic/.cic.gzfiles. Sibling files are loaded only when the currently loaded design references a missing instance cell, so openingLELOTEMP_CCMP.ciccan pull inLELOTEMP_CMP.cicwithout loading every sibling.
Overrides
cicpy gui CELL.cic --tech path/to/sky130A.tech \
--I extra_lib.cic \
--no-auto-libs
--tech FILE— override auto-discovery.--I FILE(repeatable) — merge an extra.cicbefore opening (in addition to auto-discovered libs unless--no-auto-libs).--no-auto-libs— disable dependency-library auto-discovery.
Keybindings
| Action | Binding |
|---|---|
| Fit cell to view | F |
| Zoom in | Z |
| Zoom out | Ctrl+Z (Cmd+Z on macOS) |
| Zoom to area | right-click drag |
| Pan | wheel, arrow keys |
| Toggle all layers | T |
| Toggle one layer | checkbox in layer list |
Reload .cic |
Shift+R (auto-reload also fires when the file changes on disk) |
| Descend hierarchy | click a schematic component, then E |
| Ascend hierarchy | Ctrl+E (Cmd+E on macOS) |
| Rerun spi2mag | Ctrl+R (Cmd+R on macOS) — runs make in the IP root by default |
Ctrl/Cmd + wheel also zooms; Shift + wheel pans horizontally.
What’s in the window
- Cell list (top-left) — every cell in the loaded design + dependency libraries. Row change loads that cell into the layout pane.
- Layer list (middle-left) — every layer from the tech file. Pin layers and
TXTare visible by default; non-pin implant layers default off. Each row has a color swatch icon and a checkbox for visibility. State persists across sessions per tech viaQSettings. - Route list (bottom-left) — routes in the selected cell. Each row is checkable, and entries prefixed with
*touch or overlap another differently named route on the same layer. Same-name route contacts are not marked. - Layout pane (middle) — the cell rendered into a
QGraphicsScene. Y-flipped to match conventional layout view (Y grows up). - Schematic pane (right) — the matching XSchem
.schfor the selected cell, if one is found next to the.cicor in the IP / dependency design directories. Hidden when no schematic exists. - Status bar — cursor coordinates (Ångström + µm for layout, raw grid units for schematic).
Rerunning spi2mag
Ctrl+R (or Run → Rerun spi2mag) shells out to make in the IP root (the directory containing config.yaml). Override either with --rerun-cmd and --rerun-cwd on the command line, or via Run → Set rerun command…. The CICPY_GUI_RERUN_CMD env var is also honoured.
Run → Auto-rerun on .py change (persistent in QSettings) watches the active cell’s pycell <CellName>.py and triggers a debounced rerun whenever it changes on disk. The new .cic is then auto-reloaded by the existing QFileSystemWatcher. The intended loop is:
- Edit
<CellName>.py(or the sidecar<CellName>.groups.yaml) - Save
- GUI reruns spi2mag
- GUI reloads the freshly-written
.cic
Planning groups (Phase 4a)
Each cell can have a sidecar <CellName>.groups.yaml next to its .py describing planning groups — named subsets of instances. Membership can be enumerated explicitly (members:), pattern-matched (member_regex:), or net-driven (member_nets:); the resolver unions all three.
When any group is checked visible, both panes filter:
- Layout pane hides non-member top-level instances
- Schematic pane dims non-members to ~18% opacity (still legible context)
The bottom-left Groups panel manages them: New to create, right-click to rename / edit description / regex / members, Add selection to push the last-clicked schematic component (and its naming-convention peers) into the active group. The YAML is rewritten on every change.
cell: LELOTEMP_OTAN
groups:
- name: bias_chain
description: Output stage bias mirror
visible: true
members: [xn_mirr_bias1, xn_mirr_bias2]
member_regex: ['^xn_mirr_bias\d+']
Phases 4b–4f layer route/placement intent into the same YAML, where it’ll be consumed by a cicpy.groups.apply() helper inside the pycell.
Pycell consumption (Phase 4d)
The pycell opts into the YAML-driven flow with one call:
import cicpy.groups as gp
def beforePlace(layout):
# honours <CellName>.groups.yaml next to this .py file
gp.apply(layout)
Each visible group with a placement.stack: true entry becomes a
makeCellGroup(parent).addStack(name, ...) call. Members are taken from
placement.instances_regex if set, otherwise from member_regex, otherwise
from members (joined as an exact-match regex). Returns
{group_name: stack_object} so the pycell can plug the result into
addRouteConnection, etc.
cell: LELOTEMP_CMP
groups:
- name: n_mirr_load
visible: true
members: [xn_mirr_load1, xn_mirr_load2, xn_mirr_load3]
placement:
stack: true
parent: nmos # CellGroup name; created on first reference
Cross-probing
Click a component in the schematic pane. The GUI parses the instance name (e.g. xn_mirr_load2 → group xn_mirr_load) and outlines every peer in both panes. The naming convention is x<kind>[_<gid>]_<role> — the cIcSpice::Component.group() regex captures the longest non-digit prefix.
E descends into the clicked component’s underlying cell (<symbol-basename> looked up in Design.cells). Ctrl+E pops the history stack to ascend.
Route labels and top-cell port labels are rendered as TXT text. Sub-circuit port labels are suppressed to avoid clutter; use the route list and top-level port labels for the first-level view.
Window geometry, splitter sizes, last-opened cell, and per-layer visibility are all persisted.