StateMachine<StateIdentifier> constructor Null safety

StateMachine<StateIdentifier>(
  1. Logic clk,
  2. Logic reset,
  3. StateIdentifier resetState,
  4. List<State<StateIdentifier>> _states
)

Constructs a simple FSM, using the clk and reset signals. Also accepts the reset state to transition to resetState along with the List of _states of the FSM.

If a reset signal is provided the FSM transitions to the resetState on the next clock cycle.

Implementation

StateMachine(this.clk, this.reset, this.resetState, this._states)
    : _stateWidth = _logBase(_states.length, 2),
      currentState =
          Logic(name: 'currentState', width: _logBase(_states.length, 2)),
      nextState =
          Logic(name: 'nextState', width: _logBase(_states.length, 2)) {
  var stateCounter = 0;

  for (final state in _states) {
    _stateLookup[state.identifier] = state;
    _stateValueLookup[state] = stateCounter++;
  }

  Combinational([
    Case(
        currentState,
        _states
            .map((state) => CaseItem(
                    Const(_stateValueLookup[state], width: _stateWidth), [
                  ...state.actions,
                  Case(
                      Const(1),
                      state.events.entries
                          .map((entry) => CaseItem(entry.key, [
                                nextState <
                                    _stateValueLookup[
                                        _stateLookup[entry.value]]
                              ]))
                          .toList(),
                      conditionalType: ConditionalType.unique,
                      defaultItem: [nextState < currentState])
                ]))
            .toList(),
        conditionalType: ConditionalType.unique,
        defaultItem: [nextState < currentState])
  ]);

  Sequential(clk, [
    If(
      reset,
      then: [currentState < _stateValueLookup[_stateLookup[resetState]]],
      orElse: [currentState < nextState],
    )
  ]);
}