Skip to content

Commit

Permalink
Upgrade VcdParser to handle more VCD files (#260)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkorbel1 authored Feb 7, 2023
1 parent 5ea9512 commit a0aa8fe
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 11 deletions.
35 changes: 24 additions & 11 deletions lib/src/utilities/vcd_parser.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
/// Copyright (C) 2023 Intel Corporation
/// SPDX-License-Identifier: BSD-3-Clause
///
/// vcd_parser.dart
/// Utility for parsing VCD files for tests
///
/// 2023 January 5
/// Author: Max Korbel <max.korbel@intel.com>
///
import 'package:rohd/rohd.dart';

/// State of VCD parsing
enum _VCDParseState { findSig, findDumpVars, findValue }
enum _VcdParseState { findSig, findDumpVars, findValue }

/// A parser for VCD files for testing purposes.
abstract class VcdParser {
Expand All @@ -19,28 +29,29 @@ abstract class VcdParser {
var currentTime = 0;
LogicValue? currentValue;

var state = _VCDParseState.findSig;
var state = _VcdParseState.findSig;

final sigNameRegexp = RegExp(r'\s*\$var\swire\s(\d+)\s(\S*)\s(\S*)\s\$end');
final sigNameRegexp = RegExp(
r'\s*\$var\s(wire|reg)\s(\d+)\s(\S*)\s(\S*)\s+(\[\d+\:\d+\])?\s*\$end');
for (final line in lines) {
if (state == _VCDParseState.findSig) {
if (state == _VcdParseState.findSig) {
if (sigNameRegexp.hasMatch(line)) {
final match = sigNameRegexp.firstMatch(line)!;
final w = int.parse(match.group(1)!);
final sName = match.group(2)!;
final lName = match.group(3)!;
final w = int.parse(match.group(2)!);
final sName = match.group(3)!;
final lName = match.group(4)!;

if (lName == signalName) {
sigName = sName;
width = w;
state = _VCDParseState.findDumpVars;
state = _VcdParseState.findDumpVars;
}
}
} else if (state == _VCDParseState.findDumpVars) {
} else if (state == _VcdParseState.findDumpVars) {
if (line.contains(r'$dumpvars')) {
state = _VCDParseState.findValue;
state = _VcdParseState.findValue;
}
} else if (state == _VCDParseState.findValue) {
} else if (state == _VcdParseState.findValue) {
if (line.startsWith('#')) {
currentTime = int.parse(line.substring(1));
if (currentTime > timestamp) {
Expand All @@ -54,6 +65,8 @@ abstract class VcdParser {
// ex: bzzzzzzzz s2
currentValue = LogicValue.ofString(line.split(' ')[0].substring(1));
}

currentValue = currentValue.zeroExtend(width!);
}
}
}
Expand Down
101 changes: 101 additions & 0 deletions test/example_icarus_waves.vcd
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
$date
Tue Feb 7 10:45:30 2023
$end
$version
Icarus Verilog
$end
$timescale
1ps
$end
$scope module cosim_wrapper $end
$scope module external_module $end
$var wire 1 ! clk $end
$var wire 8 " push_data [7:0] $end
$var wire 1 # push_valid $end
$var reg 8 $ sampled [7:0] $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
$dumpvars
bx $
z#
bz "
0!
$end
#5000
1!
#5002
b0 "
1#
#10000
0!
#15000
b0 $
1!
#15002
b1 "
0#
#20000
0!
#25000
1!
#25002
b10 "
1#
#30000
0!
#35000
b10 $
1!
#35002
b11 "
0#
#40000
0!
#45000
1!
#45002
b100 "
1#
#50000
0!
#55000
b100 $
1!
#55002
b101 "
0#
#60000
0!
#65000
1!
#65002
b110 "
1#
#70000
0!
#75000
b110 $
1!
#75002
b111 "
0#
#80000
0!
#85000
1!
#85002
b1000 "
1#
#90000
0!
#95000
b1000 $
1!
#95002
b1001 "
0#
#100000
0!
#100002
33 changes: 33 additions & 0 deletions test/vcd_parser_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/// Copyright (C) 2023 Intel Corporation
/// SPDX-License-Identifier: BSD-3-Clause
///
/// vcd_parser_test.dart
/// Tests for the VcdParser
///
/// 2023 February 7
/// Author: Max Korbel <max.korbel@intel.com>
///
import 'dart:io';

import 'package:rohd/rohd.dart';
import 'package:rohd/src/utilities/vcd_parser.dart';
import 'package:test/test.dart';

void main() {
test('VCD parser can parse Icarus Verilog generated VCD file', () {
final vcdContents =
File('test/example_icarus_waves.vcd').readAsStringSync();
for (var countI = 1; countI < 10; countI++) {
expect(
VcdParser.confirmValue(
vcdContents,
'sampled',
(10 * countI + 5) * 1000,
LogicValue.ofInt(countI.isEven ? countI - 2 : countI - 1, 8),
),
isTrue,
);
}
});
}

0 comments on commit a0aa8fe

Please sign in to comment.