Test Harness

Squishy support infrastructure for testing.

This module contains 6 classes which augment the standard torii.test.ToriiTestCase with additional functionality to help with writing and running Squishy-related gateware tests. They are as follows:

  • SquishyGatewareTest - Generalized test parent, all other test classes are derived from this.

  • USBGatewarePHYTest - Tests for end-to-end USB interface tests, contains machinery for driving SOL Gateware USB PHY

  • USBGatewareTest - A more general set of USB interface tests, directly drives the SOL USB interface.

  • DFUGatewareTest - Augments the USBGatewareTest with DFU helpers.

  • SPIGatewareTest - Tests for SPI related gateware, contains helpers for driving a SPI bus for tests.

  • SCSIGatewareTest - Tests for SCSI related gateware.

class squishy.support.test.SquishyGatewareTest(*args, **kwargs)

The base class for the more specialized Squishy subsystem tests.

class squishy.support.test.USBGatewarePHYTest(*args, raw_record, **kwargs)

Unlike USBGatewareTest, this mixin is used for end-to-end USB tests where we emulate a physical USB bus, this helps test end-to-end integration.

To use this, the DUT platform rather than returning a ULPI or UTMI resource should return a DirectUSB resource, this will cause SOL to use it’s gateware PHY and we can then manually drive D+ and D- for tests.

Parameters:

raw_record (torii.hdl.rec.Record) – The Raw Torii Record representing the USB bus for the Gateware PHY. It must have 2 members d_p and d_n, each with i, o, and oe sub-members, all 1-bit wide.

static crc5(data: int, bit_len: int) int

Compute the CRC5 for the USB packet.

Parameters:
  • data (int) – The byte we are computing the CRC5 for.

  • bit_len (int) – The number of bits we are computing the CRC5 over.

Returns:

The CRC5 of bin(data)[0:bit_len].

Return type:

int

static crc16(data: int, bit_len: int, crc_in: int = 0) int

Computes the CRC16 of the given byte for the USB traffic.

Parameters:
  • data (int) – The current byte to compute the CRC16 on.

  • bit_len (int) – The number of bits of data to compute the CRC16 over.

  • crc_in (int) – The result of a previous call to crc16 if iterating over a buffer of data.

Returns:

The output CRC16 value.

Return type:

int

static crc16_buff(data: Iterable[int]) int

Compute the CRC16 value of a buffer of bytes.

Parameters:

data (Iterable[int]) – The buffer of bytes to compute the CRC16 for

Returns:

The CRC16 value of the data buffer.

Return type:

int

usb_emit_bits(bits: int, count: int = 8)

Emit appropriate K and J symbols to put raw bits onto the USB bus.

Parameters:
  • bits (int) – The bits to put out on the wire.

  • count (int) – The number of bits in bits to use. (default: 8)

usb_single_zero()

Emit a single-ended USB 0 onto the bus.

This drives the input side of D+ and D- on the USB record to 0:

D+: ┈┈┈┈🮢__ D-: ┈┈┈┈🮢__

usb_single_one()

Emit a single-ended USB 1 onto the bus.

This drives the input side of D+ and D- on the USB record to 1:

D+: ┈┈┈┈🮠 ̄ ̄ D-: ┈┈┈┈🮠 ̄ ̄

usb_j()

Emit a USB J symbol onto the bus.

This drives the input side of D+ high and D- low:

D+: ┈┈┈┈🮠 ̄ ̄ D-: ┈┈┈┈🮢__

usb_wait_j()

Wait up to 1000 cycles for the output side of the USB bus to have a J symbol emitted to it

usb_assert_j()

Assert that the current state of the output side of the USB bus is a valid J symbol.

usb_k()

Emit a USB K symbol onto the bus.

This drives the input side of D+ low and D- high:

D+: ┈┈┈┈🮢__ D-: ┈┈┈┈🮠 ̄ ̄

usb_wait_k()

Wait up to 1000 cycles for the output side of the USB bus to have a K symbol emitted to it

usb_assert_k()

Assert that the current state of the output side of the USB bus is a valid K symbol.

usb_initialize()

Emit a USB bus initialization sequence which consists of a USB 0 for 30µs followed by a USB 1 for 1µs.

usb_sync()

Emit a USB sync onto the bus.

This puts a pattern of KJKJKJKK onto the bus.

usb_assert_sync()

Assert that a USB sync has been emitted onto the bus.

usb_eop()

Emit a USB End-of-packet onto the bus.

This puts 2 USB 0’s followed by a J symbols and then a USB 1 onto the bus.

usb_sof(frame_number: int | None = None)

Emit a USB Start-of-Frame.

Parameters:

frame_number (int | None) – The frame number to use.

usb_in(addr: int, ep: int)

Emit a USB IN packet.

Parameters:
  • addr (int) – The address of the device.

  • ep (int) – The endpoint for the IN packet.

usb_out(addr: int, ep: int)

Emit a USB OUT packet.

Parameters:
  • addr (int) – The address of the device.

  • ep (int) – The endpoint for the OUT packet.

usb_setup(addr: int)

Emit a USB Setup packet.

Parameters:

addr (int) – The address of the device.

usb_send_ack()

Send a USB ACK

usb_get_ack()

Get a USB ACK

usb_get_stall()

Get a USB Stall

usb_solicit(addr: int, ep: int, pid: USBPacketID)

Solicit a USB packet.

Parameters:
  • addr (int) – The address of the device.

  • ep (int) – The device endpoint.

  • pid (USBPacketID) – The ID of the packet.

usb_data(data: Iterable[int])

Emit a USB DATA packet.

Parameters:

data (Iterable[int]) – The date in the packet.

usb_get_zlp()

Assert that the USB bus has a ZLP emitted.

usb_send_zlp()

Emit a USB Zero-length-packet.

usb_send_setup_pkt(addr: int, data: Iterable[int])

Emit a USB Setup packet.

Parameters:
  • addr (int) – The target device address.

  • data (Iterable[int]) – The data in the setup packet.

usb_set_addr(addr: int)

Emit a USB Set Address packet.

Parameters:

addr (int) – The address to set the device to.

usb_set_interface(addr: int, interface: int, alt: int)

Emit a USB Set Interface packet.

Parameters:
  • addr (int) – The address of the device.

  • interface (int) – The interface to set active.

  • alt (int) – The alternate mode of the interface to use.

usb_set_config(addr: int, cfg: int)

Emit a USB Set Configuration packet.

Parameters:
  • addr (int) – The address of the device.

  • cfg (int) – The configuration to set active.

usb_get_config(addr: int, cfg: int)

Emit a USB Get Configuration packet and assert it’s correct.

Parameters:
  • addr (int) – The address of the device.

  • cfg (int) – The configuration to assert against.

usb_get_string(addr: int, string_idx: int, string: str)

Emit a USB Get String packet and assert it matches the expected value.

Parameters:
  • addr (int) – The address of the device.

  • string_idx (int) – The index of the string descriptor to get.

  • string (str) – The expected string.

usb_get_state()

Return the state of the USB bus outgoing side.

usb_consume_byte()

Read a byte off the USB bus.

Returns:

The byte read.

Return type:

int

usb_consume_response(data: Iterable[int])

Consume bytes of off the USB bus and assert it matches data.

Parameters:

data (Iterable[int]) – The collection of bytes to assert against.

class squishy.support.test.USBGatewareTest(*args, **kwargs)

Unlike USBGatewarePHYTest, this class relies on access to a SOL interface exposed in the DUT or DUT wrapper.

Most of the USB tests in Squishy use this type of helpers, as the USBGatewarePHYTest is only used for full end-to-end USB integration validation if absolutely needed.

setup_received()

Trigger a setup received event on the USB interface.

send_setup(*, type: USBRequestType, retrieve: bool, req, value: tuple[int, int] | int, index: tuple[int, int] | int, length: int, recipient: USBRequestRecipient = USBRequestRecipient.INTERFACE)

Inject a setup packet into the USB interface.

Parameters:
  • type (USBRequestType) – The type of this USB request.

  • retrieve (bool) – If this is an IN request or not.

  • req – The request.

  • value (tuple[int, int] | int) – The one or two byte value of the setup packet.

  • index (tuple[int, int] | int) – The one or two byte index of the setup packet.

  • length (int) – The length of the setup packet.

  • recipient (USBRequestRecipient) – The recipient for this setup packet. (default: USBRequestRecipient.INTERFACE)

send_setup_set_interface(*, interface: int = 0, alt_mode: int = 0)

Inject a Set Interface packet into the USB interface.

Parameters:
  • interface (int) – The interface to set. (default: 0)

  • alt_mode (int) – The alternate mode of the interface. (default: 0)

receive_data(*, data: tuple[int, ...] | bytes, check: bool = True)

Assert that the USB interface sends the expected data.

Parameters:
  • data (tuple[int, ...] | bytes) – The data we expect from the interface.

  • check (bool) – Enable the assert on the data send back from the interface. (default: true)

receive_zlp()

Assert that the USB interface emits a ZLP

send_data(*, data: tuple[int, ...] | bytes)

Inject data into the USB interface.

Parameters:

data (tuple[int, ...] | bytes) – The data to inject.

ensure_stall()

Assert that the USB interface emits a stall.

send_get_desc(*, vendor_code, length, index)

Inject a Get Descriptor request into the USB interface.

Parameters:
  • vendor_code – The vendor code for the descriptor.

  • length – The length of the descriptor.

  • index – The index of the descriptor.

class squishy.support.test.DFUGatewareTest(*args, **kwargs)

Provides helper wrappers for USB-DFU related test driving with the USBGatewareTest class.

send_dfu_detach()

Inject a DFU Detach into the USB interface.

send_dfu_download(*, length: int = 256)

Inject a DFU download of the given length into the USB interface.

Parameters:

length (int) – The size of the DFU download. (default: 256)

send_dfu_get_status()

Inject a DFU Get Status into the USB interface.

send_dfu_get_state()

Inject a DFU Get State into the USB interface.

class squishy.support.test.SPIGatewareTest(*args, **kwargs)