Skip to main content

A low-latency communication library for RTL simulation and emulation.

Project description

Switchboard

Actions Status Documentation Status PyPI version License

Switchboard (SB) is a framework for communication between distinct hardware models, such as RTL simulations, RTL implemented on FPGAs, and fast SW models. This makes it possible to simulate large hardware systems in a distributed fashion, using whatever models are available for the different components.

In such a simulation, each hardware model has one or more SB ports. Each is unidirectional: it may act as an input or an output, but not both. In addition, each SB connection is single-producer, single-consumer (SPSC): an output port may not drive more than one input port, and an input port may not be driven by more than one output port.

Here's an example of what a switchboard connection topology might look like:

image

The method for adding a switchboard port depends on the language that a HW model is implemented in. For RTL-based models, SB ports are instantiated as Verilog models, whereas for C++ and Python-based models, these ports are instantiated as objects. We provide both a low-level interface for moving data directly between SB ports, as well as a higher-level interface for running UMI transactions over SB connections.

Under the hood, communication happens through shared-memory queues, where an SB output port is driving packets into the queue, and an SB input port is reading from that queue. This standardization is what allows any two kinds of models to talk to each other. A shared-memory SPSC queue is an appealing common interface because it is one of the fastest interprocess communication techniques, with latencies on the order of hundreds of nanoseconds; no system calls are required to transmit and receive data. At the same time, this type of queue is straightforward to implement for FPGA platforms, with queue read and write operations only requiring a handful of memory transactions.

Switchboard also has mixed-signal features that make it easy to incorporate SPICE subcircuits into a system emulation; see the xyce example.

Installation

The fastest way to install this package is from PyPI:

pip install switchboard-hw

However, if you want to run the examples below (or if you're a switchboard developer), clone this repository and install the Python package in-place:

git clone https://github.com/zeroasiccorp/switchboard.git
cd switchboard
git submodule update --init
pip install --upgrade pip
pip install -e .

Examples

Various examples demonstrating the features of switchboard are in the examples folder. If you'd like to run them yourself, please run this command first:

pip install -r examples/requirements.txt

This clones some additional repositories that are needed by the examples.

A good starting point is the python example, where a Python script sends packets to and receives packets from a Verilator RTL simulation. The configuration is simple: there is a small RTL simulation that accepts an SB packet, increments the data payload, and transmits the result on its SB output port. On the other side, a Python script sends an SB packet to the simulation, and checks that the packet it gets back has been incremented.

image

To run this example, you'll need verilator (sudo apt install verilator for Ubuntu, brew install verilator for macOS). You can then run the example by changing directory to examples/python and then typing make. That should produce output similar to the following:

*** TX packet ***
dest: 123456789
last: 1
data: [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25 26 27 28 29 30 31]

*** RX packet ***
dest: 123456789
last: 1
data: [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 25 26 27 28 29 30 31 32]

- ../verilog/testbench.sv:72: Verilog $finish
PASS!

To get a sense of how this works, open the Python script examples/python/test.py. The core logic is essentially:

from switchboard import PySbPacket, PySbTx, PySbRx

...

tx = PySbTx("to_rtl.q", fresh=True)
rx = PySbRx("from_rtl.q", fresh=True)

...

txp = PySbPacket(...)
tx.send(txp)

...

rxp = rx.recv()

In other words, we create an SB output port (tx) and an SB input port (rx). An SB packet is then created (txp) and sent via the output port. Finally, a new SB packet is received from the input port.

To get a sense of how switchboard is used in RTL, have a look at the Verilog part of this example in examples/python/testbench.sv. The core logic is the instantiation of queue_to_sb_sim (SB input port) and sb_to_queue_sim (SB output port), along with the initialization step to define the name of each SB connection. Notice that the Python output port is matched to the Verilog input port (to_rtl.q) and similarly the Python input port is matched to the Verilog output port (from_rtl.q).

`include "switchboard.vh"

...

`SB_WIRES(to_rtl, DW);
`QUEUE_TO_SB_SIM(to_rtl, DW, "to_rtl.q");

...

`SB_WIRES(from_rtl, DW);
`SB_TO_QUEUE_SIM(from_rtl, DW, "from_rtl.q");

Using the same name for two ports is what establishes a connection between them. You can use any name that you like for a SB connection, as long as it is a valid file name. The reason is that SB connections are visible as files on your file system. After this example runs, it will leave behind files called to_rtl.q and from_rtl.q. It's convenient to name SB connections in a way that is amenable to pattern matching, so that you can do things like rm *.q to clean up old connections.

We encourage you to explore the other examples, which demonstrate simulation with Icarus Verilog and switchboard's C++ library (minimal), bridging SB connections via TCP (tcp), and switchboard's UMI abstraction (umiram).

Build automation

We also provide build automation powered by SiliconCompiler that makes it easy to build RTL simulations with switchboard infrastructure (queue_to_sb_sim, sb_to_queue_sim, etc.). This is mainly important because Verilog DPI and VPI are used under the hood, requiring certain flags to be passed to the RTL simulator during the build. Using our build automation lets you focus on specifying RTL sources, without having to deal with these details.

As an example, we return to examples/python. The basic logic for a Verilator build is:

from switchboard import SbDut

dut = SbDut('name-of-top-level-module')

dut.input('path/to/file/1')
dut.input('path/to/file/2')
...

dut.build()

dut.simulate()

In other words, create an SbDut object, input() files, build() it to compile the Verilator simulator, and use simulate() to start the simulator. SbDut is a subclass of siliconcompiler.Chip, which allows you to invoke a range of features to control the simulator build, such as specifying include paths and `define macros. More information about siliconcompiler.Chip can be found here.

Packet format

An SB packet is a simple data structure with three parts, defined in switchboard/cpp/switchboard.hpp.

  1. A 32-bit destination.
  2. A 32-bit flags bit vector. Currently only bit "0" is used, providing the last flag.
  3. A 416-bit data payload. This width was chosen to accommodate a UMI packet with a 256 bit payload, 64-bit source and destination addresses, and a 32-bit command. In the future, we may support parameterizable data widths for switchboard connections.

destination and flags control how the packet is routed. destination indicates the intended recipient of the packet as a flat, unsigned 32-bit integer. This provides a mechanism where a packet can be routed through multiple hops before reaching its final destination.

For example, consider using switchboard to build a simple topology in which packets can be sent from one HW block to one of two other blocks. One could indicate which block should receive the packet using the destination field, with a router transmitting the packet to the right one.

image

The last indicator (part of the flags bit vector) indicates whether there is more to come as part of a transaction. The rule is that a transmission cannot be interrupted as long as as last is zero. As an example, consider the system below, where Block A and Block B are both sending SB packets to the same port on Block C, using a router to multiplex between the two. Following the rule of unbroken transmissions, if the router starts sending a sequence of packets from Block A to Block C, it cannot switch to sending packets from Block B to Block C until it gets a packet from Block A that has last set to one. It is legal to have last=1 set in all packets, meaning that packets can be interspersed at any time.

image

The purpose of last is two-fold. For one, it simplifies the process of transmitting "burstable" protocols such as UMI through switchboard. It also provides opportunities for performance optimization. For example, if a long sequence of SB packets is being sent over TCP, the TCP bridge knows it can wait to fill up its transmission buffer as long as last=0. Without the last bit, the bridge would have to send each packet one at a time (or speculatively wait for more packets), since any given packet may be the last one.

UMI interface

In addition to supporting data movement directly through SB packets, we provide a higher-level interface for running UMI transactions over switchboard connections. The mechanisms for this can be seen in the examples/umi* examples. Here's a sketch of what UMI transactions look like, adapted from the definition of python_intf() in examples/umiram/test.py:

from switchboard import UmiTxRx

umi = UmiTxRx(from_client, to_client, fresh=True)

wrbuf = np.array([elem1, elem2, ...], dtype)
umi.write(wraddr, wrbuf)

rdbuf = umi.read(rdaddr, num, dtype)  # also a numpy array

We are no longer creating PySbTx and PySbRx objects, but rather a single UmiTxRx object with two SB ports: from_client, and to_client. Transactions are sent by the Python script through the from_client port, and responses are received back through the to_client port.

UMI write transactions are generated with the umi.write() method, which accepts an address and numpy array or scalar as arguments. This sends out one or more SUMI packets to implement the write request, packing the data, source address, destination address, and command into SB packets. Since an SB packet is 416 bits, and the two addresses + command take up 160 bits, each SB packet contains up to 256b data. Switchboard automatically splits up larger transactions into multiple SUMI packets as needed, incrementing the source and destination addresses automatically. Optional arguments to write() control where a ack'd or non-ack'd (posted) write is used and the maximum amount of data to send in a single SUMI packet. If an ack'd write is used, write() blocks until the response is received.

In a similar fashion, umi.read() reads a certain number of words from a given address. For example, umi.read(0x1234, 4, np.uint16) will send out a UMI read request with dstaddr=0x1234, LEN=3, SIZE=1 from the SB port from_client. When it gets the response to that query on to_client, it will return an array of 4 np.uint16 words to the Python script. A umi.atomic() method is also provided to generate UMI atomic transactions.

Sometimes it is convenient to work directly with SUMI packets, for example when testing a UMI FIFO or UMI router. For that situation, we provide send() and recv() methods for UmiTxRx, highlighted in examples/umi_fifo/test.py. In that exampe, we are sending SUMI packets into a UMI FIFO, and want to make sure that the sequence of packets read out of the FIFO is the same as the sequence of packets written in.

The main while loop is essentially:

txq = []

while ...:
    txp = random_umi_packet()
    if umi.send(txp, blocking=False):
        txq.append(txp)

    rxp = umi.recv(blocking=False)
    if rxp is not None:
        assert rxp == txq[0]
        txq.pop(0)

In other words, first try to write a random packet into the FIFO. If successful, add it to the back of a list of outstanding packets. Then, try to read a packet from the FIFO. If successful, make sure that the packet is equal to the oldest outstanding packet (since this is a first-in, first-out queue) and remove that outstanding packet from our records. Continue in a loop until a sufficient number of transactions have been checked.

This code example demonstrates several features:

  1. send() and recv() for working with SUMI packets, represented using PyUmiPacket objects.
  2. blocking=False for non-blocking transactions. send() returns True if successful and False otherwise; recv() returns a PyUmiPacket if successful, and None otherwise. A transaction might be unsuccessful if the underlying UMI FIFO is full or empty. For example, if we don't call umi.recv(), eventually the FIFO will fill, and subsequent send() invocations will fail (returning False). Similarly, if we keep calling umi.recv() without calling umi.send(), eventually the FIFO will be empty, and umi.recv() will fail (returning None).
  3. The ability to generate random SUMI packets with random_umi_packet(). Various optional arguments can constrain the opcodes, addresses, and data.
  4. PyUmiPacket objects can be compared using Python == and != operators. This checks if two packets have equal commands, addresses, and data.

Queue format

Under the hood, SB ports are implemented using shared memory queues. The data structure used is made simple enough that RTL running on FPGAs can directly read and write to these queues, without the need for bridge programs. In fact, if two FPGAs have access to the same memory space, they can communicate through a shared memory queue without any involvement from the host operating system, after the initial setup.

The layout of the queue is:

  • Bytes 0-3: head (int32)
  • Bytes 64-67: tail (int32)
  • Bytes 128-179: SB packet
  • Bytes 256-307: SB packet
  • Bytes 320-371: SB packet
  • ...
  • Bytes 4,032-4,095: SB packet

To write an SB packet to the queue, compute next_head = head + 1. If next_head equals 62 (the end of the queue), then set next_head to 0. If next_head equals tail, then the write fails - the queue is full. Otherwise, write the SB packet to address 128 + (64 * head), and then set head to next_head.

Reading an SB packet works in a similar fashion. If tail equals head, the read fails - the queue is empty. Otherwise, read the SB packet from address 128 + (64 * tail), and then increment tail. If tail equals 62 (the end of the queue), then set tail to 0.

The queue implementation in C is in switchboard/cpp/spsc_queue.h, with care taken to avoid memory ordering hazards, and various cache-oriented optimizations. The queue implementation in Verilog (intended for FPGA-based emulation) can be found in switchboard/verilog/fpga/sb_rx_fpga.sv and switchboard/verilog/fpga/sb_tx_fpga.sv.

License

Apache 2.0

Contributing

switchboard is an open-source project and welcomes contributions. To find out how to contribute to the project, see our Contributing Guidelines.

Issues / Bugs

We use GitHub Issues for tracking requests and bugs.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

switchboard_hw-0.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (335.6 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (326.6 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.4-cp312-cp312-macosx_11_0_arm64.whl (292.6 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

switchboard_hw-0.2.4-cp312-cp312-macosx_10_13_x86_64.whl (298.0 kB view details)

Uploaded CPython 3.12 macOS 10.13+ x86-64

switchboard_hw-0.2.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (337.2 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (329.1 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.4-cp311-cp311-macosx_11_0_arm64.whl (292.6 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

switchboard_hw-0.2.4-cp311-cp311-macosx_10_13_x86_64.whl (296.7 kB view details)

Uploaded CPython 3.11 macOS 10.13+ x86-64

switchboard_hw-0.2.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (336.0 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (327.8 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.4-cp310-cp310-macosx_11_0_arm64.whl (291.2 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

switchboard_hw-0.2.4-cp310-cp310-macosx_10_13_x86_64.whl (295.5 kB view details)

Uploaded CPython 3.10 macOS 10.13+ x86-64

switchboard_hw-0.2.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (335.9 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (327.9 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.4-cp39-cp39-macosx_11_0_arm64.whl (291.3 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

switchboard_hw-0.2.4-cp39-cp39-macosx_10_13_x86_64.whl (295.6 kB view details)

Uploaded CPython 3.9 macOS 10.13+ x86-64

switchboard_hw-0.2.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (335.8 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (327.8 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.4-cp38-cp38-macosx_11_0_arm64.whl (291.1 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

switchboard_hw-0.2.4-cp38-cp38-macosx_10_13_x86_64.whl (295.4 kB view details)

Uploaded CPython 3.8 macOS 10.13+ x86-64

switchboard_hw-0.2.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (338.8 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (332.6 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.4-cp37-cp37m-macosx_10_13_x86_64.whl (292.1 kB view details)

Uploaded CPython 3.7m macOS 10.13+ x86-64

File details

Details for the file switchboard_hw-0.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 251b4b40636ba8d154c43bc8ce99be9550a424dc159ad96ed7bf7abe54b1377e
MD5 43a28b012a5df7dec4a0eb51e55d42b5
BLAKE2b-256 2c208f7984847f788f09a1bd90b65a260fe6c4f459c568c66c9791b1fa7e9659

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d8b198a5b1f3c11d772978d82c9290ef436068bbcbb5f10993dccb80df515475
MD5 29e586131ce23ed9a8739f2a6d62fc31
BLAKE2b-256 c6a8bd0d091e50b9c601efe2bb367949037f508c9674789be1d1eb01a8e92628

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d8e9fd15ec493bceba0cf2693ff4c77493f07eabec872dd6fd61f427bb7a8070
MD5 102f889a6553e20bf39a71b0184662c2
BLAKE2b-256 19f716277939c4d11430e7e72aa15d6e2adbbe5947067595293adeae79d2d188

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp312-cp312-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 edede60c4d7a188289835fd0ed9a3e3f248f96d67df8dd3b3382f4733e1c46bf
MD5 de5e1e89f881553e0e8e7cf1dd7c8c0b
BLAKE2b-256 a0e9e72d05703034da4851370ee8b9abfae590c6eb43a513296755c0e6d2c04b

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2d0e0ff3642e2381b658a681c1b1390ec82f446e3a9a2e45c7e1d5624ca82417
MD5 c62149e580024250016627bd8d8e52c7
BLAKE2b-256 53b14206f4a547a0ef68e93d7011241aa239c521bc86229fab17c173c4ad1c9f

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 78e59bad6da790a7c8ba5d59c9f509d59628f6ccb9053ca419308e0162fa8967
MD5 c024430a399e5b3c59b7f9c3c8a0a366
BLAKE2b-256 5d78847cd116208360fb2ec793f7f8806cb61a84a449d4590ac640feddcf7afe

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5cdf7a28f9bfbbc04c3bcf07dcfd4d74762527fd73e13d9cad6dc06769900a53
MD5 5de2d9ce77553300fd88dcc1a7b14154
BLAKE2b-256 cf03156c1a46465782d9033d95015a8fd2de1a3eaf0cacb89de7f8251b5ec555

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp311-cp311-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp311-cp311-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 b3b79393f02f1e391b3d8f5151db029d9d066495727236e8c0d477e46b23c676
MD5 bd7ac2b56924d2bf1d8feabbd8556691
BLAKE2b-256 d972aeff2b81140178bed93fc2d67984ed10633e68ba7fc8da10ba32fbd4b16d

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 439887766a33b315af85722daafb6b0cb09c4ab99fdef00bc3f387f123ec77d0
MD5 7f99b47908b214c521b132ca2a2aba3d
BLAKE2b-256 9c26e291ed2ee308a3a9d740eba30758e9fb9ebc1f1c8023097783c6849a787f

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 826d05c5ffde17ac19836dda2ff1bc70d9fa1e2e1f80887dbbeccbb4cb1760f3
MD5 f1db0dae119a615ecd7fd3fdf281ea97
BLAKE2b-256 97e09d47d41dbfd368530af167361a405d1ec97a56f4523687bc9629454ee680

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8c76318c4fe784a32206b6182106319274e5efd33b6fe0c70e5c3b6b3bcd2253
MD5 42634bf76e6d9961409e8ad49c749b32
BLAKE2b-256 21f02137780265cc9202f2d7c1766308b47c82dfa0fefc6f6d6b8a45608466ec

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp310-cp310-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp310-cp310-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 78136e304badc00b2ecef19d2dc355322af30ff43629b9ec39a5f0a9be8e8c2e
MD5 4e9dc3ba54e70541dc1167ac82b0942b
BLAKE2b-256 86a1b4d49264b3d3e048feb646da1318f574128e4d0488429333deedb1c2cfd4

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9faa6f36d1438314f18fe3d5e7f8838d89d93c1bdd60d42540afb8075498a3b6
MD5 c774a5a11d688575882b60e95209c38f
BLAKE2b-256 fa75fcc2be1aeb4e2f9a610f2a7f3eb15c2d12927bc2302e342c076a7a5a980a

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d6680ad0bb79781ac5b49c7f044adb006633b3f6926b3457444805010c95bfcf
MD5 4f6bb323317b8f7496ab2af50ad2e841
BLAKE2b-256 0a61af0add75f6a416032254fa7d13a4a5ab0f214bde84bbd46e056bfcd3fa5a

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0d7ee7b1723cad3bf1a9a30dc83b0716007fccc1cb4a975089e2fa110e38277c
MD5 9a07e635e454ac145516d9776eaf8208
BLAKE2b-256 e0fda1e74b1de5ba9e398a81877a7cf4139dd5b6a2739af72ebc990b96d34ed6

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp39-cp39-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp39-cp39-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 78b30a3adeb1ba2d2c1be1390886ff63d8021522c60c1cbe5000b4f4d1e76e60
MD5 aab14e55d7d21efb3e20b91d1d02953e
BLAKE2b-256 e075844a12e6e7b2825b887e0ebb530466671651f7e8be01515d09f1572684b7

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 00c673f961e1a7fe71b18f90629e365ef37136b3b5ce05c0beaf853d35be54bd
MD5 1b5c0fda3052e83f2503499cb49822cc
BLAKE2b-256 3084e3497451d46ad1d222db6ff7246e34efe4ed943d3a9891a1e78b576a0e0f

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 04790350a0c87a0125bba68e25ab9352aca0455ae608d70db45a0d05f0fd37d1
MD5 b2c26520dcc555e1211c117b832d335d
BLAKE2b-256 cb3c3a83bd903b692e73ce7c66008250c30db3edcbb81d1e24b7b49f52c97121

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp38-cp38-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 953a8dcf91ff4aaece674b0c5bd9c9727304d7c68cf4ddab74ab4385aaddd98f
MD5 e04bbaa18be9a7f5c1e93eae69254857
BLAKE2b-256 7e8f9e76715227d1f8381a17badddc292ff7980b116a3c7d98691bd97f8cb357

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp38-cp38-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp38-cp38-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 674ff793de17f1522c12759022ebac727c4eb5004621be1a56897ca1548c36ab
MD5 08d6ad32a0ea72c33e8aa470eabb2f17
BLAKE2b-256 52644bd1c5fb68eb05c1ad241d883bcdb3bf73e9f559d80f6a6860a87d00387d

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2ca93d43bee1c8b35b1a47c9b223df370e71f0e08600cbfb8144afcb436c292f
MD5 c9880f60b847e7c1b5295f6db20f5277
BLAKE2b-256 95d8625ebc9c4bd9a661b616fdc5b330b34973fd38de23cf7a2dcd4ea33cccf7

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5fccf66d25f7abec181e02357290f677a7f3e30fe858ba553ecdd279b0f062a9
MD5 a949c53910780184371c61d7b1fd9250
BLAKE2b-256 50f4a9cf06a2220fd303e8cf0cd62a447363f9c2bab11335c7bc937f9fa1e975

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.2.4-cp37-cp37m-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.4-cp37-cp37m-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 325486bda8b893dae9353794d09069b9c17107a8d35bbdb0aac3f5f367c119c3
MD5 043b8a20335552fda055958992afec4d
BLAKE2b-256 2f2e2d9896539b6fa84204ddc9205f64c3b5d2e3d546c0d2c8c5c52146e50a72

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page