Keeping 32-bit wide stream in byte sync, synchronous stream

Post a reply

Confirmation code
Enter the code exactly as it appears. All letters are case insensitive.
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :!: :?: :idea: :arrow: :| :mrgreen: :geek: :ugeek:
BBCode is ON
[img] is ON
[flash] is OFF
[url] is ON
Smilies are ON
Topic review

Expand view Topic review: Keeping 32-bit wide stream in byte sync, synchronous stream

Re: Keeping 32-bit wide stream in byte sync, synchronous str

Post by support » Wed Jun 13, 2018 3:53 pm


Actually, kernel 3.10 doesn't have the Xillybus driver at all, so you'll need to compile and install it.

Besides, you mentioned a VM. If you meant a virtual machine, it's not sure if it can access any PCIe device directly. Suggest checking that up.


Re: Keeping 32-bit wide stream in byte sync, synchronous str

Post by Guest » Wed Jun 13, 2018 3:46 pm

My VM has RHEL 7.2. It responds to uname -r with 3.10.0-693.5.2.el7.x86_64. I'm guessing 3.10 is less than the 3.17 you mentioned and synchronous streams might work without having to download the driver separately.

If not, you've indicated how to get around it. Thanks.

Re: Keeping 32-bit wide stream in byte sync, synchronous str

Post by support » Wed Jun 13, 2018 2:27 pm


To obtain the kernel revision of the currently running system, I suggest using "uname". For example, on my computer:
Code: Select all
$ uname -r

So it's 4.4.0, which is influenced by the bug.

If that is the case on your computer as well, just compile and install the driver available from the website, as described in the Getting Started Guide for Linux. Whether your kernel is fine to begin with, or you've installed the driver for download, everything will work fine, including synchronous streams. No need to hassle with it further.

It also seems your understanding on the mechanism is in sync (not clear if pun was intended). So I suggest just going for it.


Re: Keeping 32-bit wide stream in byte sync, synchronous str

Post by Guest » Wed Jun 13, 2018 10:33 am

Thanks very much, Eli.

Note I wanted to see fifo.c to see if it did anything special about the fifo being multiple bytes wide on the FPGA. It does not appear to do anything special.

I AM CONFUSED about Linux versions and synchronous stream support. I'll be using the latest revision of RHEL, I believe it's 7.5 right now. Frankly, I don't know how to map that to the v3.17 and v4.6 numbers you referenced, and I don't know if synchronous streams are supported. Will synchronous streams be synchronous in RHEL 7.5?

I had already read the programming guide about synchronous streams, but I got a different impression from what I read. Now that you clarified, I perhaps get the correct impression. That is, the doc says "the IP core's logic in the FPGA will not fetch data from the user application logic unless the user application has an outstanding request to read that data from the file descriptor." Originally, my mental model for that was that there was a normally empty FIFO from my FPGA fabric to the Xillybus IP, along with a separate request line from the Xillybus IP to my FPGA fabric. The separate request line kept the FIFO at either empty or one entry. Your explanation of omitting the FIFO altogether clears it up. In this case, my FPGA fabric continuously presents "live" data to the Xillybus IP. Therefore no separate request line is required. MEANWHILE, on the linux side, the synchronous nature *implies* that no further buffering occurs inside the Xillybus IP on the FPGA or inside the Xillybus driver on the linux host. With no such buffering, a linux application read() should get the "live" data my FPGA fabric has been presenting.

HOWEVER, if there's a driver bug and synchronous streams aren't properly supported in RHEL 7.5, then the above won't work as described. I *suspect* the difference will be that the Xillybus driver may buffer some data. This means the linux application must do an initial read in a loop to consume all that buffered data. But this won't work, because the asynchronous stream will repopulate that buffered data. Eventually all the buffered data will have come from my current FPGA fabric "live" output (think LOW BANDWIDTH information). Unfortunately, I can't see how my linux application will know the difference. It seems this can only work through exhausting the buffered data and blocking on the read (which won't happen with an asynchronous stream), or a working synchronous stream. (That is, without a separate request line of some kind, so that my FPGA fabric only provides non-empty at the right time, rather than providing an endless stream of live data.)

So, please help me figure out how to make sure I get the "live" data. Maybe the answer is that synchronous streams are working in RHEL 7.5. Maybe the answer is something else. (Be aware that when I suggested that synchronous streams would help with byte alignment, I was also thinking about the stream-empty-blocking interval as a method. That is, when a synchronous stream goes empty and blocks the read, this can not only help ensure "live" data, but also ensure byte alignment.)

(That appendix A explains exactly what I would have assumed was under the hood, in general. Note that I see your handling of partially filled buffered as inspired.)

Thanks VERY much.

Re: Keeping 32-bit wide stream in byte sync, synchronous str

Post by support » Wed Jun 13, 2018 4:26 am


The sample utilities, with fifo.c included, can be downloaded from the site's main download page:

fifo.c can be found under xillybus/demoapps. I should mention however that in the vast majority of cases, it has no practical use, because Xillybus' DMA buffers can usually be configured (at the IP Core Factory) to be large enough for most purposes.

If you intend to use synchronous streams, I'd suggest using the Linux driver on that bundle as well, if your Linux happens to run on a kernel between v3.17 and v4.6 (v3.17 included, v4.6 excluded). Unfortunately, a bug sneaked into the driver while adapting it to Linux' coding standard, but was never in the driver available for download at the website. This bug essentially makes an synchronous stream asynchronous.

As for maintaining 4-byte alignment: The guidelines for proper I/O are given in section 3 of the Programming Guide, ... _linux.pdf . For the experienced UNIX programmer, there is really nothing new in that section: It's just the common practice for robust I/O on a UNIX system. Also, the allwrite() function in the demo application implements these guidelines.

But even without proper interrupt handling and such, there is no way that a read() or write() call will break the stream's natural alignment as long as the number of bytes requested are a multiple of the stream's width. In other words, if you request 1024 bytes on a 4-byte stream, you might get 1020, but not 1021 (unless the alignment has been messed up on a previous read/write call).

As for your third question, synchronous streams do nothing in favor of or against keeping the 32-bit alignment (which isn't an issue anyhow, as said above). It merely makes sure that the data is consumed at the FPGA side only when requested by the host's program, and not prefetched. So it's indeed the correct thing for obtaining "live" data.

The FPGA's logic doesn't need to be aware of the nature of the stream it's connected to. But the FIFO-in-the-middle method might not be the right way for "live" data, as the data in the FIFO has to be fetched at some earlier time. For just sampling a 32-bit GPIO word at the FPGA, consider connecting the wires for sampling directly to the Xillybus core's data wires, and tie the respective "empty" port low. If the stream is synchronous, a plain read() call of 4 bytes will fetch an updated sample of the word each time. Just don't forget that the data presented to the Xillybus core (as well as all other signals) must be clocked with bus_clk.

Synchronous streams are explained in section 2 of the Programming Guide. If you want to understand the underlying mechanism, Appendix A describes the under-the-hood part. In particular, note the remark on synchronous streams at the end of section A.3.3. That's all there is to it. Reading the Appendix is however suggested only out of curiosity: To get it working right, following the guidelines is enough.


Keeping 32-bit wide stream in byte sync, synchronous stream

Post by helmutforren » Tue Jun 12, 2018 8:02 pm

First, I'm having trouble finding your example fifo.c that I read about here and there. Where do I find it? It wasn't in or at . Thanks.

Second, I'm concerned about the following. If I have a 32-bit wide FIFO in my FPGA, that connects to Xillybus at 32-bits wide, it will eventually come out a named pipe that reads 8-bit characters. If the FPGA pushes in a single 32-bit word, then the linux application will read 4 bytes. But a billion access later, with interruptions and this and that... My 40yr experience gut tells me to worry about keeping that in sync. I'm concerned I may get to the point where the application is 2 bytes off and reading the last 2 bytes of a previous 32-bit word, along with the first 2 bytes of a subsequent 32-bit word.

Do you have a built-in or preferred method for ensuring such sync?

Third, I might want to use a synchronous stream for a low-bandwidth GPIO interface of my FPGA. I imagine that making the stream synchronous should substantially or eliminate any concerns over 8-bit position synchrony within 32-bit words. I want to be sure I get "live" GPIO from FPGA to host, anyway. I don't easily find doc just yet on exactly HOW the interface between Xillybus and my FPGA fabric works for a synchronous stream. I imagine you may have an extra side signal to request that my FPGA fabric push a value onto the fifo to Xillybus. But I don't want to make an assume/out/of/and. I can't find doc on how my FPGA fabric must act differently for a synchronous stream, or how my FPGA fabric doesn't act differently and therefore what must I do to make sure that "live" GPIO data is received by the linux application when it does a read.