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: 

LV FPGA Socketed CLIP workflow w/ NI PXIe-6591R

Solved!
Go to solution

I can chime in on how to program your Microblaze in the LabVIEW environment. This is something I have done many times successfully, though it requires some interesting tricks. First of all, I am going to assume that your design is compiling succesfully in LVFPGA with the Microblaze integrated into it, and it seems like the next step for you is just to load your program into the Microblaze's memory. If you haven't got that working, we can take a step back and work on the steps needed to integrate the MIcroblaze IP into a Socketed CLIP.

 

On to loading the program into memory! There are a few files that you will need for this process to work.

 

1. The bmm file from your design. This is a file that lists the location and structure of the BRAM memory used by the Microblaze. You can generate this file by running the write_bmm command from the vivado tcl prompt. You only need to generate this file once unless you change the size or location of your BRAMs.

 

2. The elf file from the SDK. This is the compiled binary of your Microblaze project code. This is updated each time you build your c project.

 

Using these two files and a program called data2mem.exe that is provided with vivado 2013.4 and earlier we can generate a ucf that contains constraints to initialize the BRAMs with the program memory. The command to do this is:

 

data2mem.exe -p <your FPGA part> -bm <path to your bmm file> -bd <path to your elf file> -ou <output ucf file name> -u

 

Unfortunately, Vivado does not support ucf format, so we need to convert those constraints to xdc. This can be quickly done with the following regular expressions using find and replace. To do so, open the newly created ucf file in your text editor of choice and enter the following find and replace commands. Save the file as an XDC when you are done.

 

find: .*(Using_.*) (INIT_..) .=\ "(.*)";

replace: set_property \2 \3 [get_cells -hier *\1]

 

find: //

replace: #

 

Now, include your new xdc in your CLIP and be sure to add it to your CLIP xml file list so that it gets pulled by LVFPGA. Now when you rebuild your project in LabVIEW the xdc constraints will be applied to your design and your Microblaze will have its code loaded! This process is easily scripted so that is can be run automatically everytime you rebuild your design in the SDK. I would highly recommend you do that as it will make your workflow much smoother!

 

Good Luck,

Daniel

Message 11 of 26
(3,331 Views)

Hello, thank you for joining the thread and sharing your knowledge.

 

However, it seems like I cannot generate .bmm files with the Tcl console:

write_bmm file.bmm
ERROR: [Memdata 28-96] Could not find a BMM_INFO_DESIGN property in the design. Could not generate the merged BMM file: c:/NIFPGA/programs/Vivado2014_4/bin/file.bmm
ERROR: [Common 17-69] Command failed: Failed to create a merged bmm file.

I've tried troubleshooting this error digging into Xilinx board and ARs, with out luck though... I'm launching the command after synthesis because it seems pointless to me to go any further w/ implementation in Vivado.

 

Since you've talked about it (and to double check it), here it is my typical workflow (SDK apart):

To develop this design I'm using Vivado in Block Design mode. I generate the output products, add a top level wrapper and synthesize  the design with -mode out_of_context. After synthesis, I usually export  the netlists with this Tcl to a convenient location:

 

# Export top level netlist
write_edif -force $CLIP_PATH/design_1_wrapper.edf

foreach cell [get_property NAME [get_cells -hier -filter {IS_PRIMITIVE==0}]] {
    puts "Exporting '$cell' netlist..." 
    write_edif -cell $cell $CLIP_PATH/cells 
}

I then put together a Socketed CLIP VHDL wrapper plus some constraints and pack everything in the LV CLIP Wizard. Since when I've fixed the MGTRefClk issue, the compile jobs now complete successfully.

 

 

Best regards,

DMA.

 

0 Kudos
Message 12 of 26
(3,301 Views)

No problem, I'm glad to help. I followed your process in Vivado 2013.4 and was able to generate the bmm using the following steps:

 

1. I made a new empty RTL project.

2. I created a block design that had a Microblaze and some memory. (I didn't bother with any peripherals, but I doubt it will make a difference).

3. I generated the block design.

4. I let vivado generate a wrapper for the top level.

5. I synthesized the design.

6. I opened the synthesized design and typed write_bmm <path to my.bmm> and it worked!

 

You probably can start somewhere in the middle and resynthesize and open that synthesized design. If you do have to start from step 1 you should be able to import all of your sources, I would think. I haven't tested it personally though.

 

While doing this I learned that the regular expressions I gave you were specific to the design I had done previously. Vivado does not always name the BRAMs the same so you may need to update the first regular expression to search for the name of you BRAMs in the ucf. All that needs to happen is this ucf line:

 

INST U0/lmb_bram_I/RAM_Inst/Using_B36_S9.The_BRAMs[3].RAMB36_I1 INIT_00  = "001800003C00400070002800000000000000000000006C000000880058005000"

 

Needs to turn into this xdc line:

set_property INIT_00 001800003C00200050000800000000000000000000006C000000880058005000 [get_cells -hier *Using_B36_S9.The_BRAMs[3].RAMB36_I1]

I made a new regular expression search that should always (hopefully) work if it doesn't you should be able to tweak it to get the results seen above. Note that I only keep the name of the blockram at the lowest level of the hierarchy (IE after the last "/") and then use the -hier switch to force Vivado to search through the design. This is because your CLIP will not be at the top of the design hierarchy when it is pulled into the full LVFPGA project.

 

The new regex:

 

find: INST.*/(.*)\s+(INIT.*?)\s+=\s+(".*");

replace: set_property \2 \3 [get_cells -hier *\1]

 

Let me know if you have anymore questions!

Message 13 of 26
(3,274 Views)

Hello again.

 

I'm following your steps but LV throw me a lot of warnings like this (and not initializing the BRAMs consequently):

WARNING: [Vivado 12-180] No cells matched '*mb_system_i/microblaze_0_local_memory/lmb_bram/U0/inst_blk_mem_gen/gnative_mem_map_bmg.native_mem_map_blk_mem_gen/valid.cstr/ramloop[7].ram.r/prim_noinit.ram/DEVICE_7SERIES.WITH_BMM_INFO.TRUE_DP.SIMPLE_PRIM36.TDP_SP36_NO_ECC_ATTR.ram'. [/opt/apps/NIFPGA/jobs/tN30BD2_tm2jwui/PXIe6591R_Top_Gen2x8.xdc:575]

 

Seems that the compile worker cannot find the cells.

I got a data2mem .ucf output file quite different from yours. I've obtained contains constraints like this:

INST mb_system_i/microblaze_0_local_memory/lmb_bram/U0/inst_blk_mem_gen/gnative_mem_map_bmg.native_mem_map_blk_mem_gen/valid.cstr/ramloop[7].ram.r/prim_noinit.ram/DEVICE_7SERIES.WITH_BMM_INFO.TRUE_DP.SIMPLE_PRIM36.TDP_SP36_NO_ECC_ATTR.ram INIT_00  = "00000055012000104000A0A8299024510206054401207004014010144A200228";

I've tried regex replace them into:

set_property INIT_00 256'h00000055012000104000A0A8299024510206054401207004014010144A200228 [get_cells -hier {%ClipInstancePath%/mb_system_i/microblaze_0_local_memory/lmb_bram/U0/inst_blk_mem_gen/gnative_mem_map_bmg.native_mem_map_blk_mem_gen/valid.cstr/ramloop[7].ram.r/prim_noinit.ram/DEVICE_7SERIES.WITH_BMM_INFO.TRUE_DP.SIMPLE_PRIM36.TDP_SP36_NO_ECC_ATTR.ram}]

 

set_property INIT_00 256'h00000055012000104000A0A8299024510206054401207004014010144A200228 [get_cells -hier {*mb_system_i/microblaze_0_local_memory/lmb_bram/U0/inst_blk_mem_gen/gnative_mem_map_bmg.native_mem_map_blk_mem_gen/valid.cstr/ramloop[7].ram.r/prim_noinit.ram/DEVICE_7SERIES.WITH_BMM_INFO.TRUE_DP.SIMPLE_PRIM36.TDP_SP36_NO_ECC_ATTR.ram}]

 

set_property INIT_00 256'h00000055012000104000A0A8299024510206054401207004014010144A200228 [get_cells -hier -filter NAME=~*%ClipInstancePath%*mb_system_i/microblaze_0_local_memory/lmb_bram/U0/inst_blk_mem_gen/gnative_mem_map_bmg.native_mem_map_blk_mem_gen/valid.cstr/ramloop[7].ram.r/prim_noinit.ram/DEVICE_7SERIES.WITH_BMM_INFO.TRUE_DP.SIMPLE_PRIM36.TDP_SP36_NO_ECC_ATTR.ram]

 

set_property INIT_00 256'h00000055012000104000A0A8299024510206054401207004014010144A200228 [get_cells -hier -filter NAME=~*mb_system_i/microblaze_0_local_memory/lmb_bram/U0/inst_blk_mem_gen/gnative_mem_map_bmg.native_mem_map_blk_mem_gen/valid.cstr/ramloop[7].ram.r/prim_noinit.ram/DEVICE_7SERIES.WITH_BMM_INFO.TRUE_DP.SIMPLE_PRIM36.TDP_SP36_NO_ECC_ATTR.ram]

 

set_property INIT_00 256'h00000055012000104000A0A8299024510206054401207004014010144A200228 [get_cells -hier -filter NAME=~*ramloop[7].ram.r/prim_noinit.ram/DEVICE_7SERIES.WITH_BMM_INFO.TRUE_DP.SIMPLE_PRIM36.TDP_SP36_NO_ECC_ATTR.ram]

 

set_property INIT_00 256'h00000055012000104000A0A8299024510206054401207004014010144A200228 [get_cells -hier -filter NAME=~*ramloop[7]*DEVICE_7SERIES.WITH_BMM_INFO.TRUE_DP.SIMPLE_PRIM36.TDP_SP36_NO_ECC_ATTR.ram]

 but with the same outcome.

0 Kudos
Message 14 of 26
(3,196 Views)

I'm really running out of ideas here... I've tried every possible way known to me to match those cells.

 

According to this NI's white paper all I need should be the %ClipInstancePath% macro but it is not helping. Also tried all flavors of get_cells, with and without -hier, -filter or -regexp flags as well...

What works in Vivado, always return the same error stating the get_cells didn't match anything.

 

Might not be a problem in the contraints syntax. How can I be sure my design has been correctly instantiated into the socketed CLIP?

 

I've attached the resulting log (compilation completed successfully but the firmware it is not loaded into the BRAMs).

0 Kudos
Message 15 of 26
(3,169 Views)

There are two places in the Xilinx Vivado log where constraints are processed. One is in synthesis and a second time is in implementation. If you're constraining a black box/netlist, you'll likely see your synthesis constraints come back as not found since the black box netlist hasn't been processed yet. The second parsing of XDC constraints will be the actual one that you should care about. It is OK to have synthesis constraint warnings. Does this sound like what you're running into?

Kyle A.
National Instruments
Senior Applications Engineer
0 Kudos
Message 16 of 26
(3,150 Views)
Solution
Accepted by topic author DoesntMeanAnything

It seems like, in general, you are converting the UCF to XDC correctly, at least as far as syntax goes. There could be a couple of reasons that Vivado is not able to find the BRAMs in your design according to the constraint you have written. Here are two more things you can try:

 

1. Try formatting your constraint as follows:

set_property INIT_00 256'h00000055012000104000A0A8299024510206054401207004014010144A200228 [get_cells  {%ClipInstancePath%/<path from the top of your clip to the microblaze>/mb_system_i/microblaze_0_local_memory/lmb_bram/U0/inst_blk_mem_gen/gnative_mem_map_bmg.native_mem_map_blk_mem_gen/valid.cstr/ramloop[7].ram.r/prim_noinit.ram/DEVICE_7SERIES.WITH_BMM_INFO.TRUE_DP.SIMPLE_PRIM36.TDP_SP36_NO_ECC_ATTR.ram}]

Note that I eliminated the -hier (an abbreviation of -hierarchical) switch. %ClipInstancePath% will be replaced with the path to your CLIP top level. Then if you include the path from the top level of your CLIP to the microblaze and append it to the path from the microblaze to the BRAM you will have listed the path all the way from the very top of the design to the BRAM you are trying to constrain.

 

2. (LV2015 only) I believe that you may be using an EDIF netlist to wrap your CLIP and pass it into LabVIEW FPGA. Instead of an EDIF you can export a DCP from Vivado. You can open this generated DCP in Vivado and apply the XDC constraints file you generated directly in the TCL prompt. Write a new DCP that contains the applied constraints and pass that back to Labview FPGA instead of the EDIF. You will need to modify your CLIP XML to point to the DCP instead of the EDIF.

 

Good Luck,

Daniel

 

Message 17 of 26
(3,141 Views)

A couple of minutes ago I succeded into programming the MB via the XDC contraints.

 

Also I've discovered that int Vivado (at least in v2014.4)  the write_bmm commands return the error if you have the -mode out_of_context setted in the synthesis options. Just wanted to write it about in case anyone in the future might find him/herself in my shoes: first, be sure to synthetize the design without the -mode out_of_context option before launching the command to export the bmm file; then, synthetize the design again setting the option before exporting your netlists.

0 Kudos
Message 18 of 26
(3,094 Views)

Hi,

 

I am trying to use the MicroBlaze MCS on my PXIe-6592R board.  I have tried many things, but each time that I get to running my code on the actual hardware I get nothing...

 

So here is what I understand:

Step 1 - Create a Vivado Project targeting the FPGA for the PXIe-6592R (xc7k410tffg900-2)

Step 2 - Create a block design, add MicroBlaze MCS with the following options:

* 50MHZ

* 128 KB RAM

* Enable GPI channel 1, 8 bits

* Enable GPO channel 1, 8 bits

Step 3 - I run "Generate Output Products" with "Out of Context per IP" set

Step 4 - I create an "HDL Wrapper" on the Design

Step 5 - I run implementation on the entire project

Step 6 - I start SDK and create the Hardware Platform Specification project by using the file:

<project root>\lv_vivado_1.srcs\sources_1\bd\d_mcs\ip\d_mcs_microblaze_mcs_0_0\d_mcs_microblaze_mcs_0_0_sdk.xml

Step 7 - I create my ELF file

Step 8 - I associate my ELF file via "Tools->Associate ELF File"

Step 9 - I re-run my implementation

Step 10 - I write a checkpoint

Step 11 - I create a CLIP by:

* Create a wrapper VHDL file

* Add the dcp file from the checkpoint

 

When I run my code on the hardware, I get no activity.

 

I have read some documentation that calls for adding a BMM file and scoping it to cells, but still no luck.

 

Any advice/tips?

 

thanks

0 Kudos
Message 19 of 26
(2,534 Views)

Associating the ELF file is not enough, you need to convert the ELF file into XDC statements and then let LV FPGA to implement the design and generate the bitfile. XDC files can be included into your Socketed CLIP in LV FPGA.

To do so, you need the BMM file containing the available memory description. You can use the Vivado TCL write_bmm command after completing and opening a synthesized design (OoC synthesis are no good for this).

0 Kudos
Message 20 of 26
(2,527 Views)