netlistmod 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- netlistmod-0.5.0/.gitignore +47 -0
- netlistmod-0.5.0/LICENSE +21 -0
- netlistmod-0.5.0/PKG-INFO +94 -0
- netlistmod-0.5.0/README.md +68 -0
- netlistmod-0.5.0/docs/decisions/README.md +22 -0
- netlistmod-0.5.0/docs/design/README.md +48 -0
- netlistmod-0.5.0/docs/grammars/ltspice/README.md +124 -0
- netlistmod-0.5.0/docs/grammars/ngspice/README.md +87 -0
- netlistmod-0.5.0/docs/usage/README.md +20 -0
- netlistmod-0.5.0/pyproject.toml +101 -0
- netlistmod-0.5.0/src/netlistmod/__init__.py +211 -0
- netlistmod-0.5.0/src/netlistmod/dialects.py +25 -0
- netlistmod-0.5.0/src/netlistmod/document/__init__.py +36 -0
- netlistmod-0.5.0/src/netlistmod/document/diagnostics.py +474 -0
- netlistmod-0.5.0/src/netlistmod/document/document.py +255 -0
- netlistmod-0.5.0/src/netlistmod/document/index.py +523 -0
- netlistmod-0.5.0/src/netlistmod/document/lines.py +119 -0
- netlistmod-0.5.0/src/netlistmod/document/model-types.json +18 -0
- netlistmod-0.5.0/src/netlistmod/document/models.py +43 -0
- netlistmod-0.5.0/src/netlistmod/document/names.py +51 -0
- netlistmod-0.5.0/src/netlistmod/document/topology.py +274 -0
- netlistmod-0.5.0/src/netlistmod/edit/__init__.py +17 -0
- netlistmod-0.5.0/src/netlistmod/edit/_ops_behavioral.py +62 -0
- netlistmod-0.5.0/src/netlistmod/edit/_ops_common.py +223 -0
- netlistmod-0.5.0/src/netlistmod/edit/_ops_controlled.py +59 -0
- netlistmod-0.5.0/src/netlistmod/edit/_ops_directives.py +246 -0
- netlistmod-0.5.0/src/netlistmod/edit/_ops_elements.py +281 -0
- netlistmod-0.5.0/src/netlistmod/edit/_ops_sources.py +244 -0
- netlistmod-0.5.0/src/netlistmod/edit/_ops_statements.py +84 -0
- netlistmod-0.5.0/src/netlistmod/edit/api.py +685 -0
- netlistmod-0.5.0/src/netlistmod/edit/conventions.py +64 -0
- netlistmod-0.5.0/src/netlistmod/edit/operations.py +77 -0
- netlistmod-0.5.0/src/netlistmod/edit/placement.py +133 -0
- netlistmod-0.5.0/src/netlistmod/edit/plan.py +122 -0
- netlistmod-0.5.0/src/netlistmod/edit/verify.py +184 -0
- netlistmod-0.5.0/src/netlistmod/errors.py +68 -0
- netlistmod-0.5.0/src/netlistmod/grammar/__init__.py +5 -0
- netlistmod-0.5.0/src/netlistmod/grammar/core.lark +547 -0
- netlistmod-0.5.0/src/netlistmod/grammar/formula-reserved.json +18 -0
- netlistmod-0.5.0/src/netlistmod/grammar/formula.lark +77 -0
- netlistmod-0.5.0/src/netlistmod/grammar/formula.py +113 -0
- netlistmod-0.5.0/src/netlistmod/grammar/formula_ltspice.lark +21 -0
- netlistmod-0.5.0/src/netlistmod/grammar/loader.py +461 -0
- netlistmod-0.5.0/src/netlistmod/grammar/ltspice-devices.json +27 -0
- netlistmod-0.5.0/src/netlistmod/grammar/ltspice.lark +649 -0
- netlistmod-0.5.0/src/netlistmod/grammar/ngspice-devices.json +28 -0
- netlistmod-0.5.0/src/netlistmod/grammar/ngspice.lark +571 -0
- netlistmod-0.5.0/src/netlistmod/model/__init__.py +145 -0
- netlistmod-0.5.0/src/netlistmod/model/_rules_base.py +109 -0
- netlistmod-0.5.0/src/netlistmod/model/_rules_behavioral.py +70 -0
- netlistmod-0.5.0/src/netlistmod/model/_rules_controlled.py +185 -0
- netlistmod-0.5.0/src/netlistmod/model/_rules_elements.py +412 -0
- netlistmod-0.5.0/src/netlistmod/model/_rules_sources.py +268 -0
- netlistmod-0.5.0/src/netlistmod/model/_rules_statements.py +559 -0
- netlistmod-0.5.0/src/netlistmod/model/_rules_structure.py +136 -0
- netlistmod-0.5.0/src/netlistmod/model/_tree.py +358 -0
- netlistmod-0.5.0/src/netlistmod/model/nodes.py +731 -0
- netlistmod-0.5.0/src/netlistmod/model/transform.py +95 -0
- netlistmod-0.5.0/src/netlistmod/model/values.py +131 -0
- netlistmod-0.5.0/src/netlistmod/py.typed +0 -0
- netlistmod-0.5.0/src/netlistmod/source.py +289 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
temp/
|
|
2
|
+
|
|
3
|
+
# Byte-compiled / optimized / DLL files
|
|
4
|
+
__pycache__/
|
|
5
|
+
*.py[cod]
|
|
6
|
+
*$py.class
|
|
7
|
+
|
|
8
|
+
# C extensions
|
|
9
|
+
*.so
|
|
10
|
+
|
|
11
|
+
# Distribution / packaging
|
|
12
|
+
.Python
|
|
13
|
+
build/
|
|
14
|
+
develop-eggs/
|
|
15
|
+
dist/
|
|
16
|
+
downloads/
|
|
17
|
+
eggs/
|
|
18
|
+
.eggs/
|
|
19
|
+
lib/
|
|
20
|
+
lib64/
|
|
21
|
+
parts/
|
|
22
|
+
sdist/
|
|
23
|
+
var/
|
|
24
|
+
wheels/
|
|
25
|
+
*.egg-info/
|
|
26
|
+
.installed.cfg
|
|
27
|
+
*.egg
|
|
28
|
+
|
|
29
|
+
# Virtual Environments
|
|
30
|
+
.env
|
|
31
|
+
.venv
|
|
32
|
+
env/
|
|
33
|
+
venv/
|
|
34
|
+
ENV/
|
|
35
|
+
|
|
36
|
+
# Testing and Coverage
|
|
37
|
+
.cache/
|
|
38
|
+
.import_linter_cache/
|
|
39
|
+
.pytest_cache/
|
|
40
|
+
.coverage
|
|
41
|
+
htmlcov/
|
|
42
|
+
|
|
43
|
+
# Editor / IDE specific (Optional but highly recommended)
|
|
44
|
+
.vscode/
|
|
45
|
+
.idea/
|
|
46
|
+
.DS_Store
|
|
47
|
+
Thumbs.db
|
netlistmod-0.5.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 xdylanm
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: netlistmod
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: A source-preserving SPICE netlist editing library
|
|
5
|
+
Project-URL: Homepage, https://github.com/xdylanm/netlistmod
|
|
6
|
+
Project-URL: Repository, https://github.com/xdylanm/netlistmod
|
|
7
|
+
Project-URL: Changelog, https://github.com/xdylanm/netlistmod/blob/main/CHANGELOG.md
|
|
8
|
+
Author: xdylanm
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: editor,ltspice,netlist,ngspice,parser,spice
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.13
|
|
23
|
+
Requires-Dist: interegular>=0.3.3
|
|
24
|
+
Requires-Dist: lark>=1.2.2
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# netlistmod
|
|
28
|
+
|
|
29
|
+
`netlistmod` is a source-preserving SPICE netlist editing library. Its goal is
|
|
30
|
+
to make permitted value and directive edits while preserving the original text
|
|
31
|
+
and circuit topology.
|
|
32
|
+
|
|
33
|
+
## Supported dialects
|
|
34
|
+
|
|
35
|
+
The caller always selects the dialect; there is no default and no detection.
|
|
36
|
+
|
|
37
|
+
| Dialect | `Dialect` | Input | Elements | Reference | Validated on |
|
|
38
|
+
|---|---|---|---|---|---|
|
|
39
|
+
| ngspice | `NGSPICE` | `.cir`, `.sp`, `.net`, KiCad exports | R, C, L, K, V, I, D, X; Q, M, J, Z (M13); E, F, G, H, S, W (M14); B and the expression forms (M15) | [ngspice manual](docs/references.md) | ngspice 47 |
|
|
40
|
+
| LTspice | `LTSPICE` | `.net`, `.cir` (an `.asc` schematic is [exported first](docs/usage/ltspice-export.md)) | R, C, L, K, V, I, D, X; Q, M, J, Z (M13); E, F, G, H, S, W (M14); B and the expression forms (M15) | [ltspice-reference](docs/references.md) | LTspice 26.1.1, Windows |
|
|
41
|
+
|
|
42
|
+
Where a solver and the library differ, the file is `docs/grammars/<dialect>/discrepancies.md`. Other
|
|
43
|
+
device letters raise `UnsupportedConstruct` until their phase 2 milestone.
|
|
44
|
+
|
|
45
|
+
## Quick start
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install netlistmod
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
To work on the library itself, clone it and run `uv sync`.
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
>>> from pathlib import Path
|
|
55
|
+
>>> from tempfile import TemporaryDirectory
|
|
56
|
+
>>> from netlistmod import Dialect, Netlist
|
|
57
|
+
>>> folder = TemporaryDirectory()
|
|
58
|
+
>>> path = Path(folder.name) / "divider.cir"
|
|
59
|
+
>>> _ = path.write_bytes(b"divider\nV1 in 0 DC 3\nR1 in out 1k ; top\nR2 out 0 1k\n.op\n.end\n")
|
|
60
|
+
|
|
61
|
+
>>> netlist = Netlist.load(path, dialect=Dialect.NGSPICE)
|
|
62
|
+
>>> edited = netlist.set_value("R2", "3k").directives.set(".tran 1u 5u")
|
|
63
|
+
>>> edited.save()
|
|
64
|
+
>>> print(path.read_text(), end="")
|
|
65
|
+
divider
|
|
66
|
+
V1 in 0 DC 3
|
|
67
|
+
R1 in out 1k ; top
|
|
68
|
+
R2 out 0 3k
|
|
69
|
+
.op
|
|
70
|
+
.tran 1u 5u
|
|
71
|
+
.end
|
|
72
|
+
>>> folder.cleanup()
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Every edit returns a new netlist that has been re-parsed and checked against the topology of the original. `save()` changes only the edited text: comments, spacing, line endings and encoding stay as they were. For the whole cycle with a solver, see [edit_and_simulate.py](docs/usage/examples/edit_and_simulate.py).
|
|
77
|
+
|
|
78
|
+
## What it does and does not do
|
|
79
|
+
|
|
80
|
+
- **Reads** titles, comments, the phase 1 elements, `.param`, `.model`, `.subckt`, the analysis, option and output directives, and LTspice's `.step`, into typed nodes with exact source spans. It answers queries about lines, references, nets and connections.
|
|
81
|
+
- **Edits** values, formulas, instance and model parameters, source DC and AC values and functions, `.param` lines and directives, and adds an `.include`.
|
|
82
|
+
- **Preserves** other dot-commands verbatim. `.control`, `.if`, `.include` and `.lib` are opaque: their contents are not read.
|
|
83
|
+
- **Never** changes topology (elements, nodes, subcircuit ports), evaluates a value, or launches a solver.
|
|
84
|
+
- **Refuses loudly.** A line outside the grammar is an error, not a guess. Netlists with Q or M devices are rejected until phase 2.
|
|
85
|
+
|
|
86
|
+
## Status
|
|
87
|
+
|
|
88
|
+
Phase 1 is complete, with both dialects validated on their solvers ([M9](docs/design/archive/phase-1/m9-tasks.md)), and phase 2 is under way. The current release is an alpha (`0.5.0`): the public API may still change before 1.0.
|
|
89
|
+
|
|
90
|
+
Supported platforms are Linux and Windows, with Python 3.13 or newer. LTspice validation runs on Windows. macOS is not tested.
|
|
91
|
+
|
|
92
|
+
- **Guides:** [usage](docs/usage/README.md), including the [error reference](docs/usage/errors.md).
|
|
93
|
+
- **Design:** [architecture](docs/architecture.md), [phase 2 plan](docs/design/phase-2-plan.md), [phase 1 plan](docs/design/archive/phase-1/phase-1-plan.md).
|
|
94
|
+
- **Development:** [testing](docs/testing.md), [changelog](CHANGELOG.md).
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# netlistmod
|
|
2
|
+
|
|
3
|
+
`netlistmod` is a source-preserving SPICE netlist editing library. Its goal is
|
|
4
|
+
to make permitted value and directive edits while preserving the original text
|
|
5
|
+
and circuit topology.
|
|
6
|
+
|
|
7
|
+
## Supported dialects
|
|
8
|
+
|
|
9
|
+
The caller always selects the dialect; there is no default and no detection.
|
|
10
|
+
|
|
11
|
+
| Dialect | `Dialect` | Input | Elements | Reference | Validated on |
|
|
12
|
+
|---|---|---|---|---|---|
|
|
13
|
+
| ngspice | `NGSPICE` | `.cir`, `.sp`, `.net`, KiCad exports | R, C, L, K, V, I, D, X; Q, M, J, Z (M13); E, F, G, H, S, W (M14); B and the expression forms (M15) | [ngspice manual](docs/references.md) | ngspice 47 |
|
|
14
|
+
| LTspice | `LTSPICE` | `.net`, `.cir` (an `.asc` schematic is [exported first](docs/usage/ltspice-export.md)) | R, C, L, K, V, I, D, X; Q, M, J, Z (M13); E, F, G, H, S, W (M14); B and the expression forms (M15) | [ltspice-reference](docs/references.md) | LTspice 26.1.1, Windows |
|
|
15
|
+
|
|
16
|
+
Where a solver and the library differ, the file is `docs/grammars/<dialect>/discrepancies.md`. Other
|
|
17
|
+
device letters raise `UnsupportedConstruct` until their phase 2 milestone.
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install netlistmod
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
To work on the library itself, clone it and run `uv sync`.
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
>>> from pathlib import Path
|
|
29
|
+
>>> from tempfile import TemporaryDirectory
|
|
30
|
+
>>> from netlistmod import Dialect, Netlist
|
|
31
|
+
>>> folder = TemporaryDirectory()
|
|
32
|
+
>>> path = Path(folder.name) / "divider.cir"
|
|
33
|
+
>>> _ = path.write_bytes(b"divider\nV1 in 0 DC 3\nR1 in out 1k ; top\nR2 out 0 1k\n.op\n.end\n")
|
|
34
|
+
|
|
35
|
+
>>> netlist = Netlist.load(path, dialect=Dialect.NGSPICE)
|
|
36
|
+
>>> edited = netlist.set_value("R2", "3k").directives.set(".tran 1u 5u")
|
|
37
|
+
>>> edited.save()
|
|
38
|
+
>>> print(path.read_text(), end="")
|
|
39
|
+
divider
|
|
40
|
+
V1 in 0 DC 3
|
|
41
|
+
R1 in out 1k ; top
|
|
42
|
+
R2 out 0 3k
|
|
43
|
+
.op
|
|
44
|
+
.tran 1u 5u
|
|
45
|
+
.end
|
|
46
|
+
>>> folder.cleanup()
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Every edit returns a new netlist that has been re-parsed and checked against the topology of the original. `save()` changes only the edited text: comments, spacing, line endings and encoding stay as they were. For the whole cycle with a solver, see [edit_and_simulate.py](docs/usage/examples/edit_and_simulate.py).
|
|
51
|
+
|
|
52
|
+
## What it does and does not do
|
|
53
|
+
|
|
54
|
+
- **Reads** titles, comments, the phase 1 elements, `.param`, `.model`, `.subckt`, the analysis, option and output directives, and LTspice's `.step`, into typed nodes with exact source spans. It answers queries about lines, references, nets and connections.
|
|
55
|
+
- **Edits** values, formulas, instance and model parameters, source DC and AC values and functions, `.param` lines and directives, and adds an `.include`.
|
|
56
|
+
- **Preserves** other dot-commands verbatim. `.control`, `.if`, `.include` and `.lib` are opaque: their contents are not read.
|
|
57
|
+
- **Never** changes topology (elements, nodes, subcircuit ports), evaluates a value, or launches a solver.
|
|
58
|
+
- **Refuses loudly.** A line outside the grammar is an error, not a guess. Netlists with Q or M devices are rejected until phase 2.
|
|
59
|
+
|
|
60
|
+
## Status
|
|
61
|
+
|
|
62
|
+
Phase 1 is complete, with both dialects validated on their solvers ([M9](docs/design/archive/phase-1/m9-tasks.md)), and phase 2 is under way. The current release is an alpha (`0.5.0`): the public API may still change before 1.0.
|
|
63
|
+
|
|
64
|
+
Supported platforms are Linux and Windows, with Python 3.13 or newer. LTspice validation runs on Windows. macOS is not tested.
|
|
65
|
+
|
|
66
|
+
- **Guides:** [usage](docs/usage/README.md), including the [error reference](docs/usage/errors.md).
|
|
67
|
+
- **Design:** [architecture](docs/architecture.md), [phase 2 plan](docs/design/phase-2-plan.md), [phase 1 plan](docs/design/archive/phase-1/phase-1-plan.md).
|
|
68
|
+
- **Development:** [testing](docs/testing.md), [changelog](CHANGELOG.md).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Architecture decisions
|
|
2
|
+
|
|
3
|
+
Record changes to normative architecture requirements here before implementing
|
|
4
|
+
them. Use [the decision record template](TEMPLATE.md).
|
|
5
|
+
|
|
6
|
+
- [0001 — Source text policy](0001-source-text-policy.md)
|
|
7
|
+
- [0002 — Grammar structure policy](0002-grammar-structure-policy.md)
|
|
8
|
+
- [0003 — Grammar composition and opaque regions](0003-grammar-composition-and-opaque-regions.md)
|
|
9
|
+
- [0004 — Element and value grammar](0004-element-and-value-grammar.md)
|
|
10
|
+
- [0005 — Statement and directive grammar](0005-statement-and-directive-grammar.md)
|
|
11
|
+
- [0006 — Document layer: names, scope and diagnostics](0006-document-layer-names-scope-and-diagnostics.md)
|
|
12
|
+
- [0007 — Edit lifecycle and edit semantics](0007-edit-lifecycle-and-edit-semantics.md)
|
|
13
|
+
- [0008 — Validation status and solver harnesses](0008-validation-status-and-solver-harnesses.md)
|
|
14
|
+
- [0009 — The LTspice dialect](0009-ltspice-dialect.md)
|
|
15
|
+
- [0010 — Phase 1 close-out](0010-phase-1-close-out.md)
|
|
16
|
+
- [0011 — CI and release scope](0011-ci-and-release-scope.md)
|
|
17
|
+
- [0012 — Carried limits from phase 1](0012-carried-limits.md)
|
|
18
|
+
- [0013 — Stimulus specs](0013-stimulus-specs.md)
|
|
19
|
+
- [0014 — Transistors](0014-transistors.md)
|
|
20
|
+
- [0015 — Linear dependent sources and switches](0015-controlled-sources.md)
|
|
21
|
+
- [0016 — Behavioural expressions](0016-behavioral-expressions.md)
|
|
22
|
+
- [0018 — Publishing to PyPI](0018-pypi-publication.md) (0017 is reserved for M15b)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Design documents
|
|
2
|
+
|
|
3
|
+
Active plans and design notes live in this folder. Completed work records move to
|
|
4
|
+
[archive/](./archive/) so that this folder only shows what is current.
|
|
5
|
+
|
|
6
|
+
## Conventions
|
|
7
|
+
|
|
8
|
+
- Every document starts with a `Status:` line: `DRAFT`, `READY` (approved, not started), `ACTIVE`, `READY FOR REVIEW` (implemented, awaiting the maintainer), or `COMPLETE (date)`.
|
|
9
|
+
- When a milestone or design finishes and the maintainer has **approved its review**, `git mv`
|
|
10
|
+
its task list or design note into `archive/phase-N/` (keep the file name), set the status to
|
|
11
|
+
`COMPLETE`, and fix relative links. A finished implementation is `READY FOR REVIEW`, not
|
|
12
|
+
`COMPLETE`, and stays in this folder until then. The plan that owns it keeps a link to the
|
|
13
|
+
archived record.
|
|
14
|
+
- Archived files are history: do not edit them except to fix links. Changes to
|
|
15
|
+
normative behavior go through a decision record in `../decisions/`.
|
|
16
|
+
- **Living references** (`elements.md`, `statements.md`, `document-layer.md`, `edit-layer.md`) describe the library as it is, not a piece of work. They stay `ACTIVE` in this folder and are not archived. A change to the public API updates them in the same commit; `tests/architecture/test_design_notes.py` fails if a public name is missing. Their state at each milestone is in Git history. They were renamed in M9 from `m3-elements.md`, `m4-statements.md`, `m5-document.md` and `m6-edits.md`, the names the archived task lists still use in prose.
|
|
17
|
+
- `archive/` is grouped by phase: phase 1's records are in `archive/phase-1/` and phase 2's in `archive/phase-2/`.
|
|
18
|
+
|
|
19
|
+
## Index
|
|
20
|
+
|
|
21
|
+
| Document | Status |
|
|
22
|
+
|---|---|
|
|
23
|
+
| [phase-2-plan.md](./phase-2-plan.md) | ACTIVE |
|
|
24
|
+
| [m15b-tasks.md](./m15b-tasks.md) | DRAFT |
|
|
25
|
+
| [elements.md](./elements.md) | ACTIVE (living reference) |
|
|
26
|
+
| [statements.md](./statements.md) | ACTIVE (living reference) |
|
|
27
|
+
| [document-layer.md](./document-layer.md) | ACTIVE (living reference) |
|
|
28
|
+
| [edit-layer.md](./edit-layer.md) | ACTIVE (living reference) |
|
|
29
|
+
| [archive/phase-2/m10-tasks.md](./archive/phase-2/m10-tasks.md) | COMPLETE (2026-11-03) |
|
|
30
|
+
| [archive/phase-2/m12-tasks.md](./archive/phase-2/m12-tasks.md) | COMPLETE (2026-11-04) |
|
|
31
|
+
| [archive/phase-2/m11-tasks.md](./archive/phase-2/m11-tasks.md) | COMPLETE (2026-11-04) |
|
|
32
|
+
| [archive/phase-2/m13-tasks.md](./archive/phase-2/m13-tasks.md) | COMPLETE (2026-11-06) |
|
|
33
|
+
| [archive/phase-2/m14-tasks.md](./archive/phase-2/m14-tasks.md) | COMPLETE (2026-11-06) |
|
|
34
|
+
| [archive/phase-2/m15-tasks.md](./archive/phase-2/m15-tasks.md) | COMPLETE (2026-11-06) |
|
|
35
|
+
| [archive/phase-2/phase-2-code-changes.md](./archive/phase-2/phase-2-code-changes.md) | COMPLETE (2026-11-03) |
|
|
36
|
+
| [archive/phase-1/m0-tasks.md](./archive/phase-1/m0-tasks.md) | COMPLETE (2026-10-20) |
|
|
37
|
+
| [archive/phase-1/m1-tasks.md](./archive/phase-1/m1-tasks.md) | COMPLETE (2026-10-21) |
|
|
38
|
+
| [archive/phase-1/m2-tasks.md](./archive/phase-1/m2-tasks.md) | COMPLETE (2026-10-30) |
|
|
39
|
+
| [archive/phase-1/m2-review2-tasks.md](./archive/phase-1/m2-review2-tasks.md) | COMPLETE (2026-10-30) |
|
|
40
|
+
| [archive/phase-1/m3-tasks.md](./archive/phase-1/m3-tasks.md) | COMPLETE (2026-10-30) |
|
|
41
|
+
| [archive/phase-1/m4-tasks.md](./archive/phase-1/m4-tasks.md) | COMPLETE (2026-10-31) |
|
|
42
|
+
| [archive/phase-1/m5-tasks.md](./archive/phase-1/m5-tasks.md) | COMPLETE (2026-10-31) |
|
|
43
|
+
| [archive/phase-1/m6-tasks.md](./archive/phase-1/m6-tasks.md) | COMPLETE (2026-10-31) |
|
|
44
|
+
| [archive/phase-1/m7-tasks.md](./archive/phase-1/m7-tasks.md) | COMPLETE (2026-10-31) |
|
|
45
|
+
| [archive/phase-1/m8-tasks.md](./archive/phase-1/m8-tasks.md) | COMPLETE (2026-11-02) |
|
|
46
|
+
| [archive/phase-1/m9-tasks.md](./archive/phase-1/m9-tasks.md) | COMPLETE (2026-11-03) |
|
|
47
|
+
| [archive/phase-1/phase-1-review.md](./archive/phase-1/phase-1-review.md) | COMPLETE (2026-11-03) |
|
|
48
|
+
| [archive/phase-1/phase-1-plan.md](./archive/phase-1/phase-1-plan.md) | COMPLETE (2026-11-03) |
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# LTspice grammar
|
|
2
|
+
|
|
3
|
+
The LTspice grammar (M8, [decision 0009](../../decisions/0009-ltspice-dialect.md)) and its
|
|
4
|
+
conformance records:
|
|
5
|
+
|
|
6
|
+
- [Device-letter matrix](./devices.md) and its packaged
|
|
7
|
+
[machine-readable source](../../../src/netlistmod/grammar/ltspice-devices.json).
|
|
8
|
+
- [Numbers and values](./numbers.md): numbers, the embedded decimal and formulas.
|
|
9
|
+
- [Spec entries](./specs/) cite the reference and link to tests.
|
|
10
|
+
- [Names](./names.md) and [scoping](./scoping.md) rules of the document layer.
|
|
11
|
+
- [Discrepancies](./discrepancies.md) records where LTspice and the library differ.
|
|
12
|
+
- [The LTspice export workflow](../../usage/ltspice-export.md).
|
|
13
|
+
|
|
14
|
+
The manual for this dialect is `analogdevicesinc/ltspice-reference`, cited as
|
|
15
|
+
`[ltspice-ref] <FILE>.md "<heading>"` ([references.md](../../references.md)). The repository records
|
|
16
|
+
only syntax facts about LTspice: never its raw files, logs, or timing or performance numbers
|
|
17
|
+
(decision 0009 item 2). `core_rules` in an entry names the shared rules of `core.lark` and
|
|
18
|
+
`formula.lark` it relies on; `grammar` names the rules of `ltspice.lark`.
|
|
19
|
+
|
|
20
|
+
## Construct survey (M8 T1)
|
|
21
|
+
|
|
22
|
+
| Construct | Reference | ngspice form shared? | LTspice overlay |
|
|
23
|
+
|---|---|---|---|
|
|
24
|
+
| Title, `.end` | [SYNTAX] Netlist Structure | yes | `.end` takes a comment |
|
|
25
|
+
| Comments | [SYNTAX] Comments and Line Continuation | `*` and `;` only | `;` lines, ` $ `; no `//` |
|
|
26
|
+
| Continuation | same | `+` only | no `\\` |
|
|
27
|
+
| Separators | element syntax | blanks only | commas in few places |
|
|
28
|
+
| Names | [SYNTAX] Node Naming | no | own character set, Unicode fold, `$G_*` |
|
|
29
|
+
| Numbers | [SYNTAX] Engineering Multipliers | standard form | embedded decimal in every slot, any trailing letters |
|
|
30
|
+
| R | [ELEMENTS] R | value, formula | `tc` list, closed list; no model or keyword form |
|
|
31
|
+
| C, L | [ELEMENTS] C, L | value, formula; C `Q=`, L `Flux=` and the hysteretic core (M15) | closed lists; no parameters on `Flux=` or the hysteretic core |
|
|
32
|
+
| V, I | [ELEMENTS] V, I | DC, AC | `AC=`, `Rser`, `Cpar`, `load`, `R=` |
|
|
33
|
+
| D | [ELEMENTS] D | model | positional area, closed list |
|
|
34
|
+
| X, `.subckt` | [ELEMENTS] X, [COMMANDS] .SUBCKT | yes | `params:` accepted |
|
|
35
|
+
| K | [ELEMENTS] K | yes | |
|
|
36
|
+
| `.param` | [COMMANDS] .PARAM | `=` with a number or formula | no `=`, bare expressions, other names |
|
|
37
|
+
| `.model` | [COMMANDS] .MODEL | yes | `ako:` |
|
|
38
|
+
| `.tran` | [COMMANDS] .TRAN | yes | one argument, modifiers |
|
|
39
|
+
| `.ac` | [COMMANDS] .AC | yes | `list`, `file=` |
|
|
40
|
+
| `.dc` | [COMMANDS] .DC | yes | three sweeps, variation, `list`, `file=` |
|
|
41
|
+
| `.op` | [COMMANDS] .OP | yes | |
|
|
42
|
+
| `.temp` | [COMMANDS] .TEMP | one value | a list |
|
|
43
|
+
| `.options` | [COMMANDS] .OPTIONS | yes | `.opt` |
|
|
44
|
+
| `.ic`, `.nodeset` | [TROUBLE] | `v(n)=` | no `all=` |
|
|
45
|
+
| `.save` | [COMMANDS] .SAVE | `v()`, `i()` | device currents, wildcards; no plain names |
|
|
46
|
+
| `.meas` | [COMMANDS] .MEASURE | yes | optional analysis, `noise`, `op`; no `sp` |
|
|
47
|
+
| `.global` | [COMMANDS] .GLOBAL | yes | |
|
|
48
|
+
| `.step` | [COMMANDS] .STEP | no | new typed node |
|
|
49
|
+
| Other dot-commands | [COMMANDS] | no | closed list |
|
|
50
|
+
|
|
51
|
+
## Validation status
|
|
52
|
+
|
|
53
|
+
Status words have the meanings of
|
|
54
|
+
[decision 0008](../../decisions/0008-validation-status-and-solver-harnesses.md);
|
|
55
|
+
`tests/architecture/test_spec_coverage.py` checks each against its evidence and this table against
|
|
56
|
+
the entries. The probes are in `tests/solver/test_ltspice_validation.py`; a part of an entry that the
|
|
57
|
+
reference does not mention is marked observed in the entry's notes (§11.3 rule 3).
|
|
58
|
+
|
|
59
|
+
| Entry | Construct | Status | Validated on |
|
|
60
|
+
|---|---|---|---|
|
|
61
|
+
| [LT-ACA-001](./specs/LT-ACA-001.yaml) | .ac | validated | ltspice 26.1.1 (2026-11-01) |
|
|
62
|
+
| [LT-BEH-001](./specs/LT-BEH-001.yaml) | behavioral source (B) lines | validated | ltspice 26.1.1 (2026-11-06) |
|
|
63
|
+
| [LT-BJT-001](./specs/LT-BJT-001.yaml) | bipolar transistor (Q) lines | validated | ltspice 26.1.1 (2026-11-05) |
|
|
64
|
+
| [LT-CAP-001](./specs/LT-CAP-001.yaml) | capacitor (C) lines | validated | ltspice 26.1.1 (2026-11-01, 2026-11-06) |
|
|
65
|
+
| [LT-CCC-001](./specs/LT-CCC-001.yaml) | current-dependent current source (F) lines | validated | ltspice 26.1.1 (2026-11-06) |
|
|
66
|
+
| [LT-CCV-001](./specs/LT-CCV-001.yaml) | current-dependent voltage source (H) lines | validated | ltspice 26.1.1 (2026-11-06) |
|
|
67
|
+
| [LT-CNT-001](./specs/LT-CNT-001.yaml) | + continuation lines | validated | ltspice 26.1.1 (2026-11-01) |
|
|
68
|
+
| [LT-COM-001](./specs/LT-COM-001.yaml) | comment lines (* and ;) | validated | ltspice 26.1.1 (2026-11-01) |
|
|
69
|
+
| [LT-COM-002](./specs/LT-COM-002.yaml) | end-of-line comments (; and space-$-space) | validated | ltspice 26.1.1 (2026-11-01) |
|
|
70
|
+
| [LT-CTL-001](./specs/LT-CTL-001.yaml) | shared shape of the linear dependent sources and switches | validated | ltspice 26.1.1 (2026-11-06) |
|
|
71
|
+
| [LT-DCA-001](./specs/LT-DCA-001.yaml) | .dc | validated | ltspice 26.1.1 (2026-11-01) |
|
|
72
|
+
| [LT-DIO-001](./specs/LT-DIO-001.yaml) | diode (D) lines | validated | ltspice 26.1.1 (2026-11-01) |
|
|
73
|
+
| [LT-DIR-001](./specs/LT-DIR-001.yaml) | closed list of dot-commands | validated | ltspice 26.1.1 (2026-11-01) |
|
|
74
|
+
| [LT-END-001](./specs/LT-END-001.yaml) | required final .end | validated | ltspice 26.1.1 (2026-11-01) |
|
|
75
|
+
| [LT-FLD-001](./specs/LT-FLD-001.yaml) | field separators | validated | ltspice 26.1.1 (2026-11-01) |
|
|
76
|
+
| [LT-FML-001](./specs/LT-FML-001.yaml) | formula expression syntax (reference scan only) | validated | ltspice 26.1.1 (2026-11-01) |
|
|
77
|
+
| [LT-FUN-001](./specs/LT-FUN-001.yaml) | source functions, shared syntax | validated | ltspice 26.1.1 (2026-11-04) |
|
|
78
|
+
| [LT-FUN-002](./specs/LT-FUN-002.yaml) | PULSE | validated | ltspice 26.1.1 (2026-11-04) |
|
|
79
|
+
| [LT-FUN-003](./specs/LT-FUN-003.yaml) | SINE and SIN | validated | ltspice 26.1.1 (2026-11-04) |
|
|
80
|
+
| [LT-FUN-004](./specs/LT-FUN-004.yaml) | EXP | validated | ltspice 26.1.1 (2026-11-04) |
|
|
81
|
+
| [LT-FUN-005](./specs/LT-FUN-005.yaml) | SFFM | validated | ltspice 26.1.1 (2026-11-04) |
|
|
82
|
+
| [LT-FUN-006](./specs/LT-FUN-006.yaml) | PWL with its scale factors and file | validated | ltspice 26.1.1 (2026-11-04) |
|
|
83
|
+
| [LT-FUN-007](./specs/LT-FUN-007.yaml) | PWL REPEAT | validated | ltspice 26.1.1 (2026-11-04) |
|
|
84
|
+
| [LT-FUN-008](./specs/LT-FUN-008.yaml) | wave file | validated | ltspice 26.1.1 (2026-11-04) |
|
|
85
|
+
| [LT-FUN-009](./specs/LT-FUN-009.yaml) | I table | validated | ltspice 26.1.1 (2026-11-04) |
|
|
86
|
+
| [LT-FUN-010](./specs/LT-FUN-010.yaml) | I step load | validated | ltspice 26.1.1 (2026-11-04) |
|
|
87
|
+
| [LT-GLB-001](./specs/LT-GLB-001.yaml) | .global | validated | ltspice 26.1.1 (2026-11-01) |
|
|
88
|
+
| [LT-ICN-001](./specs/LT-ICN-001.yaml) | .ic and .nodeset | validated | ltspice 26.1.1 (2026-11-01) |
|
|
89
|
+
| [LT-IND-001](./specs/LT-IND-001.yaml) | inductor (L) lines | validated | ltspice 26.1.1 (2026-11-01, 2026-11-06) |
|
|
90
|
+
| [LT-JFT-001](./specs/LT-JFT-001.yaml) | junction FET (J) lines | validated | ltspice 26.1.1 (2026-11-05) |
|
|
91
|
+
| [LT-MCH-001](./specs/LT-MCH-001.yaml) | .machine blocks | validated | ltspice 26.1.1 (2026-11-01) |
|
|
92
|
+
| [LT-MEA-001](./specs/LT-MEA-001.yaml) | .meas and .measure | validated | ltspice 26.1.1 (2026-11-01) |
|
|
93
|
+
| [LT-MES-001](./specs/LT-MES-001.yaml) | MESFET and IGBT (Z) lines | validated | ltspice 26.1.1 (2026-11-05) |
|
|
94
|
+
| [LT-MOD-001](./specs/LT-MOD-001.yaml) | .model statements | validated | ltspice 26.1.1 (2026-11-01, 2026-11-05) |
|
|
95
|
+
| [LT-MOS-001](./specs/LT-MOS-001.yaml) | MOSFET and VDMOS (M) lines | validated | ltspice 26.1.1 (2026-11-05) |
|
|
96
|
+
| [LT-MUT-001](./specs/LT-MUT-001.yaml) | mutual inductance (K) lines | validated | ltspice 26.1.1 (2026-11-01) |
|
|
97
|
+
| [LT-NLS-001](./specs/LT-NLS-001.yaml) | expression forms of the dependent sources (value= on E, F, G and H) | validated | ltspice 26.1.1 (2026-11-06) |
|
|
98
|
+
| [LT-NOD-001](./specs/LT-NOD-001.yaml) | node, element and subcircuit names | validated | ltspice 26.1.1 (2026-11-01) |
|
|
99
|
+
| [LT-NUM-001](./specs/LT-NUM-001.yaml) | numbers | validated | ltspice 26.1.1 (2026-11-01) |
|
|
100
|
+
| [LT-NUM-002](./specs/LT-NUM-002.yaml) | letters following a number | validated | ltspice 26.1.1 (2026-11-01) |
|
|
101
|
+
| [LT-NUM-003](./specs/LT-NUM-003.yaml) | embedded decimal | validated | ltspice 26.1.1 (2026-11-01) |
|
|
102
|
+
| [LT-NUM-004](./specs/LT-NUM-004.yaml) | micro signs | validated | ltspice 26.1.1 (2026-11-01) |
|
|
103
|
+
| [LT-OPA-001](./specs/LT-OPA-001.yaml) | opaque .include, .inc and .lib, and .lib blocks | validated | ltspice 26.1.1 (2026-11-01) |
|
|
104
|
+
| [LT-OPP-001](./specs/LT-OPP-001.yaml) | .op | validated | ltspice 26.1.1 (2026-11-01) |
|
|
105
|
+
| [LT-OPT-001](./specs/LT-OPT-001.yaml) | .options, .option and .opt | validated | ltspice 26.1.1 (2026-11-01) |
|
|
106
|
+
| [LT-PRM-001](./specs/LT-PRM-001.yaml) | .param assignments | validated | ltspice 26.1.1 (2026-11-01) |
|
|
107
|
+
| [LT-RES-001](./specs/LT-RES-001.yaml) | resistor (R) lines | validated | ltspice 26.1.1 (2026-11-01) |
|
|
108
|
+
| [LT-SAV-001](./specs/LT-SAV-001.yaml) | .save | validated | ltspice 26.1.1 (2026-11-01) |
|
|
109
|
+
| [LT-SBD-001](./specs/LT-SBD-001.yaml) | .subckt ... .ends definitions | validated | ltspice 26.1.1 (2026-11-01) |
|
|
110
|
+
| [LT-SRC-001](./specs/LT-SRC-001.yaml) | independent sources (V, I) | validated | ltspice 26.1.1 (2026-11-01) |
|
|
111
|
+
| [LT-STP-001](./specs/LT-STP-001.yaml) | .step | validated | ltspice 26.1.1 (2026-11-01) |
|
|
112
|
+
| [LT-STR-001](./specs/LT-STR-001.yaml) | top-level source structure | validated | ltspice 26.1.1 (2026-11-01) |
|
|
113
|
+
| [LT-SUB-001](./specs/LT-SUB-001.yaml) | subcircuit calls (X) | validated | ltspice 26.1.1 (2026-11-01) |
|
|
114
|
+
| [LT-SWC-001](./specs/LT-SWC-001.yaml) | current-controlled switch (W) lines | validated | ltspice 26.1.1 (2026-11-06) |
|
|
115
|
+
| [LT-SWV-001](./specs/LT-SWV-001.yaml) | voltage-controlled switch (S) lines | validated | ltspice 26.1.1 (2026-11-06) |
|
|
116
|
+
| [LT-TMP-001](./specs/LT-TMP-001.yaml) | .temp | validated | ltspice 26.1.1 (2026-11-01) |
|
|
117
|
+
| [LT-TRN-001](./specs/LT-TRN-001.yaml) | .tran | validated | ltspice 26.1.1 (2026-11-01) |
|
|
118
|
+
| [LT-TTL-001](./specs/LT-TTL-001.yaml) | implicit first-line title and .title | validated | ltspice 26.1.1 (2026-11-01) |
|
|
119
|
+
| [LT-TXT-001](./specs/LT-TXT-001.yaml) | statement text | validated | ltspice 26.1.1 (2026-11-01) |
|
|
120
|
+
| [LT-UNS-001](./specs/LT-UNS-001.yaml) | recognised but unsupported forms | validated | ltspice 26.1.1 (2026-11-01) |
|
|
121
|
+
| [LT-VAL-001](./specs/LT-VAL-001.yaml) | brace and quoted expressions | validated | ltspice 26.1.1 (2026-11-01) |
|
|
122
|
+
| [LT-VCC-001](./specs/LT-VCC-001.yaml) | voltage-dependent current source (G) lines | validated | ltspice 26.1.1 (2026-11-06) |
|
|
123
|
+
| [LT-VCV-001](./specs/LT-VCV-001.yaml) | voltage-dependent voltage source (E) lines | validated | ltspice 26.1.1 (2026-11-06) |
|
|
124
|
+
| [LT-XTR-001](./specs/LT-XTR-001.yaml) | shared transistor line shape (Q, M, J, Z) | validated | ltspice 26.1.1 (2026-11-05) |
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# ngspice grammar
|
|
2
|
+
|
|
3
|
+
The ngspice grammar (M2 structure, M3 elements and values) and its conformance
|
|
4
|
+
records are tracked here:
|
|
5
|
+
|
|
6
|
+
- [Device-letter matrix](./devices.md) and its packaged
|
|
7
|
+
[machine-readable source](../../../src/netlistmod/grammar/ngspice-devices.json).
|
|
8
|
+
- [Numbers and values](./numbers.md): number, RKM and formula rules.
|
|
9
|
+
- [Spec entries](./specs/) cite the ngspice manual and link to tests.
|
|
10
|
+
- [Names](./names.md) and [scoping](./scoping.md) rules of the document layer.
|
|
11
|
+
- [Discrepancies](./discrepancies.md) records probe results that differ from
|
|
12
|
+
or extend the manual.
|
|
13
|
+
|
|
14
|
+
## Validation status
|
|
15
|
+
|
|
16
|
+
Status words have the meanings of
|
|
17
|
+
[decision 0008](../../decisions/0008-validation-status-and-solver-harnesses.md);
|
|
18
|
+
`tests/architecture/test_spec_coverage.py` checks each against its solver evidence and this
|
|
19
|
+
table against the entries. Re-validating appends a version to an entry (docs/testing.md).
|
|
20
|
+
|
|
21
|
+
| Entry | Construct | Status | Validated on |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| [NG-ACA-001](./specs/NG-ACA-001.yaml) | .ac small-signal analysis | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
24
|
+
| [NG-BEH-001](./specs/NG-BEH-001.yaml) | behavioral source (B) lines | validated | ngspice 47 (2026-11-06) |
|
|
25
|
+
| [NG-BJT-001](./specs/NG-BJT-001.yaml) | bipolar transistor (Q) lines | validated | ngspice 47 (2026-11-05) |
|
|
26
|
+
| [NG-CAP-001](./specs/NG-CAP-001.yaml) | capacitor (C) lines | validated | ngspice 47 (2026-10-30, 2026-10-31, 2026-11-06) |
|
|
27
|
+
| [NG-CCC-001](./specs/NG-CCC-001.yaml) | current-controlled current source (F) lines | validated | ngspice 47 (2026-11-06) |
|
|
28
|
+
| [NG-CCV-001](./specs/NG-CCV-001.yaml) | current-controlled voltage source (H) lines | validated | ngspice 47 (2026-11-06) |
|
|
29
|
+
| [NG-CNT-001](./specs/NG-CNT-001.yaml) | immediately adjacent continuation lines (+ and trailing \\) | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
30
|
+
| [NG-COM-001](./specs/NG-COM-001.yaml) | full-line star comments | observed | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
31
|
+
| [NG-CTL-001](./specs/NG-CTL-001.yaml) | shared shape of the linear dependent sources and switches | validated | ngspice 47 (2026-11-06) |
|
|
32
|
+
| [NG-DCA-001](./specs/NG-DCA-001.yaml) | .dc transfer function | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
33
|
+
| [NG-DIO-001](./specs/NG-DIO-001.yaml) | junction diode (D) lines | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
34
|
+
| [NG-DIR-001](./specs/NG-DIR-001.yaml) | unknown dot-commands and stray block terminators | validated | ngspice 47 (2026-10-31) |
|
|
35
|
+
| [NG-END-001](./specs/NG-END-001.yaml) | required final .end statement | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
36
|
+
| [NG-FLD-001](./specs/NG-FLD-001.yaml) | element field separators: blanks, one comma, = with blanks, continuation | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
37
|
+
| [NG-FML-001](./specs/NG-FML-001.yaml) | Formula expression syntax (reference scan only) | validated | ngspice 47 (2026-10-31) |
|
|
38
|
+
| [NG-FUN-001](./specs/NG-FUN-001.yaml) | source functions, shared syntax | validated | ngspice 47 (2026-11-04) |
|
|
39
|
+
| [NG-FUN-002](./specs/NG-FUN-002.yaml) | PULSE | validated | ngspice 47 (2026-11-04) |
|
|
40
|
+
| [NG-FUN-003](./specs/NG-FUN-003.yaml) | SIN, and SINE | validated | ngspice 47 (2026-11-04) |
|
|
41
|
+
| [NG-FUN-004](./specs/NG-FUN-004.yaml) | EXP | validated | ngspice 47 (2026-11-04) |
|
|
42
|
+
| [NG-FUN-005](./specs/NG-FUN-005.yaml) | PWL with r= and td= | validated | ngspice 47 (2026-11-04) |
|
|
43
|
+
| [NG-FUN-006](./specs/NG-FUN-006.yaml) | SFFM | validated | ngspice 47 (2026-11-04) |
|
|
44
|
+
| [NG-FUN-007](./specs/NG-FUN-007.yaml) | AM | validated | ngspice 47 (2026-11-04) |
|
|
45
|
+
| [NG-FUN-008](./specs/NG-FUN-008.yaml) | TRNOISE | validated | ngspice 47 (2026-11-04) |
|
|
46
|
+
| [NG-FUN-009](./specs/NG-FUN-009.yaml) | TRRANDOM | validated | ngspice 47 (2026-11-04) |
|
|
47
|
+
| [NG-FUN-010](./specs/NG-FUN-010.yaml) | EXTERNAL | validated | ngspice 47 (2026-11-04) |
|
|
48
|
+
| [NG-FUN-011](./specs/NG-FUN-011.yaml) | DISTOF1 and DISTOF2 | validated | ngspice 47 (2026-11-04) |
|
|
49
|
+
| [NG-FUN-012](./specs/NG-FUN-012.yaml) | RF port parameters | validated | ngspice 47 (2026-11-04) |
|
|
50
|
+
| [NG-GLB-001](./specs/NG-GLB-001.yaml) | .global node declarations | validated | ngspice 47 (2026-10-31) |
|
|
51
|
+
| [NG-ICN-001](./specs/NG-ICN-001.yaml) | .ic and .nodeset | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
52
|
+
| [NG-IND-001](./specs/NG-IND-001.yaml) | inductor (L) lines | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
53
|
+
| [NG-JFT-001](./specs/NG-JFT-001.yaml) | junction FET (J) lines | validated | ngspice 47 (2026-11-05) |
|
|
54
|
+
| [NG-MEA-001](./specs/NG-MEA-001.yaml) | .meas / .measure (shallow) | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
55
|
+
| [NG-MES-001](./specs/NG-MES-001.yaml) | MESFET (Z) lines | validated | ngspice 47 (2026-11-05) |
|
|
56
|
+
| [NG-MOD-001](./specs/NG-MOD-001.yaml) | .model statements | validated | ngspice 47 (2026-10-30, 2026-10-31, 2026-11-05) |
|
|
57
|
+
| [NG-MOS-001](./specs/NG-MOS-001.yaml) | MOSFET and VDMOS (M) lines | validated | ngspice 47 (2026-11-05) |
|
|
58
|
+
| [NG-MUT-001](./specs/NG-MUT-001.yaml) | mutual coupling (K) lines | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
59
|
+
| [NG-NLS-001](./specs/NG-NLS-001.yaml) | expression forms of the dependent sources (E vol= and value, G cur= and value) | validated | ngspice 47 (2026-11-06) |
|
|
60
|
+
| [NG-NOD-001](./specs/NG-NOD-001.yaml) | node, model, subcircuit and parameter names | validated | ngspice 47 (2026-10-31) |
|
|
61
|
+
| [NG-NUM-001](./specs/NG-NUM-001.yaml) | numbers: sign, mantissa, exponent and scale factor | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
62
|
+
| [NG-NUM-002](./specs/NG-NUM-002.yaml) | letters following a number | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
63
|
+
| [NG-NUM-003](./specs/NG-NUM-003.yaml) | RKM notation for R and C values (parser option rkm) | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
64
|
+
| [NG-NUM-004](./specs/NG-NUM-004.yaml) | micro sign as a scale factor | observed | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
65
|
+
| [NG-OPA-001](./specs/NG-OPA-001.yaml) | opaque .control and nested .if blocks | validated | ngspice 47 (2026-10-22, 2026-10-31) |
|
|
66
|
+
| [NG-OPA-002](./specs/NG-OPA-002.yaml) | opaque .include and .lib statements, and .lib blocks | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
67
|
+
| [NG-OPP-001](./specs/NG-OPP-001.yaml) | .op operating point | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
68
|
+
| [NG-OPT-001](./specs/NG-OPT-001.yaml) | .options / .option | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
69
|
+
| [NG-PAR-001](./specs/NG-PAR-001.yaml) | instance parameters, model references and the off flag | validated | ngspice 47 (2026-10-31) |
|
|
70
|
+
| [NG-PRM-001](./specs/NG-PRM-001.yaml) | .param assignments | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
71
|
+
| [NG-RES-001](./specs/NG-RES-001.yaml) | resistor (R) lines | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
72
|
+
| [NG-SAV-001](./specs/NG-SAV-001.yaml) | .save output vectors | validated | ngspice 47 (2026-10-31) |
|
|
73
|
+
| [NG-SBD-001](./specs/NG-SBD-001.yaml) | .subckt ... .ends definitions and their bodies | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
74
|
+
| [NG-SRC-001](./specs/NG-SRC-001.yaml) | independent sources (V, I): DC value and AC magnitude and phase | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
75
|
+
| [NG-STR-001](./specs/NG-STR-001.yaml) | top-level source structure | validated | ngspice 47 (2026-10-31) |
|
|
76
|
+
| [NG-SUB-001](./specs/NG-SUB-001.yaml) | subcircuit calls (X) | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
77
|
+
| [NG-SWC-001](./specs/NG-SWC-001.yaml) | current-controlled switch (W) lines | validated | ngspice 47 (2026-11-06) |
|
|
78
|
+
| [NG-SWV-001](./specs/NG-SWV-001.yaml) | voltage-controlled switch (S) lines | validated | ngspice 47 (2026-11-06) |
|
|
79
|
+
| [NG-TMP-001](./specs/NG-TMP-001.yaml) | .temp | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
80
|
+
| [NG-TRN-001](./specs/NG-TRN-001.yaml) | .tran transient analysis | validated | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
81
|
+
| [NG-TTL-001](./specs/NG-TTL-001.yaml) | implicit first-line title and explicit .title | validated | ngspice 47 (2026-10-22, 2026-10-31) |
|
|
82
|
+
| [NG-TXT-001](./specs/NG-TXT-001.yaml) | free text, quoted and braced segments, and trailing comments | observed | ngspice 47 (2026-10-30, 2026-10-31) |
|
|
83
|
+
| [NG-UNS-001](./specs/NG-UNS-001.yaml) | recognised but unsupported element forms | validated | ngspice 47 (2026-10-31) |
|
|
84
|
+
| [NG-VAL-001](./specs/NG-VAL-001.yaml) | brace and quoted expressions, and string parameter values | validated | ngspice 47 (2026-10-31) |
|
|
85
|
+
| [NG-VCC-001](./specs/NG-VCC-001.yaml) | voltage-controlled current source (G) lines | validated | ngspice 47 (2026-11-06) |
|
|
86
|
+
| [NG-VCV-001](./specs/NG-VCV-001.yaml) | voltage-controlled voltage source (E) lines | validated | ngspice 47 (2026-11-06) |
|
|
87
|
+
| [NG-XTR-001](./specs/NG-XTR-001.yaml) | shared transistor line shape (Q, M, J, Z) | validated | ngspice 47 (2026-11-05) |
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Usage guides
|
|
2
|
+
|
|
3
|
+
The examples in these guides are executed by the test suite. Each guide says which dialect it covers.
|
|
4
|
+
|
|
5
|
+
| Guide | Covers |
|
|
6
|
+
|---|---|
|
|
7
|
+
| [Parsing structural source](./structural-parse.md) | Titles, comments, continuations and opaque items |
|
|
8
|
+
| [Parsing element lines](./elements.md) | R, C, L, K, V, I, D and X |
|
|
9
|
+
| [Parsing statements and directives](./statements.md) | `.param`, `.model`, `.subckt` and the directives |
|
|
10
|
+
| [Reading a netlist](./document.md) | Lines, references, nets and diagnostics |
|
|
11
|
+
| [Editing a netlist](./editing.md) | Every edit, verification and `save()` |
|
|
12
|
+
| [Errors and diagnostics](./errors.md) | Each exception and diagnostic code, and what to do |
|
|
13
|
+
| [Exporting from LTspice](./ltspice-export.md) | From an `.asc` schematic to a netlist, and batch runs |
|
|
14
|
+
|
|
15
|
+
Examples you can run:
|
|
16
|
+
|
|
17
|
+
- [read_only_demo.py](./examples/read_only_demo.py): what the library sees in a KiCad export.
|
|
18
|
+
- [edit_and_simulate.py](./examples/edit_and_simulate.py): load, edit, save and run `.op` in a solver, on a built-in divider or your own netlist, and print a net's voltage. It takes `--dialect`, `--edit-value`, `--probe` and `--rkm`.
|
|
19
|
+
|
|
20
|
+
See [the architecture](../architecture.md) for the design and its constraints.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.26"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "netlistmod"
|
|
7
|
+
version = "0.5.0"
|
|
8
|
+
description = "A source-preserving SPICE netlist editing library"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.13"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "xdylanm" }]
|
|
14
|
+
keywords = ["spice", "netlist", "ngspice", "ltspice", "parser", "editor"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Intended Audience :: Science/Research",
|
|
19
|
+
"Operating System :: Microsoft :: Windows",
|
|
20
|
+
"Operating System :: POSIX :: Linux",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.13",
|
|
23
|
+
"Programming Language :: Python :: 3.14",
|
|
24
|
+
"Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
|
|
25
|
+
"Typing :: Typed",
|
|
26
|
+
]
|
|
27
|
+
dependencies = ["lark>=1.2.2", "interegular>=0.3.3"]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://github.com/xdylanm/netlistmod"
|
|
31
|
+
Repository = "https://github.com/xdylanm/netlistmod"
|
|
32
|
+
Changelog = "https://github.com/xdylanm/netlistmod/blob/main/CHANGELOG.md"
|
|
33
|
+
|
|
34
|
+
[dependency-groups]
|
|
35
|
+
dev = [
|
|
36
|
+
"build>=1.2",
|
|
37
|
+
"hypothesis>=6.100",
|
|
38
|
+
"import-linter>=2.1",
|
|
39
|
+
"mypy>=1.13",
|
|
40
|
+
"pre-commit>=4.0",
|
|
41
|
+
"pytest>=8.3",
|
|
42
|
+
"pytest-cov>=6.0",
|
|
43
|
+
"PyYAML>=6.0",
|
|
44
|
+
"ruff>=0.8",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[tool.hatch.build.targets.wheel]
|
|
48
|
+
packages = ["src/netlistmod"]
|
|
49
|
+
|
|
50
|
+
[tool.hatch.build.targets.sdist]
|
|
51
|
+
include = [
|
|
52
|
+
"src/netlistmod",
|
|
53
|
+
"README.md",
|
|
54
|
+
"LICENSE",
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
[tool.ruff]
|
|
58
|
+
target-version = "py313"
|
|
59
|
+
line-length = 100
|
|
60
|
+
extend-exclude = ["prototype/**", "docs/architecture.md"]
|
|
61
|
+
|
|
62
|
+
[tool.ruff.lint]
|
|
63
|
+
select = ["E", "F", "I"]
|
|
64
|
+
|
|
65
|
+
[tool.mypy]
|
|
66
|
+
python_version = "3.13"
|
|
67
|
+
strict = true
|
|
68
|
+
files = ["src/netlistmod"]
|
|
69
|
+
|
|
70
|
+
[tool.pytest.ini_options]
|
|
71
|
+
testpaths = ["tests"]
|
|
72
|
+
addopts = ["--strict-markers", "--cov=netlistmod", "--cov-report=term-missing"]
|
|
73
|
+
markers = [
|
|
74
|
+
"solver(name): test requiring a local solver (ngspice or ltspice)",
|
|
75
|
+
"ngspice_only: text only ngspice accepts; deselected in the LTspice run (M8 decision 16)",
|
|
76
|
+
"ltspice_only: text only LTspice accepts; deselected in the ngspice run (M8 decision 16)",
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
[tool.coverage.run]
|
|
80
|
+
branch = true
|
|
81
|
+
source = ["netlistmod"]
|
|
82
|
+
|
|
83
|
+
[tool.coverage.report]
|
|
84
|
+
fail_under = 90
|
|
85
|
+
show_missing = true
|
|
86
|
+
|
|
87
|
+
[tool.importlinter]
|
|
88
|
+
root_package = "netlistmod"
|
|
89
|
+
|
|
90
|
+
[[tool.importlinter.contracts]]
|
|
91
|
+
name = "Package layers follow the architecture"
|
|
92
|
+
type = "layers"
|
|
93
|
+
layers = [
|
|
94
|
+
"netlistmod.edit",
|
|
95
|
+
"netlistmod.document",
|
|
96
|
+
"netlistmod.model",
|
|
97
|
+
"netlistmod.grammar",
|
|
98
|
+
"netlistmod.source",
|
|
99
|
+
"netlistmod.errors",
|
|
100
|
+
"netlistmod.dialects",
|
|
101
|
+
]
|