# What's the equivalent of (ifdef) in VHDL?

Status
Not open for further replies.

#### omara007

Hi Guys

Is there anything like (ifdef) in VHDL ?

#### FvM

##### Super Moderator
Staff member
ifdef in vhdl

This is the only available construct in concurrent code:
Code:
genlabel:
if <boolean expression> generate
<conditional compiled code>
end generate;

#### omara007

ifdef vhdl

FvM said:
This is the only available construct in concurrent code:
Code:
genlabel:
if <boolean expression> generate
<conditional compiled code>
end generate;

What do you mean by Conditional Compiled Code ?

#### vomit

##### Full Member level 2
vhdl log2

#ifdef and macro expansion is a simple text-replacement, made by a preprocessor before the compiler sees the code. Therefore, #ifdef is not limited to processing and generating legal syntax. This makes it extremely versatile, at the cost of having no language knowledge at all.

You could even use the C preprocessor to do #ifdef expansion in VHDL code. Of course, it would disturb the normal automatic flow of your implementation tools: they would need an option to first run ".vhd" files through an external program, save the result in another place as "preprocessed vhdl" and compile the preprocessed VHDL.

Such a VHDL textual-preprocessor program can be found here: https://sourceforge.net/projects/vhdlpp/. Or look on Google for "vhdl preprocessor"

On the other hand, if you only want to activate or deactivate parts of legal VHDL code, you can use, as FvM stated, the VHDL "if...generate" construction.

It is itself a concurrent statement containing other concurrent statements. Concurrent statements are things like processes (process...begin...end process) and entity instantiations "instname:entityname port map (...)".

As the "if...generate...end generate" statement is a concurrent statement itself, it is equivalent to a "block...begin...end block" and you can put it everywhere you could put a process.

So if you want to activate some processes p1,p2 or instances i1 conditionally, just use
Code:
g_thisisconditional : if c_mycondition generate
p1:process
begin
...stuff (sequential statements)
end process p1;
p2:process
begin
...stuff (sequential statements)
end process p2;
inst1: myentity port map (...); -- component instantiation
end generate g_thisisconditional;

In VHDL93 there is no #elsif equivalent, so you have to put separate "if condition generate" and "if not condition generate" blocks. As a consequence, the compiler doesn't "know" that both blocks are mutually exclusive. The compiler could generate warnings about 2 drivers on the same signal. You can safely ignore the warnings: YOU know that they are never present at the same time.

If on the other hand you want to have an "#ifdef" WITHIN a process (sequential statements, not concurrent statements), you should just use a boolean constant (possibly defined in a global package or an entity-specific generic) and a normal if-statement

Code:
constant c_mycondition : boolean := true;
Code:
entity myentity is
generic (c_mycondition : boolean)
port (...)

and inside the process:

Code:
   p3:process
begin
...stuff (sequential statements)
if c_mycondition then
...stuff
else
...stuff
end if;
end process p3;

A VHDL synthesis program is extremely good in optimization of constants and will eliminate the dead if/else branch without any additional logic being generated.

#### FvM

##### Super Moderator
Staff member
log2 vhdl

A VHDL synthesis program is extremely good in optimization of constants and will eliminate the dead if/else branch without any additional logic being generated.
Yes, I also use this method as a generate supplement in sequential code. But with most VHDL compilers, you get additional warnings regarding constant expression in if statement.

#### omara007

vhdl preprocessor

What I effectively need is not to have a condition on the generation of a certain block .. my target is to have a global variable, if defined, then a set of lower variable will be assigned a specific set of values ..

For example, If we design a MAC unit .. I need to define something called (Precision) .. If this (Precision) is set to (High), then the multipliers in the MAC unit become 16-bit multipliers .. adders will be 32-bit .. etc.
And when (Precision) is set to be (Medium) .. different sizes are selected for the Multipliers ..

I understand that I can have multiple architectures for the MAC unit and use configuration to select the desired one .. but this is much more complicated than just assigning set of values to my variables according to the String value of a global variable like (Precision).

#### FvM

##### Super Moderator
Staff member
vhdl generate constant

The said configuration may be achieveable with numeric parameters for signal widths more easily, but VHDL generate statements should always work.

My personal favourite for variant designs is a library file with a package containing all constants (numeric and boolean or 0/1) that are varied between different project versions. This library is referenced in all project files. By exchanging the library file, all settings can be changed at once.

#### omara007

vhdl generate example

FvM said:
The said configuration may be achieveable with numeric parameters for signal widths more easily, but VHDL generate statements should always work.

My personal favourite for variant designs is a library file with a package containing all constants (numeric and boolean or 0/1) that are varied between different project versions. This library is referenced in all project files. By exchanging the library file, all settings can be changed at once.

Can you give an example on what you said, (using numeric parameters) given my situation ?

I indeed do have a package that contains all the constants .. but what am talking about is not constants .. it has to do with different values to be assigned to one parameter depending on another parameter. This is what #ifdef does here .. when you assign a certain value to a global parameter, some set of values are automatically assigned to a specific set of other parameters .. and when the global parameter is assigned a different value, this set changes .. and so on .. given that the changed value can't be expressed in an equation .. for example:
if X,Y,Z are all parameters like signal width .. and A is another parameter ..
If A is black, then X is 1 , Y is 123121 and Z is -123 ..
If A is Red, then X is 1231111 , Y is 1 and Z is 3 ..

#### FvM

##### Super Moderator
Staff member
ifdef equivalent in vhdl

Any variable calculated at compile time is still a constant value. It's no probem to have constants depending on other constants, even using VHDL functions as LOG2() in the below example:
Code:
CONSTANT MS20_DIV : INTEGER := 40e6/(50*CLKDIV_PWM);
CONSTANT N_MS20 : INTEGER := INTEGER(CEIL(LOG2(REAL(MS20_DIV))));
CONSTANT MS16_DIV : INTEGER := 40e6/(60*CLKDIV_PWM);

As another point, VHDL GENERATE can also be applied to SIGNAL and CONSTANT definition. Most likely, you won't find an example in most secondary literature and tool handbooks. You have to consult IEEE 1076 to learn the syntax of this option. I can't say, if it's supported by all tools, but &#65ltera Qu&#97rtus does. It's necessary e. g. to calculate constant arrays at compile time, for sine lookup table ans similar stuff.

Another thing, that should work by VHDL language standard (I didn't yet use it), is a constant array, that has deferred values for each configuration. In your example, have an X, Y and Z constant array and A as the index. You may copy the actual value to another simple constant or use the array in each instantiation of the constant.

#### omara007

vhdl if generate

FvM said:
Any variable calculated at compile time is still a constant value. It's no probem to have constants depending on other constants, even using VHDL functions as LOG2() in the below example:
Code:
CONSTANT MS20_DIV : INTEGER := 40e6/(50*CLKDIV_PWM);
CONSTANT N_MS20 : INTEGER := INTEGER(CEIL(LOG2(REAL(MS20_DIV))));
CONSTANT MS16_DIV : INTEGER := 40e6/(60*CLKDIV_PWM);

This already I know .. and I usually use in my code .. this is effectively what I referred to as one constant being a function of the other.

FvM said:
As another point, VHDL GENERATE can also be applied to SIGNAL and CONSTANT definition. Most likely, you won't find an example in most secondary literature and tool handbooks. You have to consult IEEE 1076 to learn the syntax of this option. I can't say, if it's supported by all tools, but Altera Quartus does. It's necessary e. g. to calculate constant arrays at compile time, for sine lookup table ans similar stuff.

Very interesting to know this info. Does generate also work inside entity ? .. in other words, inside the GENERIC part of it ?

FvM said:
Another thing, that should work by VHDL language standard (I didn't yet use it), is a constant array, that has deferred values for each configuration. In your example, have an X, Y and Z constant array and A as the index. You may copy the actual value to another simple constant or use the array in each instantiation of the constant.

What VHDL standard version are you referring to ?

#### FvM

##### Super Moderator
Staff member
vhdl ifdef

&#65ltera Qu&#97rtus has still VHDL 1993 as most recent language level, but there are no differences to VHDL 2000 in this resepct, as far as I know.

#### omara007

constant expression vhdl

FvM said:
Altera Quartus has still VHDL 1993 as most recent language level, but there are no differences to VHDL 2000 in this resepct, as far as I know.

Isn't the latest '2003' ?

#### FvM

##### Super Moderator
Staff member
vhdl conditional library

Yes, but I was referring to existing tools.

#### omara007

vhdl generate constants

anything regarding the use of the generate statement within the GENERIC scope ?

#### FvM

##### Super Moderator
Staff member
log2 vhdl synthesis

I don't understand what you mean with generic scope in this respect. Optionally, generate can contain a declarative part as in the declaration section of an architecture body, as shown in the generate statement specification of IEEE 1176. And it can be used to initialize a signal, that is used as a constant in the code.

I think, the example can be modified for generation of version dependant constants.
Code:
TYPE SINTAB IS ARRAY(0 TO ROMSIZE-1) OF STD_LOGIC_VECTOR (NNCO-2 DOWNTO 0);
SIGNAL SINROM: SINTAB;

BEGIN
GENROM:
FOR idx in 0 TO ROMSIZE-1 GENERATE
CONSTANT x: REAL := SIN(real(idx)*MATH_PI/real(ROMSIZE));
CONSTANT xn: UNSIGNED (NNCO-2 DOWNTO 0) := CONV_UNSIGNED(INTEGER(x*real(ROMMAX)),NNCO-1);
BEGIN
SINROM(idx) <= STD_LOGIC_VECTOR(xn);
END GENERATE;

#### omara007

vhdl if def

The problem is that the place where you can use GENERATE in the code is too late to determine the size of a port for example ..

suppose you have an entity with 10 ports .. these 10 ports can have different sizes according to a certain parameter like block precision .. can you use one parameter in the package to affect all these ports ? .. what you can currently do is to have 10 entries in the GENERIC declaration part of the entity and you give them different value each time you instantiate the block .. rather than the headache you will face inside the entity itself if you want to handle all possible sizes for the input ports corresponding to different precision level ..

In Verilog, you can easily use the #ifdef preprocessor .. In VHDL, which is my first language, I can't replace it, specifically in this circumstance, with the generate statement .. which can't generate the parameters needed for the ports before starting anything in the block ..

#### FvM

##### Super Moderator
Staff member
vhdl boolean generate

O.K., I see now what you previously meant with generic scope. But I think, deferred generic constants for port widths can be mostly calculated by simple arithmetic expressions. In cases, where more complex calculations or e. g. type definition are needed for component ports, they must be imported through a library statement from a package.

#### omara007

something similar to #ifdef in vhdl

The point is that Verilog allows you to have an if statement in a header file that contains no designs/entities .. so that you can link several parameters with no visible arithmetic function that can link them together (like red/blue/orange) .. while in VHDL, library or package doesn't give you the flexibility to have such conditional statement .. only statements like (if statement) are allowed inside subprograms .. and in order to execute them, you have to call the subprogram .. which is finally a hardware to be implemented .. unlike in Verilog, just a manipulation of a parameter ..

#### rod_gilchrist

##### Newbie level 1
Re: log2 vhdl

Yes, I also use this method as a generate supplement in sequential code. But with most VHDL compilers, you get additional warnings regarding constant expression in if statement.

There is no ifdef in Java either. They replaced ifdef's with constant definitions.

Here is an 'ifdef-like' example in Quartis (12.1) VHDL that generates no extra logic elements and produces no extra warnings.
(This example doesn't use the generate statement.)

Oddly, a warning is produced if you reference 'msb_byte_order' in the main line code, but not if you
reference it in a procedure or function as in the example below. I suspect the warning is a Quartis bug.

Code:
constant msb_byte_order	: Boolean := false;

procedure out_miosio(which: natural) is
begin
if msb_byte_order then
case which is
when 0 =>
ft_miosio <= dataReg(31 downto 24);			-- msb first
when 1 =>
ft_miosio <= dataReg(23 downto 16);
when 2 =>
ft_miosio <= dataReg(15 downto 8);
when others =>
ft_miosio <= dataReg(7 downto 0);
end case;
else
case which is
when 0 =>
ft_miosio <= dataReg(7 downto 0);
when 1 =>
ft_miosio <= dataReg(15 downto 8);
when 2 =>
ft_miosio <= dataReg(23 downto 16);
when others =>
ft_miosio <= dataReg(31 downto 24);			-- msb last
end case;
end if;
end out_miosio;

#### permute

Re: vhdl preprocessor

What I effectively need is not to have a condition on the generation of a certain block .. my target is to have a global variable, if defined, then a set of lower variable will be assigned a specific set of values ..

For example, If we design a MAC unit .. I need to define something called (Precision) .. If this (Precision) is set to (High), then the multipliers in the MAC unit become 16-bit multipliers .. adders will be 32-bit .. etc.
And when (Precision) is set to be (Medium) .. different sizes are selected for the Multipliers ..

I understand that I can have multiple architectures for the MAC unit and use configuration to select the desired one .. but this is much more complicated than just assigning set of values to my variables according to the String value of a global variable like (Precision).

You can also declare functions in packages, architectures, processes, etc..

eg:
Code:
function get_width(nominal_width : integer; precision : boolean) return integer is
begin
if x and nominal_width < 16 then
return 16;
else
return nominal_width;
end if;
end function;

signal dsp_p : std_logic_vector(get_width(10,PRECISION)-1 downto 0);
VHDL doesn't have any type of lambda or bind functionality, so you'd either do what I've done, or add:
Code:
impure function get_local_width(nominal_width : integer) return integer is
begin
return get_width(nominal_width, PRECISION);
end function;`
I forget if this is allowed in all tools though.

Status
Not open for further replies.