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

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""" 

9 

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 

26 

27 

28# --------- apio sim 

29 

30 

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. 

40 

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] 

48 

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. 

52 

53[NOTE] Testbench specification is always the testbench file path relative to \ 

54the project directory, even if using the '--project-dir' option. 

55 

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. 

62 

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. 

66 

67[code]# Instead of this 

68$fatal; 

69 

70# Use this 

71if (!`APIO_SIM) $fatal;[/code] 

72 

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""" 

77 

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) 

86 

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) 

95 

96 

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 """ 

129 

130 # pylint: disable=too-many-arguments 

131 # pylint: disable=too-many-positional-arguments 

132 

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 ) 

141 

142 # -- Create the scons manager. 

143 scons = SConsManager(apio_ctx) 

144 

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) 

154 

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 ) 

162 

163 # -- Simulate the project with the given parameters 

164 exit_code = scons.sim(sim_params) 

165 

166 # -- Done! 

167 sys.exit(exit_code)