Skip to content

Commit 5aecfde

Browse files
authored
Merge pull request #53 from PyFPGA/openflow-vhdl
Openflow: re-add VHDL support
2 parents 7851b97 + aa29487 commit 5aecfde

File tree

5 files changed

+50
-21
lines changed

5 files changed

+50
-21
lines changed

docs/basic.rst

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@ Basic usage
44
Project Configuration
55
---------------------
66

7-
The first steps involve importing the necessary module to support the desired tool and instantiating the corresponding *class*:
7+
The first steps involve importing the necessary module to support the desired tool and instantiating the corresponding ``class``:
88

99
.. code-block:: python
1010
1111
from pyfpga.vivado import Vivado
1212
1313
prj = Vivado('PRJNAME', odir='OUTDIR')
1414
15-
In the example, we are using Vivado, specifying the optional parameter *project name* (*tool name* if omitted) and *output directory* (*results* by default).
15+
In the example, we are using Vivado, specifying the optional parameters
16+
``project name`` (``tool name`` if omitted) and ``output directory``
17+
(``results`` by default).
1618

1719
Next step is to specify the target FPGA device:
1820

@@ -32,9 +34,8 @@ HDL source files are added using one of the following methods:
3234
prj.add_vlog('PATH_TO_FILES_GLOB_COMPATIBLE')
3335
prj.add_slog('PATH_TO_FILES_GLOB_COMPATIBLE')
3436
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.
36-
37-
For `add_vhdl`, you can also optionally specify a library name where the files will be included.
37+
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.
38+
In case of ``add_vhdl``, you can also optionally specify a library name where the files will be included.
3839

3940
.. note::
4041

@@ -43,6 +44,15 @@ For `add_vhdl`, you can also optionally specify a library name where the files w
4344
.. _glob: https://docs.python.org/3/library/glob.html
4445
.. _Path: https://docs.python.org/3/library/pathlib.html
4546

47+
.. hint::
48+
49+
Files are processed in the order they are added. If a file is specified more than once,
50+
it is removed from its previous position and placed at the end of the list.
51+
This allows you to ensure that a file is processed after others when necessary
52+
(e.g., placing a top-level at the end) or to customize options
53+
(e.g., removing a VHDL library specification in case of a top-level)
54+
when multiple files are added using a wildcard.
55+
4656
Generics/parameters can be specified with:
4757

4858
.. code-block:: python
@@ -82,7 +92,8 @@ After configuring the project, you can run the following to generate a bitstream
8292
8393
prj.make()
8494
85-
By default, this method performs *project creation*, *synthesis*, *place and route*, and *bitstream generation*.
95+
By default, this method performs **project creation**, **synthesis**, **place and route**,
96+
and **bitstream generation**.
8697
However, you can optionally specify both the initial and final stages, as follows:
8798

8899
.. code-block:: python
@@ -100,7 +111,8 @@ However, you can optionally specify both the initial and final stages, as follow
100111

101112
.. note::
102113

103-
After executing this method, you will find the file `<TOOL>.tcl` (or `sh` in some cases) in the output directory.
114+
After executing this method, you will find the file ``<TOOL>.tcl``
115+
(``<TOOL>.sh`` in some cases) in the output directory.
104116
For debugging purposes, if things do not work as expected, you can review this file.
105117

106118
Bitstream programming
@@ -112,13 +124,14 @@ The final step is programming the FPGA:
112124
113125
prj.prog('BITSTREAM', 'POSITION')
114126
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).
127+
Both ``BITSTREAM`` and ``POSITION`` are optional.
128+
If ``BITSTREAM`` is not specified, PyFPGA will attempt to discover it based on project information.
129+
The ``POSITION`` parameter is not always required (depends on the tool being used).
118130

119131
.. note::
120132

121-
After executing this method, you will find the file `<TOOL>prog.tcl` (or `sh` in some cases) in the output directory.
133+
After executing this method, you will find the file ``<TOOL>prog.tcl``
134+
(``<TOOL>-prog.sh`` in some cases) in the output directory.
122135
For debugging purposes, if things do not work as expected, you can review this file.
123136

124137
Debugging

docs/extending.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Extending
33

44
.. note::
55

6-
All <TOOL> classes inherit from project.py.
6+
All <TOOL> classes inherit from ``Project`` (``project.py``).
77

88
This is a guide on how to add support for a new TOOL.
99

examples/projects/regress.sh

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ for TOOL in "${!TOOLS[@]}"; do
2525
if [[ "$TOOL" == "ise" && "$SOURCE" == "slog" ]]; then
2626
continue
2727
fi
28-
if [[ "$TOOL" == "openflow" && "$SOURCE" == "vhdl" ]]; then
29-
continue
30-
fi
3128
echo "> $TOOL - $BOARD - $SOURCE"
3229
python3 $TOOL.py --board $BOARD --source $SOURCE
3330
done

pyfpga/project.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,15 @@ def _add_file(self, pathname, hdl=None, lib=None):
8383
if len(files) == 0:
8484
raise FileNotFoundError(pathname)
8585
for file in files:
86-
path = Path(file).resolve()
86+
path = Path(file).resolve().as_posix()
8787
attr = {}
8888
if hdl:
8989
attr['hdl'] = hdl
9090
if lib:
9191
attr['lib'] = lib
92-
self.data.setdefault('files', {})[path.as_posix()] = attr
92+
if path in self.data.get('files', {}):
93+
del self.data['files'][path]
94+
self.data.setdefault('files', {})[path] = attr
9395

9496
def add_slog(self, pathname):
9597
"""Add System Verilog file/s.

pyfpga/templates/openflow.jinja

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ DOCKER="docker run --user $(id -u):$(id -g) --rm -v $HOME:$HOME -w $PWD"
1313
{% if 'syn' in steps %}# Synthesis
1414
$DOCKER hdlc/ghdl:yosys /bin/bash -c "
1515
{% if hooks %}{{ hooks.presyn | join('\n') }}{% endif %}
16+
17+
{% set gflags = '--std=08 -fsynopsys -fexplicit -frelaxed' %}
18+
{% if files %}# VHDL Files inclusion
19+
{% for name, attr in files.items() %}
20+
{% if attr.hdl == "vhdl" %}
21+
ghdl -a {{ gflags }}{% if 'lib' in attr %} --work={{ attr.lib }}{% endif %} {{ name }}
22+
{% endif %}
23+
{% endfor %}
24+
{% endif %}
25+
1626
yosys -Q -m ghdl -p '
1727

1828
{% if includes %}# Verilog Includes
@@ -23,19 +33,26 @@ verilog_defaults -add{% for path in includes %} -I{{ path }}{% endfor %}
2333
verilog_defines{% for key, value in defines.items() %} -D{{ key }}={{ value }}{% endfor %}
2434
{% endif %}
2535

26-
{% if files %}# Files inclusion
36+
{% if files %}# VLOG Files inclusion
2737
{% for name, attr in files.items() %}
2838
{% if attr.hdl == "vlog" %}
2939
read_verilog -defer {{ name }}
3040
{% elif attr.hdl == "slog" %}
3141
read_verilog -defer -sv {{ name }}
42+
{% elif attr.hdl == "vhdl" %}
43+
{% if loop.first %}
44+
{% if params %}# VHDL Generics
45+
ghdl {{ gflags }}{% for key, value in params.items() %} -g{{ key }}={{ value }}{% endfor %} {{ top }}
46+
{% else %}
47+
ghdl {{ gflags }} {{ top }}
3248
{% endif %}
33-
{% endfor %}
3449
{% endif %}
35-
36-
{% if params %}# Verilog Parameters / VHDL Generics
50+
{% endif %}
51+
{% if loop.last and attr.hdl in ["vlog", "slog"] and params %}# Verilog Parameters
3752
chparam{% for key, value in params.items() %} -set {{ key }} {{ value }}{% endfor %}
3853
{% endif %}
54+
{% endfor %}
55+
{% endif %}
3956

4057
# Top-level specification and Syntesis
4158
{% if family in ['ice40', 'ecp5'] %}

0 commit comments

Comments
 (0)