| # Usage | |
| ## Getting started | |
| 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 `f4pga`, go to the project's directory and run the following line to | |
| generate a bitstream: | |
| ```bash | |
| $ f4pga build -f flow.json | |
| ``` | |
| `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 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 project, it's highly recommended that you read this section first. | |
| ### f4pga | |
| `f4pga` is a modular build system designed to handle various _Verilog-to-bitstream_ 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_: | |
| * **AMD Xilinx x7a50t** (and architecturally equivalent devices, such as x7a35t) | |
| * **AMD Xilinx x7a100t** | |
| * **AMD Xilinx x7a200t** | |
| * **Quicklogic EOS-S3** (currently unsupported, provided only for development purposes) | |
| * **Quicklogic K4N8** (currently unsupported, provided only for development purposes) | |
| You can also write your own *platform flow definition* file if you want to bring support for a different device. | |
| 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 *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. | |
| ### Dependencies | |
| 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 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 F4PGA to produce. | |
| ### Flow | |
| A *flow* is set of *modules* executed in a right order to produce a *target*. | |
| ### .f4cache | |
| All *dependencies* are tracked by a modification tracking system which stores hashes of the files | |
| (directories get always `'0'` hash) in `.f4cache` 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 | |
| changed, ie. *modules* are deterministic. This is might be not true for some tools and in case you really want to re-run | |
| a stage, there's a `--nocache` option that treats the `.f4cache` file as if it was empty. | |
| ### Resolution | |
| A *dependency* is said to be *resolved* if it meets one of the following criteria: | |
| * it exists on persistent storage and its hash matches the one stored in .f4cache | |
| * there exists such *flow* that all of the dependencies of its modules are *resolved* and it produces the *dependency* in | |
| question. | |
| ### Platform's flow definition | |
| *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 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 outputs. | |
| 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*. | |
| ### Project's flow configuration | |
| 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 `f4pga`. | |
| * The other difference is that it doesn't list *modules* available for the platform. | |
| * 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 flow definition* it can give explicit paths to dependencies. | |
| * At this stage all mandatory *dependencies* should be resolved. | |
| Typically *projects flow configuration* will be used to resolve dependencies for _HDL source code_ and _device constraints_. | |
| ## Build a target | |
| ### Using flow configuration file | |
| To build a *target* `target_name`, use the following command: | |
| ```bash | |
| $ f4pga build -f 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 | |
| { | |
| "default_part": "XC7A35TCSG324-1", | |
| "dependencies": { | |
| "sources": ["counter.v"], | |
| "xdc": ["arty.xdc"], | |
| "synth_log": "synth.log", | |
| "pack_log": "pack.log", | |
| }, | |
| "values": { | |
| "top": "top" | |
| }, | |
| "XC7A35TCSG324-1": { | |
| "default_target": "bitstream", | |
| "dependencies": { | |
| "build_dir": "build/arty_35" | |
| } | |
| } | |
| } | |
| ``` | |
| It specifies list of paths to Verilog source files as `sources` dependency. | |
| Similarly 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 explicitly set. | |
| `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. | |
| With this flow configuration, you can build a bitstream for arty_35 using the | |
| following command: | |
| ``` | |
| $ f4pga build -f flow.json -p XC7A35TCSG324-1 -t bitstream | |
| ``` | |
| Because we have `default_platform` defined, we can skip the `--part` argument. | |
| We can also skip the `--target` argument because we have a `default_target` defined for the | |
| chosen platform. This will default to the `bitstream` target of `xc7a50t` platform: | |
| ``` | |
| $ f4pga build -f flow.json | |
| ``` | |
| ### Using Command-Line Interface | |
| Alternatively you can use CLI to pass the configuration without creating a flow file: | |
| ``` | |
| $ f4pga build -p XC7A35TCSG324-1 -Dsources=[counter.v] -Dxdc=[arty.xdc] -Dsynth_log=synth.log -Dpack_log=pack.log -Dbuild_dir=build/arty_35 -Vtop=top -t bitstream | |
| ``` | |
| CLI flow configuration can be used alongside a flow configuration file and will override | |
| conflicting dependencies/values from the file. | |
| CLI configuration follows the following format: | |
| `<dependency/value identifier>=<expression>` | |
| `<dependency/value identifier>` is the name of dependency or value optionally prefixed by a stage | |
| name and a dot (`.`). Using the notation with stage name sets the dependency/value only for the | |
| specified stage. | |
| `<expression>` is a form of defining a dependency path or a value. Characters are interpreted | |
| as strings unless the follow one of the following format: | |
| * `[item1,item2,item3,...]` - this is a list of strings | |
| * `{key1:value1,key2:value2,key3:value3,...}` - this is a dictionary | |
| Nesting structures is currently unsupported in CLI. | |
| ### 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 will they be stored. | |
| ### Info mode | |
| Modules have the ability to include description to the dependencies they produce. | |
| Running `f4pga` with `--info` (`-i`) flag allows you to see descriptions of these dependencies. | |
| This option doesn't require a target to be specified, but you still have to provide 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. | |
| Example: | |
| ```bash | |
| $ f4pga -v build -f flow.json -p XC7A35TCSG324-1 -i | |
| ``` | |
| ``` | |
| Platform dependencies/targets: | |
| build_dir: <no descritption> | |
| module: `mk_build_dir` | |
| eblif: Extended BLIF hierarchical sequential designs file | |
| generated by YOSYS | |
| module: `synth` | |
| fasm_extra: <no description> | |
| module: `synth` | |
| json: JSON file containing a design generated by YOSYS | |
| module: `synth` | |
| synth_json: <no description> | |
| module: `synth` | |
| sdc: <no description> | |
| module: `synth` | |
| ``` | |
| :::{important} | |
| This is only a snippet of the entire output. | |
| ::: | |
| ### Summary of global options | |
| | long | short | arguments | description | | |
| |-----------|:-----:|--------------------------|----------------------------------------------------------------------------| | |
| | --verbose | -v | - | Control verbosity level. 0 for no verbose output. 2 for maximum verbosity | | |
| | --silent | -s | - | Suppress any output | | |
| ### Summary of all available sub-commands | |
| | name | description | | |
| |---------|-----------------------------| | |
| | build | Build a project | | |
| | showd | Print value of a dependency | |
| ### Summary of all options available for `build` sub-command | |
| | long | short | arguments | description | | |
| |-------------|:-----:|--------------------------|---------------------------------------------------------| | |
| | --flow | -f | flow configuration file | Use flow configuration file | | |
| | --part | -p | part name | Specify target part name | | |
| | --target | -t | target dependency name | Specify target to produce | | |
| | --info | -i | - | Display information about available targets | | |
| | --pretend | -P | - | Resolve dependencies without executing the flow | | |
| | --nocache | | - | Do not perform incremental build (do full a full build) | | |
| | --stageinfo | -S | stage name | Display information about a specified stage | | |
| | --dep | -D | dependency_name=pathexpr | Add a dependency to configuration | | |
| | --val | -V | value_name=valueexpr | Add a value to configuration | | |
| ### Summary of all options available for `showd` sub-command | |
| | long | short | arguments | description | | |
| |-------------|:-----:|--------------------------|-------------------------------------------------------------| | |
| | --flow | -f | flow configuration file | Use flow configuration file | | |
| | --part | -p | part name | Specify target part name | | |
| | --stage | -s | part name | Specify stage name (to display stage-specific dependencies) | | |
| ### Dependency resolution display | |
| F4PGA displays some information about dependencies when requesting a target. | |
| Here's an example of a possible output when trying to build `bitstream` target (use `-P`): | |
| ``` | |
| F4PGA Build System | |
| Scanning modules... | |
| Project status: | |
| [R] bitstream: bitstream -> build/arty_35/top.bit | |
| [O] build_dir: build/arty_35 | |
| [R] eblif: synth -> build/arty_35/top.eblif | |
| [R] fasm: fasm -> build/arty_35/top.fasm | |
| [R] fasm_extra: synth -> build/arty_35/top_fasm_extra.fasm | |
| [R] io_place: ioplace -> build/arty_35/top.ioplace | |
| [R] net: pack -> build/arty_35/top.net | |
| [X] pcf: MISSING | |
| [R] place: place -> build/arty_35/top.place | |
| [R] place_constraints: place_constraints -> build/arty_35/top.preplace | |
| [R] route: route -> build/arty_35/top.route | |
| [R] sdc: synth -> build/arty_35/top.sdc | |
| [N] sources: ['counter.v'] | |
| [O] xdc: ['arty.xdc'] | |
| f4pga: DONE | |
| ``` | |
| The letters in the boxes describe the status of a dependency whose name is next to the box. | |
| * **X** - dependency unresolved. | |
| Dependency is not present or cannot be produced. | |
| This isn't always a bad sign. Some dependencies are not required to, such as `pcf`. | |
| * **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 since the last time it was used. | |
| :::{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** - dependency not present, resolved. | |
| This dependency is not currently available on the persistent storage, however it will be produced within flow's | |
| execution. | |
| * **R** - dependency 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 saying "`MISSING`" will be | |
| displayed. | |
| In the example above file `counter.v` has been modified and is now marked as "**N**". | |
| This causes a bunch of other dependencies to be rebuilt ("**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. | |
| ### Need to be provided by the user | |
| | Target name | list | Description | | |
| |-------------|:----:|-------------| | |
| | `sources` | yes | Verilog sources | | |
| | `sdc` | no | Synopsys Design Constraints | | |
| | `xdc` | yes | Xilinx Design Constraints (available only for Xilinx platforms) | | |
| | `pcf` | no | Physical Constraints File | | |
| ### Available in most flows | |
| | Target name | list | Description | | |
| |--------------|:----:|-----------------------------------------------------------------| | |
| | `eblif` | no | Extended blif file | | |
| | `bitstream` | no | Bitstream | | |
| | `net` | no | Netlist | | |
| | `fasm` | no | Final FPGA Assembly | | |
| | `fasm_extra` | no | Additional FPGA assembly that may be generated during synthesis | | |
| | `build_dir` | no | A directory to put the output files in | | |
| ### Built-in values | |
| | Value name | type | Description | | |
| |-----------------|----------|---------------------------------------------------| | |
| | `shareDir` | `string` | Path to f4pga's installation "share" directory | | |
| | `python3` | `string` | Path to Python 3 executable | | |
| | `noisyWarnings` | `string` | Path to noisy warnings log (should be deprecated) | | |
| | `prjxray_db` | `string` | Path to Project X-Ray database | | |
| ### Used in flow definitions | |
| | Value name | type | Description | | |
| |---------------|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| | |
| | `top` | `string` | Top module name | | |
| | `build_dir` | `string` | Path to build directory (should be optional) | | |
| | `device` | `string` | Name of the device | | |
| | `vpr_options` | `dict[string -> string \| number]` | Named options passed to VPR. No `--` prefix included. | | |
| | `part_name` | `string` | Name of the chip used. The distinction between `device` and `part_name` is ambiguous at the moment and should be addressed in the future. | | |
| | `arch_def` | `string` | Path to an XML file containing architecture definition. | |