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

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 --no-gtkwave # Simulate but skip GTKWave. 

46 apio sim --detach # Launch and forget gtkwave.[/code] 

47 

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. 

51 

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

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

54 

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. 

58 

59[code]# Instead of this 

60$fatal; 

61 

62# Use this 

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

64 

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

69 

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) 

78 

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) 

87 

88 

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

116 

117 # pylint: disable=too-many-arguments 

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

119 

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 ) 

128 

129 # -- Create the scons manager. 

130 scons = SConsManager(apio_ctx) 

131 

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) 

139 

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 ) 

147 

148 # -- Simulate the project with the given parameters 

149 exit_code = scons.sim(sim_params) 

150 

151 # -- Done! 

152 sys.exit(exit_code)