• Top
    • Documentation
    • Books
    • Recursion-and-induction
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
    • Interfacing-tools
    • Hardware-verification
      • Gl
      • Esim
      • Vl2014
      • Sv
      • Vwsim
      • Fgl
      • Vl
        • Syntax
        • Loader
          • Preprocessor
            • Vl-iframe
            • Preprocessor-ifdef-minutia
            • Vl-preprocess
            • Vl-preprocess-loop
            • Vl-includeskips
            • Vl-read-until-end-of-define
            • Vl-define-formallist->defaults
            • Vl-define
            • Vl-expand-define
            • Vl-read-include
            • Vl-substitute-into-macro-text
            • Vl-process-ifdef
            • Ppst
            • Vl-read-define-default-text
            • Vl-process-define
            • Preprocessor-include-minutia
            • Vl-line-up-define-formals-and-actuals
            • Vl-split-define-text
            • Vl-process-undef
            • Vl-def-context
            • Vl-process-endif
            • Vl-ifdef-context
            • Vl-trim-for-preproc
            • Vl-atvl-atts-text
            • Vl-check-remaining-formals-all-have-defaults
            • Vl-process-else
            • Vl-is-compiler-directive-p
            • Vl-includeskips-controller-lookup
            • Vl-nice-bytes
            • Vl-ifdef-use-map
            • Vl-defines
            • Vl-def-use-map
            • Vl-safe-previous-n
            • Vl-safe-next-n
            • Vl-ppst-pad
            • Vl-maybe-update-filemap
            • Vl-filename-to-string-literal
            • *vl-preprocess-clock*
            • Vl-ppst->warnings
            • Vl-ppst->iskips
            • Vl-ppst->includes
            • Vl-ppst->ifdefmap
            • Vl-ppst->idcache
            • Vl-ppst->filemap
            • Vl-ppst->defines
            • Vl-ppst->config
            • Vl-ppst-record-ifdef-use
            • Vl-ppst-record-def-use
            • Vl-istack
            • Vl-ppst->istack
            • Vl-ppst->defmap
            • Vl-ppst->bytes
            • Vl-ppst->activep
            • Vl-ppst->acc
            • Vl-ifdef-context-list
            • Vl-def-context-list
            • Vl-ppst-update-warnings
            • Vl-ppst-update-istack
            • Vl-ppst-update-iskips
            • Vl-ppst-update-includes
            • Vl-ppst-update-ifdefmap
            • Vl-ppst-update-idcache
            • Vl-ppst-update-filemap
            • Vl-ppst-update-defmap
            • Vl-ppst-update-defines
            • Vl-ppst-update-config
            • Vl-ppst-update-activep
            • Vl-ppst-update-bytes
            • Vl-ppst-update-acc
            • Vl-ppst-unsound-nreverse-acc
          • Vl-loadconfig
          • Vl-loadstate
          • Lexer
          • Parser
          • Vl-load-merge-descriptions
          • Vl-find-basename/extension
          • Vl-load-file
          • Vl-loadresult
          • Vl-find-file
          • Scope-of-defines
          • Vl-flush-out-descriptions
          • Vl-description
          • Vl-read-file
          • Vl-includeskips-report-gather
          • Vl-load-main
          • Extended-characters
          • Vl-load
          • Vl-load-description
          • Vl-preprocess-debug
          • Vl-descriptions-left-to-load
          • Inject-warnings
          • Vl-read-file-report-gather
          • Vl-write-preprocessor-debug-file
          • Vl-load-descriptions
          • Vl-load-files
          • Translate-off
          • Vl-load-read-file-hook
          • Vl-loadstate-pad
          • Vl-read-file-report
          • Vl-load-summary
          • Vl-collect-modules-from-descriptions
          • Vl-loadstate->warnings
          • Vl-iskips-report
          • Vl-descriptionlist
        • Warnings
        • Getting-started
        • Utilities
        • Printer
        • Kit
        • Mlib
        • Transforms
      • X86isa
      • Svl
      • Rtl
    • Software-verification
    • Testing-utilities
    • Math
  • Loader

Preprocessor

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 affairs.

Supported Directives

Our preprocessor has pretty good support for the define- and ifdef-related directives:

  • define
  • ifdef
  • ifndef
  • elsif
  • else
  • undef

See preprocessor-ifdef-minutia for some details and additional discussion.

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 `__FILE__ and `__LINE__ directives.

Ignored Directives

We also "support" certain directives by ignoring them.

  • `celldefine
  • `endcelldefine
  • `resetall
  • `timescale
  • `protect
  • `endprotect

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.

We also ignore `protect and `endprotect, which seem to be old Verilog-XL directives for marking code that you want a tool to encrypt. VL doesn't implement any support for decrypting protected code, but it can at least ignore these indications that you want to encrypt something. Note that these directives are not documented in the SystemVerilog-2012 standard and are probably subsumed by the pragma syntax described in Section 34, protected envelopes.

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.

Unsupported Directives

We currently make no attempt to support:

  • `begin_keywords
  • `default_nettype
  • `end_keywords
  • `line
  • `pragma
  • `nounconnected_drive
  • `unconnected_drive

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 do.

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 stuff.

Subtopics

Vl-iframe
`ifdef stack frame objects.
Preprocessor-ifdef-minutia
Subtle notes about or `define and `ifdef handling.
Vl-preprocess
Top-level interface to the preprocessor.
Vl-preprocess-loop
Main loop for the preprocessor.
Vl-includeskips
A record of which files we have already included that have ``proper'' include guards and may not need to be included again.
Vl-read-until-end-of-define
Read from `define until the end of the line.
Vl-define-formallist->defaults
(vl-define-formallist->defaults x) maps vl-define-formal->default across a list.
Vl-define
Internal representation of a `define directive.
Vl-expand-define
Expand uses of defines like `foo and `max(a,b).
Vl-read-include
Read an `include directive.
Vl-substitute-into-macro-text
Vl-process-ifdef
Handler for ifdef, ifndef, and elsif directives.
Ppst
Preprocessor state object.
Vl-read-define-default-text
Vl-process-define
Handler for define directives.
Preprocessor-include-minutia
Subtle notes about `include handling.
Vl-line-up-define-formals-and-actuals
Vl-split-define-text
Split up the rest of a define line into macro arguments and macro text.
Vl-process-undef
Handler for undef directives.
Vl-def-context
Information about a single use of a define like `FOO.
Vl-process-endif
Handler for endif directives.
Vl-ifdef-context
Information about a single use of ifdef FOO or elsif BAR.
Vl-trim-for-preproc
Trim whitespace from a string, but preserving space that might be syntactically significant.
Vl-atvl-atts-text
Vl-check-remaining-formals-all-have-defaults
Vl-process-else
Handler for else directives.
Vl-is-compiler-directive-p
List of Verilog-2005 compiler directives.
Vl-includeskips-controller-lookup
Look up the controlling define for this file, if one is known.
Vl-nice-bytes
Human-friendly summary of some number of bytes.
Vl-ifdef-use-map
A log of where `defines are used in the `ifdef tree.
Vl-defines
An alist mapping stringp to vl-maybe-define-p.
Vl-def-use-map
A log of where `defines are used, outside of ifdefs.
Vl-safe-previous-n
Used to get a context for error messages.
Vl-safe-next-n
Used to get a context for error messages.
Vl-ppst-pad
Prefix for lines produced by the preprocessor.
Vl-maybe-update-filemap
Vl-filename-to-string-literal
*vl-preprocess-clock*
Artificial bound on preprocessor loops, for termination.
Vl-ppst->warnings
Vl-ppst->iskips
Vl-ppst->includes
Vl-ppst->ifdefmap
Vl-ppst->idcache
Vl-ppst->filemap
Vl-ppst->defines
Vl-ppst->config
Vl-ppst-record-ifdef-use
Vl-ppst-record-def-use
Vl-istack
A list of vl-iframe-p objects.
Vl-ppst->istack
Vl-ppst->defmap
Vl-ppst->bytes
Vl-ppst->activep
Vl-ppst->acc
Vl-ifdef-context-list
A list of vl-ifdef-context-p objects.
Vl-def-context-list
A list of vl-def-context-p objects.
Vl-ppst-update-warnings
Vl-ppst-update-istack
Vl-ppst-update-iskips
Vl-ppst-update-includes
Vl-ppst-update-ifdefmap
Vl-ppst-update-idcache
Vl-ppst-update-filemap
Vl-ppst-update-defmap
Vl-ppst-update-defines
Vl-ppst-update-config
Vl-ppst-update-activep
Vl-ppst-update-bytes
Vl-ppst-update-acc
Vl-ppst-unsound-nreverse-acc