Product Documentation
Cadence Verilog-AMS Language Reference
Product Version 22.09, April 2022

12


Controlling the Compiler

This chapter describes how to use the Cadence® Verilog®-AMS compiler directives for a range of tasks. The following compiler directives are available in Verilog-AMS. You can identify them by the initial accent grave ( ` ) character, which is different from the single quote character ( ' ).

Compiler Directive

Task

`define
`undef

“Implementing Text Macros”

`ifdef

“Compiling Code Conditionally”

`include

“Including Files at Compilation Time”

`timescale

“Adjusting the Time Scale”

`default_discipline

“Setting a Default Discrete Discipline for Signals”

`default_transition

“Setting Default Rise and Fall Times”

`resetall

“Resetting Directives to Default Values”

`begin_keywords
`end_keywords

“Specifying Which Reserved Keyword List to Use”

`remove_keyword
`restore_keyword

“Removing and Restoring Specific Keywords”

See also “Checking Support for Compact Modeling Extensions” for information about a predefined macro that you can use to determine whether your simulator supports the compact modeling extensions.

Implementing Text Macros

By using the text macro substitution capability provided by the `define and `undef compiler directives, you can simplify your code and facilitate necessary changes. For example, you can use a text macro to represent a constant you use throughout your code. If you need to change the value of the constant, you can then change it in a single location.

`define Compiler Directive

Use the `define compiler directive to create a macro for text substitution.

text_macro_definition ::=
        `define text_macro_name macro_text
text_macro_name ::=
        text_macro_identifier[( list_of_formal_arguments ) ]
list_of_formal_arguments ::=
        formal_argument_identifier { , formal_argument_identifier }

macro_text is any text specified on the same line as text_macro_name. If macro_text is more than a single line in length, precede each new-line character with a backslash ( \ ). The first new-line character not preceded by a backslash ends macro_text. You can include arguments from the list_of_formal_arguments in macro_text.

Subject to the restrictions in the next paragraph, you can include one-line comments in macro_text. If you do, the comments do not become part of the text that is substituted. macro_text can also be blank, in which case using the macro has no effect.

You must not split macro_text across comments, numbers, strings, identifiers, keywords, or operators.

text_macro_identifier is the name you want to assign to the macro. You refer to this name later when you refer to the macro. text_macro_identifier must not be the same as any of the compiler directive keywords but can be the same as an ordinary identifier. For example, signal_name and `signal_name are different.

If your macro includes arguments, there must be no space between text_macro_identifier and the left parenthesis.

To use a macro you have created with the `define compiler directive, use this syntax:

text_macro_usage ::=
        `text_macro_identifier[( list_of_actual_arguments ) ]
list_of_actual_arguments ::=
        actual_argument { , actual_argument }
actual_argument ::=
        expression

text_macro_identifier is a name assigned to a macro by using the `define compiler directive. To refer to the name, precede it with the accent grave ( ` ) character.

If your macro includes arguments, there must be no space between text_macro_identifier and the left parenthesis.

list_of_actual_arguments corresponds with the list of formal arguments defined with the `define compiler directive. When you use the macro, each actual argument substitutes for the corresponding formal argument.

For example, the following code fragment defines a macro named sum:

`define sum(a,b) ((a)+(b)) // Defines the macro

To use sum, you might code something like this.

if (`sum(p,q) > 5) begin
    c = 0 ;
end

The next example defines an adc with a variable delay.

`define var_adc(dly) adc #(dly)
`var_adc(2) g121 (q21, n10, n11) ;
`var_adc(5) g122 (q22, n10, n11) ;

`undef Compiler Directive

Use the `undef compiler directive to undefine a macro previously defined with the `define compiler directive.

undefine_compiler_directive ::=
        `undef text_macro_identifier

If you attempt to undefine a compiler directive that was not previously defined, the compiler issues a warning.

Compiling Code Conditionally

Use the `ifdef compiler directive to control the inclusion or exclusion of code at compilation time.

conditional_compilation_directive ::=
        `ifdef text_macro_identifier
            first_group_of_lines
        [`else
            second_group_of_lines ]
        `endif

text_macro_identifier is a Verilog-AMS identifier. first_group_of_lines and second_group_of_lines are parts of your Verilog-AMS source description.

If you defined text_macro_identifier by using the `define directive, the compiler compiles first_group_of_lines and ignores second_group_of_lines. If you did not define text_macro_identifier but you include an `else, the compiler ignores first_group_of_lines and compiles second_group_of_lines.

You can use an `ifdef compiler directive anywhere in your source description. You can, in fact, nest an `ifdef directive inside another `ifdef directive.

You must ensure that all your code, including code ignored by the compiler, follows the Verilog-AMS lexical conventions for white space, comments, numbers, strings, identifiers, keywords, and operators.

Including Files at Compilation Time

Use the `include compiler directive to insert the entire contents of a file into a source file during compilation.

include_compiler_directive ::=
        `include "file"

file is the full or relative path of the file you want to include in the source file. file can contain additional `include directives. You can add a comment after the filename.

When you use the `include compiler directive, the result is as though the contents of the included source file appear in place of the directive. For example,

`include "parts/resistors/standard/count.va" // Include the counter.

would place the entire contents of file count.va in the source file at the place where the `include directive is coded.

Where the compiler looks for file depends on whether you specify an absolute path, a relative path, or a simple filename. If the compiler does not find the file, the compiler generates an error message.

Adjusting the Time Scale

Use the `timescale compiler directive to specify the time unit and time precision of the modules that follow it. This directive affects only digital contexts.

timescale_compiler_directive ::=
        `timescale time_period / time_precision
time_period ::= 
        time_integer time_unit
time_precision ::=
        time_integer time_unit

time_integer is one of the three integers: 1, 10, or 100.

time_unit is one of the following:

time_unit Meaning

s

seconds

ms

milliseconds

us

microseconds

ns

nanoseconds

ps

picoseconds

fs

femtoseconds

The time_unit specifies the unit of measurement for time values such as the simulation time and delay values.

The time_precision specifies how delay values are rounded before being used in simulation. The values used in simulation are accurate to within the unit of time specified by time_precision. The time_precision you specify must be less than or equal to time_period. The smallest time_precision argument of all the `timescale compiler directives in the design determines the time unit of the simulation.

The `timescale directive sets the transition time in the transition filter and in Z-transform filters when neither local transition settings nor a `default_transition directive is used. However, Cadence recommends using the `default_transition directive instead.

The following example illustrates how to use the `timescale directive.

`timescale 1 ns / 1 ps

In this example, all time values in the modules which follow the directive are multiples of 1 ns because the time_unit argument is 1 ns. Delays are rounded to a precision of one-thousandth of a nanosecond because the time_precision argument is 1 ps, or one-thousandth of a nanosecond.

Setting a Default Discrete Discipline for Signals

Use the `default_discipline compiler directive to specify a default discrete discipline for signals that do not have an explicit discipline declaration. You must not use this directive inside a module definition.

default_discipline_compiler_directive ::=
        `default_discipline [ discipline_identifier [qualifier] [scope]]
qualifier ::=
    |   reg
|   wire
|   tri
|   wand
|   triand
|   wor
|   wreal
|   trior
|   trireg
|   tri0
|   tri1
|   supply0
|   supply1
scope ::=
        instance_identifier

discipline_identifier is the discrete discipline to be associated with signals that do not have explicit discipline declarations. Using the `default_discipline directive without specifying a discipline_identifier turns off the directive, so subsequent signals without a discipline are associated with the empty discipline.

qualifier indicates the kind of signal to be acted upon by the `default_discipline directive. If you do not specify a qualifier, the `default_discipline compiler directive is in effect for every signal that lacks an explicit discipline declaration.

instance_identifier is the name of a module. The `default_discipline compiler directive is effective only in the indicated module. If you do not specify a module, the `default_discipline is effective in every module.

You can have more than one `default_discipline directive in effect at a time, provided that each differs in scope, qualifier, or both. Each directive remains in effect until the compiler encounters another `default_discipline with the same combination of qualifier and scope.

For example, the following statement illustrates how to use both a qualifier and a scope.

`default_discipline logic trireg example1.instance5 ;

In the following module, the signals in1, in2, and out are all associated with the discipline logic by default.

‘default_discipline logic // No qualifier or scope so affects all signals.
module behavnand(in1, in2, out);
input in1, in2;           // Not associated with any explicit discipline.
output out;
reg out;
always begin
    out = ~(in1 && in2);
end
endmodule

Setting Default Rise and Fall Times

Use the `default_transition compiler directive to specify default rise and fall times for the transition and Z-transform filters. This directive affects only analog contexts.

default_transition_compiler_directive ::=
        `default_transition transition_time

transition_time is an integer value that specifies the default rise and fall times for transition and Z-transform filters that do not have specified rise and fall times.

If your description includes more than one `default_transition directive, the effective rise and fall times are derived from the immediately preceding directive.

The `default_transition directive takes precedence over `timescale directives for setting the transition time in the transition and Z-transform transform filters when local transition settings are not provided.

If you include neither a `default_transition directive nor a `timescale directive in your description, the default rise and fall times for transition and Z-transform filters is 0.

Resetting Directives to Default Values

Use the `resetall compiler directive to set all compiler directives, except the `timescale directive, to their default values.

resetall_compiler_directive ::=
        `resetall

Placing the `resetall compiler directive at the beginning of each of your source text files, followed immediately by the directives you want to use in that file, ensures that only desired directives are active.

Use the `resetall directive with care because it resets the
`define DISCIPLINES_VAMS

directive in the discipline.vams file, which is included by most Verilog-AMS files.

Specifying Which Reserved Keyword List to Use

Use the `begin_keywords and `end_keywords compiler directives to specify the active reserved keyword list for the parser. With these directives, you can mix Verilog (digital) and Verilog-AMS modules, even when the Verilog code uses identifiers that are Verilog-AMS keywords.

begin_keywords_compiler_directive ::=
`begin_keywords "version_specifier"
version_specifier ::= 
|1364-1995
|1364-2001
|1364-2005
|1800-2005
end_keywords_compiler_directive ::=
`end_keywords

Each version_specifier value specifies an active subset of the default keyword list. The software determines the default keyword list depending on the options you specify on the xmvlog or xrun command line as follows:

Option

Default Keyword List

Active Reserved Keywords

-v95 or -v1995

1364-1995

The subset of the default list that is part of the IEEE 1364-1995 standard

-ams

1364-2005 and the Cadence AMS keywords

The subset of the default list that appears in Appendix D, “Verilog-AMS Keywords”

-sv31

1800-2005

The subset of the default list that is part of the IEEE 1800-2005 standard

None of the above

1364-2005

The subset of the default list that is part of the IEEE 1364-2005 standard

You must pair each `begin_keywords directive with a `end_keywords directive. The pair of directives defines a region of source code to which a specified version_specifier applies. The `begin_keywords directive affects all design elements (module, primitive, configuration, paramset, connectrules, and connectmodule) that follow the directive, even across source code file boundaries, until the software encounters its matching `end_keywords directive. These directives do not affect the semantics, tokens, and other aspects of the Verilog-AMS language.

You must not specify the `begin_keywords and `end_keywords directives inside a design element (module, primitive, configuration, paramset, connectrules, or connectmodule).

You can nest directive pairs. When the software encounters a `end_keywords directive, the compiler returns to using the version_specifier that was in effect prior to the matching `begin_keywords directive.

The following example shows how you might use a Verilog (digital) module together with a Verilog-AMS module in a design. The Verilog module uses a parameter called sin, which is a Verilog-AMS keyword. To tell the compiler not to see sin as a keyword, you use the ‘begin_keywords directive to change the active set of keywords to a set that does not include the sin keyword.

// Use IEEE Std 1364-2001 Verilog keywords. Do not use Verilog-AMS keywords.
`begin_keywords "1364-2001"

module digital_module;
parameter sin = "hello"; // Uses a Verilog-AMS keyword as an identifier.
                         // sin is not a keyword in 1364-2001.
initial begin
    $strobe("%s",sin);
end
endmodule
// Restore the Verilog-AMS keywords now. `end_keywords

Here is another similar example:

`begin_keywords "1364-2005" // Use IEEE Std 1364-2005 Verilog keywords.
module m2 (sin ...);
input sin // Uses Verilog-AMS keyword sin as a port name.
// sin is not a keyword in 1364-2005.
...
endmodule
`end_keywords

The following example shows a definition of module m1 that does not have a `begin_keywords directive before it. Without this directive, the set of reserved keywords in effect for this module is the default set of reserved keywords for Cadence’s implementation of Verilog-AMS.

module m1; // module definition with no `begin_keywords directive
...
endmodule

Removing and Restoring Specific Keywords

You can use the `remove_keyword and `restore_keyword compiler directives to remove and restore specific keywords from the set of reserved keywords that the parser recognizes.

You might use the `remove_keyword directive to remove one or more specific keywords from the set of reserved keywords you specify using the`begin_keywords and `end_keywords compiler directives.

You can also use the -rmkeyword command-line option (for xmvlog or xrun) in a similar fashion.

Checking Support for Compact Modeling Extensions

Use the __VAMS_COMPACT_MODELING__ macro to determine whether the simulator supports the compact modeling extensions. The AMS Designer simulator supports these extensions and sets the value of this macro to t.

VAMS_COMPACT_MODELING_macro_call::=
        
`ifdef __VAMS_COMPACT_MODELING__

The __VAMS_COMPACT_MODELING__ macro is predefined, so all you need to do is reference the macro name. (Notice the double underscore characters at both the beginning and the end of the macro name.) The returned value is t if the simulator supports the compact modeling extensions, which are:

If the simulator does not support the compact modeling extensions, the returned value is nil.


Return to top
 ⠀
X