Conditional Compilation

Proposal Details

  • Who Updates: JohnShields, ...
  • Date Proposed: 8/15/2011
  • Date Last Updated: 9/21/2011
  • Priority:
  • Complexity:
  • Focus:

Summary

  • solve problems with tool-specific and language version driven behavior using a standard mechanism
  • provide a standard mechanism for conditionally compiling VHDL code

Related Issues

See also ISAC IR-2025 and IR-2106

2009 package containing tool and vendor identification information

Current Situation

VHDL users have no standard mechanism for conditional compilation. Some industry tools have provided pragmas for synthesis based applications that ignore sections of code. With VHDL 2008, some new pragmas have been added that compile certain sections of code if the language version is VHDL 2008 and other sections if it is earlier code. There are similar examples to support other tool specific behavior. None of this is standard and portable ; some of it has become defacto standard and users have pressured tool suppliers to support a certain specific pragma syntax or provide an equivalent feature.

There is a practical consideration that has faced VHDL users for some time. Tools do not completely and rigorously implement the various versions of the VHDL standard. This may mean allowing constructs to work by not enforcing semantic restrictions or providing non-standard language extensions. It may be complicated by mixed language design using VHDL with other HDLs in which only defacto standards apply. In order to write portable VHDL code work around issues encountered when existing code is used in new tool flows, users are faced with modifying source code or using conditional compilation mechanisms. There is a lot of pain involved when that src code is golden signoff code that is being reused but cannot be modified. There are no standard ways to address this for VHDL users today. In contrast, Verilog, SystemVerilog, and SystemC have mechanisms.

Users have also desired a basic ability to support alternate code for experimental purposes, to make performance tradeoffs with abstraction, or evaluate new language features in a product. Composition of src models and adding IP protection pragmas after the fact is a source code level modification that would benefit from a conditional compilation mechanism.

While VHDL does support entities with multiple architectures and configuration, and conditional generate mechanisms, these do not have the granularity and usability necessary. More fundamental than that, no first class language feature can deal with src code that is illegal or invalid, but only in some tool contexts.

Requirement

The high level problem to be solved is to enable users to conditionally compile their VHDL code to avoid non-standard, language version incompatible, or proprietary language features in their tool flows. A standard mechanism will allow VHDL code to be compiled and used in any tool without requiring a least common denominator of language feature support.

One can break the high level problem into use cases or real world examples.

  1. conditional inclusion of ports or initial values on input ports
  2. conditional inclusion of declarations or variation in the type or initial value of a declaration
  3. avoiding declaration of two versions of subprogram with profiles that differ in base types for pre-2008 where only a single version is required
  4. protoyping code to workaround a tool bug or missing language feature, particularly in new analysis or optimization modes of those tools
  5. missing library declarations, improper declaration of subprogram purity, illegal misuse of an aggregate with others clause for assignment to an unconstrained object, and other detailed examples of things tools might allow
  6. migrating code that emulates features of vhdl 2008 in 2002 syntax to using first class 2008 constructs and references

1,2,3,5 are example conditional compilation actions that have different granularity of where they are applied in the 1st class syntax - a decl, a stmt, a use clause, part of a decl or stmt, etc. What ties them to the high level problem is that represent areas where bugs and non-standard or missing features arise and fail to compile is some part of production tool flows. -- JohnShields - 2011-09-22

There are some detailed requirements to solve these problems effectively:

  1. tools have a means to provide information to the user that can be incorporated into the conditions used to compile regions of source code
  2. the mechanism is not tied closely to a particular version of the VHDL LRM, i.e., its syntax and semantic rules. This would allow it to be delivered in a practical way in production VHDL tools that compile 87, 93, 2002, 2008, and future dialects of VHDL.
  3. allow users to flexibly compose the conditions under which a section of code will be analyzed.
  4. the granularity of what src code is conditionally compiled should be at the lexical level and not to the formal grammar productions
  5. the mechanism's syntax should avoid fundamental conflicts with VHDL syntax
  6. It should maintain an additional separation with the platform (operating system , file system details, etc.) in its definition.

There are some other guidelines for a good solution to keep in mind.

  • The mechanism should have no intent to create user-defined shorthand notation for formal language syntax and should avoid supporting it
  • no persistent state of conditional compilation should be kept across source file boundaries

Implementation

There may be alternative solutions to provide conditional compilation. If so, they should be identified here and described as a separate topic. At some point a consensus around a solution approach will happen. The other alternatives will be noted as rejected, but left as historical references.

The alternatives are:

Code Examples

An example of a problem I encountered from using various tools, and how I currently work around the problem (the workaround itself still has problems though):

--synthesis tool only supports component instantiations of encrypted IP core.
i_some_ip: someIP generic map(

/* synthesis translate_off */
--simulation tool requires specifying the architecture name for entity binding.
i_some_ip: entity ipLibrary.someIP(ip_arch) generic map(
/* synthesis translate_on */

       --## Some really long list of generics and ports. ##--
       -- Doesn't make sense to repeat this section as in the case of using configurations or if-generate, hence the reason for using the above "synthesis pragmas".
       -- Unfortunately, I will have to manually comment-out the first line if I wish to simulate the design. The synthesiser ignores the portion
       -- enclosed within the synthesis pragmas, but there is no mechanism for simulation tools to do the same, i.e. ignore the first line.
       . . .
);

Regarding my statement of having to comment-out the first line, this may sound trivial at first, but this becomes really cumbersome when many multiple source files (at different locations) have this problem.

-- DanielKho - 2012-03-02

Requirement: Understand the VHDL environment (packages, constants, generics, port widths, ...)

- JimLewis - 2011-10-12

Use case, testbench memory model where the base implementation of the memory modeling is in a protected type and it handles all of the data structures (such as pointers and sparse implementation). In the memory model, if the data width is less than 31 bits, I want to choose a package that represents the value as an integer. OTOH, if the memory model needs wider data widths, then I want to choose a package that represents the value as an integer array. The package that implements wider values has to split the data into multiple pieces and hence is slower in execution. As a result, I want to use the integer based package when it is ok to do so. I do not want to imply anything about syntax choices, so for now I will use the obnoxiously long names suggested by John A (although I think we should resolve to something reasonable).

cond_compile_if Data'length <= 31 generate
  use my_lib.PtMemPkg.all ;
cond_compile_else generate
  use my_lib.PtMemWidePkg.all ; 
cond_compile_end generate ;  

Example from StackOverflow:

How do I write a code segment which would evaluate a generic and create (or not create) an attribute accordingly?

if G_MY_GENERIC then
    attribute my_attribute_typ : string;
    attribute an_attribute of my_attribute_typ: signal is "value";
else
    --nothing is created
end if;

-- ThomasPreusser - 2016-11-07

This last example could be resolved by adopting the proposed ConditionalExpressions:

attribute my_attribute_typ : string;
attribute an_attribute of my_attribute_typ: signal is "value" when G_MY_GENERIC;

Use Cases

This is another way to express requirements, i.e., to explain how it would be used.

Arguments FOR

I'd prefer to see general comments express whether you are for it. If it is clear to you that you just want argue that the requirement should be addressed, perhaps here is the place. If you want to debate the proposed solution, make it in general comments.

generate statements aren't a perfect substitute

I came across an issue today that demonstrates why generate statements aren't always suitable to address compatibility issues between tool versions. It turns out you could use a generic in say an if interation scheme in a generate statement. By definition this would be globally static (elaboration time) being capable of being affected by configuration. Using two successive if interation schemes on say the two binary states of a generic would require both generate statements analyze cleanly, where we could see differences in syntax between versions of VHDL.

Conditional text is lexical processing and doesn't require the non-presented text be valid. Note that this doesn't support a requirement that the preprocessor function be part of the VHDL standard, which is written with design units being the smallest unit of design files currently. The implication is some amount of reorganization of the VHDL standard.

This was found in a dual port memory model representing a library element of an FPGA vendor. No guarantee they'd want to switch to conditional compilation. The question is what portion of their customers might run into an issue (that's caused by model construction).

-- DavidKoontz - 2011-10-16

Arguments AGAINST

I'd prefer to see general comments express whether you are against it. If it is clear to you that you just want argue that the requirement should not be addressed, perhaps here is the place. If you want to argue that the proposed solution is wrong, make it in general comments.

General Comments

This is a great place to ask for features to be added or removed with your rationale. Please sign comments in good wiki style -- JohnShields - 2011-08-15

One additional requirement I would like to add is that the conditional compilation mechanism needs to understand the VHDL environment (packages, constants, generics, port widths). See example above in the code examples. -- JimLewis - 2011-10-12

Another potential requirement that has come up in some of the discussions, code that is not selected for conditional compilation should not be analyzed. Some agree and some disagree - perhaps both are right and the syntax should provide a mechanism to indicate whether the code should or should not be analyzed? -- JimLewis - 2011-10-12

I really cannot agree or disagree until I see the code examples section get filled in. -- JimLewis - 2011-10-12

I won't repeat the entire argument here but I would suggest that this answer on StackOverflow provides a fairly strong argument against conditional compilation. Ensuring the compiler always analyses the unwanted code (which is the case when using generate statements) prevents the various conditional cases slipping into an unmaintained state by catching errors introduced by changes in the code elsewhere (removed variables etc). Is there a particular use case which cannot be solved using a (possibly modified) generate statement?-- ChrisHiggs - 2011-08-16

A very current example is code that doesn't compile in language version 2008 because it is structured for version 2002 or earlier cannot be solved with first class language features. All appropriate solutions either keep 2 version of the code or use conditional compiliation. The mechanisms in use today are proprietrary tool pragmas and frustrate users. Generate is good for a great many things, but not this kind of thing. You may a good point about its behavior and it is intended for first class parameterization of structure and behavior in a design. It cannot solve issues in which code inherently cannot be analyzed under certain conditions. There are other examples and the problem of testing a code base with conditionally compile code is one of discipline.

There is a lot of other utility for a preprocessor and it has been requested in the past, but I am not trying to sell anyone on other ways in can be used (some of which, you rightly point out overlap with generate). --Main.JohnShields - 2011-08-11

My concern is that adding a preprocessor is a significant addition to solve a point problem. Ada and VHDL deliberately chose not to include a preprocessor and to overturn that decision would mark fundamental shift in the VHDL language. There are no doubt many arguments for adding a preprocessor which should all be considered as a whole

This particular problem has some alternative solutions. As you state in the proposal, the industry has already developed a set of non-standard pragmas to deal with conditional compilation, and in fact some standard pragmas exist -- RTL_SYNTHESIS OFF and -- RTL_SYNTHESIS ON (though they aren't very well supported). Some alternatives to a preprocessor worth considering to solve this problem are:

  • Standardise a richer set of pragmas
  • Permit nested block comments
  • Expand capabilities of generate statement

-- ChrisHiggs - 2011-08-17

When you consider a Tool directive "directs a tool to analyze, elaborate, execute, or otherwise process a description", you could consider the LRM is limited to two aspect of simulation (execution) and elaboration is already addressed by generate statements and configuration declarations.

Analysis is by definition performed on text (one or more design unit descriptions). Conditional compilation provides the ability to preserve design unit or declared object name in the face of a variant declaration. There are two general categories of reasons for doing so that come to mind. First, overcoming non-portability issues and second to make variants without requiring a new name space.

The issue of portability can be dealt with by language definition, for instance 64 bit time is now required. There is some question of the utility of conditional compilation as noted above. VHDL has been architected to not need it at the expense of requiring unique name spaces for secondary units and configuration declarations. (e.g. Ada http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/Conditional-Compilation.html)

Considering the desire to use compilation configuration despite the ability to affect the same effect by current VHDL (or Ada) language features, there is nothing stopping the implementation of a pre-processor which contrasts favorably with the difficulty of implementing configuration as part of syntactical analysis which implies either object name uniqueness or a separate configuration name space and pontentially parsing unselected text - note tool directives aren't associated with a beginning of line (15.11) do you require potentially large look ahead looking backward from an end of line? I've also seen smart editors that can do conditional compilation by conditionally presenting the text of a design unit for analysis. (This translates to if there is a perceived user need, it should either be implemented with a preprocessor or with specific use cases demonstrating the inability to implement an equivalent with present language features).

-- DavidKoontz - 2011-08-17 (Chris commented through on this, I wish I understood revisions in this Wiki stuff)

My main reservation against conditional compilation is that it does not improve code readabiltiy or maintainability. In fact probably quite the opposite. I think it's fair to say that #ifdef, #define etc. are readily associated with C and verilog. Two things that both of these languages lack is overloading and polymorphism. True, VHDL doesn't have the latter either. At least not yet. Apart from using #ifdef to make sure that an include file isn't processed more than once, I find I never use any conditional compilation in C++ anymore. Coming back to overloading and polymorphism I do think these are the two typical situations where one would use conditional compilation in C or verilog, including or excluding code in certain scenarios. Here, I think VHDL would do better to follow the C++ approach where possible. That said, there are two situations where I would regularly like to see something like conditional compile:

1) Determining whether VHDL is being compiled for synthesis or simulation

2) Configuring whether ports are present on an entity or not

But I would prefer to go about it differently (other than #ifdef etc), something along the following lines:

For 1), my current VHDL 2008 compatible simulator has a package called ieee_proposed.env. How about making it mandatory for a tool manufacturer to include his tool name here as a string and also specifiying in a string whether his tool does simulation or synthesis. This way generics could be used to include/exclude tracing entities, simulation accelerators, simulation models, synthesis library elements etc. This would also help get away from this --synthesis on / --synthesis off stuff ( I think comments which aren't really comments are a bit dodgy). From a use case point of view, generally I solve this problem with two different make files which is fine for me. But some of my customers just wan't a push-button solution. Two make-files isn't really fool-proof. I think the ieee_proposed.env solution would be.

For 2), how about adding something like polymorphism to primary and secondary units. Something along these lines: An entity can be derived from another entity (ENTITY EntityName EXTENDING BaseEntityName IS ....). This would automatically include all ports from the base entity. Additional ports can be added. This concept could also be extended to allow selective overloading of named blocks (e.g. processes) in an architecture derived from a base architecture while retaining all other definitions from the base architecture.

In this tenor I would particularily like to see generates allowed in the "passive processes" part of an entity declaration. One use case where I miss this is the following:

Associating different attributes with an entity when mapping it to different target FPGAs. Something like the following

ENTITY FPGA_Top IS
GENERIC (
TECH : STRING;
.....
);
PORT (
CLK : IN STD_LOGIC;
......
);
BEGIN
IF TECH = "Vendor_B" GENERATE
ATTRIBUTE LOC of CLK is "AA12";
END GENERATE;

IF TECH = "Vendor_C" GENERATE
ATTRIBUTE PAD_POS of CLK is "Z1";
END GENERATE;
END ENTITY FPGA_TOP;

-- CharlesGardiner - 2011-08-17

I'm not completely convinced of the need for conditional compilation (conditional text), but I have looked at internal (between lexical analysis and syntax analysis or within lexical analysis) and external (preprocessor) implementations. An external implementation is definitely easier, only requiring lexical recognition for elements that can interfere (e.g. tool directives and comments). There are various conventions that could be made such as how input lines relate to the lines a VHDL analyzer sees (preserving line numbers, commenting out or blank lines). Conventions on identifiers (they should match identifiers in VHDL as to not preclude internal implementation). I'd suggest a syntax description, that could be viewed as a subset of Appendix C with added tool directives that will end up in Clause 24.

While internal implementations are very much implementation dependent, I'd be willing to implement a preprocessor (in ANSI C) and release it as open source. I'd have written one already (derived from an existing analyzer) except the syntax isn't fixed yet.

While the polymorphism model suggested by Charles (above) isn't in keeping with John's suggestion, note he implies identifiers define objects that can be other than defined/undefined ( IF TECH = "Vendor_C" GENERATE) which could be expressed with binary types:

`IF Vendor_B -- A tool directive is a lexical element, doesn't conflict with reserved (key) words
ATTRIBUTE LOC of CLK is "AA12";
`ELSIF Vendor_C
ATTRIBUTE PAD_POS of CLK is "Z1";
`END -- (ENDIF [identifier]) - allows multiple levels of conditional expressions, if identifier provided must match current nesting level.

Adding identifier meaning other than defined/undefined implies adding operators. There's an interesting question of the value of defining identifiers as strings in addition to defined/undefined, in that this would allow standardization (portability). You can imagine supporting an equality operator and string type.

My reservation to the need for conditional text stems from the utility being offered already by smart editors/IDEs or databases. The effect is to only conserve name space for design units or sub elements while allowing an implementation independent way to sweep complexity under the rug. You could note that an Ada author might use makefile targets to construct conditional text:

ifdef ORTHO_X86_FLAGS

ORTHO_DEPS=ortho_code-x86-flags.ads
endif

ortho_code-x86-flags.ads:

echo "with Ortho_Code.X86.$(ORTHO_X86_FLAGS);" > $@
echo "package Ortho_Code.X86.Flags renames Ortho_Code.X86.$(ORTHO_X86_FLAGS);" >> $@

The facility exists elsewise and if a vendor were to be driven by customer demand they might already have a solution.

You could note there are no restrictions on vendor specific tool directives nor a practical way to bar say use of cpp, m4, or a custom preprocessor implementing Charle's polymorphism other than the ability to peer into an implementation design library or conditionally evaluate a design unit which sort of implies simply using conditional text.

-- DavidKoontz - 2011-09-08

I posted a code example (above) that I believe can't be solved using if-generate or even configurations without introducing a lot of duplication / redundancy. Using if-generate will require all the ports and generics to be duplicated in the elsif / else sections of the if-generate statement, even though there are no differences in the generics / ports involved. Using configurations will require the (lengthy) architecture to be exactly duplicated and leaving only the instantiation technique to be different.

Feel free to comment otherwise by posting a concise alternative (that I may not be aware of) using existing VHDL techniques without imposing too much code redundancy.

-- DanielKho - 2012-03-02

As a maintainer of a vendor independent IP core library, I can definitively say: It's a horror to encapsulate all workarounds in generate statements and sometimes in different files per vendor and language version...

-- PatrickLehmann - 2016-02-19

It appears that this request should be carefully judged in the context of other proposals that are on their way. Quite a few use cases should probably be tackled by means that fit better to the VHDL language:

  1. Flexible port list: use an interface/bundle type that can be manipulated in one place within its defining package.
  2. Conditional declaration of attributes: allow a conditional expression in the attribute assignment.
  3. Global language version and tool information: define a set of standard identifiers for global constants that hold these values, possible introducing a new namespace, e.g., using a tick syntax like 'VHDL_VERSION. These would be available for evaluation in all expressions and hence could be used for controlling generate statements but also for the computation of constants as for ROM signatures.
-- ThomasPreusser - 2016-11-07

On questioning conditional compilation being included in VHDL

Tool directive background

I can find anecdotal evidence of at least three tool vendors supporting protect tool directives and there is a requirement plaintext not be accessible[1], the only requirement advancing need for VHDL tool internal implementation. The reasoning goes that if a tool vendor complies with the standard\x{2019}s Clause 24 implementing protect tool directives the lexical and semantic requirements of additional tool directives are incremental to implement internally.

Tool directives are defined to be syntactically and semantically separate from the analysis of design units[2]. Tool directive parsing is not defined as part of design unit analysis. The effect is to make tool directives separate from VHDL, other than the ability to implement them internally (in the VHDL analyzer's lexer). The model is that tool directives can be interpreted at the lexical analysis level, and imply a name space that is separate from design unit analysis. This implies that tool directives other than restriction imposed in Clause 24 can be internally or externally implemented. Design units (primary and secondary units) are the smallest units of text that are stored in design libraries - failure to properly analyze a design unit is required to not modify the contents of a design library[3]. The tool directive syntax is borrowed from Verilog Compiler Directives[4] and is interpretive[5].

On the Need for Conditional Text

I was surprised by John Shields blanket statement that no tool vendor offers preprocessor capability. There is no 'marketing' demand demonstrated. How many tool vendors will embrace a requirement for it? We have anecdotal evidence there are users using existing preprocessors for conditional text purposes (by those attending the meeting).

There's this tension between the interpreter based roots of Verilog and the compiler based roots of VHDL derived from Ada[6]. VHDL has this concept of Design Libraries as receptacles for syntactically and semantically correct design unit descriptions found in implementation defined design files[7]. These are treated atomically during analysis. The effect is to use the input text as a repository for correctly and severally interpreted representations of design units, when VHDL requires these to be in design libraries as the result of analysis. Conditional text leaves these multiple views of a design text in the same name space, while allowing them to be syntactically and semantically distinct. The idea being that the external design text is the repository of design correctness, and that the VHDL analyzer can't verify the correctness of all possible design texts only conditionally presented to it. This should be sufficient to demonstrate that Conditional Text has no place in VHDL, nor it's progenitor Ada[8] analog to design unit analysis[9].

After having waxed eloquently (and over long) in a manner reminiscent of Il Duce's six hour 1933 radio broadcast on the relative merits of staples and paper clips[10]. I'd point out that the GNU gcc Ada tools make a preprocessor available as part of the Ada language distribution to include Ada in gcc, the gnatprep preprocessor supplies only a slight superset of the features John Shields and others propose for VHDL[11], in part shaped the structural relationship of VHDL and Ada language elements. That while shaped by the same design goals proposed by those in the P1076 working group, gnatprep however is not part of the Ada language specification although written in Ada. The view of the Ada language developers that preprocessors macros are unsafe [12]. Granted that the proposal does not allow for macro definition as found in Verilog we are still missing an argument on why conditional text should be part of VHDL despite the observation that should compilation directives be tool directive syntax compliant they could be implemented internally.

When you consider a mechanism to supply keys for a protect tool directive is outside the domain of the Language Reference Manual and that the result of the inability to supply keys is identical to the inability to properly interpret protect tool directives, there is no overwhelming need to include protect tool directives in the LRM either. Providing tool directives in ancillary standards seems entirely appropriate when noting the desire to provide 'standard' implementation dependent tool directive definitions by included files.

VHDL isn't an interpretive language and it has been originally specified to be tool implementation independent. Conditional text (as in tool directives) is only of interest to address implementation dependent interpretive tool uses. I'm reminded of the Europe English joke[13], instead of Germanization, Verilog-ification. Consider that someone who comes from a Verilog background may not be satisfied with the set of supported tool directives, that not implementing a preprocessor internally is a perfectly adequate way of not affording a demand for an ever expanding set of compiler directives, in that an external preprocessor can't reach into an implementation dependent tool. Defining conditional text tool directives in an unrelated standard would be a useful way of defending that boundary, allowing a tool vendor to optionally implement such a standard internally while defining a demarcation with the VHDL standard.


References

[1] IEEE Std 1076-2008 Clause 24.1.6 Protection requirements for decryption tools \x{201c}A decryption tool shall not display or store in any form accessible to the user or other tools any parts of decrypted portions of a VHDL description, decrypted keys, or decrypted digests\x{201c}.

[2] IEEE Std 1076-2008 Clause 13. Design units and their analysis.

[3] IEEE Std 1076-2008 13.5 Order of analysis, "If any error is detected while attempting to analyze a design unit, then the attempted analysis is rejected and has no effect whatsoever on the current working library"

[4] A Comparative analysis of Verilog HDL over VHDL, Gurprasad Srivastava, Dayalbagh Educational Institute, Agra, November 1, 2005, Page 2. \x{201c}Verilog has compiler directives which affect the processing of the input files. The directives start with a grave accent ( \x{2018} ) followed by some keyword. A directive takes effect from the point that it appears in the file until either the end of all the files, or until another directive that cancels the effect of the first one is encountered.\x{201d}

Comparative analysis of Verilog HDL over VHDL.pdf (116 KB)

[5] Also note Page 5 of Srivastava, Compilation, Verilog - "The Verilog language is still rooted in its native interpretative mode. Compilation is a means of speeding up simulation, but has not changed the original nature of the language." The view of Verilog as interpretive contrasts strongly with analysis of design units atomically.

[6] See High Level Constructs and Libraries sections found on Page 6 of the Srivastava paper (a useful distillation despite the conclusions being a hatchet job).

[7] IEEE Std 1076-2008 Clause 24.1.1 Protect tool directive, "As part of the analysis phase of tool execution (see Clause 20), a tool may perform encryption or decryption of a design file". See also Annex I (the glossary) defines analysis phase: That phase of tool execution in which analysis of a design file occurs. The analysis phase is not synonymous with analysis: The syntactic and semantic analysis of source code in a VHDL design file and the insertion of intermediate form representations of design units into a design library.

[8] Ada95 Reference Manual, Section 10: Program Structure and Compilation Issues http://www.adahome.com/rm95/rm9x-10.html

[9] IEEE Std 1076-2008, Clause 13. Design units and their analysis

[10] Something taught in World History in High School. No longer found by googling.

[11] Preprocessing Using gnatprep http://sandbox.mc.edu/~bennet/ada/gnat_ug/gnat_ug_13.html

[12] An Introduction to Ada, Part 2, \x{201c}Ada does not provide a preprocessor. Preprocessors were left out of the language on purpose. The view of the Ada language developers was that preprocessor macros are unsafe. Interestingly, many C++ developers also believe that preprocessor macros are unsafe and should be avoided whenever possible.\x{201d}

http://www.adaic.org/learn/materials/intro/part2/

[13] Europe English joke http://www.ahajokes.com/eng011.htm

-- DavidKoontz - 2011-09-23

"That while shaped by the same design goals proposed by those in the P1076 working group, gnatprep however is not part of the Ada language specification although written in Ada. The view of the Ada language developers that preprocessors macros are unsafe [12]. Granted that the proposal does not allow for macro definition as found in Verilog we are still missing an argument on why conditional text should be part of VHDL despite the observation that should compilation directives be tool directive syntax compliant they could be implemented internally."

Though gnatprep is not being standardised as part of the Ada language, given the current circumstances of competing language features from Verilog etc., I feel it is wise for the WG to standardise this feature as part of the VHDL language. We have often faced the issue of VHDL users switching to other languages simply because they "thought" some feature was not possible in VHDL, and this is partly due to the fact that existing feature implementations are not being standardised. One example is constrained randomisation and functional coverage, being a big hype and a great advantage for competing languages simply because those were part of their standard and have gained enough attention. Existing CRV and Coverage implementations in VHDL have not been standardised thus giving people the wrong impression that this is not possible in VHDL. The lack of publicity of existing implementations also contributed to the lack of adoption, hence standardising them would provide the publicity and awareness long due to these available features.

Regarding your next statement that preprocessor macros are unsafe, my view is that they are meant to be unsafe anyway. VHDL in itself is very safe, and of course, if anything has to be done using conditional text, it has to be assumed to be unsafe. This applies to almost any language I know, including C and C++. The C/C++ community use preprocessor directives to work around different processors, operating systems, etc. Thus, compiler directives have to be assumed to be unsafe. However, they are necessary to work around different vendor tools, proprietary compilers, etc. If you think about it, even existing synthesis pragmas can be considered unsafe, so I feel there is nothing wrong in extending this concept to have more powerful preprocessor capability. Most of us will only resort to conditional compilation techniques when there are no better ways to do it in simple VHDL.

-- DanielKho - 2012-03-02

This is in response to the comments by DavidKoontz above. David argues that macros are unsafe and uses as reference [12] a note in an ADA introduction and a colloquial reference to C/C++ developers. It is true that certain macros with arguments may be considered unsafe because they can have unexpected side effects. The typical example is #define min(x,y) (x) > (y) ? (y) : (x) used with a prefix/postfix increment or decrement, e.g. min(a++, --b). Another example is a macro substitution with an argument that is a call to an impure function. There are no such issues for macros without arguments, such macros are safe.

However, the requirement asks for conditional compilation, not for a macro capability. The requirement can be met, for example, by introducing a simple preprocessor that supports the definition of symbols and an ifdef/ifndef capability. It is sufficient for the preprocessor symbols to only be visible in preprocessor directives, i.e. no text substitutions. This is also the reason why I am using the term symbol, not macro. Of course this begs for allowing a symbol to have a value, plus the corresponding arithmetic functionality in a preprocessor if. Still, as long as there are no textual substitutions, all such a preprocessor would do is filter the input stream to the analyzer. It is up to the user to ensure that this stream is valid text.

-- ErnstChristen - 2016-04-07

Introducing an independent symbol namespace that is only accessible within preprocessor directives is unrealistic. Direct language access to the values of existing defines will be expected and asked for just as it is available in other pre-processed languages. Engineers will want to control generate statements and to parameterize constants through these defines. Tools will have to provide means to edit the set of defines active within a project.

Once available, conditional compilation will compete with the conditional generate statement in many use cases. Driven by an external define made somewhere in the project settings rather than by the evaluation of generic parameters, the affected elaborated entities will, in fact, be less generic and will hide parameters of their implementation from the entity interface. I doubt that calling for discipline will prevent such misuse simply because an 'ifdef - 'endif block is quicker to build than declaring and using generics.

However, there are clear and useful benefits of the conditional compilation: It may mask language version incompatibilities. It may be used in the declaration section. Nonetheless, I would rather like to see these issues addressed:

  • by relaxing the analyzability requirements of code contained within an if-generate statement whose condition is unsatisfied (e.g. delayed symbol resolution), and
  • by expanding the capabilities of the if-generate construct so that it may also cover, for instance, the declaration section.

-- ThomasPreusser - 2016-11-06

Supporters

Add your signature here to indicate your support for the proposal. While this is in the template, I'd prefer to see general comments express whether you support it. This is a lot like a vote and it is too early for up/down support.

-- Brent Hayhoe - 2014-12-17

-- ErnstChristen - 2015-01-21

-- PatrickLehmann - 2016-02-19

-- ThomasPreusser - 2016-11-06 (in the form of more capable if-generate and other conditional statements without using a set of external defines)

Topic revision: r31 - 2020-02-17 - 15:34:28 - JimLewis
 
Copyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback