diff options
author | 1138-4EB <1138-4EB@users.noreply.github.com> | 2019-11-11 18:46:36 +0000 |
---|---|---|
committer | tgingold <tgingold@users.noreply.github.com> | 2019-11-11 19:46:36 +0100 |
commit | 8599d9ddd15b15afdeced6059b1e1b7a972f4db1 (patch) | |
tree | 499b9c6fe0f85ce7ed221f72ac31036eefde0194 /doc/examples | |
parent | 22775978be88c5ea8e5b740734e42eeb2fef0968 (diff) | |
download | ghdl-8599d9ddd15b15afdeced6059b1e1b7a972f4db1.tar.gz ghdl-8599d9ddd15b15afdeced6059b1e1b7a972f4db1.tar.bz2 ghdl-8599d9ddd15b15afdeced6059b1e1b7a972f4db1.zip |
Update doc (#1003)
* doc: update makefile and build scripts
* actions: add workflow 'doc'
* doc: reorganize sections
* doc: fix 'unknown option' warnings, headings, spaces, etc.
* doc: add subdir 'examples', move 'quick_start' sources
* doc: add section 'Development/Debugging'
* doc: add section'Development/Synthesis'
* doc: update roadmap
* doc: add section examples
* doc: use standard domain
* doc: add comment about 'vhd' vs 'vhdl'
Diffstat (limited to 'doc/examples')
-rw-r--r-- | doc/examples/README.rst | 12 | ||||
-rw-r--r-- | doc/examples/VHPIDIRECT.rst | 18 | ||||
-rw-r--r-- | doc/examples/quick_start/DLXModelSuite.rst | 66 | ||||
-rw-r--r-- | doc/examples/quick_start/README.rst | 49 | ||||
-rw-r--r-- | doc/examples/quick_start/adder/README.rst | 35 | ||||
-rw-r--r-- | doc/examples/quick_start/adder/adder.vhdl | 14 | ||||
-rw-r--r-- | doc/examples/quick_start/adder/adder_tb.vhdl | 57 | ||||
-rw-r--r-- | doc/examples/quick_start/heartbeat/README.rst | 41 | ||||
-rw-r--r-- | doc/examples/quick_start/heartbeat/heartbeat.vhdl | 20 | ||||
-rw-r--r-- | doc/examples/quick_start/hello/README.rst | 52 | ||||
-rw-r--r-- | doc/examples/quick_start/hello/hello.vhdl | 17 |
11 files changed, 381 insertions, 0 deletions
diff --git a/doc/examples/README.rst b/doc/examples/README.rst new file mode 100644 index 000000000..921bcf2a3 --- /dev/null +++ b/doc/examples/README.rst @@ -0,0 +1,12 @@ +.. _USING:Examples: + +Examples +######## + +This sections contains advanced examples using specific features of the language, the tool, +or interaction with third-party projects. It is suggested for users who are new to either +`GHDL` or `VHDL` to read :ref:`USING:QuickStart` first. + +.. toctree:: + + ../examples/VHPIDIRECT diff --git a/doc/examples/VHPIDIRECT.rst b/doc/examples/VHPIDIRECT.rst new file mode 100644 index 000000000..f8eddf911 --- /dev/null +++ b/doc/examples/VHPIDIRECT.rst @@ -0,0 +1,18 @@ +.. _Examples:VHPIDIRECT: + +Data exchange through VHPIDIRECT +################################ + +VUnit +===== + +`VUnit <https://github.com/VUnit/vunit>`_ is an open source unit testing framework for VHDL/SystemVerilog. Sharing memory buffers between foreign C or Python applications and VHDL testbenches is supported through GHDL's VHPIDIRECT features. Buffers are accessed from VHDL as either strings, arrays of bytes or arrays of 32 bit integers. See VUnit example `external buffer <https://github.com/VUnit/vunit/tree/master/examples/vhdl/external_buffer>`_ for details about the API. + +ghdlex and netpp +================ + +`netpp (network property protocol) <https://section5.ch/index.php/netpp/>`_ is a communication library allowing to expose variables or other properties of an application to the network as abstract 'Properties'. Its basic philosophy is that a device always knows its capabilities. netpp capable devices can be explored by command line, Python scripts or GUI applications. Properties of a device - be it virtual or real - are typically described by a static description in an XML device description language, but they can also be constructed on the fly. + +`ghdlex <https://github.com/hackfin/ghdlex>`_ is a set of C extensions to facilitate data exchange between a GHDL simulation and external applications. VHPIDIRECT mechanisms are used to wrap GHDL data types into structures usable from a C library. `ghdlex` uses the `netpp <https://section5.ch/index.php/netpp/>`_ library to expose virtual entities (such as pins or RAM) to the network. It also demonstrates simple data I/O through unix pipes. A few VHDL example entities are provided, such as a virtual console, FIFOs, RAM. + +The author of `netpp` and `ghdlex` is also working on `MaSoCist <https://github.com/hackfin/MaSoCist>`_, a linux'ish build system for System on Chip designs, based on GHDL. It allows to handle more complex setup, e.g. how a RISC-V architecture (for example) is regress-tested using a virtual debug interface. diff --git a/doc/examples/quick_start/DLXModelSuite.rst b/doc/examples/quick_start/DLXModelSuite.rst new file mode 100644 index 000000000..0c8259cac --- /dev/null +++ b/doc/examples/quick_start/DLXModelSuite.rst @@ -0,0 +1,66 @@ +.. _QuickStart:DLX: + +Working with non-trivial designs +================================ + +Designs are usually more complex than the previous examples. Unless you are only studying VHDL, you will work with +larger designs. Let's see how to analyse a design such as the DLX model suite written by Peter Ashenden, which is +distributed under the terms of the GNU General Public License. A copy is kept at `ghdl.free.fr/dlx.tar.gz <http://ghdl.free.fr/dlx.tar.gz>`_ . + +- First, untar the sources: ``tar zxvf dlx.tar.gz``. + +.. HINT:: + + In order not to pollute the sources with the artifacts (`WORK` library), it is a good idea to create a + :file:`work/` subdirectory. To any GHDL commands, we will add the :option:`--workdir=work <--workdir>` option, so + that all files generated by the compiler (except the executable) will be placed in this directory. + + .. code-block:: shell + + $ cd dlx + $ mkdir work + +* Then, we will run the ``dlx_test_behaviour`` design. We need to analyse all the design units for the design + hierarchy, in the correct order. GHDL provides an easy way to do this, by :ref:`importing <Import:command>` the + sources: ``ghdl -i --workdir=work *.vhdl``. + +* GHDL knows all the design units of the DLX, but none of them has been analysed. Run the :ref:`make <Make:command>` + command, ``ghdl -m --workdir=work dlx_test_behaviour``, which analyses and elaborates a design. This creates many + files in the :file:`work/` directory, and (GCC/LLVM only) the :file:`dlx_test_behaviour` executable in the current + directory. + +.. HINT:: + + The simulation needs to have a DLX program contained in the file :file:`dlx.out`. This memory image will be loaded + in the DLX memory. Just take one sample: ``cp test_loop.out dlx.out``. + +* Now, you can :ref:`run <Run:command>` the test suite: ``ghdl -r --workdir=work dlx_test_behaviour``. The test bench + monitors the bus and displays each executed instruction. It finishes with an assertion of severity level note: + + .. code-block:: shell + + dlx-behaviour.vhdl:395:11:(assertion note): TRAP instruction + encountered, execution halted + +* Last, since the clock is still running, you have to manually stop the program with the :kbd:`C-c` key sequence. This + behavior prevents you from running the testbench in batch mode. However, you may force the simulator to stop when an + assertion above or equal a certain severity level occurs. To do so, call run with this option instead: + ``ghdl -r --workdir=work dlx_test_behaviour --assert-level=note```. With :option:`--assert-level`, the program stops + just after the previous message: + + .. code-block:: shell + + dlx-behaviour.vhdl:395:11:(assertion note): TRAP instruction + encountered, execution halted + error: assertion failed + +.. TIP:: If you want to make room on your hard drive, you can either: + + * :ref:`Clean <Clean:command>` the design library with ``ghdl --clean --workdir=work``. This removes the executable + and all the object files. If you want to rebuild the design at this point, just do the make command as shown above. + * :ref:`Remove <Remove:command>` the design library with ``ghdl --remove --workdir=work``. This removes the + executable, all the object files and the library file. If you want to rebuild the design, you have to import the + sources again and make the design. + * Remove the :file:`work/` directory: ``rm -rf work``. Only the executable is kept. If you want to rebuild the design, create the :file:`work/` directory, import the sources, and make the design. + +.. WARNING:: Sometimes, a design does not fully follow the VHDL standards. For example it might use the badly engineered ``std_logic_unsigned`` package. GHDL supports this VHDL dialect through some options: :option:`--ieee=synopsys <--ieee>`, :option:`-fexplicit`, etc. See section :ref:`IEEE_library_pitfalls`, for more details. diff --git a/doc/examples/quick_start/README.rst b/doc/examples/quick_start/README.rst new file mode 100644 index 000000000..6399996f5 --- /dev/null +++ b/doc/examples/quick_start/README.rst @@ -0,0 +1,49 @@ +.. _USING:QuickStart: + +Quick Start Guide +################# + +Since this is the user and reference manual for `GHDL`, it does not contain an +introduction to `VHDL`. Thus, the reader should have at least a basic knowledge +of `VHDL`. A good knowledge of `VHDL` language reference manual (usually called +LRM) is a plus. Nevertheless, multiple examples are provided, in the hope that +they are useful for users to learn about both `GHDL` and `VHDL`. For advanced +examples using specific features see :ref:`USING:Examples`. + +As explained in :ref:`INTRO:GHDL`, `GHDL` is a compiler which translates `VHDL` files to +machine code. Hence, the regular workflow is composed of three steps: + +* :ref:`Analysis:command`: convert design units (`VHDL` sources) to an internal representation. +* :ref:`Elaboration:command`: generate executable machine code for a target module (top-level entity). +* :ref:`Run:command`: execute the design to test the behaviour, generate output/waveforms, etc. + +The following tips might be useful: + +* Don't forget to select the version of the VHDL standard you want to use (see + :ref:`VHDL_standards`). The default is :option:`--std=93c <--std>`. Use :option:`--std=08 <--std>` for VHDL-2008 + (albeit not fully implemented). + + * Use :option:`--ieee=synopsys <--ieee>` if your design depends on a non-standard implementation of the IEEE library. + + * Use :option:`-fexplicit` and :option:`-frelaxed-rules` if needed. + +* Use :option:`--work=LIB_NAME <--work>` to analyze files into the ``LIB_NAME`` library. + To use files analyzed to a different directory, give the path + to the ``LIB_NAME`` library using :option:`-P/path/to/name/directory/ <-P<DIRECTORY>>`. + +* Use the same options for analysis and elaboration. E.g., first analyse with ``ghdl -a --std=08 --work=mylib myfile.vhdl``; + and then elaborate and run with ``ghdl --elab-run --std=08 top``. + +Due to the fact that `VHDL` is processed as a general purpose language +(instead of an `HDL`), all the language features are to be supported. I.e., `VHDL` +sources do not need to be limited to the synthesisable subset. However, distinction +between synthesisable and non-synthesisable (simulation-only) subsets is often misleading +for users who are new to the language. Different examples are provided, +in the hope of helping understand the different use cases: + +.. toctree:: + + hello/README + heartbeat/README + adder/README + DLXModelSuite diff --git a/doc/examples/quick_start/adder/README.rst b/doc/examples/quick_start/adder/README.rst new file mode 100644 index 000000000..6a0bcea91 --- /dev/null +++ b/doc/examples/quick_start/adder/README.rst @@ -0,0 +1,35 @@ +.. _QuickStart:adder: + +`Full adder` module and testbench +================================= + +Unlike :ref:`Heartbeat <QuickStart:heartbeat>`, the target hardware design in this example is written using the +synthesisable subset of `VHDL`. It is a `full adder <https://en.wikipedia.org/wiki/Adder_(electronics)#Full_adder>`_ +described in a file named :file:`adder.vhdl`: + +.. literalinclude:: adder.vhdl + :language: vhdl + +You can :ref:`analyse <Analysis:command>` this design file, ``ghdl -a adder.vhdl``, and try to execute the `adder` +design. But this is useless, since nothing externally visible will happen. In order to check this full adder, a +:dfn:`testbench` has to be run. The :dfn:`testbench` is a description of how to generate inputs and how to check the +outputs of the Unit Under Test (UUT). This one is very simple, since the adder is also simple: it checks exhaustively +all inputs. Note that only the behaviour is tested, timing constraints are not checked. A file named +:file:`adder_tb.vhdl` contains the testbench for the adder: + +.. literalinclude:: adder_tb.vhdl + :language: vhdl + +As usual, you should analyze the file, ``ghdl -a adder_tb.vhdl``. + +.. HINT:: + Then, if required, :ref:`elaborate <Elaboration:command>` the testbench: ``ghdl -e adder_tb``. You do not need to + specify which object files are required, since `GHDL` knows them and automatically adds them. + +Now, it is time to :ref:`run <Run:command>` the testbench, ``ghdl -r adder_tb``, and check the result on screen:: + + adder_tb.vhdl:52:7:(assertion note): end of test + +If your design is rather complex, you'd like to inspect signals as explained in :ref:`Heartbeat <QuickStart:heartbeat>`. + +See section :ref:`simulation_options`, for more details on other runtime options. diff --git a/doc/examples/quick_start/adder/adder.vhdl b/doc/examples/quick_start/adder/adder.vhdl new file mode 100644 index 000000000..cf60e8fbe --- /dev/null +++ b/doc/examples/quick_start/adder/adder.vhdl @@ -0,0 +1,14 @@ +entity adder is + -- `i0`, `i1`, and the carry-in `ci` are inputs of the adder. + -- `s` is the sum output, `co` is the carry-out. + port (i0, i1 : in bit; ci : in bit; s : out bit; co : out bit); +end adder; + +architecture rtl of adder is +begin + -- This full-adder architecture contains two concurrent assignments. + -- Compute the sum. + s <= i0 xor i1 xor ci; + -- Compute the carry. + co <= (i0 and i1) or (i0 and ci) or (i1 and ci); +end rtl; diff --git a/doc/examples/quick_start/adder/adder_tb.vhdl b/doc/examples/quick_start/adder/adder_tb.vhdl new file mode 100644 index 000000000..4a3fca5e4 --- /dev/null +++ b/doc/examples/quick_start/adder/adder_tb.vhdl @@ -0,0 +1,57 @@ +-- A testbench has no ports. +entity adder_tb is +end adder_tb; + +architecture behav of adder_tb is + -- Declaration of the component that will be instantiated. + component adder + port (i0, i1 : in bit; ci : in bit; s : out bit; co : out bit); + end component; + + -- Specifies which entity is bound with the component. + for adder_0: adder use entity work.adder; + signal i0, i1, ci, s, co : bit; +begin + -- Component instantiation. + adder_0: adder port map (i0 => i0, i1 => i1, ci => ci, s => s, co => co); + + -- This process does the real job. + process + type pattern_type is record + -- The inputs of the adder. + i0, i1, ci : bit; + -- The expected outputs of the adder. + s, co : bit; + end record; + -- The patterns to apply. + type pattern_array is array (natural range <>) of pattern_type; + constant patterns : pattern_array := + (('0', '0', '0', '0', '0'), + ('0', '0', '1', '1', '0'), + ('0', '1', '0', '1', '0'), + ('0', '1', '1', '0', '1'), + ('1', '0', '0', '1', '0'), + ('1', '0', '1', '0', '1'), + ('1', '1', '0', '0', '1'), + ('1', '1', '1', '1', '1')); + begin + -- Check each pattern. + for i in patterns'range loop + -- Set the inputs. + i0 <= patterns(i).i0; + i1 <= patterns(i).i1; + ci <= patterns(i).ci; + -- Wait for the results. + wait for 1 ns; + -- Check the outputs. + assert s = patterns(i).s + report "bad sum value" severity error; + assert co = patterns(i).co + report "bad carry out value" severity error; + end loop; + assert false report "end of test" severity note; + -- Wait forever; this will finish the simulation. + wait; + end process; + +end behav; diff --git a/doc/examples/quick_start/heartbeat/README.rst b/doc/examples/quick_start/heartbeat/README.rst new file mode 100644 index 000000000..55f1e20c7 --- /dev/null +++ b/doc/examples/quick_start/heartbeat/README.rst @@ -0,0 +1,41 @@ +.. _QuickStart:heartbeat: + +`Heartbeat` module +================== + +Although :ref:`Hello world <QuickStart:hello>` illustrates that `VHDL` is supported as a general purpose language, the main use case +of `GHDL` is to simulate hardware descriptions. The following block, which is saved in a file named +:file:`heartbeat.vhdl`, is an example of how to generate a 100 MHz clock signal with non-synthesisable VHDL: + +.. literalinclude:: heartbeat.vhdl + :language: vhdl + +It can be :ref:`analysed <Analysis:command>`, :ref:`elaborated <Elaboration:command>` and :ref:`run <Run:command>`, as you already know: + +.. code-block:: shell + + ghdl -a heartbeat.vhdl + ghdl -e heartbeat + ghdl -r heartbeat + +However, execution of the design does not terminate. At the same time, no output is shown on screen. This is because, +traditionally, hardware designs are continuously running devices which do not have a screen where to print. In this +context, inspection and verification of the behaviour is done through `waveforms <https://en.wikipedia.org/wiki/Waveform_viewer>`_, +which is supported by `GHDL` (see :ref:`export_waves`). You can use either :option:`--wave`, :option:`--vcd`, +:option:`--vcdgz` or :option:`--fst` to save the signals of the simulation to a file. Then, terminate the execution +(:kbd:`C-c`) and you can inspect the wave with a viewer, such as `GtkWave <http://gtkwave.sourceforge.net/>`_. As +explained in the `manual <http://gtkwave.sourceforge.net/gtkwave.pdf>`_, GtkWave *'relies on a post-mortem approach +through the use of dumpfiles'*. Therefore, you should first simulate your design and dump a waveform file, say GHW: + +.. code-block:: shell + + ghdl -r --wave=wave.ghw heartbeat + +Then, you can view the dump: + +.. code-block:: shell + + gtkwave wave.ghw + +Of course, manually terminating the simulation is for illustration purposes only. In :ref:`Full adder <QuickStart:adder>` and +:ref:`QuickStart:DLX`, you will see how to write a testbench to terminate the simulation programmatically. diff --git a/doc/examples/quick_start/heartbeat/heartbeat.vhdl b/doc/examples/quick_start/heartbeat/heartbeat.vhdl new file mode 100644 index 000000000..0a312641e --- /dev/null +++ b/doc/examples/quick_start/heartbeat/heartbeat.vhdl @@ -0,0 +1,20 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity heartbeat is + port ( clk: out std_logic); +end heartbeat; + +architecture behaviour of heartbeat +is + constant clk_period : time := 10 ns; +begin + -- Clock process definition + clk_process: process + begin + clk <= '0'; + wait for clk_period/2; + clk <= '1'; + wait for clk_period/2; + end process; +end behaviour; diff --git a/doc/examples/quick_start/hello/README.rst b/doc/examples/quick_start/hello/README.rst new file mode 100644 index 000000000..85d07d2b9 --- /dev/null +++ b/doc/examples/quick_start/hello/README.rst @@ -0,0 +1,52 @@ +.. _QuickStart:hello: + +`Hello world` program +===================== + +To illustrate the general purpose of `VHDL`, the following block is a commented `Hello world` program which is saved in +a file named :file:`hello.vhdl`: + +.. literalinclude:: hello.vhdl + :language: vhdl + +.. TIP:: + + * Both ``.vhdl`` and ``.vhd`` extensions are used for `VHDL` source files, while ``.v`` is used for Verilog. + + * Since, extension ``.vhd`` is also interpreted as a `Virtual Hard Disk <https://en.wikipedia.org/wiki/VHD_(file_format)>`_ + file format, some users prefer ``.vhdl``, to avoid ambiguity. This is the case with `GHDL`'s codebase. However, in order + to maintain `backward-compatibility <https://en.wikipedia.org/wiki/8.3_filename>`_ with legacy DOS systems, + other users prefer ``.vhd``. + + * Unless you use especial characters, either `UTF-8` or `ISO-8859-1` encodings can be used. However, if you do, the + latter should be used. The standard defines ASCII (7-bit encoding) or ISO Latin-1 (ISO-8859-1) as default. + However, GHDL has a relaxing option, :option:`--mb-comments` (multi byte), to allow UTF-8 or other encodings in + comments. + +- First, you have to compile the file; this is called :ref:`analysis <Analysis:command>` of a design file in `VHDL` + terms. Run ``ghdl -a hello.vhdl`` in the `shell`. This command creates or updates a file :file:`work-obj93.cf`, which + describes the library ``work``. +- Then, run ``ghdl -e hello_world`` in the `shell`. Command :option:`-e` means :ref:`elaborate <Elaboration:command>`, + which is used to build a design, with the ``hello_world`` entity at the top of the hierarchy. +- Last, you can directly launch the simulation :ref:`running <Run:command>` ``ghdl -r hello_world`` in the `shell`. The + result of the simulation will be shown on screen: + +.. code-block:: shell + + Hello world! + +.. HINT:: + If a GCC/LLVM variant of `GHDL` is used: + + * :ref:`Analysis <Analysis:command>` generates a file, :file:`hello.o`, which is the object file corresponding to + your `VHDL` program. This is not created with :ref:`mcode <BUILD>`. These kind of object files can be + compiled into foreign programs (see :ref:`Linking_with_Ada`). + * The :ref:`elaboration <Elaboration:command>` step is mandatory after running the analysis and prior to launching the + simulation. This will generate an executable binary named :file:`hello_world`. + * As a result, :option:`-r` is just a passthrough to the binary generated in the `elaboration`. Therefore, the + executable can be run directly: ``./hello_world``. See :option:`-r` for more informartion. + +.. HINT:: + + :option:`-e` can be bypassed with :ref:`mcode <BUILD>`, since :option:`-r` actually elaborates the design and saves + it on memory before running the simulation. But you can still use it to check for some elaboration problems. diff --git a/doc/examples/quick_start/hello/hello.vhdl b/doc/examples/quick_start/hello/hello.vhdl new file mode 100644 index 000000000..4d969c6a8 --- /dev/null +++ b/doc/examples/quick_start/hello/hello.vhdl @@ -0,0 +1,17 @@ +-- Hello world program +use std.textio.all; -- Imports the standard textio package. + +-- Defines a design entity, without any ports. +entity hello_world is +end hello_world; + +architecture behaviour of hello_world is +begin + process + variable l : line; + begin + write (l, String'("Hello world!")); + writeline (output, l); + wait; + end process; +end behaviour; |