Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] SFBUILD/F4BUILD - Vendor-independent build system for F4PGA #2455

Closed
wants to merge 1 commit into from

Conversation

kboronski-ant
Copy link
Contributor

This is an update to #2225. I squashed everything into a separate branch since the commit history is quite long and chaotic and the branch was rebased by @mkurc-ant, no longer matching my local version which was based on Quicklogic's fork.

What is this?

sfbuild (not a final name) is a CLI tool written in Python that serves as a frontend for executing flows. On the other hand, sfbuild aims to provide developers with an ability to easily add platforms and modify/extend flows in a vendor-independent way. The philosophy behind this tool is to generate and execute flows dynamically based on user and developer-provided configurations and metadata that descibes the tools utilized within the flow (think edalize wrappers on steroids).

How to use it?

Example usage:

sfbuild -v build -p XC7A35TICSG324-1L -t bitstream -Dsources=[counter.v] -Dsynth_log=synth.log -Dpack_log=pack.log -Dbuild_dir=build/arty_35 -Dxdc=[arty.xdc] -Vpart=xc7a35tcpg236-1 -Vtop=top

builds target bitstream using a list of source files (one entry: counter.v), arty.xdc as constraints, top being the name of a top module. Additionally it will create build/arty_35 directory to output all files and will produce logs from synh and pack stages. The target is XC7A35TICSG324-1L chip.

You can provide any depency with -D flag followed by a symbolic dependency name and a path or list of paths. In a similar manner, you can provide values with -V flag. You can learn more about differences between dependencies and values in a later section.

Alternatively the configuration can be provided through a JSON.

Ok, but how does it work and what does any of that mean?

sfbuild splits a flow into stages, where each stage represents an instance of a module. A module is similar to an edatool, from edalize in a sense that it wraps an external tool, but contains more metadata and has more complex configuration interface. Each module features a set of inputs and outputs which are represented by symbolic dependencies. A symbolic dependency is a name given to a file/set of files that play a particular role in the flow. By using symbolic dependencies instead of explicit paths, sfbuild is able to perform dependency resolution without requiring the user to figure any of the logic behind flow, as long as they are able to provide necessary dependencies.

In the example above, -t bitstream is a request for building a dependency whose symbolic name is bitstream. Requesting this dependency causes sfbuild to perform dependency resolution on stages associated with the target platform (xc7a50t). If there are any dependencies required for building bitstream that cannot be built, the user would be notified and would have to provide them explicitely. That's where the -Dsources=[counter.v]and -Dxdc=[arty.xdc] come into play. Since EDA tools may have optional outputs, we can also provide sfbuild with explicit paths for dependencies to force their production. That's the case with -Dsynth_log=synth.log and -Dpack_log=pack.log. Finally, there are also optional inputs, which are dependencies that will be taken as an input for a stage when present, but if they are missing the flow would resolve anyway.

Dependencies are always meant to be files, so sfbuild can check for their existence and whether they are up-to-date (yes-there's modification tracking, to avoid unnecessary re-runs (can be disabled with --nocache flag). Because of that, any configuration/input for an EDA tool that is not a file (eg. a CLI option) is represented a a value. This works just like dependencies, but without tracking and allows passing dictionaries (eg. vpr_options).

On the developer side, all platforms are defined by their respective flow-definitions. Those are JSONS located under sfbuild/platforms. They instantiate a set of stages, default values, as well as choose parameters for constructing stages (Plenty of modules modules can be parametrized, which affects their I/O - something that's not possible with values/dependencies. See generic_script_wrapper for example).

About modules

Modules are stored in directories whose names follow the sf_<module_category>_modules.
There are essentially three stages of module's lifetime.

  • Instantiation - this is where the module is instantiated as a stage. During this phase the module declares its inputs and outputs and their modes (dependency/value, required/optional/on-demand).
  • I/O mapping - this phase is used to generate default file names for module's output dependencies given file names and values at its input. This allows the user to skip naming any intermediate products and serves as a sort of promise on how the tool will act when executed.
  • Execution - in this phase the actual EDA tool or helper script is executed. If the outputs promised during I/O mapping were not produced the flow fails.

Quicklogic

Since the development was based o Quicklogic's fork, this won't work out-of-the-box with EOS-S3 and K4N8 platforms.

Aside from pulling Quicklogic changes, there are also other changes that need to be done in order to make it work with those targets and by that I mean resolving collisions between platform-specific scripts. F4PGA when installed for all families will overwrite some platform-specific scripts with their counter-parts that were meant to be used for another platform. If you resolve these conflicts by renaming the scripts to the name you can find in platform flow definitions (sfbuild/platforms), you should get an F4PGA installation that's compatible both with Xilinx and Quicklogic devices (at least when using sfbuild, the original wrappers will be broken).

@probot-autolabeler probot-autolabeler bot added lang-python Issue uses (or requires) Python language. type-docs Issue is related to documentation. type-utils Issues is related to the scripts inside the repo. labels Feb 25, 2022
Signed-off-by: Krzysztof Boronski <[email protected]>
@umarcor
Copy link
Contributor

umarcor commented Mar 3, 2022

Superseeded by chipsalliance/f4pga#530.

@umarcor umarcor closed this Mar 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lang-python Issue uses (or requires) Python language. type-docs Issue is related to documentation. type-utils Issues is related to the scripts inside the repo.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants