Design libraries and v2cc
-------------------------

v2cc does not have a opaque notion of design libraries.  VHDL files
are not pre-analyzed and checked into some library data base.
Instead, whenever a reference to a design unit needs to be made, v2cc
parses the VHDL code of that design unit from fresh.  Therefore, it
needs to be able to find the source file of a design unit given the
VHDL name of that unit.

Thus, as far as v2cc is concerned, a design library is a mapping from
VHDL identifiers to file names.  There is also a mapping for getting
library names from mapping files.

Such a mapping is specified via a "mapping file".  It contains a list
of pattern rules that each transform a certain class of identifiers
into file names.

The syntax of a mapping file is:

  Lexical:

     litchar: 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '/' | '-' | '.' escchar

     escchar: '\' char

     whitespace: ' ' | '\n' | '\v' | '\t' | comment

     comment: '#' any_character* '\n'

     opchar: ':' | ',' | '(' | ')'

     specchar: every printable char except litchar, whitespace and opchar

     symchar: litchar | specchar

     symbol: symchar+

  Grammar:

     mapping: version patternrule*

     version: "v2cc_mapfile" "0"

     patternrule: symbol [ ':' symbol ]

Comments are ignored.

A mapping files specifies a sequence of pattern rules.  When
transforming an indentifier, each rule is tried in turn and the first
one that matches is choosen.

A rule looks like

  pattern: filename

When the ": filename" part is omitted, it defaults to "patternEXT"
where "EXT" is determined by the user of the mapping file.

The "pattern" can contain the special character "<" which introduces a
`wildcard'.  The "<" must be followed by a ">", with arbitrary
characters inbetween.  These characters form the name of the wildcard.
A wildcard matches any sequence of characters.  There can be any
number of wildcards in the pattern, but each must have a unique name.

The "filename" can also contain the character "<", followed by a name,
followed by ">".  There, it introduces a `wildcard substitution'.  It
will be replaced with the characters that matched the wildcard with
the same name in "pattern".  When there is no wildcard in "pattern"
with the right name, it will be replaced with nothing.  While doing
this replacement, the characters "#" and "/" are replaced as "##", and
"#-" respectively.  No other character translations are done, so if
you have funny characters in your VHDL identifiers, you will have
funny characters in your filenames.

Before doing the comparison with the patterns, the VHDL identifier is
brought into a canononical form: when it is not an abstract
identifier, all its characters are down-cased.

When the resulting filename is relative (does not begin with "/"), it
is prefixed with the directory of the mapping file.

A non-existent mapping file is equivalent to the single rule

  <>

An empty mapping file is just that: an empty mapping.

The mapping does not need to be reversible.  It is OK when multiple
identifiers map to a single filename.

No special character besides "<" and ">" is valid in "pattern" or
"filename".  They are reserved for future extensions.


The mapping files for going from design unit names to filenames are
found by looking into directories specified by the `v2cc library
path'.  You can use the environment variable V2CC_LIBRARY_PATH and
command line options to define the path.  When the environment
variable is not set, it defaults to a value that makes the standard
libraries available that are distributed and installed with v2cc
itself.  When it is set, it completely overwrites this default value.

The variable V2CC_LIBRARY_PATH consists of ":" separated filenames.
The filename "*" is replaced with the default value mentioned above.

In addition to the environment variable, you can use the "-L libdir"
command line option with v2cc.  The directories specified with "-L"
are added in front of the ones specified by V2CC_LIBRARY_PATH.  In the
final library path, they appear in the same order as on the command
line.

Looking for a design unit named UNIT in a library named LIB is done
like this:

     for each component of the library path, L
       if L is a regular file
         set LMAP to L
       else if L is a directory
         set LMAP to L/v2cc.libs
       else
         continue with next component
       translate LIB into FLIB using LMAP with EXT=""
       if FLIB.vhdl exists
         terminate with FLIB.vhdl as the result
       if FLIB.v2cc exists
         set UMAP to FLIB.v2cc
       else if FLIB is a directory
         set UMAP to FLIB/v2cc.units
       else
         continue with next component
       translate UNIT into FUNIT using UMAP with EXT=".vhdl"
       terminate with FUNIT as the result
     terminate unsuccessfully


This mechanism is used for all design units that are referenced from
within VHDL code (or via other means).  There is a complication with
architectures and package bodies, though, because they are not
uniquely identified by a single identifier.  For them, a artifical
identifier is constructed.  Architectures get names of the form 

    <entity>(<architecture>)

while package bodies become

    <package>(body)

For example, "architecture struct of model" is turned into
"model(struct)" and "package body misc" is turned into "misc(body)".

When a design file contains multiple design units, they are all
parsed, checked for correctnes and remembered, but only the needed
unit will be used for code generation.  That is, when a design file
contains both a package header and a package body and the package
header is referenced from another design unit, no code will be
generated for the package body.  When one of the ignored units will be
referenced later in the same invocation of v2cc, the design file will
not be read again because all design units are retained in core.


Examples
--------

The simplest situation is when you have no mapping files at all.  A
design library is then a directory on your library path.  The name of
that directory is that of the library in VHDL.  Each file in that
directory with a ".vhdl" extension is used for a design unit with the
same name as the file without the extension.

Say you have this directory structure

    somedir/
      std/
        standard.vhdl
        textio.vhdl
      ieee/
        numeric_bit.vhdl
        std_logic_1164.vhdl

When you put "somedir" into your library path, you have access to the
design units

       STD.STANDARD
       STD.TEXTIO
       IEEE.NUMERIC_BIT
       IEEE.STD_LOGIC_1164

In this situation, you have one file per design unit.  When you have
one file per design library, it would look like this

    somedir/
      fmf.vhdl

All references to design units in the FMF design library would be
routed to "fmf.vhdl".




Considerations
--------------

- Simplicity

  The mapping is intended to be simple.  If you find yourself doing
  complicated things or wanting complicated extensions, we should
  probably rethink the mapping file completely.  Maybe it is better to
  be able to specify an external program that gets called to do the
  mapping.

- Extensibility

  Simple things within the pattern rules can be done by defining a
  meaning for other special characters.

  Broader changes to the grammar of the file should be marked with a
  different version number, or maybe even a different format name.

- Efficiency

  It might be that the repeated parsing of VHDL source code will be an
  unduly overhead.  This might not really be the case (Edwin says the
  C++ compiler takes much longer anyway), but if it turns out to be a
  problem, the solution would be to cache the results of previous
  parsing runs on disk.  This should be done transparent to the user
  (although the user should of course be able to detect and correct
  problems with the caching like full disks or denied write permission
  to the caching directoy).

- Automatic generation

  Mapping files are meant to be written by hand.  If you are thinking
  about some automatic mechanism by which to generate them, it is
  probably better to extend the capabilities of the mapping files so
  that your new mechanism can be selected.
