ULPI interfacing hardware.

class sol_usb.gateware.interface.ulpi.UPLIDataRecord
class sol_usb.gateware.interface.ulpi.UPLIDirRecord
class sol_usb.gateware.interface.ulpi.ULPIInterface

Record that represents a standard ULPI interface.

class sol_usb.gateware.interface.ulpi.ULPIRegisterWindow(*args, src_loc_at: int = 0, **kwargs)

Gateware interface that handles ULPI register reads and writes.

I/O ports:

# ULPI signals: I: ulpi_data_in[8] – input value of the ULPI data lines O: ulpi_data_out[8] – output value of the ULPI data lines O: ulpi_out_en – true iff we’re trying to drive the ULPI data lines

# Controller signals: O: busy – indicates when the register window is busy processing a transaction I: address[6] – the address of the register to work with O: done – strobe that indicates when a register request is complete

I: read_request – strobe that requests a register read O: read_data[8] – data read from the relevant register read

I: write_request – strobe that indicates a register write I: write_data[8] – data to be written during a register write

class sol_usb.gateware.interface.ulpi.ULPIRxEventDecoder(*args, src_loc_at: int = 0, **kwargs)

Simple piece of gateware that tracks receive events.

I/O port:

I: ulpi_data_in[8] – The current input state of the ULPI data lines. I: ulpi_dir – The ULPI bus-direction signal. I: ulpi_nxt – The ULPI ‘next’ throttle signal. I: register_operation_in_progress

Signal that should be true iff we’re performing a register operation.

O: last_rx_command – The full byte value of the last RxCmd.

O: line_state[2] – The states of the two USB lines. O: rx_active – True when a packet receipt is active. O: rx_error – True when a packet receive error has occurred. O: host_disconnect – True if the host has just disconnected. O: id_digital – Digital value of the ID pin. O: vbus_valid – True iff a valid VBUS voltage is present O: session_end – True iff a session has just ended.

# Strobes indicating signal changes. O: rx_start – True iff an RxEvent has changed the value of RxActive from 0 -> 1. O: rx_stop – True iff an RxEvent has changed the value of RxActive from 1 -> 0.

class sol_usb.gateware.interface.ulpi.ULPIControlTranslator(*args, src_loc_at: int = 0, **kwargs)

Gateware that translates ULPI control signals to their UTMI equivalents.

I/O port:
I: bus_idle – Indicates that the ULPI bus is idle, and thus capable of

performing register writes.

I: xcvr_select[2] – selects the operating speed of the transciever;

00 = HS, 01 = FS, 10 = LS, 11 = LS on FS bus

I: term_select – enables termination for the given operating mode; see spec I: op_mode – selects the operating mode of the transciever;

00 = normal, 01 = non-driving, 10 = disable bit-stuff/NRZI

I: suspend – places the transceiver into suspend mode; active high

I: id_pullup – when set, places a 100kR pull-up on the ID pin I: dp_pulldown – when set, enables a 15kR pull-down on D+; intended for host mode I: dm_pulldown – when set, enables a 15kR pull-down on D+; intended for host mode

I: chrg_vbus – when set, connects a resistor from VBUS to GND to discharge VBUS I: dischrg_vbus – when set, connects a resistor from VBUS to 3V3 to charge VBUS above SessValid

O: busy – true iff the control translator is actively performing an operation

add_composite_register(m, address, value, *, reset_value=0)

Adds a ULPI register that’s composed of multiple control signals.

  • address – The register number in the ULPI register space.

  • value – An 8-bit signal composing the bits that should be placed in the given register.


If provided, the given value will be assumed as the reset value of the given register; allowing us to avoid an initial write.


Creates translator objects that map our control signals to ULPI registers.

class sol_usb.gateware.interface.ulpi.ULPITransmitTranslator(*args, src_loc_at: int = 0, **kwargs)

Accepts UTMI transmit signals, and converts them into ULPI equivalents.

I/O port:

I: tx_data[8] – The data to be transmitted. I: tx_valid – Driven high to indicate we’re trying to transmit. O: tx_ready – Driven high when a given byte will be accepted on tx_data on the next clock edge.

I: op_mode[2] – The UTMI operating mode. Used to determine when NOPID commands should be issued;

and when to force transmit errors.

I: bus_idle – Should be asserted when the transmitter is able to control the bus.

O: ulpi_data_out – The data to be driven onto the ULPI transmit lines. O: ulpi_out_req – Asserted when we’re trying to drive the ULPI data lines. I: ulpi_nxt – The NXT signal for the relevant ULPI bus. O: ulpi_stp – The STP signal for the relevant ULPI bus.

O: busy – True iff this module is using the bus.

class sol_usb.gateware.interface.ulpi.UTMITranslator(*args, src_loc_at: int = 0, **kwargs)

Gateware that translates a ULPI interface into a simpler UTMI one.

I/O port:

O: busy – signal that’s true iff the ULPI interface is being used

for a register or transmit command

# See the UTMI specification for most signals.

# Data signals: I: tx_data[8] – data to be transmitted; valid when tx_valid is asserted I: tx_valid – set to true when data is to be transmitted; indicates the data_in

byte is valid; de-asserting this line terminates the transmission

O: tx_ready – indicates the the PHY is ready to accept a new byte of data, and that the

transmitter should move on to the next byte after the given cycle

O: rx_data[8] – data received from the PHY; valid when rx_valid is asserted O: rx_valid – indicates that the data present on rx_data is new and valid data;

goes high for a single ULPI clock cycle to indicate new data is ready

O: rx_active – indicates that the PHY is actively receiving data from the host; data is

slewed on rx_data by rx_valid

O: rx_error – indicates that an error has occurred in the current transmission

# Extra signals: O: rx_complete – strobe that goes high for one cycle when a packet rx is complete

# Signals for diagnostic use: O: last_rxcmd – The byte content of the last RxCmd.

I: address – The ULPI register address to work with. O: read_data[8] – The contents of the most recently read ULPI command. I: write_data[8] – The data to be written on the next write request. I: manual_read – Strobe that triggers a diagnostic read. I: manual_write – Strobe that triggers a diagnostic write.

add_extra_register(write_address, write_value, *, default_value=None)

Adds logic to configure an extra ULPI register. Useful for configuring vendor registers.

  • write_address – The write address of the target ULPI register.

  • write_value – The value to be written. If a Signal is provided; the given register will be set post-reset, if necessary; and then dynamically updated each time the signal changes. If an integer constant is provided, this value will be written once upon startup.

  • default_value – The default value the register is expected to have post-reset; used to determine if the value needs to be updated post-reset. If a Signal is provided for write_value, this must be provided; if an integer is provided for write_value, this is optional.