We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
AvalonSTPkts hexdump needs a minor fix now that the transaction is of type bytes rather than string
When DEBUG logging level is enabled, the `hexdump` call in `_monitor_recv` function of AvalonSTPkts calls hexdump after converting the `pkt` in to `str` which is no longer needed

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cocotb/monitors/avalon.py`
Content:
```
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 """Monitors for Intel Avalon interfaces.
29 
30 See https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/manual/mnl_avalon_spec_1_3.pdf
31 
32 NB Currently we only support a very small subset of functionality.
33 """
34 
35 import warnings
36 
37 from cocotb.utils import hexdump
38 from cocotb.decorators import coroutine
39 from cocotb.monitors import BusMonitor
40 from cocotb.triggers import RisingEdge, ReadOnly
41 from cocotb.binary import BinaryValue
42 
43 
44 class AvalonProtocolError(Exception):
45     pass
46 
47 
48 class AvalonST(BusMonitor):
49     """Avalon-ST bus.
50 
51     Non-packetized so each valid word is a separate transaction.
52     """
53 
54     _signals = ["valid", "data"]
55     _optional_signals = ["ready"]
56 
57     _default_config = {"firstSymbolInHighOrderBits": True}
58 
59     def __init__(self, entity, name, clock, *, config={}, **kwargs):
60         BusMonitor.__init__(self, entity, name, clock, **kwargs)
61 
62         self.config = self._default_config.copy()
63 
64         for configoption, value in config.items():
65             self.config[configoption] = value
66             self.log.debug("Setting config option %s to %s", configoption, str(value))
67 
68     @coroutine
69     def _monitor_recv(self):
70         """Watch the pins and reconstruct transactions."""
71 
72         # Avoid spurious object creation by recycling
73         clkedge = RisingEdge(self.clock)
74         rdonly = ReadOnly()
75 
76         def valid():
77             if hasattr(self.bus, "ready"):
78                 return self.bus.valid.value and self.bus.ready.value
79             return self.bus.valid.value
80 
81         # NB could yield on valid here more efficiently?
82         while True:
83             yield clkedge
84             yield rdonly
85             if valid():
86                 vec = self.bus.data.value
87                 vec.big_endian = self.config["firstSymbolInHighOrderBits"]
88                 self._recv(vec.buff)
89 
90 
91 class AvalonSTPkts(BusMonitor):
92     """Packetized Avalon-ST bus.
93 
94     Args:
95         entity, name, clock: see :class:`BusMonitor`
96         config (dict): bus configuration options
97         report_channel (bool): report channel with data, default is False
98             Setting to True on bus without channel signal will give an error
99     """
100 
101     _signals = ["valid", "data", "startofpacket", "endofpacket"]
102     _optional_signals = ["error", "channel", "ready", "empty"]
103 
104     _default_config = {
105         "dataBitsPerSymbol"             : 8,
106         "firstSymbolInHighOrderBits"    : True,
107         "maxChannel"                    : 0,
108         "readyLatency"                  : 0,
109         "invalidTimeout"                : 0,
110     }
111 
112     def __init__(self, entity, name, clock, *, config={}, report_channel=False, **kwargs):
113         BusMonitor.__init__(self, entity, name , clock, **kwargs)
114 
115         self.config = self._default_config.copy()
116         self.report_channel = report_channel
117 
118         # Set default config maxChannel to max value on channel bus
119         if hasattr(self.bus, 'channel'):
120             self.config['maxChannel'] = (2 ** len(self.bus.channel)) -1
121         else:
122             if report_channel:
123                 raise ValueError("Channel reporting asked on bus without channel signal")
124 
125         for configoption, value in config.items():
126             self.config[configoption] = value
127             self.log.debug("Setting config option %s to %s",
128                            configoption, str(value))
129 
130         num_data_symbols = (len(self.bus.data) /
131                             self.config["dataBitsPerSymbol"])
132         if (num_data_symbols > 1 and not hasattr(self.bus, 'empty')):
133             raise AttributeError(
134                 "%s has %i data symbols, but contains no object named empty" %
135                 (self.name, num_data_symbols))
136 
137         self.config["useEmpty"] = (num_data_symbols > 1)
138 
139         if hasattr(self.bus, 'channel'):
140             if len(self.bus.channel) > 128:
141                 raise AttributeError("AvalonST interface specification defines channel width as 1-128. "
142                                      "%d channel width is %d" %
143                                      (self.name, len(self.bus.channel)))
144             maxChannel = (2 ** len(self.bus.channel)) -1
145             if self.config['maxChannel'] > maxChannel:
146                 raise AttributeError("%s has maxChannel=%d, but can only support a maximum channel of "
147                                      "(2**channel_width)-1=%d, channel_width=%d" %
148                                      (self.name, self.config['maxChannel'], maxChannel, len(self.bus.channel)))
149 
150     @coroutine
151     def _monitor_recv(self):
152         """Watch the pins and reconstruct transactions."""
153 
154         # Avoid spurious object creation by recycling
155         clkedge = RisingEdge(self.clock)
156         rdonly = ReadOnly()
157         pkt = b""
158         in_pkt = False
159         invalid_cyclecount = 0
160         channel = None
161 
162         def valid():
163             if hasattr(self.bus, 'ready'):
164                 return self.bus.valid.value and self.bus.ready.value
165             return self.bus.valid.value
166 
167         while True:
168             yield clkedge
169             yield rdonly
170 
171             if self.in_reset:
172                 continue
173 
174             if valid():
175                 invalid_cyclecount = 0
176 
177                 if self.bus.startofpacket.value:
178                     if pkt:
179                         raise AvalonProtocolError("Duplicate start-of-packet received on %s" %
180                                                   str(self.bus.startofpacket))
181                     pkt = b""
182                     in_pkt = True
183 
184                 if not in_pkt:
185                     raise AvalonProtocolError("Data transfer outside of "
186                                               "packet")
187 
188                 # Handle empty and X's in empty / data
189                 vec = BinaryValue()
190                 if not self.bus.endofpacket.value:
191                     vec = self.bus.data.value
192                 else:
193                     value = self.bus.data.value.get_binstr()
194                     if self.config["useEmpty"] and self.bus.empty.value.integer:
195                         empty = self.bus.empty.value.integer * self.config["dataBitsPerSymbol"]
196                         if self.config["firstSymbolInHighOrderBits"]:
197                             value = value[:-empty]
198                         else:
199                             value = value[empty:]
200                     vec.assign(value)
201                     if not vec.is_resolvable:
202                         raise AvalonProtocolError("After empty masking value is still bad?  "
203                                                   "Had empty {:d}, got value {:s}".format(empty,
204                                                                                           self.bus.data.value.get_binstr()))
205 
206                 vec.big_endian = self.config['firstSymbolInHighOrderBits']
207                 pkt += vec.buff
208 
209                 if hasattr(self.bus, 'channel'):
210                     if channel is None:
211                         channel = self.bus.channel.value.integer
212                         if channel > self.config["maxChannel"]:
213                             raise AvalonProtocolError("Channel value (%d) is greater than maxChannel (%d)" %
214                                                       (channel, self.config["maxChannel"]))
215                     elif self.bus.channel.value.integer != channel:
216                         raise AvalonProtocolError("Channel value changed during packet")
217 
218                 if self.bus.endofpacket.value:
219                     self.log.info("Received a packet of %d bytes", len(pkt))
220                     self.log.debug(hexdump(str((pkt))))
221                     self.channel = channel
222                     if self.report_channel:
223                         self._recv({"data": pkt, "channel": channel})
224                     else:
225                         self._recv(pkt)
226                     pkt = b""
227                     in_pkt = False
228                     channel = None
229             else:
230                 if in_pkt:
231                     invalid_cyclecount += 1
232                     if self.config["invalidTimeout"]:
233                         if invalid_cyclecount >= self.config["invalidTimeout"]:
234                             raise AvalonProtocolError(
235                                 "In-Packet Timeout. Didn't receive any valid data for %d cycles!" %
236                                 invalid_cyclecount)
237 
238 
239 class AvalonSTPktsWithChannel(AvalonSTPkts):
240     """Packetized AvalonST bus using channel.
241 
242     This class is deprecated. Use AvalonSTPkts(..., report_channel=True, ...)
243     """
244 
245     def __init__(self, entity, name, clock, **kwargs):
246         warnings.warn(
247             "Use of AvalonSTPktsWithChannel is deprecated\n"
248             "\tUse AvalonSTPkts(..., report_channel=True, ...)",
249             DeprecationWarning, stacklevel=2
250         )
251         AvalonSTPkts.__init__(self, entity, name, clock, report_channel=True, **kwargs)
252
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/cocotb/monitors/avalon.py b/cocotb/monitors/avalon.py
--- a/cocotb/monitors/avalon.py
+++ b/cocotb/monitors/avalon.py
@@ -217,7 +217,7 @@
 
                 if self.bus.endofpacket.value:
                     self.log.info("Received a packet of %d bytes", len(pkt))
-                    self.log.debug(hexdump(str((pkt))))
+                    self.log.debug(hexdump(pkt))
                     self.channel = channel
                     if self.report_channel:
                         self._recv({"data": pkt, "channel": channel})

{"golden_diff": "diff --git a/cocotb/monitors/avalon.py b/cocotb/monitors/avalon.py\n--- a/cocotb/monitors/avalon.py\n+++ b/cocotb/monitors/avalon.py\n@@ -217,7 +217,7 @@\n \n                 if self.bus.endofpacket.value:\n                     self.log.info(\"Received a packet of %d bytes\", len(pkt))\n-                    self.log.debug(hexdump(str((pkt))))\n+                    self.log.debug(hexdump(pkt))\n                     self.channel = channel\n                     if self.report_channel:\n                         self._recv({\"data\": pkt, \"channel\": channel})\n", "issue": "AvalonSTPkts hexdump needs a minor fix now that the transaction is of type bytes rather than string\nWhen DEBUG logging level is enabled, the `hexdump` call in `_monitor_recv` function of AvalonSTPkts calls hexdump after converting the `pkt` in to `str` which is no longer needed\n", "before_files": [{"content": "# Copyright (c) 2013 Potential Ventures Ltd\n# Copyright (c) 2013 SolarFlare Communications Inc\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are met:\n#     * Redistributions of source code must retain the above copyright\n#       notice, this list of conditions and the following disclaimer.\n#     * Redistributions in binary form must reproduce the above copyright\n#       notice, this list of conditions and the following disclaimer in the\n#       documentation and/or other materials provided with the distribution.\n#     * Neither the name of Potential Ventures Ltd,\n#       SolarFlare Communications Inc nor the\n#       names of its contributors may be used to endorse or promote products\n#       derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n# DISCLAIMED. IN NO EVENT SHALL POTENTIAL VENTURES LTD BE LIABLE FOR ANY\n# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\"\"\"Monitors for Intel Avalon interfaces.\n\nSee https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/manual/mnl_avalon_spec_1_3.pdf\n\nNB Currently we only support a very small subset of functionality.\n\"\"\"\n\nimport warnings\n\nfrom cocotb.utils import hexdump\nfrom cocotb.decorators import coroutine\nfrom cocotb.monitors import BusMonitor\nfrom cocotb.triggers import RisingEdge, ReadOnly\nfrom cocotb.binary import BinaryValue\n\n\nclass AvalonProtocolError(Exception):\n    pass\n\n\nclass AvalonST(BusMonitor):\n    \"\"\"Avalon-ST bus.\n\n    Non-packetized so each valid word is a separate transaction.\n    \"\"\"\n\n    _signals = [\"valid\", \"data\"]\n    _optional_signals = [\"ready\"]\n\n    _default_config = {\"firstSymbolInHighOrderBits\": True}\n\n    def __init__(self, entity, name, clock, *, config={}, **kwargs):\n        BusMonitor.__init__(self, entity, name, clock, **kwargs)\n\n        self.config = self._default_config.copy()\n\n        for configoption, value in config.items():\n            self.config[configoption] = value\n            self.log.debug(\"Setting config option %s to %s\", configoption, str(value))\n\n    @coroutine\n    def _monitor_recv(self):\n        \"\"\"Watch the pins and reconstruct transactions.\"\"\"\n\n        # Avoid spurious object creation by recycling\n        clkedge = RisingEdge(self.clock)\n        rdonly = ReadOnly()\n\n        def valid():\n            if hasattr(self.bus, \"ready\"):\n                return self.bus.valid.value and self.bus.ready.value\n            return self.bus.valid.value\n\n        # NB could yield on valid here more efficiently?\n        while True:\n            yield clkedge\n            yield rdonly\n            if valid():\n                vec = self.bus.data.value\n                vec.big_endian = self.config[\"firstSymbolInHighOrderBits\"]\n                self._recv(vec.buff)\n\n\nclass AvalonSTPkts(BusMonitor):\n    \"\"\"Packetized Avalon-ST bus.\n\n    Args:\n        entity, name, clock: see :class:`BusMonitor`\n        config (dict): bus configuration options\n        report_channel (bool): report channel with data, default is False\n            Setting to True on bus without channel signal will give an error\n    \"\"\"\n\n    _signals = [\"valid\", \"data\", \"startofpacket\", \"endofpacket\"]\n    _optional_signals = [\"error\", \"channel\", \"ready\", \"empty\"]\n\n    _default_config = {\n        \"dataBitsPerSymbol\"             : 8,\n        \"firstSymbolInHighOrderBits\"    : True,\n        \"maxChannel\"                    : 0,\n        \"readyLatency\"                  : 0,\n        \"invalidTimeout\"                : 0,\n    }\n\n    def __init__(self, entity, name, clock, *, config={}, report_channel=False, **kwargs):\n        BusMonitor.__init__(self, entity, name , clock, **kwargs)\n\n        self.config = self._default_config.copy()\n        self.report_channel = report_channel\n\n        # Set default config maxChannel to max value on channel bus\n        if hasattr(self.bus, 'channel'):\n            self.config['maxChannel'] = (2 ** len(self.bus.channel)) -1\n        else:\n            if report_channel:\n                raise ValueError(\"Channel reporting asked on bus without channel signal\")\n\n        for configoption, value in config.items():\n            self.config[configoption] = value\n            self.log.debug(\"Setting config option %s to %s\",\n                           configoption, str(value))\n\n        num_data_symbols = (len(self.bus.data) /\n                            self.config[\"dataBitsPerSymbol\"])\n        if (num_data_symbols > 1 and not hasattr(self.bus, 'empty')):\n            raise AttributeError(\n                \"%s has %i data symbols, but contains no object named empty\" %\n                (self.name, num_data_symbols))\n\n        self.config[\"useEmpty\"] = (num_data_symbols > 1)\n\n        if hasattr(self.bus, 'channel'):\n            if len(self.bus.channel) > 128:\n                raise AttributeError(\"AvalonST interface specification defines channel width as 1-128. \"\n                                     \"%d channel width is %d\" %\n                                     (self.name, len(self.bus.channel)))\n            maxChannel = (2 ** len(self.bus.channel)) -1\n            if self.config['maxChannel'] > maxChannel:\n                raise AttributeError(\"%s has maxChannel=%d, but can only support a maximum channel of \"\n                                     \"(2**channel_width)-1=%d, channel_width=%d\" %\n                                     (self.name, self.config['maxChannel'], maxChannel, len(self.bus.channel)))\n\n    @coroutine\n    def _monitor_recv(self):\n        \"\"\"Watch the pins and reconstruct transactions.\"\"\"\n\n        # Avoid spurious object creation by recycling\n        clkedge = RisingEdge(self.clock)\n        rdonly = ReadOnly()\n        pkt = b\"\"\n        in_pkt = False\n        invalid_cyclecount = 0\n        channel = None\n\n        def valid():\n            if hasattr(self.bus, 'ready'):\n                return self.bus.valid.value and self.bus.ready.value\n            return self.bus.valid.value\n\n        while True:\n            yield clkedge\n            yield rdonly\n\n            if self.in_reset:\n                continue\n\n            if valid():\n                invalid_cyclecount = 0\n\n                if self.bus.startofpacket.value:\n                    if pkt:\n                        raise AvalonProtocolError(\"Duplicate start-of-packet received on %s\" %\n                                                  str(self.bus.startofpacket))\n                    pkt = b\"\"\n                    in_pkt = True\n\n                if not in_pkt:\n                    raise AvalonProtocolError(\"Data transfer outside of \"\n                                              \"packet\")\n\n                # Handle empty and X's in empty / data\n                vec = BinaryValue()\n                if not self.bus.endofpacket.value:\n                    vec = self.bus.data.value\n                else:\n                    value = self.bus.data.value.get_binstr()\n                    if self.config[\"useEmpty\"] and self.bus.empty.value.integer:\n                        empty = self.bus.empty.value.integer * self.config[\"dataBitsPerSymbol\"]\n                        if self.config[\"firstSymbolInHighOrderBits\"]:\n                            value = value[:-empty]\n                        else:\n                            value = value[empty:]\n                    vec.assign(value)\n                    if not vec.is_resolvable:\n                        raise AvalonProtocolError(\"After empty masking value is still bad?  \"\n                                                  \"Had empty {:d}, got value {:s}\".format(empty,\n                                                                                          self.bus.data.value.get_binstr()))\n\n                vec.big_endian = self.config['firstSymbolInHighOrderBits']\n                pkt += vec.buff\n\n                if hasattr(self.bus, 'channel'):\n                    if channel is None:\n                        channel = self.bus.channel.value.integer\n                        if channel > self.config[\"maxChannel\"]:\n                            raise AvalonProtocolError(\"Channel value (%d) is greater than maxChannel (%d)\" %\n                                                      (channel, self.config[\"maxChannel\"]))\n                    elif self.bus.channel.value.integer != channel:\n                        raise AvalonProtocolError(\"Channel value changed during packet\")\n\n                if self.bus.endofpacket.value:\n                    self.log.info(\"Received a packet of %d bytes\", len(pkt))\n                    self.log.debug(hexdump(str((pkt))))\n                    self.channel = channel\n                    if self.report_channel:\n                        self._recv({\"data\": pkt, \"channel\": channel})\n                    else:\n                        self._recv(pkt)\n                    pkt = b\"\"\n                    in_pkt = False\n                    channel = None\n            else:\n                if in_pkt:\n                    invalid_cyclecount += 1\n                    if self.config[\"invalidTimeout\"]:\n                        if invalid_cyclecount >= self.config[\"invalidTimeout\"]:\n                            raise AvalonProtocolError(\n                                \"In-Packet Timeout. Didn't receive any valid data for %d cycles!\" %\n                                invalid_cyclecount)\n\n\nclass AvalonSTPktsWithChannel(AvalonSTPkts):\n    \"\"\"Packetized AvalonST bus using channel.\n\n    This class is deprecated. Use AvalonSTPkts(..., report_channel=True, ...)\n    \"\"\"\n\n    def __init__(self, entity, name, clock, **kwargs):\n        warnings.warn(\n            \"Use of AvalonSTPktsWithChannel is deprecated\\n\"\n            \"\\tUse AvalonSTPkts(..., report_channel=True, ...)\",\n            DeprecationWarning, stacklevel=2\n        )\n        AvalonSTPkts.__init__(self, entity, name, clock, report_channel=True, **kwargs)\n", "path": "cocotb/monitors/avalon.py"}], "after_files": [{"content": "# Copyright (c) 2013 Potential Ventures Ltd\n# Copyright (c) 2013 SolarFlare Communications Inc\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are met:\n#     * Redistributions of source code must retain the above copyright\n#       notice, this list of conditions and the following disclaimer.\n#     * Redistributions in binary form must reproduce the above copyright\n#       notice, this list of conditions and the following disclaimer in the\n#       documentation and/or other materials provided with the distribution.\n#     * Neither the name of Potential Ventures Ltd,\n#       SolarFlare Communications Inc nor the\n#       names of its contributors may be used to endorse or promote products\n#       derived from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n# DISCLAIMED. IN NO EVENT SHALL POTENTIAL VENTURES LTD BE LIABLE FOR ANY\n# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\"\"\"Monitors for Intel Avalon interfaces.\n\nSee https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/manual/mnl_avalon_spec_1_3.pdf\n\nNB Currently we only support a very small subset of functionality.\n\"\"\"\n\nimport warnings\n\nfrom cocotb.utils import hexdump\nfrom cocotb.decorators import coroutine\nfrom cocotb.monitors import BusMonitor\nfrom cocotb.triggers import RisingEdge, ReadOnly\nfrom cocotb.binary import BinaryValue\n\n\nclass AvalonProtocolError(Exception):\n    pass\n\n\nclass AvalonST(BusMonitor):\n    \"\"\"Avalon-ST bus.\n\n    Non-packetized so each valid word is a separate transaction.\n    \"\"\"\n\n    _signals = [\"valid\", \"data\"]\n    _optional_signals = [\"ready\"]\n\n    _default_config = {\"firstSymbolInHighOrderBits\": True}\n\n    def __init__(self, entity, name, clock, *, config={}, **kwargs):\n        BusMonitor.__init__(self, entity, name, clock, **kwargs)\n\n        self.config = self._default_config.copy()\n\n        for configoption, value in config.items():\n            self.config[configoption] = value\n            self.log.debug(\"Setting config option %s to %s\", configoption, str(value))\n\n    @coroutine\n    def _monitor_recv(self):\n        \"\"\"Watch the pins and reconstruct transactions.\"\"\"\n\n        # Avoid spurious object creation by recycling\n        clkedge = RisingEdge(self.clock)\n        rdonly = ReadOnly()\n\n        def valid():\n            if hasattr(self.bus, \"ready\"):\n                return self.bus.valid.value and self.bus.ready.value\n            return self.bus.valid.value\n\n        # NB could yield on valid here more efficiently?\n        while True:\n            yield clkedge\n            yield rdonly\n            if valid():\n                vec = self.bus.data.value\n                vec.big_endian = self.config[\"firstSymbolInHighOrderBits\"]\n                self._recv(vec.buff)\n\n\nclass AvalonSTPkts(BusMonitor):\n    \"\"\"Packetized Avalon-ST bus.\n\n    Args:\n        entity, name, clock: see :class:`BusMonitor`\n        config (dict): bus configuration options\n        report_channel (bool): report channel with data, default is False\n            Setting to True on bus without channel signal will give an error\n    \"\"\"\n\n    _signals = [\"valid\", \"data\", \"startofpacket\", \"endofpacket\"]\n    _optional_signals = [\"error\", \"channel\", \"ready\", \"empty\"]\n\n    _default_config = {\n        \"dataBitsPerSymbol\"             : 8,\n        \"firstSymbolInHighOrderBits\"    : True,\n        \"maxChannel\"                    : 0,\n        \"readyLatency\"                  : 0,\n        \"invalidTimeout\"                : 0,\n    }\n\n    def __init__(self, entity, name, clock, *, config={}, report_channel=False, **kwargs):\n        BusMonitor.__init__(self, entity, name , clock, **kwargs)\n\n        self.config = self._default_config.copy()\n        self.report_channel = report_channel\n\n        # Set default config maxChannel to max value on channel bus\n        if hasattr(self.bus, 'channel'):\n            self.config['maxChannel'] = (2 ** len(self.bus.channel)) -1\n        else:\n            if report_channel:\n                raise ValueError(\"Channel reporting asked on bus without channel signal\")\n\n        for configoption, value in config.items():\n            self.config[configoption] = value\n            self.log.debug(\"Setting config option %s to %s\",\n                           configoption, str(value))\n\n        num_data_symbols = (len(self.bus.data) /\n                            self.config[\"dataBitsPerSymbol\"])\n        if (num_data_symbols > 1 and not hasattr(self.bus, 'empty')):\n            raise AttributeError(\n                \"%s has %i data symbols, but contains no object named empty\" %\n                (self.name, num_data_symbols))\n\n        self.config[\"useEmpty\"] = (num_data_symbols > 1)\n\n        if hasattr(self.bus, 'channel'):\n            if len(self.bus.channel) > 128:\n                raise AttributeError(\"AvalonST interface specification defines channel width as 1-128. \"\n                                     \"%d channel width is %d\" %\n                                     (self.name, len(self.bus.channel)))\n            maxChannel = (2 ** len(self.bus.channel)) -1\n            if self.config['maxChannel'] > maxChannel:\n                raise AttributeError(\"%s has maxChannel=%d, but can only support a maximum channel of \"\n                                     \"(2**channel_width)-1=%d, channel_width=%d\" %\n                                     (self.name, self.config['maxChannel'], maxChannel, len(self.bus.channel)))\n\n    @coroutine\n    def _monitor_recv(self):\n        \"\"\"Watch the pins and reconstruct transactions.\"\"\"\n\n        # Avoid spurious object creation by recycling\n        clkedge = RisingEdge(self.clock)\n        rdonly = ReadOnly()\n        pkt = b\"\"\n        in_pkt = False\n        invalid_cyclecount = 0\n        channel = None\n\n        def valid():\n            if hasattr(self.bus, 'ready'):\n                return self.bus.valid.value and self.bus.ready.value\n            return self.bus.valid.value\n\n        while True:\n            yield clkedge\n            yield rdonly\n\n            if self.in_reset:\n                continue\n\n            if valid():\n                invalid_cyclecount = 0\n\n                if self.bus.startofpacket.value:\n                    if pkt:\n                        raise AvalonProtocolError(\"Duplicate start-of-packet received on %s\" %\n                                                  str(self.bus.startofpacket))\n                    pkt = b\"\"\n                    in_pkt = True\n\n                if not in_pkt:\n                    raise AvalonProtocolError(\"Data transfer outside of \"\n                                              \"packet\")\n\n                # Handle empty and X's in empty / data\n                vec = BinaryValue()\n                if not self.bus.endofpacket.value:\n                    vec = self.bus.data.value\n                else:\n                    value = self.bus.data.value.get_binstr()\n                    if self.config[\"useEmpty\"] and self.bus.empty.value.integer:\n                        empty = self.bus.empty.value.integer * self.config[\"dataBitsPerSymbol\"]\n                        if self.config[\"firstSymbolInHighOrderBits\"]:\n                            value = value[:-empty]\n                        else:\n                            value = value[empty:]\n                    vec.assign(value)\n                    if not vec.is_resolvable:\n                        raise AvalonProtocolError(\"After empty masking value is still bad?  \"\n                                                  \"Had empty {:d}, got value {:s}\".format(empty,\n                                                                                          self.bus.data.value.get_binstr()))\n\n                vec.big_endian = self.config['firstSymbolInHighOrderBits']\n                pkt += vec.buff\n\n                if hasattr(self.bus, 'channel'):\n                    if channel is None:\n                        channel = self.bus.channel.value.integer\n                        if channel > self.config[\"maxChannel\"]:\n                            raise AvalonProtocolError(\"Channel value (%d) is greater than maxChannel (%d)\" %\n                                                      (channel, self.config[\"maxChannel\"]))\n                    elif self.bus.channel.value.integer != channel:\n                        raise AvalonProtocolError(\"Channel value changed during packet\")\n\n                if self.bus.endofpacket.value:\n                    self.log.info(\"Received a packet of %d bytes\", len(pkt))\n                    self.log.debug(hexdump(pkt))\n                    self.channel = channel\n                    if self.report_channel:\n                        self._recv({\"data\": pkt, \"channel\": channel})\n                    else:\n                        self._recv(pkt)\n                    pkt = b\"\"\n                    in_pkt = False\n                    channel = None\n            else:\n                if in_pkt:\n                    invalid_cyclecount += 1\n                    if self.config[\"invalidTimeout\"]:\n                        if invalid_cyclecount >= self.config[\"invalidTimeout\"]:\n                            raise AvalonProtocolError(\n                                \"In-Packet Timeout. Didn't receive any valid data for %d cycles!\" %\n                                invalid_cyclecount)\n\n\nclass AvalonSTPktsWithChannel(AvalonSTPkts):\n    \"\"\"Packetized AvalonST bus using channel.\n\n    This class is deprecated. Use AvalonSTPkts(..., report_channel=True, ...)\n    \"\"\"\n\n    def __init__(self, entity, name, clock, **kwargs):\n        warnings.warn(\n            \"Use of AvalonSTPktsWithChannel is deprecated\\n\"\n            \"\\tUse AvalonSTPkts(..., report_channel=True, ...)\",\n            DeprecationWarning, stacklevel=2\n        )\n        AvalonSTPkts.__init__(self, entity, name, clock, report_channel=True, **kwargs)\n", "path": "cocotb/monitors/avalon.py"}]}