switchboard-hw 0.3.0__cp314-cp314t-macosx_10_15_x86_64.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.
Files changed (99) hide show
  1. _switchboard.cpython-314t-darwin.so +0 -0
  2. switchboard/__init__.py +24 -0
  3. switchboard/ams.py +668 -0
  4. switchboard/apb.py +278 -0
  5. switchboard/autowrap.py +1000 -0
  6. switchboard/axi.py +571 -0
  7. switchboard/axil.py +348 -0
  8. switchboard/bitvector.py +112 -0
  9. switchboard/cmdline.py +142 -0
  10. switchboard/cpp/Makefile +13 -0
  11. switchboard/cpp/bitutil.h +39 -0
  12. switchboard/cpp/pagemap.h +91 -0
  13. switchboard/cpp/pciedev.h +86 -0
  14. switchboard/cpp/router.cc +89 -0
  15. switchboard/cpp/spsc_queue.h +267 -0
  16. switchboard/cpp/switchboard.hpp +257 -0
  17. switchboard/cpp/switchboard_pcie.hpp +234 -0
  18. switchboard/cpp/switchboard_tlm.hpp +98 -0
  19. switchboard/cpp/umilib.h +144 -0
  20. switchboard/cpp/umilib.hpp +113 -0
  21. switchboard/cpp/umisb.hpp +364 -0
  22. switchboard/cpp/xyce.hpp +90 -0
  23. switchboard/deps/__init__.py +0 -0
  24. switchboard/deps/verilog_axi.py +23 -0
  25. switchboard/dpi/__init__.py +0 -0
  26. switchboard/dpi/switchboard_dpi.cc +119 -0
  27. switchboard/dpi/switchboard_dpi.py +13 -0
  28. switchboard/dpi/xyce_dpi.cc +43 -0
  29. switchboard/gpio.py +108 -0
  30. switchboard/icarus.py +85 -0
  31. switchboard/loopback.py +157 -0
  32. switchboard/network.py +714 -0
  33. switchboard/pytest_plugin.py +11 -0
  34. switchboard/sbdesign.py +55 -0
  35. switchboard/sbdut.py +744 -0
  36. switchboard/sbtcp.py +345 -0
  37. switchboard/sc/__init__.py +0 -0
  38. switchboard/sc/morty/__init__.py +0 -0
  39. switchboard/sc/morty/uniquify.py +67 -0
  40. switchboard/sc/sed/__init__.py +0 -0
  41. switchboard/sc/sed/sed_remove.py +47 -0
  42. switchboard/sc/standalone_netlist_flow.py +25 -0
  43. switchboard/switchboard.py +53 -0
  44. switchboard/test_util.py +46 -0
  45. switchboard/uart_xactor.py +66 -0
  46. switchboard/umi.py +793 -0
  47. switchboard/util.py +131 -0
  48. switchboard/verilator/__init__.py +0 -0
  49. switchboard/verilator/config.vlt +13 -0
  50. switchboard/verilator/testbench.cc +143 -0
  51. switchboard/verilator/verilator.py +13 -0
  52. switchboard/verilator_run.py +31 -0
  53. switchboard/verilog/__init__.py +0 -0
  54. switchboard/verilog/common/__init__.py +0 -0
  55. switchboard/verilog/common/common.py +26 -0
  56. switchboard/verilog/common/switchboard.vh +429 -0
  57. switchboard/verilog/common/uart_xactor.sv +247 -0
  58. switchboard/verilog/common/umi_gpio.v +236 -0
  59. switchboard/verilog/fpga/__init__.py +0 -0
  60. switchboard/verilog/fpga/axi_reader.sv +82 -0
  61. switchboard/verilog/fpga/axi_writer.sv +111 -0
  62. switchboard/verilog/fpga/config_registers.sv +249 -0
  63. switchboard/verilog/fpga/fpga.py +21 -0
  64. switchboard/verilog/fpga/include/sb_queue_regmap.vh +21 -0
  65. switchboard/verilog/fpga/include/spsc_queue.vh +7 -0
  66. switchboard/verilog/fpga/memory_fault.sv +40 -0
  67. switchboard/verilog/fpga/sb_fpga_queues.sv +416 -0
  68. switchboard/verilog/fpga/sb_rx_fpga.sv +303 -0
  69. switchboard/verilog/fpga/sb_tx_fpga.sv +294 -0
  70. switchboard/verilog/fpga/umi_fpga_queues.sv +146 -0
  71. switchboard/verilog/sim/__init__.py +0 -0
  72. switchboard/verilog/sim/auto_stop_sim.sv +25 -0
  73. switchboard/verilog/sim/perf_meas_sim.sv +97 -0
  74. switchboard/verilog/sim/queue_to_sb_sim.sv +176 -0
  75. switchboard/verilog/sim/queue_to_umi_sim.sv +66 -0
  76. switchboard/verilog/sim/sb_apb_m.sv +146 -0
  77. switchboard/verilog/sim/sb_axi_m.sv +199 -0
  78. switchboard/verilog/sim/sb_axil_m.sv +180 -0
  79. switchboard/verilog/sim/sb_axil_s.sv +180 -0
  80. switchboard/verilog/sim/sb_clk_gen.sv +89 -0
  81. switchboard/verilog/sim/sb_jtag_rbb_sim.sv +148 -0
  82. switchboard/verilog/sim/sb_rx_sim.sv +55 -0
  83. switchboard/verilog/sim/sb_to_queue_sim.sv +196 -0
  84. switchboard/verilog/sim/sb_tx_sim.sv +55 -0
  85. switchboard/verilog/sim/switchboard_sim.py +49 -0
  86. switchboard/verilog/sim/umi_rx_sim.sv +61 -0
  87. switchboard/verilog/sim/umi_to_queue_sim.sv +66 -0
  88. switchboard/verilog/sim/umi_tx_sim.sv +61 -0
  89. switchboard/verilog/sim/xyce_intf.sv +67 -0
  90. switchboard/vpi/switchboard_vpi.cc +431 -0
  91. switchboard/vpi/xyce_vpi.cc +200 -0
  92. switchboard/warn.py +14 -0
  93. switchboard/xyce.py +27 -0
  94. switchboard_hw-0.3.0.dist-info/METADATA +303 -0
  95. switchboard_hw-0.3.0.dist-info/RECORD +99 -0
  96. switchboard_hw-0.3.0.dist-info/WHEEL +6 -0
  97. switchboard_hw-0.3.0.dist-info/entry_points.txt +6 -0
  98. switchboard_hw-0.3.0.dist-info/licenses/LICENSE +190 -0
  99. switchboard_hw-0.3.0.dist-info/top_level.txt +2 -0
switchboard/apb.py ADDED
@@ -0,0 +1,278 @@
1
+ # Python interface for AXI-Lite reads and writes
2
+
3
+ # Copyright (c) 2024 Zero ASIC Corporation
4
+ # This code is licensed under Apache License 2.0 (see LICENSE for details)
5
+
6
+ import numpy as np
7
+
8
+ from math import floor, ceil, log2
9
+ from numbers import Integral
10
+
11
+ from _switchboard import PySbPacket, PySbTx, PySbRx
12
+
13
+
14
+ class ApbTxRx:
15
+ def __init__(
16
+ self,
17
+ uri: str,
18
+ fresh: bool = True,
19
+ data_width: int = 32,
20
+ addr_width: int = 16,
21
+ prot: int = 0,
22
+ slv_err_expected: bool = False,
23
+ queue_suffix: str = '.q',
24
+ max_rate: float = -1
25
+ ):
26
+ """
27
+ Parameters
28
+ ----------
29
+ uri: str
30
+ Base name of for switchboard queues used to convey APB transactions.
31
+ fresh: bool, optional
32
+ If True (default), the queue specified by the uri parameter will get cleared
33
+ before executing the simulation.
34
+ data_width: int, optional
35
+ Width the write and read data buses, in bits.
36
+ addr_width: int, optional
37
+ Width the write and read address buses, in bits.
38
+ prot: int, optional
39
+ Default value of PROT to use for read and write transactions. Can be
40
+ overridden on a transaction-by-transaction basis.
41
+ slv_err_expected: bool, optional
42
+ Default response to expect from reads and writes.
43
+ None means "don't check the response".
44
+ This default can be overridden on a transaction-by-transaction basis.
45
+ queue_suffix: str, optional
46
+ File extension/suffix to use when naming switchboard queues that carry
47
+ APB transactions. For example, if set to ".queue", the write address
48
+ queue name will be "{uri}-aw.queue"
49
+ """
50
+
51
+ # check data types
52
+ assert isinstance(data_width, Integral), 'data_width must be an integer'
53
+ assert isinstance(addr_width, Integral), 'addr_width must be an integer'
54
+
55
+ # check that data width is a multiple of a byte
56
+ data_width_choices = [8, 16, 32, 64, 128, 256, 512, 1024]
57
+ assert data_width in data_width_choices, \
58
+ f'data_width must be in {data_width_choices}'
59
+
60
+ # check that data and address widths are supported
61
+ SBDW = 416
62
+ assert 0 < data_width <= floor(SBDW / (1 + (1 / 8))), 'data_width out of range'
63
+ assert 0 < addr_width <= SBDW - 3, 'addr_width out of range'
64
+
65
+ # save settings
66
+ self.data_width = data_width
67
+ self.addr_width = addr_width
68
+ self.default_prot = prot
69
+ self.default_slv_err_expected = slv_err_expected
70
+
71
+ # create the queues
72
+ self.apb_req = PySbTx(f'{uri}_apb_req{queue_suffix}', fresh=fresh, max_rate=max_rate)
73
+ self.apb_resp = PySbRx(f'{uri}_apb_resp{queue_suffix}', fresh=fresh, max_rate=max_rate)
74
+
75
+ @property
76
+ def strb_width(self):
77
+ return self.data_width // 8
78
+
79
+ def write(
80
+ self,
81
+ addr: Integral,
82
+ data,
83
+ prot: Integral = None,
84
+ slv_err_expected: bool = None
85
+ ):
86
+ """
87
+ Parameters
88
+ ----------
89
+ addr: int
90
+ Address to write to
91
+
92
+ data: np.uint8, np.uint16, np.uint32, np.uint64, or np.array
93
+ Data to write
94
+
95
+ prot: Integral
96
+ Value of PROT for this transaction. Defaults to the value provided in the
97
+ ApbTxRx constructor if not provided, which in turn defaults to 0.
98
+
99
+ slv_err_expected: str, optional
100
+ Response to expect for this transaction.
101
+ None means, "don't check the response". Defaults to the
102
+ value provided in the ApbTxRx constructor if not provided, which in turn
103
+ defaults to False.
104
+
105
+ Returns
106
+ -------
107
+ bool
108
+ slv_err: True if SLVERR was received, False otherwise.
109
+ """
110
+ (rd_data, slv_err) = self.transaction(
111
+ write=True,
112
+ addr=addr,
113
+ data=data,
114
+ prot=prot,
115
+ slv_err_expected=slv_err_expected
116
+ )
117
+ return slv_err
118
+
119
+ def read(
120
+ self,
121
+ addr: Integral,
122
+ prot: Integral = None,
123
+ resp_expected: str = None
124
+ ):
125
+ """
126
+ Parameters
127
+ ----------
128
+ addr: int
129
+ Address to read from
130
+
131
+ prot: Integral
132
+ Value of PROT for this transaction. Defaults to the value provided in the
133
+ AxiLiteTxRx constructor if not provided, which in turn defaults to 0.
134
+
135
+ resp_expected: str, optional
136
+ Response to expect for this transaction. Options are 'OKAY', 'EXOKAY', 'SLVERR',
137
+ 'DECERR', and None. None means, "don't check the response". Defaults to the
138
+ value provided in the AxiLiteTxRx constructor if not provided, which in turn
139
+ defaults to 'OKAY'
140
+
141
+ Returns
142
+ -------
143
+ int
144
+ Value read, as an arbitrary-size Python integer.
145
+ """
146
+ (rd_data, slv_err) = self.transaction(
147
+ write=False,
148
+ addr=addr,
149
+ data=None,
150
+ prot=prot,
151
+ slv_err_expected=resp_expected
152
+ )
153
+ return rd_data
154
+
155
+ def transaction(
156
+ self,
157
+ write: bool,
158
+ addr: Integral,
159
+ data,
160
+ prot: Integral = None,
161
+ slv_err_expected: bool = None
162
+ ):
163
+ """
164
+ Parameters
165
+ ----------
166
+ addr: int
167
+ Address to write to
168
+
169
+ data: np.uint8, np.uint16, np.uint32, np.uint64
170
+ Data to write
171
+
172
+ prot: Integral
173
+ Value of PROT for this transaction. Defaults to the value provided in the
174
+ ApbTxRx constructor if not provided, which in turn defaults to 0.
175
+
176
+ slv_err_expected: str, optional
177
+ Response to expect for this transaction.
178
+ None means, "don't check the response". Defaults to the
179
+ value provided in the ApbTxRx constructor if not provided, which in turn
180
+ defaults to False.
181
+
182
+ Returns
183
+ -------
184
+ bool
185
+ slv_err: True if SLVERR was received, False otherwise.
186
+ """
187
+
188
+ # set defaults
189
+
190
+ if prot is None:
191
+ prot = self.default_prot
192
+
193
+ if slv_err_expected is None:
194
+ slv_err_expected = self.default_slv_err_expected
195
+
196
+ # check/standardize data types
197
+
198
+ assert isinstance(addr, Integral), 'addr must be an integer'
199
+ addr = int(addr)
200
+
201
+ assert isinstance(prot, Integral), 'prot must be an integer'
202
+ prot = int(prot)
203
+
204
+ if data is None:
205
+ data = np.zeros((self.data_width // 8,), dtype=np.uint8)
206
+ elif isinstance(data, np.integer):
207
+ data = np.frombuffer(data.tobytes(), dtype=np.uint8)
208
+ else:
209
+ raise TypeError(f"Unknown data type: {type(data)}")
210
+
211
+ bytes_to_send = data.size
212
+
213
+ # range validation
214
+
215
+ assert 0 <= addr < (1 << self.addr_width), 'addr out of range'
216
+ assert addr + bytes_to_send <= (1 << self.addr_width), \
217
+ "transaction exceeds the address space."
218
+
219
+ assert 0 <= prot < (1 << 3), 'prot out of range'
220
+
221
+ header_bytes: int = int(ceil((1 + 3 + self.strb_width) / 8.0))
222
+ data_bytes: int = self.data_width // 8
223
+ addr_bytes: int = self.addr_width // 8
224
+
225
+ addr_mask = (1 << self.addr_width) - 1
226
+ addr_mask >>= ceil(log2(data_bytes))
227
+ addr_mask <<= ceil(log2(data_bytes))
228
+
229
+ # calculate strobe value based on the offset and number
230
+ # of bytes that we're writing.
231
+ strb = (1 << data_bytes) - 1
232
+ header = int(write)
233
+ header = (header << 3) | prot
234
+ header = (header << self.strb_width) | strb
235
+ header = np.frombuffer(
236
+ header.to_bytes(header_bytes, 'little'),
237
+ dtype=np.uint8
238
+ )
239
+
240
+ addr_as_buff = np.frombuffer(
241
+ (addr & addr_mask).to_bytes((self.addr_width + 7) // 8, 'little'),
242
+ dtype=np.uint8
243
+ )
244
+
245
+ pack = np.empty((header_bytes + addr_bytes + data_bytes,), dtype=np.uint8)
246
+ pack[0:data_bytes] = data
247
+ pack[data_bytes:data_bytes + addr_bytes] = addr_as_buff
248
+ pack[data_bytes + addr_bytes:] = header
249
+ pack = PySbPacket(data=pack, flags=1, destination=0)
250
+ # Transmit request
251
+ self.apb_req.send(pack, True)
252
+
253
+ # wait for response
254
+ pack = self.apb_resp.recv(True)
255
+ pack = pack.data.tobytes()
256
+ pack = int.from_bytes(pack, 'little')
257
+
258
+ # decode the response
259
+ rd_data = pack & ((1 << self.data_width) - 1)
260
+ slv_err = bool((pack >> self.data_width) & 0b1)
261
+
262
+ # check the response if desired
263
+ if slv_err_expected is not None:
264
+ assert slv_err == slv_err_expected, f'Unexpected response: slv_err = {slv_err}'
265
+
266
+ return (rd_data, slv_err)
267
+
268
+
269
+ def apb_uris(prefix, suffix='.q'):
270
+ # returns a list of the URIs associated with a given APB
271
+ # prefix. For example, apb_uris('apb') returns ['apb_apb_req.q',
272
+ # 'apb_apb_resp.q']. Changing the optional suffix
273
+ # argument changes the file extension assumed in generating this list.
274
+
275
+ return [
276
+ f'{prefix}_apb_req{suffix}',
277
+ f'{prefix}_apb_resp{suffix}'
278
+ ]