cancel
Showing results for 
Search instead for 
Did you mean: 

USB Superspeed Peripherals

Anonymous
Not applicable

Hello,

i have a couple of question regarding the FX3 GPIF Interface. I plan to use a synchronous 32 Bit Interface to the FX3 with a 100 MHz clock. I hope i can use the firmware provided with AN65974 with very little modifications.

My first question is on the polarity of the "Thread_X_DMA_Ready" and "Thread_X_DMA_Watermark" flags: It seems that you have to wait until the the flag is deasserted before reading/writing. Is that correct? This seems very unintuitive for a "ready" flag. I plan to configure all flags with active low polarity and initial value low, and then wait with reading/writing until i see a high level on the line.

The next question is regarding partial flags: With a 100 MHz Clock, i can't meet the setup and hold times on the flag signals. To fix this i plan to treat the flags as asychronous signals and use snychronizers in the FPGA to make sure things are stable. That introduces a lot of additional delay on the flags, so i hope i can the following scheme:

Since data should always be written and read in bursts of 1 kB, i hope i can just use watermark flags with a watermark level of 255. If i see a high level on the flag (deasserted) i can read/write a burst of 256 words. Shortly after starting the burst, the flag should change or not. When i'm finished with the burst, the flag should should show if i can start another burst, regardles of all the delays. Is that sensible? I'm afraid of +-1 erros on the watermark level, but 255 seems like a sensible value.

My final question regards (potential) bugs with the watermark flags: I found the attached memo in this post: https://community.cypress.com/message/70337#70337​ . It mentions problems using only the watermark flags in the way i described above. I hope i can use the following workaround: I would just wait initially until the Thread_3_DMA_Ready (Thread 3 is USB->GPIF) flag goes high (deasserted) for the first time, before reading or writing using just the watermark flags. Judging by the waveform in the memo, that should fix the described problem in the USB->GPIF direction. Do you thing this approach will work?

I also wonder if that workaround fixes the described problem in the GPIF->USB direction. And will the workaround "survive" if there is a USB reconnect?

Regards,

Markus

0 Likes
Reply
1 Solution
Moderator
Moderator

Please find my comments below in bold format.

Thanks for your reply, that was very helpful! I can indeed always work with bursts of exactly 1 kB and use a counter in the FPGA. However, I was worried about the delays on the DMA_READY flags after reading/writing. But just waiting until the Flag goes low after reading/writing should solve that. I will eventually see this transition regardless of any delays.

So can i just use the following logic? DMA Buffers are 1 kB. Flags are configured to DMA_READY with active low polarity and initial value low. The FPGA logic works basically with just three states:

1.) Wait until the flag is high and at least 1 kB data is available for sending.

2.) Write a burst of 1 kB data.

3.) Wait until the flag goes low and go back to step 1.

The logic for reading is the same, except that i check for 1 kB available space in my receive FIFO.

I hope the Flag lines start low while the FX3 is booting and waiting for a USB connection, if i'm using the AN65974 firmware? Do i need i any extra logic to handle USB (re-)connects? I don't care about data loss, but i don't want to receive garbage data, or get stuck in state 3.).

>>  The application should be stopped when there is a disconnect. Please refer AN65974 FW. We called CyFxSlFifoApplnStop function on disconnect. This actually flush the endpoint data and destroy the DMA channels. Hence, there is no data received by the GPIF (DMA) on disconnect.

My next problem is that i need very high throughput (300 MB/s) in the FPGA->PC direction. So i'm afraid the using only 1 kB DMA buffers won't work due to the buffer switching time. Is the following approach sane:

The DMA buffers for this direction are 16 kB. The FPGA logic is extended as follows:

1.) Wait until the flag is high and at least 1 kB data is available for sending.

2.) Write a burst of n * 1 kB data where n is 1-16.

3.) If n < 16 write a single ZLP, otherwise skip this step.

4.) Wait until the flag goes low and go back to step 1.

I hope step 3.) will commit the partially full DMA buffer, so no data can get "stuck" in the DMA buffer in very low throughput scenarios.

>> You must use a higher buffer size. 1KB buffer size surely affect the throughput. Please go ahead with 16 KB.

>> You have to use PKTEND signal to commit a short or zero length packet. These two cases are different w.r.t SLWR signal. refer App. Note.

Instead of step 3.) i could also assert pktend with the very last data word written in step 2.), to hopefully commit a partially DMA buffer. However this post suggest that it won't work: https://community.cypress.com/message/62625#62625

>> In this thread, the user talks about committing a short or ZLP from USB to GPIF perspective. Note that this is different from GPIF to USB.

In the case of USB to GPIF, the DMA buffer is committed automatically in the following three cases.

Say buffer size is 16KB.

a. full buffer is received

b. partial buffer (say 12 KB - integer multiple of end point size (1024 bytes in USB 3.0 mode)) is received + ZLP (zero length packet)

c. partial buffer (say 11 KB + 400 Bytes) - this is called short packet.

Hence, the user should handle a,b and c cases in the host application.

View solution in original post

0 Likes
Reply
3 Replies
Moderator
Moderator

Please find the comments below.

My first question is on the polarity of the "Thread_X_DMA_Ready" and "Thread_X_DMA_Watermark" flags: It seems that you have to wait until the flag is de-asserted before reading/writing. Is that correct?

>> Yes, it is correct.

This seems very unintuitive for a "ready" flag.

I plan to configure all flags with active low polarity and initial value low, and then wait with reading/writing until i see a high level on the line.

>> Note that there is a finite delay present between the point at which the buffers inside the FX3 become full/empty and actual assertion of flags.

>>This might be unintuitive to you.

>>This is where the partial flags coming into the picture. This flag should be configured in such a way that the external processor should know      how many cycles it can read/write the data from/to the GPIF.

>>i.e the number of bytes that the external processor can read/write from/to the GPIF should be known to the external processor and stop the      data transfer after the count. Later wait for de-assertion of the watermark or ready flag then do the data transfer.

The next question is regarding partial flags: With a 100 MHz Clock, i can't meet the setup and hold times on the flag signals. To fix this i plan to treat the flags as asychronous signals and use snychronizers in the FPGA to make sure things are stable. That introduces a lot of additional delay on the flags, so i hope i can the following scheme:

Since data should always be written and read in bursts of 1 kB, i hope i can just use watermark flags with a watermark level of 255. If i see a high level on the flag (deasserted) i can read/write a burst of 256 words. Shortly after starting the burst, the flag should change or not. When i'm finished with the burst, the flag should should show if i can start another burst, regardles of all the delays. Is that sensible? I'm afraid of +-1 erros on the watermark level, but 255 seems like a sensible value.

>> If you have the feasibility to write/read in 1KB bursts, you can set up a counter in FPGA itself and remove the watermark flags on the GPIF II.

i.e. Let me explain the read operation in this approach.

1. The DMA Buffer is created and SM is started

2. Initially, the buffer is empty. Hence, the ready is asserted - indicates that there is no data to read

3. FPGA starts reading the data  from GPIF II and counting the data that is read.

4. FPGA stops the data transfer as the counter hits after 1024 bytes.

5. Then it waits for the Ready Flag to go low and come high. Saying that the next is buffer is ready to read.

If you still want to use the water mark flags, here are the comments on it.

My final question regards (potential) bugs with the watermark flags: I found the attached memo in this post: https://community.cypress.com/message/70337#70337 . It mentions problems using only the watermark flags in the way i described above. I hope i can use the following workaround: I would just wait initially until the Thread_3_DMA_Ready (Thread 3 is USB->GPIF) flag goes high (deasserted) for the first time, before reading or writing using just the watermark flags. Judging by the waveform in the memo, that should fix the described problem in the USB->GPIF direction. Do you thing this approach will work?

>> If you can wait initially until the Thread_3_DMA_Ready (Thread 3 is USB->GPIF) flag goes high (de-asserted) for the first time, before reading or writing using just the watermark flags, that solves the problem.

OR

>> You can START reading the data based on ready flag and STOP reading based on Watermark Flag.

I also wonder if that workaround fixes the described problem in the GPIF->USB direction. And will the workaround "survive" if there is a USB reconnect?

>> If there is USB reconnect, you have to stop the application.

Start the application when there is USB connection again.

>>P.S. If you go with a counter in FPGA, you don't need to worry about the partial flags. Hence, the job would be easy.

0 Likes
Reply
Anonymous
Not applicable

Thanks for your reply, that was very helpful! I can indeed always work with bursts of exactly 1 kB and use a counter in the FPGA. However, I was worried about the delays on the DMA_READY flags after reading/writing. But just waiting until the Flag goes low after reading/writing should solve that. I will eventually see this transition regardless of any delays.

So can i just use the following logic? DMA Buffers are 1 kB. Flags are configured to DMA_READY with active low polarity and initial value low. The FPGA logic works basically with just three states:

1.) Wait until the flag is high and at least 1 kB data is available for sending.

2.) Write a burst of 1 kB data.

3.) Wait until the flag goes low and go back to step 1.

The logic for reading is the same, except that i check for 1 kB available space in my receive FIFO.

I hope the Flag lines start low while the FX3 is booting and waiting for a USB connection, if i'm using the AN65974 firmware? Do i need i any extra logic to handle USB (re-)connects? I don't care about data loss, but i don't want to receive garbage data, or get stuck in state 3.).

My next problem is that i need very high throughput (300 MB/s) in the FPGA->PC direction. So i'm afraid the using only 1 kB DMA buffers won't work due to the buffer switching time. Is the following approach sane:

The DMA buffers for this direction are 16 kB. The FPGA logic is extended as follows:

1.) Wait until the flag is high and at least 1 kB data is available for sending.

2.) Write a burst of n * 1 kB data where n is 1-16.

3.) If n < 16 write a single ZLP, otherwise skip this step.

4.) Wait until the flag goes low and go back to step 1.

I hope step 3.) will commit the partially full DMA buffer, so no data can get "stuck" in the DMA buffer in very low throughput scenarios.

Instead of step 3.) i could also assert pktend with the very last data word written in step 2.), to hopefully commit a partially DMA buffer. However this post suggest that it won't work: https://community.cypress.com/message/62625#62625

0 Likes
Reply
Moderator
Moderator

Please find my comments below in bold format.

Thanks for your reply, that was very helpful! I can indeed always work with bursts of exactly 1 kB and use a counter in the FPGA. However, I was worried about the delays on the DMA_READY flags after reading/writing. But just waiting until the Flag goes low after reading/writing should solve that. I will eventually see this transition regardless of any delays.

So can i just use the following logic? DMA Buffers are 1 kB. Flags are configured to DMA_READY with active low polarity and initial value low. The FPGA logic works basically with just three states:

1.) Wait until the flag is high and at least 1 kB data is available for sending.

2.) Write a burst of 1 kB data.

3.) Wait until the flag goes low and go back to step 1.

The logic for reading is the same, except that i check for 1 kB available space in my receive FIFO.

I hope the Flag lines start low while the FX3 is booting and waiting for a USB connection, if i'm using the AN65974 firmware? Do i need i any extra logic to handle USB (re-)connects? I don't care about data loss, but i don't want to receive garbage data, or get stuck in state 3.).

>>  The application should be stopped when there is a disconnect. Please refer AN65974 FW. We called CyFxSlFifoApplnStop function on disconnect. This actually flush the endpoint data and destroy the DMA channels. Hence, there is no data received by the GPIF (DMA) on disconnect.

My next problem is that i need very high throughput (300 MB/s) in the FPGA->PC direction. So i'm afraid the using only 1 kB DMA buffers won't work due to the buffer switching time. Is the following approach sane:

The DMA buffers for this direction are 16 kB. The FPGA logic is extended as follows:

1.) Wait until the flag is high and at least 1 kB data is available for sending.

2.) Write a burst of n * 1 kB data where n is 1-16.

3.) If n < 16 write a single ZLP, otherwise skip this step.

4.) Wait until the flag goes low and go back to step 1.

I hope step 3.) will commit the partially full DMA buffer, so no data can get "stuck" in the DMA buffer in very low throughput scenarios.

>> You must use a higher buffer size. 1KB buffer size surely affect the throughput. Please go ahead with 16 KB.

>> You have to use PKTEND signal to commit a short or zero length packet. These two cases are different w.r.t SLWR signal. refer App. Note.

Instead of step 3.) i could also assert pktend with the very last data word written in step 2.), to hopefully commit a partially DMA buffer. However this post suggest that it won't work: https://community.cypress.com/message/62625#62625

>> In this thread, the user talks about committing a short or ZLP from USB to GPIF perspective. Note that this is different from GPIF to USB.

In the case of USB to GPIF, the DMA buffer is committed automatically in the following three cases.

Say buffer size is 16KB.

a. full buffer is received

b. partial buffer (say 12 KB - integer multiple of end point size (1024 bytes in USB 3.0 mode)) is received + ZLP (zero length packet)

c. partial buffer (say 11 KB + 400 Bytes) - this is called short packet.

Hence, the user should handle a,b and c cases in the host application.

View solution in original post

0 Likes
Reply