Skip to content
Andy Leiserson edited this page Sep 9, 2013 · 9 revisions

Manual

This page contains a snapshot of the vp3 documentation. Changes should be made in the vp3 source, not here.

NAME

VP3 - Verilog preprocessor and generator

SYNOPSIS

vp3 -y . -o module.v module.vp

DESCRIPTION

VP3 is a tool to assist in the description of a hardware design in Verilog. VP3 can generate module instantiations and signal declarations for you. It provides a preprocessor function comparable to the C preprocessor, and allows you to generate portions of your Verilog with embedded perl code.

VP3 works on the input in several passes. The first pass is a preprocessor. Two preprocessors are currently supported. The built-in preprocessor is used by default. If you specify the -p ep3 option, the ep3 tool will be invoked to preprocess the source. To use the ep3 preprocessor, Text::EP3 must be installed (available on CPAN).

After preprocessing is complete, VP3 parses the input, which should consist of Verilog and VP3 directives. VP3 then performs the following translations:

  • Expands @Instance directives to a complete module instantiation.

  • Analyzes signal usage by the design and constructs a connectivity database.

  • Expands remaining VP3 directives. The @Regs and @Wires directives generate declarations for any signals identified in the previous step that are not otherwise declared.

The core processing steps are performed on a module-by-module basis. If there are multiple modules in the file, VP3 will process them in bottom-to-top hierarchical order, regardless of the order they appear in the input.

After processing has completed, VP3 performs a connectivity check on the design. Unloaded and undriven signals are flagged. Note that port inference for unconnected signals will mask many of these connectivity errors.

Why use VP3?

  • Saves tedious and error prone typing.

  • Instance expansion with regular expression renaming rules is more powerful than SystemVerilog wildcard connects (.*)

  • Using VP3 shorthand rather than a complete verilog description reduces the verbosity of the design description, improving maintainability

  • Immediate feedback about potential design issues (unconnected signals, width mismatch, etc...) during RTL entry.

  • Compared to editor-based tools like Verilog-mode for Emacs, VP3 has the advantage that it does not inflame editor holy wars and does not encourage placing generated code under version control.

OPTIONS

-o file

Required. Specifies where to write the output.

-p preprocessor

Optional. Specifies an alternate preprocessor. The available preprocessors are standard (the default), and ep3.

--debug

Optional. Enables additional debug output.

--vdefine NAME, --vdefine NAME=VALUE

Optional. Defines the Verilog preprocessor macro `NAME, either with an empty expansion, or as VALUE.

--define NAME[=VALUE]

Optional. Defines the VP3 preprocessor macro NAME, either with an empty expansion, or as VALUE.

--vinclude path

Optional. Specifies include paths in which to search for Verilog `include files.

-i path, --include path

Optional. Specifies include paths in which to search for VP3 preprocessor @include files.

-v file

Optional. Specifies a Verilog library file to search for instantiated modules. Libraries specified with -v must be completely read and parsed to determine if they contain a sought module, so their use entails a performance penalty.

-y path

Optional. Specifies a Verilog library directory to search for instantiated modules. The module is expected to be defined in a file named module.v in one of the specified library directories.

-w

Optional. Treat warnings as errors.

DIRECTIVES

There are two classes of directives: preprocessor directives and VP3 directives. By convention, preprocessor directives start with a lower case letter, and VP3 directives start with an upper case letter.

Preprocessor directives

The built-in preprocessor supports the following directives. Consult the Text::EP3 documentation for information on preprocessor directives in -p ep3 mode.

@define NAME value

Defines NAME as a preprocessor macro to be substituted with value.

@include "file"

Includes the contents of file at the current source location.

@perl_begin ... @perl_end

Usage:

@perl_begin
# any number of lines of perl code
@perl_end

Evaluates the text between the begin/end directives as perl code.

The embedded perl code may emit text into the preprocessor output by calling vprint.

Any subroutines defined by the perl code will become available to the remainder of the source as a directive with the same name. When invoked, the directive subroutine will be passed a single argument containing the text (if any) on the line, with the directive and any whitespace after the directive name removed.

@if

Introduces a conditional section of the source. The remainder of the line after @if is macro-expanded and then evaluated as perl code. The conditional section continues until the next matching @elsif, @else, or @endif directive. Conditional sections may be nested.

@ifdef / @ifndef

Introduces a conditional section of the source. The remainder of the line after the directive must consist of a single identifier. For @ifdef, if that identifier has been previously defined as a preprocessor macro, the conditional section will be included. For @ifndef, the conditional section is included if the identifier has not been previously defined.

@elsif

Must be preceeded by one or more conditional directives. @elsif terminates the preceeding conditional section and introduces a new section. The section following @elsif is ignored if a previous section in the current conditional chain has been included. Otherwise, the section following @elsif is included if the condition specified after the directive is true. @elsif may be followed either by a single identifier, in which case that identifier is tested in the same manner as @ifdef, or by a complex expression, in which case that expression is tested in the same manner as @if.

@else

Similar to @elsif, but with an implicit true condition.

@endif

Ends a chain of conditional sections.

VP3 directives

@Module

Usage:

@Module [-none] [-v2k] [-attr <attributes>] [module_identifier] ;

The @Module directive introduces a module. If the module_identifier is not given, the module name will be taken from the name of the input file. Except for the special case of @Module -none (see below), @Module should have a corresponding endmodule.

The @Module directive accepts the following options:

-attr <attributes>

The -attr option prints the specified text as attribute(s) on the generated module header. The string given should not include the (* and *) delimeters.

-none

Enter module context, but don't generate any module statement. This may be useful to generate files to be inserted in other source using `include. When @Module -none is used, do not use endmodule. In this mode, connectivity validation is disabled.

-v2k

The -v2k option causes the generated module header to use the Verilog-2001 syntax, which has full port declarations inline with the header. For more detail, see below.

The @Module directive is useful when using VP3's optional port inference function, which automatically creates port declarations for signals that are undriven or unloaded in the input module description:

  • For Verilog-1995-style module headers, use the @Module directive (without the -v2k option) regardless of whether inferred ports are desired. If inferred ports are desired, specify the @Ports directive within the module. Whether or not port inference is enabled, VP3 will scan the module definition for input and output declarations, and @Module will include identifiers found in those declarations in the generated port list. If @Ports is specified in the module, @Module will also include the names of any inferred ports in the generated port list.

  • For Verilog-2001-style module headers, use @Module -v2k if and only if port inference is desired. When using inferred ports, signals may be explicitly declared as I/O with the @Input and @Output directives. If port inference is not desired, do not use the @Module directive. Code the module header directly in Verilog syntax.

@Ports

Usage:

@Ports;

The @Ports directive generates Verilog-1995 port declarations for any signals used in the module that are undriven or unloaded. An input or output port will be defined, as applicable.

When using Verilog-2001 module headers, inferred ports are generated directly in the module header by @Module. @Ports should not be used.

@Regs, @Wires

Usage:

@Regs;
@Wires;

These directives generate signal declarations for signals that are used in the source but are not otherwise declared. The type of declaration is inferred automatically based on usage.

@Input, @Output

Usage:

@Input signal_identifier;
@Output signal_identifier;

These directives force a signal to be declared as an input or output even if it would not normally be inferred as such. A typical usage is a signal that is used locally within the module but is also required in other modules. The local usage of the signal would normally prevent automatic output port declaration.

These directives should be used only when ports are being inferred with @Ports or @Module -v2k. Otherwise, the desired port declarations should be coded explicitly.

@Waive

Usage:

@Waive no_source signal_identifier;
@Waive no_sink signal_identifier;

The @Waive directive inhibits connectivity errors for the specified signals.

@Vector

Usage:

@Vector expression signal_identifier;

@Vector [msb:lsb] signal_identifier;

The @Vector directive specifies the size of the specified signal. The size will be used in any autogenerated declarations for that signal. The size may be specified as a single number, in which case the signal range will be [size-1:0], or the range may be specified directly.

@Unparsed

Usage:

@Unparsed begin;
// unsupported Verilog constructs
@Unparsed end;

The @Unparsed directive provides a means to pass through Verilog constructs that are not yet supported by the VP3 parser. It can also be used around code that should not be processed by VP3 for some other reason. The text between the directives will be included verbatim in the output. No connectivity analysis or VP3 directive expansion will be performed on the unparsed section.

@Instance

Usage:

@Instance [-file instance.v] instance instance_name
  -connect instance_portA     connectionA
  -connect instance_portB     connectionB
  -connect /^instance_prefix/ connection_prefix
;

The @Instance directive expands as an instantiation of the specified module. The source of the instantiated module must either be located in one of the search locations specified on the command line or be specified with the -file option.

By default, ports of the instantiated module will be connected to like-named signals in the current module. The connection can be modified with -connect options. The first argument after -connect is a pattern to match against the ports of the instantiated module, and the second argument is replacement text. If the pattern is not delimited by slashes, it must match the full port name (^ and $ are implicitly added to the pattern). If the pattern is delimited by slashes, it may match any part of the port name, and the replacement will be applied only to the matching part.

PERL FUNCTIONS

VP3 provides some functions which may be used by user Perl code running in @perl_begin/@perl_end sections.

vexpr

Usage:

vexpr ("verilog expression")

Example:

vexpr ("2 + 2")
// Returns 4

The vexpr function allows user code to call VP3's expression evaluation engine.

vports

Usage:

vports ("module")

The vports function searches for the specified module using the same search locations that would be used for a @Instance directive, parses it, and returns a list of the ports of the module. The return value is a VP3::Ports object.

vprint

Usage:

vprint (list)

This function prints the provided arguments into the intermediate Verilog. Text inserted in will be seen by the later phases of VP3 processing. This means that it is possible to emit, for example, VP3 @Instance directives.

This function is provided only under the built-in preprocessor. When using the ep3 preprocessor, print should be used instead. The built-in preprocessor preserves print as a means of printing text to the console.

BUGS

This is alpha-quality software and bugs are to be expected. Please report bugs in the issue tracker on github.

The following Verilog constructs are not yet supported:

  • specify blocks

  • primitives (gates and UDPs)

  • text macros with arguments

  • preprocessor directives other than `timescale, `include, `define, `undef, and `line

  • ports connected by order (accepted by the parser but not understood for connectivity analysis)

  • complex ports (all the examples other than module test in section 12.3.3 of the standard)

  • instance arrays

  • generate blocks (accepted by the parser but not otherwise handled)

  • big-endian vectors

  • port connection attributes, and some other attribute uses that are (I hope) esoteric

AUTHOR

Andrew Leiserson <andy@leiserson.org>