diff --git a/rtl/__init__.py b/rtl/__init__.py index db75282..38491de 100644 --- a/rtl/__init__.py +++ b/rtl/__init__.py @@ -103,6 +103,46 @@ def interactive_rtl(self): def interactive_rtl(self, value): self._interactive_rtl = value + @property + def dump_waves(self): + """True | False (default) + + Generate a VCD waveform dumpfile without opening a waveform viewer. + If interactive_rtl is True, that takes precedence and this has + no effect.""" + + if not hasattr(self, "_dump_waves"): + self._dump_waves = False + return self._dump_waves + + @dump_waves.setter + def dump_waves(self, value): + self._dump_waves = value + + @property + def dumpfile_name(self): + """String (default '_dump.vcd') + + Basename of the VCD waveform dumpfile generated by interactive_rtl or + dump_waves. Set this to override the default name.""" + + if not hasattr(self, "_dumpfile_name"): + self._dumpfile_name = self.name + "_dump.vcd" + return self._dumpfile_name + + @dumpfile_name.setter + def dumpfile_name(self, value): + self._dumpfile_name = value + + @property + def dumpfilepath(self): + """String + + Full path to the VCD waveform dumpfile, i.e. dumpfile_name located in + rtlsimpath.""" + + return os.path.join(self.rtlsimpath, self.dumpfile_name) + @property def lsf_submission(self): """ @@ -374,12 +414,19 @@ def rtlsimpath(self): return self._rtlsimpath def delete_rtlsimpath(self): - """Deletes all files in rtlsimpath""" + """Deletes all files in rtlsimpath. + + ``self.preserve_rtlfiles`` preserves all files under rtlsimpath from deletion. + ``self.dump_waves`` preserves the waveform dump file. + """ + dumpfilename = self.dumpfile_name if os.path.exists(self.rtlsimpath): try: for target in os.listdir(self.rtlsimpath): targetpath = "%s/%s" % (self.rtlsimpath, target) - if self.preserve_rtlfiles: + if self.preserve_rtlfiles or ( + self.dump_waves and target == dumpfilename + ): self.print_log( type="I", msg="Preserving %s" % targetpath ) @@ -392,7 +439,7 @@ def delete_rtlsimpath(self): except: self.print_log(type="W", msg="Could not remove %s" % targetpath) - if not self.preserve_rtlfiles: + if not self.preserve_rtlfiles and not self.dump_waves: try: shutil.rmtree(self.rtlsimpath) self.print_log( diff --git a/rtl/ghdl/ghdl.py b/rtl/ghdl/ghdl.py index 4a8a422..4fbe8bb 100644 --- a/rtl/ghdl/ghdl.py +++ b/rtl/ghdl/ghdl.py @@ -83,36 +83,41 @@ def ghdl_rtlcmd(self): interactive_string = "" self.print_log(type="I", msg="No interactive control file set.") - if not self.interactive_rtl: + vcdstring = " --vcd=" + self.dumpfilepath + + if self.interactive_rtl: + submission = "" # Local execution rtlsimcmd = ( - "ghdl -r --std=08 --workdir=" + "ghdl -r --std=08 --workdir=" + self.rtlworkpath - + " tb_" - + self.name + " " + + "tb_" + + self.name + controlstring + + vcdstring + + " && gtkwave " + + interactive_string + + " " + + self.dumpfilepath ) - else: - submission = "" # Local execution + elif self.dump_waves: rtlsimcmd = ( - "ghdl -r --std=08 --workdir=" + "ghdl -r --std=08 --workdir=" + self.rtlworkpath + " " + "tb_" + self.name + controlstring - + " --vcd=" - + self.rtlsimpath - + "/" + + vcdstring + ) + else: + rtlsimcmd = ( + "ghdl -r --std=08 --workdir=" + + self.rtlworkpath + + " tb_" + self.name - + "_dump.vcd" - + " && gtkwave " - + interactive_string + " " - + self.rtlsimpath - + "/" - + self.name - + "_dump.vcd" + + controlstring ) self._rtlcmd = ( diff --git a/rtl/icarus/icarus.py b/rtl/icarus/icarus.py index a8f0cf4..4e66672 100644 --- a/rtl/icarus/icarus.py +++ b/rtl/icarus/icarus.py @@ -77,10 +77,7 @@ def icarus_rtlcmd(self): + " && gtkwave " + dostring + " " - + self.rtlsimpath - + "/" - + self.name - + "_dump.vcd" + + self.dumpfilepath ) else: rtlsimcmd = ( diff --git a/rtl/questasim/questasim.py b/rtl/questasim/questasim.py index c422f78..eb54e37 100644 --- a/rtl/questasim/questasim.py +++ b/rtl/questasim/questasim.py @@ -123,6 +123,15 @@ def questasim_rtlcmd(self): interactive_string = ' -do "run -all; quit;"' self.print_log(type="I", msg="No interactive control file set.") + if self.dump_waves and not self.interactive_rtl: + vcdstring = ( + ' -do "vcd file ' + + self.dumpfilepath + + '; vcd add -r *;"' + ) + else: + vcdstring = "" + # Choose command if not self.interactive_rtl: rtlsimcmd = ( @@ -135,6 +144,7 @@ def questasim_rtlcmd(self): + vlogsimargs + " work.tb_" + self.name + + vcdstring + controlstring ) else: diff --git a/rtl/testbench_common.py b/rtl/testbench_common.py index a6e915c..d2a6539 100644 --- a/rtl/testbench_common.py +++ b/rtl/testbench_common.py @@ -161,15 +161,11 @@ def dumpfile(self): if ( self.parent.model == "icarus" or self.parent.model == "verilator" - ) and self.parent.interactive_rtl: + ) and (self.parent.interactive_rtl or self.parent.dump_waves): dump_str = "// Generates dumpfile\n" dump_str += "initial begin\n" dump_str += ( - ' $dumpfile("' - + self.parent.rtlsimpath - + "/" - + self.parent.name - + '_dump.vcd");\n' + ' $dumpfile("' + self.parent.dumpfilepath + '");\n' ) dump_str += " $dumpvars(0, tb_" + self.parent.name + ");\nend \n" else: diff --git a/rtl/verilator/verilator.py b/rtl/verilator/verilator.py index 2d2c09b..4fe002f 100644 --- a/rtl/verilator/verilator.py +++ b/rtl/verilator/verilator.py @@ -84,10 +84,7 @@ def verilator_rtlcmd(self): + " && gtkwave " + dostring + " " - + self.rtlsimpath - + "/" - + self.name - + "_dump.vcd" + + self.dumpfilepath ) else: rtlsimcmd = "cd " + self.rtlworkpath + " && ./Vtb_" + self.name