From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Labview FPGA DMA FIFO number of elements to read does not match elements sent among other issues

Solved!
Go to solution

I am trying to implement a serial communications controller on a PCI-7830R using LabVIEW 2016 and my current architecture requires a FIFO in different clock domains so I have been attempting to hand off the DMA fifo elements coming from the host to a target scoped fifo using a for loop.  Everything simulates correctly but when I implement it in hardware, the results become unpredictable, as when I send small number of elements it works perfectly, but when sending larger numbers i.e. ~1kB of data sometimes it works and sometimes it doesn't. by this I mean, my architecture strips the top two bytes from the FIFO which is the number of elements that are part of the packet, a for loop uses this number to transfer that many elements into the transmit FIFO (all of this is done in a regular while loop). the issue is that the for loop executes

the correct number of times, but when it is over, the transmit fifo is missing elements, and the DMA fifo has extra elements.  I thought maybe the DMA fifo is being loaded with elements too slowly even though I load it all as a single array so I tried to make it wait for the DMA fifo to have alteast the number of elements in the packet, but then the transfer between FIFOs never executes, as it seems the Number of Elements to Read value is incorrect.

 

When I send the array, my host VI reads back the empty elements remaining which updates correctly (~1kB less than the depth) but the number of elements to read only gives 69 elements in the FIFO. I have Isolated this behavior in it's own minimal VI, see below.

note: CMD is the DMA FIFO, each element is U8 and it is set to arbitrate if multiple requestors only. top level clk is 40 MHz

 

FPGA Vi:

FPGA Target VI.png

HOST VI:

 

Host Target VI.png

 

HOST Front panel while running:

Host VI front Panel.png

0 Kudos
Message 1 of 7
(1,037 Views)

I suspect something is wrong with the handshaking and that is causing data to be lost.

 

Can you post your LabVIEW project (.lvproj) file?  Does the code you post, demonstrate the error when running on hardware but not in simulation?


Certified LabVIEW Architect, Certified Professional Instructor
ALE Consultants

Introduction to LabVIEW FPGA for RF, Radar, and Electronic Warfare Applications
0 Kudos
Message 2 of 7
(1,021 Views)
Solution
Accepted by topic author JGagnon

Keep in mind that Host-to-Target and Target-to-Host DMA FIFOs have 2 different buffers. One on the host side, which you configure in your host VI with the "Configure" method node, and one on the target side, which can be configured in the properties of your FIFO project item, under your FPGA target (right-click on your FIFO item in the project explorer -> Properties -> General -> Requested Number of Elements).

 

I suspect that your buffer size on the target side is only 69. If you never activate "Boolean 2", your data is never dequeued and the FIFO buffer on the target side fills up and simply blocks any further transmission from the host to the target. From your code and screenshots, I see that you are sending 1031 bytes in total (including the size info), of which 962 (5000-4038) are in your host buffer, and the remaining 69 are stuck in your target buffer.

Message 3 of 7
(1,009 Views)

Thank you for giving an excellent explanation, I did not realize there were two separate buffers but it makes sense now that I think about it. I have increased the number of elements on the target side now, but I am still getting the same error that led me down this rabbit hole, I will mark this as a solution once the other half of my problem gets some help, I will upload new files shortly.

0 Kudos
Message 4 of 7
(992 Views)

Simulation: start of the VI

JGagnon_12-1680906513119.png

 

 

Simulation: Running normally

JGagnon_13-1680906542115.png

 

no matter how many times I load into the CMD fifo and clear the transmit fifo i do not encounter an issue.

 

 

Running on hardware: start of the VI

JGagnon_10-1680906413378.png

 

strangely the space in the transmit fifo is different compared to the simulation but this isn't really an issue

 

Running on hardware: semi-normal operation

JGagnon_14-1680906597455.png

 

 

transmit fifo fills successfully although it seems like the actual size matches the simulation even though when it is empty it does not match the simulation not really sure if it is an issue or not but the error is more apparent below

 

Running on hardware: abnormal operation

JGagnon_8-1680906150674.png

 

6 elements get left behind in the cmd fifo, leading to two of them being stripped off the top as it appears to the program that there is another packet of size FFFF waiting to be transitioned into the FIFO when in reality the 6 bytes is the last part of the previous packet that was loaded. this is despite the fact that the reported packet size of the previous packet was 1024 as it should be.

 

 

to recreate this error, it seems to pretty consistently happen if I hit ld once, flip read Tx FIFO on and then off, then hit ld a second time, the packet size buffer will get filled with FFFF and 4 bytes get left in the CMD FIFO.  I have attached the files and project.  Any help is very much appreciated.

 

 

 

0 Kudos
Message 5 of 7
(987 Views)
Solution
Accepted by topic author JGagnon

By looking at your code, it seems that you are always using a timeout of 0 when reading from the CMD FIFO. While it may work in simulation (because it executes way slower), with the hardware your FPGA loop may execute faster than the speed to which the CMD FIFO is transmitting data from host to target.

 

There are 2 main places that may have a problem:

 - when reading the size info: As soon as you have at least 1 byte, you immediately read 2 bytes. The second byte may not even be there yet.

 - when reading the actual data: As soon as you have the size, you immediately read N bytes, which may not be there yet.

 

Try your code by setting a timeout of -1 to wait indefinitely in first place, then you can always try later some finite amount of time like 1000 ticks if you are worried about deadlocking your loop.

 

 

Message 6 of 7
(955 Views)

sorry for the late reply, this works perfectly thanks! I feel silly for not realizing this

0 Kudos
Message 7 of 7
(876 Views)