# Changelog

All notable changes to **xviv** are documented here.

---

## [0.2.8] - 2026-06-08

59 commits since v0.2.7 (2026-05-25 → 2026-06-05). The headline addition is
`xviv validate` — a Vivado-free XDC constraint lint tool that cross-references
`.xdc` files against RTL port declarations using `tkinter.Tcl` and `pyslang`.
Internally, `utils/parallel.py` and `utils/process.py` have been replaced by a
new `Job` / `Stream` / `Display` execution stack, and the test suite has been
reorganised from monolithic files into a structured unit + integration layout.

### New features

#### `xviv validate` — XDC constraint linter

- New top-level `validate` command and `functions/validate.py` module.
- Sub-command `validate synth` validates a synth target's I/O constraints
  without invoking Vivado:
  - `--design <name>` or `--bd <name>` selects the target (core not yet
    supported).
  - `--io {short|full}` toggles summary vs full per-port table output.
  - `--level {error|info}` filters reported issues (default: `info`).
- Prints a run summary (top module, FPGA part, enabled pipeline stages) before
  the constraint table.

#### `parsers/xdc.py` — native XDC parser

- `XDCParser` uses Python's built-in `tkinter.Tcl` engine to evaluate `.xdc`
  files directly — no Vivado required.
- Handles `set_property PACKAGE_PIN`, `IOSTANDARD`, `DRIVE`, `SLEW`,
  `PULLTYPE`, `DIFF_TERM`; `create_clock`; `set_input_delay`,
  `set_output_delay`; `set_false_path`; `set_max_delay`; `set_logic_*`.
- Vivado-compatible glob / bus-bit wildcard expansion: `[*]`, `[?]`, and plain
  base-name matching against unexpanded bus bits.
- `PortConstraint` dataclass accumulates all constraints per port bit via
  `merge()`.

#### `parsers/rtl.py` — RTL port extractor

- `RTLPortExtractor` drives `pyslang` to parse SystemVerilog source files and
  return a list of `PortInfo` records (name, direction, width, MSB/LSB).
- `PortInfo.expand_bits()` flattens multi-bit ports to individual bit names for
  XDC matching.
- Top module auto-detection when `top_module` is `None`.

#### `generator/sby.py` — SymbiYosys script generator

- `SbyGenerator` / `SbyTask` replace the old ad-hoc `generate_sby()` function
  in `functions/formal.py`.
- `SbyEngine` constants for all common SMT solvers (`smtbmc yices`, `smtbmc z3`,
  `btor`, `abc pdr`, etc.) and a combinational mode.
- `SbyMode` constants: `bmc`, `prove`, `cover`, `live`.
- Fluent builder API for constructing multi-task `.sby` scripts.

#### `tools/symbiyosys.py` — SbyRunner

- Dedicated `SbyRunner` wrapping the `sby` binary, replacing the ad-hoc
  `subprocess` calls in `functions/formal.py`.
- Output classifier recognises `SBY … PASS/FAIL/UNKNOWN/ERROR/TIMEOUT` lines,
  per-engine status, cover-point hits, and VCD trace paths.
- `FormalResult` / `PropertyResult` dataclasses carry structured pass/fail
  outcome, elapsed time, and trace file paths per target.

#### `utils/job.py` — unified job execution

- New `Job` frozen dataclass encapsulates a command, working directory, dry-run
  flag, interactive flag, **detach mode**, and an output classifier.
- `JobResult` carries return code, elapsed time, captured output, and exception.
- `LiveSink` runs a single `Job` synchronously with full PTY / pipe / detach
  dispatch.
- `run_job_list()` drives a list of jobs either sequentially or in parallel via
  `ThreadPoolExecutor`, replacing `utils/parallel.py`'s `run_parallel()`.
- Detach mode (`job.detach = True`) forks a process and returns its PID
  immediately — used for launching Vivado GUI sessions.

#### `utils/stream.py` — process output streaming

- `stream_pipe()` — subprocess stdout/stderr captured line-by-line via
  `subprocess.PIPE`.
- `stream_pty()` — interactive subprocess through a pseudo-terminal, preserving
  ANSI colour and cursor control from Vivado's interactive console.
- `stream_popen()` — fire-and-forget detached process launch.
- `OutputLine` dataclass carries `text`, `level`, and `raw` fields.
- Replaces the ad-hoc PTY loop in the old `utils/process.py`.

#### `utils/display.py` — event-driven terminal display

- Structured display events: `EvDispatch`, `EvLine`, `EvComplete`, `EvSummary`.
- Parallel job output rendered as grouped, labelled blocks with coloured
  OK / FAILED status and elapsed time.
- Replaces the `_print_job()` logic scattered across `utils/parallel.py`.

#### `utils/theme.py` — centralised colour/style

- `Theme` class with `bold`, `dim`, `red`, `green`, `yellow`, `blue`, `cyan`,
  `magenta` helpers, all gated on `NO_COLOR` / `FORCE_COLOR` env vars and
  `sys.stdout.isatty()`.
- Global `theme_cfg` singleton imported across `functions/`, `utils/`, and
  `tools/`.
- Replaces the scattered `BOLD`, `DIM`, `GREEN`, `RED`, `RESET` constants that
  were imported directly from `utils/log.py`.

#### `utils/ascii_table.py` — table renderer

- `AsciiTable` renders aligned, bordered tables to the terminal.
- Used by `validate` to display per-port constraint coverage.

#### `utils/hash.py` — file fingerprinting

- `sha512_file(path)` for content-based staleness checks on source files.
- `SourceFile` hash bug fix: hash was not being recomputed after file path
  normalisation, causing false cache hits.

#### `config/params.py` — typed command parameters

- All per-command parameters factored out of the CLI layer into typed
  dataclasses: `CreateParams`, `IpCreateParams`, `BdCreateParams`,
  `CoreCreateParams`, `EditParams`, `GenerateParams`, `SynthParams`,
  `SimulateParams`, `ValidateParams`, `ProgramParams`, `ProcessorParams`,
  `AppBuildParams`, `PlatformBuildParams`, `AppCreateParams`,
  `PlatformCreateParams`, `OpenParams`.
- `SynthParams` carries `resume` and `parallel_subcore_synth`; `ValidateParams`
  carries `design`, `bd`, `core`, `io`, and `level`.
- Functions in `functions/` now receive a typed `params` object instead of
  individual keyword arguments, reducing call-site coupling.

### Changes

- **`utils/parallel.py` removed** — functionality absorbed into `utils/job.py`
  (`run_job_list`) and `utils/display.py`.
- **`utils/process.py` removed** — PTY streaming absorbed into `utils/stream.py`;
  Vivado output classification moved to `tools/vivado.py` (`VivadoRunner.classify`).
- **`tools/vivado.py` refactored** — `VivadoRunner` now uses `Job` / `LiveSink`
  internally; `run_vivado_xvlog` / `run_vivado_xelab` free functions removed in
  favour of `XvlogRunner`, `XelabRunner`, `XsimRunner` runner classes.
- **`functions/formal.py` overhauled** — inline `.sby` generation removed;
  delegates to `SbyGenerator` and `SbyRunner`. Adds parallel multi-target
  execution via `ThreadPoolExecutor`.
- **`generator/wrapper.py` simplified** — SV wrapper parser ported to use the
  new `RTLPortExtractor` from `parsers/rtl.py`; removed ~600 lines of
  duplicated `pyslang` traversal code.
- **`cmd_simulate` signature** — now accepts a `SimulateParams` dataclass
  instead of individual `uvm_name`, `run`, `mode` keyword args.
- **`cmd_synthesis` signature** — now accepts a `SynthParams` dataclass;
  `--usr-access-type` removed from the hot path (value derived from git SHA
  automatically).
- Dirty-tree warning on synthesis elevated from `INFO` to `WARNING`.

### Fixed

- **`usr_access_value`** — bitstream USR_ACCESS embedded value was silently
  dropped when `synth_cfg.usr_access_value` was set explicitly in `project.toml`;
  now correctly overrides the git-SHA path.
- **XSCT runner** — `XsctRunner` failed when the XSCT binary was found via
  `XVIV_VIVADO_SOURCE_SCRIPT` rather than `PATH`; fixed path resolution.
- **`SourceFile` hash** — hash was not recomputed after path normalisation,
  causing incorrect incremental-synthesis cache hits.
- **`ValidateCommand` loglevel** — `--level error` filter was not wired into the
  lint engine's output; now correctly suppresses `INFO`-level rows.

### Tests

- **Monolithic test files removed**: `test_2.py`, `test_comprehensive.py`,
  `test_functions.py`, `test_tcl_commands.py`, `test_tool_runners.py`.
- **Replaced with structured layout**:
  - `tests/unit/config/` — `test_loader`, `test_lock`, `test_model`,
    `test_project`, `test_project_resolve`, `test_project_synth`.
  - `tests/unit/generator/` — `test_tcl_builder`, `test_tcl_project`,
    `test_tcl_synth`.
  - `tests/unit/parsers/` — `test_bd_json`.
  - `tests/unit/tools/` — `test_verilator_runner`, `test_vivado_runner`,
    `test_xsct_runner`.
  - `tests/unit/utils/` — `test_display`, `test_error`, `test_fs`, `test_git`,
    `test_hash`, `test_job`, `test_stream`.
  - `tests/integration/` — `test_cli_dispatch`, `test_error_surfaces`,
    `test_lock_roundtrip`, `test_toml_fixtures`.
- `tests/fixtures/` — TOML fixture files: `minimal.toml`, `design_synth.toml`,
  `custom_ip_core.toml`, `multi_fpga.toml`, `simulation_xsim.toml`,
  `formal_all_modes.toml`; BD JSON fixtures `flat.bd.json`, `nested.bd.json`.
- `tests/conftest.py` and `tests/helpers.py` added for shared fixtures and
  assertion helpers.

---

## [0.2.7] - 2026-05-24

Largest release to date. The codebase was restructured into a proper
multi-package layout (`cli/`, `functions/`, `tools/`, `utils/`, `parsers/`,
`generator/tcl/`) and a significant amount of new functionality was added across
simulation, formal verification, XSCT/embedded, and TCL generation.

### Breaking changes

- `generate_config_tcl` removed; TCL generation is now entirely handled by the
`ConfigTclBuilder` / `ConfigTclCommands` class hierarchy in
`generator/tcl/builder.py` and `generator/tcl/commands.py`.
- `run_tcl` helper removed; tool runners in `tools/` call Vivado/XSCT directly.
- `typing.Optional` usage removed project-wide in favour of `X | None` union
syntax (requires Python >= 3.10).

### New features

#### Restructured package layout

- Source tree reorganised into focused sub-packages:
`cli/command/` (one module per subcommand), `functions/` (high-level command
logic), `tools/` (Vivado, XSCT, Verilator runner wrappers), `utils/`
(error, fs, git, log, parallel, process, tools helpers), `parsers/`
(BD JSON, `component.xml`, Vivado index XML), `generator/tcl/` (TCL builder),
`generator/hooks.py` (hooks file generators).
- `config/` split into `config/model.py`, `config/loader.py`,
`config/project.py`, `config/catalog.py`, and `config/tcl.py`.

#### `ConfigTclBuilder` / `ConfigTclCommands`

- New `ConfigTclBuilder` base class encapsulates all TCL script generation
primitives. `ConfigTclCommands` inherits from it and exposes high-level
command builders for IP, BD, core, synthesis, simulation, and XSCT workflows.
- A `_define_proc` guard decorator prevents duplicate proc definitions in
generated TCL.
- New TCL builder primitives cover XSCT/HSI, simulation waveform config, block
design lifecycle (`create`, `edit`, `generate`), and core (`create`, `edit`,
`generate`) operations.

#### Simulation

- `xsim` simulation pipeline now fully operational end-to-end: `xvlog` compile →
`xelab` elaborate → `xsim` run, with `-R` flag for immediate run-after-elab.
- Waveform configuration TCL (`waveform_config.tcl`) is generated automatically
before simulation.
- SDF annotation support (`--sdf`, `--sdfmax`) added to the elaborate command.
- `UVM` configuration support via `add_uvm_cfg` in `config/tcl.py`.

#### Formal verification

- `functions/formal.py` added: `SymbiYosys`-backed formal verification workflow
for bounded model checking and cover reachability analysis.
- `[[formal]]` sections supported in `project.toml`.

#### Verilator integration

- `tools/verilator.py` added with lint and simulation support.
- `verilator --lint-only` invoked via `xviv lint` when Verilator is available.

#### Design synthesis

- Custom (non-BD, non-IP) design synthesis flow (`cmd_design_synth`) now
operational, driven by `[[design]]` sections in `project.toml`.
- Synthesis configuration (`SynthConfig`) can be declared inline per design in
`project.toml` via `[design.<n>.synth]`.
- `dcp synth working` - DCP-mode synthesis path stabilised.
- Parallel synthesis via `utils/parallel.py` helper wrapping
`ThreadPoolExecutor`.

#### XSCT / embedded

- `functions/xsct.py` overhauled; XSCT commands (platform create/build, app
create/build, program, processor control) are now fully operational.
- `scripts/dispatch/xsct.tcl` added as the XSCT-side dispatcher.

#### Error handling and diagnostics

- `utils/error.py` centralises all exception types (`XvivError` hierarchy).
- Custom exceptions propagate through the CLI layer and produce clean
user-facing error messages without tracebacks.
- Assertions added to internal state transitions to catch mis-configuration
early.
- `require_project` guard added to all commands that need a loaded
`project.toml`.

#### BD improvements

- `bd --source-file <path|bool>` flag added to `create --bd` for explicit BD
TCL source file override.
- `bd close design` fix in `create --bd` prevents stale in-memory state.
- BD save-state TCL simplified; unnecessary regex removed.
- `generate --bd` now triggers automatically on GUI exit.
- `bd_core_list` return-value contract fixed.
- `create_bd_design` now creates its own subdirectory under the build tree.

#### IP / core

- IP create and edit pipeline confirmed working end-to-end.
- `generate --all` regenerates all cores after a `create --ip` run.
- XCI file existence check added before generating a core to avoid redundant
Vivado invocations.
- `is_stale()` utility used in `generate_bd` to skip up-to-date outputs.
- OOC synthesis for cores (`eecfd78`) confirmed working.
- IP repo list fix (`22571bf`).
- IPGUI and wrapper generation fixes.

#### Tests

- New test suite added under `tests/`:
- `test_project_config.py` - `ProjectConfig` dataclass parsing and validation.
- `test_tcl_commands.py` - `ConfigTclCommands` output correctness.
- `test_functions.py` - high-level command function integration tests.
- `test_tool_runners.py` - `tools/vivado.py`, `tools/xsct.py` runner unit
	tests.
- Pre-commit hooks configured (`.pre-commit-config.yaml`).
- GitHub Actions workflow updated to run the test suite.

#### Miscellaneous

- `utils/tools.py` and `utils/error.py` improved for robustness.
- `sources` glob resolution fix in `config/loader.py`.
- Section register fix in constraint-set handling (`constrs_set`).
- `xelab` fix for elaboration argument ordering.
- README revised: completion setup instructions clarified, project layout
section expanded.

---

## [0.2.6] - 2026-04-20

### Added

- `xviv create --edit` flag (replaces the old `--gui`): opens Vivado in GUI mode
for BD/IP creation, consistent with the `edit` subcommand naming.
- `xelab -R` support: elaborate and run simulation in a single step.
- `core_state_tcl` added to the core workflow for persisting core state between
sessions analogously to BD state.
- Utilisation reports written to `reports/utilisation/` after synthesis.
- Environment variable support for Vivado/Vitis paths via `XVIV_VIVADO_DIR` and
`XVIV_VITIS_DIR` (in addition to `project.toml`-level config).

### Fixed

- `catalog.py` core-listing fix for entries with missing metadata fields.
- `version` reporting bug resolved.
- `config --synth` incorrectly mutating config state - fixed.
- `bd export` command removed (superseded by BD state TCL workflow from v0.2.2).
- `open --nogui` flag now correctly passed through to Vivado for TCL-mode
sessions.

### Changed

- Build artefact directory restructure: synthesis outputs organised more
consistently under `build/synth/`.
- Small robustness fixes across `catalog.py`, `project.py`, and BD generation.

---

## [0.2.5] - 2026-04-19

Packaging fix release.

### Fixed

- `hatchling` VCS version source (`hatch-vcs`) properly wired in `pyproject.toml`
so `pip install` from a git checkout derives the version from the tag rather
than falling back to `0.0.0`.
- Hatchling build backend entry corrected.

---

## [0.2.4] - 2026-04-19

Packaging fix release.

### Fixed

- `pyproject.toml` dependency and metadata corrections following the v0.2.3
upload.

---

## [0.2.3] - 2026-04-19

Packaging fix release.

### Fixed

- `--verbose` flag added to the `twine upload` step in the publish workflow to
surface upload errors that were previously swallowed silently.

---

## [0.2.2] - 2026-04-19

### Breaking changes

- **BD export command removed.** `export --bd` is superseded by the new BD state
TCL workflow. The persistent re-runnable script is now managed automatically
under `scripts/bd/state/` (previously `scripts/bd/export/`).
- **`[sources]` section removed** from `project.toml`. RTL sources for synthesis
are now declared directly under each `[[synthesis]]` or `[[ip]]` entry.
- The `generate_config_tcl` summary output that was printed to stdout on every
command is now suppressed by default; pass `--verbose` to restore it.

### Added

- **BD state TCL.** `scripts/bd/state/<bd_name>.tcl` replaces the old export
file. The state script is written on every `generate --bd` or GUI-close,
keeping a complete, reproducible record of the BD without requiring manual
exports.
- **Core catalog.** New `xviv search --core <query>` command searches the Vivado
IP catalog. Versioned core instance tab-completion (`--core`) is wired into the
argcomplete setup. `xviv --vlnv <vlnv> --core <name>` convenience shorthand
added.
- **Core creation.** `xviv create --core <name>` scaffolds a new packaged IP core
(without the `-driver` peripheral option that was used in older Vivado flows).
- **`[[simulate]]` section** added to `project.toml` schema. Declares simulation
tops alongside optional RTL-only source overrides. `cmd_top_simulate` wired up
correspondingly.
- **Synthesis options.** `[[synthesis]]` entries now accept an `options` sub-table
for per-run Vivado synthesis flags (e.g. `flatten_hierarchy`, `directive`).
Implementation is stubbed; flags are passed to TCL but not all are consumed yet.
- **Utilisation reports.** `xviv reports/utilisation` writes a post-synthesis
resource utilisation report to `reports/utilisation/<top>.rpt`.
- **`.cue` config support.** `project.toml` can be co-located with a `.cue` file
for schema validation (optional; has no runtime effect).
- **FPGA default resolution.** When an `[[ip]]` or `[[bd]]` entry omits `fpga =`,
the project-level `[fpga]` target is used automatically.
- **Config TCL summary.** `generate --bd` / `config --ip` now emit a structured
summary of the resolved configuration before invoking Vivado.
- **`open --nogui` flag.** Opens a Vivado TCL console without a GUI for
non-interactive DCP/snapshot inspection.
- **`proc xviv_add_xdc_sources`** added to TCL infrastructure for constraint-set
management.
- **`elaborate` → renamed to `elab`** for consistency. Old `elaborate` alias
retained.
- Hooks system fixed; hook procs are called correctly at synthesis lifecycle
stages.

### Changed

- `scripts/bd/` directory layout: `export/` → `state/`; `bd_export_tcl` →
`bd_state_tcl` throughout Python and TCL.
- BD recreation from state TCL is now the default path when a state file exists;
interactive GUI is only opened when no state is available.
- `cmd_create_bd` checks for the state TCL file existence before deciding
whether to run interactively.
- SHA tag is only embedded in build artefact names when the project directory is
a git repository; non-git projects fall back to a datestamp.
- Synth artefact directory restructured for better isolation of multiple synth
runs.
- `tcl --nogui` mode used for `edit --bd` and `edit --ip` when invoked from a
scripted context.
- Temporary removal of `bd_deps.py` and `inference.py` pending the module
restructure in v0.2.7.

### Fixed

- `fix create --bd` - BD creation from state TCL path resolution corrected.
- `fix export bd tcl` - TCL path substitution fixed for relocated project roots.
- `cmd_create_bd` / `xviv_bd_state_tcl` file-existence check order corrected.
- IP create: `remove hdl dir` and `remove -driver in create peripheral` - both
caused errors in Vivado 2025.x peripheral packaging flows.
- `pyproject.toml` entry-point fix.

---

## [0.2.0] - 2026-04-14

Complete rewrite. Single-file CLI replaced by a modular package. See below for
full details; the summary is reproduced from the `CHANGELOG` file committed at
this tag.

### Breaking changes

- **CLI redesign.** All commands are now grouped under verb subcommands rather
than hyphenated names. The old flat-command style (`create-ip`, `edit-bd`,
`synthesis`, `elaborate`, `open-wdb`, etc.) is replaced by a two-token style:

| 0.1.x command | 0.2.0 command |
|---|---|
| `create-ip --ip <n>` | `create --ip <n>` |
| `edit-ip --ip <n>` | `edit --ip <n>` |
| `ip-config --ip <n>` | `config --ip <n>` |
| `create-bd --bd <n>` | `create --bd <n>` |
| `edit-bd --bd <n>` | `edit --bd <n>` |
| `generate-bd --bd <n>` | `generate --bd <n>` |
| `bd-config --bd <n>` | `config --bd <n>` |
| `synthesis --top <n>` | `synth --top <n>` |
| `synth-config --top <n>` | `config --top <n>` |
| `elaborate --top <n>` | `elab --top <n>` |
| `open-dcp --top <n>` | `open --dcp <stem> --top <n>` |
| `open-snapshot --top <n>` | `open --snapshot --top <n>` |
| `open-wdb --top <n>` | `open --wdb --top <n>` |
| `reload-snapshot --top <n>` | `reload --snapshot --top <n>` |
| `reload-wdb --top <n>` | `reload --wdb --top <n>` |

- **`project.toml` schema changes.** The `[synthesis]` section key `constrs` is
renamed `xdc`. Constraint files for IPs and BDs are now declared under `xdc`
and `xdc_ooc` per-entry keys. The `wrapper` source glob is replaced by the
`[build] wrapper_dir` path.

- **Entry point renamed.** The `cli.py` / `wrap_top.py` entry points are
replaced by `xviv.py` and `wrapper.py` respectively, with `__main__.py` added
for `python -m xviv` invocation.

- **`elaborate` → `elab`.** The `--so` / `--dpi-lib` DPI options are no longer
supported (they were unused and coupled to the old Vivado-project simulation
flow, superseded by the standalone xvlog/xelab flow).

### Added

#### Block design export / import workflow

- New `export --bd <n>` command exports the BD as a versioned, self-contained
re-runnable TCL script. The output filename encodes the git SHA tag; a stable
symlink at `<bd_name>.tcl` is updated atomically after each export.
- `create --bd` auto-sources the exported TCL when it exists, recreating the BD
non-interactively. When no export TCL is found, the GUI opens.
- `config --bd` generates a hooks file that includes a `bd_design_config` proc
wired to the export TCL path, enabling the full create → design → export → recreate
round-trip automatically.

#### Out-of-context BD synthesis

- New `synth --bd <n>` command runs a two-phase OOC synthesis flow: each leaf IP
is synthesised out-of-context first (cached by DCP mtime vs `component.xml`),
then the BD wrapper is synthesised with the OOC DCPs loaded as black-box
replacements. Incremental re-use of the previous `post_route.dcp` is applied
automatically when available.

#### Vitis / embedded processor support

New `xsct`-backed commands:

- `create --platform <n>` - generate a BSP from the XSA using `hsi::generate_bsp`.
- `build --platform <n>` - compile the BSP with `make`.
- `create --app <n>` - scaffold a Vitis application from a template.
- `build --app <n>` - compile the application.
- `program` - download bitstream and/or ELF over JTAG.
- `processor --reset | --status` - soft-reset or inspect the embedded processor.

`xviv_xsct.tcl` implements all XSCT-side logic.

#### Shell completion

- Tab completion for all subcommands and arguments via `argcomplete`. Activate
with `eval "$(register-python-argcomplete xviv)"`.

#### Build manifests and git SHA tagging

- Synthesis outputs are named with the short git SHA (e.g. `top_abc1234.bit`);
a stable symlink `<top>.bit` always points at the latest build.
- `build.json` manifest written after each successful synthesis run (Vivado
version, part, top, git SHA, dirty flag, elapsed time, timestamp).
- Git SHA embedded into the bitstream's `USR_ACCESS` register for readback via
JTAG.

#### Typed configuration system

- `project.toml` parsed into a `ProjectConfig` dataclass tree. All raw dict
access confined to `_parse_*` functions in `config.py`.
- Named FPGA targets: `[fpga.<name>]` entries referenceable from `[[ip]]`,
`[[bd]]`, or `[[synthesis]]` via `fpga = '<name>'`.
- `hw_server` configurable under `[vivado] hw_server = 'host:port'`.

#### Improved TCL infrastructure

- Monolithic `scripts/xviv.tcl` split into focused files per command.
- `xviv_die`, `xviv_require_vars`, `xviv_elapsed`, `xviv_stage`,
`xviv_create_project`, `xviv_add_rtl_sources`, `xviv_update_symlink`,
`xviv_write_manifest` added.
- IP creation split into staged scaffold procs.

### Changed

- Elaboration outputs moved to `build/elab/<top>/`.
- `bd_design_config` hooks file now includes synthesis lifecycle stubs.
- Physical optimisation (`phys_opt_design`) only runs when timing fails after
placement.
- Logger hierarchy rooted at `xviv` across all modules; log file at
`build/xviv/xviv.log`.

### Internal

- `cli.py` removed; logic split across `xviv.py`, `command.py`, `config.py`,
`hooks.py`, `vivado.py`, `waveform.py`, `wrapper.py`, `utils.py`, `vitis.py`,
`platform.py`.

---

## [0.1.2] - 2026-04-04

Initial public release. Single-file CLI (`cli.py`) with flat subcommands backed
by a monolithic `scripts/xviv.tcl`.

### Added

- `create-ip`, `edit-ip`, `ip-config` commands for custom IP packaging.
- `create-bd`, `edit-bd`, `generate-bd`, `bd-config` commands for block design
management.
- `synthesis`, `synth-config` commands for non-project-mode synthesis.
- `elaborate`, `open-wdb`, `open-dcp`, `open-snapshot`, `reload-snapshot`,
`reload-wdb` commands for simulation and checkpoint inspection.
- `project.toml` as the single project configuration file; `[[ip]]`, `[[bd]]`,
`[[synthesis]]` sections with `part`, `xdc`, `rtl`, and `hooks` fields.
- `xviv_wrap_top` SV wrapper generator invokable via `xviv_wrapper` entry point.
- GitHub Actions publish workflow (`publish.yml`).
- MIT licence.