Coverage for apio / commands / apio_sim.py: 100%
32 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-24 01:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-24 01:53 +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 --no-gtkwave # Simulate but skip GTKWave.
46 apio sim --detach # Launch and forget gtkwave.[/code]
48[IMPORTANT] Avoid using the Verilog '$dumpfile()' function in your \
49testbenches, as this may override the default name and location Apio sets \
50for the generated .vcd file.
52[NOTE] Testbench specification is always the testbench file path relative to \
53the project directory, even if using the '--project-dir' option.
55The sim command defines the macro 'APIO_SIM=1' which can be used by \
56testbenches to skip `$fatal` statements to have the simulation continue and \
57generate signals for the GTKWave viewer.
59[code]# Instead of this
60$fatal;
62# Use this
63if (!`APIO_SIM) $fatal;[/code]
65[b][Hint][/b] When configuring the signals in GTKWave, save the \
66configuration so you don’t need to repeat it each time you run the \
67simulation.
68"""
70no_gtkw_wave_option = click.option(
71 "no_gtkwave", # Var name.
72 "-n",
73 "--no-gtkwave",
74 is_flag=True,
75 help="Skip GTKWave",
76 cls=cmd_util.ApioOption,
77)
79detach_option = click.option(
80 "detach", # Var name.
81 "-d",
82 "--detach",
83 is_flag=True,
84 help="Launch and forget GTKWave.",
85 cls=cmd_util.ApioOption,
86)
89@click.command(
90 name="sim",
91 cls=cmd_util.ApioCommand,
92 short_help="Simulate a testbench with graphic results.",
93 help=APIO_SIM_HELP,
94)
95@click.pass_context
96@click.argument("testbench", nargs=1, required=False)
97@options.force_option_gen(short_help="Force simulation.")
98@options.env_option_gen()
99@no_gtkw_wave_option
100@detach_option
101@options.project_dir_option
102def cli(
103 _: click.Context,
104 # Arguments
105 testbench: str,
106 # Options
107 force: bool,
108 env: Optional[str],
109 no_gtkwave: bool,
110 detach: bool,
111 project_dir: Optional[Path],
112):
113 """Implements the apio sim command. It simulates a single testbench
114 file and shows graphically the signal graphs.
115 """
117 # pylint: disable=too-many-arguments
118 # pylint: disable=too-many-positional-arguments
120 # -- Create the apio context.
121 apio_ctx = ApioContext(
122 project_policy=ProjectPolicy.PROJECT_REQUIRED,
123 remote_config_policy=RemoteConfigPolicy.CACHED_OK,
124 packages_policy=PackagesPolicy.ENSURE_PACKAGES,
125 project_dir_arg=project_dir,
126 env_arg=env,
127 )
129 # -- Create the scons manager.
130 scons = SConsManager(apio_ctx)
132 # -- If testbench not given, try to get a default from apio.ini.
133 if not testbench:
134 # -- If the option is not specified, testbench is set to None and
135 # -- we issue an error message in the scons process.
136 testbench = apio_ctx.project.get_str_option("default-testbench", None)
137 if testbench:
138 cout(f"Using default testbench: {testbench}", style=EMPH1)
140 # -- Construct the scons sim params.
141 sim_params = SimParams(
142 testbench=testbench,
143 force_sim=force,
144 no_gtkwave=no_gtkwave,
145 detach_gtkwave=detach,
146 )
148 # -- Simulate the project with the given parameters
149 exit_code = scons.sim(sim_params)
151 # -- Done!
152 sys.exit(exit_code)