diff options
author | umarcor <unai.martinezcorral@ehu.eus> | 2020-05-08 11:17:36 +0200 |
---|---|---|
committer | tgingold <tgingold@users.noreply.github.com> | 2020-05-08 17:40:30 +0200 |
commit | 763e2444798682f39e1e43397b549629372b47d8 (patch) | |
tree | 70c2874844735df13a320eeb0511e42ebda6c681 /doc/quick_start | |
parent | 203564db51bb4db5b9009f122ac4823d6c499e9c (diff) | |
download | ghdl-763e2444798682f39e1e43397b549629372b47d8.tar.gz ghdl-763e2444798682f39e1e43397b549629372b47d8.tar.bz2 ghdl-763e2444798682f39e1e43397b549629372b47d8.zip |
doc: move 'examples/quick_start' to 'quick_start'
Diffstat (limited to 'doc/quick_start')
-rw-r--r-- | doc/quick_start/DLXModelSuite.rst | 67 | ||||
-rw-r--r-- | doc/quick_start/README.rst | 49 | ||||
-rw-r--r-- | doc/quick_start/adder/README.rst | 36 | ||||
-rw-r--r-- | doc/quick_start/adder/adder.vhdl | 14 | ||||
-rw-r--r-- | doc/quick_start/adder/adder_tb.vhdl | 57 | ||||
-rw-r--r-- | doc/quick_start/heartbeat/README.rst | 42 | ||||
-rw-r--r-- | doc/quick_start/heartbeat/heartbeat.vhdl | 20 | ||||
-rw-r--r-- | doc/quick_start/hello/README.rst | 53 | ||||
-rw-r--r-- | doc/quick_start/hello/hello.vhdl | 17 |
9 files changed, 355 insertions, 0 deletions
diff --git a/doc/quick_start/DLXModelSuite.rst b/doc/quick_start/DLXModelSuite.rst new file mode 100644 index 000000000..0cdc8be86 --- /dev/null +++ b/doc/quick_start/DLXModelSuite.rst @@ -0,0 +1,67 @@ +.. program:: ghdl +.. _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/quick_start/README.rst b/doc/quick_start/README.rst new file mode 100644 index 000000000..d599ba631 --- /dev/null +++ b/doc/quick_start/README.rst @@ -0,0 +1,49 @@ +.. program:: ghdl +.. _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`. + +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. For instance when relaxing VHDL 2008's need for shared variables to be protected types, you can use ``--std=08 -frelaxed-rules``. + +* 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/quick_start/adder/README.rst b/doc/quick_start/adder/README.rst new file mode 100644 index 000000000..5ff607801 --- /dev/null +++ b/doc/quick_start/adder/README.rst @@ -0,0 +1,36 @@ +.. program:: ghdl +.. _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/quick_start/adder/adder.vhdl b/doc/quick_start/adder/adder.vhdl new file mode 100644 index 000000000..cf60e8fbe --- /dev/null +++ b/doc/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/quick_start/adder/adder_tb.vhdl b/doc/quick_start/adder/adder_tb.vhdl new file mode 100644 index 000000000..4a3fca5e4 --- /dev/null +++ b/doc/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/quick_start/heartbeat/README.rst b/doc/quick_start/heartbeat/README.rst new file mode 100644 index 000000000..e95145095 --- /dev/null +++ b/doc/quick_start/heartbeat/README.rst @@ -0,0 +1,42 @@ +.. program:: ghdl +.. _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 heartbeat --wave=wave.ghw + +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/quick_start/heartbeat/heartbeat.vhdl b/doc/quick_start/heartbeat/heartbeat.vhdl new file mode 100644 index 000000000..0a312641e --- /dev/null +++ b/doc/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/quick_start/hello/README.rst b/doc/quick_start/hello/README.rst new file mode 100644 index 000000000..104a12efa --- /dev/null +++ b/doc/quick_start/hello/README.rst @@ -0,0 +1,53 @@ +.. program:: ghdl +.. _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/quick_start/hello/hello.vhdl b/doc/quick_start/hello/hello.vhdl new file mode 100644 index 000000000..4d969c6a8 --- /dev/null +++ b/doc/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; |