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

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (329.7 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.13-cp312-cp312-macosx_11_0_arm64.whl (296.5 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

switchboard_hw-0.2.13-cp312-cp312-macosx_10_13_x86_64.whl (302.3 kB view details)

Uploaded CPython 3.12 macOS 10.13+ x86-64

switchboard_hw-0.2.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (340.2 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (332.5 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.13-cp311-cp311-macosx_11_0_arm64.whl (296.2 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

switchboard_hw-0.2.13-cp311-cp311-macosx_10_13_x86_64.whl (300.5 kB view details)

Uploaded CPython 3.11 macOS 10.13+ x86-64

switchboard_hw-0.2.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (338.8 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (331.3 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.13-cp310-cp310-macosx_11_0_arm64.whl (294.4 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

switchboard_hw-0.2.13-cp310-cp310-macosx_10_13_x86_64.whl (299.2 kB view details)

Uploaded CPython 3.10 macOS 10.13+ x86-64

switchboard_hw-0.2.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (339.1 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (331.3 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.13-cp39-cp39-macosx_11_0_arm64.whl (294.4 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

switchboard_hw-0.2.13-cp39-cp39-macosx_10_13_x86_64.whl (299.3 kB view details)

Uploaded CPython 3.9 macOS 10.13+ x86-64

switchboard_hw-0.2.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (338.4 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (331.3 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.13-cp38-cp38-macosx_11_0_arm64.whl (294.2 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

switchboard_hw-0.2.13-cp38-cp38-macosx_10_13_x86_64.whl (298.9 kB view details)

Uploaded CPython 3.8 macOS 10.13+ x86-64

switchboard_hw-0.2.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (341.2 kB view details)

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

switchboard_hw-0.2.13-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (335.6 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.13-cp37-cp37m-macosx_10_13_x86_64.whl (295.9 kB view details)

Uploaded CPython 3.7m macOS 10.13+ x86-64

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5732ee4271edf1e708cdf9a0f6969ede8cf7adc3383c78a077082ea23224246e
MD5 18c4c153507691e1ce60c3d14c0ef12a
BLAKE2b-256 a8e05c3b8528e414e4d20e8750565d30847cffe0a9ace00cecd7c423dd2ccb02

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 3acab4cb226afeec2e3cd09a0fa1f3a54b84090b78307004299886c8ed4e0ff3
MD5 3ebe186e52936a21ef215f95ec714b49
BLAKE2b-256 a7020daf52797c877eccf298a110857e602118475846a4492d9bbcd8d0803e49

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 07ae7d1a11dfdfd3f7cedbb3524c379779c882c4086c367a5a648f90ee0ad3a1
MD5 af61e50b2af60c004b834615b7baa03f
BLAKE2b-256 a5ca73c00a7cf7b820437ab5275b04f7506677046abba3c7c77aa4364f9378a1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 1c27a33444e95a9dd0a19ac08d572e6f0cf99db31abe412b2dbfe4b54b4eb038
MD5 f40f435569519593201a510b956597c4
BLAKE2b-256 7a16c959da89a3afc4b161eb1c906b00eec256524e73655ebde9a9b5308699c6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f0a4f5ed2111cc90e197976e600a018e515db2993f47dfbda04dd82f85f3871f
MD5 039f89a70d68be7212f49a4655859c5c
BLAKE2b-256 8f4c0d43feb7e1e2ce1400bc4455a896fa0726d598e9068265dcbae8aa93c6da

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 1d8823556343cec4e63a091e18650552b3d81713c24db905722a770c9b2c6a6e
MD5 e29193e9ed9caa971f22ed6703001f70
BLAKE2b-256 0c0c11ae607b5d2cc93f88f7478eaa84f8dc75a972ee6d015ed27322a064aef9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f761bc3b33a4ca7b51f977d83377c71296f64e149a527c191a0bc10c8eb6e2b5
MD5 170303d3f2d7d7a02ded172e1ac7c552
BLAKE2b-256 796ca8cc56ffa248be07f9fc0d0a1901a519018f8e19e364f15a4b0a07a04b4e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp311-cp311-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 0f3c595006ce004bc667b541b633ace2629926c255b0bfa1a4d89e874936fcf3
MD5 7e95388c40d60734579fd1cd33c59672
BLAKE2b-256 0077b35983f32b889f5a807563d48a7d429e32b47936cdce4567c90bbae2245f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 38094fd0eef95e5c6b86bd5313ac62a8e9cffdaf545d9ec65ed1e82a0928118b
MD5 2b8edb4babd5cc9e57ea168099c24830
BLAKE2b-256 64d898e121fef27f03ebe7dbf9f748c27b4663000453e2e4394fef1392aa3326

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 364ff569c34914e1b6e1fae307d4bbbb69ce02230a4b4d88550e6d43cc245b8a
MD5 a6a6882bddf818ff8ca6b32329ed510a
BLAKE2b-256 131103cf31d27d6ad35aa6498938d95b3f70eb4cb2fa004da9f197c5eb2202e5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f472129ab36c825178d8abdb5e88894f2b46fbc7574616f1130f8b17920336be
MD5 54cd8b792628ba0fad83482c9e97c98c
BLAKE2b-256 4a53b5f536f297a38bc1c4277aba10d2a901014262c49b488eec02a3f5b40bc4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp310-cp310-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 eb0ed430e5730c78356728245892f2bdd93596a89cc7c4c26ebf05924bca8aa2
MD5 dff9a0353964366850a888be0e8228ed
BLAKE2b-256 a3115a6d193aacf55faba49e95391fc738455a5bf0a44134f49262708ddcb169

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 79b78c5da76b4cd0d1c89c451640cb119b80d3a468f51b7aa4feb9fa8a95f3cf
MD5 4ae509a51ad5a5eba08d6ccb5dc74245
BLAKE2b-256 f1c4e9e734fb20857baa702fffa5f18b9d3c092e9367e8dfb673bbc99d190c54

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 012ef055ed067e0e312aaa0e50761f90e3944d1ffff34055bea3f652c06f9369
MD5 2221e6dc467e1d62abc84f2b6750816a
BLAKE2b-256 b690194fabe3d26e8bc3d83d35d9f8f48976981a170d00e5acabcf7de3b82eac

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b22f5e5f8dc139f667bce065c52f3455e9a01a59389ec727c5a7a96556fb8eed
MD5 9346cdac99e4d3e098c959bc596f93ac
BLAKE2b-256 dad03d3dbd22f574c54fda3b1a8cc7207d2d55354ed61618a206d7f71c29c0bf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp39-cp39-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 d7961cb207c875fd19eb841c28c0476ea3a2ad210b143510b66ed0d0e265b195
MD5 ba81927cfadea23ca209d5298b4daf7e
BLAKE2b-256 f8dec469904ba139210a47b0d7f74b445eb7edad95786353dbd313cd77b88beb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3e31b3e6f65a434253430382b016e3a67cb34f2ff8239e65a5ca058f78252af3
MD5 be7643be9ea186aaedc2934fbe079f3b
BLAKE2b-256 83eeafc535708e087500fcfe701cf2928362cdc3d2ed8df906879f801106ddc4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 daa2b7ddd11628cc0041530f1b24bd4325c4048b6bc1cbed5a5fd00c697166ce
MD5 5d7d1c1276e4866d495786b9afeb7b21
BLAKE2b-256 c961a3279c4fc435fd8b0c27b1510ab1c5fcb31d5140566c694f30e141ab70b2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 af67873e744c28680f7684ab712f78203ad75734ba9a505fca30ce45a4236096
MD5 7be6e517399caee4c409c448f13e5db9
BLAKE2b-256 e73abac3bf94b3b75b94c1b7bb87de3684746e4f672e6e85d1285e46654b4ec2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp38-cp38-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 339223f4ea53686bf30a7aa482db31bcd39865a7c767151043e52589620baf27
MD5 e885c5ed096b24d192d0f9d078b7696b
BLAKE2b-256 f09c7cb887d50e66ed8fa451edc726c1b564f9195aedf727f078422a762a1e5b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ea6eb6260aa3027cf77f16d79b9583752e393d3c581bc12c29a8dd7690feb9b2
MD5 e54c07f1ed168f419dbcc168c8a5b15b
BLAKE2b-256 7705596b1d2e30c4bafefc3617701bac3b9bb11df5e8d77c47ed238333e369e9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4c0b44ae7ad0c409d4932a8a1538012ba5214dc7b3c96803454a7335e2f0d5a8
MD5 b67f94a0dce715f1dabd61de12a46ee0
BLAKE2b-256 40873188989ec7875d7f7ef8dda9b0c385533dbc084ae247d8f72bb69f9e35d8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.13-cp37-cp37m-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 ee3e283988c333ab18209eb7c6d109e728cbe2973b5b30755bdbdc93e87db7f5
MD5 445df0d0d502eff5c76683e7af7d92a0
BLAKE2b-256 a21947ca01aaa5b82467e1b3d5e043f9bd4e9d5afb10e23bf5cca7ac7012c274

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