cxxrtl: escape colon in variable names in VCD writer.
authorwhitequark <whitequark@whitequark.org>
Mon, 19 Jul 2021 16:20:49 +0000 (16:20 +0000)
committerwhitequark <whitequark@whitequark.org>
Mon, 19 Jul 2021 16:22:55 +0000 (16:22 +0000)
The following VCD file crashes GTKWave's VCD loader:

    $var wire 1 ! x:1 $end
    $enddefinitions $end

In practice, a colon can be a part of a variable name that is
translated from a Verilog function, something like:

    update$func$.../hdl/hazard3_csr.v:350$2534.$result

backends/cxxrtl/cxxrtl_vcd.h

index 3f40a8d122d4e409412e6a87318d82c60ddbdfa7..b76922bbd8a01731b07ed18fb49e671f5d613716 100644 (file)
@@ -69,12 +69,25 @@ class vcd_writer {
                } while (ident != 0);
        }
 
+       void emit_name(const std::string &name) {
+               for (char c : name) {
+                       if (c == ':') {
+                               // Due to a bug, GTKWave cannot parse a colon in the variable name, causing the VCD file
+                               // to be unreadable. It cannot be escaped either, so replace it with the sideways colon.
+                               buffer += "..";
+                       } else {
+                               buffer += c;
+                       }
+               }
+       }
+
        void emit_var(const variable &var, const std::string &type, const std::string &name,
                      size_t lsb_at, bool multipart) {
                assert(!streaming);
                buffer += "$var " + type + " " + std::to_string(var.width) + " ";
                emit_ident(var.ident);
-               buffer += " " + name;
+               buffer += " ";
+               emit_name(name);
                if (multipart || name.back() == ']' || lsb_at != 0) {
                        if (var.width == 1)
                                buffer += " [" + std::to_string(lsb_at) + "]";