2121from ..ostools import Process
2222from . import SimulatorInterface , ListOfStringOption , StringOption , BooleanOption
2323from ..vhdl_standard import VHDL
24+ from ._ossmixin import OSSMixin
2425
2526LOGGER = logging .getLogger (__name__ )
2627
2728
28- class GHDLInterface (SimulatorInterface ): # pylint: disable=too-many-instance-attributes
29+ class GHDLInterface (SimulatorInterface , OSSMixin ): # pylint: disable=too-many-instance-attributes
2930 """
3031 Interface for GHDL simulator
3132 """
@@ -43,7 +44,9 @@ class GHDLInterface(SimulatorInterface): # pylint: disable=too-many-instance-at
4344 sim_options = [
4445 ListOfStringOption ("ghdl.sim_flags" ),
4546 ListOfStringOption ("ghdl.elab_flags" ),
46- StringOption ("ghdl.gtkwave_script.gui" ),
47+ StringOption ("ghdl.gtkwave_script.gui" ), # Deprecated in v5.1.0
48+ StringOption ("ghdl.viewer_script.gui" ),
49+ StringOption ("ghdl.viewer.gui" ),
4750 BooleanOption ("ghdl.elab_e" ),
4851 ]
4952
@@ -52,14 +55,16 @@ def add_arguments(parser):
5255 """
5356 Add command line arguments
5457 """
55- group = parser .add_argument_group ("ghdl" , description = "GHDL specific flags" )
58+ group = parser .add_argument_group ("ghdl/nvc " , description = "GHDL/NVC specific flags" )
5659 group .add_argument (
60+ "--viewer-fmt" ,
5761 "--gtkwave-fmt" ,
5862 choices = ["vcd" , "fst" , "ghw" ],
5963 default = None ,
60- help = "Save .vcd, .fst, or .ghw to open in gtkwave " ,
64+ help = "Save .vcd, .fst, or .ghw to open in waveform viewer. NVC does not support ghw. " ,
6165 )
62- group .add_argument ("--gtkwave-args" , default = "" , help = "Arguments to pass to gtkwave" )
66+ group .add_argument ("--viewer-args" , "--gtkwave-args" , default = "" , help = "Arguments to pass to waveform viewer" )
67+ group .add_argument ("--viewer" , default = None , help = "Waveform viewer to use" )
6368
6469 @classmethod
6570 def from_args (cls , args , output_path , ** kwargs ):
@@ -71,8 +76,9 @@ def from_args(cls, args, output_path, **kwargs):
7176 output_path = output_path ,
7277 prefix = prefix ,
7378 gui = args .gui ,
74- gtkwave_fmt = args .gtkwave_fmt ,
75- gtkwave_args = args .gtkwave_args ,
79+ viewer_fmt = args .viewer_fmt ,
80+ viewer_args = args .viewer_args ,
81+ viewer = args .viewer ,
7682 backend = cls .determine_backend (prefix ),
7783 )
7884
@@ -88,20 +94,23 @@ def __init__( # pylint: disable=too-many-arguments
8894 output_path ,
8995 prefix ,
9096 gui = False ,
91- gtkwave_fmt = None ,
92- gtkwave_args = "" ,
97+ viewer_fmt = None ,
98+ viewer_args = "" ,
99+ viewer = None ,
93100 backend = "llvm" ,
94101 ):
95102 SimulatorInterface .__init__ (self , output_path , gui )
103+ OSSMixin .__init__ (
104+ self ,
105+ gui = gui ,
106+ viewer = viewer ,
107+ viewer_fmt = "ghw" if gui and viewer_fmt is None else viewer_fmt ,
108+ viewer_args = viewer_args ,
109+ )
110+
96111 self ._prefix = prefix
97112 self ._project = None
98113
99- if gui and (not self .find_executable ("gtkwave" )):
100- raise RuntimeError ("Cannot find the gtkwave executable in the PATH environment variable. GUI not possible" )
101-
102- self ._gui = gui
103- self ._gtkwave_fmt = "ghw" if gui and gtkwave_fmt is None else gtkwave_fmt
104- self ._gtkwave_args = gtkwave_args
105114 self ._backend = backend
106115 self ._vhdl_standard = None
107116 self ._coverage_test_dirs = set () # For gcov
@@ -315,11 +324,11 @@ def _get_command(
315324 sim += ["--ieee-asserts=disable" ]
316325
317326 if wave_file :
318- if self ._gtkwave_fmt == "ghw" :
327+ if self ._viewer_fmt == "ghw" :
319328 sim += [f"--wave={ wave_file !s} " ]
320- elif self ._gtkwave_fmt == "vcd" :
329+ elif self ._viewer_fmt == "vcd" :
321330 sim += [f"--vcd={ wave_file !s} " ]
322- elif self ._gtkwave_fmt == "fst" :
331+ elif self ._viewer_fmt == "fst" :
323332 sim += [f"--fst={ wave_file !s} " ]
324333
325334 if not ghdl_e :
@@ -355,8 +364,8 @@ def simulate(self, output_path, test_suite_name, config, elaborate_only): # pyl
355364
356365 ghdl_e = elaborate_only and config .sim_options .get ("ghdl.elab_e" , False )
357366
358- if self ._gtkwave_fmt is not None :
359- data_file_name = str (Path (script_path ) / f"wave.{ self ._gtkwave_fmt !s} " )
367+ if self ._viewer_fmt is not None :
368+ data_file_name = str (Path (script_path ) / f"wave.{ self ._viewer_fmt !s} " )
360369 if Path (data_file_name ).exists ():
361370 remove (data_file_name )
362371 else :
@@ -382,10 +391,19 @@ def simulate(self, output_path, test_suite_name, config, elaborate_only): # pyl
382391 except Process .NonZeroExitCode :
383392 status = False
384393
394+ if config .sim_options .get (self .name + ".gtkwave_script.gui" , None ):
395+ w = (
396+ "%s.gtkwave_script.gui is deprecated and will be removed " % self .name # pylint: disable=C0209
397+ + "in a future version, use %s.viewer_script.gui instead" % self .name # pylint: disable=C0209
398+ )
399+ LOGGER .warning (w )
400+
385401 if self ._gui and not elaborate_only :
386- cmd = ["gtkwave" ] + shlex .split (self ._gtkwave_args ) + [data_file_name ]
402+ cmd = [self . _get_viewer ( config ) ] + shlex .split (self ._viewer_args ) + [data_file_name ]
387403
388- init_file = config .sim_options .get (self .name + ".gtkwave_script.gui" , None )
404+ init_file = config .sim_options .get (
405+ self .name + ".viewer_script.gui" , config .sim_options .get (self .name + ".gtkwave_script.gui" , None )
406+ )
389407 if init_file is not None :
390408 cmd += ["--script" , str (Path (init_file ).resolve ())]
391409
0 commit comments