Skip to content

Commit

Permalink
Unique case with multiple match behavior (#403)
Browse files Browse the repository at this point in the history
  • Loading branch information
dmetis authored Sep 6, 2023
1 parent 0d8735e commit 858daad
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 11 deletions.
26 changes: 15 additions & 11 deletions lib/src/modules/conditional.dart
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,16 @@ abstract class Conditional {
/// This is used for [Combinational.ssa].
Map<Logic, Logic> _processSsa(Map<Logic, Logic> currentMappings,
{required int context});

/// Drives X to all receivers.
void _driveX(Set<Logic> drivenSignals) {
for (final receiver in receivers) {
receiverOutput(receiver).put(LogicValue.x);
if (!drivenSignals.contains(receiver) || receiver.value.isValid) {
drivenSignals.add(receiver);
}
}
}
}

/// Represents a group of [Conditional]s to be executed.
Expand Down Expand Up @@ -1043,12 +1053,7 @@ class Case extends Conditional {

if (!expression.value.isValid) {
// if expression has X or Z, then propogate X's!
for (final receiver in receivers) {
receiverOutput(receiver).put(LogicValue.x);
if (!drivenSignals.contains(receiver) || receiver.value.isValid) {
drivenSignals.add(receiver);
}
}
_driveX(drivenSignals);
return;
}

Expand All @@ -1061,9 +1066,8 @@ class Case extends Conditional {
conditional.execute(drivenSignals, guard);
}
if (foundMatch != null && conditionalType == ConditionalType.unique) {
throw Exception('Unique case statement had multiple matching cases.'
' Original: "$foundMatch".'
' Duplicate: "$item".');
_driveX(drivenSignals);
return;
}

foundMatch = item;
Expand All @@ -1082,8 +1086,8 @@ class Case extends Conditional {
} else if (foundMatch == null &&
(conditionalType == ConditionalType.unique ||
conditionalType == ConditionalType.priority)) {
throw Exception('$conditionalType case statement had no matching case,'
' and type was $conditionalType.');
_driveX(drivenSignals);
return;
}
}

Expand Down
34 changes: 34 additions & 0 deletions test/conditionals_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,28 @@ class CaseModule extends Module {
}
}

class UniqueCase extends Module {
UniqueCase(Logic a, Logic b) : super(name: 'UniqueCase') {
a = addInput('a', a);
b = addInput('b', b);
final c = addOutput('c');
final d = addOutput('d');
Combinational([
Case(
Const(1),
[
CaseItem(a, [c < 1, d < 0]),
CaseItem(b, [c < 1, d < 0]),
],
defaultItem: [
c < 0,
d < 1,
],
conditionalType: ConditionalType.unique),
]);
}
}

enum SeqCondModuleType { caseNormal, caseZ, ifNormal }

class SeqCondModule extends Module {
Expand Down Expand Up @@ -568,6 +590,18 @@ void main() {
expect(simResult, equals(true));
});

test('Unique case', () async {
final mod = UniqueCase(Logic(), Logic());
await mod.build();
final vectors = [
Vector({'a': 0, 'b': 0}, {'c': 0, 'd': 1}),
Vector({'a': 0, 'b': 1}, {'c': 1, 'd': 0}),
Vector({'a': 1, 'b': 0}, {'c': 1, 'd': 0}),
Vector({'a': 1, 'b': 1}, {'c': LogicValue.x, 'd': LogicValue.x}),
];
await SimCompare.checkFunctionalVector(mod, vectors);
});

test('conditional ff', () async {
final mod = SequentialModule(Logic(), Logic(), Logic(width: 8));
await mod.build();
Expand Down

0 comments on commit 858daad

Please sign in to comment.