evas-sim 0.1.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.
Files changed (114) hide show
  1. evas_sim-0.1.0/LICENSE +21 -0
  2. evas_sim-0.1.0/PKG-INFO +178 -0
  3. evas_sim-0.1.0/README.md +145 -0
  4. evas_sim-0.1.0/evas/__init__.py +1 -0
  5. evas_sim-0.1.0/evas/cli.py +156 -0
  6. evas_sim-0.1.0/evas/compiler/__init__.py +0 -0
  7. evas_sim-0.1.0/evas/compiler/ast_nodes.py +216 -0
  8. evas_sim-0.1.0/evas/compiler/lexer.py +333 -0
  9. evas_sim-0.1.0/evas/compiler/parser.py +808 -0
  10. evas_sim-0.1.0/evas/compiler/preprocessor.py +106 -0
  11. evas_sim-0.1.0/evas/examples/__init__.py +0 -0
  12. evas_sim-0.1.0/evas/examples/adc_dac_ideal_4b/__init__.py +0 -0
  13. evas_sim-0.1.0/evas/examples/adc_dac_ideal_4b/adc_ideal_4b.va +51 -0
  14. evas_sim-0.1.0/evas/examples/adc_dac_ideal_4b/dac_ideal_4b.va +43 -0
  15. evas_sim-0.1.0/evas/examples/adc_dac_ideal_4b/sh_ideal.va +35 -0
  16. evas_sim-0.1.0/evas/examples/adc_dac_ideal_4b/tb_adc_dac_ideal_4b_ramp.scs +37 -0
  17. evas_sim-0.1.0/evas/examples/adc_dac_ideal_4b/tb_adc_dac_ideal_4b_sine.scs +42 -0
  18. evas_sim-0.1.0/evas/examples/adc_dac_ideal_4b/tb_adc_dac_ideal_4b_sine1000.scs +42 -0
  19. evas_sim-0.1.0/evas/examples/adc_dac_ideal_4b/validate_adc_dac_ideal_4b.py +259 -0
  20. evas_sim-0.1.0/evas/examples/clk_burst_gen/__init__.py +0 -0
  21. evas_sim-0.1.0/evas/examples/clk_burst_gen/analyze_clk_burst_gen.py +38 -0
  22. evas_sim-0.1.0/evas/examples/clk_burst_gen/clk_burst_gen.va +55 -0
  23. evas_sim-0.1.0/evas/examples/clk_burst_gen/tb_clk_burst_gen.scs +17 -0
  24. evas_sim-0.1.0/evas/examples/clk_burst_gen/validate_clk_burst_gen.py +59 -0
  25. evas_sim-0.1.0/evas/examples/clk_div/__init__.py +0 -0
  26. evas_sim-0.1.0/evas/examples/clk_div/analyze_clk_div.py +38 -0
  27. evas_sim-0.1.0/evas/examples/clk_div/clk_div.va +38 -0
  28. evas_sim-0.1.0/evas/examples/clk_div/tb_clk_div.scs +13 -0
  29. evas_sim-0.1.0/evas/examples/clk_div/validate_clk_div.py +70 -0
  30. evas_sim-0.1.0/evas/examples/cmp_offset_search/__init__.py +0 -0
  31. evas_sim-0.1.0/evas/examples/cmp_offset_search/analyze_cmp_offset_search.py +55 -0
  32. evas_sim-0.1.0/evas/examples/cmp_offset_search/cmp_offset_search.va +42 -0
  33. evas_sim-0.1.0/evas/examples/cmp_offset_search/tb_cmp_offset_search.scs +31 -0
  34. evas_sim-0.1.0/evas/examples/cmp_offset_search/validate_cmp_offset_search.py +79 -0
  35. evas_sim-0.1.0/evas/examples/cmp_strongarm/__init__.py +0 -0
  36. evas_sim-0.1.0/evas/examples/cmp_strongarm/analyze_cmp_strongarm.py +46 -0
  37. evas_sim-0.1.0/evas/examples/cmp_strongarm/cmp_strongarm.va +61 -0
  38. evas_sim-0.1.0/evas/examples/cmp_strongarm/tb_cmp_strongarm.scs +23 -0
  39. evas_sim-0.1.0/evas/examples/d2b_4b/__init__.py +0 -0
  40. evas_sim-0.1.0/evas/examples/d2b_4b/analyze_d2b_4b.py +59 -0
  41. evas_sim-0.1.0/evas/examples/d2b_4b/d2b_4b.va +78 -0
  42. evas_sim-0.1.0/evas/examples/d2b_4b/tb_d2b_4b.scs +46 -0
  43. evas_sim-0.1.0/evas/examples/d2b_4b/validate_d2b_4b.py +152 -0
  44. evas_sim-0.1.0/evas/examples/d2b_4b/visualize_d2b_4b.py +171 -0
  45. evas_sim-0.1.0/evas/examples/dac_binary_clk_4b/__init__.py +0 -0
  46. evas_sim-0.1.0/evas/examples/dac_binary_clk_4b/analyze_dac_binary_clk_4b.py +64 -0
  47. evas_sim-0.1.0/evas/examples/dac_binary_clk_4b/dac_binary_clk_4b.va +39 -0
  48. evas_sim-0.1.0/evas/examples/dac_binary_clk_4b/tb_dac_binary_clk_4b.scs +56 -0
  49. evas_sim-0.1.0/evas/examples/dac_therm_16b/__init__.py +0 -0
  50. evas_sim-0.1.0/evas/examples/dac_therm_16b/analyze_dac_therm_16b.py +53 -0
  51. evas_sim-0.1.0/evas/examples/dac_therm_16b/dac_therm_16b.va +42 -0
  52. evas_sim-0.1.0/evas/examples/dac_therm_16b/tb_dac_therm_16b.scs +45 -0
  53. evas_sim-0.1.0/evas/examples/dac_therm_16b/validate_dac_therm_16b.py +65 -0
  54. evas_sim-0.1.0/evas/examples/digital_basics/__init__.py +0 -0
  55. evas_sim-0.1.0/evas/examples/digital_basics/analyze_digital_basics.py +122 -0
  56. evas_sim-0.1.0/evas/examples/digital_basics/analyze_inverter_chain.py +71 -0
  57. evas_sim-0.1.0/evas/examples/digital_basics/and_gate.va +23 -0
  58. evas_sim-0.1.0/evas/examples/digital_basics/dff_rst.va +37 -0
  59. evas_sim-0.1.0/evas/examples/digital_basics/inverter.va +24 -0
  60. evas_sim-0.1.0/evas/examples/digital_basics/not_gate.va +23 -0
  61. evas_sim-0.1.0/evas/examples/digital_basics/or_gate.va +23 -0
  62. evas_sim-0.1.0/evas/examples/digital_basics/tb_and_gate.scs +23 -0
  63. evas_sim-0.1.0/evas/examples/digital_basics/tb_dff_rst.scs +41 -0
  64. evas_sim-0.1.0/evas/examples/digital_basics/tb_inverter_chain.scs +24 -0
  65. evas_sim-0.1.0/evas/examples/digital_basics/tb_not_gate.scs +19 -0
  66. evas_sim-0.1.0/evas/examples/digital_basics/tb_or_gate.scs +21 -0
  67. evas_sim-0.1.0/evas/examples/digital_basics/validate_digital_basics.py +142 -0
  68. evas_sim-0.1.0/evas/examples/dwa_ptr_gen/__init__.py +0 -0
  69. evas_sim-0.1.0/evas/examples/dwa_ptr_gen/analyze_dwa_ptr_gen.py +75 -0
  70. evas_sim-0.1.0/evas/examples/dwa_ptr_gen/dwa_ptr_gen.va +83 -0
  71. evas_sim-0.1.0/evas/examples/dwa_ptr_gen/tb_dwa_ptr_gen.scs +45 -0
  72. evas_sim-0.1.0/evas/examples/dwa_ptr_gen/validate_dwa_ptr_gen.py +105 -0
  73. evas_sim-0.1.0/evas/examples/edge_interval_timer/__init__.py +0 -0
  74. evas_sim-0.1.0/evas/examples/edge_interval_timer/analyze_edge_interval_timer.py +53 -0
  75. evas_sim-0.1.0/evas/examples/edge_interval_timer/edge_interval_timer.va +58 -0
  76. evas_sim-0.1.0/evas/examples/edge_interval_timer/tb_edge_interval_timer.scs +16 -0
  77. evas_sim-0.1.0/evas/examples/edge_interval_timer/validate_edge_interval_timer.py +90 -0
  78. evas_sim-0.1.0/evas/examples/lfsr/__init__.py +0 -0
  79. evas_sim-0.1.0/evas/examples/lfsr/analyze_lfsr.py +44 -0
  80. evas_sim-0.1.0/evas/examples/lfsr/lfsr.va +49 -0
  81. evas_sim-0.1.0/evas/examples/lfsr/tb_lfsr.scs +23 -0
  82. evas_sim-0.1.0/evas/examples/noise_gen/__init__.py +0 -0
  83. evas_sim-0.1.0/evas/examples/noise_gen/analyze_noise_gen.py +51 -0
  84. evas_sim-0.1.0/evas/examples/noise_gen/noise_gen.va +43 -0
  85. evas_sim-0.1.0/evas/examples/noise_gen/tb_noise_gen.scs +13 -0
  86. evas_sim-0.1.0/evas/examples/noise_gen/validate_noise_gen.py +64 -0
  87. evas_sim-0.1.0/evas/examples/ramp_gen/__init__.py +0 -0
  88. evas_sim-0.1.0/evas/examples/ramp_gen/analyze_ramp_gen.py +60 -0
  89. evas_sim-0.1.0/evas/examples/ramp_gen/ramp_gen.va +97 -0
  90. evas_sim-0.1.0/evas/examples/ramp_gen/tb_ramp_gen.scs +25 -0
  91. evas_sim-0.1.0/evas/examples/ramp_gen/validate_ramp_gen.py +124 -0
  92. evas_sim-0.1.0/evas/examples/sar_adc_dac_weighted_8b/__init__.py +0 -0
  93. evas_sim-0.1.0/evas/examples/sar_adc_dac_weighted_8b/dac_weighted_8b.va +55 -0
  94. evas_sim-0.1.0/evas/examples/sar_adc_dac_weighted_8b/sar_adc_weighted_8b.va +86 -0
  95. evas_sim-0.1.0/evas/examples/sar_adc_dac_weighted_8b/tb_sar_adc_dac_weighted_8b.scs +41 -0
  96. evas_sim-0.1.0/evas/examples/sar_adc_dac_weighted_8b/validate_sar_adc_dac_weighted_8b.py +276 -0
  97. evas_sim-0.1.0/evas/netlist/__init__.py +0 -0
  98. evas_sim-0.1.0/evas/netlist/runner.py +483 -0
  99. evas_sim-0.1.0/evas/netlist/spectre_parser.py +774 -0
  100. evas_sim-0.1.0/evas/simulator/__init__.py +0 -0
  101. evas_sim-0.1.0/evas/simulator/backend.py +665 -0
  102. evas_sim-0.1.0/evas/simulator/engine.py +386 -0
  103. evas_sim-0.1.0/evas/vams/constants.vams +17 -0
  104. evas_sim-0.1.0/evas/vams/disciplines.vams +40 -0
  105. evas_sim-0.1.0/evas_sim.egg-info/PKG-INFO +178 -0
  106. evas_sim-0.1.0/evas_sim.egg-info/SOURCES.txt +112 -0
  107. evas_sim-0.1.0/evas_sim.egg-info/dependency_links.txt +1 -0
  108. evas_sim-0.1.0/evas_sim.egg-info/entry_points.txt +2 -0
  109. evas_sim-0.1.0/evas_sim.egg-info/not-zip-safe +1 -0
  110. evas_sim-0.1.0/evas_sim.egg-info/requires.txt +14 -0
  111. evas_sim-0.1.0/evas_sim.egg-info/top_level.txt +1 -0
  112. evas_sim-0.1.0/pyproject.toml +52 -0
  113. evas_sim-0.1.0/setup.cfg +4 -0
  114. evas_sim-0.1.0/tests/test_examples.py +197 -0
evas_sim-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Zhishuai Zhang
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,178 @@
1
+ Metadata-Version: 2.4
2
+ Name: evas-sim
3
+ Version: 0.1.0
4
+ Summary: Event-driven Verilog-A Simulator — pure-Python behavioral simulation
5
+ Author: Zhishuai Zhang
6
+ License: MIT
7
+ Project-URL: Homepage, https://evas.tokenzhang.com
8
+ Project-URL: Documentation, https://evas.tokenzhang.com
9
+ Project-URL: Repository, https://github.com/Arcadia-1/EVAS
10
+ Project-URL: Bug Tracker, https://github.com/Arcadia-1/EVAS/issues
11
+ Keywords: verilog-a,simulation,mixed-signal,eda
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
17
+ Requires-Python: >=3.9
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: numpy
21
+ Requires-Dist: matplotlib
22
+ Requires-Dist: pandas
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=7.0; extra == "dev"
25
+ Requires-Dist: pytest-cov; extra == "dev"
26
+ Requires-Dist: ruff; extra == "dev"
27
+ Provides-Extra: docs
28
+ Requires-Dist: sphinx>=7.0; extra == "docs"
29
+ Requires-Dist: furo; extra == "docs"
30
+ Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
31
+ Requires-Dist: myst-parser; extra == "docs"
32
+ Dynamic: license-file
33
+
34
+ # EVAS — Event-driven Verilog-A Simulator
35
+
36
+ [![PyPI version](https://img.shields.io/pypi/v/evas-sim.svg)](https://pypi.org/project/evas-sim/)
37
+ [![CI](https://github.com/Arcadia-1/EVAS/actions/workflows/ci.yml/badge.svg)](https://github.com/Arcadia-1/EVAS/actions/workflows/ci.yml)
38
+ [![Docs](https://img.shields.io/badge/docs-evas.tokenzhang.com-blue)](https://evas.tokenzhang.com)
39
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
40
+
41
+ EVAS is a lightweight, pure-Python behavioral simulator for digital/control-class
42
+ Verilog-A models. It provides fast event-driven simulation with zero external
43
+ EDA dependencies — no C compiler, no ngspice.
44
+
45
+ 📖 **Documentation:** [evas.tokenzhang.com](https://evas.tokenzhang.com) | [English](/en/)
46
+
47
+ ## Target Use Cases
48
+
49
+ - Rapid behavioral verification of clocked digital blocks (comparators, ADCs, DACs, dividers, LFSRs, DFFs)
50
+ - Event-driven models using `@cross`, `@above`, `transition()`, `@initial_step`
51
+ - Voltage-mode contributions (`V() <+`)
52
+
53
+ ## Installation
54
+
55
+ ```bash
56
+ pip install evas-sim
57
+ ```
58
+
59
+ No C compiler, no ngspice. NumPy, Matplotlib, and Pandas are installed automatically.
60
+
61
+ ## Quickstart
62
+
63
+ ```bash
64
+ # List all 15 bundled examples
65
+ evas list
66
+
67
+ # Run the clock divider example
68
+ evas run clk_div
69
+
70
+ # Run a specific testbench in a multi-testbench example
71
+ evas run digital_basics --tb tb_not_gate.scs
72
+
73
+ # Simulate your own netlist
74
+ evas simulate path/to/tb.scs -o output/mydesign
75
+ ```
76
+
77
+ `evas run clk_div` copies the Verilog-A model and Spectre testbench into
78
+ `./clk_div/`, simulates it, and saves waveform data + a PNG plot to
79
+ `./output/clk_div/`.
80
+
81
+ ## Bundled Examples
82
+
83
+ | Name | Description |
84
+ |------|-------------|
85
+ | `clk_div` | Clock divider (ratio = 4) |
86
+ | `clk_burst_gen` | Clock burst generator |
87
+ | `digital_basics` | Basic gates: AND, NOT, OR, DFF, inverter chain |
88
+ | `lfsr` | Linear feedback shift register |
89
+ | `noise_gen` | Noise signal generator |
90
+ | `ramp_gen` | Ramp signal generator |
91
+ | `edge_interval_timer` | Edge-interval timer |
92
+ | `d2b_4b` | 4-bit thermometer-to-binary decoder |
93
+ | `dac_binary_clk_4b` | 4-bit binary DAC (clocked) |
94
+ | `dac_therm_16b` | 16-bit thermometer DAC |
95
+ | `adc_dac_ideal_4b` | 4-bit ideal ADC + DAC with sample-hold |
96
+ | `cmp_strongarm` | StrongARM comparator |
97
+ | `cmp_offset_search` | Comparator offset search algorithm |
98
+ | `dwa_ptr_gen` | DWA pointer generator |
99
+ | `sar_adc_dac_weighted_8b` | 8-bit weighted SAR ADC + DAC |
100
+
101
+ ## CSV Output Format
102
+
103
+ All signals default to 6-digit scientific notation (`:.6e`). The `save` statement
104
+ accepts an optional `:fmt` suffix per signal:
105
+
106
+ | Suffix | Format | Example value |
107
+ |--------|--------|---------------|
108
+ | `:6e` | `:.6e` (default) | `4.500000e-01` |
109
+ | `:10e` | `:.10e` | `4.5000000000e-01` |
110
+ | `:2e` | `:.2e` | `4.50e-01` |
111
+ | `:4f` | `:.4f` | `0.4500` |
112
+ | `:d` | integer | `7` |
113
+
114
+ ```
115
+ // With format hints
116
+ save vin:10e vout:6e clk:2e dout_code:d
117
+ ```
118
+
119
+ ## Supported Verilog-A Features
120
+
121
+ - Module declarations with parameters and port arrays
122
+ - `@(cross(...))`, `@(above(...))` zero-crossing events
123
+ - `@(initial_step)` initialization; combined events
124
+ - `transition()` operator with delay, rise/fall times
125
+ - `V(node)`, `V(a, b)` voltage access; `V(node) <+` voltage contributions
126
+ - Arithmetic, logical, bitwise, shift, ternary operators
127
+ - `for` loops, `if/else`, `begin/end` blocks
128
+ - Integer and real variables, arrays, parameters with ranges
129
+ - `` `include ``, `` `define ``, `` `default_transition `` preprocessor directives
130
+ - SI suffixes; math functions: `ln`, `log`, `exp`, `sqrt`, `pow`, `abs`, `sin`, `cos`, `floor`, `ceil`, `min`, `max`
131
+ - String parameters with `.substr()` method calls
132
+
133
+ ## Spectre Netlist Support
134
+
135
+ - `vsource` with `dc`, `pulse`, `pwl`, `sin` types
136
+ - `ahdl_include` for VA model files
137
+ - `parameters` with expression evaluation
138
+ - `tran` analysis with `stop` and `maxstep`
139
+ - `save` signal selection with optional per-signal format specifiers
140
+
141
+ ## Limitations
142
+
143
+ - No `I() <+` current contributions
144
+ - No `ddt()`, `idt()` calculus operators
145
+ - No MNA matrix solve (no KCL/KVL enforcement)
146
+ - No transistor-level simulation
147
+ - No AC or DC analysis (transient only)
148
+ - No subcircuit hierarchy
149
+
150
+ ## Project Structure
151
+
152
+ ```
153
+ EVAS/
154
+ ├── evas/
155
+ │ ├── cli.py # CLI entry point (evas simulate / run / list)
156
+ │ ├── compiler/ # Verilog-A front-end (lexer, parser, AST)
157
+ │ ├── simulator/ # Event-driven simulation engine + backend
158
+ │ ├── netlist/ # Spectre .scs parser + orchestration runner
159
+ │ ├── vams/ # VAMS include files (constants, disciplines)
160
+ │ └── examples/ # 15 bundled example circuits
161
+ ├── docs/ # Sphinx documentation (Chinese, default)
162
+ ├── docs_en/ # Sphinx documentation (English)
163
+ ├── tests/
164
+ └── pyproject.toml
165
+ ```
166
+
167
+ ## Development
168
+
169
+ ```bash
170
+ git clone https://github.com/Arcadia-1/EVAS.git
171
+ cd EVAS
172
+ pip install -e ".[dev]"
173
+ pytest tests/ -v
174
+ ```
175
+
176
+ ## License
177
+
178
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,145 @@
1
+ # EVAS — Event-driven Verilog-A Simulator
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/evas-sim.svg)](https://pypi.org/project/evas-sim/)
4
+ [![CI](https://github.com/Arcadia-1/EVAS/actions/workflows/ci.yml/badge.svg)](https://github.com/Arcadia-1/EVAS/actions/workflows/ci.yml)
5
+ [![Docs](https://img.shields.io/badge/docs-evas.tokenzhang.com-blue)](https://evas.tokenzhang.com)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
+
8
+ EVAS is a lightweight, pure-Python behavioral simulator for digital/control-class
9
+ Verilog-A models. It provides fast event-driven simulation with zero external
10
+ EDA dependencies — no C compiler, no ngspice.
11
+
12
+ 📖 **Documentation:** [evas.tokenzhang.com](https://evas.tokenzhang.com) | [English](/en/)
13
+
14
+ ## Target Use Cases
15
+
16
+ - Rapid behavioral verification of clocked digital blocks (comparators, ADCs, DACs, dividers, LFSRs, DFFs)
17
+ - Event-driven models using `@cross`, `@above`, `transition()`, `@initial_step`
18
+ - Voltage-mode contributions (`V() <+`)
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ pip install evas-sim
24
+ ```
25
+
26
+ No C compiler, no ngspice. NumPy, Matplotlib, and Pandas are installed automatically.
27
+
28
+ ## Quickstart
29
+
30
+ ```bash
31
+ # List all 15 bundled examples
32
+ evas list
33
+
34
+ # Run the clock divider example
35
+ evas run clk_div
36
+
37
+ # Run a specific testbench in a multi-testbench example
38
+ evas run digital_basics --tb tb_not_gate.scs
39
+
40
+ # Simulate your own netlist
41
+ evas simulate path/to/tb.scs -o output/mydesign
42
+ ```
43
+
44
+ `evas run clk_div` copies the Verilog-A model and Spectre testbench into
45
+ `./clk_div/`, simulates it, and saves waveform data + a PNG plot to
46
+ `./output/clk_div/`.
47
+
48
+ ## Bundled Examples
49
+
50
+ | Name | Description |
51
+ |------|-------------|
52
+ | `clk_div` | Clock divider (ratio = 4) |
53
+ | `clk_burst_gen` | Clock burst generator |
54
+ | `digital_basics` | Basic gates: AND, NOT, OR, DFF, inverter chain |
55
+ | `lfsr` | Linear feedback shift register |
56
+ | `noise_gen` | Noise signal generator |
57
+ | `ramp_gen` | Ramp signal generator |
58
+ | `edge_interval_timer` | Edge-interval timer |
59
+ | `d2b_4b` | 4-bit thermometer-to-binary decoder |
60
+ | `dac_binary_clk_4b` | 4-bit binary DAC (clocked) |
61
+ | `dac_therm_16b` | 16-bit thermometer DAC |
62
+ | `adc_dac_ideal_4b` | 4-bit ideal ADC + DAC with sample-hold |
63
+ | `cmp_strongarm` | StrongARM comparator |
64
+ | `cmp_offset_search` | Comparator offset search algorithm |
65
+ | `dwa_ptr_gen` | DWA pointer generator |
66
+ | `sar_adc_dac_weighted_8b` | 8-bit weighted SAR ADC + DAC |
67
+
68
+ ## CSV Output Format
69
+
70
+ All signals default to 6-digit scientific notation (`:.6e`). The `save` statement
71
+ accepts an optional `:fmt` suffix per signal:
72
+
73
+ | Suffix | Format | Example value |
74
+ |--------|--------|---------------|
75
+ | `:6e` | `:.6e` (default) | `4.500000e-01` |
76
+ | `:10e` | `:.10e` | `4.5000000000e-01` |
77
+ | `:2e` | `:.2e` | `4.50e-01` |
78
+ | `:4f` | `:.4f` | `0.4500` |
79
+ | `:d` | integer | `7` |
80
+
81
+ ```
82
+ // With format hints
83
+ save vin:10e vout:6e clk:2e dout_code:d
84
+ ```
85
+
86
+ ## Supported Verilog-A Features
87
+
88
+ - Module declarations with parameters and port arrays
89
+ - `@(cross(...))`, `@(above(...))` zero-crossing events
90
+ - `@(initial_step)` initialization; combined events
91
+ - `transition()` operator with delay, rise/fall times
92
+ - `V(node)`, `V(a, b)` voltage access; `V(node) <+` voltage contributions
93
+ - Arithmetic, logical, bitwise, shift, ternary operators
94
+ - `for` loops, `if/else`, `begin/end` blocks
95
+ - Integer and real variables, arrays, parameters with ranges
96
+ - `` `include ``, `` `define ``, `` `default_transition `` preprocessor directives
97
+ - SI suffixes; math functions: `ln`, `log`, `exp`, `sqrt`, `pow`, `abs`, `sin`, `cos`, `floor`, `ceil`, `min`, `max`
98
+ - String parameters with `.substr()` method calls
99
+
100
+ ## Spectre Netlist Support
101
+
102
+ - `vsource` with `dc`, `pulse`, `pwl`, `sin` types
103
+ - `ahdl_include` for VA model files
104
+ - `parameters` with expression evaluation
105
+ - `tran` analysis with `stop` and `maxstep`
106
+ - `save` signal selection with optional per-signal format specifiers
107
+
108
+ ## Limitations
109
+
110
+ - No `I() <+` current contributions
111
+ - No `ddt()`, `idt()` calculus operators
112
+ - No MNA matrix solve (no KCL/KVL enforcement)
113
+ - No transistor-level simulation
114
+ - No AC or DC analysis (transient only)
115
+ - No subcircuit hierarchy
116
+
117
+ ## Project Structure
118
+
119
+ ```
120
+ EVAS/
121
+ ├── evas/
122
+ │ ├── cli.py # CLI entry point (evas simulate / run / list)
123
+ │ ├── compiler/ # Verilog-A front-end (lexer, parser, AST)
124
+ │ ├── simulator/ # Event-driven simulation engine + backend
125
+ │ ├── netlist/ # Spectre .scs parser + orchestration runner
126
+ │ ├── vams/ # VAMS include files (constants, disciplines)
127
+ │ └── examples/ # 15 bundled example circuits
128
+ ├── docs/ # Sphinx documentation (Chinese, default)
129
+ ├── docs_en/ # Sphinx documentation (English)
130
+ ├── tests/
131
+ └── pyproject.toml
132
+ ```
133
+
134
+ ## Development
135
+
136
+ ```bash
137
+ git clone https://github.com/Arcadia-1/EVAS.git
138
+ cd EVAS
139
+ pip install -e ".[dev]"
140
+ pytest tests/ -v
141
+ ```
142
+
143
+ ## License
144
+
145
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1 @@
1
+ __version__ = '0.1.0'
@@ -0,0 +1,156 @@
1
+ """EVAS command-line interface."""
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import os
6
+ import shutil
7
+ import sys
8
+ from pathlib import Path
9
+
10
+
11
+ def _get_examples_root() -> Path:
12
+ """Return the path to the bundled examples directory."""
13
+ try:
14
+ from importlib.resources import files
15
+ pkg = files("evas.examples")
16
+ # On Python 3.9-3.10 with zip-safe=false, this returns a real Path
17
+ p = Path(str(pkg))
18
+ if p.is_dir():
19
+ return p
20
+ except Exception:
21
+ pass
22
+ # Fallback: locate relative to this file (editable installs)
23
+ return Path(__file__).parent / "examples"
24
+
25
+
26
+ def _list_examples() -> list[str]:
27
+ root = _get_examples_root()
28
+ if not root.is_dir():
29
+ return []
30
+ return sorted(
31
+ d.name for d in root.iterdir()
32
+ if d.is_dir() and not d.name.startswith("_") and not d.name.startswith(".")
33
+ )
34
+
35
+
36
+ def cmd_list(_args: argparse.Namespace) -> int:
37
+ names = _list_examples()
38
+ if not names:
39
+ print("No bundled examples found.", file=sys.stderr)
40
+ return 1
41
+ print(f"Available examples ({len(names)}):")
42
+ for name in names:
43
+ print(f" {name}")
44
+ return 0
45
+
46
+
47
+ def cmd_simulate(args: argparse.Namespace) -> int:
48
+ from evas.netlist.runner import evas_simulate
49
+ ok = evas_simulate(args.input, log_path=args.log, output_dir=args.output)
50
+ return 0 if ok else 1
51
+
52
+
53
+ def cmd_run(args: argparse.Namespace) -> int:
54
+ from evas.netlist.runner import evas_simulate
55
+
56
+ name = args.name
57
+ examples_root = _get_examples_root()
58
+ src = examples_root / name
59
+ if not src.is_dir():
60
+ available = _list_examples()
61
+ print(f"Error: example '{name}' not found.", file=sys.stderr)
62
+ print(f"Available: {', '.join(available)}", file=sys.stderr)
63
+ return 1
64
+
65
+ # Copy example files to <cwd>/<name>/
66
+ dst = Path.cwd() / name
67
+ dst.mkdir(parents=True, exist_ok=True)
68
+
69
+ for f in src.iterdir():
70
+ if f.is_file() and not f.name.startswith("_"):
71
+ shutil.copy2(f, dst / f.name)
72
+
73
+ # Determine which .scs to run
74
+ if args.tb:
75
+ scs_file = dst / args.tb
76
+ if not scs_file.exists():
77
+ print(f"Error: testbench '{args.tb}' not found in {dst}", file=sys.stderr)
78
+ return 1
79
+ else:
80
+ # Prefer tb_<name>.scs; fall back to any single .scs
81
+ preferred = dst / f"tb_{name}.scs"
82
+ if preferred.exists():
83
+ scs_file = preferred
84
+ else:
85
+ scs_files = sorted(dst.glob("*.scs"))
86
+ if not scs_files:
87
+ print(f"Error: no .scs testbench found in {dst}", file=sys.stderr)
88
+ return 1
89
+ scs_file = scs_files[0]
90
+
91
+ output_dir = Path.cwd() / "output" / name
92
+ output_dir.mkdir(parents=True, exist_ok=True)
93
+
94
+ print(f"Running example '{name}': {scs_file.name} → {output_dir}")
95
+ env_backup = os.environ.get("EVAS_OUTPUT_DIR")
96
+ os.environ["EVAS_OUTPUT_DIR"] = str(output_dir)
97
+
98
+ try:
99
+ ok = evas_simulate(str(scs_file), output_dir=str(output_dir))
100
+ finally:
101
+ if env_backup is None:
102
+ os.environ.pop("EVAS_OUTPUT_DIR", None)
103
+ else:
104
+ os.environ["EVAS_OUTPUT_DIR"] = env_backup
105
+
106
+ if not ok:
107
+ return 1
108
+
109
+ # Run analyze_<name>.py if present
110
+ analyze = dst / f"analyze_{name}.py"
111
+ if analyze.exists():
112
+ import subprocess
113
+ print(f"Running analysis: {analyze.name}")
114
+ result = subprocess.run(
115
+ [sys.executable, str(analyze)],
116
+ cwd=str(dst),
117
+ env={**os.environ, "EVAS_OUTPUT_DIR": str(output_dir)},
118
+ )
119
+ return result.returncode
120
+
121
+ return 0
122
+
123
+
124
+ def main() -> None:
125
+ parser = argparse.ArgumentParser(
126
+ prog="evas",
127
+ description="EVAS — Event-driven Verilog-A Simulator",
128
+ )
129
+ sub = parser.add_subparsers(dest="command", metavar="<command>")
130
+ sub.required = True
131
+
132
+ # evas simulate
133
+ p_sim = sub.add_parser("simulate", help="Simulate a Spectre .scs netlist")
134
+ p_sim.add_argument("input", help=".scs netlist file")
135
+ p_sim.add_argument("-o", "--output", default="./output",
136
+ help="Output directory (default: ./output)")
137
+ p_sim.add_argument("-log", help="Log file path")
138
+ p_sim.set_defaults(func=cmd_simulate)
139
+
140
+ # evas run
141
+ p_run = sub.add_parser("run", help="Run a bundled example")
142
+ p_run.add_argument("name", help="Example name (see 'evas list')")
143
+ p_run.add_argument("--tb", metavar="FILE",
144
+ help="Testbench filename override (default: tb_<name>.scs)")
145
+ p_run.set_defaults(func=cmd_run)
146
+
147
+ # evas list
148
+ p_list = sub.add_parser("list", help="List all available examples")
149
+ p_list.set_defaults(func=cmd_list)
150
+
151
+ args = parser.parse_args()
152
+ sys.exit(args.func(args))
153
+
154
+
155
+ if __name__ == "__main__":
156
+ main()
File without changes