tsfpga package

A flexible and scalable development platform for modern FPGA projects

Subpackages

Submodules

tsfpga.about module

tsfpga.about.get_readme_rst(include_extra_for_github: bool = False, include_extra_for_website: bool = False, include_extra_for_pypi: bool = False) str

Get the complete README.rst for tsfpga (to be used on website and in PyPI release).

The arguments control some extra text that is included. This is mainly links to the other places where you can find information on the project (website, GitHub, PyPI).

Parameters:
  • include_extra_for_github (bool) – Include the extra text that shall be included in the GitHub README.

  • include_extra_for_website – Include the extra text that shall be included in the website main page.

tsfpga.about.get_short_slogan() str

Short slogan used e.g. on pypi.org. Note that there seems to be an upper limit of 98 characters when rendering the slogan on pypi.org.

Note that this slogan should be the same as the one used in the readme and on the website below. The difference is capitalization and whether the project name is included.

tsfpga.build_project_list module

class tsfpga.build_project_list.BuildProjectBuildWrapper(project: VivadoProject, collect_artifacts: Callable[[...], bool] | None, **kwargs: Any)

Bases: object

Wrapper to build a project, for usage in the build runner. Mimics a VUnit test object.

__init__(project: VivadoProject, collect_artifacts: Callable[[...], bool] | None, **kwargs: Any) None
property build_result_report_length: int

The number of lines in the build_result report from this project.

run(output_path: Path, read_output: Any) bool

VUnit test runner sends another argument “read_output” which we don’t use.

class tsfpga.build_project_list.BuildProjectCreateWrapper(project: VivadoProject, **kwargs: Any)

Bases: object

Wrapper to create a build project, for usage in the build runner. Mimics a VUnit test object.

__init__(project: VivadoProject, **kwargs: Any) None
run(output_path: Path, read_output: Any) bool

VUnit test runner sends another argument “read_output” which we don’t use.

class tsfpga.build_project_list.BuildProjectList(modules: ModuleList, project_filters: list[str], include_netlist_not_top_builds: bool = False, no_color: bool = False)

Bases: object

Interface to handle a list of FPGA build projects. Enables building many projects in parallel.

__init__(modules: ModuleList, project_filters: list[str], include_netlist_not_top_builds: bool = False, no_color: bool = False)
Parameters:
  • modules – Module objects that can define build projects.

  • project_filters – Project name filters. Can use wildcards (*). Leave empty for all.

  • include_netlist_not_top_builds – Set True to get only netlist builds, instead of only top level builds.

  • no_color – Disable color in printouts.

build(projects_path: Path, num_parallel_builds: int, num_threads_per_build: int, output_path: Path | None = None, collect_artifacts: Callable[[VivadoProject, Path], bool] | None = None, **kwargs: Any) bool

Build all the projects in the list.

Parameters:
  • projects_path – The projects are placed here.

  • num_parallel_builds – The number of projects that will be built in parallel.

  • num_threads_per_build – The number threads that will be used for each parallel build process.

  • output_path – Where the artifacts should be placed. Will default to within the projects_path if not set.

  • collect_artifacts

    Callback to collect artifacts. Takes two named arguments:

    project (VivadoProject): The project that is being built.
    output_path (pathlib.Path): Where the build artifacts should be placed.
    Must return True.

  • kwargs

    Other arguments as accepted by VivadoProject.build().

    Note

    Argument project_path can not be set, it is set by this class based on the project_paths argument to this function.

    Argument num_threads is set by the num_threads_per_build argument to this function. This naming difference is done to avoid confusion with regards to num_parallel_builds.

Returns:

True if everything went well.

create(projects_path: Path, num_parallel_builds: int, **kwargs: Any) bool

Create build project on disk for all the projects in the list.

Parameters:
  • projects_path – The projects will be placed here.

  • num_parallel_builds – The number of projects that will be created in parallel.

  • kwargs

    Other arguments as accepted by VivadoProject.create().

    Note

    Argument project_path can not be set, it is set by this class based on the project_paths argument to this function.

Returns:

True if everything went well.

create_unless_exists(projects_path: Path, num_parallel_builds: int, **kwargs: Any) bool

Create build project for all the projects in the list, unless the project already exists.

Parameters:
  • projects_path – The projects will be placed here.

  • num_parallel_builds – The number of projects that will be created in parallel.

  • kwargs

    Other arguments as accepted by VivadoProject.create().

    Note

    Argument project_path can not be set, it is set by this class based on the project_paths argument to this function.

Returns:

True if everything went well.

static get_build_project_output_path(project: VivadoProject, projects_path: Path, output_path: Path | None = None) Path

Find where build artifacts will be placed for a project. Arguments are the same as for build().

get_short_str() str

Returns a short string with a description list of the projects.

This is an alternative function that is more compact than __str__.

open(projects_path: Path) bool

Open the projects in EDA GUI.

Parameters:

projects_path – The projects are placed here.

Returns:

True if everything went well.

class tsfpga.build_project_list.BuildProjectOpenWrapper(project: VivadoProject)

Bases: object

Wrapper to open a build project, for usage in the build runner. Mimics a VUnit test object.

__init__(project: VivadoProject) None
run(output_path: Path, read_output: Any) bool

VUnit test runner sends another argument “read_output” which we don’t use.

class tsfpga.build_project_list.BuildReport(printer=<vunit.color_printer.LinuxColorPrinter object>)

Bases: TestReport

add_result(*args: Any, **kwargs: Any) None

Overloaded from super class.

Add a a test result.

Uses a different Result class than the super method.

print_latest_status(total_tests: int) None

Overloaded from super class.

This method is called for each build when it should print its result just as it finished, but other builds may not be finished yet.

Inherited and adapted from the VUnit function: * Removed support for the “skipped” result. * Do not use abbreviations in the printout. * Use f-strings.

set_report_length(report_length_lines: int) None

Set the report length for all test results that have been added to the report.

class tsfpga.build_project_list.BuildResult(name, status, time, output_file_name)

Bases: TestResult

print_status(printer: Any, padding: int = 0, **kwargs: dict[str, Any]) None

Overloaded from super class.

The printer argument should of type ColorPrinter from VUnit.

This method is called for each build when it should print its result in the “Summary” at the end when all builds have finished.

Inherited and adapted from the VUnit function.

Note that a max_time integer argument is added in VUnit >4.7.0, but at the time of writing this is un-released on the VUnit master branch. In order to be compatible with both older and newer versions, we use **kwargs for this.

report_length_lines = None
set_report_length(report_length_lines: int) None

Set how many lines shall be printed when this result is printed.

class tsfpga.build_project_list.BuildRunner(report, output_path, verbosity=1, num_threads=1, fail_fast=False, dont_catch_exceptions=False, no_color=False)

Bases: TestRunner

Build runner that mimics a VUnit TestRunner. Most things are used as they are in the base class, but some behavior is overridden.

class tsfpga.build_project_list.ThreadSafeCollectArtifacts(collect_artifacts: Callable[[...], bool])

Bases: object

A thread-safe wrapper around a user-supplied function that makes sure the function is not launched more than once at the same time. When two builds finish at the same time, race conditions can arise depending on what the function does.

Note that this is a VERY fringe case, since builds usually take >20 minutes, and the collection probably only takes a few seconds. But it happens sometimes with the tsfpga example projects which are identical and quite fast (roughly three minutes).

__init__(collect_artifacts: Callable[[...], bool]) None
collect_artifacts(project: VivadoProject, output_path: Path) bool

tsfpga.build_step_tcl_hook module

class tsfpga.build_step_tcl_hook.BuildStepTclHook(tcl_file: Path, hook_step: str)

Bases: object

Represent a TCL file that shall be used as hook in one of the build steps.

__init__(tcl_file: Path, hook_step: str) None
Parameters:
property step_is_synth: bool

True if the build step is in synthesis. False otherwise.

tsfpga.constraint module

class tsfpga.constraint.Constraint(file: Path, used_in: str = 'all', scoped_constraint: bool = False, processing_order: str = 'normal')

Bases: object

Class for handling a constraint file.

Can handle the regular global constraint files as well as scoped constraints. For the latter to work the constraint file name must be the same as the .vhd file name, which must be the same as the entity name.

__init__(file: Path, used_in: str = 'all', scoped_constraint: bool = False, processing_order: str = 'normal') None
Parameters:
  • file – Path to the constraint file. Typically ends in .xdc or .tcl.

  • used_in – Optionally the constraint can be enabled only for “synth” or “impl”.

  • scoped_constraint – If enabled the constraint file will be loaded with the “-ref” argument in Vivado. An entity with the same name must exist.

  • processing_order – Optionally the processing order can be changed to “early” or “late”.

validate_scoped_entity(source_files: list[HdlFile]) bool

Make sure that a matching entity file exists in case this is a scoped constraint. The list of source files should be the synthesis files for the module that this constraint belongs to.

tsfpga.create_ghdl_ls_config module

tsfpga.create_ghdl_ls_config.create_ghdl_ls_configuration(output_path: Path, modules: ModuleList, vunit_proj: Any, simlib: VivadoSimlibCommon | None = None) None

Create a configuration file (hdl-prj.json) for the vhdl-lsp VHDL Language Server (https://github.com/ghdl/ghdl-language-server).

Can be used with modules and an “empty” VUnit project, or with a complete VUnit project with all user files added.

Execution of this function takes roughly 12 ms for a large project (62 modules and a VUnit project).

Parameters:
  • output_path – Output folder.

  • modules – Source files from these modules will be included.

  • vunit_proj – A VUnit project.

  • simlib – Source from this Vivado simlib project will be added.

tsfpga.create_vhdl_ls_config module

tsfpga.create_vhdl_ls_config.create_configuration(output_path: Path, modules: ModuleList | None = None, vunit_proj: VUnit | None = None, files: list[tuple[Path, str]] | None = None, vivado_location: Path | None = None, ip_core_vivado_project_directory: Path | None = None) None

Create a configuration file (vhdl_ls.toml) for the rust_hdl VHDL Language Server (https://github.com/VHDL-LS/rust_hdl).

Can be used with modules and an “empty” VUnit project, or with a complete VUnit project with all user files added. Files can also be added manually with the files argument.

Execution of this function takes roughly 12 ms for a large project (62 modules and a VUnit project).

Parameters:
  • output_path – vhdl_ls.toml file will be placed in this folder.

  • modules – All files from these modules will be added.

  • vunit_proj

    All files in this VUnit project will be added. This includes the files from VUnit itself, and any user files.

    Warning

    Using a VUnit project with user files and location/check preprocessing enabled is dangerous, since it introduces the risk of editing a generated file.

  • files – All files listed here will be added. Can be used to add additional files outside of the modules or the VUnit project. The list shall contain tuples: (Path, "library name").

  • vivado_location – Vivado binary path. The unisim from this Vivado installation will be added.

  • ip_core_vivado_project_directory – Path to a Vivado project that contains generated “simulation” and “synthesis” files of IP cores (the “generate_target” TCL command). See examples.simulate.py for an example of using this.

tsfpga.git_simulation_subset module

class tsfpga.git_simulation_subset.GitSimulationSubset(repo_root: Path, reference_branch: str, vunit_proj: VUnit, modules: ModuleList | None = None, vunit_preprocessed_path: Path | None = None)

Bases: object

Find a subset of testbenches to simulate based on git history.

__init__(repo_root: Path, reference_branch: str, vunit_proj: VUnit, modules: ModuleList | None = None, vunit_preprocessed_path: Path | None = None) None
Parameters:
  • repo_root – Root directory where git commands will be run.

  • reference_branch – What git branch to compare against, when finding what files have changed. Typically “origin/main” or “origin/master”.

  • vunit_proj – A vunit project with all source files and testbenches added. Will be used for dependency scanning.

  • modules

    A list of modules that are included in the VUnit project.

    When this argument is provided, this class will look for changes in the modules’ register data files, and simulate the testbenches that depend on register artifacts in case of any changes.

    This argument must be supplied if VUnit preprocessing is enabled.

  • vunit_preprocessed_path – If location/check preprocessing is enabled in your VUnit project, supply the path to vunit_out/preprocessed.

find_subset() list[tuple[str, str]]

Return all testbenches that have changes, or depend on files that have changes.

Returns:

The testbench names and their corresponding library names. A list of tuples (“testbench name”, “library name”).

tsfpga.git_utils module

tsfpga.git_utils.find_git_files(directory: Path, exclude_directories: list[Path] | None = None, file_endings_include: str | tuple[str] | None = None, file_endings_avoid: str | tuple[str] | None = None) Iterator[Path]

Find files that are checked in to git.

Parameters:
  • directory – Search in this directory.

  • exclude_directories – Files in these directories will not be included.

  • file_endings_include – Only files with these endings will be included.

  • file_endings_avoid – Files with these endings will not be included.

Returns:

The files that are available in git.

tsfpga.git_utils.get_git_commit(directory: Path) str

Get a string describing the current git commit. E.g. "abcdef0123" or "12345678 (local changes present)".

Parameters:

directory – The directory where git commands will be run.

Returns:

Git commit information.

tsfpga.git_utils.get_git_sha(directory: Path) str

Get a short git SHA.

Parameters:

directory – The directory where git commands will be run.

Returns:

The SHA.

tsfpga.git_utils.git_commands_are_available(directory: Path) bool

True if “git” command executable is available, and directory is in a valid git repo.

tsfpga.git_utils.git_local_changes_present(directory: Path) bool

Check if the git repo has local changes.

Parameters:

directory – The directory where git commands will be run.

Returns:

True if the repo contains changes that have been made after the last commit.

tsfpga.hdl_file module

class tsfpga.hdl_file.HdlFile(path: Path)

Bases: object

Class for representing a HDL source code file in the file system.

class Type(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: Enum

Enumeration of supported HDL file types.

SYSTEMVERILOG_HEADER = 5
SYSTEMVERILOG_SOURCE = 4
VERILOG_HEADER = 3
VERILOG_SOURCE = 2
VHDL = 1
__init__(path: Path) None
Parameters:

path – Path to a HDL source code file.

file_endings = ('.vhd', '.vhdl', '.v', '.vh', '.sv', '.svh')
file_endings_mapping = {Type.SYSTEMVERILOG_HEADER: ('.svh',), Type.SYSTEMVERILOG_SOURCE: ('.sv',), Type.VERILOG_HEADER: ('.vh',), Type.VERILOG_SOURCE: ('.v',), Type.VHDL: ('.vhd', '.vhdl')}
property path: Path

Path to the HDL file. Getter for read-only class variable.

property type: Type

The file type of the HDL file. Getter for read-only class variable.

tsfpga.ip_core_file module

class tsfpga.ip_core_file.IpCoreFile(path: Path, **variables: Any)

Bases: object

Class for handling an IP core file.

__init__(path: Path, **variables: Any) None
Parameters:
  • path – Path to the TCL script that creates the IP. Should typically end in .tcl.

  • variables

    These name/value variable pairs will be set in TCL before the IP core .tcl file is sourced. This makes it possible to parameterize the IP core creation.

    Note

    This is a “kwargs” style argument. You can pass any number of named arguments.

property name: str

A shorthand name for this IP core.

tsfpga.math_utils module

tsfpga.math_utils.to_binary_nibble_string(value: int, result_width_bits: int) str

Convert unsigned integer value to a zero-padded string of 1’s and 0’s, with each nibble (4 bits) separated by “_”. Most significant bit is the first (left-most) character in the string.

For example, value 37, width 6, returns 10_0101. For example, value 37, width 8, returns 0010_0101.

Parameters:
  • value – The value to be converted.

  • result_width_bits – The supplied value will be interpreted as an unsigned value with this many bits. The result string will contain this many bit characters, plus separators.

tsfpga.math_utils.to_binary_string(value: int, result_width: int) str

Convert unsigned integer value to a zero-padded string of 1’s and 0’s. Most significant bit is the first (left-most) character in the string.

For example, value 37, width 6, returns 100101. For example, value 37, width 8, returns 00100101.

Parameters:
  • value – The value to be converted.

  • result_width – The supplied value will be interpreted as an unsigned value with this many bits. The result string will contain this many bit characters.

tsfpga.math_utils.to_hex_byte_string(value: int, result_width_bits: int) str

Convert unsigned integer value to a zero-padded string of 01ABCDEF, with each byte (8 bits, 2 result characters) separated by “_”. Most significant bit is the first (left-most) character in the string.

For example, value 60, width 6, returns 3C. For example, value 60, width 9, returns 0_3C.

Parameters:
  • value – The value to be converted.

  • result_width_bits – The supplied value will be interpreted as an unsigned value with this many bits. The result string will contain enough hex characters to represent this many bits (rounded up), plus separators.

tsfpga.math_utils.to_hex_string(value: int, result_width_bits: int) str

Convert unsigned integer value to a zero-padded string of 01ABCDEF. Most significant bit is the first (left-most) character in the string.

For example, value 60, width 6, returns 3C. For example, value 60, width 9, returns 03C.

Parameters:
  • value – The value to be converted.

  • result_width_bits – The supplied value will be interpreted as an unsigned value with this many bits. The result string will contain enough hex characters to represent this many bits (rounded up).

tsfpga.module module

class tsfpga.module.BaseModule(path: Path, library_name: str, default_registers: list[Register] | None = None)

Bases: object

Base class for handling a HDL module with RTL code, constraints, etc.

Files are gathered from a lot of different sub-folders, to accommodate for projects having different catalog structure.

__init__(path: Path, library_name: str, default_registers: list[Register] | None = None)
Parameters:
  • path – Path to the module folder.

  • library_name – VHDL library name.

  • default_registers – Default registers.

add_vunit_config(test: Any, name: str | None = None, generics: dict[str, Any] | None = None, set_random_seed: bool | int | None = False, pre_config: Callable[[...], bool] | None = None, post_check: Callable[[...], bool] | None = None) None

Add config for VUnit test case. Wrapper that sets a suitable name and can set a random seed generic.

Parameters:
  • test – VUnit test object. Can be testbench or test case.

  • name – Optional designated name for this config. Will be used to form the name of the config together with the generics value.

  • generics – Generic values that will be applied to the testbench entity. The values will also be used to form the name of the config.

  • set_random_seed

    Controls setting of the seed generic:

    • When this argument is not assigned, or assigned False, the generic will not be set.

    • When set to boolean True, a random natural (non-negative integer) generic value will be set.

    • When set to an integer value, that value will be set for the generic. This is useful to get a static test case name for waveform inspection.

    If the generic is to be set it must exist in the testbench entity, and should have VHDL type natural.

  • pre_config – Function to be run before the test. See VUnit documentation for details.

  • post_check

    Function to be run after the test. See VUnit documentation for details.

create_axi_lite_wrapper = True
create_record_package = True
create_register_package = True
create_register_simulation_files() None

Create the register artifacts that are needed for simulation. Does not create the implementation files, which are also technically needed for simulation. So a call to create_register_synthesis_files() must also be done.

If this module does not have registers, this method does nothing.

create_register_synthesis_files() None

Create the register artifacts that are needed for synthesis. If this module does not have registers, this method does nothing.

create_simulation_check_package = True
create_simulation_read_write_package = True
create_simulation_wait_until_package = True
get_build_projects() list[VivadoProject]

Get FPGA build projects defined by this module.

Note

This default method does nothing. Should be overridden by modules that set up build projects.

Returns:

FPGA build projects.

get_documentation_files(files_include: set[Path] | None = None, files_avoid: set[Path] | None = None, include_vhdl_files: bool = True, include_verilog_files: bool = True, include_systemverilog_files: bool = True, **kwargs: Any) list[HdlFile]

Get a list of files that shall be included in a documentation build.

It will return all files from the module except testbenches and any generated register package. Overwrite in a subclass if you want to change this behavior.

Parameters:
  • files_include – Optionally filter to only include these files.

  • files_avoid – Optionally filter to discard these files.

  • include_vhdl_files – Optionally disable inclusion of files with VHDL file endings.

  • include_verilog_files – Optionally disable inclusion of files with Verilog file endings.

  • include_systemverilog_files – Optionally disable inclusion of files with SystemVerilog file endings.

Returns:

Files that should be included in documentation.

get_ip_core_files(files_include: set[Path] | None = None, files_avoid: set[Path] | None = None, **kwargs: Any) list[IpCoreFile]

Get IP cores for this module.

Note that the ip_core_file.IpCoreFile class accepts a variables argument that can be used to parameterize IP core creation. By overloading this method in a subclass you can pass on kwargs arguments from the build/simulation flow to ip_core_file.IpCoreFile creation to achieve this parameterization.

Parameters:
  • files_include – Optionally filter to only include these files.

  • files_avoid – Optionally filter to discard these files.

  • kwargs – Further parameters that can be sent by build/simulation flow to control what IP cores are included and what their variables are.

Returns:

The IP cores for this module.

get_scoped_constraints(files_include: set[Path] | None = None, files_avoid: set[Path] | None = None, **kwargs: Any) list[Constraint]

Constraints that shall be applied to a certain entity within this module.

Parameters:
  • files_include – Optionally filter to only include these files.

  • files_avoid – Optionally filter to discard these files.

  • kwargs – Further parameters that can be sent by build/simulation flow to control what constraints are included.

Returns:

The constraints.

get_simulation_files(include_tests: bool = True, files_include: set[Path] | None = None, files_avoid: set[Path] | None = None, include_vhdl_files: bool = True, include_verilog_files: bool = True, include_systemverilog_files: bool = True, **kwargs: Any) list[HdlFile]

See get_synthesis_files() for instructions on how to use files_include and files_avoid.

Parameters:
  • include_tests – When False, the test files are not included (the sim files are always included).

  • files_include – Optionally filter to only include these files.

  • files_avoid – Optionally filter to discard these files.

  • include_vhdl_files – Optionally disable inclusion of files with VHDL file endings.

  • include_verilog_files – Optionally disable inclusion of files with Verilog file endings.

  • include_systemverilog_files – Optionally disable inclusion of files with SystemVerilog file endings.

  • kwargs – Further parameters that can be sent by simulation flow to control what files are included.

Returns:

Files that should be included in a simulation project.

get_synthesis_files(files_include: set[Path] | None = None, files_avoid: set[Path] | None = None, include_vhdl_files: bool = True, include_verilog_files: bool = True, include_systemverilog_files: bool = True, **kwargs: Any) list[HdlFile]

Get a list of files that shall be included in a synthesis project.

The files_include and files_avoid arguments can be used to filter what files are included. This can be useful in many situations, e.g. when encrypted files of files that include an IP core shall be avoided. It is recommended to overload this function in a subclass in your module_*.py, and call this super method with the arguments supplied.

Parameters:
  • files_include – Optionally filter to only include these files.

  • files_avoid – Optionally filter to discard these files.

  • include_vhdl_files – Optionally disable inclusion of files with VHDL file endings.

  • include_verilog_files – Optionally disable inclusion of files with Verilog file endings.

  • include_systemverilog_files – Optionally disable inclusion of files with SystemVerilog file endings.

  • kwargs – Further parameters that can be sent by build flow to control what files are included.

Returns:

Files that should be included in a synthesis project.

pre_build(project: VivadoProject, **kwargs: Any) bool

This method hook will be called before an FPGA build is run. A typical use case for this mechanism is to set a register constant or default value based on the generics that are passed to the project. Could also be used to, e.g., generate BRAM init files based on project information, etc.

Note

This default method does nothing. Should be overridden by modules that utilize this mechanism.

Parameters:
Returns:

True if everything went well.

property register_data_file: Path

The path to this module’s register data file (which may or may not exist).

property register_simulation_folder: Path

Generated register artifacts that are needed for simulation will be placed in this folder.

property register_synthesis_folder: Path

Generated register artifacts that are needed for synthesis/implementation will be placed in this folder.

property registers: RegisterList | None

Get the registers for this module. Will be None if the module doesn’t have any registers. I.e. if no TOML file exists and no hook creates registers.

registers_hook() None

This function will be called directly after creating this module’s registers from the TOML definition file. If the TOML file does not exist this hook will still be called, but the module’s registers will be None.

This is a good place if you want to add or modify some registers from Python. Override this method and implement the desired behavior in a subclass.

Note

This default method does nothing. Shall be overridden by modules that utilize this mechanism.

setup_vunit(vunit_proj: Any, **kwargs: Any) None

Setup local configuration of this module’s test benches.

Note

This default method does nothing. Should be overridden by modules that have any test benches that operate via generics.

Parameters:
  • vunit_proj – The VUnit project that is used to run simulation.

  • kwargs – Use this to pass an arbitrary list of arguments from your simulate.py to the module where you set up your tests. This could be, e.g., data dimensions, location of test files, etc.

property sim_folders: list[Path]

Files with simulation models (the sim folder) will be gathered from these folders.

property synthesis_folders: list[Path]

Synthesis/implementation source code files will be gathered from these folders.

static test_case_name(name: str | None = None, generics: dict[str, Any] | None = None) str

Construct a string suitable for naming test cases.

Parameters:
  • name – Optional base name.

  • generics – Dictionary of values that will be included in the name.

Returns:

For example MyBaseName.GenericA_ValueA.GenericB_ValueB.

property test_folders: list[Path]

Testbench files will be gathered from these folders.

tsfpga.module.get_module(name: str, modules_folder: Path | None = None, modules_folders: list[Path] | None = None, library_name_has_lib_suffix: bool = False, default_registers: list[Register] | None = None) BaseModule

Get a single module object, for a module found in one of the specified source code folders. Is a wrapper around get_modules().

Parameters:
  • name – The name of the module.

  • modules_folder – The path to the folder containing modules.

  • modules_folders – Optionally, you can specify many folders with modules that will all be searched.

  • library_name_has_lib_suffix – If set, the library name will be <module name>_lib, otherwise it is just <module name>.

  • default_registers – Default registers.

Returns:

The requested module.

tsfpga.module.get_modules(modules_folder: Path | None = None, modules_folders: list[Path] | None = None, names_include: set[str] | None = None, names_avoid: set[str] | None = None, library_name_has_lib_suffix: bool = False, default_registers: list[Register] | None = None) ModuleList

Get a list of module objects (BaseModule or subclasses thereof) based on the source code folders.

Parameters:
  • modules_folder – The path to the folder containing modules.

  • modules_folders – Optionally, you can specify many folders with modules that will all be searched.

  • names_include – If specified, only modules with these names will be included.

  • names_avoid – If specified, modules with these names will be discarded.

  • library_name_has_lib_suffix – If set, the library name will be <module name>_lib, otherwise it is just <module name>.

  • default_registers – Default registers.

Returns:

The modules created from the specified folders.

tsfpga.module_documentation module

class tsfpga.module_documentation.ModuleDocumentation(module: BaseModule, repository_url: str | None = None, repository_name: str | None = None)

Bases: object

Methods for generating a reStructuredText document with module documentation. The content is extracted from VHDL source file headers.

__init__(module: BaseModule, repository_url: str | None = None, repository_name: str | None = None) None
Parameters:
  • module – The module which shall be documented.

  • repository_url – Optionally specify an URL where the source code can be viewed. If this argument is specified, links will be added to the documentation. URL should be to the module folder within the repository.

  • repository_name – Optionally specify the name of the repository URL. For example “GitLab”.

create_rst_document(output_path: Path, exclude_module_folders: list[str] | None = None) None

Create an .rst file in output_path with the content from get_rst_document(). If the module has registers, the HTML page will also be generated in output_path, so that e.g. sphinx can be run directly.

Parameters:
  • output_path – Document will be placed here.

  • exclude_module_folders – Folder names within the module root that shall be excluded from documentation.

get_overview_rst() str | None

Get the contents of the module’s doc/<name>.rst, i.e. the module “overview” document.

Returns:

Module overview RST. None if file does not exist.

get_register_rst(heading_character: str) str | None

Get an RST snippet with a link to the module’s register documentation, if available. Note that this will create an RST :download: statement to the register .html page. When building, the .html file must be present in the same directory as the .rst file. This is done automatically by create_rst_document().

Parameters:

heading_character – Character to use for heading underline.

Returns:

RST snippet with link to register HTML. None if module does not have registers.

get_rst_document(exclude_module_folders: list[str] | None = None) str

Get a complete RST document with the content of get_overview_rst(), get_register_rst(), and get_submodule_rst(), as well as a top level heading.

Parameters:

exclude_module_folders – Folder names within the module root that shall be excluded from documentation.

Returns:

An RST document.

get_submodule_rst(heading_character: str, heading_character_2: str, exclude_files: set[Path] | None = None, exclude_module_folders: list[str] | None = None) str

Get RST code with documentation of the different sub-modules (files) of the module. Contains documentation that is extracted from the file headers, as well as a symbolator symbol of the entity.

Parameters:
  • heading_character – Character to use for heading underline.

  • heading_character_2 – Character to use for next level of heading underline.

  • exclude_files – Files that shall be excluded from the documentation.

  • exclude_module_folders – Folder names within the module root that shall be excluded from documentation. For example, if you chosen module structure places only netlist build wrappers in the “rtl/” folder within modules, and you do not want them included in the documentation, then pass the argument [“rtl”].

Returns:

RST code with sub-module documentation.

tsfpga.module_list module

class tsfpga.module_list.ModuleList

Bases: object

Wrapper for a list of modules, with convenience functions.

__init__() None
append(module: BaseModule) None

Append a module to the list.

copy() ModuleList

Create a shallow copy of the module list. This public function is available as a convenience and to mimic the interface of a regular python list.

get(module_name: str) BaseModule

Get the module with the specified name. If no module matched, an exception is raised.

tsfpga.svn_utils module

tsfpga.svn_utils.check_that_svn_commands_are_available(cwd: Path | None = None) None

Raise an exception unless “svn” command executable is available and cwd is in a valid SVN repo.

Parameters:

cwd – The directory where SVN commands will be run.

tsfpga.svn_utils.find_svn_files(directory: Path, excludes: list[Path] | None = None, file_endings_include: str | tuple[str, ...] | None = None, file_endings_avoid: str | tuple[str, ...] | None = None) Iterable[Path]

Find files that are checked in to SVN. It runs “svn status” rather than “svn ls”. This means that it is a local operation, that does not require credentials or any connection with an SVN server.

Parameters:
  • directory – Search in this directory.

  • excludes – These files and folders will not be included.

  • file_endings_include – Only files with these endings will be included.

  • file_endings_avoid – Files with these endings will not be included.

Returns:

The files that are available in SVN.

tsfpga.svn_utils.get_svn_revision(cwd: Path | None = None) int

Get the current SVN revision number.

Parameters:

cwd – The directory where SVN commands will be run.

tsfpga.svn_utils.get_svn_revision_information(cwd: Path | None = None) str

Get a string describing the current SVN commit. E.g. "r1234" or "r1234 (local changes present)".

Parameters:

cwd – The directory where SVN commands will be run.

tsfpga.svn_utils.svn_commands_are_available(cwd: Path | None = None) bool

True if “svn” command executable is available and cwd is in a valid SVN repo.

Parameters:

cwd – The directory where SVN commands will be run.

tsfpga.svn_utils.svn_local_changes_are_present(cwd: Path | None = None) bool

Return true if the repo contains changes that have been made after the last commit. Info from here: https://rubyinrails.com/2014/01/11/svn-command-to-check-modified-files/

Parameters:

cwd – The directory where SVN commands will be run.

tsfpga.system_utils module

tsfpga.system_utils.create_directory(directory: Path, empty: bool = True) Path

Create a directory.

Parameters:
  • directory – Path to the directory.

  • empty – If true and the directory already exists, all existing files/folders in it will be deleted. If false, the directory will be left as-is if it already exists, or will be newly created if it does not.

Returns:

The path that was created (i.e. the original directory argument).

tsfpga.system_utils.create_file(file: Path, contents: str | None = None) Path

Create the file and any parent directories that do not exist. File will be empty unless contents is specified.

Returns:

The path to the file that was created (i.e. the original file argument).

tsfpga.system_utils.delete(path: Path, wait_until_deleted: bool = False) Path

Delete a file or directory from the filesystem.

Parameters:
  • path – The file/directory to be deleted.

  • wait_until_deleted – When set to True, the function will poll the filesystem after initiating the deletion, and not return until the path is in fact deleted. Is needed on some filesystems/mounts in a situation where we delete a path and then directly want to write to it afterwards.

Returns:

The path that was deleted (i.e. the original path argument).

tsfpga.system_utils.file_is_in_directory(file_path: Path, directories: list[Path]) bool

Check if the file is in any of the directories.

Parameters:
  • file_path – The file to be checked.

  • directories – The directories to be controlled.

Returns:

True if there is a common path.

tsfpga.system_utils.load_python_module(file: Path) Any

Load the specified Python module. Note that in Python nomenclature, a module is a source code file.

On the returned object, you can call functions or instantiate classes that are in the module.

tsfpga.system_utils.path_relative_to(path: Path, other: Path) Path

Return a relative path from other to path. This function works even if path is not inside a other folder.

Note Path.relative_to() does not support the use case where e.g. readme.md should get relative path “../readme.md”. Hence we have to use os.path.

tsfpga.system_utils.read_file(file: Path) str

Read and return the file contents.

tsfpga.system_utils.read_last_lines_of_file(file: Path, num_lines: int) str

Read a number of lines from the end of a file, without buffering the whole file. Similar to unix tail command.

Parameters:
  • file – The file that shall be read.

  • num_lines – The number of lines to read.

Returns:

The last lines of the file.

tsfpga.system_utils.run_command(cmd: list[str], cwd: Path | None = None, env: dict[str, str] | None = None, capture_output: bool = False) CompletedProcess[str]

Will raise CalledProcessError if the command fails.

Parameters:
  • cmd – The command to run.

  • cwd – The working directory where the command shall be executed.

  • env – Environment variables to set.

  • capture_output – Enable capturing of STDOUT and STDERR.

Returns:

Returns the subprocess completed process object, which contains useful information. If capture_output is set, the stdout and stderr members of this object can be inspected.

tsfpga.system_utils.system_is_windows() bool

Return True if the script is being executed on a computer running the Windows operating system.

tsfpga.vhdl_file_documentation module

class tsfpga.vhdl_file_documentation.VhdlFileDocumentation(vhd_file_path: Path)

Bases: object

Methods to extract documentation from a VHDL source file.

__init__(vhd_file_path: Path) None
Parameters:

vhd_file_path – Path to the VHDL file which shall be documented.

get_header_rst() str | None

Get the contents of the VHDL file’s header. This means everything that is in the comment block at the start of the file, after the copyright notice.

Returns:

File header content.

get_symbolator_component() str | None

Return a string with a component declaration equivalent to the entity declaration within the file. (We use entity’s but symbolator requires component’s).

Default values and range declarations on ports are removed since symbolator does not seem to handle them.

This implementation uses some regular expressions to find the generics and ports and modify them. The use of regular expressions makes it somewhat simple but also limited. Comments in strange places, specifically the string port ( in a comment will make the mechanism fail. Also an entity with generics but no ports will be falsely interpreted as only ports.

These known limitations do not pose any known practical problem and are hence considered worth it in order to keep the implementation simple. The real solution would be to fix upstream in symbolator and hdlparse.

Returns:

VHDL component declaration. None if file is a package, and hence contains no entity. None if no entity is found in the file.