davidthings / tinyfpga_bx_usbserial

USB Serial on the TinyFPGA BX
Apache License 2.0
133 stars 37 forks source link

Advice on connecting this code to a larger design #6

Open cpitclaudel opened 4 years ago

cpitclaudel commented 4 years ago

Hi there,

Thanks for putting this project together; it's great :) I've successfully programmed a BX with the sample echo device, and verified that it works nicely.

I'd like to get some advice on connecting this to a larger project. When I hook this up to my design, I observe all sorts of transmission errors (duplicated and missing data values, hangs). I'm guessing it's because of timing issues, as I get the following output from nextpnr:

Info: Device utilisation:
Info:            ICESTORM_LC:  5124/ 7680    66%
Info:           ICESTORM_RAM:    18/   32    56%
Info:                  SB_IO:     4/  256     1%
Info:                  SB_GB:     3/    8    37%
Info:           ICESTORM_PLL:     1/    2    50%
Info:            SB_WARMBOOT:     0/    1     0%

[…]

Warning: Max frequency for clock 'CLK$SB_IO_IN_$glb_clk': 23.41 MHz (FAIL at 48.00 MHz)
Warning: Max frequency for clock    'clk_48mhz_$glb_clk': 42.82 MHz (FAIL at 48.00 MHz)

Info: Max delay <async>                       -> posedge clk_48mhz_$glb_clk   : 2.48 ns
Info: Max delay posedge CLK$SB_IO_IN_$glb_clk -> posedge clk_48mhz_$glb_clk   : 37.36 ns
Info: Max delay posedge clk_48mhz_$glb_clk    -> <async>                      : 3.14 ns
Info: Max delay posedge clk_48mhz_$glb_clk    -> posedge CLK$SB_IO_IN_$glb_clk: 8.36 ns

I assume the communication issues stem from that; correct?

I have a toplevel clock that I use to run my main design, and as input to the PLL to derive the 48MHz clock. Is this how I should do it? Or should I divide down the 48MHz clock to get a 12MHz back from it? (I tried that approach and got to 46MHz).

Is there any way to run the USB module at a lower speed?

davidthings commented 4 years ago

Hi! Thanks for taking a look at the code.

First... I assume you are using NextPNR. Older code, like Arachne, won't work. Arachne doesn't optimize for clock time! NextPNR does.

One thing I should have emphasized in the doc is that the module doesn't like getting overrun. I always use it with a FIFO or two to try to avoid a situation where it gets blocked or overrun.

USB_SERIAL -> FIFO -> modules

USB_SERIAL <- FIFO <- modules

Also, if the whole design fails timing, the whole thing is in trouble. The usual symptom is that the USB port just fails to enumerate.

Finally I see that you're at 66% fullness. This is a biggish project for our beloved TinyFPGA BX. Can you try some smaller subsets to see if pure code magnitude is part of the problem.

Let me know how things go!

cpitclaudel commented 4 years ago

Hi ! Thanks for the quick response :)

Yup, I'm using nextpnr. I do have a FIFO between my design and usb_serial. Interestingly, failing timing gives me these data curruption errors, but no enumeration failure just yet ^^

The smaller designs I've tried passed timing, and things worked fine there.

Thanks again for your help!

cpitclaudel commented 4 years ago

I've tried to shrink my design further. On very small designs I pass timing and things work, but as I add complexity things start breaking again.

Do you have experience with Low-Speed USB (running at 1.5Mbits/s instead of 12, with a clock speed of 24MHz)? How hard would it be to adjust the existing code to run with a 24MHz clock? Or am I approaching this wrong?

ulixxe commented 3 years ago

Maybe you can try my implementation at: https://github.com/ulixxe/usb_cdc