Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## Next Release

- Fixed `LogicValue.ofRadixString` round trips with empty separators and separators containing regular-expression metacharacters (<https://github.com/intel/rohd/issues/722>).

## 0.6.11

- Added `NetlistSynthesizer` for generating JSON netlists, with configurable synthesis passes, validation, and hierarchy support (<https://github.com/intel/rohd/pull/675>).
Expand Down
10 changes: 7 additions & 3 deletions lib/src/values/logic_value.dart
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,10 @@ abstract class LogicValue implements Comparable<LogicValue> {
/// illegal characters
/// in the string or too long of a value string.
///
/// Strings created by [toRadixString] are parsed by [ofRadixString].
/// Strings created by [toRadixString] are parsed by [ofRadixString].
/// [sepChar] is interpreted literally and must match the separator used when
/// formatting the string. An empty [sepChar] is allowed for strings without
/// separators.
///
/// If the LogicValue width is not encoded as round number of radix
/// characters, the leading character must be small enough to be encoded
Expand All @@ -773,12 +776,13 @@ abstract class LogicValue implements Comparable<LogicValue> {
/// - 11'h4aa
/// - 12'haa
static LogicValue ofRadixString(String valueString, {String sepChar = '_'}) {
if (radixStringChars.contains(sepChar)) {
if (sepChar.isNotEmpty && radixStringChars.contains(sepChar)) {
throw LogicValueConstructionException('separation character invalid');
}
final escapedSeparator = RegExp.escape(sepChar);
if (RegExp(r'^\d+').firstMatch(valueString) != null) {
final formatStr =
RegExp("^(\\d+)'([bqodh])([0-9aAbBcCdDeEfFzZxX<>$sepChar]*)")
RegExp("^(\\d+)'([bqodh])([0-9aAbBcCdDeEfFzZxX<>$escapedSeparator]*)")
.firstMatch(valueString);
if (formatStr != null) {
if (valueString.length != formatStr.group(0)!.length) {
Expand Down
15 changes: 15 additions & 0 deletions test/logic_value_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2144,6 +2144,21 @@ void main() {
}
});

for (final separator in ['', ']', r'\', '[', '^', '.', '-']) {
test('radixString literal separator "$separator" round trip', () {
final known = LogicValue.ofInt(0x1234abcd, 40);
final fourState = LogicValue.ofString('10xz1010zz01');
for (final radix in [2, 4, 8, 10, 16]) {
for (final value in [known, if (radix != 10) fourState]) {
final encoded = value.toRadixString(
radix: radix, leadingZeros: true, sepChar: separator);
expect(
LogicValue.ofRadixString(encoded, sepChar: separator), value);
}
}
});
}

test('radixString space separators', () {
final lv = LogicValue.ofRadixString("10'b10 0010 0111", sepChar: ' ');
expect(lv.toInt(), equals(551));
Expand Down