Limited preprocessor for Verilog.
First, a warning. In general, the Verilog specification does not
cover how preprocessing is to be done in a very complete way. We are left with
many subtle questions about how the preprocessor should behave, and to resolve
these questions we have sometimes just given test cases to simulators such as
Verilog-XL, NCVerilog, and VCS. This is not a very satisfying state of
Our preprocessor has pretty good support for the define- and
We place some (reasonable) restrictions on the above macros. For instance,
we do not allow definitions to include most compiler directives—we allow
the body of `foo to include `bar, but not `endif. These
restrictions are intended to ensure that we do not "mispreprocess" anything.
See preprocessor-ifdef-minutia for some details and additional
We also have pretty good support for `include directives. This is
quite underspecified, and we have basically tried to mimic the behavior of
Verilog-XL and NCVerilog. See also preprocessor-include-minutia.
We also "support" certain directives by ignoring them.
When we say we ignore these directives, we mean that the preprocessor
literally removes them from the source code that the lexer sees. No record of
these directives is ever kept. A consequence of this is, upon having loaded
some VL modules, there is not really any way to know whether these directives
were included anywhere in the source code.
In the case of celldefine and endcelldefine, this seems pretty
reasonable. It seems that these directives only mark modules as "cells" for
certain PLI directives or other tools. None of the tools we are developing
care about this, so for now we just ignore this directive.
The resetall directive is tool dependent and it seems valid to ignore
it entirely. We do not try to enforce the restriction that resetall must
not occur within a module definition.
We also ignore timescale directives. This is not ideal, but is pretty
reasonable for things like ESIM where timing is irrelevant. It is also fairly
reasonable even for something like a transistor analyzer that cares about unit
delays, as long as differnet timescales are not being mixed together. (Mixing
timescales within a single design seems insane, and after all what is the
"default" timescale supposed to be? BOZO maybe add a warning if more than
one kind of timescale is seen.
As future work, there might be some benefit to somehow preserving these
directives so that they can be printed out again in the simplified Verilog we
produce. That is, maybe it would make the simplified Verilog easier to use as
a "drop-in replacement" for the unsimplified Verilog.
We currently make no attempt to support:
It might be good to ignore `begin_keywords "1364-2005" and just cause
an error if a different set of keywords is requested. We could also ignore
`end_keywords. But trying to add anything more sophisticated than this
seems very tricky and messy.
It would be good to add proper support for `line. Failing that, it
would be quite easy to just ignore it, like the other ignored directives. We
should probably also ignore `pragma directives, and this should be easy to
It would be somewhat difficult to support `default_nettype and
`unconnected_drive. Probably the thing to do would be build a table of
when the declarations are made, and then use some trick like comment injection
to mark modules appropriately. We would then have to change the make-implicit-wires transform to consider the `default_nettype for the
module, and probably use a separate transform to handle `unconnected_drive
- `ifdef stack frame objects.
- Subtle notes about or `define and `ifdef handling.
- Main loop for the preprocessor.
- Read from `define until the end of the line.
- Expand uses of defines like `foo and `max(a,b).
- Read an `include directive.
- Handler for ifdef, ifndef, and elsif directives.
- Top-level interface to the preprocessor.
- Internal representation of a `define directive.
- Handler for define directives.
- Handler for undef directives.
- Subtle notes about `include handling.
- Split up the rest of a define line into macro arguments and macro text.
- Handler for else directives.
- Handler for endif directives.
- (vl-istack-p x) recognizes lists where every element satisfies vl-iframe-p.
- List of Verilog-2005 compiler directives.
- Used to get a context for error messages.
- Used to get a context for error messages.
- A list of vl-define-p objects.
- Artificial bound on preprocessor loops, for termination.