docs: s/sfbuild/f4pga/
Signed-off-by: Unai Martinez-Corral <umartinezcorral@antmicro.com>
This commit is contained in:
parent
2ba01e787a
commit
f00ff8924d
|
@ -53,6 +53,10 @@ extensions = [
|
|||
bibtex_default_style = 'plain'
|
||||
bibtex_bibfiles = ['refs.bib']
|
||||
|
||||
myst_enable_extensions = [
|
||||
"colon_fence",
|
||||
]
|
||||
|
||||
numfig = True
|
||||
|
||||
templates_path = ['_templates']
|
||||
|
|
|
@ -2,154 +2,134 @@
|
|||
|
||||
## Getting started
|
||||
|
||||
To use _**sfbuild**_ you need a working python 3 installation which should be icluded
|
||||
as a part of conda virtual environment set up during symbiflow installation.
|
||||
_**sfbuild**_ installs along _**Symbiflow**_ with any version of toolchain. However,
|
||||
only _XC7_ architectures are supported currently and _Quicklogic_ support is a work
|
||||
in progress. _**sfbuild**_'s installation directory is `bin/sfbuild`, under your
|
||||
_**Symbiflow**_ installation directory. `sfbuild.py` is the script that you should
|
||||
run to use _**sfbuild**_.
|
||||
To use `f4pga` you need a working Python 3 installation which should be included as a part of the conda virtual
|
||||
environment set up during F4PGA installation.
|
||||
`f4pga` is installed together with F4PGA, regardless of the version of the toolchain.
|
||||
However, only _XC7_ architectures are supported currently and _Quicklogic_ support is a work in progress.
|
||||
|
||||
To get started with a project that already uses sfbuild, go to the project's
|
||||
directory and run the following line to build a bitstream:
|
||||
```
|
||||
$ python3 /path/to/sfbuild.py flow.json -p platform_name -t bitstream
|
||||
To get started with a project that already uses `f4pga`, go to the project's directory and run the following line to
|
||||
generate a bitstream:
|
||||
|
||||
```bash
|
||||
$ f4pga flow.json -p platform_name -t bitstream
|
||||
```
|
||||
|
||||
Substitute `platform_name` by the name of the target platform (eg. `x7a50t`).
|
||||
`flow.json` should be a **project's flow configuration** file included with the
|
||||
project. If you are unsure if you got the right file, you can check an example of
|
||||
the contents of such file shown in the "_Using sfbuild to build a target_" section.
|
||||
`flow.json` should be a *project flow configuration* file included with the project.
|
||||
If you are unsure if you got the right file, you can check an example of the contents of such file shown in the
|
||||
*Build a target* section below.
|
||||
|
||||
The location of the file containing bitstream will be indicated by sfbuild after the
|
||||
flow completes. Look for a line like this one on stdout.:
|
||||
The location of the bitstream will be indicated by `f4pga` after the flow completes.
|
||||
Look for a line like this one on stdout:
|
||||
|
||||
```
|
||||
```bash
|
||||
Target `bitstream` -> build/arty_35/top.bit
|
||||
```
|
||||
|
||||
## Fundamental concepts
|
||||
|
||||
If you want to create a new sfbuild project, it's highly recommended that you
|
||||
read this section first.
|
||||
If you want to create a new project, it's highly recommended that you read this section first.
|
||||
|
||||
### sfbuild
|
||||
### f4pga
|
||||
|
||||
_**sfbuild**_ is a modular build system designed to handle various
|
||||
_Verilog-to-bitsream_ flows for FPGAs. It works by wrapping the necessary tools
|
||||
in python scripts, which are called **sfbuild modules**. The modules are then
|
||||
referenced in a **platform's flow definition** files along configurations specific
|
||||
for given platform. These files for come included as a part of _**sfbuild**_ for the
|
||||
following platforms:
|
||||
`f4pga` is a modular build system designed to handle various _Verilog-to-bitsream_ flows for FPGAs.
|
||||
It works by wrapping the necessary tools in Python, which are called *f4pga modules*.
|
||||
Modules are then referenced in *platform flow definition* files, together with configuration specific for a given
|
||||
platform.
|
||||
Flow definition files for the following platforms are included as a part of `f4pga`:
|
||||
|
||||
* x7a50t
|
||||
* x7a100t
|
||||
* x7a200t (_soon_)
|
||||
|
||||
You can also write your own **platform's flow definition** file if you want to bring
|
||||
support to a different device.
|
||||
You can also write your own *platform flow definition* file if you want to bring support for a different device.
|
||||
|
||||
Each project that uses _**sfbuild**_ to perform any flow should include a _.json_
|
||||
file describing the project. The purpose of that file is to configure inputs
|
||||
for the flow and possibly override configuration values if necessary.
|
||||
Each project that uses `f4pga` to perform any flow should include a _.json_ file describing the project.
|
||||
The purpose of that file is to configure inputs for the flow and override configuration values if necessary.
|
||||
|
||||
### Modules
|
||||
|
||||
A **module** (also referred to as **sfbuild module** in sistuations where there might
|
||||
be confusion between Python's _modules_ and sfbuild's _modules_) is a python scripts
|
||||
that wraps a tool used within **Symbilfow's** ecosystem. The main purpouse of this
|
||||
wrapper is to provide a unified interface for sfbuild to use and configure the tool
|
||||
A *module* (also referred to as *f4pga module* in situations where there might be confusion between arbitrary Python
|
||||
_modules_ and f4pga _modules_) is a Python script that wraps a tool used within the F4PGA ecosystem.
|
||||
The main purpose of the wrappers is to provide a unified interface for `f4pga` to use and to configure the tool,
|
||||
as well as provide information about files required and produced by the tool.
|
||||
|
||||
### Dependecies
|
||||
|
||||
A **dependency** is any file, directory or a list of such that a **module** takes as
|
||||
its input or produces on its output.
|
||||
A *dependency* is any file, directory or a list of such that a *module* takes as its input or produces on its output.
|
||||
|
||||
Modules specify their dependencies by using symbolic names instead of file paths.
|
||||
The files they produce are also given symbolic names and paths which are either set
|
||||
through **project's flow configuration** file or derived from the paths of the
|
||||
dependencies taken by the module.
|
||||
The files they produce are also given symbolic names and paths which are either set through *project flow configuration*
|
||||
file or derived from the paths of the dependencies taken by the module.
|
||||
|
||||
### Target
|
||||
|
||||
**Target** is a dependency that the user has asked sfbuild to produce.
|
||||
*Target* is a dependency that the user has asked F4PGA to produce.
|
||||
|
||||
### Flow
|
||||
|
||||
A **flow** is set of **modules** executed in a right order to produce a **target**.
|
||||
A *flow* is set of *modules* executed in a right order to produce a *target*.
|
||||
|
||||
### .symbicache
|
||||
|
||||
All **dependencies** are tracked by a modification tracking system which stores hashes
|
||||
of the files (directories get always `'0'` hash) in `.symbicache` file in the root of
|
||||
the project. When _**sfbuild**_ constructs a **flow**, it will try to omit execution
|
||||
of modules which would receive the same data on their input. There's a strong
|
||||
_assumption_ there that a **module**'s output remains unchanged if the input
|
||||
doconfiguring esn't
|
||||
change, ie. **modules** are deterministic.
|
||||
All *dependencies* are tracked by a modification tracking system which stores hashes of the files
|
||||
(directories get always `'0'` hash) in `.symbicache` file in the root of the project.
|
||||
When F4PGA constructs a *flow*, it will try to omit execution of modules which would receive the same data on their
|
||||
input.
|
||||
There is a strong _assumption_ there that a *module*'s output remains unchanged if the input configuration isn't
|
||||
change, ie. *modules* are deterministic.
|
||||
|
||||
### Resolution
|
||||
|
||||
A **dependency** is said to be **resolved** if it meets one of the following
|
||||
critereia:
|
||||
A *dependency* is said to be *resolved* if it meets one of the following critereia:
|
||||
|
||||
* it exists on persistent storage and its hash matches the one stored in .symbicache
|
||||
* there exists such **flow** that all of the dependieces of its modules are
|
||||
**resolved** and it produces the **dependency** in question.
|
||||
* there exists such *flow* that all of the dependieces of its modules are *resolved* and it produces the *dependency* in
|
||||
question.
|
||||
|
||||
### Platform's flow definition
|
||||
|
||||
**Platform's flow definition** is a piece of data describing a space of flows for a
|
||||
given platform, serialized into a _JSON_.
|
||||
It's stored in a file that's named after the device's name under `sfbuild/platforms`.
|
||||
*Platform flow definition* is a piece of data describing a space of flows for a given platform, serialized into a _JSON_.
|
||||
It's stored in a file that's named after the device's name under `f4pga/platforms`.
|
||||
|
||||
**Platform's flow definition** contains a list of modules available for constructing
|
||||
flows and defines a set of values which the modules can reference. In case of some
|
||||
modules it may also define a set of parameters used during their construction.
|
||||
`mkdirs` module uses that to allow production of of multiple directories as separate
|
||||
dependencies. This however is an experimental feature which possibly will be
|
||||
removed in favor of having multiple instances of the same module with renameable
|
||||
ouputs.
|
||||
*Platform flow definition* contains a list of modules available for constructing flows and defines a set of values which
|
||||
the modules can reference.
|
||||
In case of some modules it may also define a set of parameters used during their construction.
|
||||
`mkdirs` module uses that to allow production of of multiple directories as separate dependencies.
|
||||
This however is an experimental feature which possibly will be removed in favor of having multiple instances of the same
|
||||
module with renameable ouputs.
|
||||
|
||||
Not all **dependencies** have to be **resolved** at this stage, a **platform's flow
|
||||
definition** for example won't be able to provide a list of source files needed in a
|
||||
**flow**.
|
||||
Not all *dependencies** have to be *resolved* at this stage, a *platform's flow definition* for example won't be able to
|
||||
provide a list of source files needed in a *flow*.
|
||||
|
||||
### Projects's flow configuration
|
||||
|
||||
Similarly to **platform's flow definition**, **Projects's flow configuration** is a
|
||||
_JSON_ that is used to configure **modules**. There are however a couple differences
|
||||
here and there.
|
||||
Similarly to *platform flow definition*, *Projects flow configuration* is a _JSON_ that is used to configure *modules*. There are however a couple differences here and there.
|
||||
|
||||
* The most obvious one is that this file is unique for a project and
|
||||
is provided by the user of _**sfbuild**_.
|
||||
* The most obvious one is that this file is unique for a project and is provided by the user of `f4pga`.
|
||||
|
||||
* The other difference is that it doesn't list **modules** available for the
|
||||
platform.
|
||||
* The other difference is that it doesn't list *modules* available for the platform.
|
||||
|
||||
* All the values provided in **projects's flow configuration** will override those
|
||||
provided in **platform's flow definition**.
|
||||
* All the values provided in *projects flow configuration* will override those provided in *platform flow definition*.
|
||||
|
||||
* It can contain sections with configurations for different platforms.
|
||||
|
||||
* Unlike **platform's flow definition** it can give explicit paths to dependencies.
|
||||
* Unlike *platform flow definition* it can give explicit paths to dependencies.
|
||||
|
||||
* At this stage all mandatory **dependencies** should be resolved.
|
||||
* At this stage all mandatory *dependencies* should be resolved.
|
||||
|
||||
Typically **projects's flow configuration** will be used to resolve dependencies
|
||||
for _HDL source code_ and _device constraints_.
|
||||
Typically *projects flow configuration* will be used to resolve dependencies for _HDL source code_ and _device constraints_.
|
||||
|
||||
## Build a target
|
||||
|
||||
To build a **target** "`target_name`", use the following command:
|
||||
```
|
||||
$ python3 /path/to/sfbuild.py flow.json -p platform_device_name -t target_name
|
||||
```
|
||||
where `flow.json` is a path to **projects's flow configuration**
|
||||
To build a *target* `target_name`, use the following command:
|
||||
|
||||
For example, let's consider the following
|
||||
**projects's flow configuration (flow.json)**:
|
||||
```bash
|
||||
$ f4pga flow.json -p platform_device_name -t target_name
|
||||
```
|
||||
where `flow.json` is a path to *projects flow configuration*.
|
||||
|
||||
For example, let's consider the following *projects flow configuration (flow.json)*:
|
||||
|
||||
```json
|
||||
{
|
||||
|
@ -168,52 +148,49 @@ For example, let's consider the following
|
|||
}
|
||||
```
|
||||
|
||||
It specifies list of paths to Verilog source files as "`sources`" dependency.
|
||||
Similarily it also provides an "`XDC`" file with constrains. ("`xdc`" dependency)
|
||||
It specifies list of paths to Verilog source files as `sources` dependency.
|
||||
Similarily it also provides an `XDC` file with constrains (`xdc` dependency).
|
||||
|
||||
It also names a path for synthesis and logs ("`synth_log`", "`pack_log`").
|
||||
These two are optional on-demand outputs, meaning they won't be produces unless
|
||||
their paths are explicitely set.
|
||||
It also names a path for synthesis and logs (`synth_log`, `pack_log`).
|
||||
These two are optional on-demand outputs, meaning they won't be produces unless their paths are explicitely set.
|
||||
|
||||
"`top`" value is set to in order to specify the name of top Verilog module, which
|
||||
is required during synthesis.
|
||||
`top` value is set to in order to specify the name of top Verilog module, which is required during synthesis.
|
||||
|
||||
"`build_dir`" is an optional helper dependency. When available, modules will put
|
||||
their outputs into that directory. It's also an _on-demand_ output of `mkdirs`
|
||||
module in _xc7a50t_ flow definition, which means that if specified directory does
|
||||
not exist, `mkdirs` will create it and provide as `build_dir` dependency.
|
||||
|
||||
building a bitstream for *x7a50t* would look like that:
|
||||
`build_dir` is an optional helper dependency.
|
||||
When available, modules will put their outputs into that directory.
|
||||
It's also an _on-demand_ output of `mkdirs` module in _xc7a50t_ flow definition, which means that if specified directory
|
||||
does not exist, `mkdirs` will create it and provide as `build_dir` dependency.
|
||||
|
||||
With this flow configuration, you can build a bitstream for arty_35 using the
|
||||
following command:
|
||||
|
||||
```
|
||||
$ python3 /path/to/sfbuild.py flow.json -p x7a50t -t bitstream
|
||||
$ f4pga flow.json -p x7a50t -t bitstream
|
||||
```
|
||||
|
||||
### Pretend mode
|
||||
|
||||
You can also add a `--pretend` (`-P`) option if you just want to see the results of
|
||||
dependency resolution for a specified target without building it. This is useful
|
||||
when you just want to know what files will be generated and where wilh they be
|
||||
stored.
|
||||
You can also add a `--pretend` (`-P`) option if you just want to see the results of dependency resolution for a
|
||||
specified target without building it.
|
||||
This is useful when you just want to know what files will be generated and where wilh they be stored.
|
||||
|
||||
### Info mode
|
||||
|
||||
Modules have the ability to include description to the dependencies they produce.
|
||||
|
||||
Running _**sfbuild**_ with `--info` (`-i`) flag allows youn to see descriptions of
|
||||
these dependencies. This option doesn't require a target to be specified, but you
|
||||
still have to provuide a flow configuration and platform name.
|
||||
Running `f4pga` with `--info` (`-i`) flag allows youn to see descriptions of these dependencies.
|
||||
This option doesn't require a target to be specified, but you still have to provuide a flow configuration and platform
|
||||
name.
|
||||
|
||||
This is still an experimental option, most targets currently lack descriptions
|
||||
and no information whether the output is _on-demand_ is currently displayed.
|
||||
This is still an experimental option, most targets currently lack descriptions and no information whether the output is
|
||||
_on-demand_ is currently displayed.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
$ f4pga flow.json -p x7a50t -i
|
||||
```
|
||||
$ python3 /path/to/sfbuild.py flow.json -p x7a50t -i
|
||||
```
|
||||
|
||||
```
|
||||
Platform dependencies/targets:
|
||||
build_dir: <no descritption>
|
||||
|
@ -231,9 +208,11 @@ Platform dependencies/targets:
|
|||
module: `synth`
|
||||
```
|
||||
|
||||
_This is only a snippet of the entire output_
|
||||
:::{important}
|
||||
This is only a snippet of the entire output.
|
||||
:::
|
||||
|
||||
### Summary of all available sfbuild options
|
||||
### Summary of all available options
|
||||
|
||||
| long | short | arguments | description |
|
||||
|------------|:-----:|------------------------|-------------------------------------------------|
|
||||
|
@ -244,11 +223,12 @@ _This is only a snippet of the entire output_
|
|||
|
||||
### Dependency resolution display
|
||||
|
||||
sfbuild displays some information about dependencies when requesting a target.
|
||||
F4PGA displays some information about dependencies when requesting a target.
|
||||
|
||||
Here's an example of a possible output when trying to build `bitstream` target:
|
||||
|
||||
```
|
||||
sfbuild: Symbiflow Build System
|
||||
F4PGA Build System
|
||||
Scanning modules...
|
||||
|
||||
Project status:
|
||||
|
@ -267,55 +247,62 @@ Project status:
|
|||
[N] sources: ['counter.v']
|
||||
[O] xdc: ['arty.xdc']
|
||||
|
||||
sfbuild: DONE
|
||||
F4PGA: DONE
|
||||
```
|
||||
|
||||
The letters in the boxes describe the status of a dependency which's name is next
|
||||
to the box.
|
||||
The letters in the boxes describe the status of a dependency which's name is next to the box.
|
||||
|
||||
* **X** - dependency unresolved. This isn't always a bad sign. Some dependencies
|
||||
are not required to, such as "`pcf`".
|
||||
* **U** - dependency unreachable. The dependency has a module that could produce
|
||||
it, but the module's dependencies are unresolved. This doesn't say whether the
|
||||
dependency was necessary or not.
|
||||
* **O** - dependency present, unchanged. This dependency is already built and is
|
||||
confirmed to stay unchanged during flow execution.
|
||||
* **N** - dependency present, new/changed. This dependency is already present on
|
||||
the persistent storage, but it was either missing earlier, or
|
||||
its content changed from the last time.
|
||||
(WARNING: it won't continue to be reported as "**N**" after a successful build of
|
||||
any target. This may lead to some false "**O**"s in some complex scenarios. This
|
||||
should be fixed in the future.)
|
||||
* **S** - depenendency not present, resolved. This dependency is not
|
||||
currently available on the persistent storage, however it will be produced within
|
||||
flow's execution.
|
||||
* **R** - depenendency present, resolved, requires rebuild. This dependency is
|
||||
currently available on the persistent storage, however it has to be rebuilt due
|
||||
to the changes in the project.
|
||||
* **X** - dependency unresolved.
|
||||
This isn't always a bad sign. Some dependencies are not required to, such as `pcf`.
|
||||
|
||||
Additional info about a dependency will be displayed next to its name after a
|
||||
colon:
|
||||
* **U** - dependency unreachable.
|
||||
The dependency has a module that could produce it, but the module's dependencies are unresolved.
|
||||
This doesn't say whether the dependency was necessary or not.
|
||||
|
||||
* In case of dependencies that are to be built (**S**/**R**), there's a name of a
|
||||
module that will produce this dependency, followed by "`->`" and a path or list of
|
||||
paths to file(s)/directory(ies) that will be produced as this dependency.
|
||||
* **O** - dependency present, unchanged.
|
||||
This dependency is already built and is confirmed to stay unchanged during flow execution.
|
||||
|
||||
* In case of dependencies which do not require execution of any modules, only
|
||||
a path or list of paths to file(s)/directory(ies) that will be displayed
|
||||
* **N** - dependency present, new/changed.
|
||||
This dependency is already present on the persistent storage, but it was either missing earlier, or its content
|
||||
changed from the last time.
|
||||
|
||||
* In case of unresolved dependencies (**X**), which are never produced by any
|
||||
module, a text sying "`MISSING`" will be displayed
|
||||
* In case of unreachable dependencies, a name of such module that could produce
|
||||
them will be displayed followed by "`-> ???`".
|
||||
:::{warning}
|
||||
It won't continue to be reported as "**N**" after a successful build of any target.
|
||||
This may lead to some false "**O**"s in some complex scenarios.
|
||||
This should be fixed in the future.
|
||||
:::
|
||||
|
||||
In the example above file `counter.v` has been modified and is now marked as
|
||||
"**N**". This couses a bunch of other dependencies to be reqbuilt ("**R**").
|
||||
* **S** - depenendency not present, resolved.
|
||||
This dependency is not currently available on the persistent storage, however it will be produced within flow's
|
||||
execution.
|
||||
|
||||
* **R** - depenendency present, resolved, requires rebuild.
|
||||
This dependency is currently available on the persistent storage, however it has to be rebuilt due to the changes in
|
||||
the project.
|
||||
|
||||
Additional info about a dependency will be displayed next to its name after a colon:
|
||||
|
||||
* In case of dependencies that are to be built (**S**/**R**), there's a name of a module that will produce this
|
||||
dependency, followed by `->` and a path or list of paths to file(s)/directory(ies) that will be produced as this
|
||||
dependency.
|
||||
|
||||
* In case of dependencies which do not require execution of any modules, only a path or list of paths to
|
||||
file(s)/directory(ies) that will be displayed.
|
||||
|
||||
* In case of unresolved dependencies (**X**), which are never produced by any module, a text sying "`MISSING`" will be
|
||||
displayed.
|
||||
|
||||
* In case of unreachable dependencies, a name of such module that could produce them will be displayed followed by
|
||||
`-> ???`.
|
||||
|
||||
In the example above file `counter.v` has been modified and is now marked as "**N**".
|
||||
This couses a bunch of other dependencies to be reqbuilt ("**R**").
|
||||
`build_dir` and `xdc` were already present, so they are marked as "**O**".
|
||||
|
||||
## Common targets and values
|
||||
|
||||
Targets and values are named with some conventions.
|
||||
Below are lists of the target and value names along with their meanings"
|
||||
Below are lists of the target and value names along with their meanings.
|
||||
|
||||
### Need to be provided by the user
|
||||
|
||||
|
|
|
@ -20,15 +20,17 @@ data. And they contain snippets of _module configurations_
|
|||
|
||||
A _module configuration_ is a structure with the following fields:
|
||||
|
||||
* `takes` - a dictionary that contains keys which are names of the dependencies
|
||||
used by the module. The values are paths to those dependencies. They can be
|
||||
either singular strings or lists of strings.
|
||||
* `produces` = a dictionary that contains keys which are names of the
|
||||
dependencies produced by the module. The values are requested filenames for the
|
||||
files generated by the module. They can be either singular strings or lists of
|
||||
strings.
|
||||
* `takes` - a dictionary that contains keys which are names of the dependencies used by the module.
|
||||
The values are paths to those dependencies.
|
||||
They can be either singular strings or lists of strings.
|
||||
|
||||
* `produces` = a dictionary that contains keys which are names of the dependencies produced by the module.
|
||||
The values are requested filenames for the files generated by the module.
|
||||
They can be either singular strings or lists of strings.
|
||||
|
||||
* `values` - a dictionary that contains other values used to configure the module.
|
||||
The keys are value's names and the values can have any type.
|
||||
|
||||
* `platform` - Platform's name. This is a string.
|
||||
|
||||
### Platform-level configuration
|
||||
|
|
Loading…
Reference in New Issue