docs: document the BSDL workflow + add a batch/TUI tutorial
DESIGN.md: libbsdl dependency and --batch headless mode; bsdl_model/bsdl_check in the layout; the attach-bsdl command and the `B` persist tag; PinSpec is now BSDL-populated; verify's five passes incl. the model-driven and JTAG checks and the new AnomalyKinds. README: libbsdl dependency, --batch usage, tutorial link. New doc/user/tutorial.md: end-to-end batch and TUI walkthroughs (load → tag → connect → attach-bsdl → verify, with the pin/JTAG findings explained). Regenerated commands.md (adds attach-bsdl); index.md links the tutorial. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
18
DESIGN.md
18
DESIGN.md
@@ -12,8 +12,10 @@ cmake --build build -j
|
|||||||
|
|
||||||
- CMake **3.14+** required (uses `FetchContent_MakeAvailable`).
|
- CMake **3.14+** required (uses `FetchContent_MakeAvailable`).
|
||||||
- FTXUI is fetched at configure time from GitHub (`v6.1.9`, shallow clone). First configure pays ~20 s for the clone; subsequent ones are cached in `build/_deps/`.
|
- FTXUI is fetched at configure time from GitHub (`v6.1.9`, shallow clone). First configure pays ~20 s for the clone; subsequent ones are cached in `build/_deps/`.
|
||||||
- **System dependencies** (resolved via `find_package`): `libzip` (target `libzip::zip`) and `pugixml` (target `pugixml::pugixml`). Used by the ODS importer. Available on Arch via `pacman -S libzip pugixml`.
|
- **System dependencies** (resolved via `find_package`): `libzip` (target `libzip::zip`) and `pugixml` (target `pugixml::pugixml`). Used by the ODS importer. Arch: `pacman -S libzip pugixml`; Debian/Ubuntu: `libzip-dev libpugixml-dev`.
|
||||||
|
- **`libbsdl`** (standalone BSDL parser, LGPL-2.1) is the sibling repo at `../libbsdl`, pulled in via `add_subdirectory` (path overridable with `-DBSDL_DIR=...`) and linked dynamically (`bsdl::bsdl`; an LGPL `.so` is fine from EUPL essim). Powers the BSDL ingest behind `attach-bsdl`.
|
||||||
- Sources are collected with `file(GLOB_RECURSE ALL_SOURCES "src/*.cpp")`. **After adding a new `.cpp`, re-run `cmake -S . -B build`** — CMake does not re-glob automatically and link will fail with "undefined reference".
|
- Sources are collected with `file(GLOB_RECURSE ALL_SOURCES "src/*.cpp")`. **After adding a new `.cpp`, re-run `cmake -S . -B build`** — CMake does not re-glob automatically and link will fail with "undefined reference".
|
||||||
|
- **Headless / batch**: `essim --batch --source FILE` runs a script and prints its console output to stdout, then exits without the TUI (good for CI / capturing `verify`). Also `--restore FILE` and `--commands-md [FILE]`. `BootDispatch` runs `--restore`/`--source` synchronously before the event loop (`Source` takes its headless drain branch when no screen is attached), so the console buffer is complete by the time `--batch` dumps it (`Tui::DumpOutput`).
|
||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
@@ -35,6 +37,8 @@ src/
|
|||||||
CheckIdentityCompatible + FillIdentityNCs
|
CheckIdentityCompatible + FillIdentityNCs
|
||||||
pin_role.{hpp,cpp} pin_role(kind, name) → PinSpec, pin_layout(kind),
|
pin_role.{hpp,cpp} pin_role(kind, name) → PinSpec, pin_layout(kind),
|
||||||
FillPartFromLayout(part, kind)
|
FillPartFromLayout(part, kind)
|
||||||
|
bsdl_model.{hpp,cpp} BsdlModel (libbsdl C-ABI wrapper) + apply_bsdl(Part*, model)
|
||||||
|
bsdl_check.{hpp,cpp} check_pin_specs / check_jtag_chain → vector<Anomaly>
|
||||||
nets.{hpp,cpp} find_net / compute_all_nets / net_type_consistent
|
nets.{hpp,cpp} find_net / compute_all_nets / net_type_consistent
|
||||||
analysis.{hpp,cpp} analyze_system → AnalysisReport (diff pairs, buses, anomalies)
|
analysis.{hpp,cpp} analyze_system → AnalysisReport (diff pairs, buses, anomalies)
|
||||||
persist.{hpp,cpp} save / restore (tab-delimited)
|
persist.{hpp,cpp} save / restore (tab-delimited)
|
||||||
@@ -91,7 +95,7 @@ doc/classes.puml -- PlantUML class diagram
|
|||||||
- Multi-step prompts work via a `std::deque<Prompt>` queue. `Submit()` pops them one by one before falling back to dispatch. Adding a new command = one entry in `RegisterCommands()`; the prompt-flow and inline-flow are both handled automatically.
|
- Multi-step prompts work via a `std::deque<Prompt>` queue. `Submit()` pops them one by one before falling back to dispatch. Adding a new command = one entry in `RegisterCommands()`; the prompt-flow and inline-flow are both handled automatically.
|
||||||
- Tab completion: at the top-level prompt (no `pending`), completes built-in command names. Inside a prompt with `path_completion = true` (e.g. the `filename` step of `load`), completes file paths via `std::filesystem::directory_iterator` (handles `~/`, dirs get a trailing `/`). Logic: 1 match → replace; multiple with progress on the longest common prefix → extend; multiple stuck at LCP → list candidates in the visualisation area.
|
- Tab completion: at the top-level prompt (no `pending`), completes built-in command names. Inside a prompt with `path_completion = true` (e.g. the `filename` step of `load`), completes file paths via `std::filesystem::directory_iterator` (handles `~/`, dirs get a trailing `/`). Logic: 1 match → replace; multiple with progress on the longest common prefix → extend; multiple stuck at LCP → list candidates in the visualisation area.
|
||||||
|
|
||||||
Built-in commands: `new`, `set`, `load`, `duplicate`, `save`, `restore`, `source`, `script-save`, `connect` (alias `plug`), `set-connector-type`, `set-signal-type`, `explore`, `verify`, `analyze`, `dashboard`, `clear`, `help`, `quit`/`exit`. `Esc` cancels an in-progress multi-step prompt.
|
Built-in commands: `new`, `set`, `load`, `duplicate`, `save`, `restore`, `source`, `script-save`, `connect` (alias `plug`), `set-connector-type`, `attach-bsdl`, `set-signal-type`, `explore`, `verify`, `analyze`, `dashboard`, `clear`, `help`, `quit`/`exit`. `Esc` cancels an in-progress multi-step prompt.
|
||||||
|
|
||||||
`set <name> <value>` declares a session-scoped variable. Subsequent commands expand `$name` and `${name}` in their args (substitution happens in `Finalize` between canonical-form recording and `spec.action(args)` — so `history` and `script-save` keep the **unexpanded** form, while the action sees resolved values). Unknown variables are left literal. `vars` is reset by `new`. Validation: `[A-Za-z_][A-Za-z0-9_]*`.
|
`set <name> <value>` declares a session-scoped variable. Subsequent commands expand `$name` and `${name}` in their args (substitution happens in `Finalize` between canonical-form recording and `spec.action(args)` — so `history` and `script-save` keep the **unexpanded** form, while the action sees resolved values). Unknown variables are left literal. `vars` is reset by `new`. Validation: `[A-Za-z_][A-Za-z0-9_]*`.
|
||||||
|
|
||||||
@@ -105,7 +109,7 @@ Built-in commands: `new`, `set`, `load`, `duplicate`, `save`, `restore`, `source
|
|||||||
|
|
||||||
Pending prompts (from incomplete inline commands) are NOT considered interactive and are filled by subsequent script lines, the way you'd expect. Lines starting with `#` and blank lines are skipped; leading/trailing whitespace is trimmed; `~/` is expanded.
|
Pending prompts (from incomplete inline commands) are NOT considered interactive and are filled by subsequent script lines, the way you'd expect. Lines starting with `#` and blank lines are skipped; leading/trailing whitespace is trimmed; `~/` is expanded.
|
||||||
|
|
||||||
`save` / `restore` (`src/system/persist.{hpp,cpp}`): tab-delimited line format, no extra deps. Tags: `M` (module), `P` (part with `connector_type`), `N` (pin → signal name; empty = NC; optional 4th field carries `nc_origin_tag()`: `U` = ImportedUnconnected, `D` = DroppedSingleton — omitted when the pin has a signal or when origin is `None`), `S` (signal → type override; only emitted for non-default), `C` (connection header with endpoints + `transform_name`), `W` (wire pair within the current connection). The 4th N field is backward-compatible: pre-existing snapshots without it restore with `nc_origin = None`.
|
`save` / `restore` (`src/system/persist.{hpp,cpp}`): tab-delimited line format, no extra deps. Tags: `M` (module), `P` (part with `connector_type`), `B` (part's attached BSDL `.bsd` path — re-parsed and re-applied on restore; the path is persisted, **not** the derived pin specs), `N` (pin → signal name; empty = NC; optional 4th field carries `nc_origin_tag()`: `U` = ImportedUnconnected, `D` = DroppedSingleton — omitted when the pin has a signal or when origin is `None`), `S` (signal → type override; only emitted for non-default), `C` (connection header with endpoints + `transform_name`), `W` (wire pair within the current connection). The 4th N field is backward-compatible: pre-existing snapshots without it restore with `nc_origin = None`.
|
||||||
|
|
||||||
**Signals** carry a `type` (`SignalType::Power | GndShield | Other`). The `Signal` constructor **defaults to `Other`** — auto-inference no longer happens at construction. Types are set in three ways, in priority order:
|
**Signals** carry a `type` (`SignalType::Power | GndShield | Other`). The `Signal` constructor **defaults to `Other`** — auto-inference no longer happens at construction. Types are set in three ways, in priority order:
|
||||||
|
|
||||||
@@ -118,11 +122,13 @@ Pending prompts (from incomplete inline commands) are NOT considered interactive
|
|||||||
|
|
||||||
The explore screen shows the type in the signal detail header.
|
The explore screen shows the type in the signal detail header.
|
||||||
|
|
||||||
**Pin spec (expected attributes)**: every Pin carries a `PinSpec spec` (`src/system/pin_spec.hpp`) — the *expected* half of verification, set from a model: `function` (Power/Ground/Signal/Clock/NoConnect/Jtag*), `direction` (In/Out/Bidir/Passive/Power), `pad` (physical package terminal, e.g. a BSDL ball), and `source` (which model wrote it). `set-connector-type` populates it via `pin_role(connector_type, pin_name) → PinSpec`. `Pin::expected_signal_type()` is now a **derived accessor** — `to_signal_type(spec.function)` (Power→Power, Ground→GndShield, else Other) — not a stored field; the *observed* half stays `Pin::signal()` + the net + inference, and `verify` diffs the two. The framework is wired end-to-end; the VPX 3U lookup (`vpx_3u_role`) is still a stub returning Other for every position, so today every pin's `function` resolves to Unknown → `expected_signal_type()` Other (behaviour unchanged from the old field) — fill in the real VITA 46 layout when needed. `direction`/`function`/`pad` are present but not yet model-populated: they are what the BSDL ingest (`libbsdl`) and the planned contention / undriven-net / NC-wired / JTAG-chain checks will consume.
|
**Pin spec (expected attributes)**: every Pin carries a `PinSpec spec` (`src/system/pin_spec.hpp`) — the *expected* half of verification, set from a model: `function` (Power/Ground/Signal/Clock/NoConnect/Jtag*), `direction` (In/Out/Bidir/Passive/Power), `pad` (physical package terminal, e.g. a BSDL ball), and `source` (which model wrote it). `set-connector-type` populates it via `pin_role(connector_type, pin_name) → PinSpec`. `Pin::expected_signal_type()` is now a **derived accessor** — `to_signal_type(spec.function)` (Power→Power, Ground→GndShield, else Other) — not a stored field; the *observed* half stays `Pin::signal()` + the net + inference, and `verify` diffs the two. The VPX 3U connector lookup (`vpx_3u_role`) is still a stub returning Other, so connector-typed pins resolve to function Unknown until that table is filled. **`direction`/`function`/`pad` are populated from BSDL** via `attach-bsdl` (see below) and consumed by the model-driven checks (`check_pin_specs`: contention / undriven / NC-wired) and the JTAG chain check (`check_jtag_chain`), both run by `verify`.
|
||||||
|
|
||||||
**Connector pin layout (preparation)**: `pin_layout(connector_type)` returns the canonical full pin-name list for a known connector kind, and `FillPartFromLayout(part, kind)` materialises NC pins for any layout position absent from the imported netlist. `set-connector-type` calls it after setting `connector_type` (no-op today since `pin_layout` is a stub returning `{}` for everything — populate alongside `vpx_3u_role`). End-to-end chain in place: `set-connector-type → FillPartFromLayout → pin_role`.
|
**Connector pin layout (preparation)**: `pin_layout(connector_type)` returns the canonical full pin-name list for a known connector kind, and `FillPartFromLayout(part, kind)` materialises NC pins for any layout position absent from the imported netlist. `set-connector-type` calls it after setting `connector_type` (no-op today since `pin_layout` is a stub returning `{}` for everything — populate alongside `vpx_3u_role`). End-to-end chain in place: `set-connector-type → FillPartFromLayout → pin_role`.
|
||||||
|
|
||||||
**`verify` (three passes)**: (1) walks all typed pins and reports local mismatches between each pin's `expected_signal_type()` (derived from its `PinSpec`) and the actual signal type; (2) walks all bridged nets reporting Power↔GndShield inconsistencies; (3) prints a single-line orphan summary `N orphan pin(s) at import (X imported NC, Y dropped singleton)`. The orphan pass filters out pins that appear in any `Connection::pin_map` — those are bridged to a real signal on the peer module (typically `FillIdentityNCs`-materialised) and not real NCs at system level. The BFS-reached `(module, signal)` set for any signal is shown live in `explore`'s detail pane when a signal entry is selected.
|
**BSDL models (`attach-bsdl`)**: `attach-bsdl <module> <part> <file.bsd>` parses a BSDL device through `libbsdl` (wrapped by `BsdlModel`, `src/system/bsdl_model.{hpp,cpp}`), then `apply_bsdl(part, model)` binds each port to a Pin **by port name first, then by physical pad** — so a netlist that names IC pins either by signal or by package ball both bind. Each bound pin gets its `spec` set: `direction` (BSDL in/out/inout/linkage), `function` (TAP role → Jtag\*, `linkage` → Power/Ground/NoConnect by name, else Signal), `pad` (PIN_MAP ball), `source = Bsdl`. The `.bsd` path is stored on `Part::bsdl_path`, persisted via the `B` tag and re-applied on `restore`. Real-world check: an `xcku15p` FPGA in a VPX system binds 1517/1517 ports.
|
||||||
|
|
||||||
|
**`verify` (five passes)**: (1) typed pins — local mismatch between each pin's `expected_signal_type()` (derived from its `PinSpec`) and the actual signal type; (2) bridged nets — Power↔GndShield inconsistencies; (3) orphan summary `N orphan pin(s) at import (X imported NC, Y dropped singleton)` (filters out pins bridged via any `Connection::pin_map` — typically `FillIdentityNCs`-materialised); (4) **model-driven pin checks** (`check_pin_specs`): `DriveContention` (≥2 push-pull `Out` on a net), `UndrivenNet` (a **fully-modelled** net with input(s) but no driver — nets with any Unknown-direction pin are skipped, so un-modelled drivers don't cause false positives), `NcWired` (a no-connect pin on a multi-pin net); (5) **JTAG chain** (`check_jtag_chain`): collects TAP pins by `spec.function`, maps each to its net, emits `JtagTapIncomplete` / `JtagBusUnbridged` (TMS or TCK not common to all TAP devices) / `JtagChainBreak` (dangling TDO/TDI, chain fan-out, or not a single head→tail daisy chain). The BFS-reached `(module, signal)` set for any signal is shown live in `explore`'s detail pane when a signal entry is selected.
|
||||||
|
|
||||||
**`analyze` (post-processing pass)**: `analyze_system(System*) → AnalysisReport` (`src/system/analysis.{hpp,cpp}`) is a stateless read-only pass that detects structural signal groups and anomalies. Per-module (signals are module-scoped):
|
**`analyze` (post-processing pass)**: `analyze_system(System*) → AnalysisReport` (`src/system/analysis.{hpp,cpp}`) is a stateless read-only pass that detects structural signal groups and anomalies. Per-module (signals are module-scoped):
|
||||||
|
|
||||||
@@ -290,6 +296,8 @@ The analyze screen additionally surfaces two "verify-class" issues, computed the
|
|||||||
- **pin-role mismatch** — a pin whose `expected_signal_type()` (derived from its `PinSpec`, set by `set-connector-type` via `pin_role(connector_type, pin_name)`) disagrees with the actual signal type.
|
- **pin-role mismatch** — a pin whose `expected_signal_type()` (derived from its `PinSpec`, set by `set-connector-type` via `pin_role(connector_type, pin_name)`) disagrees with the actual signal type.
|
||||||
- **net-mix** — a bridged net (BFS over `Connection::pin_map`, ≥ 2 members) where `net_type_consistent(net, &dominant)` returns false. Specifically, the net contains both `Power` and `GndShield` signals.
|
- **net-mix** — a bridged net (BFS over `Connection::pin_map`, ≥ 2 members) where `net_type_consistent(net, &dominant)` returns false. Specifically, the net contains both `Power` and `GndShield` signals.
|
||||||
|
|
||||||
|
The `verify` command (not the analyze screen, yet) also emits the **model-driven `AnomalyKind`s** from `bsdl_check.{hpp,cpp}`: `DriveContention` / `UndrivenNet` / `NcWired` (`check_pin_specs`) and `JtagTapIncomplete` / `JtagChainBreak` / `JtagBusUnbridged` (`check_jtag_chain`). They consume the BSDL-populated `PinSpec` plus `compute_all_nets`. Surfacing them in the analyze/dashboard Issues pane is a TODO.
|
||||||
|
|
||||||
### Component kind
|
### Component kind
|
||||||
|
|
||||||
`Part::kind` is inferred at construction (`src/system/component_kind.cpp`) from the leading reference-designator letter(s) of the part name. **Longest-match wins**:
|
`Part::kind` is inferred at construction (`src/system/component_kind.cpp`) from the leading reference-designator letter(s) of the part name. **Longest-match wins**:
|
||||||
|
|||||||
13
README.md
13
README.md
@@ -20,6 +20,15 @@ auto-generated reference at [`doc/user/commands.md`](doc/user/commands.md).
|
|||||||
A worked bring-up script is at [`test/system.essim`](test/system.essim);
|
A worked bring-up script is at [`test/system.essim`](test/system.essim);
|
||||||
load it with `source test/system.essim`.
|
load it with `source test/system.essim`.
|
||||||
|
|
||||||
|
To run a script without the TUI and print its output to stdout (CI-friendly):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./build/essim --batch --source bring-up.essim
|
||||||
|
```
|
||||||
|
|
||||||
|
Step-by-step walkthroughs for both the batch and TUI workflows are in
|
||||||
|
[`doc/user/tutorial.md`](doc/user/tutorial.md).
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
- **C++17 compiler** and **CMake 3.14+**.
|
- **C++17 compiler** and **CMake 3.14+**.
|
||||||
@@ -28,6 +37,10 @@ load it with `source test/system.essim`.
|
|||||||
- Debian/Ubuntu — `sudo apt install libzip-dev libpugixml-dev`
|
- Debian/Ubuntu — `sudo apt install libzip-dev libpugixml-dev`
|
||||||
- Arch — `sudo pacman -S libzip pugixml`
|
- Arch — `sudo pacman -S libzip pugixml`
|
||||||
- Fedora — `sudo dnf install libzip-devel pugixml-devel`
|
- Fedora — `sudo dnf install libzip-devel pugixml-devel`
|
||||||
|
- **libbsdl** — the standalone BSDL parser, a sibling repo expected at
|
||||||
|
`../libbsdl`, pulled in via `add_subdirectory` and linked dynamically.
|
||||||
|
Override its location with `-DBSDL_DIR=/path/to/libbsdl`. Powers the
|
||||||
|
`attach-bsdl` command and the pin/JTAG checks.
|
||||||
- Fetched automatically at configure time via `FetchContent` (nothing to
|
- Fetched automatically at configure time via `FetchContent` (nothing to
|
||||||
install): **FTXUI** v6.1.9 and **doctest** v2.4.11.
|
install): **FTXUI** v6.1.9 and **doctest** v2.4.11.
|
||||||
- Optional, only for the `doc` target: **doxygen** and **python3**.
|
- Optional, only for the `doc` target: **doxygen** and **python3**.
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ browse modules → parts/signals/connections → details (interactive)
|
|||||||
---
|
---
|
||||||
### `export` *(interactive)*
|
### `export` *(interactive)*
|
||||||
|
|
||||||
export structured data to CSV (kinds: connections; bare form opens the file-picker dialog)
|
export structured data to CSV / ODS (kinds: connections; bare form opens the file-picker dialog)
|
||||||
|
|
||||||
**Arguments**
|
**Arguments**
|
||||||
|
|
||||||
@@ -88,6 +88,21 @@ tag a part's connector type for transform lookup
|
|||||||
detect signal groups (diff pairs, buses) and structural anomalies
|
detect signal groups (diff pairs, buses) and structural anomalies
|
||||||
|
|
||||||
**No arguments.**
|
**No arguments.**
|
||||||
|
---
|
||||||
|
### `attach-bsdl`
|
||||||
|
|
||||||
|
attach a BSDL (.bsd) model to a part and populate pin specs
|
||||||
|
|
||||||
|
**Arguments**
|
||||||
|
|
||||||
|
1. `module`
|
||||||
|
2. `part (name or pattern)`
|
||||||
|
3. `bsdl file (.bsd path)`
|
||||||
|
|
||||||
|
**Notes**
|
||||||
|
|
||||||
|
- no per-arg prompt: pass all args inline (or run bare for an empty-args path)
|
||||||
|
|
||||||
---
|
---
|
||||||
### `clear`
|
### `clear`
|
||||||
|
|
||||||
@@ -238,7 +253,7 @@ execute a file of commands line by line (interactive cmds rejected)
|
|||||||
---
|
---
|
||||||
### `verify`
|
### `verify`
|
||||||
|
|
||||||
check pin roles locally and signal-type consistency across bridged nets
|
check pin roles, bridged-net consistency, and model-driven pin specs (contention/undriven/NC)
|
||||||
|
|
||||||
**No arguments.**
|
**No arguments.**
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
# essim — user guide
|
# essim — user guide
|
||||||
|
|
||||||
A short, task-oriented introduction to using essim. For an exhaustive
|
A short, task-oriented introduction to using essim. For step-by-step
|
||||||
reference of every command, see [`commands.md`](commands.md) (auto-
|
**batch** and **TUI** walkthroughs, see [`tutorial.md`](tutorial.md). For an
|
||||||
generated from the binary). For scripting and `$variable` expansion,
|
exhaustive reference of every command, see [`commands.md`](commands.md)
|
||||||
|
(auto-generated from the binary). For scripting and `$variable` expansion,
|
||||||
see [`scripting.md`](scripting.md).
|
see [`scripting.md`](scripting.md).
|
||||||
|
|
||||||
## What essim is
|
## What essim is
|
||||||
@@ -91,6 +92,8 @@ fresh.
|
|||||||
|
|
||||||
## Where to look next
|
## Where to look next
|
||||||
|
|
||||||
|
- [`tutorial.md`](tutorial.md) — end-to-end batch and TUI walkthroughs,
|
||||||
|
including BSDL attach + the pin/JTAG checks.
|
||||||
- [`commands.md`](commands.md) — exhaustive command reference,
|
- [`commands.md`](commands.md) — exhaustive command reference,
|
||||||
regenerated from the binary on every `cmake --build build --target doc`.
|
regenerated from the binary on every `cmake --build build --target doc`.
|
||||||
- [`analysis.md`](analysis.md) — how essim classifies signals
|
- [`analysis.md`](analysis.md) — how essim classifies signals
|
||||||
|
|||||||
225
doc/user/tutorial.md
Normal file
225
doc/user/tutorial.md
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
# essim — tutorial
|
||||||
|
|
||||||
|
Two end-to-end walkthroughs of the same work. The **batch** one runs everything
|
||||||
|
from a script with no terminal UI (ideal for CI or quick reproducible checks);
|
||||||
|
the **TUI** one drives the same operations interactively.
|
||||||
|
|
||||||
|
Both assume essim is built (`cmake -S . -B build && cmake --build build -j` — see
|
||||||
|
the [README](../../README.md)). For the exhaustive command list see
|
||||||
|
[`commands.md`](commands.md); for `$variable` expansion see
|
||||||
|
[`scripting.md`](scripting.md).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Batch mode
|
||||||
|
|
||||||
|
`essim --batch --source FILE` runs an essim script and prints the console output
|
||||||
|
to stdout, then exits — no TUI. The script is the same language you'd type at the
|
||||||
|
prompt: one command per line, `#` comments, blank lines ignored, `$variables`
|
||||||
|
expanded, `~/` paths supported.
|
||||||
|
|
||||||
|
### 1.1 A first script
|
||||||
|
|
||||||
|
Create `bring-up.essim`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
# Load two cards, tag + wire their VPX connectors, then verify.
|
||||||
|
new
|
||||||
|
|
||||||
|
set nl /path/to/netlists
|
||||||
|
|
||||||
|
load backplane $nl/backplane.NET altium
|
||||||
|
load payload1 $nl/payload.qcv mentor
|
||||||
|
|
||||||
|
set-connector-type backplane J20 vpx-3u-bkp-p0
|
||||||
|
set-connector-type payload1 P0 vpx-3u-payload-p0
|
||||||
|
connect backplane J20 payload1 P0
|
||||||
|
|
||||||
|
verify
|
||||||
|
save system.essim
|
||||||
|
```
|
||||||
|
|
||||||
|
Run it:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./build/essim --batch --source bring-up.essim
|
||||||
|
```
|
||||||
|
|
||||||
|
Each command is echoed with its result, e.g.:
|
||||||
|
|
||||||
|
```text
|
||||||
|
> load backplane /path/to/netlists/backplane.NET altium
|
||||||
|
loaded 'backplane' from /path/to/netlists/backplane.NET
|
||||||
|
> connect backplane J20 payload1 P0
|
||||||
|
connected: backplane/J20 <-> payload1/P0 via vpx-3u-p0 (59 wires)
|
||||||
|
> verify
|
||||||
|
verify: 0 local mismatch(es) over 0 typed pin(s).
|
||||||
|
verify: 0 inconsistent net(s) over 1 bridged net(s) (... total).
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 Attaching a BSDL model and checking the JTAG chain
|
||||||
|
|
||||||
|
For complex ICs (FPGAs, big SoCs) you can attach a **BSDL** (`.bsd`) device model
|
||||||
|
to a part. essim binds each BSDL port to a pin — **by port name first, then by
|
||||||
|
package ball** — and fills the pin's direction / function / pad. `verify` then
|
||||||
|
runs model-driven checks on top of the basic ones.
|
||||||
|
|
||||||
|
Add this before `verify`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
attach-bsdl payload1 U14 /path/to/bsdl/xcku15p_ffve1517.bsd
|
||||||
|
```
|
||||||
|
|
||||||
|
`attach-bsdl` reports the binding:
|
||||||
|
|
||||||
|
```text
|
||||||
|
payload1/U14: attached BSDL 'XCKU15P_FFVE1517' — 1517/1517 ports bound
|
||||||
|
```
|
||||||
|
|
||||||
|
and `verify` now also prints the model-driven and JTAG passes, e.g.:
|
||||||
|
|
||||||
|
```text
|
||||||
|
verify: 0 model-driven pin anomaly(ies).
|
||||||
|
[jtag-bus-unbridged] TMS is not common to all TAP devices (off-bus: ...)
|
||||||
|
[jtag-chain-break] JTAG chain is not a single daisy chain: 3 head(s), 3 tail(s) over 3 TAP device(s)
|
||||||
|
verify: 3 JTAG chain anomaly(ies).
|
||||||
|
```
|
||||||
|
|
||||||
|
What the new findings mean:
|
||||||
|
|
||||||
|
| Finding | Meaning |
|
||||||
|
|---|---|
|
||||||
|
| `drive-contention` | ≥2 push-pull outputs share a net |
|
||||||
|
| `undriven-net` | a **fully-modelled** net has input(s) but no driver |
|
||||||
|
| `nc-wired` | a no-connect pin is wired onto a multi-pin net |
|
||||||
|
| `jtag-tap-incomplete` | a TAP device is missing TDI/TDO/TMS/TCK |
|
||||||
|
| `jtag-bus-unbridged` | TMS or TCK isn't common to every TAP device |
|
||||||
|
| `jtag-chain-break` | the TDO→TDI daisy chain dangles, forks, or isn't a single path |
|
||||||
|
|
||||||
|
`undriven-net` only fires when *every* pin on the net is modelled — otherwise the
|
||||||
|
driver might sit on a part with no model, so essim stays quiet rather than guess.
|
||||||
|
|
||||||
|
The attached `.bsd` path is stored in the `save` snapshot and re-applied on
|
||||||
|
`restore` (the path is persisted, not the derived pin data), so the model survives
|
||||||
|
round-trips.
|
||||||
|
|
||||||
|
### 1.3 Capturing and chaining
|
||||||
|
|
||||||
|
`--batch` exits 0 after the script, so pipe/grep the output like any tool:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./build/essim --batch --source bring-up.essim | grep -E '\[jtag-|verify:'
|
||||||
|
```
|
||||||
|
|
||||||
|
Layer a script on top of a saved snapshot with `--restore`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./build/essim --batch --restore system.essim --source extra.essim
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. TUI mode
|
||||||
|
|
||||||
|
Launch with no script:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./build/essim
|
||||||
|
```
|
||||||
|
|
||||||
|
You land on the **dashboard** — a read-only overview (module / part / signal /
|
||||||
|
connection counts, health rows, a per-module table). It's the home screen.
|
||||||
|
|
||||||
|
### 2.1 Getting around
|
||||||
|
|
||||||
|
Dashboard single-key shortcuts:
|
||||||
|
|
||||||
|
| Key | Goes to |
|
||||||
|
|---|---|
|
||||||
|
| `c` | console (type commands, read output) |
|
||||||
|
| `p` | plug / connect screen |
|
||||||
|
| `t` | set-connector-type screen |
|
||||||
|
| `e` | explore screen |
|
||||||
|
| `a` | analyze screen |
|
||||||
|
| `q` | quit |
|
||||||
|
|
||||||
|
From anywhere, `Ctrl-P` opens the **command palette** (fuzzy-find a command, or
|
||||||
|
jump to a module / signal). `Esc` backs out of a screen or cancels a prompt.
|
||||||
|
|
||||||
|
### 2.2 The console
|
||||||
|
|
||||||
|
Press `c`. This is the textual shell — the same commands as the batch script,
|
||||||
|
typed one at a time:
|
||||||
|
|
||||||
|
```text
|
||||||
|
> new
|
||||||
|
> load backplane ~/netlists/backplane.NET altium
|
||||||
|
> set-connector-type backplane J20 vpx-3u-bkp-p0
|
||||||
|
> verify
|
||||||
|
```
|
||||||
|
|
||||||
|
Helpers:
|
||||||
|
|
||||||
|
| Action | How |
|
||||||
|
|---|---|
|
||||||
|
| List commands / help on one | `help`, `help <name>` |
|
||||||
|
| Tab-complete a command or path | `‹Tab›` |
|
||||||
|
| Recall previous commands | ↑ / ↓ |
|
||||||
|
| Scroll output | `PageUp`/`PageDown`, `Home`/`End` |
|
||||||
|
| Cancel a multi-step prompt | `Esc` |
|
||||||
|
|
||||||
|
Any command works inline (`set-connector-type backplane J20 vpx-3u-bkp-p0`) or
|
||||||
|
**bare** to open its interactive screen (`set-connector-type` then Enter).
|
||||||
|
|
||||||
|
### 2.3 Interactive screens
|
||||||
|
|
||||||
|
Bare `connect`, `set-connector-type`, `explore`, `analyze` open a full-screen
|
||||||
|
layout. Conventions: a title bar at the top, `Tab` cycles fields (the active one
|
||||||
|
flips to reverse video), `Esc` returns to the prompt.
|
||||||
|
|
||||||
|
- **connect** (`p`) — pick module A, filter + pick its part, module B, its part,
|
||||||
|
then Apply. The transform is chosen from the two `connector_type`s.
|
||||||
|
- **set-connector-type** (`t`) — pick a module, filter + pick a part, type the
|
||||||
|
kind, Apply. Materialises any missing layout pins and fills each pin's expected
|
||||||
|
spec.
|
||||||
|
- **explore** (`e`) — browse modules → parts / signals → pins. Selecting a signal
|
||||||
|
shows its net (the members reached across connections); Enter on a signal opens
|
||||||
|
the power / gnd / other popup.
|
||||||
|
- **analyze** (`a`) — Issues / Groups / Types panes: pin-role mismatches,
|
||||||
|
bridged-net inconsistencies, diff pairs, buses, structural anomalies.
|
||||||
|
|
||||||
|
### 2.4 Attaching BSDL in the TUI
|
||||||
|
|
||||||
|
`attach-bsdl` has no dedicated screen — run it inline from the console:
|
||||||
|
|
||||||
|
```text
|
||||||
|
> attach-bsdl payload1 U14 ~/bsdl/xcku15p_ffve1517.bsd
|
||||||
|
payload1/U14: attached BSDL 'XCKU15P_FFVE1517' — 1517/1517 ports bound
|
||||||
|
> verify
|
||||||
|
```
|
||||||
|
|
||||||
|
The model-driven and JTAG findings appear in the console output (see §1.2).
|
||||||
|
(Surfacing them on the analyze screen is planned.)
|
||||||
|
|
||||||
|
### 2.5 Saving your work
|
||||||
|
|
||||||
|
| Command | Writes |
|
||||||
|
|---|---|
|
||||||
|
| `save <file>` | full snapshot (including attached BSDL paths) |
|
||||||
|
| `script-save <file>` | replay-ready script of this session |
|
||||||
|
| `source <file>` | run a script line by line |
|
||||||
|
|
||||||
|
A common loop: experiment in the console, `script-save` what works, hand-edit it
|
||||||
|
into a parametrised `$variable` script, then `--batch --source` it for repeatable
|
||||||
|
runs.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Where to look next
|
||||||
|
|
||||||
|
- [`index.md`](index.md) — the user-guide overview.
|
||||||
|
- [`commands.md`](commands.md) — every command, regenerated from the binary.
|
||||||
|
- [`analysis.md`](analysis.md) — signal classification, buses, diff pairs.
|
||||||
|
- [`scripting.md`](scripting.md) — `set` / `$var`, `source` semantics.
|
||||||
|
- [`../../DESIGN.md`](../../DESIGN.md) — implementation notes (BSDL ingest, checks).
|
||||||
Reference in New Issue
Block a user