Skip to content

Commit

Permalink
Fix bug where FSM may cause inferred latch (#390)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkorbel1 authored Jun 29, 2023
1 parent ad73088 commit 7dab293
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
17 changes: 15 additions & 2 deletions lib/src/state_machine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
/// Author: Shubham Kumar <shubham.kumar@intel.com>
///
import 'dart:collection';
import 'dart:io';
import 'dart:math';

import 'package:collection/collection.dart';
import 'package:rohd/rohd.dart';

/// Simple class for FSM [StateMachine].
Expand Down Expand Up @@ -91,7 +91,20 @@ class StateMachine<StateIdentifier> {
]))
.toList(growable: false),
conditionalType: ConditionalType.unique,
defaultItem: [nextState < currentState])
defaultItem: [
nextState < currentState,

// zero out all other receivers from state actions...
// even though out-of-state is unreachable,
// we don't want any inferred latches
..._states
.map((state) => state.actions)
.flattened
.map((conditional) => conditional.receivers)
.flattened
.toSet()
.map((receiver) => receiver < 0)
])
]);

Sequential(clk, [
Expand Down
13 changes: 12 additions & 1 deletion test/fsm_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ class TestModule extends Module {
}, actions: [
b < c,
]),
State<MyStates>(MyStates.state2, events: {}, actions: []),
State<MyStates>(MyStates.state2, events: {}, actions: [
b < 1,
]),
State<MyStates>(MyStates.state3, events: {}, actions: [
b < ~c,
]),
Expand Down Expand Up @@ -120,6 +122,15 @@ void main() {

setUpAll(() => Directory(_tmpDir).createSync(recursive: true));

test('zero-out receivers in default case', () async {
final pipem = TestModule(Logic(), Logic(), Logic());
await pipem.build();

final sv = pipem.generateSynth();

expect(sv, contains("b = 1'h0;"));
});

group('simcompare', () {
test('simple fsm', () async {
final pipem = TestModule(Logic(), Logic(), Logic());
Expand Down

0 comments on commit 7dab293

Please sign in to comment.