QDB vs. QXP, Quartus Pro vs. Standard: Post-synthesis packaging of an IP core

This post was written by eli on February 25, 2018
Posted Under: FPGA,Intel FPGA (Altera)


It’s often desired to package an piece of FPGA logic in a post-synthesis (netlist) format for later use in another project. IP core vendors often deliver their products as netlists, partly to protect themselves from unauthorized copying and use, and partly to ensure that possible bugs in the end-user’s synthesizer don’t influence the product they support.

Intel FPGA (formerly Altera) have recently released a new edition of Quartus, codenamed Pro. Intel’s publications indicate that all of their series-10 FPGAs (Cyclone-10, Arria-10, Stratix-10) are covered by the Pro edition only, with the exception of Arria-10 (covered by both editions) and Cyclone-10 LP (covered by the Standard edition).

Among other differences, Quartus Pro doesn’t support the QXP format, which was the netlist-like format used with Quartus Standard. As the Pro edition arrives with a different synthesizer (“quartus_syn” instead of “quartus_map”) and a different internal database structure, the QXP doesn’t fit in.

Aside from this, I can’t comment much on the differences between Standard and Pro, and just by using both, no other difference stands out. As for the new synthesizer: On my own anecdotal experiment with an Arria-10 design that failed timing with the Standard edition, the Pro edition’s ended up with a slightly worse timing result. So on the face of it, there is nothing new and blazing about Pro.

All said in this post relates to Quartus Prime Version 17.1.0 Build 240 SJ Pro Edition running on a Linux machine. I’d expect things to change in future revision (or maybe this is just wishful thinking). The HDL language in this post is Verilog.

The official source of information, followed below, is the Intel Quartus Prime Pro Edition Handbook Volume 1, Design and Compilation, section 7.4, titled “Design Block Reuse”. Intel also offers a free online 45-minute training lecture (Design Block Reuse in the Intel Quartus Prime Pro Software, slides + sound), which pretty much covers the topic.

Update, 8.7.18: Be sure to read the bottom of this post regarding the VQM format.

How to convert a QXP to a QDB

It’s not possible, seemingly because of the difference in the internal database structure.

Packaging a core as a QDB

The desired QDB file is a post-synthesis export of a partition which contains the IP core. Even if the design consists the core to package only, neither an export of the entire synthesized design, nor an export of the root partition will do the trick (or so the Handbook says).

It’s therefore required to generate a wrapper module for the core in question, and instantiate the core in it. This allows defining a dedicated partition at the core’s boundaries. It can be done with the GUI, or a line like the following can be added to the QSF file:

set_instance_assignment -name PARTITION my_core -to my_core_ins -entity top

Where “top” is the name of the toplevel module, which wraps my_core. my_core_ins is the instance name used in the instantiation of my_core.

With this line in place, run Analysis & Synthesis in Quartus, or launch quartus_syn as a command-line utility to synthesize the design.

Once the synthesis is finished, export the core’s Synthesized snapshot with Project > Export Design Partition, and select my_core as the Partition name (it will most likely be the only choice).

Alternatively, use the following command:

quartus_cdb my_core -c my_core --export_partition my_core --snapshot synthesized --file /path/to/my_core.qdb

Note that some information of the file path at which the core was compiled is stored in the qdb file (see e.g. qdb/qar_info.json and sdc.cdb after including the QDB file in the target project) as well as the operating system used (the same file).

Aug 2019 update: As of Quartus Pro 19.2, the following assignment can be used instead of both the assignment and the quartus_cdb command. Also, it’s occasionally fine to export the root partition as follows:

set_instance_assignment -name EXPORT_PARTITION_SNAPSHOT_SYNTHESIZED my_core.qdb -to | -entity my_core

and then there’s no problem importing it into another design. Once again, occasionally: On one project it went through fine, on another it didn’t. Haven’t figured it out yet, so the recommendation remains to export internal partition, possibly with EXPORT_PARTITION_SNAPSHOT_SYNTHESIZED.

Including the QDB file in a design

To include the core in a design, a partition is generated in the target design, and then the QDB file is plugged into that partition by virtue of a QDB_FILE_PARTITION partition. For example:

set_instance_assignment -name PARTITION pr_foo -to foo_ins|my_core_ins
set_instance_assignment -name QDB_FILE_PARTITION /path/to/my_core.qdb -to foo_ins|my_core_ins

In the example above, my_core_ins is the instance name of the core within a module, which is in turn instantiated with the name foo_ins in the toplevel module.

The name pr_foo has no special significance, expect that it’s the name given to the partition.

Unlike the use of QXP files in Quartus’ Standard edition, a black box file must be included in the project: It’s just like the core’s top level module, but with anything between the port declaration and the “endmodule” statement wiped out.

Failing to include a black box file in the project causes a few warnings by fitter like

Warning(13032): The following tri-state nodes are fed by constants
        Warning(13033): The node "foo_ins|my_core_ins" is fed by GND

which escalate to errors, also by the fitter:

Error(13076): The pin "foo_ins|my_core_ins.user_r_read_32_data_w" has multiple drivers due to the non-tri-state driver "foo_ins|my_core_ins"

As a side note, I’d also mention another QSF assignment, QDB_FILE, which may appear to replace QXP_FILE, but attempting to use it with QDB file yields an error:

Error(19507): QDB_FILE assignment "my_core.qdb" is not supported.

Quartus’ help on this error just says that the QDB_FILE assignment isn’t supported, and suggests using QDB_FILE_PARTITION. So it’s not really clear why the QSB_FILE assignment exists.

Matching target device / Quartus revision

Unlike common practice with netlist files, the FPGA part number for which the QDB file was synthesized must match the FPGA part number of the project in which it’s instantiated, or the fitter rejects it with an error like

Error(18097): Partition "|" contains assignment "DEVICE" with setting "10AX115S3F45E2SG", which is different from setting "10AX115S2F45I2VG" in partition "foo_ins|my_core_ins". Modify your design so all partitions use the same setting for the specified assignment.

This finding is contrary to Intel’s training lecture, which says that another FPGA device can be used if the exported snapshot was of post-synthesis type. My experience was different. Also, the Handbook (revision of 2017.11.06) says in Section “Because the exported .qdb includes compiled netlist information, the Consumer project must target the same FPGA device part number and use the same Intel Quartus Prime version as the Developer project.”

I’ve also tried to get an answer on this in Altera’s forum.

So while QXP files can be used freely within an entire device family with Quartus Standard edition, Quartus Pro’s QDB is by far more limited, at least on revisions 17.1 and 19.2. And there is no way to generate an EDIF file or anything of that sort in any Quartus edition.

My bet would be that the original intention was to make QDB a true netlist replacement, but then too much of the internal database quirks leaked into the QDB format, making it dependent on both software version and FPGA device. Whether this will be solved, time will tell.

All in all, it’s not clear if a reasonable substitute for a netlist exists at all in Quartus Pro as of writing this. Which is make the choice calling this edition “Pro” quite ironic.

The VQM format

It turns out that Quartus Standard Edition can generate a netlist in VQM format, which is the format used when importing netlists from third-party synthesizers into Quartus (Quartus Pro included).

So after a successful Quartus synthesis, just go

$ quartus_cdb my_core --vqm=my_core.vqm

which generates a post-synthesis netlist in Verilog. Note that a FAMILY or DEVICE  assignment must be present in the QSF file, or quartus_cdb complains quartus_map should be run with the –family flag assigned (which is wrong, it doesn’t help).

It can be imported into any design with the following line in the QSF file (or use the GUI to import it):

set_global_assignment -name VQM_FILE /path/to/my_core.vqm

and it works exactly like a QXP. Or so it did in my own anecdotal experiment: The entire compilation went through cleanly, and the design worked exactly the same on hardware.

Quartus can be instructed to resynthesize the VQM’s WYSIWYG primitives with the following assignment in the QSF file:

set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON

In Quartus’ context, the term WYSIWYG seems to mean that the instantiated modules turn into logic block as defined in the Verilog file (so what is instantiated, “seen” is “what you get”).

The reason I call my own experiment “anecdotal” is the following couple of lines at the very top of the VQM file generated by quartus_cdb:

// !!!!!! This generated VQM is intended for Academic use or Internal Altera use only !!!!!!
// Functionality may not be correct on the programmed device or in simulation

So despite this scary warning, it did work for me. How seriously this warning should be taken is still to find out. Comments are welcome.

Now, here’s the catch: Quartus Pro won’t generate VQM (according to the Intel Quartus Prime Pro Edition Handbook Volume 1, section 1.1, “Saving a node-level netlist as .vqm” is one of the features explicitly not supported).

To make things worse, there’s an obvious problem exporting a VQM made by Quartus Standard to Quartus Pro, because the VQM is a Verilog file, but the wire names contain all kind of Verilog-wise illegal characters, such as “.”, “:”, “~” and “|”. So even though Quartus Standard accepts its own VQM file, Quartus Pro spits out error messages like

Error(18303): Name "mod:mod_i|twentynm_lcell_comb:wr_data~20_I" is illegal. Avoid using '*', ':' and '|' in your naming scheme because these characters have special meaning in Quartus.
Error(18303): Name "mod:mod_i|twentynm_lcell_comb:wr_data~0_I" is illegal. Avoid using '*', ':' and '|' in your naming scheme because these characters have special meaning in Quartus.
Error(18303): Name "mod:mod_i|twentynm_lcell_comb:wr_data~14_I" is illegal. Avoid using '*', ':' and '|' in your naming scheme because these characters have special meaning in Quartus.

Not to mention that the only device family Standard and Pro shares is Arria 10 (and maybe a bit of Cyclone 10?).

Add a Comment

required, use real name
required, will not be published
optional, your blog address