cocotb 1.9.2__cp310-cp310-win_amd64.whl → 2.0.0rc2__cp310-cp310-win_amd64.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.cp310-win_amd64.exp +0 -0
  86. cocotb/simulator.cp310-win_amd64.lib +0 -0
  87. cocotb/simulator.cp310-win_amd64.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-2.0.0rc2.dist-info/METADATA +60 -0
  101. cocotb-2.0.0rc2.dist-info/RECORD +146 -0
  102. {cocotb-1.9.2.dist-info → cocotb-2.0.0rc2.dist-info}/WHEEL +1 -1
  103. cocotb-2.0.0rc2.dist-info/entry_points.txt +2 -0
  104. {cocotb-1.9.2.dist-info → cocotb-2.0.0rc2.dist-info/licenses}/LICENSE +1 -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
@@ -1,298 +0,0 @@
1
- # Copyright cocotb contributors
2
- # Licensed under the Revised BSD License, see LICENSE for details.
3
- # SPDX-License-Identifier: BSD-3-Clause
4
- import typing
5
-
6
- from cocotb.binary import BinaryRepresentation, BinaryValue
7
- from cocotb.types.array import Array
8
- from cocotb.types.logic import Logic, LogicConstructibleT
9
- from cocotb.types.range import Range
10
-
11
- LogicT = typing.TypeVar("LogicT", bound=Logic)
12
- S = typing.TypeVar("S")
13
- Self = typing.TypeVar("Self", bound="LogicArray")
14
-
15
-
16
- class LogicArray(Array[Logic]):
17
- r"""
18
- Fixed-sized, arbitrarily-indexed, array of :class:`cocotb.types.Logic`.
19
-
20
- .. currentmodule:: cocotb.types
21
-
22
- :class:`LogicArray`\ s can be constructed from either iterables of values
23
- constructible into :class:`Logic`: like :class:`bool`, :class:`str`, :class:`int`;
24
- or from integers.
25
- If constructed from a positive integer, an unsigned bit representation is used to
26
- construct the :class:`LogicArray`.
27
- If constructed from a negative integer, a two's complement bit representation is
28
- used.
29
- Like :class:`Array`, if no *range* argument is given, it is deduced from the length
30
- of the iterable or bit string used to initialize the variable.
31
- If a *range* argument is given, but no value,
32
- the array is filled with the default value of Logic().
33
-
34
- .. code-block:: python3
35
-
36
- >>> LogicArray("01XZ")
37
- LogicArray('01XZ', Range(3, 'downto', 0))
38
-
39
- >>> LogicArray([0, True, "X"])
40
- LogicArray('01X', Range(2, 'downto', 0))
41
-
42
- >>> LogicArray(0xA) # picks smallest range that can fit the value
43
- LogicArray('1010', Range(3, 'downto', 0))
44
-
45
- >>> LogicArray(-4, Range(0, "to", 3)) # will sign-extend
46
- LogicArray('1100', Range(0, 'to', 3))
47
-
48
- >>> LogicArray(range=Range(0, "to", 3)) # default values
49
- LogicArray('XXXX', Range(0, 'to', 3))
50
-
51
- :class:`LogicArray`\ s support the same operations as :class:`Array`;
52
- however, it enforces the condition that all elements must be a :class:`Logic`.
53
-
54
- .. code-block:: python3
55
-
56
- >>> la = LogicArray("1010")
57
- >>> la[0] # is indexable
58
- Logic('0')
59
-
60
- >>> la[1:] # is slice-able
61
- LogicArray('10', Range(1, 'downto', 0))
62
-
63
- >>> Logic("0") in la # is a collection
64
- True
65
-
66
- >>> list(la) # is an iterable
67
- [Logic('1'), Logic('0'), Logic('1'), Logic('0')]
68
-
69
- When setting an element or slice, the *value* is first constructed into a
70
- :class:`Logic`.
71
-
72
- .. code-block:: python3
73
-
74
- >>> la = LogicArray("1010")
75
- >>> la[3] = "Z"
76
- >>> la[3]
77
- Logic('Z')
78
-
79
- >>> la[2:] = ['X', True, 0]
80
- >>> la
81
- LogicArray('ZX10', Range(3, 'downto', 0))
82
-
83
- :class:`LogicArray`\ s can be converted into :class:`str`\ s or :class:`int`\ s.
84
-
85
- .. code-block:: python3
86
-
87
- >>> la = LogicArray("1010")
88
- >>> la.binstr
89
- '1010'
90
-
91
- >>> la.integer # uses unsigned representation
92
- 10
93
-
94
- >>> la.signed_integer # uses two's complement representation
95
- -6
96
-
97
- :class:`LogicArray`\ s also support element-wise logical operations: ``&``, ``|``,
98
- ``^``, and ``~``.
99
-
100
- .. code-block:: python3
101
-
102
- >>> def big_mux(a: LogicArray, b: LogicArray, sel: Logic) -> LogicArray:
103
- ... s = LogicArray([sel] * len(a))
104
- ... return (a & ~s) | (b & s)
105
-
106
- >>> la = LogicArray("0110")
107
- >>> p = LogicArray("1110")
108
- >>> sel = Logic('1') # choose second option
109
- >>> big_mux(la, p, sel)
110
- LogicArray('1110', Range(3, 'downto', 0))
111
-
112
- Args:
113
- value: Initial value for the array.
114
- range: Indexing scheme of the array.
115
-
116
- Raises:
117
- ValueError: When argument values cannot be used to construct an array.
118
- TypeError: When invalid argument types are used.
119
- """
120
-
121
- __slots__ = ()
122
-
123
- @typing.overload
124
- def __init__(
125
- self,
126
- value: typing.Union[int, typing.Iterable[LogicConstructibleT], BinaryValue],
127
- range: typing.Optional[Range],
128
- ):
129
- ...
130
-
131
- @typing.overload
132
- def __init__(
133
- self,
134
- value: typing.Union[
135
- int, typing.Iterable[LogicConstructibleT], BinaryValue, None
136
- ],
137
- range: Range,
138
- ):
139
- ...
140
-
141
- def __init__(
142
- self,
143
- value: typing.Union[
144
- int, typing.Iterable[LogicConstructibleT], BinaryValue, None
145
- ] = None,
146
- range: typing.Optional[Range] = None,
147
- ) -> None:
148
- if value is None and range is None:
149
- raise ValueError(
150
- "at least one of the value and range input parameters must be given"
151
- )
152
- if value is None:
153
- self._value = [Logic() for _ in range]
154
- elif isinstance(value, int):
155
- if value < 0:
156
- bitlen = int.bit_length(value + 1) + 1
157
- else:
158
- bitlen = max(1, int.bit_length(value))
159
- if range is None:
160
- self._value = [Logic(v) for v in _int_to_bitstr(value, bitlen)]
161
- else:
162
- if bitlen > len(range):
163
- raise ValueError(f"{value} will not fit in {range}")
164
- self._value = [Logic(v) for v in _int_to_bitstr(value, len(range))]
165
- elif isinstance(value, typing.Iterable):
166
- self._value = [Logic(v) for v in value]
167
- elif isinstance(value, BinaryValue):
168
- self._value = [Logic(v) for v in value.binstr]
169
- else:
170
- raise TypeError(
171
- f"cannot construct {type(self).__qualname__} from value of type {type(value).__qualname__}"
172
- )
173
- if range is None:
174
- self._range = Range(len(self._value) - 1, "downto", 0)
175
- else:
176
- self._range = range
177
- if len(self._value) != len(self._range):
178
- raise ValueError(
179
- f"value of length {len(self._value)} will not fit in {self._range}"
180
- )
181
-
182
- @property
183
- def binstr(self) -> str:
184
- return "".join(str(bit) for bit in self)
185
-
186
- @property
187
- def is_resolvable(self) -> bool:
188
- return all(bit in (Logic(0), Logic(1)) for bit in self)
189
-
190
- @property
191
- def integer(self) -> int:
192
- value = 0
193
- for bit in self:
194
- value = value << 1 | int(bit)
195
- return value
196
-
197
- @property
198
- def signed_integer(self) -> int:
199
- value = self.integer
200
- if value >= (1 << (len(self) - 1)):
201
- value -= 1 << len(self)
202
- return value
203
-
204
- @typing.overload
205
- def __setitem__(self, item: int, value: LogicConstructibleT) -> None:
206
- ...
207
-
208
- @typing.overload
209
- def __setitem__(
210
- self, item: slice, value: typing.Iterable[LogicConstructibleT]
211
- ) -> None:
212
- ...
213
-
214
- def __setitem__(
215
- self,
216
- item: typing.Union[int, slice],
217
- value: typing.Union[LogicConstructibleT, typing.Iterable[LogicConstructibleT]],
218
- ) -> None:
219
- if isinstance(item, int):
220
- super().__setitem__(item, Logic(typing.cast(LogicConstructibleT, value)))
221
- elif isinstance(item, slice):
222
- super().__setitem__(
223
- item,
224
- (
225
- Logic(v)
226
- for v in typing.cast(typing.Iterable[LogicConstructibleT], value)
227
- ),
228
- )
229
- else:
230
- raise TypeError(
231
- f"indexes must be ints or slices, not {type(item).__name__}"
232
- )
233
-
234
- def __repr__(self) -> str:
235
- return "{}({!r}, {!r})".format(type(self).__qualname__, self.binstr, self.range)
236
-
237
- def __and__(self: Self, other: Self) -> Self:
238
- if isinstance(other, type(self)):
239
- if len(self) != len(other):
240
- raise ValueError(
241
- f"cannot perform bitwise & "
242
- f"between {type(self).__qualname__} of length {len(self)} "
243
- f"and {type(other).__qualname__} of length {len(other)}"
244
- )
245
- return type(self)(a & b for a, b in zip(self, other)) # type: ignore
246
- return NotImplemented
247
-
248
- def __rand__(self: Self, other: Self) -> Self:
249
- return self & other
250
-
251
- def __or__(self: Self, other: Self) -> Self:
252
- if isinstance(other, type(self)):
253
- if len(self) != len(other):
254
- raise ValueError(
255
- f"cannot perform bitwise | "
256
- f"between {type(self).__qualname__} of length {len(self)} "
257
- f"and {type(other).__qualname__} of length {len(other)}"
258
- )
259
- return type(self)(a | b for a, b in zip(self, other)) # type: ignore
260
- return NotImplemented
261
-
262
- def __ror__(self: Self, other: Self) -> Self:
263
- return self | other
264
-
265
- def __xor__(self: Self, other: Self) -> Self:
266
- if isinstance(other, type(self)):
267
- if len(self) != len(other):
268
- raise ValueError(
269
- f"cannot perform bitwise ^ "
270
- f"between {type(self).__qualname__} of length {len(self)} "
271
- f"and {type(other).__qualname__} of length {len(other)}"
272
- )
273
- return type(self)(a ^ b for a, b in zip(self, other)) # type: ignore
274
- return NotImplemented
275
-
276
- def __rxor__(self: Self, other: Self) -> Self:
277
- return self ^ other
278
-
279
- def __invert__(self: Self) -> Self:
280
- return type(self)(~v for v in self)
281
-
282
- def to_BinaryValue(
283
- self,
284
- bigEndian: bool = True,
285
- binaryRepresentation: BinaryRepresentation = BinaryRepresentation.UNSIGNED,
286
- ) -> BinaryValue:
287
- return BinaryValue(
288
- value=self.binstr,
289
- n_bits=len(self),
290
- bigEndian=bigEndian,
291
- binaryRepresentation=binaryRepresentation,
292
- )
293
-
294
-
295
- def _int_to_bitstr(value: int, n_bits: int) -> str:
296
- if value < 0:
297
- value += 1 << n_bits
298
- return format(value, f"0{n_bits}b")
cocotb/wavedrom.py DELETED
@@ -1,199 +0,0 @@
1
- # Copyright cocotb contributors
2
- # Copyright (c) 2014 Potential Ventures Ltd
3
- # Licensed under the Revised BSD License, see LICENSE for details.
4
- # SPDX-License-Identifier: BSD-3-Clause
5
-
6
- import json
7
- from collections import OrderedDict, defaultdict
8
- from collections.abc import Mapping
9
-
10
- import cocotb
11
- from cocotb.handle import SimHandleBase
12
- from cocotb.triggers import ReadOnly, RisingEdge
13
-
14
- try:
15
- from cocotb_bus.bus import Bus
16
- except ImportError:
17
- Bus = None
18
-
19
-
20
- class Wavedrom:
21
- """Base class for a WaveDrom compatible tracer."""
22
-
23
- def __init__(self, obj, name=""):
24
- self._hdls = OrderedDict()
25
- self._name = name
26
- if isinstance(obj, Mapping):
27
- self._hdls.update(obj)
28
- elif isinstance(obj, SimHandleBase):
29
- name = obj._name.split(".")[-1]
30
- self._hdls[name] = obj
31
- self._name = name
32
- elif Bus is not None and isinstance(obj, Bus):
33
- self._hdls.update(obj._signals)
34
- self._name = obj._name
35
- else:
36
- raise TypeError(
37
- "Cannot use {} with {} objects".format(
38
- type(self).__qualname__, type(obj).__name__
39
- )
40
- ) from None
41
- self.clear()
42
-
43
- def sample(self):
44
- """Record a sample of the signal value at this point in time."""
45
-
46
- def _lastval(samples):
47
- for x in range(len(samples) - 1, -1, -1):
48
- if samples[x] not in "=.|":
49
- return samples[x]
50
- return None
51
-
52
- for name, hdl in self._hdls.items():
53
- val = hdl.value
54
- valstr = val.binstr.lower()
55
-
56
- # Decide what character to use to represent this signal
57
- if len(valstr) == 1:
58
- char = valstr
59
- elif "x" in valstr:
60
- char = "x"
61
- elif "u" in valstr:
62
- char = "u"
63
- elif "z" in valstr:
64
- char = "z"
65
- else:
66
- if (
67
- len(self._data[name])
68
- and self._data[name][-1] == int(val)
69
- and self._samples[name][-1] in "=."
70
- ):
71
- char = "."
72
- else:
73
- char = "="
74
- self._data[name].append(int(val))
75
-
76
- # Detect if this is unchanged
77
- if len(valstr) == 1 and char == _lastval(self._samples[name]):
78
- char = "."
79
- self._samples[name].append(char)
80
-
81
- def clear(self):
82
- """Delete all sampled data."""
83
- self._samples = defaultdict(list)
84
- self._data = defaultdict(list)
85
-
86
- def gap(self):
87
- for name, hdl in self._hdls.items():
88
- self._samples[name].append("|")
89
-
90
- def get(self, add_clock=True):
91
- """Return the samples as a list suitable for use with WaveDrom."""
92
- siglist = []
93
- traces = []
94
- for name in self._hdls.keys():
95
- samples = self._samples[name]
96
- traces.append({"name": name, "wave": "".join(samples)})
97
- if name in self._data:
98
- traces[-1]["data"] = " ".join([repr(s) for s in self._data[name]])
99
-
100
- if len(traces) > 1:
101
- traces.insert(0, self._name)
102
- siglist.append(traces)
103
- else:
104
- siglist.append(traces[0])
105
-
106
- if add_clock:
107
- tracelen = len(traces[-1]["wave"])
108
- siglist.insert(0, {"name": "clk", "wave": "p" + "." * (tracelen - 1)})
109
-
110
- return siglist
111
-
112
-
113
- class trace:
114
- """Context manager to enable tracing of signals.
115
-
116
- Arguments are an arbitrary number of signals or buses to trace.
117
- We also require a clock to sample on, passed in as a keyword argument.
118
-
119
- Usage::
120
-
121
- with trace(sig1, sig2, a_bus, clk=clk) as waves:
122
- # Stuff happens, we trace it
123
-
124
- # Dump to JSON format compatible with WaveDrom
125
- j = waves.dumpj()
126
- """
127
-
128
- def __init__(self, *args, clk=None):
129
- self._clock = clk
130
- self._signals = []
131
- for arg in args:
132
- self._signals.append(Wavedrom(arg))
133
- self._coro = None
134
- self._clocks = 0
135
- self._enabled = False
136
-
137
- if self._clock is None:
138
- raise ValueError("Trace requires a clock to sample")
139
-
140
- async def _monitor(self):
141
- self._clocks = 0
142
- while True:
143
- await RisingEdge(self._clock)
144
- await ReadOnly()
145
- if not self._enabled:
146
- continue
147
- self._clocks += 1
148
- for sig in self._signals:
149
- sig.sample()
150
-
151
- def insert_gap(self):
152
- self._clocks += 1
153
- for sig in self._signals:
154
- sig.gap()
155
-
156
- def disable(self):
157
- self._enabled = False
158
-
159
- def enable(self):
160
- self._enabled = True
161
-
162
- def __enter__(self):
163
- for sig in self._signals:
164
- sig.clear()
165
- self.enable()
166
- self._coro = cocotb.start_soon(self._monitor())
167
- return self
168
-
169
- def __exit__(self, exc_type, exc_val, exc_tb):
170
- self._coro.kill()
171
- for sig in self._signals:
172
- sig.clear()
173
- self.disable()
174
- return None
175
-
176
- def write(self, filename, **kwargs):
177
- with open(filename, "w") as f:
178
- f.write(self.dumpj(**kwargs))
179
-
180
- def dumpj(self, header="", footer="", config=""):
181
- trace = {"signal": []}
182
- trace["signal"].append(
183
- {"name": "clock", "wave": "p" + "." * (self._clocks - 1)}
184
- )
185
- for sig in self._signals:
186
- trace["signal"].extend(sig.get(add_clock=False))
187
- if header:
188
- if isinstance(header, dict):
189
- trace["head"] = header
190
- else:
191
- trace["head"] = {"text": header}
192
- if footer:
193
- if isinstance(footer, dict):
194
- trace["foot"] = footer
195
- else:
196
- trace["foot"] = {"text": footer}
197
- if config:
198
- trace["config"] = config
199
- return json.dumps(trace, indent=4, sort_keys=False)
cocotb/xunit_reporter.py DELETED
@@ -1,80 +0,0 @@
1
- # Copyright (c) 2013 Potential Ventures Ltd
2
- # Copyright (c) 2013 SolarFlare Communications Inc
3
- # All rights reserved.
4
- #
5
- # Redistribution and use in source and binary forms, with or without
6
- # modification, are permitted provided that the following conditions are met:
7
- # * Redistributions of source code must retain the above copyright
8
- # notice, this list of conditions and the following disclaimer.
9
- # * Redistributions in binary form must reproduce the above copyright
10
- # notice, this list of conditions and the following disclaimer in the
11
- # documentation and/or other materials provided with the distribution.
12
- # * Neither the name of Potential Ventures Ltd,
13
- # SolarFlare Communications Inc nor the
14
- # names of its contributors may be used to endorse or promote products
15
- # derived from this software without specific prior written permission.
16
- #
17
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
- # DISCLAIMED. IN NO EVENT SHALL POTENTIAL VENTURES LTD BE LIABLE FOR ANY
21
- # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
- # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
- # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
- # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
- # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
-
28
- import xml.etree.ElementTree as ET
29
- from xml.etree.ElementTree import Element, SubElement
30
-
31
-
32
- class XUnitReporter:
33
- def __init__(self, filename="results.xml"):
34
- self.results = Element("testsuites", name="results")
35
- self.filename = filename
36
-
37
- def add_testsuite(self, **kwargs):
38
- self.last_testsuite = SubElement(self.results, "testsuite", **kwargs)
39
- return self.last_testsuite
40
-
41
- def add_testcase(self, testsuite=None, **kwargs):
42
- if testsuite is None:
43
- testsuite = self.last_testsuite
44
- self.last_testcase = SubElement(testsuite, "testcase", **kwargs)
45
- return self.last_testcase
46
-
47
- def add_property(self, testsuite=None, **kwargs):
48
- if testsuite is None:
49
- testsuite = self.last_testsuite
50
- self.last_property = SubElement(testsuite, "property", **kwargs)
51
- return self.last_property
52
-
53
- def add_failure(self, testcase=None, **kwargs):
54
- if testcase is None:
55
- testcase = self.last_testcase
56
- SubElement(testcase, "failure", **kwargs)
57
-
58
- def add_skipped(self, testcase=None, **kwargs):
59
- if testcase is None:
60
- testcase = self.last_testcase
61
- SubElement(testcase, "skipped", **kwargs)
62
-
63
- def indent(self, elem, level=0):
64
- i = "\n" + level * " "
65
- if len(elem):
66
- if not elem.text or not elem.text.strip():
67
- elem.text = i + " "
68
- if not elem.tail or not elem.tail.strip():
69
- elem.tail = i
70
- for elem in elem:
71
- self.indent(elem, level + 1)
72
- if not elem.tail or not elem.tail.strip():
73
- elem.tail = i
74
- else:
75
- if level and (not elem.tail or not elem.tail.strip()):
76
- elem.tail = i
77
-
78
- def write(self):
79
- self.indent(self.results)
80
- ET.ElementTree(self.results).write(self.filename, encoding="UTF-8")