Coverage for apio / commands / apio_sim.py: 100%
32 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-08 02:47 +0000
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-08 02:47 +0000
1# -*- coding: utf-8 -*-
2# -- This file is part of the Apio project
3# -- (C) 2016-2024 FPGAwars
4# -- Authors
5# -- * Jesús Arroyo (2016-2019)
6# -- * Juan Gonzalez (obijuan) (2019-2024)
7# -- License GPLv2
8"""Implementation of 'apio sim' command"""
10import sys
11from typing import Optional
12from pathlib import Path
13import click
14from apio.common.apio_console import cout
15from apio.common.apio_styles import EMPH1
16from apio.managers.scons_manager import SConsManager
17from apio.commands import options
18from apio.apio_context import (
19 ApioContext,
20 PackagesPolicy,
21 ProjectPolicy,
22 RemoteConfigPolicy,
23)
24from apio.common.proto.apio_pb2 import SimParams
25from apio.utils import cmd_util
28# --------- apio sim
31# -- Text in the rich-text format of the python rich library.
32APIO_SIM_HELP = """
33The command 'apio sim' simulates the default or the specified testbench file \
34and displays its simulation results in a graphical GTKWave window. \
35The testbench is expected to have a name ending with _tb, such as \
36'main_tb.v' or 'main_tb.sv'. The default testbench file can be specified \
37using the apio.ini option 'default-testbench'. If 'default-testbench' is not \
38specified and the project has exactly one testbench file, that file will be \
39used as the default testbench.
41Example:[code]
42 apio sim # Simulate the default testbench.
43 apio sim my_module_tb.v # Simulate the specified testbench.
44 apio sim my_module_tb.sv # Simulate the specified testbench.
45 apio sim util/led_tb.v # Simulate a testbench in a sub-folder.
46 apio sim --no-gtkwave # Simulate but skip GTKWave.
47 apio sim --detach # Launch and forget gtkwave.[/code]
49[IMPORTANT] Avoid using the Verilog '$dumpfile()' function in your \
50testbenches, as this may override the default name and location Apio sets \
51for the generated .vcd file.
53[NOTE] Testbench specification is always the testbench file path relative to \
54the project directory, even if using the '--project-dir' option.
56[NOTE] If the testbench doesn't have a matching user-saved '.gtkw' file, \
57'apio sim' creates it automatically on each run to to have GTKWave displaying \
58the testbench signals. To customize the presentation of the signals, modify \
59them in GTKWave and save your configuration using the \
60'File > Write Save File' menu command. The 'apio sim' command will never \
61overwrite a '.gtkw' files that were saved in this way.
63The sim command defines the macro 'APIO_SIM=1' which can be used by \
64testbenches to skip `$fatal` statements to have the simulation continue and \
65generate signals for the GTKWave viewer.
67[code]# Instead of this
68$fatal;
70# Use this
71if (!`APIO_SIM) $fatal;[/code]
73[b][Hint][/b] When configuring the signals in GTKWave, save the \
74configuration so you don’t need to repeat it each time you run the \
75simulation.
76"""
78no_gtkw_wave_option = click.option(
79 "no_gtkwave", # Var name.
80 "-n",
81 "--no-gtkwave",
82 is_flag=True,
83 help="Skip GTKWave",
84 cls=cmd_util.ApioOption,
85)
87detach_option = click.option(
88 "detach", # Var name.
89 "-d",
90 "--detach",
91 is_flag=True,
92 help="Launch and forget GTKWave.",
93 cls=cmd_util.ApioOption,
94)
97@click.command(
98 name="sim",
99 cls=cmd_util.ApioCommand,
100 short_help="Simulate a testbench with graphic results.",
101 help=APIO_SIM_HELP,
102)
103@click.pass_context
104@click.argument(
105 "testbench_path",
106 metavar="[TESTBENCH-PATH]",
107 nargs=1,
108 required=False,
109)
110@options.force_option_gen(short_help="Force simulation.")
111@options.env_option_gen()
112@no_gtkw_wave_option
113@detach_option
114@options.project_dir_option
115def cli(
116 _: click.Context,
117 # Arguments
118 testbench_path: str,
119 # Options
120 force: bool,
121 env: Optional[str],
122 no_gtkwave: bool,
123 detach: bool,
124 project_dir: Optional[Path],
125):
126 """Implements the apio sim command. It simulates a single testbench
127 file and shows graphically the signal graphs.
128 """
130 # pylint: disable=too-many-arguments
131 # pylint: disable=too-many-positional-arguments
133 # -- Create the apio context.
134 apio_ctx = ApioContext(
135 project_policy=ProjectPolicy.PROJECT_REQUIRED,
136 remote_config_policy=RemoteConfigPolicy.CACHED_OK,
137 packages_policy=PackagesPolicy.ENSURE_PACKAGES,
138 project_dir_arg=project_dir,
139 env_arg=env,
140 )
142 # -- Create the scons manager.
143 scons = SConsManager(apio_ctx)
145 # -- If testbench not given, try to get a default from apio.ini.
146 if not testbench_path:
147 # -- If the option is not specified, testbench is set to None and
148 # -- we issue an error message in the scons process.
149 testbench_path = apio_ctx.project.get_str_option(
150 "default-testbench", None
151 )
152 if testbench_path:
153 cout(f"Using default testbench: {testbench_path}", style=EMPH1)
155 # -- Construct the scons sim params.
156 sim_params = SimParams(
157 testbench_path=testbench_path if testbench_path else None,
158 force_sim=force,
159 no_gtkwave=no_gtkwave,
160 detach_gtkwave=detach,
161 )
163 # -- Simulate the project with the given parameters
164 exit_code = scons.sim(sim_params)
166 # -- Done!
167 sys.exit(exit_code)