- USB FS has a 1ms frame limit (HS is 125µs)
- UBS FS Bulk is thusly limited to ~19 transactions x 64 bytes maximum (HS is 512)
- USB FS Isochronous can do 1023 byte transfers, but you can only fit one of those in a 1ms frame (resulting in a giant quantization hole in the packet)
- Focusing on bulk only: the token packet, ACK handshake, inter-packet bus turnaround time minimums, framing bits, CRC bits, and periodic FS SOF packets mean that the actual theoretical maximum data rate is ~81% of the signaling rate
- Bit stuffing optimality issues (required for clock recovery) eat an additional several percent on most data, up to ~17% on pathological data
Therefore: ~9.5Mb/s is the best theoretical data rate that can be obtained with optimal host and device IP and an ideal application layer.
Realistically, ~8Mb/s is the most one can expect on real hardware with an ideal application (and this is optimistically high in my experience.)
I doubt you will be able to achieve USB HS via a ULPI PHY without an FPGA tunneling the USB SIE for you and handling the tight turnaround requirement (in which case, you might as well give it the entire MAC workload or just use an MCU with an integrated HS PHY.)
The ULPI clock is a 60MHz free-running PHY-sourced signal (typically - some PHYs allow MAC-sourced clocks and this would likely be a little easier), the PHY is entirely in control of when the MAC can transmit (DIR pin), and the protocol is unforgiving from a timing standpoint.