wavekit 0.7.2__tar.gz → 0.7.3__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 (32) hide show
  1. wavekit-0.7.3/PKG-INFO +134 -0
  2. wavekit-0.7.3/README.md +109 -0
  3. {wavekit-0.7.2 → wavekit-0.7.3}/pyproject.toml +8 -2
  4. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/__init__.py +0 -2
  5. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/expression.py +1 -1
  6. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/pattern/dsl.py +17 -9
  7. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/pattern/result.py +5 -1
  8. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/pattern/runtime.py +1 -1
  9. wavekit-0.7.3/src/wavekit/readers/__init__.py +1 -0
  10. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/readers/base.py +158 -96
  11. wavekit-0.7.3/src/wavekit/readers/fsdb/__init__.py +1 -0
  12. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/readers/fsdb/reader.py +5 -2
  13. wavekit-0.7.3/src/wavekit/readers/fst/__init__.py +1 -0
  14. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/readers/fst/reader.py +7 -4
  15. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/readers/hierarchy.py +8 -11
  16. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/readers/matcher.py +2 -5
  17. wavekit-0.7.3/src/wavekit/readers/vcd/__init__.py +1 -0
  18. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/readers/vcd/reader.py +8 -5
  19. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/waveform.py +71 -60
  20. wavekit-0.7.2/PKG-INFO +0 -556
  21. wavekit-0.7.2/README.md +0 -532
  22. {wavekit-0.7.2 → wavekit-0.7.3}/LICENSE +0 -0
  23. {wavekit-0.7.2 → wavekit-0.7.3}/build.py +0 -0
  24. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/pattern/__init__.py +0 -0
  25. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/pattern/compiler.py +0 -0
  26. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/pattern/errors.py +0 -0
  27. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/pattern/steps.py +0 -0
  28. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/readers/expr_parser.py +0 -0
  29. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/readers/fsdb/npi_fsdb.pxd +0 -0
  30. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/readers/fsdb/npi_fsdb_reader.pyx +0 -0
  31. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/readers/range.py +0 -0
  32. {wavekit-0.7.2 → wavekit-0.7.3}/src/wavekit/readers/value_change.pyx +0 -0
wavekit-0.7.3/PKG-INFO ADDED
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.4
2
+ Name: wavekit
3
+ Version: 0.7.3
4
+ Summary: High-level digital waveform analysis in Python
5
+ License-File: LICENSE
6
+ Author: cxzzzz
7
+ Author-email: cxz19961010@outlook.com
8
+ Requires-Python: >=3.9,<4.0
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Requires-Dist: lark (>=1.2,<2)
17
+ Requires-Dist: numpy (>=2.0.0,<3.0.0)
18
+ Requires-Dist: pylibfst (>=0.2.1,<0.3.0)
19
+ Requires-Dist: pytest (>=8.2.2,<9.0.0)
20
+ Requires-Dist: vcdvcd (>=2.3.5,<3.0.0)
21
+ Project-URL: Documentation, https://cxzzzz.github.io/wavekit
22
+ Project-URL: Repository, https://github.com/cxzzzz/wavekit
23
+ Description-Content-Type: text/markdown
24
+
25
+ # <img src="docs/en/images/logo.svg" alt="" width="30" height="30" valign="middle"> wavekit
26
+
27
+ [![CI](https://github.com/cxzzzz/wavekit/actions/workflows/python-package.yml/badge.svg)](https://github.com/cxzzzz/wavekit/actions/workflows/python-package.yml)
28
+ [![PyPI version](https://img.shields.io/pypi/v/wavekit.svg)](https://pypi.org/project/wavekit/)
29
+ [![Python Versions](https://img.shields.io/pypi/pyversions/wavekit.svg)](https://pypi.org/project/wavekit/)
30
+ [![Downloads](https://pepy.tech/badge/wavekit)](https://pepy.tech/project/wavekit)
31
+ [![License](https://img.shields.io/github/license/cxzzzz/wavekit.svg)](LICENSE)
32
+
33
+ English | [中文](README_ZH.md)
34
+
35
+ **Wavekit is a Python library for high-level digital waveform analysis.**
36
+ Wavekit supports common digital waveform formats; by combining batch signal
37
+ queries with analysis at the cycle and transaction levels, it helps users
38
+ interpret recorded signal changes in terms of per-cycle state and temporal
39
+ relationships.
40
+
41
+ > **AI integration:** [wavekit-mcp](https://github.com/cxzzzz/wavekit-mcp) exposes wavekit analysis through
42
+ > MCP tools for AI-assisted workflows.
43
+
44
+ ## Features
45
+
46
+ - **Flexible signal queries:** find and batch-load related signals from
47
+ hierarchical waveform data using multiple path-matching options.
48
+ - **Cycle-level analysis:** use a range of waveform operations on clock-sampled
49
+ data to analyze cycle-based behavior such as interface backpressure and FIFO
50
+ occupancy.
51
+ - **Transaction-level analysis:** use temporal pattern matching to describe
52
+ signal relationships across multiple clock cycles for protocol analysis,
53
+ transaction extraction, and latency measurement.
54
+ - **Multi-format waveform support:** load and analyze VCD, FST, and FSDB files
55
+ using the same API.
56
+
57
+ ## Installation
58
+
59
+ ```console
60
+ python -m pip install wavekit
61
+ ```
62
+
63
+ wavekit supports Python 3.9 and newer. FSDB support requires the Verdi NPI
64
+ runtime (`libNPI.so`); see the [installation guide](https://cxzzzz.github.io/wavekit/getting-started/installation/) for
65
+ setup details.
66
+
67
+ ## Quick start
68
+
69
+ Calculate the occupancy of a FIFO from a VCD waveform:
70
+
71
+ ```python
72
+ import numpy as np
73
+
74
+ from wavekit import VcdReader
75
+
76
+ with VcdReader('simulation.vcd') as r:
77
+ clock = 'tb.clk'
78
+ depth = 16
79
+
80
+ w_ptr = r.load_waveform(
81
+ 'tb.u_fifo.w_ptr',
82
+ clock=clock,
83
+ )
84
+ r_ptr = r.load_waveform(
85
+ 'tb.u_fifo.r_ptr',
86
+ clock=clock,
87
+ )
88
+
89
+ occupancy = (w_ptr + depth - r_ptr) % depth
90
+
91
+ print('Average occupancy:', np.mean(occupancy.value))
92
+ ```
93
+
94
+ See the [first waveform tutorial](https://cxzzzz.github.io/wavekit/getting-started/first-waveform/) for a
95
+ complete runnable FIFO example.
96
+
97
+ ## Documentation
98
+
99
+ See the [documentation](https://cxzzzz.github.io/wavekit/) for the full reference and guides:
100
+
101
+ - [Installation](https://cxzzzz.github.io/wavekit/getting-started/installation/)
102
+ - [First waveform](https://cxzzzz.github.io/wavekit/getting-started/first-waveform/)
103
+ - [Reader guide](https://cxzzzz.github.io/wavekit/guides/reader/)
104
+ - [Signal queries](https://cxzzzz.github.io/wavekit/guides/signal-query/)
105
+ - [Waveform analysis](https://cxzzzz.github.io/wavekit/guides/waveform-analysis/)
106
+ - [Pattern matching](https://cxzzzz.github.io/wavekit/guides/pattern-matching/)
107
+ - [API reference](https://cxzzzz.github.io/wavekit/reference/api/)
108
+ - [Complete examples](https://cxzzzz.github.io/wavekit/examples/)
109
+
110
+ ## Development
111
+
112
+ Install the development dependencies and run the checks with Poetry:
113
+
114
+ ```console
115
+ poetry install
116
+ poetry run pytest
117
+ poetry run ruff check .
118
+ poetry run ruff format --check .
119
+ poetry run mypy
120
+ ```
121
+
122
+ Build the documentation locally with Python 3.10 or newer:
123
+
124
+ ```console
125
+ poetry install --with docs
126
+ poetry run zensical build --clean --strict
127
+ ```
128
+
129
+ See [Contributing](https://cxzzzz.github.io/wavekit/contributing/) for contribution guidelines.
130
+
131
+ ## License
132
+
133
+ This project is licensed under the MIT License. See [LICENSE](LICENSE).
134
+
@@ -0,0 +1,109 @@
1
+ # <img src="docs/en/images/logo.svg" alt="" width="30" height="30" valign="middle"> wavekit
2
+
3
+ [![CI](https://github.com/cxzzzz/wavekit/actions/workflows/python-package.yml/badge.svg)](https://github.com/cxzzzz/wavekit/actions/workflows/python-package.yml)
4
+ [![PyPI version](https://img.shields.io/pypi/v/wavekit.svg)](https://pypi.org/project/wavekit/)
5
+ [![Python Versions](https://img.shields.io/pypi/pyversions/wavekit.svg)](https://pypi.org/project/wavekit/)
6
+ [![Downloads](https://pepy.tech/badge/wavekit)](https://pepy.tech/project/wavekit)
7
+ [![License](https://img.shields.io/github/license/cxzzzz/wavekit.svg)](LICENSE)
8
+
9
+ English | [中文](README_ZH.md)
10
+
11
+ **Wavekit is a Python library for high-level digital waveform analysis.**
12
+ Wavekit supports common digital waveform formats; by combining batch signal
13
+ queries with analysis at the cycle and transaction levels, it helps users
14
+ interpret recorded signal changes in terms of per-cycle state and temporal
15
+ relationships.
16
+
17
+ > **AI integration:** [wavekit-mcp](https://github.com/cxzzzz/wavekit-mcp) exposes wavekit analysis through
18
+ > MCP tools for AI-assisted workflows.
19
+
20
+ ## Features
21
+
22
+ - **Flexible signal queries:** find and batch-load related signals from
23
+ hierarchical waveform data using multiple path-matching options.
24
+ - **Cycle-level analysis:** use a range of waveform operations on clock-sampled
25
+ data to analyze cycle-based behavior such as interface backpressure and FIFO
26
+ occupancy.
27
+ - **Transaction-level analysis:** use temporal pattern matching to describe
28
+ signal relationships across multiple clock cycles for protocol analysis,
29
+ transaction extraction, and latency measurement.
30
+ - **Multi-format waveform support:** load and analyze VCD, FST, and FSDB files
31
+ using the same API.
32
+
33
+ ## Installation
34
+
35
+ ```console
36
+ python -m pip install wavekit
37
+ ```
38
+
39
+ wavekit supports Python 3.9 and newer. FSDB support requires the Verdi NPI
40
+ runtime (`libNPI.so`); see the [installation guide](https://cxzzzz.github.io/wavekit/getting-started/installation/) for
41
+ setup details.
42
+
43
+ ## Quick start
44
+
45
+ Calculate the occupancy of a FIFO from a VCD waveform:
46
+
47
+ ```python
48
+ import numpy as np
49
+
50
+ from wavekit import VcdReader
51
+
52
+ with VcdReader('simulation.vcd') as r:
53
+ clock = 'tb.clk'
54
+ depth = 16
55
+
56
+ w_ptr = r.load_waveform(
57
+ 'tb.u_fifo.w_ptr',
58
+ clock=clock,
59
+ )
60
+ r_ptr = r.load_waveform(
61
+ 'tb.u_fifo.r_ptr',
62
+ clock=clock,
63
+ )
64
+
65
+ occupancy = (w_ptr + depth - r_ptr) % depth
66
+
67
+ print('Average occupancy:', np.mean(occupancy.value))
68
+ ```
69
+
70
+ See the [first waveform tutorial](https://cxzzzz.github.io/wavekit/getting-started/first-waveform/) for a
71
+ complete runnable FIFO example.
72
+
73
+ ## Documentation
74
+
75
+ See the [documentation](https://cxzzzz.github.io/wavekit/) for the full reference and guides:
76
+
77
+ - [Installation](https://cxzzzz.github.io/wavekit/getting-started/installation/)
78
+ - [First waveform](https://cxzzzz.github.io/wavekit/getting-started/first-waveform/)
79
+ - [Reader guide](https://cxzzzz.github.io/wavekit/guides/reader/)
80
+ - [Signal queries](https://cxzzzz.github.io/wavekit/guides/signal-query/)
81
+ - [Waveform analysis](https://cxzzzz.github.io/wavekit/guides/waveform-analysis/)
82
+ - [Pattern matching](https://cxzzzz.github.io/wavekit/guides/pattern-matching/)
83
+ - [API reference](https://cxzzzz.github.io/wavekit/reference/api/)
84
+ - [Complete examples](https://cxzzzz.github.io/wavekit/examples/)
85
+
86
+ ## Development
87
+
88
+ Install the development dependencies and run the checks with Poetry:
89
+
90
+ ```console
91
+ poetry install
92
+ poetry run pytest
93
+ poetry run ruff check .
94
+ poetry run ruff format --check .
95
+ poetry run mypy
96
+ ```
97
+
98
+ Build the documentation locally with Python 3.10 or newer:
99
+
100
+ ```console
101
+ poetry install --with docs
102
+ poetry run zensical build --clean --strict
103
+ ```
104
+
105
+ See [Contributing](https://cxzzzz.github.io/wavekit/contributing/) for contribution guidelines.
106
+
107
+ ## License
108
+
109
+ This project is licensed under the MIT License. See [LICENSE](LICENSE).
@@ -1,10 +1,11 @@
1
1
  [tool.poetry]
2
2
  name = "wavekit"
3
- version = "0.7.2"
4
- description = "a fundamental package for digital circuit waveform analysis"
3
+ version = "0.7.3"
4
+ description = "High-level digital waveform analysis in Python"
5
5
  authors = ["cxzzzz <cxz19961010@outlook.com>"]
6
6
  readme = "README.md"
7
7
  repository = "https://github.com/cxzzzz/wavekit"
8
+ documentation = "https://cxzzzz.github.io/wavekit"
8
9
  build = "build.py"
9
10
  include = [
10
11
  { path = "src/wavekit/**/*.so", format = "wheel" },
@@ -22,6 +23,11 @@ lark = ">=1.2,<2"
22
23
  ruff = "^0.6.2"
23
24
  mypy = "^1.11.2"
24
25
 
26
+
27
+ [tool.poetry.group.docs.dependencies]
28
+ zensical = {version = "^0.0.57", python = ">=3.10,<4.0"}
29
+ mkdocstrings-python = {version = "1.18.2", python = ">=3.10,<4.0"}
30
+
25
31
  [tool.ruff]
26
32
  target-version = "py39"
27
33
  line-length = 100
@@ -16,7 +16,6 @@ from .readers.hierarchy import Signal as Signal
16
16
  from .readers.hierarchy import SignalCompositeType as SignalCompositeType
17
17
  from .readers.matcher import BraceCapture as BraceCapture
18
18
  from .readers.matcher import Capture as Capture
19
- from .readers.matcher import CaptureKey as CaptureKey
20
19
  from .readers.matcher import ExactCapture as ExactCapture
21
20
  from .readers.matcher import RegexCapture as RegexCapture
22
21
  from .readers.matcher import WildcardCapture as WildcardCapture
@@ -35,7 +34,6 @@ __all__ = [
35
34
  'Signal',
36
35
  'SignalCompositeType',
37
36
  'Capture',
38
- 'CaptureKey',
39
37
  'ExactCapture',
40
38
  'BraceCapture',
41
39
  'RegexCapture',
@@ -149,7 +149,7 @@ def evaluate_expression(expr: str, namespace: dict[str, Any]) -> Any:
149
149
  Parameters
150
150
  ----------
151
151
  expr:
152
- The substituted expression returned by :func:`parse_expression`.
152
+ The substituted expression returned by ``parse_expression``.
153
153
  Physical paths must be resolved and replaced before calling this
154
154
  function.
155
155
  namespace:
@@ -28,8 +28,8 @@ class Pattern:
28
28
  """Declarative temporal pattern builder over waveform signals.
29
29
 
30
30
  Build steps with ``Pattern().wait(...).capture(...)`` and execute with
31
- module-level :func:`match`. ``Pattern`` stores only the declarative step AST;
32
- programmable checking/extraction uses :func:`match(body)` or :func:`collect(body)`.
31
+ module-level ``match``. ``Pattern`` stores only the declarative step AST;
32
+ programmable checking/extraction uses ``match(body)`` or ``collect(body)``.
33
33
 
34
34
  The first blocking step selects candidate start cycles. Later blocking steps
35
35
  wait within a matched transaction.
@@ -77,7 +77,10 @@ class Pattern:
77
77
  def consume(
78
78
  self,
79
79
  cond: Waveform | Callable[[int, dict[str, Any]], bool] | bool,
80
- channel: Channel | Hashable | Callable[[int, dict[str, Any]], Channel | Hashable],
80
+ channel: Channel
81
+ | Hashable
82
+ | Callable[[int, dict[str, Any]], Channel | Hashable]
83
+ | None = None,
81
84
  *,
82
85
  require: Waveform | Callable[[int, dict[str, Any]], bool] | bool | None = None,
83
86
  require_message: str | Callable[[int, dict[str, Any]], str] | None = None,
@@ -93,10 +96,11 @@ class Pattern:
93
96
  cycle number. ``captures`` is the current match's capture dict.
94
97
  channel:
95
98
  ``Channel``, hashable key, or ``callable(index, captures) -> Channel | Hashable``.
96
- Channel callbacks use the same ``(index, captures)`` arguments.
97
- The resolved ``(channel, cycle)`` can be claimed by at most one match;
98
- earlier start cycles win. This does not reserve the channel while
99
- ``cond`` is false.
99
+ If omitted, this consume step receives a private channel created when
100
+ the step is declared. Channel callbacks use the same ``(index, captures)``
101
+ arguments. The resolved ``(channel, cycle)`` can be claimed by at most
102
+ one match; earlier start cycles win. This does not reserve the channel
103
+ while ``cond`` is false.
100
104
  require:
101
105
  Optional condition checked while ``cond`` is false, or while ``cond`` is
102
106
  true but the current ``(channel, cycle)`` was already claimed. It is not
@@ -110,9 +114,13 @@ class Pattern:
110
114
  Pattern
111
115
  This pattern, for chaining.
112
116
  """
117
+ resolved_channel = Channel() if channel is None else channel
113
118
  self._steps.append(
114
119
  ConsumeStep(
115
- cond=cond, channel=channel, require=require, require_message=require_message
120
+ cond=cond,
121
+ channel=resolved_channel,
122
+ require=require,
123
+ require_message=require_message,
116
124
  )
117
125
  )
118
126
  return self
@@ -235,7 +243,7 @@ class Pattern:
235
243
  Notes
236
244
  -----
237
245
  Exactly one of ``until`` and ``when`` is required. Conditions use the same
238
- ``Waveform`` / ``bool`` / callable forms as :meth:`wait`.
246
+ ``Waveform`` / ``bool`` / callable forms as ``wait``.
239
247
  """
240
248
  if until is not None and when is not None:
241
249
  raise ValueError("Cannot specify both 'until' and 'when' in loop()")
@@ -19,14 +19,18 @@ class MatchStatus:
19
19
 
20
20
  @dataclass(frozen=True)
21
21
  class OK(MatchStatusValue):
22
- pass
22
+ """Successful completion of a pattern candidate."""
23
23
 
24
24
  @dataclass(frozen=True)
25
25
  class Timeout(MatchStatusValue):
26
+ """A pattern candidate did not complete within its allowed duration."""
27
+
26
28
  message: str | None = None
27
29
 
28
30
  @dataclass(frozen=True)
29
31
  class RequireViolated(MatchStatusValue):
32
+ """A non-blocking ``require`` check failed."""
33
+
30
34
  message: str | None = None
31
35
 
32
36
 
@@ -37,7 +37,7 @@ class PatternContext:
37
37
 
38
38
  Programmable bodies run once per scanned start cycle. Use ``ctx.value(...)``
39
39
  to read waveforms, ``ctx.wait(...)`` / ``ctx.consume(...)`` / ``ctx.delay(...)``
40
- to move through time, and return ``ctx.OK`` from :func:`wavekit.pattern.match`
40
+ to move through time, and return ``ctx.OK`` from ``wavekit.pattern.match``
41
41
  bodies to record a successful match.
42
42
  """
43
43
 
@@ -0,0 +1 @@
1
+ """Waveform reader backends and hierarchy types."""