I am using this USB 1.1 PHY (a VHDL translation) for an open-source project, and I ran into an issue. This only seems to happen when I use an USB HUB I have (a chinese one, have not tested with other hubs though). It works OK when I connect to the host directly.
I'm using the PHY as an FS Device, using a simple external USB transceiver.
So, what is happening is I have an IN/DATA0 transaction that never gets acknowledged by the host. This causes retransmission of the same DATA0 ad-eternum.
Looking at the concrete data being sent, the only think that makes me believe it's causing this relates to CRC transmission ending with (binary) "00111111". I suspect HUB is somehow expecting a stuff bit before EOP, and hence not reading the CRC correctly.
Section 7.1.9 of USB 2.0 standard states: "If required by the bit stuffing rules, a zero bit will be inserted even if it is the last bit before the end-of-packet (EOP) signal".
This is also part of the USB certification Peripheral Silicon Checklist (http://www.usb.org/developers/compliance/check_list/), B6, section 3.1: "Is bit stuffing performed even if the stuffed bit follows the last bit of a packet".
Here's my fix (basically delaying EOP by one FS cycle):
<pre> --- a/rtl/verilog/usb_tx_phy.v +++ b/rtl/verilog/usb_tx_phy.v @@ -317,7 +317,7 @@ always @(posedge clk) `endif if(!rst) append_eop_sync2 <= 1'b0; else - if(fs_ce) append_eop_sync2 <= append_eop_sync1; + if(fs_ce && !stuff) append_eop_sync2 <= append_eop_sync1; `ifdef USB_ASYNC_REST always @(posedge clk or negedge rst) </pre>