Coverage for tsfpga/examples/simulate.py: 0%
48 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-10-28 20:52 +0000
« prev ^ index » next coverage.py v7.6.4, created at 2024-10-28 20:52 +0000
1# --------------------------------------------------------------------------------------------------
2# Copyright (c) Lukas Vik. All rights reserved.
3#
4# This file is part of the tsfpga project, a project platform for modern FPGA development.
5# https://tsfpga.com
6# https://github.com/tsfpga/tsfpga
7# --------------------------------------------------------------------------------------------------
9# Standard libraries
10import argparse
11import sys
12from pathlib import Path
13from typing import TYPE_CHECKING, Any, Optional
15if TYPE_CHECKING:
16 # First party libraries
17 from tsfpga.module_list import ModuleList
19# Do PYTHONPATH insert() instead of append() to prefer any local repo checkout over any pip install.
20REPO_ROOT = Path(__file__).parent.parent.parent.resolve()
21sys.path.insert(0, str(REPO_ROOT))
23# Import before others since it modifies PYTHONPATH. pylint: disable=unused-import
24import tsfpga.examples.example_pythonpath # noqa: F401
26# First party libraries
27import tsfpga
28import tsfpga.create_vhdl_ls_config
29from tsfpga.create_ghdl_ls_config import create_ghdl_ls_configuration
30from tsfpga.examples.example_env import (
31 TSFPGA_EXAMPLES_TEMP_DIR,
32 get_hdl_modules,
33 get_tsfpga_example_modules,
34)
35from tsfpga.examples.simulation_utils import (
36 SimulationProject,
37 create_vhdl_ls_configuration,
38 get_arguments_cli,
39)
40from tsfpga.git_simulation_subset import GitSimulationSubset
43def main() -> None:
44 """
45 Main function for the simulation flow. If you are setting up a new simulation environment
46 you probably want to copy and modify this function. The other functions and classes
47 should be reusable in most cases.
48 """
49 cli = get_arguments_cli(default_output_path=TSFPGA_EXAMPLES_TEMP_DIR)
50 args = cli.parse_args()
52 modules = get_tsfpga_example_modules()
53 modules_no_sim = get_hdl_modules()
55 if args.vcs_minimal:
56 if args.test_patterns != "*":
57 sys.exit(
58 "Can not specify a test pattern when using the --vcs-minimal flag."
59 f' Got "{args.test_patterns}"',
60 )
62 test_filters = find_git_test_filters(
63 args=args,
64 repo_root=tsfpga.REPO_ROOT,
65 modules=modules,
66 modules_no_sim=modules_no_sim,
67 reference_branch="origin/main",
68 )
69 if not test_filters:
70 print("Nothing to run. Appears to be no VHDL-related git diff.")
71 return
73 # Override the test pattern argument to VUnit.
74 args.test_patterns = test_filters
75 print(f"Running VUnit with test pattern {args.test_patterns}")
77 # Enable minimal compilation in VUnit
78 args.minimal = True
80 simulation_project = SimulationProject(args=args)
81 simulation_project.add_modules(
82 args=args,
83 modules=modules,
84 modules_no_sim=modules_no_sim,
85 include_verilog_files=False,
86 include_systemverilog_files=False,
87 )
88 simlib = simulation_project.add_vivado_simlib()
89 ip_core_vivado_project_directory = simulation_project.add_vivado_ip_cores(
90 modules=modules + modules_no_sim
91 )
92 # Synopsys is needed by unisim MMCME2_ADV primitive.
93 # Relaxed rules needed by unisim VITAL2000 package.
94 # Do not use in any new code.
95 simulation_project.vunit_proj.set_sim_option("ghdl.elab_flags", ["-frelaxed", "-fsynopsys"])
97 create_vhdl_ls_configuration(
98 output_path=tsfpga.REPO_ROOT,
99 temp_files_path=TSFPGA_EXAMPLES_TEMP_DIR,
100 modules=modules + modules_no_sim,
101 ip_core_vivado_project_directory=ip_core_vivado_project_directory,
102 )
104 create_ghdl_ls_configuration(
105 output_path=tsfpga.REPO_ROOT,
106 modules=modules + modules_no_sim,
107 vunit_proj=simulation_project.vunit_proj,
108 simlib=simlib,
109 )
111 simulation_project.vunit_proj.main()
114def find_git_test_filters(
115 args: argparse.Namespace,
116 repo_root: Path,
117 modules: "ModuleList",
118 modules_no_sim: Optional["ModuleList"] = None,
119 reference_branch: str = "origin/master",
120 **setup_vunit_kwargs: Any,
121) -> list[str]:
122 """
123 Construct a VUnit test filter that will run all test cases that are affected by git changes.
124 The current git state is compared to a reference branch, and differences are derived.
125 See :class:`.GitSimulationSubset` for details.
127 Arguments:
128 args: Command line argument namespace.
129 repo_root: Path to the repository root. Git commands will be run here.
130 modules: Will be passed on to :meth:`.SimulationProject.add_modules`.
131 modules_no_sim: Will be passed on to :meth:`.SimulationProject.add_modules`.
132 reference_branch (str): The name of the reference branch that is used to collect a diff.
133 setup_vunit_kwargs : Will be passed on to :meth:`.SimulationProject.add_modules`.
135 Return:
136 A list of VUnit test case filters.
137 """
138 # Set up a dummy VUnit project that will be used for dependency scanning.
139 # Note that sources are added identical to the "real" project above.
140 simulation_project = SimulationProject(args=args)
141 simulation_project.add_modules(
142 args=args,
143 modules=modules,
144 modules_no_sim=modules_no_sim,
145 include_verilog_files=False,
146 include_systemverilog_files=False,
147 **setup_vunit_kwargs,
148 )
150 testbenches_to_run = GitSimulationSubset(
151 repo_root=repo_root,
152 reference_branch=reference_branch,
153 vunit_proj=simulation_project.vunit_proj,
154 modules=modules,
155 ).find_subset()
157 test_filters = []
158 for testbench_file_name, library_name in testbenches_to_run:
159 test_filters.append(f"{library_name}.{testbench_file_name}.*")
161 return test_filters
164if __name__ == "__main__":
165 main()