sv-weave 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 (52) hide show
  1. sv_weave-0.1.0/LICENSE +73 -0
  2. sv_weave-0.1.0/PKG-INFO +103 -0
  3. sv_weave-0.1.0/README.md +69 -0
  4. sv_weave-0.1.0/pyproject.toml +74 -0
  5. sv_weave-0.1.0/setup.cfg +4 -0
  6. sv_weave-0.1.0/src/sv_weave/__init__.py +2 -0
  7. sv_weave-0.1.0/src/sv_weave/__version__.py +5 -0
  8. sv_weave-0.1.0/src/sv_weave/api.py +11 -0
  9. sv_weave-0.1.0/src/sv_weave/api_version.py +3 -0
  10. sv_weave-0.1.0/src/sv_weave/bindings/__init__.py +3 -0
  11. sv_weave-0.1.0/src/sv_weave/bus.py +159 -0
  12. sv_weave-0.1.0/src/sv_weave/check.py +60 -0
  13. sv_weave-0.1.0/src/sv_weave/cli.py +206 -0
  14. sv_weave-0.1.0/src/sv_weave/config.py +259 -0
  15. sv_weave-0.1.0/src/sv_weave/dfm/__ext__.py +9 -0
  16. sv_weave-0.1.0/src/sv_weave/dfm/__init__.py +0 -0
  17. sv_weave-0.1.0/src/sv_weave/dfm/flow.dv +53 -0
  18. sv_weave-0.1.0/src/sv_weave/dfm/tasks.py +112 -0
  19. sv_weave-0.1.0/src/sv_weave/diag.py +56 -0
  20. sv_weave-0.1.0/src/sv_weave/filelist.py +119 -0
  21. sv_weave-0.1.0/src/sv_weave/frontend/__init__.py +0 -0
  22. sv_weave-0.1.0/src/sv_weave/frontend/loader.py +112 -0
  23. sv_weave-0.1.0/src/sv_weave/frontend/model.py +526 -0
  24. sv_weave-0.1.0/src/sv_weave/frontend/specialize.py +113 -0
  25. sv_weave-0.1.0/src/sv_weave/frontend/types.py +202 -0
  26. sv_weave-0.1.0/src/sv_weave/match.py +309 -0
  27. sv_weave-0.1.0/src/sv_weave/plugin.py +235 -0
  28. sv_weave-0.1.0/src/sv_weave/render.py +223 -0
  29. sv_weave-0.1.0/src/sv_weave/report.py +140 -0
  30. sv_weave-0.1.0/src/sv_weave/run.py +295 -0
  31. sv_weave-0.1.0/src/sv_weave/select.py +124 -0
  32. sv_weave-0.1.0/src/sv_weave/share/__init__.py +2 -0
  33. sv_weave-0.1.0/src/sv_weave/verify.py +142 -0
  34. sv_weave-0.1.0/src/sv_weave/verify_rules.py +98 -0
  35. sv_weave-0.1.0/src/sv_weave/weave/__init__.py +1 -0
  36. sv_weave-0.1.0/src/sv_weave/weave/ctx.py +278 -0
  37. sv_weave-0.1.0/src/sv_weave/weave/design.py +146 -0
  38. sv_weave-0.1.0/src/sv_weave/weave/model.py +338 -0
  39. sv_weave-0.1.0/src/sv_weave/weave/svhelpers.py +219 -0
  40. sv_weave-0.1.0/src/sv_weave/weavers/__init__.py +7 -0
  41. sv_weave-0.1.0/src/sv_weave/weavers/compare.py +27 -0
  42. sv_weave-0.1.0/src/sv_weave/weavers/copy.py +28 -0
  43. sv_weave-0.1.0/src/sv_weave/weavers/print.py +25 -0
  44. sv_weave-0.1.0/src/sv_weave/weavers/xcheck.py +58 -0
  45. sv_weave-0.1.0/src/sv_weave/write.py +48 -0
  46. sv_weave-0.1.0/src/sv_weave.egg-info/PKG-INFO +103 -0
  47. sv_weave-0.1.0/src/sv_weave.egg-info/SOURCES.txt +50 -0
  48. sv_weave-0.1.0/src/sv_weave.egg-info/dependency_links.txt +1 -0
  49. sv_weave-0.1.0/src/sv_weave.egg-info/entry_points.txt +5 -0
  50. sv_weave-0.1.0/src/sv_weave.egg-info/requires.txt +15 -0
  51. sv_weave-0.1.0/src/sv_weave.egg-info/top_level.txt +1 -0
  52. sv_weave-0.1.0/tests/test_weavers.py +128 -0
sv_weave-0.1.0/LICENSE ADDED
@@ -0,0 +1,73 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
10
+
11
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
12
+
13
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
14
+
15
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
16
+
17
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
18
+
19
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
20
+
21
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
22
+
23
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
24
+
25
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
26
+
27
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
28
+
29
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
30
+
31
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
32
+
33
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
34
+
35
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
36
+
37
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
38
+
39
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
40
+
41
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
42
+
43
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
44
+
45
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
46
+
47
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
48
+
49
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
50
+
51
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
52
+
53
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
54
+
55
+ END OF TERMS AND CONDITIONS
56
+
57
+ APPENDIX: How to apply the Apache License to your work.
58
+
59
+ To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
60
+
61
+ Copyright 2026 sv-weave
62
+
63
+ Licensed under the Apache License, Version 2.0 (the "License");
64
+ you may not use this file except in compliance with the License.
65
+ You may obtain a copy of the License at
66
+
67
+ http://www.apache.org/licenses/LICENSE-2.0
68
+
69
+ Unless required by applicable law or agreed to in writing, software
70
+ distributed under the License is distributed on an "AS IS" BASIS,
71
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
72
+ See the License for the specific language governing permissions and
73
+ limitations under the License.
@@ -0,0 +1,103 @@
1
+ Metadata-Version: 2.4
2
+ Name: sv-weave
3
+ Version: 0.1.0
4
+ Summary: Factory weaving for SystemVerilog class libraries
5
+ Author-email: Matthew Ballance <matt.ballance@gmail.com>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Documentation, https://dvkit.org/sv-weave/sv-weave/
8
+ Project-URL: Source, https://github.com/sv-weave/sv-weave
9
+ Keywords: systemverilog,uvm,code-generation,verification,slang
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
16
+ Classifier: Topic :: Software Development :: Code Generators
17
+ Requires-Python: >=3.11
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: pyslang>=12.1
21
+ Requires-Dist: pydantic>=2
22
+ Requires-Dist: pyyaml
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest; extra == "dev"
25
+ Requires-Dist: pytest-dfm; extra == "dev"
26
+ Requires-Dist: dv-flow-mgr; extra == "dev"
27
+ Requires-Dist: dv-flow-libhdlsim; extra == "dev"
28
+ Provides-Extra: docs
29
+ Requires-Dist: sphinx; extra == "docs"
30
+ Requires-Dist: sphinx-rtd-theme; extra == "docs"
31
+ Requires-Dist: sphinx-jsonschema; extra == "docs"
32
+ Requires-Dist: sphinx-dv-flow; extra == "docs"
33
+ Dynamic: license-file
34
+
35
+ # sv-weave
36
+
37
+ **Factory weaving for SystemVerilog class libraries.**
38
+
39
+ You write plain SystemVerilog classes against your class library's base classes: no
40
+ macros, no generated code to merge with your own. sv-weave reads your sources with
41
+ [slang](https://github.com/MikePopoloski/slang) (through pyslang), and its plugins
42
+ generate a subclass of each matching class that implements the library's virtual hooks
43
+ (for UVM: `do_copy`, `do_compare`, `convert2string`, ...). The library's own factory
44
+ resolves your overrides as usual and then hands out the generated class wherever your
45
+ code asks for the original. Your code never names the generated code.
46
+
47
+ This is the model of .NET's [Fody](https://github.com/Fody/Fody) weavers, applied to
48
+ the SV factory.
49
+
50
+ ```systemverilog
51
+ class tx extends uvm_sequence_item; // no field macros, no do_copy by hand
52
+ `uvm_object_utils(tx)
53
+ rand bit [7:0] addr;
54
+ rand bit [31:0] data;
55
+ ...
56
+ endclass
57
+
58
+ t = tx::type_id::create("t"); // the factory returns a Woven_tx__release
59
+ u.copy(t); // reaches the generated do_copy()
60
+ ```
61
+
62
+ ## Features
63
+
64
+ - **sv-weave is the generator.** It ships no SV runtime and no binding. A **binding**
65
+ adapts it to one library: which base classes it claims, which virtual hooks the
66
+ features map onto, and how woven classes register with the library's factory. The
67
+ UVM binding belongs in the separate `sv-weave-uvm` library; `examples/uvm/` and
68
+ `examples/reflib/` show how bindings work.
69
+ - **Weavers** decide what to generate. Built in: `copy`, `compare`, `print`, and
70
+ `xcheck` (a debug X-check). Weavers can also query the whole
71
+ design and generate code about sets of classes (`examples/selector/`).
72
+ - **Profiles** (release, debug, ...) generated side by side and chosen through the
73
+ library's factory. Debug-only extension sets are checked so that they cannot change
74
+ randomisation.
75
+ - **Verification:** the generated code is elaborated with the design by pyslang
76
+ before anything is written, and errors point at the weaver that produced the line.
77
+ - **dv-flow-mgr task** `svweave.Weave`, a CLI, a manifest and a report of what was
78
+ woven.
79
+
80
+ ## Getting started
81
+
82
+ - Quickstart: `docs/quickstart.rst` (example in `examples/quickstart/`).
83
+ - Build the docs: `python -m sphinx -b html docs docs/_build`.
84
+ - CLI: `sv-weave gen`, `sv-weave list`, `sv-weave report`, `sv-weave schema`.
85
+
86
+ ## Status
87
+
88
+ Early development (0.0.x). The core weavers work end to end on Verilator 5.054, with
89
+ the example reference library and with the example UVM binding on Verilator's UVM. Design: `docs/design/initial-design.md`. Plan and status:
90
+ `docs/plan/implementation-plan.md`.
91
+
92
+ ## Development
93
+
94
+ ```
95
+ ivpm update # dependencies into packages/
96
+ uv pip install --python packages/python/bin/python --no-deps -e .
97
+ packages/python/bin/python -m pytest # unit, golden, Verilator sims, docs
98
+ packages/python/bin/python -m pytest -m perf -s # timing measurements
99
+ ```
100
+
101
+ ## License
102
+
103
+ Apache-2.0
@@ -0,0 +1,69 @@
1
+ # sv-weave
2
+
3
+ **Factory weaving for SystemVerilog class libraries.**
4
+
5
+ You write plain SystemVerilog classes against your class library's base classes: no
6
+ macros, no generated code to merge with your own. sv-weave reads your sources with
7
+ [slang](https://github.com/MikePopoloski/slang) (through pyslang), and its plugins
8
+ generate a subclass of each matching class that implements the library's virtual hooks
9
+ (for UVM: `do_copy`, `do_compare`, `convert2string`, ...). The library's own factory
10
+ resolves your overrides as usual and then hands out the generated class wherever your
11
+ code asks for the original. Your code never names the generated code.
12
+
13
+ This is the model of .NET's [Fody](https://github.com/Fody/Fody) weavers, applied to
14
+ the SV factory.
15
+
16
+ ```systemverilog
17
+ class tx extends uvm_sequence_item; // no field macros, no do_copy by hand
18
+ `uvm_object_utils(tx)
19
+ rand bit [7:0] addr;
20
+ rand bit [31:0] data;
21
+ ...
22
+ endclass
23
+
24
+ t = tx::type_id::create("t"); // the factory returns a Woven_tx__release
25
+ u.copy(t); // reaches the generated do_copy()
26
+ ```
27
+
28
+ ## Features
29
+
30
+ - **sv-weave is the generator.** It ships no SV runtime and no binding. A **binding**
31
+ adapts it to one library: which base classes it claims, which virtual hooks the
32
+ features map onto, and how woven classes register with the library's factory. The
33
+ UVM binding belongs in the separate `sv-weave-uvm` library; `examples/uvm/` and
34
+ `examples/reflib/` show how bindings work.
35
+ - **Weavers** decide what to generate. Built in: `copy`, `compare`, `print`, and
36
+ `xcheck` (a debug X-check). Weavers can also query the whole
37
+ design and generate code about sets of classes (`examples/selector/`).
38
+ - **Profiles** (release, debug, ...) generated side by side and chosen through the
39
+ library's factory. Debug-only extension sets are checked so that they cannot change
40
+ randomisation.
41
+ - **Verification:** the generated code is elaborated with the design by pyslang
42
+ before anything is written, and errors point at the weaver that produced the line.
43
+ - **dv-flow-mgr task** `svweave.Weave`, a CLI, a manifest and a report of what was
44
+ woven.
45
+
46
+ ## Getting started
47
+
48
+ - Quickstart: `docs/quickstart.rst` (example in `examples/quickstart/`).
49
+ - Build the docs: `python -m sphinx -b html docs docs/_build`.
50
+ - CLI: `sv-weave gen`, `sv-weave list`, `sv-weave report`, `sv-weave schema`.
51
+
52
+ ## Status
53
+
54
+ Early development (0.0.x). The core weavers work end to end on Verilator 5.054, with
55
+ the example reference library and with the example UVM binding on Verilator's UVM. Design: `docs/design/initial-design.md`. Plan and status:
56
+ `docs/plan/implementation-plan.md`.
57
+
58
+ ## Development
59
+
60
+ ```
61
+ ivpm update # dependencies into packages/
62
+ uv pip install --python packages/python/bin/python --no-deps -e .
63
+ packages/python/bin/python -m pytest # unit, golden, Verilator sims, docs
64
+ packages/python/bin/python -m pytest -m perf -s # timing measurements
65
+ ```
66
+
67
+ ## License
68
+
69
+ Apache-2.0
@@ -0,0 +1,74 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sv-weave"
7
+ dynamic = ["version"]
8
+ description = "Factory weaving for SystemVerilog class libraries"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11" # pyslang 12 requires 3.11
11
+ license = "Apache-2.0"
12
+ license-files = ["LICENSE"]
13
+ authors = [
14
+ {name = "Matthew Ballance", email = "matt.ballance@gmail.com"},
15
+ ]
16
+ keywords = ["systemverilog", "uvm", "code-generation", "verification", "slang"]
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "Intended Audience :: Developers",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
24
+ "Topic :: Software Development :: Code Generators",
25
+ ]
26
+ dependencies = [
27
+ "pyslang>=12.1",
28
+ "pydantic>=2",
29
+ "pyyaml",
30
+ ]
31
+
32
+ [project.urls]
33
+ Documentation = "https://dvkit.org/sv-weave/sv-weave/"
34
+ Source = "https://github.com/sv-weave/sv-weave"
35
+
36
+ [project.optional-dependencies]
37
+ dev = [
38
+ "pytest",
39
+ "pytest-dfm",
40
+ "dv-flow-mgr",
41
+ "dv-flow-libhdlsim",
42
+ ]
43
+ docs = [
44
+ "sphinx",
45
+ "sphinx-rtd-theme",
46
+ "sphinx-jsonschema",
47
+ "sphinx-dv-flow",
48
+ ]
49
+
50
+ [project.scripts]
51
+ sv-weave = "sv_weave.cli:main"
52
+
53
+ [project.entry-points."dv_flow.mgr"]
54
+ svweave = "sv_weave.dfm.__ext__"
55
+
56
+ [tool.setuptools.dynamic]
57
+ version = {attr = "sv_weave.__version__.__version__"}
58
+
59
+ [tool.setuptools.packages.find]
60
+ where = ["src"]
61
+
62
+ [tool.setuptools.package-data]
63
+ "sv_weave" = ["**/*.sv", "**/*.svh", "**/flow.dv"]
64
+
65
+ [tool.pytest.ini_options]
66
+ testpaths = ["tests"]
67
+ markers = [
68
+ "sim: end-to-end weave + Verilator simulation (pytest-dfm)",
69
+ "perf: timing measurements; run only with -m perf",
70
+ "docs: Sphinx documentation build",
71
+ "xezim: needs the xezim simulator; skipped when it is not on PATH",
72
+ ]
73
+ addopts = "-m 'not perf'"
74
+ asyncio_default_fixture_loop_scope = "function"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,2 @@
1
+ """sv-weave: factory weaving for SystemVerilog class libraries."""
2
+ from .__version__ import __version__
@@ -0,0 +1,5 @@
1
+ # The release version. CI's tag check reads version_info; non-tag CI builds set SUFFIX
2
+ # to a PEP 440 local segment (".dev<run>+gh.g<sha>"), which PyPI refuses.
3
+ version_info = (0, 1, 0)
4
+ SUFFIX = ""
5
+ __version__ = ".".join(str(n) for n in version_info) + SUFFIX
@@ -0,0 +1,11 @@
1
+ """Public API of sv-weave.
2
+
3
+ Weavers and bindings import from this module only. Anything not re-exported
4
+ here is internal and may change without notice. ``API_VERSION`` follows the
5
+ rules in design §10: a minor bump adds, a major bump breaks.
6
+ """
7
+ from .__version__ import __version__
8
+
9
+ from .api_version import API_VERSION
10
+
11
+ __all__ = ["API_VERSION", "__version__"]
@@ -0,0 +1,3 @@
1
+ """The contribution-API version (design §10): weavers and bindings declare a range
2
+ over it. Minor bumps add, major bumps break."""
3
+ API_VERSION = (0, 1)
@@ -0,0 +1,3 @@
1
+ """Built-in bindings: none. A binding belongs with the class library it adapts (for
2
+ UVM, the separate sv-weave-uvm package). See examples/reflib/ and examples/uvm/."""
3
+ BUILTIN = []
@@ -0,0 +1,159 @@
1
+ """The event bus (design §6.1, §6.7): subscriptions and deterministic dispatch.
2
+
3
+ Dispatch order, per profile:
4
+ 1. for each target: the binding's ``prepare``, then matching weaver subscriptions, by
5
+ ``order``, then weaver name, then the order the weaver subscribed in;
6
+ 2. ``on_design`` handlers, in the same order;
7
+ 3. for each target that a weaver contributed to: the binding's ``finalize``.
8
+
9
+ A subscription runs only for profiles that include its weaver's extension set.
10
+ """
11
+ import dataclasses as dc
12
+ import traceback
13
+ from typing import Any, Callable, Dict, List, Optional, Sequence
14
+
15
+ from .diag import Diag, Severity, SrcLoc, SvWeaveError
16
+ from .frontend.model import SvClass
17
+ from .match import Pred, parse
18
+ from .plugin import Weaver
19
+ from .weave.ctx import WeaveCtx, WovenClassBuilder
20
+ from .weave.model import WovenClass, WovenPackage
21
+
22
+
23
+ @dc.dataclass
24
+ class Subscription:
25
+ weaver: str
26
+ ext_set: str
27
+ order: int
28
+ seq: int
29
+ pred: Callable[[SvClass], bool]
30
+ handler: Callable[[WeaveCtx], None]
31
+ options: Dict[str, Any]
32
+ before: tuple = ()
33
+ after: tuple = ()
34
+
35
+
36
+ @dc.dataclass
37
+ class _Active:
38
+ weaver: Weaver
39
+ ext_set: str
40
+ order: int
41
+ match: Optional[Pred]
42
+ before: tuple = ()
43
+ after: tuple = ()
44
+
45
+
46
+ class Bus:
47
+ def __init__(self):
48
+ self.subs: List[Subscription] = []
49
+ self.design_subs: List[Subscription] = []
50
+ self._active: Optional[_Active] = None
51
+ self._seq = 0
52
+
53
+ # -- weaver side -----------------------------------------------------------------
54
+ def on(self, pred: Callable[[SvClass], bool], handler: Callable[[WeaveCtx], None]) -> None:
55
+ """Calls ``handler(w)`` for every target (and profile) that ``pred`` matches."""
56
+ a = self._require_active("on")
57
+ if a.match is not None:
58
+ pred = (pred & a.match) if isinstance(pred, Pred) else _and(pred, a.match)
59
+ self.subs.append(Subscription(a.weaver.name, a.ext_set, a.order, self._next(),
60
+ pred, handler, a.weaver.options, a.before, a.after))
61
+
62
+ def on_design(self, handler: Callable[[Any], None]) -> None:
63
+ """Calls ``handler(d)`` once per profile, after all per-class handlers (§6.7)."""
64
+ a = self._require_active("on_design")
65
+ self.design_subs.append(Subscription(a.weaver.name, a.ext_set, a.order, self._next(),
66
+ lambda c: True, handler, a.weaver.options,
67
+ a.before, a.after))
68
+
69
+ def _next(self) -> int:
70
+ self._seq += 1
71
+ return self._seq
72
+
73
+ def _require_active(self, what: str) -> _Active:
74
+ if self._active is None:
75
+ raise RuntimeError("Bus.%s() may only be called from Weaver.subscribe()" % what)
76
+ return self._active
77
+
78
+ # -- framework side --------------------------------------------------------------
79
+ def subscribe(self, weaver: Weaver, ext_set: str, order: int = 0,
80
+ match: Optional[str] = None, where: str = "",
81
+ before=(), after=()) -> None:
82
+ self._active = _Active(weaver, ext_set, order, parse(match, where) if match else None,
83
+ tuple(getattr(weaver, "before", ())) + tuple(before),
84
+ tuple(getattr(weaver, "after", ())) + tuple(after))
85
+ try:
86
+ weaver.subscribe(self)
87
+ finally:
88
+ self._active = None
89
+
90
+ def ordered(self) -> List[Subscription]:
91
+ return sorted(self.subs, key=lambda s: (s.order, s.weaver, s.seq))
92
+
93
+ def wanted(self, cls: SvClass) -> bool:
94
+ """Whether a class can receive contributions. Design handlers may contribute to
95
+ any class, so with one subscribed every claimed class qualifies."""
96
+ return bool(self.design_subs) or any(s.pred(cls) for s in self.subs)
97
+
98
+ def dispatch(self, targets: Sequence, profiles: Sequence[str], profile_sets: Callable,
99
+ bindings: Dict[str, Any], cfg, model, aggregates=None):
100
+ """Runs every handler. Per profile: bindings' ``prepare`` and the weavers for
101
+ each target, then the ``on_design`` handlers, then bindings' ``finalize`` for
102
+ each target some weaver contributed to. Returns (woven classes, diagnostics);
103
+ design-handler package code collects in ``aggregates``."""
104
+ from .weave.design import DesignCtx
105
+ diags: List[Diag] = []
106
+ out: List[WovenClass] = []
107
+ aggregates = {} if aggregates is None else aggregates
108
+ subs = self.ordered()
109
+ dsubs = sorted(self.design_subs, key=lambda s: (s.order, s.weaver, s.seq))
110
+ for profile in profiles:
111
+ sets = set(profile_sets(profile))
112
+ builders: Dict[int, WovenClassBuilder] = {}
113
+ for t in targets:
114
+ binding = bindings[t.binding]
115
+ b = WovenClassBuilder(t, profile, binding, cfg, model, diags)
116
+ builders[id(t.cls)] = b
117
+ with b.contributor(binding.name, None):
118
+ _call(binding.prepare, WeaveCtx(b), binding.name, t, diags)
119
+ for s in subs:
120
+ if s.ext_set not in sets or not s.pred(t.cls):
121
+ continue
122
+ with b.contributor(s.weaver, s.ext_set, s.before, s.after):
123
+ _call(s.handler, WeaveCtx(b, s.ext_set, s.options), s.weaver, t, diags)
124
+ for s in dsubs:
125
+ if s.ext_set not in sets:
126
+ continue
127
+ d = DesignCtx(model, profile, s.ext_set, s.options, s.weaver, builders,
128
+ bindings, aggregates, diags)
129
+ d._relations = (s.before, s.after)
130
+ try:
131
+ _call(s.handler, d, s.weaver, None, diags)
132
+ finally:
133
+ d._release()
134
+ for t in targets:
135
+ b = builders[id(t.cls)]
136
+ if not b.woven.contributed:
137
+ continue
138
+ with b.contributor(b.binding.name, None):
139
+ _call(b.binding.finalize, WeaveCtx(b), b.binding.name, t, diags)
140
+ out.append(b.woven)
141
+ return out, diags
142
+
143
+
144
+ def _and(a, b):
145
+ return lambda c: a(c) and b(c)
146
+
147
+
148
+ def _call(fn, ctx, who: str, target, diags: List[Diag]) -> None:
149
+ try:
150
+ fn(ctx)
151
+ except SvWeaveError as e:
152
+ diags.extend(e.diags)
153
+ except Exception as e:
154
+ tb = traceback.extract_tb(e.__traceback__)
155
+ frame = tb[-1] if tb else None
156
+ loc = SrcLoc(frame.filename, frame.lineno) if frame else None
157
+ on = (" on %s" % target.cls.qname) if target is not None else ""
158
+ diags.append(Diag(Severity.ERROR, "%s failed%s: %s: %s"
159
+ % (who, on, type(e).__name__, e), loc))
@@ -0,0 +1,60 @@
1
+ """Stage 5, Check: model-level checks on the woven classes (design §5, §6.3, §6.5).
2
+
3
+ - An overridden method must be virtual and not static. Reported at the user's
4
+ declaration of the method.
5
+ - Added fields need an extension set with ``allow_state``.
6
+ - A woven class that leaves a pure virtual method unimplemented is not concrete, so it
7
+ is not registered (a note, not an error).
8
+ """
9
+ from typing import List
10
+
11
+ from .diag import Diag, Severity, SrcLoc
12
+ from .weave.model import MethodSlot, OrderError, WovenClass
13
+
14
+
15
+ # pre_randomize/post_randomize behave as virtual without being declared so (1800-2017 18.6.2).
16
+ IMPLICITLY_VIRTUAL = {"pre_randomize", "post_randomize"}
17
+
18
+
19
+ def _at(origin):
20
+ return SrcLoc(origin.file, origin.line) if origin is not None and origin.file else None
21
+
22
+
23
+ def check(woven: List[WovenClass], cfg) -> List[Diag]:
24
+ diags: List[Diag] = []
25
+ for wc in woven:
26
+ for slot in wc.slots.values():
27
+ for part in (slot.decl, slot.pre, slot.post):
28
+ try:
29
+ part.ordered()
30
+ except OrderError as e:
31
+ diags.append(Diag(Severity.ERROR, "%s: %s" % (wc.name, e),
32
+ _at(slot.first_origin)))
33
+ m = slot.overrides
34
+ if slot.kind in (MethodSlot.KIND_OVERRIDE, MethodSlot.KIND_FEATURE) and m is not None:
35
+ if m.static:
36
+ diags.append(Diag(Severity.ERROR, "%s::%s is static; cannot weave (from %s)"
37
+ % (m.owner.qname, m.name, slot.first_origin), m.loc))
38
+ elif not m.virtual and m.name not in IMPLICITLY_VIRTUAL:
39
+ diags.append(Diag(Severity.ERROR,
40
+ "%s::%s is not virtual; cannot weave (requested by %s). "
41
+ "Declare it virtual in %s."
42
+ % (m.owner.qname, m.name, slot.first_origin, m.owner.qname),
43
+ m.loc))
44
+ for f in wc.fields:
45
+ es = f.origin.ext_set if f.origin else None
46
+ if es is not None and not cfg.extension_sets[es].allow_state:
47
+ diags.append(Diag(Severity.ERROR,
48
+ "%s adds a field to %s, but extension set '%s' does not "
49
+ "allow_state: %s" % (f.origin.contributor, wc.name, es, f.text),
50
+ _at(f.origin)))
51
+ implemented = {n for n, s in wc.slots.items()}
52
+ missing = [m for m in wc.cls.unimplemented_pure() if m.name not in implemented]
53
+ wc.unimplemented = [m.name for m in missing]
54
+ wc.concrete = not missing
55
+ if missing:
56
+ diags.append(Diag(Severity.NOTE,
57
+ "%s is abstract (pure virtual %s not implemented); it is not "
58
+ "registered" % (wc.name, ", ".join(m.name for m in missing)),
59
+ wc.cls.loc))
60
+ return diags