wavekit 0.5.3__tar.gz → 0.5.5__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.
- {wavekit-0.5.3 → wavekit-0.5.5}/PKG-INFO +1 -1
- {wavekit-0.5.3 → wavekit-0.5.5}/pyproject.toml +1 -1
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/__init__.py +29 -5
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/readers/fsdb/reader.py +7 -1
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/waveform.py +19 -6
- {wavekit-0.5.3 → wavekit-0.5.5}/LICENSE +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/README.md +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/build.py +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/pattern/__init__.py +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/pattern/dsl.py +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/pattern/engine.py +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/pattern/instance.py +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/pattern/result.py +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/pattern/steps.py +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/readers/base.py +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/readers/expr_parser.py +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/readers/fsdb/npi_fsdb.pxd +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/readers/fsdb/npi_fsdb_reader.pyx +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/readers/pattern_parser.py +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/readers/value_change.pyx +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/readers/vcd/reader.py +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/scope.py +0 -0
- {wavekit-0.5.3 → wavekit-0.5.5}/src/wavekit/signal.py +0 -0
|
@@ -34,11 +34,35 @@ __all__ = [
|
|
|
34
34
|
'MatchResult',
|
|
35
35
|
'MatchStatus',
|
|
36
36
|
'PatternError',
|
|
37
|
+
'has_fsdb_support',
|
|
37
38
|
]
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
# Detect if FSDB support is available (compiled with VERDI_HOME)
|
|
41
|
+
import importlib.util
|
|
42
|
+
|
|
43
|
+
_fsdb_available = (
|
|
44
|
+
importlib.util.find_spec('.readers.fsdb.npi_fsdb_reader', package=__name__) is not None
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def has_fsdb_support() -> bool:
|
|
49
|
+
"""Check if FsdbReader is available in the current installation."""
|
|
50
|
+
return _fsdb_available
|
|
41
51
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
52
|
+
|
|
53
|
+
class _FsdbReaderStub:
|
|
54
|
+
"""Placeholder that raises an error when FsdbReader is used without Verdi support."""
|
|
55
|
+
|
|
56
|
+
def __init__(self, *args, **kwargs):
|
|
57
|
+
raise RuntimeError(
|
|
58
|
+
'FsdbReader requires Verdi to be installed and configured.\n\n'
|
|
59
|
+
'1. Set VERDI_HOME environment variable to your Verdi installation path.\n'
|
|
60
|
+
'2. Reinstall wavekit:\n'
|
|
61
|
+
' pip install --force-reinstall --no-cache-dir --no-deps wavekit'
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
if _fsdb_available:
|
|
66
|
+
from .readers.fsdb.reader import FsdbReader as FsdbReader
|
|
67
|
+
else:
|
|
68
|
+
FsdbReader = _FsdbReaderStub # type: ignore[assignment]
|
|
@@ -138,7 +138,13 @@ class FsdbReader(Reader):
|
|
|
138
138
|
import os
|
|
139
139
|
import sys
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
verdi_home = os.environ.get('VERDI_HOME')
|
|
142
|
+
if verdi_home is None:
|
|
143
|
+
raise RuntimeError(
|
|
144
|
+
'VERDI_HOME environment variable is not set.\n'
|
|
145
|
+
'Please set VERDI_HOME to your Verdi installation path.'
|
|
146
|
+
)
|
|
147
|
+
rel_lib_path = verdi_home + '/share/NPI/python'
|
|
142
148
|
sys.path.append(os.path.abspath(rel_lib_path))
|
|
143
149
|
FsdbReader.pynpi['npisys'] = importlib.import_module('pynpi.npisys')
|
|
144
150
|
FsdbReader.pynpi['waveform'] = importlib.import_module('pynpi.waveform')
|
|
@@ -130,17 +130,30 @@ class Waveform:
|
|
|
130
130
|
dense sampled waveform to just the value-change events.
|
|
131
131
|
|
|
132
132
|
Returns a new :class:`Waveform` where no two adjacent entries have the
|
|
133
|
-
same value. :
|
|
133
|
+
same value. Behavior matches :func:`numpy.unique_consecutive`.
|
|
134
134
|
"""
|
|
135
135
|
if len(self.value) <= 1:
|
|
136
136
|
return self.copy()
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
return self.take(diff_indices)
|
|
137
|
+
# Keep first element, then keep elements where value changed from previous
|
|
138
|
+
mask = np.concatenate(([True], np.diff(self.value) != 0))
|
|
139
|
+
return self.take(np.where(mask)[0])
|
|
141
140
|
|
|
142
141
|
def compress(self) -> Waveform:
|
|
143
|
-
|
|
142
|
+
"""Remove consecutive duplicate values, keeping the last occurrence.
|
|
143
|
+
|
|
144
|
+
Unlike :meth:`unique_consecutive`, this preserves the final timestamp
|
|
145
|
+
and value, which is useful for waveforms where the end time matters.
|
|
146
|
+
|
|
147
|
+
Returns a new :class:`Waveform` where no two adjacent entries have the
|
|
148
|
+
same value, except the last sample is always preserved.
|
|
149
|
+
"""
|
|
150
|
+
if len(self.value) <= 1:
|
|
151
|
+
return self.copy()
|
|
152
|
+
diff_mask = np.diff(self.value) != 0
|
|
153
|
+
# Keep where next value changed (which means current is last of its group)
|
|
154
|
+
# plus always keep last element
|
|
155
|
+
mask = np.concatenate((diff_mask, [True]))
|
|
156
|
+
return self.take(np.where(mask)[0])
|
|
144
157
|
|
|
145
158
|
def vectorized_filter(
|
|
146
159
|
self,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|