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

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.[/code] 

46 

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

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

49 

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. 

53 

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. 

57 

58[code]# Instead of this 

59$fatal; 

60 

61# Use this 

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

63 

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

68 

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) 

77 

78 

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

104 

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 ) 

113 

114 # -- Create the scons manager. 

115 scons = SConsManager(apio_ctx) 

116 

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) 

124 

125 # -- Construct the scons sim params. 

126 sim_params = SimParams( 

127 testbench=testbench, force_sim=force, no_gtkwave=no_gtkwave 

128 ) 

129 

130 # -- Simulate the project with the given parameters 

131 exit_code = scons.sim(sim_params) 

132 

133 # -- Done! 

134 sys.exit(exit_code)