PyIBIS-AMI 9.0.0__tar.gz → 9.2.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.
- pyibis_ami-9.2.0/PKG-INFO +111 -0
- pyibis_ami-9.2.0/README.md +68 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/pyproject.toml +18 -14
- pyibis_ami-9.2.0/src/pyibis_ami.egg-info/PKG-INFO +111 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibis_ami.egg-info/SOURCES.txt +2 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibis_ami.egg-info/entry_points.txt +1 -0
- pyibis_ami-9.2.0/src/pyibis_ami.egg-info/requires.txt +15 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/__init__.py +1 -1
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/ami/model.py +35 -39
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/ami/parser.py +2 -1
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/ibis/model.py +16 -1
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/ibis/parser.py +29 -3
- pyibis_ami-9.2.0/src/pyibisami/testing/ami_test_config.py +518 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/testing/ami_tests.py +1 -1
- pyibis_ami-9.2.0/tests/test_ami_test_config.py +370 -0
- pyibis_ami-9.0.0/PKG-INFO +0 -136
- pyibis_ami-9.0.0/README.md +0 -96
- pyibis_ami-9.0.0/src/pyibis_ami.egg-info/PKG-INFO +0 -136
- pyibis_ami-9.0.0/src/pyibis_ami.egg-info/requires.txt +0 -13
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/LICENSE +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/MANIFEST.in +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/docs/source/ami.rst +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/docs/source/conf.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/docs/source/ibis.rst +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/docs/source/index.rst +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/docs/source/install.rst +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/docs/source/modules.rst +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/docs/source/tools.rst +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/examples/all_taps.run +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/examples/bandwidth.run +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/examples/dummy.em +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/examples/examples.md +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/examples/freq_resp.em +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/examples/impulse.em +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/examples/impulse_response_8ma.txt +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/examples/mode.run +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/examples/stratix4_ami_tx_runs/all_taps.run +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/examples/stratix4_ami_tx_runs/test_results.xml +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/examples/test_results/test_results.xsl +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/setup.cfg +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibis_ami.egg-info/dependency_links.txt +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibis_ami.egg-info/top_level.txt +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/IBIS_AMI_Checker.ipynb +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/IBIS_AMI_Tester.ipynb +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/__main__.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/ami/__init__.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/ami/config.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/ami/generic.ami.em +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/ami/generic.ibs.em +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/ami/parameter.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/ami/reserved_parameter_names.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/common.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/ibis/__init__.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/ibis/file.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/testing/__init__.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/testing/ami_tests_helpers.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/testing/ibis_file_tests.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/testing/test_defs.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/testing/test_models.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/testing/util.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/tools/__init__.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/tools/run_notebook.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/tools/run_tests.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/tools/test_results.xsl +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/util/ami.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/util/misc.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/util/plot.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/src/pyibisami/util/reportlab.py +0 -0
- {pyibis_ami-9.0.0 → pyibis_ami-9.2.0}/tests/test_run_tests.py +0 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyibis-ami
|
|
3
|
+
Version: 9.2.0
|
|
4
|
+
Summary: Facilitates working directly with IBIS-AMI DLLs from the Python command prompt.
|
|
5
|
+
Author-email: David Banas <capn.freako@gmail.com>
|
|
6
|
+
Project-URL: Documentation, https://pyibis-ami.readthedocs.io/en/latest/
|
|
7
|
+
Project-URL: Wiki, https://github.com/capn-freako/PyAMI/wiki
|
|
8
|
+
Project-URL: GitHub, https://github.com/capn-freako/PyAMI
|
|
9
|
+
Project-URL: PyPi, https://pypi.org/project/PyIBIS-AMI/
|
|
10
|
+
Keywords: ibis-ami
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
22
|
+
Classifier: Topic :: System :: Emulators
|
|
23
|
+
Classifier: Topic :: Utilities
|
|
24
|
+
Requires-Python: <3.14,>=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: chaco==6.1.1
|
|
28
|
+
Requires-Dist: click==8.4.2
|
|
29
|
+
Requires-Dist: empy==4.2.1
|
|
30
|
+
Requires-Dist: importlib_resources==7.1.0
|
|
31
|
+
Requires-Dist: jupyter==1.1.1
|
|
32
|
+
Requires-Dist: lxml-html-clean==0.4.5
|
|
33
|
+
Requires-Dist: matplotlib>=3.6.1
|
|
34
|
+
Requires-Dist: numpy>=1.26
|
|
35
|
+
Requires-Dist: papermill==2.7.0
|
|
36
|
+
Requires-Dist: parsec==3.17
|
|
37
|
+
Requires-Dist: reportlab==5.0.0
|
|
38
|
+
Requires-Dist: scipy>=1.15
|
|
39
|
+
Requires-Dist: traits==7.1.0
|
|
40
|
+
Requires-Dist: traitsui==8.0.0
|
|
41
|
+
Requires-Dist: types-reportlab==4.5.1.20260712
|
|
42
|
+
Dynamic: license-file
|
|
43
|
+
|
|
44
|
+
[](https://results.pre-commit.ci/latest/github/capn-freako/PyAMI/master)
|
|
45
|
+
|
|
46
|
+
# PyIBIS-AMI
|
|
47
|
+
|
|
48
|
+
PyIBIS-AMI is a Python package of tools useful in the development and testing of IBIS-AMI models.
|
|
49
|
+
This library is used in [PyBERT](https://github.com/capn-freako/PyBERT) and also provides three
|
|
50
|
+
command line applications.
|
|
51
|
+
|
|
52
|
+
It can be installed via: `pip install PyIBIS-AMI`.
|
|
53
|
+
|
|
54
|
+
[View API/Developer's Documentation.](https://pyibis-ami.readthedocs.io/en/latest/)
|
|
55
|
+
|
|
56
|
+
## Command Line Tools
|
|
57
|
+
|
|
58
|
+
### IBIS-AMI Model Testing
|
|
59
|
+
|
|
60
|
+
**PyIBIS-AMI Native:**
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
% test-model -h
|
|
64
|
+
Usage: test-model [OPTIONS] IBIS_FILE
|
|
65
|
+
|
|
66
|
+
Options:
|
|
67
|
+
-m, --model TEXT Name of IBIS-AMI model to test.
|
|
68
|
+
-p, --params TEXT Directory containing test configuration sweeps.
|
|
69
|
+
-d, --debug Provide extra debugging information.
|
|
70
|
+
--version Show the version and exit.
|
|
71
|
+
-h, --help Show this message and exit.
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**IBIS v8.0:**
|
|
75
|
+
|
|
76
|
+
% check-ami -h
|
|
77
|
+
Usage: check-ami [OPTIONS] IBIS_FILE
|
|
78
|
+
|
|
79
|
+
Run [AMI Test Configuration] blocks embedded in an IBIS file (IBIS 8.0
|
|
80
|
+
§10.11).
|
|
81
|
+
|
|
82
|
+
Parses IBIS_FILE, locates the target model, then calls AMI_Init() (and
|
|
83
|
+
AMI_GetWave() for Time_domain configs) and compares the outputs against the
|
|
84
|
+
golden data files referenced in each [AMI Test Configuration] block.
|
|
85
|
+
|
|
86
|
+
Exits with status 1 if any configuration fails.
|
|
87
|
+
|
|
88
|
+
Options:
|
|
89
|
+
-m, --model-name TEXT Name of the [Model] to test. Required when the .ibs
|
|
90
|
+
file defines more than one model.
|
|
91
|
+
-c, --config TEXT Name of a single [AMI Test Configuration] to run.
|
|
92
|
+
Runs all configs when omitted.
|
|
93
|
+
--tol-ir FLOAT Absolute tolerance for impulse-response comparison.
|
|
94
|
+
[default: 1e-06]
|
|
95
|
+
--tol-wave FLOAT Absolute tolerance for waveform comparison.
|
|
96
|
+
[default: 1e-06]
|
|
97
|
+
-h, --help Show this message and exit.
|
|
98
|
+
|
|
99
|
+
### IBIS-AMI Model Pre-build Configuration
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
ami_config -h
|
|
103
|
+
Usage: ami_config [OPTIONS] PY_FILE
|
|
104
|
+
|
|
105
|
+
Configure IBIS-AMI model C++ source code, IBIS model, and AMI file.
|
|
106
|
+
|
|
107
|
+
py_file: name of model configuration file (*.py)
|
|
108
|
+
|
|
109
|
+
Options:
|
|
110
|
+
-h, --help Show this message and exit.
|
|
111
|
+
```
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
[](https://results.pre-commit.ci/latest/github/capn-freako/PyAMI/master)
|
|
2
|
+
|
|
3
|
+
# PyIBIS-AMI
|
|
4
|
+
|
|
5
|
+
PyIBIS-AMI is a Python package of tools useful in the development and testing of IBIS-AMI models.
|
|
6
|
+
This library is used in [PyBERT](https://github.com/capn-freako/PyBERT) and also provides three
|
|
7
|
+
command line applications.
|
|
8
|
+
|
|
9
|
+
It can be installed via: `pip install PyIBIS-AMI`.
|
|
10
|
+
|
|
11
|
+
[View API/Developer's Documentation.](https://pyibis-ami.readthedocs.io/en/latest/)
|
|
12
|
+
|
|
13
|
+
## Command Line Tools
|
|
14
|
+
|
|
15
|
+
### IBIS-AMI Model Testing
|
|
16
|
+
|
|
17
|
+
**PyIBIS-AMI Native:**
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
% test-model -h
|
|
21
|
+
Usage: test-model [OPTIONS] IBIS_FILE
|
|
22
|
+
|
|
23
|
+
Options:
|
|
24
|
+
-m, --model TEXT Name of IBIS-AMI model to test.
|
|
25
|
+
-p, --params TEXT Directory containing test configuration sweeps.
|
|
26
|
+
-d, --debug Provide extra debugging information.
|
|
27
|
+
--version Show the version and exit.
|
|
28
|
+
-h, --help Show this message and exit.
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**IBIS v8.0:**
|
|
32
|
+
|
|
33
|
+
% check-ami -h
|
|
34
|
+
Usage: check-ami [OPTIONS] IBIS_FILE
|
|
35
|
+
|
|
36
|
+
Run [AMI Test Configuration] blocks embedded in an IBIS file (IBIS 8.0
|
|
37
|
+
§10.11).
|
|
38
|
+
|
|
39
|
+
Parses IBIS_FILE, locates the target model, then calls AMI_Init() (and
|
|
40
|
+
AMI_GetWave() for Time_domain configs) and compares the outputs against the
|
|
41
|
+
golden data files referenced in each [AMI Test Configuration] block.
|
|
42
|
+
|
|
43
|
+
Exits with status 1 if any configuration fails.
|
|
44
|
+
|
|
45
|
+
Options:
|
|
46
|
+
-m, --model-name TEXT Name of the [Model] to test. Required when the .ibs
|
|
47
|
+
file defines more than one model.
|
|
48
|
+
-c, --config TEXT Name of a single [AMI Test Configuration] to run.
|
|
49
|
+
Runs all configs when omitted.
|
|
50
|
+
--tol-ir FLOAT Absolute tolerance for impulse-response comparison.
|
|
51
|
+
[default: 1e-06]
|
|
52
|
+
--tol-wave FLOAT Absolute tolerance for waveform comparison.
|
|
53
|
+
[default: 1e-06]
|
|
54
|
+
-h, --help Show this message and exit.
|
|
55
|
+
|
|
56
|
+
### IBIS-AMI Model Pre-build Configuration
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
ami_config -h
|
|
60
|
+
Usage: ami_config [OPTIONS] PY_FILE
|
|
61
|
+
|
|
62
|
+
Configure IBIS-AMI model C++ source code, IBIS model, and AMI file.
|
|
63
|
+
|
|
64
|
+
py_file: name of model configuration file (*.py)
|
|
65
|
+
|
|
66
|
+
Options:
|
|
67
|
+
-h, --help Show this message and exit.
|
|
68
|
+
```
|
|
@@ -5,25 +5,27 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyibis-ami"
|
|
7
7
|
description = "Facilitates working directly with IBIS-AMI DLLs from the Python command prompt."
|
|
8
|
-
version = "9.
|
|
8
|
+
version = "9.2.0"
|
|
9
9
|
authors = [ {name = "David Banas", email = "capn.freako@gmail.com"}
|
|
10
10
|
]
|
|
11
11
|
readme = "README.md"
|
|
12
|
-
requires-python = ">=3.10,<3.
|
|
12
|
+
requires-python = ">=3.10,<3.14"
|
|
13
13
|
dependencies = [
|
|
14
|
-
"chaco
|
|
15
|
-
"click
|
|
16
|
-
"empy
|
|
17
|
-
"importlib_resources",
|
|
18
|
-
"jupyter",
|
|
19
|
-
"lxml-html-clean
|
|
14
|
+
"chaco==6.1.1",
|
|
15
|
+
"click==8.4.2",
|
|
16
|
+
"empy==4.2.1",
|
|
17
|
+
"importlib_resources==7.1.0",
|
|
18
|
+
"jupyter==1.1.1",
|
|
19
|
+
"lxml-html-clean==0.4.5",
|
|
20
20
|
"matplotlib>=3.6.1",
|
|
21
|
-
"numpy>=1.26
|
|
22
|
-
"papermill",
|
|
23
|
-
"parsec
|
|
24
|
-
"reportlab
|
|
25
|
-
"scipy>=1.
|
|
26
|
-
"
|
|
21
|
+
"numpy>=1.26",
|
|
22
|
+
"papermill==2.7.0",
|
|
23
|
+
"parsec==3.17",
|
|
24
|
+
"reportlab==5.0.0",
|
|
25
|
+
"scipy>=1.15",
|
|
26
|
+
"traits==7.1.0",
|
|
27
|
+
"traitsui==8.0.0",
|
|
28
|
+
"types-reportlab==4.5.1.20260712",
|
|
27
29
|
]
|
|
28
30
|
keywords=["ibis-ami"]
|
|
29
31
|
classifiers=[
|
|
@@ -36,6 +38,7 @@ classifiers=[
|
|
|
36
38
|
"Programming Language :: Python :: 3.10",
|
|
37
39
|
"Programming Language :: Python :: 3.11",
|
|
38
40
|
"Programming Language :: Python :: 3.12",
|
|
41
|
+
"Programming Language :: Python :: 3.13",
|
|
39
42
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
40
43
|
"Topic :: System :: Emulators",
|
|
41
44
|
"Topic :: Utilities",
|
|
@@ -52,6 +55,7 @@ ami-config = "pyibisami.ami.config:main"
|
|
|
52
55
|
run-tests = "pyibisami.tools.run_tests:main"
|
|
53
56
|
run-notebook = "pyibisami.tools.run_notebook:main"
|
|
54
57
|
test-model = "pyibisami.testing.test_models:main"
|
|
58
|
+
check-ami = "pyibisami.testing.ami_test_config:main"
|
|
55
59
|
|
|
56
60
|
[tool.setuptools.packages.find]
|
|
57
61
|
where = ["src"]
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyibis-ami
|
|
3
|
+
Version: 9.2.0
|
|
4
|
+
Summary: Facilitates working directly with IBIS-AMI DLLs from the Python command prompt.
|
|
5
|
+
Author-email: David Banas <capn.freako@gmail.com>
|
|
6
|
+
Project-URL: Documentation, https://pyibis-ami.readthedocs.io/en/latest/
|
|
7
|
+
Project-URL: Wiki, https://github.com/capn-freako/PyAMI/wiki
|
|
8
|
+
Project-URL: GitHub, https://github.com/capn-freako/PyAMI
|
|
9
|
+
Project-URL: PyPi, https://pypi.org/project/PyIBIS-AMI/
|
|
10
|
+
Keywords: ibis-ami
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
22
|
+
Classifier: Topic :: System :: Emulators
|
|
23
|
+
Classifier: Topic :: Utilities
|
|
24
|
+
Requires-Python: <3.14,>=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: chaco==6.1.1
|
|
28
|
+
Requires-Dist: click==8.4.2
|
|
29
|
+
Requires-Dist: empy==4.2.1
|
|
30
|
+
Requires-Dist: importlib_resources==7.1.0
|
|
31
|
+
Requires-Dist: jupyter==1.1.1
|
|
32
|
+
Requires-Dist: lxml-html-clean==0.4.5
|
|
33
|
+
Requires-Dist: matplotlib>=3.6.1
|
|
34
|
+
Requires-Dist: numpy>=1.26
|
|
35
|
+
Requires-Dist: papermill==2.7.0
|
|
36
|
+
Requires-Dist: parsec==3.17
|
|
37
|
+
Requires-Dist: reportlab==5.0.0
|
|
38
|
+
Requires-Dist: scipy>=1.15
|
|
39
|
+
Requires-Dist: traits==7.1.0
|
|
40
|
+
Requires-Dist: traitsui==8.0.0
|
|
41
|
+
Requires-Dist: types-reportlab==4.5.1.20260712
|
|
42
|
+
Dynamic: license-file
|
|
43
|
+
|
|
44
|
+
[](https://results.pre-commit.ci/latest/github/capn-freako/PyAMI/master)
|
|
45
|
+
|
|
46
|
+
# PyIBIS-AMI
|
|
47
|
+
|
|
48
|
+
PyIBIS-AMI is a Python package of tools useful in the development and testing of IBIS-AMI models.
|
|
49
|
+
This library is used in [PyBERT](https://github.com/capn-freako/PyBERT) and also provides three
|
|
50
|
+
command line applications.
|
|
51
|
+
|
|
52
|
+
It can be installed via: `pip install PyIBIS-AMI`.
|
|
53
|
+
|
|
54
|
+
[View API/Developer's Documentation.](https://pyibis-ami.readthedocs.io/en/latest/)
|
|
55
|
+
|
|
56
|
+
## Command Line Tools
|
|
57
|
+
|
|
58
|
+
### IBIS-AMI Model Testing
|
|
59
|
+
|
|
60
|
+
**PyIBIS-AMI Native:**
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
% test-model -h
|
|
64
|
+
Usage: test-model [OPTIONS] IBIS_FILE
|
|
65
|
+
|
|
66
|
+
Options:
|
|
67
|
+
-m, --model TEXT Name of IBIS-AMI model to test.
|
|
68
|
+
-p, --params TEXT Directory containing test configuration sweeps.
|
|
69
|
+
-d, --debug Provide extra debugging information.
|
|
70
|
+
--version Show the version and exit.
|
|
71
|
+
-h, --help Show this message and exit.
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**IBIS v8.0:**
|
|
75
|
+
|
|
76
|
+
% check-ami -h
|
|
77
|
+
Usage: check-ami [OPTIONS] IBIS_FILE
|
|
78
|
+
|
|
79
|
+
Run [AMI Test Configuration] blocks embedded in an IBIS file (IBIS 8.0
|
|
80
|
+
§10.11).
|
|
81
|
+
|
|
82
|
+
Parses IBIS_FILE, locates the target model, then calls AMI_Init() (and
|
|
83
|
+
AMI_GetWave() for Time_domain configs) and compares the outputs against the
|
|
84
|
+
golden data files referenced in each [AMI Test Configuration] block.
|
|
85
|
+
|
|
86
|
+
Exits with status 1 if any configuration fails.
|
|
87
|
+
|
|
88
|
+
Options:
|
|
89
|
+
-m, --model-name TEXT Name of the [Model] to test. Required when the .ibs
|
|
90
|
+
file defines more than one model.
|
|
91
|
+
-c, --config TEXT Name of a single [AMI Test Configuration] to run.
|
|
92
|
+
Runs all configs when omitted.
|
|
93
|
+
--tol-ir FLOAT Absolute tolerance for impulse-response comparison.
|
|
94
|
+
[default: 1e-06]
|
|
95
|
+
--tol-wave FLOAT Absolute tolerance for waveform comparison.
|
|
96
|
+
[default: 1e-06]
|
|
97
|
+
-h, --help Show this message and exit.
|
|
98
|
+
|
|
99
|
+
### IBIS-AMI Model Pre-build Configuration
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
ami_config -h
|
|
103
|
+
Usage: ami_config [OPTIONS] PY_FILE
|
|
104
|
+
|
|
105
|
+
Configure IBIS-AMI model C++ source code, IBIS model, and AMI file.
|
|
106
|
+
|
|
107
|
+
py_file: name of model configuration file (*.py)
|
|
108
|
+
|
|
109
|
+
Options:
|
|
110
|
+
-h, --help Show this message and exit.
|
|
111
|
+
```
|
|
@@ -44,6 +44,7 @@ src/pyibisami/ibis/file.py
|
|
|
44
44
|
src/pyibisami/ibis/model.py
|
|
45
45
|
src/pyibisami/ibis/parser.py
|
|
46
46
|
src/pyibisami/testing/__init__.py
|
|
47
|
+
src/pyibisami/testing/ami_test_config.py
|
|
47
48
|
src/pyibisami/testing/ami_tests.py
|
|
48
49
|
src/pyibisami/testing/ami_tests_helpers.py
|
|
49
50
|
src/pyibisami/testing/ibis_file_tests.py
|
|
@@ -58,4 +59,5 @@ src/pyibisami/util/ami.py
|
|
|
58
59
|
src/pyibisami/util/misc.py
|
|
59
60
|
src/pyibisami/util/plot.py
|
|
60
61
|
src/pyibisami/util/reportlab.py
|
|
62
|
+
tests/test_ami_test_config.py
|
|
61
63
|
tests/test_run_tests.py
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
chaco==6.1.1
|
|
2
|
+
click==8.4.2
|
|
3
|
+
empy==4.2.1
|
|
4
|
+
importlib_resources==7.1.0
|
|
5
|
+
jupyter==1.1.1
|
|
6
|
+
lxml-html-clean==0.4.5
|
|
7
|
+
matplotlib>=3.6.1
|
|
8
|
+
numpy>=1.26
|
|
9
|
+
papermill==2.7.0
|
|
10
|
+
parsec==3.17
|
|
11
|
+
reportlab==5.0.0
|
|
12
|
+
scipy>=1.15
|
|
13
|
+
traits==7.1.0
|
|
14
|
+
traitsui==8.0.0
|
|
15
|
+
types-reportlab==4.5.1.20260712
|
|
@@ -17,6 +17,6 @@ try:
|
|
|
17
17
|
except Exception as err: # pylint: disable=broad-exception-caught
|
|
18
18
|
__version__ = f"{err} (dev)"
|
|
19
19
|
|
|
20
|
-
__date__ = "
|
|
20
|
+
__date__ = "June 18, 2026"
|
|
21
21
|
__authors__ = "David Banas & David Patterson"
|
|
22
22
|
__copy__ = "Copyright (c) 2012 David Banas, 2019 David Patterson"
|
|
@@ -12,7 +12,7 @@ import copy as cp
|
|
|
12
12
|
from ctypes import CDLL, byref, c_char_p, c_double # pylint: disable=no-name-in-module
|
|
13
13
|
from dataclasses import dataclass
|
|
14
14
|
from pathlib import Path
|
|
15
|
-
from typing import Any, Optional, TypeAlias
|
|
15
|
+
from typing import Any, Optional, TypeAlias, TypedDict
|
|
16
16
|
|
|
17
17
|
from matplotlib import pyplot as plt
|
|
18
18
|
import numpy as np
|
|
@@ -109,6 +109,17 @@ def interpFile(filename: str, sample_per: float) -> Rvec:
|
|
|
109
109
|
return np.array(res)
|
|
110
110
|
|
|
111
111
|
|
|
112
|
+
_DEFAULT_ROW_SIZE = 128
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class _InitData(TypedDict):
|
|
116
|
+
channel_response: Any # ctypes array: c_double * N
|
|
117
|
+
row_size: int
|
|
118
|
+
num_aggressors: int
|
|
119
|
+
sample_interval: c_double
|
|
120
|
+
bit_time: c_double
|
|
121
|
+
|
|
122
|
+
|
|
112
123
|
class AMIModelInitializer:
|
|
113
124
|
"""
|
|
114
125
|
Class containing the initialization data for an instance of ``AMIModel``.
|
|
@@ -125,16 +136,6 @@ class AMIModelInitializer:
|
|
|
125
136
|
|
|
126
137
|
# pylint: disable=too-few-public-methods,too-many-instance-attributes
|
|
127
138
|
|
|
128
|
-
ami_params = {"root_name": ""}
|
|
129
|
-
|
|
130
|
-
_init_data = {
|
|
131
|
-
"channel_response": (c_double * 128)(0.0, 1.0, 0.0),
|
|
132
|
-
"row_size": 128,
|
|
133
|
-
"num_aggressors": 0,
|
|
134
|
-
"sample_interval": c_double(25.0e-12),
|
|
135
|
-
"bit_time": c_double(0.1e-9),
|
|
136
|
-
}
|
|
137
|
-
|
|
138
139
|
def __init__(self, ami_params: dict, info_params: Optional[dict] = None, **optional_args):
|
|
139
140
|
"""
|
|
140
141
|
Constructor accepts a mandatory dictionary containing the AMI
|
|
@@ -176,25 +177,31 @@ class AMIModelInitializer:
|
|
|
176
177
|
Default) 100e-12 (10 Gbits/s)
|
|
177
178
|
"""
|
|
178
179
|
|
|
179
|
-
self.
|
|
180
|
-
|
|
180
|
+
self._init_data: _InitData = {
|
|
181
|
+
"channel_response": (c_double * _DEFAULT_ROW_SIZE)(0.0, 1.0, 0.0),
|
|
182
|
+
"row_size": _DEFAULT_ROW_SIZE,
|
|
183
|
+
"num_aggressors": 0,
|
|
184
|
+
"sample_interval": c_double(25.0e-12),
|
|
185
|
+
"bit_time": c_double(0.1e-9),
|
|
186
|
+
}
|
|
187
|
+
self.ami_params = {"root_name": "", **ami_params}
|
|
181
188
|
self.info_params = info_params
|
|
182
189
|
|
|
183
190
|
# Need to reverse sort, in order to catch ``sample_interval`` and ``row_size``,
|
|
184
191
|
# before ``channel_response``, since ``channel_response`` depends upon ``sample_interval``,
|
|
185
192
|
# when ``h`` is a file name, and overwrites ``row_size``, in any case.
|
|
186
|
-
keys = list(optional_args.keys())
|
|
193
|
+
keys: list[str] = list(optional_args.keys())
|
|
187
194
|
keys.sort(reverse=True)
|
|
188
195
|
if keys:
|
|
189
196
|
for key in keys:
|
|
190
197
|
if key in self._init_data:
|
|
191
|
-
self._init_data[key] = optional_args[key]
|
|
198
|
+
self._init_data[key] = optional_args[key] # type: ignore[literal-required]
|
|
192
199
|
|
|
193
200
|
def __str__(self):
|
|
194
201
|
return "\n\t".join([
|
|
195
202
|
"AMIModelInitializer instance:",
|
|
196
203
|
f"`ami_params`: {self.ami_params}",
|
|
197
|
-
f"`info_params`: {self.
|
|
204
|
+
f"`info_params`: {self.info_params}"])
|
|
198
205
|
|
|
199
206
|
def _getChannelResponse(self):
|
|
200
207
|
return list(map(float, self._init_data["channel_response"]))
|
|
@@ -336,26 +343,15 @@ class AMIModel: # pylint: disable=too-many-instance-attributes
|
|
|
336
343
|
self._amiClose(self._ami_mem_handle)
|
|
337
344
|
|
|
338
345
|
# Set up the AMI_Init() arguments.
|
|
346
|
+
# channel_response must be fetched as a ctypes array; the public property returns a plain list.
|
|
339
347
|
self._channel_response = ( # pylint: disable=attribute-defined-outside-init
|
|
340
|
-
init_object._init_data[ # pylint: disable=protected-access
|
|
341
|
-
"channel_response"
|
|
342
|
-
]
|
|
348
|
+
init_object._init_data["channel_response"] # pylint: disable=protected-access
|
|
343
349
|
)
|
|
344
350
|
self._initOut = cp.copy(self._channel_response) # type: ignore # pylint: disable=attribute-defined-outside-init
|
|
345
|
-
self._row_size = init_object.
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
self.
|
|
349
|
-
"num_aggressors"
|
|
350
|
-
]
|
|
351
|
-
self._sample_interval = ( # pylint: disable=attribute-defined-outside-init
|
|
352
|
-
init_object._init_data[ # pylint: disable=protected-access
|
|
353
|
-
"sample_interval"
|
|
354
|
-
]
|
|
355
|
-
)
|
|
356
|
-
self._bit_time = init_object._init_data[ # pylint: disable=protected-access,attribute-defined-outside-init
|
|
357
|
-
"bit_time"
|
|
358
|
-
]
|
|
351
|
+
self._row_size = init_object.row_size # pylint: disable=attribute-defined-outside-init
|
|
352
|
+
self._num_aggressors = init_object.num_aggressors # pylint: disable=attribute-defined-outside-init
|
|
353
|
+
self._sample_interval = c_double(init_object.sample_interval) # pylint: disable=attribute-defined-outside-init
|
|
354
|
+
self._bit_time = c_double(init_object.bit_time) # pylint: disable=attribute-defined-outside-init
|
|
359
355
|
self._info_params = init_object.info_params # pylint: disable=attribute-defined-outside-init
|
|
360
356
|
|
|
361
357
|
# Check GetWave() consistency if possible.
|
|
@@ -538,10 +534,10 @@ class AMIModel: # pylint: disable=too-many-instance-attributes
|
|
|
538
534
|
Returns:
|
|
539
535
|
Dictionary containing the following keys
|
|
540
536
|
|
|
541
|
-
-
|
|
542
|
-
-
|
|
543
|
-
-
|
|
544
|
-
-
|
|
537
|
+
- ``IMP_RESP_INIT``: The model's impulse response, from its `AMI_Init()` function (V/sample).
|
|
538
|
+
- ``OUT_RESP_INIT``: `imp_resp_init` convolved with the channel.
|
|
539
|
+
- ``IMP_RESP_GETW``: The model's impulse response, from its `AMI_GetWave()` function (V/sample).
|
|
540
|
+
- ``OUT_RESP_GETW``: `imp_resp_getw` convolved with the channel.
|
|
545
541
|
|
|
546
542
|
Notes:
|
|
547
543
|
1. If either set of keys (i.e. - "..._init" or "..._getw")
|
|
@@ -571,8 +567,8 @@ class AMIModel: # pylint: disable=too-many-instance-attributes
|
|
|
571
567
|
ignore_bits = info_params["Ignore_Bits"].pvalue
|
|
572
568
|
|
|
573
569
|
# Capture/convert instance variables.
|
|
574
|
-
chnl_imp = np.array(self.channel_response) * ts
|
|
575
|
-
out_imp = np.array(self.initOut) * ts
|
|
570
|
+
chnl_imp = np.array(self.channel_response[:self.row_size]) * ts # input (a.k.a. - "channel") impulse response (V/sample)
|
|
571
|
+
out_imp = np.array(self.initOut[:self.row_size]) * ts # output impulse response (V/sample)
|
|
576
572
|
|
|
577
573
|
# Calculate some needed intermediate values.
|
|
578
574
|
nspui = int(ui / ts) # samps per UI
|
|
@@ -367,7 +367,8 @@ integ = lexeme(regex(r"[-+]?[0-9]+"))
|
|
|
367
367
|
nat = lexeme(regex(r"[0-9]+"))
|
|
368
368
|
# tap_ix = (integ << whitespace).parsecmap(int2tap) # Doesn't work!
|
|
369
369
|
# tap_ix = integ.parsecmap(int2tap) # Breaks parsing of node names that begin with a numeral!
|
|
370
|
-
tap_ix = integ.parsecmap(int2tap) << whitespace
|
|
370
|
+
# tap_ix = integ.parsecmap(int2tap) << whitespace # This fails; I don't know why.
|
|
371
|
+
tap_ix = lexeme(integ.parsecmap(int2tap)) # This works, as an alternative to the line above.
|
|
371
372
|
symbol = lexeme(regex(r"[0-9a-zA-Z_][^\s()]*"))
|
|
372
373
|
true = lexeme(string("True")).result(True)
|
|
373
374
|
false = lexeme(string("False")).result(False)
|
|
@@ -285,8 +285,13 @@ class Model(HasTraits): # pylint: disable=too-many-instance-attributes
|
|
|
285
285
|
|
|
286
286
|
self._exec32Wins, self._exec32Lins = [], []
|
|
287
287
|
self._exec64Wins, self._exec64Lins = [], []
|
|
288
|
+
self._test_configs = {}
|
|
289
|
+
self._executables = []
|
|
288
290
|
if "algorithmic_model" in subDict:
|
|
289
|
-
|
|
291
|
+
algo_model_data = subDict["algorithmic_model"]
|
|
292
|
+
execs = algo_model_data.get("executables", [])
|
|
293
|
+
self._test_configs = algo_model_data.get("test_configs", {})
|
|
294
|
+
self._executables = execs
|
|
290
295
|
exec64s, exec32s = partition(is64, execs)
|
|
291
296
|
self._exec32Wins, self._exec32Lins = splitExecs(exec32s)
|
|
292
297
|
self._exec64Wins, self._exec64Lins = splitExecs(exec64s)
|
|
@@ -402,3 +407,13 @@ class Model(HasTraits): # pylint: disable=too-many-instance-attributes
|
|
|
402
407
|
"32-bit": {"lin": self._exec32Lins, "win": self._exec32Wins},
|
|
403
408
|
"64-bit": {"lin": self._exec64Lins, "win": self._exec64Wins}
|
|
404
409
|
}
|
|
410
|
+
|
|
411
|
+
@property
|
|
412
|
+
def test_configs(self) -> dict:
|
|
413
|
+
"Named [AMI Test Configuration] blocks from the IBIS file."
|
|
414
|
+
return self._test_configs
|
|
415
|
+
|
|
416
|
+
@property
|
|
417
|
+
def executables(self) -> list:
|
|
418
|
+
"Raw ordered list of Executable entries from [Algorithmic Model], for executable_index lookup."
|
|
419
|
+
return self._executables
|
|
@@ -106,6 +106,8 @@ def rest_line() -> GenParser[str]: # type: ignore
|
|
|
106
106
|
skip_line: Parser = lexeme(rest_line).result("(Skipped.)")
|
|
107
107
|
name_only: Parser = regex(r"[_a-zA-Z0-9/\.()#-]+")
|
|
108
108
|
name: Parser = word(name_only)
|
|
109
|
+
# Parameters must begin with a letter in column 1.
|
|
110
|
+
param_name: Parser = word(regex(r"^[a-zA-Z]\w*", re.MULTILINE))
|
|
109
111
|
symbol: Parser = lexeme(regex(r"[a-zA-Z_][^\s()\[\]]*"))
|
|
110
112
|
true: Parser = lexeme(string("True")).result(True)
|
|
111
113
|
false: Parser = lexeme(string("False")).result(False)
|
|
@@ -187,6 +189,31 @@ ex_line: Parser = (
|
|
|
187
189
|
)
|
|
188
190
|
|
|
189
191
|
|
|
192
|
+
@generate("[AMI Test Configuration] subparam")
|
|
193
|
+
def ami_tc_param() -> GenParser[tuple[str, str]]:
|
|
194
|
+
"Parse a single [AMI Test Configuration] subparameter line."
|
|
195
|
+
pname = yield param_name
|
|
196
|
+
pval = yield rest_line
|
|
197
|
+
return (pname.lower(), pval.strip())
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
@generate("[AMI Test Configuration]")
|
|
201
|
+
def ami_test_config() -> GenParser[tuple[str, dict[str, str]]]:
|
|
202
|
+
"Parse [AMI Test Configuration] block (name + subparameters)."
|
|
203
|
+
cfg_name = yield rest_line
|
|
204
|
+
params = yield many(ami_tc_param)
|
|
205
|
+
return (cfg_name.strip(), dict(params))
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@generate("[Algorithmic Model]")
|
|
209
|
+
def algo_model() -> GenParser[dict]:
|
|
210
|
+
"Parse [Algorithmic Model]: Executable lines then optional [AMI Test Configuration] blocks."
|
|
211
|
+
execs = yield many1(ex_line)
|
|
212
|
+
cfg_pairs = yield many(keyword("ami_test_configuration") >> ami_test_config)
|
|
213
|
+
yield keyword("end_algorithmic_model")
|
|
214
|
+
return {"executables": execs, "test_configs": dict(cfg_pairs)}
|
|
215
|
+
|
|
216
|
+
|
|
190
217
|
def manyTrue(p: Parser) -> Parser:
|
|
191
218
|
"Run a parser multiple times, filtering ``False`` results."
|
|
192
219
|
|
|
@@ -271,8 +298,7 @@ model_type = reduce(try_choice, model_type_parsers)
|
|
|
271
298
|
@generate("IBIS parameter")
|
|
272
299
|
def param() -> GenParser[tuple[str, Any]]:
|
|
273
300
|
"Parse IBIS parameter."
|
|
274
|
-
|
|
275
|
-
pname = yield word(regex(r"^[a-zA-Z]\w*", re.MULTILINE))
|
|
301
|
+
pname = yield param_name
|
|
276
302
|
if DEBUG:
|
|
277
303
|
print(f"Parsing parameter {pname}...", end="", flush=True)
|
|
278
304
|
match pname: # Handle special cases.
|
|
@@ -370,7 +396,7 @@ Model_keywords: dict[str, Parser] = {
|
|
|
370
396
|
"pulldown": many1(vi_line),
|
|
371
397
|
"pullup": many1(vi_line),
|
|
372
398
|
"ramp": ramp,
|
|
373
|
-
"algorithmic_model":
|
|
399
|
+
"algorithmic_model": algo_model,
|
|
374
400
|
"voltage_range": typminmax,
|
|
375
401
|
"temperature_range": typminmax,
|
|
376
402
|
"gnd_clamp": many1(vi_line),
|