LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Help Implementing CANBUS RX fifo - LabVIEW FPGA

Hello,

 

I am implementing a Labview FPGA project in which CANBUS messages are handed off to a software application. In our initial program, we handed the CANBUS messages to software with no buffer. This results in lost messages. What is the easiest way to instantiate a FIFO in this case? I am noticing that the CANBUS type in Labview is a cluster with multiple fields of different sizes, which makes it difficult to pass to other types of processing blocks.

 

I have attached an example which I think will work. By joining the fields, I was able to pass them to a custom IP block I will replace with a simple FIFO written in VHDL (for now, the VHDL module simply passes the input to the output so I can verify the Labview interfaces).

labview_canfifo_implementation.png

 

I have confirmed that the indicators all show the same data, which means the above configuration should work as expected. I am a bit dissatisfied with how messy the diagram is. See below for matching data at both the input and the output to the placeholder FIFO module. Does anyone have recommendations for cleaning up the above diagram?

labview_canfifo_running.png

 

 Furthermore, the field for "data" breaks out to an array of 9 fields on the left for some reason, and only 8 on the right. Does anyone know why this is?

rottenelk_0-1726186311545.png

 

Another pet peeve is that Labview doesn't allow IP ports greater than 64 bits. The total amount of bits in a CANBUS cluster is 200 bits (or 192 bits, depending on the answer to the extra byte in the "data" field above). Is there anyway to pass the entire cluster as a single input to the VHDL IP port?

 

Thanks in advance for the help! 😁

0 Kudos
Message 1 of 9
(583 Views)

The NI 985x FPGA I/O node returns data as either six U32s corresponding to the 192 bits of a CAN Frame, or as a cluster of elements representing the different parts of a CAN Frame such as identifier and timestamp. Reference: NI 9853 and 9852 with CompactRIO FAQ - NI

Why don't you use the six U32 instead? You can merge them into three U64. You can skip all the bundling and unbundling.

 

According to Importing External IP Into LabVIEW FPGA,

An important consideration when using CLIP Nodes is the data types supported in LabVIEW FPGA and how they translate to VHDL data types. If your IP uses a logic vector that is not one of the data types listed in Table 1, you need to write a wrapper to extend, cut off, or break up the standard LabVIEW types to fit the data widths of the IP.

Unfortunately, I don't think there is anyway to fit the entire 192 fits into one input.

-------------------------------------------------------
Control Lead | Intelline Inc
Message 2 of 9
(560 Views)

Hi elk,

 


@rottenelk wrote:

Furthermore, the field for "data" breaks out to an array of 9 fields on the left for some reason, and only 8 on the right. Does anyone know why this is?

Most probably because you use the ArrayToCluster function followed by Unbundle instead of IndexArray…

Why do you need to convert an array to a cluster just to index the elements???

(Did you read the help for ArrayToCluster and learn about all its options and their default values?)

 

The same applies to this Bundle node: why do you need to create an intermediate cluster when you want to build an array? (There's a function named "BuildArray", guess what it's for…)

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
Message 3 of 9
(538 Views)

Thanks for your inputs! Basically I placed nodes until I found one that didn't produce any errors, sorry if it wasn't what I should have used. Labview isn't very intuitive when it comes to data types.

 

Can I also ask how I might implement a rising edge detect boolean type signal that goes high when a new can frame is received? I need it to indicate when my fifo should write a new piece of data to memory. Thanks!

0 Kudos
Message 4 of 9
(502 Views)

@rottenelk wrote:

Can I also ask how I might implement a rising edge detect boolean type signal that goes high when a new can frame is received? I need it to indicate when my fifo should write a new piece of data to memory. Thanks!


You already implemented that. By polling the CAN FPGA node, you get a new frame when there is no error.

-------------------------------------------------------
Control Lead | Intelline Inc
Message 5 of 9
(496 Views)

I see, thanks. Can I ask another question about that case statement in green? Inside of it, I have instantiated a proper FIFO module in VHDL. In writing this module, I assumed that the clock input would be the system clock, 40MHz. Based on the testing I've done, it almost appears that the VHDL module only ticks forward when there is a new CAN message. This is somewhat problematic for the way I wrote the module and with my understanding of how FPGAs work.

 

Here is my question: when VHDL modules are instantiated inside of case statements, do they tick forward at the FPGA clock rate, or only when the case statement is called?

0 Kudos
Message 6 of 9
(491 Views)

Hi elk,

 


@rottenelk wrote:

Here is my question: when (VHDL modules are instantiated) code inside of case statements, do they tick forward at the FPGA clock rate, or only when the case statement is called?


LabVIEW follows the main mantra "THINK DATAFLOW!".

As such code is only executed when it is called (with data available) so also the code in your case structure is only executed in the "no error" case…

 

Can you name any other programming language that executes code inside cases (or IF-THEN-ELSE branches) when the branch isn't called?

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 7 of 9
(478 Views)

@GerdW wrote:

 

LabVIEW follows the main mantra "THINK DATAFLOW!". As such code is only executed when it is called (with data available) so also the code in your case structure is only executed in the "no error" case…

That is not entirely true for the case of FPGA code. For most cases you can assume that it is like that but in the case of FPGA hardware it is often much easier to simply have code segments execute anyhow and ignore the result, since FPGA is great in having many things go on in parallel and much more difficult to have certain aspects only execute sometimes. But LabVIEW also goes to great lengths to try to avoid side effects of such code execution (with the exception of increased power consumption because of gates toggling while they shouldn't according to the LabVIEW code diagram).

 

Those transformations from a LabVIEW directed graph to the VHDL source code used to compile into the FPGA bitfile are pretty complex and involved because of such constraints.

Rolf Kalbermatter
My Blog
Message 8 of 9
(468 Views)

@rottenelk wrote:

Here is my question: when VHDL modules are instantiated inside of case statements, do they tick forward at the FPGA clock rate, or only when the case statement is called


The CLIP Node executes independently and in parallel with your IP developed in LabVIEW FPGA.

In contrast, the IP Integration Node is inserted into the LabVIEW FPGA block diagram and executes as defined by the dataflow of the LabVIEW VI.

Reference: Importing External IP Into LabVIEW FPGA

 

Since you are using a CLIP node, it runs independently on the FPGA clock.

-------------------------------------------------------
Control Lead | Intelline Inc
0 Kudos
Message 9 of 9
(439 Views)