Skip to main content

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

Project description

Switchboard

Actions Status Documentation Status PyPI version License

Introduction

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.

For an in depth explanation of the theory and philosophy behind Switchboard, we recommend reading the paper Switchboard: an Open-Source Framework for Modular Simulation of Large Hardware Systems".

If used for research, please cite Switchboard by the following publication:

@misc{herbst2024switchboardopensourceframeworkmodular,
      title={Switchboard: An Open-Source Framework for Modular Simulation of Large Hardware Systems},
      author={Steven Herbst and Noah Moroze and Edgar Iglesias and Andreas Olofsson},
      year={2024},
      eprint={2407.20537},
      archivePrefix={arXiv},
      primaryClass={cs.DC},
      url={https://arxiv.org/abs/2407.20537},
}

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

If you're not sure about the file name format, learn more about wheel file names.

switchboard_hw-0.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (342.2 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

switchboard_hw-0.3.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (379.1 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ x86-64

switchboard_hw-0.3.3-cp314-cp314t-macosx_11_0_arm64.whl (341.8 kB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

switchboard_hw-0.3.3-cp314-cp314t-macosx_10_15_x86_64.whl (347.0 kB view details)

Uploaded CPython 3.14tmacOS 10.15+ x86-64

switchboard_hw-0.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (339.3 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

switchboard_hw-0.3.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (375.4 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

switchboard_hw-0.3.3-cp314-cp314-macosx_11_0_arm64.whl (329.3 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

switchboard_hw-0.3.3-cp314-cp314-macosx_10_15_x86_64.whl (335.9 kB view details)

Uploaded CPython 3.14macOS 10.15+ x86-64

switchboard_hw-0.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (338.1 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

switchboard_hw-0.3.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (375.3 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

switchboard_hw-0.3.3-cp313-cp313-macosx_11_0_arm64.whl (328.9 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

switchboard_hw-0.3.3-cp313-cp313-macosx_10_13_x86_64.whl (336.1 kB view details)

Uploaded CPython 3.13macOS 10.13+ x86-64

switchboard_hw-0.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (338.4 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

switchboard_hw-0.3.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (375.2 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

switchboard_hw-0.3.3-cp312-cp312-macosx_11_0_arm64.whl (328.7 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

switchboard_hw-0.3.3-cp312-cp312-macosx_10_13_x86_64.whl (336.1 kB view details)

Uploaded CPython 3.12macOS 10.13+ x86-64

switchboard_hw-0.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (336.5 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

switchboard_hw-0.3.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (375.7 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

switchboard_hw-0.3.3-cp311-cp311-macosx_11_0_arm64.whl (327.2 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

switchboard_hw-0.3.3-cp311-cp311-macosx_10_13_x86_64.whl (332.8 kB view details)

Uploaded CPython 3.11macOS 10.13+ x86-64

switchboard_hw-0.3.3-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (334.7 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

switchboard_hw-0.3.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (374.7 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

switchboard_hw-0.3.3-cp310-cp310-macosx_11_0_arm64.whl (325.8 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

switchboard_hw-0.3.3-cp310-cp310-macosx_10_13_x86_64.whl (331.5 kB view details)

Uploaded CPython 3.10macOS 10.13+ x86-64

File details

Details for the file switchboard_hw-0.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 595078d61625b0773b272bc70efc15c7eeff2c34dc46b144131a14614bb6671f
MD5 683d7d82202d50523355d829cc07f985
BLAKE2b-256 b458143fa233ecbb7d5b43711fbbbe9000081a52fc0e65f7e6922e1342224550

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 1a0b4625643134d92d2c9e866f047c708901975227c16ea2d8d69ff7450062db
MD5 6e25087f99bfcec290d809182bd33d37
BLAKE2b-256 41426d7d243f4672f63b354566e2cfe87877f41cb463a78c4a6d27c27942e5b6

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp314-cp314t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1ac0615723f234e13854c3cc04c7e4a08f7f2ca683cd2d38b7e2ceff58b7dd0e
MD5 8cf16a0f1752903f6a1502bfec6236df
BLAKE2b-256 575849df6eabbf05b479d67e76ec3da410b34bd2caef2af713987d6372da2183

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp314-cp314t-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp314-cp314t-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 b9b918c52b0ba63730ebeb89ec3eacd39bd71c1d3765dae2c07ac85c9c328326
MD5 c883e1ed7ab9e0675b741896f7f37954
BLAKE2b-256 38a047b1b76e0f76e98eacc13fe3cd184e6f248ff765155657c7185a10a30aac

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a21483547e8a95b70b332c360832d7825654e60d87e015a0995c7fea2d6e5cc6
MD5 42f6e258a5222094a426fefed2c89fb7
BLAKE2b-256 6411f66f43ed2c1e8338a616fc9d028852d9c93207dfd3df1a062ddfd9489379

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 fae815977f64fc26d2e3421f143f0fe785767d59681e4319c25c27424a5a4a7b
MD5 0c9368025e78dd74ef4a13e4b6fef338
BLAKE2b-256 da328a4ad935a54678ffef05f9dfbf9df44866636f84ba61d1b72e5f11e518d1

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5dba7c5f6d3c85a66075eccae27e584f6c692711e7ded1fdf7f69822aa030b2a
MD5 9d04906a31dcdf34be2d109f15e4ca17
BLAKE2b-256 6ca0c78a683d69499b3ac4de7efa226b1291c1ba3f1b502e330a5790d980ab80

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp314-cp314-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp314-cp314-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 05a4c307ea4369a61a67c771c45ad2cccb8ed5d3bf184f086e1c6e2dd1a62cb0
MD5 84c72799cdf793803b2c45cfdb4d6073
BLAKE2b-256 c6e6ebbce330565512f4fe654f41024295c85ab6de31d25a55694734f8488895

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 b471f9233f3428b9865833f224237ce0042794412236c366dfe7cc62f6e25298
MD5 34524458bc137278acfaa6d4fd077ec0
BLAKE2b-256 d43ffd1879a550a17069618a437e7395067148db591a64090e1ed87c7d3b550a

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 5d9ce8ff9e7656a71c53ce7644b671e0749f7dfcf0cf07dfda25b0a69d52549d
MD5 dabe6cef5e2edfa430220586f72a89e6
BLAKE2b-256 cfc602b54620415b1d3ba52fd78a37891eb678970b7d85bce64feeaeaefc57bf

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0f361206f4e683359c657eaed65bb42f2e0d95c4108fa9b8944c5cd7e61cb9e5
MD5 9e7db324159640e7db3a3c3b55a02860
BLAKE2b-256 c50c90fc7543afdcd57f95fd81f21045ae1eeec6e60ad5da4bd7cc6be1d617c1

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp313-cp313-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp313-cp313-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 04c159fb094c71225f87997a4dba90eecc746227d83396c2cac8dc5d844ac77e
MD5 ae992c77c631497d37d5114e23d56728
BLAKE2b-256 9f4ed7d84c091b6bc892d6eabb1da6bc8961ae07722542bd29fd14431cbbb268

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7d330e0006047ec1d1e3a867cca6df643314252f916d59fd0addc639bf1f0615
MD5 899deeaab9d16ea40d7b9d80799cbfa4
BLAKE2b-256 e5d533e6f61fbe3bc7fc2a858baae0297f4540171cd2846bab3a9fc419cb8da4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 72a9777d6d7bcb7e59b68a56a82087905a569a12badfd70d95a939d9a69c1e86
MD5 9122946e65f91b62494019b4ec7c35f9
BLAKE2b-256 11dde2847f4fde481f541232cd9cde44bf73a70a54060f9ef56d5e6f2c363db4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 03962040d0c48f2c3f2f882540c56dee5075a3e0fd426ebbab757f1a42d534eb
MD5 1e70186fa2fcea3beacb8bd857618e46
BLAKE2b-256 c6842ee39c072c69757b945da03cb51990f5408cedcc7402fd3fc49da2b2dce0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 afd89b390a56a2c2ff0ca41af9b7fc77ef4c0a3dcf433d6583a306026b0422e3
MD5 4b09b01c6dd1927a0e50bec0d0b101ed
BLAKE2b-256 d12549c535dd639efb6f44bc1375d36f2b0d74d04accd26cff1a58ee37804af6

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 876753f92477ea6782613e7de6cc57928f7bcd89ddfd9f54a13c6a85ad24d282
MD5 ac57ac03bf0e618039cd058a669e1a05
BLAKE2b-256 2a4f1ffed84d3751d03e411d67626d885d98a63d28c070a77633735f504afaf8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 550261b85810a177a47b02381c7ddf9e279171a37a40f7a42f9bf2b8068fe7c4
MD5 3331dc1dbb7e1f5b7ba15b1268f85fd7
BLAKE2b-256 9822bd447629a72f2e6b7bdfac24c2c9b956e5f42eeb6e65b88262474cbef54b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9c0042d4d381338bb02783ad077c821df12a8259573b9988b79acdd2c6855f16
MD5 acdbd74329e1ddeacf9cacb68c9a1518
BLAKE2b-256 356ba17bcba30223b44f852c6ee11e4e0eb6c10c46a77b3d6ecea35409744e51

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp311-cp311-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 4b848e142fab84e9fe317515f7a6c3c55be7675bb1d69f72e86fe9e86b0505e1
MD5 9ae56c32b7736bdf7ba3942dfc090e12
BLAKE2b-256 5826f2995571cf858900ce1c952f9efb99acaec4f20bbaa7695290a680257db2

See more details on using hashes here.

File details

Details for the file switchboard_hw-0.3.3-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 128515186a9576a58b13f035563f1a69f563ac126c86fed5a187384ce7eb4ad1
MD5 2973dee49780305d4a2d9e21aede685d
BLAKE2b-256 a00d306c0204c7ecbf79dd31f267c931f7a59f5230c222e1d7f98439c119028c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 480e45339605d4c490c22b8cee2c143ecb977bda8235931383b56b28c9ab781c
MD5 8f348da2c2476e9152fe0f4c7ee22a97
BLAKE2b-256 81caaf85e2a09427eddd3dde6868c7a25bf625836d0006731501880f8c844f2f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fb0e703db03a979aff25cf59829b98b6a13dea9727bb9370637aeb70335260ed
MD5 1df5b0fab4aeaf68ca6f43da3c3655c8
BLAKE2b-256 1c1bfbb27964ace99285cfdca169da13e30f385abccc01488334011f72c6124c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for switchboard_hw-0.3.3-cp310-cp310-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 a185689922c507d0db217884bce43790158dcdf3f3606be8ef15172c3dffb6f1
MD5 98cbbe872b4d0e936a303f286b3eb3f5
BLAKE2b-256 d8301e5666eff4dbf3ca800576df3f7609c0b6b4cb8bc0858ced8592e83ede7c

See more details on using hashes here.

Supported by

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