sim.pysim: use VCD aliases to reduce space and time overhead.
authorwhitequark <whitequark@whitequark.org>
Sat, 11 Jul 2020 12:25:31 +0000 (12:25 +0000)
committerwhitequark <whitequark@whitequark.org>
Sat, 11 Jul 2020 12:26:34 +0000 (12:26 +0000)
On Minerva SoC, this reduces VCD file size by about 35%, and reduces
runtime overhead of writing VCDs by 10% or less.

nmigen/sim/pysim.py
setup.py

index 9dde3459db63a8c310257927ca22bc3b0049f2a5..166e2a1d6aa320ed8a3c794b4e3c82a357033183 100644 (file)
@@ -111,23 +111,25 @@ class _VCDWaveformWriter(_WaveformWriter):
                             var_name_suffix = var_name
                         else:
                             var_name_suffix = "{}${}".format(var_name, suffix)
-                        vcd_var = self.vcd_writer.register_var(
-                            scope=var_scope, name=var_name_suffix,
-                            var_type=var_type, size=var_size, init=var_init)
+                        if signal not in self.vcd_vars:
+                            vcd_var = self.vcd_writer.register_var(
+                                scope=var_scope, name=var_name_suffix,
+                                var_type=var_type, size=var_size, init=var_init)
+                            self.vcd_vars[signal] = vcd_var
+                        else:
+                            self.vcd_writer.register_alias(
+                                scope=var_scope, name=var_name_suffix,
+                                var=self.vcd_vars[signal])
                         break
                     except KeyError:
                         suffix = (suffix or 0) + 1
 
-                if signal not in self.vcd_vars:
-                    self.vcd_vars[signal] = set()
-                self.vcd_vars[signal].add(vcd_var)
-
                 if signal not in self.gtkw_names:
                     self.gtkw_names[signal] = (*var_scope, var_name_suffix)
 
     def update(self, timestamp, signal, value):
-        vcd_vars = self.vcd_vars.get(signal)
-        if vcd_vars is None:
+        vcd_var = self.vcd_vars.get(signal)
+        if vcd_var is None:
             return
 
         vcd_timestamp = self.timestamp_to_vcd(timestamp)
@@ -135,8 +137,7 @@ class _VCDWaveformWriter(_WaveformWriter):
             var_value = self.decode_to_vcd(signal, value)
         else:
             var_value = value
-        for vcd_var in vcd_vars:
-            self.vcd_writer.change(vcd_var, vcd_timestamp, var_value)
+        self.vcd_writer.change(vcd_var, vcd_timestamp, var_value)
 
     def close(self, timestamp):
         if self.vcd_writer is not None:
index cb31d1c20aede8fc6e30b5bb0c1c978de933f2a3..335dde772726a4da16ec463e0ac67dc91ecf1166 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -40,7 +40,7 @@ setup(
     install_requires=[
         "importlib_metadata; python_version<'3.8'",  # for __version__ and nmigen._yosys
         "importlib_resources; python_version<'3.9'", # for nmigen._yosys
-        "pyvcd~=0.2.0", # for nmigen.pysim
+        "pyvcd~=0.2.2", # for nmigen.pysim
         "Jinja2~=2.11", # for nmigen.build
     ],
     extras_require={