FPGA platform and approach to send samples to host PC - Page 1
Forum section: electronics / general

author: timg11
author_rank: Contributor
timestamp: November 22, 2021, 12:05:44 am
content: I'm looking for approaches for a FPGA design that is relatively simple.It will gather and generate data in a burst of 1-2 seconds.The data generated will consist of 64 bit values every 50 uS, or 1280 kbits/secA total of 160 to 320 kbytes per capture.What are the pros and cons for transferring this data to a host computer?To stream it in real time is not particularly demanding - even USB 1 at 12 mbps could support the rate.Or I could store the data in SRAM - I've seen boards likePapilio Duothat have a 512K SRAM on the board. But it's still not clear how that data could then be moved to the host.What are your recommendations for an approach - both in terms of finding the right FPGA board, and the host interface? My searching shows that most low-cost, small FPGA development boards are not available. Are there any that are recommended and are available? What are simple host interface approaches?

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 22, 2021, 12:13:09 am
content: There is throughput and then there is latency.While throughput is absolutely no problem for USB FS as you said, you will still need to buffer data inside the FPGA, because if you just try to send it every 50 us without any buffering, it won't work! (Due to the nature of USB.)But you definitely won't need as much as 512 KBytes of RAM. A reasonable buffering time, if you're just using USB FS in bulk mode and want to be on the safe side without having to go through hoops with the PC software side, would be something like 100 ms. (You can probably get away with much less, but that wouldn't be as robust.) You can alternatively use USB with an isochronous transfer mode, but you'd still have to buffer data - just with a much smaller buffer. But something like 16 KB of internal memory on any but the smallest FPGAs should be no problem.

author: BrianHG
author_rank: Super Contributor
timestamp: November 22, 2021, 01:12:01 am
content: There are some 32bit micro-controllers (including those with >64k, or with built in dram) with full speed USB and a DMA capture port which might do all the work for you. An FPGA may be an extreme exercise in difficulty unless you are experienced or you have there is a reason you must use an FPGA, like generating special clock pulses and external control logic.As for USB in windows, worse comes to worse, there exists the media streaming channel which operates at the same level as USB audio devices and will shrink your buffer needs as you get a guaranteed low latency priority scheduled interval continuous set bitrate com channel.

author: voltsandjolts
author_rank: Unknown
timestamp: November 22, 2021, 10:52:38 am
content: Unless there are other requirements not mentioned, this does sound like a job for a usb capable microcontroller.One example could be theCypress FX2(cheap boards available on eBay) which thesigrokproject use for some multiple MB/s logic analyser. Thefirmwareand thedriverare open source so you can see how it's done. They use the GPIF to clock data into the FX2 at a fixed rate but you can alternatively use the FX2 FIFO mode just provides you with a simple, erm, FIFO interface that you fill at the rate your hardware wants. The FX2 is an 8051 based MCU so its a bit old school but all its doing is setting up the FX2 peripherals the way you want, it's not in the high speed data path. The freesdcc compilerworks fine with it.

author: mfro
author_rank: Regular Contributor
timestamp: November 22, 2021, 12:02:03 pm
content: if this is an inhouse and/or hobbyist setup, the simplest (and cheapest) way to send data from the FPGA to the host is using something that's already there.At least for Intel/Altera, you can send data back from the FPGA through the same JTAG (USB-Blaster, usually) connection that you need anyway to download/flash the bitstream the other way round. From the user point of view, this can be handled just like a serial connection.While it is not officially documented, this method works fine for me up to approx. 1 MB/s.

author: timg11
author_rank: Contributor
timestamp: November 22, 2021, 01:54:11 pm
content: Thanks for the comments. I didn't adequately explain that latency is not an issue at all. The 1-2 second event that is captured (triggered by an external signal, and combining logic analyzer functions for external signals and internal FPGA counters data) is standalone. After it occurs there is no constraint (other than patience) on transferring the data. That's why I was suggesting 512Kbytes of RAM to easily hold all the data.I'll look into 32 bit microcontrollers with built in RAM and USB, as suggested by @BrianHG. I'll dig into the Raspberry Pi Pico state machines to see if they could do the job.The algorithm is fairly simple: Clock a 24 bit counter at about 10 MHz. Every time a specific IO Pin changes state, synchronously capture the value of a 24 bit counter and (up to) 24 other IO pins, and save the data into the RAM buffer, incrementing the save address.If I find an FPGA board, I'll also look into reading the data after the capture over JTAG as suggested by @mfro.

author: rstofer
author_rank: Super Contributor
timestamp: November 22, 2021, 05:10:32 pm
content: The Teensy 4.1 might be a candidate:https://www.pjrc.com/store/teensy41.htmlAt a minimum, the Teensyduino library supports creating a USB->Serial device, you'll have to research the other USB functionalities.Personally, I would probably use Ethernet, specifically the LWIP library. I could create a socket server on the PC and a socket client on the Teensy. When the samples are ready, I would make a connection (TCP) from the Teensy and send the data to the server. I might consider which device should be the client and which should be the server.. The server creates a port and waits for a connection. The client initiates the connection.https://github.com/ssilverman/QNEthernethttps://github-wiki-see.page/m/TeensyUser/doc/wiki/EthernetWith just a quick glance, I don't see how QNEthernet implements Berkeley Sockets. LWIP natively implements the sockets and QNEthernet is built on top of LWIP so it ought to work.I think I would try to avoid USB unless it was a simple protocol like Serial or HID.

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 22, 2021, 06:25:27 pm
content: Quote from: timg11 on November 22, 2021, 01:54:11 pmFrom your description, doing this with a Pi Pico and its PIO would be no problem. You could use the PIO to both capture the pins and capture the counter, and use DMA to copy that in memory. That could essentially be done without any CPU intervention once set up, so the CPU would have time doing anything else, including transferring the data to the PC. Using TinyUSB for implementing the USB communication is the recommended way of doing it on the Pi Pico, and rather straightforward. The only thing to check would be the number of IOs you need. From what I got, you need at least 25 free IOs. The Pico board has them, but you'll be left with only a couple spare ones.

author: laugensalm
author_rank: Regular Contributor
timestamp: November 23, 2021, 08:53:54 am
content: If you don't need extended safety (verified behaviour) or real time / super low latency, there's indeed no need to use an FPGA, as outlined above and just any linux board would do (although I'd rather go with the Linkit Smart Duo, with on-board AVR for the low level stuff - unfortunately, those tend to be sold out).If you'd still want to do FPGA, I have some reference setups that do UDP/RTP streaming (the 'net scope' approach), but USB is also an option. The board/project is outlined here:https://hackaday.io/project/162259-netpp-nodeThe general pros/cons with UDP and TCP:- UDP : data will go out, no buffering, no SDRAM needed, but: potential packet loss or reordering through routers- TCP: Buffering required, arbitrary stalls can delay your stream, low performance with lwipSame goes on the USB side for Bulk transfers (TCP-like) and isochronous (UDP-like).So the basic dogma in a flaky network then boils down to choosing from either:- TCP: Rare timeouts and session aborts- UDP: More frequent drops and gaps in your stream, but data keeps flowingIn general, just any solution can cause potential overhead, either on the hardware or on the software side. Eventually, it all depends on the framework you're embedding this in.The quick spin with an embedded linux is often good enough for a prototype, but maybe not so for 24/7/365 usage.

author: tszaboo
author_rank: Super Contributor
timestamp: November 23, 2021, 09:50:05 am
content: FT2232H in FIFO mode (or some parallel interface) can support this speed. You should be aware, that the max speed on USB doesn't guarantee that it is received.

author: langwadt
author_rank: Super Contributor
timestamp: November 23, 2021, 10:43:34 am
content: Quote from: tszaboo on November 23, 2021, 09:50:05 amyes it can do close to 40MB/s and you can use the second interface on the chip to configure the FPGA

author: Morgan127
author_rank: Contributor
timestamp: November 25, 2021, 06:44:57 am
content: If you got a Xilinx FPGA I can recommend to use one of the drop-in Ethernet ip cores fromFPGA-Cores.com.It is very easy to use and supports all necessary Ethernet stuff. They are free to download and use. No processor needed.

author: hal9001
author_rank: Regular Contributor
timestamp: November 25, 2021, 09:31:46 am
content: Quote from: mfro on November 22, 2021, 12:02:03 pmWhere can I find more information about this? Can you read the data by a terminal emulator?

author: NorthGuy
author_rank: Super Contributor
timestamp: November 25, 2021, 02:49:57 pm
content: Quote from: mfro on November 22, 2021, 12:02:03 pmI get almost 3 MB/s with FT232H through JTAG pins with Xilinx. The big problem is that you have to poll.

author: mfro
author_rank: Regular Contributor
timestamp: November 25, 2021, 02:52:31 pm
content: Quote from: hal9001 on November 25, 2021, 09:31:46 amThis is what I'm using:https://github.com/mfro0/jtag_terminalMight need a little tweeking depending on what Intel FPGA you are working with.You can use the jtag_terminal (part of the Quartus installation) or write something on your own using the Intel/Altera librariies.

author: timg11
author_rank: Contributor
timestamp: November 28, 2021, 08:39:08 pm
content: Quote from: SiliconWizard on November 22, 2021, 06:25:27 pmThanks! I'm exploring this option. I've got the VScode environment for the Pico set up on a Pi4, with the Pi-pico plugged in. I have built hello_usb.c, and it runs on the Pico.Next up is learn how to configure a PWM block to use the 16 bit counter to measure the interval between rising edges. When the program runs it will capture the counter values for each rising edge, starting with the first input signal edge, as well as capturing 16 of the GPIO pins. Both 16 bit values will be written to an array in RAM. It will run for 1 second or until RAM is full. The the results can be written out over the USB STDIO.

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 28, 2021, 10:11:50 pm
content: If you learn a bit about PIO, you may find out that you could also use it to capture counters (but 32-bit this time!) with it instead of using the PWM, which would probably make it easier to synchronize with IO state capture.