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