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.5-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.5-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.5-cp312-cp312-macosx_11_0_arm64.whl (292.6 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

switchboard_hw-0.2.5-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.5-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.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (329.2 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

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

Uploaded CPython 3.11 macOS 11.0+ ARM64

switchboard_hw-0.2.5-cp311-cp311-macosx_10_13_x86_64.whl (296.8 kB view details)

Uploaded CPython 3.11 macOS 10.13+ x86-64

switchboard_hw-0.2.5-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.5-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.5-cp310-cp310-macosx_11_0_arm64.whl (291.3 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

switchboard_hw-0.2.5-cp310-cp310-macosx_10_13_x86_64.whl (295.6 kB view details)

Uploaded CPython 3.10 macOS 10.13+ x86-64

switchboard_hw-0.2.5-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.5-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.5-cp39-cp39-macosx_11_0_arm64.whl (291.3 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

switchboard_hw-0.2.5-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.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (335.9 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

switchboard_hw-0.2.5-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.5-cp38-cp38-macosx_11_0_arm64.whl (291.1 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

switchboard_hw-0.2.5-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.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (338.9 kB view details)

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

switchboard_hw-0.2.5-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.5-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.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9fc719e86ce2aa8fef5568ae94cd26de04dbfef99a87e3f422eaed801b6f49d7
MD5 f0b4f456bdee97339d920250d8766b85
BLAKE2b-256 ee21c59a58ea00a605cb52cd58c377f7e03557d967fe79a621840e11b949b6e4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 2e6709d20b436a6f45aa4ff16268b618ff3f3aad14b144b5fb50d3869f18a096
MD5 efe405a2d377deb411aefbdd64b140aa
BLAKE2b-256 a05a8e3bdb8cee4634542c3c2e78cc4756f2fa1b284341e1a2a347971b859f64

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e7a9b849b7e226c5d1fe22e22e842159118e8f350c6d6702732fd3b6775add54
MD5 d3790f769825db8d3baf4fb69a3adc94
BLAKE2b-256 20fdc59b7a46391305721668801d27849135212d1a7d842063aa4bd1aee299d5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 72076654bf86103de226a959a834dbf3421a93183dc97affbb1694b6fca7f340
MD5 c001be7d7a03456d057c734f1a2abd0b
BLAKE2b-256 47815e2a96189d0dea5ad85f9ff077215559d1a159d64e7b1fafc0732ef3bd60

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 03dec042a5471ea73ab0b7185450b20d25a7a6637439d866a3effdd27f563ceb
MD5 72bfbbe610b1bbd8b35acd938ec9bd13
BLAKE2b-256 65910f9e4566d478572d63eb7f82d1b9049451f6c041f1a81e87278e64f4f066

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 f15257119206c0fc61697efacf42bd7769023ab38b0ea8d39710f5d6a7ad6e06
MD5 5b2f3064556189686b97328a0d562670
BLAKE2b-256 9f2f4d757fe17d2c7cd9f6aa7d3f8fadde92de6e303489b686d23a3a8d90b3b2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 12bcd3de1f101b6473d54e5315f85824e8be0589f2f9fa3e208231305f493f7e
MD5 6e25e147fcac7f54ecb3bcba20d5c266
BLAKE2b-256 899624486ce9326ed6bcad4df3e9fa1bb91b9566a6600e2b6b3b13ae97189ebb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp311-cp311-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 d64209897937f87f60487d95d02dbc1f6c2349f690d6ada9dbbe2eb8faa780fe
MD5 f9521429cd9360879af75328e0cc4d02
BLAKE2b-256 43acf22322b3414a84cacb7272707ac938166a565cfe8c2c8e827bb6de81a483

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 81e4cac05c0fa63aad3e42b49287c974d3639039fc3783d12305abdd31b36644
MD5 d0cc9c7a6da37cca6babfbad5c138494
BLAKE2b-256 d9af7beac8adb39a120591c9cbc5bac273adc9d95bbf1b0045c34fe6eb239e10

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5ad1890e36977c9a421007292b9ca572621efe139838d45f5bf1d272bd158f62
MD5 bbb69d151ec88a224c88ad9b89c12ed6
BLAKE2b-256 3ded6d543ab34a913efca40810369de7a2d7a91bcbe9f9c24c2f48327cdb4af7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f613f8f0da4e3f84d11a510eaf5e151e5d9d37456a4ee912f55b710c890f2c27
MD5 99d56d81755c4d9f303bf9b77b5d3463
BLAKE2b-256 e5771c65d89cfff681922bfd074dcc449cf7ac5ef2161f3dcb3efabc95db5859

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp310-cp310-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 70b152455c5181f91b51305c22acfab21ab5e8c5d5119f429e4592d18d8e7f3d
MD5 4049e6821c45737f1b298beefbe15475
BLAKE2b-256 318e39aef7d535a50ca8a4b7dff4bdf535cb490479c66e0613e374174a17479c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9ee78785fc3a844ef0017427e8da24af0dfed5ad61ee5aef43b14a9f4b224932
MD5 530c48acdba7e366c574d91a41d95dc6
BLAKE2b-256 66d39d4f0ddf3165b4b408a6b72fa3bfb094ea227370a9f47fdc45d345b69806

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5e8866cf07b3069f3c6514916069670a9e7e48dee70f73153c9dd63001f7b7dc
MD5 2364d62998d4d99b81c2688c65722f2f
BLAKE2b-256 665268022c10419f19612f47e8fde0c015d3b6ed9dbb8e9642806bb5d3ed47b5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 42bf0610452d89499d015a4fb814dd7372f803b380d47b56a2badce56a4d744f
MD5 08e23d73a31859c2d942b339a7ca74a0
BLAKE2b-256 23a57c7cc9e81c82c62fb605988109c582bd4d7d2aaa833dc5cb1956dd67b086

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp39-cp39-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 4f2f54986997bb6eb17bae0235b977f9d4d89f91bb3b302af0e33534bbc4bbec
MD5 dcd87116f083a39ad6c400540a712509
BLAKE2b-256 8700d96e6df8a32631157669d2ed9a67c4471f9a258751d6a8b327000aeac361

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 449ffb0e58afd03e914aa939657375e75b234144825e98e3bb019a94ae6e50b8
MD5 7013dca7b92b6f49bccc506831d6e7cd
BLAKE2b-256 1aaef6b3eeca97fb829478ae980ec1aeccd3c3ef3daf4f33f89622870028c2d1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 add41f8977a85dbe73b61fc263c7aaa48405d52ee1b18b7168c1f1afd6d61236
MD5 17e279713d7f43839d63c2b8471d3c52
BLAKE2b-256 6363a2ec70e04a5c011d3aef9c96e002d0c82dccaa42d3c088e22bbabed25811

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f6fd9fa09f378479a3619041d4b84a92a5acd932f0bf0844b6022b4d5e855831
MD5 3eb94a3e8c560ff1735d59ac85253bbe
BLAKE2b-256 cdc725cf72d5bba2b5e2464e73340741902c9caaa01b2639ad7252cd9a33cd9f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp38-cp38-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 63467ad17277e7105a2d1ff28bacd0b1cbf66df068804b0c4fd4fe646a36b8d8
MD5 07a40d8561086401df0bfde5358db6ae
BLAKE2b-256 4c5a28b64cc8450c19d68e0979e247efd17d6ace46050aad299de2c901beb13a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 48679ba963cf8617970e2da94a0bbf5d3ff21311aaa0540289385588b9f4706e
MD5 b829e53d28d86f39204705d47076b22b
BLAKE2b-256 a67c009f309690deeda983471a822c44ead53a2e6e2bbbd45442e3bc1972f9ce

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 78cfb742a02000fb15badc05aeeb66987d86fca3b93b782e34cd846846fe7af2
MD5 fdea1636af9510a2f8827c0ed8145761
BLAKE2b-256 a289a11b9d57f41c477735ccdfaf1b7e6157c60b76eb1a3e1d23626456fcce04

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.2.5-cp37-cp37m-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 4850694e919e92815ebde3025f0fb9236c8b710f175b32203c4cedc2e642e965
MD5 38a5d61356fa37048a58f8ca0449d8d9
BLAKE2b-256 82ae33fe65473a1d4e2c518df96a32c9e28bbe05f33fda521943bd88ce5a1436

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