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

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (324.5 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.2-cp312-cp312-macosx_11_0_arm64.whl (291.3 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

switchboard_hw-0.2.2-cp312-cp312-macosx_10_13_x86_64.whl (297.2 kB view details)

Uploaded CPython 3.12 macOS 10.13+ x86-64

switchboard_hw-0.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (335.1 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (327.1 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.2-cp311-cp311-macosx_11_0_arm64.whl (291.2 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

switchboard_hw-0.2.2-cp311-cp311-macosx_10_13_x86_64.whl (295.4 kB view details)

Uploaded CPython 3.11 macOS 10.13+ x86-64

switchboard_hw-0.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (333.9 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (325.7 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.2-cp310-cp310-macosx_11_0_arm64.whl (289.4 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

switchboard_hw-0.2.2-cp310-cp310-macosx_10_13_x86_64.whl (294.1 kB view details)

Uploaded CPython 3.10 macOS 10.13+ x86-64

switchboard_hw-0.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (333.8 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (325.8 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.2-cp39-cp39-macosx_11_0_arm64.whl (289.5 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

switchboard_hw-0.2.2-cp39-cp39-macosx_10_13_x86_64.whl (294.2 kB view details)

Uploaded CPython 3.9 macOS 10.13+ x86-64

switchboard_hw-0.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (333.8 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (325.7 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.2-cp38-cp38-macosx_11_0_arm64.whl (289.3 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

switchboard_hw-0.2.2-cp38-cp38-macosx_10_13_x86_64.whl (293.9 kB view details)

Uploaded CPython 3.8 macOS 10.13+ x86-64

switchboard_hw-0.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (336.7 kB view details)

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

switchboard_hw-0.2.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (330.5 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ ARM64

switchboard_hw-0.2.2-cp37-cp37m-macosx_10_13_x86_64.whl (290.9 kB view details)

Uploaded CPython 3.7m macOS 10.13+ x86-64

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 99c9a6a594e84e7cf29c1bfcb3f540ea116df37e3bcfcb93153fa6c33fa2e9b5
MD5 0a1ce255293b943d3ce829607df8cbff
BLAKE2b-256 ee74229cc8f75f986f18b510a134a77916ba6b966cb52580d66bb040fd1c5717

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c0755686d5adf95df92c3d2854e299c313e0e9959ef2b5cf29fca3873d28e926
MD5 3b5d91b06438cb39af15a8b3b016071c
BLAKE2b-256 b28a7fb38957182c84acfaeecb4c1ff5e2196e4c9c3b0d837895f6fcabcd1d6e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a1cea9ecd0615027f9809ada0d1d3da410ff452fb017da4ef3d1e7f5ca4633fb
MD5 e68b6985d18f834c1713640f1d5244fa
BLAKE2b-256 86e2d434cadbf6ba35b825717e8aa95be2264e905b3d5b1b36de812d282d3c2a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 799ee1b8ec58813624389796205d100fcbddaeef59da538aaa9e7df95d8fc7df
MD5 f8effd9e745d534d2bc6ea88742edf24
BLAKE2b-256 53a66f1a2fc7e7b0da9bd9b8b10f2bf7ee38051ab05a0650257f743352536b85

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4021ea384e2b7212a6ca38e9aa5dd10d7254c441e056032c3320aa1a79be0281
MD5 b10695f529f84967d3fd382325a9c645
BLAKE2b-256 53203f175ae055d2251a7d4026867d8f35e2079762ce04614d644c347b945d41

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 2cd72724f881fe0da98c5b94b2734448ba671961d31976eda473cb1b4d98230f
MD5 2d846d42c9b16094fc5bae10bdca596a
BLAKE2b-256 cb6486741d56d87baca44f2403c862fa7a0a510fc93f0e1f28bded9770a3719e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c25cce39928ff50ba977b9d5dd4fae329bf1eb831baaaa1d6c67fc63fee96e6c
MD5 195f00cbd65c69422ca4596103a658c5
BLAKE2b-256 505bcd241a8cedf4f936f2c3e0336da18181b4b3013180977e00d81797e922ab

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp311-cp311-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 9ad0831fd7b4dc4ede7df02f883a0d33b3e06d351854f1db9af78bdcf5550e88
MD5 7e4c8b3ea8a4d4a347440baa0bd1f9ac
BLAKE2b-256 22d9bd0a61f81400a072cd9bee260895b2eb4b13386dc7cecc0b8c70a52506f6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 aa6490cefe00975b155c9c2a8acb17e6f1b24a4d801ead70cd34437ef771f461
MD5 26732171b79c311d9da5ae575d3e875a
BLAKE2b-256 c54945f53287ee245d880f6cf14421791325ea553fea06ffc941f211b0bde647

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 a87f9010746a6cf8617277c33e0094727d72bd1949a87b8dc06f09fbf9c09d15
MD5 bbfe2b74ad7922126cb03cc5ecb707a4
BLAKE2b-256 ea51cb154243e850f31ab576e6abd116bc27e91e9342e60919a4a792de0a631d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c6867371e6793f6f2c1758e82ebc17e415942f456c5c39043985b75bda32477a
MD5 1eea9f32bfda5c5d92047c6483f36c27
BLAKE2b-256 459fd09beb69735f530b9ee42d83b5fe8f746b1745edcf9f1d43932cc75a1a25

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp310-cp310-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 6ed52d73c03309e0697418637124a7e117ee76f20dbbced39f343a9d05c23bef
MD5 b46ae9d15825eb85be4748ccbbf7ec52
BLAKE2b-256 a9ab5e7a18d3fbbe75fb5b8b22d2a2d781013747aa89f860a55122f6ae98a12e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b3dd6efc025d9233b4cc413517476e2a047d44702d39e6bdee99e4b451f428ff
MD5 dafd15ce7ea66e9d7f06a22a79a479bb
BLAKE2b-256 00c81d07203074170b92a00d4b113ccf447d44a2b8755d0995f7b65e267084e8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 85cd1b2a74492e66bd99237d254119a46d54e01798b33af8dd12cc65469301c1
MD5 20b919e17824f671fcd44cd527f1555d
BLAKE2b-256 ac1b7a97c4b88eb0e3db097a9495b27241a08e2cd789146e2b2cec3e61e4713d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 258b717fb2255c8ac2a2bc9ee57544eff20a8fe34e0667acf58fdd669037010f
MD5 ae0006226dd1123001edb767c06aaffd
BLAKE2b-256 bf252f9cadfd1c810e23484c59f7ffa597bd2610c2b2dd677506a417b42cd884

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp39-cp39-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 c40a241c0aa5d0f0bfca5f23305fe2bcf755c8c603a121850f62b868d6e134c2
MD5 65d085e66d9d75cae6771c405468b914
BLAKE2b-256 dabece328cd70decedbbbae6527291e9a6a46cc02c4bfc7f9651277c6330720c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 650c09078ffd68e4a28dcdd264c78c962804c78dc42638d8ee5ed6489d80bc30
MD5 87b010b8f862582d84ec51ce26d40d48
BLAKE2b-256 9d7940205704ba732bcf2c12618145a1eeb41348c352c6b6312008feb47f5c8a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 642faec4a6e89bc9fe3c2ed5dff7dd214e36533697a4ee28dbd130e77aa12601
MD5 4db04d907899c0a1889003242640960b
BLAKE2b-256 5274a72764ee8419f5d1d00d2608dcadf6c050626369cff2654b51623843a3dc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 da5ae31bb6846f98eb934d6ab60c8183bec868343c14e47c0faa39657b2bf7cd
MD5 94320facc0334d3c19420d3a1d3ced9c
BLAKE2b-256 12e9a22930670f03b66e53b4bfeff9cc2cf49073affd2c87ce81cfe11e396ab5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp38-cp38-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 ab49747304885344c4243ebc5dbbd9931c78bb33ff1c25c1969caf99bf6b75e3
MD5 8bd1c0e98b1504533a0f99f0e0b7ec75
BLAKE2b-256 6671796de1d95c49e60d77ebaed3ce580553e08406ce8f20278d627378d45ccd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f52303eabb89bf183a2198906a964f244d0bbbb1f47ea2aa07d4a2db27973d95
MD5 87fba7ab0dd09fce221bb99232971397
BLAKE2b-256 f394907174de2ad5ef192f8d1afaee87d6eecd374ca37e828a257be965e3c0ac

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 2e34d62a745e9b798884fc7d66968d7f9e5f28afe7eb49d40807952eb5d601d6
MD5 3e5b1dd8a7cad3c344014ed5b9aad1bb
BLAKE2b-256 a39867df8a9d22016361c42671f84a01bad3dd4088a8fa87faa61aeaf70ef806

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.2-cp37-cp37m-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 8c91983644cd03e5544bdfb404769aedd8c2cb03d1bf8bba1a3bb8119132b48f
MD5 dd3e1672c1f189d3cf85c0effe227d72
BLAKE2b-256 a8d04a03df000058f6a5c4db28475fd73daf8001485054f2e0a80674eaebb72c

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