cocotb 1.9.2__cp311-cp311-win32.whl → 2.0.0rc2__cp311-cp311-win32.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.
Potentially problematic release.
This version of cocotb might be problematic. Click here for more details.
- cocotb/_ANSI.py +65 -0
- cocotb/__init__.py +81 -327
- cocotb/_base_triggers.py +515 -0
- cocotb/_bridge.py +186 -0
- cocotb/_decorators.py +515 -0
- cocotb/_deprecation.py +3 -3
- cocotb/_exceptions.py +7 -0
- cocotb/_extended_awaitables.py +419 -0
- cocotb/_gpi_triggers.py +385 -0
- cocotb/_init.py +301 -0
- cocotb/_outcomes.py +54 -0
- cocotb/_profiling.py +46 -0
- cocotb/_py_compat.py +114 -29
- cocotb/_scheduler.py +448 -0
- cocotb/_test.py +248 -0
- cocotb/_test_factory.py +312 -0
- cocotb/_test_functions.py +42 -0
- cocotb/_typing.py +7 -0
- cocotb/_utils.py +274 -0
- cocotb/_version.py +3 -7
- cocotb/_xunit_reporter.py +66 -0
- cocotb/clock.py +353 -108
- cocotb/debug.py +24 -0
- cocotb/handle.py +1370 -793
- cocotb/libs/cocotb.dll +0 -0
- cocotb/libs/cocotb.exp +0 -0
- cocotb/libs/cocotb.lib +0 -0
- cocotb/libs/cocotbfli_modelsim.dll +0 -0
- cocotb/libs/cocotbfli_modelsim.exp +0 -0
- cocotb/libs/cocotbfli_modelsim.lib +0 -0
- cocotb/libs/cocotbutils.dll +0 -0
- cocotb/libs/cocotbutils.exp +0 -0
- cocotb/libs/cocotbutils.lib +0 -0
- cocotb/libs/cocotbvhpi_aldec.dll +0 -0
- cocotb/libs/cocotbvhpi_aldec.exp +0 -0
- cocotb/libs/cocotbvhpi_aldec.lib +0 -0
- cocotb/libs/cocotbvhpi_modelsim.dll +0 -0
- cocotb/libs/cocotbvhpi_modelsim.exp +0 -0
- cocotb/libs/cocotbvhpi_modelsim.lib +0 -0
- cocotb/libs/cocotbvpi_aldec.dll +0 -0
- cocotb/libs/cocotbvpi_aldec.exp +0 -0
- cocotb/libs/cocotbvpi_aldec.lib +0 -0
- cocotb/libs/cocotbvpi_ghdl.dll +0 -0
- cocotb/libs/cocotbvpi_ghdl.exp +0 -0
- cocotb/libs/cocotbvpi_ghdl.lib +0 -0
- cocotb/libs/cocotbvpi_icarus.exp +0 -0
- cocotb/libs/cocotbvpi_icarus.lib +0 -0
- cocotb/libs/cocotbvpi_icarus.vpl +0 -0
- cocotb/libs/cocotbvpi_modelsim.dll +0 -0
- cocotb/libs/cocotbvpi_modelsim.exp +0 -0
- cocotb/libs/cocotbvpi_modelsim.lib +0 -0
- cocotb/libs/embed.dll +0 -0
- cocotb/libs/embed.exp +0 -0
- cocotb/libs/embed.lib +0 -0
- cocotb/libs/gpi.dll +0 -0
- cocotb/libs/gpi.exp +0 -0
- cocotb/libs/gpi.lib +0 -0
- cocotb/libs/gpilog.dll +0 -0
- cocotb/libs/gpilog.exp +0 -0
- cocotb/libs/gpilog.lib +0 -0
- cocotb/libs/pygpilog.dll +0 -0
- cocotb/libs/pygpilog.exp +0 -0
- cocotb/libs/pygpilog.lib +0 -0
- cocotb/logging.py +424 -0
- cocotb/queue.py +103 -57
- cocotb/regression.py +680 -717
- cocotb/result.py +17 -188
- cocotb/share/def/aldec.exp +0 -0
- cocotb/share/def/aldec.lib +0 -0
- cocotb/share/def/ghdl.exp +0 -0
- cocotb/share/def/ghdl.lib +0 -0
- cocotb/share/def/icarus.exp +0 -0
- cocotb/share/def/icarus.lib +0 -0
- cocotb/share/def/modelsim.def +1 -0
- cocotb/share/def/modelsim.exp +0 -0
- cocotb/share/def/modelsim.lib +0 -0
- cocotb/share/include/cocotb_utils.h +9 -32
- cocotb/share/include/embed.h +7 -30
- cocotb/share/include/gpi.h +331 -137
- cocotb/share/include/gpi_logging.h +221 -142
- cocotb/share/include/py_gpi_logging.h +8 -5
- cocotb/share/include/vpi_user_ext.h +4 -26
- cocotb/share/lib/verilator/verilator.cpp +80 -67
- cocotb/simtime.py +230 -0
- cocotb/simulator.cp311-win32.exp +0 -0
- cocotb/simulator.cp311-win32.lib +0 -0
- cocotb/simulator.cp311-win32.pyd +0 -0
- cocotb/simulator.pyi +107 -0
- cocotb/task.py +478 -213
- cocotb/triggers.py +55 -1092
- cocotb/types/__init__.py +28 -47
- cocotb/types/_abstract_array.py +151 -0
- cocotb/types/_array.py +295 -0
- cocotb/types/_indexing.py +17 -0
- cocotb/types/_logic.py +333 -0
- cocotb/types/_logic_array.py +868 -0
- cocotb/types/{range.py → _range.py} +47 -48
- cocotb/types/_resolve.py +76 -0
- cocotb/utils.py +58 -646
- cocotb-2.0.0rc2.dist-info/METADATA +60 -0
- cocotb-2.0.0rc2.dist-info/RECORD +146 -0
- {cocotb-1.9.2.dist-info → cocotb-2.0.0rc2.dist-info}/WHEEL +1 -1
- cocotb-2.0.0rc2.dist-info/entry_points.txt +2 -0
- {cocotb-1.9.2.dist-info → cocotb-2.0.0rc2.dist-info/licenses}/LICENSE +1 -0
- {cocotb-1.9.2.dist-info → cocotb-2.0.0rc2.dist-info}/top_level.txt +1 -0
- cocotb_tools/__init__.py +0 -0
- cocotb_tools/_coverage.py +33 -0
- cocotb_tools/_vendor/__init__.py +3 -0
- cocotb_tools/check_results.py +65 -0
- cocotb_tools/combine_results.py +152 -0
- cocotb_tools/config.py +241 -0
- {cocotb → cocotb_tools}/ipython_support.py +29 -22
- cocotb_tools/makefiles/Makefile.deprecations +27 -0
- {cocotb/share → cocotb_tools}/makefiles/Makefile.inc +77 -55
- {cocotb/share → cocotb_tools}/makefiles/Makefile.sim +16 -33
- {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.activehdl +9 -16
- cocotb_tools/makefiles/simulators/Makefile.cvc +61 -0
- cocotb_tools/makefiles/simulators/Makefile.dsim +39 -0
- {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.ghdl +13 -42
- cocotb_tools/makefiles/simulators/Makefile.icarus +80 -0
- cocotb_tools/makefiles/simulators/Makefile.ius +93 -0
- cocotb_tools/makefiles/simulators/Makefile.modelsim +9 -0
- cocotb_tools/makefiles/simulators/Makefile.nvc +60 -0
- cocotb_tools/makefiles/simulators/Makefile.questa +29 -0
- cocotb/share/makefiles/simulators/Makefile.questa → cocotb_tools/makefiles/simulators/Makefile.questa-compat +26 -54
- cocotb_tools/makefiles/simulators/Makefile.questa-qisqrun +149 -0
- {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.riviera +17 -56
- cocotb_tools/makefiles/simulators/Makefile.vcs +65 -0
- {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.verilator +15 -22
- {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.xcelium +20 -52
- cocotb_tools/py.typed +0 -0
- cocotb_tools/runner.py +1868 -0
- cocotb/_sim_versions.py → cocotb_tools/sim_versions.py +16 -21
- pygpi/entry.py +34 -18
- pygpi/py.typed +0 -0
- cocotb/ANSI.py +0 -92
- cocotb/binary.py +0 -858
- cocotb/config.py +0 -289
- cocotb/decorators.py +0 -332
- cocotb/log.py +0 -303
- cocotb/memdebug.py +0 -35
- cocotb/outcomes.py +0 -56
- cocotb/runner.py +0 -1400
- cocotb/scheduler.py +0 -1099
- cocotb/share/makefiles/Makefile.deprecations +0 -12
- cocotb/share/makefiles/simulators/Makefile.cvc +0 -94
- cocotb/share/makefiles/simulators/Makefile.icarus +0 -111
- cocotb/share/makefiles/simulators/Makefile.ius +0 -125
- cocotb/share/makefiles/simulators/Makefile.modelsim +0 -32
- cocotb/share/makefiles/simulators/Makefile.nvc +0 -64
- cocotb/share/makefiles/simulators/Makefile.vcs +0 -98
- cocotb/types/array.py +0 -309
- cocotb/types/logic.py +0 -292
- cocotb/types/logic_array.py +0 -298
- cocotb/wavedrom.py +0 -199
- cocotb/xunit_reporter.py +0 -80
- cocotb-1.9.2.dist-info/METADATA +0 -168
- cocotb-1.9.2.dist-info/RECORD +0 -121
- cocotb-1.9.2.dist-info/entry_points.txt +0 -2
- /cocotb/{_vendor/__init__.py → py.typed} +0 -0
- {cocotb → cocotb_tools}/_vendor/distutils_version.py +0 -0
cocotb/binary.py
DELETED
|
@@ -1,858 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
|
|
3
|
-
# Copyright (c) 2013 Potential Ventures Ltd
|
|
4
|
-
# Copyright (c) 2013 SolarFlare Communications Inc
|
|
5
|
-
# All rights reserved.
|
|
6
|
-
#
|
|
7
|
-
# Redistribution and use in source and binary forms, with or without
|
|
8
|
-
# modification, are permitted provided that the following conditions are met:
|
|
9
|
-
# * Redistributions of source code must retain the above copyright
|
|
10
|
-
# notice, this list of conditions and the following disclaimer.
|
|
11
|
-
# * Redistributions in binary form must reproduce the above copyright
|
|
12
|
-
# notice, this list of conditions and the following disclaimer in the
|
|
13
|
-
# documentation and/or other materials provided with the distribution.
|
|
14
|
-
# * Neither the name of Potential Ventures Ltd,
|
|
15
|
-
# SolarFlare Communications Inc nor the
|
|
16
|
-
# names of its contributors may be used to endorse or promote products
|
|
17
|
-
# derived from this software without specific prior written permission.
|
|
18
|
-
#
|
|
19
|
-
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
20
|
-
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
21
|
-
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
-
# DISCLAIMED. IN NO EVENT SHALL POTENTIAL VENTURES LTD BE LIABLE FOR ANY
|
|
23
|
-
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
24
|
-
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
25
|
-
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
26
|
-
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
27
|
-
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
28
|
-
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
29
|
-
|
|
30
|
-
import os
|
|
31
|
-
import random
|
|
32
|
-
import re
|
|
33
|
-
import warnings
|
|
34
|
-
from enum import Enum
|
|
35
|
-
|
|
36
|
-
from cocotb._deprecation import deprecated
|
|
37
|
-
|
|
38
|
-
_RESOLVE_TO_0 = "-lL"
|
|
39
|
-
_RESOLVE_TO_1 = "hH"
|
|
40
|
-
_RESOLVE_TO_CHOICE = "xXzZuUwW"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class _ResolveXToValue(Enum):
|
|
44
|
-
VALUE_ERROR = "VALUE_ERROR"
|
|
45
|
-
ZEROS = "ZEROS"
|
|
46
|
-
ONES = "ONES"
|
|
47
|
-
RANDOM = "RANDOM"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def _resolve_x_to_from_env() -> _ResolveXToValue:
|
|
51
|
-
env_value = os.getenv("COCOTB_RESOLVE_X", "VALUE_ERROR")
|
|
52
|
-
try:
|
|
53
|
-
return _ResolveXToValue(env_value)
|
|
54
|
-
except ValueError:
|
|
55
|
-
raise ValueError(
|
|
56
|
-
"The COCOTB_RESOLVE_X environment variable is set to an unknown "
|
|
57
|
-
f"value: {env_value!r}"
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
resolve_x_to = _resolve_x_to_from_env()
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
class _ResolveTable(dict):
|
|
65
|
-
"""Translation table class for resolving binary strings.
|
|
66
|
-
|
|
67
|
-
For use with :func:`str.translate()`, which indexes into table with Unicode ordinals.
|
|
68
|
-
"""
|
|
69
|
-
|
|
70
|
-
def __init__(self):
|
|
71
|
-
self.update({ord("0"): ord("0"), ord("1"): ord("1")})
|
|
72
|
-
self.update({ord(k): ord("0") for k in _RESOLVE_TO_0})
|
|
73
|
-
self.update({ord(k): ord("1") for k in _RESOLVE_TO_1})
|
|
74
|
-
|
|
75
|
-
# Do not resolve if resolve_x_to is not set to one of the supported values
|
|
76
|
-
def no_resolve(key):
|
|
77
|
-
return key
|
|
78
|
-
|
|
79
|
-
self.resolve_x = no_resolve
|
|
80
|
-
|
|
81
|
-
if resolve_x_to == _ResolveXToValue.VALUE_ERROR:
|
|
82
|
-
|
|
83
|
-
def resolve_error(key):
|
|
84
|
-
raise ValueError(
|
|
85
|
-
f"Unresolvable bit in binary string: {chr(key)!r}. "
|
|
86
|
-
"Set the COCOTB_RESOLVE_X environment variable to "
|
|
87
|
-
"configure how special values are resolved."
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
self.resolve_x = resolve_error
|
|
91
|
-
elif resolve_x_to == _ResolveXToValue.ZEROS:
|
|
92
|
-
self.update({ord(k): ord("0") for k in _RESOLVE_TO_CHOICE})
|
|
93
|
-
elif resolve_x_to == _ResolveXToValue.ONES:
|
|
94
|
-
self.update({ord(k): ord("1") for k in _RESOLVE_TO_CHOICE})
|
|
95
|
-
elif resolve_x_to == _ResolveXToValue.RANDOM:
|
|
96
|
-
|
|
97
|
-
def resolve_random(key):
|
|
98
|
-
# convert to correct Unicode ordinal:
|
|
99
|
-
# ord('0') = 48
|
|
100
|
-
# ord('1') = 49
|
|
101
|
-
return random.getrandbits(1) + 48
|
|
102
|
-
|
|
103
|
-
self.resolve_x = resolve_random
|
|
104
|
-
|
|
105
|
-
self._resolve_to_choice = {ord(c) for c in _RESOLVE_TO_CHOICE}
|
|
106
|
-
|
|
107
|
-
def __missing__(self, key):
|
|
108
|
-
if key in self._resolve_to_choice:
|
|
109
|
-
return self.resolve_x(key)
|
|
110
|
-
else:
|
|
111
|
-
return key
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
_resolve_table = _ResolveTable()
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
def resolve(string):
|
|
118
|
-
return string.translate(_resolve_table)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def _clog2(val):
|
|
122
|
-
if val < 0:
|
|
123
|
-
raise ValueError("_clog2 can't take a negative")
|
|
124
|
-
exp = 0
|
|
125
|
-
while True:
|
|
126
|
-
if (1 << exp) >= val:
|
|
127
|
-
return exp
|
|
128
|
-
exp += 1
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
class BinaryRepresentation: # noqa
|
|
132
|
-
UNSIGNED = 0 #: Unsigned format
|
|
133
|
-
SIGNED_MAGNITUDE = 1 #: Sign and magnitude format
|
|
134
|
-
TWOS_COMPLEMENT = 2 #: Two's complement format
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
class BinaryValue:
|
|
138
|
-
"""Representation of values in binary format.
|
|
139
|
-
|
|
140
|
-
The underlying value can be set or accessed using these aliasing attributes:
|
|
141
|
-
|
|
142
|
-
- :attr:`BinaryValue.integer` is an integer
|
|
143
|
-
- :attr:`BinaryValue.signed_integer` is a signed integer
|
|
144
|
-
- :attr:`BinaryValue.binstr` is a string of ``01xXzZ``
|
|
145
|
-
- :attr:`BinaryValue.buff` is a binary buffer of bytes
|
|
146
|
-
- :attr:`BinaryValue.value` is an integer **deprecated**
|
|
147
|
-
|
|
148
|
-
For example:
|
|
149
|
-
|
|
150
|
-
>>> vec = BinaryValue()
|
|
151
|
-
>>> vec.integer = 42
|
|
152
|
-
>>> print(vec.binstr)
|
|
153
|
-
101010
|
|
154
|
-
>>> print(vec.buff)
|
|
155
|
-
b'*'
|
|
156
|
-
|
|
157
|
-
"""
|
|
158
|
-
|
|
159
|
-
_permitted_chars = _RESOLVE_TO_0 + _RESOLVE_TO_1 + _RESOLVE_TO_CHOICE + "01" # noqa
|
|
160
|
-
|
|
161
|
-
def __init__(
|
|
162
|
-
self,
|
|
163
|
-
value=None,
|
|
164
|
-
n_bits=None,
|
|
165
|
-
bigEndian=True,
|
|
166
|
-
binaryRepresentation=BinaryRepresentation.UNSIGNED,
|
|
167
|
-
bits=None,
|
|
168
|
-
):
|
|
169
|
-
"""
|
|
170
|
-
Args:
|
|
171
|
-
value (str or int or long, optional): Value to assign to the bus.
|
|
172
|
-
n_bits (int, optional): Number of bits to use for the underlying
|
|
173
|
-
binary representation.
|
|
174
|
-
bigEndian (bool, optional): Interpret the binary as big-endian
|
|
175
|
-
when converting to/from a string buffer.
|
|
176
|
-
binaryRepresentation (BinaryRepresentation): The representation
|
|
177
|
-
of the binary value
|
|
178
|
-
(one of :any:`UNSIGNED`, :any:`SIGNED_MAGNITUDE`, :any:`TWOS_COMPLEMENT`).
|
|
179
|
-
Defaults to unsigned representation.
|
|
180
|
-
bits (int, optional): Deprecated: Compatibility wrapper for :attr:`n_bits`.
|
|
181
|
-
"""
|
|
182
|
-
self._str = ""
|
|
183
|
-
self.big_endian = bigEndian
|
|
184
|
-
self.binaryRepresentation = binaryRepresentation
|
|
185
|
-
|
|
186
|
-
# bits is the deprecated name for n_bits, allow its use for
|
|
187
|
-
# backward-compat reasons.
|
|
188
|
-
if bits is not None and n_bits is not None:
|
|
189
|
-
raise TypeError("You cannot use n_bits and bits at the same time.")
|
|
190
|
-
if bits is not None:
|
|
191
|
-
warnings.warn(
|
|
192
|
-
"The bits argument to BinaryValue has been renamed to n_bits",
|
|
193
|
-
DeprecationWarning,
|
|
194
|
-
stacklevel=2,
|
|
195
|
-
)
|
|
196
|
-
n_bits = bits
|
|
197
|
-
|
|
198
|
-
self._n_bits = n_bits
|
|
199
|
-
|
|
200
|
-
self._convert_to = self._convert_to_map[self.binaryRepresentation].__get__(
|
|
201
|
-
self, self.__class__
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
self._convert_from = self._convert_from_map[self.binaryRepresentation].__get__(
|
|
205
|
-
self, self.__class__
|
|
206
|
-
)
|
|
207
|
-
|
|
208
|
-
if value is not None:
|
|
209
|
-
self.assign(value)
|
|
210
|
-
|
|
211
|
-
def assign(self, value):
|
|
212
|
-
"""Decides how best to assign the value to the vector.
|
|
213
|
-
|
|
214
|
-
Picks from the type of its argument whether to set :attr:`integer`,
|
|
215
|
-
:attr:`binstr`, or :attr:`buff`.
|
|
216
|
-
|
|
217
|
-
Args:
|
|
218
|
-
value (str or int or bytes): The value to assign.
|
|
219
|
-
|
|
220
|
-
.. versionchanged:: 1.4
|
|
221
|
-
|
|
222
|
-
This no longer falls back to setting :attr:`buff` if a :class:`str`
|
|
223
|
-
containing any characters that aren't ``0``, ``1``, ``X`` or ``Z``
|
|
224
|
-
is used, since :attr:`buff` now accepts only :class:`bytes`. Instead,
|
|
225
|
-
an error is raised.
|
|
226
|
-
"""
|
|
227
|
-
if isinstance(value, int):
|
|
228
|
-
self.integer = value
|
|
229
|
-
elif isinstance(value, str):
|
|
230
|
-
self.binstr = value
|
|
231
|
-
elif isinstance(value, bytes):
|
|
232
|
-
self.buff = value
|
|
233
|
-
else:
|
|
234
|
-
raise TypeError(
|
|
235
|
-
"value must be int, str, or bytes, not {!r}".format(
|
|
236
|
-
type(value).__qualname__
|
|
237
|
-
)
|
|
238
|
-
)
|
|
239
|
-
|
|
240
|
-
def _convert_to_unsigned(self, x):
|
|
241
|
-
if x == 0:
|
|
242
|
-
return self._adjust_unsigned("")
|
|
243
|
-
x = bin(x)
|
|
244
|
-
if x[0] == "-":
|
|
245
|
-
raise ValueError(
|
|
246
|
-
"Attempt to assigned negative number to unsigned " "BinaryValue"
|
|
247
|
-
)
|
|
248
|
-
return self._adjust_unsigned(x[2:])
|
|
249
|
-
|
|
250
|
-
def _convert_to_signed_mag(self, x):
|
|
251
|
-
if x == 0:
|
|
252
|
-
return self._adjust_unsigned("")
|
|
253
|
-
x = bin(x)
|
|
254
|
-
if x[0] == "-":
|
|
255
|
-
binstr = self._adjust_signed_mag("1" + x[3:])
|
|
256
|
-
else:
|
|
257
|
-
binstr = self._adjust_signed_mag("0" + x[2:])
|
|
258
|
-
if self.big_endian:
|
|
259
|
-
binstr = binstr[::-1]
|
|
260
|
-
return binstr
|
|
261
|
-
|
|
262
|
-
def _convert_to_twos_comp(self, x):
|
|
263
|
-
if x < 0:
|
|
264
|
-
binstr = bin(2 ** (_clog2(abs(x)) + 1) + x)[2:]
|
|
265
|
-
binstr = self._adjust_twos_comp(binstr)
|
|
266
|
-
elif x == 0:
|
|
267
|
-
binstr = self._adjust_twos_comp("")
|
|
268
|
-
else:
|
|
269
|
-
binstr = self._adjust_twos_comp("0" + bin(x)[2:])
|
|
270
|
-
if self.big_endian:
|
|
271
|
-
binstr = binstr[::-1]
|
|
272
|
-
return binstr
|
|
273
|
-
|
|
274
|
-
def _convert_from_unsigned(self, x):
|
|
275
|
-
if not len(x):
|
|
276
|
-
return 0
|
|
277
|
-
return int(x.translate(_resolve_table), 2)
|
|
278
|
-
|
|
279
|
-
def _convert_from_signed_mag(self, x):
|
|
280
|
-
if not len(x):
|
|
281
|
-
return 0
|
|
282
|
-
rv = int(self._str[1:].translate(_resolve_table), 2)
|
|
283
|
-
if self._str[0] == "1":
|
|
284
|
-
rv = rv * -1
|
|
285
|
-
return rv
|
|
286
|
-
|
|
287
|
-
def _convert_from_twos_comp(self, x):
|
|
288
|
-
if not len(x):
|
|
289
|
-
return 0
|
|
290
|
-
if x[0] == "1":
|
|
291
|
-
binstr = x[1:]
|
|
292
|
-
binstr = self._invert(binstr)
|
|
293
|
-
rv = int(binstr, 2) + 1
|
|
294
|
-
rv = rv * -1
|
|
295
|
-
else:
|
|
296
|
-
rv = int(x.translate(_resolve_table), 2)
|
|
297
|
-
return rv
|
|
298
|
-
|
|
299
|
-
_convert_to_map = {
|
|
300
|
-
BinaryRepresentation.UNSIGNED: _convert_to_unsigned,
|
|
301
|
-
BinaryRepresentation.SIGNED_MAGNITUDE: _convert_to_signed_mag,
|
|
302
|
-
BinaryRepresentation.TWOS_COMPLEMENT: _convert_to_twos_comp,
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
_convert_from_map = {
|
|
306
|
-
BinaryRepresentation.UNSIGNED: _convert_from_unsigned,
|
|
307
|
-
BinaryRepresentation.SIGNED_MAGNITUDE: _convert_from_signed_mag,
|
|
308
|
-
BinaryRepresentation.TWOS_COMPLEMENT: _convert_from_twos_comp,
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
_invert_table = str.maketrans({"0": "1", "1": "0"})
|
|
312
|
-
|
|
313
|
-
def _invert(self, x):
|
|
314
|
-
return x.translate(self._invert_table)
|
|
315
|
-
|
|
316
|
-
def _adjust_unsigned(self, x):
|
|
317
|
-
if self._n_bits is None:
|
|
318
|
-
return x
|
|
319
|
-
l = len(x)
|
|
320
|
-
if l <= self._n_bits:
|
|
321
|
-
if self.big_endian:
|
|
322
|
-
rv = x + "0" * (self._n_bits - l)
|
|
323
|
-
else:
|
|
324
|
-
rv = "0" * (self._n_bits - l) + x
|
|
325
|
-
elif l > self._n_bits:
|
|
326
|
-
if self.big_endian:
|
|
327
|
-
rv = x[l - self._n_bits :]
|
|
328
|
-
else:
|
|
329
|
-
rv = x[: l - self._n_bits]
|
|
330
|
-
warnings.warn(
|
|
331
|
-
"{}-bit value requested, truncating value {!r} ({} bits) to {!r}".format(
|
|
332
|
-
self._n_bits, x, l, rv
|
|
333
|
-
),
|
|
334
|
-
category=RuntimeWarning,
|
|
335
|
-
stacklevel=3,
|
|
336
|
-
)
|
|
337
|
-
return rv
|
|
338
|
-
|
|
339
|
-
def _adjust_signed_mag(self, x):
|
|
340
|
-
"""Pad/truncate the bit string to the correct length."""
|
|
341
|
-
if self._n_bits is None:
|
|
342
|
-
return x
|
|
343
|
-
l = len(x)
|
|
344
|
-
if l < self._n_bits:
|
|
345
|
-
if self.big_endian:
|
|
346
|
-
rv = x[:-1] + "0" * (self._n_bits - 1 - l)
|
|
347
|
-
rv = rv + x[-1]
|
|
348
|
-
else:
|
|
349
|
-
rv = "0" * (self._n_bits - 1 - l) + x[1:]
|
|
350
|
-
rv = x[0] + rv
|
|
351
|
-
elif l > self._n_bits:
|
|
352
|
-
if self.big_endian:
|
|
353
|
-
rv = x[l - self._n_bits :]
|
|
354
|
-
else:
|
|
355
|
-
rv = x[: -(l - self._n_bits)]
|
|
356
|
-
warnings.warn(
|
|
357
|
-
"{}-bit value requested, truncating value {!r} ({} bits) to {!r}".format(
|
|
358
|
-
self._n_bits, x, l, rv
|
|
359
|
-
),
|
|
360
|
-
category=RuntimeWarning,
|
|
361
|
-
stacklevel=3,
|
|
362
|
-
)
|
|
363
|
-
else:
|
|
364
|
-
rv = x
|
|
365
|
-
return rv
|
|
366
|
-
|
|
367
|
-
def _adjust_twos_comp(self, x):
|
|
368
|
-
if self._n_bits is None:
|
|
369
|
-
return x
|
|
370
|
-
l = len(x)
|
|
371
|
-
if l == 0:
|
|
372
|
-
rv = x
|
|
373
|
-
elif l < self._n_bits:
|
|
374
|
-
if self.big_endian:
|
|
375
|
-
rv = x + x[-1] * (self._n_bits - l)
|
|
376
|
-
else:
|
|
377
|
-
rv = x[0] * (self._n_bits - l) + x
|
|
378
|
-
elif l > self._n_bits:
|
|
379
|
-
if self.big_endian:
|
|
380
|
-
rv = x[l - self._n_bits :]
|
|
381
|
-
else:
|
|
382
|
-
rv = x[: -(l - self._n_bits)]
|
|
383
|
-
warnings.warn(
|
|
384
|
-
"{}-bit value requested, truncating value {!r} ({} bits) to {!r}".format(
|
|
385
|
-
self._n_bits, x, l, rv
|
|
386
|
-
),
|
|
387
|
-
category=RuntimeWarning,
|
|
388
|
-
stacklevel=3,
|
|
389
|
-
)
|
|
390
|
-
else:
|
|
391
|
-
rv = x
|
|
392
|
-
return rv
|
|
393
|
-
|
|
394
|
-
@property
|
|
395
|
-
def integer(self):
|
|
396
|
-
"""The integer representation of the underlying vector."""
|
|
397
|
-
return self._convert_from(self._str)
|
|
398
|
-
|
|
399
|
-
@integer.setter
|
|
400
|
-
def integer(self, val):
|
|
401
|
-
self._str = self._convert_to(val)
|
|
402
|
-
|
|
403
|
-
@property
|
|
404
|
-
@deprecated("Use `bv.integer` instead.")
|
|
405
|
-
def value(self):
|
|
406
|
-
"""Integer access to the value. **deprecated**"""
|
|
407
|
-
return self.integer
|
|
408
|
-
|
|
409
|
-
@value.setter
|
|
410
|
-
@deprecated("Use `bv.integer` instead.")
|
|
411
|
-
def value(self, val):
|
|
412
|
-
self.integer = val
|
|
413
|
-
|
|
414
|
-
get_value = value.fget
|
|
415
|
-
set_value = value.fset
|
|
416
|
-
|
|
417
|
-
@property
|
|
418
|
-
def signed_integer(self):
|
|
419
|
-
"""The signed integer representation of the underlying vector."""
|
|
420
|
-
ival = int(self._str.translate(_resolve_table), 2)
|
|
421
|
-
bits = len(self._str)
|
|
422
|
-
signbit = 1 << (bits - 1)
|
|
423
|
-
if (ival & signbit) == 0:
|
|
424
|
-
return ival
|
|
425
|
-
else:
|
|
426
|
-
return -1 * (1 + (int(~ival) & (signbit - 1)))
|
|
427
|
-
|
|
428
|
-
@signed_integer.setter
|
|
429
|
-
def signed_integer(self, val):
|
|
430
|
-
self.integer = val
|
|
431
|
-
|
|
432
|
-
get_value_signed = signed_integer.fget
|
|
433
|
-
|
|
434
|
-
@property
|
|
435
|
-
def is_resolvable(self) -> bool:
|
|
436
|
-
"""
|
|
437
|
-
Return whether the value contains only resolvable (i.e. no "unknown") bits.
|
|
438
|
-
|
|
439
|
-
By default the values ``X``, ``Z``, ``U`` and ``W`` are considered unresolvable.
|
|
440
|
-
This can be configured with :envvar:`COCOTB_RESOLVE_X`.
|
|
441
|
-
|
|
442
|
-
This is similar to the SystemVerilog Assertion ``$isunknown`` system function
|
|
443
|
-
or the VHDL function ``is_x`` (with an inverted meaning).
|
|
444
|
-
"""
|
|
445
|
-
return not any(char in self._str for char in _RESOLVE_TO_CHOICE)
|
|
446
|
-
|
|
447
|
-
@property
|
|
448
|
-
def buff(self) -> bytes:
|
|
449
|
-
r"""The value as a binary string buffer.
|
|
450
|
-
|
|
451
|
-
>>> BinaryValue("01000001" + "00101111").buff == b"\x41\x2F"
|
|
452
|
-
True
|
|
453
|
-
|
|
454
|
-
.. versionchanged:: 1.4
|
|
455
|
-
This changed from :class:`str` to :class:`bytes`.
|
|
456
|
-
Note that for older versions used with Python 2 these types were
|
|
457
|
-
indistinguishable.
|
|
458
|
-
"""
|
|
459
|
-
bits = self._str.translate(_resolve_table)
|
|
460
|
-
|
|
461
|
-
if len(bits) % 8:
|
|
462
|
-
bits = "0" * (8 - len(bits) % 8) + bits
|
|
463
|
-
|
|
464
|
-
buff = []
|
|
465
|
-
while bits:
|
|
466
|
-
byte = bits[:8]
|
|
467
|
-
bits = bits[8:]
|
|
468
|
-
val = int(byte, 2)
|
|
469
|
-
if self.big_endian:
|
|
470
|
-
buff += [val]
|
|
471
|
-
else:
|
|
472
|
-
buff = [val] + buff
|
|
473
|
-
return bytes(buff)
|
|
474
|
-
|
|
475
|
-
@buff.setter
|
|
476
|
-
def buff(self, val: bytes):
|
|
477
|
-
if not self.big_endian:
|
|
478
|
-
val = reversed(val)
|
|
479
|
-
self._str = "".join([format(char, "08b") for char in val])
|
|
480
|
-
self._adjust()
|
|
481
|
-
|
|
482
|
-
def _adjust(self):
|
|
483
|
-
"""Pad/truncate the bit string to the correct length."""
|
|
484
|
-
if self._n_bits is None:
|
|
485
|
-
return
|
|
486
|
-
l = len(self._str)
|
|
487
|
-
if l < self._n_bits:
|
|
488
|
-
if self.big_endian:
|
|
489
|
-
self._str = self._str + "0" * (self._n_bits - l)
|
|
490
|
-
else:
|
|
491
|
-
self._str = "0" * (self._n_bits - l) + self._str
|
|
492
|
-
elif l > self._n_bits:
|
|
493
|
-
rv = self._str[l - self._n_bits :]
|
|
494
|
-
warnings.warn(
|
|
495
|
-
"{}-bit value requested, truncating value {!r} ({} bits) to {!r}".format(
|
|
496
|
-
self._n_bits, self._str, l, rv
|
|
497
|
-
),
|
|
498
|
-
category=RuntimeWarning,
|
|
499
|
-
stacklevel=3,
|
|
500
|
-
)
|
|
501
|
-
self._str = rv
|
|
502
|
-
|
|
503
|
-
get_buff = buff.fget
|
|
504
|
-
set_buff = buff.fset
|
|
505
|
-
|
|
506
|
-
@property
|
|
507
|
-
def binstr(self):
|
|
508
|
-
"""The binary representation stored as a string of ``0``, ``1``, and possibly ``x``, ``z``, and other states."""
|
|
509
|
-
return self._str
|
|
510
|
-
|
|
511
|
-
_non_permitted_regex = re.compile(f"[^{_permitted_chars}]")
|
|
512
|
-
|
|
513
|
-
@binstr.setter
|
|
514
|
-
def binstr(self, string):
|
|
515
|
-
match = self._non_permitted_regex.search(string)
|
|
516
|
-
if match:
|
|
517
|
-
raise ValueError(
|
|
518
|
-
"Attempting to assign character %s to a %s"
|
|
519
|
-
% (match.group(), self.__class__.__name__)
|
|
520
|
-
)
|
|
521
|
-
self._str = string
|
|
522
|
-
self._adjust()
|
|
523
|
-
|
|
524
|
-
get_binstr = binstr.fget
|
|
525
|
-
set_binstr = binstr.fset
|
|
526
|
-
|
|
527
|
-
def _set_trusted_binstr(self, string):
|
|
528
|
-
self._str = string
|
|
529
|
-
|
|
530
|
-
@property
|
|
531
|
-
def n_bits(self):
|
|
532
|
-
"""The number of bits of the binary value."""
|
|
533
|
-
return self._n_bits
|
|
534
|
-
|
|
535
|
-
def hex(self):
|
|
536
|
-
try:
|
|
537
|
-
return hex(self.integer)
|
|
538
|
-
except Exception:
|
|
539
|
-
return hex(int(self.binstr, 2))
|
|
540
|
-
|
|
541
|
-
def __le__(self, other):
|
|
542
|
-
self.assign(other)
|
|
543
|
-
|
|
544
|
-
def __str__(self):
|
|
545
|
-
return self.binstr
|
|
546
|
-
|
|
547
|
-
def __repr__(self):
|
|
548
|
-
return self.__str__()
|
|
549
|
-
|
|
550
|
-
def __bool__(self):
|
|
551
|
-
"""Provide boolean testing of a :attr:`binstr`.
|
|
552
|
-
|
|
553
|
-
>>> val = BinaryValue("0000")
|
|
554
|
-
>>> if val: print("True")
|
|
555
|
-
... else: print("False")
|
|
556
|
-
False
|
|
557
|
-
>>> val.integer = 42
|
|
558
|
-
>>> if val: print("True")
|
|
559
|
-
... else: print("False")
|
|
560
|
-
True
|
|
561
|
-
|
|
562
|
-
"""
|
|
563
|
-
for char in self._str:
|
|
564
|
-
if char == "1":
|
|
565
|
-
return True
|
|
566
|
-
return False
|
|
567
|
-
|
|
568
|
-
def __eq__(self, other):
|
|
569
|
-
if isinstance(other, (BinaryValue, LogicArray)):
|
|
570
|
-
return self.binstr == other.binstr
|
|
571
|
-
elif isinstance(other, int):
|
|
572
|
-
try:
|
|
573
|
-
return self.integer == other
|
|
574
|
-
except ValueError:
|
|
575
|
-
return False
|
|
576
|
-
elif isinstance(other, str):
|
|
577
|
-
return self.binstr == other
|
|
578
|
-
elif isinstance(other, Logic):
|
|
579
|
-
return self.binstr == str(other)
|
|
580
|
-
else:
|
|
581
|
-
return NotImplemented
|
|
582
|
-
|
|
583
|
-
def __int__(self):
|
|
584
|
-
return self.integer
|
|
585
|
-
|
|
586
|
-
def __long__(self):
|
|
587
|
-
return self.integer
|
|
588
|
-
|
|
589
|
-
def __add__(self, other):
|
|
590
|
-
return self.integer + int(other)
|
|
591
|
-
|
|
592
|
-
def __iadd__(self, other):
|
|
593
|
-
self.integer = self.integer + int(other)
|
|
594
|
-
return self
|
|
595
|
-
|
|
596
|
-
def __radd__(self, other):
|
|
597
|
-
return self.integer + other
|
|
598
|
-
|
|
599
|
-
def __sub__(self, other):
|
|
600
|
-
return self.integer - int(other)
|
|
601
|
-
|
|
602
|
-
def __isub__(self, other):
|
|
603
|
-
self.integer = self.integer - int(other)
|
|
604
|
-
return self
|
|
605
|
-
|
|
606
|
-
def __rsub__(self, other):
|
|
607
|
-
return other - self.integer
|
|
608
|
-
|
|
609
|
-
def __mul__(self, other):
|
|
610
|
-
return self.integer * int(other)
|
|
611
|
-
|
|
612
|
-
def __imul__(self, other):
|
|
613
|
-
self.integer = self.integer * int(other)
|
|
614
|
-
return self
|
|
615
|
-
|
|
616
|
-
def __rmul__(self, other):
|
|
617
|
-
return self.integer * other
|
|
618
|
-
|
|
619
|
-
def __floordiv__(self, other):
|
|
620
|
-
return self.integer // int(other)
|
|
621
|
-
|
|
622
|
-
def __ifloordiv__(self, other):
|
|
623
|
-
self.integer = self.__floordiv__(other)
|
|
624
|
-
return self
|
|
625
|
-
|
|
626
|
-
def __rfloordiv__(self, other):
|
|
627
|
-
return other // self.integer
|
|
628
|
-
|
|
629
|
-
def __divmod__(self, other):
|
|
630
|
-
return (self.integer // other, self.integer % other)
|
|
631
|
-
|
|
632
|
-
def __rdivmod__(self, other):
|
|
633
|
-
return other // self.integer
|
|
634
|
-
|
|
635
|
-
def __mod__(self, other):
|
|
636
|
-
return self.integer % int(other)
|
|
637
|
-
|
|
638
|
-
def __imod__(self, other):
|
|
639
|
-
self.integer = self.integer % int(other)
|
|
640
|
-
return self
|
|
641
|
-
|
|
642
|
-
def __rmod__(self, other):
|
|
643
|
-
return other % self.integer
|
|
644
|
-
|
|
645
|
-
def __pow__(self, other, modulo=None):
|
|
646
|
-
return pow(self.integer, other)
|
|
647
|
-
|
|
648
|
-
def __ipow__(self, other):
|
|
649
|
-
self.integer = pow(self.integer, other)
|
|
650
|
-
return self
|
|
651
|
-
|
|
652
|
-
def __rpow__(self, other):
|
|
653
|
-
return pow(other, self.integer)
|
|
654
|
-
|
|
655
|
-
def __lshift__(self, other):
|
|
656
|
-
return int(self) << int(other)
|
|
657
|
-
|
|
658
|
-
def __ilshift__(self, other):
|
|
659
|
-
"""Preserves X values"""
|
|
660
|
-
self.binstr = self.binstr[other:] + self.binstr[:other]
|
|
661
|
-
return self
|
|
662
|
-
|
|
663
|
-
def __rlshift__(self, other):
|
|
664
|
-
return other << self.integer
|
|
665
|
-
|
|
666
|
-
def __rshift__(self, other):
|
|
667
|
-
return int(self) >> int(other)
|
|
668
|
-
|
|
669
|
-
def __irshift__(self, other):
|
|
670
|
-
"""Preserves X values"""
|
|
671
|
-
self.binstr = self.binstr[-other:] + self.binstr[:-other]
|
|
672
|
-
return self
|
|
673
|
-
|
|
674
|
-
def __rrshift__(self, other):
|
|
675
|
-
return other >> self.integer
|
|
676
|
-
|
|
677
|
-
def __and__(self, other):
|
|
678
|
-
return self.integer & other
|
|
679
|
-
|
|
680
|
-
def __iand__(self, other):
|
|
681
|
-
self.integer &= other
|
|
682
|
-
return self
|
|
683
|
-
|
|
684
|
-
def __rand__(self, other):
|
|
685
|
-
return self.integer & other
|
|
686
|
-
|
|
687
|
-
def __xor__(self, other):
|
|
688
|
-
return self.integer ^ other
|
|
689
|
-
|
|
690
|
-
def __ixor__(self, other):
|
|
691
|
-
self.integer ^= other
|
|
692
|
-
return self
|
|
693
|
-
|
|
694
|
-
def __rxor__(self, other):
|
|
695
|
-
return self.__xor__(other)
|
|
696
|
-
|
|
697
|
-
def __or__(self, other):
|
|
698
|
-
return self.integer | other
|
|
699
|
-
|
|
700
|
-
def __ior__(self, other):
|
|
701
|
-
self.integer |= other
|
|
702
|
-
return self
|
|
703
|
-
|
|
704
|
-
def __ror__(self, other):
|
|
705
|
-
return self.__or__(other)
|
|
706
|
-
|
|
707
|
-
def __div__(self, other):
|
|
708
|
-
return self.integer / other
|
|
709
|
-
|
|
710
|
-
def __idiv__(self, other):
|
|
711
|
-
self.integer /= other
|
|
712
|
-
return self
|
|
713
|
-
|
|
714
|
-
def __rdiv__(self, other):
|
|
715
|
-
return other / self.integer
|
|
716
|
-
|
|
717
|
-
def __neg__(self):
|
|
718
|
-
return -self.integer
|
|
719
|
-
|
|
720
|
-
def __pos__(self):
|
|
721
|
-
return +self.integer
|
|
722
|
-
|
|
723
|
-
def __abs__(self):
|
|
724
|
-
return abs(self.integer)
|
|
725
|
-
|
|
726
|
-
def __invert__(self):
|
|
727
|
-
"""Preserves X values"""
|
|
728
|
-
return self._invert(self.binstr)
|
|
729
|
-
|
|
730
|
-
def __oct__(self):
|
|
731
|
-
return oct(self.integer)
|
|
732
|
-
|
|
733
|
-
def __hex__(self):
|
|
734
|
-
return hex(self.integer)
|
|
735
|
-
|
|
736
|
-
def __index__(self):
|
|
737
|
-
return self.integer
|
|
738
|
-
|
|
739
|
-
def __len__(self):
|
|
740
|
-
return len(self.binstr)
|
|
741
|
-
|
|
742
|
-
def __getitem__(self, key):
|
|
743
|
-
"""BinaryValue uses Verilog/VHDL style slices as opposed to Python
|
|
744
|
-
style"""
|
|
745
|
-
if isinstance(key, slice):
|
|
746
|
-
first, second = key.start, key.stop
|
|
747
|
-
if self.big_endian:
|
|
748
|
-
if first < 0 or second < 0:
|
|
749
|
-
raise IndexError("BinaryValue does not support negative " "indices")
|
|
750
|
-
if second > self._n_bits - 1:
|
|
751
|
-
raise IndexError("High index greater than number of bits.")
|
|
752
|
-
if first > second:
|
|
753
|
-
raise IndexError(
|
|
754
|
-
"Big Endian indices must be specified " "low to high"
|
|
755
|
-
)
|
|
756
|
-
_binstr = self.binstr[first : (second + 1)]
|
|
757
|
-
else:
|
|
758
|
-
if first < 0 or second < 0:
|
|
759
|
-
raise IndexError("BinaryValue does not support negative " "indices")
|
|
760
|
-
if first > self._n_bits - 1:
|
|
761
|
-
raise IndexError("High index greater than number of bits.")
|
|
762
|
-
if second > first:
|
|
763
|
-
raise IndexError(
|
|
764
|
-
"Litte Endian indices must be specified " "high to low"
|
|
765
|
-
)
|
|
766
|
-
high = self._n_bits - second
|
|
767
|
-
low = self._n_bits - 1 - first
|
|
768
|
-
_binstr = self.binstr[low:high]
|
|
769
|
-
else:
|
|
770
|
-
index = key
|
|
771
|
-
if index > self._n_bits - 1:
|
|
772
|
-
raise IndexError("Index greater than number of bits.")
|
|
773
|
-
if self.big_endian:
|
|
774
|
-
_binstr = self.binstr[index]
|
|
775
|
-
else:
|
|
776
|
-
_binstr = self.binstr[self._n_bits - 1 - index]
|
|
777
|
-
rv = BinaryValue(
|
|
778
|
-
n_bits=len(_binstr),
|
|
779
|
-
bigEndian=self.big_endian,
|
|
780
|
-
binaryRepresentation=self.binaryRepresentation,
|
|
781
|
-
)
|
|
782
|
-
rv.binstr = _binstr
|
|
783
|
-
return rv
|
|
784
|
-
|
|
785
|
-
def __setitem__(self, key, val):
|
|
786
|
-
"""BinaryValue uses Verilog/VHDL style slices as opposed to Python style."""
|
|
787
|
-
if not isinstance(val, str) and not isinstance(val, int):
|
|
788
|
-
raise TypeError("BinaryValue slices only accept string or integer values")
|
|
789
|
-
|
|
790
|
-
# convert integer to string
|
|
791
|
-
if isinstance(val, int):
|
|
792
|
-
if isinstance(key, slice):
|
|
793
|
-
num_slice_bits = abs(key.start - key.stop) + 1
|
|
794
|
-
else:
|
|
795
|
-
num_slice_bits = 1
|
|
796
|
-
if val < 0:
|
|
797
|
-
raise ValueError("Integer must be positive")
|
|
798
|
-
if val >= 2**num_slice_bits:
|
|
799
|
-
raise ValueError(
|
|
800
|
-
"Integer is too large for the specified slice " "length"
|
|
801
|
-
)
|
|
802
|
-
val = "{:0{width}b}".format(val, width=num_slice_bits)
|
|
803
|
-
|
|
804
|
-
if isinstance(key, slice):
|
|
805
|
-
first, second = key.start, key.stop
|
|
806
|
-
|
|
807
|
-
if self.big_endian:
|
|
808
|
-
if first < 0 or second < 0:
|
|
809
|
-
raise IndexError("BinaryValue does not support negative " "indices")
|
|
810
|
-
if second > self._n_bits - 1:
|
|
811
|
-
raise IndexError("High index greater than number of bits.")
|
|
812
|
-
if first > second:
|
|
813
|
-
raise IndexError(
|
|
814
|
-
"Big Endian indices must be specified " "low to high"
|
|
815
|
-
)
|
|
816
|
-
if len(val) > (second + 1 - first):
|
|
817
|
-
raise ValueError("String length must be equal to slice " "length")
|
|
818
|
-
slice_1 = self.binstr[:first]
|
|
819
|
-
slice_2 = self.binstr[second + 1 :]
|
|
820
|
-
self.binstr = slice_1 + val + slice_2
|
|
821
|
-
else:
|
|
822
|
-
if first < 0 or second < 0:
|
|
823
|
-
raise IndexError("BinaryValue does not support negative " "indices")
|
|
824
|
-
if first > self._n_bits - 1:
|
|
825
|
-
raise IndexError("High index greater than number of bits.")
|
|
826
|
-
if second > first:
|
|
827
|
-
raise IndexError(
|
|
828
|
-
"Litte Endian indices must be specified " "high to low"
|
|
829
|
-
)
|
|
830
|
-
high = self._n_bits - second
|
|
831
|
-
low = self._n_bits - 1 - first
|
|
832
|
-
if len(val) > (high - low):
|
|
833
|
-
raise ValueError("String length must be equal to slice " "length")
|
|
834
|
-
slice_1 = self.binstr[:low]
|
|
835
|
-
slice_2 = self.binstr[high:]
|
|
836
|
-
self.binstr = slice_1 + val + slice_2
|
|
837
|
-
else:
|
|
838
|
-
if len(val) != 1:
|
|
839
|
-
raise ValueError("String length must be equal to slice " "length")
|
|
840
|
-
index = key
|
|
841
|
-
if index > self._n_bits - 1:
|
|
842
|
-
raise IndexError("Index greater than number of bits.")
|
|
843
|
-
if self.big_endian:
|
|
844
|
-
self.binstr = self.binstr[:index] + val + self.binstr[index + 1 :]
|
|
845
|
-
else:
|
|
846
|
-
self.binstr = (
|
|
847
|
-
self.binstr[0 : self._n_bits - index - 1]
|
|
848
|
-
+ val
|
|
849
|
-
+ self.binstr[self._n_bits - index : self._n_bits]
|
|
850
|
-
)
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
from cocotb.types import Logic, LogicArray # noqa: E402
|
|
854
|
-
|
|
855
|
-
if __name__ == "__main__":
|
|
856
|
-
import doctest
|
|
857
|
-
|
|
858
|
-
doctest.testmod()
|