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.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (339.2 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.17-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (330.3 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.17-cp312-cp312-macosx_11_0_arm64.whl (297.1 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

switchboard_hw-0.2.17-cp312-cp312-macosx_10_13_x86_64.whl (302.9 kB view details)

Uploaded CPython 3.12 macOS 10.13+ x86-64

switchboard_hw-0.2.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (340.8 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.17-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (333.1 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.17-cp311-cp311-macosx_11_0_arm64.whl (296.8 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

switchboard_hw-0.2.17-cp311-cp311-macosx_10_13_x86_64.whl (301.1 kB view details)

Uploaded CPython 3.11 macOS 10.13+ x86-64

switchboard_hw-0.2.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (339.4 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.17-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (331.9 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.17-cp310-cp310-macosx_11_0_arm64.whl (295.0 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

switchboard_hw-0.2.17-cp310-cp310-macosx_10_13_x86_64.whl (299.8 kB view details)

Uploaded CPython 3.10 macOS 10.13+ x86-64

switchboard_hw-0.2.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (339.7 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.17-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (331.9 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.17-cp39-cp39-macosx_11_0_arm64.whl (295.0 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

switchboard_hw-0.2.17-cp39-cp39-macosx_10_13_x86_64.whl (299.9 kB view details)

Uploaded CPython 3.9 macOS 10.13+ x86-64

switchboard_hw-0.2.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (338.9 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.17-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (331.9 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.17-cp38-cp38-macosx_11_0_arm64.whl (294.8 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

switchboard_hw-0.2.17-cp38-cp38-macosx_10_13_x86_64.whl (299.5 kB view details)

Uploaded CPython 3.8 macOS 10.13+ x86-64

switchboard_hw-0.2.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (341.8 kB view details)

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

switchboard_hw-0.2.17-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (336.2 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.17-cp37-cp37m-macosx_10_13_x86_64.whl (296.5 kB view details)

Uploaded CPython 3.7m macOS 10.13+ x86-64

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e691298313833923219d79e1f885b640c6aaa60634a54e1844832b184dcbae4e
MD5 504b5a257ce93c8605d43c7f7c784d90
BLAKE2b-256 65a01fd0a77745f52109170bbfd09211f393e5b65f13dd76a35f2be84a30042c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 761356b19d0a73f023bf3272914afa0cfeb681e4a513498110c3d155027fa4fc
MD5 7008e4db036e61d1ec08caa686282101
BLAKE2b-256 68d9acc04d550c641108e4ec245715fdcc72b151ca5434c98812d013211c5084

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 010e4b450f176f819cbd20fc8792988ecdba0dd7c1038617498dfdfd91623994
MD5 c4a10ef49249f627c5467d7b57754f09
BLAKE2b-256 a48f2496f4430576913676b6335ac5f9452f29f92265613048b443be26d6891e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 a5e38f69a62a589bb65912f3c3b55f6b3840a4bd731bfd7647962e0b1eda67c5
MD5 6835963447ee6ed35f55bd52c87d37bb
BLAKE2b-256 2c3063924f92b429a2fd453f0ebe6ee6dad85911600243dfe9244a279c7ed256

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b562a7d454a04eb3dfff799029413299d69303c7f39be4a9987723c0b9ba2db4
MD5 5cf62ad6f80ca97133f57fb77434a18a
BLAKE2b-256 facf2d474c43a7a62cb30647d2cb3bab839812d530baa725ee66dc059f227068

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 dc4dda7ec58b9c11376dde459bf0a53a3c3ee20a567bbd5c3cf2b5bcbb3869e5
MD5 8a3c1798856ca056fdd2137cc5f52e13
BLAKE2b-256 576a0721e00ae2f912421b4130b65f6e4c7a0e8498f4e62ae15f37381571650c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c1a74f5bf8ebfe96af270503521d1b91cbd2e84b0d484607f2a67360ac2505f6
MD5 fad3645a39398eb41c6e13611fb83542
BLAKE2b-256 5aa1690738ccd5a6a686bfb30fb079ec8c81c3880490e6e9786c73598136080b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp311-cp311-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 b7236c4447597280ffa999d1526acba7c52987f1e059ad6db5fb888666d750bc
MD5 e04083fa946c20664c1b6de6c113c042
BLAKE2b-256 9d4035f1d7fcaba69f136fbdae1ecd21f81314b1b9d02ca313b4ff8635b4cdf7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 588b622d07ef8df8605c5633851de7622a17989e1ec32afd79fccde64f161db0
MD5 6e1ceeb77a377145e5146f88ffdcd6e0
BLAKE2b-256 882b409adb66ca92335b89719b9a189692f3209b800cf1c7339b8f69ed06aecf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6bac86be6f858f22129558b78a6ca1312bf7aa03a0ff31d51655ee82d0112384
MD5 94a2cf60862cbcccdf0a2a5ee464c7da
BLAKE2b-256 811cf26bfaabab16d90244928e63614178d1966968ef9a432f6f6b79848b3af4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 10b8f1a834a29b050916829aea8ffdc5f84f3e68aa66375de7dbcfd4653170f8
MD5 276cd9e6db9d31c3336f7f5e228c6a9b
BLAKE2b-256 37c84558fae271c99b42486eb50c9429432362914641c19311e9678d199357b0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp310-cp310-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 39eb86167a076fe0e44230fe21cc0c634c040c46927a4ebcd9afa5bb9f378779
MD5 0b1b9e271b30987a52c8ef50f39a7b62
BLAKE2b-256 721fea7c695e92f72e7d5231c88296e671f178f9b49b79c63d122dfddcca429b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 70ab479850113fe2b8d661716a105202b997dc8d928fa50d15e47f6187dc39f5
MD5 9cdaf80072d5c82b29c63a3dd518c315
BLAKE2b-256 5b1ecdb51ba5ea22d099cc3d3f5493da911b5715a7b8bd6655cbc23195fce346

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6923f1b68b30355d169fa62546e799359bf6bbed159e149a7eb60d09311e633e
MD5 8130bef2521657b07f759773e89e26d8
BLAKE2b-256 a494bd428d829fe17d5bcda759d5da493e425bb509f6999a66abfd3d84eb3277

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d39cd45a2f64f12923f53941c2d27d46dd0eb02086b2f26987014f6d731451cb
MD5 b74308cf86e05aeb4d17935f8e8505c6
BLAKE2b-256 4b4711fa266a0e41b9823ab4963603b56ae9d5d6023e6f80e4e5d98fcf542d6d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp39-cp39-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 f0ee280ca1c0a7979b0ccdf9f3fb15a72ba72576aa93cfc97e7c6c51e0728610
MD5 36c03924720f3ca4b2f02841ea192cd6
BLAKE2b-256 a9e0cb63b4f7367ecb3b3a3c812f7bb4595498ab124270f3d8ba8481c8cc009c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 16477a526d63af3fc014307400d8e6771db59d925a4260bdb9afa77baaa52a2d
MD5 da20edc33d900a1f6d0d7e1fd43c6b48
BLAKE2b-256 8c6901f565e98f920550095c425b768bef28776489dd77e2b8748d02ebd2c7ca

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 53ba0cd0f6c35ac1fe295fca5ea3f11c31db8dc98e235e3b6863e11624a25fac
MD5 620e767969a2abc8c5e97cd671eda5ec
BLAKE2b-256 1d27e508ae08f3e72ea41b1248f2f4bd17f99d2f9cb2a30c024a991a13932384

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e730a2d2250f7002935f638ca55834e090576476a981442f697cbf0295491ede
MD5 793c0f788cd96323ae4cf81bd1a24647
BLAKE2b-256 e7b756817379d8f241ffca7963111b36f0bad8bf943c906c7581353240b958d0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp38-cp38-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 d675428705eb47f42578d7a9089b77428e9ffa9a513bbfa4657ab93a90f41154
MD5 97a4da16b43ae97a3fae54bc7c8da2af
BLAKE2b-256 158f3026b596ff252af2578691857d38a8220b7b8a5f97bf7d86b38e63c5d912

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 cb281344cfaca02ee83f9696a20631479dd664a4d76b9b5f9535f890328fb0fd
MD5 79f46cb8ea2397ad91e93458bf7fb07e
BLAKE2b-256 2b2e453266e7d2541f3aabda8d568136cec2981d851e2500283db3f613313b3b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 621799fcd20c3bb4dcb3a5d641968dd3b23ed3028228f49d540f97cb33434ab6
MD5 4c78846ed7cc37ebf3ac8d05a6e0997f
BLAKE2b-256 8a249f3af49c3fd5eaf697ce6895d209594bf8b4093910ec834446f06500dd28

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.17-cp37-cp37m-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 21ef72447b08293517927607b3f7905007a43366f645cf96cb5d4138871ce63e
MD5 8085c07cc93ad0ef6344596812408ea3
BLAKE2b-256 f1951f25bb8815a0185e7ec720a9590ed650246b205da0c2235f1a1e156af24d

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