SOL On Your Own Hardware
The SOL stack is designed to be easy to use on your own FPGA hardware – if you can already run Torii designs on your board, all you’ll need is to set up some I/O definitions and some clock domains.
The exact platform requirements depend on how you’ll perform USB interfacing, and are detailed below.
High-Speed via a ULPI PHY
Using a ULPI PHY is relatively straightforward; and typically requires no hardware beyond the ULPI PHY. SOL works with
both designs that receive their usb
-domain clocks from the PHY (typical) and designs that provide a 60MHz clock to
their PHY.
The following clock domains are required:
Domain Name |
Frequency |
Description |
---|---|---|
|
60 MHz |
Core clock for the PHY’s clock domain. Can be provided to the FPGA by the PHY, or provided to the PHY by the FPGA. See below. |
An I/O resource with the following subsignals is required:
Subsignal Name |
Width |
Direction |
Description |
---|---|---|---|
|
1 |
input or output |
The ULPI bus clock. Should be configured as an input if the PHY is providing our clock (typical), or as an output if the FPGA will provide the clock to the PHY. |
|
8 |
bidirectional |
The bidirectional data bus. |
|
1 |
input |
The ULPI direction signal. |
|
1 |
input |
The ULPI next signal. |
|
1 |
output |
The ULPI stop signal. |
|
1 |
output |
The ULPI reset signal. The gateware asserts this signal when the PHY should be reset;
if the PHY requires an active-low reset, this can be inverted with |
An example resource might look like:
# Targeting the USB3300 PHY, which provides our clock.
Resource('ulpi', 0,
Subsignal('data', Pins(data_sites, dir = 'io')),
Subsignal('clk', Pins(clk_site, dir = 'i' )),
Subsignal('dir', Pins(dir_site, dir = 'i' )),
Subsignal('nxt', Pins(nxt_site, dir = 'i' )),
Subsignal('stp', Pins(stp_site, dir = 'o' )),
Subsignal('rst', Pins(reset_site, dir = 'o' )),
Attrs(IO_TYPE = 'LVCMOS33')
)
Full-Speed using FPGA I/O
SOL provides a gateware PHY that enables an FPGA to communicate at Full Speed using only FPGA 3V3 I/O and a pull-up resistor. The FPGA must be able to provide stable 48 MHz and 12 MHz clocks.
The following clock domains are required:
Domain Name |
Frequency |
Description |
---|---|---|
|
12 MHz |
Core clock for USB data. Ticks at the USB bitrate of 12MHz, and drives most of the USB logic. |
|
48 MHz |
Edge clock for the USB I/O. Used at the I/O boundary for clock recovery and NRZI encoding. |
An I/O resource with the following subsignals is required:
Subsignal Name |
Width |
Direction |
Description |
---|---|---|---|
|
1 |
bidirectional |
The raw USB D+ line; must be on a 3.3V logic bank. |
|
1 |
bidirectional |
The raw USB D- line; must be on a 3.3V logic bank. |
|
1 |
output |
Control for the USB pull-up resistor; should be connected to D+ via a 1.5k resistor. |
|
1 |
input |
Optional. If provided, this signal will be used for VBUS detection logic; should be asserted whenever VBUS is present. Many devices are ‘bus-powered’ (receive their power from USB), and thus have no need for VBUS detection, in which case this signal can be omitted. |
An example resource might look like:
Resource('usb', 0,
Subsignal('d_p', Pins('A4')),
Subsignal('d_n', Pins('A2')),
Subsignal('pullup', Pins('D5', dir = 'o')),
Attrs(IO_STANDARD = 'SB_LVCMOS'),
),