|
1 | 1 | Basic usage |
2 | 2 | =========== |
3 | 3 |
|
4 | | -.. ATTENTION:: |
| 4 | +Project Configuration |
| 5 | +--------------------- |
5 | 6 |
|
6 | | - (2024-08-08) To be updated. |
| 7 | +The first steps involve importing the necessary module to support the desired tool and instantiating the corresponding *class*: |
7 | 8 |
|
8 | | -Project Creation |
9 | | ----------------- |
| 9 | +.. code-block:: python |
| 10 | +
|
| 11 | + from pyfpga.vivado import Vivado |
| 12 | +
|
| 13 | + prj = Vivado('PRJNAME', odir='OUTDIR') |
10 | 14 |
|
11 | | -The first steps are import the module and instantiate the ``Project`` *class*, |
12 | | -specifying the *TOOL* to use and, optionally, a *PROJECT NAME* (the *tool* |
13 | | -name is used when *no name* is provided). |
| 15 | +In the example, we are using Vivado, specifying the optional parameter *project name* (*tool name* if omitted) and *output directory* (*results* by default). |
| 16 | + |
| 17 | +Next step is to specify the target FPGA device: |
14 | 18 |
|
15 | 19 | .. code-block:: python |
16 | 20 |
|
17 | | - from fpga.project import Project |
| 21 | + prj.set_part('xc7k160t-3-fbg484') |
| 22 | +
|
| 23 | +.. note:: |
18 | 24 |
|
19 | | - prj = Project('vivado', 'projectName') |
| 25 | + Default parts are provided for each supported tool. |
20 | 26 |
|
21 | | -By default, the directory where the project is generated is called ``build`` |
22 | | -and is located in the same place that the script, but another name and location |
23 | | -can be specified. |
| 27 | +HDL source files are added using one of the following methods: |
24 | 28 |
|
25 | 29 | .. code-block:: python |
26 | 30 |
|
27 | | - prj.set_outdir('../temp') |
| 31 | + prj.add_vhdl('PATH_TO_FILES_GLOB_COMPATIBLE', 'OPTIONAL_LIBNAME') |
| 32 | + prj.add_vlog('PATH_TO_FILES_GLOB_COMPATIBLE') |
| 33 | + prj.add_slog('PATH_TO_FILES_GLOB_COMPATIBLE') |
28 | 34 |
|
29 | | -Next, the FPGA part would be specified: |
| 35 | +In these methods, you provide a path to the files. The path can include wildcards (like `*.vhdl`), allowing you to match multiple files at once. |
30 | 36 |
|
31 | | -.. code-block:: python |
| 37 | +For `add_vhdl`, you can also optionally specify a library name where the files will be included. |
32 | 38 |
|
33 | | - prj.set_part('xc7k160t-3-fbg484') |
| 39 | +.. note:: |
| 40 | + |
| 41 | + Internally, the methods that specify files use `glob`_ to support wildcards and `Path`_ to obtain absolute paths. |
34 | 42 |
|
35 | | -.. NOTE:: |
| 43 | + .. _glob: https://docs.python.org/3/library/glob.html |
| 44 | + .. _Path: https://docs.python.org/3/library/pathlib.html |
36 | 45 |
|
37 | | - You can use the default FPGA part for a quick test or make a lazy comparison |
38 | | - between tools, but generally, you will want to specify a particular one. |
39 | | - Examples about how to specify a part according the tool, are (default values |
40 | | - when ``set_part`` is not employed): |
| 46 | +Generics/parameters can be specified with: |
| 47 | + |
| 48 | +.. code-block:: python |
41 | 49 |
|
42 | | - * **Ise:** ``xc7k160t-3-fbg484`` (*device-speed-package*) |
43 | | - * **Libero:** ``mpf100t-1-fcg484`` (*device-speed-package*) |
44 | | - * **Openflow:** ``hx8k-ct256`` (*device-package*) |
45 | | - * **Quartus:** ``10cl120zf780i8g`` (*part*) |
46 | | - * **Vivado:** ``xc7k160t-3-fbg484`` (*part*) |
| 50 | + prj.add_param('PARAMNAME', 'PARAMVALUE') |
47 | 51 |
|
48 | | -The files addition method allows specifying one or more HDL or constraint files |
49 | | -(also block designs in case of Vivado). |
50 | | -It uses ``glob`` internally, which makes available the use of wildcards. |
51 | | -The path to their location must be relative to the Python script, and there |
52 | | -are optional parameters to indicate the file type (``vhdl``, ``verilog``, |
53 | | -``constraint`` or ``design``), which is automatically detected based on the |
54 | | -file extension, and if it is a member of a VHDL package. |
| 52 | +For Verilog and SystemVerilog, the following methods are also available: |
55 | 53 |
|
56 | 54 | .. code-block:: python |
57 | 55 |
|
58 | | - prj.add_files('hdl/blinking.vhdl', library='examples') |
59 | | - prj.add_files('hdl/examples_pkg.vhdl', library='examples') |
60 | | - prj.add_files('hdl/top.vhdl') |
| 56 | + prj.add_include('PATH_TO_A_DIRECTORY') |
| 57 | + prj.add_define('DEFNAME', 'DEFVALUE') |
61 | 58 |
|
62 | | -.. NOTE:: |
| 59 | +Constraint source files are included using the following: |
63 | 60 |
|
64 | | - * In some cases, the files order could be a problem, so take into account to |
65 | | - change the order if needed. |
66 | | - * If a file seems unsupported, you can always use the ``prefile`` or |
67 | | - ``project`` :ref:`hooks`. |
68 | | - * In case of Verilog, ``add_vlog_include`` can be used to specify where to |
69 | | - search for included files. |
| 61 | +.. code-block:: python |
| 62 | +
|
| 63 | + prj.add_cons('PATH_TO_FILES_GLOB_COMPATIBLE') |
70 | 64 |
|
71 | | -Finally, the top-level must be specified: |
| 65 | +Finally, the top-level can be specified as follows: |
72 | 66 |
|
73 | 67 | .. code-block:: python |
74 | 68 |
|
75 | 69 | prj.set_top('Top') |
76 | 70 |
|
77 | | -.. NOTE:: |
| 71 | +.. note:: |
78 | 72 |
|
79 | | - A relative path to a valid VHDL/Verilog file is also accepted by ``set_top``, |
80 | | - to automatically extract the top-level name. |
| 73 | + The order of the methods described in this section is not significant. |
| 74 | + They will be arranged in the required order by the underlying template. |
81 | 75 |
|
82 | | -Project generation |
83 | | ------------------- |
| 76 | +Bitstream generation |
| 77 | +-------------------- |
84 | 78 |
|
85 | | -Next step if to generate the project. In the most basic form, you can run the |
86 | | -following to get a bitstream: |
| 79 | +After configuring the project, you can run the following to generate a bitstream: |
87 | 80 |
|
88 | 81 | .. code-block:: python |
89 | 82 |
|
90 | | - prj.generate() |
| 83 | + prj.make() |
91 | 84 |
|
92 | | -Additionally, you can specify which task to perform: |
| 85 | +By default, this method performs *project creation*, *synthesis*, *place and route*, and *bitstream generation*. |
| 86 | +However, you can optionally specify both the initial and final stages, as follows: |
93 | 87 |
|
94 | 88 | .. code-block:: python |
95 | 89 |
|
96 | | - prj.generate('syn') |
97 | | -
|
98 | | -.. NOTE:: |
99 | | - |
100 | | - The valid values are: |
| 90 | + prj.make(first='syn', last='par') |
101 | 91 |
|
102 | | - * ``prj``: to generate only a project file (only supported for privative tools) |
103 | | - * ``syn``: to performs synthesis. |
104 | | - * ``imp``: to performs synthesis and implementation (place and route, |
105 | | - optimizations and static timming analysis when available). |
106 | | - * ``bit``: (default) to perform synthesis, implementation and bitstream generation. |
| 92 | +.. note:: |
107 | 93 |
|
108 | | -Bitstream transfer |
109 | | ------------------- |
| 94 | + Valid values are: |
110 | 95 |
|
111 | | -This method is in charge of run the needed tool to transfer a bitstream to a |
112 | | -device (commonly an FPGA, but memories are also supported in some cases). |
113 | | -It has up to four main optional parameters: |
| 96 | + * ``cfg``: generates the project file |
| 97 | + * ``syn``: performs synthesis |
| 98 | + * ``par``: performs place and route |
| 99 | + * ``bit``: performs bitstream generation |
114 | 100 |
|
115 | | -.. code-block:: python |
| 101 | +.. note:: |
116 | 102 |
|
117 | | - prj.transfer(devtype, position, part, width) |
| 103 | + After executing this method, you will find the file `<TOOL>.tcl` (or `sh` in some cases) in the output directory. |
| 104 | + For debugging purposes, if things do not work as expected, you can review this file. |
118 | 105 |
|
119 | | -Where *devtype* is ``fpga`` by default but can also be ``spi``, ``bpi``, etc, if |
120 | | -supported. An integer number can be used to specify the *position* (1) in the |
121 | | -Jtag chain. When a memory is used as *devtype*, the *part* name and the |
122 | | -*width* in bits must be also specified. |
| 106 | +Bitstream programming |
| 107 | +--------------------- |
123 | 108 |
|
124 | | -.. NOTE:: |
| 109 | +The final step is programming the FPGA: |
125 | 110 |
|
126 | | - * In Xilinx, `spi` and `bpi` memories are out of the Jtag chain and are |
127 | | - programmed through the FPGA. You must specify the FPGA *position*. |
128 | | - * In a Linux systems, you need to have permission over the device |
129 | | - (udev rule, be a part of a group, etc). |
| 111 | +.. code-block:: python |
130 | 112 |
|
131 | | -Logging capabilities |
132 | | --------------------- |
| 113 | + prj.prog('BITSTREAM', 'POSITION') |
133 | 114 |
|
134 | | -PyFPGA uses the `logging <https://docs.python.org/3/library/logging.html>`_ |
135 | | -module, with a *NULL* handler and the *INFO* level by default. |
136 | | -Messages can be enabled with: |
| 115 | +Both `BITSTREAM` and `POSITION` are optional. |
| 116 | +If `BITSTREAM` is not specified, PyFPGA will attempt to discover it based on project information. |
| 117 | +The `POSITION` parameter is not always required (depends on the tool being used). |
137 | 118 |
|
138 | | -.. code-block:: python |
| 119 | +.. note:: |
139 | 120 |
|
140 | | - import logging |
| 121 | + After executing this method, you will find the file `<TOOL>prog.tcl` (or `sh` in some cases) in the output directory. |
| 122 | + For debugging purposes, if things do not work as expected, you can review this file. |
141 | 123 |
|
142 | | - logging.basicConfig() |
| 124 | +Debugging |
| 125 | +--------- |
143 | 126 |
|
144 | | -You can enable *DEBUG* messages adding: |
| 127 | +Under the hood, `logging`_ is employed. To enable debug messages, you can use: |
145 | 128 |
|
146 | 129 | .. code-block:: python |
147 | 130 |
|
148 | | - logging.getLogger('fpga.project').level = logging.DEBUG |
| 131 | + prj.set_debug() |
| 132 | +
|
| 133 | +.. _logging: https://docs.python.org/3/library/logging.html |
0 commit comments