# `wishbone-tool` - All-in-one Wishbone Binary and Library `wishbone-tool` is useful for interacting with the internal Wishbone bridge on a device. Some of the things you can use `wishbone-tool` for: - Peeking and poking memory, similar to using `devmem2` - Testing memory and bridge link quality - Exposing a Wishbone bridge to Ethernet - Attaching a GDB server to a softcore Currently-supported Wishbone bridges include: - **USB** - For use with Valentyusb such as on Fomu - **Serial** - Generic UART, nominally running at 115200 (but can be changed with ``--baud``) - **SPI** - Using 2-, 3-, or 4-wire SPI from [spibone](https://github.com/litex-hub/spibone) - **Ethernet** - Both TCP (e.g. a remote copy of `wishbone-tool`) or UDP (via Etherbone) - **PCI Express** - Using a PCIe softcore with the CSR register bank exposed ## Binaries Precompiled versions of `wishbone-tool` can be found in the [Releases](https://github.com/litex-hub/wishbone-utils/releases) section. ## Building To build `wishbone-tool`: 1. Install Rust and Cargo. The easiest way to do this is to go to and follow the instructions. 2. Enter the ``wishbone-tool`` directory. 3. Run `cargo build` or `cargo build --release` The `wishbone-tool` binary will be located under `target/debug/` or `target/release/`. ## Usage By default, `wishbone-tool` will communicate via USB, attempting to open a device with PID `0x5bf0`. It will also run the `peek/poke` server, allowing basic manipulation of memory addresses on the target device. ### USB Bridge Simply run `wishbone-tool [ADDRESS]` to peek at a particular address. To specify a particular vendor ID, pass `--vid [ID]`, for example `--vid 0xb0f1`. To read from an area of memory (such as 0x10000000), run: ```shell $ # Read from address 0x10000000 via USB $ wishbone-tool 0x10000000 INFO [wishbone_tool::usb_bridge] waiting for target device INFO [wishbone_tool::usb_bridge] opened USB device device 019 on bus 001 Value at 00000000: 6f80106f $ ``` To write a value to memory, add an additional parameter: ```shell $ wishbone-tool 0x10000000 0x12345678 INFO [wishbone_tool::usb_bridge] opened USB device device 019 on bus 001 $ wishbone-tool 0x10000000 INFO [wishbone_tool::usb_bridge] opened USB device device 019 on bus 001 Value at 00000000: 12345678 $ ``` ### Serial Bridge You can connect to a serial port by specifying the `--serial` argument: ```shell $ wishbone-tool --serial COM4: 0x00000000 Value at 00000000: ffffffff $ wishbone-tool --serial /dev/ttyUSB0 0x00000000 Value at 00000000: ffffffff ``` Ensure that you have write permission to the serial port. On some Linux systems you may need to add your user to the `dialout` group. ### Ethernet Bridge To connect to an Ethernet device, pass the `--ethernet-host` parameter: ```sh $ wishbone-tool --ethernet 192.168.100.50 0x00000000 Value at 00000000: ffffffff ``` To connect to a different port, add `--ethernet-port PORT_NUMBER`. Finally, if you would like to connect to another copy of `wishbone-tool` or to a copy of `lxserver`, add `--ethernet-tcp` to switch the connection from Etherbone to TCP. ### PCIe Bridge If your device is connected via PCI Express, you can specify a PCIe BAR with `--pcie-bar FILE_PATH`. This will be a device under `/sys/bus`. Note that when running in PCIe mode, only a small portion of the memory space is exposed. This means that you may need to specify `--register-offset OFFSET`, because e.g. address 0 in the PCIe BAR may actually correspond to address 0xe0000000, and `wishbone-tool` needs to know how to perform the translation. ### SPI Bridge If you specify `--spi-pins`, `wishbone-tool` will communicate with the target device via SPI. This is currently only supported on Raspberry Pi. Specify the physical Broadcom Pin numbers. Consult [Pinout.xyz](https://pinout.xyz/) for more details. For example, assume you want to connect COPI,CPIO,CLK, and CS_N to pins 3,5,7, and 12 on the Raspberry Pi header. If you consult that website, you'll see pin 3 is BCM2, pin 5 is BCM3, pin 7 is BCM4, and pin 12 is BCM18. Therefore, the argument you would provide to `wishbone-tool` is `--spi-pins 2,3,4,18` ## Crossover UART If your bridge is over a UART, then that means your UART is already in use, and isn't available for use as a console. Or if you're connecting via some other medium and you only have a single cable connecting the two devices. LiteX supports creating a "crossover" UART that `wishbone-tool` can interact with and present a local terminal on. To add a UART bridge and a crossover UART to your design, instantiate the main SoC object with `uart_name="crossover"` and add a separate Wishbone bridge. ```python class MySoC(SoCCore): def __init__(self, platform, sys_clk_freq): SoCCore.__init__(self, platform, sys_clk_freq, uart_name="crossover") # Add a bridge with the real UART pins self.submodules.uart_bridge = UARTWishboneBridge( platform.request("serial"), sys_clk_freq, baudrate=115200) self.add_wb_master(self.uart_bridge.wishbone) ``` Then, to interact with the terminal, run `wishbone-tool` and provide it with the `csr.csv` file from your build, and add the `-s terminal` flag: ```shell $ wishbone-tool -s terminal --csr-csv build/csr.csv $ ``` Note that you can run multiple `wishbone-tool` servers at the same time. For example, to run the `gdb` server as well, run: ```shell $ wishbone-tool -s gdb -s terminal --csr-csv build/csr.csv $ ``` To exit the session, press `Ctrl-C`. ## GDB Server If your softcore has a Vexriscv CPU in it, you can enable debug mode and use `wishbone-tool` to act as a gdbserver. ## Command line Auto-Completion You can generate auto-completion for `wishbone-tool` with the `-c` option. For example, to generate auto-completion for bash, run: ```shell $ wishbone-tool -c bash > wishbone-tool.bash $ . wishbone-tool.bash $ ``` Auto-completion is available for zsh, bash, fish, powershell, and elvish. ## `wishbone-bridge` as a Library You can also use `wishbone-bridge` as a library from within your own program. For more information, see the [wishbone-bridge documentation](https://docs.rs/wishbone-bridge/1.0.1/wishbone_bridge/).