Repository: intel/rohd (dart)

Issue:
`WaveDumper` dumps improper vcd format for multi-bit values
## Describe the bug
Multi-bit values in dumped VCD files from `WaveDumper` are printed incorrectly.

Instead of things like `0101` it prints `1'b01'b11'b01'b1`, which is a result of a `toString` change to `LogicValue`.  

## To Reproduce
Dump any waveform of multi-bit signals and look at the dumped waveform in a waveform viewer.

## Expected behavior
Properly dumped waves.

## Actual behavior
Corrupted waves, shows "------" in GtkWave

**Additional context**  
The existing tests for `WaveDumper` did not test multi-bit values, only single bit values, which is how this bug was missed when it was introduced in v0.3.0.

Pull request:
<!-- Please make sure you check out the contribution guidelines before submitting a pull request! -->

## Description & Motivation

Fix a bug where multi-bit values don't properly dump into VCDs by the `WaveDumper`.

## Related Issue(s)

Fix #129 

## Testing

Added new tests to cover this scenario.

## Backwards-compatibility

> Is this a breaking change that will not be backwards-compatible?  If yes, how so?

No

## Documentation

> Does the change require any updates to documentation?  If so, where?  Are they included?

No

Patch:
diff --git a/lib/src/wave_dumper.dart b/lib/src/wave_dumper.dart
index f8dfdfb41..d55ec07fa 100644
--- a/lib/src/wave_dumper.dart
+++ b/lib/src/wave_dumper.dart
@@ -172,7 +172,10 @@ class WaveDumper {
   void _writeSignalValueUpdate(Logic signal) {
     var updateValue = signal.width > 1
         ? 'b' +
-            signal.value.reversed.toList().map((e) => e.toString()).join() +
+            signal.value.reversed
+                .toList()
+                .map((e) => e.toString(includeWidth: false))
+                .join() +
             ' '
         : signal.value.toString(includeWidth: false);
     var marker = _signalToMarkerMap[signal];


Test patch:
diff --git a/test/wave_dumper_test.dart b/test/wave_dumper_test.dart
index 76fc58012..3a80f5898 100644
--- a/test/wave_dumper_test.dart
+++ b/test/wave_dumper_test.dart
@@ -16,8 +16,8 @@ import 'package:test/test.dart';
 
 class SimpleModule extends Module {
   SimpleModule(Logic a) {
-    a = addInput('a', a);
-    addOutput('b') <= ~a;
+    a = addInput('a', a, width: a.width);
+    addOutput('b', width: a.width) <= ~a;
   }
 }
 
@@ -194,4 +194,50 @@ void main() {
 
     deleteTemporaryDump(dumpName);
   });
+
+  test('multi-bit value', () async {
+    var a = Logic(name: 'a', width: 8);
+    var mod = SimpleModule(a);
+    await mod.build();
+
+    var dumpName = 'multiBit';
+
+    createTemporaryDump(mod, dumpName);
+    a.inject(0x5a);
+
+    Simulator.registerAction(10, () => a.put(0xa5));
+    await Simulator.run();
+
+    var vcdContents = File(temporaryDumpPath(dumpName)).readAsStringSync();
+
+    expect(confirmValue(vcdContents, 'a', 0, LogicValue.ofInt(0x5a, 8)),
+        equals(true));
+    expect(confirmValue(vcdContents, 'a', 10, LogicValue.ofInt(0xa5, 8)),
+        equals(true));
+
+    deleteTemporaryDump(dumpName);
+  });
+
+  test('multi-bit value mixed invalid', () async {
+    var a = Logic(name: 'a', width: 8);
+    var mod = SimpleModule(a);
+    await mod.build();
+
+    var dumpName = 'multiBitInvalid';
+
+    createTemporaryDump(mod, dumpName);
+    a.inject(LogicValue.ofString('01xzzx10'));
+
+    Simulator.registerAction(10, () => a.put(LogicValue.ofString('0x0x1z1z')));
+    await Simulator.run();
+
+    var vcdContents = File(temporaryDumpPath(dumpName)).readAsStringSync();
+
+    expect(confirmValue(vcdContents, 'a', 0, LogicValue.ofString('01xzzx10')),
+        equals(true));
+    expect(confirmValue(vcdContents, 'a', 10, LogicValue.ofString('0x0x1z1z')),
+        equals(true));
+
+    deleteTemporaryDump(dumpName);
+  });
 }