pyibis-ami 7.1.0__py3-none-any.whl
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-7.1.0.dist-info/LICENSE +8 -0
- pyibis_ami-7.1.0.dist-info/METADATA +134 -0
- pyibis_ami-7.1.0.dist-info/RECORD +26 -0
- pyibis_ami-7.1.0.dist-info/WHEEL +5 -0
- pyibis_ami-7.1.0.dist-info/entry_points.txt +4 -0
- pyibis_ami-7.1.0.dist-info/top_level.txt +1 -0
- pyibisami/IBIS_AMI_Checker.ipynb +1693 -0
- pyibisami/IBIS_AMI_Tester.ipynb +1457 -0
- pyibisami/__init__.py +22 -0
- pyibisami/__main__.py +7 -0
- pyibisami/ami/__init__.py +0 -0
- pyibisami/ami/config.py +297 -0
- pyibisami/ami/generic.ami.em +20 -0
- pyibisami/ami/generic.ibs.em +139 -0
- pyibisami/ami/model.py +596 -0
- pyibisami/ami/parameter.py +375 -0
- pyibisami/ami/parser.py +635 -0
- pyibisami/common.py +40 -0
- pyibisami/ibis/__init__.py +0 -0
- pyibisami/ibis/file.py +325 -0
- pyibisami/ibis/model.py +399 -0
- pyibisami/ibis/parser.py +525 -0
- pyibisami/tools/__init__.py +0 -0
- pyibisami/tools/run_notebook.py +144 -0
- pyibisami/tools/run_tests.py +273 -0
- pyibisami/tools/test_results.xsl +42 -0
pyibisami/__init__.py
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
"""A package of Python modules, used to configure and test IBIS-AMI models.
|
2
|
+
|
3
|
+
.. moduleauthor:: David Banas <capn.freako@gmail.com>
|
4
|
+
|
5
|
+
Original Author: David Banas <capn.freako@gmail.com>
|
6
|
+
|
7
|
+
Original Date: 3 July 2012
|
8
|
+
|
9
|
+
Copyright (c) 2012 by David Banas; All rights reserved World wide.
|
10
|
+
"""
|
11
|
+
|
12
|
+
from importlib.metadata import version as _get_version
|
13
|
+
|
14
|
+
# Set PEP396 version attribute
|
15
|
+
try:
|
16
|
+
__version__ = _get_version("PyIBIS-AMI")
|
17
|
+
except Exception as err: # pylint: disable=broad-exception-caught
|
18
|
+
__version__ = f"{err} (dev)"
|
19
|
+
|
20
|
+
__date__ = "October 12, 2023"
|
21
|
+
__authors__ = "David Banas & David Patterson"
|
22
|
+
__copy__ = "Copyright (c) 2012 David Banas, 2019 David Patterson"
|
pyibisami/__main__.py
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
"""A package of Python modules, used to configure and test IBIS-AMI models."""
|
2
|
+
|
3
|
+
print("pyibisami is a package of sub-modules, and is not directly executable.")
|
4
|
+
print("Perhaps, you meant:")
|
5
|
+
print(" - pyibisami.ami.config")
|
6
|
+
print(" - pyibisami.tools.run_tests")
|
7
|
+
raise RuntimeError("pyibisami is not executable.")
|
File without changes
|
pyibisami/ami/config.py
ADDED
@@ -0,0 +1,297 @@
|
|
1
|
+
#! /usr/bin/env python
|
2
|
+
|
3
|
+
"""IBIS-AMI model source code, AMI file, and IBIS file configuration utility.
|
4
|
+
|
5
|
+
Original author: David Banas
|
6
|
+
|
7
|
+
Original date: February 26, 2016
|
8
|
+
|
9
|
+
Copyright (c) 2016 David Banas; all rights reserved World wide.
|
10
|
+
|
11
|
+
**Note:** The following use model has been deprecated!
|
12
|
+
The preferred approach is to make *executable* model configurators,
|
13
|
+
which draw what they need from this module.
|
14
|
+
|
15
|
+
This script gets called from a makefile, when any of the following need rebuilding:
|
16
|
+
|
17
|
+
* a C++ source code file
|
18
|
+
* a ``*.AMI`` file
|
19
|
+
* a ``*.IBS`` file
|
20
|
+
* a ``*.TST`` file (a dummy place-holder indicating that the test run config. files have been made)
|
21
|
+
|
22
|
+
All files will be rebuilt.
|
23
|
+
(We rebuild all files, because it doesn't take very long, and we can
|
24
|
+
ensure consistency this way.)
|
25
|
+
|
26
|
+
This gets triggered by one of two things:
|
27
|
+
|
28
|
+
#. The common model configuration information has changed, or
|
29
|
+
#. One of the EmPy template files was updated.
|
30
|
+
|
31
|
+
The idea here is that the ``*.IBS`` file, the ``*.AMI`` file, the C++ source file,
|
32
|
+
and the test run configuration files should be configured from a common model
|
33
|
+
configuration file, so as to ensure consistency between them all.
|
34
|
+
"""
|
35
|
+
|
36
|
+
import importlib.util
|
37
|
+
from datetime import date
|
38
|
+
from pathlib import Path
|
39
|
+
from typing import Any, NewType
|
40
|
+
|
41
|
+
import click
|
42
|
+
import em
|
43
|
+
|
44
|
+
ParamDict = NewType("ParamDict", dict[str, Any])
|
45
|
+
NamedParamDict = NewType("NamedParamDict", tuple[str, ParamDict])
|
46
|
+
TestDefinition = NewType("TestDefinition", tuple[str, NamedParamDict, NamedParamDict, str])
|
47
|
+
|
48
|
+
param_types = {
|
49
|
+
"INT": {"c_type": "int", "ami_type": "Integer", "getter": "get_param_int"},
|
50
|
+
"FLOAT": {"c_type": "double", "ami_type": "Float", "getter": "get_param_float"},
|
51
|
+
"TAP": {"c_type": "double", "ami_type": "Tap", "getter": "get_param_float"},
|
52
|
+
"BOOL": {"c_type": "bool", "ami_type": "Boolean", "getter": "get_param_bool"},
|
53
|
+
"STRING": {"c_type": "char *", "ami_type": "String", "getter": "get_param_str"},
|
54
|
+
}
|
55
|
+
|
56
|
+
|
57
|
+
def print_param(indent, name, param): # pylint: disable=too-many-branches
|
58
|
+
"""Print AMI parameter specification. Handle nested parameters, via
|
59
|
+
recursion.
|
60
|
+
|
61
|
+
Args:
|
62
|
+
indent (str): String containing some number of spaces.
|
63
|
+
name (str): Parameter name.
|
64
|
+
param (dict): Dictionary containing parameter definition fields.
|
65
|
+
"""
|
66
|
+
|
67
|
+
print(indent, f"({name}")
|
68
|
+
if "subs" in param:
|
69
|
+
for key in param["subs"]:
|
70
|
+
print_param(indent + " ", key, param["subs"][key])
|
71
|
+
if "description" in param:
|
72
|
+
print(indent + " ", f"(Description {param['description']})")
|
73
|
+
else:
|
74
|
+
for fld_name, fld_key in [
|
75
|
+
("Usage", "usage"),
|
76
|
+
("Type", "type"),
|
77
|
+
("Format", "format"),
|
78
|
+
("Default", "default"),
|
79
|
+
("Description", "description"),
|
80
|
+
]:
|
81
|
+
# Trap the special cases.
|
82
|
+
if fld_name == "Type":
|
83
|
+
print(indent, " (Type", param_types[param["type"]]["ami_type"], ")")
|
84
|
+
elif fld_name == "Default":
|
85
|
+
if param["format"] == "Value":
|
86
|
+
pass
|
87
|
+
elif fld_name == "Format":
|
88
|
+
if param["format"] == "Value":
|
89
|
+
print(indent, " (Value", param["default"], ")")
|
90
|
+
elif param["format"] == "List":
|
91
|
+
print(indent, " (List", end=" ")
|
92
|
+
for item in param["values"]:
|
93
|
+
print(item, end=" ")
|
94
|
+
print(")")
|
95
|
+
print(indent, " (List_Tip", end=" ")
|
96
|
+
for item in param["labels"]:
|
97
|
+
print(item, end=" ")
|
98
|
+
print(")")
|
99
|
+
else:
|
100
|
+
print(indent, f" ({param['format']}", param["default"], param["min"], param["max"], ")")
|
101
|
+
# Execute the default action.
|
102
|
+
else:
|
103
|
+
print(indent, f" ({fld_name}", param[fld_key], ")")
|
104
|
+
print(indent, ")")
|
105
|
+
|
106
|
+
|
107
|
+
def print_code(pname, param):
|
108
|
+
"""Print C++ code needed to query AMI parameter tree for a particular leaf.
|
109
|
+
|
110
|
+
Args:
|
111
|
+
pname (str): Parameter name.
|
112
|
+
param (dict): Dictionary containing parameter definition fields.
|
113
|
+
"""
|
114
|
+
|
115
|
+
print(" ", f'node_names.push_back("{pname}");')
|
116
|
+
if "subs" in param:
|
117
|
+
for key in param["subs"]:
|
118
|
+
print_code(key, param["subs"][key])
|
119
|
+
else:
|
120
|
+
if param["usage"] == "In" or param["usage"] == "InOut":
|
121
|
+
ptype = param["type"]
|
122
|
+
print(f" {param_types[ptype]['c_type']} {pname};")
|
123
|
+
if ptype == "BOOL":
|
124
|
+
print(f" {pname} = {param_types[ptype]['getter']}(node_names, {param['default'].lower()});")
|
125
|
+
else:
|
126
|
+
print(f" {pname} = {param_types[ptype]['getter']}(node_names, {param['default']});")
|
127
|
+
print(" ", "node_names.pop_back();")
|
128
|
+
|
129
|
+
|
130
|
+
def mk_model(
|
131
|
+
ibis_params: ParamDict,
|
132
|
+
ami_params: ParamDict,
|
133
|
+
model_name: str,
|
134
|
+
description: str,
|
135
|
+
out_dir: str = "."
|
136
|
+
) -> None:
|
137
|
+
"""
|
138
|
+
Generate ibis, ami, and cpp files, by merging the
|
139
|
+
device specific parameterization with the templates.
|
140
|
+
|
141
|
+
Args:
|
142
|
+
ibis_params: Dictionary of IBIS model parameter definitions.
|
143
|
+
ami_params: Dictionary of AMI parameter definitions.
|
144
|
+
model_name: Name given to IBIS model.
|
145
|
+
description: Model description.
|
146
|
+
|
147
|
+
Keyword Args:
|
148
|
+
out_dir: Directory in which to place created files.
|
149
|
+
Default: "."
|
150
|
+
"""
|
151
|
+
|
152
|
+
py_file = (Path(out_dir).resolve() / model_name).with_suffix(".py")
|
153
|
+
# Configure the model files.
|
154
|
+
for ext in ["cpp", "ami", "ibs"]:
|
155
|
+
out_file = py_file.with_suffix(f".{ext}")
|
156
|
+
if ext == "ami":
|
157
|
+
em_file = Path(__file__).parent.joinpath("generic.ami.em")
|
158
|
+
elif ext == "ibs":
|
159
|
+
em_file = Path(__file__).parent.joinpath("generic.ibs.em")
|
160
|
+
else:
|
161
|
+
em_file = out_file.with_suffix(".cpp.em")
|
162
|
+
|
163
|
+
print(f"Building '{out_file}' from '{em_file}'...")
|
164
|
+
with open(out_file, "w", encoding="utf-8") as o_file:
|
165
|
+
interpreter = em.Interpreter(
|
166
|
+
output=o_file,
|
167
|
+
globals={
|
168
|
+
"ami_params": ami_params,
|
169
|
+
"ibis_params": ibis_params,
|
170
|
+
"param_types": param_types,
|
171
|
+
"model_name": model_name,
|
172
|
+
"description": description,
|
173
|
+
"date": str(date.today()),
|
174
|
+
},
|
175
|
+
)
|
176
|
+
try:
|
177
|
+
with open(em_file, "rt", encoding="utf-8") as in_file:
|
178
|
+
interpreter.file(in_file)
|
179
|
+
finally:
|
180
|
+
interpreter.shutdown()
|
181
|
+
|
182
|
+
|
183
|
+
def ami_config(py_file):
|
184
|
+
"""
|
185
|
+
Read in ``py_file`` and cpp.em files, then generate: ibis, ami, and cpp files.
|
186
|
+
|
187
|
+
Args:
|
188
|
+
py_file: name of model configuration file (<stem>.py)
|
189
|
+
|
190
|
+
Notes:
|
191
|
+
1. This function is deprecated! Instead, make your model configurator executable
|
192
|
+
and import what you need from this module. This is much cleaner.
|
193
|
+
"""
|
194
|
+
|
195
|
+
file_base_name = Path(py_file).stem
|
196
|
+
|
197
|
+
# Read model configuration information.
|
198
|
+
print(f"Reading model configuration information from file: {py_file}.")
|
199
|
+
spec = importlib.util.spec_from_file_location(file_base_name, py_file)
|
200
|
+
cfg = importlib.util.module_from_spec(spec)
|
201
|
+
spec.loader.exec_module(cfg)
|
202
|
+
|
203
|
+
mk_model(cfg.ibis_params, cfg.ami_params, cfg.kFileBaseName, cfg.kDescription, out_dir=Path(py_file).parent)
|
204
|
+
|
205
|
+
|
206
|
+
def mk_combs(dict_items: list[tuple[str, Any]]) -> list[list[tuple[str, Any]]]:
|
207
|
+
"""
|
208
|
+
Make all combinations possible from a list of dictionary items.
|
209
|
+
|
210
|
+
Args:
|
211
|
+
dict_items: List of dictionary key/value pairs.
|
212
|
+
The values are lists.
|
213
|
+
|
214
|
+
Return:
|
215
|
+
List of all possible combinations of key values.
|
216
|
+
"""
|
217
|
+
if not dict_items:
|
218
|
+
return [
|
219
|
+
[],
|
220
|
+
]
|
221
|
+
head, *tail = dict_items
|
222
|
+
k, vs = head
|
223
|
+
kvals = [(k, v) for v in vs]
|
224
|
+
return [[kval] + rest for kval in kvals for rest in mk_combs(tail)]
|
225
|
+
|
226
|
+
|
227
|
+
def mk_tests( # pylint: disable=too-many-locals
|
228
|
+
test_defs: dict[str, TestDefinition],
|
229
|
+
file_base_name: str,
|
230
|
+
test_dir: str = "test_runs"
|
231
|
+
) -> None:
|
232
|
+
"""
|
233
|
+
Make the test run configuration files.
|
234
|
+
|
235
|
+
Args:
|
236
|
+
test_defs: Dictionary of test sweep definitions.
|
237
|
+
file_base_name: Stem name for test run definition files.
|
238
|
+
|
239
|
+
Keyword Args:
|
240
|
+
test_dir: Directory in which to place the created test run definition files.
|
241
|
+
Default: "test_runs/"
|
242
|
+
"""
|
243
|
+
|
244
|
+
pname = Path(test_dir).resolve()
|
245
|
+
pname.mkdir(exist_ok=True)
|
246
|
+
pname = (pname / file_base_name).resolve()
|
247
|
+
pname.mkdir(exist_ok=True)
|
248
|
+
for fname in test_defs.keys():
|
249
|
+
desc, ami_defs, sim_defs, ref_fstr = test_defs[fname]
|
250
|
+
ami_str, ami_dict = ami_defs
|
251
|
+
sim_str, sim_dict = sim_defs
|
252
|
+
with open((pname / fname).with_suffix(".run"), "w", encoding="utf-8") as f:
|
253
|
+
f.write(desc + "\n")
|
254
|
+
for ami_comb in mk_combs(list(ami_dict.items())):
|
255
|
+
for sim_comb in mk_combs(list(sim_dict.items())):
|
256
|
+
pdict = dict(ami_comb)
|
257
|
+
pdict.update(dict(sim_comb))
|
258
|
+
f.write(f"\n('{ami_str.format(pdict=pdict)}_{sim_str.format(pdict=pdict)}', \\\n")
|
259
|
+
f.write(f" ({{'root_name': '{file_base_name}', \\\n")
|
260
|
+
for k, v in ami_comb:
|
261
|
+
f.write(f" '{k}': {v}, \\\n")
|
262
|
+
f.write(" }, \\\n")
|
263
|
+
if sim_comb:
|
264
|
+
head, *tail = sim_comb
|
265
|
+
k, v = head
|
266
|
+
f.write(f" {{'{k}': {v}, \\\n")
|
267
|
+
for k, v in tail:
|
268
|
+
f.write(f" '{k}': {v}, \\\n")
|
269
|
+
f.write(" } \\\n")
|
270
|
+
f.write(" ), \\\n")
|
271
|
+
if ref_fstr:
|
272
|
+
f.write(f" '{ref_fstr.format(pdict=pdict)}', \\\n")
|
273
|
+
f.write(")\n")
|
274
|
+
|
275
|
+
|
276
|
+
@click.command(context_settings={"help_option_names": ["-h", "--help"]})
|
277
|
+
@click.argument("py_file", type=click.Path(exists=True, resolve_path=True))
|
278
|
+
@click.version_option()
|
279
|
+
def main(py_file):
|
280
|
+
"""
|
281
|
+
Configure IBIS-AMI model C++ source code, IBIS model, and AMI file.
|
282
|
+
This command generates three files based off the input config file.
|
283
|
+
It expects a .cpp.em file to be located in the same directory so that it can
|
284
|
+
generate a cpp file from the config file and template file.
|
285
|
+
|
286
|
+
Args:
|
287
|
+
py_file: name of model configuration file (*.py)
|
288
|
+
|
289
|
+
Notes:
|
290
|
+
1. This command is deprecated! Instead, make your model configurator executable
|
291
|
+
and import what you need from this module. This is much cleaner.
|
292
|
+
"""
|
293
|
+
ami_config(py_file)
|
294
|
+
|
295
|
+
|
296
|
+
if __name__ == "__main__":
|
297
|
+
main() # pylint: disable=no-value-for-parameter
|
@@ -0,0 +1,20 @@
|
|
1
|
+
(@model_name
|
2
|
+
|
3
|
+
(Description "@description")
|
4
|
+
|
5
|
+
@{
|
6
|
+
import sys
|
7
|
+
from pyibisami.ami import config as ac
|
8
|
+
|
9
|
+
for (sec_name, sec_key) in [('Reserved_Parameters', 'reserved'), ('Model_Specific', 'model')]:
|
10
|
+
print(" (%s" % sec_name)
|
11
|
+
for param_name in ami_params[sec_key]:
|
12
|
+
param = ami_params[sec_key][param_name]
|
13
|
+
try:
|
14
|
+
ac.print_param(" ", param_name, param)
|
15
|
+
except Exception as e:
|
16
|
+
e.args += (param_name,)
|
17
|
+
raise
|
18
|
+
print(" )")
|
19
|
+
}
|
20
|
+
)
|
@@ -0,0 +1,139 @@
|
|
1
|
+
@{
|
2
|
+
from numpy import array
|
3
|
+
|
4
|
+
version = ibis_params['version']
|
5
|
+
file_name = ibis_params['file_name']
|
6
|
+
file_rev = ibis_params['file_rev']
|
7
|
+
copyright = ibis_params['copyright']
|
8
|
+
source = ibis_params['source']
|
9
|
+
component = ibis_params['component']
|
10
|
+
manufacturer = ibis_params['manufacturer']
|
11
|
+
r_pkg = ibis_params['r_pkg']
|
12
|
+
l_pkg = ibis_params['l_pkg']
|
13
|
+
c_pkg = ibis_params['c_pkg']
|
14
|
+
model_name = ibis_params['model_name']
|
15
|
+
model_type = ibis_params['model_type']
|
16
|
+
c_comp = ibis_params['c_comp']
|
17
|
+
c_ref = ibis_params['c_ref']
|
18
|
+
v_ref = ibis_params['v_ref']
|
19
|
+
v_meas = ibis_params['v_meas']
|
20
|
+
r_ref = ibis_params['r_ref']
|
21
|
+
temperature_range = ibis_params['temperature_range']
|
22
|
+
voltage_range = ibis_params['voltage_range']
|
23
|
+
impedance = ibis_params['impedance']
|
24
|
+
slew_rate = ibis_params['slew_rate']
|
25
|
+
}
|
26
|
+
|
27
|
+
[IBIS Ver] @(version)
|
28
|
+
[File Name] @(file_name)
|
29
|
+
[File Rev] @(file_rev)
|
30
|
+
|
31
|
+
[Date] @(date)
|
32
|
+
|
33
|
+
[Source] @(source)
|
34
|
+
|
35
|
+
[Disclaimer]
|
36
|
+
THIS MODEL IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
37
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
38
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
39
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
40
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
41
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
42
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
43
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
44
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
45
|
+
OF THIS MODEL, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
46
|
+
|
47
|
+
[Notes]
|
48
|
+
This IBIS file was generated using the template file: "generic.ibs.em".
|
49
|
+
|
50
|
+
[Copyright] @(copyright)
|
51
|
+
[Component] @(component)
|
52
|
+
[Manufacturer] @(manufacturer)
|
53
|
+
|
54
|
+
[Package]
|
55
|
+
|
56
|
+
@{
|
57
|
+
print("R_pkg %5.2f %5.2f %5.2f" % (r_pkg[0], r_pkg[1], r_pkg[2]))
|
58
|
+
print("L_pkg %5.2fn %5.2fn %5.2fn" % (l_pkg[0] * 1.e9, l_pkg[1] * 1.e9, l_pkg[2] * 1.e9))
|
59
|
+
print("C_pkg %5.2fp %5.2fp %5.2fp" % (c_pkg[0] * 1.e12, c_pkg[1] * 1.e12, c_pkg[2] * 1.e12))
|
60
|
+
}
|
61
|
+
|
62
|
+
[Pin] signal_name model_name R_pin L_pin C_pin
|
63
|
+
1p Tx_1_P @(model_name)
|
64
|
+
1n Tx_1_N @(model_name)
|
65
|
+
2p Tx_2_P @(model_name)
|
66
|
+
2n Tx_2_N @(model_name)
|
67
|
+
3p Tx_3_P @(model_name)
|
68
|
+
3n Tx_3_N @(model_name)
|
69
|
+
|
70
|
+
[Diff_Pin] inv_pin vdiff tdelay_typ tdelay_min tdelay_max
|
71
|
+
1p 1n 0.1V NA NA NA
|
72
|
+
2p 2n 0.1V NA NA NA
|
73
|
+
3p 3n 0.1V NA NA NA
|
74
|
+
|
75
|
+
[Model] @(model_name)
|
76
|
+
Model_type @(model_type)
|
77
|
+
|
78
|
+
@{
|
79
|
+
print("C_comp %5.2fp %5.2fp %5.2fp" % (c_comp[0] * 1.e12, c_comp[1] * 1.e12, c_comp[2] * 1.e12))
|
80
|
+
if(model_type == 'Output'):
|
81
|
+
print("Cref = {}".format(c_ref))
|
82
|
+
print("Vref = {}".format(v_ref))
|
83
|
+
print("Vmeas = {}".format(v_meas))
|
84
|
+
print("Rref = {}".format(r_ref))
|
85
|
+
else:
|
86
|
+
print("Vinl = {}".format(voltage_range[0] / 2. - 0.025))
|
87
|
+
print("Vinh = {}".format(voltage_range[0] / 2. + 0.025))
|
88
|
+
}
|
89
|
+
|
90
|
+
[Algorithmic Model]
|
91
|
+
Executable linux_gcc4.1.2_32 @(model_name)_x86.so @(model_name).ami
|
92
|
+
Executable linux_gcc4.1.2_64 @(model_name)_x86_amd64.so @(model_name).ami
|
93
|
+
Executable Windows_VisualStudio_32 @(model_name)_x86.dll @(model_name).ami
|
94
|
+
Executable Windows_VisualStudio_64 @(model_name)_x86_amd64.dll @(model_name).ami
|
95
|
+
[End Algorithmic Model]
|
96
|
+
|
97
|
+
@{
|
98
|
+
print("[Temperature_Range] %5.1f %5.1f %5.1f" % (temperature_range[0], temperature_range[1], temperature_range[2]))
|
99
|
+
print("[Voltage_Range] %5.2f %5.2f %5.2f" % (voltage_range[0], voltage_range[1], voltage_range[2]))
|
100
|
+
}
|
101
|
+
|
102
|
+
@{
|
103
|
+
if(model_type == 'Output'):
|
104
|
+
print("[Pulldown]")
|
105
|
+
print("%-5.2f %-10.3e %-10.3e %-10.3e" % (-1. * voltage_range[0], -10., -10., -10.))
|
106
|
+
for v in [k * voltage_range[0] for k in range(2)]:
|
107
|
+
i = v / array(impedance)
|
108
|
+
print("%-5.2f %-10.3e %-10.3e %-10.3e" % (v, i[0], i[1], i[2]))
|
109
|
+
print("%-5.2f %-10.3e %-10.3e %-10.3e" % (2. * voltage_range[0], 10., 10., 10.))
|
110
|
+
|
111
|
+
print("[Pullup]")
|
112
|
+
print("%-5.2f %-10.3e %-10.3e %-10.3e" % (-1. * voltage_range[0], 10., 10., 10.))
|
113
|
+
for v in [k * voltage_range[0] for k in range(2)]:
|
114
|
+
i = -1. * v / array(impedance)
|
115
|
+
print("%-5.2f %-10.3e %-10.3e %-10.3e" % (v, i[0], i[1], i[2]))
|
116
|
+
print("%-5.2f %-10.3e %-10.3e %-10.3e" % (2. * voltage_range[0], -10., -10., -10.))
|
117
|
+
|
118
|
+
print("[Ramp]")
|
119
|
+
dv = 0.6 * array([v * 50. / (50. + z) for (v, z) in zip(voltage_range, impedance)])
|
120
|
+
dt = 1.e12 * dv / array(slew_rate)
|
121
|
+
print("dV/dt_r %5.3f/%5.2fp %5.3f/%5.2fp %5.3f/%5.2fp" % (dv[0], dt[0], dv[1], dt[1], dv[2], dt[2]))
|
122
|
+
print("dV/dt_f %5.3f/%5.2fp %5.3f/%5.2fp %5.3f/%5.2fp" % (dv[0], dt[0], dv[1], dt[1], dv[2], dt[2]))
|
123
|
+
print("")
|
124
|
+
else:
|
125
|
+
print("[GND Clamp]")
|
126
|
+
print("%-5.2f %-10.3e %-10.3e %-10.3e" % (-1. * voltage_range[0], -10., -10., -10.))
|
127
|
+
for v in [k * voltage_range[0] for k in range(3)]:
|
128
|
+
i = v / array(impedance) / 2
|
129
|
+
print("%-5.2f %-10.3e %-10.3e %-10.3e" % (v, i[0], i[1], i[2]))
|
130
|
+
print("")
|
131
|
+
print("[Power Clamp]")
|
132
|
+
print("%-5.2f %-10.3e %-10.3e %-10.3e" % (-1. * voltage_range[0], 10., 10., 10.))
|
133
|
+
for v in [k * voltage_range[0] for k in range(3)]:
|
134
|
+
i = v / array(impedance) / 2
|
135
|
+
print("%-5.2f %-10.3e %-10.3e %-10.3e" % (v, -i[0], -i[1], -i[2]))
|
136
|
+
print("")
|
137
|
+
}
|
138
|
+
|
139
|
+
[END]
|