virtuoso-cli 0.1.2

CLI tool to control Cadence Virtuoso from anywhere, locally or remotely
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
# vcli — Virtuoso CLI

<p align="center">
  <a href="https://crates.io/crates/virtuoso-cli"><img src="https://img.shields.io/crates/v/virtuoso-cli.svg" alt="crates.io"/></a>
  <a href="https://www.rust-lang.org/"><img src="https://img.shields.io/badge/rust-1.75+-blue.svg" alt="Rust 1.75+"/></a>
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License: MIT"/></a>
  <a href="https://github.com/deanyou/virtuoso-cli/actions"><img src="https://github.com/deanyou/virtuoso-cli/actions/workflows/ci.yml/badge.svg" alt="CI"/></a>
</p>

<p align="center">
  <a href="#english">English</a> | <a href="#中文">中文</a>
</p>

---

## English

Control Cadence Virtuoso from anywhere — locally or remotely. Designed for AI Agents and humans alike.

> **Based on** [virtuoso-bridge-lite]https://github.com/Arcadia-1/virtuoso-bridge-lite by Arcadia-1.
> `vcli` is a full Rust rewrite and major extension of that project, adding multi-session support, dynamic port assignment, session registry, an agent-native CLI, and Spectre simulation integration.

### Overview

`vcli` is a lightweight Rust-based bridge tool for executing SKILL code outside of Virtuoso. It starts a Rust daemon inside Virtuoso via `ramic_bridge.il`, which accepts commands over TCP, calls `evalstring`, and returns results.

### Key Features

- **Multi-session support** — Multiple Virtuoso instances on the same server each get a unique session ID and random port, with no conflicts
- **Dynamic port assignment** — Daemon binds port 0 (OS assigns), eliminating port collision
- **Session auto-discovery** — Single session connects automatically; multiple sessions require `--session` or `VB_SESSION`
- **Three programming modes** — Raw SKILL expressions, high-level API, or load `.il` files directly
- **Local + remote modes** — Direct local connection or SSH tunnel with ControlMaster multiplexing
- **Agent-native CLI** — Noun-verb command structure, JSON structured output, schema introspection, semantic exit codes
- **Schematic editing & reading** — Create, place, wire, connect + read instances, nets, pins, parameters
- **Maestro ADE management** — Open/close Explorer (`maestro`) view sessions, set variables, run simulations, export results (IC23.1+ unified ADE)
- **Spectre simulation** — Sync/async simulation, job registry with status tracking, PSF parser
- **Multi-profile support**`--profile` flag for concurrent connections to multiple Virtuoso instances
- **Command logging** — All SKILL executions logged to `~/.cache/virtuoso_bridge/logs/commands.log`
- **Interactive TUI**`vtui` terminal dashboard showing sessions, jobs, tunnel status

### Installation

**From crates.io (recommended):**

```bash
cargo install virtuoso-cli                          # vcli (main CLI)
cargo install virtuoso-cli --bin vtui               # vtui (interactive TUI dashboard)
cargo install virtuoso-cli --features daemon        # virtuoso-daemon (bridge backend)
```

**From source:**

```bash
git clone https://github.com/deanyou/virtuoso-cli.git
cd virtuoso-cli
cargo install --path .
```

All binaries (`vcli`, `vtui`) are installed to `~/.cargo/bin/`.

> **Note**: Do not name the binary `virtuoso` — it conflicts with Cadence's `virtuoso` executable.

### Quick Start

**1. Load RAMIC Bridge in Virtuoso CIW:**

```skill
load("/path/to/virtuoso-cli/resources/ramic_bridge.il")
vcli()
```

Output:
```
┌─────────────────────────────────────────┐
│  vcli (Virtuoso CLI Bridge) — Ready     │
├─────────────────────────────────────────┤
│  Session : eda-meow-1                   │
│  Port    : 42109                        │
├─────────────────────────────────────────┤
│  Terminal: vcli skill exec 'version()'  │
│  Sessions: vcli session list            │
└─────────────────────────────────────────┘
```

Add to `~/.cdsinit` for automatic loading on Virtuoso startup:
```skill
load("/path/to/virtuoso-cli/resources/ramic_bridge.il")
vcli()
```

**2. Connect from terminal:**

```bash
vcli session list                                        # list active sessions
vcli skill exec 'getCurrentTime()'                       # auto-connects if single session
vcli --session eda-meow-2 skill exec 'getCurrentTime()' # specify session explicitly
```

**Remote mode:**
```bash
vcli init           # generate .env template
# edit .env: set VB_REMOTE_HOST, VB_SPECTRE_CMD (absolute path)
vcli tunnel start
vcli skill exec 'getCurrentTime()'
vcli tunnel stop
```

**Remote async simulation:**
```bash
vcli sim run-async --netlist my_tb.scs   # launch on remote server, return immediately
vcli sim job-list                        # check all jobs (auto-refreshes status via SSH)
vcli sim job-status <id>                 # detailed status for one job
vcli sim job-cancel <id>                 # kill remote spectre process
```

**Maestro ADE Explorer (IC23.1+):**
```bash
# IC23.1 unified ADE uses "maestro" view (formerly adexl/ade_xl)
vcli maestro open --lib myLib --cell myCell            # defaults to view=maestro
vcli maestro set-var --session fnxSession4 --name W --value 10u
vcli maestro run --session fnxSession4                 # async run
vcli maestro export --session fnxSession4 --path out.csv
```

### Multi-Session Architecture

```
Virtuoso-1 → vcli() → daemon on port 42109 → session: eda-meow-1
Virtuoso-2 → vcli() → daemon on port 51337 → session: eda-meow-2

Terminal A: vcli skill exec '...'                  # auto-selects (single session)
Terminal B: vcli --session eda-meow-2 skill exec   # explicit selection
```

Session files: `~/.cache/virtuoso_bridge/sessions/<id>.json`

### Command Reference

```
vcli [--profile P] [--session S] [--format json|table]
├── init                              Generate .env config template
├── session                           Manage bridge sessions
│   ├── list                              List all active sessions
│   └── show [id]                         Show session details
├── tunnel                            Manage SSH tunnel
│   ├── start [--timeout N] [--dry-run]
│   ├── stop [--force] [--dry-run]
│   ├── restart [--timeout N]
│   ├── status
│   └── diagnose                          Full connection diagnostics
├── skill                             Execute SKILL code
│   ├── exec <code> [--timeout N]
│   └── load <file>
├── cell                              Manage cellviews
│   ├── open --lib L --cell C [--view V] [--mode M] [--dry-run]
│   ├── save / close / info
├── schematic                         Schematic editing & reading
│   ├── open / save / check / build --spec file.json
│   ├── place / wire / conn / label / pin
│   ├── list-instances / list-nets / list-pins
│   └── get-params --inst M1
├── maestro                           Maestro ADE Explorer (maestro view) sessions
│   ├── open --lib L --cell C
│   ├── close / list-sessions / save
│   ├── set-var / get-analyses / add-output
│   ├── run / export
├── sim                               Simulation
│   ├── setup / run / measure / sweep / corner
│   ├── run-async --netlist file.scs
│   ├── job-status / job-list / job-cancel
│   └── results / netlist
├── design                            gm/Id sizing tools
│   ├── size / explore
├── process                           Process characterization
│   └── char [--netlist]
└── schema [--all] [noun] [verb]      Output command schema (for Agent discovery)
```

### Configuration

| Variable | Default | Description |
|----------|---------|-------------|
| `VB_SESSION` || Target session ID (for multi-instance) |
| `VB_PORT` | per-user hash | Direct port (fallback when no session file) |
| `VB_REMOTE_HOST` || SSH remote hostname or alias |
| `VB_REMOTE_USER` | current user | SSH login username |
| `VB_JUMP_HOST` || Bastion/jump host address |
| `VB_TIMEOUT` | `30` | Connection/execution timeout (seconds) |
| `VB_PROFILE` || Config profile (reads `VB_*_<profile>` vars) |
| `RB_DAEMON_PATH` | auto-detected | Override daemon binary path |

### How It Works

```
Terminal                      Virtuoso Process
────────                      ────────────────

vcli skill exec "1+2"
      │ TCP: {"skill":"1+2"}
      ├──────────────────► virtuoso-daemon (port 42109)
      │                          │
      │                          │ evalstring("1+2")
      │                          │
      │ TCP: "3"
      ◄──────────────────────────┘
```

Session registration flow:
```
vcli() in CIW
  → RBStart(): ipcBeginProcess(daemon, port=0)
  → OS assigns port N; daemon prints "PORT:N" to stderr
  → RBIpcErrHandler: RBPort=N, writes session file
  → ~/.cache/virtuoso_bridge/sessions/<id>.json

vcli session list  # reads session files
vcli skill exec    # connects to port N
```

---

## 中文

从任何地方控制 Cadence Virtuoso,本地或远程均可。为 AI Agent 和人类共同设计。

> **基于** [virtuoso-bridge-lite]https://github.com/Arcadia-1/virtuoso-bridge-lite(作者 Arcadia-1)重构。
> `vcli` 是对该项目的完整 Rust 重写与大幅扩展,新增了多 session 支持、动态端口分配、session 注册表、Agent 原生 CLI 以及 Spectre 仿真集成。

### 简介

`vcli` 是一个用 Rust 编写的轻量级桥接工具,用于在 Virtuoso 外部执行 SKILL 代码。它通过 `ramic_bridge.il` 在 Virtuoso 内启动一个 Rust daemon,并通过 TCP 接收来自 CLI 的命令,调用 `evalstring` 执行 SKILL 并返回结果。

### 核心特性

- **多 session 支持** — 同一台服务器上可同时运行多个 Virtuoso 实例,每个实例自动分配唯一 session_id 和随机端口,互不干扰
- **动态端口分配** — daemon 绑定端口 0(OS 自动分配),彻底避免端口冲突
- **session 自动发现** — 只有一个 session 时无需指定;多个 session 时通过 `--session``VB_SESSION` 选择
- **三种编程方式** — 原始 SKILL 表达式、高阶 API、或直接加载 .il 文件
- **本地+远程模式** — 支持本地直连或 SSH 隧道(ControlMaster 连接复用)
- **Agent 原生 CLI** — noun-verb 命令结构、JSON 结构化输出、schema 自省、语义化退出码
- **原理图编辑与读取** — 创建、放置、连线 + 读取实例/网络/引脚/参数
- **Maestro ADE 管理** — 打开/关闭 Explorer(`maestro` view)session、设置变量、运行仿真、导出结果(IC23.1+ 统一 ADE)
- **Spectre 仿真** — 同步/异步仿真、Job 注册与状态跟踪、PSF 结果解析
- **多 Profile 支持**`--profile` 参数支持同时连接多个 Virtuoso 实例
- **命令日志** — 所有 SKILL 调用记录到 `~/.cache/virtuoso_bridge/logs/commands.log`
- **交互式 TUI**`vtui` 终端仪表盘,实时显示 session、仿真 job、隧道状态

### 安装

**从 crates.io 安装(推荐):**

```bash
cargo install virtuoso-cli                          # vcli(主 CLI)
cargo install virtuoso-cli --bin vtui               # vtui(交互式 TUI 仪表盘)
cargo install virtuoso-cli --features daemon        # virtuoso-daemon(bridge 后端)
```

**从源码安装:**

```bash
git clone https://github.com/deanyou/virtuoso-cli.git
cd virtuoso-cli
cargo install --path .
```

安装后 `vcli` 和 `virtuoso-daemon` 均位于 `~/.cargo/bin/`。

> **注意**:不要将 CLI 命名为 `virtuoso`,与 Cadence Virtuoso 二进制名冲突。

### 快速开始

**第一步:在 Virtuoso CIW 中加载 RAMIC Bridge:**

```skill
load("/path/to/virtuoso-cli/resources/ramic_bridge.il")
vcli()
```

输出:
```
┌─────────────────────────────────────────┐
│  vcli (Virtuoso CLI Bridge) — Ready     │
├─────────────────────────────────────────┤
│  Session : eda-meow-1                   │
│  Port    : 42109                        │
├─────────────────────────────────────────┤
│  Terminal: vcli skill exec 'version()'  │
│  Sessions: vcli session list            │
└─────────────────────────────────────────┘
```

在 `~/.cdsinit` 中加入以下内容,实现 Virtuoso 启动时自动加载:
```skill
load("/path/to/virtuoso-cli/resources/ramic_bridge.il")
vcli()
```

**第二步:从终端连接:**

```bash
vcli session list                                        # 查看所有活跃 session
vcli skill exec 'getCurrentTime()'                       # 单 session 时自动连接
vcli --session eda-meow-2 skill exec 'getCurrentTime()' # 多 session 时指定目标
```

**远程模式:**
```bash
vcli init           # 生成 .env 配置模板
# 编辑 .env:设置 VB_REMOTE_HOST、VB_SPECTRE_CMD(绝对路径)
vcli tunnel start
vcli skill exec 'getCurrentTime()'
vcli tunnel stop
```

**远程异步仿真:**
```bash
vcli sim run-async --netlist my_tb.scs   # 在远程服务器启动仿真,立即返回
vcli sim job-list                        # 查看所有 job(通过 SSH 自动刷新状态)
vcli sim job-status <id>                 # 查看单个 job 详情
vcli sim job-cancel <id>                 # 终止远程 spectre 进程
```

**Maestro ADE Explorer(IC23.1+):**
```bash
# IC23.1 统一 ADE 使用 "maestro" view(旧版本为 adexl/ade_xl)
vcli maestro open --lib myLib --cell myCell            # 默认 view=maestro
vcli maestro set-var --session fnxSession4 --name W --value 10u
vcli maestro run --session fnxSession4                 # 异步运行
vcli maestro export --session fnxSession4 --path out.csv
```

### 多 Session 工作原理

```
Virtuoso-1 → vcli() → daemon on port 42109 → session: eda-meow-1
Virtuoso-2 → vcli() → daemon on port 51337 → session: eda-meow-2

终端 A: vcli skill exec '...'                  # 自动连接(单 session)
终端 B: vcli --session eda-meow-2 skill exec   # 显式指定
```

Session 注册文件保存在 `~/.cache/virtuoso_bridge/sessions/<id>.json`。

### 命令参考

```
vcli [--profile P] [--session S] [--format json|table]
├── init                              创建 .env 配置模板
├── session                           管理 bridge session
│   ├── list                              列出所有活跃 session
│   └── show [id]                         查看 session 详情
├── tunnel                            管理 SSH 隧道
│   ├── start / stop / restart / status
│   └── diagnose                          完整连接诊断
├── skill                             执行 SKILL 代码
│   ├── exec <code> [--timeout N]
│   └── load <file>
├── cell                              管理 cellview
│   ├── open / save / close / info
├── schematic                         原理图编辑与读取
│   ├── open / save / check / build --spec file.json
│   ├── place / wire / conn / label / pin
│   ├── list-instances / list-nets / list-pins
│   └── get-params --inst M1
├── maestro                           Maestro ADE Explorer(maestro view)仿真
│   ├── open / close / list-sessions / save
│   ├── set-var / get-analyses / add-output
│   ├── run / export
├── sim                               仿真
│   ├── setup / run / measure / sweep / corner
│   ├── run-async / job-status / job-list / job-cancel
│   └── results / netlist
├── design                            gm/Id 设计工具
├── process                           工艺表征
└── schema [--all] [noun] [verb]      输出命令 schema(供 Agent 发现)
```

### 配置说明

| 变量 | 默认值 | 说明 |
|------|--------|------|
| `VB_SESSION` | - | 目标 session ID(多实例时使用) |
| `VB_PORT` | 按用户名 hash | 直连端口(无 session 文件时的回退值) |
| `VB_REMOTE_HOST` | - | SSH 远程主机名或别名 |
| `VB_REMOTE_USER` | 当前用户 | SSH 登录用户名 |
| `VB_JUMP_HOST` | - | 跳板机/堡垒机地址 |
| `VB_TIMEOUT` | `30` | 连接/执行超时(秒) |
| `VB_PROFILE` | - | 配置 profile(读取 `VB_*_<profile>` 变量) |
| `RB_DAEMON_PATH` | 自动检测 | 覆盖 daemon 二进制路径 |

### 工作原理

```
终端                          Virtuoso 进程
────                          ─────────────

vcli skill exec "1+2"
      │ TCP: {"skill":"1+2"}
      ├──────────────────► virtuoso-daemon (port 42109)
      │                          │
      │                          │ evalstring("1+2") → "3"
      │                          │
      │ TCP: "3"
      ◄──────────────────────────┘
```

Session 注册流程:
```
vcli() in CIW
  → RBStart(): ipcBeginProcess(daemon, port=0)
  → OS 分配端口 N;daemon 打印 "PORT:N" 到 stderr
  → RBIpcErrHandler: RBPort=N,写入 session 文件
  → ~/.cache/virtuoso_bridge/sessions/<id>.json

vcli session list  # 读取 session 文件
vcli skill exec    # 连接到端口 N
```

---

## License / 许可证

MIT License — see [LICENSE](LICENSE)