-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathcli.html
More file actions
2611 lines (2593 loc) · 155 KB
/
Copy pathcli.html
File metadata and controls
2611 lines (2593 loc) · 155 KB
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
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>circuitRF — The Command Line</title>
<link rel="icon" href="../assets/img/favicon.svg" type="image/svg+xml">
<link rel="stylesheet" href="../assets/css/circuitrf-docs.css">
<!--
GENERATED FILE - do not edit. Edit the Markdown source named below and re-run:
dotnet run [project tools/DocGen] [flag out] docs/user
(XML comments cannot contain a double hyphen; the flags are ordinary ones.)
Source: docs/user/src/reference/cli.md
-->
</head>
<body>
<header class="doc-header">
<a class="brand" href="../index.html"><img class="logo" src="../assets/img/favicon.svg" alt="circuitRF"><span class="wordmark">circuitRF</span></a>
<span class="doc-kind">Reference Guide</span>
<div class="doc-search" data-crf-search data-root="../" hidden>
<input type="search" class="search-input" autocomplete="off" spellcheck="false"
aria-label="Search the documentation" placeholder="Search docs"
role="combobox" aria-expanded="false" aria-autocomplete="list">
<div class="search-panel" role="listbox" hidden></div>
</div>
</header>
<hr class="doc-headrule">
<main class="page">
<p class="breadcrumb"><a href="../index.html">Docs</a> › <a href="index.html">Reference</a> › The command line</p>
<h1>The Command Line</h1>
<p class="lede">circuitRF runs without the GUI — not just its engines, but authoring, validation, resolution and drawing too. One executable, fifteen verbs — S-parameters, DC, harmonic balance, loadpull, loadpull pursuit, electromagnetic extraction, layout interchange, creating a workspace or a cell, importing a part, rendering a document as a picture, checking a design, explaining what it resolved to, reading a result back, an elaborated-netlist dump, and an MCP server. Every one of them answers --json. This chapter is the operational reference for all of them, including a worked EM run and a worked render, each from an empty folder.</p>
<nav class="toc">
<h2>On this page</h2>
<ol>
<li><a href="#invoking">Invoking it</a></li>
<li><a href="#verbs">The verbs at a glance</a></li>
<li><a href="#channels">Results on stdout, everything else on stderr</a></li>
<li><a href="#common">Options every verb takes</a></li>
<li><a href="#sparam"><code>sparam</code> — S-parameters</a></li>
<li><a href="#dc"><code>dc</code> — the operating point</a></li>
<li><a href="#hb"><code>hb</code> — harmonic balance</a></li>
<li><a href="#lp"><code>lp</code> — loadpull</a></li>
<li><a href="#lpp"><code>lpp</code> — loadpull pursuit</a></li>
<li><a href="#em"><code>em</code> — electromagnetic extraction</a></li>
<li><a href="#convert"><code>convert</code> — layout interchange</a></li>
<li><a href="#new"><code>new</code> — a workspace or a cell</a></li>
<li><a href="#import"><code>import part</code> — a footprint and its symbol</a></li>
<li><a href="#render"><code>render</code> — a picture of a document</a>
<ol>
<li><a href="#render-viewport">The viewport, and the unit rule</a></li>
<li><a href="#render-detail">Size, and what <code>--detail</code> costs</a></li>
<li><a href="#render-layers">Layers and colour</a></li>
<li><a href="#render-cdd">A data display</a></li>
<li><a href="#render-example">A worked example, from an empty folder</a></li>
</ol>
</li>
<li><a href="#check"><code>check</code> — is it sound?</a></li>
<li><a href="#explain"><code>explain</code> — what did it resolve to?</a>
<ol>
<li><a href="#explain-cells">What cells are in here?</a></li>
<li><a href="#explain-layers">What layers may I ask for?</a></li>
<li><a href="#explain-extents">How big is it?</a></li>
</ol>
</li>
<li><a href="#read"><code>read</code> — a result or a document, back</a></li>
<li><a href="#netlist"><code>netlist</code> — the netlist a schematic runs as</a></li>
<li><a href="#plot"><code>plot</code> — a picture of a result</a></li>
<li><a href="#find"><code>find</code> — what is in this folder?</a></li>
<li><a href="#reference"><code>reference</code> — what may I write?</a></li>
<li><a href="#elab"><code>elab</code> — the elaborated netlist</a></li>
<li><a href="#json"><code>--json</code> — one machine-readable document</a></li>
<li><a href="#serve"><code>serve</code> — the MCP server</a></li>
<li><a href="#exit">Exit codes</a></li>
<li><a href="#scripting">Scripting patterns</a></li>
</ol>
</nav>
<h2 id="invoking">Invoking it</h2>
<p>The command-line driver is the same program as the GUI's Run button with the window taken off. It
reads the same files, elaborates them with the same elaborator, runs the same engines, and evaluates
the test bench's <code>measure</code> lines with the same evaluator.</p>
<pre><code class="cmd"><span class="prompt">$ </span>circuitrf <verb> <file> [options]</code></pre>
<p>From a source checkout there is no <code>circuitrf</code> on your path yet, so put <code>dotnet run --project src/Cli --</code>
wherever <code>circuitrf</code> appears:</p>
<pre><code class="cmd"><span class="prompt">$ </span>dotnet run --project src/Cli -- sparam mycircuit.cnl --freq 1GHz:3GHz:50MHz</code></pre>
<p>Run it with no arguments for the built-in help.</p>
<div class="callout note">
<span class="label">A file that works headless works when opened</span>
<p>This is the point of the command line being the <em>same</em> code rather than a second
implementation. A <code>.cnl</code> that runs here runs when you open it in the workspace, and an EM
setup run with <code>em</code> writes the byte-identical Touchstone the <b>Simulate</b> button writes.
There is one elaborator, one set of engines, one measurement evaluator and one results-path
convention behind both.</p>
</div>
<h2 id="verbs">The verbs at a glance</h2>
<table>
<thead>
<tr>
<th>Verb</th>
<th>Takes</th>
<th>Runs</th>
<th>Writes</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>sparam</code></td>
<td><code>.cnl</code> or <code>.csch</code></td>
<td>The linear S-parameter engine over a frequency sweep</td>
<td>A Touchstone <code>.sNp</code>, always</td>
</tr>
<tr>
<td><code>dc</code></td>
<td><code>.cnl</code> or <code>.csch</code></td>
<td>The nonlinear DC engine</td>
<td>Node voltages and probe currents, to stdout</td>
</tr>
<tr>
<td><code>hb</code></td>
<td><code>.cnl</code> or <code>.csch</code></td>
<td>Harmonic balance, single- or multi-tone</td>
<td>Spectra tables to stdout; <code>-o .mat/.npy/.txt</code></td>
</tr>
<tr>
<td><code>lp</code></td>
<td><code>.cnl</code> or <code>.csch</code></td>
<td>Loadpull over the directive's Γ grid</td>
<td>A per-Γ-point table; <code>-o .mat/.npy/.txt/.spl/.lpcwave</code></td>
</tr>
<tr>
<td><code>lpp</code></td>
<td><code>.cnl</code> or <code>.csch</code></td>
<td>Loadpull <strong>pursuit</strong> — searches for the optima</td>
<td>Optima + the follow-on grid; <code>-o</code> as <code>hb</code>; <code>--out-grid</code> writes a <code>.gam</code></td>
</tr>
<tr>
<td><code>em</code></td>
<td><code>.cem</code></td>
<td>The EM kernel the setup resolves to</td>
<td>A Touchstone <code>.sNp</code> <strong>and</strong> a grouped <code>.npy</code>, where <strong>Simulate</strong> writes them</td>
</tr>
<tr>
<td><code>rail</code></td>
<td><code>.crail</code></td>
<td>The same DC solve and via check <a href="railrf.html">railRF</a>'s <strong>Run</strong> button calls</td>
<td>The ports, the ranked breakdown and the via check to stdout; <code>-o .csv/.npy/.mat/.txt/.svg/.pdf</code></td>
</tr>
<tr>
<td><code>smith</code></td>
<td><code>.csmith</code></td>
<td>The same cascade evaluator the Smith Chart window walks on every edit</td>
<td>The reading and the per-node table to stdout; <code>-o .s1p</code> for the load Γ, <code>-o .svg/.pdf/.png</code> for the chart</td>
</tr>
<tr>
<td><code>lvs</code></td>
<td>a cell folder, a workspace, a <code>.clay</code> or a <code>.csch</code></td>
<td>The same comparison the <a href="lvs.html">LVS panel</a>'s <strong>Compare</strong> button calls</td>
<td><strong>Nothing</strong> — the report to stdout; <code>-o report.txt</code></td>
</tr>
<tr>
<td><code>convert</code></td>
<td>any layout format</td>
<td>The same importer and exporter <strong>File ▸ Import/Export</strong> runs</td>
<td>The layout in the format you asked for</td>
</tr>
<tr>
<td><code>new workspace</code></td>
<td>a directory</td>
<td>The same code <strong>File ▸ New Workspace</strong> runs</td>
<td>A <code>.cws</code> and, unless you say otherwise, a copied technology</td>
</tr>
<tr>
<td><code>new cell</code></td>
<td>a workspace + a name</td>
<td>The same code <strong>New Cell</strong> runs</td>
<td>A cell folder and one empty-but-valid file per view</td>
</tr>
<tr>
<td><code>import part</code></td>
<td>a component file or folder</td>
<td>The same code <strong>Import Component</strong> runs</td>
<td>A cell folder holding the land patterns and the symbol</td>
</tr>
<tr>
<td><code>render</code></td>
<td>a <code>.csch</code>, <code>.csym</code>, <code>.clay</code> or <code>.cdd</code>, a cell folder, or a workspace</td>
<td>The same Skia renderers the editors draw every frame with</td>
<td>A <code>.svg</code>, <code>.pdf</code> or <code>.png</code>, where <code>-o</code> says</td>
</tr>
<tr>
<td><code>check</code></td>
<td>a workspace, a cell folder, or one document</td>
<td>Every validator the application already uses</td>
<td><strong>Nothing</strong> — findings to stdout</td>
</tr>
<tr>
<td><code>explain</code></td>
<td>the same</td>
<td>Resolution only — no analysis</td>
<td><strong>Nothing</strong> — the walk and the answer, to stdout</td>
</tr>
<tr>
<td><code>read</code></td>
<td>a result file, or one of circuitRF's own documents</td>
<td>The same loaders the Data Display reads a file with</td>
<td><strong>Nothing</strong> — what the file holds, to stdout</td>
</tr>
<tr>
<td><code>netlist</code></td>
<td>a <code>.csch</code>, a cell folder, or a workspace</td>
<td>The same extraction <strong>Simulate</strong> performs</td>
<td>A <code>.cnl</code>, or the netlist text to stdout</td>
</tr>
<tr>
<td><code>plot</code></td>
<td>a result file</td>
<td>Builds a one-plot data display and draws it</td>
<td>A <code>.svg</code>, <code>.pdf</code> or <code>.png</code>, where <code>-o</code> says</td>
</tr>
<tr>
<td><code>find</code></td>
<td>a directory</td>
<td>Nothing — it reads documents</td>
<td><strong>Nothing</strong> — the workspaces, cells, views and analyses under it</td>
</tr>
<tr>
<td><code>reference</code></td>
<td><strong>nothing</strong></td>
<td>Nothing — it reads no file</td>
<td><strong>Nothing</strong> — the reference pages, and every netlist primitive with its terminals and parameters</td>
</tr>
<tr>
<td><code>elab</code></td>
<td><code>.cnl</code> or <code>.csch</code></td>
<td>Elaboration only, no analysis</td>
<td>The elaborated netlist, to stdout</td>
</tr>
<tr>
<td><code>serve</code></td>
<td><code>--root <dir></code></td>
<td>An MCP server for an external client</td>
<td>Whatever the tool it is asked for writes</td>
</tr>
</tbody>
</table>
<p><code>hb</code>, <code>lp</code> and <code>lpp</code> all run <strong>the whole parametric sweep</strong> when one wraps the analysis — see
<a href="#wrapper">naming the wrapper</a>.</p>
<p><strong>Every run verb takes a schematic as well as a netlist.</strong> Hand it a <code>.csch</code> and it extracts the
netlist in memory first — the same extraction <strong>Simulate</strong> performs — so you do not have to write one
out to run a design you drew. <a href="#netlist"><code>netlist</code></a> is how you see what it will run.</p>
<h2 id="channels">Results on stdout, everything else on stderr</h2>
<p><strong>stdout is the result. stderr is everything else</strong> — progress, per-grid-point engine chatter,
<code>[circuitRF]</code> notes, elaboration and engine warnings, device-worker logs.</p>
<p>That split is what makes the output pipeable while the terminal still shows a long run moving:</p>
<pre><code class="cmd"><span class="prompt">$ </span>circuitrf lp hero3.cnl > table.txt</code></pre>
<p><code>table.txt</code> gets the loadpull table and nothing else; the per-drive-step <code>[LP]</code> lines and the
convergence notes still scroll past on screen. Redirect <code>2&gt;/dev/null</code> to silence them, or
<code>2&gt;run.log</code> to keep them.</p>
<h2 id="common">Options every verb takes</h2>
<table>
<thead>
<tr>
<th>Option</th>
<th>What it does</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--kits <dir></code></td>
<td>A folder of installed kits, so an externally-supplied device model (<code>ExtDevice Provider=…</code>) resolves headlessly the way opening a workspace resolves it in the GUI. Repeatable.</td>
</tr>
<tr>
<td><code>--json</code></td>
<td>Put <strong>one JSON document</strong> on stdout and nothing else — <a href="#json">see below</a>. stderr is untouched.</td>
</tr>
<tr>
<td><code>--only a,b</code></td>
<td>Narrow that document's result to these cubes.</td>
</tr>
<tr>
<td><code>--group g,h</code></td>
<td>Narrow that document's result to these groups.</td>
</tr>
<tr>
<td><code>--at axis=value</code></td>
<td>Narrow it to <strong>one point of an axis</strong> — <code>--at freq=2GHz</code>. The nearest grid point, and the document says which one it gave you.</td>
</tr>
<tr>
<td><code>--interp</code></td>
<td>Make every <code>--at</code> interpolate between the two bracketing points instead. Never the default: it returns a number the run did not compute, and the document says so.</td>
</tr>
<tr>
<td><code>--range axis=lo:hi</code></td>
<td>Keep a band of an axis — <code>--range freq=1GHz:3GHz</code>.</td>
</tr>
<tr>
<td><code>--result full\|summary</code></td>
<td><code>summary</code> returns the result's <strong>shape</strong> — group and cube names, units, axis lengths and extents — and no values at all.</td>
</tr>
<tr>
<td><code>--summary</code></td>
<td>Report the informational notes as counts by severity instead of in full. Warnings and errors always travel in full, and stderr is untouched.</td>
</tr>
</tbody>
</table>
<p>Frequencies are written as <code>1GHz</code>, <code>100MHz</code>, or bare Hz (<code>1e9</code>) anywhere a frequency is accepted.</p>
<div class="callout">
<span class="label">Ask for the part you want, not the whole result</span>
<p><code>--only</code> and <code>--group</code> narrow by cube <i>name</i>, which does nothing when the
result has one cube. A 551-point two-port S-parameter run is about 173 kB of JSON; if the
question is "what is S21 at 2 GHz", <code class="nowrap">--at freq=2GHz --only S</code> is a few
hundred bytes. Every value carries its own unit — a bare <code>2</code> could be 2 Hz or
2 GHz — and an axis name nothing in the result has is refused, listing the ones that exist,
rather than quietly handing you everything.</p>
<p>Every run returns <code>result.shape</code> whether or not it returns the values, so
<code class="nowrap">--result summary</code> is how you find out what a run produced before deciding
what to ask for.</p>
</div>
<div class="callout">
<span class="label">An option a verb does not take is refused, never ignored</span>
<p>Every verb stops with <code>unknown option '…'</code> and exit 1 rather than dropping a flag it
does not recognise. This matters more than it sounds: most verbs find their input file as
<i>the first argument that is not an option</i>, so a silently dropped flag's <b>value</b> would be
read as the file name — and a flag that carries an override, like
<code class="nowrap">--set</code>, would simply not be applied, giving you a run that answers a
different question with nothing to say so.</p>
</div>
<hr />
<h2 id="sparam"><code>sparam</code> — S-parameters</h2>
<pre><code class="cmd"><span class="prompt">$ </span>circuitrf sparam <file.cnl|.csch> [--freq start:stop:step] [-o out.sNp]</code></pre>
<pre><code class="language-text">$ circuitrf sparam hero1.cnl --freq 1GHz:3GHz:1GHz -o hero1.s2p
S-parameter analysis: 3 points, 1–3 GHz
Wrote hero1.s2p
</code></pre>
<table>
<thead>
<tr>
<th>Option</th>
<th>What it does</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--freq start:stop:step</code></td>
<td>Override the sweep. <strong>Omit it and the netlist's own <code>sparam</code> analysis is used</strong>, segments and all — which is almost always what you want, because it is the sweep the design was set up with.</td>
</tr>
<tr>
<td><code>-o</code>, <code>--output <path></code></td>
<td>Where the result goes, and <strong>its extension picks the format</strong>: <code>.s1p</code>…<code>.s99p</code> for a Touchstone, or <code>.npy</code> / <code>.mat</code> / <code>.txt</code> for the cubes. Omitted, it is the input file with its extension changed to <code>.sNp</code> for the port count found.</td>
</tr>
</tbody>
</table>
<p>There is no stdout table. The port count in the default extension comes from the network, so a
circuit that grew a port writes <code>.s3p</code> without you editing the command. An extension naming no format
this verb writes is refused, listing the ones it does — you never get a Touchstone under a name that
says otherwise.</p>
<p><strong>A run carrying <a href="wsprobe.html">WSProbes</a> prints one line per probe</strong> after the S summary, and a run
with <code>NDF=yes</code> on its directive prints the right-half-plane pole count:</p>
<pre><code class="language-text">$ circuitrf sparam amp.cnl
S-parameter analysis 'SP1': 2001 points, 0.5-3 GHz (1 segment(s))
NDF: 2 right-half-plane pole(s) (net clockwise encirclement 1.989; NDF(100 GHz)=1 ∠ 1.8)
WSProbe P idx=1 H0(0.5 GHz)=11.597 ∠ -1.4 ZG(0.5 GHz)=10.482 ∠ 17.4
SM_Y0 min -18.1 dB @ 1.59125 GHz SM_H0 min -19.8 dB @ 1.73375 GHz
</code></pre>
<p><code>--json</code> carries the same under <code>wsprobes</code> and <code>ndf</code>. <strong>The margins are linear there and dB on the
line</strong>, because dB is a display convention and a document should carry the number. A circuit that has
WSProbes and <strong>no ports at all</strong> is a legitimate run — it writes every <code>wsp</code> cube and no <code>S</code> — and
asking it for a Touchstone is refused, naming the spellings that do carry the result.</p>
<div class="callout">
<span class="label">Ports with different reference impedances</span>
<p>A Touchstone file declares <b>one</b> reference impedance, and circuitRF writes port 1's on
the option line. When the ports differ, the file also carries a header note listing each port's own
impedance and saying that the data is referenced to <i>those</i> — and circuitRF reads that note back,
so <code>circuitrf read</code> on the file reports the real per-port references rather than the
option line repeated. Nothing is renormalized: the numbers are the ones the solve produced. If you
want the per-port references in a form every tool reads, write <code>.npy</code> instead.</p>
</div>
<h2 id="dc"><code>dc</code> — the operating point</h2>
<pre><code class="cmd"><span class="prompt">$ </span>circuitrf dc <file.cnl|.csch></code></pre>
<pre><code class="language-text">$ circuitrf dc hero2.cnl
DC: converged in 3 iteration(s), residual 7.27E-16
Node voltages:
0 0
n_src 0
n_gate -3.05
n_drain 48
</code></pre>
<p>No options beyond the common ones. It prints the converged node voltages and any probe currents, and
<a href="#exit">exits 2</a> if the solve did not converge — the operating point is the one thing every nonlinear
analysis is built on, so a non-converged DC is a failed run, not a partial one.</p>
<h2 id="hb"><code>hb</code> — harmonic balance</h2>
<pre><code class="cmd"><span class="prompt">$ </span>circuitrf hb <file.cnl|.csch> [-a name] [--set var=expr] [-o out.npy]</code></pre>
<p>The same verb runs <strong>single- and multi-tone</strong> — which it is comes from the netlist's directive, not
from a flag.</p>
<pre><code class="language-text">$ circuitrf hb hero2.cnl --rows 6
HB 'HB1': f0=2 GHz, MaxHarm=4, tol=1E-06
Analysis: HB1 (hero2.cnl)
Converged: yes (1 solve(s))
Residual: 1.24E-09 (worst)
Tones: 2 GHz
V [node:7 x harmonic:5] (mag ∠deg)
0 1 2
n_gate 3.05 ∠ 180.0 0.029814 ∠ 0.1 0
n_drain 48 ∠ 0.0 0.15004 ∠ -172.4 1.6824E-05 ∠ -179.8
… 1 more row(s) — use --all or --rows N
</code></pre>
<table>
<thead>
<tr>
<th>Option</th>
<th>What it does</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>-a</code>, <code>--analysis <name></code></td>
<td>Which analysis to run. Optional when the file declares one HB chain.</td>
</tr>
<tr>
<td><code>--set <var=expr></code></td>
<td>Override a global variable <strong>before elaboration</strong>. Repeatable.</td>
</tr>
<tr>
<td><code>--maxharm K</code></td>
<td>Override <code>MaxHarm</code>.</td>
</tr>
<tr>
<td><code>--maxmix M</code></td>
<td>Override <code>MaxMixOrder</code> (multi-tone only).</td>
</tr>
<tr>
<td><code>--tol t</code>, <code>--max-iter N</code></td>
<td>Override the convergence tolerance and the iteration cap.</td>
</tr>
<tr>
<td><code>--rows N</code>, <code>--all</code></td>
<td>How much of each printed table to show. Default is a truncated head.</td>
</tr>
<tr>
<td><code>--diag</code></td>
<td>Engine convergence diagnostics, on stderr.</td>
</tr>
<tr>
<td><code>-o</code>, <code>--export <path></code></td>
<td>Export the results. <strong>The extension picks the format</strong>: <code>.mat</code>, <code>.npy</code> or <code>.txt</code>.</td>
</tr>
</tbody>
</table>
<h3 id="set"><code>--set</code> overrides the VARIABLE, not the number</h3>
<p><code>--set Pavl_dbm=0</code> replaces the global variable in the test bench's own scope, then elaborates. So
every expression derived from it re-derives — a bias that was written <code>Vg = Vth + 0.2</code> follows a
changed <code>Vth</code>, and a sweep computed from the variable sweeps the new values.</p>
<p>An override pushed at the engine instead would move one number and leave everything computed from it
stale, which is why there is no such option.</p>
<h3 id="wrapper">Name the wrapper, or name nothing</h3>
<p>When a <a href="simulations.html#parametric-sweep">parametric sweep</a> wraps an analysis, the sweep is what
runs. Naming the inner analysis with <code>-a</code> is <strong>promoted</strong> to its outermost enabled wrapper, and the
promotion is announced:</p>
<pre><code class="language-text">[circuitRF] 'HB1' is the inner analysis of 'SW1' — running 'SW1' so the sweep axis is not lost.
</code></pre>
<div class="callout note">
<span class="label">Why it is promoted rather than obeyed</span>
<p>Running the inner analysis alone produces a converged, plausible, complete-looking result at one
operating point — <em>with the sweep axis silently missing</em>. Nothing about it looks wrong. A
frequency-swept loadpull has exactly this shape, which is why the rule is the same for every verb
rather than something harmonic balance does on its own.</p>
</div>
<p>If more than one runnable chain exists, all their names are printed and the first runs; if none does,
the message says whether the netlist declares no such analysis or declares one that is disabled.</p>
<h3 id="measurements">Measurements</h3>
<p>The <code>measure</code> lines on the test bench are evaluated exactly as the GUI evaluates them, and the results
join the exported <code>DataSet</code> as named cubes. A measurement that fails to evaluate is <strong>reported on
stderr and the run continues</strong> — one bad expression does not throw away a run that took minutes:</p>
<pre><code class="language-text">[circuitRF] measurement: Measurement 'Gain_dB': failed to evaluate 'Pout_dBm - Pavl_dbm':
Unresolved name 'Pout_dBm' in scope 'measurements'
</code></pre>
<h2 id="lp"><code>lp</code> — loadpull</h2>
<pre><code class="cmd"><span class="prompt">$ </span>circuitrf lp <file.cnl|.csch> [--grid grid.gam] [--pin start:step:max] [-o out.spl]</code></pre>
<p><code>lp</code> sweeps the load (or source) termination over the directive's Γ grid, runs a harmonic-balance
drive ladder at each point, and reports the figures of merit.</p>
<pre><code class="language-text">$ circuitrf lp hero3.cnl --rows 8
Analysis: LP1 (hero3.cnl)
Grid: 20 point(s) — 0 reached compression, 20 stopped at max drive
Nothing reached compression — raise --pin's max (or the directive's PinMax).
# GammaLoad ZLoad (ohm) stop Pavl Pout Gt DE% PAE%
0 0.0000 ∠ 0.0 50.00+j0.00 max drive 10.00 20.54 10.54 3.35 3.09
1 0.2000 ∠ 0.0 75.00+j0.00 max drive 10.00 22.31 12.31 5.03 4.76
2 0.2000 ∠ 90.0 46.15+j19.23 max drive 10.00 20.19 10.19 3.09 2.83
… 12 more point(s) — use --all or --rows N
</code></pre>
<table>
<thead>
<tr>
<th>Option</th>
<th>What it does</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>-a</code>, <code>--analysis <name></code></td>
<td>Which loadpull analysis to run.</td>
</tr>
<tr>
<td><code>--set <var=expr></code></td>
<td>Override a global variable before elaboration. Repeatable.</td>
</tr>
<tr>
<td><code>--grid <file.gam></code></td>
<td>Override the Γ grid the directive reads. <strong>Resolved against your working directory</strong>, not the netlist's.</td>
</tr>
<tr>
<td><code>--pin start:step:max</code></td>
<td>Override the drive ladder, in dBm.</td>
</tr>
<tr>
<td><code>--compression dB</code></td>
<td>Override the compression target.</td>
</tr>
<tr>
<td><code>--maxharm K</code>, <code>--tol t</code>, <code>--max-iter N</code></td>
<td>Override the inner HB settings.</td>
</tr>
<tr>
<td><code>--rows N</code>, <code>--all</code></td>
<td><code>--all</code> dumps every cube instead of the summary table.</td>
</tr>
<tr>
<td><code>--diag</code></td>
<td>Engine diagnostics, on stderr.</td>
</tr>
<tr>
<td><code>-o</code>, <code>--export <path></code></td>
<td><code>.mat</code>, <code>.npy</code>, <code>.txt</code> — <strong>or <code>.spl</code> / <code>.lpcwave</code></strong>, the loadpull interchange formats.</td>
</tr>
</tbody>
</table>
<h3 id="lp-rows">One row per Γ point, at the point that answers the question</h3>
<p>A loadpull's raw cubes are <code>[gridPoint × driveStep]</code> — a 61-point grid driven up in 1 dB steps is a
61 × 30 table <em>per figure of merit</em>, and eight of those scroll a terminal without answering anything.</p>
<p>So the default table is <strong>one row per Γ grid point</strong>: where it was, how it stopped, and its FOMs at
the <strong>last converged, non-tickle drive step</strong> — the compression point where the point compressed, the
highest drive it managed otherwise. Reading a fixed drive index instead would mix compressed and
uncompressed points in one column. <code>--all</code> still dumps everything.</p>
<p>A swept run prints one table per sweep point.</p>
<h3 id="lp-export"><code>.spl</code> and <code>.lpcwave</code></h3>
<p><code>-o out.spl</code> writes the loadpull interchange format the <a href="data-display.html">Data Display</a> reads back
as a measured surface, so a headless run can produce a file the GUI opens. <code>lp</code> also runs the same
post-processor a GUI run does, so the exported cubes carry the derived display metrics (<code>Pout_dBm</code>,
<code>Zin</code>, <code>IRL_dB</code>, <code>AMPM_deg</code>) — a <code>.npy</code> written here and one written by the GUI carry the same cubes.</p>
<h2 id="lpp"><code>lpp</code> — loadpull pursuit</h2>
<pre><code class="cmd"><span class="prompt">$ </span>circuitrf lpp <file.cnl|.csch> [--out-grid found.gam] [-o out.npy]</code></pre>
<p>A pursuit <strong>searches</strong> for the max-power (MXP) and max-efficiency (MXE) terminations rather than
reading a grid, then runs a follow-on loadpull over the terminations it recommends.</p>
<pre><code class="language-text">$ circuitrf lpp hero3B_at_compression.cnl
Analysis: LP1 (hero3B_at_compression.cnl)
Pursuit optima:
MXP (max power) converged Pout=40.625 dBm Zload=80.48+j0.00 Zsource=50.00+j0.00
MXE (max efficiency) converged Eff=69.617 % Zload=140.31-j4.95 Zsource=50.00+j0.00
21 termination(s) queried, 45 recommended termination(s)
Grid: 45 point(s) — 45 reached compression
# GammaLoad ZLoad (ohm) stop Pavl Pout Gt DE% PAE%
0 0.2690 ∠ 7.0 86.15+j6.11 compressed 26.00 40.56 14.56 67.08 64.74
1 0.2030 ∠ 9.6 74.80+j5.30 compressed 27.00 40.68 13.68 63.55 60.82
</code></pre>
<p><code>lpp</code> takes every <code>lp</code> option <strong>except <code>--grid</code></strong>, and adds <code>--out-grid</code>:</p>
<table>
<thead>
<tr>
<th>Option</th>
<th>What it does</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--out-grid <file.gam></code></td>
<td>Where the terminations the pursuit found are written, as a <code>.gam</code> you can feed back to <code>lp</code>. Resolved against your working directory.</td>
</tr>
</tbody>
</table>
<div class="callout warn">
<span class="label">The two grid options are refused, not ignored</span>
<p><code>--grid</code> on <code>lpp</code> and <code>--out-grid</code> on <code>lp</code> each stop the
run with a sentence naming the verb that owns them. A grid option silently doing nothing would be a
run that answered a different question and said nothing about it.</p>
</div>
<p>A <strong>non-converged</strong> optimum is still printed, with its status. The engine publishes the last
termination it looked at, and printing nothing there reads as "the search found nothing" when what
actually happened is "nothing it tried reached compression".</p>
<hr />
<h2 id="em"><code>em</code> — electromagnetic extraction</h2>
<pre><code class="cmd"><span class="prompt">$ </span>circuitrf em <setup.cem> [-o out.sNp] [--workspace file.cws]</code></pre>
<p><code>em</code> is the only verb that does not take a <code>.cnl</code>. It takes a <strong><code>.cem</code> EM setup</strong> — the document the
<a href="em-setup.html">EM Setup panel</a> edits — and runs it: extracts the geometry from the layout the setup
names, resolves the stackup, meshes, solves the frequency plan, de-embeds, and writes the results.</p>
<p><strong>It needs no other arguments.</strong> Everything else it needs is already recorded in the files.</p>
<h3 id="em-inputs">What an EM run takes</h3>
<p>Four files, and three of them are things you already have if you have drawn a layout:</p>
<table>
<thead>
<tr>
<th>File</th>
<th>What it supplies</th>
<th>Where it comes from</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong><code>.cem</code></strong></td>
<td>The setup: which layout, which analysis, the frequency plan, port impedances and types, mesh settings, solver switches</td>
<td><strong>File ▸ New ▸ EM Setup…</strong>, or the layout editor's <strong>EM</strong> button</td>
</tr>
<tr>
<td><strong><code>.clay</code></strong></td>
<td>The artwork — the metal, and the port labels for a full-wave run</td>
<td>The <a href="layout-editor.html">layout editor</a></td>
</tr>
<tr>
<td><strong><code>.ctech</code></strong></td>
<td>The <a href="stackup.html">stackup</a>: layer thicknesses, ε_r, tanδ, conductivity, which conductor is ground, and which drawing layers map onto what</td>
<td>The technology editor, or one of the shipped starter technologies</td>
</tr>
<tr>
<td><strong><code>.cws</code></strong></td>
<td>The workspace marker, carrying <code>DefaultTechRef</code> — the technology a layout uses when it does not name one itself</td>
<td>Created with the workspace</td>
</tr>
</tbody>
</table>
<div class="callout note">
<span class="label">Author the setup in the GUI; run it from the command line</span>
<p>The <code>em</code> verb <b>runs</b> a setup — it does not create or edit one, and it will not
repair one. A setup with no ports, no technology or no signal conductor is <a href="#em-refusals">refused
with the sentence explaining what is missing</a>. Build the <code>.cem</code> once in the
<a href="em-setup.html">EM Setup panel</a>, where every control tells you as you type whether the run
is blocked and why, then commit it beside the layout and run it headlessly from then on.</p>
</div>
<h3 id="em-resolution">Both file references resolve by walking UP, and neither is a flag</h3>
<p>A <code>.cem</code> names a layout; the layout names — or inherits — a technology. Neither reference is stored
absolutely, and neither needs an argument:</p>
<ul>
<li><strong>The layout.</strong> The setup's layout reference is relative to the <strong>workspace root</strong>: the nearest
ancestor <code>.cws</code> found by walking up from the <code>.cem</code>. With no workspace above it at all, the
reference falls back to the <code>.cem</code>'s own directory, so a loose <code>.cem</code> sitting beside its <code>.clay</code>
simply works.</li>
<li><strong>The technology.</strong> Resolved against <strong>the layout's own parent workspace</strong>, found by walking up from
the <code>.clay</code> — never against "the workspace you are in", of which there is none headlessly. A <code>.clay</code>
that names no technology picks up its workspace's <code>DefaultTechRef</code>.</li>
</ul>
<p><strong>The two walks start from different files, and that is deliberate.</strong> A <code>.cem</code> in one workspace may
point at a layout in another, and that layout's layers have to be read by <em>its</em> technology, not by
whichever workspace the setup happened to live in.</p>
<p><code>--workspace <file.cws></code> overrides the first walk, for a <code>.cem</code> being run from outside its own tree.
It is never required.</p>
<p>The three resolutions are echoed on stderr before anything expensive starts, so you can see what the
run is actually about to read:</p>
<pre><code class="language-text">[circuitRF] workspace: /work/amp/.cws
[circuitRF] layout: /work/amp/Line/layout/Line.clay
[circuitRF] technology: /work/amp/pcb.ctech
</code></pre>
<h3 id="em-example">A worked example, from an empty folder</h3>
<p>Here is a complete, minimal EM workspace — a single 20 mm × 2.9 mm microstrip line on a two-layer PCB
technology, swept 1–10 GHz in 3 points. Four files:</p>
<pre><code class="language-text">amp/
├─ .cws the workspace marker, naming the default technology
├─ pcb.ctech the stackup
├─ line.cem the EM setup
└─ Line/
└─ layout/
└─ Line.clay the artwork
</code></pre>
<p>The <code>.cem</code> is JSON, and this is all of it — every field not written takes its documented default:</p>
<pre><code class="language-json">{
"FormatVersion": 1,
"Name": "line",
"LayoutRef": "Line/layout/Line.clay",
"Frequency": {
"StartExpr": "1", "StopExpr": "10", "NumPoints": 3,
"Mode": "PointCount", "Kind": "Linear",
"StartUnit": "GHz", "StopUnit": "GHz"
},
"Port1Z0Real": 50, "Port2Z0Real": 50
}
</code></pre>
<p><code>LayoutRef</code> is <strong>workspace-relative</strong> — relative to the directory holding <code>.cws</code>, not to the <code>.cem</code>.
The <code>.cws</code> supplies the technology:</p>
<pre><code class="language-json">{ "DefaultTechRef": "pcb.ctech" }
</code></pre>
<p>Nothing in the <code>.cem</code> names a technology, a kernel, a mesh or a port. The technology is inherited, the
kernel is chosen from the geometry, the mesh settings are the engine's own defaults, and this
structure's ports are the two ends of a uniform line by construction. Then:</p>
<pre><code class="cmd"><span class="prompt">$ </span>circuitrf em amp/line.cem</code></pre>
<pre><code class="language-text">[circuitRF] workspace: amp/.cws
[circuitRF] layout: amp/Line/layout/Line.clay
[circuitRF] technology: amp/pcb.ctech
[0] solving the cross-section
[3] solving the cross-section
note: Automatic chose "Uniform transmission line": this geometry is a uniform cross-section, which
that analysis solves exactly and is about a thousand times cheaper than "Full-wave planar".
Set Analysis to "Full-wave planar" if you want the full-wave answer anyway.
note: Dielectric interfaces truncated 20 substrate heights (32000 µm) beyond the outermost conductor
on each side.
EM setup: line
Kernel: Quasi-static cross-section (CrossSection)
Points: 3
Wrote amp/results/line.s2p
Wrote amp/results/line_em.npy
</code></pre>
<p>Everything from <code>EM setup:</code> down is on <strong>stdout</strong>; the resolution lines, the progress and the notes are
on stderr.</p>
<p>A <strong>full-wave</strong> run differs only in what the files say, not in how you invoke it: draw port labels in
the layout with the layout editor's <strong>Port</strong> tool, set the setup's analysis to <code>Planar</code> (or leave it
<code>Auto</code> and let the geometry decide), and run exactly the same command. It will take very much longer —
a de-embedded full-wave point costs tens of seconds at the shipping mesh — which is why the progress
lines exist.</p>
<h3 id="em-output">Where the results go, and what <code>-o</code> moves</h3>
<p>With no <code>-o</code>, the run writes <strong>exactly where the Simulate button writes</strong>: into the workspace's
<code>results/</code> folder. Two files come out, and they are not redundant:</p>
<table>
<thead>
<tr>
<th>File</th>
<th>Holds</th>
</tr>
</thead>
<tbody>
<tr>
<td><code><name>.sNp</code></td>
<td>S-parameters only — the artefact a schematic's <a href="components.html#snp">SnP component</a> references by path</td>
</tr>
<tr>
<td><code><name>_em.npy</code></td>
<td>The whole <code>DataSet</code>, including the per-kernel <strong>diagnostics</strong> group — Z_c, γ, ε_eff, RLGC for the cross-section kernel; the calibration residual and usability flags for the full-wave one</td>
</tr>
</tbody>
</table>
<div class="callout warn">
<span class="label">Why the default path is not the CLI's to choose</span>
<p>That results path is <b>predictable by design</b>, so a schematic's SnP reference stays valid across
re-runs. A headless run that minted its own file name would orphan every one of them — so
<code>circuitrf em</code> writes the same file <b>Simulate</b> does, and the acceptance test for the
verb compares the two Touchstones <em>byte for byte</em>.</p>
</div>
<p><code>-o</code> moves <strong>the Touchstone only</strong>. The <code>.npy</code> stays where it was, because it is the diagnostics
record of the run rather than the deliverable:</p>
<pre><code class="language-text">$ circuitrf em amp/line.cem -o /tmp/mine.s2p
Wrote /tmp/mine.s2p
Wrote amp/results/line_em.npy
</code></pre>
<p>You do not have to get the extension right — the port count decides it, so a <code>.s2p</code> you typed for a
structure that turned out to have four ports is written <code>.s4p</code>.</p>
<p>With no workspace above the <code>.cem</code>, <code>results/</code> is created beside the <code>.cem</code> itself.</p>
<h3 id="em-messages">note, warning, error — three lists, kept apart</h3>
<p>An EM run has three different things to say and they ask three different things of you, so they are
printed under three labels rather than flattened into one stream:</p>
<table>
<thead>
<tr>
<th>Prefix</th>
<th>Means</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>note:</code></td>
<td>The run explaining itself — which kernel it chose and why, the mesh's own sentences, RLGC, the ports it found. Read these; they are the cheapest check that the tool is looking at the structure you think it is.</td>
</tr>
<tr>
<td><code>warning:</code></td>
<td>Something to act on — a stale <code>.sNp</code> about to be replaced, a technology that resolved but failed validation.</td>
</tr>
<tr>
<td><code>error:</code></td>
<td>Something you asked for and did not get — a results file that could not be written.</td>
</tr>
</tbody>
</table>
<h3 id="em-refusals">A refusal is a result</h3>
<p>The EM engine declines geometry it cannot solve <em>correctly</em> rather than returning a plausible number.
Each refusal carries a written explanation of what is wrong with <strong>this</strong> setup, and <code>em</code> prints that
explanation rather than collapsing it into "EM failed":</p>
<pre><code class="language-text">[circuitRF] workspace: amp/.cws
warning: Layout file not found: amp/Line/layout/Missing.clay
No layout: The layout 'Line/layout/Missing.clay' could not be found, so there is no geometry to
analyse. Point this EM setup at a layout that exists.
</code></pre>
<table>
<thead>
<tr>
<th>Status</th>
<th>Means</th>
<th>Exit</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Refused</strong></td>
<td>The extractor or the kernel declined this geometry — see <a href="mom-engine.html#refusals">what the engine refuses</a></td>
<td>1</td>
</tr>
<tr>
<td><strong>No layout</strong></td>
<td>The layout reference did not resolve</td>
<td>1</td>
</tr>
<tr>
<td><strong>Engine error</strong></td>
<td>The solve failed</td>
<td>1</td>
</tr>
<tr>
<td><strong>Cancelled</strong></td>
<td>Stopped at a work boundary</td>
<td>130</td>
</tr>
</tbody>
</table>
<h2 id="rail"><code>rail</code> — power integrity, headless</h2>
<pre><code class="cmd"><span class="prompt">$ </span>circuitrf rail <board.crail> [--rail NAME] [--accurate] [-o out.{csv,npy,mat,txt,svg,pdf}]</code></pre>
<p><code>rail</code> runs a <strong><code>.crail</code></strong> — the document the <a href="railrf.html">railRF window</a> edits. It resolves the
artwork and the stackup, extracts the copper, solves the rail at DC, checks the vias and prints the
answer. Every number comes out of the same call the window's <strong>Run</strong> button makes, and every pixel of an
<code>.svg</code> or <code>.pdf</code> report out of the same renderer the window draws with, so a report produced on a build
machine is the one you would have got by pressing the button.</p>
<p><strong>Omitting <code>--rail</code> runs them all</strong>, in dependency order — the same shape <code>hb</code> and <code>lp</code> have for a
wrapped sweep, and for the same reason: a downstream rail solved on its own would start its source from
a nominal instead of from the upstream answer.</p>
<p>It can also take the <code>.clay</code>, the cell folder or the workspace the <code>.crail</code> sits in, and find it.</p>
<h3 id="rail-resolution">What it reads, and what walks up to it</h3>
<p>Like <a href="#em"><code>em</code></a>, the references are walk-ups rather than flags. The <code>.crail</code> names its artwork; the
artwork names — or inherits from its workspace — a technology.</p>
<table>
<thead>
<tr>
<th>File</th>
<th>What it supplies</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong><code>.crail</code></strong></td>
<td>The rails, their references and extents, the sources, the loads and their currents, the parts, the targets, the band and the aggressors</td>
</tr>
<tr>
<td><strong><code>.clay</code></strong> (or a Gerber set)</td>
<td>The copper being measured</td>
</tr>
<tr>
<td><strong><code>.ctech</code></strong></td>
<td>The stackup: conductor thicknesses and conductivities, the dielectrics between them, and the via entry's plated-wall thickness</td>
</tr>
<tr>
<td><strong><code>.crlib</code></strong></td>
<td>The part library the decoupling resolves against</td>
</tr>
</tbody>
</table>
<h3 id="rail-options">Options</h3>
<table>
<thead>
<tr>
<th>Option</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--rail <name></code></td>
<td>Which rail. Omitting it runs every one.</td>
</tr>
<tr>
<td><code>--fast</code> (default) / <code>--accurate</code></td>
<td><a href="railrf.html#speeds">The two readings of the copper</a>. Fast is the default, as in the window.</td>
</tr>
<tr>
<td><code>--source REFDES.PIN=<model></code></td>
<td>Repeatable. <code>3.7V,50mOhm,10nH</code> — any subset, in any order, each field identified by its unit or by a <code>v=</code>/<code>r=</code>/<code>l=</code> key — or a Touchstone file. A row for the same anchor is <strong>replaced</strong>, not added beside it.</td>
</tr>
<tr>
<td><code>--load REFDES.PIN[=<current>]</code></td>
<td>Repeatable. <strong>The current may be left out</strong>: that makes it an observation port.</td>
</tr>
<tr>
<td><code>--target-drop</code>, <code>--target-z</code>, <code>--mask [PORT=]<file></code></td>
<td>The target forms. A mask is per observation port; one that lands on no port is refused, because a mask nobody applied reads on the report exactly like one that was honoured.</td>
</tr>
<tr>
<td><code>--aggressor NAME=<freq>[xN]</code></td>
<td>Repeatable. <code>x</code> and <code>×</code> both spell the harmonic count.</td>
</tr>
<tr>
<td><code>--reference <layer></code>, <code>--extent as-imported\|filled\|infinite</code></td>
<td>The return conductor, and how far it is taken to extend.</td>
</tr>
<tr>
<td><code>--rows N</code>, <code>--all</code></td>
<td>How much of the ranked breakdown to print.</td>
</tr>
<tr>
<td><code>-o out.…</code></td>
<td><code>.csv</code> for the tables, <code>.npy</code>/<code>.mat</code>/<code>.txt</code> through the usual exporter, <code>.svg</code>/<code>.pdf</code> for the report page.</td>
</tr>
</tbody>
</table>
<p><strong>An anchor is <code>REFDES</code>, <code>REFDES.PIN</code>, or <code>@x,y</code> in DBU.</strong> Headless it is always the coordinate form:
a <code>.crail</code> names no placement file, so there is nothing to resolve a refdes against — see
<a href="railrf.html#notyet">what is not wired up yet</a>.</p>
<p><strong>Values carry units</strong>, through the same table the <a href="expressions.html">expression engine</a> uses, so a
spelling that works in a <code>.cnl</code> works here. A bare number is base SI, which is what every number in a
<code>.crail</code> already is.</p>
<h3 id="rail-refusals">What is refused, and what is not</h3>
<table>
<thead>
<tr>
<th>Unstated</th>
<th>Answer</th>
</tr>
</thead>
<tbody>
<tr>
<td>The <strong>reference layer</strong></td>
<td><strong>Refused</strong>, naming <code>--reference</code>. railRF never infers one.</td>
</tr>
<tr>
<td>The <strong>technology</strong></td>
<td><strong>Refused.</strong> Copper priced with no thickness and no conductivity produces numbers that look exactly like numbers with physics behind them.</td>
</tr>
<tr>
<td>The <strong>Excellon coordinate format</strong>, on a Gerber import</td>
<td><strong>Refused</strong> — the same sentence <a href="#convert"><code>convert</code></a> gives.</td>
</tr>
<tr>
<td>The <strong>via plating thickness</strong></td>
<td><strong>Not refused.</strong> It is a setting, and every flag says which basis produced its limit.</td>
</tr>
<tr>
<td>A <strong>load's current</strong></td>
<td><strong>Not refused.</strong> It is an observation port, it contributes nothing to the DC solve, and the report lists it <em>as observed</em>. Refusing it — or defaulting it to zero — would make <em>not added</em> and <em>added with no current</em> indistinguishable.</td>
</tr>
</tbody>
</table>
<p><code>-o out.sNp</code> is <strong>refused</strong>: Z(f) at the observation ports is the frequency answer, this verb answers
DC, and a Touchstone holding the DC point repeated would look like a measurement. <code>--set</code> is refused
too, naming the flags that do state those quantities: a <code>.crail</code> declares no variables, so a <code>--set</code>
accepted here would be silently dropped.</p>
<h3 id="rail-provenance">Every export says which model produced it</h3>
<p>A file read six months later has no status strip beside it, so every format carries the model (Fast or
Accuracy), the reference extent, the copper temperature, how many parts are modelled from a file, how
many have no bias curve, and whether any ESR fell back to a class default — which makes a derived peak
height <strong>indicative</strong> rather than measured.</p>
<h2 id="lvs"><code>lvs</code> — does the artwork implement the drawing?</h2>
<pre><code class="cmd"><span class="prompt">$ </span>circuitrf lvs <path> [--no-reduce] [--flat] [--flatten-cell NAME] [--testbench]
<span class="prompt"> </span>[--recognize] [--set var=expr] [--severity warning|error] [-o report.txt]</code></pre>
<p><code>lvs</code> compares a cell's <strong>layout</strong> against its <strong>schematic</strong> and reports every device, net, terminal and
value the two disagree about. It answers the one question a headless client cannot answer any other way:
the design was drawn twice, and do the two drawings say the same thing? An agent that authored a <code>.clay</code>
cannot look at the screen.</p>
<p>Every finding comes out of the same call the <a href="lvs.html#window">LVS panel</a>'s <strong>Compare</strong> button makes, so
a design that passes on a build machine passes when somebody opens it.</p>
<p>The path may be a <strong>cell folder</strong> (the default unit — its primary schematic against its primary
layout), a <strong>workspace</strong> (every cell holding both views), a <strong><code>.clay</code></strong> or a <strong><code>.csch</code></strong> (each finds its
sibling in the cell folder that holds it). A cell holding only one of the two views is reported and
skipped, not failed: that is the ordinary state of a design being drawn.</p>
<table>
<thead>
<tr>
<th>Option</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--no-reduce</code></td>
<td>Compare object for object. By default parallel and series <code>R</code>/<code>C</code>/<code>L</code> collapse first, and every finding un-reduces to the objects you drew.</td>
</tr>
<tr>
<td><code>--flat</code> / <code>--flatten-cell <name></code></td>
<td>Flatten the whole hierarchy, or one named sub-cell (repeatable). Every use is reported, so a design that quietly flattens everything is visible.</td>
</tr>
<tr>
<td><code>--testbench</code></td>
<td>Compare a bench as drawn rather than the cell it instantiates.</td>
</tr>
<tr>
<td><code>--recognize</code></td>
<td>Also read devices out of bare copper, through the technology's own <code>DeviceRules</code> deck. Off by default, and off for a process that declares no rules.</td>
</tr>
<tr>
<td><code>--set var=expr</code></td>
<td>Set a global before the schematic elaborates, exactly as a run verb does.</td>
</tr>
<tr>
<td><code>--severity warning\|error</code></td>
<td>What makes the exit code non-zero. Default <code>error</code>.</td>
</tr>