Gateware PHY - Receiver

class sol_usb.gateware.interface.gateware_phy.receiver.RxClockDataRecovery(*args, src_loc_at: int = 0, **kwargs)

RX Clock Data Recovery module.

RxClockDataRecovery synchronizes the USB differential pair with the FPGAs clocks, de-glitches the differential pair, and recovers the incoming clock and data.

Clock Domain

usb_48 : 48MHz

Input Ports

Input ports are passed in via the constructor.

usbp_rawSignal(1)

Raw USB+ input from the FPGA IOs, no need to synchronize.

usbn_rawSignal(1)

Raw USB- input from the FPGA IOs, no need to synchronize.

Output Ports

Output ports are data members of the module. All output ports are flopped. The line_state_dj/dk/se0/se1 outputs are 1-hot encoded.

line_state_validSignal(1)

Asserted for one clock when the output line state is ready to be sampled.

line_state_djSignal(1)

Represents Full Speed J-state on the incoming USB data pair. Qualify with line_state_valid.

line_state_dkSignal(1)

Represents Full Speed K-state on the incoming USB data pair. Qualify with line_state_valid.

line_state_se0Signal(1)

Represents SE0 on the incoming USB data pair. Qualify with line_state_valid.

line_state_se1Signal(1)

Represents SE1 on the incoming USB data pair. Qualify with line_state_valid.

class sol_usb.gateware.interface.gateware_phy.receiver.RxNRZIDecoder(*args, src_loc_at: int = 0, **kwargs)

RX NRZI decoder.

In order to ensure there are enough bit transitions for a receiver to recover the clock usb uses NRZI encoding. This module processes the incoming dj, dk, se0, and valid signals and decodes them to data values. It also pipelines the se0 signal and passes it through unmodified.

https://www.pjrc.com/teensy/beta/usb20.pdf, USB2 Spec, 7.1.8 https://en.wikipedia.org/wiki/Non-return-to-zero

Clock Domain

usb_48 : 48MHz

Input Ports

Input ports are passed in via the constructor.

i_validSignal(1)

Qualifier for all of the input signals. Indicates one bit of valid data is present on the inputs.

i_djSignal(1)

Indicates the bus is currently in a Full-Speed J-state. Qualified by valid.

i_dkSignal(1)

Indicates the bus is currently in a Full-Speed K-state. Qualified by valid.

i_se0Signal(1)

Indicates the bus is currently in a SE0 state. Qualified by valid.

Output Ports

Output ports are data members of the module. All output ports are flopped.

o_validSignal(1)

Qualifier for all of the output signals. Indicates one bit of valid data is present on the outputs.

o_dataSignal(1)

Decoded data bit from USB bus. Qualified by valid.

o_se0Signal(1)

Indicates the bus is currently in a SE0 state. Qualified by valid.

class sol_usb.gateware.interface.gateware_phy.receiver.RxPacketDetect(*args, src_loc_at: int = 0, **kwargs)

Packet Detection

Full Speed packets begin with the following sequence:

KJKJKJKK

This raw sequence corresponds to the following data:

00000001

The bus idle condition is signaled with the J state:

JJJJJJJJ

This translates to a series of ‘1’s since there are no transitions. Given this information, it is easy to detect the beginning of a packet by looking for 00000001.

The end of a packet is even easier to detect. The end of a packet is signaled with two SE0 and one J. We can just look for the first SE0 to detect the end of the packet.

Packet detection can occur in parallel with bitstuff removal.

https://www.pjrc.com/teensy/beta/usb20.pdf, USB2 Spec, 7.1.10

Input Ports

i_validSignal(1)

Qualifier for all of the input signals. Indicates one bit of valid data is present on the inputs.

i_dataSignal(1)

Decoded data bit from USB bus. Qualified by valid.

i_se0Signal(1)

Indicator for SE0 from USB bus. Qualified by valid.

Output Ports

o_pkt_startSignal(1)

Asserted for one clock on the last bit of the sync.

o_pkt_activeSignal(1)

Asserted while in the middle of a packet.

o_pkt_endSignal(1)

Asserted for one clock after the last data bit of a packet was received.

class sol_usb.gateware.interface.gateware_phy.receiver.RxBitstuffRemover(*args, src_loc_at: int = 0, **kwargs)

RX Bitstuff Removal

Long sequences of 1’s would cause the receiver to lose it’s lock on the transmitter’s clock. USB solves this with bitstuffing. A ‘0’ is stuffed after every 6 consecutive 1’s. This extra bit is required to recover the clock, but it should not be passed on to higher layers in the device.

https://www.pjrc.com/teensy/beta/usb20.pdf, USB2 Spec, 7.1.9 https://en.wikipedia.org/wiki/Bit_stuffing

Clock Domain

usb_48 : 48MHz

Input Ports

i_validSignal(1)

Qualifier for all of the input signals. Indicates one bit of valid data is present on the inputs.

i_dataSignal(1)

Decoded data bit from USB bus. Qualified by valid.

Output Ports

o_dataSignal(1)

Decoded data bit from USB bus.

o_stallSignal(1)

Indicates the bit stuffer just removed an extra bit, so no data available.

o_errorSignal(1)

Indicates there has been a bitstuff error. A bitstuff error occurs when there should be a stuffed ‘0’ after 6 consecutive 1’s; but instead of a ‘0’, there is an additional ‘1’. This is normal during IDLE, but should never happen within a packet. Qualified by valid.

class sol_usb.gateware.interface.gateware_phy.receiver.RxShifter(*args, src_loc_at: int = 0, **kwargs)

RX Shifter

A shifter is responsible for shifting in serial bits and presenting them as parallel data. The shifter knows how many bits to shift and has controls for resetting the shifter.

Clock Domain

usb : 12MHz

param Parameters are passed in via the constructor.:

param width:

Number of bits to shift in.

type width:

int

param Input Ports:

param ———–:

param i_valid:

Qualifier for all of the input signals. Indicates one bit of valid data is present on the inputs.

type i_valid:

Signal(1)

param i_data:

Serial input data. Qualified by valid.

type i_data:

Signal(1)

param Output Ports:

param ————:

param o_data:

Shifted in data.

type o_data:

Signal(width)

param o_put:

Asserted for one clock once the register is full.

type o_put:

Signal(1)