cocotb 1.9.2__cp38-cp38-win32.whl → 2.0.0rc2__cp38-cp38-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.

Files changed (161) hide show
  1. cocotb/_ANSI.py +65 -0
  2. cocotb/__init__.py +81 -327
  3. cocotb/_base_triggers.py +515 -0
  4. cocotb/_bridge.py +186 -0
  5. cocotb/_decorators.py +515 -0
  6. cocotb/_deprecation.py +3 -3
  7. cocotb/_exceptions.py +7 -0
  8. cocotb/_extended_awaitables.py +419 -0
  9. cocotb/_gpi_triggers.py +385 -0
  10. cocotb/_init.py +301 -0
  11. cocotb/_outcomes.py +54 -0
  12. cocotb/_profiling.py +46 -0
  13. cocotb/_py_compat.py +114 -29
  14. cocotb/_scheduler.py +448 -0
  15. cocotb/_test.py +248 -0
  16. cocotb/_test_factory.py +312 -0
  17. cocotb/_test_functions.py +42 -0
  18. cocotb/_typing.py +7 -0
  19. cocotb/_utils.py +274 -0
  20. cocotb/_version.py +3 -7
  21. cocotb/_xunit_reporter.py +66 -0
  22. cocotb/clock.py +353 -108
  23. cocotb/debug.py +24 -0
  24. cocotb/handle.py +1370 -793
  25. cocotb/libs/cocotb.dll +0 -0
  26. cocotb/libs/cocotb.exp +0 -0
  27. cocotb/libs/cocotb.lib +0 -0
  28. cocotb/libs/cocotbfli_modelsim.dll +0 -0
  29. cocotb/libs/cocotbfli_modelsim.exp +0 -0
  30. cocotb/libs/cocotbfli_modelsim.lib +0 -0
  31. cocotb/libs/cocotbutils.dll +0 -0
  32. cocotb/libs/cocotbutils.exp +0 -0
  33. cocotb/libs/cocotbutils.lib +0 -0
  34. cocotb/libs/cocotbvhpi_aldec.dll +0 -0
  35. cocotb/libs/cocotbvhpi_aldec.exp +0 -0
  36. cocotb/libs/cocotbvhpi_aldec.lib +0 -0
  37. cocotb/libs/cocotbvhpi_modelsim.dll +0 -0
  38. cocotb/libs/cocotbvhpi_modelsim.exp +0 -0
  39. cocotb/libs/cocotbvhpi_modelsim.lib +0 -0
  40. cocotb/libs/cocotbvpi_aldec.dll +0 -0
  41. cocotb/libs/cocotbvpi_aldec.exp +0 -0
  42. cocotb/libs/cocotbvpi_aldec.lib +0 -0
  43. cocotb/libs/cocotbvpi_ghdl.dll +0 -0
  44. cocotb/libs/cocotbvpi_ghdl.exp +0 -0
  45. cocotb/libs/cocotbvpi_ghdl.lib +0 -0
  46. cocotb/libs/cocotbvpi_icarus.exp +0 -0
  47. cocotb/libs/cocotbvpi_icarus.lib +0 -0
  48. cocotb/libs/cocotbvpi_icarus.vpl +0 -0
  49. cocotb/libs/cocotbvpi_modelsim.dll +0 -0
  50. cocotb/libs/cocotbvpi_modelsim.exp +0 -0
  51. cocotb/libs/cocotbvpi_modelsim.lib +0 -0
  52. cocotb/libs/embed.dll +0 -0
  53. cocotb/libs/embed.exp +0 -0
  54. cocotb/libs/embed.lib +0 -0
  55. cocotb/libs/gpi.dll +0 -0
  56. cocotb/libs/gpi.exp +0 -0
  57. cocotb/libs/gpi.lib +0 -0
  58. cocotb/libs/gpilog.dll +0 -0
  59. cocotb/libs/gpilog.exp +0 -0
  60. cocotb/libs/gpilog.lib +0 -0
  61. cocotb/libs/pygpilog.dll +0 -0
  62. cocotb/libs/pygpilog.exp +0 -0
  63. cocotb/libs/pygpilog.lib +0 -0
  64. cocotb/logging.py +424 -0
  65. cocotb/queue.py +103 -57
  66. cocotb/regression.py +680 -717
  67. cocotb/result.py +17 -188
  68. cocotb/share/def/aldec.exp +0 -0
  69. cocotb/share/def/aldec.lib +0 -0
  70. cocotb/share/def/ghdl.exp +0 -0
  71. cocotb/share/def/ghdl.lib +0 -0
  72. cocotb/share/def/icarus.exp +0 -0
  73. cocotb/share/def/icarus.lib +0 -0
  74. cocotb/share/def/modelsim.def +1 -0
  75. cocotb/share/def/modelsim.exp +0 -0
  76. cocotb/share/def/modelsim.lib +0 -0
  77. cocotb/share/include/cocotb_utils.h +9 -32
  78. cocotb/share/include/embed.h +7 -30
  79. cocotb/share/include/gpi.h +331 -137
  80. cocotb/share/include/gpi_logging.h +221 -142
  81. cocotb/share/include/py_gpi_logging.h +8 -5
  82. cocotb/share/include/vpi_user_ext.h +4 -26
  83. cocotb/share/lib/verilator/verilator.cpp +80 -67
  84. cocotb/simtime.py +230 -0
  85. cocotb/simulator.cp38-win32.exp +0 -0
  86. cocotb/simulator.cp38-win32.lib +0 -0
  87. cocotb/simulator.cp38-win32.pyd +0 -0
  88. cocotb/simulator.pyi +107 -0
  89. cocotb/task.py +478 -213
  90. cocotb/triggers.py +55 -1092
  91. cocotb/types/__init__.py +28 -47
  92. cocotb/types/_abstract_array.py +151 -0
  93. cocotb/types/_array.py +295 -0
  94. cocotb/types/_indexing.py +17 -0
  95. cocotb/types/_logic.py +333 -0
  96. cocotb/types/_logic_array.py +868 -0
  97. cocotb/types/{range.py → _range.py} +47 -48
  98. cocotb/types/_resolve.py +76 -0
  99. cocotb/utils.py +58 -646
  100. {cocotb-1.9.2.dist-info → cocotb-2.0.0rc2.dist-info}/LICENSE +1 -0
  101. cocotb-2.0.0rc2.dist-info/METADATA +46 -0
  102. cocotb-2.0.0rc2.dist-info/RECORD +146 -0
  103. {cocotb-1.9.2.dist-info → cocotb-2.0.0rc2.dist-info}/WHEEL +1 -1
  104. cocotb-2.0.0rc2.dist-info/entry_points.txt +2 -0
  105. {cocotb-1.9.2.dist-info → cocotb-2.0.0rc2.dist-info}/top_level.txt +1 -0
  106. cocotb_tools/__init__.py +0 -0
  107. cocotb_tools/_coverage.py +33 -0
  108. cocotb_tools/_vendor/__init__.py +3 -0
  109. cocotb_tools/check_results.py +65 -0
  110. cocotb_tools/combine_results.py +152 -0
  111. cocotb_tools/config.py +241 -0
  112. {cocotb → cocotb_tools}/ipython_support.py +29 -22
  113. cocotb_tools/makefiles/Makefile.deprecations +27 -0
  114. {cocotb/share → cocotb_tools}/makefiles/Makefile.inc +77 -55
  115. {cocotb/share → cocotb_tools}/makefiles/Makefile.sim +16 -33
  116. {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.activehdl +9 -16
  117. cocotb_tools/makefiles/simulators/Makefile.cvc +61 -0
  118. cocotb_tools/makefiles/simulators/Makefile.dsim +39 -0
  119. {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.ghdl +13 -42
  120. cocotb_tools/makefiles/simulators/Makefile.icarus +80 -0
  121. cocotb_tools/makefiles/simulators/Makefile.ius +93 -0
  122. cocotb_tools/makefiles/simulators/Makefile.modelsim +9 -0
  123. cocotb_tools/makefiles/simulators/Makefile.nvc +60 -0
  124. cocotb_tools/makefiles/simulators/Makefile.questa +29 -0
  125. cocotb/share/makefiles/simulators/Makefile.questa → cocotb_tools/makefiles/simulators/Makefile.questa-compat +26 -54
  126. cocotb_tools/makefiles/simulators/Makefile.questa-qisqrun +149 -0
  127. {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.riviera +17 -56
  128. cocotb_tools/makefiles/simulators/Makefile.vcs +65 -0
  129. {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.verilator +15 -22
  130. {cocotb/share → cocotb_tools}/makefiles/simulators/Makefile.xcelium +20 -52
  131. cocotb_tools/py.typed +0 -0
  132. cocotb_tools/runner.py +1868 -0
  133. cocotb/_sim_versions.py → cocotb_tools/sim_versions.py +16 -21
  134. pygpi/entry.py +34 -18
  135. pygpi/py.typed +0 -0
  136. cocotb/ANSI.py +0 -92
  137. cocotb/binary.py +0 -858
  138. cocotb/config.py +0 -289
  139. cocotb/decorators.py +0 -332
  140. cocotb/log.py +0 -303
  141. cocotb/memdebug.py +0 -35
  142. cocotb/outcomes.py +0 -56
  143. cocotb/runner.py +0 -1400
  144. cocotb/scheduler.py +0 -1099
  145. cocotb/share/makefiles/Makefile.deprecations +0 -12
  146. cocotb/share/makefiles/simulators/Makefile.cvc +0 -94
  147. cocotb/share/makefiles/simulators/Makefile.icarus +0 -111
  148. cocotb/share/makefiles/simulators/Makefile.ius +0 -125
  149. cocotb/share/makefiles/simulators/Makefile.modelsim +0 -32
  150. cocotb/share/makefiles/simulators/Makefile.nvc +0 -64
  151. cocotb/share/makefiles/simulators/Makefile.vcs +0 -98
  152. cocotb/types/array.py +0 -309
  153. cocotb/types/logic.py +0 -292
  154. cocotb/types/logic_array.py +0 -298
  155. cocotb/wavedrom.py +0 -199
  156. cocotb/xunit_reporter.py +0 -80
  157. cocotb-1.9.2.dist-info/METADATA +0 -168
  158. cocotb-1.9.2.dist-info/RECORD +0 -121
  159. cocotb-1.9.2.dist-info/entry_points.txt +0 -2
  160. /cocotb/{_vendor/__init__.py → py.typed} +0 -0
  161. {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()