docs: Initial Sphinx setup

Signed-off-by: Filip Kokosinski <fkokosinski@antmicro.com>
This commit is contained in:
Filip Kokosinski 2020-12-08 13:11:13 +01:00 committed by Robert Winkler
parent 9c697e24d1
commit 2ddee57006
22 changed files with 698 additions and 0 deletions

3
docs/.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
*.png binary
*.gif binary
*.jpg binary

1
docs/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
_build

20
docs/Makefile Normal file
View File

@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View File

@ -0,0 +1,82 @@
Building example designs
========================
Before building any example, set the installation directory to match what you
set it to earlier, for example:
.. code-block:: bash
:name: export-install-dir
export INSTALL_DIR=~/opt/symbiflow
Select your fpga family:
.. tabs::
.. group-tab:: Artix-7
.. code-block:: bash
:name: fpga-fam-xc7
FPGA_FAM="xc7"
.. group-tab:: EOS S3
.. code-block:: bash
:name: fpga-fam-eos-s3
FPGA_FAM="eos-s3"
Next, prepare the enviroment:
.. code-block:: bash
:name: conda-prep-env
export PATH="$INSTALL_DIR/$FPGA_FAM/install/bin:$PATH";
source "$INSTALL_DIR/$FPGA_FAM/conda/etc/profile.d/conda.sh"
Finally, enter your working Conda enviroment:
.. code-block:: bash
:name: conda-act-env
conda activate $FPGA_FAM
.. note::
If you don't know how to upload any of the following examples onto your
development board, please refer to the Running examples section.
Xilinx 7-Series
---------------
Enter the directory that contains examples for Xilinx 7-Series FPGAs:
.. code-block:: bash
:name: enter-dir-xc7
cd xc7
.. jinja:: xc7_counter_test
:file: templates/example.jinja
.. jinja:: xc7_picosoc_demo
:file: templates/example.jinja
.. jinja:: xc7_linux_litex_demo
:file: templates/example.jinja
QuickLogic EOS S3
-----------------
Enter the directory that contains examples for QuickLogic EOS S3:
.. code-block:: bash
:name: enter-dir-eos-s3
cd eos-s3
.. jinja:: eos-s3_btn_counter
:file: templates/example.jinja

247
docs/conf.py Normal file
View File

@ -0,0 +1,247 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = u'SymbiFlow examples'
authors = u'SymbiFlow'
copyright = authors + u', 2020'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx_tabs.tabs',
'sphinxcontrib.jinja',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_show_sourcelink = True
html_sidebars = {
"**": ["logo-text.html", "globaltoc.html", "localtoc.html", "searchbox.html"]
}
html_theme = 'sphinx_material'
html_theme_options = {
'nav_title': project,
'color_primary': 'deep-purple',
'color_accent': 'purple',
'repo_name': "antmicro/symbiflow-examples",
'repo_url': 'https://github.com/antmicro/symbiflow-examples',
'globaltoc_depth': 2,
'globaltoc_collapse': True
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# html_static_path = ['_static']
import os
from docutils.core import publish_doctree
full_name_lut = {
'a35t': 'Arty 35T',
'a100t': 'Arty 100T',
'basys3': 'Basys 3',
'eos_s3': 'EOS S3',
}
families = ('xc7', 'eos-s3')
def handle_default_with_literals(block):
text = ""
for node in block.traverse(include_self=False, condition=lambda x:
x.parent.tagname.strip() != 'literal'):
tagname = node.tagname.strip()
if tagname in ('paragraph',):
continue
if tagname == 'literal':
text = text + '``' + node.astext() + '``'
else:
text = text + node.astext()
ret = {}
ret['type'] = block.tagname.strip()
ret['text'] = text
return ret
def subtree_has_tag(block, tagname):
for node in block.traverse(include_self=False):
if node.tagname.strip() == tagname:
return True
return False
def handle_title(block):
ret = {
'type': 'title',
'text': '\n'.join((block.astext(), '~' * 20)),
}
return ret
def handle_img(block):
ret = {}
ret['type'] = 'image'
ret['uri'] = os.path.join(*block['uri'].split('/')[3:])
ret['align'] = block.get('align', 'center')
ret['width'] = block.get('width', '100%')
return ret
def handle_literal_block(block):
ret = {}
ret['type'] = 'literal_block'
ret['text'] = block.astext().split('\n')
ret['classes'] = block['classes']
try:
ret['name'] = full_name_lut[''.join(block['names']).split('-')[2]]
except:
ret['name'] = ''
return ret
def handle_note(block):
ret = {}
ret['type'] = block.tagname.strip()
if subtree_has_tag(block, 'literal'):
for node in block.traverse(condition=lambda x:
x.tagname.strip() == 'paragraph'):
ret['text'] = handle_default_with_literals(node)['text']
else:
ret['text'] = block.astext()
ret['text'] = ret['text'].split('\n')
return ret
def handle_default(block):
if subtree_has_tag(block, 'literal'):
return handle_default_with_literals(block)
ret = {}
ret['type'] = block.tagname.strip()
ret['text'] = block.astext()
return ret
handle_block_funcs = {
'title': handle_title,
'image': handle_img,
'literal_block': handle_literal_block,
'note': handle_note,
'default': handle_default,
}
def get_blocks(text):
doctree = publish_doctree(text)
return doctree.traverse(condition=lambda x: x.tagname.strip() != 'document'
and x.parent.tagname.strip() != 'note')
def fill_context(text):
ret = []
start_group = False
in_group = False
for block in get_blocks(text):
tagname = block.tagname.strip()
# do not process those
if tagname in ('#text', 'inline', 'literal'):
continue
# try do get handler; if not found, use the default one
if tagname not in handle_block_funcs.keys():
handler = 'default'
else:
handler = tagname
entry = handle_block_funcs[handler](block)
# internal logic for grouping code blocks into tab groups
if tagname == 'literal_block' and 'group' in ''.join(block['names']):
if not in_group:
start_group = True
in_group = True
else:
start_group = False
in_group = True
else:
in_group = False
start_group = False
entry['start_group'] = start_group
entry['in_group'] = in_group
ret.append(entry)
return ret
# register examples
jinja_contexts = {}
top_dir = os.path.join(os.path.dirname(__file__), '..')
for family in families:
examples = os.scandir(os.path.join(top_dir, family))
for example in examples:
if example.is_dir():
# get README
path = os.path.join(top_dir, family, example, 'README.rst')
# skip if file does not exist
if not os.path.isfile(path):
continue
with open(path) as f:
text = f.read()
key = '_'.join((family, example.name))
jinja_contexts[key] = {'blocks': fill_context(text)}

137
docs/getting-symbiflow.rst Normal file
View File

@ -0,0 +1,137 @@
Getting SymbiFlow
=================
This section describe how to install SymbiFlow and setup a fully working
enviroment to later build example desings.
Prerequisites
-------------
To be able to follow through this tutorial, install the following software:
.. tabs::
.. group-tab:: Ubuntu
.. code-block:: bash
:name: install-reqs-ubuntu
apt install -y git wget picocom
.. group-tab:: CentOS
.. code-block:: bash
:name: install-reqs-centos
yum install -y git wget picocom
.. group-tab:: Arch
.. code-block:: bash
:name: install-reqs-arch
pacman -Sy git wget picocom
Next, clone the SymbiFlow examples repository and enter it:
.. code-block:: bash
:name: get-symbiflow
git clone https://github.com/SymbiFlow/symbiflow-examples
cd symbiflow-examples
Toolchain installation
----------------------
Now we are able to install the SymbiFlow toolchain. This procedure is divided
into three steps:
- installing the Conda package manager,
- choosing an installation directory,
- downloading the architecture definitions and installing the toolchain.
Conda
~~~~~
Download Conda installer script:
.. code-block:: bash
:name: wget-conda
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O conda_installer.sh
Choose the install directory
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The install directory can either be in your home directory
such as ``~/opt/symbiflow`` or in a system directory such as ``/opt/symbiflow``.
If you choose a system directory, you will need root permission to perform the installation,
and so you will need to add some ``sudo`` commands to the instructions below.
.. code-block:: bash
:name: conda-install-dir
export INSTALL_DIR=~/opt/symbiflow
Toolchain
~~~~~~~~~
Select your target FPGA family:
.. tabs::
.. group-tab:: Artix-7
.. code-block:: bash
:name: fpga-fam-xc7
export FPGA_FAM=xc7
.. group-tab:: EOS S3
.. code-block:: bash
:name: fpga-fam-eos-s3
export FPGA_FAM=eos-s3
Next, setup Conda and your system's enviroment:
.. code-block:: bash
:name: conda-setup
bash conda_installer.sh -u -b -p $INSTALL_DIR/$FPGA_FAM/conda;
source "$INSTALL_DIR/$FPGA_FAM/conda/etc/profile.d/conda.sh";
conda env create -f $FPGA_FAM/environment.yml
Download architecture definitions:
.. tabs::
.. group-tab:: Artix-7
.. code-block:: bash
:name: download-arch-def-xc7
mkdir -p $INSTALL_DIR/xc7/install;
wget -qO- https://storage.googleapis.com/symbiflow-arch-defs/artifacts/prod/foss-fpga-tools/symbiflow-arch-defs/presubmit/install/1049/20201123-030526/symbiflow-arch-defs-install-05bd35c7.tar.xz | tar -xJC $INSTALL_DIR/xc7/install;
mkdir -p $INSTALL_DIR/xc7/install/share/symbiflow/arch;
wget -qO- https://storage.googleapis.com/symbiflow-arch-defs/artifacts/prod/foss-fpga-tools/symbiflow-arch-defs/presubmit/install/1049/20201123-030526/symbiflow-xc7a50t_test.tar.xz | tar -xJC $INSTALL_DIR/xc7/install/share/symbiflow/arch;
wget -qO- https://storage.googleapis.com/symbiflow-arch-defs/artifacts/prod/foss-fpga-tools/symbiflow-arch-defs/presubmit/install/1049/20201123-030526/symbiflow-xc7a100t_test.tar.xz | tar -xJC $INSTALL_DIR/xc7/install/share/symbiflow/arch
.. group-tab:: EOS-S3
.. code-block:: bash
:name: download-arch-def-eos-s3
wget -qO- https://quicklogic-my.sharepoint.com/:u:/p/kkumar/EWuqtXJmalROpI2L5XeewMIBRYVCY8H4yc10nlli-Xq79g?download=1 | tar -xJ -C $INSTALL_DIR/eos-s3/
If the above commands exited without errors, you have successfuly installed and configured your working enviroment.
Build Example Designs
---------------------
With the toolchain installed, you can build the example designs.
The example designs are provided in separate directories:
* ``xc7`` directory for the Artix-7 devices
* ``eos-s3`` directory for the EOS S3 devices

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

BIN
docs/images/arty.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

BIN
docs/images/basys3-usb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 KiB

BIN
docs/images/basys3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

30
docs/index.rst Normal file
View File

@ -0,0 +1,30 @@
Welcome to SymbiFlow examples!
==============================
This guide explains how to get started with SymbiFlow and build example designs from the `SymbiFlow Examples <https://github.com/antmicro/symbiflow-examples>`_ GitHub repository. It currently focuses on two FPGA families:
- Artix-7 from Xilinx,
- EOS S3 from QuickLogic.
Follow this guide to:
- :doc:`install SymbiFlow <getting-symbiflow>` and all of its dependencies,
- :doc:`build <building-examples>` and :doc:`upload <running-examples>` example designs onto the devboard of your choice.
About SymbiFlow
---------------
SymbiFlow is a fully open source toolchain for the development of FPGAs, currently targeting chips from multiple vendors, e.g.:
- Xilinx 7-Series
- Lattice iCE40
- Lattice ECP5 FPGAs
- QuickLogic EOS S3
.. toctree::
:maxdepth: 2
:caption: Sections
getting-symbiflow
building-examples
running-examples

4
docs/requirements.txt Normal file
View File

@ -0,0 +1,4 @@
Sphinx==3.3.0
sphinx-material==0.0.32
sphinx-tabs==1.3.0
sphinx-jinja==1.1.1

123
docs/running-examples.rst Normal file
View File

@ -0,0 +1,123 @@
Running example designs
========================
This section desribes how to properly connect your board.
It also helps you configure and run any other software that is necessary to observe results.
Connecting development boards
-----------------------------
Arty board
~~~~~~~~~~
#. Connect the board to your computer using the USB cable:
#. Connect the board to your computer using the Ethernet cable
(only if you want to test the LiteX Linux Example)
.. image:: images/arty-usb-ethernet.png
:width: 49%
:align: center
Basys 3 board
~~~~~~~~~~~~~
Connect the Basys3 Board to your computer using the USB cable:
.. image:: images/basys3-usb.png
:width: 49%
:align: center
Connecting to UART
------------------
First check available teletypes with:
.. code-block:: bash
ls -l /dev | grep ttyUSB
You should see at least one, e.g.:
.. code-block:: bash
crw-rw----+ 1 root plugdev 188, 0 11-06 13:58 ttyUSB0
crw-rw----+ 1 root plugdev 188, 1 11-06 13:58 ttyUSB1
Simply use ``picocom`` to connect:
.. code-block:: bash
picocom -b 115200 --imap lfcrlf /dev/ttyUSB1
.. warning::
Substitute ``115200`` with the baud rate that your design uses!
.. warning::
Please note that ``/dev/ttyUSB1`` is just an example. The number appearing may change!
.. note::
If the picocom is unable to connect to any ``ttyUSBx`` device, you probably don't have appropriate user permissions.
On Debian distributions, type the command below to add the user to the ``dialout`` group.
This should resolve the missing permissions problem:
.. code-block:: bash
sudo usermod -a -G dialout `whoami`
Setting up TFTP
---------------
It is assumed that the server is running on port ``6069`` and uses ``/tftp`` directory.
#. Install tftp with (Ubuntu example):
.. code-block:: bash
sudo apt install tftpd-hpa
#. Create a directory for the server:
.. code-block:: bash
sudo mkdir -p /tftp
sudo chmod 777 -R /tftp
sudo chown tftp -R /tftp
#. Set up your TFTP configuration with:
.. code-block:: bash
cat << EOF | sudo tee /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftp"
TFTP_ADDRESS=":6069"
TFTP_OPTIONS="--secure"
EOF
#. Restart the TFTP server:
.. code-block:: bash
sudo systemctl restart tftpd-hpa
Configuring your network interfaces
-----------------------------------
Check your network interfaces with:
.. code-block::
ip link
Add IPv4 address to you interface:
.. code-block:: bash
ip addr add 192.168.100.100/24 dev eth0
.. warning::
``192.169.100.100/24`` and ``eth0`` are just examples!

51
docs/templates/example.jinja vendored Normal file
View File

@ -0,0 +1,51 @@
{% for block in blocks -%}
{% if block.type == 'literal_block' %}
{% if not block.start_group and not block.in_group %}
.. code-block:: {% if 'bash' in block.classes %}bash{% endif %}
{% for line in block.text -%}
{{ line }}
{% endfor %}
{% elif block.start_group %}
.. tabs::
.. group-tab:: {{ block.name }}
.. code-block:: bash
{% for line in block.text -%}
{{ line }}
{% endfor %}
{% elif block.in_group %}
.. group-tab:: {{ block.name }}
.. code-block:: bash
{% for line in block.text -%}
{{ line }}
{% endfor %}
{% endif %}
{% elif block.type == 'image' %}
.. image:: {{ block.uri }}
:align: {{ block.align }}
:width: {{ block.width }}
{% elif block.type == 'note' %}
.. note::
{% for line in block.text -%}
{{ line }}
{% endfor %}
{% else %}
{{ block.text }}
{% endif %}
{% endfor %}