summaryrefslogtreecommitdiff
path: root/doc/GHDL_implementation_of_VHDL.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/GHDL_implementation_of_VHDL.rst')
-rw-r--r--doc/GHDL_implementation_of_VHDL.rst479
1 files changed, 479 insertions, 0 deletions
diff --git a/doc/GHDL_implementation_of_VHDL.rst b/doc/GHDL_implementation_of_VHDL.rst
new file mode 100644
index 0000000..808c391
--- /dev/null
+++ b/doc/GHDL_implementation_of_VHDL.rst
@@ -0,0 +1,479 @@
+***************************
+GHDL implementation of VHDL
+***************************
+
+This chapter describes several implementation defined aspect of VHDL in GHDL.
+
+.. _VHDL_standards:
+
+VHDL standards
+==============
+
+.. index:: VHDL standards
+
+.. index:: IEEE 1076
+
+.. index:: IEEE 1076a
+
+.. index:: 1076
+
+.. index:: 1076a
+
+.. index:: v87
+
+.. index:: v93
+
+.. index:: v93c
+
+.. index:: v00
+
+.. index:: v02
+
+This is very unfortunate, but there are many versions of the VHDL
+language, and they aren't backward compatible.
+
+The VHDL language was first standardized in 1987 by IEEE as IEEE 1076-1987, and
+is commonly referred as VHDL-87. This is certainly the most important version,
+since most of the VHDL tools are still based on this standard.
+
+Various problems of this first standard have been analyzed by experts groups
+to give reasonable ways of interpreting the unclear portions of the standard.
+
+VHDL was revised in 1993 by IEEE as IEEE 1076-1993. This revision is still
+well-known.
+
+Unfortunately, VHDL-93 is not fully compatible with VHDL-87, i.e. some perfectly
+valid VHDL-87 programs are invalid VHDL-93 programs. Here are some of the
+reasons:
+
+* the syntax of file declaration has changed (this is the most visible source
+ of incompatibility),
+* new keywords were introduced (group, impure, inertial, literal,
+ postponed, pure, reject, rol, ror, shared, sla, sll, sra, srl,
+ unaffected, xnor),
+* some dynamic behaviours have changed (the concatenation is one of them),
+* rules have been added.
+
+Shared variables were replaced by protected types in the 2000 revision of
+the VHDL standard. This modification is also known as 1076a. Note that this
+standard is not fully backward compatible with VHDL-93, since the type of a
+shared variable must now be a protected type (there was no such restriction
+before).
+
+Minors corrections were added by the 2002 revision of the VHDL standard. This
+revision is not fully backward compatible with VHDL-00 since, for example,
+the value of the `'instance_name` attribute has slightly changed.
+
+You can select the VHDL standard expected by GHDL with the
+:samp:`--std=VER` option, where :samp:`VER` is one of the left column of the
+table below:
+
+
+87
+ Select VHDL-87 standard as defined by IEEE 1076-1987. LRM bugs corrected by
+ later revisions are taken into account.
+
+93
+ Select VHDL-93; VHDL-87 file declarations are not accepted.
+
+93c
+ Select VHDL-93 standard with relaxed rules:
+
+
+ * VHDL-87 file declarations are accepted;
+
+ * default binding indication rules of VHDL-02 are used. Default binding rules
+ are often used, but they are particularly obscure before VHDL-02.
+
+00
+ Select VHDL-2000 standard, which adds protected types.
+
+02
+ Select VHDL-2002 standard
+
+08
+ Select VHDL-2008 standard (partially implemented).
+
+You cannot mix VHDL-87 and VHDL-93 units. A design hierarchy must have been
+completely analyzed using either the 87 or the 93 version of the VHDL standard.
+
+.. _psl_implementation:
+
+PSL implementation
+==================
+
+GHDL understands embedded PSL annotations in VHDL files, but not in
+separate files.
+
+As PSL annotations are embedded within comments, you must analyze and elaborate
+your design with option *-fpsl* to enable PSL annotations.
+
+A PSL assertion statement must appear within a comment that starts
+with the `psl` keyword. The keyword must be followed (on the
+same line) by a PSL keyword such as `assert` or `default`.
+To continue a PSL statement on the next line, just start a new comment.
+
+A PSL statement is considered as a process. So it is not allowed within
+a process.
+
+All PSL assertions must be clocked (GHDL doesn't support unclocked assertion).
+Furthermore only one clock per assertion is allowed.
+
+You can either use a default clock like this:
+
+.. code-block:: VHDL
+
+ -- psl default clock is rising_edge (CLK);
+ -- psl assert always
+ -- a -> eventually! b;
+
+or use a clocked expression (note the use of parenthesis):
+
+.. code-block:: VHDL
+
+ -- psl assert (always a -> next[3](b)) @rising_edge (clk);
+
+
+Of course only the simple subset of PSL is allowed.
+
+Currently the built-in functions are not implemented.
+
+Source representation
+=====================
+
+According to the VHDL standard, design units (i.e. entities,
+architectures, packages, package bodies and configurations) may be
+independently analyzed.
+
+Several design units may be grouped into a design file.
+
+In GHDL, a system file represents a design file. That is, a file compiled by
+GHDL may contain one or more design units.
+
+It is common to have several design units in a design file.
+
+GHDL does not impose any restriction on the name of a design file
+(except that the filename may not contain any control character or
+spaces).
+
+GHDL do not keep a binary representation of the design units analyzed like
+other VHDL analyzers. The sources of the design units are re-read when
+needed (for example, an entity is re-read when one of its architecture is
+analyzed). Therefore, if you delete or modify a source file of a unit
+analyzed, GHDL will refuse to use it.
+
+.. _Library_database:
+
+Library database
+================
+
+Each design unit analyzed is placed into a design library. By default,
+the name of this design library is :samp:`work`; however, this can be
+changed with the :option:`--work=NAME` option of GHDL.
+
+To keep the list of design units in a design library, GHDL creates
+library files. The name of these files is :file:`NAME-objVER.cf`, where
+`NAME` is the name of the library, and `VER` the VHDL version (87
+or 93) used to analyze the design units.
+
+You don't have to know how to read a library file. You can display it
+using the *-d* of `ghdl`. The file contains the name of the
+design units, as well as the location and the dependencies.
+
+The format may change with the next version of GHDL.
+
+.. _Top_entity:
+
+Top entity
+==========
+
+There are some restrictions on the entity being at the apex of a design
+hierarchy:
+
+* The generic must have a default value, and the value of a generic is its
+ default value;
+* The ports type must be constrained.
+
+Using vendor libraries
+======================
+
+Many vendors libraries have been analyzed with GHDL. There are
+usually no problems. Be sure to use the :option:`--work=` option.
+However, some problems have been encountered.
+
+GHDL follows the VHDL LRM (the manual which defines VHDL) more
+strictly than other VHDL tools. You could try to relax the
+restrictions by using the :option:`--std=93c`, :option:`-fexplicit`,
+:option:`-frelaxed-rules` and :option:`--warn-no-vital-generic`.
+
+Interfacing to other languages
+==============================
+
+.. index:: interfacing
+
+.. index:: other languages
+
+.. index:: foreign
+
+.. index:: VHPI
+
+.. index:: VHPIDIRECT
+
+Interfacing with foreign languages is possible only on GNU/Linux systems.
+
+You can define a subprogram in a foreign language (such as `C` or
+`Ada`) and import it in a VHDL design.
+
+Foreign declarations
+--------------------
+
+Only subprograms (functions or procedures) can be imported, using the foreign
+attribute. In this example, the `sin` function is imported:
+
+.. code-block:: VHDL
+
+ package math is
+ function sin (v : real) return real;
+ attribute foreign of sin : function is "VHPIDIRECT sin";
+ end math;
+
+ package body math is
+ function sin (v : real) return real is
+ begin
+ assert false severity failure;
+ end sin;
+ end math;
+
+
+A subprogram is made foreign if the `foreign` attribute decorates
+it. This attribute is declared in the 1993 revision of the
+:samp:`std.standard` package. Therefore, you cannot use this feature in
+VHDL 1987.
+
+The decoration is achieved through an attribute specification. The
+attribute specification must be in the same declarative part as the
+subprogram and must be after it. This is a general rule for specifications.
+The value of the specification must be a locally static string.
+
+Even when a subprogram is foreign, its body must be present. However, since
+it won't be called, you can made it empty or simply but an assertion.
+
+The value of the attribute must start with :samp:`VHPIDIRECT` (an
+upper-case keyword followed by one or more blanks). The linkage name of the
+subprogram follows.
+
+.. _Restrictions_on_foreign_declarations:
+
+Restrictions on foreign declarations
+------------------------------------
+
+Any subprogram can be imported. GHDL puts no restrictions on foreign
+subprograms. However, the representation of a type or of an interface in a
+foreign language may be obscure. Most of non-composite types are easily imported:
+
+
+*integer types*
+ They are represented on a 32 bits word. This generally corresponds to
+ `int` for `C` or `Integer` for `Ada`.
+
+*physical types*
+ They are represented on a 64 bits word. This generally corresponds to the
+ `long long` for `C` or `Long_Long_Integer` for `Ada`.
+
+*floating point types*
+ They are represented on a 64 bits floating point word. This generally
+ corresponds to `double` for `C` or `Long_Float` for `Ada`.
+
+*enumeration types*
+ They are represented on 8 bits or 32 bits word, if the number of literals is
+ greater than 256. There is no corresponding C types, since arguments are
+ not promoted.
+
+Non-composite types are passed by value. For the `in` mode, this
+corresponds to the `C` or `Ada` mechanism. The `out` and
+`inout` interfaces of non-composite types are gathered in a record
+and this record is passed by reference as the first argument to the
+subprogram. As a consequence, you shouldn't use `in` and
+`inout` modes in foreign subprograms, since they are not portable.
+
+Records are represented like a `C` structure and are passed by reference
+to subprograms.
+
+Arrays with static bounds are represented like a `C` array, whose
+length is the number of elements, and are passed by reference to subprograms.
+
+Unconstrained array are represented by a fat pointer. Do not use unconstrained
+arrays in foreign subprograms.
+
+Accesses to an unconstrained array is a fat pointer. Other accesses correspond to an address and are passed to a subprogram like other non-composite types.
+
+Files are represented by a 32 bits word, which corresponds to an index
+in a table.
+
+.. _Linking_with_foreign_object_files:
+
+Linking with foreign object files
+---------------------------------
+
+You may add additional files or options during the link using the
+*-Wl,* of `GHDL`, as described in :ref:`Elaboration_command`.
+For example::
+
+ ghdl -e -Wl,-lm math_tb
+
+will create the :file:`math_tb` executable with the :file:`lm` (mathematical)
+library.
+
+Note the :file:`c` library is always linked with an executable.
+
+.. _Starting_a_simulation_from_a_foreign_program:
+
+Starting a simulation from a foreign program
+--------------------------------------------
+
+You may run your design from an external program. You just have to call
+the :samp:`ghdl_main` function which can be defined:
+
+in C:
+
+.. code-block:: C
+
+ extern int ghdl_main (int argc, char **argv);
+
+in Ada:
+
+.. code-block:: Ada
+
+ with System;
+ ...
+ function Ghdl_Main (Argc : Integer; Argv : System.Address)
+ return Integer;
+ pragma import (C, Ghdl_Main, "ghdl_main");
+
+
+This function must be called once, and returns 0 at the end of the simulation.
+In case of failure, this function does not return. This has to be fixed.
+
+.. _Linking_with_Ada:
+
+Linking with Ada
+----------------
+
+As explained previously in :ref:`Starting_a_simulation_from_a_foreign_program`,
+you can start a simulation from an `Ada` program. However the build
+process is not trivial: you have to elaborate your `Ada` program and your
+`VHDL` design.
+
+First, you have to analyze all your design files. In this example, we
+suppose there is only one design file, :file:`design.vhdl`.
+
+::
+
+ $ ghdl -a design.vhdl
+
+Then, bind your design. In this example, we suppose the entity at the
+design apex is :samp:`design`.
+
+::
+
+ $ ghdl --bind design
+
+Finally, compile, bind your `Ada` program at link it with your `VHDL`
+design::
+
+ $ gnatmake my_prog -largs `ghdl --list-link design`
+
+
+Using GRT from Ada
+------------------
+
+.. warning::
+ This topic is only for advanced users knowing how to use `Ada`
+ and `GNAT`. This is provided only for reference, I have tested
+ this once before releasing `GHDL` 0.19 but this is not checked at
+ each release.
+
+The simulator kernel of `GHDL` named :dfn:`GRT` is written in
+`Ada95` and contains a very light and slightly adapted version
+of `VHPI`. Since it is an `Ada` implementation it is
+called :dfn:`AVHPI`. Although being tough, you may interface to `AVHPI`.
+
+For using `AVHPI`, you need the sources of `GHDL` and to recompile
+them (at least the `GRT` library). This library is usually compiled with
+a `No_Run_Time` pragma, so that the user does not need to install the
+`GNAT` runtime library. However, you certainly want to use the usual
+runtime library and want to avoid this pragma. For this, reset the
+`GRT_PRAGMA_FLAG` variable.
+
+::
+
+ $ make GRT_PRAGMA_FLAG= grt-all
+
+
+Since `GRT` is a self-contained library, you don't want
+`gnatlink` to fetch individual object files (furthermore this
+doesn't always work due to tricks used in `GRT`). For this,
+remove all the object files and make the :file:`.ali` files read-only.
+
+::
+
+ $ rm *.o
+ $ chmod -w *.ali
+
+
+You may then install the sources files and the :file:`.ali` files. I have never
+tested this step.
+
+You are now ready to use it.
+
+For example, here is an example, :file:`test_grt.adb` which displays the top
+level design name.
+
+.. code-block:: Ada
+
+ with System; use System;
+ with Grt.Avhpi; use Grt.Avhpi;
+ with Ada.Text_IO; use Ada.Text_IO;
+ with Ghdl_Main;
+
+ procedure Test_Grt is
+ -- VHPI handle.
+ H : VhpiHandleT;
+ Status : Integer;
+
+ -- Name.
+ Name : String (1 .. 64);
+ Name_Len : Integer;
+ begin
+ -- Elaborate and run the design.
+ Status := Ghdl_Main (0, Null_Address);
+
+ -- Display the status of the simulation.
+ Put_Line ("Status is " & Integer'Image (Status));
+
+ -- Get the root instance.
+ Get_Root_Inst(H);
+
+ -- Disp its name using vhpi API.
+ Vhpi_Get_Str (VhpiNameP, H, Name, Name_Len);
+ Put_Line ("Root instance name: " & Name (1 .. Name_Len));
+ end Test_Grt;
+
+
+First, analyze and bind your design::
+
+ $ ghdl -a counter.vhdl
+ $ ghdl --bind counter
+
+
+Then build the whole::
+
+ $ gnatmake test_grt -aL`grt_ali_path` -aI`grt_src_path` -largs
+ `ghdl --list-link counter`
+
+
+Finally, run your design::
+
+ $ ./test_grt
+ Status is 0
+ Root instance name: counter