Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
15378 Discussions

SystemVerilog compile guards and macros

DYaro1
Novice
553 Views

Hello,

 

In our team, we used for a long time compile guards (with Quartus and VCS):

`ifndef MODULE_NAME

`define MODULE_NAME

// module decalaration:

module module_name etc...

`endif

 

We need it in order to prevent packages/modules with same name from being compiled twice - we only want the first one being the one that compiles.

This need comes from a generated code - for each hierarchy, we create it's relevant part in our register tree, such that it compiles by itself (for simulation for example), and the top have the fullest network.

 

Some time ago we migrated from Quartus 17 to newer versions (18, 21) and this method stopped working - it seems Quartus ignores the order in which the macros are defined and ends up outputting 'module "module_name" cannot be declared more than once' error.

If needed, I can supply an example project on Quartus 21, or example rtl files.

 

Can anybody help me with this? either making Quartus 'eat' this with some compilation flags, changing how we use macros in our code or other creative way - any suggestion will be helpful!

 

Another note on macros in general - we had another weird macro behavior with Quartus18 - we defined a macro function, but Quartus ended up not understanding what we did while VCS did. Any light on how Quartus handles macros in the code will be greatly appriciated.

 

Dan

 

0 Kudos
1 Solution
DYaro1
Novice
453 Views

TL;DR - If you have the exact problem as me use the following statement in the .qsf: 

set_global_assignment -name VERILOG_CU_MODE MFCU

 

OK, so I've managed to understand what's happening.

In general, the scope in which a macro is defined called "Compilation Unit". Older Quartus verisons and newer Quartus lite/std versions use Multi File Compilation Unit (MFCU), while Quartus Pro (starting from 18 probably) uses Single File Compilation Unit (SFCU) by default.

What's the difference?

MFCU means the compilation unit includes ALL of the files, while SFCU includes only each single file. Macros from a different file CAN be defined with SFCU, but only using `include <file> macro.

SFCU is required for Quartus to auto-sort the compilation order of files. It's rational - in order the determine the compilation order, each file should be viewed separately by Quartus (It's as if Quartus regards them all in parallel), So we can't expect the order in which the files are listed to affect the compilation of a single file and hence the compilation order (it's a logic loop =)). SFCU also make macros safer - only what you explicitly include (either via `include or using global macro assignment) is defined.

Unfortunately in order for the macro guards to work GLOBALY we have to use MFCU mode instead (Again, this is rational as I explained). Adding the following statement in the .qsf does the trick:

set_global_assignment -name VERILOG_CU_MODE MFCU

After compiling with this statement, Quartus will throw a warning about turning off the auto-discovery feature (this is the automatic compile order feature I've mentioned above).

As the build system my team use explicitly order the files by their compilation order I'm fine with this.

 

Thanks for the help, and thanks for Intel Forums, Google (and my tenacity ) to find the answer.

View solution in original post

6 Replies
BDarji
New Contributor I
500 Views

Hello,

 

Something interesting! I do not have answer for your question but would like to analyze it.

 

If you can share example RTL code, I will analyze it. We are using Quartus Prime 18.1 Standard Edition.

 

Kind Regards,

Bhaumik

 

DYaro1
Novice
493 Views

Hi Bhaumik,

 

I added some design files that showcase the problem - try to create a project with them.
If you have Quartus 21-Lite, or it's easier for you editing the qsf to match your Quartus version, I also supplied a project I created for this example.

 

This isn't our actual code as I can't post it here, but it showcase the problem very well.

 

Thanks for showing interest,

Dan

BDarji
New Contributor I
480 Views

Hello Dan,

 

Thank you for sharing your files here.

 

In your top.sv file, module name should be top, not test. It looks typo mistake. In top module, you are  planning to instantiate test module. Right?

 

I made this correction and was able to successfully compile that design. 

 

Have a Good Day!

 

Cheers,

Bhaumik

DYaro1
Novice
462 Views

Aww, that's awkward.
I was tired when I did this, sorry.

Anyway, I compiled this again at work on Quartus18.1 Pro. It doesn't throw the above error, but there's a warning about the previous declaration of test being overwritten.

So we still end up with the define macro not working as intended (Otherwise no overwrite would've occured).

Thanks for the help up 'till now.

 

Edit: Ok, it's wierder - I tested in Quartus18.1 standard and it worked as intended, while Quartus18.1 pro doesn't as I've mentioned above.

DYaro1
Novice
454 Views

TL;DR - If you have the exact problem as me use the following statement in the .qsf: 

set_global_assignment -name VERILOG_CU_MODE MFCU

 

OK, so I've managed to understand what's happening.

In general, the scope in which a macro is defined called "Compilation Unit". Older Quartus verisons and newer Quartus lite/std versions use Multi File Compilation Unit (MFCU), while Quartus Pro (starting from 18 probably) uses Single File Compilation Unit (SFCU) by default.

What's the difference?

MFCU means the compilation unit includes ALL of the files, while SFCU includes only each single file. Macros from a different file CAN be defined with SFCU, but only using `include <file> macro.

SFCU is required for Quartus to auto-sort the compilation order of files. It's rational - in order the determine the compilation order, each file should be viewed separately by Quartus (It's as if Quartus regards them all in parallel), So we can't expect the order in which the files are listed to affect the compilation of a single file and hence the compilation order (it's a logic loop =)). SFCU also make macros safer - only what you explicitly include (either via `include or using global macro assignment) is defined.

Unfortunately in order for the macro guards to work GLOBALY we have to use MFCU mode instead (Again, this is rational as I explained). Adding the following statement in the .qsf does the trick:

set_global_assignment -name VERILOG_CU_MODE MFCU

After compiling with this statement, Quartus will throw a warning about turning off the auto-discovery feature (this is the automatic compile order feature I've mentioned above).

As the build system my team use explicitly order the files by their compilation order I'm fine with this.

 

Thanks for the help, and thanks for Intel Forums, Google (and my tenacity ) to find the answer.

BDarji
New Contributor I
435 Views

Hello Den,

Glad to know that you have been able to solve this issue.

And many thanks for sharing your findings here and describing it very well. This will surely be useful to someone in future.

Cheers,
Bhaumik

Reply